@aztec/aztec.js 0.81.0 → 0.82.1-alpha-testnet.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/dest/account/{contract.d.ts → account_contract.d.ts} +3 -2
  2. package/dest/account/account_contract.d.ts.map +1 -0
  3. package/dest/account/index.d.ts +2 -3
  4. package/dest/account/index.d.ts.map +1 -1
  5. package/dest/account/index.js +1 -2
  6. package/dest/account/interface.d.ts +1 -13
  7. package/dest/account/interface.d.ts.map +1 -1
  8. package/dest/account/interface.js +1 -0
  9. package/dest/account_manager/account_manager.d.ts +106 -0
  10. package/dest/account_manager/account_manager.d.ts.map +1 -0
  11. package/dest/account_manager/account_manager.js +216 -0
  12. package/dest/account_manager/deploy_account_sent_tx.d.ts +3 -3
  13. package/dest/account_manager/deploy_account_sent_tx.d.ts.map +1 -1
  14. package/dest/account_manager/deploy_account_sent_tx.js +2 -2
  15. package/dest/account_manager/index.d.ts +1 -105
  16. package/dest/account_manager/index.d.ts.map +1 -1
  17. package/dest/account_manager/index.js +1 -166
  18. package/dest/api/account.d.ts +2 -1
  19. package/dest/api/account.d.ts.map +1 -1
  20. package/dest/api/contract.d.ts +4 -1
  21. package/dest/api/contract.d.ts.map +1 -1
  22. package/dest/api/contract.js +3 -0
  23. package/dest/api/fee.d.ts +2 -1
  24. package/dest/api/fee.d.ts.map +1 -1
  25. package/dest/api/fee.js +1 -0
  26. package/dest/api/fee_testing.d.ts +2 -0
  27. package/dest/api/fee_testing.d.ts.map +1 -0
  28. package/dest/api/fee_testing.js +1 -0
  29. package/dest/api/utils.d.ts +2 -1
  30. package/dest/api/utils.d.ts.map +1 -1
  31. package/dest/api/utils.js +2 -1
  32. package/dest/api/wallet.d.ts +1 -1
  33. package/dest/api/wallet.d.ts.map +1 -1
  34. package/dest/contract/base_contract_interaction.d.ts +22 -57
  35. package/dest/contract/base_contract_interaction.d.ts.map +1 -1
  36. package/dest/contract/base_contract_interaction.js +12 -67
  37. package/dest/contract/batch_call.d.ts +6 -18
  38. package/dest/contract/batch_call.d.ts.map +1 -1
  39. package/dest/contract/batch_call.js +25 -54
  40. package/dest/contract/contract.d.ts +1 -1
  41. package/dest/contract/contract.d.ts.map +1 -1
  42. package/dest/contract/contract_base.d.ts +1 -1
  43. package/dest/contract/contract_base.d.ts.map +1 -1
  44. package/dest/contract/contract_function_interaction.d.ts +38 -18
  45. package/dest/contract/contract_function_interaction.d.ts.map +1 -1
  46. package/dest/contract/contract_function_interaction.js +34 -41
  47. package/dest/contract/deploy_method.d.ts +7 -8
  48. package/dest/contract/deploy_method.d.ts.map +1 -1
  49. package/dest/contract/deploy_method.js +27 -32
  50. package/dest/contract/deploy_proven_tx.d.ts +2 -3
  51. package/dest/contract/deploy_proven_tx.d.ts.map +1 -1
  52. package/dest/contract/deploy_proven_tx.js +1 -1
  53. package/dest/contract/deploy_sent_tx.d.ts +2 -3
  54. package/dest/contract/deploy_sent_tx.d.ts.map +1 -1
  55. package/dest/contract/deploy_sent_tx.js +4 -4
  56. package/dest/contract/protocol_contracts.d.ts +1 -1
  57. package/dest/contract/protocol_contracts.d.ts.map +1 -1
  58. package/dest/contract/proven_tx.d.ts +3 -5
  59. package/dest/contract/proven_tx.d.ts.map +1 -1
  60. package/dest/contract/proven_tx.js +2 -6
  61. package/dest/contract/sent_tx.d.ts +4 -16
  62. package/dest/contract/sent_tx.d.ts.map +1 -1
  63. package/dest/contract/sent_tx.js +6 -37
  64. package/dest/contract/unsafe_contract.d.ts +1 -1
  65. package/dest/contract/unsafe_contract.d.ts.map +1 -1
  66. package/dest/contract/wait_for_proven.d.ts +17 -0
  67. package/dest/contract/wait_for_proven.d.ts.map +1 -0
  68. package/dest/contract/wait_for_proven.js +17 -0
  69. package/dest/deployment/broadcast_function.js +12 -8
  70. package/dest/deployment/contract_deployer.d.ts +1 -1
  71. package/dest/deployment/contract_deployer.d.ts.map +1 -1
  72. package/dest/deployment/register_class.d.ts +1 -1
  73. package/dest/deployment/register_class.d.ts.map +1 -1
  74. package/dest/deployment/register_class.js +6 -11
  75. package/dest/ethereum/portal_manager.d.ts +20 -11
  76. package/dest/ethereum/portal_manager.d.ts.map +1 -1
  77. package/dest/ethereum/portal_manager.js +64 -30
  78. package/dest/fee/account_entrypoint_meta_payment_method.d.ts +31 -0
  79. package/dest/fee/account_entrypoint_meta_payment_method.d.ts.map +1 -0
  80. package/dest/fee/account_entrypoint_meta_payment_method.js +64 -0
  81. package/dest/fee/fee_juice_payment_method.d.ts +3 -3
  82. package/dest/fee/fee_juice_payment_method.d.ts.map +1 -1
  83. package/dest/fee/fee_juice_payment_method.js +3 -2
  84. package/dest/fee/fee_juice_payment_method_with_claim.d.ts +4 -4
  85. package/dest/fee/fee_juice_payment_method_with_claim.d.ts.map +1 -1
  86. package/dest/fee/fee_juice_payment_method_with_claim.js +6 -5
  87. package/dest/fee/private_fee_payment_method.d.ts +6 -6
  88. package/dest/fee/private_fee_payment_method.d.ts.map +1 -1
  89. package/dest/fee/private_fee_payment_method.js +13 -12
  90. package/dest/fee/public_fee_payment_method.d.ts +7 -7
  91. package/dest/fee/public_fee_payment_method.d.ts.map +1 -1
  92. package/dest/fee/public_fee_payment_method.js +10 -11
  93. package/dest/fee/sponsored_fee_payment.d.ts +15 -0
  94. package/dest/fee/sponsored_fee_payment.d.ts.map +1 -0
  95. package/dest/fee/sponsored_fee_payment.js +30 -0
  96. package/dest/fee/utils.d.ts +13 -0
  97. package/dest/fee/utils.d.ts.map +1 -0
  98. package/dest/fee/utils.js +32 -0
  99. package/dest/utils/authwit.d.ts +16 -9
  100. package/dest/utils/authwit.d.ts.map +1 -1
  101. package/dest/utils/authwit.js +27 -36
  102. package/dest/wallet/account_wallet.d.ts +6 -6
  103. package/dest/wallet/account_wallet.d.ts.map +1 -1
  104. package/dest/wallet/account_wallet.js +15 -17
  105. package/dest/wallet/base_wallet.d.ts +12 -35
  106. package/dest/wallet/base_wallet.d.ts.map +1 -1
  107. package/dest/wallet/base_wallet.js +11 -64
  108. package/dest/wallet/index.d.ts +2 -2
  109. package/dest/wallet/index.d.ts.map +1 -1
  110. package/dest/wallet/index.js +1 -1
  111. package/dest/wallet/signerless_wallet.d.ts +3 -3
  112. package/dest/wallet/signerless_wallet.d.ts.map +1 -1
  113. package/dest/wallet/signerless_wallet.js +3 -6
  114. package/dest/wallet/wallet.d.ts +11 -0
  115. package/dest/wallet/wallet.d.ts.map +1 -0
  116. package/package.json +10 -8
  117. package/src/account/{contract.ts → account_contract.ts} +2 -1
  118. package/src/account/index.ts +2 -3
  119. package/src/account/interface.ts +1 -12
  120. package/src/account_manager/account_manager.ts +294 -0
  121. package/src/account_manager/deploy_account_sent_tx.ts +4 -4
  122. package/src/account_manager/index.ts +1 -237
  123. package/src/api/account.ts +2 -8
  124. package/src/api/contract.ts +5 -5
  125. package/src/api/fee.ts +2 -1
  126. package/src/api/fee_testing.ts +1 -0
  127. package/src/api/utils.ts +1 -1
  128. package/src/api/wallet.ts +7 -1
  129. package/src/contract/base_contract_interaction.ts +32 -88
  130. package/src/contract/batch_call.ts +40 -43
  131. package/src/contract/contract.ts +1 -1
  132. package/src/contract/contract_base.ts +1 -1
  133. package/src/contract/contract_function_interaction.ts +85 -56
  134. package/src/contract/deploy_method.ts +24 -26
  135. package/src/contract/deploy_proven_tx.ts +3 -4
  136. package/src/contract/deploy_sent_tx.ts +6 -6
  137. package/src/contract/protocol_contracts.ts +1 -1
  138. package/src/contract/proven_tx.ts +4 -22
  139. package/src/contract/sent_tx.ts +6 -47
  140. package/src/contract/unsafe_contract.ts +1 -1
  141. package/src/contract/wait_for_proven.ts +38 -0
  142. package/src/deployment/broadcast_function.ts +40 -40
  143. package/src/deployment/contract_deployer.ts +1 -1
  144. package/src/deployment/register_class.ts +9 -22
  145. package/src/ethereum/portal_manager.ts +73 -24
  146. package/src/fee/account_entrypoint_meta_payment_method.ts +90 -0
  147. package/src/fee/fee_juice_payment_method.ts +4 -5
  148. package/src/fee/fee_juice_payment_method_with_claim.ts +24 -20
  149. package/src/fee/private_fee_payment_method.ts +29 -28
  150. package/src/fee/public_fee_payment_method.ts +29 -29
  151. package/src/fee/sponsored_fee_payment.ts +38 -0
  152. package/src/fee/utils.ts +39 -0
  153. package/src/utils/authwit.ts +26 -37
  154. package/src/wallet/account_wallet.ts +18 -17
  155. package/src/wallet/base_wallet.ts +27 -88
  156. package/src/wallet/index.ts +2 -2
  157. package/src/wallet/signerless_wallet.ts +9 -8
  158. package/src/wallet/wallet.ts +34 -0
  159. package/dest/account/contract.d.ts.map +0 -1
  160. package/dest/account/wallet.d.ts +0 -11
  161. package/dest/account/wallet.d.ts.map +0 -1
  162. package/dest/account_manager/deploy_account_method.d.ts +0 -15
  163. package/dest/account_manager/deploy_account_method.d.ts.map +0 -1
  164. package/dest/account_manager/deploy_account_method.js +0 -36
  165. package/dest/api/entrypoint.d.ts +0 -2
  166. package/dest/api/entrypoint.d.ts.map +0 -1
  167. package/dest/api/entrypoint.js +0 -1
  168. package/dest/entrypoint/default_entrypoint.d.ts +0 -12
  169. package/dest/entrypoint/default_entrypoint.d.ts.map +0 -1
  170. package/dest/entrypoint/default_entrypoint.js +0 -28
  171. package/dest/entrypoint/default_multi_call_entrypoint.d.ts +0 -15
  172. package/dest/entrypoint/default_multi_call_entrypoint.d.ts.map +0 -1
  173. package/dest/entrypoint/default_multi_call_entrypoint.js +0 -130
  174. package/dest/entrypoint/entrypoint.d.ts +0 -39
  175. package/dest/entrypoint/entrypoint.d.ts.map +0 -1
  176. package/dest/entrypoint/entrypoint.js +0 -20
  177. package/dest/entrypoint/payload.d.ts +0 -128
  178. package/dest/entrypoint/payload.d.ts.map +0 -1
  179. package/dest/entrypoint/payload.js +0 -143
  180. package/dest/fee/fee_payment_method.d.ts +0 -22
  181. package/dest/fee/fee_payment_method.d.ts.map +0 -1
  182. package/dest/fee/fee_payment_method.js +0 -3
  183. package/src/account/wallet.ts +0 -13
  184. package/src/account_manager/deploy_account_method.ts +0 -67
  185. package/src/api/entrypoint.ts +0 -1
  186. package/src/entrypoint/default_entrypoint.ts +0 -39
  187. package/src/entrypoint/default_multi_call_entrypoint.ts +0 -93
  188. package/src/entrypoint/entrypoint.ts +0 -60
  189. package/src/entrypoint/payload.ts +0 -238
  190. package/src/fee/fee_payment_method.ts +0 -22
  191. /package/dest/account/{contract.js → account_contract.js} +0 -0
  192. /package/dest/{account → wallet}/wallet.js +0 -0
