@aztec/noir-protocol-circuits-types 0.24.0

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 (77) hide show
  1. package/README.md +1 -0
  2. package/dest/index.d.ts +69 -0
  3. package/dest/index.d.ts.map +1 -0
  4. package/dest/index.js +268 -0
  5. package/dest/scripts/generate_ts_from_abi.d.ts +2 -0
  6. package/dest/scripts/generate_ts_from_abi.d.ts.map +1 -0
  7. package/dest/scripts/generate_ts_from_abi.js +180 -0
  8. package/dest/target/private_kernel_init.json +1 -0
  9. package/dest/target/private_kernel_init_simulated.json +1 -0
  10. package/dest/target/private_kernel_inner.json +1 -0
  11. package/dest/target/private_kernel_inner_simulated.json +1 -0
  12. package/dest/target/private_kernel_tail.json +1 -0
  13. package/dest/target/private_kernel_tail_simulated.json +1 -0
  14. package/dest/target/public_kernel_app_logic.json +1 -0
  15. package/dest/target/public_kernel_app_logic_simulated.json +1 -0
  16. package/dest/target/public_kernel_setup.json +1 -0
  17. package/dest/target/public_kernel_setup_simulated.json +1 -0
  18. package/dest/target/rollup_base.json +1 -0
  19. package/dest/target/rollup_base_simulated.json +1 -0
  20. package/dest/target/rollup_merge.json +1 -0
  21. package/dest/target/rollup_root.json +1 -0
  22. package/dest/type_conversion.d.ts +574 -0
  23. package/dest/type_conversion.d.ts.map +1 -0
  24. package/dest/type_conversion.js +1115 -0
  25. package/dest/types/private_kernel_init_types.d.ts +232 -0
  26. package/dest/types/private_kernel_init_types.d.ts.map +1 -0
  27. package/dest/types/private_kernel_init_types.js +3 -0
  28. package/dest/types/private_kernel_inner_types.d.ts +233 -0
  29. package/dest/types/private_kernel_inner_types.d.ts.map +1 -0
  30. package/dest/types/private_kernel_inner_types.js +3 -0
  31. package/dest/types/private_kernel_tail_types.d.ts +182 -0
  32. package/dest/types/private_kernel_tail_types.d.ts.map +1 -0
  33. package/dest/types/private_kernel_tail_types.js +3 -0
  34. package/dest/types/public_kernel_app_logic_types.d.ts +212 -0
  35. package/dest/types/public_kernel_app_logic_types.d.ts.map +1 -0
  36. package/dest/types/public_kernel_app_logic_types.js +3 -0
  37. package/dest/types/public_kernel_setup_types.d.ts +212 -0
  38. package/dest/types/public_kernel_setup_types.d.ts.map +1 -0
  39. package/dest/types/public_kernel_setup_types.js +3 -0
  40. package/dest/types/rollup_base_types.d.ts +220 -0
  41. package/dest/types/rollup_base_types.d.ts.map +1 -0
  42. package/dest/types/rollup_base_types.js +3 -0
  43. package/dest/types/rollup_merge_types.d.ts +71 -0
  44. package/dest/types/rollup_merge_types.d.ts.map +1 -0
  45. package/dest/types/rollup_merge_types.js +3 -0
  46. package/dest/types/rollup_root_types.d.ts +92 -0
  47. package/dest/types/rollup_root_types.d.ts.map +1 -0
  48. package/dest/types/rollup_root_types.js +3 -0
  49. package/package.json +60 -0
  50. package/src/fixtures/nested-call-private-kernel-init.hex +1 -0
  51. package/src/fixtures/nested-call-private-kernel-inner.hex +1 -0
  52. package/src/fixtures/nested-call-private-kernel-ordering.hex +1 -0
  53. package/src/index.ts +438 -0
  54. package/src/scripts/generate_ts_from_abi.ts +233 -0
  55. package/src/target/private_kernel_init.json +1 -0
  56. package/src/target/private_kernel_init_simulated.json +1 -0
  57. package/src/target/private_kernel_inner.json +1 -0
  58. package/src/target/private_kernel_inner_simulated.json +1 -0
  59. package/src/target/private_kernel_tail.json +1 -0
  60. package/src/target/private_kernel_tail_simulated.json +1 -0
  61. package/src/target/public_kernel_app_logic.json +1 -0
  62. package/src/target/public_kernel_app_logic_simulated.json +1 -0
  63. package/src/target/public_kernel_setup.json +1 -0
  64. package/src/target/public_kernel_setup_simulated.json +1 -0
  65. package/src/target/rollup_base.json +1 -0
  66. package/src/target/rollup_base_simulated.json +1 -0
  67. package/src/target/rollup_merge.json +1 -0
  68. package/src/target/rollup_root.json +1 -0
  69. package/src/type_conversion.ts +1673 -0
  70. package/src/types/private_kernel_init_types.ts +272 -0
  71. package/src/types/private_kernel_inner_types.ts +273 -0
  72. package/src/types/private_kernel_tail_types.ts +214 -0
  73. package/src/types/public_kernel_app_logic_types.ts +250 -0
  74. package/src/types/public_kernel_setup_types.ts +250 -0
  75. package/src/types/rollup_base_types.ts +259 -0
  76. package/src/types/rollup_merge_types.ts +85 -0
  77. package/src/types/rollup_root_types.ts +109 -0
