Skip to content

Commit

Permalink
docs: Fees doc snippets and code snippets (#12229)
Browse files Browse the repository at this point in the history
  • Loading branch information
jzaki authored Feb 26, 2025
1 parent 5da66c8 commit 5d49445
Show file tree
Hide file tree
Showing 16 changed files with 159 additions and 14 deletions.
8 changes: 0 additions & 8 deletions docs/components/snippet.js

This file was deleted.

31 changes: 31 additions & 0 deletions docs/components/snippets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from "react";

export const CLI_Fees = () => (
<p>
The CLI tool <code>aztec-wallet</code> takes the fee payment method via the
param: <code>--payment method=fee_juice</code>. See help for sending txs, eg{" "}
<code>aztec-wallet help deploy</code>
</p>
);

export const Gas_Settings = () => (
<p>
<code>Gas Settings</code> used in transactions specify gas limits and
maximum fee rates (fees-per-gas)
</p>
);

export const Gas_Components = () => (
<p>
The <code>Gas</code> and <code>GasFees</code> types each specify Data
availability and L2 cost components.
</p>
);

export const Spec_Placeholder = () => (
<p>
The design and implementation have largely changed since the original
specification, and these docs will soon be updated to reflect the latest
implementation.
</p>
);
2 changes: 1 addition & 1 deletion docs/docs/aztec/concepts/accounts/_category_.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"label": "Accounts",
"position": 2,
"position": 4,
"collapsible": true,
"collapsed": true
}
9 changes: 9 additions & 0 deletions docs/docs/aztec/concepts/fees.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: Fees
sidebar_position: 0
tags: [fees]
---

This section is currently being updated and will supplemented by information in the corresponding section of the protocol specifications.

For a guide on how to pay fees programmatically, see [Paying fees in TypeScript](../../developers/guides/js_apps/pay_fees).
2 changes: 1 addition & 1 deletion docs/docs/aztec/concepts/storage/_category_.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"label": "Storage",
"position": 0,
"position": 1,
"collapsible": true,
"collapsed": true
}
2 changes: 1 addition & 1 deletion docs/docs/aztec/smart_contracts/contract_creation.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Contract Deployment
tags: [contracts, protocol]
---

import Spec_Placeholder from '/components/snippet';
import { Spec_Placeholder } from '/components/snippets';

