@provablehq/veil-codegen 0.4.1 → 0.6.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.
- package/README.md +7 -4
- package/dist/{chunk-OU67QL3U.js → chunk-OQWGO46H.js} +134 -28
- package/dist/chunk-OQWGO46H.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-OU67QL3U.js.map +0 -1
package/README.md
CHANGED
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
Generates TypeScript bindings from an Aleo program's ABI, and ships the
|
|
4
4
|
`veil-codegen` CLI that drives it.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
It applies to package maintainers, not consumers: point it at a program's
|
|
7
7
|
`abi.json` and it emits a `.ts` module of struct and record interfaces, record
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
decoders (`RecordValue` → typed interface), struct decoders (`StructValue` →
|
|
9
|
+
typed interface), per-function input and output types, mapping key/value
|
|
10
|
+
types with value decoders (raw Aleo literal → typed value), storage types,
|
|
11
|
+
the parsed `PROGRAM_ABI` constant, and a typed contract factory
|
|
12
|
+
(`read`/`write`/`simulate`/`execute`) whose read methods encode the typed
|
|
13
|
+
key, decode the value, and resolve to `null` for an absent key. A package like
|
|
11
14
|
`@provablehq/shield-swap-sdk` commits that output and ships it — a consumer installing the
|
|
12
15
|
package gets the bindings already. You run codegen when the upstream contract
|
|
13
16
|
drifts (redeploy, a new or renamed entrypoint, struct, or mapping) and the
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
// src/generate.ts
|
|
2
2
|
function generate(options) {
|
|
3
3
|
const { abi, coreImport = "@provablehq/veil-core", programId = abi.program } = options;
|
|
4
|
+
currentProgram = abi.program;
|
|
4
5
|
const lines = [];
|
|
5
6
|
lines.push(`// Auto-generated by @provablehq/veil-codegen from ${abi.program}`);
|
|
6
7
|
lines.push(`// Do not edit manually.`);
|
|
7
8
|
lines.push("");
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
const coreValueImports = ["getContract"];
|
|
10
|
+
if (abi.mappings.some((m) => mappingKeyNeedsEncode(m.key))) coreValueImports.push("encodeValue");
|
|
11
|
+
if (abi.mappings.some((m) => mappingValueUsesParseValue(m.value))) coreValueImports.push("parseValue");
|
|
12
|
+
if (abi.mappings.some((m) => !mappingValueUsesParseValue(m.value))) coreValueImports.push("parsePlaintextValue");
|
|
13
|
+
lines.push(`import { ${coreValueImports.join(", ")} } from '${coreImport}'`);
|
|
14
|
+
lines.push(`import type { RecordValue, FutureValue, DynamicFutureValue, PublicClient, WalletClient, ABI, InputRequest, PlaintextValue, StructValue } from '${coreImport}'`);
|
|
10
15
|
lines.push("");
|
|
11
16
|
lines.push(`export const PROGRAM_ID = '${programId}' as const`);
|
|
12
17
|
lines.push("");
|
|
@@ -22,13 +27,13 @@ function generate(options) {
|
|
|
22
27
|
for (const struct of abi.structs) {
|
|
23
28
|
lines.push(...generateStructInterface(struct));
|
|
24
29
|
lines.push("");
|
|
25
|
-
lines.push(...
|
|
30
|
+
lines.push(...generateStructDecoder(struct));
|
|
26
31
|
lines.push("");
|
|
27
32
|
}
|
|
28
33
|
for (const record of abi.records) {
|
|
29
34
|
lines.push(...generateRecordInterface(record));
|
|
30
35
|
lines.push("");
|
|
31
|
-
lines.push(...
|
|
36
|
+
lines.push(...generateRecordDecoder(record));
|
|
32
37
|
lines.push("");
|
|
33
38
|
}
|
|
34
39
|
for (const fn of abi.functions) {
|
|
@@ -40,6 +45,8 @@ function generate(options) {
|
|
|
40
45
|
for (const mapping of abi.mappings) {
|
|
41
46
|
lines.push(...generateMappingType(mapping));
|
|
42
47
|
lines.push("");
|
|
48
|
+
lines.push(...generateMappingDecoder(mapping));
|
|
49
|
+
lines.push("");
|
|
43
50
|
}
|
|
44
51
|
for (const sv of abi.storageVariables) {
|
|
45
52
|
lines.push(...generateStorageVariableType(sv));
|
|
@@ -76,20 +83,23 @@ function generateRecordInterface(record) {
|
|
|
76
83
|
lines.push(`}`);
|
|
77
84
|
return lines;
|
|
78
85
|
}
|
|
79
|
-
function
|
|
86
|
+
function generateFieldConversions(fields, container, access) {
|
|
80
87
|
const lines = [];
|
|
81
88
|
for (const field of fields) {
|
|
82
|
-
|
|
89
|
+
const rawAccess = access(field.name);
|
|
83
90
|
if (field.type.kind === "struct") {
|
|
91
|
+
if (isExternalStructRef(field.type)) {
|
|
92
|
+
lines.push(` ${field.name}: ${rawAccess} as unknown as StructValue ?? {},`);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
84
95
|
const structName = field.type.path.at(-1);
|
|
85
96
|
if (!structName) {
|
|
86
97
|
throw new Error(
|
|
87
98
|
`Malformed ABI: struct field "${field.name}" in "${container}" has an empty type path. Cannot derive struct name for code generation.`
|
|
88
99
|
);
|
|
89
100
|
}
|
|
90
|
-
lines.push(` ${field.name}: ${
|
|
101
|
+
lines.push(` ${field.name}: ${rawAccess} as unknown as ${structName} ?? {} as unknown as ${structName},`);
|
|
91
102
|
} else {
|
|
92
|
-
const rawAccess = `${fieldsVar}.${field.name}?.value`;
|
|
93
103
|
const expr = plaintextFieldExpr(rawAccess, field.type);
|
|
94
104
|
lines.push(` ${field.name}: ${expr} ?? ${plaintextDefault(field.type)},`);
|
|
95
105
|
}
|
|
@@ -99,25 +109,29 @@ function mapperFieldLines(fields, container, fieldsVar) {
|
|
|
99
109
|
function fieldsGuardLine(varName) {
|
|
100
110
|
return ` const fields = (typeof ${varName} === 'object' && ${varName} !== null ? ${varName}.fields : undefined) ?? {}`;
|
|
101
111
|
}
|
|
102
|
-
function
|
|
112
|
+
function generateRecordDecoder(record) {
|
|
103
113
|
const name = recordName(record);
|
|
104
114
|
const lines = [];
|
|
105
115
|
lines.push(`export function to${name}(record: RecordValue | string): ${name} {`);
|
|
106
116
|
lines.push(fieldsGuardLine("record"));
|
|
107
117
|
lines.push(` return {`);
|
|
108
118
|
lines.push(` owner: ((typeof record === 'object' && record !== null ? record.owner : undefined) ?? '') as string,`);
|
|
109
|
-
lines.push(...
|
|
119
|
+
lines.push(...generateFieldConversions(
|
|
120
|
+
record.fields.filter((f) => f.name !== "owner"),
|
|
121
|
+
name,
|
|
122
|
+
(n) => `fields.${n}?.value`
|
|
123
|
+
));
|
|
110
124
|
lines.push(` _record: record as unknown as RecordValue,`);
|
|
111
125
|
lines.push(` }`);
|
|
112
126
|
lines.push(`}`);
|
|
113
127
|
return lines;
|
|
114
128
|
}
|
|
115
|
-
function
|
|
129
|
+
function generateStructDecoder(struct) {
|
|
116
130
|
const name = struct.path[struct.path.length - 1] ?? "UnknownStruct";
|
|
117
131
|
const lines = [];
|
|
118
|
-
lines.push(`export function to${name}(value:
|
|
132
|
+
lines.push(`export function to${name}(value: StructValue): ${name} {`);
|
|
119
133
|
lines.push(` return {`);
|
|
120
|
-
lines.push(...
|
|
134
|
+
lines.push(...generateFieldConversions(struct.fields, name, (n) => `value.${n}`));
|
|
121
135
|
lines.push(` }`);
|
|
122
136
|
lines.push(`}`);
|
|
123
137
|
return lines;
|
|
@@ -167,20 +181,76 @@ function outputToTsType(output, abi) {
|
|
|
167
181
|
return isLocal ? recName : "RecordValue";
|
|
168
182
|
} else if (output.kind === "dynamicRecord") {
|
|
169
183
|
return "RecordValue";
|
|
170
|
-
} else if (output.kind === "future"
|
|
184
|
+
} else if (output.kind === "future") {
|
|
171
185
|
return "FutureValue";
|
|
186
|
+
} else if (output.kind === "dynamicFuture") {
|
|
187
|
+
return "DynamicFutureValue";
|
|
172
188
|
}
|
|
173
189
|
return "unknown";
|
|
174
190
|
}
|
|
191
|
+
function mappingKeyTsType(key) {
|
|
192
|
+
if (key.kind !== "primitive") return "string";
|
|
193
|
+
return primitiveToTsType(key.primitive);
|
|
194
|
+
}
|
|
195
|
+
function mappingKeyNeedsEncode(key) {
|
|
196
|
+
return key.kind === "primitive" && (isIntPrimitive(key.primitive) || key.primitive === "boolean");
|
|
197
|
+
}
|
|
198
|
+
function mappingKeyEncodeExpr(expr, key) {
|
|
199
|
+
if (!mappingKeyNeedsEncode(key)) return expr;
|
|
200
|
+
return `encodeValue(${expr}, '${key.primitive}')`;
|
|
201
|
+
}
|
|
175
202
|
function generateMappingType(mapping) {
|
|
176
203
|
const name = pascalCase(mapping.name);
|
|
177
|
-
const keyType =
|
|
204
|
+
const keyType = mappingKeyTsType(mapping.key);
|
|
178
205
|
const valueType = plaintextToTsType(mapping.value);
|
|
179
206
|
return [
|
|
180
207
|
`export type ${name}MappingKey = ${keyType}`,
|
|
181
208
|
`export type ${name}MappingValue = ${valueType}`
|
|
182
209
|
];
|
|
183
210
|
}
|
|
211
|
+
function mappingValueUsesParseValue(value) {
|
|
212
|
+
if (value.kind !== "primitive") return false;
|
|
213
|
+
const p = value.primitive;
|
|
214
|
+
return isIntPrimitive(p) || p === "boolean" || p === "address" || p === "signature" || p === "field" || p === "group" || p === "scalar";
|
|
215
|
+
}
|
|
216
|
+
function generateMappingDecoder(mapping) {
|
|
217
|
+
const name = pascalCase(mapping.name);
|
|
218
|
+
const lines = [];
|
|
219
|
+
lines.push(`/** Decodes a raw \`${mapping.name}\` mapping value into a typed ${name}MappingValue. */`);
|
|
220
|
+
lines.push(`export function to${name}MappingValue(raw: string): ${name}MappingValue {`);
|
|
221
|
+
const throwLine = (expected) => ` throw new Error(\`${mapping.name} stores ${expected} values, got: \${raw}\`)`;
|
|
222
|
+
const typeGuard = (p) => [
|
|
223
|
+
` const parsed = parseValue(raw)`,
|
|
224
|
+
` if (parsed.type !== '${p}') {`,
|
|
225
|
+
throwLine(p),
|
|
226
|
+
` }`
|
|
227
|
+
];
|
|
228
|
+
if (mapping.value.kind === "struct") {
|
|
229
|
+
const structName = isExternalStructRef(mapping.value) ? null : mapping.value.path.at(-1);
|
|
230
|
+
lines.push(` const value = parsePlaintextValue(raw)`);
|
|
231
|
+
lines.push(` if (typeof value !== 'object' || Array.isArray(value)) {`);
|
|
232
|
+
lines.push(throwLine(structName ?? "struct"));
|
|
233
|
+
lines.push(` }`);
|
|
234
|
+
lines.push(` return ${structName ? `to${structName}(value)` : "value"}`);
|
|
235
|
+
} else if (mapping.value.kind === "primitive" && mappingValueUsesParseValue(mapping.value)) {
|
|
236
|
+
const p = mapping.value.primitive;
|
|
237
|
+
lines.push(...typeGuard(p));
|
|
238
|
+
if (isSmallInt(p)) {
|
|
239
|
+
lines.push(` return Number(parsed.value)`);
|
|
240
|
+
} else if (isIntPrimitive(p)) {
|
|
241
|
+
lines.push(` return parsed.value as bigint`);
|
|
242
|
+
} else if (p === "field" || p === "group" || p === "scalar") {
|
|
243
|
+
lines.push(` return raw`);
|
|
244
|
+
} else {
|
|
245
|
+
lines.push(` return parsed.value as ${primitiveToTsType(p)}`);
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
lines.push(` const value = parsePlaintextValue(raw)`);
|
|
249
|
+
lines.push(` return ${plaintextFieldExpr("value", mapping.value)}`);
|
|
250
|
+
}
|
|
251
|
+
lines.push(`}`);
|
|
252
|
+
return lines;
|
|
253
|
+
}
|
|
184
254
|
function generateStorageVariableType(sv) {
|
|
185
255
|
const name = pascalCase(sv.name);
|
|
186
256
|
const tsType = storageTypeToTs(sv.type);
|
|
@@ -197,6 +267,14 @@ function storageTypeToTs(st) {
|
|
|
197
267
|
function isSmallInt(p) {
|
|
198
268
|
return p === "u8" || p === "u16" || p === "u32" || p === "i8" || p === "i16" || p === "i32";
|
|
199
269
|
}
|
|
270
|
+
function isIntPrimitive(p) {
|
|
271
|
+
return isSmallInt(p) || p === "u64" || p === "u128" || p === "i64" || p === "i128";
|
|
272
|
+
}
|
|
273
|
+
var currentProgram = "";
|
|
274
|
+
function isExternalStructRef(pt) {
|
|
275
|
+
if (!pt.program) return false;
|
|
276
|
+
return pt.program.replace(/\.aleo$/, "") !== currentProgram.replace(/\.aleo$/, "");
|
|
277
|
+
}
|
|
200
278
|
function plaintextToTsType(pt) {
|
|
201
279
|
switch (pt.kind) {
|
|
202
280
|
case "primitive":
|
|
@@ -204,6 +282,7 @@ function plaintextToTsType(pt) {
|
|
|
204
282
|
case "array":
|
|
205
283
|
return `${plaintextToTsType(pt.element)}[]`;
|
|
206
284
|
case "struct":
|
|
285
|
+
if (isExternalStructRef(pt)) return "StructValue";
|
|
207
286
|
return pt.path[pt.path.length - 1] ?? "unknown";
|
|
208
287
|
case "optional":
|
|
209
288
|
return `${plaintextToTsType(pt.inner)} | undefined`;
|
|
@@ -234,6 +313,15 @@ function primitiveToTsType(p) {
|
|
|
234
313
|
}
|
|
235
314
|
}
|
|
236
315
|
function plaintextFieldExpr(rawAccess, pt) {
|
|
316
|
+
if (pt.kind === "array") {
|
|
317
|
+
const element = plaintextFieldExpr("el", pt.element);
|
|
318
|
+
if (element === "el") return `${rawAccess} as ${plaintextToTsType(pt)}`;
|
|
319
|
+
return `((${rawAccess} ?? []) as PlaintextValue[]).map((el) => ${element}) as ${plaintextToTsType(pt)}`;
|
|
320
|
+
}
|
|
321
|
+
if (pt.kind === "optional") {
|
|
322
|
+
const inner = plaintextFieldExpr(rawAccess, pt.inner);
|
|
323
|
+
return `(${rawAccess} === undefined ? undefined : ${inner})`;
|
|
324
|
+
}
|
|
237
325
|
if (pt.kind !== "primitive") return rawAccess;
|
|
238
326
|
const p = pt.primitive;
|
|
239
327
|
if (isSmallInt(p)) return `Number((${rawAccess} ?? 0n) as bigint)`;
|
|
@@ -262,6 +350,8 @@ function plaintextFieldExpr(rawAccess, pt) {
|
|
|
262
350
|
}
|
|
263
351
|
}
|
|
264
352
|
function plaintextDefault(pt) {
|
|
353
|
+
if (pt.kind === "array") return "[]";
|
|
354
|
+
if (pt.kind === "optional") return "undefined";
|
|
265
355
|
if (pt.kind !== "primitive") return "''";
|
|
266
356
|
if (isSmallInt(pt.primitive)) return "0";
|
|
267
357
|
switch (pt.primitive) {
|
|
@@ -337,7 +427,7 @@ function resolveRecordInputs(fn) {
|
|
|
337
427
|
}
|
|
338
428
|
return { resolveLines, resolvedNames };
|
|
339
429
|
}
|
|
340
|
-
function
|
|
430
|
+
function generateOutputDecodeExpr(output, i, abi) {
|
|
341
431
|
if (output.type.kind === "record") {
|
|
342
432
|
const recName = output.type.path[output.type.path.length - 1] ?? "";
|
|
343
433
|
const isLocal = !output.type.program || output.type.program.replace(/\.aleo$/, "") === abi.program.replace(/\.aleo$/, "");
|
|
@@ -349,9 +439,12 @@ function outputMapperExpr(output, i, abi) {
|
|
|
349
439
|
if (output.type.kind === "plaintext") {
|
|
350
440
|
return `result.outputs[${i}] as unknown as ${plaintextToTsType(output.type.type)}`;
|
|
351
441
|
}
|
|
352
|
-
if (output.type.kind === "future"
|
|
442
|
+
if (output.type.kind === "future") {
|
|
353
443
|
return `result.outputs[${i}] as unknown as FutureValue`;
|
|
354
444
|
}
|
|
445
|
+
if (output.type.kind === "dynamicFuture") {
|
|
446
|
+
return `result.outputs[${i}] as unknown as DynamicFutureValue`;
|
|
447
|
+
}
|
|
355
448
|
return `result.outputs[${i}]`;
|
|
356
449
|
}
|
|
357
450
|
function generateContractFactory(abi) {
|
|
@@ -364,12 +457,12 @@ function generateContractFactory(abi) {
|
|
|
364
457
|
if (abi.mappings.length > 0) {
|
|
365
458
|
lines.push(` read: {`);
|
|
366
459
|
for (const mapping of abi.mappings) {
|
|
367
|
-
const
|
|
368
|
-
lines.push(` ${mapping.name}: (params: { key: ${
|
|
460
|
+
const name = pascalCase(mapping.name);
|
|
461
|
+
lines.push(` ${mapping.name}: (params: { key: ${name}MappingKey }) => Promise<${name}MappingValue | null>`);
|
|
369
462
|
}
|
|
370
463
|
lines.push(` }`);
|
|
371
464
|
} else {
|
|
372
|
-
lines.push(` read: Record<string, (params: { key: string }) => Promise<
|
|
465
|
+
lines.push(` read: Record<string, (params: { key: string }) => Promise<string | null>>`);
|
|
373
466
|
}
|
|
374
467
|
if (abi.functions.length > 0) {
|
|
375
468
|
lines.push(` write: {`);
|
|
@@ -416,7 +509,20 @@ function generateContractFactory(abi) {
|
|
|
416
509
|
lines.push(` return {`);
|
|
417
510
|
lines.push(` program: raw.program,`);
|
|
418
511
|
lines.push(` abi: raw.abi as ABI,`);
|
|
419
|
-
|
|
512
|
+
if (abi.mappings.length > 0) {
|
|
513
|
+
lines.push(` read: {`);
|
|
514
|
+
for (const mapping of abi.mappings) {
|
|
515
|
+
const name = pascalCase(mapping.name);
|
|
516
|
+
const keyExpr = mappingKeyEncodeExpr("params.key", mapping.key);
|
|
517
|
+
lines.push(` ${mapping.name}: async (params: any) => {`);
|
|
518
|
+
lines.push(` const raw = await _raw.read.${mapping.name}({ key: ${keyExpr} })`);
|
|
519
|
+
lines.push(` return raw == null ? null : to${name}MappingValue(raw)`);
|
|
520
|
+
lines.push(` },`);
|
|
521
|
+
}
|
|
522
|
+
lines.push(` },`);
|
|
523
|
+
} else {
|
|
524
|
+
lines.push(` read: _raw.read as ${factoryName}Contract['read'],`);
|
|
525
|
+
}
|
|
420
526
|
if (abi.functions.length > 0) {
|
|
421
527
|
lines.push(` write: {`);
|
|
422
528
|
for (const fn of abi.functions) {
|
|
@@ -445,10 +551,10 @@ function generateContractFactory(abi) {
|
|
|
445
551
|
}
|
|
446
552
|
if (fn.outputs.length === 0) {
|
|
447
553
|
} else if (fn.outputs.length === 1) {
|
|
448
|
-
lines.push(` return ${
|
|
554
|
+
lines.push(` return ${generateOutputDecodeExpr(fn.outputs[0], 0, abi)}`);
|
|
449
555
|
} else {
|
|
450
|
-
const
|
|
451
|
-
lines.push(` return [${
|
|
556
|
+
const decoders = fn.outputs.map((o, i) => generateOutputDecodeExpr(o, i, abi));
|
|
557
|
+
lines.push(` return [${decoders.join(", ")}] as const`);
|
|
452
558
|
}
|
|
453
559
|
lines.push(` },`);
|
|
454
560
|
}
|
|
@@ -466,10 +572,10 @@ function generateContractFactory(abi) {
|
|
|
466
572
|
if (fn.outputs.length === 0) {
|
|
467
573
|
lines.push(` return { transactionId: result.transactionId }`);
|
|
468
574
|
} else if (fn.outputs.length === 1) {
|
|
469
|
-
lines.push(` return { transactionId: result.transactionId, result: ${
|
|
575
|
+
lines.push(` return { transactionId: result.transactionId, result: ${generateOutputDecodeExpr(fn.outputs[0], 0, abi)} }`);
|
|
470
576
|
} else {
|
|
471
|
-
const
|
|
472
|
-
lines.push(` return { transactionId: result.transactionId, result: [${
|
|
577
|
+
const decoders = fn.outputs.map((o, i) => generateOutputDecodeExpr(o, i, abi));
|
|
578
|
+
lines.push(` return { transactionId: result.transactionId, result: [${decoders.join(", ")}] as const }`);
|
|
473
579
|
}
|
|
474
580
|
lines.push(` },`);
|
|
475
581
|
}
|
|
@@ -490,4 +596,4 @@ function pascalCase(s) {
|
|
|
490
596
|
export {
|
|
491
597
|
generate
|
|
492
598
|
};
|
|
493
|
-
//# sourceMappingURL=chunk-
|
|
599
|
+
//# sourceMappingURL=chunk-OQWGO46H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/generate.ts"],"sourcesContent":["// Code generator — reads a parsed ABI and produces TypeScript source code.\n\nimport type { ABI, RecordDef, StructDef, AbiFunction, Mapping, StorageVariable, StorageType } from '@provablehq/veil-core'\nimport type { Plaintext, Primitive } from '@provablehq/veil-core'\n\n// ── Public API ────────────────────────────────────────────────────────\n\n/**\n * Options for {@link generate}.\n *\n * @property abi Parsed ABI the bindings are generated from — it supplies the\n * structs, records, functions, mappings, and storage variables to emit.\n * @property coreImport Import path emitted for `@provablehq/veil-core` types. Defaults to\n * `'@provablehq/veil-core'`. Override when the generated file resolves core through an\n * alias or a relative path (e.g. inside the monorepo).\n * @property programId Program id to stamp into the emitted `PROGRAM_ID` and\n * the generated contract factory. Defaults to the ABI's own `program`.\n * Override when the bindings' shape is taken from one deployment's ABI but\n * they target another — e.g. when a newer program version's ABI is the only\n * one current tooling can parse, yet the live deployment (identical shape)\n * has a different id.\n */\nexport interface GenerateOptions {\n abi: ABI\n coreImport?: string\n programId?: string\n}\n\n/**\n * Generates TypeScript source code from an Aleo program ABI.\n *\n * Produces:\n * - Struct interfaces\n * - Record interfaces with correctly typed fields\n * - Record and struct decoder functions (RecordValue/StructValue → typed interface)\n * - Function input and output types\n * - Mapping key/value types and value decoders (raw Aleo literal → typed value)\n * - Storage variable types\n */\nexport function generate(options: GenerateOptions): string {\n const { abi, coreImport = '@provablehq/veil-core', programId = abi.program } = options\n currentProgram = abi.program\n const lines: string[] = []\n\n // Header\n lines.push(`// Auto-generated by @provablehq/veil-codegen from ${abi.program}`)\n lines.push(`// Do not edit manually.`)\n lines.push('')\n // Runtime helpers are imported only when a mapping in this ABI needs them,\n // so a program without mappings emits no dead imports.\n const coreValueImports = ['getContract']\n if (abi.mappings.some((m) => mappingKeyNeedsEncode(m.key))) coreValueImports.push('encodeValue')\n if (abi.mappings.some((m) => mappingValueUsesParseValue(m.value))) coreValueImports.push('parseValue')\n if (abi.mappings.some((m) => !mappingValueUsesParseValue(m.value))) coreValueImports.push('parsePlaintextValue')\n lines.push(`import { ${coreValueImports.join(', ')} } from '${coreImport}'`)\n lines.push(`import type { RecordValue, FutureValue, DynamicFutureValue, PublicClient, WalletClient, ABI, InputRequest, PlaintextValue, StructValue } from '${coreImport}'`)\n lines.push('')\n\n // Program ID constant — the program these bindings target (see programId option).\n lines.push(`export const PROGRAM_ID = '${programId}' as const`)\n lines.push('')\n\n // Decoder helper: literal types (field/group/scalar) may arrive from runtime\n // parsers as bigint (suffix stripped) or as the canonical suffixed string.\n // Normalize to the canonical string form so decoded objects match the\n // generated interfaces at runtime.\n lines.push(`function litStr(v: PlaintextValue | undefined, suffix: string): string {`)\n lines.push(` if (typeof v === 'bigint') return \\`\\${v}\\${suffix}\\``)\n lines.push(` if (typeof v === 'string') return v`)\n lines.push(` if (v == null) return ''`)\n lines.push(` // Fail fast: a struct/array/boolean value in a literal slot means the ABI`)\n lines.push(` // or an upstream parser is wrong — never coerce it into corrupt data.`)\n lines.push(` throw new Error(\\`Expected \\${suffix} literal, got \\${typeof v}\\`)`)\n lines.push(`}`)\n lines.push('')\n\n // Structs\n for (const struct of abi.structs) {\n lines.push(...generateStructInterface(struct))\n lines.push('')\n lines.push(...generateStructDecoder(struct))\n lines.push('')\n }\n\n // Records\n for (const record of abi.records) {\n lines.push(...generateRecordInterface(record))\n lines.push('')\n lines.push(...generateRecordDecoder(record))\n lines.push('')\n }\n\n // Function input + output types\n for (const fn of abi.functions) {\n lines.push(...generateFunctionInputType(fn, abi))\n lines.push('')\n lines.push(...generateFunctionOutputType(fn, abi))\n lines.push('')\n }\n\n // Mapping types + value decoders\n for (const mapping of abi.mappings) {\n lines.push(...generateMappingType(mapping))\n lines.push('')\n lines.push(...generateMappingDecoder(mapping))\n lines.push('')\n }\n\n // Storage variable types\n for (const sv of abi.storageVariables) {\n lines.push(...generateStorageVariableType(sv))\n lines.push('')\n }\n\n // ABI constant + contract factory\n lines.push(...generateAbiConstant(abi))\n lines.push('')\n lines.push(...generateContractFactory(abi))\n lines.push('')\n\n return lines.join('\\n')\n}\n\n// ── Struct generation ─────────────────────────────────────────────────\n\nfunction generateStructInterface(struct: StructDef): string[] {\n const name = struct.path[struct.path.length - 1] ?? 'UnknownStruct'\n const lines: string[] = []\n\n lines.push(`export interface ${name} {`)\n\n for (const field of struct.fields) {\n const tsType = plaintextToTsType(field.type)\n lines.push(` ${field.name}: ${tsType}`)\n }\n\n lines.push(`}`)\n return lines\n}\n\n// ── Record generation ─────────────────────────────────────────────────\n\nfunction generateRecordInterface(record: RecordDef): string[] {\n const name = recordName(record)\n const lines: string[] = []\n\n lines.push(`export interface ${name} {`)\n lines.push(` owner: string`)\n\n for (const field of record.fields) {\n if (field.name === 'owner') continue\n const tsType = plaintextToTsType(field.type)\n lines.push(` ${field.name}: ${tsType}`)\n }\n\n // Carry the underlying RecordValue so typed records can be passed back as inputs\n lines.push(` _record: RecordValue`)\n lines.push(`}`)\n return lines\n}\n\n// Emit the `field: <converted value>` lines shared by record and struct decoders.\n// `container` names the enclosing type for error messages. `access` yields the\n// raw-value expression for a field name — records reach through their\n// `{ value, mode, type }` entries (`fields.<name>?.value`), structs are plain\n// StructValue objects with direct member access. Record-only policy (the\n// reserved `owner` entry) stays in the record decoder, which filters its field\n// list before calling; a struct member named `owner` is data like any other.\nfunction generateFieldConversions(\n fields: readonly { name: string; type: Plaintext }[],\n container: string,\n access: (name: string) => string,\n): string[] {\n const lines: string[] = []\n for (const field of fields) {\n const rawAccess = access(field.name)\n // Struct-typed fields: the raw PlaintextValue is a StructValue at runtime.\n // Cast through unknown to the generated struct interface so the return type\n // is correct. A missing field falls back to an empty object cast the same way.\n if (field.type.kind === 'struct') {\n if (isExternalStructRef(field.type)) {\n lines.push(` ${field.name}: ${rawAccess} as unknown as StructValue ?? {},`)\n continue\n }\n const structName = field.type.path.at(-1)\n if (!structName) {\n throw new Error(\n `Malformed ABI: struct field \"${field.name}\" in \"${container}\" has an empty type path. ` +\n `Cannot derive struct name for code generation.`\n )\n }\n lines.push(` ${field.name}: ${rawAccess} as unknown as ${structName} ?? {} as unknown as ${structName},`)\n } else {\n const expr = plaintextFieldExpr(rawAccess, field.type)\n lines.push(` ${field.name}: ${expr} ?? ${plaintextDefault(field.type)},`)\n }\n }\n return lines\n}\n\n/**\n * Emits a `const fields = …` guard so a decoder tolerates an undecryptable\n * output. Record outputs owned by another party (e.g. a compliance record\n * minted to an authority) arrive as ciphertext strings, and every record\n * output arrives as ciphertext on the wallet path — the decoder then returns\n * defaulted fields with the raw ciphertext preserved on `_record`, rather\n * than dereferencing `.fields` on a string and throwing.\n */\nfunction fieldsGuardLine(varName: string): string {\n return ` const fields = (typeof ${varName} === 'object' && ${varName} !== null ? ${varName}.fields : undefined) ?? {}`\n}\n\nfunction generateRecordDecoder(record: RecordDef): string[] {\n const name = recordName(record)\n const lines: string[] = []\n\n // Accepts a ciphertext string for records the caller cannot decrypt.\n lines.push(`export function to${name}(record: RecordValue | string): ${name} {`)\n lines.push(fieldsGuardLine('record'))\n lines.push(` return {`)\n lines.push(` owner: ((typeof record === 'object' && record !== null ? record.owner : undefined) ?? '') as string,`)\n lines.push(...generateFieldConversions(\n record.fields.filter((f) => f.name !== 'owner'),\n name,\n (n) => `fields.${n}?.value`,\n ))\n lines.push(` _record: record as unknown as RecordValue,`)\n lines.push(` }`)\n lines.push(`}`)\n return lines\n}\n\n// Decoder for a struct (e.g. a mapping value like PoolState/Slot). Same per-field\n// width conversions as records, without the record-only `owner`/`_record` fields.\nfunction generateStructDecoder(struct: StructDef): string[] {\n const name = struct.path[struct.path.length - 1] ?? 'UnknownStruct'\n const lines: string[] = []\n\n // Struct values (mapping reads, nested struct fields) are always readable\n // plaintext — never ciphertext — so no tolerance guard: a shape mismatch\n // should still fail loudly rather than return a silently-zeroed struct.\n lines.push(`export function to${name}(value: StructValue): ${name} {`)\n lines.push(` return {`)\n lines.push(...generateFieldConversions(struct.fields, name, (n) => `value.${n}`))\n lines.push(` }`)\n lines.push(`}`)\n return lines\n}\n\n// ── Function input generation ─────────────────────────────────────────\n\nfunction generateFunctionInputType(fn: AbiFunction, abi: ABI): string[] {\n const typeName = pascalCase(fn.name) + 'Inputs'\n const lines: string[] = []\n\n lines.push(`export type ${typeName} = {`)\n\n for (const input of fn.inputs) {\n const name = input.name ?? `arg${fn.inputs.indexOf(input)}`\n\n // Every input slot also accepts an InputRequest — a privacy-preserving\n // wallet fulfils it (address injection, record selection, derived value).\n if (input.type.kind === 'plaintext') {\n const tsType = plaintextToTsType(input.type.type)\n lines.push(` ${name}: ${tsType} | InputRequest`)\n } else if (input.type.kind === 'record') {\n const recName = input.type.path[input.type.path.length - 1] ?? 'RecordValue'\n const isLocal = !input.type.program || input.type.program.replace(/\\.aleo$/, '') === abi.program.replace(/\\.aleo$/, '')\n lines.push(` ${name}: ${isLocal ? recName : 'RecordValue'} | RecordValue | string | InputRequest`)\n } else if (input.type.kind === 'dynamicRecord') {\n lines.push(` ${name}: RecordValue | string | InputRequest`)\n }\n }\n\n lines.push(`}`)\n return lines\n}\n\n// ── Function output generation ────────────────────────────────────────\n\nfunction generateFunctionOutputType(fn: AbiFunction, abi: ABI): string[] {\n const typeName = pascalCase(fn.name) + 'Outputs'\n const lines: string[] = []\n\n if (fn.outputs.length === 0) {\n lines.push(`export type ${typeName} = void`)\n return lines\n }\n\n if (fn.outputs.length === 1) {\n const tsType = outputToTsType(fn.outputs[0].type, abi)\n lines.push(`export type ${typeName} = ${tsType}`)\n return lines\n }\n\n const typeElements = fn.outputs.map((output) => outputToTsType(output.type, abi))\n lines.push(`export type ${typeName} = [${typeElements.join(', ')}]`)\n return lines\n}\n\nfunction outputToTsType(output: AbiFunction['outputs'][number]['type'], abi: ABI): string {\n if (output.kind === 'plaintext') {\n return plaintextToTsType(output.type)\n } else if (output.kind === 'record') {\n const recName = output.path[output.path.length - 1] ?? 'RecordValue'\n const isLocal = !output.program || output.program.replace(/\\.aleo$/, '') === abi.program.replace(/\\.aleo$/, '')\n return isLocal ? recName : 'RecordValue'\n } else if (output.kind === 'dynamicRecord') {\n return 'RecordValue'\n } else if (output.kind === 'future') {\n return 'FutureValue'\n } else if (output.kind === 'dynamicFuture') {\n return 'DynamicFutureValue'\n }\n return 'unknown'\n}\n\n// ── Mapping generation ────────────────────────────────────────────────\n\n// TS type of the key a generated read method accepts. Primitive keys take\n// their natural TS type and are encoded to a suffixed Aleo literal by the\n// read wrapper; composite keys (struct/array) have no generated encoder, so\n// the caller supplies the raw Aleo literal string.\nfunction mappingKeyTsType(key: Plaintext): string {\n if (key.kind !== 'primitive') return 'string'\n return primitiveToTsType(key.primitive)\n}\n\n// True when the read wrapper must encode the key — integer and boolean keys\n// arrive as native TS values and gain their literal form via core's\n// encodeValue. Other keys are already Aleo literal strings and pass through.\nfunction mappingKeyNeedsEncode(key: Plaintext): boolean {\n return key.kind === 'primitive' && (isIntPrimitive(key.primitive) || key.primitive === 'boolean')\n}\n\n// Expression encoding a typed mapping key into the Aleo literal string the\n// node expects. Delegates to core's encodeValue so the wire-encoding rules\n// have one owner; string-typed keys (addresses, fields, composite literals)\n// pass through.\nfunction mappingKeyEncodeExpr(expr: string, key: Plaintext): string {\n if (!mappingKeyNeedsEncode(key)) return expr\n return `encodeValue(${expr}, '${(key as Extract<Plaintext, { kind: 'primitive' }>).primitive}')`\n}\n\nfunction generateMappingType(mapping: Mapping): string[] {\n const name = pascalCase(mapping.name)\n const keyType = mappingKeyTsType(mapping.key)\n const valueType = plaintextToTsType(mapping.value)\n\n return [\n `export type ${name}MappingKey = ${keyType}`,\n `export type ${name}MappingValue = ${valueType}`,\n ]\n}\n\n// True when the mapping's value decodes through core's strict parseValue —\n// the literal types its grammar covers. Identifier literals (bare tokens\n// with no recognizable shape) and composite values fall back to\n// parsePlaintextValue.\nfunction mappingValueUsesParseValue(value: Plaintext): boolean {\n if (value.kind !== 'primitive') return false\n const p = value.primitive\n return (\n isIntPrimitive(p) ||\n p === 'boolean' ||\n p === 'address' ||\n p === 'signature' ||\n p === 'field' ||\n p === 'group' ||\n p === 'scalar'\n )\n}\n\n// Decoder from a raw mapping value (Aleo plaintext string) to the typed\n// value. Struct-valued mappings guard the shape and delegate to the struct's\n// decoder. Literal-valued mappings decode through core's strict parseValue —\n// it throws on malformed responses and returns the literal's declared type,\n// so a value of the wrong width fails loudly instead of silently coercing.\nfunction generateMappingDecoder(mapping: Mapping): string[] {\n const name = pascalCase(mapping.name)\n const lines: string[] = []\n\n lines.push(`/** Decodes a raw \\`${mapping.name}\\` mapping value into a typed ${name}MappingValue. */`)\n lines.push(`export function to${name}MappingValue(raw: string): ${name}MappingValue {`)\n\n const throwLine = (expected: string) =>\n ` throw new Error(\\`${mapping.name} stores ${expected} values, got: \\${raw}\\`)`\n const typeGuard = (p: Primitive) => [\n ` const parsed = parseValue(raw)`,\n ` if (parsed.type !== '${p}') {`,\n throwLine(p),\n ` }`,\n ]\n\n if (mapping.value.kind === 'struct') {\n const structName = isExternalStructRef(mapping.value) ? null : mapping.value.path.at(-1)\n lines.push(` const value = parsePlaintextValue(raw)`)\n lines.push(` if (typeof value !== 'object' || Array.isArray(value)) {`)\n lines.push(throwLine(structName ?? 'struct'))\n lines.push(` }`)\n lines.push(` return ${structName ? `to${structName}(value)` : 'value'}`)\n } else if (mapping.value.kind === 'primitive' && mappingValueUsesParseValue(mapping.value)) {\n const p = mapping.value.primitive\n lines.push(...typeGuard(p))\n if (isSmallInt(p)) {\n lines.push(` return Number(parsed.value)`)\n } else if (isIntPrimitive(p)) {\n lines.push(` return parsed.value as bigint`)\n } else if (p === 'field' || p === 'group' || p === 'scalar') {\n // The node returns the canonical suffixed literal; the parse was only\n // validation, so hand back the input untouched.\n lines.push(` return raw`)\n } else {\n lines.push(` return parsed.value as ${primitiveToTsType(p)}`)\n }\n } else {\n // Identifier literals, arrays, and optionals sit outside parseValue's\n // grammar — decode leniently with the field conversions.\n lines.push(` const value = parsePlaintextValue(raw)`)\n lines.push(` return ${plaintextFieldExpr('value', mapping.value)}`)\n }\n lines.push(`}`)\n return lines\n}\n\n// ── Storage variable generation ───────────────────────────────────────\n\nfunction generateStorageVariableType(sv: StorageVariable): string[] {\n const name = pascalCase(sv.name)\n const tsType = storageTypeToTs(sv.type)\n\n return [`export type ${name}StorageType = ${tsType}`]\n}\n\nfunction storageTypeToTs(st: StorageType): string {\n if (st.kind === 'plaintext') {\n return plaintextToTsType(st.type)\n } else if (st.kind === 'vector') {\n return `${storageTypeToTs(st.element)}[]`\n }\n return 'unknown'\n}\n\n// ── Type mapping helpers ──────────────────────────────────────────────\n\n/**\n * Returns true for integer primitives that fit safely in a JS number (≤ 32-bit).\n *\n * u8/u16/u32 and i8/i16/i32 are typed as `number`; u64/u128 and i64/i128 require\n * `bigint` to avoid precision loss. This predicate is the single source of truth\n * for that boundary — all three type-mapping helpers delegate to it so that adding\n * a new width requires changing only this function.\n */\nfunction isSmallInt(p: Primitive): boolean {\n return p === 'u8' || p === 'u16' || p === 'u32' || p === 'i8' || p === 'i16' || p === 'i32'\n}\n\n/** Returns true for integer primitives of any width. */\nfunction isIntPrimitive(p: Primitive): boolean {\n return isSmallInt(p) || p === 'u64' || p === 'u128' || p === 'i64' || p === 'i128'\n}\n\n// Set by generate() so struct references resolve relative to the program\n// being generated; external struct refs have no local interface.\nlet currentProgram = ''\n\n// True when a struct reference points into another program — its definition\n// is not in this ABI (leo prunes to local types), so the generated code\n// treats the value as an opaque StructValue.\nfunction isExternalStructRef(pt: Extract<Plaintext, { kind: 'struct' }>): boolean {\n if (!pt.program) return false\n return pt.program.replace(/\\.aleo$/, '') !== currentProgram.replace(/\\.aleo$/, '')\n}\n\nfunction plaintextToTsType(pt: Plaintext): string {\n switch (pt.kind) {\n case 'primitive':\n return primitiveToTsType(pt.primitive)\n case 'array':\n return `${plaintextToTsType(pt.element)}[]`\n case 'struct':\n if (isExternalStructRef(pt)) return 'StructValue'\n return pt.path[pt.path.length - 1] ?? 'unknown'\n case 'optional':\n return `${plaintextToTsType(pt.inner)} | undefined`\n default:\n return 'unknown'\n }\n}\n\nfunction primitiveToTsType(p: Primitive): string {\n if (isSmallInt(p)) return 'number'\n switch (p) {\n case 'address':\n case 'field':\n case 'group':\n case 'scalar':\n case 'signature':\n case 'identifier':\n return 'string'\n case 'boolean':\n return 'boolean'\n // 64-bit and wider: must be bigint to avoid precision loss\n case 'u64':\n case 'u128':\n case 'i64':\n case 'i128':\n return 'bigint'\n default:\n return 'unknown'\n }\n}\n\n/**\n * Builds the full typed expression for a primitive record field access.\n *\n * The raw value stored in RecordFieldValue is always a bigint for all integer\n * widths (parsed by core's parseValue). For u8/u16/u32 and i8/i16/i32 fields\n * (typed as `number`), the access is wrapped with Number() to convert at\n * runtime. For u64+ (typed as `bigint`), it is cast directly. For non-primitive types (array,\n * optional) the raw access is returned unchanged — those fall through to the\n * caller's existing handling.\n *\n * @param rawAccess - Expression yielding the raw PlaintextValue, e.g. `record.fields.x?.value`\n */\nfunction plaintextFieldExpr(rawAccess: string, pt: Plaintext): string {\n // Arrays decode element-by-element with the same conversions as scalar\n // fields; the runtime parser (parseCompositeValue in core) delivers them\n // as PlaintextValue[]. Structs pass through as parsed objects; optionals\n // convert their inner value when present.\n if (pt.kind === 'array') {\n const element = plaintextFieldExpr('el', pt.element)\n // Identity element conversion needs no map at all.\n if (element === 'el') return `${rawAccess} as ${plaintextToTsType(pt)}`\n return `((${rawAccess} ?? []) as PlaintextValue[]).map((el) => ${element}) as ${plaintextToTsType(pt)}`\n }\n if (pt.kind === 'optional') {\n const inner = plaintextFieldExpr(rawAccess, pt.inner)\n return `(${rawAccess} === undefined ? undefined : ${inner})`\n }\n if (pt.kind !== 'primitive') return rawAccess\n const p = pt.primitive\n // Small integers stored as bigint at runtime, exposed as number in the interface.\n // The ?? 0n guard is inside the Number() call: Number(undefined) = NaN, and\n // NaN ?? 0 does NOT trigger (?? only catches null/undefined). Guarding before\n // Number() ensures a missing field correctly defaults to 0.\n if (isSmallInt(p)) return `Number((${rawAccess} ?? 0n) as bigint)`\n switch (p) {\n // Wide integers stay bigint end-to-end.\n case 'u64':\n case 'u128':\n case 'i64':\n case 'i128':\n return `${rawAccess} as bigint`\n // Literal types with a suffix: runtime parsers may deliver these as bigint\n // (suffix stripped) or as the canonical suffixed string — normalize to the\n // canonical string form (e.g. 123n → \"123field\").\n case 'field':\n case 'group':\n case 'scalar':\n return `litStr(${rawAccess}, '${p}')`\n case 'address':\n case 'signature':\n case 'identifier':\n return `${rawAccess} as string`\n case 'boolean':\n return `${rawAccess} as boolean`\n default:\n return rawAccess\n }\n}\n\nfunction plaintextDefault(pt: Plaintext): string {\n if (pt.kind === 'array') return '[]'\n if (pt.kind === 'optional') return 'undefined'\n if (pt.kind !== 'primitive') return \"''\"\n if (isSmallInt(pt.primitive)) return '0'\n switch (pt.primitive) {\n case 'boolean':\n return 'false'\n // Wide integers — bigint default\n case 'u64': case 'u128': case 'i64': case 'i128':\n return '0n'\n case 'field': case 'group': case 'scalar':\n return \"''\"\n case 'address': case 'signature': case 'identifier':\n return \"''\"\n default:\n return \"''\"\n }\n}\n\n// ── ABI constant + contract factory ───────────────────────────────────\n\nfunction generateAbiConstant(abi: ABI): string[] {\n // Embed the already-parsed ABI as a typed constant.\n // This avoids a round-trip through parseAbi at runtime.\n return [\n `/** The parsed ABI for ${abi.program}. */`,\n `export const PROGRAM_ABI: ABI = ${JSON.stringify(abi, null, 2)}`,\n ]\n}\n\n/** Generate named param type string for a function's inputs */\nfunction namedParamsType(fn: AbiFunction, abi: ABI): string {\n if (fn.inputs.length === 0) return '{}'\n const params = fn.inputs.map((input) => {\n const name = input.name ?? `arg${fn.inputs.indexOf(input)}`\n let tsType: string\n if (input.type.kind === 'plaintext') {\n tsType = plaintextToTsType(input.type.type)\n } else if (input.type.kind === 'record') {\n const recName = input.type.path[input.type.path.length - 1] ?? 'RecordValue'\n const isLocal = !input.type.program || input.type.program.replace(/\\.aleo$/, '') === abi.program.replace(/\\.aleo$/, '')\n tsType = isLocal ? `${recName} | RecordValue | string` : 'RecordValue | string'\n } else {\n tsType = 'RecordValue | string'\n }\n // Also accept an InputRequest in every slot (wallet-fulfilled input).\n return `${name}: ${tsType} | InputRequest`\n })\n return `{ ${params.join(', ')} }`\n}\n\n/** Generate the typed return type for simulate */\nfunction simulateReturnType(fn: AbiFunction, abi: ABI): string {\n if (fn.outputs.length === 0) return 'void'\n if (fn.outputs.length === 1) return outputToTsType(fn.outputs[0].type, abi)\n return `[${fn.outputs.map((o) => outputToTsType(o.type, abi)).join(', ')}]`\n}\n\n/** Generate the typed return type for execute (includes transactionId) */\nfunction executeReturnType(fn: AbiFunction, abi: ABI): string {\n const simType = simulateReturnType(fn, abi)\n if (simType === 'void') return '{ transactionId: string }'\n return `{ transactionId: string, result: ${simType} }`\n}\n\n/** Generate the input names array for converting named params to positional */\nfunction inputNames(fn: AbiFunction): string[] {\n return fn.inputs.map((input, i) => input.name ?? `arg${i}`)\n}\n\n/**\n * For record inputs, generate resolution lines that extract _record from typed records.\n * Returns { resolveLines: string[], resolvedNames: string[] }.\n * resolvedNames replaces record input names with their resolved versions.\n */\nfunction resolveRecordInputs(fn: AbiFunction): { resolveLines: string[], resolvedNames: string[] } {\n const resolveLines: string[] = []\n const resolvedNames: string[] = []\n\n for (let i = 0; i < fn.inputs.length; i++) {\n const input = fn.inputs[i]\n const name = input.name ?? `arg${i}`\n\n if (input.type.kind === 'record' || input.type.kind === 'dynamicRecord') {\n resolveLines.push(` const _${name} = ${name}?._record ?? ${name}`)\n resolvedNames.push(`_${name}`)\n } else {\n resolvedNames.push(name)\n }\n }\n\n return { resolveLines, resolvedNames }\n}\n\n/** Generate the output-decoding expression for a single output at index i */\nfunction generateOutputDecodeExpr(output: AbiFunction['outputs'][number], i: number, abi: ABI): string {\n if (output.type.kind === 'record') {\n const recName = output.type.path[output.type.path.length - 1] ?? ''\n const isLocal = !output.type.program || output.type.program.replace(/\\.aleo$/, '') === abi.program.replace(/\\.aleo$/, '')\n // Double-cast through unknown: result.outputs[i] is ParsedOutput | undefined under\n // noUncheckedIndexedAccess. The cast to unknown then to RecordValue is intentional —\n // the ABI guarantees this output is a record at this position.\n if (isLocal && recName) {\n return `to${recName}(result.outputs[${i}] as unknown as RecordValue)`\n }\n return `result.outputs[${i}] as unknown as RecordValue`\n }\n if (output.type.kind === 'plaintext') {\n return `result.outputs[${i}] as unknown as ${plaintextToTsType(output.type.type)}`\n }\n if (output.type.kind === 'future') {\n return `result.outputs[${i}] as unknown as FutureValue`\n }\n if (output.type.kind === 'dynamicFuture') {\n return `result.outputs[${i}] as unknown as DynamicFutureValue`\n }\n return `result.outputs[${i}]`\n}\n\nfunction generateContractFactory(abi: ABI): string[] {\n const programName = abi.program\n const factoryName = pascalCase(programName.replace('.aleo', ''))\n const lines: string[] = []\n\n // Generate typed interface with named params and typed returns\n lines.push(`export interface ${factoryName}Contract {`)\n lines.push(` program: string`)\n lines.push(` abi: ABI`)\n\n // read methods — typed key in, decoded value (or null for an absent key) out\n if (abi.mappings.length > 0) {\n lines.push(` read: {`)\n for (const mapping of abi.mappings) {\n const name = pascalCase(mapping.name)\n lines.push(` ${mapping.name}: (params: { key: ${name}MappingKey }) => Promise<${name}MappingValue | null>`)\n }\n lines.push(` }`)\n } else {\n lines.push(` read: Record<string, (params: { key: string }) => Promise<string | null>>`)\n }\n\n // write methods — named params, returns tx ID\n if (abi.functions.length > 0) {\n lines.push(` write: {`)\n for (const fn of abi.functions) {\n const params = namedParamsType(fn, abi)\n lines.push(` ${fn.name}: (params: ${params}) => Promise<string>`)\n }\n lines.push(` }`)\n }\n\n // simulate methods — named params, typed return\n if (abi.functions.length > 0) {\n lines.push(` simulate: {`)\n for (const fn of abi.functions) {\n const params = namedParamsType(fn, abi)\n const retType = simulateReturnType(fn, abi)\n lines.push(` ${fn.name}: (params: ${params}) => Promise<${retType}>`)\n }\n lines.push(` }`)\n }\n\n // execute methods — named params, typed return + transactionId.\n // Fee belongs in proving config, not per-call params — do not add fee here.\n if (abi.functions.length > 0) {\n lines.push(` execute: {`)\n for (const fn of abi.functions) {\n const params = namedParamsType(fn, abi)\n const retType = executeReturnType(fn, abi)\n lines.push(` ${fn.name}: (params: ${params}) => Promise<${retType}>`)\n }\n lines.push(` }`)\n }\n\n lines.push(` fetchAbi: () => Promise<ABI>`)\n lines.push(`}`)\n lines.push('')\n\n // Generate factory with wrapper methods\n lines.push(`export function create${factoryName}Contract(options: {`)\n lines.push(` publicClient?: PublicClient,`)\n lines.push(` walletClient?: WalletClient,`)\n lines.push(` programSource?: string,`)\n lines.push(` imports?: Record<string, string>,`)\n lines.push(`}): ${factoryName}Contract {`)\n lines.push(` if (!options.publicClient && !options.walletClient) throw new Error('At least one of publicClient or walletClient is required')`)\n lines.push(` const client = options.publicClient && options.walletClient`)\n lines.push(` ? { public: options.publicClient, wallet: options.walletClient }`)\n lines.push(` : (options.publicClient ?? options.walletClient)!`)\n lines.push(` const raw = getContract({ program: PROGRAM_ID, abi: PROGRAM_ABI, client, programSource: options.programSource, imports: options.imports })`)\n // Proxy method access is typed as Record<string, fn> whose properties are\n // T | undefined under noUncheckedIndexedAccess. Cast to any for the internal\n // wrappers — the typed factory interface above is what consumers see.\n lines.push(` const _raw = raw as any`)\n lines.push('')\n lines.push(` return {`)\n lines.push(` program: raw.program,`)\n lines.push(` abi: raw.abi as ABI,`)\n\n // read wrappers — encode the typed key to an Aleo literal, null-guard the\n // absent-key result, decode the raw value with the mapping's decoder\n if (abi.mappings.length > 0) {\n lines.push(` read: {`)\n for (const mapping of abi.mappings) {\n const name = pascalCase(mapping.name)\n const keyExpr = mappingKeyEncodeExpr('params.key', mapping.key)\n lines.push(` ${mapping.name}: async (params: any) => {`)\n lines.push(` const raw = await _raw.read.${mapping.name}({ key: ${keyExpr} })`)\n lines.push(` return raw == null ? null : to${name}MappingValue(raw)`)\n lines.push(` },`)\n }\n lines.push(` },`)\n } else {\n lines.push(` read: _raw.read as ${factoryName}Contract['read'],`)\n }\n\n // write wrappers — convert named params to positional inputs\n if (abi.functions.length > 0) {\n lines.push(` write: {`)\n for (const fn of abi.functions) {\n const names = inputNames(fn)\n const { resolveLines, resolvedNames } = resolveRecordInputs(fn)\n lines.push(` ${fn.name}: (params: any) => {`)\n if (names.length > 0) lines.push(` const { ${names.join(', ')} } = params`)\n for (const line of resolveLines) lines.push(line)\n lines.push(` return _raw.write.${fn.name}({ inputs: [${resolvedNames.join(', ')}] })`)\n lines.push(` },`)\n }\n lines.push(` },`)\n }\n\n // simulate wrappers — convert named params to positional, map outputs to typed returns\n if (abi.functions.length > 0) {\n lines.push(` simulate: {`)\n for (const fn of abi.functions) {\n const names = inputNames(fn)\n const { resolveLines, resolvedNames } = resolveRecordInputs(fn)\n lines.push(` ${fn.name}: async (params: any) => {`)\n if (names.length > 0) lines.push(` const { ${names.join(', ')} } = params`)\n for (const line of resolveLines) lines.push(line)\n\n if (fn.outputs.length === 0) {\n lines.push(` await _raw.simulate.${fn.name}({ inputs: [${resolvedNames.join(', ')}] })`)\n } else {\n lines.push(` const result = await _raw.simulate.${fn.name}({ inputs: [${resolvedNames.join(', ')}] })`)\n }\n\n if (fn.outputs.length === 0) {\n // void return\n } else if (fn.outputs.length === 1) {\n lines.push(` return ${generateOutputDecodeExpr(fn.outputs[0], 0, abi)}`)\n } else {\n const decoders = fn.outputs.map((o, i) => generateOutputDecodeExpr(o, i, abi))\n lines.push(` return [${decoders.join(', ')}] as const`)\n }\n\n lines.push(` },`)\n }\n lines.push(` },`)\n }\n\n // execute wrappers — same as simulate but includes transactionId\n if (abi.functions.length > 0) {\n lines.push(` execute: {`)\n for (const fn of abi.functions) {\n const names = inputNames(fn)\n const { resolveLines, resolvedNames } = resolveRecordInputs(fn)\n lines.push(` ${fn.name}: async (params: any) => {`)\n if (names.length > 0) lines.push(` const { ${names.join(', ')} } = params`)\n for (const line of resolveLines) lines.push(line)\n lines.push(` const result = await _raw.execute.${fn.name}({ inputs: [${resolvedNames.join(', ')}] })`)\n\n if (fn.outputs.length === 0) {\n lines.push(` return { transactionId: result.transactionId }`)\n } else if (fn.outputs.length === 1) {\n lines.push(` return { transactionId: result.transactionId, result: ${generateOutputDecodeExpr(fn.outputs[0], 0, abi)} }`)\n } else {\n const decoders = fn.outputs.map((o, i) => generateOutputDecodeExpr(o, i, abi))\n lines.push(` return { transactionId: result.transactionId, result: [${decoders.join(', ')}] as const }`)\n }\n\n lines.push(` },`)\n }\n lines.push(` },`)\n }\n\n lines.push(` fetchAbi: _raw.fetchAbi as unknown as ${factoryName}Contract['fetchAbi'],`)\n lines.push(` }`)\n lines.push(`}`)\n\n return lines\n}\n\n// ── Utility ───────────────────────────────────────────────────────────\n\nfunction recordName(record: RecordDef): string {\n return record.path[record.path.length - 1] ?? 'UnknownRecord'\n}\n\nfunction pascalCase(s: string): string {\n return s\n .split('_')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('')\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -26,9 +26,9 @@ interface GenerateOptions {
|
|
|
26
26
|
* Produces:
|
|
27
27
|
* - Struct interfaces
|
|
28
28
|
* - Record interfaces with correctly typed fields
|
|
29
|
-
* - Record
|
|
29
|
+
* - Record and struct decoder functions (RecordValue/StructValue → typed interface)
|
|
30
30
|
* - Function input and output types
|
|
31
|
-
* - Mapping key/value types
|
|
31
|
+
* - Mapping key/value types and value decoders (raw Aleo literal → typed value)
|
|
32
32
|
* - Storage variable types
|
|
33
33
|
*/
|
|
34
34
|
declare function generate(options: GenerateOptions): string;
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@provablehq/veil-codegen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Generates executable TypeScript contracts from Aleo program ABIs.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -32,14 +32,14 @@
|
|
|
32
32
|
"access": "public"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@provablehq/veil-core": "0.
|
|
35
|
+
"@provablehq/veil-core": "0.6.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"tsup": "^8.0.0",
|
|
39
39
|
"typescript": "^5.7.0",
|
|
40
|
-
"@provablehq/veil-aleo-devnode": "0.
|
|
41
|
-
"@provablehq/veil-leo": "0.
|
|
42
|
-
"@provablehq/veil-aleo-sdk": "0.
|
|
40
|
+
"@provablehq/veil-aleo-devnode": "0.6.0",
|
|
41
|
+
"@provablehq/veil-leo": "0.6.0",
|
|
42
|
+
"@provablehq/veil-aleo-sdk": "0.6.0"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "tsup",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/generate.ts"],"sourcesContent":["// Code generator — reads a parsed ABI and produces TypeScript source code.\n\nimport type { ABI, RecordDef, StructDef, AbiFunction, Mapping, StorageVariable, StorageType } from '@provablehq/veil-core'\nimport type { Plaintext, Primitive } from '@provablehq/veil-core'\n\n// ── Public API ────────────────────────────────────────────────────────\n\n/**\n * Options for {@link generate}.\n *\n * @property abi Parsed ABI the bindings are generated from — it supplies the\n * structs, records, functions, mappings, and storage variables to emit.\n * @property coreImport Import path emitted for `@provablehq/veil-core` types. Defaults to\n * `'@provablehq/veil-core'`. Override when the generated file resolves core through an\n * alias or a relative path (e.g. inside the monorepo).\n * @property programId Program id to stamp into the emitted `PROGRAM_ID` and\n * the generated contract factory. Defaults to the ABI's own `program`.\n * Override when the bindings' shape is taken from one deployment's ABI but\n * they target another — e.g. when a newer program version's ABI is the only\n * one current tooling can parse, yet the live deployment (identical shape)\n * has a different id.\n */\nexport interface GenerateOptions {\n abi: ABI\n coreImport?: string\n programId?: string\n}\n\n/**\n * Generates TypeScript source code from an Aleo program ABI.\n *\n * Produces:\n * - Struct interfaces\n * - Record interfaces with correctly typed fields\n * - Record mapper functions (RecordValue → typed interface)\n * - Function input and output types\n * - Mapping key/value types\n * - Storage variable types\n */\nexport function generate(options: GenerateOptions): string {\n const { abi, coreImport = '@provablehq/veil-core', programId = abi.program } = options\n const lines: string[] = []\n\n // Header\n lines.push(`// Auto-generated by @provablehq/veil-codegen from ${abi.program}`)\n lines.push(`// Do not edit manually.`)\n lines.push('')\n lines.push(`import { getContract } from '${coreImport}'`)\n lines.push(`import type { RecordValue, FutureValue, PublicClient, WalletClient, ABI, InputRequest, PlaintextValue } from '${coreImport}'`)\n lines.push('')\n\n // Program ID constant — the program these bindings target (see programId option).\n lines.push(`export const PROGRAM_ID = '${programId}' as const`)\n lines.push('')\n\n // Decoder helper: literal types (field/group/scalar) may arrive from runtime\n // parsers as bigint (suffix stripped) or as the canonical suffixed string.\n // Normalize to the canonical string form so decoded objects match the\n // generated interfaces at runtime.\n lines.push(`function litStr(v: PlaintextValue | undefined, suffix: string): string {`)\n lines.push(` if (typeof v === 'bigint') return \\`\\${v}\\${suffix}\\``)\n lines.push(` if (typeof v === 'string') return v`)\n lines.push(` if (v == null) return ''`)\n lines.push(` // Fail fast: a struct/array/boolean value in a literal slot means the ABI`)\n lines.push(` // or an upstream parser is wrong — never coerce it into corrupt data.`)\n lines.push(` throw new Error(\\`Expected \\${suffix} literal, got \\${typeof v}\\`)`)\n lines.push(`}`)\n lines.push('')\n\n // Structs\n for (const struct of abi.structs) {\n lines.push(...generateStructInterface(struct))\n lines.push('')\n lines.push(...generateStructMapper(struct))\n lines.push('')\n }\n\n // Records\n for (const record of abi.records) {\n lines.push(...generateRecordInterface(record))\n lines.push('')\n lines.push(...generateRecordMapper(record))\n lines.push('')\n }\n\n // Function input + output types\n for (const fn of abi.functions) {\n lines.push(...generateFunctionInputType(fn, abi))\n lines.push('')\n lines.push(...generateFunctionOutputType(fn, abi))\n lines.push('')\n }\n\n // Mapping types\n for (const mapping of abi.mappings) {\n lines.push(...generateMappingType(mapping))\n lines.push('')\n }\n\n // Storage variable types\n for (const sv of abi.storageVariables) {\n lines.push(...generateStorageVariableType(sv))\n lines.push('')\n }\n\n // ABI constant + contract factory\n lines.push(...generateAbiConstant(abi))\n lines.push('')\n lines.push(...generateContractFactory(abi))\n lines.push('')\n\n return lines.join('\\n')\n}\n\n// ── Struct generation ─────────────────────────────────────────────────\n\nfunction generateStructInterface(struct: StructDef): string[] {\n const name = struct.path[struct.path.length - 1] ?? 'UnknownStruct'\n const lines: string[] = []\n\n lines.push(`export interface ${name} {`)\n\n for (const field of struct.fields) {\n const tsType = plaintextToTsType(field.type)\n lines.push(` ${field.name}: ${tsType}`)\n }\n\n lines.push(`}`)\n return lines\n}\n\n// ── Record generation ─────────────────────────────────────────────────\n\nfunction generateRecordInterface(record: RecordDef): string[] {\n const name = recordName(record)\n const lines: string[] = []\n\n lines.push(`export interface ${name} {`)\n lines.push(` owner: string`)\n\n for (const field of record.fields) {\n if (field.name === 'owner') continue\n const tsType = plaintextToTsType(field.type)\n lines.push(` ${field.name}: ${tsType}`)\n }\n\n // Carry the underlying RecordValue so typed records can be passed back as inputs\n lines.push(` _record: RecordValue`)\n lines.push(`}`)\n return lines\n}\n\n// Emit the `field: <converted value>` lines shared by record and struct mappers.\n// `varName` is the mapper's parameter name (the value being decoded); `container`\n// names the enclosing type for error messages.\nfunction mapperFieldLines(\n fields: readonly { name: string; type: Plaintext }[],\n container: string,\n fieldsVar: string,\n): string[] {\n const lines: string[] = []\n for (const field of fields) {\n if (field.name === 'owner') continue\n // Struct-typed fields: the raw PlaintextValue is a StructValue at runtime.\n // Cast through unknown to the generated struct interface so the return type\n // is correct. A missing field falls back to an empty object cast the same way.\n if (field.type.kind === 'struct') {\n const structName = field.type.path.at(-1)\n if (!structName) {\n throw new Error(\n `Malformed ABI: struct field \"${field.name}\" in \"${container}\" has an empty type path. ` +\n `Cannot derive struct name for code generation.`\n )\n }\n lines.push(` ${field.name}: ${fieldsVar}.${field.name}?.value as unknown as ${structName} ?? {} as unknown as ${structName},`)\n } else {\n const rawAccess = `${fieldsVar}.${field.name}?.value`\n const expr = plaintextFieldExpr(rawAccess, field.type)\n lines.push(` ${field.name}: ${expr} ?? ${plaintextDefault(field.type)},`)\n }\n }\n return lines\n}\n\n/**\n * Emits a `const fields = …` guard so a mapper tolerates an undecryptable\n * output. Record outputs owned by another party (e.g. a compliance record\n * minted to an authority) arrive as ciphertext strings, and every record\n * output arrives as ciphertext on the wallet path — the mapper then returns\n * defaulted fields with the raw ciphertext preserved on `_record`, rather\n * than dereferencing `.fields` on a string and throwing.\n */\nfunction fieldsGuardLine(varName: string): string {\n return ` const fields = (typeof ${varName} === 'object' && ${varName} !== null ? ${varName}.fields : undefined) ?? {}`\n}\n\nfunction generateRecordMapper(record: RecordDef): string[] {\n const name = recordName(record)\n const lines: string[] = []\n\n // Accepts a ciphertext string for records the caller cannot decrypt.\n lines.push(`export function to${name}(record: RecordValue | string): ${name} {`)\n lines.push(fieldsGuardLine('record'))\n lines.push(` return {`)\n lines.push(` owner: ((typeof record === 'object' && record !== null ? record.owner : undefined) ?? '') as string,`)\n lines.push(...mapperFieldLines(record.fields, name, 'fields'))\n lines.push(` _record: record as unknown as RecordValue,`)\n lines.push(` }`)\n lines.push(`}`)\n return lines\n}\n\n// Decoder for a struct (e.g. a mapping value like PoolState/Slot). Same per-field\n// width conversions as records, without the record-only `owner`/`_record` fields.\nfunction generateStructMapper(struct: StructDef): string[] {\n const name = struct.path[struct.path.length - 1] ?? 'UnknownStruct'\n const lines: string[] = []\n\n // Struct values (mapping reads, nested struct fields) are always readable\n // plaintext — never ciphertext — so no tolerance guard: a shape mismatch\n // should still fail loudly rather than return a silently-zeroed struct.\n lines.push(`export function to${name}(value: RecordValue): ${name} {`)\n lines.push(` return {`)\n lines.push(...mapperFieldLines(struct.fields, name, 'value.fields'))\n lines.push(` }`)\n lines.push(`}`)\n return lines\n}\n\n// ── Function input generation ─────────────────────────────────────────\n\nfunction generateFunctionInputType(fn: AbiFunction, abi: ABI): string[] {\n const typeName = pascalCase(fn.name) + 'Inputs'\n const lines: string[] = []\n\n lines.push(`export type ${typeName} = {`)\n\n for (const input of fn.inputs) {\n const name = input.name ?? `arg${fn.inputs.indexOf(input)}`\n\n // Every input slot also accepts an InputRequest — a privacy-preserving\n // wallet fulfils it (address injection, record selection, derived value).\n if (input.type.kind === 'plaintext') {\n const tsType = plaintextToTsType(input.type.type)\n lines.push(` ${name}: ${tsType} | InputRequest`)\n } else if (input.type.kind === 'record') {\n const recName = input.type.path[input.type.path.length - 1] ?? 'RecordValue'\n const isLocal = !input.type.program || input.type.program.replace(/\\.aleo$/, '') === abi.program.replace(/\\.aleo$/, '')\n lines.push(` ${name}: ${isLocal ? recName : 'RecordValue'} | RecordValue | string | InputRequest`)\n } else if (input.type.kind === 'dynamicRecord') {\n lines.push(` ${name}: RecordValue | string | InputRequest`)\n }\n }\n\n lines.push(`}`)\n return lines\n}\n\n// ── Function output generation ────────────────────────────────────────\n\nfunction generateFunctionOutputType(fn: AbiFunction, abi: ABI): string[] {\n const typeName = pascalCase(fn.name) + 'Outputs'\n const lines: string[] = []\n\n if (fn.outputs.length === 0) {\n lines.push(`export type ${typeName} = void`)\n return lines\n }\n\n if (fn.outputs.length === 1) {\n const tsType = outputToTsType(fn.outputs[0].type, abi)\n lines.push(`export type ${typeName} = ${tsType}`)\n return lines\n }\n\n const typeElements = fn.outputs.map((output) => outputToTsType(output.type, abi))\n lines.push(`export type ${typeName} = [${typeElements.join(', ')}]`)\n return lines\n}\n\nfunction outputToTsType(output: AbiFunction['outputs'][number]['type'], abi: ABI): string {\n if (output.kind === 'plaintext') {\n return plaintextToTsType(output.type)\n } else if (output.kind === 'record') {\n const recName = output.path[output.path.length - 1] ?? 'RecordValue'\n const isLocal = !output.program || output.program.replace(/\\.aleo$/, '') === abi.program.replace(/\\.aleo$/, '')\n return isLocal ? recName : 'RecordValue'\n } else if (output.kind === 'dynamicRecord') {\n return 'RecordValue'\n } else if (output.kind === 'future' || output.kind === 'dynamicFuture') {\n return 'FutureValue'\n }\n return 'unknown'\n}\n\n// ── Mapping generation ────────────────────────────────────────────────\n\nfunction generateMappingType(mapping: Mapping): string[] {\n const name = pascalCase(mapping.name)\n const keyType = plaintextToTsType(mapping.key)\n const valueType = plaintextToTsType(mapping.value)\n\n return [\n `export type ${name}MappingKey = ${keyType}`,\n `export type ${name}MappingValue = ${valueType}`,\n ]\n}\n\n// ── Storage variable generation ───────────────────────────────────────\n\nfunction generateStorageVariableType(sv: StorageVariable): string[] {\n const name = pascalCase(sv.name)\n const tsType = storageTypeToTs(sv.type)\n\n return [`export type ${name}StorageType = ${tsType}`]\n}\n\nfunction storageTypeToTs(st: StorageType): string {\n if (st.kind === 'plaintext') {\n return plaintextToTsType(st.type)\n } else if (st.kind === 'vector') {\n return `${storageTypeToTs(st.element)}[]`\n }\n return 'unknown'\n}\n\n// ── Type mapping helpers ──────────────────────────────────────────────\n\n/**\n * Returns true for integer primitives that fit safely in a JS number (≤ 32-bit).\n *\n * u8/u16/u32 and i8/i16/i32 are typed as `number`; u64/u128 and i64/i128 require\n * `bigint` to avoid precision loss. This predicate is the single source of truth\n * for that boundary — all three type-mapping helpers delegate to it so that adding\n * a new width requires changing only this function.\n */\nfunction isSmallInt(p: Primitive): boolean {\n return p === 'u8' || p === 'u16' || p === 'u32' || p === 'i8' || p === 'i16' || p === 'i32'\n}\n\nfunction plaintextToTsType(pt: Plaintext): string {\n switch (pt.kind) {\n case 'primitive':\n return primitiveToTsType(pt.primitive)\n case 'array':\n return `${plaintextToTsType(pt.element)}[]`\n case 'struct':\n return pt.path[pt.path.length - 1] ?? 'unknown'\n case 'optional':\n return `${plaintextToTsType(pt.inner)} | undefined`\n default:\n return 'unknown'\n }\n}\n\nfunction primitiveToTsType(p: Primitive): string {\n if (isSmallInt(p)) return 'number'\n switch (p) {\n case 'address':\n case 'field':\n case 'group':\n case 'scalar':\n case 'signature':\n case 'identifier':\n return 'string'\n case 'boolean':\n return 'boolean'\n // 64-bit and wider: must be bigint to avoid precision loss\n case 'u64':\n case 'u128':\n case 'i64':\n case 'i128':\n return 'bigint'\n default:\n return 'unknown'\n }\n}\n\n/**\n * Builds the full typed expression for a primitive record field access.\n *\n * The raw value stored in RecordFieldValue is always a bigint for all integer\n * widths (parsed by core's parseValue). For u8/u16/u32 and i8/i16/i32 fields\n * (typed as `number`), the access is wrapped with Number() to convert at\n * runtime. For u64+ (typed as `bigint`), it is cast directly. For non-primitive types (array,\n * optional) the raw access is returned unchanged — those fall through to the\n * caller's existing handling.\n *\n * @param rawAccess - Expression yielding the raw PlaintextValue, e.g. `record.fields.x?.value`\n */\nfunction plaintextFieldExpr(rawAccess: string, pt: Plaintext): string {\n // TODO(follow-up): non-primitive record fields other than struct (i.e. `array`,\n // `optional`) are NOT yet handled and fall through to the raw expression.\n // This is a known gap — ABIs containing such fields will produce non-compiling\n // output. Implement `array` and `optional` handling before using codegen with\n // such ABIs.\n if (pt.kind !== 'primitive') return rawAccess\n const p = pt.primitive\n // Small integers stored as bigint at runtime, exposed as number in the interface.\n // The ?? 0n guard is inside the Number() call: Number(undefined) = NaN, and\n // NaN ?? 0 does NOT trigger (?? only catches null/undefined). Guarding before\n // Number() ensures a missing field correctly defaults to 0.\n if (isSmallInt(p)) return `Number((${rawAccess} ?? 0n) as bigint)`\n switch (p) {\n // Wide integers stay bigint end-to-end.\n case 'u64':\n case 'u128':\n case 'i64':\n case 'i128':\n return `${rawAccess} as bigint`\n // Literal types with a suffix: runtime parsers may deliver these as bigint\n // (suffix stripped) or as the canonical suffixed string — normalize to the\n // canonical string form (e.g. 123n → \"123field\").\n case 'field':\n case 'group':\n case 'scalar':\n return `litStr(${rawAccess}, '${p}')`\n case 'address':\n case 'signature':\n case 'identifier':\n return `${rawAccess} as string`\n case 'boolean':\n return `${rawAccess} as boolean`\n default:\n return rawAccess\n }\n}\n\nfunction plaintextDefault(pt: Plaintext): string {\n // TODO(follow-up): see plaintextFieldExpr for the known array/optional gap.\n // Non-primitive record fields fall through to \"''\" (empty string default).\n if (pt.kind !== 'primitive') return \"''\"\n if (isSmallInt(pt.primitive)) return '0'\n switch (pt.primitive) {\n case 'boolean':\n return 'false'\n // Wide integers — bigint default\n case 'u64': case 'u128': case 'i64': case 'i128':\n return '0n'\n case 'field': case 'group': case 'scalar':\n return \"''\"\n case 'address': case 'signature': case 'identifier':\n return \"''\"\n default:\n return \"''\"\n }\n}\n\n// ── ABI constant + contract factory ───────────────────────────────────\n\nfunction generateAbiConstant(abi: ABI): string[] {\n // Embed the already-parsed ABI as a typed constant.\n // This avoids a round-trip through parseAbi at runtime.\n return [\n `/** The parsed ABI for ${abi.program}. */`,\n `export const PROGRAM_ABI: ABI = ${JSON.stringify(abi, null, 2)}`,\n ]\n}\n\n/** Generate named param type string for a function's inputs */\nfunction namedParamsType(fn: AbiFunction, abi: ABI): string {\n if (fn.inputs.length === 0) return '{}'\n const params = fn.inputs.map((input) => {\n const name = input.name ?? `arg${fn.inputs.indexOf(input)}`\n let tsType: string\n if (input.type.kind === 'plaintext') {\n tsType = plaintextToTsType(input.type.type)\n } else if (input.type.kind === 'record') {\n const recName = input.type.path[input.type.path.length - 1] ?? 'RecordValue'\n const isLocal = !input.type.program || input.type.program.replace(/\\.aleo$/, '') === abi.program.replace(/\\.aleo$/, '')\n tsType = isLocal ? `${recName} | RecordValue | string` : 'RecordValue | string'\n } else {\n tsType = 'RecordValue | string'\n }\n // Also accept an InputRequest in every slot (wallet-fulfilled input).\n return `${name}: ${tsType} | InputRequest`\n })\n return `{ ${params.join(', ')} }`\n}\n\n/** Generate the typed return type for simulate */\nfunction simulateReturnType(fn: AbiFunction, abi: ABI): string {\n if (fn.outputs.length === 0) return 'void'\n if (fn.outputs.length === 1) return outputToTsType(fn.outputs[0].type, abi)\n return `[${fn.outputs.map((o) => outputToTsType(o.type, abi)).join(', ')}]`\n}\n\n/** Generate the typed return type for execute (includes transactionId) */\nfunction executeReturnType(fn: AbiFunction, abi: ABI): string {\n const simType = simulateReturnType(fn, abi)\n if (simType === 'void') return '{ transactionId: string }'\n return `{ transactionId: string, result: ${simType} }`\n}\n\n/** Generate the input names array for converting named params to positional */\nfunction inputNames(fn: AbiFunction): string[] {\n return fn.inputs.map((input, i) => input.name ?? `arg${i}`)\n}\n\n/**\n * For record inputs, generate resolution lines that extract _record from typed records.\n * Returns { resolveLines: string[], resolvedNames: string[] }.\n * resolvedNames replaces record input names with their resolved versions.\n */\nfunction resolveRecordInputs(fn: AbiFunction): { resolveLines: string[], resolvedNames: string[] } {\n const resolveLines: string[] = []\n const resolvedNames: string[] = []\n\n for (let i = 0; i < fn.inputs.length; i++) {\n const input = fn.inputs[i]\n const name = input.name ?? `arg${i}`\n\n if (input.type.kind === 'record' || input.type.kind === 'dynamicRecord') {\n resolveLines.push(` const _${name} = ${name}?._record ?? ${name}`)\n resolvedNames.push(`_${name}`)\n } else {\n resolvedNames.push(name)\n }\n }\n\n return { resolveLines, resolvedNames }\n}\n\n/** Generate output mapper expression for a single output at index i */\nfunction outputMapperExpr(output: AbiFunction['outputs'][number], i: number, abi: ABI): string {\n if (output.type.kind === 'record') {\n const recName = output.type.path[output.type.path.length - 1] ?? ''\n const isLocal = !output.type.program || output.type.program.replace(/\\.aleo$/, '') === abi.program.replace(/\\.aleo$/, '')\n // Double-cast through unknown: result.outputs[i] is ParsedOutput | undefined under\n // noUncheckedIndexedAccess. The cast to unknown then to RecordValue is intentional —\n // the ABI guarantees this output is a record at this position.\n if (isLocal && recName) {\n return `to${recName}(result.outputs[${i}] as unknown as RecordValue)`\n }\n return `result.outputs[${i}] as unknown as RecordValue`\n }\n if (output.type.kind === 'plaintext') {\n return `result.outputs[${i}] as unknown as ${plaintextToTsType(output.type.type)}`\n }\n if (output.type.kind === 'future' || output.type.kind === 'dynamicFuture') {\n return `result.outputs[${i}] as unknown as FutureValue`\n }\n return `result.outputs[${i}]`\n}\n\nfunction generateContractFactory(abi: ABI): string[] {\n const programName = abi.program\n const factoryName = pascalCase(programName.replace('.aleo', ''))\n const lines: string[] = []\n\n // Generate typed interface with named params and typed returns\n lines.push(`export interface ${factoryName}Contract {`)\n lines.push(` program: string`)\n lines.push(` abi: ABI`)\n\n // read methods\n if (abi.mappings.length > 0) {\n lines.push(` read: {`)\n for (const mapping of abi.mappings) {\n const keyType = plaintextToTsType(mapping.key)\n lines.push(` ${mapping.name}: (params: { key: ${keyType} }) => Promise<unknown>`)\n }\n lines.push(` }`)\n } else {\n lines.push(` read: Record<string, (params: { key: string }) => Promise<unknown>>`)\n }\n\n // write methods — named params, returns tx ID\n if (abi.functions.length > 0) {\n lines.push(` write: {`)\n for (const fn of abi.functions) {\n const params = namedParamsType(fn, abi)\n lines.push(` ${fn.name}: (params: ${params}) => Promise<string>`)\n }\n lines.push(` }`)\n }\n\n // simulate methods — named params, typed return\n if (abi.functions.length > 0) {\n lines.push(` simulate: {`)\n for (const fn of abi.functions) {\n const params = namedParamsType(fn, abi)\n const retType = simulateReturnType(fn, abi)\n lines.push(` ${fn.name}: (params: ${params}) => Promise<${retType}>`)\n }\n lines.push(` }`)\n }\n\n // execute methods — named params, typed return + transactionId.\n // Fee belongs in proving config, not per-call params — do not add fee here.\n if (abi.functions.length > 0) {\n lines.push(` execute: {`)\n for (const fn of abi.functions) {\n const params = namedParamsType(fn, abi)\n const retType = executeReturnType(fn, abi)\n lines.push(` ${fn.name}: (params: ${params}) => Promise<${retType}>`)\n }\n lines.push(` }`)\n }\n\n lines.push(` fetchAbi: () => Promise<ABI>`)\n lines.push(`}`)\n lines.push('')\n\n // Generate factory with wrapper methods\n lines.push(`export function create${factoryName}Contract(options: {`)\n lines.push(` publicClient?: PublicClient,`)\n lines.push(` walletClient?: WalletClient,`)\n lines.push(` programSource?: string,`)\n lines.push(` imports?: Record<string, string>,`)\n lines.push(`}): ${factoryName}Contract {`)\n lines.push(` if (!options.publicClient && !options.walletClient) throw new Error('At least one of publicClient or walletClient is required')`)\n lines.push(` const client = options.publicClient && options.walletClient`)\n lines.push(` ? { public: options.publicClient, wallet: options.walletClient }`)\n lines.push(` : (options.publicClient ?? options.walletClient)!`)\n lines.push(` const raw = getContract({ program: PROGRAM_ID, abi: PROGRAM_ABI, client, programSource: options.programSource, imports: options.imports })`)\n // Proxy method access is typed as Record<string, fn> whose properties are\n // T | undefined under noUncheckedIndexedAccess. Cast to any for the internal\n // wrappers — the typed factory interface above is what consumers see.\n lines.push(` const _raw = raw as any`)\n lines.push('')\n lines.push(` return {`)\n lines.push(` program: raw.program,`)\n lines.push(` abi: raw.abi as ABI,`)\n lines.push(` read: _raw.read as ${factoryName}Contract['read'],`)\n\n // write wrappers — convert named params to positional inputs\n if (abi.functions.length > 0) {\n lines.push(` write: {`)\n for (const fn of abi.functions) {\n const names = inputNames(fn)\n const { resolveLines, resolvedNames } = resolveRecordInputs(fn)\n lines.push(` ${fn.name}: (params: any) => {`)\n if (names.length > 0) lines.push(` const { ${names.join(', ')} } = params`)\n for (const line of resolveLines) lines.push(line)\n lines.push(` return _raw.write.${fn.name}({ inputs: [${resolvedNames.join(', ')}] })`)\n lines.push(` },`)\n }\n lines.push(` },`)\n }\n\n // simulate wrappers — convert named params to positional, map outputs to typed returns\n if (abi.functions.length > 0) {\n lines.push(` simulate: {`)\n for (const fn of abi.functions) {\n const names = inputNames(fn)\n const { resolveLines, resolvedNames } = resolveRecordInputs(fn)\n lines.push(` ${fn.name}: async (params: any) => {`)\n if (names.length > 0) lines.push(` const { ${names.join(', ')} } = params`)\n for (const line of resolveLines) lines.push(line)\n\n if (fn.outputs.length === 0) {\n lines.push(` await _raw.simulate.${fn.name}({ inputs: [${resolvedNames.join(', ')}] })`)\n } else {\n lines.push(` const result = await _raw.simulate.${fn.name}({ inputs: [${resolvedNames.join(', ')}] })`)\n }\n\n if (fn.outputs.length === 0) {\n // void return\n } else if (fn.outputs.length === 1) {\n lines.push(` return ${outputMapperExpr(fn.outputs[0], 0, abi)}`)\n } else {\n const mappers = fn.outputs.map((o, i) => outputMapperExpr(o, i, abi))\n lines.push(` return [${mappers.join(', ')}] as const`)\n }\n\n lines.push(` },`)\n }\n lines.push(` },`)\n }\n\n // execute wrappers — same as simulate but includes transactionId\n if (abi.functions.length > 0) {\n lines.push(` execute: {`)\n for (const fn of abi.functions) {\n const names = inputNames(fn)\n const { resolveLines, resolvedNames } = resolveRecordInputs(fn)\n lines.push(` ${fn.name}: async (params: any) => {`)\n if (names.length > 0) lines.push(` const { ${names.join(', ')} } = params`)\n for (const line of resolveLines) lines.push(line)\n lines.push(` const result = await _raw.execute.${fn.name}({ inputs: [${resolvedNames.join(', ')}] })`)\n\n if (fn.outputs.length === 0) {\n lines.push(` return { transactionId: result.transactionId }`)\n } else if (fn.outputs.length === 1) {\n lines.push(` return { transactionId: result.transactionId, result: ${outputMapperExpr(fn.outputs[0], 0, abi)} }`)\n } else {\n const mappers = fn.outputs.map((o, i) => outputMapperExpr(o, i, abi))\n lines.push(` return { transactionId: result.transactionId, result: [${mappers.join(', ')}] as const }`)\n }\n\n lines.push(` },`)\n }\n lines.push(` },`)\n }\n\n lines.push(` fetchAbi: _raw.fetchAbi as unknown as ${factoryName}Contract['fetchAbi'],`)\n lines.push(` }`)\n lines.push(`}`)\n\n return lines\n}\n\n// ── Utility ───────────────────────────────────────────────────────────\n\nfunction recordName(record: RecordDef): string {\n return record.path[record.path.length - 1] ?? 'UnknownRecord'\n}\n\nfunction pascalCase(s: string): string {\n return s\n .split('_')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('')\n}\n"],"mappings":"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","names":[]}
|