diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8ff4a9a95..a71b4ce7e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -28,7 +28,7 @@ jobs:
- name: Setup Xcode Version
uses: maxim-lobanov/setup-xcode@v1
with:
- xcode-version: '13.4.1'
+ xcode-version: 14.1
- uses: actions/cache@v2
with:
diff --git a/.github/workflows/set-user-agent.yml b/.github/workflows/set-user-agent.yml
index 1919088d5..a08089f8a 100644
--- a/.github/workflows/set-user-agent.yml
+++ b/.github/workflows/set-user-agent.yml
@@ -17,6 +17,9 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
+ with:
+ token: ${{ secrets.GH_TOKEN }}
+
- name: Set User Agent
shell: bash
run: ./.github/scripts/set-user-agent.sh
diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/WalletConnectVerify.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/WalletConnectVerify.xcscheme
new file mode 100644
index 000000000..b5ef0e1c9
--- /dev/null
+++ b/.swiftpm/xcode/xcshareddata/xcschemes/WalletConnectVerify.xcscheme
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Example/DApp/SceneDelegate.swift b/Example/DApp/SceneDelegate.swift
index afeca0dce..c1ea35937 100644
--- a/Example/DApp/SceneDelegate.swift
+++ b/Example/DApp/SceneDelegate.swift
@@ -1,16 +1,8 @@
import UIKit
-import Starscream
+import Auth
import WalletConnectRelay
import WalletConnectNetworking
-extension WebSocket: WebSocketConnecting { }
-
-struct SocketFactory: WebSocketFactory {
- func create(with url: URL) -> WebSocketConnecting {
- return WebSocket(url: url)
- }
-}
-
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
@@ -19,7 +11,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
private let authCoordinator = AuthCoordinator()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
- Networking.configure(projectId: InputConfig.projectId, socketFactory: SocketFactory())
+ Networking.configure(projectId: InputConfig.projectId, socketFactory: DefaultSocketFactory())
+ Auth.configure(signerFactory: DefaultSignerFactory())
setupWindow(scene: scene)
}
diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj
index fc6357d2b..6e5062005 100644
--- a/Example/ExampleApp.xcodeproj/project.pbxproj
+++ b/Example/ExampleApp.xcodeproj/project.pbxproj
@@ -31,6 +31,7 @@
84494388278D9C1B00CC26BB /* UIAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84494387278D9C1B00CC26BB /* UIAlertController.swift */; };
8460DCFC274F98A10081F94C /* RequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8460DCFB274F98A10081F94C /* RequestViewController.swift */; };
847CF3AF28E3141700F1D760 /* WalletConnectPush in Frameworks */ = {isa = PBXBuildFile; productRef = 847CF3AE28E3141700F1D760 /* WalletConnectPush */; settings = {ATTRIBUTES = (Required, ); }; };
+ 849D7A90292665D3006A2BD4 /* WalletConnectVerify in Frameworks */ = {isa = PBXBuildFile; productRef = 849D7A8F292665D3006A2BD4 /* WalletConnectVerify */; };
84AA01DB28CF0CD7005D48D8 /* XCTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AA01DA28CF0CD7005D48D8 /* XCTest.swift */; };
84CE641F27981DED00142511 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE641E27981DED00142511 /* AppDelegate.swift */; };
84CE642127981DED00142511 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE642027981DED00142511 /* SceneDelegate.swift */; };
@@ -57,6 +58,11 @@
A51AC0D928E436A3001BACF9 /* InputConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51AC0D828E436A3001BACF9 /* InputConfig.swift */; };
A51AC0DD28E43727001BACF9 /* InputConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51AC0DB28E436E6001BACF9 /* InputConfig.swift */; };
A51AC0DF28E4379F001BACF9 /* InputConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51AC0DE28E4379F001BACF9 /* InputConfig.swift */; };
+ A541959E2934BFEF0035AD19 /* CacaoSignerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A541959A2934BFEF0035AD19 /* CacaoSignerTests.swift */; };
+ A541959F2934BFEF0035AD19 /* SignerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A541959B2934BFEF0035AD19 /* SignerTests.swift */; };
+ A54195A02934BFEF0035AD19 /* EIP1271VerifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A541959C2934BFEF0035AD19 /* EIP1271VerifierTests.swift */; };
+ A54195A12934BFEF0035AD19 /* EIP191VerifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A541959D2934BFEF0035AD19 /* EIP191VerifierTests.swift */; };
+ A54195A52934E83F0035AD19 /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = A54195A42934E83F0035AD19 /* Web3 */; };
A5434023291E6A270068F706 /* SolanaSwift in Frameworks */ = {isa = PBXBuildFile; productRef = A5434022291E6A270068F706 /* SolanaSwift */; };
A55CAAB028B92AFF00844382 /* ScanModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55CAAAB28B92AFF00844382 /* ScanModule.swift */; };
A55CAAB128B92AFF00844382 /* ScanPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55CAAAC28B92AFF00844382 /* ScanPresenter.swift */; };
@@ -85,15 +91,14 @@
A5629AE42876E6D200094373 /* ThreadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AE32876E6D200094373 /* ThreadViewModel.swift */; };
A5629AE828772A0100094373 /* InviteViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AE728772A0100094373 /* InviteViewModel.swift */; };
A5629AEA2877F2D600094373 /* WalletConnectChat in Frameworks */ = {isa = PBXBuildFile; productRef = A5629AE92877F2D600094373 /* WalletConnectChat */; };
- A5629AF02877F73000094373 /* SocketFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AEF2877F73000094373 /* SocketFactory.swift */; };
A5629AF22877F75100094373 /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = A5629AF12877F75100094373 /* Starscream */; };
A578FA322873036400AA7720 /* InputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A578FA312873036400AA7720 /* InputView.swift */; };
A578FA35287304A300AA7720 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = A578FA34287304A300AA7720 /* Color.swift */; };
A578FA372873D8EE00AA7720 /* UIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A578FA362873D8EE00AA7720 /* UIColor.swift */; };
A578FA392873FCE000AA7720 /* ChatScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A578FA382873FCE000AA7720 /* ChatScrollView.swift */; };
A578FA3D2874002400AA7720 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A578FA3C2874002400AA7720 /* View.swift */; };
- A57E71A6291CF76400325797 /* EthereumSigner.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57E71A5291CF76400325797 /* EthereumSigner.swift */; };
- A57E71A8291CF8A500325797 /* SolanaSigner.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57E71A7291CF8A500325797 /* SolanaSigner.swift */; };
+ A57E71A6291CF76400325797 /* ETHSigner.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57E71A5291CF76400325797 /* ETHSigner.swift */; };
+ A57E71A8291CF8A500325797 /* SOLSigner.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57E71A7291CF8A500325797 /* SOLSigner.swift */; };
A58E7CEB28729F550082D443 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58E7CEA28729F550082D443 /* AppDelegate.swift */; };
A58E7CED28729F550082D443 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58E7CEC28729F550082D443 /* SceneDelegate.swift */; };
A58E7CF428729F550082D443 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A58E7CF328729F550082D443 /* Assets.xcassets */; };
@@ -120,6 +125,7 @@
A58E7D432872EE320082D443 /* MessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58E7D422872EE320082D443 /* MessageView.swift */; };
A58E7D452872EE570082D443 /* ContentMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58E7D442872EE570082D443 /* ContentMessageView.swift */; };
A58E7D482872EF610082D443 /* MessageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58E7D472872EF610082D443 /* MessageViewModel.swift */; };
+ A59CF4F6292F83D50031A42F /* DefaultSignerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */; };
A59EBEF828B54A2A003EDAAF /* AuthRequestModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59EBEF328B54A2A003EDAAF /* AuthRequestModule.swift */; };
A59EBEF928B54A2A003EDAAF /* AuthRequestPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59EBEF428B54A2A003EDAAF /* AuthRequestPresenter.swift */; };
A59EBEFA28B54A2A003EDAAF /* AuthRequestRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59EBEF528B54A2A003EDAAF /* AuthRequestRouter.swift */; };
@@ -138,6 +144,12 @@
A5A4FC5C283D1F6700BBEC1E /* SessionDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A4FC5B283D1F6700BBEC1E /* SessionDetailViewController.swift */; };
A5A4FC5E283D23CA00BBEC1E /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A4FC5D283D23CA00BBEC1E /* Array.swift */; };
A5A4FC772840C12C00BBEC1E /* RegressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A4FC762840C12C00BBEC1E /* RegressionTests.swift */; };
+ A5A8E47A293A1C9B00FEB97D /* DefaultSocketFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AEF2877F73000094373 /* DefaultSocketFactory.swift */; };
+ A5A8E47B293A1CFE00FEB97D /* DefaultSocketFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AEF2877F73000094373 /* DefaultSocketFactory.swift */; };
+ A5A8E47D293A1CFE00FEB97D /* DefaultSocketFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AEF2877F73000094373 /* DefaultSocketFactory.swift */; };
+ A5A8E47E293A1CFE00FEB97D /* DefaultSignerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */; };
+ A5A8E47F293A1D0000FEB97D /* DefaultSocketFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AEF2877F73000094373 /* DefaultSocketFactory.swift */; };
+ A5A8E480293A1D0000FEB97D /* DefaultSignerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */; };
A5AE354728A1A2AC0059AE8A /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = A5AE354628A1A2AC0059AE8A /* Web3 */; };
A5BB7F9F28B69B7100707FC6 /* SignCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5BB7F9E28B69B7100707FC6 /* SignCoordinator.swift */; };
A5BB7FA128B69F3400707FC6 /* AuthCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5BB7FA028B69F3400707FC6 /* AuthCoordinator.swift */; };
@@ -161,6 +173,7 @@
A5C2022B287EB89A007E3188 /* WelcomeInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5C2022A287EB89A007E3188 /* WelcomeInteractor.swift */; };
A5C2022D287EC3F0007E3188 /* RegisterService.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5C2022C287EC3F0007E3188 /* RegisterService.swift */; };
A5C4DD8728A2DE88006A626D /* WalletConnectRouter in Frameworks */ = {isa = PBXBuildFile; productRef = A5C4DD8628A2DE88006A626D /* WalletConnectRouter */; };
+ A5C8BE85292FE20B006CC85C /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = A5C8BE84292FE20B006CC85C /* Web3 */; };
A5D85226286333D500DAF5C3 /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = A5D85225286333D500DAF5C3 /* Starscream */; };
A5D85228286333E300DAF5C3 /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = A5D85227286333E300DAF5C3 /* Starscream */; };
A5E03DF52864651200888481 /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = A5E03DF42864651200888481 /* Starscream */; };
@@ -170,7 +183,6 @@
A5E03E01286466EA00888481 /* WalletConnectChat in Frameworks */ = {isa = PBXBuildFile; productRef = A5E03E00286466EA00888481 /* WalletConnectChat */; };
A5E03E03286466F400888481 /* ChatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E03E02286466F400888481 /* ChatTests.swift */; };
A5E03E0D28646AD200888481 /* RelayClientEndToEndTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E03E0C28646AD200888481 /* RelayClientEndToEndTests.swift */; };
- A5E03E0F28646D8A00888481 /* WebSocketFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E03E0E28646D8A00888481 /* WebSocketFactory.swift */; };
A5E03E1128646F8000888481 /* KeychainStorageMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E03E1028646F8000888481 /* KeychainStorageMock.swift */; };
A5E22D1A2840C62A00E36487 /* Engine.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E22D192840C62A00E36487 /* Engine.swift */; };
A5E22D1C2840C85D00E36487 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E22D1B2840C85D00E36487 /* App.swift */; };
@@ -253,6 +265,10 @@
A51AC0D828E436A3001BACF9 /* InputConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputConfig.swift; sourceTree = ""; };
A51AC0DB28E436E6001BACF9 /* InputConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputConfig.swift; sourceTree = ""; };
A51AC0DE28E4379F001BACF9 /* InputConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputConfig.swift; sourceTree = ""; };
+ A541959A2934BFEF0035AD19 /* CacaoSignerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CacaoSignerTests.swift; sourceTree = ""; };
+ A541959B2934BFEF0035AD19 /* SignerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignerTests.swift; sourceTree = ""; };
+ A541959C2934BFEF0035AD19 /* EIP1271VerifierTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EIP1271VerifierTests.swift; sourceTree = ""; };
+ A541959D2934BFEF0035AD19 /* EIP191VerifierTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EIP191VerifierTests.swift; sourceTree = ""; };
A55CAAAB28B92AFF00844382 /* ScanModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanModule.swift; sourceTree = ""; };
A55CAAAC28B92AFF00844382 /* ScanPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanPresenter.swift; sourceTree = ""; };
A55CAAAD28B92AFF00844382 /* ScanRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanRouter.swift; sourceTree = ""; };
@@ -279,14 +295,14 @@
A5629ADD2876CC6E00094373 /* InviteListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteListView.swift; sourceTree = ""; };
A5629AE32876E6D200094373 /* ThreadViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadViewModel.swift; sourceTree = ""; };
A5629AE728772A0100094373 /* InviteViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteViewModel.swift; sourceTree = ""; };
- A5629AEF2877F73000094373 /* SocketFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocketFactory.swift; sourceTree = ""; };
+ A5629AEF2877F73000094373 /* DefaultSocketFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultSocketFactory.swift; sourceTree = ""; };
A578FA312873036400AA7720 /* InputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputView.swift; sourceTree = ""; };
A578FA34287304A300AA7720 /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = ""; };
A578FA362873D8EE00AA7720 /* UIColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColor.swift; sourceTree = ""; };
A578FA382873FCE000AA7720 /* ChatScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatScrollView.swift; sourceTree = ""; };
A578FA3C2874002400AA7720 /* View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = View.swift; sourceTree = ""; };
- A57E71A5291CF76400325797 /* EthereumSigner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumSigner.swift; sourceTree = ""; };
- A57E71A7291CF8A500325797 /* SolanaSigner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SolanaSigner.swift; sourceTree = ""; };
+ A57E71A5291CF76400325797 /* ETHSigner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ETHSigner.swift; sourceTree = ""; };
+ A57E71A7291CF8A500325797 /* SOLSigner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SOLSigner.swift; sourceTree = ""; };
A58E7CE828729F550082D443 /* Showcase.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Showcase.app; sourceTree = BUILT_PRODUCTS_DIR; };
A58E7CEA28729F550082D443 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
A58E7CEC28729F550082D443 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
@@ -315,6 +331,7 @@
A58E7D422872EE320082D443 /* MessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageView.swift; sourceTree = ""; };
A58E7D442872EE570082D443 /* ContentMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentMessageView.swift; sourceTree = ""; };
A58E7D472872EF610082D443 /* MessageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageViewModel.swift; sourceTree = ""; };
+ A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultSignerFactory.swift; sourceTree = ""; };
A59EBEF328B54A2A003EDAAF /* AuthRequestModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRequestModule.swift; sourceTree = ""; };
A59EBEF428B54A2A003EDAAF /* AuthRequestPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRequestPresenter.swift; sourceTree = ""; };
A59EBEF528B54A2A003EDAAF /* AuthRequestRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRequestRouter.swift; sourceTree = ""; };
@@ -357,7 +374,6 @@
A5E03DFC286465D100888481 /* Stubs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stubs.swift; sourceTree = ""; };
A5E03E02286466F400888481 /* ChatTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTests.swift; sourceTree = ""; };
A5E03E0C28646AD200888481 /* RelayClientEndToEndTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RelayClientEndToEndTests.swift; sourceTree = ""; };
- A5E03E0E28646D8A00888481 /* WebSocketFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebSocketFactory.swift; sourceTree = ""; };
A5E03E1028646F8000888481 /* KeychainStorageMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainStorageMock.swift; sourceTree = ""; };
A5E22D192840C62A00E36487 /* Engine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Engine.swift; sourceTree = ""; };
A5E22D1B2840C85D00E36487 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = ""; };
@@ -376,6 +392,7 @@
files = (
A5AE354728A1A2AC0059AE8A /* Web3 in Frameworks */,
A5434023291E6A270068F706 /* SolanaSwift in Frameworks */,
+ 849D7A90292665D3006A2BD4 /* WalletConnectVerify in Frameworks */,
764E1D5826F8DBAB00A1FB15 /* WalletConnect in Frameworks */,
A5D85226286333D500DAF5C3 /* Starscream in Frameworks */,
A5C4DD8728A2DE88006A626D /* WalletConnectRouter in Frameworks */,
@@ -387,6 +404,7 @@
buildActionMask = 2147483647;
files = (
8448F1D427E4726F0000B866 /* WalletConnect in Frameworks */,
+ A54195A52934E83F0035AD19 /* Web3 in Frameworks */,
A5D85228286333E300DAF5C3 /* Starscream in Frameworks */,
A5BB7FA328B6A50400707FC6 /* WalletConnectAuth in Frameworks */,
);
@@ -417,6 +435,7 @@
A5E03DFF2864662500888481 /* WalletConnect in Frameworks */,
A5E03DF52864651200888481 /* Starscream in Frameworks */,
847CF3AF28E3141700F1D760 /* WalletConnectPush in Frameworks */,
+ A5C8BE85292FE20B006CC85C /* Web3 in Frameworks */,
84DDB4ED28ABB663003D66ED /* WalletConnectAuth in Frameworks */,
A5E03E01286466EA00888481 /* WalletConnectChat in Frameworks */,
);
@@ -465,6 +484,7 @@
764E1D3326F8D3FC00A1FB15 = {
isa = PBXGroup;
children = (
+ A5A8E479293A1C4400FEB97D /* Shared */,
A5F48A0528E43D3F0034CBFB /* Configuration.xcconfig */,
84CE6453279FFE1100142511 /* Wallet.entitlements */,
764E1D3E26F8D3FC00A1FB15 /* ExampleApp */,
@@ -609,6 +629,7 @@
84D2A66728A4F5260088AE09 /* Auth */ = {
isa = PBXGroup;
children = (
+ A54195992934BFDD0035AD19 /* Signer */,
84D2A66528A4F51E0088AE09 /* AuthTests.swift */,
);
path = Auth;
@@ -630,6 +651,17 @@
path = Common;
sourceTree = "";
};
+ A54195992934BFDD0035AD19 /* Signer */ = {
+ isa = PBXGroup;
+ children = (
+ A541959A2934BFEF0035AD19 /* CacaoSignerTests.swift */,
+ A541959D2934BFEF0035AD19 /* EIP191VerifierTests.swift */,
+ A541959C2934BFEF0035AD19 /* EIP1271VerifierTests.swift */,
+ A541959B2934BFEF0035AD19 /* SignerTests.swift */,
+ );
+ path = Signer;
+ sourceTree = "";
+ };
A55CAAAA28B92AF200844382 /* Scan */ = {
isa = PBXGroup;
children = (
@@ -657,7 +689,6 @@
isa = PBXGroup;
children = (
A5C20227287EB342007E3188 /* AccountStorage */,
- A5629AEE2877F72B00094373 /* SocketFactory */,
A5629AEB2877F69C00094373 /* Chat */,
);
path = DomainLayer;
@@ -727,14 +758,6 @@
path = Chat;
sourceTree = "";
};
- A5629AEE2877F72B00094373 /* SocketFactory */ = {
- isa = PBXGroup;
- children = (
- A5629AEF2877F73000094373 /* SocketFactory.swift */,
- );
- path = SocketFactory;
- sourceTree = "";
- };
A578FA332873049400AA7720 /* Style */ = {
isa = PBXGroup;
children = (
@@ -765,8 +788,8 @@
isa = PBXGroup;
children = (
84F568C1279582D200D0A289 /* Signer.swift */,
- A57E71A5291CF76400325797 /* EthereumSigner.swift */,
- A57E71A7291CF8A500325797 /* SolanaSigner.swift */,
+ A57E71A5291CF76400325797 /* ETHSigner.swift */,
+ A57E71A7291CF8A500325797 /* SOLSigner.swift */,
);
path = Signer;
sourceTree = "";
@@ -986,6 +1009,15 @@
path = Engine;
sourceTree = "";
};
+ A5A8E479293A1C4400FEB97D /* Shared */ = {
+ isa = PBXGroup;
+ children = (
+ A5629AEF2877F73000094373 /* DefaultSocketFactory.swift */,
+ A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */,
+ );
+ path = Shared;
+ sourceTree = "";
+ };
A5BB7FA528B6A5DC00707FC6 /* Auth */ = {
isa = PBXGroup;
children = (
@@ -1096,7 +1128,6 @@
children = (
A518B31328E33A6500A2CE93 /* InputConfig.swift */,
A5E03E1028646F8000888481 /* KeychainStorageMock.swift */,
- A5E03E0E28646D8A00888481 /* WebSocketFactory.swift */,
A5E03DFC286465D100888481 /* Stubs.swift */,
84FE684528ACDB4700C893FF /* RequestParams.swift */,
);
@@ -1149,6 +1180,7 @@
A5AE354628A1A2AC0059AE8A /* Web3 */,
A5C4DD8628A2DE88006A626D /* WalletConnectRouter */,
A5434022291E6A270068F706 /* SolanaSwift */,
+ 849D7A8F292665D3006A2BD4 /* WalletConnectVerify */,
);
productName = ExampleApp;
productReference = 764E1D3C26F8D3FC00A1FB15 /* WalletConnect Wallet.app */;
@@ -1171,6 +1203,7 @@
8448F1D327E4726F0000B866 /* WalletConnect */,
A5D85227286333E300DAF5C3 /* Starscream */,
A5BB7FA228B6A50400707FC6 /* WalletConnectAuth */,
+ A54195A42934E83F0035AD19 /* Web3 */,
);
productName = DApp;
productReference = 84CE641C27981DED00142511 /* DApp.app */;
@@ -1237,6 +1270,7 @@
A5E03E00286466EA00888481 /* WalletConnectChat */,
84DDB4EC28ABB663003D66ED /* WalletConnectAuth */,
847CF3AE28E3141700F1D760 /* WalletConnectPush */,
+ A5C8BE84292FE20B006CC85C /* Web3 */,
);
productName = IntegrationTests;
productReference = A5E03DED286464DB00888481 /* IntegrationTests.xctest */;
@@ -1357,11 +1391,12 @@
76235E8B28201C9C004ED0AA /* Utilities.swift in Sources */,
76744CF726FE4D5400B77ED9 /* ActiveSessionItem.swift in Sources */,
A5A4FC5A283CC08600BBEC1E /* SessionNamespaceViewModel.swift in Sources */,
- A57E71A8291CF8A500325797 /* SolanaSigner.swift in Sources */,
+ A5A8E47B293A1CFE00FEB97D /* DefaultSocketFactory.swift in Sources */,
+ A57E71A8291CF8A500325797 /* SOLSigner.swift in Sources */,
764E1D4226F8D3FC00A1FB15 /* SceneDelegate.swift in Sources */,
84F568C2279582D200D0A289 /* Signer.swift in Sources */,
A5A4FC56283CBB7800BBEC1E /* SessionDetailView.swift in Sources */,
- A57E71A6291CF76400325797 /* EthereumSigner.swift in Sources */,
+ A57E71A6291CF76400325797 /* ETHSigner.swift in Sources */,
7600223B2819FC0B0011DD38 /* ProposalView.swift in Sources */,
761248172819F9E600CB6D48 /* WalletView.swift in Sources */,
A5A4FC58283CBB9F00BBEC1E /* SessionDetailViewModel.swift in Sources */,
@@ -1383,10 +1418,12 @@
A5BB7FA128B69F3400707FC6 /* AuthCoordinator.swift in Sources */,
84CE645527A29D4D00142511 /* ResponseViewController.swift in Sources */,
84CE641F27981DED00142511 /* AppDelegate.swift in Sources */,
+ A5A8E47D293A1CFE00FEB97D /* DefaultSocketFactory.swift in Sources */,
A5BB7FAD28B6AA7D00707FC6 /* QRCodeGenerator.swift in Sources */,
A51AC0D928E436A3001BACF9 /* InputConfig.swift in Sources */,
A5BB7FA928B6A5FD00707FC6 /* AuthViewModel.swift in Sources */,
84CE6452279ED42B00142511 /* ConnectView.swift in Sources */,
+ A5A8E47E293A1CFE00FEB97D /* DefaultSignerFactory.swift in Sources */,
84CE6448279AE68600142511 /* AccountRequestViewController.swift in Sources */,
A5BB7F9F28B69B7100707FC6 /* SignCoordinator.swift in Sources */,
84CE642127981DED00142511 /* SceneDelegate.swift in Sources */,
@@ -1464,12 +1501,13 @@
A5629AC02876CBC000094373 /* ChatListInteractor.swift in Sources */,
A55CAAB428B92AFF00844382 /* ScanView.swift in Sources */,
A5629AE22876CC6E00094373 /* InviteListView.swift in Sources */,
+ A5A8E47F293A1D0000FEB97D /* DefaultSocketFactory.swift in Sources */,
A578FA3D2874002400AA7720 /* View.swift in Sources */,
A5629AD72876CC5700094373 /* InviteView.swift in Sources */,
A59EBEFA28B54A2A003EDAAF /* AuthRequestRouter.swift in Sources */,
- A5629AF02877F73000094373 /* SocketFactory.swift in Sources */,
A55CAAB228B92AFF00844382 /* ScanRouter.swift in Sources */,
A5C20221287EA5B8007E3188 /* TextFieldView.swift in Sources */,
+ A5A8E480293A1D0000FEB97D /* DefaultSignerFactory.swift in Sources */,
A5C2022B287EB89A007E3188 /* WelcomeInteractor.swift in Sources */,
A5C2020C287D9DEE007E3188 /* WelcomePresenter.swift in Sources */,
A58E7D1D2872A57B0082D443 /* Configurator.swift in Sources */,
@@ -1510,17 +1548,22 @@
84CEC64628D89D6B00D081A8 /* PairingTests.swift in Sources */,
767DC83528997F8E00080FA9 /* EthSendTransaction.swift in Sources */,
A518B31428E33A6500A2CE93 /* InputConfig.swift in Sources */,
+ A541959E2934BFEF0035AD19 /* CacaoSignerTests.swift in Sources */,
+ A59CF4F6292F83D50031A42F /* DefaultSignerFactory.swift in Sources */,
A5E03E03286466F400888481 /* ChatTests.swift in Sources */,
84D2A66628A4F51E0088AE09 /* AuthTests.swift in Sources */,
84FE684628ACDB4700C893FF /* RequestParams.swift in Sources */,
7694A5262874296A0001257E /* RegistryTests.swift in Sources */,
+ A541959F2934BFEF0035AD19 /* SignerTests.swift in Sources */,
A50C036528AAD32200FE72D3 /* ClientDelegate.swift in Sources */,
A5E03E0D28646AD200888481 /* RelayClientEndToEndTests.swift in Sources */,
A5E03DFA286465C700888481 /* SignClientTests.swift in Sources */,
- A5E03E0F28646D8A00888481 /* WebSocketFactory.swift in Sources */,
+ A54195A02934BFEF0035AD19 /* EIP1271VerifierTests.swift in Sources */,
+ A54195A12934BFEF0035AD19 /* EIP191VerifierTests.swift in Sources */,
84AA01DB28CF0CD7005D48D8 /* XCTest.swift in Sources */,
A5E03E1128646F8000888481 /* KeychainStorageMock.swift in Sources */,
A5E03DFD286465D100888481 /* Stubs.swift in Sources */,
+ A5A8E47A293A1C9B00FEB97D /* DefaultSocketFactory.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2016,7 +2059,7 @@
repositoryURL = "https://github.com/WalletConnect/Web3.swift";
requirement = {
kind = exactVersion;
- version = 1.0.0;
+ version = 1.0.2;
};
};
A5D85224286333D500DAF5C3 /* XCRemoteSwiftPackageReference "Starscream" */ = {
@@ -2042,10 +2085,19 @@
isa = XCSwiftPackageProductDependency;
productName = WalletConnectPush;
};
+ 849D7A8F292665D3006A2BD4 /* WalletConnectVerify */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = WalletConnectVerify;
+ };
84DDB4EC28ABB663003D66ED /* WalletConnectAuth */ = {
isa = XCSwiftPackageProductDependency;
productName = WalletConnectAuth;
};
+ A54195A42934E83F0035AD19 /* Web3 */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = A5AE354528A1A2AC0059AE8A /* XCRemoteSwiftPackageReference "Web3" */;
+ productName = Web3;
+ };
A5434022291E6A270068F706 /* SolanaSwift */ = {
isa = XCSwiftPackageProductDependency;
package = A5434021291E6A270068F706 /* XCRemoteSwiftPackageReference "solana-swift" */;
@@ -2082,6 +2134,11 @@
isa = XCSwiftPackageProductDependency;
productName = WalletConnectRouter;
};
+ A5C8BE84292FE20B006CC85C /* Web3 */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = A5AE354528A1A2AC0059AE8A /* XCRemoteSwiftPackageReference "Web3" */;
+ productName = Web3;
+ };
A5D85225286333D500DAF5C3 /* Starscream */ = {
isa = XCSwiftPackageProductDependency;
package = A5D85224286333D500DAF5C3 /* XCRemoteSwiftPackageReference "Starscream" */;
diff --git a/Example/ExampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example/ExampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
index 8893d902d..4dc474e71 100644
--- a/Example/ExampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/Example/ExampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -78,8 +78,8 @@
"repositoryURL": "https://github.com/WalletConnect/Web3.swift",
"state": {
"branch": null,
- "revision": "bdaaed96eee3a9bf7f341165f89a94288961d14c",
- "version": "1.0.0"
+ "revision": "569255adcfff0b37e4cb8004aea29d0e2d6266df",
+ "version": "1.0.2"
}
}
]
diff --git a/Example/ExampleApp/SceneDelegate.swift b/Example/ExampleApp/SceneDelegate.swift
index 0037fb05b..c3ddd5743 100644
--- a/Example/ExampleApp/SceneDelegate.swift
+++ b/Example/ExampleApp/SceneDelegate.swift
@@ -5,15 +5,6 @@ import WalletConnectSign
import WalletConnectNetworking
import WalletConnectRelay
import WalletConnectPairing
-import Starscream
-
-extension WebSocket: WebSocketConnecting { }
-
-struct SocketFactory: WebSocketFactory {
- func create(with url: URL) -> WebSocketConnecting {
- return WebSocket(url: url)
- }
-}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
@@ -27,7 +18,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
url: "example.wallet",
icons: ["https://avatars.githubusercontent.com/u/37784886"])
- Networking.configure(projectId: InputConfig.projectId, socketFactory: SocketFactory())
+ Networking.configure(projectId: InputConfig.projectId, socketFactory: DefaultSocketFactory())
Pair.configure(metadata: metadata)
#if DEBUG
if CommandLine.arguments.contains("-cleanInstall") {
diff --git a/Example/ExampleApp/Shared/Signer/EthereumSigner.swift b/Example/ExampleApp/Shared/Signer/ETHSigner.swift
similarity index 98%
rename from Example/ExampleApp/Shared/Signer/EthereumSigner.swift
rename to Example/ExampleApp/Shared/Signer/ETHSigner.swift
index 6f1178872..3d1e0e743 100644
--- a/Example/ExampleApp/Shared/Signer/EthereumSigner.swift
+++ b/Example/ExampleApp/Shared/Signer/ETHSigner.swift
@@ -2,7 +2,7 @@ import Foundation
import Commons
import Web3
-struct EthereumSigner {
+struct ETHSigner {
private init() {}
diff --git a/Example/ExampleApp/Shared/Signer/SolanaSigner.swift b/Example/ExampleApp/Shared/Signer/SOLSigner.swift
similarity index 98%
rename from Example/ExampleApp/Shared/Signer/SolanaSigner.swift
rename to Example/ExampleApp/Shared/Signer/SOLSigner.swift
index c65ec83f1..557d0177f 100644
--- a/Example/ExampleApp/Shared/Signer/SolanaSigner.swift
+++ b/Example/ExampleApp/Shared/Signer/SOLSigner.swift
@@ -3,7 +3,7 @@ import Commons
import SolanaSwift
import TweetNacl
-struct SolanaSigner {
+struct SOLSigner {
static var address: String {
return account.publicKey.base58EncodedString
diff --git a/Example/ExampleApp/Shared/Signer/Signer.swift b/Example/ExampleApp/Shared/Signer/Signer.swift
index dde8e101f..d22d863da 100644
--- a/Example/ExampleApp/Shared/Signer/Signer.swift
+++ b/Example/ExampleApp/Shared/Signer/Signer.swift
@@ -9,16 +9,16 @@ class Signer {
static func sign(request: Request) -> AnyCodable {
switch request.method {
case "personal_sign":
- return EthereumSigner.personalSign(request.params)
+ return ETHSigner.personalSign(request.params)
case "eth_signTypedData":
- return EthereumSigner.signTypedData(request.params)
+ return ETHSigner.signTypedData(request.params)
case "eth_sendTransaction":
- return EthereumSigner.sendTransaction(request.params)
+ return ETHSigner.sendTransaction(request.params)
case "solana_signTransaction":
- return SolanaSigner.signTransaction(request.params)
+ return SOLSigner.signTransaction(request.params)
default:
fatalError("not implemented")
}
diff --git a/Example/ExampleApp/Wallet/WalletViewController.swift b/Example/ExampleApp/Wallet/WalletViewController.swift
index 034998740..b20a21ea0 100644
--- a/Example/ExampleApp/Wallet/WalletViewController.swift
+++ b/Example/ExampleApp/Wallet/WalletViewController.swift
@@ -9,8 +9,8 @@ import Combine
final class WalletViewController: UIViewController {
lazy var accounts = [
- "eip155": EthereumSigner.address,
- "solana": SolanaSigner.address
+ "eip155": ETHSigner.address,
+ "solana": SOLSigner.address
]
var sessionItems: [ActiveSessionItem] = []
diff --git a/Example/IntegrationTests/Auth/AuthTests.swift b/Example/IntegrationTests/Auth/AuthTests.swift
index ea165a98f..8bede13a1 100644
--- a/Example/IntegrationTests/Auth/AuthTests.swift
+++ b/Example/IntegrationTests/Auth/AuthTests.swift
@@ -14,6 +14,8 @@ final class AuthTests: XCTestCase {
var appAuthClient: AuthClient!
var walletAuthClient: AuthClient!
+
+ let walletAccount = Account(chainIdentifier: "eip155:1", address: "0x724d0D2DaD3fbB0C168f947B87Fa5DBe36F1A8bf")!
let prvKey = Data(hex: "462c1dad6832d7d96ccf87bd6a686a4110e114aaaebd5512e552c0e3a87b480f")
let eip1271Signature = "0xc1505719b2504095116db01baaf276361efd3a73c28cf8cc28dabefa945b8d536011289ac0a3b048600c1e692ff173ca944246cf7ceb319ac2262d27b395c82b1c"
private var publishers = [AnyCancellable]()
@@ -22,16 +24,15 @@ final class AuthTests: XCTestCase {
setupClients()
}
- private func setupClients(address: String = "0x724d0D2DaD3fbB0C168f947B87Fa5DBe36F1A8bf", iatProvider: IATProvider = DefaultIATProvider()) {
- let walletAccount = Account(chainIdentifier: "eip155:1", address: address)!
+ private func setupClients(iatProvider: IATProvider = DefaultIATProvider()) {
(appPairingClient, appAuthClient) = makeClients(prefix: "🤖 App", iatProvider: iatProvider)
- (walletPairingClient, walletAuthClient) = makeClients(prefix: "🐶 Wallet", account: walletAccount, iatProvider: iatProvider)
+ (walletPairingClient, walletAuthClient) = makeClients(prefix: "🐶 Wallet", iatProvider: iatProvider)
}
- func makeClients(prefix: String, account: Account? = nil, iatProvider: IATProvider) -> (PairingClient, AuthClient) {
+ func makeClients(prefix: String, iatProvider: IATProvider) -> (PairingClient, AuthClient) {
let logger = ConsoleLogger(suffix: prefix, loggingLevel: .debug)
let keychain = KeychainStorageMock()
- let relayClient = RelayClient(relayHost: InputConfig.relayHost, projectId: InputConfig.projectId, keychainStorage: keychain, socketFactory: SocketFactory(), logger: logger)
+ let relayClient = RelayClient(relayHost: InputConfig.relayHost, projectId: InputConfig.projectId, keychainStorage: keychain, socketFactory: DefaultSocketFactory(), logger: logger)
let keyValueStorage = RuntimeKeyValueStorage()
let networkingClient = NetworkingClientFactory.create(
@@ -48,8 +49,8 @@ final class AuthTests: XCTestCase {
let authClient = AuthClientFactory.create(
metadata: AppMetadata(name: name, description: "", url: "", icons: [""]),
- account: account,
projectId: InputConfig.projectId,
+ signerFactory: DefaultSignerFactory(),
logger: logger,
keyValueStorage: keyValueStorage,
keychainStorage: keychain,
@@ -80,9 +81,10 @@ final class AuthTests: XCTestCase {
try! await walletPairingClient.pair(uri: uri)
walletAuthClient.authRequestPublisher.sink { [unowned self] request in
Task(priority: .high) {
- let signer = MessageSignerFactory.create(projectId: InputConfig.projectId)
- let signature = try! signer.sign(message: request.message, privateKey: prvKey, type: .eip191)
- try! await walletAuthClient.respond(requestId: request.id, signature: signature)
+ let signerFactory = DefaultSignerFactory()
+ let signer = MessageSignerFactory(signerFactory: signerFactory).create(projectId: InputConfig.projectId)
+ let signature = try! signer.sign(payload: request.payload, address: walletAccount.address, privateKey: prvKey, type: .eip191)
+ try! await walletAuthClient.respond(requestId: request.id, signature: signature, from: walletAccount)
}
}
.store(in: &publishers)
@@ -95,7 +97,9 @@ final class AuthTests: XCTestCase {
}
func testEIP1271RespondSuccess() async {
- setupClients(address: "0x2faf83c542b68f1b4cdc0e770e8cb9f567b08f71", iatProvider: IATProviderMock())
+ setupClients(iatProvider: IATProviderMock())
+
+ let account = Account(chainIdentifier: "eip155:1", address: "0x2faf83c542b68f1b4cdc0e770e8cb9f567b08f71")!
let responseExpectation = expectation(description: "successful response delivered")
let uri = try! await appPairingClient.create()
@@ -115,7 +119,7 @@ final class AuthTests: XCTestCase {
walletAuthClient.authRequestPublisher.sink { [unowned self] request in
Task(priority: .high) {
let signature = CacaoSignature(t: .eip1271, s: eip1271Signature)
- try! await walletAuthClient.respond(requestId: request.id, signature: signature)
+ try! await walletAuthClient.respond(requestId: request.id, signature: signature, from: account)
}
}
.store(in: &publishers)
@@ -136,7 +140,7 @@ final class AuthTests: XCTestCase {
walletAuthClient.authRequestPublisher.sink { [unowned self] request in
Task(priority: .high) {
let signature = CacaoSignature(t: .eip1271, s: eip1271Signature)
- try! await walletAuthClient.respond(requestId: request.id, signature: signature)
+ try! await walletAuthClient.respond(requestId: request.id, signature: signature, from: walletAccount)
}
}
.store(in: &publishers)
@@ -179,7 +183,7 @@ final class AuthTests: XCTestCase {
Task(priority: .high) {
let invalidSignature = "438effc459956b57fcd9f3dac6c675f9cee88abf21acab7305e8e32aa0303a883b06dcbd956279a7a2ca21ffa882ff55cc22e8ab8ec0f3fe90ab45f306938cfa1b"
let cacaoSignature = CacaoSignature(t: .eip191, s: invalidSignature)
- try! await walletAuthClient.respond(requestId: request.id, signature: cacaoSignature)
+ try! await walletAuthClient.respond(requestId: request.id, signature: cacaoSignature, from: walletAccount)
}
}
.store(in: &publishers)
diff --git a/Tests/AuthTests/CacaoSignerTests.swift b/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift
similarity index 52%
rename from Tests/AuthTests/CacaoSignerTests.swift
rename to Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift
index 95a01a538..c6481015b 100644
--- a/Tests/AuthTests/CacaoSignerTests.swift
+++ b/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift
@@ -1,11 +1,11 @@
import Foundation
import XCTest
@testable import Auth
-import TestingUtils
class CacaoSignerTest: XCTestCase {
- let signer = MessageSignerFactory.create(projectId: "project-id")
+ let signer = MessageSignerFactory(signerFactory: DefaultSignerFactory())
+ .create(projectId: InputConfig.projectId)
let privateKey = Data(hex: "305c6cde3846927892cd32762f6120539f3ec74c9e3a16b9b798b1e85351ae2a")
@@ -26,10 +26,31 @@ class CacaoSignerTest: XCTestCase {
- https://example.com/my-web2-claim.json
"""
+ let payload = AuthPayload(requestParams: RequestParams(
+ domain: "service.invalid",
+ chainId: "eip155:1",
+ nonce: "32891756",
+ aud: "https://service.invalid/login",
+ nbf: nil,
+ exp: nil,
+ statement: "I accept the ServiceOrg Terms of Service: https://service.invalid/tos",
+ requestId: nil,
+ resources: [
+ "ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/",
+ "https://example.com/my-web2-claim.json"
+ ]
+ ), iat: "2021-09-30T16:25:24Z")
+
let signature = CacaoSignature(t: .eip191, s: "0x438effc459956b57fcd9f3dac6c675f9cee88abf21acab7305e8e32aa0303a883b06dcbd956279a7a2ca21ffa882ff55cc22e8ab8ec0f3fe90ab45f306938cfa1b")
func testCacaoSign() throws {
- XCTAssertEqual(try signer.sign(message: message, privateKey: privateKey, type: .eip191), signature)
+ let address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
+ let formatted = try SIWEMessageFormatter().formatMessage(
+ from: payload,
+ address: address
+ )
+ XCTAssertEqual(formatted, message)
+ XCTAssertEqual(try signer.sign(payload: payload, address: address, privateKey: privateKey, type: .eip191), signature)
}
func testCacaoVerify() async throws {
diff --git a/Example/IntegrationTests/Auth/Signer/EIP1271VerifierTests.swift b/Example/IntegrationTests/Auth/Signer/EIP1271VerifierTests.swift
new file mode 100644
index 000000000..45c5c1bdd
--- /dev/null
+++ b/Example/IntegrationTests/Auth/Signer/EIP1271VerifierTests.swift
@@ -0,0 +1,39 @@
+import Foundation
+import XCTest
+@testable import Auth
+import JSONRPC
+
+class EIP1271VerifierTests: XCTestCase {
+
+ let signature = Data(hex: "c1505719b2504095116db01baaf276361efd3a73c28cf8cc28dabefa945b8d536011289ac0a3b048600c1e692ff173ca944246cf7ceb319ac2262d27b395c82b1c")
+
+ let message = Data(hex: "19457468657265756d205369676e6564204d6573736167653a0a3235326c6f63616c686f73742077616e747320796f7520746f207369676e20696e207769746820796f757220457468657265756d206163636f756e743a0a3078326661663833633534326236386631623463646330653737306538636239663536376230386637310a0a5552493a20687474703a2f2f6c6f63616c686f73743a333030302f0a56657273696f6e3a20310a436861696e2049443a20310a4e6f6e63653a20313636353434333031353730300a4973737565642041743a20323032322d31302d31305432333a30333a33352e3730305a0a45787069726174696f6e2054696d653a20323032322d31302d31315432333a30333a33352e3730305a")
+
+ let address = "0x2faf83c542b68f1b4cdc0e770e8cb9f567b08f71"
+ let chainId = "eip155:1"
+
+ func testSuccessVerify() async throws {
+ let httpClient = HTTPNetworkClient(host: "rpc.walletconnect.com")
+ let signer = DefaultSignerFactory().createEthereumSigner()
+ let verifier = EIP1271Verifier(projectId: InputConfig.projectId, httpClient: httpClient, signer: signer)
+ try await verifier.verify(
+ signature: signature,
+ message: message,
+ address: address,
+ chainId: chainId
+ )
+ }
+
+ func testFailureVerify() async throws {
+ let httpClient = HTTPNetworkClient(host: "rpc.walletconnect.com")
+ let signer = DefaultSignerFactory().createEthereumSigner()
+ let verifier = EIP1271Verifier(projectId: InputConfig.projectId, httpClient: httpClient, signer: signer)
+
+ await XCTAssertThrowsErrorAsync(try await verifier.verify(
+ signature: Data("deadbeaf"),
+ message: message,
+ address: address,
+ chainId: chainId
+ ))
+ }
+}
diff --git a/Tests/AuthTests/EIP191VerifierTests.swift b/Example/IntegrationTests/Auth/Signer/EIP191VerifierTests.swift
similarity index 95%
rename from Tests/AuthTests/EIP191VerifierTests.swift
rename to Example/IntegrationTests/Auth/Signer/EIP191VerifierTests.swift
index 7b683ab14..2e5c9c1f3 100644
--- a/Tests/AuthTests/EIP191VerifierTests.swift
+++ b/Example/IntegrationTests/Auth/Signer/EIP191VerifierTests.swift
@@ -1,11 +1,10 @@
import Foundation
import XCTest
-import TestingUtils
@testable import Auth
class EIP191VerifierTests: XCTestCase {
- private let verifier = EIP191Verifier()
+ private let verifier = EIP191Verifier(signer: DefaultSignerFactory().createEthereumSigner())
private let address = "0x15bca56b6e2728aec2532df9d436bd1600e86688"
private let message = "\u{19}Ethereum Signed Message:\n7Message".data(using: .utf8)!
diff --git a/Tests/AuthTests/SignerTests.swift b/Example/IntegrationTests/Auth/Signer/SignerTests.swift
similarity index 78%
rename from Tests/AuthTests/SignerTests.swift
rename to Example/IntegrationTests/Auth/Signer/SignerTests.swift
index 80b19ecfb..2a8f49b2d 100644
--- a/Tests/AuthTests/SignerTests.swift
+++ b/Example/IntegrationTests/Auth/Signer/SignerTests.swift
@@ -1,24 +1,21 @@
import Foundation
import XCTest
@testable import Auth
-import secp256k1
-import Web3
-import WalletConnectUtils
import WalletConnectRelay
class SignerTest: XCTestCase {
- private let signer = Signer()
+ private let signer = DefaultSignerFactory().createEthereumSigner()
private let message = "\u{19}Ethereum Signed Message:\n7Message".data(using: .utf8)!
private let privateKey = Data(hex: "305c6cde3846927892cd32762f6120539f3ec74c9e3a16b9b798b1e85351ae2a")
- private let signature = Data(hex: "66121e60cccc01fbf7fcba694a1e08ac5db35fb4ec6c045bedba7860445b95c021cad2c595f0bf68ff896964c7c02bb2f3a3e9540e8e4595c98b737ce264cc541b")
+ private let signature = "0x66121e60cccc01fbf7fcba694a1e08ac5db35fb4ec6c045bedba7860445b95c021cad2c595f0bf68ff896964c7c02bb2f3a3e9540e8e4595c98b737ce264cc541b"
private var address = "0x15bca56b6e2728aec2532df9d436bd1600e86688"
func testValidSignature() throws {
let result = try signer.sign(message: message, with: privateKey)
- XCTAssertEqual(signature.toHexString(), result.toHexString())
+ XCTAssertEqual(signature, result.hex())
}
private func prefixed(_ message: Data) -> Data {
diff --git a/Example/IntegrationTests/Chat/ChatTests.swift b/Example/IntegrationTests/Chat/ChatTests.swift
index 4c305a88f..0f7d770ce 100644
--- a/Example/IntegrationTests/Chat/ChatTests.swift
+++ b/Example/IntegrationTests/Chat/ChatTests.swift
@@ -21,7 +21,7 @@ final class ChatTests: XCTestCase {
func makeClient(prefix: String) -> ChatClient {
let logger = ConsoleLogger(suffix: prefix, loggingLevel: .debug)
let keychain = KeychainStorageMock()
- let relayClient = RelayClient(relayHost: InputConfig.relayHost, projectId: InputConfig.projectId, keychainStorage: keychain, socketFactory: SocketFactory(), logger: logger)
+ let relayClient = RelayClient(relayHost: InputConfig.relayHost, projectId: InputConfig.projectId, keychainStorage: keychain, socketFactory: DefaultSocketFactory(), logger: logger)
return ChatClientFactory.create(registry: registry, relayClient: relayClient, kms: KeyManagementService(keychain: keychain), logger: logger, keyValueStorage: RuntimeKeyValueStorage())
}
diff --git a/Example/IntegrationTests/Pairing/PairingTests.swift b/Example/IntegrationTests/Pairing/PairingTests.swift
index dce08c134..a3724cb67 100644
--- a/Example/IntegrationTests/Pairing/PairingTests.swift
+++ b/Example/IntegrationTests/Pairing/PairingTests.swift
@@ -34,7 +34,7 @@ final class PairingTests: XCTestCase {
projectId: InputConfig.projectId,
keyValueStorage: RuntimeKeyValueStorage(),
keychainStorage: keychain,
- socketFactory: SocketFactory(),
+ socketFactory: DefaultSocketFactory(),
logger: relayLogger)
let networkingClient = NetworkingClientFactory.create(
@@ -68,7 +68,7 @@ final class PairingTests: XCTestCase {
relayHost: InputConfig.relayHost,
projectId: InputConfig.projectId,
keychainStorage: keychain,
- socketFactory: SocketFactory(),
+ socketFactory: DefaultSocketFactory(),
logger: logger)
let networkingClient = NetworkingClientFactory.create(
diff --git a/Example/IntegrationTests/Sign/SignClientTests.swift b/Example/IntegrationTests/Sign/SignClientTests.swift
index acbfbb728..a429d0884 100644
--- a/Example/IntegrationTests/Sign/SignClientTests.swift
+++ b/Example/IntegrationTests/Sign/SignClientTests.swift
@@ -19,7 +19,7 @@ final class SignClientTests: XCTestCase {
projectId: InputConfig.projectId,
keyValueStorage: RuntimeKeyValueStorage(),
keychainStorage: keychain,
- socketFactory: SocketFactory(),
+ socketFactory: DefaultSocketFactory(),
socketConnectionType: .automatic,
logger: logger
)
diff --git a/Example/IntegrationTests/Stubs/WebSocketFactory.swift b/Example/IntegrationTests/Stubs/WebSocketFactory.swift
deleted file mode 100644
index 22f45a8cb..000000000
--- a/Example/IntegrationTests/Stubs/WebSocketFactory.swift
+++ /dev/null
@@ -1,14 +0,0 @@
-import Foundation
-import Starscream
-import WalletConnectRelay
-
-extension WebSocket: WebSocketConnecting { }
-
-public struct SocketFactory: WebSocketFactory {
-
- public init() { }
-
- public func create(with url: URL) -> WebSocketConnecting {
- return WebSocket(url: url)
- }
-}
diff --git a/Example/Shared/DefaultSignerFactory.swift b/Example/Shared/DefaultSignerFactory.swift
new file mode 100644
index 000000000..ac720452d
--- /dev/null
+++ b/Example/Shared/DefaultSignerFactory.swift
@@ -0,0 +1,36 @@
+import Foundation
+import CryptoSwift
+import Web3
+import Auth
+
+public struct DefaultSignerFactory: SignerFactory {
+
+ public func createEthereumSigner() -> EthereumSigner {
+ return Web3Signer()
+ }
+}
+
+public struct Web3Signer: EthereumSigner {
+
+ public func sign(message: Data, with key: Data) throws -> EthereumSignature {
+ let privateKey = try EthereumPrivateKey(privateKey: [UInt8](key))
+ let signature = try privateKey.sign(message: message.bytes)
+ return EthereumSignature(v: UInt8(signature.v), r: signature.r, s: signature.s)
+ }
+
+ public func recoverPubKey(signature: EthereumSignature, message: Data) throws -> Data {
+ let publicKey = try EthereumPublicKey(
+ message: message.bytes,
+ v: EthereumQuantity(quantity: BigUInt(signature.v)),
+ r: EthereumQuantity(signature.r),
+ s: EthereumQuantity(signature.s)
+ )
+ return Data(publicKey.rawPublicKey)
+ }
+
+ public func keccak256(_ data: Data) -> Data {
+ let digest = SHA3(variant: .keccak256)
+ let hash = digest.calculate(for: [UInt8](data))
+ return Data(hash)
+ }
+}
diff --git a/Example/Showcase/Classes/DomainLayer/SocketFactory/SocketFactory.swift b/Example/Shared/DefaultSocketFactory.swift
similarity index 81%
rename from Example/Showcase/Classes/DomainLayer/SocketFactory/SocketFactory.swift
rename to Example/Shared/DefaultSocketFactory.swift
index d22a5ef48..14bb1ed98 100644
--- a/Example/Showcase/Classes/DomainLayer/SocketFactory/SocketFactory.swift
+++ b/Example/Shared/DefaultSocketFactory.swift
@@ -4,7 +4,7 @@ import WalletConnectRelay
extension WebSocket: WebSocketConnecting { }
-struct SocketFactory: WebSocketFactory {
+struct DefaultSocketFactory: WebSocketFactory {
func create(with url: URL) -> WebSocketConnecting {
return WebSocket(url: url)
}
diff --git a/Example/Showcase/Classes/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift b/Example/Showcase/Classes/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift
index a8936517a..f71b9de3e 100644
--- a/Example/Showcase/Classes/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift
+++ b/Example/Showcase/Classes/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift
@@ -5,7 +5,7 @@ import Auth
struct ThirdPartyConfigurator: Configurator {
func configure() {
- Networking.configure(projectId: InputConfig.projectId, socketFactory: SocketFactory())
+ Networking.configure(projectId: InputConfig.projectId, socketFactory: DefaultSocketFactory())
Pair.configure(
metadata: AppMetadata(
name: "Showcase App",
@@ -14,8 +14,6 @@ struct ThirdPartyConfigurator: Configurator {
icons: ["https://avatars.githubusercontent.com/u/37784886"]
))
- Auth.configure(
- account: Account("eip155:1:0xe5EeF1368781911d265fDB6946613dA61915a501")!
- )
+ Auth.configure(signerFactory: DefaultSignerFactory())
}
}
diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift b/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift
index c0c3a8bd3..816d0b398 100644
--- a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift
+++ b/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift
@@ -4,14 +4,27 @@ import WalletConnectUtils
final class AuthRequestInteractor {
+ private let signer = MessageSignerFactory(signerFactory: DefaultSignerFactory()).create()
+ private let account = Account("eip155:1:0xe5EeF1368781911d265fDB6946613dA61915a501")!
+
func approve(request: AuthRequest) async throws {
let privateKey = Data(hex: "e56da0e170b5e09a8bb8f1b693392c7d56c3739a9c75740fbc558a2877868540")
- let signer = MessageSignerFactory.create()
- let signature = try signer.sign(message: request.message, privateKey: privateKey, type: .eip191)
- try await Auth.instance.respond(requestId: request.id, signature: signature)
+ let signature = try signer.sign(
+ payload: request.payload,
+ address: account.address,
+ privateKey: privateKey,
+ type: .eip191)
+ try await Auth.instance.respond(requestId: request.id, signature: signature, from: account)
}
func reject(request: AuthRequest) async throws {
try await Auth.instance.reject(requestId: request.id)
}
+
+ func formatted(request: AuthRequest) -> String {
+ return try! Auth.instance.formatMessage(
+ payload: request.payload,
+ address: account.address
+ )
+ }
}
diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestPresenter.swift b/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestPresenter.swift
index f70700e86..3aece0e97 100644
--- a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestPresenter.swift
+++ b/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestPresenter.swift
@@ -17,7 +17,7 @@ final class AuthRequestPresenter: ObservableObject {
}
var message: String {
- return request.message
+ return interactor.formatted(request: request)
}
@MainActor
diff --git a/Package.swift b/Package.swift
index 5ea3fe03c..a9f2af394 100644
--- a/Package.swift
+++ b/Package.swift
@@ -30,11 +30,12 @@ let package = Package(
targets: ["WalletConnectRouter"]),
.library(
name: "WalletConnectNetworking",
- targets: ["WalletConnectNetworking"])
- ],
- dependencies: [
- .package(url: "https://github.com/WalletConnect/Web3.swift", .exact("1.0.0"))
+ targets: ["WalletConnectNetworking"]),
+ .library(
+ name: "WalletConnectVerify",
+ targets: ["WalletConnectVerify"])
],
+ dependencies: [],
targets: [
.target(
name: "WalletConnectSign",
@@ -46,7 +47,7 @@ let package = Package(
path: "Sources/Chat"),
.target(
name: "Auth",
- dependencies: ["WalletConnectPairing", .product(name: "Web3", package: "Web3.swift")],
+ dependencies: ["WalletConnectPairing"],
path: "Sources/Auth"),
.target(
name: "WalletConnectPush",
@@ -79,6 +80,9 @@ let package = Package(
.target(
name: "WalletConnectRouter",
dependencies: []),
+ .target(
+ name: "WalletConnectVerify",
+ dependencies: ["WalletConnectUtils"]),
.testTarget(
name: "WalletConnectSignTests",
dependencies: ["WalletConnectSign", "TestingUtils"]),
@@ -94,6 +98,9 @@ let package = Package(
.testTarget(
name: "RelayerTests",
dependencies: ["WalletConnectRelay", "WalletConnectUtils", "TestingUtils"]),
+ .testTarget(
+ name: "VerifyTests",
+ dependencies: ["WalletConnectVerify", "TestingUtils"]),
.testTarget(
name: "WalletConnectKMSTests",
dependencies: ["WalletConnectKMS", "WalletConnectUtils", "TestingUtils"]),
diff --git a/README.md b/README.md
index 32b7736dd..3b269c948 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,16 @@ dependencies: [
.package(url: "https://github.com/WalletConnect/WalletConnectSwiftV2", .branch("main")),
],
```
+### Cocoapods
+Add pod to your Podfile:
+
+```Ruby
+pod 'WalletConnectSwiftV2'
+```
+If you encounter any problems during package installation, you can specify the exact path to the repository
+```Ruby
+pod 'WalletConnectSwiftV2', :git => 'https://github.com/WalletConnect/WalletConnectSwiftV2.git', :tag => '1.0.5'
+```
## Setting Project ID
Follow instructions from *Configuration.xcconfig* and configure PROJECT_ID with your ID from WalletConnect Dashboard
```
diff --git a/Sources/Auth/Auth.swift b/Sources/Auth/Auth.swift
index 52bda894a..263e742e6 100644
--- a/Sources/Auth/Auth.swift
+++ b/Sources/Auth/Auth.swift
@@ -16,10 +16,13 @@ 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,
- account: config?.account,
projectId: Networking.projectId,
+ signerFactory: config.signerFactory,
networkingClient: Networking.interactor,
pairingRegisterer: Pair.registerer
)
@@ -29,10 +32,10 @@ public class Auth {
private init() { }
- /// Auth instance wallet config method
+ /// Auth instance wallet config method. For DApp usage
/// - Parameters:
- /// - account: account that wallet will be authenticating with.
- static public func configure(account: Account) {
- Auth.config = Auth.Config(account: account)
+ /// - signerFactory: Auth signers factory
+ static public func configure(signerFactory: SignerFactory) {
+ Auth.config = Auth.Config(signerFactory: signerFactory)
}
}
diff --git a/Sources/Auth/AuthClient.swift b/Sources/Auth/AuthClient.swift
index 1de34a126..43847d3ef 100644
--- a/Sources/Auth/AuthClient.swift
+++ b/Sources/Auth/AuthClient.swift
@@ -7,9 +7,6 @@ import Combine
///
/// Access via `Auth.instance`
public class AuthClient {
- enum Errors: Error {
- case unknownWalletAddress
- }
// MARK: - Public Properties
@@ -46,13 +43,11 @@ public class AuthClient {
private let walletRequestSubscriber: WalletRequestSubscriber
private let walletRespondService: WalletRespondService
private let pendingRequestsProvider: PendingRequestsProvider
- private var account: Account?
init(appRequestService: AppRequestService,
appRespondSubscriber: AppRespondSubscriber,
walletRequestSubscriber: WalletRequestSubscriber,
walletRespondService: WalletRespondService,
- account: Account?,
pendingRequestsProvider: PendingRequestsProvider,
logger: ConsoleLogging,
socketConnectionStatusPublisher: AnyPublisher,
@@ -62,7 +57,6 @@ public class AuthClient {
self.walletRequestSubscriber = walletRequestSubscriber
self.walletRespondService = walletRespondService
self.appRespondSubscriber = appRespondSubscriber
- self.account = account
self.pendingRequestsProvider = pendingRequestsProvider
self.logger = logger
self.socketConnectionStatusPublisher = socketConnectionStatusPublisher
@@ -83,8 +77,7 @@ public class AuthClient {
/// - Parameters:
/// - requestId: authentication request id
/// - signature: CACAO signature of requested message
- public func respond(requestId: RPCID, signature: CacaoSignature) async throws {
- guard let account = account else { throw Errors.unknownWalletAddress }
+ public func respond(requestId: RPCID, signature: CacaoSignature, from account: Account) async throws {
try await walletRespondService.respond(requestId: requestId, signature: signature, account: account)
}
@@ -96,11 +89,14 @@ public class AuthClient {
/// Query pending authentication requests
/// - Returns: Pending authentication requests
- public func getPendingRequests() throws -> [AuthRequest] {
- guard let account = account else { throw Errors.unknownWalletAddress }
+ public func getPendingRequests(account: Account) throws -> [AuthRequest] {
return try pendingRequestsProvider.getPendingRequests(account: account)
}
+ public func formatMessage(payload: AuthPayload, address: String) throws -> String {
+ return try SIWEMessageFormatter().formatMessage(from: payload, address: address)
+ }
+
private func setUpPublishers() {
appRespondSubscriber.onResponse = { [unowned self] (id, result) in
authResponsePublisherSubject.send((id, result))
diff --git a/Sources/Auth/AuthClientFactory.swift b/Sources/Auth/AuthClientFactory.swift
index 89816a70f..5fc6cb188 100644
--- a/Sources/Auth/AuthClientFactory.swift
+++ b/Sources/Auth/AuthClientFactory.swift
@@ -2,33 +2,65 @@ import Foundation
public struct AuthClientFactory {
- public static func create(metadata: AppMetadata, account: Account?, projectId: String, networkingClient: NetworkingInteractor, pairingRegisterer: PairingRegisterer) -> AuthClient {
+ public static func create(
+ metadata: AppMetadata,
+ projectId: String,
+ signerFactory: SignerFactory,
+ networkingClient: NetworkingInteractor,
+ pairingRegisterer: PairingRegisterer
+ ) -> AuthClient {
+
let logger = ConsoleLogger(loggingLevel: .off)
let keyValueStorage = UserDefaults.standard
let keychainStorage = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk")
- return AuthClientFactory.create(metadata: metadata, account: account, projectId: projectId, logger: logger, keyValueStorage: keyValueStorage, keychainStorage: keychainStorage, networkingClient: networkingClient, pairingRegisterer: pairingRegisterer, iatProvider: DefaultIATProvider())
+ let iatProvider = DefaultIATProvider()
+
+ return AuthClientFactory.create(
+ metadata: metadata,
+ projectId: projectId,
+ signerFactory: signerFactory,
+ logger: logger,
+ keyValueStorage: keyValueStorage,
+ keychainStorage: keychainStorage,
+ networkingClient: networkingClient,
+ pairingRegisterer: pairingRegisterer,
+ iatProvider: iatProvider
+ )
}
- static func create(metadata: AppMetadata, account: Account?, projectId: String, logger: ConsoleLogging, keyValueStorage: KeyValueStorage, keychainStorage: KeychainStorageProtocol, networkingClient: NetworkingInteractor, pairingRegisterer: PairingRegisterer, iatProvider: IATProvider) -> AuthClient {
+ static func create(
+ metadata: AppMetadata,
+ projectId: String,
+ signerFactory: SignerFactory,
+ 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 = SIWEMessageFormatter()
let appRequestService = AppRequestService(networkingInteractor: networkingClient, kms: kms, appMetadata: metadata, logger: logger, iatProvader: iatProvider)
- let messageSigner = MessageSignerFactory.create(projectId: projectId)
+ let messageSignerFactory = MessageSignerFactory(signerFactory: signerFactory)
+ let messageSigner = messageSignerFactory.create(projectId: projectId)
let appRespondSubscriber = AppRespondSubscriber(networkingInteractor: networkingClient, logger: logger, rpcHistory: history, signatureVerifier: messageSigner, pairingRegisterer: pairingRegisterer, messageFormatter: messageFormatter)
let walletErrorResponder = WalletErrorResponder(networkingInteractor: networkingClient, logger: logger, kms: kms, rpcHistory: history)
- let walletRequestSubscriber = WalletRequestSubscriber(networkingInteractor: networkingClient, logger: logger, kms: kms, messageFormatter: messageFormatter, address: account?.address, walletErrorResponder: walletErrorResponder, pairingRegisterer: pairingRegisterer)
+ let walletRequestSubscriber = WalletRequestSubscriber(networkingInteractor: networkingClient, logger: logger, kms: kms, walletErrorResponder: walletErrorResponder, pairingRegisterer: pairingRegisterer)
let walletRespondService = WalletRespondService(networkingInteractor: networkingClient, logger: logger, kms: kms, rpcHistory: history, walletErrorResponder: walletErrorResponder)
let pendingRequestsProvider = PendingRequestsProvider(rpcHistory: history)
- return AuthClient(appRequestService: appRequestService,
- appRespondSubscriber: appRespondSubscriber,
- walletRequestSubscriber: walletRequestSubscriber,
- walletRespondService: walletRespondService,
- account: account,
- pendingRequestsProvider: pendingRequestsProvider,
- logger: logger,
- socketConnectionStatusPublisher: networkingClient.socketConnectionStatusPublisher,
- pairingRegisterer: pairingRegisterer)
+ return AuthClient(
+ appRequestService: appRequestService,
+ appRespondSubscriber: appRespondSubscriber,
+ walletRequestSubscriber: walletRequestSubscriber,
+ walletRespondService: walletRespondService,
+ pendingRequestsProvider: pendingRequestsProvider,
+ logger: logger,
+ socketConnectionStatusPublisher: networkingClient.socketConnectionStatusPublisher,
+ pairingRegisterer: pairingRegisterer
+ )
}
}
diff --git a/Sources/Auth/AuthConfig.swift b/Sources/Auth/AuthConfig.swift
index 00a98faed..bf5c09c24 100644
--- a/Sources/Auth/AuthConfig.swift
+++ b/Sources/Auth/AuthConfig.swift
@@ -2,6 +2,6 @@ import Foundation
extension Auth {
struct Config {
- let account: Account?
+ let signerFactory: SignerFactory
}
}
diff --git a/Sources/Auth/Extensions/Data+Keccak256.swift b/Sources/Auth/Extensions/Data+Keccak256.swift
deleted file mode 100644
index 1bfbc1b8b..000000000
--- a/Sources/Auth/Extensions/Data+Keccak256.swift
+++ /dev/null
@@ -1,9 +0,0 @@
-import Foundation
-import CryptoSwift
-
-extension Data {
-
- var keccak256: Data {
- return sha3(.keccak256)
- }
-}
diff --git a/Sources/Auth/Services/App/AppRespondSubscriber.swift b/Sources/Auth/Services/App/AppRespondSubscriber.swift
index 99b8410b8..2aaaba9e9 100644
--- a/Sources/Auth/Services/App/AppRespondSubscriber.swift
+++ b/Sources/Auth/Services/App/AppRespondSubscriber.swift
@@ -49,7 +49,11 @@ class AppRespondSubscriber {
let message = try? messageFormatter.formatMessage(from: cacao.p)
else { self.onResponse?(requestId, .failure(.malformedResponseParams)); return }
- guard messageFormatter.formatMessage(from: requestPayload.payloadParams, address: address) == message
+ guard
+ let recovered = try? messageFormatter.formatMessage(
+ from: requestPayload.payloadParams,
+ address: address
+ ), recovered == message
else { self.onResponse?(requestId, .failure(.messageCompromised)); return }
Task(priority: .high) {
diff --git a/Sources/Auth/Services/Common/SIWEMessageFormatter.swift b/Sources/Auth/Services/Common/SIWEMessageFormatter.swift
index 5c69caa90..5e8c82d57 100644
--- a/Sources/Auth/Services/Common/SIWEMessageFormatter.swift
+++ b/Sources/Auth/Services/Common/SIWEMessageFormatter.swift
@@ -1,25 +1,35 @@
import Foundation
protocol SIWEMessageFormatting {
- func formatMessage(from authPayload: AuthPayload, address: String) -> String?
+ func formatMessage(from payload: AuthPayload, address: String) throws -> String
func formatMessage(from payload: CacaoPayload) throws -> String
}
-struct SIWEMessageFormatter: SIWEMessageFormatting {
- func formatMessage(from payload: AuthPayload, address: String) -> String? {
- guard let chain = Blockchain(payload.chainId) else {return nil}
- let message = SIWEMessage(domain: payload.domain,
- uri: payload.aud,
- address: address,
- version: payload.version,
- nonce: payload.nonce,
- chainId: chain.reference,
- iat: payload.iat,
- nbf: payload.nbf,
- exp: payload.exp,
- statement: payload.statement,
- requestId: payload.requestId,
- resources: payload.resources
+public struct SIWEMessageFormatter: SIWEMessageFormatting {
+
+ enum Errors: Error {
+ case invalidChainID
+ }
+
+ public init() { }
+
+ public func formatMessage(from payload: AuthPayload, address: String) throws -> String {
+ guard let chain = Blockchain(payload.chainId) else {
+ throw Errors.invalidChainID
+ }
+ let message = SIWEMessage(
+ domain: payload.domain,
+ uri: payload.aud,
+ address: address,
+ version: payload.version,
+ nonce: payload.nonce,
+ chainId: chain.reference,
+ iat: payload.iat,
+ nbf: payload.nbf,
+ exp: payload.exp,
+ statement: payload.statement,
+ requestId: payload.requestId,
+ resources: payload.resources
)
return message.formatted
}
diff --git a/Sources/Auth/Services/Signer/EIP191/EIP191Verifier.swift b/Sources/Auth/Services/Signer/EIP191/EIP191Verifier.swift
deleted file mode 100644
index 7622cae14..000000000
--- a/Sources/Auth/Services/Signer/EIP191/EIP191Verifier.swift
+++ /dev/null
@@ -1,36 +0,0 @@
-import Foundation
-import Web3
-
-actor EIP191Verifier {
-
- func verify(signature: Data, message: Data, address: String) async throws {
- let sig = decompose(signature: signature)
- let publicKey = try EthereumPublicKey.init(
- message: message.bytes,
- v: EthereumQuantity(quantity: BigUInt(sig.v)),
- r: EthereumQuantity(sig.r),
- s: EthereumQuantity(sig.s)
- )
- try verifyPublicKey(publicKey, address: address)
- }
-
- private func decompose(signature: Data) -> Signer.Signature {
- let v = signature.bytes[signature.count-1]
- let r = signature.bytes[0..<32]
- let s = signature.bytes[32..<64]
- return (UInt(v), [UInt8](r), [UInt8](s))
- }
-
- private func verifyPublicKey(_ publicKey: EthereumPublicKey, address: String) throws {
- guard publicKey.address.hex(eip55: false) == address.lowercased() else {
- throw Errors.invalidSignature
- }
- }
-}
-
-extension EIP191Verifier {
-
- enum Errors: Error {
- case invalidSignature
- }
-}
diff --git a/Sources/Auth/Services/Signer/EIP1271/EIP1271Verifier.swift b/Sources/Auth/Services/Signer/Ethereum/EIP1271/EIP1271Verifier.swift
similarity index 85%
rename from Sources/Auth/Services/Signer/EIP1271/EIP1271Verifier.swift
rename to Sources/Auth/Services/Signer/Ethereum/EIP1271/EIP1271Verifier.swift
index a3e6d527c..a3b70ae8b 100644
--- a/Sources/Auth/Services/Signer/EIP1271/EIP1271Verifier.swift
+++ b/Sources/Auth/Services/Signer/Ethereum/EIP1271/EIP1271Verifier.swift
@@ -3,14 +3,17 @@ import Foundation
actor EIP1271Verifier {
private let projectId: String
private let httpClient: HTTPClient
+ private let signer: EthereumSigner
- init(projectId: String, httpClient: HTTPClient) {
+ init(projectId: String, httpClient: HTTPClient, signer: EthereumSigner) {
self.projectId = projectId
self.httpClient = httpClient
+ self.signer = signer
}
func verify(signature: Data, message: Data, address: String, chainId: String) async throws {
- let encoder = ValidSignatureMethod(signature: signature, messageHash: message.keccak256)
+ let messageHash = signer.keccak256(message)
+ let encoder = ValidSignatureMethod(signature: signature, messageHash: messageHash)
let call = EthCall(to: address, data: encoder.encode())
let params = AnyCodable([AnyCodable(call), AnyCodable("latest")])
let request = RPCRequest(method: "eth_call", params: params)
diff --git a/Sources/Auth/Services/Signer/EIP1271/RPCService.swift b/Sources/Auth/Services/Signer/Ethereum/EIP1271/RPCService.swift
similarity index 100%
rename from Sources/Auth/Services/Signer/EIP1271/RPCService.swift
rename to Sources/Auth/Services/Signer/Ethereum/EIP1271/RPCService.swift
diff --git a/Sources/Auth/Services/Signer/EIP1271/ValidSignatureMethod.swift b/Sources/Auth/Services/Signer/Ethereum/EIP1271/ValidSignatureMethod.swift
similarity index 100%
rename from Sources/Auth/Services/Signer/EIP1271/ValidSignatureMethod.swift
rename to Sources/Auth/Services/Signer/Ethereum/EIP1271/ValidSignatureMethod.swift
diff --git a/Sources/Auth/Services/Signer/Ethereum/EIP191/EIP191Verifier.swift b/Sources/Auth/Services/Signer/Ethereum/EIP191/EIP191Verifier.swift
new file mode 100644
index 000000000..9517e0831
--- /dev/null
+++ b/Sources/Auth/Services/Signer/Ethereum/EIP191/EIP191Verifier.swift
@@ -0,0 +1,32 @@
+import Foundation
+
+actor EIP191Verifier {
+
+ let signer: EthereumSigner
+
+ init(signer: EthereumSigner) {
+ self.signer = signer
+ }
+
+ func verify(signature: Data, message: Data, address: String) async throws {
+ let sig = EthereumSignature(serialized: signature)
+ let publicKey = try signer.recoverPubKey(signature: sig, message: message)
+ try verifyPublicKey(publicKey, address: address)
+ }
+
+ private func verifyPublicKey(_ publicKey: Data, address: String) throws {
+ let recovered = "0x" + signer.keccak256(publicKey)
+ .suffix(20)
+ .toHexString()
+
+ guard recovered == address.lowercased() else {
+ throw Errors.invalidSignature
+ }
+ }
+}
+
+extension EIP191Verifier {
+ enum Errors: Error {
+ case invalidSignature
+ }
+}
diff --git a/Sources/Auth/Services/Signer/Ethereum/EthereumSignature.swift b/Sources/Auth/Services/Signer/Ethereum/EthereumSignature.swift
new file mode 100644
index 000000000..e992023ff
--- /dev/null
+++ b/Sources/Auth/Services/Signer/Ethereum/EthereumSignature.swift
@@ -0,0 +1,38 @@
+import Foundation
+
+public struct EthereumSignature {
+ public let v: UInt8
+ public let r: [UInt8]
+ public let s: [UInt8]
+
+ public init(v: UInt8, r: [UInt8], s: [UInt8]) {
+ self.v = v
+ self.r = r
+ self.s = s
+ }
+
+ public init(serialized: Data) {
+ let bytes = [UInt8](serialized)
+
+ var v = bytes[bytes.count-1]
+ if v >= 27 && v <= 30 {
+ v -= 27
+ } else if v >= 31 && v <= 34 {
+ v -= 31
+ } else if v >= 35 && v <= 38 {
+ v -= 35
+ }
+
+ self.v = v
+ self.r = [UInt8](bytes[0..<32])
+ self.s = [UInt8](bytes[32..<64])
+ }
+
+ public var serialized: Data {
+ return Data(r + s + [UInt8(v + 27)])
+ }
+
+ public func hex() -> String {
+ return "0x" + serialized.toHexString()
+ }
+}
diff --git a/Sources/Auth/Services/Signer/Ethereum/EthereumSigner.swift b/Sources/Auth/Services/Signer/Ethereum/EthereumSigner.swift
new file mode 100644
index 000000000..9865b04c3
--- /dev/null
+++ b/Sources/Auth/Services/Signer/Ethereum/EthereumSigner.swift
@@ -0,0 +1,7 @@
+import Foundation
+
+public protocol EthereumSigner {
+ func sign(message: Data, with key: Data) throws -> EthereumSignature
+ func recoverPubKey(signature: EthereumSignature, message: Data) throws -> Data
+ func keccak256(_ data: Data) -> Data
+}
diff --git a/Sources/Auth/Services/Signer/MessageSigner.swift b/Sources/Auth/Services/Signer/MessageSigner.swift
index fd4ffffbb..7af8792a2 100644
--- a/Sources/Auth/Services/Signer/MessageSigner.swift
+++ b/Sources/Auth/Services/Signer/MessageSigner.swift
@@ -1,37 +1,63 @@
import Foundation
public protocol MessageSignatureVerifying {
- func verify(signature: CacaoSignature, message: String, address: String, chainId: String) async throws
+ func verify(signature: CacaoSignature,
+ message: String,
+ address: String,
+ chainId: String
+ ) async throws
}
public protocol MessageSigning {
- func sign(message: String, privateKey: Data, type: CacaoSignatureType) throws -> CacaoSignature
+ func sign(payload: AuthPayload,
+ address: String,
+ privateKey: Data,
+ type: CacaoSignatureType
+ ) throws -> CacaoSignature
}
-struct MessageSigner: MessageSignatureVerifying, MessageSigning {
+public typealias AuthMessageSigner = MessageSignatureVerifying & MessageSigning
+
+struct MessageSigner: AuthMessageSigner {
enum Errors: Error {
case utf8EncodingFailed
}
- private let signer: Signer
+ private let signer: EthereumSigner
private let eip191Verifier: EIP191Verifier
private let eip1271Verifier: EIP1271Verifier
+ private let messageFormatter: SIWEMessageFormatting
- init(signer: Signer, eip191Verifier: EIP191Verifier, eip1271Verifier: EIP1271Verifier) {
+ init(signer: EthereumSigner, eip191Verifier: EIP191Verifier, eip1271Verifier: EIP1271Verifier, messageFormatter: SIWEMessageFormatting) {
self.signer = signer
self.eip191Verifier = eip191Verifier
self.eip1271Verifier = eip1271Verifier
+ self.messageFormatter = messageFormatter
}
- func sign(message: String, privateKey: Data, type: CacaoSignatureType) throws -> CacaoSignature {
- guard let messageData = message.data(using: .utf8) else { throw Errors.utf8EncodingFailed }
+ func sign(payload: AuthPayload,
+ address: String,
+ privateKey: Data,
+ type: CacaoSignatureType
+ ) throws -> CacaoSignature {
+
+ let message = try messageFormatter.formatMessage(from: payload, address: address)
+
+ guard let messageData = message.data(using: .utf8)else {
+ throw Errors.utf8EncodingFailed
+ }
+
let signature = try signer.sign(message: prefixed(messageData), with: privateKey)
- let prefixedHexSignature = "0x" + signature.toHexString()
- return CacaoSignature(t: type, s: prefixedHexSignature)
+ return CacaoSignature(t: type, s: signature.hex())
}
- func verify(signature: CacaoSignature, message: String, address: String, chainId: String) async throws {
+ func verify(signature: CacaoSignature,
+ message: String,
+ address: String,
+ chainId: String
+ ) async throws {
+
guard let messageData = message.data(using: .utf8) else {
throw Errors.utf8EncodingFailed
}
diff --git a/Sources/Auth/Services/Signer/MessageSignerFactory.swift b/Sources/Auth/Services/Signer/MessageSignerFactory.swift
index 85dd7d780..88d56d374 100644
--- a/Sources/Auth/Services/Signer/MessageSignerFactory.swift
+++ b/Sources/Auth/Services/Signer/MessageSignerFactory.swift
@@ -2,18 +2,26 @@ import Foundation
public struct MessageSignerFactory {
- public static func create() -> MessageSigning & MessageSignatureVerifying {
+ public let signerFactory: SignerFactory
+
+ public init(signerFactory: SignerFactory) {
+ self.signerFactory = signerFactory
+ }
+
+ public func create() -> AuthMessageSigner {
return create(projectId: Networking.projectId)
}
- static func create(projectId: String) -> MessageSigning & MessageSignatureVerifying {
+ func create(projectId: String) -> AuthMessageSigner {
return MessageSigner(
- signer: Signer(),
- eip191Verifier: EIP191Verifier(),
+ signer: signerFactory.createEthereumSigner(),
+ eip191Verifier: EIP191Verifier(signer: signerFactory.createEthereumSigner()),
eip1271Verifier: EIP1271Verifier(
projectId: projectId,
- httpClient: HTTPNetworkClient(host: "rpc.walletconnect.com")
- )
+ httpClient: HTTPNetworkClient(host: "rpc.walletconnect.com"),
+ signer: signerFactory.createEthereumSigner()
+ ),
+ messageFormatter: SIWEMessageFormatter()
)
}
}
diff --git a/Sources/Auth/Services/Signer/Signer.swift b/Sources/Auth/Services/Signer/Signer.swift
deleted file mode 100644
index cbd56ca89..000000000
--- a/Sources/Auth/Services/Signer/Signer.swift
+++ /dev/null
@@ -1,19 +0,0 @@
-import Foundation
-import Web3
-
-struct Signer {
-
- typealias Signature = (v: UInt, r: [UInt8], s: [UInt8])
-
- init() {}
-
- func sign(message: Data, with key: Data) throws -> Data {
- let privateKey = try EthereumPrivateKey(privateKey: key.bytes)
- let signature = try privateKey.sign(message: message.bytes)
- return serialized(signature: signature)
- }
-
- private func serialized(signature: Signature) -> Data {
- return Data(signature.r + signature.s + [UInt8(signature.v)])
- }
-}
diff --git a/Sources/Auth/Services/Signer/SignerFactory.swift b/Sources/Auth/Services/Signer/SignerFactory.swift
new file mode 100644
index 000000000..8f26baf15
--- /dev/null
+++ b/Sources/Auth/Services/Signer/SignerFactory.swift
@@ -0,0 +1,5 @@
+import Foundation
+
+public protocol SignerFactory {
+ func createEthereumSigner() -> EthereumSigner
+}
diff --git a/Sources/Auth/Services/Wallet/PendingRequestsProvider.swift b/Sources/Auth/Services/Wallet/PendingRequestsProvider.swift
index 35bb47265..4aa8c04c0 100644
--- a/Sources/Auth/Services/Wallet/PendingRequestsProvider.swift
+++ b/Sources/Auth/Services/Wallet/PendingRequestsProvider.swift
@@ -11,9 +11,8 @@ class PendingRequestsProvider {
let pendingRequests: [AuthRequest] = rpcHistory.getPending()
.filter {$0.request.method == "wc_authRequest"}
.compactMap {
- guard let params = try? $0.request.params?.get(AuthRequestParams.self),
- let message = SIWEMessageFormatter().formatMessage(from: params.payloadParams, address: account.address) else {return nil}
- return AuthRequest(id: $0.request.id!, message: message)
+ guard let params = try? $0.request.params?.get(AuthRequestParams.self) else { return nil }
+ return AuthRequest(id: $0.request.id!, payload: params.payloadParams)
}
return pendingRequests
}
diff --git a/Sources/Auth/Services/Wallet/WalletRequestSubscriber.swift b/Sources/Auth/Services/Wallet/WalletRequestSubscriber.swift
index d2bb83ef2..b47f1cbf2 100644
--- a/Sources/Auth/Services/Wallet/WalletRequestSubscriber.swift
+++ b/Sources/Auth/Services/Wallet/WalletRequestSubscriber.swift
@@ -5,44 +5,34 @@ class WalletRequestSubscriber {
private let networkingInteractor: NetworkInteracting
private let logger: ConsoleLogging
private let kms: KeyManagementServiceProtocol
- private let address: String?
private var publishers = [AnyCancellable]()
- private let messageFormatter: SIWEMessageFormatting
private let walletErrorResponder: WalletErrorResponder
private let pairingRegisterer: PairingRegisterer
var onRequest: ((AuthRequest) -> Void)?
- init(networkingInteractor: NetworkInteracting,
- logger: ConsoleLogging,
- kms: KeyManagementServiceProtocol,
- messageFormatter: SIWEMessageFormatting,
- address: String?,
- walletErrorResponder: WalletErrorResponder,
- pairingRegisterer: PairingRegisterer) {
+ init(
+ networkingInteractor: NetworkInteracting,
+ logger: ConsoleLogging,
+ kms: KeyManagementServiceProtocol,
+ walletErrorResponder: WalletErrorResponder,
+ pairingRegisterer: PairingRegisterer)
+ {
self.networkingInteractor = networkingInteractor
self.logger = logger
self.kms = kms
- self.address = address
- self.messageFormatter = messageFormatter
self.walletErrorResponder = walletErrorResponder
self.pairingRegisterer = pairingRegisterer
subscribeForRequest()
}
private func subscribeForRequest() {
- guard let address = address else { return }
-
pairingRegisterer.register(method: AuthRequestProtocolMethod())
.sink { [unowned self] (payload: RequestSubscriptionPayload) in
logger.debug("WalletRequestSubscriber: Received request")
- guard let message = messageFormatter.formatMessage(from: payload.request.payloadParams, address: address) else {
- Task(priority: .high) {
- try? await walletErrorResponder.respondError(AuthError.malformedRequestParams, requestId: payload.id)
- }
- return
- }
pairingRegisterer.activate(pairingTopic: payload.topic)
- onRequest?(.init(id: payload.id, message: message))
+
+ let request = AuthRequest(id: payload.id, payload: payload.request.payloadParams)
+ onRequest?(request)
}.store(in: &publishers)
}
}
diff --git a/Sources/Auth/Types/AuthPayload.swift b/Sources/Auth/Types/AuthPayload.swift
index 1329f5265..621df1ea3 100644
--- a/Sources/Auth/Types/AuthPayload.swift
+++ b/Sources/Auth/Types/AuthPayload.swift
@@ -1,18 +1,18 @@
import Foundation
-struct AuthPayload: Codable, Equatable {
- let domain: String
- let aud: String
- let version: String
- let nonce: String
- let chainId: String
- let type: String
- let iat: String
- let nbf: String?
- let exp: String?
- let statement: String?
- let requestId: String?
- let resources: [String]?
+public struct AuthPayload: 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"
diff --git a/Sources/Auth/Types/Public/AuthRequest.swift b/Sources/Auth/Types/Public/AuthRequest.swift
index f431ccb4d..b5095751c 100644
--- a/Sources/Auth/Types/Public/AuthRequest.swift
+++ b/Sources/Auth/Types/Public/AuthRequest.swift
@@ -2,6 +2,5 @@ import Foundation
public struct AuthRequest: Equatable, Codable {
public let id: RPCID
- /// EIP-4361: Sign-In with Ethereum message
- public let message: String
+ public let payload: AuthPayload
}
diff --git a/Sources/WalletConnectRelay/PackageConfig.json b/Sources/WalletConnectRelay/PackageConfig.json
index 4a5b368a0..48f893bf2 100644
--- a/Sources/WalletConnectRelay/PackageConfig.json
+++ b/Sources/WalletConnectRelay/PackageConfig.json
@@ -1 +1 @@
-{"version": "1.0.6"}
+{"version": "1.1.0"}
diff --git a/Sources/WalletConnectUtils/Data+Extension.swift b/Sources/WalletConnectUtils/Data+Extension.swift
deleted file mode 100644
index 88624109f..000000000
--- a/Sources/WalletConnectUtils/Data+Extension.swift
+++ /dev/null
@@ -1,56 +0,0 @@
-import Foundation
-
-// MARK: - Random data generation
-
-extension Data {
-
- public static func randomBytes(count: Int) -> Data {
- var buffer = [UInt8](repeating: 0, count: count)
- let status = SecRandomCopyBytes(kSecRandomDefault, count, &buffer)
- guard status == errSecSuccess else {
- fatalError("Failed to generate secure random data of size \(count).")
- }
- return Data(buffer)
- }
-}
-
-// MARK: - Hexadecimal string conversion
-
-extension Data {
-
- static func value(of nibble: UInt8) -> UInt8? {
- guard let letter = String(bytes: [nibble], encoding: .ascii) else { return nil }
- return UInt8(letter, radix: 16)
- }
-
- public init(hex: String) {
- var data = Data()
- let string = hex.hasPrefix("0x") ? String(hex.dropFirst(2)) : hex
-
- // Convert the string to bytes for better performance
- guard
- let stringData = string.data(using: .ascii, allowLossyConversion: true)
- else {
- self = data
- return
- }
-
- let stringBytes = Array(stringData)
- for idx in stride(from: 0, to: stringBytes.count, by: 2) {
- guard let high = Data.value(of: stringBytes[idx]) else {
- data.removeAll()
- break
- }
- if idx < stringBytes.count - 1, let low = Data.value(of: stringBytes[idx + 1]) {
- data.append((high << 4) | low)
- } else {
- data.append(high)
- }
- }
- self = data
- }
-
- public func toHexString() -> String {
- return map({ String(format: "%02x", $0) }).joined()
- }
-}
diff --git a/Sources/WalletConnectUtils/Extensions/Data.swift b/Sources/WalletConnectUtils/Extensions/Data.swift
index 90236854f..88624109f 100644
--- a/Sources/WalletConnectUtils/Extensions/Data.swift
+++ b/Sources/WalletConnectUtils/Extensions/Data.swift
@@ -1,8 +1,56 @@
import Foundation
-public extension UInt8 {
- var data: Data {
- var int = self
- return Data(bytes: &int, count: MemoryLayout.size)
+// MARK: - Random data generation
+
+extension Data {
+
+ public static func randomBytes(count: Int) -> Data {
+ var buffer = [UInt8](repeating: 0, count: count)
+ let status = SecRandomCopyBytes(kSecRandomDefault, count, &buffer)
+ guard status == errSecSuccess else {
+ fatalError("Failed to generate secure random data of size \(count).")
+ }
+ return Data(buffer)
+ }
+}
+
+// MARK: - Hexadecimal string conversion
+
+extension Data {
+
+ static func value(of nibble: UInt8) -> UInt8? {
+ guard let letter = String(bytes: [nibble], encoding: .ascii) else { return nil }
+ return UInt8(letter, radix: 16)
+ }
+
+ public init(hex: String) {
+ var data = Data()
+ let string = hex.hasPrefix("0x") ? String(hex.dropFirst(2)) : hex
+
+ // Convert the string to bytes for better performance
+ guard
+ let stringData = string.data(using: .ascii, allowLossyConversion: true)
+ else {
+ self = data
+ return
+ }
+
+ let stringBytes = Array(stringData)
+ for idx in stride(from: 0, to: stringBytes.count, by: 2) {
+ guard let high = Data.value(of: stringBytes[idx]) else {
+ data.removeAll()
+ break
+ }
+ if idx < stringBytes.count - 1, let low = Data.value(of: stringBytes[idx + 1]) {
+ data.append((high << 4) | low)
+ } else {
+ data.append(high)
+ }
+ }
+ self = data
+ }
+
+ public func toHexString() -> String {
+ return map({ String(format: "%02x", $0) }).joined()
}
}
diff --git a/Sources/WalletConnectUtils/Extensions/String+Extension.swift b/Sources/WalletConnectUtils/Extensions/String+CAIPs.swift
similarity index 100%
rename from Sources/WalletConnectUtils/Extensions/String+Extension.swift
rename to Sources/WalletConnectUtils/Extensions/String+CAIPs.swift
diff --git a/Sources/WalletConnectUtils/Extensions/UInt8.swift b/Sources/WalletConnectUtils/Extensions/UInt8.swift
new file mode 100644
index 000000000..c147c544f
--- /dev/null
+++ b/Sources/WalletConnectUtils/Extensions/UInt8.swift
@@ -0,0 +1,15 @@
+import Foundation
+
+public extension UInt8 {
+ var data: Data {
+ var int = self
+ return Data(bytes: &int, count: MemoryLayout.size)
+ }
+}
+
+public extension Array where Element == UInt8 {
+
+ func toHexString() -> String {
+ return Data(self).toHexString()
+ }
+}
diff --git a/Sources/WalletConnectVerify/AppAttestationRegistrer.swift b/Sources/WalletConnectVerify/AppAttestationRegistrer.swift
new file mode 100644
index 000000000..04e7cd819
--- /dev/null
+++ b/Sources/WalletConnectVerify/AppAttestationRegistrer.swift
@@ -0,0 +1,49 @@
+import Foundation
+import DeviceCheck
+import WalletConnectUtils
+import CryptoKit
+
+
+@available(iOS 14.0, *)
+@available(macOS 11.0, *)
+class AppAttestationRegistrer {
+ private let logger: ConsoleLogging
+ private let keyIdStorage: CodableStore
+
+ let attestKeyGenerator: AttestKeyGenerating
+ let attestChallengeProvider: AttestChallengeProviding
+ let keyAttestationService: KeyAttesting
+
+ init(logger: ConsoleLogging,
+ keyIdStorage: CodableStore,
+ attestKeyGenerator: AttestKeyGenerating,
+ attestChallengeProvider: AttestChallengeProviding,
+ keyAttestationService: KeyAttesting
+ ) {
+ self.logger = logger
+ self.keyIdStorage = keyIdStorage
+ self.attestKeyGenerator = attestKeyGenerator
+ self.attestChallengeProvider = attestChallengeProvider
+ self.keyAttestationService = keyAttestationService
+ }
+
+ func registerAttestationIfNeeded() async throws {
+ if let _ = try? keyIdStorage.get(key: Constants.keyIdStorageKey) { return }
+ let keyId = try await generateKeys()
+ let challenge = try await getChallenge()
+ let hash = Data(SHA256.hash(data: challenge))
+ try await attestKey(keyId: keyId, clientDataHash: hash)
+ }
+
+ private func generateKeys() async throws -> String {
+ try await attestKeyGenerator.generateKeys()
+ }
+
+ private func getChallenge() async throws -> Data {
+ try await attestChallengeProvider.getChallenge()
+ }
+
+ private func attestKey(keyId: String, clientDataHash: Data) async throws {
+ try await keyAttestationService.attestKey(keyId: keyId, clientDataHash: clientDataHash)
+ }
+}
diff --git a/Sources/WalletConnectVerify/AssertionRegistrer.swift b/Sources/WalletConnectVerify/AssertionRegistrer.swift
new file mode 100644
index 000000000..2cf2289ad
--- /dev/null
+++ b/Sources/WalletConnectVerify/AssertionRegistrer.swift
@@ -0,0 +1,6 @@
+
+import Foundation
+
+class AssertionRegistrer {
+ func registerAssertion() async throws {}
+}
diff --git a/Sources/WalletConnectVerify/AttestChallengeProvider.swift b/Sources/WalletConnectVerify/AttestChallengeProvider.swift
new file mode 100644
index 000000000..5d2891e67
--- /dev/null
+++ b/Sources/WalletConnectVerify/AttestChallengeProvider.swift
@@ -0,0 +1,12 @@
+import Foundation
+
+protocol AttestChallengeProviding {
+ func getChallenge() async throws -> Data
+}
+
+class AttestChallengeProvider: AttestChallengeProviding {
+ func getChallenge() async throws -> Data {
+ return Data()
+ fatalError("not implemented")
+ }
+}
diff --git a/Sources/WalletConnectVerify/AttestKeyGenerator.swift b/Sources/WalletConnectVerify/AttestKeyGenerator.swift
new file mode 100644
index 000000000..166d84a01
--- /dev/null
+++ b/Sources/WalletConnectVerify/AttestKeyGenerator.swift
@@ -0,0 +1,29 @@
+import DeviceCheck
+import Foundation
+import WalletConnectUtils
+
+protocol AttestKeyGenerating {
+ func generateKeys() async throws -> String
+}
+
+@available(iOS 14.0, *)
+@available(macOS 11.0, *)
+class AttestKeyGenerator: AttestKeyGenerating {
+ private let service = DCAppAttestService.shared
+ private let logger: ConsoleLogging
+ private let keyIdStorage: CodableStore
+
+
+ init(logger: ConsoleLogging,
+ keyIdStorage: CodableStore
+ ) {
+ self.logger = logger
+ self.keyIdStorage = keyIdStorage
+ }
+
+ func generateKeys() async throws -> String {
+ let keyId = try await service.generateKey()
+ keyIdStorage.set(keyId, forKey: Constants.keyIdStorageKey)
+ return keyId
+ }
+}
diff --git a/Sources/WalletConnectVerify/Constants.swift b/Sources/WalletConnectVerify/Constants.swift
new file mode 100644
index 000000000..47e31f2ab
--- /dev/null
+++ b/Sources/WalletConnectVerify/Constants.swift
@@ -0,0 +1,5 @@
+import Foundation
+
+enum Constants {
+ static let keyIdStorageKey = "attested_key_id"
+}
diff --git a/Sources/WalletConnectVerify/KeyAttestationService.swift b/Sources/WalletConnectVerify/KeyAttestationService.swift
new file mode 100644
index 000000000..ce0833d81
--- /dev/null
+++ b/Sources/WalletConnectVerify/KeyAttestationService.swift
@@ -0,0 +1,26 @@
+import Foundation
+import DeviceCheck
+
+protocol KeyAttesting {
+ func attestKey(keyId: String, clientDataHash: Data) async throws
+}
+
+@available(iOS 14.0, *)
+@available(macOS 11.0, *)
+class KeyAttestationService: KeyAttesting {
+ private let service = DCAppAttestService.shared
+ // If the method, which accesses a remote Apple server, returns the serverUnavailable error,
+ // try attestation again later with the same key. For any other error,
+ //discard the key identifier and create a new key when you want to try again.
+ //Otherwise, send the completion handler’s attestation object and the keyId to your server for processing.
+ func attestKey(keyId: String, clientDataHash: Data) async throws {
+
+ try await service.attestKey(keyId, clientDataHash: clientDataHash)
+ //TODO - Send the attestation object to your server for verification. handle errors
+
+ }
+
+ private func sendAttestationToVerifyServer() async throws {
+
+ }
+}
diff --git a/Sources/WalletConnectVerify/OriginVerifier.swift b/Sources/WalletConnectVerify/OriginVerifier.swift
new file mode 100644
index 000000000..de33c5fff
--- /dev/null
+++ b/Sources/WalletConnectVerify/OriginVerifier.swift
@@ -0,0 +1,7 @@
+
+import Foundation
+
+class OriginVerifier {
+ func verifyOrigin() async throws {}
+}
+
diff --git a/Sources/WalletConnectVerify/VerifyClient.swift b/Sources/WalletConnectVerify/VerifyClient.swift
new file mode 100644
index 000000000..0936d9da0
--- /dev/null
+++ b/Sources/WalletConnectVerify/VerifyClient.swift
@@ -0,0 +1,38 @@
+import DeviceCheck
+import Foundation
+import WalletConnectUtils
+
+@available(iOS 14.0, *)
+@available(macOS 11.0, *)
+public actor VerifyClient {
+ enum Errors: Error {
+ case attestationNotSupported
+ }
+ let originVerifier: OriginVerifier
+ let assertionRegistrer: AssertionRegistrer
+ let appAttestationRegistrer: AppAttestationRegistrer
+
+ init(originVerifier: OriginVerifier,
+ assertionRegistrer: AssertionRegistrer,
+ appAttestationRegistrer: AppAttestationRegistrer) throws {
+ if !DCAppAttestService.shared.isSupported {
+ throw Errors.attestationNotSupported
+ }
+ self.originVerifier = originVerifier
+ self.assertionRegistrer = assertionRegistrer
+ self.appAttestationRegistrer = appAttestationRegistrer
+ }
+
+ public func registerAttestationIfNeeded() async throws {
+ try await appAttestationRegistrer.registerAttestationIfNeeded()
+ }
+
+ public func verifyOrigin() async throws {
+ try await originVerifier.verifyOrigin()
+ }
+
+ public func registerAssertion() async throws {
+ try await assertionRegistrer.registerAssertion()
+ }
+
+}
diff --git a/Sources/WalletConnectVerify/VerifyClientFactory.swift b/Sources/WalletConnectVerify/VerifyClientFactory.swift
new file mode 100644
index 000000000..7554a3189
--- /dev/null
+++ b/Sources/WalletConnectVerify/VerifyClientFactory.swift
@@ -0,0 +1,24 @@
+import Foundation
+import WalletConnectUtils
+
+@available(iOS 14.0, *)
+@available(macOS 11.0, *)
+public class VerifyClientFactory {
+
+ public static func create() throws -> VerifyClient {
+ let originVerifier = OriginVerifier()
+ let assertionRegistrer = AssertionRegistrer()
+ let logger = ConsoleLogger(loggingLevel: .off)
+ let keyValueStorage = UserDefaults.standard
+ let keyIdStorage = CodableStore(defaults: keyValueStorage, identifier: VerifyStorageIdentifier.keyId)
+ let attestKeyGenerator = AttestKeyGenerator(logger: logger, keyIdStorage: keyIdStorage)
+ let attestChallengeProvider = AttestChallengeProvider()
+ let keyAttestationService = KeyAttestationService()
+ let appAttestationRegistrer = AppAttestationRegistrer(logger: logger,
+ keyIdStorage: keyIdStorage,
+ attestKeyGenerator: attestKeyGenerator,
+ attestChallengeProvider: attestChallengeProvider,
+ keyAttestationService: keyAttestationService)
+ return try VerifyClient(originVerifier: originVerifier, assertionRegistrer: assertionRegistrer, appAttestationRegistrer: appAttestationRegistrer)
+ }
+}
diff --git a/Sources/WalletConnectVerify/VerifyStorageIdentifier.swift b/Sources/WalletConnectVerify/VerifyStorageIdentifier.swift
new file mode 100644
index 000000000..18b6484dd
--- /dev/null
+++ b/Sources/WalletConnectVerify/VerifyStorageIdentifier.swift
@@ -0,0 +1,5 @@
+import Foundation
+
+enum VerifyStorageIdentifier {
+ static let keyId = "com.walletconnect.sdk.keyId"
+}
diff --git a/Tests/AuthTests/AppRespondSubscriberTests.swift b/Tests/AuthTests/AppRespondSubscriberTests.swift
index 07492323e..72f3f4f51 100644
--- a/Tests/AuthTests/AppRespondSubscriberTests.swift
+++ b/Tests/AuthTests/AppRespondSubscriberTests.swift
@@ -8,21 +8,20 @@ import XCTest
import JSONRPC
class AppRespondSubscriberTests: XCTestCase {
+
var networkingInteractor: NetworkingInteractorMock!
var sut: AppRespondSubscriber!
var messageFormatter: SIWEMessageFormatter!
var rpcHistory: RPCHistory!
let defaultTimeout: TimeInterval = 0.01
- let walletAccount = Account(chainIdentifier: "eip155:1", address: "0x724d0D2DaD3fbB0C168f947B87Fa5DBe36F1A8bf")!
- let prvKey = Data(hex: "462c1dad6832d7d96ccf87bd6a686a4110e114aaaebd5512e552c0e3a87b480f")
- var messageSigner: (MessageSigning & MessageSignatureVerifying)!
+ var messageSigner: AuthMessageSigner!
var pairingStorage: WCPairingStorageMock!
var pairingRegisterer: PairingRegistererMock!
override func setUp() {
networkingInteractor = NetworkingInteractorMock()
messageFormatter = SIWEMessageFormatter()
- messageSigner = MessageSignerFactory.create(projectId: "project-id")
+ messageSigner = MessageSignerMock()
rpcHistory = RPCHistoryFactory.createForNetwork(keyValueStorage: RuntimeKeyValueStorage())
pairingStorage = WCPairingStorageMock()
pairingRegisterer = PairingRegistererMock()
@@ -41,6 +40,12 @@ class AppRespondSubscriberTests: XCTestCase {
// set history record for a request
let topic = "topic"
let requestId: RPCID = RPCID(1234)
+
+ let params = AuthRequestParams.stub()
+ let compromissedParams = AuthRequestParams.stub(nonce: "Compromissed nonce")
+
+ XCTAssertNotEqual(params.payloadParams, compromissedParams.payloadParams)
+
let request = RPCRequest(method: "wc_authRequest", params: AuthRequestParams.stub(), id: requestId.right!)
try! rpcHistory.set(request, forTopic: topic, emmitedBy: .local)
@@ -53,13 +58,12 @@ class AppRespondSubscriberTests: XCTestCase {
}
// subscribe on compromised cacao
- let header = CacaoHeader(t: "eip4361")
- let payload = CacaoPayload(params: AuthPayload.stub(nonce: "compromised nonce"), didpkh: DIDPKH(account: walletAccount))
-
- let message = try! messageFormatter.formatMessage(from: payload)
- let cacaoSignature = try! messageSigner.sign(message: message, privateKey: prvKey, type: .eip191)
+ let account = Account(chainIdentifier: "eip155:1", address: "0x724d0D2DaD3fbB0C168f947B87Fa5DBe36F1A8bf")!
+ let cacaoHeader = CacaoHeader(t: "eip4361")
+ let cacaoPayload = CacaoPayload(params: compromissedParams.payloadParams, didpkh: DIDPKH(account: account))
+ let cacaoSignature = CacaoSignature(t: .eip191, s: "")
- let cacao = Cacao(h: header, p: payload, s: cacaoSignature)
+ let cacao = Cacao(h: cacaoHeader, p: cacaoPayload, s: cacaoSignature)
let response = RPCResponse(id: requestId, result: cacao)
networkingInteractor.responsePublisherSubject.send((topic, request, response))
diff --git a/Tests/AuthTests/EIP1271VerifierTests.swift b/Tests/AuthTests/EIP1271VerifierTests.swift
deleted file mode 100644
index 796c146ff..000000000
--- a/Tests/AuthTests/EIP1271VerifierTests.swift
+++ /dev/null
@@ -1,38 +0,0 @@
-import Foundation
-import XCTest
-@testable import Auth
-import JSONRPC
-import TestingUtils
-
-class EIP1271VerifierTests: XCTestCase {
-
- let signature = Data(hex: "c1505719b2504095116db01baaf276361efd3a73c28cf8cc28dabefa945b8d536011289ac0a3b048600c1e692ff173ca944246cf7ceb319ac2262d27b395c82b1c")
- let message = Data(hex: "3aaa8393796c7388e4e062861d8238503de7584c977676fe9d8d551c30e11f84")
- let address = "0x2faf83c542b68f1b4cdc0e770e8cb9f567b08f71"
- let chainId = "eip155:1"
-
- func testSuccessVerify() async throws {
- let response = RPCResponse(id: "1", result: "0x1626ba7e00000000000000000000000000000000000000000000000000000000")
- let httpClient = HTTPClientMock(object: response)
- let verifier = EIP1271Verifier(projectId: "project-id", httpClient: httpClient)
- try await verifier.verify(
- signature: signature,
- message: message,
- address: address,
- chainId: chainId
- )
- }
-
- func testFailureVerify() async throws {
- let response = RPCResponse(id: "1", error: .internalError)
- let httpClient = HTTPClientMock(object: response)
- let verifier = EIP1271Verifier(projectId: "project-id", httpClient: httpClient)
-
- await XCTAssertThrowsErrorAsync(try await verifier.verify(
- signature: signature,
- message: message,
- address: address,
- chainId: chainId
- ))
- }
-}
diff --git a/Tests/AuthTests/Mocks/SIWEMessageFormatterMock.swift b/Tests/AuthTests/Mocks/SIWEMessageFormatterMock.swift
index e15d682be..64adc7c96 100644
--- a/Tests/AuthTests/Mocks/SIWEMessageFormatterMock.swift
+++ b/Tests/AuthTests/Mocks/SIWEMessageFormatterMock.swift
@@ -4,7 +4,7 @@ import Foundation
class SIWEMessageFormatterMock: SIWEMessageFormatting {
var formattedMessage: String!
- func formatMessage(from authPayload: AuthPayload, address: String) -> String? {
+ func formatMessage(from authPayload: AuthPayload, address: String) throws -> String {
return formattedMessage
}
diff --git a/Tests/AuthTests/Mocks/SignerFactoryMock.swift b/Tests/AuthTests/Mocks/SignerFactoryMock.swift
new file mode 100644
index 000000000..f8110b951
--- /dev/null
+++ b/Tests/AuthTests/Mocks/SignerFactoryMock.swift
@@ -0,0 +1,24 @@
+import Foundation
+import Auth
+
+struct SignerFactoryMock: SignerFactory {
+
+ func createEthereumSigner() -> EthereumSigner {
+ return EthereumSignerMock()
+ }
+}
+
+struct EthereumSignerMock: EthereumSigner {
+
+ func sign(message: Data, with key: Data) throws -> EthereumSignature {
+ return EthereumSignature(v: 0, r: [], s: [])
+ }
+
+ func recoverPubKey(signature: EthereumSignature, message: Data) throws -> Data {
+ return Data()
+ }
+
+ func keccak256(_ data: Data) -> Data {
+ return Data()
+ }
+}
diff --git a/Tests/AuthTests/SIWEMessageFormatterTests.swift b/Tests/AuthTests/SIWEMessageFormatterTests.swift
index 1b14c21a4..859b2cf41 100644
--- a/Tests/AuthTests/SIWEMessageFormatterTests.swift
+++ b/Tests/AuthTests/SIWEMessageFormatterTests.swift
@@ -10,7 +10,7 @@ class SIWEMessageFormatterTests: XCTestCase {
sut = SIWEMessageFormatter()
}
- func testFormatMessage() {
+ func testFormatMessage() throws {
let expectedMessage =
"""
service.invalid wants you to sign in with your Ethereum account:
@@ -27,11 +27,11 @@ class SIWEMessageFormatterTests: XCTestCase {
- ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/
- https://example.com/my-web2-claim.json
"""
- let message = sut.formatMessage(from: AuthPayload.stub(), address: address)
+ let message = try sut.formatMessage(from: AuthPayload.stub(), address: address)
XCTAssertEqual(message, expectedMessage)
}
- func testNilStatement() {
+ func testNilStatement() throws {
let expectedMessage =
"""
service.invalid wants you to sign in with your Ethereum account:
@@ -46,14 +46,14 @@ class SIWEMessageFormatterTests: XCTestCase {
- ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/
- https://example.com/my-web2-claim.json
"""
- let message = sut.formatMessage(
+ let message = try sut.formatMessage(
from: AuthPayload.stub(
requestParams: RequestParams.stub(statement: nil)),
address: address)
XCTAssertEqual(message, expectedMessage)
}
- func testNilResources() {
+ func testNilResources() throws {
let expectedMessage =
"""
service.invalid wants you to sign in with your Ethereum account:
@@ -67,14 +67,14 @@ class SIWEMessageFormatterTests: XCTestCase {
Nonce: 32891756
Issued At: 2021-09-30T16:25:24Z
"""
- let message = sut.formatMessage(
+ let message = try sut.formatMessage(
from: AuthPayload.stub(
requestParams: RequestParams.stub(resources: nil)),
address: address)
XCTAssertEqual(message, expectedMessage)
}
- func testNilAllOptionalParams() {
+ func testNilAllOptionalParams() throws {
let expectedMessage =
"""
service.invalid wants you to sign in with your Ethereum account:
@@ -86,7 +86,7 @@ class SIWEMessageFormatterTests: XCTestCase {
Nonce: 32891756
Issued At: 2021-09-30T16:25:24Z
"""
- let message = sut.formatMessage(
+ let message = try sut.formatMessage(
from: AuthPayload.stub(
requestParams: RequestParams.stub(statement: nil,
resources: nil)),
diff --git a/Tests/AuthTests/Stubs/MessageSignerMock.swift b/Tests/AuthTests/Stubs/MessageSignerMock.swift
new file mode 100644
index 000000000..4275cd1b9
--- /dev/null
+++ b/Tests/AuthTests/Stubs/MessageSignerMock.swift
@@ -0,0 +1,21 @@
+import Foundation
+import Auth
+
+struct MessageSignerMock: AuthMessageSigner {
+
+ func verify(signature: CacaoSignature,
+ message: String,
+ address: String,
+ chainId: String
+ ) async throws {
+
+ }
+
+ func sign(payload: AuthPayload,
+ address: String,
+ privateKey: Data,
+ type: CacaoSignatureType
+ ) throws -> CacaoSignature {
+ return CacaoSignature(t: .eip191, s: "")
+ }
+}
diff --git a/Tests/AuthTests/Stubs/RequestSubscriptionPayload.swift b/Tests/AuthTests/Stubs/RequestSubscriptionPayload.swift
index 7944b241b..baf9546bf 100644
--- a/Tests/AuthTests/Stubs/RequestSubscriptionPayload.swift
+++ b/Tests/AuthTests/Stubs/RequestSubscriptionPayload.swift
@@ -4,11 +4,10 @@ import WalletConnectNetworking
@testable import Auth
extension AuthRequestParams {
- static func stub(id: RPCID) -> AuthRequestParams {
+ static func stub(id: RPCID, iat: String) -> AuthRequestParams {
let appMetadata = AppMetadata(name: "", description: "", url: "", icons: [])
let requester = AuthRequestParams.Requester(publicKey: "", metadata: appMetadata)
- let issueAt = ISO8601DateFormatter().string(from: Date())
- let payload = AuthPayload(requestParams: RequestParams.stub(), iat: issueAt)
+ let payload = AuthPayload(requestParams: RequestParams.stub(), iat: iat)
return AuthRequestParams(requester: requester, payloadParams: payload)
}
}
diff --git a/Tests/AuthTests/WalletRequestSubscriberTests.swift b/Tests/AuthTests/WalletRequestSubscriberTests.swift
index de7dbe28d..d94567432 100644
--- a/Tests/AuthTests/WalletRequestSubscriberTests.swift
+++ b/Tests/AuthTests/WalletRequestSubscriberTests.swift
@@ -23,31 +23,31 @@ class WalletRequestSubscriberTests: XCTestCase {
sut = WalletRequestSubscriber(networkingInteractor: networkingInteractor,
logger: ConsoleLoggerMock(),
kms: KeyManagementServiceMock(),
- messageFormatter: messageFormatter, address: "",
walletErrorResponder: walletErrorResponder,
pairingRegisterer: pairingRegisterer)
}
func testSubscribeRequest() {
- let expectedMessage = "Expected Message"
+ let iat = ISO8601DateFormatter().string(from: Date())
+ let expectedPayload = AuthPayload(requestParams: .stub(), iat: iat)
let expectedRequestId: RPCID = RPCID(1234)
let messageExpectation = expectation(description: "receives formatted message")
- messageFormatter.formattedMessage = expectedMessage
- var messageId: RPCID!
- var message: String!
+
+ var requestId: RPCID!
+ var requestPayload: AuthPayload!
sut.onRequest = { request in
- messageId = request.id
- message = request.message
+ requestId = request.id
+ requestPayload = request.payload
messageExpectation.fulfill()
}
- let payload = RequestSubscriptionPayload(id: expectedRequestId, topic: "123", request: AuthRequestParams.stub(id: expectedRequestId))
+ let payload = RequestSubscriptionPayload(id: expectedRequestId, topic: "123", request: AuthRequestParams.stub(id: expectedRequestId, iat: iat))
pairingRegisterer.subject.send(payload)
wait(for: [messageExpectation], timeout: defaultTimeout)
XCTAssertTrue(pairingRegisterer.isActivateCalled)
- XCTAssertEqual(message, expectedMessage)
- XCTAssertEqual(messageId, expectedRequestId)
+ XCTAssertEqual(requestPayload, expectedPayload)
+ XCTAssertEqual(requestId, expectedRequestId)
}
}
diff --git a/Tests/VerifyTests/AppAttestationRegistrerTests.swift b/Tests/VerifyTests/AppAttestationRegistrerTests.swift
new file mode 100644
index 000000000..e1e81bc40
--- /dev/null
+++ b/Tests/VerifyTests/AppAttestationRegistrerTests.swift
@@ -0,0 +1,47 @@
+
+import Foundation
+import XCTest
+import WalletConnectUtils
+import TestingUtils
+@testable import WalletConnectVerify
+
+@available(iOS 14.0, *)
+@available(macOS 11.0, *)
+class AppAttestationRegistrerTests: XCTestCase {
+ var attestKeyGenerator: AttestKeyGeneratingMock!
+ var attestChallengeProvider: AttestChallengeProvidingMock!
+ var keyAttestationService: KeyAttestingMock!
+ var sut: AppAttestationRegistrer!
+ var keyIdStorage: CodableStore!
+
+ override func setUp() {
+ let kvStorage = RuntimeKeyValueStorage()
+
+ keyIdStorage = CodableStore(defaults: kvStorage, identifier: "")
+ attestKeyGenerator = AttestKeyGeneratingMock()
+ attestChallengeProvider = AttestChallengeProvidingMock()
+ keyAttestationService = KeyAttestingMock()
+
+ sut = AppAttestationRegistrer(
+ logger: ConsoleLoggerMock(),
+ keyIdStorage: keyIdStorage,
+ attestKeyGenerator: attestKeyGenerator,
+ attestChallengeProvider: attestChallengeProvider,
+ keyAttestationService: keyAttestationService)
+ }
+
+ func testAttestation() async {
+ try! await sut.registerAttestationIfNeeded()
+ XCTAssertTrue(attestKeyGenerator.keysGenerated)
+ XCTAssertTrue(attestChallengeProvider.challengeProvided)
+ XCTAssertTrue(keyAttestationService.keyAttested)
+ }
+
+ func testAttestationAlreadyRegistered() async {
+ keyIdStorage.set("123", forKey: "attested_key_id")
+ try! await sut.registerAttestationIfNeeded()
+ XCTAssertFalse(attestKeyGenerator.keysGenerated)
+ XCTAssertFalse(attestChallengeProvider.challengeProvided)
+ XCTAssertFalse(keyAttestationService.keyAttested)
+ }
+}
diff --git a/Tests/VerifyTests/Mocks/AttestChallengeProvidingMock.swift b/Tests/VerifyTests/Mocks/AttestChallengeProvidingMock.swift
new file mode 100644
index 000000000..1bc958055
--- /dev/null
+++ b/Tests/VerifyTests/Mocks/AttestChallengeProvidingMock.swift
@@ -0,0 +1,11 @@
+
+import Foundation
+@testable import WalletConnectVerify
+
+class AttestChallengeProvidingMock: AttestChallengeProviding {
+ var challengeProvided = false
+ func getChallenge() async throws -> Data {
+ challengeProvided = true
+ return Data()
+ }
+}
diff --git a/Tests/VerifyTests/Mocks/AttestKeyGeneratingMock.swift b/Tests/VerifyTests/Mocks/AttestKeyGeneratingMock.swift
new file mode 100644
index 000000000..a44916d56
--- /dev/null
+++ b/Tests/VerifyTests/Mocks/AttestKeyGeneratingMock.swift
@@ -0,0 +1,12 @@
+
+import Foundation
+@testable import WalletConnectVerify
+
+
+class AttestKeyGeneratingMock: AttestKeyGenerating {
+ var keysGenerated = false
+ func generateKeys() async throws -> String {
+ keysGenerated = true
+ return ""
+ }
+}
diff --git a/Tests/VerifyTests/Mocks/KeyAttestingMock.swift b/Tests/VerifyTests/Mocks/KeyAttestingMock.swift
new file mode 100644
index 000000000..d68057125
--- /dev/null
+++ b/Tests/VerifyTests/Mocks/KeyAttestingMock.swift
@@ -0,0 +1,9 @@
+@testable import WalletConnectVerify
+import Foundation
+
+class KeyAttestingMock: KeyAttesting {
+ var keyAttested = false
+ func attestKey(keyId: String, clientDataHash: Data) async throws {
+ keyAttested = true
+ }
+}
diff --git a/WalletConnectSwiftV2.podspec b/WalletConnectSwiftV2.podspec
index 256509ece..881bfe09c 100644
--- a/WalletConnectSwiftV2.podspec
+++ b/WalletConnectSwiftV2.podspec
@@ -82,7 +82,6 @@ Pod::Spec.new do |spec|
spec.subspec 'WalletConnectAuth' do |ss|
ss.source_files = 'Sources/Auth/**/*'
ss.dependency 'WalletConnectSwiftV2/WalletConnectPairing'
- ss.dependency "WalletConnectWeb3", "1.0.1"
end
spec.subspec 'WalletConnectChat' do |ss|