@@ -59,31 +59,31 @@ export async function broadcastPrivateFunction(
59
59
  const vkHash = await computeVerificationKeyHash(privateFunctionArtifact);
60
60
 
61
61
  const registerer = await getRegistererContract(wallet);
62
- const fn = registerer.methods.broadcast_private_function(
63
- contractClass.id,
64
- artifactMetadataHash,
65
- unconstrainedFunctionsArtifactTreeRoot,
66
- privateFunctionTreeSiblingPath,
67
- privateFunctionTreeLeafIndex,
68
- padArrayEnd(artifactTreeSiblingPath, Fr.ZERO, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT),
69
- artifactTreeLeafIndex,
70
- // eslint-disable-next-line camelcase
71
- { selector, metadata_hash: functionMetadataHash, vk_hash: vkHash },
72
- );
73
-
74
62
  const bytecode = bufferAsFields(
75
63
  privateFunctionArtifact.bytecode,
76
64
  MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS,
77
65
  );
78
- fn.addCapsule(
79
- new Capsule(
80
- ProtocolContractAddress.ContractClassRegisterer,
81
- new Fr(REGISTERER_CONTRACT_BYTECODE_CAPSULE_SLOT),
82
- bytecode,
83
- ),
84
- );
85
-
86
- return fn;
66
+ return registerer.methods
67
+ .broadcast_private_function(
68
+ contractClass.id,
69
+ artifactMetadataHash,
70
+ unconstrainedFunctionsArtifactTreeRoot,
71
+ privateFunctionTreeSiblingPath,
72
+ privateFunctionTreeLeafIndex,
73
+ padArrayEnd(artifactTreeSiblingPath, Fr.ZERO, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT),
74
+ artifactTreeLeafIndex,
75
+ // eslint-disable-next-line camelcase
76
+ { selector, metadata_hash: functionMetadataHash, vk_hash: vkHash },
77
+ )
78
+ .with({
79
+ capsules: [
80
+ new Capsule(
81
+ ProtocolContractAddress.ContractClassRegisterer,
82
+ new Fr(REGISTERER_CONTRACT_BYTECODE_CAPSULE_SLOT),
83
+ bytecode,
84
+ ),
85
+ ],
86
+ });
87
87
  }
