From 33af170a11954b846ab2490eca9eff4c0230c8fd Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Fri, 15 Mar 2024 14:48:36 +0100 Subject: [PATCH 01/11] savepoint --- .../Services/ProposalNamespaceBuilder.swift | 2 +- .../Auth/Services/SignRecap.swift | 4 +- Sources/WalletConnectSign/Namespace.swift | 63 ++++++++++++++----- .../SessionNamespaceBuilderTests.swift | 4 +- 4 files changed, 53 insertions(+), 20 deletions(-) diff --git a/Sources/WalletConnectSign/Auth/Services/ProposalNamespaceBuilder.swift b/Sources/WalletConnectSign/Auth/Services/ProposalNamespaceBuilder.swift index 3c4ca0861..5a3faa1fc 100644 --- a/Sources/WalletConnectSign/Auth/Services/ProposalNamespaceBuilder.swift +++ b/Sources/WalletConnectSign/Auth/Services/ProposalNamespaceBuilder.swift @@ -13,7 +13,7 @@ struct ProposalNamespaceBuilder { if methods.isEmpty { methods = ["personal_sign"] } - let chains: Set = Set(params.chains.compactMap { Blockchain($0) }) + let chains: [Blockchain] = params.chains.compactMap { Blockchain($0) } guard chains.allSatisfy({$0.namespace == "eip155"}) else { throw Errors.unsupportedChain } diff --git a/Sources/WalletConnectSign/Auth/Services/SignRecap.swift b/Sources/WalletConnectSign/Auth/Services/SignRecap.swift index bcda4fdba..8c0b53b9c 100644 --- a/Sources/WalletConnectSign/Auth/Services/SignRecap.swift +++ b/Sources/WalletConnectSign/Auth/Services/SignRecap.swift @@ -40,7 +40,7 @@ struct SignRecap { .filter { $0.hasPrefix("request/") } .map { String($0.dropFirst("request/".count)) }) } - var chains: Set { + var chains: [Blockchain] { guard let eip155Actions = recapData.att?["eip155"] else { return [] } // Attempt to find and decode the first action's chain array from AnyCodable @@ -49,7 +49,7 @@ struct SignRecap { let firstActionValue = firstActionValues.first, let dict = try? firstActionValue.get([String:[String]].self), let chainsArray = dict["chains"]{ - return Set(chainsArray.compactMap(Blockchain.init)) + return chainsArray.compactMap(Blockchain.init) } return [] diff --git a/Sources/WalletConnectSign/Namespace.swift b/Sources/WalletConnectSign/Namespace.swift index af84a5fb4..8349f46b9 100644 --- a/Sources/WalletConnectSign/Namespace.swift +++ b/Sources/WalletConnectSign/Namespace.swift @@ -24,12 +24,11 @@ public enum AutoNamespacesError: Error, LocalizedError { } public struct ProposalNamespace: Equatable, Codable { - - public let chains: Set? + public let chains: [Blockchain]? public let methods: Set public let events: Set - public init(chains: Set? = nil, methods: Set, events: Set) { + public init(chains: [Blockchain]? = nil, methods: Set, events: Set) { self.chains = chains self.methods = methods self.events = events @@ -37,19 +36,19 @@ public struct ProposalNamespace: Equatable, Codable { } public struct SessionNamespace: Equatable, Codable { - public var chains: Set? + public var chains: [Blockchain]? public var accounts: Set public var methods: Set public var events: Set - public init(chains: Set? = nil, accounts: Set, methods: Set, events: Set) { + public init(chains: [Blockchain]? = nil, accounts: Set, methods: Set, events: Set) { self.chains = chains self.accounts = accounts self.methods = methods self.events = events } - static func accountsAreCompliant(_ accounts: Set, toChains chains: Set) -> Bool { + static func accountsAreCompliant(_ accounts: Set, toChains chains: [Blockchain]) -> Bool { for chain in chains { guard accounts.contains(where: { $0.blockchain == chain }) else { return false @@ -59,6 +58,7 @@ public struct SessionNamespace: Equatable, Codable { } } + enum Namespace { static func validate(_ namespaces: [String: ProposalNamespace]) throws { @@ -116,7 +116,7 @@ enum Namespace { if requiredNamespaces[network] == nil { requiredNamespaces[network] = proposalNamespace } else { - let unionChains = requiredNamespaces[network]?.chains!.union(proposalNamespace.chains ?? []) + let unionChains = requiredNamespaces[network]?.chains!.orderedUnion(proposalNamespace.chains ?? []) let unionMethods = requiredNamespaces[network]?.methods.union(proposalNamespace.methods) let unionEvents = requiredNamespaces[network]?.events.union(proposalNamespace.events) @@ -197,7 +197,7 @@ public enum AutoNamespaces { } let availableAccountsBlockchains = accounts.map { $0.blockchain } - guard !sessionChains.intersection(Set(availableAccountsBlockchains)).isEmpty else { + guard !sessionChains.intersection(availableAccountsBlockchains).isEmpty else { throw AutoNamespacesError.requiredAccountsNotSatisfied } @@ -211,7 +211,7 @@ public enum AutoNamespaces { if sessionNamespaces[caip2Namespace] == nil { sessionNamespaces[caip2Namespace] = sessionNamespace } else { - let unionChains = (sessionNamespaces[caip2Namespace]?.chains ?? []).union(sessionNamespace.chains ?? []) + let unionChains = (sessionNamespaces[caip2Namespace]?.chains ?? []).orderedUnion(sessionNamespace.chains ?? []) sessionNamespaces[caip2Namespace]?.chains = unionChains let unionAccounts = sessionNamespaces[caip2Namespace]?.accounts.union(sessionNamespace.accounts) sessionNamespaces[caip2Namespace]?.accounts = unionAccounts ?? [] @@ -245,7 +245,7 @@ public enum AutoNamespaces { } let sessionNamespace = SessionNamespace( - chains: Set([Blockchain(namespace: network, reference: chain)!]), + chains: [Blockchain(namespace: network, reference: chain)!], accounts: Set(accounts).filter { $0.blockchain == Blockchain(namespace: network, reference: chain)! }, methods: sessionMethods, events: sessionEvents @@ -254,7 +254,7 @@ public enum AutoNamespaces { if sessionNamespaces[network] == nil { sessionNamespaces[network] = sessionNamespace } else { - let unionChains = (sessionNamespaces[network]?.chains ?? []).union(sessionNamespace.chains ?? []) + let unionChains = (sessionNamespaces[network]?.chains ?? []).orderedUnion(sessionNamespace.chains ?? []) sessionNamespaces[network]?.chains = unionChains let unionAccounts = sessionNamespaces[network]?.accounts.union(sessionNamespace.accounts) sessionNamespaces[network]?.accounts = unionAccounts ?? [] @@ -272,7 +272,7 @@ public enum AutoNamespaces { let proposalNamespace = $0.value if let proposalChains = proposalNamespace.chains { - let sessionChains = Set(proposalChains).intersection(Set(chains)) + let sessionChains = proposalChains.intersection(chains) guard !sessionChains.isEmpty else { return } @@ -294,7 +294,7 @@ public enum AutoNamespaces { if sessionNamespaces[caip2Namespace] == nil { sessionNamespaces[caip2Namespace] = sessionNamespace } else { - let unionChains = (sessionNamespaces[caip2Namespace]?.chains ?? []).union(sessionNamespace.chains ?? []) + let unionChains = (sessionNamespaces[caip2Namespace]?.chains ?? []).orderedUnion(sessionNamespace.chains ?? []) sessionNamespaces[caip2Namespace]?.chains = unionChains let unionAccounts = sessionNamespaces[caip2Namespace]?.accounts.union(sessionNamespace.accounts) sessionNamespaces[caip2Namespace]?.accounts = unionAccounts ?? [] @@ -320,7 +320,7 @@ public enum AutoNamespaces { let sessionEvents = Set(proposalNamespace.events).intersection(Set(events)) let sessionNamespace = SessionNamespace( - chains: Set([Blockchain(namespace: network, reference: chain)!]), + chains: [Blockchain(namespace: network, reference: chain)!], accounts: Set(accounts).filter { $0.blockchain == Blockchain(namespace: network, reference: chain)! }, methods: sessionMethods, events: sessionEvents @@ -329,7 +329,7 @@ public enum AutoNamespaces { if sessionNamespaces[network] == nil { sessionNamespaces[network] = sessionNamespace } else { - let unionChains = (sessionNamespaces[network]?.chains ?? []).union(sessionNamespace.chains ?? []) + let unionChains = (sessionNamespaces[network]?.chains ?? []).orderedUnion(sessionNamespace.chains ?? []) sessionNamespaces[network]?.chains = unionChains let unionAccounts = sessionNamespaces[network]?.accounts.union(sessionNamespace.accounts) sessionNamespaces[network]?.accounts = unionAccounts ?? [] @@ -346,3 +346,36 @@ public enum AutoNamespaces { return sessionNamespaces } } + + +extension Array where Element: Hashable { + + // Checks if the current array is a subset of the provided array. + func isSubset(of other: [Element]) -> Bool { + let otherSet = Set(other) + for element in self { + if !otherSet.contains(element) { + return false + } + } + return true + } + + // Returns the intersection of the current array and the provided array. + // Elements are returned in the order they appear in the current array. + func intersection(_ other: [Element]) -> [Element] { + let otherSet = Set(other) + return self.filter { otherSet.contains($0) } + } + + // Returns the ordered union of the current array and the provided array. + // Elements from the current array are prioritized, and the order is preserved. + func orderedUnion(_ other: [Element]) -> [Element] { + var combined = self + let selfSet = Set(self) + for element in other where !selfSet.contains(element) { + combined.append(element) + } + return combined + } +} diff --git a/Tests/WalletConnectSignTests/SessionNamespaceBuilderTests.swift b/Tests/WalletConnectSignTests/SessionNamespaceBuilderTests.swift index 2fcde6eb5..116af8abe 100644 --- a/Tests/WalletConnectSignTests/SessionNamespaceBuilderTests.swift +++ b/Tests/WalletConnectSignTests/SessionNamespaceBuilderTests.swift @@ -40,7 +40,7 @@ class SessionNamespaceBuilderTests: XCTestCase { func testBuildSessionNamespaces_ValidCacaos_ReturnsExpectedNamespace() { let expectedSessionNamespace = SessionNamespace( - chains: Set([Blockchain("eip155:1")!, Blockchain("eip155:137")!]), + chains: [Blockchain("eip155:1")!, Blockchain("eip155:137")!], accounts: Set([ Account("eip155:1:0x000a10343Bcdebe21283c7172d67a9a113E819C5")!, Account("eip155:137:0x000a10343Bcdebe21283c7172d67a9a113E819C5")! @@ -67,7 +67,7 @@ class SessionNamespaceBuilderTests: XCTestCase { func testMutlipleRecapsInCacaoWhereOnlyOneIsSessionRecap() { let expectedSessionNamespace = SessionNamespace( - chains: Set([Blockchain("eip155:1")!, Blockchain("eip155:137")!]), + chains: [Blockchain("eip155:1")!, Blockchain("eip155:137")!], accounts: Set([ Account("eip155:1:0x000a10343Bcdebe21283c7172d67a9a113E819C5")! ]), From 1fce1cf56e6c731239cc623541ec9900f0d7ec19 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 18 Mar 2024 10:01:51 +0100 Subject: [PATCH 02/11] savepoint --- Sources/WalletConnectSign/Namespace.swift | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Sources/WalletConnectSign/Namespace.swift b/Sources/WalletConnectSign/Namespace.swift index 8349f46b9..ade22b0ac 100644 --- a/Sources/WalletConnectSign/Namespace.swift +++ b/Sources/WalletConnectSign/Namespace.swift @@ -224,7 +224,7 @@ public enum AutoNamespaces { if let network = $0.key.components(separatedBy: ":").first, let chain = $0.key.components(separatedBy: ":").last { - let sessionChains = Set([Blockchain(namespace: network, reference: chain)]).intersection(Set(chains)) + let sessionChains = [Blockchain(namespace: network, reference: chain)].intersection(chains) guard !sessionChains.isEmpty else { throw AutoNamespacesError.requiredChainsNotSatisfied } @@ -240,7 +240,7 @@ public enum AutoNamespaces { } let availableAccountsBlockchains = accounts.map { $0.blockchain } - guard !sessionChains.intersection(Set(availableAccountsBlockchains)).isEmpty else { + guard !sessionChains.intersection(availableAccountsBlockchains).isEmpty else { throw AutoNamespacesError.requiredAccountsNotSatisfied } @@ -273,6 +273,8 @@ public enum AutoNamespaces { if let proposalChains = proposalNamespace.chains { let sessionChains = proposalChains.intersection(chains) + print("session chains: \(sessionChains)") + print("proposal chains: \(proposalChains)") guard !sessionChains.isEmpty else { return } @@ -295,6 +297,9 @@ public enum AutoNamespaces { sessionNamespaces[caip2Namespace] = sessionNamespace } else { let unionChains = (sessionNamespaces[caip2Namespace]?.chains ?? []).orderedUnion(sessionNamespace.chains ?? []) + print("caip2namespace chains: \(sessionNamespaces[caip2Namespace]?.chains)") + print("sessionNamespace.chains \(sessionNamespace.chains)") + print("union chains: \(unionChains)") sessionNamespaces[caip2Namespace]?.chains = unionChains let unionAccounts = sessionNamespaces[caip2Namespace]?.accounts.union(sessionNamespace.accounts) sessionNamespaces[caip2Namespace]?.accounts = unionAccounts ?? [] @@ -307,11 +312,13 @@ public enum AutoNamespaces { if let network = $0.key.components(separatedBy: ":").first, let chain = $0.key.components(separatedBy: ":").last { - let sessionChains = Set([Blockchain(namespace: network, reference: chain)]).intersection(Set(chains)) + let sessionChains = [Blockchain(namespace: network, reference: chain)].intersection(chains) guard !sessionChains.isEmpty else { return } - + + print("session chains: \(sessionChains)") + let sessionMethods = Set(proposalNamespace.methods).intersection(Set(methods)) guard !sessionMethods.isEmpty else { return From 2629394ee23fe75d3bfddb56243ec5ebe8fa3f84 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 18 Mar 2024 11:00:09 +0100 Subject: [PATCH 03/11] fix tests --- .../SessionProposalInteractor.swift | 4 +- .../SessionProposal/SessionProposalView.swift | 2 +- Sources/WalletConnectSign/Namespace.swift | 2 +- .../AutoNamespacesValidationTests.swift | 66 ++++++------------- 4 files changed, 23 insertions(+), 51 deletions(-) diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalInteractor.swift index 7c6fe2cc0..ceeef4bc2 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalInteractor.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalInteractor.swift @@ -9,9 +9,9 @@ final class SessionProposalInteractor { let supportedMethods = Set(proposal.requiredNamespaces.flatMap { $0.value.methods } + (proposal.optionalNamespaces?.flatMap { $0.value.methods } ?? [])) let supportedEvents = Set(proposal.requiredNamespaces.flatMap { $0.value.events } + (proposal.optionalNamespaces?.flatMap { $0.value.events } ?? [])) - let supportedRequiredChains = proposal.requiredNamespaces["eip155"]?.chains + let supportedRequiredChains = proposal.requiredNamespaces["eip155"]?.chains ?? [] let supportedOptionalChains = proposal.optionalNamespaces?["eip155"]?.chains ?? [] - var supportedChains = (supportedRequiredChains ?? []).union(supportedOptionalChains) + var supportedChains = supportedRequiredChains + supportedOptionalChains let supportedAccounts = Array(supportedChains).map { Account(blockchain: $0, address: account.address)! } diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalView.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalView.swift index 02f4b0401..62dec77ae 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalView.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalView.swift @@ -168,7 +168,7 @@ struct SessionProposalView: View { private func sessionProposalView(namespaces: ProposalNamespace) -> some View { VStack { VStack(alignment: .leading) { - TagsView(items: Array(namespaces.chains ?? Set())) { + TagsView(items: Array(namespaces.chains ?? [])) { Text($0.absoluteString.uppercased()) .font(.system(size: 15, weight: .semibold, design: .rounded)) .foregroundColor(.whiteBackground) diff --git a/Sources/WalletConnectSign/Namespace.swift b/Sources/WalletConnectSign/Namespace.swift index ade22b0ac..7e439a03d 100644 --- a/Sources/WalletConnectSign/Namespace.swift +++ b/Sources/WalletConnectSign/Namespace.swift @@ -250,7 +250,7 @@ public enum AutoNamespaces { methods: sessionMethods, events: sessionEvents ) - + print("$0 \($0)") if sessionNamespaces[network] == nil { sessionNamespaces[network] = sessionNamespace } else { diff --git a/Tests/WalletConnectSignTests/AutoNamespacesValidationTests.swift b/Tests/WalletConnectSignTests/AutoNamespacesValidationTests.swift index f0c0a9fc3..618580e58 100644 --- a/Tests/WalletConnectSignTests/AutoNamespacesValidationTests.swift +++ b/Tests/WalletConnectSignTests/AutoNamespacesValidationTests.swift @@ -122,12 +122,10 @@ final class AutoNamespacesValidationTests: XCTestCase { Account(blockchain: Blockchain("eip155:2")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")!, Account(blockchain: Blockchain("eip155:3")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")! ] + let requiredNamespaces = [ - "eip155:1": ProposalNamespace( - methods: ["personal_sign", "eth_sendTransaction"], - events: ["chainChanged"] - ), - "eip155:2": ProposalNamespace( + "eip155": ProposalNamespace( + chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -167,22 +165,15 @@ final class AutoNamespacesValidationTests: XCTestCase { Account(blockchain: Blockchain("eip155:4")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")! ] let requiredNamespaces = [ - "eip155:1": ProposalNamespace( - methods: ["personal_sign", "eth_sendTransaction"], - events: ["chainChanged"] - ), - "eip155:2": ProposalNamespace( + "eip155": ProposalNamespace( + chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) ] let optionalNamespaces = [ "eip155": ProposalNamespace( - chains: [Blockchain("eip155:3")!], - methods: ["personal_sign", "eth_sendTransaction"], - events: ["chainChanged"] - ), - "eip155:4": ProposalNamespace( + chains: [Blockchain("eip155:3")!, Blockchain("eip155:4")!], methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -213,11 +204,8 @@ final class AutoNamespacesValidationTests: XCTestCase { Account(blockchain: Blockchain("eip155:2")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")! ] let requiredNamespaces = [ - "eip155:1": ProposalNamespace( - methods: ["personal_sign", "eth_sendTransaction"], - events: ["chainChanged"] - ), - "eip155:2": ProposalNamespace( + "eip155": ProposalNamespace( + chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -260,11 +248,8 @@ final class AutoNamespacesValidationTests: XCTestCase { Account(blockchain: Blockchain("eip155:4")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")! ] let requiredNamespaces = [ - "eip155:1": ProposalNamespace( - methods: ["personal_sign", "eth_sendTransaction"], - events: ["chainChanged"] - ), - "eip155:2": ProposalNamespace( + "eip155": ProposalNamespace( + chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -306,11 +291,8 @@ final class AutoNamespacesValidationTests: XCTestCase { Account(blockchain: Blockchain("eip155:2")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")! ] let requiredNamespaces = [ - "eip155:1": ProposalNamespace( - methods: ["personal_sign", "eth_sendTransaction"], - events: ["chainChanged"] - ), - "eip155:2": ProposalNamespace( + "eip155": ProposalNamespace( + chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -348,11 +330,8 @@ final class AutoNamespacesValidationTests: XCTestCase { Account(blockchain: Blockchain("eip155:2")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")! ] let requiredNamespaces = [ - "eip155:1": ProposalNamespace( - methods: ["personal_sign", "eth_sendTransaction"], - events: ["chainChanged"] - ), - "eip155:2": ProposalNamespace( + "eip155": ProposalNamespace( + chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -391,11 +370,8 @@ final class AutoNamespacesValidationTests: XCTestCase { Account(blockchain: Blockchain("eip155:4")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")! ] let requiredNamespaces = [ - "eip155:1": ProposalNamespace( - methods: ["personal_sign", "eth_sendTransaction"], - events: ["chainChanged"] - ), - "eip155:2": ProposalNamespace( + "eip155": ProposalNamespace( + chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -652,14 +628,10 @@ final class AutoNamespacesValidationTests: XCTestCase { Account(blockchain: Blockchain("eip155:2")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")! ] let requiredNamespaces = [ - "eip155:1": ProposalNamespace( - methods: ["personal_sign", "eth_sendTransaction"], - events: ["chainChanged"] - ), - "eip155:2": ProposalNamespace( + "eip155": ProposalNamespace( + chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], methods: ["personal_sign", "eth_sendTransaction"], - events: ["chainChanged"] - ) + events: ["chainChanged", "accountsChanged"]) ] let optionalNamespaces = [ "eip155": ProposalNamespace( From 591b5d0dbabbde7c875ba21be91d2c5e3c736189 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 18 Mar 2024 11:09:29 +0100 Subject: [PATCH 04/11] accounts as array --- .../Services/SessionNamespaceBuilder.swift | 2 +- Sources/WalletConnectSign/Namespace.swift | 20 ++++----- .../AutoNamespacesValidationTests.swift | 44 +++++++++---------- .../SessionNamespaceBuilderTests.swift | 8 ++-- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/Sources/WalletConnectSign/Auth/Services/SessionNamespaceBuilder.swift b/Sources/WalletConnectSign/Auth/Services/SessionNamespaceBuilder.swift index 967715cbb..ddb897788 100644 --- a/Sources/WalletConnectSign/Auth/Services/SessionNamespaceBuilder.swift +++ b/Sources/WalletConnectSign/Auth/Services/SessionNamespaceBuilder.swift @@ -34,7 +34,7 @@ class SessionNamespaceBuilder { } let accounts = cacaos.compactMap { try? DIDPKH(did: $0.p.iss).account } - let accountsSet = Set(accounts) + let accountsSet = accounts let methods = firstRecapResource.methods let chains = firstRecapResource.chains let events: Set = ["chainChanged", "accountsChanged"] diff --git a/Sources/WalletConnectSign/Namespace.swift b/Sources/WalletConnectSign/Namespace.swift index 7e439a03d..9b115d436 100644 --- a/Sources/WalletConnectSign/Namespace.swift +++ b/Sources/WalletConnectSign/Namespace.swift @@ -37,18 +37,18 @@ public struct ProposalNamespace: Equatable, Codable { public struct SessionNamespace: Equatable, Codable { public var chains: [Blockchain]? - public var accounts: Set + public var accounts: [Account] public var methods: Set public var events: Set - public init(chains: [Blockchain]? = nil, accounts: Set, methods: Set, events: Set) { + public init(chains: [Blockchain]? = nil, accounts: [Account], methods: Set, events: Set) { self.chains = chains self.accounts = accounts self.methods = methods self.events = events } - static func accountsAreCompliant(_ accounts: Set, toChains chains: [Blockchain]) -> Bool { + static func accountsAreCompliant(_ accounts: [Account], toChains chains: [Blockchain]) -> Bool { for chain in chains { guard accounts.contains(where: { $0.blockchain == chain }) else { return false @@ -203,7 +203,7 @@ public enum AutoNamespaces { let sessionNamespace = SessionNamespace( chains: sessionChains, - accounts: Set(accounts).filter { sessionChains.contains($0.blockchain) }, + accounts: accounts.filter { sessionChains.contains($0.blockchain) }, methods: sessionMethods, events: sessionEvents ) @@ -213,7 +213,7 @@ public enum AutoNamespaces { } else { let unionChains = (sessionNamespaces[caip2Namespace]?.chains ?? []).orderedUnion(sessionNamespace.chains ?? []) sessionNamespaces[caip2Namespace]?.chains = unionChains - let unionAccounts = sessionNamespaces[caip2Namespace]?.accounts.union(sessionNamespace.accounts) + let unionAccounts = sessionNamespaces[caip2Namespace]?.accounts.orderedUnion(sessionNamespace.accounts) sessionNamespaces[caip2Namespace]?.accounts = unionAccounts ?? [] let unionMethods = sessionNamespaces[caip2Namespace]?.methods.union(sessionNamespace.methods) sessionNamespaces[caip2Namespace]?.methods = unionMethods ?? [] @@ -256,7 +256,7 @@ public enum AutoNamespaces { } else { let unionChains = (sessionNamespaces[network]?.chains ?? []).orderedUnion(sessionNamespace.chains ?? []) sessionNamespaces[network]?.chains = unionChains - let unionAccounts = sessionNamespaces[network]?.accounts.union(sessionNamespace.accounts) + let unionAccounts = sessionNamespaces[network]?.accounts.orderedUnion(sessionNamespace.accounts) sessionNamespaces[network]?.accounts = unionAccounts ?? [] let unionMethods = sessionNamespaces[network]?.methods.union(sessionNamespace.methods) sessionNamespaces[network]?.methods = unionMethods ?? [] @@ -288,7 +288,7 @@ public enum AutoNamespaces { let sessionNamespace = SessionNamespace( chains: sessionChains, - accounts: Set(accounts).filter { sessionChains.contains($0.blockchain) }, + accounts: accounts.filter { sessionChains.contains($0.blockchain) }, methods: sessionMethods, events: sessionEvents ) @@ -301,7 +301,7 @@ public enum AutoNamespaces { print("sessionNamespace.chains \(sessionNamespace.chains)") print("union chains: \(unionChains)") sessionNamespaces[caip2Namespace]?.chains = unionChains - let unionAccounts = sessionNamespaces[caip2Namespace]?.accounts.union(sessionNamespace.accounts) + let unionAccounts = sessionNamespaces[caip2Namespace]?.accounts.orderedUnion(sessionNamespace.accounts) sessionNamespaces[caip2Namespace]?.accounts = unionAccounts ?? [] let unionMethods = sessionNamespaces[caip2Namespace]?.methods.union(sessionNamespace.methods) sessionNamespaces[caip2Namespace]?.methods = unionMethods ?? [] @@ -328,7 +328,7 @@ public enum AutoNamespaces { let sessionNamespace = SessionNamespace( chains: [Blockchain(namespace: network, reference: chain)!], - accounts: Set(accounts).filter { $0.blockchain == Blockchain(namespace: network, reference: chain)! }, + accounts: accounts.filter { $0.blockchain == Blockchain(namespace: network, reference: chain)! }, methods: sessionMethods, events: sessionEvents ) @@ -338,7 +338,7 @@ public enum AutoNamespaces { } else { let unionChains = (sessionNamespaces[network]?.chains ?? []).orderedUnion(sessionNamespace.chains ?? []) sessionNamespaces[network]?.chains = unionChains - let unionAccounts = sessionNamespaces[network]?.accounts.union(sessionNamespace.accounts) + let unionAccounts = sessionNamespaces[network]?.accounts.orderedUnion(sessionNamespace.accounts) sessionNamespaces[network]?.accounts = unionAccounts ?? [] let unionMethods = sessionNamespaces[network]?.methods.union(sessionNamespace.methods) sessionNamespaces[network]?.methods = unionMethods ?? [] diff --git a/Tests/WalletConnectSignTests/AutoNamespacesValidationTests.swift b/Tests/WalletConnectSignTests/AutoNamespacesValidationTests.swift index 618580e58..d9b0f4acd 100644 --- a/Tests/WalletConnectSignTests/AutoNamespacesValidationTests.swift +++ b/Tests/WalletConnectSignTests/AutoNamespacesValidationTests.swift @@ -30,7 +30,7 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!], - accounts: Set(accounts), + accounts: accounts, methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -70,7 +70,7 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], - accounts: Set(accounts), + accounts: accounts, methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -108,7 +108,7 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], - accounts: Set(accounts), + accounts: accounts, methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -149,7 +149,7 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!, Blockchain("eip155:3")!], - accounts: Set(accounts), + accounts: accounts, methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -190,7 +190,7 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!, Blockchain("eip155:3")!, Blockchain("eip155:4")!], - accounts: Set(accounts), + accounts: accounts, methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -233,7 +233,7 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], - accounts: Set(accounts), + accounts: accounts, methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -277,7 +277,7 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!, Blockchain("eip155:4")!], - accounts: Set(accounts), + accounts: accounts, methods: ["personal_sign", "eth_sendTransaction"], events: ["chainChanged"] ) @@ -316,7 +316,7 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], - accounts: Set(accounts), + accounts: accounts, methods: ["personal_sign", "eth_sendTransaction", "eth_signTransaction"], events: ["chainChanged"] ) @@ -355,7 +355,7 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], - accounts: Set(accounts), + accounts: accounts, methods: ["personal_sign", "eth_sendTransaction", "eth_signTransaction"], events: ["chainChanged", "accountsChanged"] ) @@ -443,10 +443,10 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!, Blockchain("eip155:2")!], - accounts: Set([ + accounts: [ Account(blockchain: Blockchain("eip155:1")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")!, Account(blockchain: Blockchain("eip155:2")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")! - ]), + ], methods: ["personal_sign", "eth_sendTransaction", "eth_signTransaction"], events: ["chainChanged", "accountsChanged"] ), @@ -682,9 +682,9 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!], - accounts: Set([ + accounts: [ Account(blockchain: Blockchain("eip155:1")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")! - ]), + ], methods: ["eth_signTypedData_v4", "eth_signTransaction", "eth_signTypedData", "eth_sign", "personal_sign", "eth_sendTransaction"], events: ["chainChanged", "accountsChanged"] ) @@ -722,9 +722,9 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!], - accounts: Set([ + accounts: [ Account(blockchain: Blockchain("eip155:1")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")! - ]), + ], methods: ["eth_signTypedData_v4", "eth_signTransaction", "eth_signTypedData", "eth_sign", "personal_sign", "eth_sendTransaction"], events: ["chainChanged", "accountsChanged"] ) @@ -762,9 +762,9 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!], - accounts: Set([ + accounts: [ Account(blockchain: Blockchain("eip155:1")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")! - ]), + ], methods: ["eth_signTypedData_v4", "eth_signTransaction", "eth_signTypedData", "eth_sign", "personal_sign", "eth_sendTransaction"], events: [] ) @@ -807,17 +807,17 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!], - accounts: Set([ + accounts: [ Account(blockchain: Blockchain("eip155:1")!, address: "0x57f48fAFeC1d76B27e3f29b8d277b6218CDE6092")! - ]), + ], methods: ["eth_signTypedData_v4", "eth_signTransaction", "eth_signTypedData", "eth_sign", "personal_sign", "eth_sendTransaction"], events: ["chainChanged", "accountsChanged"] ), "solana": SessionNamespace( chains: [Blockchain("solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp")!], - accounts: Set([ + accounts: [ Account(blockchain: Blockchain("solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp")!, address: "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp")!, - ]), + ], methods: ["solana_signMessage"], events: [] ) @@ -928,7 +928,7 @@ final class AutoNamespacesValidationTests: XCTestCase { let expectedNamespaces: [String: SessionNamespace] = [ "eip155": SessionNamespace( chains: [Blockchain("eip155:1")!], - accounts: Set(accounts), + accounts: accounts, methods: ["personal_sign", "eth_sendTransaction", "eth_sign"], events: ["chainChanged", "accountsChanged"] ) diff --git a/Tests/WalletConnectSignTests/SessionNamespaceBuilderTests.swift b/Tests/WalletConnectSignTests/SessionNamespaceBuilderTests.swift index 116af8abe..21928efc4 100644 --- a/Tests/WalletConnectSignTests/SessionNamespaceBuilderTests.swift +++ b/Tests/WalletConnectSignTests/SessionNamespaceBuilderTests.swift @@ -41,10 +41,10 @@ class SessionNamespaceBuilderTests: XCTestCase { func testBuildSessionNamespaces_ValidCacaos_ReturnsExpectedNamespace() { let expectedSessionNamespace = SessionNamespace( chains: [Blockchain("eip155:1")!, Blockchain("eip155:137")!], - accounts: Set([ + accounts: [ Account("eip155:1:0x000a10343Bcdebe21283c7172d67a9a113E819C5")!, Account("eip155:137:0x000a10343Bcdebe21283c7172d67a9a113E819C5")! - ]), + ], methods: Set(["personal_sign", "eth_signTypedData", "eth_sign"]), events: Set(["chainChanged", "accountsChanged"]) ) @@ -68,9 +68,9 @@ class SessionNamespaceBuilderTests: XCTestCase { func testMutlipleRecapsInCacaoWhereOnlyOneIsSessionRecap() { let expectedSessionNamespace = SessionNamespace( chains: [Blockchain("eip155:1")!, Blockchain("eip155:137")!], - accounts: Set([ + accounts: [ Account("eip155:1:0x000a10343Bcdebe21283c7172d67a9a113E819C5")! - ]), + ], methods: ["personal_sign", "eth_signTypedData", "eth_sign"], events: ["chainChanged", "accountsChanged"] ) From 6e40168444de8ba0e42123bd8f0cc6cc07d9a205 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 18 Mar 2024 11:17:08 +0100 Subject: [PATCH 05/11] savepoint --- Sources/WalletConnectSign/Namespace.swift | 24 ++--------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/Sources/WalletConnectSign/Namespace.swift b/Sources/WalletConnectSign/Namespace.swift index 9b115d436..e9889b2dd 100644 --- a/Sources/WalletConnectSign/Namespace.swift +++ b/Sources/WalletConnectSign/Namespace.swift @@ -182,7 +182,7 @@ public enum AutoNamespaces { if let proposalChains = proposalNamespace.chains { let sessionChains = proposalChains - guard !sessionChains.isEmpty && proposalChains.isSubset(of: chains) else { + guard !sessionChains.isEmpty && Set(proposalChains).isSubset(of: chains) else { throw AutoNamespacesError.requiredChainsNotSatisfied } @@ -250,7 +250,6 @@ public enum AutoNamespaces { methods: sessionMethods, events: sessionEvents ) - print("$0 \($0)") if sessionNamespaces[network] == nil { sessionNamespaces[network] = sessionNamespace } else { @@ -273,8 +272,6 @@ public enum AutoNamespaces { if let proposalChains = proposalNamespace.chains { let sessionChains = proposalChains.intersection(chains) - print("session chains: \(sessionChains)") - print("proposal chains: \(proposalChains)") guard !sessionChains.isEmpty else { return } @@ -297,9 +294,6 @@ public enum AutoNamespaces { sessionNamespaces[caip2Namespace] = sessionNamespace } else { let unionChains = (sessionNamespaces[caip2Namespace]?.chains ?? []).orderedUnion(sessionNamespace.chains ?? []) - print("caip2namespace chains: \(sessionNamespaces[caip2Namespace]?.chains)") - print("sessionNamespace.chains \(sessionNamespace.chains)") - print("union chains: \(unionChains)") sessionNamespaces[caip2Namespace]?.chains = unionChains let unionAccounts = sessionNamespaces[caip2Namespace]?.accounts.orderedUnion(sessionNamespace.accounts) sessionNamespaces[caip2Namespace]?.accounts = unionAccounts ?? [] @@ -317,8 +311,6 @@ public enum AutoNamespaces { return } - print("session chains: \(sessionChains)") - let sessionMethods = Set(proposalNamespace.methods).intersection(Set(methods)) guard !sessionMethods.isEmpty else { return @@ -355,19 +347,7 @@ public enum AutoNamespaces { } -extension Array where Element: Hashable { - - // Checks if the current array is a subset of the provided array. - func isSubset(of other: [Element]) -> Bool { - let otherSet = Set(other) - for element in self { - if !otherSet.contains(element) { - return false - } - } - return true - } - +fileprivate extension Array where Element: Hashable { // Returns the intersection of the current array and the provided array. // Elements are returned in the order they appear in the current array. func intersection(_ other: [Element]) -> [Element] { From 31333adc9a5f5eca61a2eb16b98072009c15502b Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 18 Mar 2024 11:33:56 +0100 Subject: [PATCH 06/11] rename auth errors --- Sources/Auth/AuthClient.swift | 4 ++-- Sources/Auth/Services/App/AppRespondSubscriber.swift | 4 ++-- Sources/Auth/Services/Wallet/WalletErrorResponder.swift | 2 +- Sources/Auth/Services/Wallet/WalletRespondService.swift | 2 +- Sources/Auth/Types/Errors/AuthError.swift | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Sources/Auth/AuthClient.swift b/Sources/Auth/AuthClient.swift index d1e34537d..8efd60dad 100644 --- a/Sources/Auth/AuthClient.swift +++ b/Sources/Auth/AuthClient.swift @@ -25,7 +25,7 @@ public class AuthClient: AuthClientProtocol { /// /// 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> { + public var authResponsePublisher: AnyPublisher<(id: RPCID, result: Result), Never> { authResponsePublisherSubject.eraseToAnyPublisher() } @@ -40,7 +40,7 @@ public class AuthClient: AuthClientProtocol { private let pairingRegisterer: PairingRegisterer - private var authResponsePublisherSubject = PassthroughSubject<(id: RPCID, result: Result), Never>() + 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 diff --git a/Sources/Auth/Services/App/AppRespondSubscriber.swift b/Sources/Auth/Services/App/AppRespondSubscriber.swift index 25c7917e0..fe1d07287 100644 --- a/Sources/Auth/Services/App/AppRespondSubscriber.swift +++ b/Sources/Auth/Services/App/AppRespondSubscriber.swift @@ -10,7 +10,7 @@ class AppRespondSubscriber { private let pairingRegisterer: PairingRegisterer private var publishers = [AnyCancellable]() - var onResponse: ((_ id: RPCID, _ result: Result) -> Void)? + var onResponse: ((_ id: RPCID, _ result: Result) -> Void)? init(networkingInteractor: NetworkInteracting, logger: ConsoleLogging, @@ -30,7 +30,7 @@ class AppRespondSubscriber { private func subscribeForResponse() { networkingInteractor.responseErrorSubscription(on: AuthRequestProtocolMethod()) .sink { [unowned self] (payload: ResponseSubscriptionErrorPayload) in - guard let error = AuthError(code: payload.error.code) else { return } + guard let error = AuthErrors(code: payload.error.code) else { return } onResponse?(payload.id, .failure(error)) }.store(in: &publishers) diff --git a/Sources/Auth/Services/Wallet/WalletErrorResponder.swift b/Sources/Auth/Services/Wallet/WalletErrorResponder.swift index 597185480..f6047f016 100644 --- a/Sources/Auth/Services/Wallet/WalletErrorResponder.swift +++ b/Sources/Auth/Services/Wallet/WalletErrorResponder.swift @@ -21,7 +21,7 @@ actor WalletErrorResponder { self.rpcHistory = rpcHistory } - func respondError(_ error: AuthError, requestId: RPCID) async throws { + func respondError(_ error: AuthErrors, requestId: RPCID) async throws { let authRequestParams = try getAuthRequestParams(requestId: requestId) let (topic, keys) = try generateAgreementKeys(requestParams: authRequestParams) diff --git a/Sources/Auth/Services/Wallet/WalletRespondService.swift b/Sources/Auth/Services/Wallet/WalletRespondService.swift index a06a16027..3735ce663 100644 --- a/Sources/Auth/Services/Wallet/WalletRespondService.swift +++ b/Sources/Auth/Services/Wallet/WalletRespondService.swift @@ -53,7 +53,7 @@ actor WalletRespondService { } func respondError(requestId: RPCID) async throws { - try await walletErrorResponder.respondError(AuthError.userRejeted, requestId: requestId) + try await walletErrorResponder.respondError(AuthErrors.userRejeted, requestId: requestId) verifyContextStore.delete(forKey: requestId.string) } diff --git a/Sources/Auth/Types/Errors/AuthError.swift b/Sources/Auth/Types/Errors/AuthError.swift index cf4accb16..9cfda6bd1 100644 --- a/Sources/Auth/Types/Errors/AuthError.swift +++ b/Sources/Auth/Types/Errors/AuthError.swift @@ -1,7 +1,7 @@ import Foundation /// Authentication error -public enum AuthError: Codable, Equatable, Error { +public enum AuthErrors: Codable, Equatable, Error { case methodUnsupported case userDisconnected case userRejeted @@ -11,7 +11,7 @@ public enum AuthError: Codable, Equatable, Error { case signatureVerificationFailed } -extension AuthError: Reason { +extension AuthErrors: Reason { init?(code: Int) { switch code { From e601c4c2bc47e02571e6900f1bfde2d42372ef42 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 18 Mar 2024 13:23:25 +0100 Subject: [PATCH 07/11] savepoint --- Sources/WalletConnectModal/WalletConnectModal.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WalletConnectModal/WalletConnectModal.swift b/Sources/WalletConnectModal/WalletConnectModal.swift index c74e5c884..3bdafbea8 100644 --- a/Sources/WalletConnectModal/WalletConnectModal.swift +++ b/Sources/WalletConnectModal/WalletConnectModal.swift @@ -153,7 +153,7 @@ public struct SessionParams { public static let `default`: Self = { let methods: Set = ["eth_sendTransaction", "personal_sign", "eth_signTypedData"] let events: Set = ["chainChanged", "accountsChanged"] - let blockchains: Set = [Blockchain("eip155:1")!] + let blockchains = [Blockchain("eip155:1")!] let namespaces: [String: ProposalNamespace] = [ "eip155": ProposalNamespace( chains: blockchains, From ee49c5b1cbc2b7626c23c6a34558c5fcd1bdd44c Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 18 Mar 2024 14:52:09 +0100 Subject: [PATCH 08/11] resolve w3m dependency issues --- Example/DApp/SceneDelegate.swift | 1 + Example/ExampleApp.xcodeproj/project.pbxproj | 66 +++++++++---------- .../xcshareddata/swiftpm/Package.resolved | 4 +- 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/Example/DApp/SceneDelegate.swift b/Example/DApp/SceneDelegate.swift index 9b23a6e93..c8abceae9 100644 --- a/Example/DApp/SceneDelegate.swift +++ b/Example/DApp/SceneDelegate.swift @@ -31,6 +31,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { Web3Modal.configure( projectId: InputConfig.projectId, metadata: metadata, + crypto: DefaultCryptoProvider(), customWallets: [ .init( id: "swift-sample", diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index 9f5e8dba5..ec7366b09 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -8,9 +8,6 @@ /* Begin PBXBuildFile section */ 767DC83528997F8E00080FA9 /* EthSendTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 767DC83428997F8E00080FA9 /* EthSendTransaction.swift */; }; - 842B1D132B988BC5007F1EF8 /* Web3Modal in Frameworks */ = {isa = PBXBuildFile; productRef = 842B1D122B988BC5007F1EF8 /* Web3Modal */; }; - 842B1D152B988BC5007F1EF8 /* Web3ModalUI in Frameworks */ = {isa = PBXBuildFile; productRef = 842B1D142B988BC5007F1EF8 /* Web3ModalUI */; }; - 842B1D172B988BF0007F1EF8 /* Web3ModalUI in Frameworks */ = {isa = PBXBuildFile; productRef = 842B1D162B988BF0007F1EF8 /* Web3ModalUI */; }; 84310D05298BC980000C15B6 /* MainInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84310D04298BC980000C15B6 /* MainInteractor.swift */; }; 8439CB89293F658E00F2F2E2 /* PushMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8439CB88293F658E00F2F2E2 /* PushMessage.swift */; }; 844749F629B9E5B9005F520B /* RelayClientEndToEndTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844749F529B9E5B9005F520B /* RelayClientEndToEndTests.swift */; }; @@ -58,6 +55,9 @@ 84DB38F32983CDAE00BFEE37 /* PushRegisterer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DB38F22983CDAE00BFEE37 /* PushRegisterer.swift */; }; 84E6B84A29787A8000428BAF /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E6B84929787A8000428BAF /* NotificationService.swift */; }; 84E6B84E29787A8000428BAF /* PNDecryptionService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 84E6B84729787A8000428BAF /* PNDecryptionService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 84F391FA2BA87CEB00FDC20A /* Web3ModalUI in Frameworks */ = {isa = PBXBuildFile; productRef = 84F391F92BA87CEB00FDC20A /* Web3ModalUI */; }; + 84F3EFC52BA87C09005FCFAE /* Web3Modal in Frameworks */ = {isa = PBXBuildFile; productRef = 84F3EFC42BA87C09005FCFAE /* Web3Modal */; }; + 84F3EFC72BA87C09005FCFAE /* Web3ModalUI in Frameworks */ = {isa = PBXBuildFile; productRef = 84F3EFC62BA87C09005FCFAE /* Web3ModalUI */; }; 84FE684628ACDB4700C893FF /* RequestParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FE684528ACDB4700C893FF /* RequestParams.swift */; }; A507BE1A29E8032E0038EF70 /* EIP55Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A507BE1929E8032E0038EF70 /* EIP55Tests.swift */; }; A50B6A362B06683800162B01 /* InputConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE25D293F56D6004840D1 /* InputConfig.swift */; }; @@ -692,13 +692,13 @@ buildActionMask = 2147483647; files = ( 8448F1D427E4726F0000B866 /* WalletConnect in Frameworks */, - 842B1D132B988BC5007F1EF8 /* Web3Modal in Frameworks */, + 84F3EFC52BA87C09005FCFAE /* Web3Modal in Frameworks */, C5BE01DF2AF692D80064FC88 /* WalletConnectRouter in Frameworks */, A5B6C0F12A6EAB0800927332 /* WalletConnectNotify in Frameworks */, A54195A52934E83F0035AD19 /* Web3 in Frameworks */, 8487A9442A836C2A0003D5AF /* Sentry in Frameworks */, A5D85228286333E300DAF5C3 /* Starscream in Frameworks */, - 842B1D152B988BC5007F1EF8 /* Web3ModalUI in Frameworks */, + 84F3EFC72BA87C09005FCFAE /* Web3ModalUI in Frameworks */, 8486EDD32B4F2EA6008E53C3 /* SwiftMessages in Frameworks */, 84943C7B2A9BA206007EBAC2 /* Mixpanel in Frameworks */, A573C53929EC365000E3CBFD /* HDWalletKit in Frameworks */, @@ -764,7 +764,7 @@ 8487A9462A836C3F0003D5AF /* Sentry in Frameworks */, C55D349929630D440004314A /* Web3Wallet in Frameworks */, C56EE255293F569A004840D1 /* Starscream in Frameworks */, - 842B1D172B988BF0007F1EF8 /* Web3ModalUI in Frameworks */, + 84F391FA2BA87CEB00FDC20A /* Web3ModalUI in Frameworks */, 84AEC2542B4D43CD00E27A5B /* SwiftMessages in Frameworks */, A5B6C0F52A6EAB2800927332 /* WalletConnectNotify in Frameworks */, C54C24902AEB1B5600DA4BF6 /* WalletConnectRouter in Frameworks */, @@ -1937,8 +1937,8 @@ C5BE01DE2AF692D80064FC88 /* WalletConnectRouter */, CFDB50712B2869AA00A0CBC2 /* WalletConnectModal */, 8486EDD22B4F2EA6008E53C3 /* SwiftMessages */, - 842B1D122B988BC5007F1EF8 /* Web3Modal */, - 842B1D142B988BC5007F1EF8 /* Web3ModalUI */, + 84F3EFC42BA87C09005FCFAE /* Web3Modal */, + 84F3EFC62BA87C09005FCFAE /* Web3ModalUI */, ); productName = DApp; productReference = 84CE641C27981DED00142511 /* DApp.app */; @@ -2065,7 +2065,7 @@ A59D25ED2AB3672700D7EA3A /* AsyncButton */, C54C248F2AEB1B5600DA4BF6 /* WalletConnectRouter */, 84AEC2532B4D43CD00E27A5B /* SwiftMessages */, - 842B1D162B988BF0007F1EF8 /* Web3ModalUI */, + 84F391F92BA87CEB00FDC20A /* Web3ModalUI */, ); productName = ChatWallet; productReference = C56EE21B293F55ED004840D1 /* WalletApp.app */; @@ -2144,7 +2144,7 @@ 8487A9422A836C2A0003D5AF /* XCRemoteSwiftPackageReference "sentry-cocoa" */, 84943C792A9BA206007EBAC2 /* XCRemoteSwiftPackageReference "mixpanel-swift" */, 84AEC2522B4D43CD00E27A5B /* XCRemoteSwiftPackageReference "SwiftMessages" */, - 842B1D112B987D40007F1EF8 /* XCRemoteSwiftPackageReference "web3modal-swift" */, + 84F3EFC32BA87C09005FCFAE /* XCRemoteSwiftPackageReference "web3modal-swift" */, ); productRefGroup = 764E1D3D26F8D3FC00A1FB15 /* Products */; projectDirPath = ""; @@ -3243,14 +3243,6 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - 842B1D112B987D40007F1EF8 /* XCRemoteSwiftPackageReference "web3modal-swift" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/WalletConnect/web3modal-swift"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 1.0.0; - }; - }; 8487A9422A836C2A0003D5AF /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/getsentry/sentry-cocoa.git"; @@ -3275,6 +3267,14 @@ minimumVersion = 9.0.9; }; }; + 84F3EFC32BA87C09005FCFAE /* XCRemoteSwiftPackageReference "web3modal-swift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/WalletConnect/web3modal-swift"; + requirement = { + kind = revision; + revision = c73ce390bc249af155b7320346b7045e53b89866; + }; + }; A5434021291E6A270068F706 /* XCRemoteSwiftPackageReference "solana-swift" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/flypaper0/solana-swift"; @@ -3318,21 +3318,6 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - 842B1D122B988BC5007F1EF8 /* Web3Modal */ = { - isa = XCSwiftPackageProductDependency; - package = 842B1D112B987D40007F1EF8 /* XCRemoteSwiftPackageReference "web3modal-swift" */; - productName = Web3Modal; - }; - 842B1D142B988BC5007F1EF8 /* Web3ModalUI */ = { - isa = XCSwiftPackageProductDependency; - package = 842B1D112B987D40007F1EF8 /* XCRemoteSwiftPackageReference "web3modal-swift" */; - productName = Web3ModalUI; - }; - 842B1D162B988BF0007F1EF8 /* Web3ModalUI */ = { - isa = XCSwiftPackageProductDependency; - package = 842B1D112B987D40007F1EF8 /* XCRemoteSwiftPackageReference "web3modal-swift" */; - productName = Web3ModalUI; - }; 844749FC29B9E6B2005F520B /* WalletConnectNetworking */ = { isa = XCSwiftPackageProductDependency; productName = WalletConnectNetworking; @@ -3380,6 +3365,21 @@ package = 84AEC2522B4D43CD00E27A5B /* XCRemoteSwiftPackageReference "SwiftMessages" */; productName = SwiftMessages; }; + 84F391F92BA87CEB00FDC20A /* Web3ModalUI */ = { + isa = XCSwiftPackageProductDependency; + package = 84F3EFC32BA87C09005FCFAE /* XCRemoteSwiftPackageReference "web3modal-swift" */; + productName = Web3ModalUI; + }; + 84F3EFC42BA87C09005FCFAE /* Web3Modal */ = { + isa = XCSwiftPackageProductDependency; + package = 84F3EFC32BA87C09005FCFAE /* XCRemoteSwiftPackageReference "web3modal-swift" */; + productName = Web3Modal; + }; + 84F3EFC62BA87C09005FCFAE /* Web3ModalUI */ = { + isa = XCSwiftPackageProductDependency; + package = 84F3EFC32BA87C09005FCFAE /* XCRemoteSwiftPackageReference "web3modal-swift" */; + productName = Web3ModalUI; + }; A54195A42934E83F0035AD19 /* Web3 */ = { isa = XCSwiftPackageProductDependency; package = A5AE354528A1A2AC0059AE8A /* XCRemoteSwiftPackageReference "Web3" */; diff --git a/Example/ExampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example/ExampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 9c85155e8..84752135e 100644 --- a/Example/ExampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Example/ExampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -186,8 +186,8 @@ "repositoryURL": "https://github.com/WalletConnect/web3modal-swift", "state": { "branch": null, - "revision": "4f2f4ca6497b7335a53c7b5c4fb3db554e0351ba", - "version": "1.3.0" + "revision": "c73ce390bc249af155b7320346b7045e53b89866", + "version": null } } ] From f5499fd02a4871fcd8a7e109cd626dd0524b9131 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 18 Mar 2024 14:56:19 +0100 Subject: [PATCH 09/11] fix integration tests build --- Example/IntegrationTests/Stubs/Stubs.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/IntegrationTests/Stubs/Stubs.swift b/Example/IntegrationTests/Stubs/Stubs.swift index 7d8cb9172..ac61de16c 100644 --- a/Example/IntegrationTests/Stubs/Stubs.swift +++ b/Example/IntegrationTests/Stubs/Stubs.swift @@ -1,7 +1,7 @@ import WalletConnectSign extension ProposalNamespace { - static func stubRequired(chains: Set = [Blockchain("eip155:1")!]) -> [String: ProposalNamespace] { + static func stubRequired(chains: [Blockchain] = [Blockchain("eip155:1")!]) -> [String: ProposalNamespace] { return [ "eip155": ProposalNamespace( chains: chains, @@ -15,7 +15,7 @@ extension SessionNamespace { static func make(toRespond namespaces: [String: ProposalNamespace]) -> [String: SessionNamespace] { return namespaces.mapValues { proposalNamespace in SessionNamespace( - accounts: Set(proposalNamespace.chains!.map { Account(blockchain: $0, address: "0x00")! }), + accounts: proposalNamespace.chains!.map { Account(blockchain: $0, address: "0x00")! }, methods: proposalNamespace.methods, events: proposalNamespace.events ) From 83d967399fa65144e394b2d8100272403da76099 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 18 Mar 2024 15:48:39 +0100 Subject: [PATCH 10/11] remove duplicates --- Sources/WalletConnectSign/Namespace.swift | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Sources/WalletConnectSign/Namespace.swift b/Sources/WalletConnectSign/Namespace.swift index e9889b2dd..a20f02fae 100644 --- a/Sources/WalletConnectSign/Namespace.swift +++ b/Sources/WalletConnectSign/Namespace.swift @@ -175,6 +175,8 @@ public enum AutoNamespaces { ) throws -> [String: SessionNamespace] { var sessionNamespaces = [String: SessionNamespace]() + let chains = chains.removeDuplicates() + let accounts = accounts.removeDuplicates() try sessionProposal.requiredNamespaces.forEach { let caip2Namespace = $0.key let proposalNamespace = $0.value @@ -365,4 +367,19 @@ fileprivate extension Array where Element: Hashable { } return combined } + + func removeDuplicates() -> [Element] { + var uniqueElements = [Element]() + var seenElements = Set() + + for element in self { + if !seenElements.contains(element) { + uniqueElements.append(element) + seenElements.insert(element) + } + } + + return uniqueElements + } + } From 4bf498e9543028a0a9d6d7b958bb816d42f18de1 Mon Sep 17 00:00:00 2001 From: llbartekll Date: Tue, 19 Mar 2024 06:40:19 +0000 Subject: [PATCH 11/11] Set User Agent --- Sources/WalletConnectRelay/PackageConfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WalletConnectRelay/PackageConfig.json b/Sources/WalletConnectRelay/PackageConfig.json index 77e713b60..8c3caff7b 100644 --- a/Sources/WalletConnectRelay/PackageConfig.json +++ b/Sources/WalletConnectRelay/PackageConfig.json @@ -1 +1 @@ -{"version": "1.16.0"} +{"version": "1.17.0"}