Skip to main content
Version: dev

How to Pay Fees

This guide shows you how to pay fees for transactions in Aztec using different payment methods.

Prerequisites:

  • Aztec sandbox or testnet access
  • aztec-wallet CLI or aztec.js installed
  • Basic understanding of Aztec accounts and transactions

Note:

The fee asset is only transferrable within a block to the current sequencer, as it powers the fee abstraction mechanism on Aztec. The asset is not transferable beyond this to ensure credible neutrality between all third party developer made asset portals and to ensure local compliance rules can be followed.

Payment Methods Overview

MethodUse CaseRequirements
Sponsored FPCFirst account deploymentNone (free bootstrap)
Fee Juice (direct)Regular transactionsFunded account
Fee Juice (from another account)New account deploymentAnother funded account
Fee Juice (bridged)Initial fundingL1 assets
Custom FPCPay with other tokensFPC setup

Quick Start: Deploy Your First Account

Using Sponsored FPC (Bootstrap Method)

The easiest way to get started is with a sponsored FPC, available in sandbox environments.

CLI:

# Get the sponsored FPC address
SPONSORED_FPC_ADDRESS=$(aztec get-canonical-sponsored-fpc-address)

# Register and deploy account
aztec-wallet register-contract $SPONSORED_FPC_ADDRESS SponsoredFPC --salt 0 --from main
aztec-wallet deploy-account --from main --payment method=fpc-sponsored,fpc=$SPONSORED_FPC_ADDRESS

JavaScript:

import { SponsoredFeePaymentMethod } from "@aztec/aztec.js/fee/testing";
import { getSponsoredFPCInstance } from "../src/utils/sponsored_fpc.js";

const sponsoredFPC = await getSponsoredFPCInstance();
await pxe.registerContract({
instance: sponsoredFPC,
artifact: SponsoredFPCContract.artifact,
});

const paymentMethod = new SponsoredFeePaymentMethod(sponsoredFPC.address);
await accountManager.deploy({ fee: { paymentMethod } }).wait();

Using Another Account's Fee Juice

If you have an existing funded account:

CLI:

aztec-wallet create-account -a alice --payment method=fee_juice,feePayer=test0

JavaScript:

import { FeeJuicePaymentMethod } from "@aztec/aztec.js";

const paymentMethod = new FeeJuicePaymentMethod(fundedAccount.getAddress());
await newAccount.deploy({
fee: {
deployWallet: fundedAccount,
paymentMethod
}
}).wait();

Bridging Fee Juice

Sandbox (Free Minting)

get_node_info_pub_client
const info = await pxe.getNodeInfo();
const publicClient = getPublicClient({
l1RpcUrls: ['http://localhost:8545'],
l1ChainId: foundry.id,
});
Source code: yarn-project/end-to-end/src/spartan/smoke.test.ts#L52-L58
import { L1FeeJuicePortalManager } from "@aztec/aztec.js";
bridge_fee_juice
const portal = await L1FeeJuicePortalManager.new(pxe, l1Client, log);
const claim = await portal.bridgeTokensPublic(recipient, amount, true /* mint */);
Source code: yarn-project/end-to-end/src/spartan/setup_test_wallets.ts#L186-L189

CLI:

aztec-wallet bridge-fee-juice 1000000000000000000 myAccount --mint --no-wait

Testnet

First mint fee juice on L1:

cast call $FEE_ASSET_HANDLER_CONTRACT "mint(address)" $MY_L1_ADDRESS --rpc-url <RPC_URL>

Then bridge with CLI:

aztec-wallet bridge-fee-juice 1000000000000000000 myAccount --no-wait \
--l1-rpc-urls https://rpc.sepolia.ethpandaops.io \
--l1-chain-id 11155111 \
--l1-private-key <YOUR_L1_PRIVATE_KEY>

Wait for 2 blocks, then claim and deploy:

aztec-wallet deploy-account --from myAccount --payment method=fee_juice,claim

Payment Examples

Pay with Fee Juice

Standard payment from a funded account:

import { FeeJuicePaymentMethod } from "@aztec/aztec.js";
pay_fee_juice_send
const paymentMethod = new FeeJuicePaymentMethod(aliceAddress);
const { transactionFee } = await bananaCoin.methods
.transfer_in_public(aliceAddress, bobAddress, 1n, 0n)
.send({ from: aliceAddress, fee: { gasSettings, paymentMethod } })
.wait();
Source code: yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts#L98-L104

CLI equivalent:

The CLI tool aztec-wallet takes the fee payment method via the param: --payment method=fee_juice. See help for sending txs, eg aztec-wallet help deploy

Claim and Deploy

Using bridged fee juice to deploy an account:

import { FeeJuicePaymentMethodWithClaim } from "@aztec/aztec.js";
claim_and_deploy
const wallet = await account.getWallet();
const paymentMethod = new FeeJuicePaymentMethodWithClaim(wallet, claim);
const sentTx = account.deploy({ fee: { paymentMethod } });
const txHash = await sentTx.getTxHash();
Source code: yarn-project/bot/src/factory.ts#L152-L157

