@provablehq/veil-codegen 0.5.0 → 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 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
- Reach for it as a package maintainer, not a consumer: point it at a program's
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
- and struct decoders (`RecordValue` → typed interface), per-function input and
9
- output types, mapping and storage types, the parsed `PROGRAM_ABI` constant, and
10
- a typed contract factory (`read`/`write`/`simulate`/`execute`). A package like
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
- lines.push(`import { getContract } from '${coreImport}'`);
9
- lines.push(`import type { RecordValue, FutureValue, PublicClient, WalletClient, ABI, InputRequest, PlaintextValue } from '${coreImport}'`);
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(...generateStructMapper(struct));
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(...generateRecordMapper(record));
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 mapperFieldLines(fields, container, fieldsVar) {
86
+ function generateFieldConversions(fields, container, access) {
80
87
  const lines = [];
81
88
  for (const field of fields) {
82
- if (field.name === "owner") continue;
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}: ${fieldsVar}.${field.name}?.value as unknown as ${structName} ?? {} as unknown as ${structName},`);
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 generateRecordMapper(record) {
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(...mapperFieldLines(record.fields, name, "fields"));
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 generateStructMapper(struct) {
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: RecordValue): ${name} {`);
132
+ lines.push(`export function to${name}(value: StructValue): ${name} {`);
119
133
  lines.push(` return {`);
120
- lines.push(...mapperFieldLines(struct.fields, name, "value.fields"));
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" || output.kind === "dynamicFuture") {
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 = plaintextToTsType(mapping.key);
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 outputMapperExpr(output, i, abi) {
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" || output.type.kind === "dynamicFuture") {
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 keyType = plaintextToTsType(mapping.key);
368
- lines.push(` ${mapping.name}: (params: { key: ${keyType} }) => Promise<unknown>`);
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<unknown>>`);
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
- lines.push(` read: _raw.read as ${factoryName}Contract['read'],`);
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 ${outputMapperExpr(fn.outputs[0], 0, abi)}`);
554
+ lines.push(` return ${generateOutputDecodeExpr(fn.outputs[0], 0, abi)}`);
449
555
  } else {
450
- const mappers = fn.outputs.map((o, i) => outputMapperExpr(o, i, abi));
451
- lines.push(` return [${mappers.join(", ")}] as const`);
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: ${outputMapperExpr(fn.outputs[0], 0, abi)} }`);
575
+ lines.push(` return { transactionId: result.transactionId, result: ${generateOutputDecodeExpr(fn.outputs[0], 0, abi)} }`);
470
576
  } else {
471
- const mappers = fn.outputs.map((o, i) => outputMapperExpr(o, i, abi));
472
- lines.push(` return { transactionId: result.transactionId, result: [${mappers.join(", ")}] as const }`);
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-OU67QL3U.js.map
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
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  generate
4
- } from "./chunk-OU67QL3U.js";
4
+ } from "./chunk-OQWGO46H.js";
5
5
 
6
6
  // src/cli.ts
7
7
  import { readFileSync, writeFileSync, mkdirSync } from "fs";
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 mapper functions (RecordValue → typed interface)
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
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  generate
3
- } from "./chunk-OU67QL3U.js";
3
+ } from "./chunk-OQWGO46H.js";
4
4
  export {
5
5
  generate
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@provablehq/veil-codegen",
3
- "version": "0.5.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.5.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-leo": "0.5.0",
41
- "@provablehq/veil-aleo-devnode": "0.5.0",
42
- "@provablehq/veil-aleo-sdk": "0.5.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":[]}