From 22dc120fd89c38f152f9442ec5070a7f600c3a31 Mon Sep 17 00:00:00 2001 From: Dimitar Nestorov <8790386+dimitarnestorov@users.noreply.github.com> Date: Sat, 8 Jan 2022 21:47:41 +0200 Subject: [PATCH 1/2] Add support for `eth_signTypedData_v3` and `eth_signTypedData_v4` --- Sources/SafariWalletCore/Extensions/String.swift | 5 +++++ Sources/SafariWalletCore/Extensions/Wallet.swift | 2 +- Sources/SafariWalletCore/Models/Account.swift | 16 ++++++++++++++-- .../SafariWalletCore/Provider/ProviderAPI.swift | 12 ++++++++++++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/Sources/SafariWalletCore/Extensions/String.swift b/Sources/SafariWalletCore/Extensions/String.swift index 1340afb..4746777 100644 --- a/Sources/SafariWalletCore/Extensions/String.swift +++ b/Sources/SafariWalletCore/Extensions/String.swift @@ -26,4 +26,9 @@ extension String { public func toHexString(uppercase: Bool = false, prefix: String? = nil) -> String { return unicodeScalars.map { prefix ?? "" + .init($0.value, radix: 16, uppercase: uppercase) }.joined() } + + public func toJSON() -> Any? { + guard let data = self.data(using: .utf8, allowLossyConversion: false) else { return nil } + return try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) + } } diff --git a/Sources/SafariWalletCore/Extensions/Wallet.swift b/Sources/SafariWalletCore/Extensions/Wallet.swift index 9892f98..7d4b71d 100644 --- a/Sources/SafariWalletCore/Extensions/Wallet.swift +++ b/Sources/SafariWalletCore/Extensions/Wallet.swift @@ -18,7 +18,7 @@ extension Wallet { } public convenience init(mnemonic: String, language: BIP39Wordlist = .english, network: Network = .ethereum) throws { - guard let seed = try BIP39(mnemonic: mnemonic.components(separatedBy: " ")).seed() else { throw MEWwalletKit.WalletError.emptySeed } + guard let seed = try BIP39(mnemonic: mnemonic).seed() else { throw MEWwalletKit.WalletError.emptySeed } try self.init(seed: seed, network: network) } diff --git a/Sources/SafariWalletCore/Models/Account.swift b/Sources/SafariWalletCore/Models/Account.swift index 1e4a814..2716f50 100644 --- a/Sources/SafariWalletCore/Models/Account.swift +++ b/Sources/SafariWalletCore/Models/Account.swift @@ -10,7 +10,7 @@ import MEWwalletKit public struct Account { - public let addresss: Address + public let address: Address public let publicKey: PublicKeyEth1 private let privateKey: PrivateKeyEth1 public let wallet: String @@ -20,7 +20,7 @@ public struct Account { self.privateKey = privateKey self.publicKey = try privateKey.publicKey() guard let address = privateKey.address() else { throw WalletCoreError.addressGenerationError } - self.addresss = address + self.address = address self.wallet = wallet self.derivationpath = derivationpath } @@ -35,6 +35,18 @@ public struct Account { return signedMessage } + public func signTypedMessage(payload: TypedMessage, version: SignTypedDataVersion = .v3) throws -> String { + do { + return try MEWwalletKit.signTypedMessage( + privateKey: privateKey, + payload: SignedMessagePayload.init(data: payload, signature: nil), + version: version + ).addHexPrefix() + } catch { + throw WalletCoreError.signingError + } + } + // public init(address: Address, path: String, network: Network, mnemonic: String) /* public func sign(tx: Transaction) throws -> String { diff --git a/Sources/SafariWalletCore/Provider/ProviderAPI.swift b/Sources/SafariWalletCore/Provider/ProviderAPI.swift index 4b19148..6baf828 100644 --- a/Sources/SafariWalletCore/Provider/ProviderAPI.swift +++ b/Sources/SafariWalletCore/Provider/ProviderAPI.swift @@ -119,6 +119,18 @@ public struct ProviderAPI { let result = try await client.ethGetBalance(address: params[0], blockNumber: Block(rawValue: params[1])) return result.hexString + case "eth_signTypedData_v3", "eth_signTypedData_v4": + guard let params = params as? [String], params.count == 2 else { + throw WalletCoreError.invalidParams + } + let account = try await delegate.account(address: params[0], password: "password123") // FIXME: password + guard let json = params[1].toJSON() as? [String : Any] else { + throw WalletCoreError.invalidParams + } + return try account.signTypedMessage( + payload: .init(json: json), + version: method == "eth_signTypedData_v4" ? .v4 : .v3 + ) case "eth_sendTransaction": // https://eth.wiki/json-rpc/API#eth_sendtransaction // FIXME: Returns mock result From bf7a16706660521e575850c17e508f15c46ede99 Mon Sep 17 00:00:00 2001 From: Dimitar Nestorov <8790386+dimitarnestorov@users.noreply.github.com> Date: Tue, 11 Jan 2022 18:28:20 +0200 Subject: [PATCH 2/2] Add support fot `eth_sign` and `personal_sign` --- Sources/SafariWalletCore/Models/Account.swift | 8 ++++++ .../Provider/ProviderAPI.swift | 28 +++++++++++-------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/Sources/SafariWalletCore/Models/Account.swift b/Sources/SafariWalletCore/Models/Account.swift index 2716f50..bfe3bee 100644 --- a/Sources/SafariWalletCore/Models/Account.swift +++ b/Sources/SafariWalletCore/Models/Account.swift @@ -26,6 +26,14 @@ public struct Account { } public func sign(hexString: String) throws -> String { + let data = Data(hex: hexString) + guard let signedMessage = data.sign(key: privateKey, leadingV: false)?.toHexString().addHexPrefix() else { + throw WalletCoreError.signingError + } + return signedMessage + } + + public func personalSign(hexString: String) throws -> String { guard let data = Data(hex: hexString).hashPersonalMessage() else { throw WalletCoreError.invalidHexString(hexString) } diff --git a/Sources/SafariWalletCore/Provider/ProviderAPI.swift b/Sources/SafariWalletCore/Provider/ProviderAPI.swift index 6baf828..52fc4d4 100644 --- a/Sources/SafariWalletCore/Provider/ProviderAPI.swift +++ b/Sources/SafariWalletCore/Provider/ProviderAPI.swift @@ -131,10 +131,6 @@ public struct ProviderAPI { payload: .init(json: json), version: method == "eth_signTypedData_v4" ? .v4 : .v3 ) - case "eth_sendTransaction": - // https://eth.wiki/json-rpc/API#eth_sendtransaction - // FIXME: Returns mock result - return "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" case "eth_sign": // https://eth.wiki/json-rpc/API#eth_sign @@ -143,15 +139,23 @@ public struct ProviderAPI { } let address = params[0] let message = params[1] - let password: String? - if params.count >= 3 { - password = params[2] - } else { - password = nil - } - let account = try await delegate.account(address: address, password: password) + let account = try await delegate.account(address: address, password: "password123") // FIXME: password return try account.sign(hexString: message) - + + case "personal_sign": + guard let params = params as? [String], params.count >= 2 else { + throw WalletCoreError.invalidParams + } + let address = params[0] + let message = params[1] + let account = try await delegate.account(address: address, password: "password123") // FIXME: password + return try account.personalSign(hexString: message) + + case "eth_sendTransaction": + // https://eth.wiki/json-rpc/API#eth_sendtransaction + // FIXME: Returns mock result + return "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" + default: throw WalletCoreError.unknownMethod(method) }