Skip to content

Commit

Permalink
Merge pull request #78 from reown-com/enable-6492-verification
Browse files Browse the repository at this point in the history
Enable 6492 verification
  • Loading branch information
llbartekll authored Jan 10, 2025
2 parents d26cb4d + b6bbaa1 commit d55f2bf
Show file tree
Hide file tree
Showing 16 changed files with 105 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,8 @@
"repositoryURL": "https://github.com/reown-com/yttrium",
"state": {
"branch": null,
"revision": "533e9bacce2c7a45b1f9b3705726d03f2a37be4e",
"version": "0.4.8"
"revision": "eb6e3f8351fc3972df37c9b72c04cd606e01bac9",
"version": "0.5.1"
}
}
]
Expand Down
4 changes: 2 additions & 2 deletions Example/Shared/Signer/Signer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ final class Signer {
var value: String
var data: String
}
let params = try request.params.get([Tx].self).map { FfiTransaction(to: $0.to, value: $0.value, data: $0.data)}
let params = try request.params.get([Tx].self).map { Execution(to: $0.to, value: $0.value, data: $0.data)}
let prepareSendTransactions = try await WalletKit.instance.prepareSendTransactions(params, ownerAccount: ownerAccount)

let signer = ETHSigner(importAccount: importAccount)
Expand All @@ -179,7 +179,7 @@ final class Signer {
}

