From 7e32f5ee516afb1b79e57eb505d0b1695010ef37 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Mon, 24 Jan 2022 14:40:47 +0100 Subject: [PATCH] Add Signer.estimateGas() --- ethers/provider.nim | 4 ++++ ethers/providers/jsonrpc.nim | 5 +++++ ethers/providers/rpccalls/conversions.nim | 4 +++- ethers/providers/rpccalls/signatures.nim | 3 ++- ethers/signer.nim | 6 ++++++ ethers/transaction.nim | 8 +++++++- testmodule/examples.nim | 18 ++++++++++++++++++ testmodule/testJsonRpcSigner.nim | 6 ++++++ 8 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 testmodule/examples.nim diff --git a/ethers/provider.nim b/ethers/provider.nim index 9bf3f04..0972868 100644 --- a/ethers/provider.nim +++ b/ethers/provider.nim @@ -25,3 +25,7 @@ method getTransactionCount*(provider: Provider, blockTag = BlockTag.latest): Future[UInt256] {.base.} = doAssert false, "not implemented" + +method estimateGas*(provider: Provider, + transaction: Transaction): Future[UInt256] {.base.} = + doAssert false, "not implemented" diff --git a/ethers/providers/jsonrpc.nim b/ethers/providers/jsonrpc.nim index 210f776..9f70576 100644 --- a/ethers/providers/jsonrpc.nim +++ b/ethers/providers/jsonrpc.nim @@ -75,6 +75,11 @@ method getTransactionCount*(provider: JsonRpcProvider, let client = await provider.client return await client.eth_getTransactionCount(address, blockTag) +method estimateGas*(provider: JsonRpcProvider, + transaction: Transaction): Future[UInt256] {.async.} = + let client = await provider.client + return await client.eth_estimateGas(transaction) + # Signer method provider*(signer: JsonRpcSigner): Provider = diff --git a/ethers/providers/rpccalls/conversions.nim b/ethers/providers/rpccalls/conversions.nim index 8167739..1066560 100644 --- a/ethers/providers/rpccalls/conversions.nim +++ b/ethers/providers/rpccalls/conversions.nim @@ -34,7 +34,9 @@ func fromJson*(json: JsonNode, name: string, result: var UInt256) = # Transaction func `%`*(tx: Transaction): JsonNode = - %{ "to": %tx.to, "data": %tx.data } + result = %{ "to": %tx.to, "data": %tx.data } + if sender =? tx.sender: + result["from"] = %sender # BlockTag diff --git a/ethers/providers/rpccalls/signatures.nim b/ethers/providers/rpccalls/signatures.nim index 18184c8..b308ef0 100644 --- a/ethers/providers/rpccalls/signatures.nim +++ b/ethers/providers/rpccalls/signatures.nim @@ -1,5 +1,6 @@ proc eth_accounts: seq[Address] proc eth_blockNumber: UInt256 -proc eth_call(tx: Transaction): seq[byte] +proc eth_call(transaction: Transaction): seq[byte] proc eth_gasPrice(): UInt256 proc eth_getTransactionCount(address: Address, blockTag: BlockTag): UInt256 +proc eth_estimateGas(transaction: Transaction): UInt256 diff --git a/ethers/signer.nim b/ethers/signer.nim index 53f9c0c..17b8840 100644 --- a/ethers/signer.nim +++ b/ethers/signer.nim @@ -19,3 +19,9 @@ method getTransactionCount*(signer: Signer, Future[UInt256] {.base, async.} = let address = await signer.getAddress() return await signer.provider.getTransactionCount(address, blockTag) + +method estimateGas*(signer: Signer, + transaction: Transaction): Future[UInt256] {.base, async.} = + var transaction = transaction + transaction.sender = some(await signer.getAddress) + return await signer.provider.estimateGas(transaction) diff --git a/ethers/transaction.nim b/ethers/transaction.nim index fd2413a..7ec828b 100644 --- a/ethers/transaction.nim +++ b/ethers/transaction.nim @@ -2,8 +2,14 @@ import pkg/stew/byteutils import ./basics type Transaction* = object + sender*: ?Address to*: Address data*: seq[byte] func `$`*(transaction: Transaction): string = - "(to: " & $transaction.to & ", data: 0x" & $transaction.data.toHex & ")" + result = "(" + if sender =? transaction.sender: + result &= "from: " & $sender & ", " + result &= "to: " & $transaction.to & ", " + result &= "data: 0x" & $transaction.data.toHex + result &= ")" diff --git a/testmodule/examples.nim b/testmodule/examples.nim new file mode 100644 index 0000000..b4eba00 --- /dev/null +++ b/testmodule/examples.nim @@ -0,0 +1,18 @@ +import std/random +import std/sequtils +import pkg/ethers + +randomize() + +proc example*(_: type Address): Address = + var address: array[20, byte] + for b in address.mitems: + b = rand(byte) + Address.init(address) + +proc example*(_: type seq[byte]): seq[byte] = + let length = rand(0..<20) + newSeqWith(length, rand(byte)) + +proc example*(_: type Transaction): Transaction = + Transaction(to: Address.example, data: seq[byte].example) diff --git a/testmodule/testJsonRpcSigner.nim b/testmodule/testJsonRpcSigner.nim index c5b5dc1..8963b25 100644 --- a/testmodule/testJsonRpcSigner.nim +++ b/testmodule/testJsonRpcSigner.nim @@ -1,5 +1,6 @@ import pkg/asynctest import pkg/ethers +import ./examples suite "JsonRpcSigner": @@ -27,3 +28,8 @@ suite "JsonRpcSigner": let signer = provider.getSigner(accounts[9]) let count = await signer.getTransactionCount(BlockTag.pending) check count == 0.u256 + + test "can estimate gas cost of a transaction": + let signer = provider.getSigner() + let estimate = await signer.estimateGas(Transaction.example) + check estimate > 0.u256