<Spec_Placeholder />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ When you define a function in an Aztec contract, it undergoes several transforma
- [Creating a context for the function](#context-creation)
- [Handling function inputs](#private-and-public-input-injection)
- [Processing return values](#return-value-handling)
- [Computing note hashes and nullifiers](#computing-note-hash-and-nullifier)
- [Generating function signatures](#function-signature-generation)
- [Generating contract artifacts](#contract-artifacts)

Expand Down Expand Up @@ -155,7 +154,7 @@ fn compute_fn_signature_hash(fn_name: &str, parameters: &[Type]) -> u32 {

- A string representation of the function is created, including the function name and parameter types
- This signature string is then hashed using Keccak-256
- The first 4 bytes of the resulting hash are coverted to a u32 integer
- The first 4 bytes of the resulting hash are converted to a u32 integer

### Integration into contract interface

Expand Down
96 changes: 96 additions & 0 deletions docs/docs/developers/guides/js_apps/pay_fees.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
title: How to Pay Fees
tags: [fees, transactions, developers]
---

There a several ways to pay for transaction fees, thanks to fee abstraction implemented in the Aztec protocol.

This guide shows the various ways this can be done. For more of a background see [Fees on Aztec](../../../aztec/concepts/fees).

## Methods to pay a tx fee

### Natively via an existing balance of fee juice

Either your own account or someone else's address has a balance of fee juice, and the transaction is paid for from this balance.

### Natively via a balance of fee juice to be claimed

Processing this transaction first claims bridged fee juice then is paid for from the balance, all in the same public/private tx.

### Privately or publicly via a Fee Paying Contract

A fee paying contract (FPC) is created and nominates a token that it accepts to then pay for txs in fee juice. So a user doesn't need to hold fee juice, they only need the token that the FPC accepts.

## Fee Options

Functions pertaining to sending a transaction, such as `deploy` and `send`, each include a `fee` variable defined with the following (optional) parameters:

#include_code user_fee_options yarn-project/aztec.js/src/entrypoint/payload.ts javascript


### Fee Payment Method

The `paymentMethod` is an object for the type of payment. Each of the implementations can be found [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/aztec.js/src/fee). For example:

#include_code fee_juice_method yarn-project/aztec.js/src/fee/fee_juice_payment_method.ts javascript

### Gas Settings

#include_code gas_settings_vars yarn-project/stdlib/src/gas/gas_settings.ts javascript

import { Gas_Components, Gas_Settings } from '/components/snippets';

<Gas_Settings />

<Gas_Components />

### Other params

Fee and gas padding params can be left to their default values, and the estimateGas boolean can be used when simulating a tx to calculate gas.

With the fee options explained, lets do a paid transaction.

## Examples

### Pay with FeeJuice

An account can be deployed directly via fee-juice payment if the address has been pre-funded.
This is done using the AccountManager as follows:

#include_code pay_fee_juice_deploy yarn-project/end-to-end/src/e2e_fees/account_init.test.ts javascript

Or to send a transaction from an account holding fee juice:
(Note: this example is a public token transfer call, but can equally be a private function call)

#include_code pay_fee_juice_send yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts javascript

**The equivalent to specify fees via CLI...**

import { CLI_Fees } from '/components/snippets';

<CLI_Fees />

See here to [Bridge Fee Juice](../../../developers/reference/environment_reference/cli_wallet_reference#bridge-fee-juice) via the CLI wallet.

### Claim and pay

After a user has sent fee juice from L1 to be bridged to L2, a transaction can be made that claims this to pay for itself, and make the transaction, in one.

The claim object:

#include_code claim_type_amount yarn-project/aztec.js/src/api/ethereum/portal_manager.ts javascript

Calling a function on an object (in this case checking the balance of the fee juice contract)

#include_code claim_and_pay yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts javascript


### Fee Paying Contract

Similarly with a fee paying contract, the fee payment method is created and used as follows:

#include_code fpc yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts javascript

In this example, thanks to the FPC's `accepted_asset` being banana tokens, Alice only needs to hold this token and not fee juice. The function being called happens to also be a transfer of banana tokens to Bob.

More on FPCs [here](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr)
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ aztec codegen target -o src/artifacts

### Token Bridge Contract

The [token bridge tutorial](./token_bridge/index.md) is a great follow up to this one.
The [token bridge tutorial](./token_bridge) is a great follow up to this one.

It builds on the Token contract described here and goes into more detail about Aztec contract composability and Ethereum (L1) and Aztec (L2) cross-chain messaging.

Expand Down
4 changes: 4 additions & 0 deletions yarn-project/aztec.js/src/api/ethereum/portal_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
toFunctionSelector,
} from 'viem';

// docs:start:claim_type
// docs:start:claim_type_amount
/** L1 to L2 message info to claim it on L2. */
export type L2Claim = {
/** Secret for claiming. */
Expand All @@ -32,9 +34,11 @@ export type L2Claim = {
/** Leaf index in the L1 to L2 message tree. */
messageLeafIndex: bigint;
};
// docs:end:claim_type

/** L1 to L2 message info that corresponds to an amount to claim. */
export type L2AmountClaim = L2Claim & { /** Amount to claim */ claimAmount: bigint };
// docs:end:claim_type_amount

/** L1 to L2 message info that corresponds to an amount to claim with associated recipient. */
export type L2AmountClaimWithRecipient = L2AmountClaim & {
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/aztec.js/src/entrypoint/payload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export type FeeOptions = {
gasSettings: GasSettings;
};

// docs:start:user_fee_options
/** Fee options as set by a user. */
export type UserFeeOptions = {
/** The fee payment method to use */
Expand All @@ -34,6 +35,7 @@ export type UserFeeOptions = {
/** Percentage to pad the estimated gas limits by, if empty, defaults to 0.1. Only relevant if estimateGas is set. */
estimatedGasPadding?: number;
};
// docs:end:user_fee_options

// These must match the values defined in:
// - noir-projects/aztec-nr/aztec/src/entrypoint/app.nr
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/aztec.js/src/fee/fee_juice_payment_method.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import type { AztecAddress } from '@aztec/stdlib/aztec-address';

import type { FeePaymentMethod } from './fee_payment_method.js';

// docs:start:fee_juice_method
/**
* Pay fee directly in the Fee Juice.
*/
export class FeeJuicePaymentMethod implements FeePaymentMethod {
// docs:end:fee_juice_method
constructor(protected sender: AztecAddress) {}

getAsset() {
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/end-to-end/src/e2e_fees/account_init.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,10 @@ describe('e2e_fees account_init', () => {
const [bobsInitialGas] = await t.getGasBalanceFn(bobsAddress);
expect(bobsInitialGas).toEqual(FEE_FUNDING_FOR_TESTER_ACCOUNT);

// docs:start:pay_fee_juice_deploy
const paymentMethod = new FeeJuicePaymentMethod(bobsAddress);
const tx = await bobsAccountManager.deploy({ fee: { paymentMethod } }).wait();
// docs:end:pay_fee_juice_deploy

expect(tx.transactionFee!).toBeGreaterThan(0n);
await expect(t.getGasBalanceFn(bobsAddress)).resolves.toEqual([bobsInitialGas - tx.transactionFee!]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@ describe('e2e_fees Fee Juice payments', () => {

it('claims bridged funds and pays with them on the same tx', async () => {
const claim = await t.feeJuiceBridgeTestHarness.prepareTokensOnL1(FEE_FUNDING_FOR_TESTER_ACCOUNT, bobAddress);
// docs:start:claim_and_pay
const paymentMethod = new FeeJuicePaymentMethodWithClaim(bobAddress, claim);
const receipt = await feeJuiceContract
.withWallet(bobWallet)
.methods.check_balance(0n)
.send({ fee: { gasSettings, paymentMethod } })
.wait();
// docs:end:claim_and_pay
const endBalance = await feeJuiceContract.methods.balance_of_public(bobAddress).simulate();

expect(endBalance).toBeGreaterThan(0n);
Expand All @@ -84,11 +86,13 @@ describe('e2e_fees Fee Juice payments', () => {
describe('with initial funds', () => {
it('sends tx with payment in Fee Juice with public calls', async () => {
const initialBalance = await feeJuiceContract.methods.balance_of_public(aliceAddress).simulate();
// docs:start:pay_fee_juice_send
const paymentMethod = new FeeJuicePaymentMethod(aliceAddress);
const { transactionFee } = await bananaCoin.methods
.transfer_in_public(aliceAddress, bobAddress, 1n, 0n)
.send({ fee: { gasSettings, paymentMethod } })
.wait();
// docs:end:pay_fee_juice_send
expect(transactionFee).toBeGreaterThan(0n);
const endBalance = await feeJuiceContract.methods.balance_of_public(aliceAddress).simulate();
expect(endBalance).toBeLessThan(initialBalance);
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ describe('e2e_fees public_payment', () => {

it('pays fees for tx that make public transfer', async () => {
const bananasToSendToBob = 10n;
// docs:start:fpc
const tx = await bananaCoin.methods
.transfer_in_public(aliceAddress, bobAddress, bananasToSendToBob, 0)
.send({
Expand All @@ -68,6 +69,7 @@ describe('e2e_fees public_payment', () => {
},
})
.wait();
// docs:end:fpc

const feeAmount = tx.transactionFee!;

Expand Down
2 changes: 2 additions & 0 deletions yarn-project/stdlib/src/gas/gas_settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { z } from 'zod';
import { Gas, GasDimensions } from './gas.js';
import { GasFees } from './gas_fees.js';

// docs:start:gas_settings_vars
/** Gas usage and fees limits set by the transaction sender for different dimensions and phases. */
export class GasSettings {
constructor(
Expand All @@ -16,6 +17,7 @@ export class GasSettings {
public readonly maxFeesPerGas: GasFees,
public readonly maxPriorityFeesPerGas: GasFees,
) {}
// docs:end:gas_settings_vars

static get schema() {
return z
Expand Down

2 comments on commit 5d49445

@AztecBot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'C++ Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: 5d49445 Previous: 5da66c8 Ratio
wasmconstruct_proof_ultrahonk_power_of_2/20 11671.069705999998 ms/iter 11103.012053 ms/iter 1.05

This comment was automatically generated by workflow using github-action-benchmark.

CC: @ludamad @codygunton

@AztecBot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'P2P Testbench'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: 5d49445 Previous: 5da66c8 Ratio
degree-1-strict - minDelay 408 ms 106 ms 3.85
degree-1-strict - maxDelay 1442 ms 524 ms 2.75
degree-1-strict - averageDelay 788.67 ms 315.25 ms 2.50
degree-1-strict - medianDelay 516 ms 425 ms 1.21
normal-degree-50-nodes - maxDelay 7243 ms 6769 ms 1.07
normal-degree-50-nodes - averageDelay 2472.71 ms 2255.8 ms 1.10
normal-degree-50-nodes - medianDelay 1307 ms 1136 ms 1.15

This comment was automatically generated by workflow using github-action-benchmark.

CC: @Maddiaa0

Please sign in to comment.