@aztec/aztec.js 0.0.1-commit.27d773e65 → 0.0.1-commit.2c85e299c

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 (71) hide show
  1. package/dest/api/abi.d.ts +2 -2
  2. package/dest/api/abi.d.ts.map +1 -1
  3. package/dest/api/contract.d.ts +3 -3
  4. package/dest/api/contract.d.ts.map +1 -1
  5. package/dest/api/contract.js +1 -1
  6. package/dest/api/events.d.ts +11 -3
  7. package/dest/api/events.d.ts.map +1 -1
  8. package/dest/api/events.js +11 -6
  9. package/dest/contract/base_contract_interaction.d.ts +3 -3
  10. package/dest/contract/base_contract_interaction.d.ts.map +1 -1
  11. package/dest/contract/batch_call.d.ts +1 -1
  12. package/dest/contract/batch_call.d.ts.map +1 -1
  13. package/dest/contract/batch_call.js +9 -3
  14. package/dest/contract/contract_function_interaction.d.ts +5 -5
  15. package/dest/contract/contract_function_interaction.d.ts.map +1 -1
  16. package/dest/contract/contract_function_interaction.js +98 -12
  17. package/dest/contract/deploy_method.d.ts +20 -8
  18. package/dest/contract/deploy_method.d.ts.map +1 -1
  19. package/dest/contract/deploy_method.js +17 -11
  20. package/dest/contract/interaction_options.d.ts +55 -21
  21. package/dest/contract/interaction_options.d.ts.map +1 -1
  22. package/dest/contract/interaction_options.js +33 -0
  23. package/dest/contract/protocol_contracts/auth-registry.d.ts +1 -1
  24. package/dest/contract/protocol_contracts/auth-registry.d.ts.map +1 -1
  25. package/dest/contract/protocol_contracts/auth-registry.js +8 -0
  26. package/dest/contract/protocol_contracts/fee-juice.d.ts +1 -1
  27. package/dest/contract/protocol_contracts/fee-juice.d.ts.map +1 -1
  28. package/dest/contract/protocol_contracts/fee-juice.js +8 -0
  29. package/dest/contract/protocol_contracts/multi-call-entrypoint.d.ts +1 -1
  30. package/dest/contract/protocol_contracts/multi-call-entrypoint.d.ts.map +1 -1
  31. package/dest/contract/protocol_contracts/multi-call-entrypoint.js +8 -0
  32. package/dest/contract/protocol_contracts/public-checks.d.ts +1 -1
  33. package/dest/contract/protocol_contracts/public-checks.d.ts.map +1 -1
  34. package/dest/contract/protocol_contracts/public-checks.js +8 -0
  35. package/dest/fee/private_fee_payment_method.d.ts +2 -1
  36. package/dest/fee/private_fee_payment_method.d.ts.map +1 -1
  37. package/dest/fee/private_fee_payment_method.js +1 -0
  38. package/dest/fee/public_fee_payment_method.d.ts +2 -1
  39. package/dest/fee/public_fee_payment_method.d.ts.map +1 -1
  40. package/dest/fee/public_fee_payment_method.js +1 -0
  41. package/dest/utils/abi_types.d.ts +6 -1
  42. package/dest/utils/abi_types.d.ts.map +1 -1
  43. package/dest/utils/abi_types.js +1 -1
  44. package/dest/utils/authwit.d.ts +5 -5
  45. package/dest/utils/authwit.d.ts.map +1 -1
  46. package/dest/utils/authwit.js +10 -6
  47. package/dest/utils/cross_chain.d.ts +3 -8
  48. package/dest/utils/cross_chain.d.ts.map +1 -1
  49. package/dest/utils/cross_chain.js +8 -15
  50. package/dest/wallet/wallet.d.ts +75 -2
  51. package/dest/wallet/wallet.d.ts.map +1 -1
  52. package/dest/wallet/wallet.js +22 -3
  53. package/package.json +9 -9
  54. package/src/api/abi.ts +1 -0
  55. package/src/api/contract.ts +8 -1
  56. package/src/api/events.ts +16 -6
  57. package/src/contract/base_contract_interaction.ts +3 -2
  58. package/src/contract/batch_call.ts +10 -2
  59. package/src/contract/contract_function_interaction.ts +97 -19
  60. package/src/contract/deploy_method.ts +37 -26
  61. package/src/contract/interaction_options.ts +89 -23
  62. package/src/contract/protocol_contracts/auth-registry.ts +2 -0
  63. package/src/contract/protocol_contracts/fee-juice.ts +2 -0
  64. package/src/contract/protocol_contracts/multi-call-entrypoint.ts +2 -0
  65. package/src/contract/protocol_contracts/public-checks.ts +2 -0
  66. package/src/fee/private_fee_payment_method.ts +1 -0
  67. package/src/fee/public_fee_payment_method.ts +1 -0
  68. package/src/utils/abi_types.ts +7 -0
  69. package/src/utils/authwit.ts +20 -22
  70. package/src/utils/cross_chain.ts +9 -18
  71. package/src/wallet/wallet.ts +26 -1
