import WalletConnectSwift
class WalletConnectDelegate: WalletDelegate {
private let session: Session
private let client: Client
init(session: Session, client: Client) {
self.session = session
self.client = client
}
func getAddress() throws -> String {
guard let account = session.walletInfo?.accounts.first else {
throw WalletError.notConnected
}
return account
}
func getChainId() throws -> UInt64 {
guard let chainId = session.walletInfo?.chainId else {
throw WalletError.notConnected
}
return UInt64(chainId)
}
func signMessage(message: String) throws -> String {
let semaphore = DispatchSemaphore(value: 0)
var result: Result<String, Error>?
let address = try getAddress()
try client.personal_sign(
url: session.url,
message: message,
account: address
) { response in
switch response {
case .success(let signature):
result = .success(signature)
case .failure(let error):
result = .failure(error)
}
semaphore.signal()
}
semaphore.wait()
switch result {
case .success(let signature):
return signature
case .failure(let error):
throw error
case .none:
throw WalletError.timeout
}
}
func signTypedData(typedDataJson: String) throws -> String {
let semaphore = DispatchSemaphore(value: 0)
var result: Result<String, Error>?
let address = try getAddress()
try client.eth_signTypedData(
url: session.url,
account: address,
message: typedDataJson
) { response in
switch response {
case .success(let signature):
result = .success(signature)
case .failure(let error):
result = .failure(error)
}
semaphore.signal()
}
semaphore.wait()
switch result {
case .success(let signature):
return signature
case .failure(let error):
throw error
case .none:
throw WalletError.timeout
}
}
func sendTransaction(toAddress: String, value: String, data: String) throws -> String {
let semaphore = DispatchSemaphore(value: 0)
var result: Result<String, Error>?
let address = try getAddress()
let transaction = Client.Transaction(
from: address,
to: toAddress,
data: data,
gas: nil,
gasPrice: nil,
value: value,
nonce: nil
)
try client.eth_sendTransaction(
url: session.url,
transaction: transaction
) { response in
switch response {
case .success(let txHash):
result = .success(txHash)
case .failure(let error):
result = .failure(error)
}
semaphore.signal()
}
semaphore.wait()
switch result {
case .success(let txHash):
return txHash
case .failure(let error):
throw error
case .none:
throw WalletError.timeout
}
}
}
enum WalletError: Error {
case notConnected
case timeout
case userRejected
}