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..bfe3bee 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,12 +20,20 @@ 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 } 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) } @@ -35,6 +43,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..52fc4d4 100644 --- a/Sources/SafariWalletCore/Provider/ProviderAPI.swift +++ b/Sources/SafariWalletCore/Provider/ProviderAPI.swift @@ -119,10 +119,18 @@ public struct ProviderAPI { let result = try await client.ethGetBalance(address: params[0], blockNumber: Block(rawValue: params[1])) return result.hexString - case "eth_sendTransaction": - // https://eth.wiki/json-rpc/API#eth_sendtransaction - // FIXME: Returns mock result - return "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" + 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_sign": // https://eth.wiki/json-rpc/API#eth_sign @@ -131,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) }