88
88
 
89
89
  /**
@@ -122,27 +122,27 @@ export async function broadcastUnconstrainedFunction(
122
122
  } = await createUnconstrainedFunctionMembershipProof(selector, artifact);
123
123
 
124
124
  const registerer = await getRegistererContract(wallet);
125
- const fn = registerer.methods.broadcast_unconstrained_function(
126
- contractClass.id,
127
- artifactMetadataHash,
128
- privateFunctionsArtifactTreeRoot,
129
- padArrayEnd(artifactTreeSiblingPath, Fr.ZERO, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT),
130
- artifactTreeLeafIndex,
131
- // eslint-disable-next-line camelcase
132
- { selector, metadata_hash: functionMetadataHash },
133
- );
134
-
135
125
  const bytecode = bufferAsFields(
136
126
  unconstrainedFunctionArtifact.bytecode,
137
127
  MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS,
138
128
  );
139
- fn.addCapsule(
140
- new Capsule(
141
- ProtocolContractAddress.ContractClassRegisterer,
142
- new Fr(REGISTERER_CONTRACT_BYTECODE_CAPSULE_SLOT),
143
- bytecode,
144
- ),
145
- );
146
-
147
- return fn;
129
+ return registerer.methods
130
+ .broadcast_unconstrained_function(
131
+ contractClass.id,
132
+ artifactMetadataHash,
133
+ privateFunctionsArtifactTreeRoot,
134
+ padArrayEnd(artifactTreeSiblingPath, Fr.ZERO, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT),
135
+ artifactTreeLeafIndex,
136
+ // eslint-disable-next-line camelcase
137
+ { selector, metadata_hash: functionMetadataHash },
138
+ )
139
+ .with({
140
+ capsules: [
141
+ new Capsule(
142
+ ProtocolContractAddress.ContractClassRegisterer,
143
+ new Fr(REGISTERER_CONTRACT_BYTECODE_CAPSULE_SLOT),
144
+ bytecode,
145
+ ),
146
+ ],
147
+ });
148
148
  }
@@ -2,9 +2,9 @@ import type { ContractArtifact } from '@aztec/stdlib/abi';
2
2
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
3
3
  import { PublicKeys } from '@aztec/stdlib/keys';
4
4
 
5
- import type { Wallet } from '../account/wallet.js';
6
5
  import { Contract } from '../contract/contract.js';
7
6
  import { DeployMethod } from '../contract/deploy_method.js';
7
+ import type { Wallet } from '../wallet/wallet.js';
8
8
 
9
9
  /**
10
10
  * A class for deploying contract.
@@ -9,36 +9,23 @@ import type { ContractFunctionInteraction } from '../contract/contract_function_
9
9
  import { getRegistererContract } from '../contract/protocol_contracts.js';
10
10
  import type { Wallet } from '../wallet/index.js';
11
11
 
12
- const defaultEmitPublicBytecode =
13
- // guard against `process` not being defined (e.g. in the browser)
14
- typeof process === 'object' && typeof process.env === 'object'
15
- ? ['1', 'true', 'yes', ''].includes(process.env.AZTEC_EMIT_PUBLIC_BYTECODE ?? '')
16
- : true;
17
-
18
12
  /** Sets up a call to register a contract class given its artifact. */
