diff --git a/docs/docs/aztec/concepts/fees.md b/docs/docs/aztec/concepts/fees.md
index 2f0ad1cea459..8f721c55c0a7 100644
--- a/docs/docs/aztec/concepts/fees.md
+++ b/docs/docs/aztec/concepts/fees.md
@@ -60,6 +60,8 @@ These are:
A fee payer will have bridged fee-juice from L1. On Aztec this fee asset is non-transferrable, and only deducted by the protocol to pay for fees.
+The mechanisms for bridging is the same as any other token. For more on this concept see the start of the [Token Bridge Tutorial](../../developers/tutorials/codealong/contract_tutorials/token_bridge) where it describes the components and how bridging works (under the hood this makes use of [portals](https://docs.aztec.network/aztec/concepts/communication/portals)).
+
### Payment methods
An account with fee-juice can pay for its transactions, including deployment of a new account.
diff --git a/docs/docs/developers/guides/js_apps/authwit.md b/docs/docs/developers/guides/js_apps/authwit.md
index 4392befc9770..730911a01237 100644
--- a/docs/docs/developers/guides/js_apps/authwit.md
+++ b/docs/docs/developers/guides/js_apps/authwit.md
@@ -1,6 +1,7 @@
---
title: How to use authentication witnesses (authwit)
tags: [accounts, authwit]
+sidebar_position: 5
---
This page assumes you have authwit set up correctly in your contract. To learn how to do that, [go here](../smart_contracts/writing_contracts/authwit.md).
diff --git a/docs/docs/developers/guides/js_apps/pay_fees.md b/docs/docs/developers/guides/js_apps/pay_fees.md
index 920485bff762..510da2b61e48 100644
--- a/docs/docs/developers/guides/js_apps/pay_fees.md
+++ b/docs/docs/developers/guides/js_apps/pay_fees.md
@@ -1,6 +1,7 @@
---
title: How to Pay Fees
tags: [fees, transactions, developers]
+sidebar_position: 3
---
There a several ways to pay for transaction fees, thanks to fee abstraction implemented in the Aztec protocol.
@@ -21,6 +22,40 @@ Processing this transaction first claims bridged fee juice then is paid for from
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.
+## Bridging fee-juice
+
+To first get fee juice into an account it needs to be bridged from L1.
+
+:::note
+See here to [Bridge Fee Juice](../../../developers/reference/environment_reference/cli_wallet_reference#bridge-fee-juice) via the CLI wallet.
+
+:::
+
+One way of bridging of tokens is described fully [here](../../../developers/tutorials/codealong/contract_tutorials/token_bridge#deposit-to-aztec). Below summarises specifically bridging fee juice on the sandbox.
+
+First get the node info and create a public client pointing to the sandbox's anvil L1 node (from foundry):
+
+#include_code get_node_info_pub_client yarn-project/end-to-end/src/spartan/smoke.test.ts javascript
+
+After importing:
+
+```ts
+import { L1FeeJuicePortalManager } from "@aztec/aztec.js";
+```
+
+Create a new fee juice portal manager and bridge fee juice publicly to Aztec:
+
+#include_code bridge_fee_juice yarn-project/end-to-end/src/spartan/setup_test_wallets.ts javascript
+
+Bridging can also be done privately with the corresponding function:
+
+#include_code bridge_tokens_private yarn-project/aztec.js/src/ethereum/portal_manager.ts javascript
+
+For the mechanisms to complete bridging between L1 and Aztec, any two other transactions on the sandbox are made. After this, an already deployed account should have its fee juice ready to use in transactions.
+
+Alternatively, the resulting claim object can be used to create a payment method to claim and pay for a transaction in one, where the transaction is the contract's deployment.
+
+
## Fee Options
Functions pertaining to sending a transaction, such as `deploy` and `send`, each include a `fee` variable defined with the following (optional) parameters:
@@ -55,12 +90,7 @@ With the fee options explained, lets do a paid transaction.
### 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:
+To send a transaction from an already deployed account already 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
@@ -71,21 +101,18 @@ import { CLI_Fees } from '/components/snippets';
-See here to [Bridge Fee Juice](../../../developers/reference/environment_reference/cli_wallet_reference#bridge-fee-juice) via the CLI wallet.
+### Claim and deploy
-### Claim and pay
+Here we will use the `claim` object previously from the bridging section, and the corresponding `wallet`, to create the payment method. The payment method is then used to claim fee juice and pay for account contract deployment. Note the function used to bridge fee juice (private/public) should correspond to how the fee juice is claimed.
-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.
+#include_code claim_and_deploy yarn-project/bot/src/factory.ts javascript
-The claim object:
+#### Claim and Pay
-#include_code claim_type_amount yarn-project/aztec.js/src/ethereum/portal_manager.ts javascript
-
-Calling a function on an object (in this case checking the balance of the fee juice contract)
+Calling a function, 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:
diff --git a/docs/docs/developers/guides/js_apps/send_transaction.md b/docs/docs/developers/guides/js_apps/send_transaction.md
index 6d21bcf362c8..fd6ee53531ca 100644
--- a/docs/docs/developers/guides/js_apps/send_transaction.md
+++ b/docs/docs/developers/guides/js_apps/send_transaction.md
@@ -1,18 +1,20 @@
---
title: How to Send a Transaction
-sidebar_position: 3
+sidebar_position: 4
---
This guide explains how to send a transaction using Aztec.js.
## Prerequisites
-You should have a wallet to act as the transaction sender, and a contract that has been deployed.
+You should have a wallet to act as the transaction sender, a contract that has been deployed, and fee juice to pay for transactions.
You can learn how to create wallets from [this guide](./create_account.md).
You can learn how to deploy a contract [here](./deploy_contract.md).
+You can learn how to use fee juice [here](./pay_fees.md).
+
## Relevant imports
You will need to import this library:
diff --git a/docs/docs/developers/guides/js_apps/test.md b/docs/docs/developers/guides/js_apps/test.md
index d58f8975865a..978aa008549a 100644
--- a/docs/docs/developers/guides/js_apps/test.md
+++ b/docs/docs/developers/guides/js_apps/test.md
@@ -1,6 +1,7 @@
---
title: Testing Aztec.nr contracts with TypeScript
tags: [contracts, tests]
+sidebar_position: 6
---
In this guide we will cover how to interact with your Aztec.nr smart contracts in a testing environment to write automated tests for your apps.
diff --git a/yarn-project/aztec.js/src/ethereum/portal_manager.ts b/yarn-project/aztec.js/src/ethereum/portal_manager.ts
index 37ce8c50428a..b127f1d9d912 100644
--- a/yarn-project/aztec.js/src/ethereum/portal_manager.ts
+++ b/yarn-project/aztec.js/src/ethereum/portal_manager.ts
@@ -267,6 +267,7 @@ export class L1ToL2TokenPortalManager {
};
}
+ // docs:start:bridge_tokens_private
/**
* Bridges tokens from L1 to L2 privately. Handles token approvals. Returns once the tx has been mined.
* @param to - Address to send the tokens to on L2.
@@ -278,6 +279,7 @@ export class L1ToL2TokenPortalManager {
amount: bigint,
mint = false,
): Promise {
+ // docs:end:bridge_tokens_private
const [claimSecret, claimSecretHash] = await this.bridgeSetup(amount, mint);
this.logger.info('Sending L1 tokens to L2 to be claimed privately');
diff --git a/yarn-project/bot/src/factory.ts b/yarn-project/bot/src/factory.ts
index 86a3bad11aa0..5e95cc17014b 100644
--- a/yarn-project/bot/src/factory.ts
+++ b/yarn-project/bot/src/factory.ts
@@ -96,10 +96,12 @@ export class BotFactory {
const claim = await this.bridgeL1FeeJuice(address, 10n ** 22n);
+ // docs:start: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();
+ // docs:end:claim_and_deploy
this.log.info(`Sent tx with hash ${txHash.toString()}`);
await this.tryFlushTxs();
this.log.verbose('Waiting for account deployment to settle');
diff --git a/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts b/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts
index 814fec2e2fd4..1cc1ce6e3784 100644
--- a/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts
+++ b/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts
@@ -108,8 +108,10 @@ async function bridgeL1FeeJuice(
const chain = createEthereumChain(l1RpcUrls, l1ChainId);
const { publicClient, walletClient } = createL1Clients(chain.rpcUrls, mnemonicOrPrivateKey, chain.chainInfo);
+ // docs:start:bridge_fee_juice
const portal = await L1FeeJuicePortalManager.new(pxe, publicClient, walletClient, log);
const claim = await portal.bridgeTokensPublic(recipient, amount, true /* mint */);
+ // docs:end:bridge_fee_juice
const isSynced = async () => await pxe.isL1ToL2MessageSynced(Fr.fromHexString(claim.messageHash));
await retryUntil(isSynced, `message ${claim.messageHash} sync`, 24, 0.5);
diff --git a/yarn-project/end-to-end/src/spartan/smoke.test.ts b/yarn-project/end-to-end/src/spartan/smoke.test.ts
index a08f95067ea2..d9c3b4748007 100644
--- a/yarn-project/end-to-end/src/spartan/smoke.test.ts
+++ b/yarn-project/end-to-end/src/spartan/smoke.test.ts
@@ -48,11 +48,13 @@ describe('smoke test', () => {
// also because it assumes foundry.
it.skip('should be able to get rollup info', async () => {
+ // docs:start:get_node_info_pub_client
const info = await pxe.getNodeInfo();
const publicClient = createPublicClient({
chain: foundry,
transport: http('http://localhost:8545'),
});
+ // docs:end:get_node_info_pub_client
const rollupContract = getContract({
address: getAddress(info.l1ContractAddresses.rollupAddress.toString()),