@@ -1,14 +1,18 @@
1
1
  import {
2
+ type ABIParameter,
3
+ type AbiType,
2
4
  type FunctionAbi,
3
5
  FunctionCall,
4
6
  FunctionSelector,
5
7
  FunctionType,
8
+ canBeMappedFromNullOrUndefined,
6
9
  decodeFromAbi,
7
10
  encodeArguments,
11
+ isOptionStruct,
8
12
  } from '@aztec/stdlib/abi';
9
13
  import type { AuthWitness } from '@aztec/stdlib/auth-witness';
10
14
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
11
- import { type Capsule, type HashedValues, type TxProfileResult, collectOffchainEffects } from '@aztec/stdlib/tx';
15
+ import type { Capsule, HashedValues, TxProfileResult } from '@aztec/stdlib/tx';
12
16
  import { ExecutionPayload, mergeExecutionPayloads } from '@aztec/stdlib/tx';
13
17
 
14
18
  import type { Wallet } from '../wallet/wallet.js';
@@ -18,7 +22,9 @@ import {
18
22
  type ProfileInteractionOptions,
19
23
  type RequestInteractionOptions,
20
24
  type SimulateInteractionOptions,
21
- type SimulationReturn,
25
+ type SimulationResult,
26
+ emptyOffchainOutput,
27
+ extractOffchainOutput,
22
28
  toProfileOptions,
23
29
  toSimulateOptions,
24
30
  } from './interaction_options.js';
@@ -38,11 +44,32 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
38
44
  private extraHashedArgs: HashedValues[] = [],
39
45
  ) {
40
46
  super(wallet, authWitnesses, capsules);
41
- if (args.some(arg => arg === undefined || arg === null)) {
42
- throw new Error(`All function interaction arguments must be defined and not null. Received: ${args}`);
47
+ // This may feel a bit ad-hoc here, so it warrants a comment. We accept Noir Option<T> parameters, and it's natural
48
+ // to map JS's null/undefined to Noir Option's None. One possible way to deal with null/undefined arguments at this
49
+ // point in the codebase is to conclude that they are accepted since at least one Noir type (ie: Option) can be
50
+ // encoded from them. Then we would let `encode` deal with potential mismatches. I chose not to do that because of
51
+ // the pervasiveness of null/undefined in JS, and how easy it is to inadvertently pass it around. Having this check
52
+ // here allows us to fail at a point where the boundaries and intent are clear.
53
+ if (this.hasInvalidNullOrUndefinedArguments(args)) {
54
+ const signature = formatFunctionSignature(this.functionDao.name, this.functionDao.parameters);
55
+ const received = args.map(formatArg).join(', ');
56
+ throw new Error(
57
+ `Null or undefined arguments are only allowed for Option<T> parameters in ${signature}. Received: (${received}).`,
58
+ );
43
59
  }
44
60
  }
45
61
 
62
+ private hasInvalidNullOrUndefinedArguments(args: any[]) {
63
+ return args.some((arg, index) => {
64
+ if (arg !== undefined && arg !== null) {
65
+ return false;
66
+ }
67
+
68
+ const parameterType = this.functionDao.parameters[index]?.type;
69
+ return !parameterType || !canBeMappedFromNullOrUndefined(parameterType);
70
+ });
71
+ }
72
+
46
73
  /**
47
74
  * Returns the encoded function call wrapped by this interaction
48
75
  * Useful when generating authwits
@@ -97,17 +124,9 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
97
124
  * function or a rich object containing extra metadata, such as estimated gas costs (if requested via options),
98
125
  * execution statistics and emitted offchain effects
99
126
  */
100
- public async simulate<T extends SimulateInteractionOptions>(
101
- options: T,
102
- ): Promise<SimulationReturn<Exclude<T['fee'], undefined>['estimateGas']>>;
103
- // eslint-disable-next-line jsdoc/require-jsdoc
104
- public async simulate<T extends SimulateInteractionOptions>(
105
- options: T,
106
- ): Promise<SimulationReturn<T['includeMetadata']>>;
107
- // eslint-disable-next-line jsdoc/require-jsdoc
108
127
  public async simulate(
109
- options: SimulateInteractionOptions,
110
- ): Promise<SimulationReturn<typeof options.includeMetadata>> {
128
+ options: SimulateInteractionOptions = {} as SimulateInteractionOptions,
129
+ ): Promise<SimulationResult> {
111
130
  // docs:end:simulate
112
131
  if (this.functionDao.functionType == FunctionType.UTILITY) {
113
132
  const call = await this.getFunctionCall();
@@ -122,11 +141,11 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
122
141
  if (options.includeMetadata) {
123
142
  return {
124
143
  stats: utilityResult.stats,
144
+ ...emptyOffchainOutput(),
125
145
  result: returnValue,
126
146
  };
127
- } else {
128
- return returnValue;
129
147
  }
148
+ return { result: returnValue, ...emptyOffchainOutput() };
130
149
  }
131
150
 
132
151
  const executionPayload = await this.request(options);
@@ -148,6 +167,7 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
148
167
  }
149
168
 
150
169
  const returnValue = rawReturnValues ? decodeFromAbi(this.functionDao.returnTypes, rawReturnValues) : [];
170
+ const offchainOutput = extractOffchainOutput(simulatedTx.offchainEffects);
151
171
 
152
172
  if (options.includeMetadata || options.fee?.estimateGas) {
153
173
  const { gasLimits, teardownGasLimits } = getGasLimits(simulatedTx, options.fee?.estimatedGasPadding);
@@ -156,13 +176,12 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
156
176
  );
157
177
  return {
158
178
  stats: simulatedTx.stats,
159
- offchainEffects: collectOffchainEffects(simulatedTx.privateExecutionResult),
179
+ ...offchainOutput,
160
180
  result: returnValue,
161
181
  estimatedGas: { gasLimits, teardownGasLimits },
162
182
  };
163
- } else {
164
- return returnValue;
165
183
  }