let transactions = calls.map {
FfiTransaction(
Execution(
to: $0.to!,
value: $0.value ?? "0",
data: $0.data ?? ""
Expand Down
4 changes: 2 additions & 2 deletions Example/WalletApp/BusinessLayer/ChainAbstractionService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ class ChainAbstractionService {
}

let privateKey: EthereumPrivateKey
private let routeResponseAvailable: RouteResponseAvailable
private let routeResponseAvailable: PrepareResponseAvailable

init(privateKey: EthereumPrivateKey, routeResponseAvailable: RouteResponseAvailable) {
init(privateKey: EthereumPrivateKey, routeResponseAvailable: PrepareResponseAvailable) {
self.privateKey = privateKey
self.routeResponseAvailable = routeResponseAvailable
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ final class CATransactionModule {
app: Application,
sessionRequest: Request,
importAccount: ImportAccount,
routeResponseAvailable: RouteResponseAvailable
routeResponseAvailable: PrepareResponseAvailable
) -> UIViewController {
let router = CATransactionRouter(app: app)
let presenter = CATransactionPresenter(sessionRequest: sessionRequest, importAccount: importAccount, routeResponseAvailable: routeResponseAvailable, router: router)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ final class CATransactionPresenter: ObservableObject {


private let sessionRequest: Request
private let routeResponseAvailable: RouteResponseAvailable
private let routeResponseAvailable: PrepareResponseAvailable
let chainAbstractionService: ChainAbstractionService!
var fundingFrom: [FundingMetadata] {
return routeResponseAvailable.metadata.fundingFrom
Expand All @@ -42,7 +42,7 @@ final class CATransactionPresenter: ObservableObject {
init(
sessionRequest: Request,
importAccount: ImportAccount,
routeResponseAvailable: RouteResponseAvailable,
routeResponseAvailable: PrepareResponseAvailable,
router: CATransactionRouter
) {
self.sessionRequest = sessionRequest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ final class MainRouter {
.presentFullScreen(from: viewController, transparentBackground: true)
}

func presentCATransaction(sessionRequest: Request, importAccount: ImportAccount, routeResponseAvailable: RouteResponseAvailable, context: VerifyContext?) {
func presentCATransaction(sessionRequest: Request, importAccount: ImportAccount, routeResponseAvailable: PrepareResponseAvailable, context: VerifyContext?) {
CATransactionModule.create(app: app, sessionRequest: sessionRequest, importAccount: importAccount, routeResponseAvailable: routeResponseAvailable)
.present(from: viewController)
}
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ build_all:
set -o pipefail && env NSUnbufferedIO=YES \
xcodebuild \
-scheme "WalletConnect-Package" \
-destination "platform=iOS Simulator,name=iPhone 15,OS=17.5" \
-destination "platform=iOS Simulator,name=iPhone 16,OS=18.1" \
-derivedDataPath DerivedDataCache \
-clonedSourcePackagesDirPath ../SourcePackagesCache \
RELAY_HOST='$(RELAY_HOST)' \
Expand Down
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@
"repositoryURL": "https://github.com/reown-com/yttrium",
"state": {
"branch": null,
"revision": "79fdd0d3be2d00e371b8f23998a4aa7b1c14e847",
"version": "0.4.7"
"revision": "eb6e3f8351fc3972df37c9b72c04cd606e01bac9",
"version": "0.5.1"
}
}
]
Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func buildYttriumWrapperTarget() -> Target {
path: "Sources/YttriumWrapper"
)
} else {
dependencies.append(.package(url: "https://github.com/reown-com/yttrium", .exact("0.4.8")))
dependencies.append(.package(url: "https://github.com/reown-com/yttrium", .exact("0.5.1")))
return .target(
name: "YttriumWrapper",
dependencies: [.product(name: "Yttrium", package: "yttrium")],
Expand Down Expand Up @@ -197,7 +197,7 @@ let package = Package(
dependencies: ["WalletConnectPairing", "TestingUtils"]),
.testTarget(
name: "NotifyTests",
dependencies: ["WalletConnectNotify", "TestingUtils"]),
dependencies: ["WalletConnectNotify", "TestingUtils", "YttriumWrapper"]),
.testTarget(
name: "RelayerTests",
dependencies: ["WalletConnectRelay", "WalletConnectUtils", "TestingUtils"]),
Expand Down
19 changes: 10 additions & 9 deletions Sources/ReownWalletKit/SmartAccount/SafesManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@ class SafesManager {
))
// use YttriumWrapper.Config.local() for local foundry node

let FfiAccountClientConfig = FfiAccountClientConfig(
ownerAddress: ownerAccount.address,
chainId: UInt64(ownerAccount.blockchain.reference)!,
config: pimlicoSepolia,
signerType: "PrivateKey",
safe: true,
privateKey: "ff89825a799afce0d5deaa079cdde227072ec3f62973951683ac8cc033092156")

let client = FfiAccountClient(config: FfiAccountClientConfig)
// let FfiAccountClientConfig = FfiAccountClientConfig(
// ownerAddress: ownerAccount.address,
// chainId: UInt64(ownerAccount.blockchain.reference)!,
// config: pimlicoSepolia,
// signerType: "PrivateKey",
// safe: true,
// privateKey: "ff89825a799afce0d5deaa079cdde227072ec3f62973951683ac8cc033092156")

let client = FfiAccountClient(owner: ownerAccount.address, chainId: UInt64(ownerAccount.blockchain.reference)!, config: pimlicoSepolia)
// FfiAccountClient(config: FfiAccountClientConfig)


return client
Expand Down
58 changes: 29 additions & 29 deletions Sources/ReownWalletKit/WalletKitClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ public class WalletKitClient {

// MARK: Yttrium
@available(*, message: "This method is experimental. Use with caution.")
public func prepareSendTransactions(_ transactions: [FfiTransaction], ownerAccount: Account) async throws -> PreparedSendTransaction {
public func prepareSendTransactions(_ transactions: [Execution], ownerAccount: Account) async throws -> PreparedSendTransaction {
guard let smartAccountsManager = smartAccountsManager else {
throw Errors.smartAccountNotEnabled
}
Expand All @@ -285,7 +285,7 @@ public class WalletKitClient {
}

@available(*, message: "This method is experimental. Use with caution.")
public func doSendTransaction(signatures: [OwnerSignature], doSendTransactionParams: String, ownerAccount: Account) async throws -> String {
public func doSendTransaction(signatures: [OwnerSignature], doSendTransactionParams: DoSendTransactionParams, ownerAccount: Account) async throws -> String {
guard let smartAccountsManager = smartAccountsManager else {
throw Errors.smartAccountNotEnabled
}
Expand Down Expand Up @@ -313,32 +313,32 @@ public class WalletKitClient {
let client = smartAccountsManager.getOrCreateSafe(for: ownerAccount)
return try await client.waitForUserOperationReceipt(userOperationHash: userOperationHash)
}
//
// public func prepareSignMessage(_ messageHash: String, ownerAccount: Account) async throws -> PreparedSignMessage {
// guard let smartAccountsManager = smartAccountsManager else {
// throw Errors.smartAccountNotEnabled
// }
// let client = smartAccountsManager.getOrCreateSafe(for: ownerAccount)
// return try await client.prepareSignMessage(messageHash)
// }
//
// public func doSignMessage(_ signatures: [String], ownerAccount: Account) async throws -> PreparedSign {
// guard let smartAccountsManager = smartAccountsManager else {
// throw Errors.smartAccountNotEnabled
// }
// let client = smartAccountsManager.getOrCreateSafe(for: ownerAccount)
// let signature = try await client.doSignMessage(signatures)
// return signature
// }
//
// public func finalizeSignMessage(_ signatures: [String], signStep3Params: String, ownerAccount: Account) async throws -> String {
// guard let smartAccountsManager = smartAccountsManager else {
// throw Errors.smartAccountNotEnabled
// }
// let client = smartAccountsManager.getOrCreateSafe(for: ownerAccount)
// let signature = try await client.finalizeSignMessage(signatures, signStep3Params: signStep3Params)
// return signature
// }

public func prepareSignMessage(_ messageHash: String, ownerAccount: Account) throws -> FfiPreparedSignature {
guard let smartAccountsManager = smartAccountsManager else {
throw Errors.smartAccountNotEnabled
}
let client = smartAccountsManager.getOrCreateSafe(for: ownerAccount)
return client.prepareSignMessage(messageHash: messageHash)
}

public func doSignMessage(_ signatures: [OwnerSignature], ownerAccount: Account) async throws -> SignOutputEnum {
guard let smartAccountsManager = smartAccountsManager else {
throw Errors.smartAccountNotEnabled
}
let client = smartAccountsManager.getOrCreateSafe(for: ownerAccount)
let signature = try await client.doSignMessage(signatures: signatures)
return signature
}

public func finalizeSignMessage(_ signatures: [OwnerSignature], signStep3Params: SignStep3Params, ownerAccount: Account) async throws -> String {
guard let smartAccountsManager = smartAccountsManager else {
throw Errors.smartAccountNotEnabled
}
let client = smartAccountsManager.getOrCreateSafe(for: ownerAccount)
let signature = try await client.finalizeSignMessage(signatures: signatures, signStep3Params: signStep3Params)
return signature
}

@available(*, message: "This method is experimental. Use with caution.")
public func status(orchestrationId: String) async throws -> StatusResponse {
Expand Down Expand Up @@ -369,7 +369,7 @@ public class WalletKitClient {
}

@available(*, message: "This method is experimental. Use with caution.")
public func getUiFields(routeResponse: RouteResponseAvailable, currency: Currency) async throws -> UiFields {
public func getUiFields(routeResponse: PrepareResponseAvailable, currency: Currency) async throws -> UiFields {
guard let chainAbstractionClient = chainAbstractionClient else {
throw Errors.chainAbstractionNotEnabled
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ extension WalletPairService {
extension WalletPairService.Errors: LocalizedError {
var errorDescription: String? {
switch self {
case .noPendingRequestsForPairing(let topic): return "No pending requests for pairing, topic: \(topic)"
case .noPendingRequestsForPairing(let topic): return "No pending requests for pairing, topic: \(topic), Please try again with a new connection URI."
case .networkNotConnected: return "Pairing failed. You seem to be offline"
}
}
Expand Down
6 changes: 4 additions & 2 deletions Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,8 @@ private extension ApproveEngine {

func setupRequestSubscriptions() {
pairingRegisterer.register(method: SessionProposeProtocolMethod.responseAutoReject())
.sink { [unowned self] (payload: RequestSubscriptionPayload<SessionType.ProposeParams>) in
.sink { [weak self] (payload: RequestSubscriptionPayload<SessionType.ProposeParams>) in
guard let self = self else { return }
guard let pairing = pairingStore.getPairing(forTopic: payload.topic) else { return }
let responseApproveMethod = SessionAuthenticatedProtocolMethod.responseApprove().method
if let methods = pairing.methods,
Expand Down Expand Up @@ -417,7 +418,8 @@ private extension ApproveEngine {
return
}

Task(priority: .high) {
Task(priority: .high) { [weak self] in
guard let self = self else {return}
do {
let response: VerifyResponse
if let attestation = payload.attestation,
Expand Down
3 changes: 0 additions & 3 deletions Sources/WalletConnectSign/WalletConnectError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ enum WalletConnectError: Error {
case invalidEvent
case invalidUpdateExpiryValue
case unauthorizedNonControllerCall
case pairingAlreadyExist
case topicGenerationFailed
case invalidPermissions // TODO: Refactor into actual cases
case unsupportedNamespace(SignReasonCode)
Expand Down Expand Up @@ -49,8 +48,6 @@ extension WalletConnectError {
return "Method must be called by a controller client."
case .topicGenerationFailed:
return "Failed to generate topic from random bytes."
case .pairingAlreadyExist:
return "Pairing already exist"
case .invalidPermissions:
return "Invalid permissions for call."
case .unsupportedNamespace(let reason):
Expand Down
73 changes: 44 additions & 29 deletions Sources/WalletConnectSigner/Verifier/MessageVerifier.swift
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
import Foundation
import YttriumWrapper

public struct MessageVerifier {

enum Errors: Error {
enum Errors: LocalizedError {
case utf8EncodingFailed
case verificationFailed(message: String)

var errorDescription: String? {
switch self {
case .utf8EncodingFailed:
return "Failed to encode string using UTF-8."
case .verificationFailed(let message):
return "Verification failed: \(message)"
}
}
}

private let eip191Verifier: EIP191Verifier
private let eip1271Verifier: EIP1271Verifier
private let crypto: CryptoProvider
private let projectId: String

init(eip191Verifier: EIP191Verifier, eip1271Verifier: EIP1271Verifier) {
init(
eip191Verifier: EIP191Verifier,
eip1271Verifier: EIP1271Verifier,
crypto: CryptoProvider,
projectId: String
) {
self.eip191Verifier = eip191Verifier
self.eip1271Verifier = eip1271Verifier
self.crypto = crypto
self.projectId = projectId
}

public func verify(signature: CacaoSignature,
Expand All @@ -31,28 +51,7 @@ public struct MessageVerifier {
address: String,
chainId: String
) async throws {

guard let messageData = message.data(using: .utf8) else {
throw Errors.utf8EncodingFailed
}

let signatureData = Data(hex: signature.s)

switch signature.t {
case .eip191:
return try await eip191Verifier.verify(
signature: signatureData,
message: messageData.prefixed,
address: address
)
case .eip1271:
return try await eip1271Verifier.verify(
signature: signatureData,
message: messageData.prefixed,
address: address,
chainId: chainId
)
}
try await verifySignature(signature.s, message: message, address: address, chainId: chainId)
}

public func verify(signature: String,
Expand Down Expand Up @@ -85,13 +84,29 @@ public struct MessageVerifier {
)
return // If 191 verification succeeds, we’re done
} catch {
// If eip191 verification fails, try eip1271 verification
try await eip1271Verifier.verify(
signature: signatureData,
message: prefixedMessage,
// If eip191 verification fails, we’ll attempt 6492 verification
}

// Fallback to 6492 verification
print("i was called only once")
let rpcUrl = "https://rpc.walletconnect.com/v1?chainId=\(chainId)&projectId=\(projectId)"
let erc6492Client = Erc6492Client(rpcUrl: rpcUrl)
let messageHash = crypto.keccak256(prefixedMessage)

do {
let result = try await erc6492Client.verifySignature(
signature: signatureString,
address: address,
chainId: chainId
messageHash: messageHash.toHexString()
)

if result == true {
return
} else {
throw Errors.verificationFailed(message: "Signature verification failed.")
}
} catch {
throw error
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public struct MessageVerifierFactory {
}

public func create(projectId: String) -> MessageVerifier {
return MessageVerifier(eip191Verifier: EIP191Verifier(crypto: crypto), eip1271Verifier: EIP1271Verifier(projectId: projectId, httpClient: HTTPNetworkClient(host: "rpc.walletconnect.com"), crypto: crypto))

return MessageVerifier(eip191Verifier: EIP191Verifier(crypto: crypto), eip1271Verifier: EIP1271Verifier(projectId: projectId, httpClient: HTTPNetworkClient(host: "rpc.walletconnect.com"), crypto: crypto), crypto: crypto, projectId: projectId)
}
}

0 comments on commit d55f2bf

Please sign in to comment.