@aztec/builder 0.0.0-test.1 → 0.0.1-commit.017a351

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.
package/dest/bin/cli.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  export {};
3
- //# sourceMappingURL=cli.d.ts.map
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYmluL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
@@ -5,5 +5,5 @@ export type GenerateCodeOptions = {
5
5
  /**
6
6
  * Generates Noir interface or Typescript interface for a folder or single file from a Noir compilation artifact.
7
7
  */
8
- export declare function generateCode(outputPath: string, fileOrDirPath: string, opts?: GenerateCodeOptions): Promise<string[]>;
9
- //# sourceMappingURL=codegen.d.ts.map
8
+ export declare function generateCode(outputPath: string, fileOrDirPath: string, opts?: GenerateCodeOptions): Promise<(string | undefined)[]>;
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZWdlbi5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbnRyYWN0LWludGVyZmFjZS1nZW4vY29kZWdlbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFZQSw0QkFBNEI7QUFDNUIsTUFBTSxNQUFNLG1CQUFtQixHQUFHO0lBQUUsS0FBSyxDQUFDLEVBQUUsT0FBTyxDQUFBO0NBQUUsQ0FBQztBQUV0RDs7R0FFRztBQUNILHdCQUFzQixZQUFZLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLElBQUksR0FBRSxtQkFBd0IsbUNBa0IzRyJ9
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/contract-interface-gen/codegen.ts"],"names":[],"mappings":"AAYA,4BAA4B;AAC5B,MAAM,MAAM,mBAAmB,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtD;;GAEG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,GAAE,mBAAwB,qBAkB3G"}
1
+ {"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/contract-interface-gen/codegen.ts"],"names":[],"mappings":"AAYA,4BAA4B;AAC5B,MAAM,MAAM,mBAAmB,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtD;;GAEG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,GAAE,mBAAwB,mCAkB3G"}
@@ -38,6 +38,10 @@ let cache = {};
38
38
  }
39
39
  const file = await readFile(noirAbiPath, 'utf8');
40
40
  const contract = JSON.parse(file);
41
+ if (!Array.isArray(contract.functions)) {
42
+ console.log(`${fileName} is not a contract artifact. Skipping.`);
43
+ return;
44
+ }
41
45
  const aztecAbi = loadContractArtifact(contract);