184
+ return { result: returnValue, ...offchainOutput };
166
185
  }
167
186
 
168
187
  /**
@@ -210,3 +229,62 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
210
229
  );
211
230
  }
212
231
  }
232
+
233
+ /**
234
+ * Render an AbiType as a human readable string
235
+ * */
236
+ function formatAbiType(abiType: AbiType): string {
237
+ switch (abiType.kind) {
238
+ case 'field':
239
+ return 'Field';
240
+ case 'boolean':
241
+ return 'bool';
242
+ case 'integer':
243
+ return `${abiType.sign === 'signed' ? 'i' : 'u'}${abiType.width}`;
244
+ case 'string':
245
+ return `str<${abiType.length}>`;
246
+ case 'array':
247
+ return `[${formatAbiType(abiType.type)}; ${abiType.length}]`;
248
+ case 'struct': {
249
+ if (isOptionStruct(abiType)) {
250
+ const innerType = abiType.fields.find(f => f.name === '_value')!.type;
251
+ return `Option<${formatAbiType(innerType)}>`;
252
+ }
253
+ return `(${abiType.fields.map(f => `${f.name}: ${formatAbiType(f.type)}`).join(', ')})`;
254
+ }
255
+ case 'tuple':
256
+ return `(${abiType.fields.map(formatAbiType).join(', ')})`;
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Pretty print a function signature
262
+ */
263
+ function formatFunctionSignature(name: string, parameters: ABIParameter[]): string {
264
+ const params = parameters.map(p => `${p.name}: ${formatAbiType(p.type)}`).join(', ');
265
+ return `${name}(${params})`;
266
+ }
267
+
268
+ /**
269
+ * Non-exhaustive pretty print of JS args to display in error messages in this module
270
+ */
271
+ function formatArg(arg: unknown): string {
272
+ if (arg === undefined) {
273
+ return 'undefined';
274
+ }
275
+ if (arg === null) {
276
+ return 'null';
277
+ }
278
+ if (typeof arg === 'bigint') {
279
+ return `${arg}n`;
280
+ }
281
+ if (Array.isArray(arg)) {
282
+ return `[${arg.map(formatArg).join(', ')}]`;
283
+ }
284
+ if (typeof arg === 'object') {
285
+ const entries = Object.entries(arg).map(([k, v]) => `${k}: ${formatArg(v)}`);
286
+ return `{ ${entries.join(', ')} }`;
287
+ }
288
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
289
+ return String(arg);
290
+ }
@@ -9,14 +9,7 @@ import {
9
9
  getContractInstanceFromInstantiationParams,
10
10
  } from '@aztec/stdlib/contract';
11
11
  import type { PublicKeys } from '@aztec/stdlib/keys';
12
- import {
13
- type Capsule,
14
- HashedValues,
15
- TxHash,
16
- type TxProfileResult,
17
- type TxReceipt,
18
- collectOffchainEffects,
19
- } from '@aztec/stdlib/tx';
12
+ import { type Capsule, HashedValues, type TxProfileResult, type TxReceipt } from '@aztec/stdlib/tx';
20
13
  import { ExecutionPayload, mergeExecutionPayloads } from '@aztec/stdlib/tx';
21
14
 
22
15
  import { publishContractClass } from '../deployment/publish_class.js';
@@ -29,11 +22,15 @@ import { getGasLimits } from './get_gas_limits.js';
29
22
  import {
30
23
  NO_WAIT,
31
24
  type NoWait,
25
+ type OffchainOutput,
32
26
  type ProfileInteractionOptions,
33
27
  type RequestInteractionOptions,
34
28
  type SendInteractionOptionsWithoutWait,
35
29
  type SimulationInteractionFeeOptions,
36
- type SimulationReturn,
30
+ type SimulationResult,
31
+ type TxSendResultImmediate,
32
+ type TxSendResultMined,
33
+ extractOffchainOutput,
37
34
  toProfileOptions,
38
35
  toSendOptions,
39
36
  toSimulateOptions,
@@ -130,20 +127,32 @@ export type DeployTxReceipt<TContract extends ContractBase = ContractBase> = TxR
130
127
  instance: ContractInstanceWithAddress;
131
128
  };
132
129
 
130
+ /** Wait options that request a full receipt instead of just the contract instance. */
131
+ type WaitWithReturnReceipt = {
132
+ /** Request the full receipt instead of just the contract instance. */
133
+ returnReceipt: true;
134
+ };
135
+
133
136
  /**
134
137
  * Represents the result type of deploying a contract.
135
138
  * - If wait is NO_WAIT, returns TxHash immediately.
136
139
  * - If wait has returnReceipt: true, returns DeployTxReceipt after waiting.
137
140
  * - Otherwise (undefined or DeployWaitOptions without returnReceipt), returns TContract after waiting.
138
141
  */
142
+ /** Result of deploying a contract when waiting for mining (default case). */
143
+ export type DeployResultMined<TContract extends ContractBase> = {
144
+ /** The deployed contract instance. */
145
+ contract: TContract;
146
+ /** The deploy transaction receipt. */
147
+ receipt: DeployTxReceipt<TContract>;
148
+ } & OffchainOutput;
149
+
150
+ /** Conditional return type for deploy based on wait options. */
139
151
  export type DeployReturn<TContract extends ContractBase, W extends DeployInteractionWaitOptions> = W extends NoWait
140
- ? TxHash
141
- : W extends {
142
- // eslint-disable-next-line jsdoc/require-jsdoc
143
- returnReceipt: true;
144
- }
145
- ? DeployTxReceipt<TContract>
146
- : TContract;
152
+ ? TxSendResultImmediate
153
+ : W extends WaitWithReturnReceipt
154
+ ? TxSendResultMined<DeployTxReceipt<TContract>>
155
+ : DeployResultMined<TContract>;
147
156
 
148
157
  /**
149
158
  * Contract interaction for deployment.
@@ -343,8 +352,7 @@ export class DeployMethod<TContract extends ContractBase = ContractBase> extends
343
352
  * @returns TxHash (if wait is NO_WAIT), TContract (if wait is undefined or doesn't have returnReceipt), or DeployTxReceipt (if wait.returnReceipt is true)
344
353
  */
345
354
  // Overload for when wait is not specified at all - returns the contract
346
- public override send(options: DeployOptionsWithoutWait): Promise<TContract>;
347
- // Generic overload for explicit wait values
355
+ public override send(options: DeployOptionsWithoutWait): Promise<DeployResultMined<TContract>>;
348
356
  // eslint-disable-next-line jsdoc/require-jsdoc
349
357
  public override send<W extends DeployInteractionWaitOptions>(
350
358
  options: DeployOptions<W>,
@@ -355,12 +363,15 @@ export class DeployMethod<TContract extends ContractBase = ContractBase> extends
355
363
  const sendOptions = this.convertDeployOptionsToSendOptions(options);
356
364
 
357
365
  if (options.wait === NO_WAIT) {
358
- const txHash = await this.wallet.sendTx(executionPayload, sendOptions as SendOptions<NoWait>);
359
- this.log.debug(`Sent deployment tx ${txHash.hash} of ${this.artifact.name} contract`);
360
- return txHash;
366
+ const result = await this.wallet.sendTx(executionPayload, sendOptions as SendOptions<NoWait>);
367
+ this.log.debug(`Sent deployment tx ${result.txHash.hash} of ${this.artifact.name} contract`);
368
+ return result;
361
369
  }
362
370
 
363
- const receipt = await this.wallet.sendTx(executionPayload, sendOptions as SendOptions<WaitOpts | undefined>);
371
+ const { receipt, ...offchainOutput } = await this.wallet.sendTx(
372
+ executionPayload,
373
+ sendOptions as SendOptions<WaitOpts | undefined>,
374
+ );
364
375
  this.log.debug(`Deployed ${this.artifact.name} contract in tx ${receipt.txHash}`);
365
376
 
366
377
  // Attach contract instance
@@ -369,10 +380,10 @@ export class DeployMethod<TContract extends ContractBase = ContractBase> extends
369
380
 
370
381
  // Return full receipt if requested, otherwise just the contract
371
382
  if (options.wait && typeof options.wait === 'object' && options.wait.returnReceipt) {
372
- return { ...receipt, contract, instance };
383
+ return { receipt: { ...receipt, contract, instance }, ...offchainOutput };
373
384
  }
374
385
 
375
- return contract;
386
+ return { contract, receipt, ...offchainOutput };
376
387
  }
377
388
 
378
389
  /**
@@ -401,7 +412,7 @@ export class DeployMethod<TContract extends ContractBase = ContractBase> extends
401
412
  * @returns A simulation result object containing metadata of the execution, including gas
402
413
  * estimations (if requested via options), execution statistics and emitted offchain effects
403
414
  */
404
- public async simulate(options: SimulateDeployOptions): Promise<SimulationReturn<true>> {
415
+ public async simulate(options: SimulateDeployOptions): Promise<SimulationResult> {
405
416
  const executionPayload = await this.request(this.convertDeployOptionsToRequestOptions(options));
406
417
  const simulatedTx = await this.wallet.simulateTx(
407
418
  executionPayload,
@@ -414,7 +425,7 @@ export class DeployMethod<TContract extends ContractBase = ContractBase> extends
414
425
  );
415
426
  return {
416
427
  stats: simulatedTx.stats!,
417
- offchainEffects: collectOffchainEffects(simulatedTx.privateExecutionResult),
428
+ ...extractOffchainOutput(simulatedTx.offchainEffects),
418
429
  result: undefined,
419
430
  estimatedGas: { gasLimits, teardownGasLimits },
420
431
  };
@@ -1,8 +1,16 @@
1
+ import type { Fr } from '@aztec/foundation/curves/bn254';
1
2
  import type { FieldsOf } from '@aztec/foundation/types';
2
3
  import type { AuthWitness } from '@aztec/stdlib/auth-witness';
3
- import type { AztecAddress } from '@aztec/stdlib/aztec-address';
4
+ import { AztecAddress } from '@aztec/stdlib/aztec-address';
4
5
  import type { GasSettings } from '@aztec/stdlib/gas';
5
- import type { Capsule, OffchainEffect, SimulationStats, TxHash, TxReceipt } from '@aztec/stdlib/tx';
6
+ import {
7
+ type Capsule,
8
+ OFFCHAIN_MESSAGE_IDENTIFIER,
9
+ type OffchainEffect,
10
+ type SimulationStats,
11
+ type TxHash,
12
+ type TxReceipt,
13
+ } from '@aztec/stdlib/tx';
6
14
 
7
15
  import type { FeePaymentMethod } from '../fee/fee_payment_method.js';
8
16
  import type { ProfileOptions, SendOptions, SimulateOptions } from '../wallet/index.js';
@@ -116,8 +124,8 @@ export type SimulateInteractionOptions = Omit<SendInteractionOptions, 'fee'> & {
116
124
  skipTxValidation?: boolean;
117
125
  /** Whether to ensure the fee payer is not empty and has enough balance to pay for the fee. */
118
126
  skipFeeEnforcement?: boolean;
119
- /** Whether to include metadata such as offchain effects and performance statistics (e.g. timing information of the different circuits and oracles) in
120
- * the simulation result, instead of just the return value of the function */
127
+ /** Whether to include metadata such as performance statistics (e.g. timing information of the different circuits and oracles) and gas estimation
128
+ * in the simulation result, in addition to the return value and offchain effects */
121
129
  includeMetadata?: boolean;
122
130
  };
123
131
 
@@ -131,31 +139,89 @@ export type ProfileInteractionOptions = SimulateInteractionOptions & {
131
139
  skipProofGeneration?: boolean;
132
140
  };
133
141
 
142
+ /** A message emitted during execution or proving, to be delivered offchain. */
143
+ export type OffchainMessage = {
144
+ /** The intended recipient of the message. */
145
+ recipient: AztecAddress;
146
+ /** The message payload (typically encrypted). */
147
+ payload: Fr[];
148
+ /** The contract that emitted the message. */
149
+ contractAddress: AztecAddress;
150
+ };
151
+
152
+ /** Groups all unproven outputs from private execution that are returned to the client. */
153
+ export type OffchainOutput = {
154
+ /** Raw offchain effects emitted during execution. */
155
+ offchainEffects: OffchainEffect[];
156
+ /** Messages emitted during execution, to be delivered offchain. */
157
+ offchainMessages: OffchainMessage[];
158
+ };
159
+
134
160
  /**
135
- * Represents the result type of a simulation.
136
- * By default, it will just be the return value of the simulated function
137
- * If `includeMetadata` is set to true in `SimulateInteractionOptions` on the input of `simulate(...)`,
138
- * it will provide extra information.
139
- */
140
- export type SimulationReturn<T extends boolean | undefined> = T extends true
141
- ? {
142
- /** Additional stats about the simulation */
143
- stats: SimulationStats;
144
- /** Offchain effects generated during the simulation */
145
- offchainEffects: OffchainEffect[];
146
- /** Return value of the function */
147
- result: any;
148
- /** Gas estimation results */
149
- estimatedGas: Pick<GasSettings, 'gasLimits' | 'teardownGasLimits'>;
161
+ * Splits an array of offchain effects into decoded offchain messages and remaining effects.
162
+ * Effects whose data starts with `OFFCHAIN_MESSAGE_IDENTIFIER` are parsed as messages and removed
163
+ * from the effects array.
164
+ */
165
+ export function extractOffchainOutput(effects: OffchainEffect[]): OffchainOutput {
166
+ const offchainEffects: OffchainEffect[] = [];
167
+ const offchainMessages: OffchainMessage[] = [];
168
+
169
+ for (const effect of effects) {
170
+ if (effect.data.length >= 2 && effect.data[0].equals(OFFCHAIN_MESSAGE_IDENTIFIER)) {
171
+ offchainMessages.push({
172
+ recipient: AztecAddress.fromField(effect.data[1]),
173
+ payload: effect.data.slice(2),
174
+ contractAddress: effect.contractAddress,
175
+ });
176
+ } else {
177
+ offchainEffects.push(effect);
150
178
  }
151
- : any;
179
+ }
180
+
181
+ return { offchainEffects, offchainMessages };
182
+ }
183
+
184
+ /**
185
+ * Returns an empty `OffchainOutput` (no effects, no messages).
186
+ */
187
+ export function emptyOffchainOutput(): OffchainOutput {
188
+ return { offchainEffects: [], offchainMessages: [] };
189
+ }
190
+
191
+ /**
192
+ * Represents the result of a simulation.
193
+ * Always includes the return value and offchain output.
194
+ * When `includeMetadata` or `fee.estimateGas` is set, also includes stats and gas estimation.
195
+ */
196
+ export type SimulationResult = {
197
+ /** Return value of the function */
198
+ result: any;
199
+ /** Additional stats about the simulation. Present when `includeMetadata` is set. */
200
+ stats?: SimulationStats;
201
+ /** Gas estimation results. Present when `includeMetadata` or `fee.estimateGas` is set. */
202
+ estimatedGas?: Pick<GasSettings, 'gasLimits' | 'teardownGasLimits'>;
203
+ } & OffchainOutput;
204
+
205
+ /** Result of sendTx when not waiting for mining. */
206
+ export type TxSendResultImmediate = {
207
+ /** The hash of the sent transaction. */
208
+ txHash: TxHash;
209
+ } & OffchainOutput;
210
+
211
+ /** Result of sendTx when waiting for mining. */
212
+ export type TxSendResultMined<TReturn = TxReceipt> = {
213
+ /** The transaction receipt. */
214
+ receipt: TReturn;
215
+ } & OffchainOutput;
152
216
 
153
217
  /**
154
218
  * Represents the result type of sending a transaction.
155
- * If `wait` is NO_WAIT, returns TxHash immediately without waiting.
156
- * If `wait` is undefined or WaitOpts, returns TReturn (defaults to TxReceipt) after waiting.
219
+ * If `wait` is NO_WAIT, returns TxSendResultImmediate.
220
+ * Otherwise returns TxSendResultMined.
157
221
  */
158
- export type SendReturn<T extends InteractionWaitOptions, TReturn = TxReceipt> = T extends NoWait ? TxHash : TReturn;
222
+ export type SendReturn<T extends InteractionWaitOptions, TReturn = TxReceipt> = T extends NoWait
223
+ ? TxSendResultImmediate
224
+ : TxSendResultMined<TReturn>;
159
225
 
160
226
  /**
161
227
  * Transforms and cleans up the higher level SendInteractionOptions defined by the interaction into
@@ -163,6 +163,7 @@ const AuthRegistryContractArtifact: ContractArtifact = {
163
163
  '4261968856572588300': { error_kind: 'string', string: 'Value does not fit in field' },
164
164
  '4440399188109668273': { error_kind: 'string', string: 'Input length must be a multiple of 32' },
165
165
  '5417577161503694006': { error_kind: 'fmtstring', length: 56, item_types: [{ kind: 'field' }] },
166
+ '5421095327929394772': { error_kind: 'string', string: 'attempt to bit-shift with overflow' },
166
167
  '9530675838293881722': { error_kind: 'string', string: 'Writer did not write all data' },
167
168
  '9791669845391776238': {
168
169
  error_kind: 'string',
@@ -266,6 +267,7 @@ const AuthRegistryContractArtifact: ContractArtifact = {
266
267
  '4261968856572588300': { error_kind: 'string', string: 'Value does not fit in field' },
267
268
  '4440399188109668273': { error_kind: 'string', string: 'Input length must be a multiple of 32' },
268
269
  '5417577161503694006': { error_kind: 'fmtstring', length: 56, item_types: [{ kind: 'field' }] },
270
+ '5421095327929394772': { error_kind: 'string', string: 'attempt to bit-shift with overflow' },
269
271
  '9530675838293881722': { error_kind: 'string', string: 'Writer did not write all data' },
270
272
  '9791669845391776238': {
271
273
  error_kind: 'string',
@@ -44,6 +44,7 @@ const FeeJuiceContractArtifact: ContractArtifact = {
44
44
  errorTypes: {
45
45
  '361444214588792908': { error_kind: 'string', string: 'attempt to multiply with overflow' },
46
46
  '1998584279744703196': { error_kind: 'string', string: 'attempt to subtract with overflow' },
47
+ '5421095327929394772': { error_kind: 'string', string: 'attempt to bit-shift with overflow' },
47
48
  '6609888949476313245': { error_kind: 'string', string: 'Message not in state' },
48
49
  '11019205087382408538': { error_kind: 'string', string: 'Field failed to decompose into specified 4 limbs' },
49
50
  '12370419938245003393': { error_kind: 'string', string: 'Field failed to decompose into specified 36 limbs' },
@@ -81,6 +82,7 @@ const FeeJuiceContractArtifact: ContractArtifact = {
81
82
  errorTypes: {
82
83
  '361444214588792908': { error_kind: 'string', string: 'attempt to multiply with overflow' },
83
84
  '1998584279744703196': { error_kind: 'string', string: 'attempt to subtract with overflow' },
85
+ '5421095327929394772': { error_kind: 'string', string: 'attempt to bit-shift with overflow' },
84
86
  '6609888949476313245': { error_kind: 'string', string: 'Message not in state' },
85
87
  '11019205087382408538': { error_kind: 'string', string: 'Field failed to decompose into specified 4 limbs' },
86
88
  '12370419938245003393': { error_kind: 'string', string: 'Field failed to decompose into specified 36 limbs' },
@@ -161,6 +161,7 @@ const MultiCallEntrypointContractArtifact: ContractArtifact = {
161
161
  '4261968856572588300': { error_kind: 'string', string: 'Value does not fit in field' },
162
162
  '4440399188109668273': { error_kind: 'string', string: 'Input length must be a multiple of 32' },
163
163
  '5417577161503694006': { error_kind: 'fmtstring', length: 56, item_types: [{ kind: 'field' }] },
164
+ '5421095327929394772': { error_kind: 'string', string: 'attempt to bit-shift with overflow' },
164
165
  '9530675838293881722': { error_kind: 'string', string: 'Writer did not write all data' },
165
166
  '9791669845391776238': {
166
167
  error_kind: 'string',
@@ -225,6 +226,7 @@ const MultiCallEntrypointContractArtifact: ContractArtifact = {
225
226
  '4261968856572588300': { error_kind: 'string', string: 'Value does not fit in field' },
226
227
  '4440399188109668273': { error_kind: 'string', string: 'Input length must be a multiple of 32' },
227
228
  '5417577161503694006': { error_kind: 'fmtstring', length: 56, item_types: [{ kind: 'field' }] },
229
+ '5421095327929394772': { error_kind: 'string', string: 'attempt to bit-shift with overflow' },
228
230
  '9530675838293881722': { error_kind: 'string', string: 'Writer did not write all data' },
229
231
  '9791669845391776238': {
230
232
  error_kind: 'string',
@@ -94,6 +94,7 @@ const PublicChecksContractArtifact: ContractArtifact = {
94
94
  '4261968856572588300': { error_kind: 'string', string: 'Value does not fit in field' },
95
95
  '4440399188109668273': { error_kind: 'string', string: 'Input length must be a multiple of 32' },
96
96
  '5417577161503694006': { error_kind: 'fmtstring', length: 56, item_types: [{ kind: 'field' }] },
97
+ '5421095327929394772': { error_kind: 'string', string: 'attempt to bit-shift with overflow' },
97
98
  '9530675838293881722': { error_kind: 'string', string: 'Writer did not write all data' },
98
99
  '9791669845391776238': {
99
100
  error_kind: 'string',
@@ -186,6 +187,7 @@ const PublicChecksContractArtifact: ContractArtifact = {
186
187
  '4261968856572588300': { error_kind: 'string', string: 'Value does not fit in field' },
187
188
  '4440399188109668273': { error_kind: 'string', string: 'Input length must be a multiple of 32' },
188
189
  '5417577161503694006': { error_kind: 'fmtstring', length: 56, item_types: [{ kind: 'field' }] },
190
+ '5421095327929394772': { error_kind: 'string', string: 'attempt to bit-shift with overflow' },
189
191
  '9530675838293881722': { error_kind: 'string', string: 'Writer did not write all data' },
190
192
  '9791669845391776238': {
191
193
  error_kind: 'string',
@@ -10,6 +10,7 @@ import type { FeePaymentMethod } from './fee_payment_method.js';
10
10
 
11
11
  /**
12
12
  * Holds information about how the fee for a transaction is to be paid.
13
+ * @deprecated Is not supported on mainnet. Use {@link FeeJuicePaymentMethodWithClaim} or `SponsoredFeePaymentMethod` instead.
13
14
  */
14
15
  export class PrivateFeePaymentMethod implements FeePaymentMethod {
15
16
  private assetPromise: Promise<AztecAddress> | null = null;
@@ -11,6 +11,7 @@ import type { FeePaymentMethod } from './fee_payment_method.js';
11
11
 
12
12
  /**
13
13
  * Holds information about how the fee for a transaction is to be paid.
14
+ * @deprecated Is not supported on mainnet. Use {@link FeeJuicePaymentMethodWithClaim} or `SponsoredFeePaymentMethod` instead.
14
15
  */
15
16
  export class PublicFeePaymentMethod implements FeePaymentMethod {
16
17
  private assetPromise: Promise<AztecAddress> | null = null;
@@ -23,3 +23,10 @@ export type U128Like = bigint | number;
23
23
 
24
24
  /** Any type that can be converted into a struct with a single `inner` field. */
25
25
  export type WrappedFieldLike = { /** Wrapped value */ inner: FieldLike } | FieldLike;
26
+
27
+ /** Noir `Option<T>` lowered ABI shape, plus ergonomic direct `T | null | undefined` inputs. */
28
+ export type OptionLike<T> =
29
+ | T
30
+ | null
31
+ | undefined
32
+ | { /** Whether the option is populated */ _is_some: boolean; /** Wrapped value */ _value: T };
@@ -5,7 +5,7 @@ import { type ABIParameterVisibility, type FunctionAbi, type FunctionCall, Funct
5
5
  import { AuthWitness, computeInnerAuthWitHash, computeOuterAuthWitHash } from '@aztec/stdlib/auth-witness';
6
6
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
7
7
  import { computeVarArgsHash } from '@aztec/stdlib/hash';
8
- import type { TxHash, TxProfileResult, TxReceipt } from '@aztec/stdlib/tx';
8
+ import type { TxProfileResult } from '@aztec/stdlib/tx';
9
9
 
10
10
  import { ContractFunctionInteraction } from '../contract/contract_function_interaction.js';
11
11
  import type {
@@ -15,7 +15,8 @@ import type {
15
15
  SendInteractionOptionsWithoutWait,
16
16
  SendReturn,
17
17
  SimulateInteractionOptions,
18
- SimulationReturn,
18
+ SimulationResult,
19
+ TxSendResultMined,
19
20
  } from '../contract/interaction_options.js';
20
21
  import type { Wallet } from '../wallet/index.js';
21
22
 
@@ -189,10 +190,12 @@ export async function lookupValidity(
189
190
  errorTypes: {},
190
191
  } as FunctionAbi;
191
192
  try {
192
- results.isValidInPrivate = (await new ContractFunctionInteraction(wallet, onBehalfOf, lookupValidityAbi, [
193
- consumer,
194
- innerHash,
195
- ]).simulate({ from: onBehalfOf, authWitnesses: [witness] })) as boolean;
193
+ results.isValidInPrivate = (
194
+ await new ContractFunctionInteraction(wallet, onBehalfOf, lookupValidityAbi, [consumer, innerHash]).simulate({
195
+ from: onBehalfOf,
196
+ authWitnesses: [witness],
197
+ })
198
+ ).result as boolean;
196
199
  // TODO: Narrow down the error to make sure simulation failed due to an invalid authwit
197
200
  // eslint-disable-next-line no-empty
198
201
  } catch {}
@@ -219,12 +222,12 @@ export async function lookupValidity(
219
222
  returnTypes: [{ kind: 'boolean' }],
220
223
  errorTypes: {},
221
224
  } as FunctionAbi;
222
- results.isValidInPublic = (await new ContractFunctionInteraction(
223
- wallet,
224
- ProtocolContractAddress.AuthRegistry,
225
- isConsumableAbi,
226
- [onBehalfOf, messageHash],
227
- ).simulate({ from: onBehalfOf })) as boolean;
225
+ results.isValidInPublic = (
226
+ await new ContractFunctionInteraction(wallet, ProtocolContractAddress.AuthRegistry, isConsumableAbi, [
227
+ onBehalfOf,
228
+ messageHash,
229
+ ]).simulate({ from: onBehalfOf })
230
+ ).result as boolean;
228
231
 
229
232
  return results;
230
233
  }
@@ -262,14 +265,10 @@ export class SetPublicAuthwitContractInteraction extends ContractFunctionInterac
262
265
  * @param options - An optional object containing additional configuration for the transaction.
263
266
  * @returns The result of the transaction as returned by the contract function.
264
267
  */
265
- public override simulate<T extends SimulateInteractionOptions>(
266
- options: Omit<T, 'from'>,
267
- ): Promise<SimulationReturn<T['includeMetadata']>>;
268
- // eslint-disable-next-line jsdoc/require-jsdoc
269
268
  public override simulate(
270
- options: Omit<SimulateInteractionOptions, 'from'> = {},
271
- ): Promise<SimulationReturn<typeof options.includeMetadata>> {
272
- return super.simulate({ ...options, from: this.from });
269
+ options: Omit<SimulateInteractionOptions, 'from'> = {} as Omit<SimulateInteractionOptions, 'from'>,
270
+ ): Promise<SimulationResult> {
271
+ return super.simulate({ ...options, from: this.from } as SimulateInteractionOptions);
273
272
  }
274
273
 
275
274
  /**
@@ -290,8 +289,7 @@ export class SetPublicAuthwitContractInteraction extends ContractFunctionInterac
290
289
  * @param options - An optional object containing 'fee' options information
291
290
  * @returns A TxReceipt (if wait is true/undefined) or TxHash (if wait is false)
292
291
  */
293
- // Overload for when wait is not specified at all - returns TxReceipt
294
- public override send(options?: Omit<SendInteractionOptionsWithoutWait, 'from'>): Promise<TxReceipt>;
292
+ public override send(options?: Omit<SendInteractionOptionsWithoutWait, 'from'>): Promise<TxSendResultMined>;
295
293
  // Generic overload for explicit wait values
296
294
  // eslint-disable-next-line jsdoc/require-jsdoc
297
295
  public override send<W extends InteractionWaitOptions>(
@@ -300,7 +298,7 @@ export class SetPublicAuthwitContractInteraction extends ContractFunctionInterac
300
298
  // eslint-disable-next-line jsdoc/require-jsdoc
301
299
  public override send(
302
300
  options?: Omit<SendInteractionOptions<InteractionWaitOptions>, 'from'>,
303
- ): Promise<TxReceipt | TxHash> {
301
+ ): Promise<SendReturn<InteractionWaitOptions>> {
304
302
  return super.send({ ...options, from: this.from });
305
303
  }
306
304