CLI:

aztec-wallet deploy-account --from myAccount --payment method=fee_juice,claim

Fee Paying Contracts

FPCs allow paying with other tokens instead of fee juice.

Setup FPC

Register an FPC in your PXE:

import { FPCContract } from "@aztec/noir-contracts.js/FPC";
import { getContractInstanceFromInstantiationParams } from "@aztec/aztec.js";

const fpcInstance = getContractInstanceFromInstantiationParams(
FPCContract.artifact,
fpcDeployParams
);

await pxe.registerContract({
instance: fpcInstance,
artifact: FPCContract.artifact,
});

Public Payment

import { PublicFeePaymentMethod } from "@aztec/aztec.js";
fpc
const tx = await bananaCoin.methods
.transfer_in_public(aliceAddress, bobAddress, bananasToSendToBob, 0)
.send({
from: aliceAddress,
fee: {
gasSettings,
paymentMethod: new PublicFeePaymentMethod(bananaFPC.address, aliceWallet),
},
})
.wait();
Source code: yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts#L58-L69

CLI:

aztec-wallet <command> --payment method=fpc-public,fpc=$FPC_ADDRESS,asset=$ASSET_ADDRESS

Private Payment

import { PrivateFeePaymentMethod } from "@aztec/aztec.js";

const privateFee = new PrivateFeePaymentMethod(fpc.address, wallet);
await contract.methods.someMethod().send({
fee: { paymentMethod: privateFee }
}).wait();

CLI:

aztec-wallet <command> --payment method=fpc-private,fpc=$FPC_ADDRESS,asset=$ASSET_ADDRESS

Fee Options Reference

JavaScript Fee Object

user_fee_options
/** Fee options as set by a user. */
export type UserFeeOptions = {
/** The fee payment method to use */
paymentMethod?: FeePaymentMethod;
/** The gas settings */
gasSettings?: Partial<FieldsOf<GasSettings>>;
/** Percentage to pad the base fee by, if empty, defaults to 0.5 */
baseFeePadding?: number;
/** Whether to run an initial simulation of the tx with high gas limit to figure out actual gas settings. */
estimateGas?: boolean;
/** Percentage to pad the estimated gas limits by, if empty, defaults to 0.1. Only relevant if estimateGas is set. */
estimatedGasPadding?: number;
};
Source code: yarn-project/entrypoints/src/interfaces.ts#L83-L97

Gas Settings

gas_settings_vars
/** Gas usage and fees limits set by the transaction sender for different dimensions and phases. */
export class GasSettings {
constructor(
public readonly gasLimits: Gas,
public readonly teardownGasLimits: Gas,
public readonly maxFeesPerGas: GasFees,
public readonly maxPriorityFeesPerGas: GasFees,
) {}
Source code: yarn-project/stdlib/src/gas/gas_settings.ts#L11-L20

Gas Settings used in transactions specify gas limits and maximum fee rates (fees-per-gas)

The Gas and GasFees types each specify Data availability and L2 cost components, so the settings are:

  • gasLimits: DA and L2 gas limits
  • teardownGasLimits: DA and L2 gas limits for a txs optional teardown operation
  • maxFeesPerGas: maximum DA and L2 fees-per-gas
  • maxPriorityFeesPerGas: maximum priority DA and L2 fees-per-gas

Quick Reference

CLI Payment Options

# Default (fee juice from sender)
--payment method=fee_juice

# From another account (deploy only)
--payment method=fee_juice,feePayer=$ADDRESS

# Claim bridged fee juice
--payment method=fee_juice,claim

# Sponsored FPC
--payment method=fpc-sponsored,fpc=$FPC_ADDRESS

# Public FPC
--payment method=fpc-public,fpc=$FPC_ADDRESS,asset=$ASSET_ADDRESS

# Private FPC
--payment method=fpc-private,fpc=$FPC_ADDRESS,asset=$ASSET_ADDRESS

JavaScript Payment Methods

// Fee juice from sender
new FeeJuicePaymentMethod(senderAddress)

// Fee juice with claim
new FeeJuicePaymentMethodWithClaim(wallet, claim)

// Sponsored FPC
new SponsoredFeePaymentMethod(fpcAddress)

// Public FPC
new PublicFeePaymentMethod(fpcAddress, wallet)

// Private FPC
new PrivateFeePaymentMethod(fpcAddress, wallet)

Tips

  • Use sponsored FPC for your first account deployment
  • Bridge fee juice before you need it (2 block confirmation time)
  • Private payment methods are the only way to pay fees privately
  • Test accounts are only available in sandbox, not testnet
  • Use block explorers to track transactions:

    Transactions and balances can be viewed in block explorers like AztecExplorer and AztecScan.