19
13
  export async function registerContractClass(
20
14
  wallet: Wallet,
21
15
  artifact: ContractArtifact,
22
- emitPublicBytecode = defaultEmitPublicBytecode,
23
16
  ): Promise<ContractFunctionInteraction> {
24
17
  const { artifactHash, privateFunctionsRoot, publicBytecodeCommitment, packedBytecode } =
25
18
  await getContractClassFromArtifact(artifact);
26
19
  const registerer = await getRegistererContract(wallet);
27
- const fn = registerer.methods.register(
28
- artifactHash,
29
- privateFunctionsRoot,
30
- publicBytecodeCommitment,
31
- emitPublicBytecode,
32
- );
33
20
 
34
21
  const encodedBytecode = bufferAsFields(packedBytecode, MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS);
35
- fn.addCapsule(
36
- new Capsule(
37
- ProtocolContractAddress.ContractClassRegisterer,
38
- new Fr(REGISTERER_CONTRACT_BYTECODE_CAPSULE_SLOT),
39
- encodedBytecode,
40
- ),
41
- );
42
-
43
- return fn;
22
+ return registerer.methods.register(artifactHash, privateFunctionsRoot, publicBytecodeCommitment).with({
23
+ capsules: [
24
+ new Capsule(
25
+ ProtocolContractAddress.ContractClassRegisterer,
26
+ new Fr(REGISTERER_CONTRACT_BYTECODE_CAPSULE_SLOT),
27
+ encodedBytecode,
28
+ ),
29
+ ],
30
+ });
44
31
  }
@@ -5,6 +5,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
5
5
  import { Fr } from '@aztec/foundation/fields';
6
6
  import type { Logger } from '@aztec/foundation/log';
7
7
  import type { SiblingPath } from '@aztec/foundation/trees';
8
+ import { FeeAssetHandlerAbi } from '@aztec/l1-artifacts/FeeAssetHandlerAbi';
8
9
  import { FeeJuicePortalAbi } from '@aztec/l1-artifacts/FeeJuicePortalAbi';
9
10
  import { OutboxAbi } from '@aztec/l1-artifacts/OutboxAbi';
10
11
  import { TestERC20Abi } from '@aztec/l1-artifacts/TestERC20Abi';
@@ -15,6 +16,8 @@ import type { PXE } from '@aztec/stdlib/interfaces/client';
15
16
 
16
17
  import { type GetContractReturnType, type Hex, getContract, toFunctionSelector } from 'viem';
17
18
 
19
+ import type { Wallet } from '../index.js';
20
+
18
21
  // docs:start:claim_type
19
22
  // docs:start:claim_type_amount
20
23
  /** L1 to L2 message info to claim it on L2. */