42
46
  await mkdir(outputPath, {
43
47
  recursive: true
@@ -0,0 +1,2 @@
1
+ export { generateTypescriptContractInterface } from './typescript.js';
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb250cmFjdC1pbnRlcmZhY2UtZ2VuL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxtQ0FBbUMsRUFBRSxNQUFNLGlCQUFpQixDQUFDIn0=
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contract-interface-gen/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mCAAmC,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1 @@
1
+ export { generateTypescriptContractInterface } from './typescript.js';
@@ -6,4 +6,4 @@ import { type ContractArtifact } from '@aztec/stdlib/abi';
6
6
  * @returns The corresponding ts code.
7
7
  */
8
8
  export declare function generateTypescriptContractInterface(input: ContractArtifact, artifactImportPath?: string): Promise<string>;
9
- //# sourceMappingURL=typescript.d.ts.map
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXNjcmlwdC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbnRyYWN0LWludGVyZmFjZS1nZW4vdHlwZXNjcmlwdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR0wsS0FBSyxnQkFBZ0IsRUFhdEIsTUFBTSxtQkFBbUIsQ0FBQztBQXVSM0I7Ozs7O0dBS0c7QUFDSCx3QkFBc0IsbUNBQW1DLENBQUMsS0FBSyxFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixDQUFDLEVBQUUsTUFBTSxtQkFrRDdHIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../src/contract-interface-gen/typescript.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EAStB,MAAM,mBAAmB,CAAC;AAyR3B;;;;;GAKG;AACH,wBAAsB,mCAAmC,CAAC,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,CAAC,EAAE,MAAM,mBA8E7G"}
1
+ {"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../src/contract-interface-gen/typescript.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EAatB,MAAM,mBAAmB,CAAC;AAuR3B;;;;;GAKG;AACH,wBAAsB,mCAAmC,CAAC,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,CAAC,EAAE,MAAM,mBAkD7G"}
@@ -1,4 +1,4 @@
1
- import { EventSelector, decodeFunctionSignature, getDefaultInitializer, isAztecAddressStruct, isEthAddressStruct, isFunctionSelectorStruct, isWrappedFieldStruct } from '@aztec/stdlib/abi';
1
+ import { EventSelector, decodeFunctionSignature, getAllFunctionAbis, getDefaultInitializer, isAztecAddressStruct, isBoundedVecStruct, isEthAddressStruct, isFunctionSelectorStruct, isOptionStruct, isPublicKeysStruct, isWrappedFieldStruct } from '@aztec/stdlib/abi';
2
2
  /**
3
3
  * Returns the corresponding typescript type for a given Noir type.
4
4
  * @param type - The input Noir type.
@@ -28,9 +28,22 @@ import { EventSelector, decodeFunctionSignature, getDefaultInitializer, isAztecA
28
28
  if (isWrappedFieldStruct(type)) {
29
29
  return 'WrappedFieldLike';
30
30
  }
31
+ if (isPublicKeysStruct(type)) {
32
+ // PublicKeys are special cased due to them being part of the preimage of contract addresses.
33
+ // The proper type is expected by the TS code that deals with the ContractInstanceRegistry protocol contract.
34
+ return 'PublicKeys';
35
+ }
36
+ if (isBoundedVecStruct(type)) {
37
+ // To make BoundedVec easier to work with, we expect a simple array on the input and then we encode it
38
+ // as a BoundedVec in the ArgumentsEncoder.
39
+ return `${abiTypeToTypescript(type.fields[0].type)}`;
40
+ }
41
+ if (isOptionStruct(type)) {
42
+ return `OptionLike<${abiTypeToTypescript(type.fields[1].type)}>`;
43
+ }
31
44
  return `{ ${type.fields.map((f)=>`${f.name}: ${abiTypeToTypescript(f.type)}`).join(', ')} }`;
32
45
  default:
33
- throw new Error(`Unknown type ${type}`);
46
+ throw new Error(`Unknown type ${type.kind}`);
34
47
  }
35
48
  }
36
49
  /**
@@ -56,38 +69,46 @@ import { EventSelector, decodeFunctionSignature, getDefaultInitializer, isAztecA
56
69
  * @returns A type-safe deploy method in ts.
57
70
  */ function generateDeploy(input) {
58
71
  const ctor = getDefaultInitializer(input);
59
- const args = (ctor?.parameters ?? []).map(generateParameter).join(', ');
72
+ const ctorParams = ctor?.parameters ?? [];
73
+ const args = ctorParams.map(generateParameter).join(', ');
74
+ const argNames = ctorParams.map((p)=>p.name).join(', ');
75
+ const argsForwarding = argNames ? `[${argNames}]` : '[]';
60
76
  const contractName = `${input.name}Contract`;
61
77
  const artifactName = `${contractName}Artifact`;
62
78
  return `
63
79
  /**
64
80
  * Creates a tx to deploy a new instance of this contract.
81
+ * @param instantiation - Optional address-affecting parameters (salt, deployer / universalDeploy, publicKeys).
82
+ * Salt defaults to a random value; the deployer is locked lazily from the first send-time \`from\`.
65
83
  */
66
- public static deploy(wallet: Wallet, ${args}) {
67
- return new DeployMethod<${contractName}>(PublicKeys.default(), wallet, ${artifactName}, ${contractName}.at, Array.from(arguments).slice(1));
68
- }
69
-
70
- /**
71
- * Creates a tx to deploy a new instance of this contract using the specified public keys hash to derive the address.
72
- */
73
- public static deployWithPublicKeys(publicKeys: PublicKeys, wallet: Wallet, ${args}) {
74
- return new DeployMethod<${contractName}>(publicKeys, wallet, ${artifactName}, ${contractName}.at, Array.from(arguments).slice(2));
84
+ public static deploy(wallet: Wallet, ${args ? `${args}, ` : ''}instantiation?: DeployInstantiationOptions) {
85
+ return DeployMethod.create<${contractName}>(
86
+ wallet,
87
+ {
88
+ artifact: ${artifactName},
89
+ postDeployCtor: (instance, wallet) => ${contractName}.at(instance.address, wallet),
90
+ args: ${argsForwarding},
91
+ },
92
+ instantiation,
93
+ );
75
94
  }
76
95
 
77
96
  /**
78
97
  * Creates a tx to deploy a new instance of this contract using the specified constructor method.
79
98
  */
80
99
  public static deployWithOpts<M extends keyof ${contractName}['methods']>(
81
- opts: { publicKeys?: PublicKeys; method?: M; wallet: Wallet },
100
+ opts: { method?: M; wallet: Wallet; instantiation?: DeployInstantiationOptions },
82
101
  ...args: Parameters<${contractName}['methods'][M]>
83
102
  ) {
84
- return new DeployMethod<${contractName}>(
85
- opts.publicKeys ?? PublicKeys.default(),
103
+ return DeployMethod.create<${contractName}>(
86
104
  opts.wallet,
87
- ${artifactName},
88
- ${contractName}.at,
89
- Array.from(arguments).slice(1),
90
- opts.method ?? 'constructor',
105
+ {
106
+ artifact: ${artifactName},
107
+ postDeployCtor: (instance, wallet) => ${contractName}.at(instance.address, wallet),
108
+ args,
109
+ constructorNameOrArtifact: opts.method ?? 'constructor',
110
+ },
111
+ opts.instantiation,
91
112
  );
92
113
  }
93
114
  `;
@@ -96,14 +117,14 @@ import { EventSelector, decodeFunctionSignature, getDefaultInitializer, isAztecA
96
117
  * Generates the constructor by supplying the ABI to the parent class so the user doesn't have to.
97
118
  * @param name - Name of the contract to derive the ABI name from.
98
119
  * @returns A constructor method.
99
- * @remarks The constructor is private because we want to force the user to use the create method.
120
+ * @remarks The constructor is private because we want to force the user to use the at method.
100
121
  */ function generateConstructor(name) {
101
122
  return `
102
123
  private constructor(
103
- instance: ContractInstanceWithAddress,
124
+ address: AztecAddress,
104
125
  wallet: Wallet,
105
126
  ) {
106
- super(instance, ${name}ContractArtifact, wallet);
127
+ super(address, ${name}ContractArtifact, wallet);
107
128
  }
108
129
  `;
109
130
  }
@@ -111,26 +132,25 @@ import { EventSelector, decodeFunctionSignature, getDefaultInitializer, isAztecA
111
132
  * Generates the at method for this contract.
112
133
  * @param name - Name of the contract to derive the ABI name from.
113
134
  * @returns An at method.
114
- * @remarks We don't use constructor directly because of the async `wallet.getContractData` call.
115
135
  */ function generateAt(name) {
116
136
  return `
117
137
  /**
118
138
  * Creates a contract instance.
119
139
  * @param address - The deployed contract's address.
120
140
  * @param wallet - The wallet to use when interacting with the contract.
121
- * @returns A promise that resolves to a new Contract instance.
141
+ * @returns A new Contract instance.
122
142
  */
123
- public static async at(
143
+ public static at(
124
144
  address: AztecAddress,
125
145
  wallet: Wallet,
126
- ) {
127
- return Contract.at(address, ${name}Contract.artifact, wallet) as Promise<${name}Contract>;
146
+ ): ${name}Contract {
147
+ return Contract.at(address, ${name}Contract.artifact, wallet) as ${name}Contract;
128
148
  }`;
129
149
  }
130
150
  /**
131
- * Generates a static getter for the contract's artifact.
151
+ * Generates static getters for the contract's artifact.
132
152
  * @param name - Name of the contract used to derive name of the artifact import.
133
- */ function generateArtifactGetter(name) {
153
+ */ function generateArtifactGetters(name) {
134
154
  const artifactName = `${name}ContractArtifact`;
135
155
  return `
136
156
  /**
@@ -139,6 +159,13 @@ import { EventSelector, decodeFunctionSignature, getDefaultInitializer, isAztecA
139
159
  public static get artifact(): ContractArtifact {
140
160
  return ${artifactName};
141
161
  }
162
+
163
+ /**
164
+ * Returns this contract's artifact with public bytecode.
165
+ */
166
+ public static get artifactForPublic(): ContractArtifact {
167
+ return loadContractArtifactForPublic(${artifactName}Json as NoirCompiledContract);
168
+ }
142
169
  `;
143
170
  }
144
171
  /**
@@ -148,7 +175,7 @@ import { EventSelector, decodeFunctionSignature, getDefaultInitializer, isAztecA
148
175
  * @returns Code.
149
176
  */ function generateAbiStatement(name, artifactImportPath) {
150
177
  const stmts = [
151
- `import ${name}ContractArtifactJson from '${artifactImportPath}' assert { type: 'json' };`,
178
+ `import ${name}ContractArtifactJson from '${artifactImportPath}' with { type: 'json' };`,
152
179
  `export const ${name}ContractArtifact = loadContractArtifact(${name}ContractArtifactJson as NoirCompiledContract);`
153
180
  ];
154
181
  return stmts.join('\n');
@@ -172,25 +199,6 @@ import { EventSelector, decodeFunctionSignature, getDefaultInitializer, isAztecA
172
199
  }
173
200
  `;
174
201
  }
175
- /**
176
- * Generates a getter for the contract notes
177
- * @param input - The contract artifact.
178
- */ function generateNotesGetter(input) {
179
- const entries = Object.entries(input.notes);
180
- if (entries.length === 0) {
181
- return '';
182
- }
183
- const notesUnionType = entries.map(([name])=>`'${name}'`).join(' | ');
184
- const noteMetadata = entries.map(([name, { id }])=>`${name}: {
185
- id: new NoteSelector(${id.value}),
186
- }`).join(',\n');
187
- return `public static get notes(): ContractNotes<${notesUnionType}> {
188
- return {
189
- ${noteMetadata}
190
- } as ContractNotes<${notesUnionType}>;
191
- }
192
- `;
193
- }
194
202
  // events is of type AbiType
195
203
  async function generateEvents(events) {
196
204
  if (events === undefined) {
@@ -240,51 +248,25 @@ async function generateEvents(events) {
240
248
  * @param artifactImportPath - Optional path to import the artifact (if not set, will be required in the constructor).
241
249
  * @returns The corresponding ts code.
242
250
  */ export async function generateTypescriptContractInterface(input, artifactImportPath) {
243
- const methods = input.functions.filter((f)=>!f.isInternal).sort((a, b)=>a.name.localeCompare(b.name)).map(generateMethod);
251
+ const methods = getAllFunctionAbis(input).filter((f)=>!f.isOnlySelf).sort((a, b)=>a.name.localeCompare(b.name)).map(generateMethod);
244
252
  const deploy = artifactImportPath && generateDeploy(input);
245
253
  const ctor = artifactImportPath && generateConstructor(input.name);
246
254
  const at = artifactImportPath && generateAt(input.name);
247
255
  const artifactStatement = artifactImportPath && generateAbiStatement(input.name, artifactImportPath);
248
- const artifactGetter = artifactImportPath && generateArtifactGetter(input.name);
256
+ const artifactGetter = artifactImportPath && generateArtifactGetters(input.name);
249
257
  const storageLayoutGetter = artifactImportPath && generateStorageLayoutGetter(input);
250
- const notesGetter = artifactImportPath && generateNotesGetter(input);
251
258
  const { eventDefs, events } = await generateEvents(input.outputs.structs?.events);
252
259
  return `
253
260
  /* Autogenerated file, do not edit! */
254
261
 
255
262
  /* eslint-disable */
256
- import {
257
- type AbiType,
258
- AztecAddress,
259
- type AztecAddressLike,
260
- CompleteAddress,
261
- Contract,
262
- type ContractArtifact,
263
- ContractBase,
264
- ContractFunctionInteraction,
265
- type ContractInstanceWithAddress,
266
- type ContractMethod,
267
- type ContractStorageLayout,
268
- type ContractNotes,
269
- decodeFromAbi,
270
- DeployMethod,
271
- EthAddress,
272
- type EthAddressLike,
273
- EventSelector,
274
- type FieldLike,
275
- Fr,
276
- type FunctionSelectorLike,
277
- L1EventPayload,
278
- loadContractArtifact,
279
- type NoirCompiledContract,
280
- NoteSelector,
281
- Point,
282
- type PublicKey,
283
- PublicKeys,
284
- type Wallet,
285
- type U128Like,
286
- type WrappedFieldLike,
287
- } from '@aztec/aztec.js';
263
+ import { AztecAddress, CompleteAddress } from '@aztec/aztec.js/addresses';
264
+ import { type AbiType, type AztecAddressLike, type ContractArtifact, EventSelector, decodeFromAbi, type EthAddressLike, type FieldLike, type FunctionSelectorLike, loadContractArtifact, loadContractArtifactForPublic, type NoirCompiledContract, type OptionLike, type U128Like, type WrappedFieldLike } from '@aztec/aztec.js/abi';
265
+ import { Contract, ContractBase, ContractFunctionInteraction, type ContractMethod, type ContractStorageLayout, type DeployInstantiationOptions, DeployMethod } from '@aztec/aztec.js/contracts';
266
+ import { EthAddress } from '@aztec/aztec.js/addresses';
267
+ import { Fr, Point } from '@aztec/aztec.js/fields';
268
+ import { type PublicKey, PublicKeys } from '@aztec/aztec.js/keys';
269
+ import type { Wallet } from '@aztec/aztec.js/wallet';
288
270
  ${artifactStatement}
289
271
 
290
272
  ${eventDefs}
@@ -303,8 +285,6 @@ export class ${input.name}Contract extends ContractBase {
303
285
 
304
286
  ${storageLayoutGetter}
305
287
 
306
- ${notesGetter}
307
-
308
288
  /** Type-safe wrappers for the public methods exposed by the contract. */
309
289
  public declare methods: {
310
290
  ${methods.join('\n')}
package/dest/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import type { Command } from 'commander';
2
2
  export declare function injectCommands(program: Command): Command;
3
- //# sourceMappingURL=index.d.ts.map
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFHekMsd0JBQWdCLGNBQWMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxXQVk5QyJ9
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@aztec/builder",
3
- "version": "0.0.0-test.1",
3
+ "version": "0.0.1-commit.017a351",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
7
- "./cli": "./dest/bin/cli.js"
7
+ "./cli": "./dest/bin/cli.js",
8
+ "./codegen": "./dest/contract-interface-gen/index.js"
8
9
  },
9
10
  "typedocOptions": {
10
11
  "entryPoints": [
@@ -13,16 +14,11 @@
13
14
  "name": "Aztec builder",
14
15
  "tsconfig": "./tsconfig.json"
15
16
  },
16
- "bin": {
17
- "aztec-builder": "dest/bin/cli.js"
18
- },
19
17
  "scripts": {
20
- "build": "yarn clean && tsc -b",
21
- "build:dev": "tsc -b --watch",
22
- "generate": "tsc -b",
18
+ "build": "yarn clean && ../scripts/tsc.sh",
19
+ "build:dev": "../scripts/tsc.sh --watch",
20
+ "generate": "../scripts/tsc.sh",
23
21
  "clean": "rm -rf ./dest .tsbuildinfo",
24
- "formatting": "run -T prettier --check ./src && run -T eslint ./src",
25
- "formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src",
26
22
  "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
27
23
  },
28
24
  "inherits": [
@@ -64,20 +60,25 @@
64
60
  "testTimeout": 120000,
65
61
  "setupFiles": [
66
62
  "../../foundation/src/jest/setup.mjs"
63
+ ],
64
+ "testEnvironment": "../../foundation/src/jest/env.mjs",
65
+ "setupFilesAfterEnv": [
66
+ "../../foundation/src/jest/setupAfterEnv.mjs"
67
67
  ]
68
68
  },
69
69
  "dependencies": {
70
- "@aztec/foundation": "0.0.0-test.1",
71
- "@aztec/stdlib": "0.0.0-test.1",
70
+ "@aztec/foundation": "0.0.1-commit.017a351",
71
+ "@aztec/stdlib": "0.0.1-commit.017a351",
72
72
  "commander": "^12.1.0"
73
73
  },
74
74
  "devDependencies": {
75
- "@jest/globals": "^29.5.0",
76
- "@types/jest": "^29.5.0",
77
- "@types/node": "^18.7.23",
78
- "jest": "^29.5.0",
75
+ "@jest/globals": "^30.0.0",
76
+ "@types/jest": "^30.0.0",
77
+ "@types/node": "^22.15.17",
78
+ "@typescript/native-preview": "7.0.0-dev.20260113.1",
79
+ "jest": "^30.0.0",
79
80
  "ts-node": "^10.9.1",
80
- "typescript": "^5.0.4"
81
+ "typescript": "^5.3.3"
81
82
  },
82
83
  "files": [
83
84
  "dest",
@@ -86,6 +87,6 @@
86
87
  ],
87
88
  "types": "./dest/index.d.ts",
88
89
  "engines": {
89
- "node": ">=18"
90
+ "node": ">=20.10"
90
91
  }
91
92
  }
@@ -50,6 +50,12 @@ async function generateFromNoirAbi(outputPath: string, noirAbiPath: string, opts
50
50
 
51
51
  const file = await readFile(noirAbiPath, 'utf8');
52
52
  const contract = JSON.parse(file);
53
+
54
+ if (!Array.isArray(contract.functions)) {
55
+ console.log(`${fileName} is not a contract artifact. Skipping.`);
56
+ return;
57
+ }
58
+
53
59
  const aztecAbi = loadContractArtifact(contract);
54
60
 
55
61
  await mkdir(outputPath, { recursive: true });
@@ -0,0 +1 @@
1
+ export { generateTypescriptContractInterface } from './typescript.js';
@@ -3,12 +3,16 @@ import {
3
3
  type ABIVariable,
4
4
  type ContractArtifact,
5
5
  EventSelector,
6
- type FunctionArtifact,
6
+ type FunctionAbi,
7
7
  decodeFunctionSignature,
8
+ getAllFunctionAbis,
8
9
  getDefaultInitializer,
9
10
  isAztecAddressStruct,
11
+ isBoundedVecStruct,
10
12
  isEthAddressStruct,
11
13
  isFunctionSelectorStruct,
14
+ isOptionStruct,
15
+ isPublicKeysStruct,
12
16
  isWrappedFieldStruct,
13
17
  } from '@aztec/stdlib/abi';
14
18
 
@@ -42,9 +46,22 @@ function abiTypeToTypescript(type: ABIParameter['type']): string {
42
46
  if (isWrappedFieldStruct(type)) {
43
47
  return 'WrappedFieldLike';
44
48
  }
49
+ if (isPublicKeysStruct(type)) {
50
+ // PublicKeys are special cased due to them being part of the preimage of contract addresses.
51
+ // The proper type is expected by the TS code that deals with the ContractInstanceRegistry protocol contract.
52
+ return 'PublicKeys';
53
+ }
54
+ if (isBoundedVecStruct(type)) {
55
+ // To make BoundedVec easier to work with, we expect a simple array on the input and then we encode it
56
+ // as a BoundedVec in the ArgumentsEncoder.
57
+ return `${abiTypeToTypescript(type.fields[0].type)}`;
58
+ }
59
+ if (isOptionStruct(type)) {
60
+ return `OptionLike<${abiTypeToTypescript(type.fields[1].type)}>`;
61
+ }
45
62
  return `{ ${type.fields.map(f => `${f.name}: ${abiTypeToTypescript(f.type)}`).join(', ')} }`;
46
63
  default:
47
- throw new Error(`Unknown type ${type}`);
64
+ throw new Error(`Unknown type ${type.kind}`);
48
65
  }
49
66
  }
50
67
 
@@ -62,7 +79,7 @@ function generateParameter(param: ABIParameter) {
62
79
  * @param param - A Noir function.
63
80
  * @returns The corresponding ts code.
64
81
  */
65
- function generateMethod(entry: FunctionArtifact) {
82
+ function generateMethod(entry: FunctionAbi) {
66
83
  const args = entry.parameters.map(generateParameter).join(', ');
67
84
  return `
68
85
  /** ${entry.name}(${entry.parameters.map(p => `${p.name}: ${p.type.kind}`).join(', ')}) */
@@ -76,39 +93,47 @@ function generateMethod(entry: FunctionArtifact) {
76
93
  */
77
94
  function generateDeploy(input: ContractArtifact) {
78
95
  const ctor = getDefaultInitializer(input);
79
- const args = (ctor?.parameters ?? []).map(generateParameter).join(', ');
96
+ const ctorParams = ctor?.parameters ?? [];
97
+ const args = ctorParams.map(generateParameter).join(', ');
98
+ const argNames = ctorParams.map(p => p.name).join(', ');
99
+ const argsForwarding = argNames ? `[${argNames}]` : '[]';
80
100
  const contractName = `${input.name}Contract`;
81
101
  const artifactName = `${contractName}Artifact`;
82
102
 
83
103
  return `
84
104
  /**
85
105
  * Creates a tx to deploy a new instance of this contract.
106
+ * @param instantiation - Optional address-affecting parameters (salt, deployer / universalDeploy, publicKeys).
107
+ * Salt defaults to a random value; the deployer is locked lazily from the first send-time \`from\`.
86
108
  */
87
- public static deploy(wallet: Wallet, ${args}) {
88
- return new DeployMethod<${contractName}>(PublicKeys.default(), wallet, ${artifactName}, ${contractName}.at, Array.from(arguments).slice(1));
89
- }
90
-
91
- /**
92
- * Creates a tx to deploy a new instance of this contract using the specified public keys hash to derive the address.
93
- */
94
- public static deployWithPublicKeys(publicKeys: PublicKeys, wallet: Wallet, ${args}) {
95
- return new DeployMethod<${contractName}>(publicKeys, wallet, ${artifactName}, ${contractName}.at, Array.from(arguments).slice(2));
109
+ public static deploy(wallet: Wallet, ${args ? `${args}, ` : ''}instantiation?: DeployInstantiationOptions) {
110
+ return DeployMethod.create<${contractName}>(
111
+ wallet,
112
+ {
113
+ artifact: ${artifactName},
114
+ postDeployCtor: (instance, wallet) => ${contractName}.at(instance.address, wallet),
115
+ args: ${argsForwarding},
116
+ },
117
+ instantiation,
118
+ );
96
119
  }
97
120
 
98
121
  /**
99
122
  * Creates a tx to deploy a new instance of this contract using the specified constructor method.
100
123
  */
101
124
  public static deployWithOpts<M extends keyof ${contractName}['methods']>(
102
- opts: { publicKeys?: PublicKeys; method?: M; wallet: Wallet },
125
+ opts: { method?: M; wallet: Wallet; instantiation?: DeployInstantiationOptions },
103
126
  ...args: Parameters<${contractName}['methods'][M]>
104
127
  ) {
105
- return new DeployMethod<${contractName}>(
106
- opts.publicKeys ?? PublicKeys.default(),
128
+ return DeployMethod.create<${contractName}>(
107
129
  opts.wallet,
108
- ${artifactName},
109
- ${contractName}.at,
110
- Array.from(arguments).slice(1),
111
- opts.method ?? 'constructor',
130
+ {
131
+ artifact: ${artifactName},
132
+ postDeployCtor: (instance, wallet) => ${contractName}.at(instance.address, wallet),
133
+ args,
134
+ constructorNameOrArtifact: opts.method ?? 'constructor',
135
+ },
136
+ opts.instantiation,
112
137
  );
113
138
  }
114
139
  `;
@@ -118,15 +143,15 @@ function generateDeploy(input: ContractArtifact) {
118
143
  * Generates the constructor by supplying the ABI to the parent class so the user doesn't have to.
119
144
  * @param name - Name of the contract to derive the ABI name from.
120
145
  * @returns A constructor method.
121
- * @remarks The constructor is private because we want to force the user to use the create method.
146
+ * @remarks The constructor is private because we want to force the user to use the at method.
122
147
  */
123
148
  function generateConstructor(name: string) {
124
149
  return `
125
150
  private constructor(
126
- instance: ContractInstanceWithAddress,
151
+ address: AztecAddress,
127
152
  wallet: Wallet,
128
153
  ) {
129
- super(instance, ${name}ContractArtifact, wallet);
154
+ super(address, ${name}ContractArtifact, wallet);
130
155
  }
131
156
  `;
132
157
  }
@@ -135,7 +160,6 @@ function generateConstructor(name: string) {
135
160
  * Generates the at method for this contract.
136
161
  * @param name - Name of the contract to derive the ABI name from.
137
162
  * @returns An at method.
138
- * @remarks We don't use constructor directly because of the async `wallet.getContractData` call.
139
163
  */
140
164
  function generateAt(name: string) {
141
165
  return `
@@ -143,21 +167,21 @@ function generateAt(name: string) {
143
167
  * Creates a contract instance.
144
168
  * @param address - The deployed contract's address.
145
169
  * @param wallet - The wallet to use when interacting with the contract.
146
- * @returns A promise that resolves to a new Contract instance.
170
+ * @returns A new Contract instance.
147
171
  */
148
- public static async at(
172
+ public static at(
149
173
  address: AztecAddress,
150
174
  wallet: Wallet,
151
- ) {
152
- return Contract.at(address, ${name}Contract.artifact, wallet) as Promise<${name}Contract>;
175
+ ): ${name}Contract {
176
+ return Contract.at(address, ${name}Contract.artifact, wallet) as ${name}Contract;
153
177
  }`;
154
178
  }
155
179
 
156
180
  /**
157
- * Generates a static getter for the contract's artifact.
181
+ * Generates static getters for the contract's artifact.
158
182
  * @param name - Name of the contract used to derive name of the artifact import.
159
183
  */
160
- function generateArtifactGetter(name: string) {
184
+ function generateArtifactGetters(name: string) {
161
185
  const artifactName = `${name}ContractArtifact`;
162
186
  return `
163
187
  /**
@@ -166,6 +190,13 @@ function generateArtifactGetter(name: string) {
166
190
  public static get artifact(): ContractArtifact {
167
191
  return ${artifactName};
168
192
  }
193
+
194
+ /**
195
+ * Returns this contract's artifact with public bytecode.
196
+ */
197
+ public static get artifactForPublic(): ContractArtifact {
198
+ return loadContractArtifactForPublic(${artifactName}Json as NoirCompiledContract);
199
+ }
169
200
  `;
170
201
  }
171
202
 
@@ -177,7 +208,7 @@ function generateArtifactGetter(name: string) {
177
208
  */
178
209
  function generateAbiStatement(name: string, artifactImportPath: string) {
179
210
  const stmts = [
180
- `import ${name}ContractArtifactJson from '${artifactImportPath}' assert { type: 'json' };`,
211
+ `import ${name}ContractArtifactJson from '${artifactImportPath}' with { type: 'json' };`,
181
212
  `export const ${name}ContractArtifact = loadContractArtifact(${name}ContractArtifactJson as NoirCompiledContract);`,
182
213
  ];
183
214
  return stmts.join('\n');
@@ -212,35 +243,6 @@ function generateStorageLayoutGetter(input: ContractArtifact) {
212
243
  `;
213
244
  }
214
245
 
215
- /**
216
- * Generates a getter for the contract notes
217
- * @param input - The contract artifact.
218
- */
219
- function generateNotesGetter(input: ContractArtifact) {
220
- const entries = Object.entries(input.notes);
221
-
222
- if (entries.length === 0) {
223
- return '';
224
- }
225
-
226
- const notesUnionType = entries.map(([name]) => `'${name}'`).join(' | ');
227
- const noteMetadata = entries
228
- .map(
229
- ([name, { id }]) =>
230
- `${name}: {
231
- id: new NoteSelector(${id.value}),
232
- }`,
233
- )
234
- .join(',\n');
235
-
236
- return `public static get notes(): ContractNotes<${notesUnionType}> {
237
- return {
238
- ${noteMetadata}
239
- } as ContractNotes<${notesUnionType}>;
240
- }
241
- `;
242
- }
243
-
244
246
  // events is of type AbiType
245
247
  async function generateEvents(events: any[] | undefined) {
246
248
  if (events === undefined) {
@@ -298,55 +300,29 @@ async function generateEvents(events: any[] | undefined) {
298
300
  * @returns The corresponding ts code.
299
301
  */
300
302
  export async function generateTypescriptContractInterface(input: ContractArtifact, artifactImportPath?: string) {
301
- const methods = input.functions
302
- .filter(f => !f.isInternal)
303
+ const methods = getAllFunctionAbis(input)
304
+ .filter(f => !f.isOnlySelf)
303
305
  .sort((a, b) => a.name.localeCompare(b.name))
304
306
  .map(generateMethod);
305
307
  const deploy = artifactImportPath && generateDeploy(input);
306
308
  const ctor = artifactImportPath && generateConstructor(input.name);
307
309
  const at = artifactImportPath && generateAt(input.name);
308
310
  const artifactStatement = artifactImportPath && generateAbiStatement(input.name, artifactImportPath);
309
- const artifactGetter = artifactImportPath && generateArtifactGetter(input.name);
311
+ const artifactGetter = artifactImportPath && generateArtifactGetters(input.name);
310
312
  const storageLayoutGetter = artifactImportPath && generateStorageLayoutGetter(input);
311
- const notesGetter = artifactImportPath && generateNotesGetter(input);
312
313
  const { eventDefs, events } = await generateEvents(input.outputs.structs?.events);
313
314
 
314
315
  return `
315
316
  /* Autogenerated file, do not edit! */
316
317
 
317
318
  /* eslint-disable */
318
- import {
319
- type AbiType,
320
- AztecAddress,
321
- type AztecAddressLike,
322
- CompleteAddress,
323
- Contract,
324
- type ContractArtifact,
325
- ContractBase,
326
- ContractFunctionInteraction,
327
- type ContractInstanceWithAddress,
328
- type ContractMethod,
329
- type ContractStorageLayout,
330
- type ContractNotes,
331
- decodeFromAbi,
332
- DeployMethod,
333
- EthAddress,
334
- type EthAddressLike,
335
- EventSelector,
336
- type FieldLike,
337
- Fr,
338
- type FunctionSelectorLike,
339
- L1EventPayload,
340
- loadContractArtifact,
341
- type NoirCompiledContract,
342
- NoteSelector,
343
- Point,
344
- type PublicKey,
345
- PublicKeys,
346
- type Wallet,
347
- type U128Like,
348
- type WrappedFieldLike,
349
- } from '@aztec/aztec.js';
319
+ import { AztecAddress, CompleteAddress } from '@aztec/aztec.js/addresses';
320
+ import { type AbiType, type AztecAddressLike, type ContractArtifact, EventSelector, decodeFromAbi, type EthAddressLike, type FieldLike, type FunctionSelectorLike, loadContractArtifact, loadContractArtifactForPublic, type NoirCompiledContract, type OptionLike, type U128Like, type WrappedFieldLike } from '@aztec/aztec.js/abi';
321
+ import { Contract, ContractBase, ContractFunctionInteraction, type ContractMethod, type ContractStorageLayout, type DeployInstantiationOptions, DeployMethod } from '@aztec/aztec.js/contracts';
322
+ import { EthAddress } from '@aztec/aztec.js/addresses';
323
+ import { Fr, Point } from '@aztec/aztec.js/fields';
324
+ import { type PublicKey, PublicKeys } from '@aztec/aztec.js/keys';
325
+ import type { Wallet } from '@aztec/aztec.js/wallet';
350
326
  ${artifactStatement}
351
327
 
352
328
  ${eventDefs}
@@ -365,8 +341,6 @@ export class ${input.name}Contract extends ContractBase {
365
341
 
366
342
  ${storageLayoutGetter}
367
343
 
368
- ${notesGetter}
369
-
370
344
  /** Type-safe wrappers for the public methods exposed by the contract. */
371
345
  public declare methods: {
372
346
  ${methods.join('\n')}