Allow types that are equivalent to Confirmable

Allows ?TransactionResponse, Option[TransactionResponse] etc
to be used instead of Confirmable.
This commit is contained in:
Mark Spanbroek 2022-05-23 16:20:51 +02:00 committed by markspanbroek
parent 270d358b86
commit 649dc8efd0
3 changed files with 24 additions and 37 deletions

View File

@ -102,35 +102,35 @@ func isConstant(procedure: NimNode): bool =
return true return true
false false
func isTxResponse(returntype: NimNode): bool =
return returntype.eqIdent($ Confirmable)
func addContractCall(procedure: var NimNode) = func addContractCall(procedure: var NimNode) =
let contract = procedure[3][1][0] let contract = procedure[3][1][0]
let function = $basename(procedure[0]) let function = $basename(procedure[0])
let parameters = getParameterTuple(procedure) let parameters = getParameterTuple(procedure)
let returntype = procedure[3][0] let returntype = procedure[3][0]
# procedure[5] =
# quote: func call: NimNode =
# static: checkReturnType(type(result)) 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] = procedure[6] =
if procedure.isConstant: if procedure.isConstant:
if returntype.kind == nnkEmpty: call()
quote:
await call(`contract`, `function`, `parameters`)
else:
quote:
return await call(`contract`, `function`, `parameters`, `returntype`)
else: else:
# When ?TransactionResponse is specified as the return type of contract send()
# 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`)
func addFuture(procedure: var NimNode) = func addFuture(procedure: var NimNode) =
let returntype = procedure[3][0] let returntype = procedure[3][0]
@ -143,20 +143,6 @@ func addAsyncPragma(procedure: var NimNode) =
procedure[4] = newNimNode(nnkPragma) procedure[4] = newNimNode(nnkPragma)
procedure[4].add ident("async") 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 = macro contract*(procedure: untyped{nkProcDef|nkMethodDef}): untyped =
let parameters = procedure[3] 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 parameters.expectMinLen(2) # at least return type and contract instance
body.expectKind(nnkEmpty) body.expectKind(nnkEmpty)
procedure.checkReturnType()
var contractcall = copyNimTree(procedure) var contractcall = copyNimTree(procedure)
contractcall.addContractCall() contractcall.addContractCall()

View File

@ -4,6 +4,7 @@ description = "Tests for Nim Ethers library"
license = "MIT" license = "MIT"
requires "asynctest >= 0.3.0 & < 0.4.0" requires "asynctest >= 0.3.0 & < 0.4.0"
requires "questionable >= 0.10.3 & < 0.11.0"
task test, "Run the test suite": task test, "Run the test suite":
exec "nimble install -d -y" exec "nimble install -d -y"

View File

@ -1,5 +1,6 @@
import std/json import std/json
import pkg/asynctest import pkg/asynctest
import pkg/questionable
import pkg/stint import pkg/stint
import pkg/ethers import pkg/ethers
import ./hardhat 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 balanceOf*(erc20: Erc20, account: Address): UInt256 {.base, contract, view.}
method allowance*(erc20: Erc20, owner, spender: 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 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": suite "Contracts":