diff --git a/ethers.nimble b/ethers.nimble index 8cf1ad6..c8bbf3a 100644 --- a/ethers.nimble +++ b/ethers.nimble @@ -8,7 +8,7 @@ requires "chronicles >= 0.10.3 & < 0.11.0" requires "chronos#f0a2d4df61302d24baa6c0f1c257f92045c9ee57" requires "contractabi >= 0.6.0 & < 0.7.0" requires "questionable >= 0.10.2 & < 0.11.0" -requires "json_rpc" +requires "json_rpc >= 0.3.0 & < 0.4.0" requires "stint" requires "stew" requires "eth" diff --git a/ethers/provider.nim b/ethers/provider.nim index d5dd22d..a8f7861 100644 --- a/ethers/provider.nim +++ b/ethers/provider.nim @@ -88,13 +88,14 @@ template raiseProviderError(msg: string) = func toTransaction*(past: PastTransaction): Transaction = Transaction( `from`: some past.`from`, - gasPrice: some past.gasPrice, - data: past.input, - nonce: some past.nonce, to: past.to, - `type`: past.`type`, + data: past.input, + value: past.value, + nonce: some past.nonce, + chainId: past.chainId, + gasPrice: some past.gasPrice, gasLimit: some past.gas, - chainId: past.chainId + `type`: past.`type` ) method getBlockNumber*( @@ -246,7 +247,9 @@ proc ensureSuccess( proc confirm*( tx: TransactionResponse, confirmations = EthersDefaultConfirmations, - timeout = EthersReceiptTimeoutBlks): Future[TransactionReceipt] {.async: (raises: [CancelledError, ProviderError, EthersError]).} = + timeout = EthersReceiptTimeoutBlks): Future[TransactionReceipt] + {.async: (raises: [CancelledError, ProviderError, EthersError]).} = + ## Waits for a transaction to be mined and for the specified number of blocks ## to pass since it was mined (confirmations). ## A timeout, in blocks, can be specified that will raise an error if too many diff --git a/ethers/providers/jsonrpc.nim b/ethers/providers/jsonrpc.nim index a2a8e24..285e4e9 100644 --- a/ethers/providers/jsonrpc.nim +++ b/ethers/providers/jsonrpc.nim @@ -26,14 +26,18 @@ type JsonRpcProvider* = ref object of Provider client: Future[RpcClient] subscriptions: Future[JsonRpcSubscriptions] - JsonRpcSigner* = ref object of Signer - provider: JsonRpcProvider - address: ?Address + JsonRpcProviderError* = object of ProviderError JsonRpcSubscription* = ref object of Subscription subscriptions: JsonRpcSubscriptions id: JsonNode + # Signer + JsonRpcSigner* = ref object of Signer + provider: JsonRpcProvider + address: ?Address + JsonRpcSignerError* = object of SignerError + proc raiseJsonRpcProviderError( message: string) {.raises: [JsonRpcProviderError].} = @@ -50,7 +54,7 @@ template convertError(body) = except JsonRpcError as error: raiseJsonRpcProviderError(error.msg) except CatchableError as error: - raiseJsonRpcProviderError(error.msg) + raise newException(JsonRpcProviderError, error.msg) # Provider @@ -104,6 +108,7 @@ proc callImpl( args: JsonNode): Future[JsonNode] {.async: (raises: [JsonRpcProviderError]).} = without response =? (await client.call(call, %args)).catch, error: + echo "[jsonrpc.callImpl] error during call: ", error.msg raiseJsonRpcProviderError error.msg echo "[jsonrpc.callImpl] response: ", response.string without json =? JsonNode.fromJson(response.string), error: @@ -111,16 +116,19 @@ proc callImpl( raiseJsonRpcProviderError "Failed to parse response: " & error.msg json - proc send*( provider: JsonRpcProvider, call: string, - arguments: seq[JsonNode] = @[]): Future[JsonNode] {.async.} = + arguments: seq[JsonNode] = @[]): Future[JsonNode] + {.async: (raises: [JsonRpcProviderError]).} = + convertError: let client = await provider.client return await client.callImpl(call, %arguments) -proc listAccounts*(provider: JsonRpcProvider): Future[seq[Address]] {.async.} = +proc listAccounts*(provider: JsonRpcProvider): Future[seq[Address]] + {.async: (raises: [JsonRpcProviderError]).} = + convertError: let client = await provider.client return await client.eth_accounts() @@ -228,7 +236,8 @@ method getChainId*( method sendTransaction*( provider: JsonRpcProvider, - rawTransaction: seq[byte]): Future[TransactionResponse] {.async: (raises:[ProviderError]).} = + rawTransaction: seq[byte]): Future[TransactionResponse] + {.async: (raises:[ProviderError]).} = convertError: let @@ -278,36 +287,55 @@ method close*( # Signer -method provider*(signer: JsonRpcSigner): Provider = +proc raiseJsonRpcSignerError( + message: string) {.raises: [JsonRpcSignerError].} = + + var message = message + if json =? JsonNode.fromJson(message): + if "message" in json: + message = json{"message"}.getStr + raise newException(JsonRpcSignerError, message) + +template convertSignerError(body) = + try: + body + except JsonRpcError as error: + raiseJsonRpcSignerError(error.msg) + except CatchableError as error: + raise newException(JsonRpcSignerError, error.msg) + +method provider*(signer: JsonRpcSigner): Provider {.gcsafe.} = signer.provider method getAddress*( - signer: JsonRpcSigner): Future[Address] {.async: (raises:[ProviderError]).} = + signer: JsonRpcSigner): Future[Address] {.async: (raises:[SignerError]).} = if address =? signer.address: return address - convertError: + convertSignerError: let accounts = await signer.provider.listAccounts() if accounts.len > 0: return accounts[0] - raiseJsonRpcProviderError "no address found" + raiseJsonRpcSignerError "no address found" method signMessage*( signer: JsonRpcSigner, - message: seq[byte]): Future[seq[byte]] {.async: (raises:[JsonRpcProviderError]).} = + message: seq[byte]): Future[seq[byte]] {.async: (raises:[SignerError]).} = - convertError: + convertSignerError: let client = await signer.provider.client let address = await signer.getAddress() return await client.eth_sign(address, message) method sendTransaction*( signer: JsonRpcSigner, - transaction: Transaction): Future[TransactionResponse] {.async: (raises:[JsonRpcProviderError]).} = + transaction: Transaction): Future[TransactionResponse] + {.async: (raises:[SignerError]).} = - convertError: + convertSignerError: + echo "[jsonrpc.sendTransaction]" if nonce =? transaction.nonce: signer.updateNonce(nonce) let diff --git a/ethers/providers/jsonrpc/conversions.nim b/ethers/providers/jsonrpc/conversions.nim index 895088e..10ccdc6 100644 --- a/ethers/providers/jsonrpc/conversions.nim +++ b/ethers/providers/jsonrpc/conversions.nim @@ -127,6 +127,25 @@ func fromJson*(_: type UInt256, json: JsonNode): ?!UInt256 = # Transaction +# TODO: add option that ignores none Option[T] +# TODO: add name option (gasLimit => gas, sender => from) +func `%`*(transaction: Transaction): JsonNode = + result = %*{ + "to": transaction.to, + "data": %transaction.data, + "value": %transaction.value + } + if sender =? transaction.`from`: + result["from"] = %sender + if nonce =? transaction.nonce: + result["nonce"] = %nonce + if chainId =? transaction.chainId: + result["chainId"] = %chainId + if gasPrice =? transaction.gasPrice: + result["gasPrice"] = %gasPrice + if gasLimit =? transaction.gasLimit: + result["gas"] = %gasLimit + # proc writeValue*( # writer: var JsonWriter[JrpcConv], # value: Transaction @@ -172,6 +191,9 @@ func fromJson*(_: type BlockTag, json: JsonNode): ?!BlockTag = # TransactionStatus | TransactionType +func `%`*(e: TransactionStatus | TransactionType): JsonNode = + % ("0x" & e.int8.toHex(1)) + proc fromJson*[E: TransactionStatus | TransactionType]( T: type E, json: JsonNode diff --git a/ethers/signer.nim b/ethers/signer.nim index e60d963..f240787 100644 --- a/ethers/signer.nim +++ b/ethers/signer.nim @@ -9,9 +9,7 @@ type Signer* = ref object of RootObj lastSeenNonce: ?UInt256 populateLock: AsyncLock - -type - SignerError* = object of EthersError + SignerError* = object of ProviderError EstimateGasError* = object of SignerError transaction*: Transaction @@ -28,46 +26,78 @@ proc raiseEstimateGasError( parent: parent) raise e -method provider*(signer: Signer): - Provider {.base, gcsafe, raises: [EthersError].} = +template convertError(body) = + try: + body + except EthersError as error: + raiseSignerError(error.msg) + except CatchableError as error: + raiseSignerError(error.msg) + +method provider*( + signer: Signer): Provider {.base, gcsafe, raises: [SignerError].} = doAssert false, "not implemented" -method getAddress*(signer: Signer): Future[Address] {.base, async: (raises:[ProviderError]).} = +method getAddress*( + signer: Signer): Future[Address] {.base, async: (raises:[SignerError]).} = + doAssert false, "not implemented" -method signMessage*(signer: Signer, - message: seq[byte]): Future[seq[byte]] {.base, async.} = +method signMessage*( + signer: Signer, + message: seq[byte]): Future[seq[byte]] {.base, async: (raises:[SignerError]).} = + doAssert false, "not implemented" -method sendTransaction*(signer: Signer, - transaction: Transaction): Future[TransactionResponse] {.base, async.} = +method sendTransaction*( + signer: Signer, + transaction: Transaction): Future[TransactionResponse] + {.base, async: (raises:[SignerError]).} = + doAssert false, "not implemented" -method getGasPrice*(signer: Signer): - Future[UInt256] {.base, gcsafe, raises: [EthersError].} = - signer.provider.getGasPrice() +method getGasPrice*( + signer: Signer): Future[UInt256] {.base, gcsafe, async: (raises: [SignerError]).} = -method getTransactionCount*(signer: Signer, - blockTag = BlockTag.latest): - Future[UInt256] {.base, async.} = - let address = await signer.getAddress() - return await signer.provider.getTransactionCount(address, blockTag) + convertError: + return await signer.provider.getGasPrice() + +method getTransactionCount*( + signer: Signer, + blockTag = BlockTag.latest): Future[UInt256] + {.base, async: (raises:[SignerError]).} = + + convertError: + let address = await signer.getAddress() + return await signer.provider.getTransactionCount(address, blockTag) + +method estimateGas*( + signer: Signer, + transaction: Transaction, + blockTag = BlockTag.latest): Future[UInt256] + {.base, async: (raises:[SignerError]).} = -method estimateGas*(signer: Signer, - transaction: Transaction, - blockTag = BlockTag.latest): Future[UInt256] {.base, async.} = var transaction = transaction - transaction.`from` = some(await signer.getAddress) + var address: Address + + convertError: + address = await signer.getAddress + + transaction.`from` = some(address) try: return await signer.provider.estimateGas(transaction) except ProviderError as e: raiseEstimateGasError transaction, e -method getChainId*(signer: Signer): - Future[UInt256] {.base, gcsafe, raises: [EthersError].} = - signer.provider.getChainId() +method getChainId*( + signer: Signer): Future[UInt256] {.base, async: (raises: [SignerError]).} = + + convertError: + return await signer.provider.getChainId() + +method getNonce( + signer: Signer): Future[UInt256] {.base, async: (raises: [SignerError]).} = -method getNonce(signer: Signer): Future[UInt256] {.base, gcsafe, async.} = var nonce = await signer.getTransactionCount(BlockTag.pending) if lastSeen =? signer.lastSeenNonce and lastSeen >= nonce: @@ -92,9 +122,10 @@ method decreaseNonce*(signer: Signer) {.base, gcsafe.} = if lastSeen =? signer.lastSeenNonce and lastSeen > 0: signer.lastSeenNonce = some lastSeen - 1 -method populateTransaction*(signer: Signer, - transaction: Transaction): - Future[Transaction] {.base, async.} = +method populateTransaction*( + signer: Signer, + transaction: Transaction): Future[Transaction] + {.base, async: (raises: [CancelledError, AsyncLockError, SignerError]).} = echo "[signer.populatetransaction] signer type: ", typeof signer if sender =? transaction.`from` and sender != await signer.getAddress(): @@ -127,7 +158,7 @@ method populateTransaction*(signer: Signer, populated.gasLimit = some(await signer.estimateGas(populated)) except ProviderError as e: signer.decreaseNonce() - raise e + raiseSignerError(e.msg) except EstimateGasError as e: signer.decreaseNonce() raise e diff --git a/ethers/signers/jsonrpc.nim b/ethers/signers/jsonrpc.nim new file mode 100644 index 0000000..cd17b31 --- /dev/null +++ b/ethers/signers/jsonrpc.nim @@ -0,0 +1,3 @@ +import ../providers/jsonrpc + +export provider, getAddress, signMessage, sendTransaction \ No newline at end of file diff --git a/ethers/signers/wallet.nim b/ethers/signers/wallet.nim new file mode 100644 index 0000000..e200860 --- /dev/null +++ b/ethers/signers/wallet.nim @@ -0,0 +1,79 @@ +import eth/keys +import ../basics +import ../provider +import ../transaction +import ../signer +import ./wallet/error +import ./wallet/signing + +export keys +export WalletError +export signing + +var rng {.threadvar.}: ref HmacDrbgContext + +proc getRng: ref HmacDrbgContext = + if rng.isNil: + rng = newRng() + rng + +type Wallet* = ref object of Signer + privateKey*: PrivateKey + publicKey*: PublicKey + address*: Address + provider*: ?Provider + +proc new*(_: type Wallet, privateKey: PrivateKey): Wallet = + let publicKey = privateKey.toPublicKey() + let address = Address.init(publicKey.toCanonicalAddress()) + Wallet(privateKey: privateKey, publicKey: publicKey, address: address) +proc new*(_: type Wallet, privateKey: PrivateKey, provider: Provider): Wallet = + let wallet = Wallet.new(privateKey) + wallet.provider = some provider + wallet +proc new*(_: type Wallet, privateKey: string): ?!Wallet = + let keyResult = PrivateKey.fromHex(privateKey) + if keyResult.isErr: + return failure newException(WalletError, "invalid key: " & $keyResult.error) + success Wallet.new(keyResult.get()) +proc new*(_: type Wallet, privateKey: string, provider: Provider): ?!Wallet = + let wallet = ? Wallet.new(privateKey) + wallet.provider = some provider + success wallet +proc connect*(wallet: Wallet, provider: Provider) = + wallet.provider = some provider +proc createRandom*(_: type Wallet): Wallet = + result = Wallet() + result.privateKey = PrivateKey.random(getRng()[]) + result.publicKey = result.privateKey.toPublicKey() + result.address = Address.init(result.publicKey.toCanonicalAddress()) +proc createRandom*(_: type Wallet, provider: Provider): Wallet = + result = Wallet() + result.privateKey = PrivateKey.random(getRng()[]) + result.publicKey = result.privateKey.toPublicKey() + result.address = Address.init(result.publicKey.toCanonicalAddress()) + result.provider = some provider + +method provider*(wallet: Wallet): Provider {.raises: [SignerError].} = + without provider =? wallet.provider: + raiseWalletError "Wallet has no provider" + provider + +method getAddress(wallet: Wallet): Future[Address] {.async: (raises:[ProviderError]).} = + return wallet.address + +proc signTransaction*(wallet: Wallet, + transaction: Transaction): Future[seq[byte]] {.async: (raises:[WalletError]).} = + if sender =? transaction.`from` and sender != wallet.address: + raiseWalletError "from address mismatch" + + return wallet.privateKey.sign(transaction) + +method sendTransaction*( + wallet: Wallet, + transaction: Transaction): Future[TransactionResponse] {.async: (raises:[ProviderError]).} = + + let signed = await signTransaction(wallet, transaction) + if nonce =? transaction.nonce: + wallet.updateNonce(nonce) + return await provider(wallet).sendTransaction(signed) diff --git a/ethers/signers/wallet/error.nim b/ethers/signers/wallet/error.nim new file mode 100644 index 0000000..749736a --- /dev/null +++ b/ethers/signers/wallet/error.nim @@ -0,0 +1,14 @@ +import ../../basics +import ../../signer + +type + WalletError* = object of SignerError + +func raiseWalletError*(message: string) {.raises: [WalletError].}= + raise newException(WalletError, message) + +template convertError(body) = + try: + body + except CatchableError as error: + raiseWalletError(error.msg) diff --git a/ethers/wallet/signing.nim b/ethers/signers/wallet/signing.nim similarity index 96% rename from ethers/wallet/signing.nim rename to ethers/signers/wallet/signing.nim index 2ea9fbf..8533d77 100644 --- a/ethers/wallet/signing.nim +++ b/ethers/signers/wallet/signing.nim @@ -2,9 +2,9 @@ import pkg/eth/keys import pkg/eth/rlp import pkg/eth/common/transaction as eth import pkg/eth/common/eth_hash -import ../basics -import ../transaction as ethers -import ../provider +import ../../basics +import ../../transaction as ethers +import ../../provider import ./error type diff --git a/ethers/wallet.nim b/ethers/wallet.nim index a773a8f..59490ca 100644 --- a/ethers/wallet.nim +++ b/ethers/wallet.nim @@ -1,76 +1,3 @@ -import eth/keys -import ./basics -import ./provider -import ./transaction -import ./signer -import ./wallet/error -import ./wallet/signing +import ./signers/wallet -export keys -export WalletError -export signing - -var rng {.threadvar.}: ref HmacDrbgContext - -proc getRng: ref HmacDrbgContext = - if rng.isNil: - rng = newRng() - rng - -type Wallet* = ref object of Signer - privateKey*: PrivateKey - publicKey*: PublicKey - address*: Address - provider*: ?Provider - -proc new*(_: type Wallet, privateKey: PrivateKey): Wallet = - let publicKey = privateKey.toPublicKey() - let address = Address.init(publicKey.toCanonicalAddress()) - Wallet(privateKey: privateKey, publicKey: publicKey, address: address) -proc new*(_: type Wallet, privateKey: PrivateKey, provider: Provider): Wallet = - let wallet = Wallet.new(privateKey) - wallet.provider = some provider - wallet -proc new*(_: type Wallet, privateKey: string): ?!Wallet = - let keyResult = PrivateKey.fromHex(privateKey) - if keyResult.isErr: - return failure newException(WalletError, "invalid key: " & $keyResult.error) - success Wallet.new(keyResult.get()) -proc new*(_: type Wallet, privateKey: string, provider: Provider): ?!Wallet = - let wallet = ? Wallet.new(privateKey) - wallet.provider = some provider - success wallet -proc connect*(wallet: Wallet, provider: Provider) = - wallet.provider = some provider -proc createRandom*(_: type Wallet): Wallet = - result = Wallet() - result.privateKey = PrivateKey.random(getRng()[]) - result.publicKey = result.privateKey.toPublicKey() - result.address = Address.init(result.publicKey.toCanonicalAddress()) -proc createRandom*(_: type Wallet, provider: Provider): Wallet = - result = Wallet() - result.privateKey = PrivateKey.random(getRng()[]) - result.publicKey = result.privateKey.toPublicKey() - result.address = Address.init(result.publicKey.toCanonicalAddress()) - result.provider = some provider - -method provider*(wallet: Wallet): Provider {.raises: [WalletError].} = - without provider =? wallet.provider: - raiseWalletError "Wallet has no provider" - provider - -method getAddress(wallet: Wallet): Future[Address] {.async.} = - return wallet.address - -proc signTransaction*(wallet: Wallet, - transaction: Transaction): Future[seq[byte]] {.async.} = - if sender =? transaction.`from` and sender != wallet.address: - raiseWalletError "from address mismatch" - - return wallet.privateKey.sign(transaction) - -method sendTransaction*(wallet: Wallet, transaction: Transaction): Future[TransactionResponse] {.async.} = - let signed = await signTransaction(wallet, transaction) - if nonce =? transaction.nonce: - wallet.updateNonce(nonce) - return await provider(wallet).sendTransaction(signed) +export wallet \ No newline at end of file diff --git a/ethers/wallet/error.nim b/ethers/wallet/error.nim deleted file mode 100644 index 3ccf94d..0000000 --- a/ethers/wallet/error.nim +++ /dev/null @@ -1,7 +0,0 @@ -import ../basics - -type - WalletError* = object of EthersError - -func raiseWalletError*(message: string) {.raises: [WalletError].}= - raise newException(WalletError, message) diff --git a/testmodule/providers/jsonrpc/testConversions.nim b/testmodule/providers/jsonrpc/testConversions.nim index 6bee429..5df1358 100644 --- a/testmodule/providers/jsonrpc/testConversions.nim +++ b/testmodule/providers/jsonrpc/testConversions.nim @@ -2,6 +2,8 @@ import std/strutils import std/unittest import pkg/ethers/provider import pkg/ethers/providers/jsonrpc/conversions +import pkg/questionable +import pkg/questionable/results import pkg/stew/byteutils func flatten(s: string): string = @@ -111,30 +113,6 @@ suite "JSON Conversions": fail check receipt.blockHash.isNone - test "newHeads subcription raises exception when deserializing to Log": - let json = """{ - "parentHash":"0xd68d4d0f29307df51e1284fc8a13595ae700ef0f1128830a69e6854381363d42", - "sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "miner":"0x0000000000000000000000000000000000000000", - "stateRoot":"0x1f6f2d05de35bbfd50213be96ddf960d62b978b472c55d6ac223cd648cbbbbb0", - "transactionsRoot":"0xb9bb8a26abe091bb628ab2b6585c5af151aeb3984f4ba47a3c65d438283e069d", - "receiptsRoot":"0x33f229b7133e1ba3fb524b8af22d8184ca10b2da5bb170092a219c61ca023c1d", - "logsBloom":"0x00000000000000000000000000000000000000000020000000000002000000000000000000000000000000000000000000000000000008080000100200200000000000000000000000000008000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000010000040000000000100000000000800000000000000000000000000000000020000000000020000000000000000000000000000040000008000000000000000000020000000000002000000000000000000000000000000000000000000000000000001000010000000000000000020002000000020000000000000008002000000000000", - "difficulty":"0x2", - "number":"0x21d", - "gasLimit":"0x1c1b59a7", - "gasUsed":"0xda41b", - "timestamp":"0x6509410e", - "extraData":"0xd883010b05846765746888676f312e32302e32856c696e7578000000000000007102a27d75709b90ca9eb23cdaaccf4fc2d571d710f3bc5a7dc874f43af116a93ff832576a53c16f0d0aa1cd9e9a1dc0a60126c4d420f72b0866fc96ba6664f601", - "mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce":"0x0000000000000000", - "baseFeePerGas":"0x7", - "withdrawalsRoot":null, - "hash":"0x64066c7150c660e5357c4b6b02d836c10353dfa8edb32c805fca9367fd29c6e7" - }""" - expect ValueError: - discard Log.fromJson(parseJson(json)) - test "correctly deserializes PastTransaction": let json = %*{ "blockHash":"0x595bffbe897e025ea2df3213c4cc52c3f3d69bc04b49011d558f1b0e70038922", @@ -159,7 +137,7 @@ suite "JSON Conversions": fail check tx.blockHash == BlockHash(array[32, byte].fromHex("0x595bffbe897e025ea2df3213c4cc52c3f3d69bc04b49011d558f1b0e70038922")) check tx.blockNumber == 0x22e.u256 - check tx.sender == Address.init("0xe00b677c29ff8d8fe6068530e2bc36158c54dd34").get + check tx.`from` == Address.init("0xe00b677c29ff8d8fe6068530e2bc36158c54dd34").get check tx.gas == 0x4d4bb.u256 check tx.gasPrice == 0x3b9aca07.u256 check tx.hash == TransactionHash(array[32, byte].fromHex("0xa31608907c338d6497b0c6ec81049d845c7d409490ebf78171f35143897ca790")) @@ -178,7 +156,7 @@ suite "JSON Conversions": let tx = PastTransaction( blockHash: BlockHash(array[32, byte].fromHex("0x595bffbe897e025ea2df3213c4cc52c3f3d69bc04b49011d558f1b0e70038922")), blockNumber: 0x22e.u256, - sender: Address.init("0xe00b677c29ff8d8fe6068530e2bc36158c54dd34").get, + `from`: Address.init("0xe00b677c29ff8d8fe6068530e2bc36158c54dd34").get, gas: 0x4d4bb.u256, gasPrice: 0x3b9aca07.u256, hash: TransactionHash(array[32, byte].fromHex("0xa31608907c338d6497b0c6ec81049d845c7d409490ebf78171f35143897ca790")), @@ -205,12 +183,12 @@ suite "JSON Conversions": "nonce":"0x3", "to":"0x92f09aa59dccb892a9f5406ddd9c0b98f02ea57e", "transactionIndex":"0x3", + "type":"0x0", + "chainId":"0xc0de4", "value":"0x0", "v":"0x181bec", "r":"0x57ba18460934526333b80b0fea08737c363f3cd5fbec4a25a8a25e3e8acb362a", - "s":"0x33aa50bc8bd719b6b17ad0bf52006bf8943999198f2bf731eb33c118091000f2", - "type":"0x0", - "chainId":"0xc0de4" + "s":"0x33aa50bc8bd719b6b17ad0bf52006bf8943999198f2bf731eb33c118091000f2" }""".flatten check $(%tx) == expected @@ -239,6 +217,7 @@ suite "JSON Conversions": check %past.toTransaction == %*{ "to": !Address.init("0x92f09aa59dccb892a9f5406ddd9c0b98f02ea57e"), "data": hexToSeqByte("0x6368a471d26ff5c7f835c1a8203235e88846ce1a196d6e79df0eaedd1b8ed3deec2ae5c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000012a00000000000000000000000000000000000000000000000000000000000000"), + "value": "0x0", "from": !Address.init("0xe00b677c29ff8d8fe6068530e2bc36158c54dd34"), "nonce": 0x3.u256, "chainId": 0xc0de4.u256, diff --git a/testmodule/providers/jsonrpc/testJsonRpcProvider.nim b/testmodule/providers/jsonrpc/testJsonRpcProvider.nim index ee00acc..ccfc5e7 100644 --- a/testmodule/providers/jsonrpc/testJsonRpcProvider.nim +++ b/testmodule/providers/jsonrpc/testJsonRpcProvider.nim @@ -1,4 +1,3 @@ -import std/json import pkg/asynctest import pkg/chronos import pkg/ethers @@ -97,5 +96,5 @@ for url in ["ws://localhost:8545", "http://localhost:8545"]: discard await provider.getBlock(BlockTag.latest) expect JsonRpcProviderError: discard await provider.subscribe(proc(_: Block) = discard) - expect JsonRpcProviderError: + expect JsonRpcSignerError: discard await provider.getSigner().sendTransaction(Transaction.example) diff --git a/testmodule/providers/jsonrpc/testJsonRpcSigner.nim b/testmodule/providers/jsonrpc/testJsonRpcSigner.nim index 1b057f3..c25ef0a 100644 --- a/testmodule/providers/jsonrpc/testJsonRpcSigner.nim +++ b/testmodule/providers/jsonrpc/testJsonRpcSigner.nim @@ -52,7 +52,7 @@ suite "JsonRpcSigner": let signer = provider.getSigner() let transaction = Transaction.example let populated = await signer.populateTransaction(transaction) - check !populated.sender == await signer.getAddress() + check !populated.`from` == await signer.getAddress() check !populated.gasPrice == await signer.getGasPrice() check !populated.nonce == await signer.getTransactionCount(BlockTag.pending) check !populated.gasLimit == await signer.estimateGas(transaction) diff --git a/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim b/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim index 8671e7a..4421c26 100644 --- a/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim +++ b/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim @@ -64,6 +64,7 @@ suite "Web socket subscriptions": client = newRpcWebSocketClient() await client.connect("ws://localhost:8545") subscriptions = JsonRpcSubscriptions.new(client) + subscriptions.init() teardown: await subscriptions.close() @@ -81,6 +82,7 @@ suite "HTTP polling subscriptions": await client.connect("http://localhost:8545") subscriptions = JsonRpcSubscriptions.new(client, pollingInterval = 100.millis) + subscriptions.init() teardown: await subscriptions.close()