diff --git a/Example/DApp/SceneDelegate.swift b/Example/DApp/SceneDelegate.swift index f4ed47f2c..03d23797f 100644 --- a/Example/DApp/SceneDelegate.swift +++ b/Example/DApp/SceneDelegate.swift @@ -136,15 +136,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { mobileLink: "wcflutterwallet://", linkMode: "https://lab.web3modal.com/walletkit_flutter" ), - .init( - id: "flutter-sample-internal", - name: "Flutter Sample Wallet Internal", - homepage: "https://walletconnect.com/", - imageUrl: "https://avatars.githubusercontent.com/u/37784886?s=200&v=4", - order: 1, - mobileLink: "wcflutterwallet-internal://", - linkMode: "https://lab.web3modal.com/walletkit_flutter_internal" - ), ] ) diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index 02e8b077f..a984e0a53 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -57,7 +57,6 @@ 84CE642127981DED00142511 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE642027981DED00142511 /* SceneDelegate.swift */; }; 84CE642827981DF000142511 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 84CE642727981DF000142511 /* Assets.xcassets */; }; 84CE642B27981DF000142511 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84CE642927981DF000142511 /* LaunchScreen.storyboard */; }; - 84CEC64628D89D6B00D081A8 /* PairingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CEC64528D89D6B00D081A8 /* PairingTests.swift */; }; 84D093EB2B4EA6CB005B1925 /* ActivityIndicatorManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84D093EA2B4EA6CB005B1925 /* ActivityIndicatorManager.swift */; }; 84DB38F32983CDAE00BFEE37 /* PushRegisterer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DB38F22983CDAE00BFEE37 /* PushRegisterer.swift */; }; 84E6B84A29787A8000428BAF /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E6B84929787A8000428BAF /* NotificationService.swift */; }; @@ -438,7 +437,6 @@ 84CE642A27981DF000142511 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 84CE642C27981DF000142511 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 84CE6453279FFE1100142511 /* Wallet.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Wallet.entitlements; sourceTree = ""; }; - 84CEC64528D89D6B00D081A8 /* PairingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PairingTests.swift; sourceTree = ""; }; 84D093EA2B4EA6CB005B1925 /* ActivityIndicatorManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorManager.swift; sourceTree = ""; }; 84D72FC62B4692770057EAF3 /* DApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DApp.entitlements; sourceTree = ""; }; 84DB38F029828A7C00BFEE37 /* WalletApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WalletApp.entitlements; sourceTree = ""; }; @@ -977,14 +975,6 @@ path = DApp; sourceTree = ""; }; - 84CEC64728D8A98900D081A8 /* Pairing */ = { - isa = PBXGroup; - children = ( - 84CEC64528D89D6B00D081A8 /* PairingTests.swift */, - ); - path = Pairing; - sourceTree = ""; - }; 84D2A66728A4F5260088AE09 /* Auth */ = { isa = PBXGroup; children = ( @@ -1457,7 +1447,6 @@ children = ( 847F07FE2A25DBC700B2A5A4 /* XPlatform */, 849D7A91292E2115006A2BD4 /* Push */, - 84CEC64728D8A98900D081A8 /* Pairing */, A5E03E0A28646A8A00888481 /* Stubs */, A5E03E0928646A8100888481 /* Sign */, 84D2A66728A4F5260088AE09 /* Auth */, @@ -2396,7 +2385,6 @@ files = ( A51606F92A2F47BD00CACB92 /* DefaultBIP44Provider.swift in Sources */, A5A0843E29D2F624000B9B17 /* DefaultCryptoProvider.swift in Sources */, - 84CEC64628D89D6B00D081A8 /* PairingTests.swift in Sources */, 767DC83528997F8E00080FA9 /* EthSendTransaction.swift in Sources */, 8439CB89293F658E00F2F2E2 /* PushMessage.swift in Sources */, A518B31428E33A6500A2CE93 /* InputConfig.swift in Sources */, @@ -3277,8 +3265,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/WalletConnect/web3modal-swift"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 1.0.0; + branch = "pairing-expiry"; + kind = branch; }; }; A5434021291E6A270068F706 /* XCRemoteSwiftPackageReference "solana-swift" */ = { diff --git a/Example/ExampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example/ExampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 53859947e..34a63bc5b 100644 --- a/Example/ExampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Example/ExampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/attaswift/BigInt.git", "state": { "branch": null, - "revision": "0ed110f7555c34ff468e72e1686e59721f2b0da6", - "version": "5.3.0" + "revision": "793a7fac0bfc318e85994bf6900652e827aef33e", + "version": "5.4.1" } }, { @@ -15,8 +15,8 @@ "repositoryURL": "https://github.com/krzyzanowskim/CryptoSwift.git", "state": { "branch": null, - "revision": "7892a123f7e8d0fe62f9f03728b17bbd4f94df5c", - "version": "1.8.1" + "revision": "678d442c6f7828def400a70ae15968aef67ef52d", + "version": "1.8.3" } }, { @@ -33,7 +33,7 @@ "repositoryURL": "https://github.com/mixpanel/mixpanel-swift", "state": { "branch": "master", - "revision": "9438b4a5f76bf2108b09f8fed1abbad8f353e1a2", + "revision": "61ce9b40817466fb1334db1d7a582fbaf616ab4c", "version": null } }, @@ -69,8 +69,8 @@ "repositoryURL": "https://github.com/getsentry/sentry-cocoa.git", "state": { "branch": null, - "revision": "38f4f70d07117b9f958a76b1bff278c2f29ffe0e", - "version": "8.21.0" + "revision": "d2ced2d961b34573ebd2ea0567a2f1408e90f0ae", + "version": "8.34.0" } }, { @@ -185,8 +185,8 @@ "package": "swift-web3modal", "repositoryURL": "https://github.com/WalletConnect/web3modal-swift", "state": { - "branch": null, - "revision": "25abd7e5471f21d662400f9763948fbf97c60c97", + "branch": "pairing-expiry", + "revision": "3088a08a43c490c24f1dfb1b858a67de089feef6", "version": null } } diff --git a/Example/IntegrationTests/Pairing/PairingTests.swift b/Example/IntegrationTests/Pairing/PairingTests.swift deleted file mode 100644 index 80c9e5f0a..000000000 --- a/Example/IntegrationTests/Pairing/PairingTests.swift +++ /dev/null @@ -1,86 +0,0 @@ -import Foundation -import XCTest -@testable import WalletConnectUtils -@testable import WalletConnectKMS -import WalletConnectRelay -import Combine -import WalletConnectNetworking -@testable import WalletConnectPairing -import WalletConnectSign - -final class PairingTests: XCTestCase { - - var appPairingClient: PairingClient! - var walletPairingClient: PairingClient! - - var pairingStorage: PairingStorage! - - private var publishers = [AnyCancellable]() - - func makeClient(prefix: String, includeSign: Bool = true) -> PairingClient { - let keychain = KeychainStorageMock() - let keyValueStorage = RuntimeKeyValueStorage() - - let logger = ConsoleLogger(prefix: prefix, loggingLevel: .debug) - - let relayClient = RelayClientFactory.create( - relayHost: InputConfig.relayHost, - projectId: InputConfig.projectId, - keyValueStorage: RuntimeKeyValueStorage(), - keychainStorage: keychain, - socketFactory: DefaultSocketFactory(), - networkMonitor: NetworkMonitor(), - logger: logger) - - let networkingClient = NetworkingClientFactory.create( - relayClient: relayClient, - logger: logger, - keychainStorage: keychain, - keyValueStorage: keyValueStorage) - - let pairingClient = PairingClientFactory.create( - logger: logger, - keyValueStorage: keyValueStorage, - keychainStorage: keychain, - networkingClient: networkingClient, - eventsClient: MockEventsClient()) - - - return pairingClient - } - - override func setUp() { - appPairingClient = makeClient(prefix: "🤖 Dapp: ") - walletPairingClient = makeClient(prefix: "🐶 Wallet: ", includeSign: false) - } - - func testPing() async { - let expectation = expectation(description: "expects ping response") - let uri = try! await appPairingClient.create() - try? await walletPairingClient.pair(uri: uri) - try! await walletPairingClient.ping(topic: uri.topic) - walletPairingClient.pingResponsePublisher - .sink { topic in - XCTAssertEqual(topic, uri.topic) - expectation.fulfill() - }.store(in: &publishers) - wait(for: [expectation], timeout: InputConfig.defaultTimeout) - } - - func testDisconnect() async { - - let expectation = expectation(description: "wallet disconnected pairing") - - - walletPairingClient.pairingDeletePublisher.sink { _ in - expectation.fulfill() - }.store(in: &publishers) - - let uri = try! await appPairingClient.create() - - try? await walletPairingClient.pair(uri: uri) - - try! await appPairingClient.disconnect(topic: uri.topic) - wait(for: [expectation], timeout: InputConfig.defaultTimeout) - } -} diff --git a/Example/IntegrationTests/Sign/SignClientTests.swift b/Example/IntegrationTests/Sign/SignClientTests.swift index 31f09a9e3..4575da2db 100644 --- a/Example/IntegrationTests/Sign/SignClientTests.swift +++ b/Example/IntegrationTests/Sign/SignClientTests.swift @@ -110,8 +110,7 @@ final class SignClientTests: XCTestCase { walletSettlementExpectation.fulfill() }.store(in: &publishers) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces) try await walletPairingClient.pair(uri: uri) await fulfillment(of: [dappSettlementExpectation, walletSettlementExpectation], timeout: InputConfig.defaultTimeout) } @@ -124,8 +123,7 @@ final class SignClientTests: XCTestCase { let store = Store() let semaphore = DispatchSemaphore(value: 0) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces) try await walletPairingClient.pair(uri: uri) wallet.sessionProposalPublisher.sink { [unowned self] (proposal, _) in @@ -164,8 +162,7 @@ final class SignClientTests: XCTestCase { sessionDeleteExpectation.fulfill() }.store(in: &publishers) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces) try await walletPairingClient.pair(uri: uri) await fulfillment(of: [sessionDeleteExpectation], timeout: InputConfig.defaultTimeout) } @@ -194,8 +191,8 @@ final class SignClientTests: XCTestCase { expectation.fulfill() }.store(in: &publishers) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces) + try await walletPairingClient.pair(uri: uri) await fulfillment(of: [expectation], timeout: InputConfig.defaultTimeout) @@ -247,8 +244,8 @@ final class SignClientTests: XCTestCase { responseExpectation.fulfill() }.store(in: &publishers) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces) + try await walletPairingClient.pair(uri: uri) await fulfillment(of: [requestExpectation, responseExpectation], timeout: InputConfig.defaultTimeout) } @@ -292,48 +289,10 @@ final class SignClientTests: XCTestCase { expectation.fulfill() }.store(in: &publishers) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, topic: uri.topic) - try await walletPairingClient.pair(uri: uri) - await fulfillment(of: [expectation], timeout: InputConfig.defaultTimeout) - } - - func testNewSessionOnExistingPairing() async throws { - let dappSettlementExpectation = expectation(description: "Dapp settles session") - dappSettlementExpectation.expectedFulfillmentCount = 2 - let walletSettlementExpectation = expectation(description: "Wallet settles session") - walletSettlementExpectation.expectedFulfillmentCount = 2 - let requiredNamespaces = ProposalNamespace.stubRequired() - let sessionNamespaces = SessionNamespace.make(toRespond: requiredNamespaces) - var initiatedSecondSession = false - - wallet.sessionProposalPublisher.sink { [unowned self] (proposal, _) in - Task(priority: .high) { - do { - _ = try await wallet.approve(proposalId: proposal.id, namespaces: sessionNamespaces) - } catch { - XCTFail("\(error)") - } - } - }.store(in: &publishers) - dapp.sessionSettlePublisher.sink { [unowned self] _ in - dappSettlementExpectation.fulfill() - let pairingTopic = dappPairingClient.getPairings().first!.topic - if !initiatedSecondSession { - Task(priority: .high) { - _ = try! await dapp.connect(requiredNamespaces: requiredNamespaces, topic: pairingTopic) - } - initiatedSecondSession = true - } - }.store(in: &publishers) - wallet.sessionSettlePublisher.sink { _ in - walletSettlementExpectation.fulfill() - }.store(in: &publishers) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, topic: uri.topic) try await walletPairingClient.pair(uri: uri) - await fulfillment(of: [dappSettlementExpectation, walletSettlementExpectation], timeout: InputConfig.defaultTimeout) + await fulfillment(of: [expectation], timeout: InputConfig.defaultTimeout) } func testSuccessfulSessionUpdateNamespaces() async throws { @@ -358,8 +317,8 @@ final class SignClientTests: XCTestCase { XCTAssertEqual(namespace.values.first?.accounts.count, 2) expectation.fulfill() }.store(in: &publishers) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces) + try await walletPairingClient.pair(uri: uri) await fulfillment(of: [expectation], timeout: InputConfig.defaultTimeout) } @@ -386,8 +345,8 @@ final class SignClientTests: XCTestCase { } }.store(in: &publishers) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces) + try await walletPairingClient.pair(uri: uri) await fulfillment(of: [expectation], timeout: InputConfig.defaultTimeout) @@ -417,8 +376,8 @@ final class SignClientTests: XCTestCase { } }.store(in: &publishers) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces) + try await walletPairingClient.pair(uri: uri) await fulfillment(of: [expectation], timeout: InputConfig.defaultTimeout) @@ -445,8 +404,8 @@ final class SignClientTests: XCTestCase { } }.store(in: &publishers) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces) + try await walletPairingClient.pair(uri: uri) await fulfillment(of: [expectation], timeout: InputConfig.defaultTimeout) @@ -524,8 +483,7 @@ final class SignClientTests: XCTestCase { walletSettlementExpectation.fulfill() }.store(in: &publishers) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, optionalNamespaces: optionalNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces, optionalNamespaces: optionalNamespaces) try await walletPairingClient.pair(uri: uri) await fulfillment(of: [dappSettlementExpectation, walletSettlementExpectation], timeout: InputConfig.defaultTimeout) } @@ -593,8 +551,8 @@ final class SignClientTests: XCTestCase { walletSettlementExpectation.fulfill() }.store(in: &publishers) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, optionalNamespaces: optionalNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces, optionalNamespaces: optionalNamespaces) + try await walletPairingClient.pair(uri: uri) await fulfillment(of: [dappSettlementExpectation, walletSettlementExpectation], timeout: InputConfig.defaultTimeout) } @@ -652,8 +610,8 @@ final class SignClientTests: XCTestCase { walletSettlementExpectation.fulfill() }.store(in: &publishers) - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, optionalNamespaces: optionalNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces, optionalNamespaces: optionalNamespaces) + try await walletPairingClient.pair(uri: uri) await fulfillment(of: [dappSettlementExpectation, walletSettlementExpectation], timeout: InputConfig.defaultTimeout) } @@ -715,8 +673,8 @@ final class SignClientTests: XCTestCase { settlementFailedExpectation.fulfill() } - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, optionalNamespaces: optionalNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces, optionalNamespaces: optionalNamespaces) + try await walletPairingClient.pair(uri: uri) await fulfillment(of: [settlementFailedExpectation], timeout: InputConfig.defaultTimeout) } @@ -781,8 +739,8 @@ final class SignClientTests: XCTestCase { settlementFailedExpectation.fulfill() } - let uri = try! await dappPairingClient.create() - try await dapp.connect(requiredNamespaces: requiredNamespaces, optionalNamespaces: optionalNamespaces, topic: uri.topic) + let uri = try! await dapp.connect(requiredNamespaces: requiredNamespaces, optionalNamespaces: optionalNamespaces) + try await walletPairingClient.pair(uri: uri) await fulfillment(of: [settlementFailedExpectation], timeout: 1) } diff --git a/Example/WalletApp/ApplicationLayer/ConfigurationService.swift b/Example/WalletApp/ApplicationLayer/ConfigurationService.swift index 970353746..7cd72d9db 100644 --- a/Example/WalletApp/ApplicationLayer/ConfigurationService.swift +++ b/Example/WalletApp/ApplicationLayer/ConfigurationService.swift @@ -67,7 +67,6 @@ final class ConfigurationService { Web3Wallet.instance.pairingExpirationPublisher .receive(on: DispatchQueue.main) .sink { pairing in - guard !pairing.active else { return } AlertPresenter.present(message: "Pairing has expired", type: .warning) }.store(in: &publishers) diff --git a/Package.swift b/Package.swift index 797d5622c..d674fea3c 100644 --- a/Package.swift +++ b/Package.swift @@ -13,9 +13,6 @@ let package = Package( .library( name: "WalletConnect", targets: ["WalletConnectSign"]), - .library( - name: "WalletConnectAuth", - targets: ["Auth"]), .library( name: "Web3Wallet", targets: ["Web3Wallet"]), @@ -54,10 +51,6 @@ let package = Package( dependencies: ["WalletConnectPairing", "WalletConnectVerify", "WalletConnectSigner", "Events"], path: "Sources/WalletConnectSign", resources: [.process("Resources/PrivacyInfo.xcprivacy")]), - .target( - name: "Auth", - dependencies: ["WalletConnectPairing", "WalletConnectSigner", "WalletConnectVerify"], - path: "Sources/Auth"), .target( name: "Web3Wallet", dependencies: ["WalletConnectSign", "WalletConnectPush", "WalletConnectVerify"], diff --git a/Sources/Auth/Auth.swift b/Sources/Auth/Auth.swift deleted file mode 100644 index 044e92bd8..000000000 --- a/Sources/Auth/Auth.swift +++ /dev/null @@ -1,46 +0,0 @@ -import Foundation -import Combine - -#if SWIFT_PACKAGE -public typealias VerifyContext = WalletConnectVerify.VerifyContext -#endif - -/// Auth instatnce wrapper -/// -/// ```Swift -/// let metadata = AppMetadata( -/// name: "Swift wallet", -/// description: "wallet", -/// url: "wallet.connect", -/// icons: ["https://my_icon.com/1"]) -/// Auth.configure(metadata: metadata, account: account) -/// try await Auth.instance.pair(uri: uri) -/// ``` -public class Auth { - - /// Auth client instance - public static var instance: AuthClient = { - guard let config = Auth.config else { - fatalError("Error - you must call Auth.configure(_:) before accessing the shared instance.") - } - return AuthClientFactory.create( - metadata: Pair.metadata, - projectId: Networking.projectId, - crypto: config.crypto, - networkingClient: Networking.interactor, - pairingRegisterer: Pair.registerer, - groupIdentifier: Networking.groupIdentifier - ) - }() - - private static var config: Config? - - private init() { } - - /// Auth instance wallet config method. For DApp usage - /// - Parameters: - /// - signerFactory: Auth signers factory - static public func configure(crypto: CryptoProvider) { - Auth.config = Auth.Config(crypto: crypto) - } -} diff --git a/Sources/Auth/AuthClient.swift b/Sources/Auth/AuthClient.swift deleted file mode 100644 index d9551bdde..000000000 --- a/Sources/Auth/AuthClient.swift +++ /dev/null @@ -1,118 +0,0 @@ -import Foundation -import Combine - -/// WalletConnect Auth Client -/// -/// Cannot be instantiated outside of the SDK -/// -/// Access via `Auth.instance` -@available(*, deprecated, message: "Use SignClient for dApps and Web3Wallet interface for wallets instead.") -public class AuthClient: AuthClientProtocol { - - // MARK: - Public Properties - - /// Publisher that sends authentication requests - /// - /// Wallet should subscribe on events in order to receive auth requests. - @available(*, deprecated, message: "Use SignClient for dApps and Web3Wallet interface for wallets instead.") - public var authRequestPublisher: AnyPublisher<(request: AuthRequest, context: VerifyContext?), Never> { - authRequestPublisherSubject.eraseToAnyPublisher() - } - - /// Publisher that sends authentication responses - /// - /// App should subscribe for events in order to receive CACAO object with a signature matching authentication request. - /// - /// Emited result may be an error. - @available(*, deprecated, message: "Use SignClient for dApps and Web3Wallet interface for wallets instead.") - public var authResponsePublisher: AnyPublisher<(id: RPCID, result: Result), Never> { - authResponsePublisherSubject.eraseToAnyPublisher() - } - - /// Publisher that sends web socket connection status - @available(*, deprecated, message: "Use Web3Wallet interface for managing socket connection status.") - public let socketConnectionStatusPublisher: AnyPublisher - - /// An object that loggs SDK's errors and info messages - public let logger: ConsoleLogging - - // MARK: - Private Properties - - private let pairingRegisterer: PairingRegisterer - - private var authResponsePublisherSubject = PassthroughSubject<(id: RPCID, result: Result), Never>() - private var authRequestPublisherSubject = PassthroughSubject<(request: AuthRequest, context: VerifyContext?), Never>() - private let appRequestService: AppRequestService - private let appRespondSubscriber: AppRespondSubscriber - private let walletRequestSubscriber: WalletRequestSubscriber - private let walletRespondService: WalletRespondService - private let pendingRequestsProvider: Auth_PendingRequestsProvider - - init(appRequestService: AppRequestService, - appRespondSubscriber: AppRespondSubscriber, - walletRequestSubscriber: WalletRequestSubscriber, - walletRespondService: WalletRespondService, - pendingRequestsProvider: Auth_PendingRequestsProvider, - logger: ConsoleLogging, - socketConnectionStatusPublisher: AnyPublisher, - pairingRegisterer: PairingRegisterer - ) { - self.appRequestService = appRequestService - self.walletRequestSubscriber = walletRequestSubscriber - self.walletRespondService = walletRespondService - self.appRespondSubscriber = appRespondSubscriber - self.pendingRequestsProvider = pendingRequestsProvider - self.logger = logger - self.socketConnectionStatusPublisher = socketConnectionStatusPublisher - self.pairingRegisterer = pairingRegisterer - setUpPublishers() - } - - /// For a dapp to send an authentication request to a wallet - /// - Parameter params: Set of parameters required to request authentication - /// - Parameter topic: Pairing topic that wallet already subscribes for - @available(*, deprecated, message: "Use SignClient for sending authentication requests.") - public func request(_ params: RequestParams, topic: String) async throws { - logger.debug("Requesting Authentication on existing pairing") - try pairingRegisterer.validatePairingExistance(topic) - try await appRequestService.request(params: params, topic: topic) - } - - /// For a wallet to respond on authentication request - /// - Parameters: - /// - requestId: authentication request id - /// - signature: CACAO signature of requested message - @available(*, deprecated, message: "Use Web3Wallet interface for responding to authentication requests.") - public func respond(requestId: RPCID, signature: CacaoSignature, from account: Account) async throws { - try await walletRespondService.respond(requestId: requestId, signature: signature, account: account) - } - - /// For wallet to reject authentication request - /// - Parameter requestId: authentication request id - @available(*, deprecated, message: "Use Web3Wallet interface for rejecting authentication requests.") - public func reject(requestId: RPCID) async throws { - try await walletRespondService.respondError(requestId: requestId) - } - - /// Query pending authentication requests - /// - Returns: Pending authentication requests - @available(*, deprecated, message: "Use SignClient for managing pending authentication requests.") - public func getPendingRequests() throws -> [(AuthRequest, VerifyContext?)] { - return try pendingRequestsProvider.getPendingRequests() - } - - @available(*, deprecated, message: "Use SignClient or Web3Wallet for message formatting.") - public func formatMessage(payload: AuthPayloadStruct, address: String) throws -> String { - return try SIWEFromCacaoPayloadFormatter().formatMessage(from: payload.cacaoPayload(address: address)) - } - - private func setUpPublishers() { - appRespondSubscriber.onResponse = { [unowned self] (id, result) in - authResponsePublisherSubject.send((id, result)) - } - - walletRequestSubscriber.onRequest = { [unowned self] request in - authRequestPublisherSubject.send(request) - } - } -} diff --git a/Sources/Auth/AuthClientFactory.swift b/Sources/Auth/AuthClientFactory.swift deleted file mode 100644 index 59b902602..000000000 --- a/Sources/Auth/AuthClientFactory.swift +++ /dev/null @@ -1,68 +0,0 @@ -import Foundation - -public struct AuthClientFactory { - public static func create( - metadata: AppMetadata, - projectId: String, - crypto: CryptoProvider, - networkingClient: NetworkingInteractor, - pairingRegisterer: PairingRegisterer, - groupIdentifier: String - ) -> AuthClient { - let logger = ConsoleLogger(loggingLevel: .off) - guard let keyValueStorage = UserDefaults(suiteName: groupIdentifier) else { - fatalError("Could not instantiate UserDefaults for a group identifier \(groupIdentifier)") - } - let keychainStorage = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk", accessGroup: groupIdentifier) - let iatProvider = DefaultIATProvider() - - return AuthClientFactory.create( - metadata: metadata, - projectId: projectId, - crypto: crypto, - logger: logger, - keyValueStorage: keyValueStorage, - keychainStorage: keychainStorage, - networkingClient: networkingClient, - pairingRegisterer: pairingRegisterer, - iatProvider: iatProvider - ) - } - - static func create( - metadata: AppMetadata, - projectId: String, - crypto: CryptoProvider, - logger: ConsoleLogging, - keyValueStorage: KeyValueStorage, - keychainStorage: KeychainStorageProtocol, - networkingClient: NetworkingInteractor, - pairingRegisterer: PairingRegisterer, - iatProvider: IATProvider - ) -> AuthClient { - let kms = KeyManagementService(keychain: keychainStorage) - let history = RPCHistoryFactory.createForNetwork(keyValueStorage: keyValueStorage) - let messageFormatter = SIWEFromCacaoPayloadFormatter() - let appRequestService = AppRequestService(networkingInteractor: networkingClient, kms: kms, appMetadata: metadata, logger: logger, iatProvader: iatProvider) - let verifyClient = VerifyClientFactory.create() - let verifyContextStore = CodableStore(defaults: keyValueStorage, identifier: VerifyStorageIdentifiers.context.rawValue) - let messageVerifierFactory = MessageVerifierFactory(crypto: crypto) - let signatureVerifier = messageVerifierFactory.create(projectId: projectId) - let appRespondSubscriber = AppRespondSubscriber(networkingInteractor: networkingClient, logger: logger, rpcHistory: history, signatureVerifier: signatureVerifier, pairingRegisterer: pairingRegisterer, messageFormatter: messageFormatter) - let walletErrorResponder = Auth_WalletErrorResponder(networkingInteractor: networkingClient, logger: logger, kms: kms, rpcHistory: history) - let walletRequestSubscriber = WalletRequestSubscriber(networkingInteractor: networkingClient, logger: logger, kms: kms, walletErrorResponder: walletErrorResponder, pairingRegisterer: pairingRegisterer, verifyClient: verifyClient, verifyContextStore: verifyContextStore) - let walletRespondService = WalletRespondService(networkingInteractor: networkingClient, logger: logger, kms: kms, rpcHistory: history, verifyContextStore: verifyContextStore, walletErrorResponder: walletErrorResponder, pairingRegisterer: pairingRegisterer) - let pendingRequestsProvider = Auth_PendingRequestsProvider(rpcHistory: history, verifyContextStore: verifyContextStore) - - return AuthClient( - appRequestService: appRequestService, - appRespondSubscriber: appRespondSubscriber, - walletRequestSubscriber: walletRequestSubscriber, - walletRespondService: walletRespondService, - pendingRequestsProvider: pendingRequestsProvider, - logger: logger, - socketConnectionStatusPublisher: networkingClient.socketConnectionStatusPublisher, - pairingRegisterer: pairingRegisterer - ) - } -} diff --git a/Sources/Auth/AuthClientProtocol.swift b/Sources/Auth/AuthClientProtocol.swift deleted file mode 100644 index d74cdbb7f..000000000 --- a/Sources/Auth/AuthClientProtocol.swift +++ /dev/null @@ -1,11 +0,0 @@ -import Foundation -import Combine - -public protocol AuthClientProtocol { - var authRequestPublisher: AnyPublisher<(request: AuthRequest, context: VerifyContext?), Never> { get } - - func formatMessage(payload: AuthPayloadStruct, address: String) throws -> String - func respond(requestId: RPCID, signature: CacaoSignature, from account: Account) async throws - func reject(requestId: RPCID) async throws - func getPendingRequests() throws -> [(AuthRequest, VerifyContext?)] -} diff --git a/Sources/Auth/AuthConfig.swift b/Sources/Auth/AuthConfig.swift deleted file mode 100644 index 183617159..000000000 --- a/Sources/Auth/AuthConfig.swift +++ /dev/null @@ -1,7 +0,0 @@ -import Foundation - -extension Auth { - struct Config { - let crypto: CryptoProvider - } -} diff --git a/Sources/Auth/AuthImports.swift b/Sources/Auth/AuthImports.swift deleted file mode 100644 index 91463cad3..000000000 --- a/Sources/Auth/AuthImports.swift +++ /dev/null @@ -1,5 +0,0 @@ -#if !CocoaPods -@_exported import WalletConnectPairing -@_exported import WalletConnectSigner -@_exported import WalletConnectVerify -#endif diff --git a/Sources/Auth/AuthProtocolMethod.swift b/Sources/Auth/AuthProtocolMethod.swift deleted file mode 100644 index a3a56117f..000000000 --- a/Sources/Auth/AuthProtocolMethod.swift +++ /dev/null @@ -1,25 +0,0 @@ -import Foundation - -struct AuthRequestProtocolMethod: ProtocolMethod { - let method: String = "wc_authRequest" - - let requestConfig = RelayConfig(tag: 3000, prompt: true, ttl: 86400) - - let responseConfig = RelayConfig(tag: 3001, prompt: false, ttl: 86400) -} - -struct PairingPingProtocolMethod: ProtocolMethod { - let method: String = "wc_pairingPing" - - let requestConfig = RelayConfig(tag: 1002, prompt: false, ttl: 30) - - let responseConfig = RelayConfig(tag: 1003, prompt: false, ttl: 30) -} - -struct PairingDeleteProtocolMethod: ProtocolMethod { - let method: String = "wc_pairingDelete" - - let requestConfig = RelayConfig(tag: 1000, prompt: false, ttl: 86400) - - let responseConfig = RelayConfig(tag: 1001, prompt: false, ttl: 86400) -} diff --git a/Sources/Auth/Services/App/AppRequestService.swift b/Sources/Auth/Services/App/AppRequestService.swift deleted file mode 100644 index 325c515b5..000000000 --- a/Sources/Auth/Services/App/AppRequestService.swift +++ /dev/null @@ -1,34 +0,0 @@ -import Foundation - -actor AppRequestService { - private let networkingInteractor: NetworkInteracting - private let appMetadata: AppMetadata - private let kms: KeyManagementService - private let logger: ConsoleLogging - private let iatProvader: IATProvider - - init(networkingInteractor: NetworkInteracting, - kms: KeyManagementService, - appMetadata: AppMetadata, - logger: ConsoleLogging, - iatProvader: IATProvider) { - self.networkingInteractor = networkingInteractor - self.kms = kms - self.appMetadata = appMetadata - self.logger = logger - self.iatProvader = iatProvader - } - - func request(params: RequestParams, topic: String) async throws { - let pubKey = try kms.createX25519KeyPair() - let responseTopic = pubKey.rawRepresentation.sha256().toHexString() - let requester = Auth_RequestParams.Requester(publicKey: pubKey.hexRepresentation, metadata: appMetadata) - let payload = AuthPayloadStruct(requestParams: params, iat: iatProvader.iat) - let params = Auth_RequestParams(requester: requester, payloadParams: payload) - let request = RPCRequest(method: "wc_authRequest", params: params) - try kms.setPublicKey(publicKey: pubKey, for: responseTopic) - logger.debug("AppRequestService: Subscribibg for response topic: \(responseTopic)") - try await networkingInteractor.request(request, topic: topic, protocolMethod: AuthRequestProtocolMethod()) - try await networkingInteractor.subscribe(topic: responseTopic) - } -} diff --git a/Sources/Auth/Services/App/AppRespondSubscriber.swift b/Sources/Auth/Services/App/AppRespondSubscriber.swift deleted file mode 100644 index e7036bf5e..000000000 --- a/Sources/Auth/Services/App/AppRespondSubscriber.swift +++ /dev/null @@ -1,75 +0,0 @@ -import Foundation -import Combine - -class AppRespondSubscriber { - private let networkingInteractor: NetworkInteracting - private let logger: ConsoleLogging - private let rpcHistory: RPCHistory - private let signatureVerifier: MessageVerifier - private let messageFormatter: SIWEFromCacaoPayloadFormatter - private let pairingRegisterer: PairingRegisterer - private var publishers = [AnyCancellable]() - - var onResponse: ((_ id: RPCID, _ result: Result) -> Void)? - - init(networkingInteractor: NetworkInteracting, - logger: ConsoleLogging, - rpcHistory: RPCHistory, - signatureVerifier: MessageVerifier, - pairingRegisterer: PairingRegisterer, - messageFormatter: SIWEFromCacaoPayloadFormatter) { - self.networkingInteractor = networkingInteractor - self.logger = logger - self.rpcHistory = rpcHistory - self.signatureVerifier = signatureVerifier - self.messageFormatter = messageFormatter - self.pairingRegisterer = pairingRegisterer - subscribeForResponse() - } - - private func subscribeForResponse() { - networkingInteractor.responseErrorSubscription(on: AuthRequestProtocolMethod()) - .sink { [unowned self] (payload: ResponseSubscriptionErrorPayload) in - guard let error = AuthErrors(code: payload.error.code) else { return } - onResponse?(payload.id, .failure(error)) - }.store(in: &publishers) - - networkingInteractor.responseSubscription(on: AuthRequestProtocolMethod()) - .sink { [unowned self] (payload: ResponseSubscriptionPayload) in - - pairingRegisterer.activate(pairingTopic: payload.topic, peerMetadata: nil) - - networkingInteractor.unsubscribe(topic: payload.topic) - - let requestId = payload.id - let cacao = payload.response - let requestPayload = payload.request - - guard - let address = try? DIDPKH(did: cacao.p.iss).account.address, - let message = try? messageFormatter.formatMessage(from: cacao.p) - else { self.onResponse?(requestId, .failure(.malformedResponseParams)); return } - - guard - let recovered = try? messageFormatter.formatMessage( - from: requestPayload.payloadParams.cacaoPayload(address: address) - ), recovered == message - else { self.onResponse?(requestId, .failure(.messageCompromised)); return } - - Task(priority: .high) { - do { - try await signatureVerifier.verify( - signature: cacao.s, - message: message, - address: address, - chainId: requestPayload.payloadParams.chainId - ) - onResponse?(requestId, .success(cacao)) - } catch { - logger.error("Signature verification failed with: \(error.localizedDescription)") - onResponse?(requestId, .failure(.signatureVerificationFailed)) - } - } - }.store(in: &publishers) - } -} diff --git a/Sources/Auth/Services/Wallet/Auth_PendingRequestsProvider.swift b/Sources/Auth/Services/Wallet/Auth_PendingRequestsProvider.swift deleted file mode 100644 index f646835e4..000000000 --- a/Sources/Auth/Services/Wallet/Auth_PendingRequestsProvider.swift +++ /dev/null @@ -1,25 +0,0 @@ -import Foundation - -class Auth_PendingRequestsProvider { - private let rpcHistory: RPCHistory - private let verifyContextStore: CodableStore - - init( - rpcHistory: RPCHistory, - verifyContextStore: CodableStore - ) { - self.rpcHistory = rpcHistory - self.verifyContextStore = verifyContextStore - } - - public func getPendingRequests() throws -> [(AuthRequest, VerifyContext?)] { - let pendingRequests: [AuthRequest] = rpcHistory.getPending() - .filter {$0.request.method == "wc_authRequest"} - .compactMap { - guard let params = try? $0.request.params?.get(Auth_RequestParams.self) else { return nil } - return AuthRequest(id: $0.request.id!, topic: $0.topic, payload: params.payloadParams, requester: params.requester.metadata) - } - - return pendingRequests.map { ($0, try? verifyContextStore.get(key: $0.id.string)) } - } -} diff --git a/Sources/Auth/Services/Wallet/Auth_WalletErrorResponder.swift b/Sources/Auth/Services/Wallet/Auth_WalletErrorResponder.swift deleted file mode 100644 index 895f41d9d..000000000 --- a/Sources/Auth/Services/Wallet/Auth_WalletErrorResponder.swift +++ /dev/null @@ -1,52 +0,0 @@ -import Foundation - -actor Auth_WalletErrorResponder { - enum Errors: Error { - case recordForIdNotFound - case malformedAuthRequestParams - } - - private let networkingInteractor: NetworkInteracting - private let kms: KeyManagementServiceProtocol - private let rpcHistory: RPCHistory - private let logger: ConsoleLogging - - init(networkingInteractor: NetworkInteracting, - logger: ConsoleLogging, - kms: KeyManagementServiceProtocol, - rpcHistory: RPCHistory) { - self.networkingInteractor = networkingInteractor - self.logger = logger - self.kms = kms - self.rpcHistory = rpcHistory - } - - func respondError(_ error: AuthErrors, requestId: RPCID) async throws { - let authRequestParams = try getAuthRequestParams(requestId: requestId) - let (topic, keys) = try generateAgreementKeys(requestParams: authRequestParams) - - try kms.setAgreementSecret(keys, topic: topic) - - let envelopeType = Envelope.EnvelopeType.type1(pubKey: keys.publicKey.rawRepresentation) - try await networkingInteractor.respondError(topic: topic, requestId: requestId, protocolMethod: AuthRequestProtocolMethod(), reason: error, envelopeType: envelopeType) - } - - private func getAuthRequestParams(requestId: RPCID) throws -> Auth_RequestParams { - guard let request = rpcHistory.get(recordId: requestId)?.request - else { throw Errors.recordForIdNotFound } - - guard let authRequestParams = try request.params?.get(Auth_RequestParams.self) - else { throw Errors.malformedAuthRequestParams } - - return authRequestParams - } - - private func generateAgreementKeys(requestParams: Auth_RequestParams) throws -> (topic: String, keys: AgreementKeys) { - let peerPubKey = try AgreementPublicKey(hex: requestParams.requester.publicKey) - let topic = peerPubKey.rawRepresentation.sha256().toHexString() - let selfPubKey = try kms.createX25519KeyPair() - let keys = try kms.performKeyAgreement(selfPublicKey: selfPubKey, peerPublicKey: peerPubKey.hexRepresentation) - // TODO - remove keys - return (topic, keys) - } -} diff --git a/Sources/Auth/Services/Wallet/WalletRequestSubscriber.swift b/Sources/Auth/Services/Wallet/WalletRequestSubscriber.swift deleted file mode 100644 index c8697ec5d..000000000 --- a/Sources/Auth/Services/Wallet/WalletRequestSubscriber.swift +++ /dev/null @@ -1,60 +0,0 @@ -import Foundation -import Combine - -class WalletRequestSubscriber { - private let networkingInteractor: NetworkInteracting - private let logger: ConsoleLogging - private let kms: KeyManagementServiceProtocol - private var publishers = [AnyCancellable]() - private let walletErrorResponder: Auth_WalletErrorResponder - private let pairingRegisterer: PairingRegisterer - private let verifyClient: VerifyClientProtocol - private let verifyContextStore: CodableStore - - var onRequest: (((request: AuthRequest, context: VerifyContext?)) -> Void)? - - init( - networkingInteractor: NetworkInteracting, - logger: ConsoleLogging, - kms: KeyManagementServiceProtocol, - walletErrorResponder: Auth_WalletErrorResponder, - pairingRegisterer: PairingRegisterer, - verifyClient: VerifyClientProtocol, - verifyContextStore: CodableStore - ) { - self.networkingInteractor = networkingInteractor - self.logger = logger - self.kms = kms - self.walletErrorResponder = walletErrorResponder - self.pairingRegisterer = pairingRegisterer - self.verifyClient = verifyClient - self.verifyContextStore = verifyContextStore - subscribeForRequest() - } - - private func subscribeForRequest() { - pairingRegisterer.register(method: AuthRequestProtocolMethod()) - .sink { [unowned self] (payload: RequestSubscriptionPayload) in - logger.debug("WalletRequestSubscriber: Received request") - - pairingRegisterer.setReceived(pairingTopic: payload.topic) - - let request = AuthRequest(id: payload.id, topic: payload.topic, payload: payload.request.payloadParams, requester: payload.request.requester.metadata) - - Task(priority: .high) { - let assertionId = payload.decryptedPayload.sha256().toHexString() - do { - let response = try await verifyClient.verify(.v1(assertionId: assertionId)) - let verifyContext = verifyClient.createVerifyContext(origin: response.origin, domain: payload.request.payloadParams.domain, isScam: response.isScam, isVerified: nil) - verifyContextStore.set(verifyContext, forKey: request.id.string) - onRequest?((request, verifyContext)) - } catch { - let verifyContext = verifyClient.createVerifyContext(origin: nil, domain: payload.request.payloadParams.domain, isScam: nil, isVerified: nil) - verifyContextStore.set(verifyContext, forKey: request.id.string) - onRequest?((request, verifyContext)) - return - } - } - }.store(in: &publishers) - } -} diff --git a/Sources/Auth/Services/Wallet/WalletRespondService.swift b/Sources/Auth/Services/Wallet/WalletRespondService.swift deleted file mode 100644 index 529ef2a79..000000000 --- a/Sources/Auth/Services/Wallet/WalletRespondService.swift +++ /dev/null @@ -1,77 +0,0 @@ -import Foundation - -actor WalletRespondService { - enum Errors: Error { - case recordForIdNotFound - case malformedAuthRequestParams - } - private let networkingInteractor: NetworkInteracting - private let kms: KeyManagementService - private let rpcHistory: RPCHistory - private let verifyContextStore: CodableStore - private let logger: ConsoleLogging - private let walletErrorResponder: Auth_WalletErrorResponder - private let pairingRegisterer: PairingRegisterer - - init( - networkingInteractor: NetworkInteracting, - logger: ConsoleLogging, - kms: KeyManagementService, - rpcHistory: RPCHistory, - verifyContextStore: CodableStore, - walletErrorResponder: Auth_WalletErrorResponder, - pairingRegisterer: PairingRegisterer - ) { - self.networkingInteractor = networkingInteractor - self.logger = logger - self.kms = kms - self.rpcHistory = rpcHistory - self.verifyContextStore = verifyContextStore - self.walletErrorResponder = walletErrorResponder - self.pairingRegisterer = pairingRegisterer - } - - func respond(requestId: RPCID, signature: CacaoSignature, account: Account) async throws { - let authRequestParams = try getAuthRequestParams(requestId: requestId) - let (topic, keys) = try generateAgreementKeys(requestParams: authRequestParams) - - try kms.setAgreementSecret(keys, topic: topic) - - let header = CacaoHeader(t: "eip4361") - let payload = try authRequestParams.payloadParams.cacaoPayload(address: account.address) - let responseParams = AuthResponseParams(h: header, p: payload, s: signature) - - let response = RPCResponse(id: requestId, result: responseParams) - try await networkingInteractor.respond(topic: topic, response: response, protocolMethod: AuthRequestProtocolMethod(), envelopeType: .type1(pubKey: keys.publicKey.rawRepresentation)) - - pairingRegisterer.activate( - pairingTopic: topic, - peerMetadata: authRequestParams.requester.metadata - ) - - verifyContextStore.delete(forKey: requestId.string) - } - - func respondError(requestId: RPCID) async throws { - try await walletErrorResponder.respondError(AuthErrors.userRejeted, requestId: requestId) - verifyContextStore.delete(forKey: requestId.string) - } - - private func getAuthRequestParams(requestId: RPCID) throws -> Auth_RequestParams { - guard let request = rpcHistory.get(recordId: requestId)?.request - else { throw Errors.recordForIdNotFound } - - guard let authRequestParams = try request.params?.get(Auth_RequestParams.self) - else { throw Errors.malformedAuthRequestParams } - - return authRequestParams - } - - private func generateAgreementKeys(requestParams: Auth_RequestParams) throws -> (topic: String, keys: AgreementKeys) { - let peerPubKey = try AgreementPublicKey(hex: requestParams.requester.publicKey) - let topic = peerPubKey.rawRepresentation.sha256().toHexString() - let selfPubKey = try kms.createX25519KeyPair() - let keys = try kms.performKeyAgreement(selfPublicKey: selfPubKey, peerPublicKey: peerPubKey.hexRepresentation) - return (topic, keys) - } -} diff --git a/Sources/Auth/Types/AuthPayloadStruct.swift b/Sources/Auth/Types/AuthPayloadStruct.swift deleted file mode 100644 index b7a1494c4..000000000 --- a/Sources/Auth/Types/AuthPayloadStruct.swift +++ /dev/null @@ -1,59 +0,0 @@ -import Foundation - -public struct AuthPayloadStruct: Codable, Equatable { - public let domain: String - public let aud: String - public let version: String - public let nonce: String - public let chainId: String - public let type: String - public let iat: String - public let nbf: String? - public let exp: String? - public let statement: String? - public let requestId: String? - public let resources: [String]? - - init(requestParams: RequestParams, iat: String) { - self.type = "eip4361" - self.chainId = requestParams.chainId - self.domain = requestParams.domain - self.aud = requestParams.aud - self.version = "1" - self.nonce = requestParams.nonce - self.iat = iat - self.nbf = requestParams.nbf - self.exp = requestParams.exp - self.statement = requestParams.statement - self.requestId = requestParams.requestId - self.resources = requestParams.resources - } - - public func cacaoPayload(address: String) throws -> CacaoPayload { - guard - let blockchain = Blockchain(chainId), - let account = Account(blockchain: blockchain, address: address) else { - throw Errors.invalidChainID - } - return CacaoPayload( - iss: account.did, - domain: domain, - aud: aud, - version: version, - nonce: nonce, - iat: iat, - nbf: nbf, - exp: exp, - statement: statement, - requestId: requestId, - resources: resources - ) - } -} - -private extension AuthPayloadStruct { - - enum Errors: Error { - case invalidChainID - } -} diff --git a/Sources/Auth/Types/AuthRespondParams.swift b/Sources/Auth/Types/AuthRespondParams.swift deleted file mode 100644 index fce3414eb..000000000 --- a/Sources/Auth/Types/AuthRespondParams.swift +++ /dev/null @@ -1,11 +0,0 @@ -import Foundation - -public struct AuthRespondParams: Equatable { - let id: RPCID - let signature: CacaoSignature - - public init(id: RPCID, signature: CacaoSignature) { - self.id = id - self.signature = signature - } -} diff --git a/Sources/Auth/Types/Errors/AuthErrors.swift b/Sources/Auth/Types/Errors/AuthErrors.swift deleted file mode 100644 index 9cfda6bd1..000000000 --- a/Sources/Auth/Types/Errors/AuthErrors.swift +++ /dev/null @@ -1,72 +0,0 @@ -import Foundation - -/// Authentication error -public enum AuthErrors: Codable, Equatable, Error { - case methodUnsupported - case userDisconnected - case userRejeted - case malformedResponseParams - case malformedRequestParams - case messageCompromised - case signatureVerificationFailed -} - -extension AuthErrors: Reason { - - init?(code: Int) { - switch code { - case Self.methodUnsupported.code: - self = .methodUnsupported - case Self.userRejeted.code: - self = .userRejeted - case Self.malformedResponseParams.code: - self = .malformedResponseParams - case Self.malformedRequestParams.code: - self = .malformedRequestParams - case Self.messageCompromised.code: - self = .messageCompromised - case Self.signatureVerificationFailed.code: - self = .signatureVerificationFailed - default: - return nil - } - } - - public var code: Int { - switch self { - case .methodUnsupported: - return 10001 - case .userDisconnected: - return 6000 - case .userRejeted: - return 14001 - case .malformedResponseParams: - return 12001 - case .malformedRequestParams: - return 12002 - case .messageCompromised: - return 12003 - case .signatureVerificationFailed: - return 12004 - } - } - - public var message: String { - switch self { - case .methodUnsupported: - return "Method Unsupported" - case .userRejeted: - return "Auth request rejected by user" - case .malformedResponseParams: - return "Response params malformed" - case .malformedRequestParams: - return "Request params malformed" - case .messageCompromised: - return "Original message compromised" - case .signatureVerificationFailed: - return "Message verification failed" - case .userDisconnected: - return "User Disconnected" - } - } -} diff --git a/Sources/Auth/Types/ProtocolRPCParams/AuthResponseParams.swift b/Sources/Auth/Types/ProtocolRPCParams/AuthResponseParams.swift deleted file mode 100644 index e2d097c01..000000000 --- a/Sources/Auth/Types/ProtocolRPCParams/AuthResponseParams.swift +++ /dev/null @@ -1,4 +0,0 @@ -import Foundation - -/// wc_authRequest RPC method respond param -typealias AuthResponseParams = Cacao diff --git a/Sources/Auth/Types/ProtocolRPCParams/Auth_RequestParams.swift b/Sources/Auth/Types/ProtocolRPCParams/Auth_RequestParams.swift deleted file mode 100644 index 4a72728ed..000000000 --- a/Sources/Auth/Types/ProtocolRPCParams/Auth_RequestParams.swift +++ /dev/null @@ -1,14 +0,0 @@ -import Foundation - -/// wc_authRequest RPC method request param -struct Auth_RequestParams: Codable, Equatable { - let requester: Requester - let payloadParams: AuthPayloadStruct -} - -extension Auth_RequestParams { - struct Requester: Codable, Equatable { - let publicKey: String - let metadata: AppMetadata - } -} diff --git a/Sources/Auth/Types/Public/AuthRequest.swift b/Sources/Auth/Types/Public/AuthRequest.swift deleted file mode 100644 index 63e553cc5..000000000 --- a/Sources/Auth/Types/Public/AuthRequest.swift +++ /dev/null @@ -1,8 +0,0 @@ -import Foundation - -public struct AuthRequest: Equatable, Codable { - public let id: RPCID - public let topic: String - public let payload: AuthPayloadStruct - public let requester: AppMetadata -} diff --git a/Sources/Auth/Types/RequestParams.swift b/Sources/Auth/Types/RequestParams.swift deleted file mode 100644 index 1f57884a9..000000000 --- a/Sources/Auth/Types/RequestParams.swift +++ /dev/null @@ -1,39 +0,0 @@ -import Foundation - -/// Parameters required to construct authentication request -/// for details read CAIP-74 and EIP-4361 specs -/// https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-74.md -/// https://eips.ethereum.org/EIPS/eip-4361 -public struct RequestParams { - public let domain: String - public let chainId: String - public let nonce: String - public let aud: String - public let nbf: String? - public let exp: String? - public let statement: String? - public let requestId: String? - public let resources: [String]? - - public init( - domain: String, - chainId: String, - nonce: String, - aud: String, - nbf: String?, - exp: String?, - statement: String?, - requestId: String?, - resources: [String]? - ) { - self.domain = domain - self.chainId = chainId - self.nonce = nonce - self.aud = aud - self.nbf = nbf - self.exp = exp - self.statement = statement - self.requestId = requestId - self.resources = resources - } -} diff --git a/Sources/Events/ExecutionTraces/PairingExecutionTraceEvents.swift b/Sources/Events/ExecutionTraces/PairingExecutionTraceEvents.swift index bfb809dd3..5b924af0f 100644 --- a/Sources/Events/ExecutionTraces/PairingExecutionTraceEvents.swift +++ b/Sources/Events/ExecutionTraces/PairingExecutionTraceEvents.swift @@ -20,7 +20,6 @@ public enum PairingExecutionTraceEvents: String, TraceEvent { public enum PairingTraceErrorEvents: String, ErrorEvent { case noInternetConnection = "no_internet_connection" case malformedPairingUri = "malformed_pairing_uri" - case activePairingAlreadyExists = "active_pairing_already_exists" case subscribePairingTopicFailure = "subscribe_pairing_topic_failure" case pairingExpired = "pairing_expired" case proposalExpired = "proposal_expired" diff --git a/Sources/WalletConnectModal/Modal/ModalInteractor.swift b/Sources/WalletConnectModal/Modal/ModalInteractor.swift index fe18b4f48..acd41c5ce 100644 --- a/Sources/WalletConnectModal/Modal/ModalInteractor.swift +++ b/Sources/WalletConnectModal/Modal/ModalInteractor.swift @@ -4,7 +4,7 @@ import Foundation protocol ModalSheetInteractor { func getWallets(page: Int, entries: Int) async throws -> (Int, [Wallet]) - func createPairingAndConnect() async throws -> WalletConnectURI? + func createPairingAndConnect() async throws -> WalletConnectURI var sessionSettlePublisher: AnyPublisher { get } var sessionRejectionPublisher: AnyPublisher<(Session.Proposal, Reason), Never> { get } @@ -34,7 +34,7 @@ final class DefaultModalSheetInteractor: ModalSheetInteractor { return (response.count, response.data.compactMap { $0 }) } - func createPairingAndConnect() async throws -> WalletConnectURI? { - try await WalletConnectModal.instance.connect(topic: nil) + func createPairingAndConnect() async throws -> WalletConnectURI { + try await WalletConnectModal.instance.connect() } } diff --git a/Sources/WalletConnectModal/Modal/ModalViewModel.swift b/Sources/WalletConnectModal/Modal/ModalViewModel.swift index e78aa56e1..3a01cba3c 100644 --- a/Sources/WalletConnectModal/Modal/ModalViewModel.swift +++ b/Sources/WalletConnectModal/Modal/ModalViewModel.swift @@ -102,10 +102,7 @@ final class ModalViewModel: ObservableObject { @MainActor func createURI() async { do { - guard let wcUri = try await interactor.createPairingAndConnect() else { - toast = Toast(style: .error, message: "Failed to create pairing") - return - } + let wcUri = try await interactor.createPairingAndConnect() uri = wcUri.absoluteString deeplinkUri = wcUri.deeplinkUri } catch { diff --git a/Sources/WalletConnectModal/WalletConnectModalClient.swift b/Sources/WalletConnectModal/WalletConnectModalClient.swift index b6a8f41be..cb16847b9 100644 --- a/Sources/WalletConnectModal/WalletConnectModalClient.swift +++ b/Sources/WalletConnectModal/WalletConnectModalClient.swift @@ -50,11 +50,11 @@ public class WalletConnectModalClient { // MARK: - Private Properties - private let signClient: SignClientProtocol + private let signClient: SignClient private let pairingClient: PairingClientProtocol & PairingInteracting & PairingRegisterer init( - signClient: SignClientProtocol, + signClient: SignClient, pairingClient: PairingClientProtocol & PairingInteracting & PairingRegisterer ) { self.signClient = signClient @@ -69,61 +69,15 @@ public class WalletConnectModalClient { /// For proposing a session to a wallet. /// Function will propose a session on existing pairing or create new one if not specified /// Namespaces from WalletConnectModal.config will be used - /// - Parameters: - /// - topic: pairing topic - public func connect( - topic: String? - ) async throws -> WalletConnectURI? { - if let topic = topic { - try pairingClient.validatePairingExistance(topic) - try await signClient.connect( - requiredNamespaces: WalletConnectModal.config.sessionParams.requiredNamespaces, - optionalNamespaces: WalletConnectModal.config.sessionParams.optionalNamespaces, - sessionProperties: WalletConnectModal.config.sessionParams.sessionProperties, - topic: topic - ) - return nil - } else { - let pairingURI = try await pairingClient.create() - try await signClient.connect( + public func connect() async throws -> WalletConnectURI { + let pairingURI = try await signClient.connect( requiredNamespaces: WalletConnectModal.config.sessionParams.requiredNamespaces, optionalNamespaces: WalletConnectModal.config.sessionParams.optionalNamespaces, - sessionProperties: WalletConnectModal.config.sessionParams.sessionProperties, - topic: pairingURI.topic + sessionProperties: WalletConnectModal.config.sessionParams.sessionProperties ) return pairingURI } - } - - /// For proposing a session to a wallet. - /// Function will propose a session on existing pairing. - /// - Parameters: - /// - requiredNamespaces: required namespaces for a session - /// - topic: pairing topic - public func connect( - requiredNamespaces: [String: ProposalNamespace], - optionalNamespaces: [String: ProposalNamespace]? = nil, - sessionProperties: [String: String]? = nil, - topic: String - ) async throws { - try await signClient.connect( - requiredNamespaces: requiredNamespaces, - optionalNamespaces: optionalNamespaces, - sessionProperties: sessionProperties, - topic: topic - ) - } - - /// Ping method allows to check if peer client is online and is subscribing for given topic - /// - /// Should Error: - /// - When the session topic is not found - /// - /// - Parameters: - /// - topic: Topic of a session - public func ping(topic: String) async throws { - try await pairingClient.ping(topic: topic) - } + /// For sending JSON-RPC requests to wallet. /// - Parameters: diff --git a/Sources/WalletConnectPairing/PairingClient.swift b/Sources/WalletConnectPairing/PairingClient.swift index 233fcd76b..7443adeee 100644 --- a/Sources/WalletConnectPairing/PairingClient.swift +++ b/Sources/WalletConnectPairing/PairingClient.swift @@ -2,9 +2,6 @@ import Foundation import Combine public class PairingClient: PairingRegisterer, PairingInteracting, PairingClientProtocol { - public var pingResponsePublisher: AnyPublisher<(String), Never> { - pingResponsePublisherSubject.eraseToAnyPublisher() - } public var pairingDeletePublisher: AnyPublisher<(code: Int, message: String), Never> { pairingDeleteRequestSubscriber.deletePublisherSubject.eraseToAnyPublisher() } @@ -21,14 +18,10 @@ public class PairingClient: PairingRegisterer, PairingInteracting, PairingClient private let pairingStorage: WCPairingStorage private let walletPairService: WalletPairService private let appPairService: AppPairService - private let appPairActivateService: AppPairActivationService - private var pingResponsePublisherSubject = PassthroughSubject() private let logger: ConsoleLogging - private let pingService: PairingPingService private let networkingInteractor: NetworkInteracting private let pairingRequestsSubscriber: PairingRequestsSubscriber private let pairingsProvider: PairingsProvider - private let pairingDeleteRequester: PairingDeleteRequester private let resubscribeService: PairingResubscribeService private let expirationService: ExpirationService private let pairingDeleteRequestSubscriber: PairingDeleteRequestSubscriber @@ -46,14 +39,11 @@ public class PairingClient: PairingRegisterer, PairingInteracting, PairingClient networkingInteractor: NetworkInteracting, logger: ConsoleLogging, walletPairService: WalletPairService, - pairingDeleteRequester: PairingDeleteRequester, pairingDeleteRequestSubscriber: PairingDeleteRequestSubscriber, resubscribeService: PairingResubscribeService, expirationService: ExpirationService, pairingRequestsSubscriber: PairingRequestsSubscriber, - appPairActivateService: AppPairActivationService, cleanupService: PairingCleanupService, - pingService: PairingPingService, socketConnectionStatusPublisher: AnyPublisher, pairingsProvider: PairingsProvider, pairingStateProvider: PairingStateProvider @@ -64,26 +54,16 @@ public class PairingClient: PairingRegisterer, PairingInteracting, PairingClient self.networkingInteractor = networkingInteractor self.socketConnectionStatusPublisher = socketConnectionStatusPublisher self.logger = logger - self.pairingDeleteRequester = pairingDeleteRequester self.pairingDeleteRequestSubscriber = pairingDeleteRequestSubscriber - self.appPairActivateService = appPairActivateService self.resubscribeService = resubscribeService self.expirationService = expirationService self.cleanupService = cleanupService - self.pingService = pingService self.pairingRequestsSubscriber = pairingRequestsSubscriber self.pairingsProvider = pairingsProvider self.pairingStateProvider = pairingStateProvider - setUpPublishers() setUpExpiration() } - private func setUpPublishers() { - pingService.onResponse = { [unowned self] topic in - pingResponsePublisherSubject.send(topic) - } - } - private func setUpExpiration() { expirationService.setupExpirationHandling() } @@ -103,10 +83,6 @@ public class PairingClient: PairingRegisterer, PairingInteracting, PairingClient return try await appPairService.create(supportedMethods: methods) } - public func activate(pairingTopic: String, peerMetadata: AppMetadata?) { - appPairActivateService.activate(for: pairingTopic, peerMetadata: peerMetadata) - } - public func setReceived(pairingTopic: String) { guard var pairing = pairingStorage.getPairing(forTopic: pairingTopic) else { return logger.error("Pairing not found for topic: \(pairingTopic)") @@ -124,17 +100,8 @@ public class PairingClient: PairingRegisterer, PairingInteracting, PairingClient try pairingsProvider.getPairing(for: topic) } - public func ping(topic: String) async throws { - try await pingService.ping(topic: topic) - } - - public func disconnect(topic: String) async { - await pairingDeleteRequester.delete(topic: topic) - } - - public func validatePairingExistance(_ topic: String) throws { - _ = try pairingsProvider.getPairing(for: topic) - } + @available(*, deprecated, message: "This method is deprecated. Pairing will disconnect automatically") + public func disconnect(topic: String) async {} public func register(method: ProtocolMethod) -> AnyPublisher, Never> { logger.debug("Pairing Client - registering for \(method.method)") diff --git a/Sources/WalletConnectPairing/PairingClientFactory.swift b/Sources/WalletConnectPairing/PairingClientFactory.swift index 26293c3ad..4cc01b94a 100644 --- a/Sources/WalletConnectPairing/PairingClientFactory.swift +++ b/Sources/WalletConnectPairing/PairingClientFactory.swift @@ -32,9 +32,6 @@ public struct PairingClientFactory { let pairingRequestsSubscriber = PairingRequestsSubscriber(networkingInteractor: networkingClient, pairingStorage: pairingStore, logger: logger) let pairingsProvider = PairingsProvider(pairingStorage: pairingStore) let cleanupService = PairingCleanupService(pairingStore: pairingStore, kms: kms) - let pairingDeleteRequester = PairingDeleteRequester(networkingInteractor: networkingClient, kms: kms, pairingStorage: pairingStore, logger: logger) - let pingService = PairingPingService(pairingStorage: pairingStore, networkingInteractor: networkingClient, logger: logger) - let appPairActivateService = AppPairActivationService(pairingStorage: pairingStore, logger: logger) let expirationService = ExpirationService(pairingStorage: pairingStore, networkInteractor: networkingClient, kms: kms) let resubscribeService = PairingResubscribeService(networkInteractor: networkingClient, pairingStorage: pairingStore) let pairingDeleteRequestSubscriber = PairingDeleteRequestSubscriber(networkingInteractor: networkingClient, kms: kms, pairingStorage: pairingStore, logger: logger) @@ -46,14 +43,11 @@ public struct PairingClientFactory { networkingInteractor: networkingClient, logger: logger, walletPairService: walletPairService, - pairingDeleteRequester: pairingDeleteRequester, pairingDeleteRequestSubscriber: pairingDeleteRequestSubscriber, resubscribeService: resubscribeService, expirationService: expirationService, pairingRequestsSubscriber: pairingRequestsSubscriber, - appPairActivateService: appPairActivateService, cleanupService: cleanupService, - pingService: pingService, socketConnectionStatusPublisher: networkingClient.socketConnectionStatusPublisher, pairingsProvider: pairingsProvider, pairingStateProvider: pairingStateProvider diff --git a/Sources/WalletConnectPairing/PairingInteracting.swift b/Sources/WalletConnectPairing/PairingInteracting.swift index 7db1ccd47..6fc1e30d5 100644 --- a/Sources/WalletConnectPairing/PairingInteracting.swift +++ b/Sources/WalletConnectPairing/PairingInteracting.swift @@ -9,8 +9,6 @@ public protocol PairingInteracting { func getPairing(for topic: String) throws -> Pairing - func ping(topic: String) async throws - func disconnect(topic: String) async throws #if DEBUG diff --git a/Sources/WalletConnectPairing/PairingRegisterer.swift b/Sources/WalletConnectPairing/PairingRegisterer.swift index e09cf9a42..a6de58164 100644 --- a/Sources/WalletConnectPairing/PairingRegisterer.swift +++ b/Sources/WalletConnectPairing/PairingRegisterer.swift @@ -6,7 +6,5 @@ public protocol PairingRegisterer { method: ProtocolMethod ) -> AnyPublisher, Never> - func activate(pairingTopic: String, peerMetadata: AppMetadata?) func setReceived(pairingTopic: String) - func validatePairingExistance(_ topic: String) throws } diff --git a/Sources/WalletConnectPairing/Services/App/AppPairActivationService.swift b/Sources/WalletConnectPairing/Services/App/AppPairActivationService.swift deleted file mode 100644 index 3ce060f22..000000000 --- a/Sources/WalletConnectPairing/Services/App/AppPairActivationService.swift +++ /dev/null @@ -1,31 +0,0 @@ -import Foundation -import Combine - -final class AppPairActivationService { - enum Errors: Error { - case pairingNotFound - } - - private let pairingStorage: WCPairingStorage - private let logger: ConsoleLogging - - init(pairingStorage: WCPairingStorage, logger: ConsoleLogging) { - self.pairingStorage = pairingStorage - self.logger = logger - } - - func activate(for topic: String, peerMetadata: AppMetadata?) { - guard var pairing = pairingStorage.getPairing(forTopic: topic) else { - return logger.error("Pairing not found for topic: \(topic)") - } - - if !pairing.active { - pairing.activate() - } else { - try? pairing.updateExpiry() - } - - pairing.updatePeerMetadata(peerMetadata) - pairingStorage.setPairing(pairing) - } -} diff --git a/Sources/WalletConnectPairing/Services/Common/Delete/PairingDeleteRequester.swift b/Sources/WalletConnectPairing/Services/Common/Delete/PairingDeleteRequester.swift deleted file mode 100644 index c8c08ba34..000000000 --- a/Sources/WalletConnectPairing/Services/Common/Delete/PairingDeleteRequester.swift +++ /dev/null @@ -1,30 +0,0 @@ -import Foundation - -class PairingDeleteRequester { - private let networkingInteractor: NetworkInteracting - private let kms: KeyManagementServiceProtocol - private let pairingStorage: WCPairingStorage - private let logger: ConsoleLogging - - init(networkingInteractor: NetworkInteracting, - kms: KeyManagementServiceProtocol, - pairingStorage: WCPairingStorage, - logger: ConsoleLogging) { - self.networkingInteractor = networkingInteractor - self.kms = kms - self.pairingStorage = pairingStorage - self.logger = logger - } - - func delete(topic: String) async { - let reason = PairingReasonCode.userDisconnected - let protocolMethod = PairingProtocolMethod.delete - let pairingDeleteParams = PairingDeleteParams(code: reason.code, message: reason.message) - logger.debug("Will delete pairing for reason: message: \(reason.message) code: \(reason.code)") - let request = RPCRequest(method: protocolMethod.method, params: pairingDeleteParams) - try? await networkingInteractor.request(request, topic: topic, protocolMethod: protocolMethod) - pairingStorage.delete(topic: topic) - kms.deleteSymmetricKey(for: topic) - networkingInteractor.unsubscribe(topic: topic) - } -} diff --git a/Sources/WalletConnectPairing/Services/Common/PairingStateProvider.swift b/Sources/WalletConnectPairing/Services/Common/PairingStateProvider.swift index ff917e33d..89ea7db8e 100644 --- a/Sources/WalletConnectPairing/Services/Common/PairingStateProvider.swift +++ b/Sources/WalletConnectPairing/Services/Common/PairingStateProvider.swift @@ -23,7 +23,7 @@ class PairingStateProvider { } private func checkPairingState() { - let pairingStateActive = !pairingStorage.getAll().allSatisfy { $0.active || $0.requestReceived } + let pairingStateActive = !pairingStorage.getAll().allSatisfy { $0.requestReceived } if lastPairingState != pairingStateActive { pairingStatePublisherSubject.send(pairingStateActive) diff --git a/Sources/WalletConnectPairing/Services/Common/Ping/PairingPingService.swift b/Sources/WalletConnectPairing/Services/Common/Ping/PairingPingService.swift deleted file mode 100644 index e1250bd5a..000000000 --- a/Sources/WalletConnectPairing/Services/Common/Ping/PairingPingService.swift +++ /dev/null @@ -1,33 +0,0 @@ -import Foundation - -public class PairingPingService { - private let pairingStorage: WCPairingStorage - private let pingRequester: PingRequester - private let pingResponder: PingResponder - private let pingResponseSubscriber: PingResponseSubscriber - - public var onResponse: ((String) -> Void)? { - get { - return pingResponseSubscriber.onResponse - } - set { - pingResponseSubscriber.onResponse = newValue - } - } - - public init( - pairingStorage: WCPairingStorage, - networkingInteractor: NetworkInteracting, - logger: ConsoleLogging) { - let protocolMethod = PairingProtocolMethod.ping - self.pairingStorage = pairingStorage - self.pingRequester = PingRequester(networkingInteractor: networkingInteractor, method: protocolMethod) - self.pingResponder = PingResponder(networkingInteractor: networkingInteractor, method: protocolMethod, logger: logger) - self.pingResponseSubscriber = PingResponseSubscriber(networkingInteractor: networkingInteractor, method: protocolMethod, logger: logger) - } - - public func ping(topic: String) async throws { - guard pairingStorage.hasPairing(forTopic: topic) else { return } - try await pingRequester.ping(topic: topic) - } -} diff --git a/Sources/WalletConnectPairing/Services/Wallet/WalletPairService.swift b/Sources/WalletConnectPairing/Services/Wallet/WalletPairService.swift index c5607aa59..8fc8b43c4 100644 --- a/Sources/WalletConnectPairing/Services/Wallet/WalletPairService.swift +++ b/Sources/WalletConnectPairing/Services/Wallet/WalletPairService.swift @@ -2,7 +2,6 @@ import Foundation actor WalletPairService { enum Errors: Error { - case pairingAlreadyExist(topic: String) case networkNotConnected } @@ -71,18 +70,12 @@ extension WalletPairService { guard let pairing = pairingStorage.getPairing(forTopic: topic), pairing.requestReceived else { return false } - - if pairing.active { - eventsClient.saveEvent(PairingTraceErrorEvents.activePairingAlreadyExists) - throw Errors.pairingAlreadyExist(topic: topic) - } - + let pendingRequests = history.getPending() .compactMap { record -> RPCRequest? in (record.topic == pairing.topic) ? record.request : nil } - guard !pendingRequests.isEmpty else { return false } pendingRequests.forEach { request in eventsClient.saveEvent(PairingExecutionTraceEvents.emitSessionProposal) @@ -110,7 +103,6 @@ extension WalletPairService { extension WalletPairService.Errors: LocalizedError { var errorDescription: String? { switch self { - case .pairingAlreadyExist(let topic): return "Pairing with topic (\(topic)) is already active" case .networkNotConnected: return "Pairing failed. You seem to be offline" } } diff --git a/Sources/WalletConnectPairing/Types/Pairing.swift b/Sources/WalletConnectPairing/Types/Pairing.swift index 9edd37941..b7b783364 100644 --- a/Sources/WalletConnectPairing/Types/Pairing.swift +++ b/Sources/WalletConnectPairing/Types/Pairing.swift @@ -4,15 +4,11 @@ import Foundation */ public struct Pairing { public let topic: String - public let peer: AppMetadata? public let expiryDate: Date - public let active: Bool init(_ pairing: WCPairing) { self.topic = pairing.topic - self.peer = pairing.peerMetadata self.expiryDate = pairing.expiryDate - self.active = pairing.active } } diff --git a/Sources/WalletConnectPairing/Types/WCPairing.swift b/Sources/WalletConnectPairing/Types/WCPairing.swift index 9bd66f103..a471fa132 100644 --- a/Sources/WalletConnectPairing/Types/WCPairing.swift +++ b/Sources/WalletConnectPairing/Types/WCPairing.swift @@ -8,9 +8,7 @@ public struct WCPairing: SequenceObject { public let topic: String public let relay: RelayProtocolOptions - public private (set) var peerMetadata: AppMetadata? public private (set) var expiryDate: Date - public private (set) var active: Bool public private (set) var requestReceived: Bool public private (set) var methods: [String]? @@ -31,47 +29,25 @@ public struct WCPairing: SequenceObject { public init(uri: WalletConnectURI) { self.topic = uri.topic self.relay = uri.relay - self.active = false self.requestReceived = false self.methods = uri.methods self.expiryDate = Date(timeIntervalSince1970: TimeInterval(uri.expiryTimestamp)) } - - public mutating func activate() { - active = true - try? updateExpiry() - } public mutating func receivedRequest() { requestReceived = true } - - public mutating func updatePeerMetadata(_ metadata: AppMetadata?) { - peerMetadata = metadata - } - - public mutating func updateExpiry(_ ttl: TimeInterval = WCPairing.timeToLiveActive) throws { - let now = Self.dateInitializer() - let newExpiryDate = now.advanced(by: ttl) - let maxExpiryDate = now.advanced(by: Self.timeToLiveActive) - guard newExpiryDate > expiryDate && newExpiryDate <= maxExpiryDate else { - throw Errors.invalidUpdateExpiryValue - } - expiryDate = newExpiryDate - } } #if DEBUG extension WCPairing { - static func stub(expiryDate: Date = Date(timeIntervalSinceNow: 10000), isActive: Bool = true, topic: String = String.generateTopic()) -> WCPairing { - WCPairing(topic: topic, relay: RelayProtocolOptions.stub(), peerMetadata: AppMetadata.stub(), isActive: isActive, expiryDate: expiryDate) + static func stub(expiryDate: Date = Date(timeIntervalSinceNow: 10000), topic: String = String.generateTopic()) -> WCPairing { + WCPairing(topic: topic, relay: RelayProtocolOptions.stub(), expiryDate: expiryDate) } - init(topic: String, relay: RelayProtocolOptions, peerMetadata: AppMetadata, isActive: Bool = false, requestReceived: Bool = false, expiryDate: Date) { + init(topic: String, relay: RelayProtocolOptions, requestReceived: Bool = false, expiryDate: Date) { self.topic = topic self.relay = relay - self.peerMetadata = peerMetadata - self.active = isActive self.requestReceived = requestReceived self.expiryDate = expiryDate } diff --git a/Sources/WalletConnectSign/Auth/Services/App/AuthResponseSubscriber.swift b/Sources/WalletConnectSign/Auth/Services/App/AuthResponseSubscriber.swift index 602827661..b4889b8e3 100644 --- a/Sources/WalletConnectSign/Auth/Services/App/AuthResponseSubscriber.swift +++ b/Sources/WalletConnectSign/Auth/Services/App/AuthResponseSubscriber.swift @@ -20,6 +20,7 @@ class AuthResponseSubscriber { private let authResponseTopicRecordsStore: CodableStore private let linkModeLinksStore: CodableStore private let supportLinkMode: Bool + private let pairingStore: WCPairingStorage init(networkingInteractor: NetworkInteracting, logger: ConsoleLogging, @@ -33,6 +34,7 @@ class AuthResponseSubscriber { authResponseTopicRecordsStore: CodableStore, linkEnvelopesDispatcher: LinkEnvelopesDispatcher, linkModeLinksStore: CodableStore, + pairingStore: WCPairingStorage, supportLinkMode: Bool) { self.networkingInteractor = networkingInteractor self.logger = logger @@ -47,6 +49,7 @@ class AuthResponseSubscriber { self.linkEnvelopesDispatcher = linkEnvelopesDispatcher self.linkModeLinksStore = linkModeLinksStore self.supportLinkMode = supportLinkMode + self.pairingStore = pairingStore subscribeForResponse() subscribeForLinkResponse() } @@ -56,7 +59,8 @@ class AuthResponseSubscriber { .responseErrorSubscription(on: SessionAuthenticatedProtocolMethod.responseApprove()) .sink { [unowned self] (payload: ResponseSubscriptionErrorPayload) in guard let error = AuthError(code: payload.error.code) else { return } - authResponsePublisherSubject.send((payload.id, .failure(error))) + Task { removePairing(pairingTopic: payload.topic) } + authResponsePublisherSubject.send((payload.id, .failure(error))) }.store(in: &publishers) networkingInteractor @@ -66,8 +70,8 @@ class AuthResponseSubscriber { let transportType = getTransportTypeUpgradeIfPossible(peerMetadata: payload.response.responder.metadata, requestId: payload.id) let pairingTopic = payload.topic - pairingRegisterer.activate(pairingTopic: pairingTopic, peerMetadata: nil) removeResponseTopicRecord(responseTopic: payload.topic) + Task { removePairing(pairingTopic: pairingTopic) } let requestId = payload.id let cacaos = payload.response.cacaos @@ -100,7 +104,6 @@ class AuthResponseSubscriber { _ = getTransportTypeUpgradeIfPossible(peerMetadata: payload.response.responder.metadata, requestId: payload.id) let pairingTopic = payload.topic - pairingRegisterer.activate(pairingTopic: pairingTopic, peerMetadata: nil) removeResponseTopicRecord(responseTopic: payload.topic) let requestId = payload.id @@ -217,5 +220,10 @@ class AuthResponseSubscriber { authResponseTopicRecordsStore.delete(forKey: responseTopic) networkingInteractor.unsubscribe(topic: responseTopic) } + + private func removePairing(pairingTopic: String) { + pairingStore.delete(topic: pairingTopic) + kms.deleteSymmetricKey(for: pairingTopic) + } } diff --git a/Sources/WalletConnectSign/Auth/Services/Wallet/SessionAuthenticateResponder.swift b/Sources/WalletConnectSign/Auth/Services/Wallet/SessionAuthenticateResponder.swift index 37e89a07d..f33758a03 100644 --- a/Sources/WalletConnectSign/Auth/Services/Wallet/SessionAuthenticateResponder.swift +++ b/Sources/WalletConnectSign/Auth/Services/Wallet/SessionAuthenticateResponder.swift @@ -12,6 +12,7 @@ actor SessionAuthenticateResponder { private let metadata: AppMetadata private let util: ApproveSessionAuthenticateUtil private let eventsClient: EventsClientProtocol + private let pairingStore: WCPairingStorage init( networkingInteractor: NetworkInteracting, @@ -22,7 +23,8 @@ actor SessionAuthenticateResponder { pairingRegisterer: PairingRegisterer, metadata: AppMetadata, approveSessionAuthenticateUtil: ApproveSessionAuthenticateUtil, - eventsClient: EventsClientProtocol + eventsClient: EventsClientProtocol, + pairingStore: WCPairingStorage ) { self.networkingInteractor = networkingInteractor self.logger = logger @@ -33,6 +35,7 @@ actor SessionAuthenticateResponder { self.metadata = metadata self.util = approveSessionAuthenticateUtil self.eventsClient = eventsClient + self.pairingStore = pairingStore } func respond(requestId: RPCID, auths: [Cacao]) async throws -> Session? { @@ -113,6 +116,9 @@ actor SessionAuthenticateResponder { protocolMethod: SessionAuthenticatedProtocolMethod.responseApprove(), envelopeType: .type1(pubKey: responseKeys.publicKey.rawRepresentation) ) + Task { + removePairing(pairingTopic: pairingTopic) + } eventsClient.saveEvent(SessionAuthenticateTraceEvents.responseSent) } catch { eventsClient.saveEvent(SessionAuthenticateErrorEvents.responseSendFailed) @@ -128,10 +134,6 @@ actor SessionAuthenticateResponder { transportType: .relay, verifyContext: util.getVerifyContext(requestId: requestId, domain: sessionAuthenticateRequestParams.requester.metadata.url) ) - pairingRegisterer.activate( - pairingTopic: pairingTopic, - peerMetadata: sessionAuthenticateRequestParams.requester.metadata - ) verifyContextStore.delete(forKey: requestId.string) return session } catch { @@ -141,11 +143,23 @@ actor SessionAuthenticateResponder { } func respondError(requestId: RPCID) async throws { + let pairingTopic = try? util.getHistoryRecord(requestId: requestId).topic do { - try await walletErrorResponder.respondError(AuthError.userRejeted, requestId: requestId) + let _ = try await walletErrorResponder.respondError(AuthError.userRejeted, requestId: requestId) + Task { + if let pairingTopic = pairingTopic { + removePairing(pairingTopic: pairingTopic) + } + } } catch { throw error } verifyContextStore.delete(forKey: requestId.string) } + + private func removePairing(pairingTopic: String) { + pairingStore.delete(topic: pairingTopic) + networkingInteractor.unsubscribe(topic: pairingTopic) + kms.deleteSymmetricKey(for: pairingTopic) + } } diff --git a/Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift b/Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift index fbe9a1a56..0c8d7530b 100644 --- a/Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift +++ b/Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift @@ -160,17 +160,15 @@ final class ApproveEngine { do { let session: WCSession = try await settleRequestTask sessionStore.setSession(session) + Task { + removePairing(pairingTopic: pairingTopic) + } onSessionSettle?(session.publicRepresentation()) eventsClient.saveEvent(SessionApproveExecutionTraceEvents.sessionSettleSuccess) logger.debug("Session proposal response and settle request have been sent") proposalPayloadsStore.delete(forKey: proposerPubKey) verifyContextStore.delete(forKey: proposerPubKey) - - pairingRegisterer.activate( - pairingTopic: payload.topic, - peerMetadata: payload.request.proposer.metadata - ) return session.publicRepresentation() } catch { eventsClient.saveEvent(ApproveSessionTraceErrorEvents.sessionSettleFailure) @@ -190,15 +188,20 @@ final class ApproveEngine { reason: reason ) - if let pairingTopic = rpcHistory.get(recordId: payload.id)?.topic, - let pairing = pairingStore.getPairing(forTopic: pairingTopic), - !pairing.active { - pairingStore.delete(topic: pairingTopic) + if let pairingTopic = rpcHistory.get(recordId: payload.id)?.topic { + Task { + removePairing(pairingTopic: pairingTopic) + } } proposalPayloadsStore.delete(forKey: proposerPubKey) verifyContextStore.delete(forKey: proposerPubKey) + } + private func removePairing(pairingTopic: String) { + pairingStore.delete(topic: pairingTopic) + networkingInteractor.unsubscribe(topic: pairingTopic) + kms.deleteSymmetricKey(for: pairingTopic) } func settle(topic: String, proposal: SessionProposal, namespaces: [String: SessionNamespace], sessionProperties: [String: String]? = nil, pairingTopic: String) async throws -> WCSession { @@ -332,6 +335,7 @@ private extension ApproveEngine { sessionTopicToProposal.set(proposal, forKey: sessionTopic) Task(priority: .high) { try await networkingInteractor.subscribe(topic: sessionTopic) + removePairing(pairingTopic: payload.topic) } } catch { return logger.debug(error.localizedDescription) @@ -339,15 +343,7 @@ private extension ApproveEngine { } func handleSessionProposeResponseError(payload: ResponseSubscriptionErrorPayload) { - guard let pairing = pairingStore.getPairing(forTopic: payload.topic) else { - return logger.debug(Errors.pairingNotFound.localizedDescription) - } - - if !pairing.active { - kms.deleteSymmetricKey(for: pairing.topic) - networkingInteractor.unsubscribe(topic: pairing.topic) - pairingStore.delete(topic: payload.topic) - } + removePairing(pairingTopic: payload.topic) logger.debug("Session Proposal has been rejected") kms.deletePrivateKey(for: payload.request.proposer.publicKey) @@ -392,7 +388,7 @@ private extension ApproveEngine { proposalPayloadsStore.set(payload, forKey: proposal.proposer.publicKey) pairingRegisterer.setReceived(pairingTopic: payload.topic) - + if let verifyContext = try? verifyContextStore.get(key: proposal.proposer.publicKey) { onSessionProposal?(proposal.publicRepresentation(pairingTopic: payload.topic), verifyContext) return @@ -457,11 +453,6 @@ private extension ApproveEngine { metadata: metadata ) - pairingRegisterer.activate( - pairingTopic: pairingTopic, - peerMetadata: params.controller.metadata - ) - let session = WCSession( topic: sessionTopic, pairingTopic: pairingTopic, diff --git a/Sources/WalletConnectSign/Session.swift b/Sources/WalletConnectSign/Session.swift index 06b2500f7..1277e69f6 100644 --- a/Sources/WalletConnectSign/Session.swift +++ b/Sources/WalletConnectSign/Session.swift @@ -5,6 +5,7 @@ import Foundation */ public struct Session: Codable { public let topic: String + @available(*, deprecated, message: "The pairingTopic property is deprecated.") public let pairingTopic: String public let peer: AppMetadata public let requiredNamespaces: [String: ProposalNamespace] diff --git a/Sources/WalletConnectSign/Sign/SignClient.swift b/Sources/WalletConnectSign/Sign/SignClient.swift index 35b7941ce..7075c9373 100644 --- a/Sources/WalletConnectSign/Sign/SignClient.swift +++ b/Sources/WalletConnectSign/Sign/SignClient.swift @@ -147,7 +147,6 @@ public final class SignClient: SignClientProtocol { private let sessionEngine: SessionEngine private let approveEngine: ApproveEngine private let disconnectService: DisconnectService - private let pairingPingService: PairingPingService private let sessionPingService: SessionPingService private let nonControllerSessionStateMachine: NonControllerSessionStateMachine private let controllerSessionStateMachine: ControllerSessionStateMachine @@ -203,7 +202,6 @@ public final class SignClient: SignClientProtocol { networkingClient: NetworkingInteractor, sessionEngine: SessionEngine, approveEngine: ApproveEngine, - pairingPingService: PairingPingService, sessionPingService: SessionPingService, nonControllerSessionStateMachine: NonControllerSessionStateMachine, controllerSessionStateMachine: ControllerSessionStateMachine, @@ -239,7 +237,6 @@ public final class SignClient: SignClientProtocol { self.networkingClient = networkingClient self.sessionEngine = sessionEngine self.approveEngine = approveEngine - self.pairingPingService = pairingPingService self.sessionPingService = sessionPingService self.nonControllerSessionStateMachine = nonControllerSessionStateMachine self.controllerSessionStateMachine = controllerSessionStateMachine @@ -299,28 +296,6 @@ public final class SignClient: SignClientProtocol { return pairingURI } - /// For a dApp to propose a session to a wallet. - /// Function will propose a session on existing pairing. - /// - Parameters: - /// - requiredNamespaces: required namespaces for a session - /// - topic: pairing topic - public func connect( - requiredNamespaces: [String: ProposalNamespace], - optionalNamespaces: [String: ProposalNamespace]? = nil, - sessionProperties: [String: String]? = nil, - topic: String - ) async throws { - logger.debug("Connecting Application") - try pairingClient.validatePairingExistance(topic) - try await appProposeService.propose( - pairingTopic: topic, - namespaces: requiredNamespaces, - optionalNamespaces: optionalNamespaces, - sessionProperties: sessionProperties, - relay: RelayProtocolOptions(protocol: "irn", data: nil) - ) - } - //---------------------------------------AUTH----------------------------------- /// For a dApp to propose an authenticated session to a wallet. @@ -573,9 +548,6 @@ public final class SignClient: SignClientProtocol { sessionEngine.onSessionResponse = { [unowned self] response in sessionResponsePublisherSubject.send(response) } - pairingPingService.onResponse = { [unowned self] topic in - pingResponsePublisherSubject.send(topic) - } sessionPingService.onResponse = { [unowned self] topic in pingResponsePublisherSubject.send(topic) } diff --git a/Sources/WalletConnectSign/Sign/SignClientFactory.swift b/Sources/WalletConnectSign/Sign/SignClientFactory.swift index 98bdb3239..523eff3a4 100644 --- a/Sources/WalletConnectSign/Sign/SignClientFactory.swift +++ b/Sources/WalletConnectSign/Sign/SignClientFactory.swift @@ -93,7 +93,6 @@ public struct SignClientFactory { let deleteSessionService = DeleteSessionService(networkingInteractor: networkingClient, kms: kms, sessionStore: sessionStore, logger: logger) let disconnectService = DisconnectService(deleteSessionService: deleteSessionService, sessionStorage: sessionStore) let sessionPingService = SessionPingService(sessionStorage: sessionStore, networkingInteractor: networkingClient, logger: logger) - let pairingPingService = PairingPingService(pairingStorage: pairingStore, networkingInteractor: networkingClient, logger: logger) let appProposerService = AppProposeService(metadata: metadata, networkingInteractor: networkingClient, kms: kms, logger: logger) let proposalExpiryWatcher = ProposalExpiryWatcher(proposalPayloadsStore: proposalPayloadsStore, rpcHistory: rpcHistory) let pendingProposalsProvider = PendingProposalsProvider(proposalPayloadsStore: proposalPayloadsStore, verifyContextStore: verifyContextStore) @@ -116,7 +115,7 @@ public struct SignClientFactory { let linkModeLinksStore = CodableStore(defaults: keyValueStorage, identifier: SignStorageIdentifiers.linkModeLinks.rawValue) let supportLinkMode = metadata.redirect?.linkMode ?? false - let appRespondSubscriber = AuthResponseSubscriber(networkingInteractor: networkingClient, logger: logger, rpcHistory: rpcHistory, signatureVerifier: signatureVerifier, pairingRegisterer: pairingClient, kms: kms, sessionStore: sessionStore, messageFormatter: messageFormatter, sessionNamespaceBuilder: sessionNameSpaceBuilder, authResponseTopicRecordsStore: authResponseTopicRecordsStore, linkEnvelopesDispatcher: linkEnvelopesDispatcher, linkModeLinksStore: linkModeLinksStore, supportLinkMode: supportLinkMode) + let appRespondSubscriber = AuthResponseSubscriber(networkingInteractor: networkingClient, logger: logger, rpcHistory: rpcHistory, signatureVerifier: signatureVerifier, pairingRegisterer: pairingClient, kms: kms, sessionStore: sessionStore, messageFormatter: messageFormatter, sessionNamespaceBuilder: sessionNameSpaceBuilder, authResponseTopicRecordsStore: authResponseTopicRecordsStore, linkEnvelopesDispatcher: linkEnvelopesDispatcher, linkModeLinksStore: linkModeLinksStore, pairingStore: pairingStore, supportLinkMode: supportLinkMode) let walletErrorResponder = WalletErrorResponder(networkingInteractor: networkingClient, logger: logger, kms: kms, rpcHistory: rpcHistory, linkEnvelopesDispatcher: linkEnvelopesDispatcher) let authRequestSubscriber = AuthRequestSubscriber(networkingInteractor: networkingClient, logger: logger, kms: kms, walletErrorResponder: walletErrorResponder, pairingRegisterer: pairingClient, verifyClient: verifyClient, verifyContextStore: verifyContextStore, pairingStore: pairingStore) @@ -129,7 +128,7 @@ public struct SignClientFactory { let linkAuthRequester = LinkAuthRequester(kms: kms, appMetadata: metadata, logger: logger, iatProvader: iatProvider, authResponseTopicRecordsStore: authResponseTopicRecordsStore, linkEnvelopesDispatcher: linkEnvelopesDispatcher, linkModeLinksStore: linkModeLinksStore) let linkAuthRequestSubscriber = LinkAuthRequestSubscriber(logger: logger, kms: kms, envelopesDispatcher: linkEnvelopesDispatcher, verifyClient: verifyClient, verifyContextStore: verifyContextStore) - let relaySessionAuthenticateResponder = SessionAuthenticateResponder(networkingInteractor: networkingClient, logger: logger, kms: kms, verifyContextStore: verifyContextStore, walletErrorResponder: walletErrorResponder, pairingRegisterer: pairingClient, metadata: metadata, approveSessionAuthenticateUtil: approveSessionAuthenticateUtil, eventsClient: eventsClient) + let relaySessionAuthenticateResponder = SessionAuthenticateResponder(networkingInteractor: networkingClient, logger: logger, kms: kms, verifyContextStore: verifyContextStore, walletErrorResponder: walletErrorResponder, pairingRegisterer: pairingClient, metadata: metadata, approveSessionAuthenticateUtil: approveSessionAuthenticateUtil, eventsClient: eventsClient, pairingStore: pairingStore) let linkSessionAuthenticateResponder = LinkSessionAuthenticateResponder(linkEnvelopesDispatcher: linkEnvelopesDispatcher, logger: logger, kms: kms, metadata: metadata, approveSessionAuthenticateUtil: approveSessionAuthenticateUtil, walletErrorResponder: walletErrorResponder, verifyContextStore: verifyContextStore) @@ -153,7 +152,6 @@ public struct SignClientFactory { networkingClient: networkingClient, sessionEngine: sessionEngine, approveEngine: approveEngine, - pairingPingService: pairingPingService, sessionPingService: sessionPingService, nonControllerSessionStateMachine: nonControllerSessionStateMachine, controllerSessionStateMachine: controllerSessionStateMachine, diff --git a/Sources/WalletConnectSign/Sign/SignClientProtocol.swift b/Sources/WalletConnectSign/Sign/SignClientProtocol.swift index f74e2c9c7..080843a99 100644 --- a/Sources/WalletConnectSign/Sign/SignClientProtocol.swift +++ b/Sources/WalletConnectSign/Sign/SignClientProtocol.swift @@ -18,8 +18,6 @@ public protocol SignClientProtocol { var pendingProposalsPublisher: AnyPublisher<[(proposal: Session.Proposal, context: VerifyContext?)], Never> { get } var requestExpirationPublisher: AnyPublisher { get } - func connect(requiredNamespaces: [String: ProposalNamespace], optionalNamespaces: [String: ProposalNamespace]?, sessionProperties: [String: String]?, topic: String) async throws - func request(params: Request) async throws func approve(proposalId: String, namespaces: [String: SessionNamespace], sessionProperties: [String: String]?) async throws -> Session func authenticate(_ params: AuthRequestParams, walletUniversalLink: String?) async throws -> WalletConnectURI? diff --git a/Sources/WalletConnectSign/SignDecryptionService.swift b/Sources/WalletConnectSign/SignDecryptionService.swift index a0b8f649a..9301c8517 100644 --- a/Sources/WalletConnectSign/SignDecryptionService.swift +++ b/Sources/WalletConnectSign/SignDecryptionService.swift @@ -50,7 +50,6 @@ public class SignDecryptionService { public func decryptAuthRequest(topic: String, ciphertext: String) throws -> AuthenticationRequest { let (rpcRequest, _, _): (RPCRequest, String?, Data) = try serializer.deserialize(topic: topic, codingType: .base64Encoded, envelopeString: ciphertext) - setPairingMetadata(rpcRequest: rpcRequest, topic: topic) if let params = try rpcRequest.params?.get(SessionAuthenticateRequestParams.self), let id = rpcRequest.id { let authRequest = AuthenticationRequest(id: id, topic: topic, payload: params.authPayload, requester: params.requester.metadata) @@ -63,14 +62,4 @@ public class SignDecryptionService { public func getMetadata(topic: String) -> AppMetadata? { sessionStorage.getSession(forTopic: topic)?.peerParticipant.metadata } - - private func setPairingMetadata(rpcRequest: RPCRequest, topic: String) { - guard var pairing = pairingStorage.getPairing(forTopic: topic), - pairing.peerMetadata == nil, - let peerMetadata = try? rpcRequest.params?.get(SessionAuthenticateRequestParams.self).requester.metadata - else { return } - - pairing.updatePeerMetadata(peerMetadata) - pairingStorage.setPairing(pairing) - } } diff --git a/Sources/Web3Wallet/Web3WalletClient.swift b/Sources/Web3Wallet/Web3WalletClient.swift index 84f636b92..62576d5a9 100644 --- a/Sources/Web3Wallet/Web3WalletClient.swift +++ b/Sources/Web3Wallet/Web3WalletClient.swift @@ -177,9 +177,8 @@ public class Web3WalletClient { try await pairingClient.pair(uri: uri) } - public func disconnectPairing(topic: String) async { - await pairingClient.disconnect(topic: topic) - } + @available(*, deprecated, message: "This method is deprecated. Pairing will disconnect automatically") + public func disconnectPairing(topic: String) async {} /// For a wallet and a dApp to terminate a session /// diff --git a/Tests/TestingUtils/Mocks/PairingRegistererMock.swift b/Tests/TestingUtils/Mocks/PairingRegistererMock.swift index 3c21567c6..36915f594 100644 --- a/Tests/TestingUtils/Mocks/PairingRegistererMock.swift +++ b/Tests/TestingUtils/Mocks/PairingRegistererMock.swift @@ -6,20 +6,11 @@ import WalletConnectNetworking public class PairingRegistererMock: PairingRegisterer where RequestParams: Codable { public let subject = PassthroughSubject, Never>() - public var isActivateCalled: Bool = false public var isReceivedCalled: Bool = false public func register(method: ProtocolMethod) -> AnyPublisher, Never> where RequestParams: Decodable, RequestParams: Encodable { subject.eraseToAnyPublisher() as! AnyPublisher, Never> } - - public func activate(pairingTopic: String, peerMetadata: WalletConnectPairing.AppMetadata?) { - isActivateCalled = true - } - - public func validatePairingExistance(_ topic: String) throws { - - } public func setReceived(pairingTopic: String) { isReceivedCalled = true diff --git a/Tests/WalletConnectModalTests/Mocks/ModalSheetInteractorMock.swift b/Tests/WalletConnectModalTests/Mocks/ModalSheetInteractorMock.swift index e22c5d5f3..216685982 100644 --- a/Tests/WalletConnectModalTests/Mocks/ModalSheetInteractorMock.swift +++ b/Tests/WalletConnectModalTests/Mocks/ModalSheetInteractorMock.swift @@ -17,7 +17,7 @@ final class ModalSheetInteractorMock: ModalSheetInteractor { (1, wallets) } - func createPairingAndConnect() async throws -> WalletConnectURI? { + func createPairingAndConnect() async throws -> WalletConnectURI { .init(topic: "foo", symKey: "bar", relay: .init(protocol: "irn", data: nil), expiryTimestamp: 1706001526) } diff --git a/Tests/WalletConnectPairingTests/AppPairActivationServiceTests.swift b/Tests/WalletConnectPairingTests/AppPairActivationServiceTests.swift deleted file mode 100644 index 601862ad6..000000000 --- a/Tests/WalletConnectPairingTests/AppPairActivationServiceTests.swift +++ /dev/null @@ -1,42 +0,0 @@ -import XCTest -@testable import WalletConnectPairing -@testable import TestingUtils -import WalletConnectUtils - -final class AppPairActivationServiceTests: XCTestCase { - - var service: AppPairActivationService! - var storageMock: WCPairingStorage! - var logger: ConsoleLogger! - - override func setUp() { - storageMock = WCPairingStorageMock() - logger = ConsoleLogger() - service = AppPairActivationService(pairingStorage: storageMock, logger: logger) - } - - override func tearDown() { - storageMock = nil - logger = nil - service = nil - } - - func testActivate() { - let pairing = WCPairing(uri: WalletConnectURI.stub()) - let topic = pairing.topic - let date = pairing.expiryDate - - storageMock.setPairing(pairing) - - XCTAssertFalse(pairing.active) - XCTAssertNil(pairing.peerMetadata) - - service.activate(for: topic, peerMetadata: .stub()) - - let activated = storageMock.getPairing(forTopic: topic)! - - XCTAssertTrue(activated.active) - XCTAssertNotNil(activated.peerMetadata) - XCTAssertTrue(activated.expiryDate > date) - } -} diff --git a/Tests/WalletConnectPairingTests/AppPairServiceTests.swift b/Tests/WalletConnectPairingTests/AppPairServiceTests.swift index 9839d5192..304bb2697 100644 --- a/Tests/WalletConnectPairingTests/AppPairServiceTests.swift +++ b/Tests/WalletConnectPairingTests/AppPairServiceTests.swift @@ -30,6 +30,5 @@ final class AppPairServiceTests: XCTestCase { XCTAssert(cryptoMock.hasSymmetricKey(for: uri.topic), "Proposer must store the symmetric key matching the URI.") XCTAssert(storageMock.hasPairing(forTopic: uri.topic), "The engine must store a pairing after creating one") XCTAssert(networkingInteractor.didSubscribe(to: uri.topic), "Proposer must subscribe to pairing topic.") - XCTAssert(storageMock.getPairing(forTopic: uri.topic)?.active == false, "Recently created pairing must be inactive.") } } diff --git a/Tests/WalletConnectPairingTests/WCPairingTests.swift b/Tests/WalletConnectPairingTests/WCPairingTests.swift deleted file mode 100644 index 8565b5bfa..000000000 --- a/Tests/WalletConnectPairingTests/WCPairingTests.swift +++ /dev/null @@ -1,102 +0,0 @@ -import XCTest -@testable import WalletConnectPairing -@testable import WalletConnectUtils -@testable import WalletConnectUtils - -final class WCPairingTests: XCTestCase { - - var referenceDate: Date! - - override func setUp() { - referenceDate = Date() - func getDate() -> Date { return referenceDate } - WCPairing.dateInitializer = getDate - } - - override func tearDown() { - WCPairing.dateInitializer = Date.init - } - - func testAbsoluteValues() { - XCTAssertEqual(WCPairing.timeToLiveInactive, 5 * .minute, "Inactive time-to-live is 5 minutes.") - XCTAssertEqual(WCPairing.timeToLiveActive, 30 * .day, "Active time-to-live is 30 days.") - } - - func testInitInactiveFromTopic() { - let pairing = WCPairing(uri: WalletConnectURI.stub()) - let inactiveExpiry = referenceDate.advanced(by: WCPairing.timeToLiveInactive) - XCTAssertFalse(pairing.active) - XCTAssertEqual(pairing.expiryDate.timeIntervalSince1970, inactiveExpiry.timeIntervalSince1970, accuracy: 1) - } - - func testInitInactiveFromURI() { - let pairing = WCPairing(uri: WalletConnectURI.stub()) - let inactiveExpiry = referenceDate.advanced(by: WCPairing.timeToLiveInactive) - XCTAssertFalse(pairing.active) - XCTAssertEqual(pairing.expiryDate.timeIntervalSince1970, inactiveExpiry.timeIntervalSince1970, accuracy: 1) - } - - func testUpdateExpiryForTopic() { - var pairing = WCPairing(uri: WalletConnectURI.stub()) - let activeExpiry = referenceDate.advanced(by: WCPairing.timeToLiveActive) - try? pairing.updateExpiry() - XCTAssertEqual(pairing.expiryDate, activeExpiry) - } - - func testUpdateExpiryForUri() { - var pairing = WCPairing(uri: WalletConnectURI.stub()) - let activeExpiry = referenceDate.advanced(by: WCPairing.timeToLiveActive) - try? pairing.updateExpiry() - XCTAssertEqual(pairing.expiryDate, activeExpiry) - } - - func testActivateTopic() { - var pairing = WCPairing(uri: WalletConnectURI.stub()) - let activeExpiry = referenceDate.advanced(by: WCPairing.timeToLiveActive) - XCTAssertFalse(pairing.active) - pairing.activate() - XCTAssertTrue(pairing.active) - XCTAssertEqual(pairing.expiryDate, activeExpiry) - } - - func testActivateURI() { - var pairing = WCPairing(uri: WalletConnectURI.stub()) - let activeExpiry = referenceDate.advanced(by: WCPairing.timeToLiveActive) - XCTAssertFalse(pairing.active) - pairing.activate() - XCTAssertTrue(pairing.active) - XCTAssertEqual(pairing.expiryDate, activeExpiry) - } - - func testUpdateExpiryWhenValueIsGreaterThanMax() { - var pairing = WCPairing(topic: "", relay: .stub(), peerMetadata: .stub(), expiryDate: referenceDate) - XCTAssertThrowsError(try pairing.updateExpiry(40 * .day)) { error in - XCTAssertEqual(error as! WCPairing.Errors, WCPairing.Errors.invalidUpdateExpiryValue) - } - } - - func testUpdateExpiryWhenNewExpiryDateIsLessThanExpiryDate() { - let expiryDate = referenceDate.advanced(by: 40 * .day) - var pairing = WCPairing(topic: "", relay: .stub(), peerMetadata: .stub(), expiryDate: expiryDate) - XCTAssertThrowsError(try pairing.updateExpiry(10 * .minute)) { error in - XCTAssertEqual(error as! WCPairing.Errors, WCPairing.Errors.invalidUpdateExpiryValue) - } - } - - func testActivateWhenCanUpdateExpiry() { - var pairing = WCPairing(topic: "", relay: .stub(), peerMetadata: .stub(), expiryDate: referenceDate) - XCTAssertFalse(pairing.active) - pairing.activate() - XCTAssertTrue(pairing.active) - XCTAssertEqual(referenceDate.advanced(by: 30 * .day), pairing.expiryDate) - } - - func testActivateWhenUpdateExpiryIsInvalid() { - let expiryDate = referenceDate.advanced(by: 40 * .day) - var pairing = WCPairing(topic: "", relay: .stub(), peerMetadata: .stub(), expiryDate: expiryDate) - XCTAssertFalse(pairing.active) - pairing.activate() - XCTAssertTrue(pairing.active) - XCTAssertEqual(expiryDate, pairing.expiryDate) - } -} diff --git a/Tests/WalletConnectSignTests/AppProposalServiceTests.swift b/Tests/WalletConnectSignTests/AppProposalServiceTests.swift index ae3a4772d..d11d3644c 100644 --- a/Tests/WalletConnectSignTests/AppProposalServiceTests.swift +++ b/Tests/WalletConnectSignTests/AppProposalServiceTests.swift @@ -128,7 +128,6 @@ final class AppProposalServiceTests: XCTestCase { networkingInteractor.responsePublisherSubject.send((topicA, request, response, Date(), nil)) let privateKey = try! cryptoMock.getPrivateKey(for: proposal.proposer.publicKey)! let topicB = deriveTopic(publicKey: responder.publicKey, privateKey: privateKey) - _ = storageMock.getPairing(forTopic: topicA)! await fulfillment(of: [exp], timeout: 5) @@ -156,37 +155,8 @@ final class AppProposalServiceTests: XCTestCase { let response = RPCResponse.stubError(forRequest: request) networkingInteractor.responsePublisherSubject.send((topicA, request, response, Date(), nil)) - XCTAssert(networkingInteractor.didUnsubscribe(to: pairing.topic), "Proposer must unsubscribe if pairing is inactive.") - XCTAssertFalse(storageMock.hasPairing(forTopic: pairing.topic), "Proposer must delete an inactive pairing.") + XCTAssertFalse(storageMock.hasPairing(forTopic: pairing.topic), "Proposer must delete the pairing.") XCTAssertFalse(cryptoMock.hasSymmetricKey(for: pairing.topic), "Proposer must delete symmetric key if pairing is inactive.") XCTAssertFalse(cryptoMock.hasPrivateKey(for: proposal.proposer.publicKey), "Proposer must remove private key for rejected session") } - - func testSessionProposeErrorOnActivePairing() async { - let uri = try! await appPairService.create(supportedMethods: nil) - let pairing = storageMock.getPairing(forTopic: uri.topic)! - let topicA = pairing.topic - let relayOptions = RelayProtocolOptions(protocol: "", data: nil) - - // Client propose session - // FIXME: namespace stub - try? await service.propose(pairingTopic: pairing.topic, namespaces: ProposalNamespace.stubDictionary(), relay: relayOptions) - - guard let request = networkingInteractor.requests.first?.request, - let proposal = try? networkingInteractor.requests.first?.request.params?.get(SessionType.ProposeParams.self) else { - XCTFail("Proposer must publish session proposal request"); return - } - - var storedPairing = storageMock.getPairing(forTopic: topicA)! - storedPairing.activate() - storageMock.setPairing(storedPairing) - - let response = RPCResponse.stubError(forRequest: request) - networkingInteractor.responsePublisherSubject.send((topicA, request, response, Date(), nil)) - - XCTAssertFalse(networkingInteractor.didUnsubscribe(to: pairing.topic), "Proposer must not unsubscribe if pairing is active.") - XCTAssert(storageMock.hasPairing(forTopic: pairing.topic), "Proposer must not delete an active pairing.") - XCTAssert(cryptoMock.hasSymmetricKey(for: pairing.topic), "Proposer must not delete symmetric key if pairing is active.") - XCTAssertFalse(cryptoMock.hasPrivateKey(for: proposal.proposer.publicKey), "Proposer must remove private key for rejected session") - } } diff --git a/Tests/WalletConnectSignTests/ApproveEngineTests.swift b/Tests/WalletConnectSignTests/ApproveEngineTests.swift index 1d36d7902..552c8b1aa 100644 --- a/Tests/WalletConnectSignTests/ApproveEngineTests.swift +++ b/Tests/WalletConnectSignTests/ApproveEngineTests.swift @@ -83,7 +83,6 @@ final class ApproveEngineTests: XCTestCase { XCTAssert(cryptoMock.hasAgreementSecret(for: topicB), "Responder must store agreement key for topic B") XCTAssertEqual(networkingInteractor.didRespondOnTopic!, topicA, "Responder must respond on topic A") XCTAssertTrue(sessionStorageMock.hasSession(forTopic: topicB), "Responder must persist session on topic B") - XCTAssertTrue(pairingRegisterer.isActivateCalled) } func testReceiveProposal() {