@@ -0,0 +1,233 @@
1
+ import { ABIType } from '@aztec/foundation/abi';
2
+ import { createConsoleLogger } from '@aztec/foundation/log';
3
+ import { NoirCompiledCircuit, NoirFunctionAbi } from '@aztec/types/noir';
4
+
5
+ import fs from 'fs/promises';
6
+
7
+ const log = createConsoleLogger('aztec:noir-contracts');
8
+
9
+ /**
10
+ * Keep track off all of the Noir primitive types that were used.
11
+ * Most of these will not have a 1-1 definition in TypeScript,
12
+ * so we will need to generate type aliases for them.
13
+ *
14
+ * We want to generate type aliases
15
+ * for specific types that are used in the ABI.
16
+ *
17
+ * For example:
18
+ * - If `Field` is used we want to alias that
19
+ * with `number`.
20
+ * - If `u32` is used we want to alias that with `number` too.
21
+ */
22
+ type PrimitiveTypesUsed = {
23
+ /**
24
+ * The name of the type alias that we will generate.
25
+ */
26
+ aliasName: string;
27
+ /**
28
+ * The TypeScript type that we will alias to.
29
+ */
30
+ tsType: string;
31
+ };
32
+
33
+ const noirPrimitiveTypesToTsTypes = new Map<string, PrimitiveTypesUsed>();
34
+
35
+ /**
36
+ * Typescript does not allow us to check for equality of non-primitive types
37
+ * easily, so we create a addIfUnique function that will only add an item
38
+ * to the map if it is not already there by using JSON.stringify.
39
+ * @param item - The item to add to the map.
40
+ */
41
+ function addIfUnique(item: PrimitiveTypesUsed) {
42
+ const key = JSON.stringify(item);
43
+ if (!noirPrimitiveTypesToTsTypes.has(key)) {
44
+ noirPrimitiveTypesToTsTypes.set(key, item);
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Converts an ABI type to a TypeScript type.
50
+ * @param type - The ABI type to convert.
51
+ * @returns The typescript code to define the type.
52
+ */
53
+ function abiTypeToTs(type: ABIType): string {
54
+ switch (type.kind) {
55
+ case 'integer': {
56
+ let tsIntType = '';
57
+ if (type.sign === 'signed') {
58
+ tsIntType = `i${type.width}`;
59
+ } else {
60
+ tsIntType = `u${type.width}`;
61
+ }
62
+ addIfUnique({ aliasName: tsIntType, tsType: 'string' });
63
+ return tsIntType;
64
+ }
65
+ case 'boolean':
66
+ return `boolean`;
67
+ case 'array':
68
+ return `FixedLengthArray<${abiTypeToTs(type.type)}, ${type.length}>`;
69
+ case 'struct':
70
+ return getLastComponentOfPath(type.path);
71
+ case 'field':
72
+ addIfUnique({ aliasName: 'Field', tsType: 'string' });
73
+ return 'Field';
74
+ default:
75
+ throw new Error(`Unknown ABI type ${type}`);
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Returns the last component of a path, e.g. "foo::bar::baz" -\> "baz"
81
+ * Note: that if we have a path such as "Baz", we will return "Baz".
82
+ *
83
+ * Since these paths corresponds to structs, we can assume that we
84
+ * cannot have "foo::bar::".
85
+ *
86
+ * We also make the assumption that since these paths are coming from
87
+ * Noir, then we will not have two paths that look like this:
88
+ * - foo::bar::Baz
89
+ * - cat::dog::Baz
90
+ * ie the last component of the path (struct name) is enough to uniquely identify
91
+ * the whole path.
92
+ *
93
+ * TODO: We should double check this assumption when we use type aliases,
94
+ * I expect that `foo::bar::Baz as Dog` would effectively give `foo::bar::Dog`
95
+ * @param str - The path to get the last component of.
96
+ * @returns The last component of the path.
97
+ */
98
+ function getLastComponentOfPath(str: string): string {
99
+ const parts = str.split('::');
100
+ const lastPart = parts[parts.length - 1];
101
+ return lastPart;
102
+ }
103
+
104
+ /**
105
+ * Generates TypeScript interfaces for the structs used in the ABI.
106
+ * @param type - The ABI type to generate the interface for.
107
+ * @param output - The set of structs that we have already generated bindings for.
108
+ * @returns The TypeScript code to define the struct.
109
+ */
110
+ function generateStructInterfaces(type: ABIType, output: Set<string>): string {
111
+ let result = '';
112
+
113
+ // Edge case to handle the array of structs case.
114
+ if (
115
+ type.kind === 'array' &&
116
+ ((type.type.kind === 'struct' && !output.has(getLastComponentOfPath(type.type.path))) || type.type.kind === 'array')
117
+ ) {
118
+ result += generateStructInterfaces(type.type, output);
119
+ }
120
+
121
+ if (type.kind !== 'struct') {
122
+ return result;
123
+ }
124
+
125
+ // List of structs encountered while viewing this type that we need to generate
126
+ // bindings for.
127
+ const typesEncountered = new Set<ABIType>();
128
+
129
+ // Codegen the struct and then its fields, so that the structs fields
130
+ // are defined before the struct itself.
131
+ let codeGeneratedStruct = '';
132
+ let codeGeneratedStructFields = '';
133
+
134
+ const structName = getLastComponentOfPath(type.path);
135
+ if (!output.has(structName)) {
136
+ codeGeneratedStruct += `export interface ${structName} {\n`;
137
+ for (const field of type.fields) {
138
+ codeGeneratedStruct += ` ${field.name}: ${abiTypeToTs(field.type)};\n`;
139
+ typesEncountered.add(field.type);
140
+ }
141
+ codeGeneratedStruct += `}\n\n`;
142
+ output.add(structName);
143
+
144
+ // Generate code for the encountered structs in the field above
145
+ for (const type of typesEncountered) {
146
+ codeGeneratedStructFields += generateStructInterfaces(type, output);
147
+ }
148
+ }
149
+
150
+ return codeGeneratedStructFields + '\n' + codeGeneratedStruct;
151
+ }
152
+
153
+ /**
154
+ * Generates a TypeScript interface for the ABI.
155
+ * @param abiObj - The ABI to generate the interface for.
156
+ * @returns The TypeScript code to define the interface.
157
+ */
158
+ function generateTsInterface(abiObj: NoirFunctionAbi): string {
159
+ let result = ``;
160
+ const outputStructs = new Set<string>();
161
+
162
+ // Define structs for composite types
163
+ for (const param of abiObj.parameters) {
164
+ result += generateStructInterfaces(param.type, outputStructs);
165
+ }
166
+
167
+ // Generating Return type, if it exists
168
+ //
169
+ if (abiObj.return_type != null) {
170
+ result += generateStructInterfaces(abiObj.return_type.abi_type, outputStructs);
171
+ result += `export type ReturnType = ${abiTypeToTs(abiObj.return_type.abi_type)};\n`;
172
+ }
173
+
174
+ // Generating Input type
175
+ result += '\nexport interface InputType {\n';
176
+ for (const param of abiObj.parameters) {
177
+ result += ` ${param.name}: ${abiTypeToTs(param.type)};\n`;
178
+ }
179
+ result += '}';
180
+
181
+ // Add the primitive Noir types that do not have a 1-1 mapping to TypeScript.
182
+ let primitiveTypeAliases = '';
183
+ for (const [, value] of noirPrimitiveTypesToTsTypes) {
184
+ primitiveTypeAliases += `\nexport type ${value.aliasName} = ${value.tsType};`;
185
+ }
186
+
187
+ const fixedLengthArray =
188
+ '\nexport type FixedLengthArray<T, L extends number> = L extends 0 ? never[]: T[] & { length: L }';
189
+
190
+ return (
191
+ `/* Autogenerated file, do not edit! */\n\n/* eslint-disable */\n` +
192
+ fixedLengthArray +
193
+ '\n' +
194
+ primitiveTypeAliases +
195
+ '\n' +
196
+ result
197
+ );
198
+ }
199
+
200
+ const circuits = [
201
+ 'private_kernel_init',
202
+ 'private_kernel_inner',
203
+ 'private_kernel_tail',
204
+ 'public_kernel_setup',
205
+ 'public_kernel_app_logic',
206
+ 'rollup_base',
207
+ 'rollup_merge',
208
+ 'rollup_root',
209
+ ];
210
+
211
+ const main = async () => {
212
+ try {
213
+ await fs.access('./src/types/');
214
+ } catch (error) {
215
+ await fs.mkdir('./src/types', { recursive: true });
216
+ }
217
+
218
+ for (const circuit of circuits) {
219
+ const rawData = await fs.readFile(`./src/target/${circuit}.json`, 'utf-8');
220
+ const abiObj: NoirCompiledCircuit = JSON.parse(rawData);
221
+ const generatedInterface = generateTsInterface(abiObj.abi);
222
+
223
+ const outputFile = `./src/types/${circuit}_types.ts`;
224
+ await fs.writeFile(outputFile, generatedInterface);
225
+ }
226
+ };
227
+
228
+ try {
229
+ await main();
230
+ } catch (err: unknown) {
231
+ log(`Error generating types ${err}`);
232
+ process.exit(1);
233
+ }