From 0b4241dcb83fe46ebe3d244266948ca02b71a860 Mon Sep 17 00:00:00 2001 From: Josh Crites Date: Fri, 11 Apr 2025 17:19:45 -0400 Subject: [PATCH 1/2] fix fees, rm confusing storage --- .../developers/guides/js_apps/pay_fees.md | 30 +++++++++++++++---- .../smart_contract_reference/storage/index.md | 19 ++---------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/docs/docs/developers/guides/js_apps/pay_fees.md b/docs/docs/developers/guides/js_apps/pay_fees.md index 091eac785a3d..26df2d79a5e3 100644 --- a/docs/docs/developers/guides/js_apps/pay_fees.md +++ b/docs/docs/developers/guides/js_apps/pay_fees.md @@ -125,16 +125,24 @@ import { } from "@aztec/aztec.js"; ``` -The FPC contract must be registered in a users PXE before it can be used. +The FPC contract must be registered in a users PXE before it can be used. This will automatically happen if you deploy the FPC to your sandbox, but must be added manually if you are using a standalone PXE. ```ts import { FPCContract } from "@aztec/noir-contracts.js/FPC"; +import { getContractInstanceFromDeployParams } from "@aztec/aztec.js"; // ... (set up the wallet and PXE) +// get the deployed FPC contract instance +const fpcContractInstance = getContractInstanceFromDeployParams( + FPCContract.artifact, + fpcDeployParams // the params used to deploy the FPC +); // register the already deployed FPC contract in users PXE -const fpcContract = FPCContract.at(fpcAddress, userWallet); -await pxe.registerContract(fpcContract); +await pxe.registerContract({ + instance: fpcContractInstance, + artifact: FPCContract.artifact, +}); ``` The fee payment method is created and used as follows, with similar syntax for private or public fee payments: @@ -154,6 +162,8 @@ The sandbox comes with a sponsored fee paying contract deployed, so this can be To use sponsored FPCs in other environments, they will need to be deployed and funded with fee juice. Using a SponsoredFPC payment method is as simple as importing it, registering it and passing it the PXE: +#### Sandbox with PXE + ```ts import { SponsoredFeePaymentMethod } from "@aztec/aztec.js/fee/testing"; ``` @@ -162,6 +172,8 @@ import { SponsoredFeePaymentMethod } from "@aztec/aztec.js/fee/testing"; const paymentMethod = new SponsoredFeePaymentMethod(deployedSponsoredFPC); ``` +#### Standalone PXE (e.g. Testnet) + Register the SponsoredFPC in the PXE: ```ts @@ -170,11 +182,17 @@ import { SponsoredFPCContract } from "@aztec/noir-contracts.js/SponsoredFPC"; // ... (set up the wallet and PXE) // register the already deployed SponsoredFPC contract in users PXE -const fpcContract = SponsoredFPCContract.at(sponsoredFpcAddress, userWallet); -await pxe.registerContract(fpcContract); +const sponseredFPC = await getSponsoredFPCInstance(); +await pxe.registerContract({ + instance: sponsoredFPC, + artifact: SponsoredFPCContract.artifact, +}); +const paymentMethod = new SponsoredFeePaymentMethod(sponseredFPC.address); ``` -Then a transaction can specify this as the `paymentMethod` in the fee object. +You can see an example implementation for `getSponsoredFPCInstance()` [here](https://github.com/AztecProtocol/aztec-packages/blob/360a5f628b4edaf1ea9b328d9e9231f60fdc81a0/yarn-project/aztec/src/sandbox/sponsored_fpc.ts#L5). + +Once this is set up, a transaction can specify this as the `paymentMethod` in the fee object. You can see an example of how to get a deployed instance of the sponsored FPC in the sandbox [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/aztec/src/sandbox/sponsored_fpc.ts#L15). For example, a contract can be deployed with an fpc as follows: diff --git a/docs/docs/developers/reference/smart_contract_reference/storage/index.md b/docs/docs/developers/reference/smart_contract_reference/storage/index.md index daf4588d9075..7b8438be8d91 100644 --- a/docs/docs/developers/reference/smart_contract_reference/storage/index.md +++ b/docs/docs/developers/reference/smart_contract_reference/storage/index.md @@ -26,28 +26,13 @@ On this and the following pages in this section, you’ll learn: Aztec contracts have three different modes of execution: private, public, and utility. How storage is accessed depends on the execution mode: for example, `PublicImmutable` can be read in all execution modes but only initialized in public, while `PrivateMutable` is entirely unavailable in public. -Aztec.nr prevents developers from calling functions unavailable in the current execution mode via the `context` variable that is injected into all contract functions. Its type indicates the current execution mode: +Aztec.nr prevents developers from calling functions unavailable in the current execution mode via the `Context` variable that is injected into all contract functions. Its type indicates the current execution mode: - `&mut PrivateContext` for private execution - `&mut PublicContext` for public execution - `UtilityContext` for utility execution -All state variables are generic over this `Context` type, and expose different methods in each execution mode. In the example above, `PublicImmutable`'s `initialize` function is only available with a public execution context, and so the following code results in a compilation error: - -```rust -#[storage] -struct Storage { - variable: PublicImmutable, -} - -#[private] -fn some_private_function() { - storage.variable.initialize(0); - // ^ ERROR: Expected type PublicImmutable<_, &mut PublicContext>, found type PublicImmutable -} -``` - -The `Context` generic type parameter is not visible in the code above as it is automatically injected by the `#[storage]` macro, in order to reduce boilerplate. Similarly, all state variables in that struct (e.g. `PublicImmutable`) similarly have that same type parameter automatically passed to them. +All state variables are generic over this `Context` type, and expose different methods in each execution mode. ## Map From cae58d9700551ae043aa280362974d30fbf4903a Mon Sep 17 00:00:00 2001 From: Josh Crites Date: Thu, 17 Apr 2025 12:41:18 -0400 Subject: [PATCH 2/2] update versions --- .../developers/guides/js_apps/pay_fees.md | 8 +- .../developers/guides/js_apps/pay_fees.md | 75 +++++++++------- .../developers/guides/js_apps/pay_fees.md | 89 ++++++++++++------- .../smart_contract_reference/storage/index.md | 27 ++---- 4 files changed, 109 insertions(+), 90 deletions(-) diff --git a/docs/docs/developers/guides/js_apps/pay_fees.md b/docs/docs/developers/guides/js_apps/pay_fees.md index 26df2d79a5e3..014f1e24e70c 100644 --- a/docs/docs/developers/guides/js_apps/pay_fees.md +++ b/docs/docs/developers/guides/js_apps/pay_fees.md @@ -125,7 +125,7 @@ import { } from "@aztec/aztec.js"; ``` -The FPC contract must be registered in a users PXE before it can be used. This will automatically happen if you deploy the FPC to your sandbox, but must be added manually if you are using a standalone PXE. +A FPC contract must be registered in a users PXE before it can be used. This will automatically happen if you deploy a FPC to your sandbox, but must be added manually if you are using a standalone PXE. ```ts import { FPCContract } from "@aztec/noir-contracts.js/FPC"; @@ -149,7 +149,7 @@ The fee payment method is created and used as follows, with similar syntax for p #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 asset that a FPC accepts for paying fees is determined when the FPC is deployed. The function being called happens to also be a transfer of banana tokens to Bob. +In this example, thanks to this FPC's `accepted_asset` being banana tokens, Alice only needs to hold this token and not fee juice. The asset that a FPC accepts for paying fees is determined when the FPC is deployed. 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/fees/fpc_contract/src/main.nr) @@ -174,7 +174,7 @@ const paymentMethod = new SponsoredFeePaymentMethod(deployedSponsoredFPC); #### Standalone PXE (e.g. Testnet) -Register the SponsoredFPC in the PXE: +Register the default SponsoredFPC in the PXE: ```ts import { SponsoredFPCContract } from "@aztec/noir-contracts.js/SponsoredFPC"; @@ -193,7 +193,7 @@ const paymentMethod = new SponsoredFeePaymentMethod(sponseredFPC.address); You can see an example implementation for `getSponsoredFPCInstance()` [here](https://github.com/AztecProtocol/aztec-packages/blob/360a5f628b4edaf1ea9b328d9e9231f60fdc81a0/yarn-project/aztec/src/sandbox/sponsored_fpc.ts#L5). Once this is set up, a transaction can specify this as the `paymentMethod` in the fee object. -You can see an example of how to get a deployed instance of the sponsored FPC in the sandbox [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/aztec/src/sandbox/sponsored_fpc.ts#L15). +You can see an example of how to get a deployed instance of a sponsored FPC in the sandbox [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/aztec/src/sandbox/sponsored_fpc.ts#L15). For example, a contract can be deployed with an fpc as follows: ```ts diff --git a/docs/versioned_docs/version-v0.85.0-alpha-testnet.0/developers/guides/js_apps/pay_fees.md b/docs/versioned_docs/version-v0.85.0-alpha-testnet.0/developers/guides/js_apps/pay_fees.md index bafbe2b61f79..ab147cc8b84d 100644 --- a/docs/versioned_docs/version-v0.85.0-alpha-testnet.0/developers/guides/js_apps/pay_fees.md +++ b/docs/versioned_docs/version-v0.85.0-alpha-testnet.0/developers/guides/js_apps/pay_fees.md @@ -44,15 +44,15 @@ One way of bridging of tokens is described fully [here](../../../developers/tuto First get the node info and create a public client pointing to the sandbox's anvil L1 node (from foundry): -```javascript title="get_node_info_pub_client" showLineNumbers +```javascript title="get_node_info_pub_client" showLineNumbers const info = await pxe.getNodeInfo(); const publicClient = getPublicClient({ - l1RpcUrls: ['http://localhost:8545'], + l1RpcUrls: ["http://localhost:8545"], l1ChainId: foundry.id, }); ``` -> Source code: yarn-project/end-to-end/src/spartan/smoke.test.ts#L52-L58 +> Source code: yarn-project/end-to-end/src/spartan/smoke.test.ts#L52-L58 After importing: @@ -62,12 +62,21 @@ import { L1FeeJuicePortalManager } from "@aztec/aztec.js"; Create a new fee juice portal manager and bridge fee juice publicly to Aztec: -```javascript title="bridge_fee_juice" showLineNumbers -const portal = await L1FeeJuicePortalManager.new(pxe, publicClient, walletClient, log); -const claim = await portal.bridgeTokensPublic(recipient, amount, true /* mint */); +```javascript title="bridge_fee_juice" showLineNumbers +const portal = await L1FeeJuicePortalManager.new( + pxe, + publicClient, + walletClient, + log +); +const claim = await portal.bridgeTokensPublic( + recipient, + amount, + true /* mint */ +); ``` -> Source code: yarn-project/end-to-end/src/spartan/setup_test_wallets.ts#L110-L113 +> Source code: yarn-project/end-to-end/src/spartan/setup_test_wallets.ts#L110-L113 For the mechanisms to complete bridging between L1 and Aztec, we have to wait for 2 Aztec blocks to progress. This can be triggered manually by sending 2 transactions in the sandbox, or by waiting for 2 blocks on a public network. After this, an account should have its fee juice ready to use in transactions. @@ -95,15 +104,15 @@ Note: this example is a public token transfer call, but can equally be a private import { FeeJuicePaymentMethod } from "@aztec/aztec.js"; ``` -```javascript title="pay_fee_juice_send" showLineNumbers +```javascript title="pay_fee_juice_send" showLineNumbers const paymentMethod = new FeeJuicePaymentMethod(aliceAddress); const { transactionFee } = await bananaCoin.methods .transfer_in_public(aliceAddress, bobAddress, 1n, 0n) .send({ fee: { gasSettings, paymentMethod } }) .wait(); ``` -> Source code: yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts#L86-L92 +> Source code: yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts#L86-L92 **The equivalent to specify fees via CLI...** @@ -119,14 +128,14 @@ Here we will use the `claim` object previously from the bridging section, and th import { FeeJuicePaymentMethodWithClaim } from "@aztec/aztec.js"; ``` -```javascript title="claim_and_deploy" showLineNumbers +```javascript title="claim_and_deploy" showLineNumbers 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#L121-L126 +> Source code: yarn-project/bot/src/factory.ts#L121-L126 **The equivalent to specify fees via CLI...** @@ -138,7 +147,7 @@ Claiming bridged fee juice and using it to pay for transaction fees results in f Calling a function, in this case checking the balance of the fee juice contract: -```javascript title="claim_and_pay" showLineNumbers +```javascript title="claim_and_pay" showLineNumbers const paymentMethod = new FeeJuicePaymentMethodWithClaim(bobWallet, claim); const receipt = await feeJuiceContract .withWallet(bobWallet) @@ -146,8 +155,8 @@ const receipt = await feeJuiceContract .send({ fee: { gasSettings, paymentMethod } }) .wait(); ``` -> Source code: yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts#L67-L74 +> Source code: yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts#L67-L74 ### Fee Paying Contract @@ -162,7 +171,7 @@ import { } from "@aztec/aztec.js"; ``` -The FPC contract must be registered in a users PXE before it can be used. +A FPC contract must be registered in a users PXE before it can be used. This will automatically happen if you deploy a FPC to your sandbox, but must be added manually if you are using a standalone PXE. ```ts import { FPCContract } from "@aztec/noir-contracts.js/FPC"; @@ -176,7 +185,7 @@ await pxe.registerContract(fpcContract); The fee payment method is created and used as follows, with similar syntax for private or public fee payments: -```javascript title="fpc" showLineNumbers +```javascript title="fpc" showLineNumbers const tx = await bananaCoin.methods .transfer_in_public(aliceAddress, bobAddress, bananasToSendToBob, 0) .send({ @@ -187,10 +196,10 @@ const tx = await bananaCoin.methods }) .wait(); ``` -> Source code: yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts#L59-L69 +> Source code: yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts#L59-L69 -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 asset that a FPC accepts for paying fees is determined when the FPC is deployed. The function being called happens to also be a transfer of banana tokens to Bob. +In this example, thanks to this FPC's `accepted_asset` being banana tokens, Alice only needs to hold this token and not fee juice. The asset that a FPC accepts for paying fees is determined when the FPC is deployed. 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/v0.85.0-alpha-testnet.0/noir-projects/noir-contracts/contracts/fees/fpc_contract/src/main.nr) @@ -211,7 +220,7 @@ import { SponsoredFeePaymentMethod } from "@aztec/aztec.js/fee/testing"; const paymentMethod = new SponsoredFeePaymentMethod(deployedSponsoredFPC); ``` -Register the SponsoredFPC in the PXE: +Register the default SponsoredFPC in the PXE: ```ts import { SponsoredFPCContract } from "@aztec/noir-contracts.js/SponsoredFPC"; @@ -219,8 +228,12 @@ import { SponsoredFPCContract } from "@aztec/noir-contracts.js/SponsoredFPC"; // ... (set up the wallet and PXE) // register the already deployed SponsoredFPC contract in users PXE -const fpcContract = SponsoredFPCContract.at(sponsoredFpcAddress, userWallet); -await pxe.registerContract(fpcContract); +const sponseredFPC = await getSponsoredFPCInstance(); +await pxe.registerContract({ + instance: sponsoredFPC, + artifact: SponsoredFPCContract.artifact, +}); +const paymentMethod = new SponsoredFeePaymentMethod(sponseredFPC.address); ``` Then a transaction can specify this as the `paymentMethod` in the fee object. @@ -238,40 +251,40 @@ You can find the corresponding CLI command info [here](../../reference/environme Functions pertaining to sending a transaction, such as `deploy` and `send`, each include a `fee` variable defined with the following (optional) parameters: -```javascript title="user_fee_options" showLineNumbers +```javascript title="user_fee_options" showLineNumbers /** Fee options as set by a user. */ export type UserFeeOptions = { /** The fee payment method to use */ - paymentMethod?: FeePaymentMethod; + paymentMethod?: FeePaymentMethod, /** The gas settings */ - gasSettings?: Partial>; + gasSettings?: Partial>, /** Percentage to pad the base fee by, if empty, defaults to 0.5 */ - baseFeePadding?: number; + baseFeePadding?: number, /** Whether to run an initial simulation of the tx with high gas limit to figure out actual gas settings. */ - estimateGas?: boolean; + estimateGas?: boolean, /** Percentage to pad the estimated gas limits by, if empty, defaults to 0.1. Only relevant if estimateGas is set. */ - estimatedGasPadding?: number; + estimatedGasPadding?: number, }; ``` -> Source code: yarn-project/entrypoints/src/interfaces.ts#L79-L93 +> Source code: yarn-project/entrypoints/src/interfaces.ts#L79-L93 ### 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/v0.85.0-alpha-testnet.0/yarn-project/aztec.js/src/fee). For example: -```javascript title="fee_juice_method" showLineNumbers +```javascript title="fee_juice_method" showLineNumbers /** * Pay fee directly in the Fee Juice. */ export class FeeJuicePaymentMethod implements FeePaymentMethod { ``` -> Source code: yarn-project/aztec.js/src/fee/fee_juice_payment_method.ts#L6-L11 +> Source code: yarn-project/aztec.js/src/fee/fee_juice_payment_method.ts#L6-L11 ### Gas Settings -```javascript title="gas_settings_vars" showLineNumbers +```javascript title="gas_settings_vars" showLineNumbers /** Gas usage and fees limits set by the transaction sender for different dimensions and phases. */ export class GasSettings { constructor( @@ -281,8 +294,8 @@ export class GasSettings { public readonly maxPriorityFeesPerGas: GasFees, ) {} ``` -> Source code: yarn-project/stdlib/src/gas/gas_settings.ts#L11-L20 +> Source code: yarn-project/stdlib/src/gas/gas_settings.ts#L11-L20 import { Gas_Settings_Components, Gas_Settings } from '/components/snippets'; diff --git a/docs/versioned_docs/version-v0.85.0/developers/guides/js_apps/pay_fees.md b/docs/versioned_docs/version-v0.85.0/developers/guides/js_apps/pay_fees.md index 85499ac88120..98f5bd330746 100644 --- a/docs/versioned_docs/version-v0.85.0/developers/guides/js_apps/pay_fees.md +++ b/docs/versioned_docs/version-v0.85.0/developers/guides/js_apps/pay_fees.md @@ -44,15 +44,15 @@ One way of bridging of tokens is described fully [here](../../../developers/tuto First get the node info and create a public client pointing to the sandbox's anvil L1 node (from foundry): -```javascript title="get_node_info_pub_client" showLineNumbers +```javascript title="get_node_info_pub_client" showLineNumbers const info = await pxe.getNodeInfo(); const publicClient = getPublicClient({ - l1RpcUrls: ['http://localhost:8545'], + l1RpcUrls: ["http://localhost:8545"], l1ChainId: foundry.id, }); ``` -> Source code: yarn-project/end-to-end/src/spartan/smoke.test.ts#L52-L58 +> Source code: yarn-project/end-to-end/src/spartan/smoke.test.ts#L52-L58 After importing: @@ -62,12 +62,21 @@ import { L1FeeJuicePortalManager } from "@aztec/aztec.js"; Create a new fee juice portal manager and bridge fee juice publicly to Aztec: -```javascript title="bridge_fee_juice" showLineNumbers -const portal = await L1FeeJuicePortalManager.new(pxe, publicClient, walletClient, log); -const claim = await portal.bridgeTokensPublic(recipient, amount, true /* mint */); +```javascript title="bridge_fee_juice" showLineNumbers +const portal = await L1FeeJuicePortalManager.new( + pxe, + publicClient, + walletClient, + log +); +const claim = await portal.bridgeTokensPublic( + recipient, + amount, + true /* mint */ +); ``` -> Source code: yarn-project/end-to-end/src/spartan/setup_test_wallets.ts#L110-L113 +> Source code: yarn-project/end-to-end/src/spartan/setup_test_wallets.ts#L110-L113 For the mechanisms to complete bridging between L1 and Aztec, we have to wait for 2 Aztec blocks to progress. This can be triggered manually by sending 2 transactions in the sandbox, or by waiting for 2 blocks on a public network. After this, an account should have its fee juice ready to use in transactions. @@ -95,15 +104,15 @@ Note: this example is a public token transfer call, but can equally be a private import { FeeJuicePaymentMethod } from "@aztec/aztec.js"; ``` -```javascript title="pay_fee_juice_send" showLineNumbers +```javascript title="pay_fee_juice_send" showLineNumbers const paymentMethod = new FeeJuicePaymentMethod(aliceAddress); const { transactionFee } = await bananaCoin.methods .transfer_in_public(aliceAddress, bobAddress, 1n, 0n) .send({ fee: { gasSettings, paymentMethod } }) .wait(); ``` -> Source code: yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts#L86-L92 +> Source code: yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts#L86-L92 **The equivalent to specify fees via CLI...** @@ -119,14 +128,14 @@ Here we will use the `claim` object previously from the bridging section, and th import { FeeJuicePaymentMethodWithClaim } from "@aztec/aztec.js"; ``` -```javascript title="claim_and_deploy" showLineNumbers +```javascript title="claim_and_deploy" showLineNumbers 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#L121-L126 +> Source code: yarn-project/bot/src/factory.ts#L121-L126 **The equivalent to specify fees via CLI...** @@ -138,7 +147,7 @@ Claiming bridged fee juice and using it to pay for transaction fees results in f Calling a function, in this case checking the balance of the fee juice contract: -```javascript title="claim_and_pay" showLineNumbers +```javascript title="claim_and_pay" showLineNumbers const paymentMethod = new FeeJuicePaymentMethodWithClaim(bobWallet, claim); const receipt = await feeJuiceContract .withWallet(bobWallet) @@ -146,8 +155,8 @@ const receipt = await feeJuiceContract .send({ fee: { gasSettings, paymentMethod } }) .wait(); ``` -> Source code: yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts#L67-L74 +> Source code: yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts#L67-L74 ### Fee Paying Contract @@ -162,21 +171,29 @@ import { } from "@aztec/aztec.js"; ``` -The FPC contract must be registered in a users PXE before it can be used. +A FPC contract must be registered in a users PXE before it can be used. This will automatically happen if you deploy a FPC to your sandbox, but must be added manually if you are using a standalone PXE. ```ts import { FPCContract } from "@aztec/noir-contracts.js/FPC"; +import { getContractInstanceFromDeployParams } from "@aztec/aztec.js"; // ... (set up the wallet and PXE) +// get the deployed FPC contract instance +const fpcContractInstance = getContractInstanceFromDeployParams( + FPCContract.artifact, + fpcDeployParams // the params used to deploy the FPC +); // register the already deployed FPC contract in users PXE -const fpcContract = FPCContract.at(fpcAddress, userWallet); -await pxe.registerContract(fpcContract); +await pxe.registerContract({ + instance: fpcContractInstance, + artifact: FPCContract.artifact, +}); ``` The fee payment method is created and used as follows, with similar syntax for private or public fee payments: -```javascript title="fpc" showLineNumbers +```javascript title="fpc" showLineNumbers const tx = await bananaCoin.methods .transfer_in_public(aliceAddress, bobAddress, bananasToSendToBob, 0) .send({ @@ -187,10 +204,10 @@ const tx = await bananaCoin.methods }) .wait(); ``` -> Source code: yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts#L59-L69 +> Source code: yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts#L59-L69 -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 asset that a FPC accepts for paying fees is determined when the FPC is deployed. The function being called happens to also be a transfer of banana tokens to Bob. +In this example, thanks to this FPC's `accepted_asset` being banana tokens, Alice only needs to hold this token and not fee juice. The asset that a FPC accepts for paying fees is determined when the FPC is deployed. 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/v0.85.0/noir-projects/noir-contracts/contracts/fees/fpc_contract/src/main.nr) @@ -211,7 +228,7 @@ import { SponsoredFeePaymentMethod } from "@aztec/aztec.js/fee/testing"; const paymentMethod = new SponsoredFeePaymentMethod(deployedSponsoredFPC); ``` -Register the SponsoredFPC in the PXE: +Register the default SponsoredFPC in the PXE: ```ts import { SponsoredFPCContract } from "@aztec/noir-contracts.js/SponsoredFPC"; @@ -219,12 +236,16 @@ import { SponsoredFPCContract } from "@aztec/noir-contracts.js/SponsoredFPC"; // ... (set up the wallet and PXE) // register the already deployed SponsoredFPC contract in users PXE -const fpcContract = SponsoredFPCContract.at(sponsoredFpcAddress, userWallet); -await pxe.registerContract(fpcContract); +const sponseredFPC = await getSponsoredFPCInstance(); +await pxe.registerContract({ + instance: sponsoredFPC, + artifact: SponsoredFPCContract.artifact, +}); +const paymentMethod = new SponsoredFeePaymentMethod(sponseredFPC.address); ``` Then a transaction can specify this as the `paymentMethod` in the fee object. -You can see an example of how to get a deployed instance of the sponsored FPC in the sandbox [here](https://github.com/AztecProtocol/aztec-packages/blob/v0.85.0/yarn-project/aztec/src/sandbox/sponsored_fpc.ts#L15). +You can see an example of how to get a deployed instance of a sponsored FPC in the sandbox [here](https://github.com/AztecProtocol/aztec-packages/blob/v0.85.0/yarn-project/aztec/src/sandbox/sponsored_fpc.ts#L15). For example, a contract can be deployed with an fpc as follows: ```ts @@ -238,40 +259,40 @@ You can find the corresponding CLI command info [here](../../reference/environme Functions pertaining to sending a transaction, such as `deploy` and `send`, each include a `fee` variable defined with the following (optional) parameters: -```javascript title="user_fee_options" showLineNumbers +```javascript title="user_fee_options" showLineNumbers /** Fee options as set by a user. */ export type UserFeeOptions = { /** The fee payment method to use */ - paymentMethod?: FeePaymentMethod; + paymentMethod?: FeePaymentMethod, /** The gas settings */ - gasSettings?: Partial>; + gasSettings?: Partial>, /** Percentage to pad the base fee by, if empty, defaults to 0.5 */ - baseFeePadding?: number; + baseFeePadding?: number, /** Whether to run an initial simulation of the tx with high gas limit to figure out actual gas settings. */ - estimateGas?: boolean; + estimateGas?: boolean, /** Percentage to pad the estimated gas limits by, if empty, defaults to 0.1. Only relevant if estimateGas is set. */ - estimatedGasPadding?: number; + estimatedGasPadding?: number, }; ``` -> Source code: yarn-project/entrypoints/src/interfaces.ts#L79-L93 +> Source code: yarn-project/entrypoints/src/interfaces.ts#L79-L93 ### 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/v0.85.0/yarn-project/aztec.js/src/fee). For example: -```javascript title="fee_juice_method" showLineNumbers +```javascript title="fee_juice_method" showLineNumbers /** * Pay fee directly in the Fee Juice. */ export class FeeJuicePaymentMethod implements FeePaymentMethod { ``` -> Source code: yarn-project/aztec.js/src/fee/fee_juice_payment_method.ts#L6-L11 +> Source code: yarn-project/aztec.js/src/fee/fee_juice_payment_method.ts#L6-L11 ### Gas Settings -```javascript title="gas_settings_vars" showLineNumbers +```javascript title="gas_settings_vars" showLineNumbers /** Gas usage and fees limits set by the transaction sender for different dimensions and phases. */ export class GasSettings { constructor( @@ -281,8 +302,8 @@ export class GasSettings { public readonly maxPriorityFeesPerGas: GasFees, ) {} ``` -> Source code: yarn-project/stdlib/src/gas/gas_settings.ts#L11-L20 +> Source code: yarn-project/stdlib/src/gas/gas_settings.ts#L11-L20 import { Gas_Settings_Components, Gas_Settings } from '/components/snippets'; diff --git a/docs/versioned_docs/version-v0.85.0/developers/reference/smart_contract_reference/storage/index.md b/docs/versioned_docs/version-v0.85.0/developers/reference/smart_contract_reference/storage/index.md index 84f5c4527a75..e4ed6a5597e8 100644 --- a/docs/versioned_docs/version-v0.85.0/developers/reference/smart_contract_reference/storage/index.md +++ b/docs/versioned_docs/version-v0.85.0/developers/reference/smart_contract_reference/storage/index.md @@ -26,28 +26,13 @@ On this and the following pages in this section, you’ll learn: Aztec contracts have three different modes of execution: private, public, and utility. How storage is accessed depends on the execution mode: for example, `PublicImmutable` can be read in all execution modes but only initialized in public, while `PrivateMutable` is entirely unavailable in public. -Aztec.nr prevents developers from calling functions unavailable in the current execution mode via the `context` variable that is injected into all contract functions. Its type indicates the current execution mode: +Aztec.nr prevents developers from calling functions unavailable in the current execution mode via the `Context` variable that is injected into all contract functions. Its type indicates the current execution mode: - `&mut PrivateContext` for private execution - `&mut PublicContext` for public execution - `UtilityContext` for utility execution -All state variables are generic over this `Context` type, and expose different methods in each execution mode. In the example above, `PublicImmutable`'s `initialize` function is only available with a public execution context, and so the following code results in a compilation error: - -```rust -#[storage] -struct Storage { - variable: PublicImmutable, -} - -#[private] -fn some_private_function() { - storage.variable.initialize(0); - // ^ ERROR: Expected type PublicImmutable<_, &mut PublicContext>, found type PublicImmutable -} -``` - -The `Context` generic type parameter is not visible in the code above as it is automatically injected by the `#[storage]` macro, in order to reduce boilerplate. Similarly, all state variables in that struct (e.g. `PublicImmutable`) similarly have that same type parameter automatically passed to them. +All state variables are generic over this `Context` type, and expose different methods in each execution mode. ## Map @@ -77,11 +62,11 @@ numbers: Map>, When declaring a public mapping in Storage, we have to specify that the type is public by declaring it as `PublicState` instead of specifying a note type like with private storage above. -```rust title="storage_minters" showLineNumbers +```rust title="storage_minters" showLineNumbers minters: Map, Context>, ``` -> Source code: noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr#L74-L76 +> Source code: noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr#L74-L76 ### `at` @@ -89,11 +74,11 @@ When dealing with a Map, we can access the value at a given key using the `::at` This function behaves similarly for both private and public maps. An example could be if we have a map with `minters`, which is mapping addresses to a flag for whether they are allowed to mint tokens or not. -```rust title="read_minter" showLineNumbers +```rust title="read_minter" showLineNumbers assert(storage.minters.at(context.msg_sender()).read(), "caller is not minter"); ``` -> Source code: noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr#L198-L200 +> Source code: noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr#L198-L200 Above, we are specifying that we want to get the storage in the Map `at` the `msg_sender()`, read the value stored and check that `msg_sender()` is indeed a minter. Doing a similar operation in Solidity code would look like: