From a7d19444065e880d6742ba1be792b87e00f1cccc Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Mon, 11 Jul 2022 15:15:01 +0200 Subject: [PATCH] Allow for custom transaction properties --- ethers/contract.nim | 33 +++++++++++++++++++++++++-------- testmodule/mocks.nim | 20 ++++++++++++++++++++ testmodule/testContracts.nim | 14 ++++++++++++++ 3 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 testmodule/mocks.nim diff --git a/ethers/contract.nim b/ethers/contract.nim index b36d7eb..f7bbc55 100644 --- a/ethers/contract.nim +++ b/ethers/contract.nim @@ -47,10 +47,14 @@ template raiseContractError(message: string) = proc createTransaction(contract: Contract, function: string, - parameters: tuple): Transaction = + parameters: tuple, + overrides = Transaction.default): Transaction = let selector = selector(function, typeof parameters).toArray let data = @selector & AbiEncoder.encode(parameters) - Transaction(to: contract.address, data: data) + var transaction = overrides + transaction.to = contract.address + transaction.data = data + return transaction proc decodeResponse(T: type, multiple: static bool, bytes: seq[byte]): T = when multiple: @@ -77,11 +81,13 @@ proc call(contract: Contract, let response = await contract.provider.call(transaction, blockTag) return decodeResponse(ReturnType, returnMultiple, response) -proc send(contract: Contract, function: string, parameters: tuple): - Future[?TransactionResponse] {.async.} = - +proc send(contract: Contract, + function: string, + parameters: tuple, + overrides = Transaction.default): + Future[?TransactionResponse] {.async.} = if signer =? contract.signer: - let transaction = createTransaction(contract, function, parameters) + let transaction = createTransaction(contract, function, parameters, overrides) let populated = await signer.populateTransaction(transaction) let txResp = await signer.sendTransaction(populated) return txResp.some @@ -111,6 +117,15 @@ func isMultipleReturn(returnType: NimNode): bool = (returnType.kind == nnkTupleConstr) or (returnType.kind == nnkTupleTy) +func addOverrides(procedure: var NimNode) = + procedure[3].add( + newIdentDefs( + ident("overrides"), + newEmptyNode(), + quote do: Transaction.default + ) + ) + func addContractCall(procedure: var NimNode) = let contract = procedure[3][1][0] let function = $basename(procedure[0]) @@ -118,6 +133,8 @@ func addContractCall(procedure: var NimNode) = let returnType = procedure[3][0] let returnMultiple = returnType.isMultipleReturn.newLit + procedure.addOverrides() + func call: NimNode = if returnType.kind == nnkEmpty: quote: @@ -130,12 +147,12 @@ func addContractCall(procedure: var NimNode) = func send: NimNode = if returnType.kind == nnkEmpty: quote: - discard await send(`contract`, `function`, `parameters`) + discard await send(`contract`, `function`, `parameters`, overrides) else: quote: when typeof(result) isnot Confirmable: {.error: "unexpected return type, missing {.view.} or {.pure.} ?".} - return await send(`contract`, `function`, `parameters`) + return await send(`contract`, `function`, `parameters`, overrides) procedure[6] = if procedure.isConstant: diff --git a/testmodule/mocks.nim b/testmodule/mocks.nim new file mode 100644 index 0000000..30584e1 --- /dev/null +++ b/testmodule/mocks.nim @@ -0,0 +1,20 @@ +import pkg/ethers + +type MockSigner* = ref object of Signer + provider: Provider + address*: Address + transactions*: seq[Transaction] + +func new*(_: type MockSigner, provider: Provider): MockSigner = + MockSigner(provider: provider) + +method provider*(signer: MockSigner): Provider = + signer.provider + +method getAddress*(signer: MockSigner): Future[Address] {.async.} = + return signer.address + +method sendTransaction*(signer: MockSigner, + transaction: Transaction): + Future[TransactionResponse] {.async.} = + signer.transactions.add(transaction) diff --git a/testmodule/testContracts.nim b/testmodule/testContracts.nim index 842c116..05e0c2d 100644 --- a/testmodule/testContracts.nim +++ b/testmodule/testContracts.nim @@ -5,6 +5,7 @@ import pkg/stint import pkg/ethers import ./hardhat import ./miner +import ./mocks type @@ -112,6 +113,19 @@ suite "Contracts": check (await token.connect(provider).balanceOf(accounts[1])) == 25.u256 check (await token.connect(provider).balanceOf(accounts[2])) == 25.u256 + test "takes custom values for nonce, gasprice and gaslimit": + let overrides = Transaction( + nonce: some 100.u256, + gasPrice: some 200.u256, + gasLimit: some 300.u256 + ) + let signer = MockSigner.new(provider) + discard await token.connect(signer).mint(accounts[0], 42.u256, overrides) + check signer.transactions.len == 1 + check signer.transactions[0].nonce == overrides.nonce + check signer.transactions[0].gasPrice == overrides.gasPrice + check signer.transactions[0].gasLimit == overrides.gasLimit + test "receives events when subscribed": var transfers: seq[Transfer]