From 649dc8efd0f2c67801b1a97b3ee7f506ab890b16 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Mon, 23 May 2022 16:20:51 +0200 Subject: [PATCH] Allow types that are equivalent to Confirmable Allows ?TransactionResponse, Option[TransactionResponse] etc to be used instead of Confirmable. --- ethers/contract.nim | 57 +++++++++++++----------------------- testmodule/test.nimble | 1 + testmodule/testContracts.nim | 3 +- 3 files changed, 24 insertions(+), 37 deletions(-) diff --git a/ethers/contract.nim b/ethers/contract.nim index c786381..ca92810 100644 --- a/ethers/contract.nim +++ b/ethers/contract.nim @@ -102,35 +102,35 @@ func isConstant(procedure: NimNode): bool = return true false -func isTxResponse(returntype: NimNode): bool = - return returntype.eqIdent($ Confirmable) - func addContractCall(procedure: var NimNode) = let contract = procedure[3][1][0] let function = $basename(procedure[0]) let parameters = getParameterTuple(procedure) let returntype = procedure[3][0] - # procedure[5] = - # quote: - # static: checkReturnType(type(result)) + + func call: NimNode = + if returntype.kind == nnkEmpty: + quote: + await call(`contract`, `function`, `parameters`) + else: + quote: + return await call(`contract`, `function`, `parameters`, `returntype`) + + func send: NimNode = + if returntype.kind == nnkEmpty: + quote: + discard await send(`contract`, `function`, `parameters`) + else: + quote: + when typeof(result) isnot Confirmable: + {.error: "unexpected return type, missing {.view.} or {.pure.} ?".} + return await send(`contract`, `function`, `parameters`) + procedure[6] = if procedure.isConstant: - if returntype.kind == nnkEmpty: - quote: - await call(`contract`, `function`, `parameters`) - else: - quote: - return await call(`contract`, `function`, `parameters`, `returntype`) + call() else: - # When ?TransactionResponse is specified as the return type of contract - # method, it allows for contract transactions to be awaited on - # confirmations - if returntype.isTxResponse: - quote: - return await send(`contract`, `function`, `parameters`) - else: - quote: - discard await send(`contract`, `function`, `parameters`) + send() func addFuture(procedure: var NimNode) = let returntype = procedure[3][0] @@ -143,20 +143,6 @@ func addAsyncPragma(procedure: var NimNode) = procedure[4] = newNimNode(nnkPragma) procedure[4].add ident("async") -func checkReturnType(procedure: NimNode) = - let returntype = procedure[3][0] - if returntype.kind != nnkEmpty: - # Do not throw exception for methods that have a TransactionResponse - # return type as that is needed for .wait - if returntype.isTxResponse: - return - - if not procedure.isConstant: - const message = - "only contract functions with {.view.} or {.pure.} " & - "can have a return type" - error(message, returntype) - macro contract*(procedure: untyped{nkProcDef|nkMethodDef}): untyped = let parameters = procedure[3] @@ -164,7 +150,6 @@ macro contract*(procedure: untyped{nkProcDef|nkMethodDef}): untyped = parameters.expectMinLen(2) # at least return type and contract instance body.expectKind(nnkEmpty) - procedure.checkReturnType() var contractcall = copyNimTree(procedure) contractcall.addContractCall() diff --git a/testmodule/test.nimble b/testmodule/test.nimble index c7c6c46..2ebc1d7 100644 --- a/testmodule/test.nimble +++ b/testmodule/test.nimble @@ -4,6 +4,7 @@ description = "Tests for Nim Ethers library" license = "MIT" requires "asynctest >= 0.3.0 & < 0.4.0" +requires "questionable >= 0.10.3 & < 0.11.0" task test, "Run the test suite": exec "nimble install -d -y" diff --git a/testmodule/testContracts.nim b/testmodule/testContracts.nim index d805e46..26e6646 100644 --- a/testmodule/testContracts.nim +++ b/testmodule/testContracts.nim @@ -1,5 +1,6 @@ import std/json import pkg/asynctest +import pkg/questionable import pkg/stint import pkg/ethers import ./hardhat @@ -19,7 +20,7 @@ method totalSupply*(erc20: Erc20): UInt256 {.base, contract, view.} method balanceOf*(erc20: Erc20, account: Address): UInt256 {.base, contract, view.} method allowance*(erc20: Erc20, owner, spender: Address): UInt256 {.base, contract, view.} method transfer*(erc20: Erc20, recipient: Address, amount: UInt256) {.base, contract.} -method mint(token: TestToken, holder: Address, amount: UInt256): Confirmable {.base, contract.} +method mint(token: TestToken, holder: Address, amount: UInt256): ?TransactionResponse {.base, contract.} suite "Contracts":