Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/actions/run_tests_without_building/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ inputs:
js-client-api-host:
description: 'JS Client Api Host'
required: false
artifact-download-token:
description: 'Token with access to download DerivedData artifacts'
required: false


runs:
Expand All @@ -47,6 +50,7 @@ runs:
name: main-derivedData
workflow: build_artifacts.yml
repo: 'reown-com/reown-swift'
github_token: ${{ inputs.artifact-download-token != '' && inputs.artifact-download-token || github.token }}
if_no_artifact_found: warn

- name: Untar DerivedDataCache
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ DerivedDataCache
test_results/

Sources/WalletConnectModal/Secrets/secrets.json

# Provisioning Profiles
*.mobileprovision
Original file line number Diff line number Diff line change
Expand Up @@ -165,17 +165,17 @@ private enum Stub {
}

static let tx = [Transaction(from: "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83",
to: "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83",
data: "0x",
to: "0x521B4C065Bbdbe3E20B3727340730936912DfA46",
data: "0x7c616fe60000000000000000000000000000000000000000000000000000000067741500",
gasLimit: "0x5208",
gasPrice: "0x013e3d2ed4",
value: "0x00",
nonce: "0x09")]

static func tx(from: String) -> [Transaction] {
return [Transaction(from: from,
to: "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83",
data: "0x",
to: "0x521B4C065Bbdbe3E20B3727340730936912DfA46",
data: "0x7c616fe60000000000000000000000000000000000000000000000000000000067741500",
gasLimit: "0x5208",
gasPrice: "0x013e3d2ed4",
value: "0x186A0",
Expand Down
2 changes: 1 addition & 1 deletion Example/DApp/Modules/Sign/SignInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ enum Proposal {
"eip155": ProposalNamespace(
chains: [
Blockchain("eip155:137")!,
Blockchain("eip155:1")!
Blockchain("eip155:10")!
],
methods: [
"eth_sendTransaction",
Expand Down
13 changes: 8 additions & 5 deletions Example/ExampleApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2518,7 +2518,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.dapp;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.walletconnect.dapp";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "com.walletconnect.dapp AppStore";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
Expand All @@ -2531,9 +2531,11 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = PNDecryptionService/PNDecryptionService.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 184;
DEVELOPMENT_TEAM = W5R8AG9K22;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = W5R8AG9K22;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = PNDecryptionService/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = PNDecryptionService;
Expand All @@ -2548,6 +2550,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.walletapp.PNDecryptionService;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "com.walletconnect.walletapp.PNDecryptionService AppStore";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
Expand Down Expand Up @@ -2580,7 +2583,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.walletapp.PNDecryptionService;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.walletconnect.walletapp.PNDecryptionService";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "com.walletconnect.walletapp.PNDecryptionService AppStore";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
Expand Down Expand Up @@ -2734,7 +2737,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.walletapp;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.walletconnect.walletapp";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "com.walletconnect.walletapp AppStore";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Example/Shared/Signer/EOASigner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ final class EOASigner {
return signer.signTypedData(request.params)

case "eth_sendTransaction":
return try signer.sendTransaction(request.params)
return try await signer.sendTransaction(request: request)

case "solana_signTransaction":
return SOLSigner.signTransaction(request.params)
Expand Down
119 changes: 101 additions & 18 deletions Example/Shared/Signer/ETHSigner.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,44 @@
import Foundation
import Commons
import Web3
import WalletConnectSign
import YttriumUtilsWrapper

struct ETHSigner {
enum Errors: LocalizedError {
case invalidTransactionParams

var errorDescription: String? {
switch self {
case .invalidTransactionParams:
return "Invalid parameters for eth_sendTransaction"
}
}
}

private struct EthSendTransactionParams: Codable {
let from: String?
let to: String?
let value: String?
let data: String?
let gas: String?
let gasLimit: String?
let gasPrice: String?
let maxFeePerGas: String?
let maxPriorityFeePerGas: String?
let nonce: String?
}

private static let evmSigningClient: EvmSigningClient = {
let metadata = YttriumUtils.PulseMetadata(
url: nil,
bundleId: Bundle.main.bundleIdentifier ?? "",
sdkVersion: "reown-swift-\(EnvironmentInfo.sdkName)",
sdkPlatform: "mobile"
)
return EvmSigningClient(projectId: InputConfig.projectId, pulseMetadata: metadata)
}()

private let importAccount: ImportAccount

init(importAccount: ImportAccount) {
Expand All @@ -22,7 +58,7 @@
let messageToSign = params[0]

// Determine if the message is hex-encoded or plain text
let dataToSign: Bytes
let dataToSign: [UInt8]
if messageToSign.hasPrefix("0x") {
// Hex-encoded message, remove "0x" and convert
let messageData = Data(hex: String(messageToSign.dropFirst(2)))
Expand All @@ -41,44 +77,91 @@

func signHash(_ hashToSign: String) throws -> String {

let dataToSign: Bytes
let dataToSign: [UInt8]
if hashToSign.hasPrefix("0x") {
// Hex-encoded message, remove "0x" and convert
let messageData = Data(hex: String(hashToSign.dropFirst(2)))
dataToSign = messageData.bytes
dataToSign = Array(messageData)
} else {
// Plain text message, convert directly to data
let messageData = Data(hashToSign.utf8)
dataToSign = messageData.bytes
dataToSign = Array(messageData)
}

let (v, r, s) = try! privateKey.sign(hash: dataToSign)
let result = "0x" + r.toHexString() + s.toHexString() + String(v + 27, radix: 16)
return result
}

func signTypedData(_ params: AnyCodable) -> AnyCodable {
func signTypedData(_ params: AnyCodable) -> AnyCodable { // TODO: implement typed data signing

Check warning on line 96 in Example/Shared/Signer/ETHSigner.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=reown-com_reown-swift&issues=AZoQ9XdNl2VnS6V4NXUG&open=AZoQ9XdNl2VnS6V4NXUG&pullRequest=198

Check warning on line 96 in Example/Shared/Signer/ETHSigner.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unused function parameter "params".

See more on https://sonarcloud.io/project/issues?id=reown-com_reown-swift&issues=AZoQ9XdNl2VnS6V4NXUH&open=AZoQ9XdNl2VnS6V4NXUH&pullRequest=198
let result = "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c"
return AnyCodable(result)
}

func sendTransaction(_ params: AnyCodable) throws -> AnyCodable {
// let params = try params.get([Tx].self)
// var transaction = params[0]
// transaction.gas = EthereumQuantity(quantity: BigUInt("1234"))
// transaction.nonce = EthereumQuantity(quantity: BigUInt("0"))
// transaction.gasPrice = EthereumQuantity(quantity: BigUInt(0))
// print(transaction.description)
// let signedTx = try transaction.sign(with: self.privateKey, chainId: 4)
// let (r, s, v) = (signedTx.r, signedTx.s, signedTx.v)
// let result = r.hex() + s.hex().dropFirst(2) + String(v.quantity, radix: 16)
return AnyCodable("0xabcd12340000000000000000000000111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000f0")
func sendTransaction(request: Request) async throws -> AnyCodable {
guard let tx = try request.params.get([EthSendTransactionParams].self).first else {
throw Errors.invalidTransactionParams
}

let fromAddress = tx.from?.isEmpty == false ? tx.from! : address
let transactionParams = SignAndSendParams(
chainId: request.chainId.absoluteString,
from: normalizeAddress(fromAddress) ?? fromAddress,
to: normalizeAddress(tx.to),
value: ensureHexPrefix(tx.value),
data: normalizedDataHex(tx.data),
gasLimit: ensureHexPrefix(coalesce(tx.gasLimit, tx.gas)),
maxFeePerGas: ensureHexPrefix(coalesce(tx.maxFeePerGas, tx.gasPrice)),
maxPriorityFeePerGas: ensureHexPrefix(tx.maxPriorityFeePerGas),
nonce: ensureHexPrefix(tx.nonce)
)

let signer = ensureHexPrefix(importAccount.privateKey)
let result = try await Self.evmSigningClient.signAndSend(
params: transactionParams,
signer: signer
)

return AnyCodable(result.transactionHash)
}

private func dataToHash(_ data: Data) -> Bytes {
private func dataToHash(_ data: Data) -> [UInt8] {
let prefix = "\u{19}Ethereum Signed Message:\n"
let prefixData = (prefix + String(data.count)).data(using: .utf8)!
let prefixedMessageData = prefixData + data
return .init(hex: prefixedMessageData.toHexString())
return Array(prefixedMessageData)
}

private func ensureHexPrefix(_ value: String?) -> String? {
guard let value = value, !value.isEmpty else { return nil }
if value.hasPrefix("0x") || value.hasPrefix("0X") {
return value.lowercased().hasPrefix("0x") ? value : "0x" + value.dropFirst(2)
}
return "0x" + value
}

private func ensureHexPrefix(_ value: String) -> String {
return ensureHexPrefix(Optional(value)) ?? value
}

private func normalizedDataHex(_ value: String?) -> String? {
guard let value = ensureHexPrefix(value) else {
return "0x"
}
return value
}

private func normalizeAddress(_ value: String?) -> String? {
guard let value = value, !value.isEmpty else { return nil }
return ensureHexPrefix(value)
}

private func coalesce(_ values: String?...) -> String? {
for value in values {
if let value, !value.isEmpty {
return value
}
}
return nil
}
}
4 changes: 2 additions & 2 deletions Example/Shared/Signer/StacksSigner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ final class StacksSigner {
private let stacksClient: StacksClient

init() {
let pulseMetadata = PulseMetadata(
let pulseMetadata = YttriumUtils.PulseMetadata(
url: nil,
bundleId: Bundle.main.bundleIdentifier ?? "",
bundleId: Bundle.main.bundleIdentifier,
sdkVersion: "reown-swift-\(EnvironmentInfo.sdkName)",
sdkPlatform: "mobile"
)
Expand Down
4 changes: 2 additions & 2 deletions Example/Shared/Signer/SuiSigner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ final class SuiSigner {
private static var suiClient: SuiClient?

static func initialize(projectId: String) {
let pulseMetadata = PulseMetadata(
let pulseMetadata = YttriumUtils.PulseMetadata(
url: nil,
bundleId: Bundle.main.bundleIdentifier ?? "",
bundleId: Bundle.main.bundleIdentifier,
sdkVersion: "reown-swift-\(EnvironmentInfo.sdkName)",
sdkPlatform: "mobile"
)
Expand Down
Loading
Loading