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.
- package/dist/abi-types.d.ts +4 -0
- package/dist/abi.d.ts +0 -4
- package/dist/dynamic-debug-print.js +1 -1
- package/dist/dynamic-get-methods.js +2 -2
- package/dist/dynamic-serialization.js +2 -2
- package/dist/emit-pack-unpack.js +16 -14
- package/dist/emit-stack-rw.js +10 -10
- package/dist/emit-ts-types.d.ts +1 -1
- package/dist/emit-ts-types.js +27 -11
- package/dist/generate-ts-wrappers.js +13 -13
- package/dist/out-template.generated.d.ts +1 -1
- package/dist/out-template.generated.js +1 -1
- package/dist/types-kernel.d.ts +1 -1
- package/dist/types-kernel.js +9 -2
- package/package.json +1 -1
package/dist/abi-types.d.ts
CHANGED
|
@@ -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
|
}
|
package/dist/emit-pack-unpack.js
CHANGED
|
@@ -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
|
|
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) {
|
package/dist/emit-stack-rw.js
CHANGED
|
@@ -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);
|
package/dist/emit-ts-types.d.ts
CHANGED
|
@@ -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;
|
package/dist/emit-ts-types.js
CHANGED
|
@@ -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':
|
|
74
|
-
|
|
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.
|
|
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.
|
|
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";
|
package/dist/types-kernel.d.ts
CHANGED
|
@@ -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): {
|
package/dist/types-kernel.js
CHANGED
|
@@ -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': {
|