@@ -55,19 +58,39 @@ export async function generateClaimSecret(logger?: Logger): Promise<[Fr, Fr]> {
55
58
  /** Helper for managing an ERC20 on L1. */
56
59
  export class L1TokenManager {
57
60
  private contract: GetContractReturnType<typeof TestERC20Abi, ViemWalletClient>;
61
+ private handler: GetContractReturnType<typeof FeeAssetHandlerAbi, ViemWalletClient> | undefined;
58
62
 
59
63
  public constructor(
60
64
  /** Address of the ERC20 contract. */
61
- public readonly address: EthAddress,
65
+ public readonly tokenAddress: EthAddress,
66
+ /** Address of the handler/faucet contract. */
67
+ public readonly handlerAddress: EthAddress | undefined,
62
68
  private publicClient: ViemPublicClient,
63
69
  private walletClient: ViemWalletClient,
64
70
  private logger: Logger,
65
71
  ) {
66
72
  this.contract = getContract({
67
- address: this.address.toString(),
73
+ address: this.tokenAddress.toString(),
68
74
  abi: TestERC20Abi,
69
75
  client: this.walletClient,
70
76
  });
77
+ if (this.handlerAddress) {
78
+ this.handler = getContract({
79
+ address: this.handlerAddress.toString(),
80
+ abi: FeeAssetHandlerAbi,
81
+ client: this.walletClient,
82
+ });
83
+ }
84
+ }
85
+
86
+ /** Returns the amount of tokens available to mint via the handler.
87
+ * @throws if the handler is not provided.
88
+ */
89
+ public async getMintAmount() {
90
+ if (!this.handler) {
91
+ throw new Error('Minting handler was not provided');
92
+ }
93
+ return await this.handler.read.mintAmount();
71
94
  }
72
95
 
73
96
  /**
@@ -79,16 +102,18 @@ export class L1TokenManager {
79
102
  }
80
103
 
81
104
  /**
82
- * Mints tokens for the given address. Returns once the tx has been mined.
83
- * @param amount - Amount to mint.
105
+ * Mints a fixed amount of tokens for the given address. Returns once the tx has been mined.
84
106
  * @param address - Address to mint the tokens for.
85
107
  * @param addressName - Optional name of the address for logging.
86
108
  */
87
- public async mint(amount: bigint, address: Hex, addressName?: string) {
88
- this.logger.info(`Minting ${amount} tokens for ${stringifyEthAddress(address, addressName)}`);
89
- await this.publicClient.waitForTransactionReceipt({
90
- hash: await this.contract.write.mint([address, amount]),
91
- });
109
+ public async mint(address: Hex, addressName?: string) {
110
+ if (!this.handler) {
111
+ throw new Error('Minting handler was not provided');
112
+ }
113
+ const mintAmount = await this.getMintAmount();
114
+ this.logger.info(`Minting ${mintAmount} tokens for ${stringifyEthAddress(address, addressName)}`);
115
+ // NOTE: the handler mints a fixed amount.
116
+ await this.handler.write.mint([address]);
92
117
  }
93
118
 
94
119
  /**
@@ -113,11 +138,12 @@ export class L1FeeJuicePortalManager {
113
138
  constructor(
114
139
  portalAddress: EthAddress,
115
140
  tokenAddress: EthAddress,
141
+ handlerAddress: EthAddress,
116
142
  private readonly publicClient: ViemPublicClient,
117
143
  private readonly walletClient: ViemWalletClient,
118
144
  private readonly logger: Logger,
119
145
  ) {
120
- this.tokenManager = new L1TokenManager(tokenAddress, publicClient, walletClient, logger);
146
+ this.tokenManager = new L1TokenManager(tokenAddress, handlerAddress, publicClient, walletClient, logger);
121
147
  this.contract = getContract({
122
148
  address: portalAddress.toString(),
123
149
  abi: FeeJuicePortalAbi,
@@ -136,16 +162,21 @@ export class L1FeeJuicePortalManager {
136
162
  * @param amount - Amount of tokens to send.
137
163
  * @param mint - Whether to mint the tokens before sending (only during testing).
138
164
  */
139
- public async bridgeTokensPublic(to: AztecAddress, amount: bigint, mint = false): Promise<L2AmountClaim> {
165
+ public async bridgeTokensPublic(to: AztecAddress, amount: bigint | undefined, mint = false): Promise<L2AmountClaim> {
140
166
  const [claimSecret, claimSecretHash] = await generateClaimSecret();
167
+ const mintableAmount = await this.tokenManager.getMintAmount();
168
+ const amountToBridge = amount ?? mintableAmount;
141
169
  if (mint) {
142
- await this.tokenManager.mint(amount, this.walletClient.account.address);
170
+ if (amountToBridge !== mintableAmount) {
171
+ throw new Error(`Minting amount must be ${mintableAmount}`);
172
+ }
173
+ await this.tokenManager.mint(this.walletClient.account.address);
143
174
  }
144
175
 
145
- await this.tokenManager.approve(amount, this.contract.address, 'FeeJuice Portal');
176
+ await this.tokenManager.approve(amountToBridge, this.contract.address, 'FeeJuice Portal');
146
177
 
147
178
  this.logger.info('Sending L1 Fee Juice to L2 to be claimed publicly');
148
- const args = [to.toString(), amount, claimSecretHash.toString()] as const;
179
+ const args = [to.toString(), amountToBridge, claimSecretHash.toString()] as const;
149
180
 
150
181
  await this.contract.simulate.depositToAztecPublic(args);
151
182
 
@@ -162,13 +193,13 @@ export class L1FeeJuicePortalManager {
162
193
  'DepositToAztecPublic',
163
194
  log =>
164
195
  log.args.secretHash === claimSecretHash.toString() &&
165
- log.args.amount === amount &&
196
+ log.args.amount === amountToBridge &&
166
197
  log.args.to === to.toString(),
167
198
  this.logger,
168
199
  );
169
200
 
170
201
  return {
171
- claimAmount: amount,
202
+ claimAmount: amountToBridge,
172
203
  claimSecret,
173
204
  claimSecretHash,
174
205
  messageHash: log.args.key,
@@ -178,26 +209,36 @@ export class L1FeeJuicePortalManager {
178
209
 
179
210
  /**
180
211
  * Creates a new instance
181
- * @param pxe - PXE client used for retrieving the L1 contract addresses.
212
+ * @param walletOrPxe - Wallet or PXE client used for retrieving the L1 contract addresses.
182
213
  * @param publicClient - L1 public client.
183
214
  * @param walletClient - L1 wallet client.
184
215
  * @param logger - Logger.
185
216
  */
186
217
  public static async new(
187
- pxe: PXE,
218
+ walletOrPxe: Wallet | PXE,
188
219
  publicClient: ViemPublicClient,
189
220
  walletClient: ViemWalletClient,
190
221
  logger: Logger,
191
222
  ): Promise<L1FeeJuicePortalManager> {
192
223
  const {
193
- l1ContractAddresses: { feeJuiceAddress, feeJuicePortalAddress },
194
- } = await pxe.getNodeInfo();
224
+ l1ContractAddresses: { feeJuiceAddress, feeJuicePortalAddress, feeAssetHandlerAddress },
225
+ } = await walletOrPxe.getNodeInfo();
195
226
 
196
227
  if (feeJuiceAddress.isZero() || feeJuicePortalAddress.isZero()) {
197
228
  throw new Error('Portal or token not deployed on L1');
198
229
  }
230
+ if (!feeAssetHandlerAddress || feeAssetHandlerAddress.isZero()) {
231
+ throw new Error('Handler not deployed on L1, or handler address is zero');
232
+ }
199
233
 
200
- return new L1FeeJuicePortalManager(feeJuicePortalAddress, feeJuiceAddress, publicClient, walletClient, logger);
234
+ return new L1FeeJuicePortalManager(
235
+ feeJuicePortalAddress,
236
+ feeJuiceAddress,
237
+ feeAssetHandlerAddress,
238
+ publicClient,
239
+ walletClient,
240
+ logger,
241
+ );
201
242
  }
202
243
  }
203
244
 
@@ -209,11 +250,12 @@ export class L1ToL2TokenPortalManager {
209
250
  constructor(
210
251
  portalAddress: EthAddress,
211
252
  tokenAddress: EthAddress,
253
+ handlerAddress: EthAddress | undefined,
212
254
  protected publicClient: ViemPublicClient,
213
255
  protected walletClient: ViemWalletClient,
214
256
  protected logger: Logger,
215
257
  ) {
216
- this.tokenManager = new L1TokenManager(tokenAddress, publicClient, walletClient, logger);
258
+ this.tokenManager = new L1TokenManager(tokenAddress, handlerAddress, publicClient, walletClient, logger);
217
259
  this.portal = getContract({
218
260
  address: portalAddress.toString(),
219
261
  abi: TokenPortalAbi,
@@ -267,6 +309,7 @@ export class L1ToL2TokenPortalManager {
267
309
  };
268
310
  }
269
311
 
312
+ // docs:start:bridge_tokens_private
270
313
  /**
271
314
  * Bridges tokens from L1 to L2 privately. Handles token approvals. Returns once the tx has been mined.
272
315
  * @param to - Address to send the tokens to on L2.
@@ -278,6 +321,7 @@ export class L1ToL2TokenPortalManager {
278
321
  amount: bigint,
279
322
  mint = false,
280
323
  ): Promise<L2AmountClaimWithRecipient> {
324
+ // docs:end:bridge_tokens_private
281
325
  const [claimSecret, claimSecretHash] = await this.bridgeSetup(amount, mint);
282
326
 
283
327
  this.logger.info('Sending L1 tokens to L2 to be claimed privately');
@@ -312,7 +356,11 @@ export class L1ToL2TokenPortalManager {
312
356
 
313
357
  private async bridgeSetup(amount: bigint, mint: boolean) {
314
358
  if (mint) {
315
- await this.tokenManager.mint(amount, this.walletClient.account.address);
359
+ const mintableAmount = await this.tokenManager.getMintAmount();
360
+ if (amount !== mintableAmount) {
361
+ throw new Error(`Minting amount must be ${mintableAmount} for testing`);
362
+ }
363
+ await this.tokenManager.mint(this.walletClient.account.address);
316
364
  }
317
365
  await this.tokenManager.approve(amount, this.portal.address, 'TokenPortal');
318
366
  return generateClaimSecret();
@@ -326,12 +374,13 @@ export class L1TokenPortalManager extends L1ToL2TokenPortalManager {
326
374
  constructor(
327
375
  portalAddress: EthAddress,
328
376
  tokenAddress: EthAddress,
377
+ handlerAddress: EthAddress | undefined,
329
378
  outboxAddress: EthAddress,
330
379
  publicClient: ViemPublicClient,
331
380
  walletClient: ViemWalletClient,
332
381
  logger: Logger,
333
382
  ) {
334
- super(portalAddress, tokenAddress, publicClient, walletClient, logger);
383
+ super(portalAddress, tokenAddress, handlerAddress, publicClient, walletClient, logger);
335
384
  this.outbox = getContract({
336
385
  address: outboxAddress.toString(),
337
386
  abi: OutboxAbi,
@@ -0,0 +1,90 @@
1
+ import {
2
+ EncodedAppEntrypointCalls,
3
+ EncodedCallsForEntrypoint,
4
+ computeCombinedPayloadHash,
5
+ } from '@aztec/entrypoints/encoding';
6
+ import type { AuthWitnessProvider, FeePaymentMethod } from '@aztec/entrypoints/interfaces';
7
+ import { ExecutionPayload } from '@aztec/entrypoints/payload';
8
+ import {
9
+ type ContractArtifact,
10
+ type FunctionArtifact,
11
+ FunctionCall,
12
+ FunctionSelector,
13
+ encodeArguments,
14
+ getFunctionArtifactByName,
15
+ } from '@aztec/stdlib/abi';
16
+ import { AztecAddress } from '@aztec/stdlib/aztec-address';
17
+ import type { GasSettings } from '@aztec/stdlib/gas';
18
+
19
+ /**
20
+ * Fee payment method that allows a contract to pay for its own deployment
21
+ * It works by rerouting the provided fee payment method through the account's entrypoint,
22
+ * which sets itself as fee payer.
23
+ *
24
+ * Usually, in order to pay fees it is necessary to obtain an ExecutionPayload that encodes the necessary information
25
+ * that is sent to the user's account entrypoint, that has plumbing to handle a fee payload.
26
+ * If there's no account contract yet (it's being deployed) a MultiCallContract is used, which doesn't have a concept of fees or
27
+ * how to handle this payload.
28
+ * HOWEVER, the account contract's entrypoint does, so this method reshapes that fee payload into a call to the account contract entrypoint
29
+ * being deployed with the original fee payload.
30
+ *
31
+ * This class can be seen in action in AccountManager.ts#getSelfPaymentMethod
32
+ */
33
+ export class AccountEntrypointMetaPaymentMethod implements FeePaymentMethod {
34
+ constructor(
35
+ private artifact: ContractArtifact,
36
+ private authWitnessProvider: AuthWitnessProvider,
37
+ private feePaymentNameOrArtifact: string | FunctionArtifact,
38
+ private accountAddress: AztecAddress,
39
+ private paymentMethod: FeePaymentMethod,
40
+ ) {}
41
+
42
+ getAsset(): Promise<AztecAddress> {
43
+ return this.paymentMethod.getAsset();
44
+ }
45
+
46
+ async getExecutionPayload(gasSettings: GasSettings): Promise<ExecutionPayload> {
47
+ const emptyAppCalls = await EncodedAppEntrypointCalls.fromAppExecution([]);
48
+ // Get the execution payload for the fee, it includes the calls and potentially authWitnesses
49
+ const { calls: feeCalls, authWitnesses: feeAuthwitnesses } = await this.paymentMethod.getExecutionPayload(
50
+ gasSettings,
51
+ );
52
+ // Encode the calls for the fee
53
+ const feePayer = await this.paymentMethod.getFeePayer(gasSettings);
54
+ const isFeePayer = feePayer.equals(this.accountAddress);
55
+ const feeEncodedCalls = await EncodedCallsForEntrypoint.fromFeeCalls(feeCalls, isFeePayer);
56
+
57
+ // Get the entrypoint args
58
+ const args = [emptyAppCalls, feeEncodedCalls, false];
59
+ const feePaymentArtifact =
60
+ typeof this.feePaymentNameOrArtifact === 'string'
61
+ ? getFunctionArtifactByName(this.artifact, this.feePaymentNameOrArtifact)
62
+ : this.feePaymentNameOrArtifact;
63
+
64
+ const entrypointCall = new FunctionCall(
65
+ feePaymentArtifact.name,
66
+ this.accountAddress,
67
+ await FunctionSelector.fromNameAndParameters(feePaymentArtifact.name, feePaymentArtifact.parameters),
68
+ feePaymentArtifact.functionType,
69
+ feePaymentArtifact.isStatic,
70
+ encodeArguments(feePaymentArtifact, args),
71
+ feePaymentArtifact.returnTypes,
72
+ );
73
+
74
+ // Compute the authwitness required to verify the combined payload
75
+ const combinedPayloadAuthWitness = await this.authWitnessProvider.createAuthWit(
76
+ await computeCombinedPayloadHash(emptyAppCalls, feeEncodedCalls),
77
+ );
78
+
79
+ return new ExecutionPayload(
80
+ [entrypointCall],
81
+ [combinedPayloadAuthWitness, ...feeAuthwitnesses],
82
+ [],
83
+ [...emptyAppCalls.hashedArguments, ...feeEncodedCalls.hashedArguments],
84
+ );
85
+ }
86
+
87
+ getFeePayer(gasSettings: GasSettings): Promise<AztecAddress> {
88
+ return this.paymentMethod.getFeePayer(gasSettings);
89
+ }
90
+ }
@@ -1,9 +1,8 @@
1
+ import type { FeePaymentMethod } from '@aztec/entrypoints/interfaces';
2
+ import { ExecutionPayload } from '@aztec/entrypoints/payload';
1
3
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
2
- import type { FunctionCall } from '@aztec/stdlib/abi';
3
4
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
4
5
 
5
- import type { FeePaymentMethod } from './fee_payment_method.js';
6
-
7
6
  // docs:start:fee_juice_method
8
7
  /**
9
8
  * Pay fee directly in the Fee Juice.
@@ -16,8 +15,8 @@ export class FeeJuicePaymentMethod implements FeePaymentMethod {
16
15
  return Promise.resolve(ProtocolContractAddress.FeeJuice);
17
16
  }
18
17
 
19
- getFunctionCalls(): Promise<FunctionCall[]> {
20
- return Promise.resolve([]);
18
+ getExecutionPayload(): Promise<ExecutionPayload> {
19
+ return Promise.resolve(ExecutionPayload.empty());
21
20
  }
22
21
 
23
22
  getFeePayer(): Promise<AztecAddress> {
@@ -1,6 +1,6 @@
1
+ import { ExecutionPayload } from '@aztec/entrypoints/payload';
1
2
  import { Fr } from '@aztec/foundation/fields';
2
3
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
3
- import type { FunctionCall } from '@aztec/stdlib/abi';
4
4
  import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
5
5
 
6
6
  import { getFeeJuice } from '../contract/protocol_contracts.js';
@@ -20,30 +20,34 @@ export class FeeJuicePaymentMethodWithClaim extends FeeJuicePaymentMethod {
20
20
  }
21
21
 
22
22
  /**
23
- * Creates a function call to pay the fee in Fee Juice.
24
- * @returns A function call
23
+ * Creates an execution payload to pay the fee in Fee Juice.
24
+ * @returns An execution payload that just contains the claim function call.
25
25
  */
26
- override async getFunctionCalls(): Promise<FunctionCall[]> {
26
+ override async getExecutionPayload(): Promise<ExecutionPayload> {
27
27
  const canonicalFeeJuice = await getFeeJuice(this.senderWallet);
28
28
  const selector = await FunctionSelector.fromNameAndParameters(
29
29
  canonicalFeeJuice.artifact.functions.find(f => f.name === 'claim')!,
30
30
  );
31
31
 
32
- return Promise.resolve([
33
- {
34
- to: ProtocolContractAddress.FeeJuice,
35
- name: 'claim',
36
- selector,
37
- isStatic: false,
38
- args: [
39
- this.senderWallet.getAddress().toField(),
40
- new Fr(this.claim.claimAmount),
41
- this.claim.claimSecret,
42
- new Fr(this.claim.messageLeafIndex),
43
- ],
44
- returnTypes: [],
45
- type: FunctionType.PRIVATE,
46
- },
47
- ]);
32
+ return new ExecutionPayload(
33
+ [
34
+ {
35
+ to: ProtocolContractAddress.FeeJuice,
36
+ name: 'claim',
37
+ selector,
38
+ isStatic: false,
39
+ args: [
40
+ this.senderWallet.getAddress().toField(),
41
+ new Fr(this.claim.claimAmount),
42
+ this.claim.claimSecret,
43
+ new Fr(this.claim.messageLeafIndex),
44
+ ],
45
+ returnTypes: [],
46
+ type: FunctionType.PRIVATE,
47
+ },
48
+ ],
49
+ [],
50
+ [],
51
+ );
48
52
  }
49
53
  }
@@ -1,12 +1,12 @@
1
+ import type { FeePaymentMethod } from '@aztec/entrypoints/interfaces';
2
+ import { ExecutionPayload } from '@aztec/entrypoints/payload';
1
3
  import { Fr } from '@aztec/foundation/fields';
2
- import { type FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
4
+ import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
3
5
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
4
6
  import type { GasSettings } from '@aztec/stdlib/gas';
5
7
 
6
- import type { Wallet } from '../account/wallet.js';
7
- import { ContractFunctionInteraction } from '../contract/contract_function_interaction.js';
8
- import { SignerlessWallet } from '../wallet/signerless_wallet.js';
9
- import type { FeePaymentMethod } from './fee_payment_method.js';
8
+ import type { Wallet } from '../wallet/wallet.js';
9
+ import { simulateWithoutSignature } from './utils.js';
10
10
 
11
11
  /**
12
12
  * Holds information about how the fee for a transaction is to be paid.
@@ -38,11 +38,10 @@ export class PrivateFeePaymentMethod implements FeePaymentMethod {
38
38
  */
39
39
  getAsset(): Promise<AztecAddress> {
40
40
  if (!this.assetPromise) {
41
- // We use signer-less wallet because this function could be triggered before the associated account is deployed.
42
- const signerlessWallet = new SignerlessWallet(this.wallet);
43
-
44
- const interaction = new ContractFunctionInteraction(
45
- signerlessWallet,
41
+ // We use the utility method to avoid a signature because this function could be triggered
42
+ // before the associated account is deployed.
43
+ this.assetPromise = simulateWithoutSignature(
44
+ this.wallet,
46
45
  this.paymentContract,
47
46
  {
48
47
  name: 'get_accepted_asset',
@@ -68,9 +67,7 @@ export class PrivateFeePaymentMethod implements FeePaymentMethod {
68
67
  isInitializer: false,
69
68
  },
70
69
  [],
71
- );
72
-
73
- this.assetPromise = interaction.simulate();
70
+ ) as Promise<AztecAddress>;
74
71
  }
75
72
  return this.assetPromise!;
76
73
  }
@@ -80,17 +77,17 @@ export class PrivateFeePaymentMethod implements FeePaymentMethod {
80
77
  }
81
78
 
82
79
  /**
83
- * Creates a function call to pay the fee in the given asset.
80
+ * Creates an execution payload to pay the fee using a private function through an FPC in the desired asset
84
81
  * @param gasSettings - The gas settings.
85
- * @returns The function call to pay the fee.
82
+ * @returns An execution payload that contains the required function calls and auth witnesses.
86
83
  */
87
- async getFunctionCalls(gasSettings: GasSettings): Promise<FunctionCall[]> {
84
+ async getExecutionPayload(gasSettings: GasSettings): Promise<ExecutionPayload> {
88
85
  // We assume 1:1 exchange rate between fee juice and token. But in reality you would need to convert feeLimit
89
86
  // (maxFee) to be in token denomination.
90
87
  const maxFee = this.setMaxFeeToOne ? Fr.ONE : gasSettings.getFeeLimit();
91
88
  const nonce = Fr.random();
92
89
 
93
- await this.wallet.createAuthWit({
90
+ const witness = await this.wallet.createAuthWit({
94
91
  caller: this.paymentContract,
95
92
  action: {
96
93
  name: 'transfer_to_public',
@@ -103,16 +100,20 @@ export class PrivateFeePaymentMethod implements FeePaymentMethod {
103
100
  },
104
101
  });
105
102
 
106
- return [
107
- {
108
- name: 'fee_entrypoint_private',
109
- to: this.paymentContract,
110
- selector: await FunctionSelector.fromSignature('fee_entrypoint_private(u128,Field)'),
111
- type: FunctionType.PRIVATE,
112
- isStatic: false,
113
- args: [maxFee, nonce],
114
- returnTypes: [],
115
- },
116
- ];
103
+ return new ExecutionPayload(
104
+ [
105
+ {
106
+ name: 'fee_entrypoint_private',
107
+ to: this.paymentContract,
108
+ selector: await FunctionSelector.fromSignature('fee_entrypoint_private(u128,Field)'),
109
+ type: FunctionType.PRIVATE,
110
+ isStatic: false,
111
+ args: [maxFee, nonce],
112
+ returnTypes: [],
113
+ },
114
+ ],
115
+ [witness],
116
+ [],
117
+ );
117
118
  }
118
119
  }