Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

someone else's address

IIRC this is currently not possible and not tested either


### 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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

would mention they can optionally claim refund too
in private - getting refund for excess repayment is very very powerful (sequencer refunds you money without knowing who you are! but this should be optional as it is costly in DA and proving time and for small txs may not make sense!)


## 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
Loading