gen-typescript-from-tolk-dev 0.3.1 → 0.3.3

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.
@@ -145,10 +145,12 @@ export interface ABIStruct {
145
145
  fields: {
146
146
  name: string;
147
147
  ty_idx: number;
148
+ client_ty_idx?: number;
148
149
  default_value?: ABIConstExpression;
149
150
  description?: string;
150
151
  }[];
151
152
  custom_pack_unpack?: ABICustomSerializers;
153
+ description?: string;
152
154
  }
153
155
  export interface ABIAlias {
154
156
  kind: 'alias';
@@ -157,6 +159,7 @@ export interface ABIAlias {
157
159
  target_ty_idx: number;
158
160
  type_params?: string[];
159
161
  custom_pack_unpack?: ABICustomSerializers;
162
+ description?: string;
160
163
  }
161
164
  export interface ABIEnum {
162
165
  kind: 'enum';
@@ -168,6 +171,7 @@ export interface ABIEnum {
168
171
  value: bigint_as_string;
169
172
  }[];
170
173
  custom_pack_unpack?: ABICustomSerializers;
174
+ description?: string;
171
175
  }
172
176
  export interface ABIStructInstantiation {
173
177
  ty_idx: number;
package/dist/abi.d.ts CHANGED
@@ -13,20 +13,16 @@ export interface ABIGetMethod {
13
13
  }
14
14
  export interface ABIInternalMessage {
15
15
  body_ty_idx: number;
16
- description?: string;
17
16
  }
18
17
  export interface ABIExternalMessage {
19
18
  body_ty_idx: number;
20
- description?: string;
21
19
  }
22
20
  export interface ABIOutgoingMessage {
23
21
  body_ty_idx: number;
24
- description?: string;
25
22
  }
26
23
  export interface ABIStorage {
27
24
  storage_ty_idx?: number;
28
25
  storage_at_deployment_ty_idx?: number;
29
- description?: string;
30
26
  }
31
27
  export interface ABIThrownError {
32
28
  kind: 'plain_int' | 'constant' | 'enum_member';
@@ -109,7 +109,7 @@ function debugFormat(ctx, r, fieldPath, tyIdx, unTupleIfW = false) {
109
109
  return `${ty.enum_name}(${value})`;
110
110
  }
111
111
  case 'StructRef': {
112
- let fields = ctx.symbols.structFieldsOf(tyIdx);
112
+ let fields = ctx.symbols.structFieldsOf(tyIdx, true);
113
113
  if (fields.length === 0) {
114
114
  return `${ty.struct_name} {}`;
115
115
  }
@@ -290,7 +290,7 @@ function dynamicConstruct(ctx, fieldPath, tyIdx, v, tupleIfW = false, uLabelTyId
290
290
  }
291
291
  case 'StructRef': {
292
292
  (0, dynamic_validation_1.checkIsObject)(ctx, fieldPath, tyIdx, v);
293
- return ctx.symbols.structFieldsOf(tyIdx).flatMap(f => dynamicConstruct(ctx, `${fieldPath}.${f.name}`, f.ty_idx, v[f.name], false, f.uLabelTyIdx));
293
+ return ctx.symbols.structFieldsOf(tyIdx, true).flatMap(f => dynamicConstruct(ctx, `${fieldPath}.${f.name}`, f.ty_idx, v[f.name], false, f.uLabelTyIdx));
294
294
  }
295
295
  case 'AliasRef': {
296
296
  const target = ctx.symbols.aliasTargetOf(tyIdx);
@@ -395,7 +395,7 @@ function dynamicParse(ctx, r, fieldPath, tyIdx, unTupleIfW = false, uLabelTyIdx)
395
395
  case 'EnumRef': return r.readBigInt();
396
396
  case 'StructRef': {
397
397
  let result = { $: ty.struct_name };
398
- for (let f of ctx.symbols.structFieldsOf(tyIdx)) {
398
+ for (let f of ctx.symbols.structFieldsOf(tyIdx, true)) {
399
399
  result[f.name] = dynamicParse(ctx, r, `${fieldPath}.${f.name}`, f.ty_idx, false, f.uLabelTyIdx);
400
400
  }
401
401
  return result;
@@ -244,7 +244,7 @@ function dynamicPack(ctx, fieldPath, tyIdx, v, b, uLabelTyIdx) {
244
244
  if (structRef.prefix) {
245
245
  b.storeUint(structRef.prefix.prefix_num, structRef.prefix.prefix_len);
246
246
  }
247
- for (let f of ctx.symbols.structFieldsOf(tyIdx)) {
247
+ for (let f of ctx.symbols.structFieldsOf(tyIdx, false)) {
248
248
  try {
249
249
  dynamicPack(ctx, `${fieldPath}.${f.name}`, f.ty_idx, v[f.name], b, f.uLabelTyIdx);
250
250
  }
@@ -387,7 +387,7 @@ function dynamicUnpack(ctx, fieldPath, tyIdx, s, uLabelTyIdx) {
387
387
  throw new unsupported_errors_1.CantUnpackDynamic(fieldPath, `incorrect prefix for '${ty.struct_name}', expected ${(0, emit_ts_types_1.emitPrefixHex)(structRef.prefix)}`);
388
388
  }
389
389
  }
390
- for (let f of ctx.symbols.structFieldsOf(tyIdx)) {
390
+ for (let f of ctx.symbols.structFieldsOf(tyIdx, false)) {
391
391
  try {
392
392
  result[f.name] = dynamicUnpack(ctx, `${fieldPath}.${f.name}`, f.ty_idx, s, f.uLabelTyIdx);
393
393
  }
@@ -34,7 +34,7 @@ function emitLoadOfStruct(ctx, structRef, instantiationTyIdx) {
34
34
  }
35
35
  buf.push(`return {`);
36
36
  buf.push(`$: '${structRef.name}',`);
37
- for (let f of ctx.symbols.structFieldsOf(instantiationTyIdx)) {
37
+ for (let f of ctx.symbols.structFieldsOf(instantiationTyIdx, false)) {
38
38
  buf.push(`${(0, formatting_1.safeFieldDecl)(f.name)}: ${emitLoadExpr(ctx, `${(0, formatting_1.safeJsIdent)(structRef.name)}${(0, formatting_1.safeFieldRead)(f.name)}`, f.ty_idx, f.uLabelTyIdx)},`);
39
39
  }
40
40
  buf.push('}');
@@ -89,9 +89,9 @@ function emitLoadExpr(ctx, fieldPath, tyIdx, uLabelTyIdx) {
89
89
  case 'nullLiteral': return `null`;
90
90
  case 'void': return `void 0`;
91
91
  case 'nullable': return `s.loadBoolean() ? ${emitLoadExpr(ctx, fieldPath, ty.inner_ty_idx)} : null`;
92
- case 'cellOf': return `${codegen_ctx_1.RUNTIME.loadCellRef}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(s, ${emitLoadCallback(ctx, fieldPath, ty.inner_ty_idx)})`;
93
- case 'arrayOf': return `${codegen_ctx_1.RUNTIME.loadArrayOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(s, ${emitLoadCallback(ctx, fieldPath + '[ith]', ty.inner_ty_idx)})`;
94
- case 'lispListOf': return `${codegen_ctx_1.RUNTIME.loadLispListOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(s, ${emitLoadCallback(ctx, fieldPath + '[ith]', ty.inner_ty_idx)})`;
92
+ case 'cellOf': return `${codegen_ctx_1.RUNTIME.loadCellRef}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx, false)}>(s, ${emitLoadCallback(ctx, fieldPath, ty.inner_ty_idx)})`;
93
+ case 'arrayOf': return `${codegen_ctx_1.RUNTIME.loadArrayOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx, false)}>(s, ${emitLoadCallback(ctx, fieldPath + '[ith]', ty.inner_ty_idx)})`;
94
+ case 'lispListOf': return `${codegen_ctx_1.RUNTIME.loadLispListOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx, false)}>(s, ${emitLoadCallback(ctx, fieldPath + '[ith]', ty.inner_ty_idx)})`;
95
95
  case 'tensor': return `[${ty.items_ty_idx.map((ty_idx, i) => emitLoadExpr(ctx, `${fieldPath}[${i}]`, ty_idx)).join(', ')}]`;
96
96
  case 'shapedTuple': return `[${ty.items_ty_idx.map((ty_idx, i) => emitLoadExpr(ctx, `${fieldPath}[${i}]`, ty_idx)).join(', ')}]`;
97
97
  case 'mapKV': return `c.Dictionary.load<${(0, emit_ts_types_1.emitDictKVTypeArgs)(ctx, ty.key_ty_idx, ty.value_ty_idx)}>(${emitDictKVSerializers(ctx, fieldPath, ty.key_ty_idx, ty.value_ty_idx)}, s)`;
@@ -113,7 +113,9 @@ function emitLoadExpr(ctx, fieldPath, tyIdx, uLabelTyIdx) {
113
113
  case 'genericT': throw new Error(`unexpected genericT=${ty.name_t} at ${fieldPath}`);
114
114
  case 'union': {
115
115
  const variants = (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants, uLabelTyIdx);
116
- const isEither01 = variants.length === 2 && variants[0].prefix_num === 0 && variants[1].prefix_num === 1;
116
+ const isEither01 = variants.length === 2
117
+ && variants[0].is_prefix_implicit && variants[1].is_prefix_implicit
118
+ && variants[0].prefix_num === 0 && variants[1].prefix_num === 1;
117
119
  if (isEither01) {
118
120
  const l = (0, emit_ts_types_1.emitUnionLabelAndValue)(variants[0], emitLoadExpr(ctx, fieldPath, variants[0].variant_ty_idx));
119
121
  const r = (0, emit_ts_types_1.emitUnionLabelAndValue)(variants[1], emitLoadExpr(ctx, fieldPath, variants[1].variant_ty_idx));
@@ -165,7 +167,7 @@ function emitStoreOfStruct(ctx, tsExpr, structRef, instantiationTyIdx) {
165
167
  if (structRef.prefix) {
166
168
  buf.push(`b.storeUint(${(0, emit_ts_types_1.emitPrefixHex)(structRef.prefix)}, ${structRef.prefix.prefix_len});`);
167
169
  }
168
- for (let f of ctx.symbols.structFieldsOf(instantiationTyIdx)) {
170
+ for (let f of ctx.symbols.structFieldsOf(instantiationTyIdx, false)) {
169
171
  buf.push(emitStoreStatement(ctx, `${tsExpr}${(0, formatting_1.safeFieldRead)(f.name)}`, f.ty_idx, f.uLabelTyIdx));
170
172
  }
171
173
  return buf.toString();
@@ -215,10 +217,10 @@ function emitStoreStatement(ctx, tsExpr, tyIdx, uLabelTyIdx) {
215
217
  case 'addressAny': return `${codegen_ctx_1.RUNTIME.storeTolkAddressAny}(${tsExpr}, b);`;
216
218
  case 'bitsN': return `${codegen_ctx_1.RUNTIME.storeTolkBitsN}(${tsExpr}, ${ty.n}, b);`;
217
219
  case 'void': return ``;
218
- case 'nullable': return `${codegen_ctx_1.RUNTIME.storeTolkNullable}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner_ty_idx)});`;
219
- case 'cellOf': return `${codegen_ctx_1.RUNTIME.storeCellRef}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner_ty_idx)});`;
220
- case 'arrayOf': return `${codegen_ctx_1.RUNTIME.storeArrayOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner_ty_idx)});`;
221
- case 'lispListOf': return `${codegen_ctx_1.RUNTIME.storeLispListOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner_ty_idx)});`;
220
+ case 'nullable': return `${codegen_ctx_1.RUNTIME.storeTolkNullable}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx, false)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner_ty_idx)});`;
221
+ case 'cellOf': return `${codegen_ctx_1.RUNTIME.storeCellRef}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx, false)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner_ty_idx)});`;
222
+ case 'arrayOf': return `${codegen_ctx_1.RUNTIME.storeArrayOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx, false)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner_ty_idx)});`;
223
+ case 'lispListOf': return `${codegen_ctx_1.RUNTIME.storeLispListOf}<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx, false)}>(${tsExpr}, b, ${emitStoreCallback(ctx, ty.inner_ty_idx)});`;
222
224
  case 'tensor': return ty.items_ty_idx.length ? ty.items_ty_idx.map((ty_idx, i) => emitStoreStatement(ctx, `${tsExpr}[${i}]`, ty_idx)).join('\n') : `{}`;
223
225
  case 'shapedTuple': return ty.items_ty_idx.length ? ty.items_ty_idx.map((ty_idx, i) => emitStoreStatement(ctx, `${tsExpr}[${i}]`, ty_idx)).join('\n') : `{}`;
224
226
  case 'mapKV': return `b.storeDict<${(0, emit_ts_types_1.emitDictKVTypeArgs)(ctx, ty.key_ty_idx, ty.value_ty_idx)}>(${tsExpr}, ${emitDictKVSerializers(ctx, tsExpr, ty.key_ty_idx, ty.value_ty_idx)});`;
@@ -295,7 +297,7 @@ function emitStoreCallback(ctx, tyIdx) {
295
297
  // Parameter `tsExpr` is a valid expression: "self.field", "v" (inside a callback), and other.
296
298
  function emitMakeCellFromExpr(ctx, tsExpr, tyIdx, disableShortHand = false) {
297
299
  if (disableShortHand) {
298
- return `${codegen_ctx_1.RUNTIME.makeCellFrom}<${(0, emit_ts_types_1.emitTsType)(ctx, tyIdx)}>(${tsExpr}, ${emitStoreCallback(ctx, tyIdx)})`;
300
+ return `${codegen_ctx_1.RUNTIME.makeCellFrom}<${(0, emit_ts_types_1.emitTsType)(ctx, tyIdx, false)}>(${tsExpr}, ${emitStoreCallback(ctx, tyIdx)})`;
299
301
  }
300
302
  const ty = ctx.symbols.tyByIdx(tyIdx);
301
303
  switch (ty.kind) {
@@ -324,12 +326,12 @@ function emitMakeCellFromExpr(ctx, tsExpr, tyIdx, disableShortHand = false) {
324
326
  function emitCallToCreateMethodExpr(ctx, bodyArg, tyIdx) {
325
327
  const ty = ctx.symbols.tyByIdx(tyIdx);
326
328
  if (ty.kind === 'StructRef') {
327
- let fields = ctx.symbols.structFieldsOf(tyIdx);
329
+ let fields = ctx.symbols.structFieldsOf(tyIdx, false);
328
330
  if (fields.length === 0) {
329
331
  bodyArg = ''; // create() is without arguments, body is an empty object
330
332
  }
331
333
  if (ty.type_args_ty_idx) {
332
- return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.create<${ty.type_args_ty_idx.map(ty_idx => (0, emit_ts_types_1.emitTsType)(ctx, ty_idx)).join(', ')}>(${bodyArg})`;
334
+ return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.create<${ty.type_args_ty_idx.map(ty_idx => (0, emit_ts_types_1.emitTsType)(ctx, ty_idx, false)).join(', ')}>(${bodyArg})`;
333
335
  }
334
336
  return `${(0, formatting_1.safeJsIdent)(ty.struct_name)}.create(${bodyArg})`;
335
337
  }
@@ -364,7 +366,7 @@ function emitDictValueSerializer(ctx, fieldPath, tyVIdx) {
364
366
  if (tyV.kind === 'cell')
365
367
  return `c.Dictionary.Values.Cell()`;
366
368
  ctx.has_customDictV = true;
367
- return `${codegen_ctx_1.RUNTIME.createDictionaryValue}<${(0, emit_ts_types_1.emitTsType)(ctx, tyVIdx)}>(${emitLoadCallback(ctx, fieldPath, tyVIdx)}, ${emitStoreCallback(ctx, tyVIdx)})`;
369
+ return `${codegen_ctx_1.RUNTIME.createDictionaryValue}<${(0, emit_ts_types_1.emitTsType)(ctx, tyVIdx, false)}>(${emitLoadCallback(ctx, fieldPath, tyVIdx)}, ${emitStoreCallback(ctx, tyVIdx)})`;
368
370
  }
369
371
  // Emit (de)serializers for c.Dictionary<K, V> (two arguments separated by a comma).
370
372
  function emitDictKVSerializers(ctx, fieldPath, tyKIdx, tyVIdx) {
@@ -28,7 +28,7 @@ function emitStackReadExpr(ctx, fieldPath, tyIdx, unTupleIfW = false, uLabelTyId
28
28
  if (unTupleIfW) { // inside `array<T>` or `[T, ...]`, if T is non-primitive, it's a sub-tuple
29
29
  let wOnStack = (0, types_kernel_1.calcWidthOnStack)(ctx.symbols, tyIdx);
30
30
  if (wOnStack !== 1) {
31
- return `r.readTuple<${(0, emit_ts_types_1.emitTsType)(ctx, tyIdx)}>(${wOnStack}, ${emitStackReadCallback(ctx, fieldPath, tyIdx, false, uLabelTyIdx)})`;
31
+ return `r.readTuple<${(0, emit_ts_types_1.emitTsType)(ctx, tyIdx, true)}>(${wOnStack}, ${emitStackReadCallback(ctx, fieldPath, tyIdx, false, uLabelTyIdx)})`;
32
32
  }
33
33
  }
34
34
  switch (ty.kind) {
@@ -55,13 +55,13 @@ function emitStackReadExpr(ctx, fieldPath, tyIdx, unTupleIfW = false, uLabelTyId
55
55
  case 'unknown': return `r.readUnknown()`;
56
56
  case 'nullable': {
57
57
  if (ty.stack_type_id) {
58
- return `r.readWideNullable<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${ty.stack_width}, ${emitStackReadCallback(ctx, fieldPath, ty.inner_ty_idx, false)})`;
58
+ return `r.readWideNullable<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx, true)}>(${ty.stack_width}, ${emitStackReadCallback(ctx, fieldPath, ty.inner_ty_idx, false)})`;
59
59
  }
60
- return `r.readNullable<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${emitStackReadCallback(ctx, fieldPath, ty.inner_ty_idx, false)})`;
60
+ return `r.readNullable<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx, true)}>(${emitStackReadCallback(ctx, fieldPath, ty.inner_ty_idx, false)})`;
61
61
  }
62
- case 'cellOf': return `r.readCellRef<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${(0, emit_pack_unpack_1.emitLoadCallback)(ctx, fieldPath + '.ref', ty.inner_ty_idx)})`;
63
- case 'arrayOf': return `r.readArrayOf<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${emitStackReadCallback(ctx, fieldPath, ty.inner_ty_idx, true)})`;
64
- case 'lispListOf': return `r.readLispListOf<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx)}>(${emitStackReadCallback(ctx, fieldPath, ty.inner_ty_idx, true)})`;
62
+ case 'cellOf': return `r.readCellRef<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx, false)}>(${(0, emit_pack_unpack_1.emitLoadCallback)(ctx, fieldPath + '.ref', ty.inner_ty_idx)})`;
63
+ case 'arrayOf': return `r.readArrayOf<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx, true)}>(${emitStackReadCallback(ctx, fieldPath, ty.inner_ty_idx, true)})`;
64
+ case 'lispListOf': return `r.readLispListOf<${(0, emit_ts_types_1.emitTsType)(ctx, ty.inner_ty_idx, true)}>(${emitStackReadCallback(ctx, fieldPath, ty.inner_ty_idx, true)})`;
65
65
  case 'tensor': {
66
66
  let buf = new formatting_1.OutBuf();
67
67
  buf.push(`[`);
@@ -73,7 +73,7 @@ function emitStackReadExpr(ctx, fieldPath, tyIdx, unTupleIfW = false, uLabelTyId
73
73
  }
74
74
  case 'shapedTuple': {
75
75
  let buf = new formatting_1.OutBuf();
76
- buf.push(`r.readTuple<${(0, emit_ts_types_1.emitTsType)(ctx, tyIdx)}>(${ty.items_ty_idx.length}, (r) => [`);
76
+ buf.push(`r.readTuple<${(0, emit_ts_types_1.emitTsType)(ctx, tyIdx, true)}>(${ty.items_ty_idx.length}, (r) => [`);
77
77
  for (let i = 0; i < ty.items_ty_idx.length; ++i) {
78
78
  buf.push(emitStackReadExpr(ctx, `${fieldPath}[${i}]`, ty.items_ty_idx[i], true) + ',');
79
79
  }
@@ -86,7 +86,7 @@ function emitStackReadExpr(ctx, fieldPath, tyIdx, unTupleIfW = false, uLabelTyId
86
86
  let buf = new formatting_1.OutBuf();
87
87
  buf.push(`({`);
88
88
  buf.push(`$: '${ty.struct_name}',`);
89
- for (let f of ctx.symbols.structFieldsOf(tyIdx)) {
89
+ for (let f of ctx.symbols.structFieldsOf(tyIdx, true)) {
90
90
  buf.push(`${(0, formatting_1.safeFieldDecl)(f.name)}: ${emitStackReadExpr(ctx, `${fieldPath}.${f.name}`, f.ty_idx, false, f.uLabelTyIdx)},`);
91
91
  }
92
92
  buf.push(`})`);
@@ -103,7 +103,7 @@ function emitStackReadExpr(ctx, fieldPath, tyIdx, unTupleIfW = false, uLabelTyId
103
103
  }
104
104
  const variants = (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants, uLabelTyIdx);
105
105
  let buf = new formatting_1.OutBuf();
106
- let tsUniTypeStr = variants.map(v => (0, emit_ts_types_1.emitUnionLabelAndValue)(v, (0, emit_ts_types_1.emitTsType)(ctx, v.variant_ty_idx))).join(' | ');
106
+ let tsUniTypeStr = variants.map(v => (0, emit_ts_types_1.emitUnionLabelAndValue)(v, (0, emit_ts_types_1.emitTsType)(ctx, v.variant_ty_idx, true))).join(' | ');
107
107
  buf.push(`r.readUnionType<${tsUniTypeStr}>(${ty.stack_width}, {`);
108
108
  for (let v of variants) {
109
109
  buf.push(`${v.stack_type_id}: [${v.stack_width}, ${v.hasValueField ? `'${v.labelStr}'` : 'null'}, ${emitStackReadCallback(ctx, `${fieldPath}#${v.stack_type_id}`, v.variant_ty_idx, false, uLabelTyIdx)}],`);
@@ -198,7 +198,7 @@ function emitStackWriteItems(ctx, tsExpr, tyIdx, tupleIfW = false, uLabelTyIdx)
198
198
  case 'mapKV': return [`${tsExpr}.size === 0 ? { type: 'null' } : { type: 'cell', cell: ${codegen_ctx_1.RUNTIME.beginCell}().storeDictDirect<${(0, emit_ts_types_1.emitDictKVTypeArgs)(ctx, ty.key_ty_idx, ty.value_ty_idx)}>(${tsExpr}, ${(0, emit_pack_unpack_1.emitDictKVSerializers)(ctx, tsExpr, ty.key_ty_idx, ty.value_ty_idx)}).endCell() }`];
199
199
  case 'EnumRef': return [`{ type: 'int', value: ${tsExpr} }`];
200
200
  case 'StructRef': {
201
- return ctx.symbols.structFieldsOf(tyIdx).flatMap(f => emitStackWriteItems(ctx, `${tsExpr}${(0, formatting_1.safeFieldRead)(f.name)}`, f.ty_idx, false, f.uLabelTyIdx));
201
+ return ctx.symbols.structFieldsOf(tyIdx, true).flatMap(f => emitStackWriteItems(ctx, `${tsExpr}${(0, formatting_1.safeFieldRead)(f.name)}`, f.ty_idx, false, f.uLabelTyIdx));
202
202
  }
203
203
  case 'AliasRef': {
204
204
  const target = ctx.symbols.aliasTargetOf(tyIdx);
@@ -5,5 +5,5 @@ export declare function emitPrefixHex(prefix: {
5
5
  prefix_num: number;
6
6
  prefix_len: number;
7
7
  }): string;
8
- export declare function emitTsType(ctx: CodegenCtx, tyIdx: number): string;
8
+ export declare function emitTsType(ctx: CodegenCtx, tyIdx: number, isForStack: boolean): string;
9
9
  export declare function emitDictKVTypeArgs(ctx: CodegenCtx, tyKIdx: number, tyVIdx: number): string;
@@ -20,7 +20,7 @@ function emitPrefixHex(prefix) {
20
20
  // Convert any Tolk type (ABI representation) to a corresponding TypeScript type.
21
21
  // Tolk `int32` -> TS `bigint`, but for readability, `type int32 = bigint` is created.
22
22
  // `c.` is import @ton/core.
23
- function emitTsType(ctx, tyIdx) {
23
+ function emitTsType(ctx, tyIdx, isForStack) {
24
24
  const ty = ctx.symbols.tyByIdx(tyIdx);
25
25
  if (ty.kind === 'intN')
26
26
  ctx.intNOccurred.add(`int${ty.n}`);
@@ -62,21 +62,37 @@ function emitTsType(ctx, tyIdx) {
62
62
  case 'callable': return `any`;
63
63
  case 'void': return `void`;
64
64
  case 'unknown': return `c.TupleItem`;
65
- case 'nullable': return `${emitTsType(ctx, ty.inner_ty_idx)} | null`;
66
- case 'cellOf': return `CellRef<${emitTsType(ctx, ty.inner_ty_idx)}>`;
67
- case 'arrayOf': return `array<${emitTsType(ctx, ty.inner_ty_idx)}>`;
68
- case 'lispListOf': return `lisp_list<${emitTsType(ctx, ty.inner_ty_idx)}>`;
69
- case 'tensor': return `[${ty.items_ty_idx.map(ty_idx => emitTsType(ctx, ty_idx)).join(', ')}]`;
70
- case 'shapedTuple': return `[${ty.items_ty_idx.map(ty_idx => emitTsType(ctx, ty_idx)).join(', ')}]`;
65
+ case 'nullable': return `${emitTsType(ctx, ty.inner_ty_idx, isForStack)} | null`;
66
+ case 'cellOf': return `CellRef<${emitTsType(ctx, ty.inner_ty_idx, false)}>`;
67
+ case 'arrayOf': return `array<${emitTsType(ctx, ty.inner_ty_idx, isForStack)}>`;
68
+ case 'lispListOf': return `lisp_list<${emitTsType(ctx, ty.inner_ty_idx, isForStack)}>`;
69
+ case 'tensor': return `[${ty.items_ty_idx.map(ty_idx => emitTsType(ctx, ty_idx, isForStack)).join(', ')}]`;
70
+ case 'shapedTuple': return `[${ty.items_ty_idx.map(ty_idx => emitTsType(ctx, ty_idx, isForStack)).join(', ')}]`;
71
71
  case 'mapKV': return `c.Dictionary<${emitDictKVTypeArgs(ctx, ty.key_ty_idx, ty.value_ty_idx)}>`;
72
72
  case 'EnumRef': return (0, formatting_1.safeJsIdent)(ty.enum_name);
73
- case 'StructRef': return (0, formatting_1.safeJsIdent)(ty.struct_name) + (ty.type_args_ty_idx ? `<${ty.type_args_ty_idx.map(ty_idx => emitTsType(ctx, ty_idx)).join(', ')}>` : '');
74
- case 'AliasRef': return (0, formatting_1.safeJsIdent)(ty.alias_name) + (ty.type_args_ty_idx ? `<${ty.type_args_ty_idx.map(ty_idx => emitTsType(ctx, ty_idx)).join(', ')}>` : '');
73
+ case 'StructRef': {
74
+ const stackFields = ctx.symbols.structFieldsOf(tyIdx, true);
75
+ const anyFieldHasAbiClientType = stackFields.some(f => f.client_ty_idx !== undefined);
76
+ if (!isForStack || !anyFieldHasAbiClientType) {
77
+ return (0, formatting_1.safeJsIdent)(ty.struct_name) + (ty.type_args_ty_idx ? `<${ty.type_args_ty_idx.map(ty_idx => emitTsType(ctx, ty_idx, isForStack)).join(', ')}>` : '');
78
+ }
79
+ // On stack, @abi.clientType does not apply: getters return the original field types.
80
+ // The exported interface (serializable) uses client types, so emit an anonymous stack-shaped object.
81
+ const buf = new formatting_1.OutBuf();
82
+ buf.push(`{`);
83
+ buf.push(`readonly $: '${ty.struct_name}'`);
84
+ for (const f of stackFields) {
85
+ buf.push(`${(0, formatting_1.safeFieldDecl)(f.name)}: ${emitTsType(ctx, f.ty_idx, true)}`);
86
+ }
87
+ buf.push(`}`);
88
+ return buf.toString();
89
+ }
90
+ case 'AliasRef': return (0, formatting_1.safeJsIdent)(ty.alias_name) + (ty.type_args_ty_idx ? `<${ty.type_args_ty_idx.map(ty_idx => emitTsType(ctx, ty_idx, isForStack)).join(', ')}>` : '');
75
91
  case 'genericT': return ty.name_t;
76
- case 'union': return (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants).map(v => emitUnionLabelAndValue(v, emitTsType(ctx, v.variant_ty_idx))).join(' | ');
92
+ case 'union': return (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants).map(v => emitUnionLabelAndValue(v, emitTsType(ctx, v.variant_ty_idx, isForStack))).join(' | ');
77
93
  }
78
94
  }
79
95
  // Emit c.Dictionary<K, V> (K and V — inside brackets, two types separated by comma).
80
96
  function emitDictKVTypeArgs(ctx, tyKIdx, tyVIdx) {
81
- return emitTsType(ctx, tyKIdx) + ', ' + emitTsType(ctx, tyVIdx);
97
+ return emitTsType(ctx, tyKIdx, false) + ', ' + emitTsType(ctx, tyVIdx, false);
82
98
  }
@@ -56,9 +56,9 @@ function tolkStructToTypeScript(ctx, s, buf) {
56
56
  buf.push(renderStructDocComment(ctx, s));
57
57
  buf.push(`export interface ${structName}${genericTs} {`);
58
58
  buf.push(`readonly $: '${s.name}'`);
59
- for (const f of s.fields) {
59
+ for (const f of ctx.symbols.structFieldsOf(s.ty_idx, false)) {
60
60
  let comment = f.default_value ? ` /* = ${(0, emit_field_defs_1.emitFieldDefaultInComment)(ctx, f.default_value)} */` : '';
61
- buf.push(`${(0, formatting_1.safeFieldDecl)(f.name)}: ${(0, emit_ts_types_1.emitTsType)(ctx, f.ty_idx)}${comment}`);
61
+ buf.push(`${(0, formatting_1.safeFieldDecl)(f.name)}: ${(0, emit_ts_types_1.emitTsType)(ctx, f.ty_idx, false)}${comment}`);
62
62
  }
63
63
  buf.push('}');
64
64
  buf.emptyLine();
@@ -71,7 +71,7 @@ function tolkStructToTypeScript(ctx, s, buf) {
71
71
  buf.push(`create${genericTs}(${argsParam}): ${structName}${genericTs} {`);
72
72
  buf.push(`return {`);
73
73
  buf.push(`$: '${s.name}',`);
74
- for (let f of s.fields.filter(f => f.default_value && (0, emit_field_defs_1.isDefaultValueSupported)(ctx, f.ty_idx))) {
74
+ for (let f of ctx.symbols.structFieldsOf(s.ty_idx, false).filter(f => f.default_value && (0, emit_field_defs_1.isDefaultValueSupported)(ctx, f.ty_idx))) {
75
75
  let needAsAny = ctx.symbols.tyByIdx(f.ty_idx).kind === 'genericT';
76
76
  buf.push(`${(0, formatting_1.safeFieldDecl)(f.name)}: ${(0, emit_field_defs_1.emitFieldDefault)(ctx, f.default_value)}${needAsAny ? ' as any' : ''},`);
77
77
  }
@@ -118,12 +118,12 @@ function tolkAliasToTypeScript(ctx, a, buf) {
118
118
  if (targetTy.kind === 'union') {
119
119
  buf.push(`export type ${aliasName}${genericTs} =`).indent();
120
120
  for (const v of (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, targetTy.variants)) {
121
- buf.push('| ' + (0, emit_ts_types_1.emitUnionLabelAndValue)(v, (0, emit_ts_types_1.emitTsType)(ctx, v.variant_ty_idx)));
121
+ buf.push('| ' + (0, emit_ts_types_1.emitUnionLabelAndValue)(v, (0, emit_ts_types_1.emitTsType)(ctx, v.variant_ty_idx, false)));
122
122
  }
123
123
  buf.outdent();
124
124
  }
125
125
  else {
126
- buf.push(`export type ${aliasName}${genericTs} = ${(0, emit_ts_types_1.emitTsType)(ctx, a.target_ty_idx)}`);
126
+ buf.push(`export type ${aliasName}${genericTs} = ${(0, emit_ts_types_1.emitTsType)(ctx, a.target_ty_idx, false)}`);
127
127
  }
128
128
  if (ps) { // generic aliases don't have `fromSlice` and `store`
129
129
  return buf.toString();
@@ -191,9 +191,9 @@ function snakeCaseToCamelCase(snakeString) {
191
191
  function structParameterNoLabel(ctx, structTyIdx) {
192
192
  let declBuf = new formatting_1.OutBuf();
193
193
  declBuf.push(`{`);
194
- for (let f of ctx.symbols.structFieldsOf(structTyIdx)) {
194
+ for (let f of ctx.symbols.structFieldsOf(structTyIdx, false)) {
195
195
  let comment = f.default_value ? ` /* = ${(0, emit_field_defs_1.emitFieldDefaultInComment)(ctx, f.default_value)} */` : '';
196
- declBuf.push(`${(0, formatting_1.safeFieldDecl)(f.name)}${f.default_value && (0, emit_field_defs_1.isDefaultValueSupported)(ctx, f.ty_idx) ? '?' : ''}: ${(0, emit_ts_types_1.emitTsType)(ctx, f.ty_idx)}${comment}`);
196
+ declBuf.push(`${(0, formatting_1.safeFieldDecl)(f.name)}${f.default_value && (0, emit_field_defs_1.isDefaultValueSupported)(ctx, f.ty_idx) ? '?' : ''}: ${(0, emit_ts_types_1.emitTsType)(ctx, f.ty_idx, false)}${comment}`);
197
197
  }
198
198
  declBuf.push(`}`);
199
199
  return declBuf.toString();
@@ -205,7 +205,7 @@ function generateFromStorageMethod(ctx, tyIdx, contractName) {
205
205
  return '';
206
206
  }
207
207
  const ty = ctx.symbols.tyByIdx(tyIdx);
208
- let storageParamT = (0, emit_ts_types_1.emitTsType)(ctx, tyIdx);
208
+ let storageParamT = (0, emit_ts_types_1.emitTsType)(ctx, tyIdx, false);
209
209
  let bodyArg = 'emptyStorage';
210
210
  if (ty.kind === 'StructRef') {
211
211
  storageParamT = structParameterNoLabel(ctx, tyIdx);
@@ -228,7 +228,7 @@ function generateFromStorageMethod(ctx, tyIdx, contractName) {
228
228
  function generateCreateCellOfMessageMethod(ctx, tyIdx) {
229
229
  const ty = ctx.symbols.tyByIdx(tyIdx);
230
230
  let functionName = snakeCaseToCamelCase((0, formatting_1.safeJsIdent)(`createCellOf_${(0, types_kernel_1.renderTy)(ctx.symbols, tyIdx)}`));
231
- let bodyParamT = (0, emit_ts_types_1.emitTsType)(ctx, tyIdx);
231
+ let bodyParamT = (0, emit_ts_types_1.emitTsType)(ctx, tyIdx, false);
232
232
  let bodyArg = 'body';
233
233
  if (ty.kind === 'StructRef') {
234
234
  bodyParamT = structParameterNoLabel(ctx, tyIdx);
@@ -245,7 +245,7 @@ function generateCreateCellOfMessageMethod(ctx, tyIdx) {
245
245
  function generateSendMethod(ctx, tyIdx) {
246
246
  const ty = ctx.symbols.tyByIdx(tyIdx);
247
247
  let functionName = snakeCaseToCamelCase((0, formatting_1.safeJsIdent)(`send_${(0, types_kernel_1.renderTy)(ctx.symbols, tyIdx)}`));
248
- let bodyParamT = (0, emit_ts_types_1.emitTsType)(ctx, tyIdx);
248
+ let bodyParamT = (0, emit_ts_types_1.emitTsType)(ctx, tyIdx, false);
249
249
  let bodyArg = 'body';
250
250
  if (ty.kind === 'StructRef') {
251
251
  bodyParamT = structParameterNoLabel(ctx, tyIdx);
@@ -274,17 +274,17 @@ function generateGetMethod(ctx, getM) {
274
274
  return (0, formatting_1.safeJsIdent)(collision ? p.name + '_' : p.name);
275
275
  });
276
276
  let buf = new formatting_1.OutBuf();
277
- let paramsStr = nParams ? `, ${getM.parameters.map((p, i) => `${paramNames[i]}: ${(0, emit_ts_types_1.emitTsType)(ctx, p.ty_idx)}${p.default_value ? ` = ${(0, emit_field_defs_1.emitFieldDefault)(ctx, p.default_value)}` : ''}`).join(', ')}` : '';
277
+ let paramsStr = nParams ? `, ${getM.parameters.map((p, i) => `${paramNames[i]}: ${(0, emit_ts_types_1.emitTsType)(ctx, p.ty_idx, true)}${p.default_value ? ` = ${(0, emit_field_defs_1.emitFieldDefault)(ctx, p.default_value)}` : ''}`).join(', ')}` : '';
278
278
  const returnTy = ctx.symbols.tyByIdx(getM.return_ty_idx);
279
279
  if (returnTy.kind === 'tensor') {
280
280
  buf.push(`async ${functionName}(provider: ContractProvider${paramsStr}): Promise<[`);
281
281
  for (let item of returnTy.items_ty_idx) {
282
- buf.push((0, emit_ts_types_1.emitTsType)(ctx, item) + ',');
282
+ buf.push((0, emit_ts_types_1.emitTsType)(ctx, item, true) + ',');
283
283
  }
284
284
  buf.push(']> {');
285
285
  }
286
286
  else {
287
- buf.push(`async ${functionName}(provider: ContractProvider${paramsStr}): Promise<${(0, emit_ts_types_1.emitTsType)(ctx, getM.return_ty_idx)}> {`);
287
+ buf.push(`async ${functionName}(provider: ContractProvider${paramsStr}): Promise<${(0, emit_ts_types_1.emitTsType)(ctx, getM.return_ty_idx, true)}> {`);
288
288
  }
289
289
  let stackW = (0, types_kernel_1.calcWidthOnStack)(ctx.symbols, getM.return_ty_idx);
290
290
  if (nParams) {
@@ -1 +1 @@
1
- export declare const OUT_TEMPLATE = "// AUTO-GENERATED, do not edit\n// it's a TypeScript wrapper for a CONTRACT_CLASS_NAME contract in Tolk\n/* eslint-disable */\n\nimport * as c from '@ton/core';\nimport { beginCell, ContractProvider, Sender, SendMode } from '@ton/core';\n\n// \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\n// predefined types and functions\n//\n\n// {{if:has_remaining}}\ntype RemainingBitsAndRefs = c.Slice\n// {{/if:has_remaining}}\n\n// {{if:has_addressAny}}\nexport type any_address = c.Address | c.ExternalAddress | 'none'\n// {{/if:has_addressAny}}\n\n// {{if:has_arrayOf}}\ntype array<T> = T[]\n// {{/if:has_arrayOf}}\n\n// {{if:has_lispListOf}}\n// TypeScript wrappers flatten a TVM linked list `[1 [2 [3 null]]]` to `[1 2 3]`\ntype lisp_list<T> = T[]\n// {{/if:has_lispListOf}}\n\ntype StoreCallback<T> = (obj: T, b: c.Builder) => void\ntype LoadCallback<T> = (s: c.Slice) => T\n\nexport type CellRef<T> = {\n ref: T\n}\n\nfunction makeCellFrom<T>(self: T, storeFn_T: StoreCallback<T>): c.Cell {\n let b = beginCell();\n storeFn_T(self, b);\n return b.endCell();\n}\n\nfunction loadAndCheckPrefix32(s: c.Slice, expected: number, structName: string): void {\n let prefix = s.loadUint(32);\n if (prefix !== expected) {\n throw new Error(`Incorrect prefix for '${structName}': expected 0x${expected.toString(16).padStart(8, '0')}, got 0x${prefix.toString(16).padStart(8, '0')}`);\n }\n}\n\n// {{if:has_non32Prefixes}}\nfunction formatPrefix(prefixNum: number, prefixLen: number): string {\n return prefixLen % 4 ? `0b${prefixNum.toString(2).padStart(prefixLen, '0')}` : `0x${prefixNum.toString(16).padStart(prefixLen / 4, '0')}`;\n}\n\nfunction loadAndCheckPrefix(s: c.Slice, expected: number, prefixLen: number, structName: string): void {\n let prefix = s.loadUint(prefixLen);\n if (prefix !== expected) {\n throw new Error(`Incorrect prefix for '${structName}': expected ${formatPrefix(expected, prefixLen)}, got ${formatPrefix(prefix, prefixLen)}`);\n }\n}\n// {{/if:has_non32Prefixes}}\n\nfunction lookupPrefix(s: c.Slice, expected: number, prefixLen: number): boolean {\n return s.remainingBits >= prefixLen && s.preloadUint(prefixLen) === expected;\n}\n\n// {{if:has_implicitUnionPrefix}}\nfunction lookupPrefixAndEat(s: c.Slice, expected: number, prefixLen: number): boolean {\n if (lookupPrefix(s, expected, prefixLen)) {\n s.skip(prefixLen);\n return true;\n }\n return false;\n}\n// {{/if:has_implicitUnionPrefix}}\n\nfunction throwNonePrefixMatch(fieldPath: string): never {\n throw new Error(`Incorrect prefix for '${fieldPath}': none of variants matched`);\n}\n\nfunction storeCellRef<T>(cell: CellRef<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n let b_ref = c.beginCell();\n storeFn_T(cell.ref, b_ref);\n b.storeRef(b_ref.endCell());\n}\n\nfunction loadCellRef<T>(s: c.Slice, loadFn_T: LoadCallback<T>): CellRef<T> {\n let s_ref = s.loadRef().beginParse();\n return { ref: loadFn_T(s_ref) };\n}\n\n// {{if:has_addressAny}}\nfunction storeTolkAddressAny(a: any_address, b: c.Builder): void {\n let maybe_addr = a === 'none' ? null : a;\n b.storeAddress(maybe_addr);\n}\n\nfunction loadTolkAddressAny(s: c.Slice): any_address {\n let maybe_addr = s.loadAddressAny();\n return maybe_addr === null ? 'none' : maybe_addr;\n}\n// {{/if:has_addressAny}}\n\n// {{if:has_bitsN}}\nfunction storeTolkBitsN(v: c.Slice, nBits: number, b: c.Builder): void {\n if (v.remainingBits !== nBits) { throw new Error(`expected ${nBits} bits, got ${v.remainingBits}`); }\n if (v.remainingRefs !== 0) { throw new Error(`expected 0 refs, got ${v.remainingRefs}`); }\n b.storeSlice(v);\n}\n\nfunction loadTolkBitsN(s: c.Slice, nBits: number): c.Slice {\n return new c.Slice(new c.BitReader(s.loadBits(nBits)), []);\n}\n// {{/if:has_bitsN}}\n\n// {{if:has_remaining}}\nfunction storeTolkRemaining(v: RemainingBitsAndRefs, b: c.Builder): void {\n b.storeSlice(v);\n}\n\nfunction loadTolkRemaining(s: c.Slice): RemainingBitsAndRefs {\n let rest = s.clone();\n s.loadBits(s.remainingBits);\n while (s.remainingRefs) {\n s.loadRef();\n }\n return rest;\n}\n// {{/if:has_remaining}}\n\nfunction storeTolkNullable<T>(v: T | null, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n if (v === null) {\n b.storeUint(0, 1);\n } else {\n b.storeUint(1, 1);\n storeFn_T(v, b);\n }\n}\n\n// {{if:has_arrayOf}}\nfunction storeArrayOf<T>(v: array<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n // the compiler stores array<T> in chunks; in TypeScript, for simplicity, store \"1 elem = 1 ref\"\n let tail = null as c.Cell | null;\n for (let i = 0; i < v.length; ++i) {\n let chunkB = beginCell().storeMaybeRef(tail);\n storeFn_T(v[v.length - 1 - i], chunkB);\n tail = chunkB.endCell();\n }\n b.storeUint(v.length, 8);\n b.storeMaybeRef(tail);\n}\n\nfunction loadArrayOf<T>(s: c.Slice, loadFn_T: LoadCallback<T>): array<T> {\n let len = s.loadUint(8);\n let head = s.loadMaybeRef();\n let outArr = [] as array<T>;\n while (head != null) {\n let s = head.beginParse();\n head = s.loadMaybeRef();\n while (s.remainingBits || s.remainingRefs) {\n outArr.push(loadFn_T(s));\n }\n }\n if (len !== outArr.length) {\n throw new Error(`mismatch array binary data: expected ${len} elements, got ${outArr.length}`);\n }\n return outArr;\n}\n// {{/if:has_arrayOf}}\n\n// {{if:has_lispListOf}}\nfunction storeLispListOf<T>(v: lisp_list<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n let tail = c.Cell.EMPTY;\n for (let i = 0; i < v.length; ++i) {\n let itemB = beginCell();\n storeFn_T(v[i], itemB);\n tail = itemB.storeRef(tail).endCell();\n }\n b.storeRef(tail);\n}\n\nfunction loadLispListOf<T>(s: c.Slice, loadFn_T: LoadCallback<T>): lisp_list<T> {\n let outArr = [] as lisp_list<T>;\n let head = s.loadRef().beginParse();\n while (head.remainingRefs) {\n let tailSnaked = head.loadRef();\n let headValue = loadFn_T(head);\n head.endParse(); // ensure no data is present besides T\n outArr.unshift(headValue);\n head = tailSnaked.beginParse();\n }\n return outArr;\n}\n// {{/if:has_lispListOf}}\n\n// {{if:has_customDictV}}\nfunction createDictionaryValue<V>(loadFn_V: LoadCallback<V>, storeFn_V: StoreCallback<V>): c.DictionaryValue<V> {\n return {\n serialize(self: V, b: c.Builder) {\n storeFn_V(self, b);\n },\n parse(s: c.Slice): V {\n const value = loadFn_V(s);\n s.endParse();\n return value;\n }\n }\n}\n// {{/if:has_customDictV}}\n\n// \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\n// parse get methods result from a TVM stack\n//\n\nclass StackReader {\n constructor(private tuple: c.TupleItem[]) {\n }\n\n static fromGetMethod(expectedN: number, getMethodResult: { stack: c.TupleReader }): StackReader {\n let tuple = [] as c.TupleItem[];\n while (getMethodResult.stack.remaining) {\n tuple.push(getMethodResult.stack.pop());\n }\n if (tuple.length !== expectedN) {\n throw new Error(`expected ${expectedN} stack width, got ${tuple.length}`);\n }\n return new StackReader(tuple);\n }\n\n private popExpecting<ItemT>(itemType: string): ItemT {\n const item = this.tuple.shift();\n if (item?.type === itemType) {\n return item as ItemT;\n }\n throw new Error(`not '${itemType}' on a stack`);\n }\n\n private popCellLike(): c.Cell {\n const item = this.tuple.shift();\n if (item && (item.type === 'cell' || item.type === 'slice' || item.type === 'builder')) {\n return item.cell;\n }\n throw new Error(`not cell/slice on a stack`);\n }\n\n readBigInt(): bigint {\n return this.popExpecting<c.TupleItemInt>('int').value;\n }\n\n readBoolean(): boolean {\n return this.popExpecting<c.TupleItemInt>('int').value !== 0n;\n }\n\n readCell(): c.Cell {\n return this.popCellLike();\n }\n\n readSlice(): c.Slice {\n return this.popCellLike().beginParse();\n }\n\n // {{if:stackReadsBuilder}}\n readBuilder(): c.Builder {\n return beginCell().storeSlice(this.popCellLike().beginParse());\n }\n // {{/if:stackReadsBuilder}}\n\n // {{if:stackReadsUnknown}}\n readUnknown(): c.TupleItem {\n // `unknown` from Tolk is left as a raw tuple item\n return this.tuple.shift()!;\n }\n // {{/if:stackReadsUnknown}}\n\n // {{if:stackReadsArrayOf}}\n readArrayOf<T>(readFn_T: (nestedReader: StackReader) => T): T[] {\n const subItems = this.popExpecting<c.Tuple>('tuple').items;\n const subReader = new StackReader(subItems);\n // array len N => N subItems => N calls to readFn_T\n return [...subItems].map(_ => readFn_T(subReader));\n }\n // {{/if:stackReadsArrayOf}}\n\n // {{if:stackReadsLispListOf}}\n readLispListOf<T>(readFn_T: (nestedReader: StackReader) => T): T[] {\n // read `[1 [2 [3 null]]]` to `[1 2 3]`\n let pairReader: StackReader = this;\n let outArr = [] as T[];\n while (true) {\n if (pairReader.tuple[0].type === 'null') {\n pairReader.tuple.shift();\n break;\n }\n let headAndTail = pairReader.popExpecting<c.Tuple>('tuple').items;\n if (headAndTail.length !== 2) {\n throw new Error(`malformed lisp_list, expected 2 stack width, got ${headAndTail.length}`);\n }\n pairReader = new StackReader(headAndTail);\n outArr.push(readFn_T(pairReader));\n }\n return outArr;\n }\n // {{/if:stackReadsLispListOf}}\n\n // {{if:stackReadsSnakeString}}\n readSnakeString(): string {\n return this.readCell().beginParse().loadStringTail();\n }\n // {{/if:stackReadsSnakeString}}\n\n // {{if:stackReadsTuple}}\n readTuple<T>(expectedN: number, readFn_T: (nestedReader: StackReader) => T): T {\n const subItems = this.popExpecting<c.Tuple>('tuple').items;\n if (subItems.length !== expectedN) {\n throw new Error(`expected ${expectedN} items in a tuple, got ${subItems.length}`);\n }\n return readFn_T(new StackReader(subItems));\n }\n // {{/if:stackReadsTuple}}\n\n // {{if:stackReadsNullLiteral}}\n readNullLiteral(): null {\n this.popExpecting<c.TupleItemNull>('null');\n return null;\n }\n // {{/if:stackReadsNullLiteral}}\n\n // {{if:stackReadsNullable}}\n readNullable<T>(readFn_T: (r: StackReader) => T): T | null {\n if (this.tuple[0].type === 'null') {\n this.tuple.shift();\n return null;\n }\n return readFn_T(this);\n }\n // {{/if:stackReadsNullable}}\n\n // {{if:stackReadsWideNullable}}\n readWideNullable<T>(stackW: number, readFn_T: (r: StackReader) => T): T | null {\n const slotTypeId = this.tuple[stackW - 1];\n if (slotTypeId?.type !== 'int') {\n throw new Error(`not 'int' on a stack`);\n }\n if (slotTypeId.value === 0n) {\n this.tuple = this.tuple.slice(stackW);\n return null;\n }\n const valueT = readFn_T(this);\n this.tuple.shift();\n return valueT;\n }\n // {{/if:stackReadsWideNullable}}\n\n // {{if:stackReadsUnionType}}\n readUnionType<T>(stackW: number, infoForTypeId: Record<number, [number, string | null, (r: StackReader) => any]>): T {\n const slotTypeId = this.tuple[stackW - 1];\n if (slotTypeId?.type !== 'int') {\n throw new Error(`not 'int' on a stack`);\n }\n const info = infoForTypeId[Number(slotTypeId.value)]; // [stackWidth, label, readFn_T{i}]\n if (info == null) {\n throw new Error(`unexpected UTag=${slotTypeId.value}`);\n }\n const label = info[1];\n this.tuple = this.tuple.slice(stackW - 1 - info[0]);\n const valueT = info[2](this);\n this.tuple.shift();\n return label == null ? valueT : { $: label, value: valueT } as T;\n }\n // {{/if:stackReadsUnionType}}\n\n // {{if:stackReadsCellRef}}\n readCellRef<T>(loadFn_T: LoadCallback<T>): CellRef<T> {\n return { ref: loadFn_T(this.readCell().beginParse()) };\n }\n // {{/if:stackReadsCellRef}}\n\n // {{if:stackReadsMapKV}}\n readDictionary<K extends c.DictionaryKeyTypes, V>(keySerializer: c.DictionaryKey<K>, valueSerializer: c.DictionaryValue<V>): c.Dictionary<K, V> {\n if (this.tuple[0].type === 'null') {\n this.tuple.shift();\n return c.Dictionary.empty<K, V>(keySerializer, valueSerializer);\n }\n return c.Dictionary.loadDirect<K, V>(keySerializer, valueSerializer, this.readCell());\n }\n // {{/if:stackReadsMapKV}}\n}\n\n// {{if:has_customPackUnpack}}\n// \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\n// custom packToBuilder and unpackFromSlice\n//\n\ntype CustomPackToBuilderFn<T> = (self: T, b: c.Builder) => void\ntype CustomUnpackFromSliceFn<T> = (s: c.Slice) => T\n\nlet customSerializersRegistry: Map<string, [CustomPackToBuilderFn<any> | null, CustomUnpackFromSliceFn<any> | null]> = new Map;\n\nfunction ensureCustomSerializerRegistered(typeName: string) {\n if (!customSerializersRegistry.has(typeName)) {\n throw new Error(`Custom packToBuilder/unpackFromSlice was not registered for type 'CONTRACT_CLASS_NAME.${typeName}'.\\n(in Tolk code, they have custom logic \\`fun ${typeName}__packToBuilder\\`)\\nSteps to fix:\\n1) in your code, create and implement\\n > function ${typeName}__packToBuilder(self: ${typeName}, b: Builder): void { ... }\\n > function ${typeName}__unpackFromSlice(s: Slice): ${typeName} { ... }\\n2) register them in advance by calling\\n > CONTRACT_CLASS_NAME.registerCustomPackUnpack('${typeName}', ${typeName}__packToBuilder, ${typeName}__unpackFromSlice);`);\n }\n}\n\nfunction invokeCustomPackToBuilder<T>(typeName: string, self: T, b: c.Builder) {\n ensureCustomSerializerRegistered(typeName);\n customSerializersRegistry.get(typeName)![0]!(self, b);\n}\n\nfunction invokeCustomUnpackFromSlice<T>(typeName: string, s: c.Slice): T {\n ensureCustomSerializerRegistered(typeName);\n return customSerializersRegistry.get(typeName)![1]!(s);\n}\n// {{/if:has_customPackUnpack}}\n\n// \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\n// auto-generated serializers to/from cells\n//\n\ntype coins = bigint\n\n// {{intNAliases}}\n\n// {{uintNAliases}}\n\n// {{if:has_varIntN}}\n// {{varIntNAliases}}\n// {{/if:has_varIntN}}\n\n// {{if:has_bitsN}}\n// {{sliceAliases}}\n// {{/if:has_bitsN}}\n\n// {{packUnpackSerializers}}\n\n// \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\n// class CONTRACT_CLASS_NAME\n//\n\ninterface ExtraSendOptions {\n bounce?: boolean // default: false\n sendMode?: SendMode // default: SendMode.PAY_GAS_SEPARATELY\n extraCurrencies?: c.ExtraCurrency // default: empty dict\n}\n\ninterface DeployedAddrOptions {\n workchain?: number // default: 0 (basechain)\n toShard?: { fixedPrefixLength: number; closeTo: c.Address }\n overrideContractCode?: c.Cell\n}\n\nfunction calculateDeployedAddress(code: c.Cell, data: c.Cell, options: DeployedAddrOptions): c.Address {\n const stateInitCell = beginCell().store(c.storeStateInit({\n code,\n data,\n splitDepth: options.toShard?.fixedPrefixLength,\n special: null,\n libraries: null,\n })).endCell();\n\n let addrHash = stateInitCell.hash();\n if (options.toShard) {\n const shardDepth = options.toShard.fixedPrefixLength;\n addrHash = beginCell()\n .storeBits(new c.BitString(options.toShard.closeTo.hash, 0, shardDepth))\n .storeBits(new c.BitString(stateInitCell.hash(), shardDepth, 256 - shardDepth))\n .endCell()\n .beginParse().loadBuffer(32);\n }\n\n return new c.Address(options.workchain ?? 0, addrHash);\n}\n\nexport class CONTRACT_CLASS_NAME implements c.Contract {\n static CodeCell = c.Cell.fromBase64('{{codeBoc64}}');\n\n static Errors = {\n // {{errorCodes}}\n }\n\n readonly address: c.Address\n readonly init?: { code: c.Cell, data: c.Cell }\n\n private constructor(address: c.Address, init?: { code: c.Cell, data: c.Cell }) {\n this.address = address;\n this.init = init;\n }\n\n // {{if:has_customPackUnpack}}\n static registerCustomPackUnpack<T>(\n typeName: string,\n packToBuilderFn: CustomPackToBuilderFn<T> | null,\n unpackFromSliceFn: CustomUnpackFromSliceFn<T> | null,\n ) {\n if (customSerializersRegistry.has(typeName)) {\n throw new Error(`Custom pack/unpack for 'CONTRACT_CLASS_NAME.${typeName}' already registered`);\n }\n customSerializersRegistry.set(typeName, [packToBuilderFn, unpackFromSliceFn]);\n }\n // {{/if:has_customPackUnpack}}\n\n static fromAddress(address: c.Address) {\n return new CONTRACT_CLASS_NAME(address);\n }\n\n // {{fromStorageMethod}}\n\n // {{createCellsMethods}}\n\n // {{if:has_sendDeploy}}\n async sendDeploy(provider: ContractProvider, via: Sender, msgValue: coins, extraOptions?: ExtraSendOptions) {\n return provider.internal(via, {\n value: msgValue,\n body: c.Cell.EMPTY,\n ...extraOptions\n });\n }\n // {{/if:has_sendDeploy}}\n\n // {{sendMethods}}\n\n // {{getMethods}}\n}\n";
1
+ export declare const OUT_TEMPLATE = "// AUTO-GENERATED, do not edit\n// It's a TypeScript wrapper for a CONTRACT_CLASS_NAME contract in Tolk.\n// Disable tsc with strict mode, it may trigger on unused aliases like `int256`.\n// @ts-nocheck\n/* eslint-disable */\n\nimport * as c from '@ton/core';\nimport { beginCell, ContractProvider, Sender, SendMode } from '@ton/core';\n\n// \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\n// predefined types and functions\n//\n\n// {{if:has_remaining}}\ntype RemainingBitsAndRefs = c.Slice\n// {{/if:has_remaining}}\n\n// {{if:has_addressAny}}\nexport type any_address = c.Address | c.ExternalAddress | 'none'\n// {{/if:has_addressAny}}\n\n// {{if:has_arrayOf}}\ntype array<T> = T[]\n// {{/if:has_arrayOf}}\n\n// {{if:has_lispListOf}}\n// TypeScript wrappers flatten a TVM linked list `[1 [2 [3 null]]]` to `[1 2 3]`\ntype lisp_list<T> = T[]\n// {{/if:has_lispListOf}}\n\ntype StoreCallback<T> = (obj: T, b: c.Builder) => void\ntype LoadCallback<T> = (s: c.Slice) => T\n\nexport type CellRef<T> = {\n ref: T\n}\n\nfunction makeCellFrom<T>(self: T, storeFn_T: StoreCallback<T>): c.Cell {\n let b = beginCell();\n storeFn_T(self, b);\n return b.endCell();\n}\n\nfunction loadAndCheckPrefix32(s: c.Slice, expected: number, structName: string): void {\n let prefix = s.loadUint(32);\n if (prefix !== expected) {\n throw new Error(`Incorrect prefix for '${structName}': expected 0x${expected.toString(16).padStart(8, '0')}, got 0x${prefix.toString(16).padStart(8, '0')}`);\n }\n}\n\n// {{if:has_non32Prefixes}}\nfunction formatPrefix(prefixNum: number, prefixLen: number): string {\n return prefixLen % 4 ? `0b${prefixNum.toString(2).padStart(prefixLen, '0')}` : `0x${prefixNum.toString(16).padStart(prefixLen / 4, '0')}`;\n}\n\nfunction loadAndCheckPrefix(s: c.Slice, expected: number, prefixLen: number, structName: string): void {\n let prefix = s.loadUint(prefixLen);\n if (prefix !== expected) {\n throw new Error(`Incorrect prefix for '${structName}': expected ${formatPrefix(expected, prefixLen)}, got ${formatPrefix(prefix, prefixLen)}`);\n }\n}\n// {{/if:has_non32Prefixes}}\n\nfunction lookupPrefix(s: c.Slice, expected: number, prefixLen: number): boolean {\n return s.remainingBits >= prefixLen && s.preloadUint(prefixLen) === expected;\n}\n\n// {{if:has_implicitUnionPrefix}}\nfunction lookupPrefixAndEat(s: c.Slice, expected: number, prefixLen: number): boolean {\n if (lookupPrefix(s, expected, prefixLen)) {\n s.skip(prefixLen);\n return true;\n }\n return false;\n}\n// {{/if:has_implicitUnionPrefix}}\n\nfunction throwNonePrefixMatch(fieldPath: string): never {\n throw new Error(`Incorrect prefix for '${fieldPath}': none of variants matched`);\n}\n\nfunction storeCellRef<T>(cell: CellRef<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n let b_ref = c.beginCell();\n storeFn_T(cell.ref, b_ref);\n b.storeRef(b_ref.endCell());\n}\n\nfunction loadCellRef<T>(s: c.Slice, loadFn_T: LoadCallback<T>): CellRef<T> {\n let s_ref = s.loadRef().beginParse();\n return { ref: loadFn_T(s_ref) };\n}\n\n// {{if:has_addressAny}}\nfunction storeTolkAddressAny(a: any_address, b: c.Builder): void {\n let maybe_addr = a === 'none' ? null : a;\n b.storeAddress(maybe_addr);\n}\n\nfunction loadTolkAddressAny(s: c.Slice): any_address {\n let maybe_addr = s.loadAddressAny();\n return maybe_addr === null ? 'none' : maybe_addr;\n}\n// {{/if:has_addressAny}}\n\n// {{if:has_bitsN}}\nfunction storeTolkBitsN(v: c.Slice, nBits: number, b: c.Builder): void {\n if (v.remainingBits !== nBits) { throw new Error(`expected ${nBits} bits, got ${v.remainingBits}`); }\n if (v.remainingRefs !== 0) { throw new Error(`expected 0 refs, got ${v.remainingRefs}`); }\n b.storeSlice(v);\n}\n\nfunction loadTolkBitsN(s: c.Slice, nBits: number): c.Slice {\n return new c.Slice(new c.BitReader(s.loadBits(nBits)), []);\n}\n// {{/if:has_bitsN}}\n\n// {{if:has_remaining}}\nfunction storeTolkRemaining(v: RemainingBitsAndRefs, b: c.Builder): void {\n b.storeSlice(v);\n}\n\nfunction loadTolkRemaining(s: c.Slice): RemainingBitsAndRefs {\n let rest = s.clone();\n s.loadBits(s.remainingBits);\n while (s.remainingRefs) {\n s.loadRef();\n }\n return rest;\n}\n// {{/if:has_remaining}}\n\nfunction storeTolkNullable<T>(v: T | null, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n if (v === null) {\n b.storeUint(0, 1);\n } else {\n b.storeUint(1, 1);\n storeFn_T(v, b);\n }\n}\n\n// {{if:has_arrayOf}}\nfunction storeArrayOf<T>(v: array<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n // the compiler stores array<T> in chunks; in TypeScript, for simplicity, store \"1 elem = 1 ref\"\n let tail = null as c.Cell | null;\n for (let i = 0; i < v.length; ++i) {\n let chunkB = beginCell().storeMaybeRef(tail);\n storeFn_T(v[v.length - 1 - i], chunkB);\n tail = chunkB.endCell();\n }\n b.storeUint(v.length, 8);\n b.storeMaybeRef(tail);\n}\n\nfunction loadArrayOf<T>(s: c.Slice, loadFn_T: LoadCallback<T>): array<T> {\n let len = s.loadUint(8);\n let head = s.loadMaybeRef();\n let outArr = [] as array<T>;\n while (head != null) {\n let s = head.beginParse();\n head = s.loadMaybeRef();\n while (s.remainingBits || s.remainingRefs) {\n outArr.push(loadFn_T(s));\n }\n }\n if (len !== outArr.length) {\n throw new Error(`mismatch array binary data: expected ${len} elements, got ${outArr.length}`);\n }\n return outArr;\n}\n// {{/if:has_arrayOf}}\n\n// {{if:has_lispListOf}}\nfunction storeLispListOf<T>(v: lisp_list<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n let tail = c.Cell.EMPTY;\n for (let i = 0; i < v.length; ++i) {\n let itemB = beginCell();\n storeFn_T(v[i], itemB);\n tail = itemB.storeRef(tail).endCell();\n }\n b.storeRef(tail);\n}\n\nfunction loadLispListOf<T>(s: c.Slice, loadFn_T: LoadCallback<T>): lisp_list<T> {\n let outArr = [] as lisp_list<T>;\n let head = s.loadRef().beginParse();\n while (head.remainingRefs) {\n let tailSnaked = head.loadRef();\n let headValue = loadFn_T(head);\n head.endParse(); // ensure no data is present besides T\n outArr.unshift(headValue);\n head = tailSnaked.beginParse();\n }\n return outArr;\n}\n// {{/if:has_lispListOf}}\n\n// {{if:has_customDictV}}\nfunction createDictionaryValue<V>(loadFn_V: LoadCallback<V>, storeFn_V: StoreCallback<V>): c.DictionaryValue<V> {\n return {\n serialize(self: V, b: c.Builder) {\n storeFn_V(self, b);\n },\n parse(s: c.Slice): V {\n const value = loadFn_V(s);\n s.endParse();\n return value;\n }\n }\n}\n// {{/if:has_customDictV}}\n\n// \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\n// parse get methods result from a TVM stack\n//\n\nclass StackReader {\n constructor(private tuple: c.TupleItem[]) {\n }\n\n static fromGetMethod(expectedN: number, getMethodResult: { stack: c.TupleReader }): StackReader {\n let tuple = [] as c.TupleItem[];\n while (getMethodResult.stack.remaining) {\n tuple.push(getMethodResult.stack.pop());\n }\n if (tuple.length !== expectedN) {\n throw new Error(`expected ${expectedN} stack width, got ${tuple.length}`);\n }\n return new StackReader(tuple);\n }\n\n private popExpecting<ItemT>(itemType: string): ItemT {\n const item = this.tuple.shift();\n if (item?.type === itemType) {\n return item as ItemT;\n }\n throw new Error(`not '${itemType}' on a stack`);\n }\n\n private popCellLike(): c.Cell {\n const item = this.tuple.shift();\n if (item && (item.type === 'cell' || item.type === 'slice' || item.type === 'builder')) {\n return item.cell;\n }\n throw new Error(`not cell/slice on a stack`);\n }\n\n readBigInt(): bigint {\n return this.popExpecting<c.TupleItemInt>('int').value;\n }\n\n readBoolean(): boolean {\n return this.popExpecting<c.TupleItemInt>('int').value !== 0n;\n }\n\n readCell(): c.Cell {\n return this.popCellLike();\n }\n\n readSlice(): c.Slice {\n return this.popCellLike().beginParse();\n }\n\n // {{if:stackReadsBuilder}}\n readBuilder(): c.Builder {\n return beginCell().storeSlice(this.popCellLike().beginParse());\n }\n // {{/if:stackReadsBuilder}}\n\n // {{if:stackReadsUnknown}}\n readUnknown(): c.TupleItem {\n // `unknown` from Tolk is left as a raw tuple item\n return this.tuple.shift()!;\n }\n // {{/if:stackReadsUnknown}}\n\n // {{if:stackReadsArrayOf}}\n readArrayOf<T>(readFn_T: (nestedReader: StackReader) => T): T[] {\n const subItems = this.popExpecting<c.Tuple>('tuple').items;\n const subReader = new StackReader(subItems);\n // array len N => N subItems => N calls to readFn_T\n return [...subItems].map(_ => readFn_T(subReader));\n }\n // {{/if:stackReadsArrayOf}}\n\n // {{if:stackReadsLispListOf}}\n readLispListOf<T>(readFn_T: (nestedReader: StackReader) => T): T[] {\n // read `[1 [2 [3 null]]]` to `[1 2 3]`\n let pairReader: StackReader = this;\n let outArr = [] as T[];\n while (true) {\n if (pairReader.tuple[0].type === 'null') {\n pairReader.tuple.shift();\n break;\n }\n let headAndTail = pairReader.popExpecting<c.Tuple>('tuple').items;\n if (headAndTail.length !== 2) {\n throw new Error(`malformed lisp_list, expected 2 stack width, got ${headAndTail.length}`);\n }\n pairReader = new StackReader(headAndTail);\n outArr.push(readFn_T(pairReader));\n }\n return outArr;\n }\n // {{/if:stackReadsLispListOf}}\n\n // {{if:stackReadsSnakeString}}\n readSnakeString(): string {\n return this.readCell().beginParse().loadStringTail();\n }\n // {{/if:stackReadsSnakeString}}\n\n // {{if:stackReadsTuple}}\n readTuple<T>(expectedN: number, readFn_T: (nestedReader: StackReader) => T): T {\n const subItems = this.popExpecting<c.Tuple>('tuple').items;\n if (subItems.length !== expectedN) {\n throw new Error(`expected ${expectedN} items in a tuple, got ${subItems.length}`);\n }\n return readFn_T(new StackReader(subItems));\n }\n // {{/if:stackReadsTuple}}\n\n // {{if:stackReadsNullLiteral}}\n readNullLiteral(): null {\n this.popExpecting<c.TupleItemNull>('null');\n return null;\n }\n // {{/if:stackReadsNullLiteral}}\n\n // {{if:stackReadsNullable}}\n readNullable<T>(readFn_T: (r: StackReader) => T): T | null {\n if (this.tuple[0].type === 'null') {\n this.tuple.shift();\n return null;\n }\n return readFn_T(this);\n }\n // {{/if:stackReadsNullable}}\n\n // {{if:stackReadsWideNullable}}\n readWideNullable<T>(stackW: number, readFn_T: (r: StackReader) => T): T | null {\n const slotTypeId = this.tuple[stackW - 1];\n if (slotTypeId?.type !== 'int') {\n throw new Error(`not 'int' on a stack`);\n }\n if (slotTypeId.value === 0n) {\n this.tuple = this.tuple.slice(stackW);\n return null;\n }\n const valueT = readFn_T(this);\n this.tuple.shift();\n return valueT;\n }\n // {{/if:stackReadsWideNullable}}\n\n // {{if:stackReadsUnionType}}\n readUnionType<T>(stackW: number, infoForTypeId: Record<number, [number, string | null, (r: StackReader) => any]>): T {\n const slotTypeId = this.tuple[stackW - 1];\n if (slotTypeId?.type !== 'int') {\n throw new Error(`not 'int' on a stack`);\n }\n const info = infoForTypeId[Number(slotTypeId.value)]; // [stackWidth, label, readFn_T{i}]\n if (info == null) {\n throw new Error(`unexpected UTag=${slotTypeId.value}`);\n }\n const label = info[1];\n this.tuple = this.tuple.slice(stackW - 1 - info[0]);\n const valueT = info[2](this);\n this.tuple.shift();\n return label == null ? valueT : { $: label, value: valueT } as T;\n }\n // {{/if:stackReadsUnionType}}\n\n // {{if:stackReadsCellRef}}\n readCellRef<T>(loadFn_T: LoadCallback<T>): CellRef<T> {\n return { ref: loadFn_T(this.readCell().beginParse()) };\n }\n // {{/if:stackReadsCellRef}}\n\n // {{if:stackReadsMapKV}}\n readDictionary<K extends c.DictionaryKeyTypes, V>(keySerializer: c.DictionaryKey<K>, valueSerializer: c.DictionaryValue<V>): c.Dictionary<K, V> {\n if (this.tuple[0].type === 'null') {\n this.tuple.shift();\n return c.Dictionary.empty<K, V>(keySerializer, valueSerializer);\n }\n return c.Dictionary.loadDirect<K, V>(keySerializer, valueSerializer, this.readCell());\n }\n // {{/if:stackReadsMapKV}}\n}\n\n// {{if:has_customPackUnpack}}\n// \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\n// custom packToBuilder and unpackFromSlice\n//\n\ntype CustomPackToBuilderFn<T> = (self: T, b: c.Builder) => void\ntype CustomUnpackFromSliceFn<T> = (s: c.Slice) => T\n\nlet customSerializersRegistry: Map<string, [CustomPackToBuilderFn<any> | null, CustomUnpackFromSliceFn<any> | null]> = new Map;\n\nfunction ensureCustomSerializerRegistered(typeName: string) {\n if (!customSerializersRegistry.has(typeName)) {\n throw new Error(`Custom packToBuilder/unpackFromSlice was not registered for type 'CONTRACT_CLASS_NAME.${typeName}'.\\n(in Tolk code, they have custom logic \\`fun ${typeName}__packToBuilder\\`)\\nSteps to fix:\\n1) in your code, create and implement\\n > function ${typeName}__packToBuilder(self: ${typeName}, b: Builder): void { ... }\\n > function ${typeName}__unpackFromSlice(s: Slice): ${typeName} { ... }\\n2) register them in advance by calling\\n > CONTRACT_CLASS_NAME.registerCustomPackUnpack('${typeName}', ${typeName}__packToBuilder, ${typeName}__unpackFromSlice);`);\n }\n}\n\nfunction invokeCustomPackToBuilder<T>(typeName: string, self: T, b: c.Builder) {\n ensureCustomSerializerRegistered(typeName);\n customSerializersRegistry.get(typeName)![0]!(self, b);\n}\n\nfunction invokeCustomUnpackFromSlice<T>(typeName: string, s: c.Slice): T {\n ensureCustomSerializerRegistered(typeName);\n return customSerializersRegistry.get(typeName)![1]!(s);\n}\n// {{/if:has_customPackUnpack}}\n\n// \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\n// auto-generated serializers to/from cells\n//\n\ntype coins = bigint\n\n// {{intNAliases}}\n\n// {{uintNAliases}}\n\n// {{if:has_varIntN}}\n// {{varIntNAliases}}\n// {{/if:has_varIntN}}\n\n// {{if:has_bitsN}}\n// {{sliceAliases}}\n// {{/if:has_bitsN}}\n\n// {{packUnpackSerializers}}\n\n// \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\n// class CONTRACT_CLASS_NAME\n//\n\ninterface ExtraSendOptions {\n bounce?: boolean // default: false\n sendMode?: SendMode // default: SendMode.PAY_GAS_SEPARATELY\n extraCurrencies?: c.ExtraCurrency // default: empty dict\n}\n\ninterface DeployedAddrOptions {\n workchain?: number // default: 0 (basechain)\n toShard?: { fixedPrefixLength: number; closeTo: c.Address }\n overrideContractCode?: c.Cell\n}\n\nfunction calculateDeployedAddress(code: c.Cell, data: c.Cell, options: DeployedAddrOptions): c.Address {\n const stateInitCell = beginCell().store(c.storeStateInit({\n code,\n data,\n splitDepth: options.toShard?.fixedPrefixLength,\n special: null,\n libraries: null,\n })).endCell();\n\n let addrHash = stateInitCell.hash();\n if (options.toShard) {\n const shardDepth = options.toShard.fixedPrefixLength;\n addrHash = beginCell()\n .storeBits(new c.BitString(options.toShard.closeTo.hash, 0, shardDepth))\n .storeBits(new c.BitString(stateInitCell.hash(), shardDepth, 256 - shardDepth))\n .endCell()\n .beginParse().loadBuffer(32);\n }\n\n return new c.Address(options.workchain ?? 0, addrHash);\n}\n\nexport class CONTRACT_CLASS_NAME implements c.Contract {\n static CodeCell = c.Cell.fromBase64('{{codeBoc64}}');\n\n static Errors = {\n // {{errorCodes}}\n }\n\n readonly address: c.Address\n readonly init?: { code: c.Cell, data: c.Cell }\n\n protected constructor(address: c.Address, init?: { code: c.Cell, data: c.Cell }) {\n this.address = address;\n this.init = init;\n }\n\n // {{if:has_customPackUnpack}}\n static registerCustomPackUnpack<T>(\n typeName: string,\n packToBuilderFn: CustomPackToBuilderFn<T> | null,\n unpackFromSliceFn: CustomUnpackFromSliceFn<T> | null,\n ) {\n if (customSerializersRegistry.has(typeName)) {\n throw new Error(`Custom pack/unpack for 'CONTRACT_CLASS_NAME.${typeName}' already registered`);\n }\n customSerializersRegistry.set(typeName, [packToBuilderFn, unpackFromSliceFn]);\n }\n // {{/if:has_customPackUnpack}}\n\n static fromAddress(address: c.Address) {\n return new CONTRACT_CLASS_NAME(address);\n }\n\n // {{fromStorageMethod}}\n\n // {{createCellsMethods}}\n\n // {{if:has_sendDeploy}}\n async sendDeploy(provider: ContractProvider, via: Sender, msgValue: coins, extraOptions?: ExtraSendOptions) {\n return provider.internal(via, {\n value: msgValue,\n body: c.Cell.EMPTY,\n ...extraOptions\n });\n }\n // {{/if:has_sendDeploy}}\n\n // {{sendMethods}}\n\n // {{getMethods}}\n}\n";
@@ -3,4 +3,4 @@
3
3
  // Source of truth: src/out-template.ts
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.OUT_TEMPLATE = void 0;
6
- exports.OUT_TEMPLATE = "// AUTO-GENERATED, do not edit\n// it's a TypeScript wrapper for a CONTRACT_CLASS_NAME contract in Tolk\n/* eslint-disable */\n\nimport * as c from '@ton/core';\nimport { beginCell, ContractProvider, Sender, SendMode } from '@ton/core';\n\n// ————————————————————————————————————————————\n// predefined types and functions\n//\n\n// {{if:has_remaining}}\ntype RemainingBitsAndRefs = c.Slice\n// {{/if:has_remaining}}\n\n// {{if:has_addressAny}}\nexport type any_address = c.Address | c.ExternalAddress | 'none'\n// {{/if:has_addressAny}}\n\n// {{if:has_arrayOf}}\ntype array<T> = T[]\n// {{/if:has_arrayOf}}\n\n// {{if:has_lispListOf}}\n// TypeScript wrappers flatten a TVM linked list `[1 [2 [3 null]]]` to `[1 2 3]`\ntype lisp_list<T> = T[]\n// {{/if:has_lispListOf}}\n\ntype StoreCallback<T> = (obj: T, b: c.Builder) => void\ntype LoadCallback<T> = (s: c.Slice) => T\n\nexport type CellRef<T> = {\n ref: T\n}\n\nfunction makeCellFrom<T>(self: T, storeFn_T: StoreCallback<T>): c.Cell {\n let b = beginCell();\n storeFn_T(self, b);\n return b.endCell();\n}\n\nfunction loadAndCheckPrefix32(s: c.Slice, expected: number, structName: string): void {\n let prefix = s.loadUint(32);\n if (prefix !== expected) {\n throw new Error(`Incorrect prefix for '${structName}': expected 0x${expected.toString(16).padStart(8, '0')}, got 0x${prefix.toString(16).padStart(8, '0')}`);\n }\n}\n\n// {{if:has_non32Prefixes}}\nfunction formatPrefix(prefixNum: number, prefixLen: number): string {\n return prefixLen % 4 ? `0b${prefixNum.toString(2).padStart(prefixLen, '0')}` : `0x${prefixNum.toString(16).padStart(prefixLen / 4, '0')}`;\n}\n\nfunction loadAndCheckPrefix(s: c.Slice, expected: number, prefixLen: number, structName: string): void {\n let prefix = s.loadUint(prefixLen);\n if (prefix !== expected) {\n throw new Error(`Incorrect prefix for '${structName}': expected ${formatPrefix(expected, prefixLen)}, got ${formatPrefix(prefix, prefixLen)}`);\n }\n}\n// {{/if:has_non32Prefixes}}\n\nfunction lookupPrefix(s: c.Slice, expected: number, prefixLen: number): boolean {\n return s.remainingBits >= prefixLen && s.preloadUint(prefixLen) === expected;\n}\n\n// {{if:has_implicitUnionPrefix}}\nfunction lookupPrefixAndEat(s: c.Slice, expected: number, prefixLen: number): boolean {\n if (lookupPrefix(s, expected, prefixLen)) {\n s.skip(prefixLen);\n return true;\n }\n return false;\n}\n// {{/if:has_implicitUnionPrefix}}\n\nfunction throwNonePrefixMatch(fieldPath: string): never {\n throw new Error(`Incorrect prefix for '${fieldPath}': none of variants matched`);\n}\n\nfunction storeCellRef<T>(cell: CellRef<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n let b_ref = c.beginCell();\n storeFn_T(cell.ref, b_ref);\n b.storeRef(b_ref.endCell());\n}\n\nfunction loadCellRef<T>(s: c.Slice, loadFn_T: LoadCallback<T>): CellRef<T> {\n let s_ref = s.loadRef().beginParse();\n return { ref: loadFn_T(s_ref) };\n}\n\n// {{if:has_addressAny}}\nfunction storeTolkAddressAny(a: any_address, b: c.Builder): void {\n let maybe_addr = a === 'none' ? null : a;\n b.storeAddress(maybe_addr);\n}\n\nfunction loadTolkAddressAny(s: c.Slice): any_address {\n let maybe_addr = s.loadAddressAny();\n return maybe_addr === null ? 'none' : maybe_addr;\n}\n// {{/if:has_addressAny}}\n\n// {{if:has_bitsN}}\nfunction storeTolkBitsN(v: c.Slice, nBits: number, b: c.Builder): void {\n if (v.remainingBits !== nBits) { throw new Error(`expected ${nBits} bits, got ${v.remainingBits}`); }\n if (v.remainingRefs !== 0) { throw new Error(`expected 0 refs, got ${v.remainingRefs}`); }\n b.storeSlice(v);\n}\n\nfunction loadTolkBitsN(s: c.Slice, nBits: number): c.Slice {\n return new c.Slice(new c.BitReader(s.loadBits(nBits)), []);\n}\n// {{/if:has_bitsN}}\n\n// {{if:has_remaining}}\nfunction storeTolkRemaining(v: RemainingBitsAndRefs, b: c.Builder): void {\n b.storeSlice(v);\n}\n\nfunction loadTolkRemaining(s: c.Slice): RemainingBitsAndRefs {\n let rest = s.clone();\n s.loadBits(s.remainingBits);\n while (s.remainingRefs) {\n s.loadRef();\n }\n return rest;\n}\n// {{/if:has_remaining}}\n\nfunction storeTolkNullable<T>(v: T | null, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n if (v === null) {\n b.storeUint(0, 1);\n } else {\n b.storeUint(1, 1);\n storeFn_T(v, b);\n }\n}\n\n// {{if:has_arrayOf}}\nfunction storeArrayOf<T>(v: array<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n // the compiler stores array<T> in chunks; in TypeScript, for simplicity, store \"1 elem = 1 ref\"\n let tail = null as c.Cell | null;\n for (let i = 0; i < v.length; ++i) {\n let chunkB = beginCell().storeMaybeRef(tail);\n storeFn_T(v[v.length - 1 - i], chunkB);\n tail = chunkB.endCell();\n }\n b.storeUint(v.length, 8);\n b.storeMaybeRef(tail);\n}\n\nfunction loadArrayOf<T>(s: c.Slice, loadFn_T: LoadCallback<T>): array<T> {\n let len = s.loadUint(8);\n let head = s.loadMaybeRef();\n let outArr = [] as array<T>;\n while (head != null) {\n let s = head.beginParse();\n head = s.loadMaybeRef();\n while (s.remainingBits || s.remainingRefs) {\n outArr.push(loadFn_T(s));\n }\n }\n if (len !== outArr.length) {\n throw new Error(`mismatch array binary data: expected ${len} elements, got ${outArr.length}`);\n }\n return outArr;\n}\n// {{/if:has_arrayOf}}\n\n// {{if:has_lispListOf}}\nfunction storeLispListOf<T>(v: lisp_list<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n let tail = c.Cell.EMPTY;\n for (let i = 0; i < v.length; ++i) {\n let itemB = beginCell();\n storeFn_T(v[i], itemB);\n tail = itemB.storeRef(tail).endCell();\n }\n b.storeRef(tail);\n}\n\nfunction loadLispListOf<T>(s: c.Slice, loadFn_T: LoadCallback<T>): lisp_list<T> {\n let outArr = [] as lisp_list<T>;\n let head = s.loadRef().beginParse();\n while (head.remainingRefs) {\n let tailSnaked = head.loadRef();\n let headValue = loadFn_T(head);\n head.endParse(); // ensure no data is present besides T\n outArr.unshift(headValue);\n head = tailSnaked.beginParse();\n }\n return outArr;\n}\n// {{/if:has_lispListOf}}\n\n// {{if:has_customDictV}}\nfunction createDictionaryValue<V>(loadFn_V: LoadCallback<V>, storeFn_V: StoreCallback<V>): c.DictionaryValue<V> {\n return {\n serialize(self: V, b: c.Builder) {\n storeFn_V(self, b);\n },\n parse(s: c.Slice): V {\n const value = loadFn_V(s);\n s.endParse();\n return value;\n }\n }\n}\n// {{/if:has_customDictV}}\n\n// ————————————————————————————————————————————\n// parse get methods result from a TVM stack\n//\n\nclass StackReader {\n constructor(private tuple: c.TupleItem[]) {\n }\n\n static fromGetMethod(expectedN: number, getMethodResult: { stack: c.TupleReader }): StackReader {\n let tuple = [] as c.TupleItem[];\n while (getMethodResult.stack.remaining) {\n tuple.push(getMethodResult.stack.pop());\n }\n if (tuple.length !== expectedN) {\n throw new Error(`expected ${expectedN} stack width, got ${tuple.length}`);\n }\n return new StackReader(tuple);\n }\n\n private popExpecting<ItemT>(itemType: string): ItemT {\n const item = this.tuple.shift();\n if (item?.type === itemType) {\n return item as ItemT;\n }\n throw new Error(`not '${itemType}' on a stack`);\n }\n\n private popCellLike(): c.Cell {\n const item = this.tuple.shift();\n if (item && (item.type === 'cell' || item.type === 'slice' || item.type === 'builder')) {\n return item.cell;\n }\n throw new Error(`not cell/slice on a stack`);\n }\n\n readBigInt(): bigint {\n return this.popExpecting<c.TupleItemInt>('int').value;\n }\n\n readBoolean(): boolean {\n return this.popExpecting<c.TupleItemInt>('int').value !== 0n;\n }\n\n readCell(): c.Cell {\n return this.popCellLike();\n }\n\n readSlice(): c.Slice {\n return this.popCellLike().beginParse();\n }\n\n // {{if:stackReadsBuilder}}\n readBuilder(): c.Builder {\n return beginCell().storeSlice(this.popCellLike().beginParse());\n }\n // {{/if:stackReadsBuilder}}\n\n // {{if:stackReadsUnknown}}\n readUnknown(): c.TupleItem {\n // `unknown` from Tolk is left as a raw tuple item\n return this.tuple.shift()!;\n }\n // {{/if:stackReadsUnknown}}\n\n // {{if:stackReadsArrayOf}}\n readArrayOf<T>(readFn_T: (nestedReader: StackReader) => T): T[] {\n const subItems = this.popExpecting<c.Tuple>('tuple').items;\n const subReader = new StackReader(subItems);\n // array len N => N subItems => N calls to readFn_T\n return [...subItems].map(_ => readFn_T(subReader));\n }\n // {{/if:stackReadsArrayOf}}\n\n // {{if:stackReadsLispListOf}}\n readLispListOf<T>(readFn_T: (nestedReader: StackReader) => T): T[] {\n // read `[1 [2 [3 null]]]` to `[1 2 3]`\n let pairReader: StackReader = this;\n let outArr = [] as T[];\n while (true) {\n if (pairReader.tuple[0].type === 'null') {\n pairReader.tuple.shift();\n break;\n }\n let headAndTail = pairReader.popExpecting<c.Tuple>('tuple').items;\n if (headAndTail.length !== 2) {\n throw new Error(`malformed lisp_list, expected 2 stack width, got ${headAndTail.length}`);\n }\n pairReader = new StackReader(headAndTail);\n outArr.push(readFn_T(pairReader));\n }\n return outArr;\n }\n // {{/if:stackReadsLispListOf}}\n\n // {{if:stackReadsSnakeString}}\n readSnakeString(): string {\n return this.readCell().beginParse().loadStringTail();\n }\n // {{/if:stackReadsSnakeString}}\n\n // {{if:stackReadsTuple}}\n readTuple<T>(expectedN: number, readFn_T: (nestedReader: StackReader) => T): T {\n const subItems = this.popExpecting<c.Tuple>('tuple').items;\n if (subItems.length !== expectedN) {\n throw new Error(`expected ${expectedN} items in a tuple, got ${subItems.length}`);\n }\n return readFn_T(new StackReader(subItems));\n }\n // {{/if:stackReadsTuple}}\n\n // {{if:stackReadsNullLiteral}}\n readNullLiteral(): null {\n this.popExpecting<c.TupleItemNull>('null');\n return null;\n }\n // {{/if:stackReadsNullLiteral}}\n\n // {{if:stackReadsNullable}}\n readNullable<T>(readFn_T: (r: StackReader) => T): T | null {\n if (this.tuple[0].type === 'null') {\n this.tuple.shift();\n return null;\n }\n return readFn_T(this);\n }\n // {{/if:stackReadsNullable}}\n\n // {{if:stackReadsWideNullable}}\n readWideNullable<T>(stackW: number, readFn_T: (r: StackReader) => T): T | null {\n const slotTypeId = this.tuple[stackW - 1];\n if (slotTypeId?.type !== 'int') {\n throw new Error(`not 'int' on a stack`);\n }\n if (slotTypeId.value === 0n) {\n this.tuple = this.tuple.slice(stackW);\n return null;\n }\n const valueT = readFn_T(this);\n this.tuple.shift();\n return valueT;\n }\n // {{/if:stackReadsWideNullable}}\n\n // {{if:stackReadsUnionType}}\n readUnionType<T>(stackW: number, infoForTypeId: Record<number, [number, string | null, (r: StackReader) => any]>): T {\n const slotTypeId = this.tuple[stackW - 1];\n if (slotTypeId?.type !== 'int') {\n throw new Error(`not 'int' on a stack`);\n }\n const info = infoForTypeId[Number(slotTypeId.value)]; // [stackWidth, label, readFn_T{i}]\n if (info == null) {\n throw new Error(`unexpected UTag=${slotTypeId.value}`);\n }\n const label = info[1];\n this.tuple = this.tuple.slice(stackW - 1 - info[0]);\n const valueT = info[2](this);\n this.tuple.shift();\n return label == null ? valueT : { $: label, value: valueT } as T;\n }\n // {{/if:stackReadsUnionType}}\n\n // {{if:stackReadsCellRef}}\n readCellRef<T>(loadFn_T: LoadCallback<T>): CellRef<T> {\n return { ref: loadFn_T(this.readCell().beginParse()) };\n }\n // {{/if:stackReadsCellRef}}\n\n // {{if:stackReadsMapKV}}\n readDictionary<K extends c.DictionaryKeyTypes, V>(keySerializer: c.DictionaryKey<K>, valueSerializer: c.DictionaryValue<V>): c.Dictionary<K, V> {\n if (this.tuple[0].type === 'null') {\n this.tuple.shift();\n return c.Dictionary.empty<K, V>(keySerializer, valueSerializer);\n }\n return c.Dictionary.loadDirect<K, V>(keySerializer, valueSerializer, this.readCell());\n }\n // {{/if:stackReadsMapKV}}\n}\n\n// {{if:has_customPackUnpack}}\n// ————————————————————————————————————————————\n// custom packToBuilder and unpackFromSlice\n//\n\ntype CustomPackToBuilderFn<T> = (self: T, b: c.Builder) => void\ntype CustomUnpackFromSliceFn<T> = (s: c.Slice) => T\n\nlet customSerializersRegistry: Map<string, [CustomPackToBuilderFn<any> | null, CustomUnpackFromSliceFn<any> | null]> = new Map;\n\nfunction ensureCustomSerializerRegistered(typeName: string) {\n if (!customSerializersRegistry.has(typeName)) {\n throw new Error(`Custom packToBuilder/unpackFromSlice was not registered for type 'CONTRACT_CLASS_NAME.${typeName}'.\\n(in Tolk code, they have custom logic \\`fun ${typeName}__packToBuilder\\`)\\nSteps to fix:\\n1) in your code, create and implement\\n > function ${typeName}__packToBuilder(self: ${typeName}, b: Builder): void { ... }\\n > function ${typeName}__unpackFromSlice(s: Slice): ${typeName} { ... }\\n2) register them in advance by calling\\n > CONTRACT_CLASS_NAME.registerCustomPackUnpack('${typeName}', ${typeName}__packToBuilder, ${typeName}__unpackFromSlice);`);\n }\n}\n\nfunction invokeCustomPackToBuilder<T>(typeName: string, self: T, b: c.Builder) {\n ensureCustomSerializerRegistered(typeName);\n customSerializersRegistry.get(typeName)![0]!(self, b);\n}\n\nfunction invokeCustomUnpackFromSlice<T>(typeName: string, s: c.Slice): T {\n ensureCustomSerializerRegistered(typeName);\n return customSerializersRegistry.get(typeName)![1]!(s);\n}\n// {{/if:has_customPackUnpack}}\n\n// ————————————————————————————————————————————\n// auto-generated serializers to/from cells\n//\n\ntype coins = bigint\n\n// {{intNAliases}}\n\n// {{uintNAliases}}\n\n// {{if:has_varIntN}}\n// {{varIntNAliases}}\n// {{/if:has_varIntN}}\n\n// {{if:has_bitsN}}\n// {{sliceAliases}}\n// {{/if:has_bitsN}}\n\n// {{packUnpackSerializers}}\n\n// ————————————————————————————————————————————\n// class CONTRACT_CLASS_NAME\n//\n\ninterface ExtraSendOptions {\n bounce?: boolean // default: false\n sendMode?: SendMode // default: SendMode.PAY_GAS_SEPARATELY\n extraCurrencies?: c.ExtraCurrency // default: empty dict\n}\n\ninterface DeployedAddrOptions {\n workchain?: number // default: 0 (basechain)\n toShard?: { fixedPrefixLength: number; closeTo: c.Address }\n overrideContractCode?: c.Cell\n}\n\nfunction calculateDeployedAddress(code: c.Cell, data: c.Cell, options: DeployedAddrOptions): c.Address {\n const stateInitCell = beginCell().store(c.storeStateInit({\n code,\n data,\n splitDepth: options.toShard?.fixedPrefixLength,\n special: null,\n libraries: null,\n })).endCell();\n\n let addrHash = stateInitCell.hash();\n if (options.toShard) {\n const shardDepth = options.toShard.fixedPrefixLength;\n addrHash = beginCell()\n .storeBits(new c.BitString(options.toShard.closeTo.hash, 0, shardDepth))\n .storeBits(new c.BitString(stateInitCell.hash(), shardDepth, 256 - shardDepth))\n .endCell()\n .beginParse().loadBuffer(32);\n }\n\n return new c.Address(options.workchain ?? 0, addrHash);\n}\n\nexport class CONTRACT_CLASS_NAME implements c.Contract {\n static CodeCell = c.Cell.fromBase64('{{codeBoc64}}');\n\n static Errors = {\n // {{errorCodes}}\n }\n\n readonly address: c.Address\n readonly init?: { code: c.Cell, data: c.Cell }\n\n private constructor(address: c.Address, init?: { code: c.Cell, data: c.Cell }) {\n this.address = address;\n this.init = init;\n }\n\n // {{if:has_customPackUnpack}}\n static registerCustomPackUnpack<T>(\n typeName: string,\n packToBuilderFn: CustomPackToBuilderFn<T> | null,\n unpackFromSliceFn: CustomUnpackFromSliceFn<T> | null,\n ) {\n if (customSerializersRegistry.has(typeName)) {\n throw new Error(`Custom pack/unpack for 'CONTRACT_CLASS_NAME.${typeName}' already registered`);\n }\n customSerializersRegistry.set(typeName, [packToBuilderFn, unpackFromSliceFn]);\n }\n // {{/if:has_customPackUnpack}}\n\n static fromAddress(address: c.Address) {\n return new CONTRACT_CLASS_NAME(address);\n }\n\n // {{fromStorageMethod}}\n\n // {{createCellsMethods}}\n\n // {{if:has_sendDeploy}}\n async sendDeploy(provider: ContractProvider, via: Sender, msgValue: coins, extraOptions?: ExtraSendOptions) {\n return provider.internal(via, {\n value: msgValue,\n body: c.Cell.EMPTY,\n ...extraOptions\n });\n }\n // {{/if:has_sendDeploy}}\n\n // {{sendMethods}}\n\n // {{getMethods}}\n}\n";
6
+ exports.OUT_TEMPLATE = "// AUTO-GENERATED, do not edit\n// It's a TypeScript wrapper for a CONTRACT_CLASS_NAME contract in Tolk.\n// Disable tsc with strict mode, it may trigger on unused aliases like `int256`.\n// @ts-nocheck\n/* eslint-disable */\n\nimport * as c from '@ton/core';\nimport { beginCell, ContractProvider, Sender, SendMode } from '@ton/core';\n\n// ————————————————————————————————————————————\n// predefined types and functions\n//\n\n// {{if:has_remaining}}\ntype RemainingBitsAndRefs = c.Slice\n// {{/if:has_remaining}}\n\n// {{if:has_addressAny}}\nexport type any_address = c.Address | c.ExternalAddress | 'none'\n// {{/if:has_addressAny}}\n\n// {{if:has_arrayOf}}\ntype array<T> = T[]\n// {{/if:has_arrayOf}}\n\n// {{if:has_lispListOf}}\n// TypeScript wrappers flatten a TVM linked list `[1 [2 [3 null]]]` to `[1 2 3]`\ntype lisp_list<T> = T[]\n// {{/if:has_lispListOf}}\n\ntype StoreCallback<T> = (obj: T, b: c.Builder) => void\ntype LoadCallback<T> = (s: c.Slice) => T\n\nexport type CellRef<T> = {\n ref: T\n}\n\nfunction makeCellFrom<T>(self: T, storeFn_T: StoreCallback<T>): c.Cell {\n let b = beginCell();\n storeFn_T(self, b);\n return b.endCell();\n}\n\nfunction loadAndCheckPrefix32(s: c.Slice, expected: number, structName: string): void {\n let prefix = s.loadUint(32);\n if (prefix !== expected) {\n throw new Error(`Incorrect prefix for '${structName}': expected 0x${expected.toString(16).padStart(8, '0')}, got 0x${prefix.toString(16).padStart(8, '0')}`);\n }\n}\n\n// {{if:has_non32Prefixes}}\nfunction formatPrefix(prefixNum: number, prefixLen: number): string {\n return prefixLen % 4 ? `0b${prefixNum.toString(2).padStart(prefixLen, '0')}` : `0x${prefixNum.toString(16).padStart(prefixLen / 4, '0')}`;\n}\n\nfunction loadAndCheckPrefix(s: c.Slice, expected: number, prefixLen: number, structName: string): void {\n let prefix = s.loadUint(prefixLen);\n if (prefix !== expected) {\n throw new Error(`Incorrect prefix for '${structName}': expected ${formatPrefix(expected, prefixLen)}, got ${formatPrefix(prefix, prefixLen)}`);\n }\n}\n// {{/if:has_non32Prefixes}}\n\nfunction lookupPrefix(s: c.Slice, expected: number, prefixLen: number): boolean {\n return s.remainingBits >= prefixLen && s.preloadUint(prefixLen) === expected;\n}\n\n// {{if:has_implicitUnionPrefix}}\nfunction lookupPrefixAndEat(s: c.Slice, expected: number, prefixLen: number): boolean {\n if (lookupPrefix(s, expected, prefixLen)) {\n s.skip(prefixLen);\n return true;\n }\n return false;\n}\n// {{/if:has_implicitUnionPrefix}}\n\nfunction throwNonePrefixMatch(fieldPath: string): never {\n throw new Error(`Incorrect prefix for '${fieldPath}': none of variants matched`);\n}\n\nfunction storeCellRef<T>(cell: CellRef<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n let b_ref = c.beginCell();\n storeFn_T(cell.ref, b_ref);\n b.storeRef(b_ref.endCell());\n}\n\nfunction loadCellRef<T>(s: c.Slice, loadFn_T: LoadCallback<T>): CellRef<T> {\n let s_ref = s.loadRef().beginParse();\n return { ref: loadFn_T(s_ref) };\n}\n\n// {{if:has_addressAny}}\nfunction storeTolkAddressAny(a: any_address, b: c.Builder): void {\n let maybe_addr = a === 'none' ? null : a;\n b.storeAddress(maybe_addr);\n}\n\nfunction loadTolkAddressAny(s: c.Slice): any_address {\n let maybe_addr = s.loadAddressAny();\n return maybe_addr === null ? 'none' : maybe_addr;\n}\n// {{/if:has_addressAny}}\n\n// {{if:has_bitsN}}\nfunction storeTolkBitsN(v: c.Slice, nBits: number, b: c.Builder): void {\n if (v.remainingBits !== nBits) { throw new Error(`expected ${nBits} bits, got ${v.remainingBits}`); }\n if (v.remainingRefs !== 0) { throw new Error(`expected 0 refs, got ${v.remainingRefs}`); }\n b.storeSlice(v);\n}\n\nfunction loadTolkBitsN(s: c.Slice, nBits: number): c.Slice {\n return new c.Slice(new c.BitReader(s.loadBits(nBits)), []);\n}\n// {{/if:has_bitsN}}\n\n// {{if:has_remaining}}\nfunction storeTolkRemaining(v: RemainingBitsAndRefs, b: c.Builder): void {\n b.storeSlice(v);\n}\n\nfunction loadTolkRemaining(s: c.Slice): RemainingBitsAndRefs {\n let rest = s.clone();\n s.loadBits(s.remainingBits);\n while (s.remainingRefs) {\n s.loadRef();\n }\n return rest;\n}\n// {{/if:has_remaining}}\n\nfunction storeTolkNullable<T>(v: T | null, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n if (v === null) {\n b.storeUint(0, 1);\n } else {\n b.storeUint(1, 1);\n storeFn_T(v, b);\n }\n}\n\n// {{if:has_arrayOf}}\nfunction storeArrayOf<T>(v: array<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n // the compiler stores array<T> in chunks; in TypeScript, for simplicity, store \"1 elem = 1 ref\"\n let tail = null as c.Cell | null;\n for (let i = 0; i < v.length; ++i) {\n let chunkB = beginCell().storeMaybeRef(tail);\n storeFn_T(v[v.length - 1 - i], chunkB);\n tail = chunkB.endCell();\n }\n b.storeUint(v.length, 8);\n b.storeMaybeRef(tail);\n}\n\nfunction loadArrayOf<T>(s: c.Slice, loadFn_T: LoadCallback<T>): array<T> {\n let len = s.loadUint(8);\n let head = s.loadMaybeRef();\n let outArr = [] as array<T>;\n while (head != null) {\n let s = head.beginParse();\n head = s.loadMaybeRef();\n while (s.remainingBits || s.remainingRefs) {\n outArr.push(loadFn_T(s));\n }\n }\n if (len !== outArr.length) {\n throw new Error(`mismatch array binary data: expected ${len} elements, got ${outArr.length}`);\n }\n return outArr;\n}\n// {{/if:has_arrayOf}}\n\n// {{if:has_lispListOf}}\nfunction storeLispListOf<T>(v: lisp_list<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {\n let tail = c.Cell.EMPTY;\n for (let i = 0; i < v.length; ++i) {\n let itemB = beginCell();\n storeFn_T(v[i], itemB);\n tail = itemB.storeRef(tail).endCell();\n }\n b.storeRef(tail);\n}\n\nfunction loadLispListOf<T>(s: c.Slice, loadFn_T: LoadCallback<T>): lisp_list<T> {\n let outArr = [] as lisp_list<T>;\n let head = s.loadRef().beginParse();\n while (head.remainingRefs) {\n let tailSnaked = head.loadRef();\n let headValue = loadFn_T(head);\n head.endParse(); // ensure no data is present besides T\n outArr.unshift(headValue);\n head = tailSnaked.beginParse();\n }\n return outArr;\n}\n// {{/if:has_lispListOf}}\n\n// {{if:has_customDictV}}\nfunction createDictionaryValue<V>(loadFn_V: LoadCallback<V>, storeFn_V: StoreCallback<V>): c.DictionaryValue<V> {\n return {\n serialize(self: V, b: c.Builder) {\n storeFn_V(self, b);\n },\n parse(s: c.Slice): V {\n const value = loadFn_V(s);\n s.endParse();\n return value;\n }\n }\n}\n// {{/if:has_customDictV}}\n\n// ————————————————————————————————————————————\n// parse get methods result from a TVM stack\n//\n\nclass StackReader {\n constructor(private tuple: c.TupleItem[]) {\n }\n\n static fromGetMethod(expectedN: number, getMethodResult: { stack: c.TupleReader }): StackReader {\n let tuple = [] as c.TupleItem[];\n while (getMethodResult.stack.remaining) {\n tuple.push(getMethodResult.stack.pop());\n }\n if (tuple.length !== expectedN) {\n throw new Error(`expected ${expectedN} stack width, got ${tuple.length}`);\n }\n return new StackReader(tuple);\n }\n\n private popExpecting<ItemT>(itemType: string): ItemT {\n const item = this.tuple.shift();\n if (item?.type === itemType) {\n return item as ItemT;\n }\n throw new Error(`not '${itemType}' on a stack`);\n }\n\n private popCellLike(): c.Cell {\n const item = this.tuple.shift();\n if (item && (item.type === 'cell' || item.type === 'slice' || item.type === 'builder')) {\n return item.cell;\n }\n throw new Error(`not cell/slice on a stack`);\n }\n\n readBigInt(): bigint {\n return this.popExpecting<c.TupleItemInt>('int').value;\n }\n\n readBoolean(): boolean {\n return this.popExpecting<c.TupleItemInt>('int').value !== 0n;\n }\n\n readCell(): c.Cell {\n return this.popCellLike();\n }\n\n readSlice(): c.Slice {\n return this.popCellLike().beginParse();\n }\n\n // {{if:stackReadsBuilder}}\n readBuilder(): c.Builder {\n return beginCell().storeSlice(this.popCellLike().beginParse());\n }\n // {{/if:stackReadsBuilder}}\n\n // {{if:stackReadsUnknown}}\n readUnknown(): c.TupleItem {\n // `unknown` from Tolk is left as a raw tuple item\n return this.tuple.shift()!;\n }\n // {{/if:stackReadsUnknown}}\n\n // {{if:stackReadsArrayOf}}\n readArrayOf<T>(readFn_T: (nestedReader: StackReader) => T): T[] {\n const subItems = this.popExpecting<c.Tuple>('tuple').items;\n const subReader = new StackReader(subItems);\n // array len N => N subItems => N calls to readFn_T\n return [...subItems].map(_ => readFn_T(subReader));\n }\n // {{/if:stackReadsArrayOf}}\n\n // {{if:stackReadsLispListOf}}\n readLispListOf<T>(readFn_T: (nestedReader: StackReader) => T): T[] {\n // read `[1 [2 [3 null]]]` to `[1 2 3]`\n let pairReader: StackReader = this;\n let outArr = [] as T[];\n while (true) {\n if (pairReader.tuple[0].type === 'null') {\n pairReader.tuple.shift();\n break;\n }\n let headAndTail = pairReader.popExpecting<c.Tuple>('tuple').items;\n if (headAndTail.length !== 2) {\n throw new Error(`malformed lisp_list, expected 2 stack width, got ${headAndTail.length}`);\n }\n pairReader = new StackReader(headAndTail);\n outArr.push(readFn_T(pairReader));\n }\n return outArr;\n }\n // {{/if:stackReadsLispListOf}}\n\n // {{if:stackReadsSnakeString}}\n readSnakeString(): string {\n return this.readCell().beginParse().loadStringTail();\n }\n // {{/if:stackReadsSnakeString}}\n\n // {{if:stackReadsTuple}}\n readTuple<T>(expectedN: number, readFn_T: (nestedReader: StackReader) => T): T {\n const subItems = this.popExpecting<c.Tuple>('tuple').items;\n if (subItems.length !== expectedN) {\n throw new Error(`expected ${expectedN} items in a tuple, got ${subItems.length}`);\n }\n return readFn_T(new StackReader(subItems));\n }\n // {{/if:stackReadsTuple}}\n\n // {{if:stackReadsNullLiteral}}\n readNullLiteral(): null {\n this.popExpecting<c.TupleItemNull>('null');\n return null;\n }\n // {{/if:stackReadsNullLiteral}}\n\n // {{if:stackReadsNullable}}\n readNullable<T>(readFn_T: (r: StackReader) => T): T | null {\n if (this.tuple[0].type === 'null') {\n this.tuple.shift();\n return null;\n }\n return readFn_T(this);\n }\n // {{/if:stackReadsNullable}}\n\n // {{if:stackReadsWideNullable}}\n readWideNullable<T>(stackW: number, readFn_T: (r: StackReader) => T): T | null {\n const slotTypeId = this.tuple[stackW - 1];\n if (slotTypeId?.type !== 'int') {\n throw new Error(`not 'int' on a stack`);\n }\n if (slotTypeId.value === 0n) {\n this.tuple = this.tuple.slice(stackW);\n return null;\n }\n const valueT = readFn_T(this);\n this.tuple.shift();\n return valueT;\n }\n // {{/if:stackReadsWideNullable}}\n\n // {{if:stackReadsUnionType}}\n readUnionType<T>(stackW: number, infoForTypeId: Record<number, [number, string | null, (r: StackReader) => any]>): T {\n const slotTypeId = this.tuple[stackW - 1];\n if (slotTypeId?.type !== 'int') {\n throw new Error(`not 'int' on a stack`);\n }\n const info = infoForTypeId[Number(slotTypeId.value)]; // [stackWidth, label, readFn_T{i}]\n if (info == null) {\n throw new Error(`unexpected UTag=${slotTypeId.value}`);\n }\n const label = info[1];\n this.tuple = this.tuple.slice(stackW - 1 - info[0]);\n const valueT = info[2](this);\n this.tuple.shift();\n return label == null ? valueT : { $: label, value: valueT } as T;\n }\n // {{/if:stackReadsUnionType}}\n\n // {{if:stackReadsCellRef}}\n readCellRef<T>(loadFn_T: LoadCallback<T>): CellRef<T> {\n return { ref: loadFn_T(this.readCell().beginParse()) };\n }\n // {{/if:stackReadsCellRef}}\n\n // {{if:stackReadsMapKV}}\n readDictionary<K extends c.DictionaryKeyTypes, V>(keySerializer: c.DictionaryKey<K>, valueSerializer: c.DictionaryValue<V>): c.Dictionary<K, V> {\n if (this.tuple[0].type === 'null') {\n this.tuple.shift();\n return c.Dictionary.empty<K, V>(keySerializer, valueSerializer);\n }\n return c.Dictionary.loadDirect<K, V>(keySerializer, valueSerializer, this.readCell());\n }\n // {{/if:stackReadsMapKV}}\n}\n\n// {{if:has_customPackUnpack}}\n// ————————————————————————————————————————————\n// custom packToBuilder and unpackFromSlice\n//\n\ntype CustomPackToBuilderFn<T> = (self: T, b: c.Builder) => void\ntype CustomUnpackFromSliceFn<T> = (s: c.Slice) => T\n\nlet customSerializersRegistry: Map<string, [CustomPackToBuilderFn<any> | null, CustomUnpackFromSliceFn<any> | null]> = new Map;\n\nfunction ensureCustomSerializerRegistered(typeName: string) {\n if (!customSerializersRegistry.has(typeName)) {\n throw new Error(`Custom packToBuilder/unpackFromSlice was not registered for type 'CONTRACT_CLASS_NAME.${typeName}'.\\n(in Tolk code, they have custom logic \\`fun ${typeName}__packToBuilder\\`)\\nSteps to fix:\\n1) in your code, create and implement\\n > function ${typeName}__packToBuilder(self: ${typeName}, b: Builder): void { ... }\\n > function ${typeName}__unpackFromSlice(s: Slice): ${typeName} { ... }\\n2) register them in advance by calling\\n > CONTRACT_CLASS_NAME.registerCustomPackUnpack('${typeName}', ${typeName}__packToBuilder, ${typeName}__unpackFromSlice);`);\n }\n}\n\nfunction invokeCustomPackToBuilder<T>(typeName: string, self: T, b: c.Builder) {\n ensureCustomSerializerRegistered(typeName);\n customSerializersRegistry.get(typeName)![0]!(self, b);\n}\n\nfunction invokeCustomUnpackFromSlice<T>(typeName: string, s: c.Slice): T {\n ensureCustomSerializerRegistered(typeName);\n return customSerializersRegistry.get(typeName)![1]!(s);\n}\n// {{/if:has_customPackUnpack}}\n\n// ————————————————————————————————————————————\n// auto-generated serializers to/from cells\n//\n\ntype coins = bigint\n\n// {{intNAliases}}\n\n// {{uintNAliases}}\n\n// {{if:has_varIntN}}\n// {{varIntNAliases}}\n// {{/if:has_varIntN}}\n\n// {{if:has_bitsN}}\n// {{sliceAliases}}\n// {{/if:has_bitsN}}\n\n// {{packUnpackSerializers}}\n\n// ————————————————————————————————————————————\n// class CONTRACT_CLASS_NAME\n//\n\ninterface ExtraSendOptions {\n bounce?: boolean // default: false\n sendMode?: SendMode // default: SendMode.PAY_GAS_SEPARATELY\n extraCurrencies?: c.ExtraCurrency // default: empty dict\n}\n\ninterface DeployedAddrOptions {\n workchain?: number // default: 0 (basechain)\n toShard?: { fixedPrefixLength: number; closeTo: c.Address }\n overrideContractCode?: c.Cell\n}\n\nfunction calculateDeployedAddress(code: c.Cell, data: c.Cell, options: DeployedAddrOptions): c.Address {\n const stateInitCell = beginCell().store(c.storeStateInit({\n code,\n data,\n splitDepth: options.toShard?.fixedPrefixLength,\n special: null,\n libraries: null,\n })).endCell();\n\n let addrHash = stateInitCell.hash();\n if (options.toShard) {\n const shardDepth = options.toShard.fixedPrefixLength;\n addrHash = beginCell()\n .storeBits(new c.BitString(options.toShard.closeTo.hash, 0, shardDepth))\n .storeBits(new c.BitString(stateInitCell.hash(), shardDepth, 256 - shardDepth))\n .endCell()\n .beginParse().loadBuffer(32);\n }\n\n return new c.Address(options.workchain ?? 0, addrHash);\n}\n\nexport class CONTRACT_CLASS_NAME implements c.Contract {\n static CodeCell = c.Cell.fromBase64('{{codeBoc64}}');\n\n static Errors = {\n // {{errorCodes}}\n }\n\n readonly address: c.Address\n readonly init?: { code: c.Cell, data: c.Cell }\n\n protected constructor(address: c.Address, init?: { code: c.Cell, data: c.Cell }) {\n this.address = address;\n this.init = init;\n }\n\n // {{if:has_customPackUnpack}}\n static registerCustomPackUnpack<T>(\n typeName: string,\n packToBuilderFn: CustomPackToBuilderFn<T> | null,\n unpackFromSliceFn: CustomUnpackFromSliceFn<T> | null,\n ) {\n if (customSerializersRegistry.has(typeName)) {\n throw new Error(`Custom pack/unpack for 'CONTRACT_CLASS_NAME.${typeName}' already registered`);\n }\n customSerializersRegistry.set(typeName, [packToBuilderFn, unpackFromSliceFn]);\n }\n // {{/if:has_customPackUnpack}}\n\n static fromAddress(address: c.Address) {\n return new CONTRACT_CLASS_NAME(address);\n }\n\n // {{fromStorageMethod}}\n\n // {{createCellsMethods}}\n\n // {{if:has_sendDeploy}}\n async sendDeploy(provider: ContractProvider, via: Sender, msgValue: coins, extraOptions?: ExtraSendOptions) {\n return provider.internal(via, {\n value: msgValue,\n body: c.Cell.EMPTY,\n ...extraOptions\n });\n }\n // {{/if:has_sendDeploy}}\n\n // {{sendMethods}}\n\n // {{getMethods}}\n}\n";
@@ -11,7 +11,7 @@ export declare class SymTable {
11
11
  getAlias(aliasName: string): ABIAlias;
12
12
  getEnum(enumName: string): ABIEnum;
13
13
  tyByIdx(tyIdx: number): Ty;
14
- structFieldsOf(tyIdx: number): (ABIStruct['fields'][number] & {
14
+ structFieldsOf(tyIdx: number, isForStack: boolean): (ABIStruct['fields'][number] & {
15
15
  uLabelTyIdx?: number;
16
16
  })[];
17
17
  aliasTargetOf(tyIdx: number): {
@@ -57,7 +57,7 @@ class SymTable {
57
57
  // Generic instantiations, e.g. `Wrapper<int32>`:
58
58
  // - override original ty_idx (potentially generic) from monomorphic instantiations (with Ts substitutes)
59
59
  // - save original ty_idx as uLabelTyIdx in case of generic unions later
60
- structFieldsOf(tyIdx) {
60
+ structFieldsOf(tyIdx, isForStack) {
61
61
  const ty = this.tyByIdx(tyIdx);
62
62
  if (ty.kind !== 'StructRef') {
63
63
  throw new Error(`expected StructRef at ty_idx=${tyIdx}`);
@@ -74,6 +74,13 @@ class SymTable {
74
74
  uLabelTyIdx: f.ty_idx,
75
75
  }));
76
76
  }
77
+ if (!isForStack) {
78
+ fields = fields.map(f => f.client_ty_idx === undefined ? f : ({
79
+ ...f,
80
+ ty_idx: f.client_ty_idx, // @abi.clientType is denied for generic fields
81
+ uLabelTyIdx: undefined, // that's why no monomorphic representations exist
82
+ }));
83
+ }
77
84
  return fields;
78
85
  }
79
86
  // Get target of an alias, `tyIdx` points to "AliasRef".
@@ -255,7 +262,7 @@ function calcWidthOnStack(symbols, tyIdx) {
255
262
  }
256
263
  case 'StructRef': {
257
264
  // a struct is a named tensor: fields one by one;
258
- const fields = symbols.structFieldsOf(tyIdx);
265
+ const fields = symbols.structFieldsOf(tyIdx, true);
259
266
  return fields.map(f => calcWidthOnStack(symbols, f.ty_idx)).reduce((p, c) => p + c, 0);
260
267
  }
261
268
  case 'AliasRef': {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gen-typescript-from-tolk-dev",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Generate TypeScript wrappers from Tolk ABI",
5
5
  "author": "TON Core",
6
6
  "license": "MIT",