From 30bea4759c45f1928bc693dfc089cf64dbceb380 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Mon, 24 Jan 2022 12:14:31 +0100 Subject: [PATCH] Adds Signer.getTransactionCount() --- ethers/blocktag.nim | 37 +++++++++++++++++++++++ ethers/provider.nim | 8 +++++ ethers/providers/jsonrpc.nim | 7 +++++ ethers/providers/rpccalls.nim | 1 + ethers/providers/rpccalls/conversions.nim | 6 ++++ ethers/providers/rpccalls/signatures.nim | 1 + ethers/signer.nim | 6 ++++ testmodule/testJsonRpcSigner.nim | 14 ++++++--- 8 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 ethers/blocktag.nim diff --git a/ethers/blocktag.nim b/ethers/blocktag.nim new file mode 100644 index 0000000..af5f9c1 --- /dev/null +++ b/ethers/blocktag.nim @@ -0,0 +1,37 @@ +import pkg/stint +import pkg/upraises + +push: {.upraises: [].} + +type + BlockTagKind = enum + stringBlockTag + numberBlockTag + BlockTag* = object + case kind: BlockTagKind + of stringBlockTag: + stringValue: string + of numberBlockTag: + numberValue: UInt256 + +func init(_: type BlockTag, value: string): BlockTag = + BlockTag(kind: stringBlockTag, stringValue: value) + +func init*(_: type BlockTag, value: UInt256): BlockTag = + BlockTag(kind: numberBlockTag, numberValue: value) + +func earliest*(_: type BlockTag): BlockTag = + BlockTag.init("earliest") + +func latest*(_: type BlockTag): BlockTag = + BlockTag.init("latest") + +func pending*(_: type BlockTag): BlockTag = + BlockTag.init("pending") + +func `$`*(blockTag: BlockTag): string = + case blockTag.kind + of stringBlockTag: + blockTag.stringValue + of numberBlockTag: + "0x" & blockTag.numberValue.toHex diff --git a/ethers/provider.nim b/ethers/provider.nim index 7d27b98..9bf3f04 100644 --- a/ethers/provider.nim +++ b/ethers/provider.nim @@ -1,8 +1,10 @@ import ./basics import ./transaction +import ./blocktag export basics export transaction +export blocktag push: {.upraises: [].} @@ -17,3 +19,9 @@ method call*(provider: Provider, tx: Transaction): Future[seq[byte]] {.base.} = method getGasPrice*(provider: Provider): Future[UInt256] {.base.} = doAssert false, "not implemented" + +method getTransactionCount*(provider: Provider, + address: Address, + blockTag = BlockTag.latest): + Future[UInt256] {.base.} = + doAssert false, "not implemented" diff --git a/ethers/providers/jsonrpc.nim b/ethers/providers/jsonrpc.nim index 27a4ac5..210f776 100644 --- a/ethers/providers/jsonrpc.nim +++ b/ethers/providers/jsonrpc.nim @@ -68,6 +68,13 @@ method getGasPrice*(provider: JsonRpcProvider): Future[UInt256] {.async.} = let client = await provider.client return await client.eth_gasprice() +method getTransactionCount*(provider: JsonRpcProvider, + address: Address, + blockTag = BlockTag.latest): + Future[UInt256] {.async.} = + let client = await provider.client + return await client.eth_getTransactionCount(address, blockTag) + # Signer method provider*(signer: JsonRpcSigner): Provider = diff --git a/ethers/providers/rpccalls.nim b/ethers/providers/rpccalls.nim index f198e1c..ea663cf 100644 --- a/ethers/providers/rpccalls.nim +++ b/ethers/providers/rpccalls.nim @@ -2,6 +2,7 @@ import std/os import pkg/json_rpc/rpcclient import ../basics import ../transaction +import ../blocktag import ./rpccalls/conversions const file = currentSourcePath.parentDir / "rpccalls" / "signatures.nim" diff --git a/ethers/providers/rpccalls/conversions.nim b/ethers/providers/rpccalls/conversions.nim index d320a1c..8167739 100644 --- a/ethers/providers/rpccalls/conversions.nim +++ b/ethers/providers/rpccalls/conversions.nim @@ -2,6 +2,7 @@ import std/json import pkg/stew/byteutils import ../../basics import ../../transaction +import ../../blocktag # byte sequence @@ -34,3 +35,8 @@ func fromJson*(json: JsonNode, name: string, result: var UInt256) = func `%`*(tx: Transaction): JsonNode = %{ "to": %tx.to, "data": %tx.data } + +# BlockTag + +func `%`*(blockTag: BlockTag): JsonNode = + %($blockTag) diff --git a/ethers/providers/rpccalls/signatures.nim b/ethers/providers/rpccalls/signatures.nim index a053415..18184c8 100644 --- a/ethers/providers/rpccalls/signatures.nim +++ b/ethers/providers/rpccalls/signatures.nim @@ -2,3 +2,4 @@ proc eth_accounts: seq[Address] proc eth_blockNumber: UInt256 proc eth_call(tx: Transaction): seq[byte] proc eth_gasPrice(): UInt256 +proc eth_getTransactionCount(address: Address, blockTag: BlockTag): UInt256 diff --git a/ethers/signer.nim b/ethers/signer.nim index 37e5ee4..53f9c0c 100644 --- a/ethers/signer.nim +++ b/ethers/signer.nim @@ -13,3 +13,9 @@ method getAddress*(signer: Signer): Future[Address] {.base.} = method getGasPrice*(signer: Signer): Future[UInt256] {.base.} = signer.provider.getGasPrice() + +method getTransactionCount*(signer: Signer, + blockTag = BlockTag.latest): + Future[UInt256] {.base, async.} = + let address = await signer.getAddress() + return await signer.provider.getTransactionCount(address, blockTag) diff --git a/testmodule/testJsonRpcSigner.nim b/testmodule/testJsonRpcSigner.nim index fa34e5b..c5b5dc1 100644 --- a/testmodule/testJsonRpcSigner.nim +++ b/testmodule/testJsonRpcSigner.nim @@ -4,20 +4,26 @@ import pkg/ethers suite "JsonRpcSigner": var provider: JsonRpcProvider + var accounts: seq[Address] setup: provider = JsonRpcProvider.new() + accounts = await provider.listAccounts() test "is connected to the first account of the provider by default": let signer = provider.getSigner() - check (await signer.getAddress()) == (await provider.listAccounts())[0] + check (await signer.getAddress()) == accounts[0] test "can connect to a different account": - let account = (await provider.listAccounts())[1] - let signer = provider.getSigner(account) - check (await signer.getAddress()) == account + let signer = provider.getSigner(accounts[1]) + check (await signer.getAddress()) == accounts[1] test "can retrieve gas price": let signer = provider.getSigner() let gasprice = await signer.getGasPrice() check gasprice > 0.u256 + + test "can retrieve transaction count": + let signer = provider.getSigner(accounts[9]) + let count = await signer.getTransactionCount(BlockTag.pending) + check count == 0.u256