Skip to content
Open
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
53 changes: 43 additions & 10 deletions Sources/web3swift/Operations/WriteOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,59 @@ public class WriteOperation: ReadOperation {
/// - sendRaw: If set to `true` transaction will be signed and sent using `eth_sendRawTransaction`.
/// Otherwise, no signing attempts will take place and the `eth_sendTransaction` RPC will be used instead.
/// Default value is `true`.
public func writeToChain(password: String, policies: Policies = .auto, sendRaw: Bool = true) async throws -> TransactionSendingResult {
try await policyResolver.resolveAll(for: &transaction, with: policies)
public func writeToChain(password: String,
policies: Policies = .auto,
sendRaw: Bool = true) async throws -> TransactionSendingResult {
try await resolvePolicies(policies)

guard sendRaw else {
return try await web3.eth.send(transaction)
}

try signTransaction(password: password)

guard let transactionData = transaction.encode(for: .transaction) else {
throw Web3Error.dataError
}
return try await web3.eth.send(raw: transactionData)
}

/// Resolves all policy-driven transaction attributes: gas limit, gas price, nonce.
/// - Parameters:
/// - policies: Determining the behaviour of how transaction attributes like gas limit and
/// nonce are resolved. Default value is ``Policies/auto``.
/// - Throws: Rethrows any error that occurs during policy resolution.
public func resolvePolicies(_ policies: Policies) async throws {
try await policyResolver.resolveAll(for: &transaction, with: policies)
}

/// Signs the transaction locally using the attached keystore manager.
/// - Parameters:
/// - password: Password for the private key in the keystore manager attached to the provider
/// you set to `web3` passed in the initializer.
/// - Throws:
/// - ``Web3Error/inputError`` if no keystore is attached to the provider,
/// or if signing fails with the provided password.
@discardableResult
public func signTransaction(password: String) throws -> CodableTransaction {
guard let attachedKeystoreManager = web3.provider.attachedKeystoreManager else {
throw Web3Error.inputError(desc: "Failed to locally sign a transaction. Web3 provider doesn't have keystore attached.")
throw Web3Error.inputError(
desc: "Failed to locally sign a transaction. Web3 provider doesn't have keystore attached."
)
}

do {
try Web3Signer.signTX(transaction: &transaction,
keystore: attachedKeystoreManager,
account: transaction.from ?? transaction.sender ?? EthereumAddress.contractDeploymentAddress(),
password: password)
try Web3Signer.signTX(
transaction: &transaction,
keystore: attachedKeystoreManager,
account: transaction.from ?? transaction.sender ?? EthereumAddress.contractDeploymentAddress(),
password: password
)
return transaction
} catch {
throw Web3Error.inputError(desc: "Failed to locally sign a transaction. \(error.localizedDescription)")
throw Web3Error.inputError(
desc: "Failed to locally sign a transaction. \(error.localizedDescription)"
)
}
guard let transactionData = transaction.encode(for: .transaction) else { throw Web3Error.dataError }
return try await web3.eth.send(raw: transactionData)
}
}
Loading