diff --git a/yarn-project/aztec.js/src/contract/base_contract_interaction.ts b/yarn-project/aztec.js/src/contract/base_contract_interaction.ts index b0ace57c3228..00b7f6e69208 100644 --- a/yarn-project/aztec.js/src/contract/base_contract_interaction.ts +++ b/yarn-project/aztec.js/src/contract/base_contract_interaction.ts @@ -1,5 +1,6 @@ import { PXE, Tx, TxExecutionRequest } from '@aztec/circuit-types'; +import { FeeOptions } from '../account/interface.js'; import { SentTx } from './sent_tx.js'; /** @@ -11,6 +12,11 @@ export type SendMethodOptions = { * Wether to skip the simulation of the public part of the transaction. */ skipPublicSimulation?: boolean; + + /** + * The fee options for the transaction. + */ + fee?: FeeOptions; }; /** diff --git a/yarn-project/aztec.js/src/contract/batch_call.ts b/yarn-project/aztec.js/src/contract/batch_call.ts index 52c3e869de70..4bfd21879527 100644 --- a/yarn-project/aztec.js/src/contract/batch_call.ts +++ b/yarn-project/aztec.js/src/contract/batch_call.ts @@ -1,7 +1,7 @@ import { FunctionCall, TxExecutionRequest } from '@aztec/circuit-types'; import { Wallet } from '../account/index.js'; -import { BaseContractInteraction } from './base_contract_interaction.js'; +import { BaseContractInteraction, SendMethodOptions } from './base_contract_interaction.js'; /** A batch of function calls to be sent as a single transaction through a wallet. */ export class BatchCall extends BaseContractInteraction { @@ -12,11 +12,12 @@ export class BatchCall extends BaseContractInteraction { /** * Create a transaction execution request that represents this batch, encoded and authenticated by the * user's wallet, ready to be simulated. + * @param opts - An optional object containing additional configuration for the transaction. * @returns A Promise that resolves to a transaction instance. */ - public async create(): Promise { + public async create(opts?: SendMethodOptions): Promise { if (!this.txRequest) { - this.txRequest = await this.wallet.createTxExecutionRequest(this.calls); + this.txRequest = await this.wallet.createTxExecutionRequest(this.calls, opts?.fee); } return this.txRequest; } diff --git a/yarn-project/aztec.js/src/contract/contract_function_interaction.ts b/yarn-project/aztec.js/src/contract/contract_function_interaction.ts index 891ffb08a629..19591797c2c9 100644 --- a/yarn-project/aztec.js/src/contract/contract_function_interaction.ts +++ b/yarn-project/aztec.js/src/contract/contract_function_interaction.ts @@ -38,14 +38,15 @@ export class ContractFunctionInteraction extends BaseContractInteraction { /** * Create a transaction execution request that represents this call, encoded and authenticated by the * user's wallet, ready to be simulated. + * @param opts - An optional object containing additional configuration for the transaction. * @returns A Promise that resolves to a transaction instance. */ - public async create(): Promise { + public async create(opts?: SendMethodOptions): Promise { if (this.functionDao.functionType === FunctionType.UNCONSTRAINED) { throw new Error("Can't call `create` on an unconstrained function."); } if (!this.txRequest) { - this.txRequest = await this.wallet.createTxExecutionRequest([this.request()]); + this.txRequest = await this.wallet.createTxExecutionRequest([this.request()], opts?.fee); } return this.txRequest; } diff --git a/yarn-project/end-to-end/package.json b/yarn-project/end-to-end/package.json index f019bf353b46..faa0cebadc64 100644 --- a/yarn-project/end-to-end/package.json +++ b/yarn-project/end-to-end/package.json @@ -38,6 +38,7 @@ "@aztec/merkle-tree": "workspace:^", "@aztec/noir-contracts": "workspace:^", "@aztec/p2p": "workspace:^", + "@aztec/protocol-contracts": "workspace:^", "@aztec/pxe": "workspace:^", "@aztec/sequencer-client": "workspace:^", "@aztec/types": "workspace:^", diff --git a/yarn-project/end-to-end/src/e2e_native_fee_payments.test.ts b/yarn-project/end-to-end/src/e2e_native_fee_payments.test.ts new file mode 100644 index 000000000000..a74ba573b774 --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_native_fee_payments.test.ts @@ -0,0 +1,62 @@ +import { AztecAddress, ContractDeployer, NativeFeePaymentMethod } from '@aztec/aztec.js'; +import { GasTokenContract, TokenContract } from '@aztec/noir-contracts'; +import { getCanonicalGasToken } from '@aztec/protocol-contracts/gas-token'; + +import { setup } from './fixtures/utils.js'; + +describe('e2e_native_fee_payments', () => { + let aliceAddress: AztecAddress; + let _bobAddress: AztecAddress; + let sequencerAddress: AztecAddress; + let gasTokenContract: GasTokenContract; + let testContract: TokenContract; + + beforeAll(async () => { + const { accounts, sequencer, wallet } = await setup(3); + sequencer?.updateSequencerConfig({ + feeRecipient: accounts.at(-1)!.address, + }); + const canonicalGasToken = getCanonicalGasToken(); + const deployer = new ContractDeployer(canonicalGasToken.artifact, wallet); + const { contract } = await deployer + .deploy() + .send({ + contractAddressSalt: canonicalGasToken.instance.salt, + }) + .wait(); + + gasTokenContract = contract as GasTokenContract; + aliceAddress = accounts.at(0)!.address; + _bobAddress = accounts.at(1)!.address; + sequencerAddress = sequencer!.feeRecipient; + + testContract = await TokenContract.deploy(wallet, aliceAddress, 'Test', 'TEST', 1).send().deployed(); + + // Alice gets a balance of 1000 gas token + await gasTokenContract.methods.redeem_bridged_balance(1000).send().wait(); + }, 100_000); + + it('deploys gas token contract at canonical address', () => { + expect(gasTokenContract.address).toEqual(getCanonicalGasToken().address); + }); + + it('pays out the expected fee to the sequencer', async () => { + await testContract.methods + .mint_public(aliceAddress, 1000) + .send({ + fee: { + maxFee: 1, + paymentMethod: new NativeFeePaymentMethod(), + }, + }) + .wait(); + + const [sequencerBalance, aliceBalance] = await Promise.all([ + gasTokenContract.methods.balance_of(sequencerAddress).view(), + gasTokenContract.methods.balance_of(aliceAddress).view(), + ]); + + expect(sequencerBalance).toEqual(1n); + expect(aliceBalance).toEqual(999n); + }); +}); diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index 5d903bf814d2..eaa83e8ae557 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -387,6 +387,7 @@ __metadata: "@aztec/merkle-tree": "workspace:^" "@aztec/noir-contracts": "workspace:^" "@aztec/p2p": "workspace:^" + "@aztec/protocol-contracts": "workspace:^" "@aztec/pxe": "workspace:^" "@aztec/sequencer-client": "workspace:^" "@aztec/types": "workspace:^"