gen-typescript-from-tolk-dev 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,514 @@
1
+ // AUTO-GENERATED, do not edit
2
+ // it's a TypeScript wrapper for a CONTRACT_CLASS_NAME contract in Tolk
3
+ /* eslint-disable */
4
+
5
+ import * as c from '@ton/core'
6
+ import { beginCell, ContractProvider, Sender, SendMode } from '@ton/core';
7
+
8
+ // ————————————————————————————————————————————
9
+ // predefined types and functions
10
+ //
11
+
12
+ // {{if:has_remaining}}
13
+ type RemainingBitsAndRefs = c.Slice
14
+ // {{/if:has_remaining}}
15
+
16
+ // {{if:has_addressAny}}
17
+ export type any_address = c.Address | c.ExternalAddress | 'none'
18
+ // {{/if:has_addressAny}}
19
+
20
+ // {{if:has_arrayOf}}
21
+ type array<T> = T[]
22
+ // {{/if:has_arrayOf}}
23
+
24
+ // {{if:has_lispListOf}}
25
+ // TypeScript wrappers flatten a TVM linked list `[1 [2 [3 null]]]` to `[1 2 3]`
26
+ type lisp_list<T> = T[]
27
+ // {{/if:has_lispListOf}}
28
+
29
+ type StoreCallback<T> = (obj: T, b: c.Builder) => void
30
+ type LoadCallback<T> = (s: c.Slice) => T
31
+
32
+ export type CellRef<T> = {
33
+ ref: T
34
+ }
35
+
36
+ function makeCellFrom<T>(self: T, storeFn_T: StoreCallback<T>): c.Cell {
37
+ let b = beginCell();
38
+ storeFn_T(self, b);
39
+ return b.endCell();
40
+ }
41
+
42
+ function loadAndCheckPrefix32(s: c.Slice, expected: number, structName: string): void {
43
+ let prefix = s.loadUint(32);
44
+ if (prefix !== expected) {
45
+ throw new Error(`Incorrect prefix for '${structName}': expected 0x${expected.toString(16).padStart(8, '0')}, got 0x${prefix.toString(16).padStart(8, '0')}`);
46
+ }
47
+ }
48
+
49
+ // {{if:has_non32Prefixes}}
50
+ function formatPrefix(prefixNum: number, prefixLen: number): string {
51
+ return prefixLen % 4 ? `0b${prefixNum.toString(2).padStart(prefixLen, '0')}` : `0x${prefixNum.toString(16).padStart(prefixLen / 4, '0')}`;
52
+ }
53
+
54
+ function loadAndCheckPrefix(s: c.Slice, expected: number, prefixLen: number, structName: string): void {
55
+ let prefix = s.loadUint(prefixLen);
56
+ if (prefix !== expected) {
57
+ throw new Error(`Incorrect prefix for '${structName}': expected ${formatPrefix(expected, prefixLen)}, got ${formatPrefix(prefix, prefixLen)}`);
58
+ }
59
+ }
60
+ // {{/if:has_non32Prefixes}}
61
+
62
+ function lookupPrefix(s: c.Slice, expected: number, prefixLen: number): boolean {
63
+ return s.remainingBits >= prefixLen && s.preloadUint(prefixLen) === expected;
64
+ }
65
+
66
+ // {{if:has_implicitUnionPrefix}}
67
+ function lookupPrefixAndEat(s: c.Slice, expected: number, prefixLen: number): boolean {
68
+ if (lookupPrefix(s, expected, prefixLen)) {
69
+ s.skip(prefixLen);
70
+ return true;
71
+ }
72
+ return false;
73
+ }
74
+ // {{/if:has_implicitUnionPrefix}}
75
+
76
+ function throwNonePrefixMatch(fieldPath: string): never {
77
+ throw new Error(`Incorrect prefix for '${fieldPath}': none of variants matched`);
78
+ }
79
+
80
+ function storeCellRef<T>(cell: CellRef<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {
81
+ let b_ref = c.beginCell();
82
+ storeFn_T(cell.ref, b_ref);
83
+ b.storeRef(b_ref.endCell());
84
+ }
85
+
86
+ function loadCellRef<T>(s: c.Slice, loadFn_T: LoadCallback<T>): CellRef<T> {
87
+ let s_ref = s.loadRef().beginParse();
88
+ return { ref: loadFn_T(s_ref) };
89
+ }
90
+
91
+ // {{if:has_addressAny}}
92
+ function storeTolkAddressAny(a: any_address, b: c.Builder): void {
93
+ let maybe_addr = a === 'none' ? null : a;
94
+ b.storeAddress(maybe_addr);
95
+ }
96
+
97
+ function loadTolkAddressAny(s: c.Slice): any_address {
98
+ let maybe_addr = s.loadAddressAny();
99
+ return maybe_addr === null ? 'none' : maybe_addr;
100
+ }
101
+ // {{/if:has_addressAny}}
102
+
103
+ // {{if:has_bitsN}}
104
+ function storeTolkBitsN(v: c.Slice, nBits: number, b: c.Builder): void {
105
+ if (v.remainingBits !== nBits) { throw new Error(`expected ${nBits} bits, got ${v.remainingBits}`); }
106
+ if (v.remainingRefs !== 0) { throw new Error(`expected 0 refs, got ${v.remainingRefs}`); }
107
+ b.storeSlice(v);
108
+ }
109
+
110
+ function loadTolkBitsN(s: c.Slice, nBits: number): c.Slice {
111
+ return new c.Slice(new c.BitReader(s.loadBits(nBits)), []);
112
+ }
113
+ // {{/if:has_bitsN}}
114
+
115
+ // {{if:has_remaining}}
116
+ function storeTolkRemaining(v: RemainingBitsAndRefs, b: c.Builder): void {
117
+ b.storeSlice(v);
118
+ }
119
+
120
+ function loadTolkRemaining(s: c.Slice): RemainingBitsAndRefs {
121
+ let rest = s.clone();
122
+ s.loadBits(s.remainingBits);
123
+ while (s.remainingRefs) {
124
+ s.loadRef();
125
+ }
126
+ return rest;
127
+ }
128
+ // {{/if:has_remaining}}
129
+
130
+ function storeTolkNullable<T>(v: T | null, b: c.Builder, storeFn_T: StoreCallback<T>): void {
131
+ if (v === null) {
132
+ b.storeUint(0, 1);
133
+ } else {
134
+ b.storeUint(1, 1);
135
+ storeFn_T(v, b);
136
+ }
137
+ }
138
+
139
+ // {{if:has_arrayOf}}
140
+ function storeArrayOf<T>(v: array<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {
141
+ // the compiler stores array<T> in chunks; in TypeScript, for simplicity, store "1 elem = 1 ref"
142
+ let tail = null as c.Cell | null;
143
+ for (let i = 0; i < v.length; ++i) {
144
+ let chunkB = beginCell().storeMaybeRef(tail);
145
+ storeFn_T(v[v.length - 1 - i], chunkB);
146
+ tail = chunkB.endCell();
147
+ }
148
+ b.storeUint(v.length, 8);
149
+ b.storeMaybeRef(tail);
150
+ }
151
+
152
+ function loadArrayOf<T>(s: c.Slice, loadFn_T: LoadCallback<T>): array<T> {
153
+ let len = s.loadUint(8);
154
+ let head = s.loadMaybeRef();
155
+ let outArr = [] as array<T>;
156
+ while (head != null) {
157
+ let s = head.beginParse();
158
+ head = s.loadMaybeRef();
159
+ while (s.remainingBits || s.remainingRefs) {
160
+ outArr.push(loadFn_T(s));
161
+ }
162
+ }
163
+ if (len !== outArr.length) {
164
+ throw new Error(`mismatch array binary data: expected ${len} elements, got ${outArr.length}`);
165
+ }
166
+ return outArr;
167
+ }
168
+ // {{/if:has_arrayOf}}
169
+
170
+ // {{if:has_lispListOf}}
171
+ function storeLispListOf<T>(v: lisp_list<T>, b: c.Builder, storeFn_T: StoreCallback<T>): void {
172
+ let tail = c.Cell.EMPTY;
173
+ for (let i = 0; i < v.length; ++i) {
174
+ let itemB = beginCell();
175
+ storeFn_T(v[i], itemB);
176
+ tail = itemB.storeRef(tail).endCell();
177
+ }
178
+ b.storeRef(tail);
179
+ }
180
+
181
+ function loadLispListOf<T>(s: c.Slice, loadFn_T: LoadCallback<T>): lisp_list<T> {
182
+ let outArr = [] as lisp_list<T>;
183
+ let head = s.loadRef().beginParse();
184
+ while (head.remainingRefs) {
185
+ let tailSnaked = head.loadRef();
186
+ let headValue = loadFn_T(head);
187
+ head.endParse(); // ensure no data is present besides T
188
+ outArr.unshift(headValue);
189
+ head = tailSnaked.beginParse();
190
+ }
191
+ return outArr;
192
+ }
193
+ // {{/if:has_lispListOf}}
194
+
195
+ // {{if:has_customDictV}}
196
+ function createDictionaryValue<V>(loadFn_V: LoadCallback<V>, storeFn_V: StoreCallback<V>): c.DictionaryValue<V> {
197
+ return {
198
+ serialize(self: V, b: c.Builder) {
199
+ storeFn_V(self, b);
200
+ },
201
+ parse(s: c.Slice): V {
202
+ const value = loadFn_V(s);
203
+ s.endParse();
204
+ return value;
205
+ }
206
+ }
207
+ }
208
+ // {{/if:has_customDictV}}
209
+
210
+ // ————————————————————————————————————————————
211
+ // parse get methods result from a TVM stack
212
+ //
213
+
214
+ class StackReader {
215
+ constructor(private tuple: c.TupleItem[]) {
216
+ }
217
+
218
+ static fromGetMethod(expectedN: number, getMethodResult: { stack: c.TupleReader }): StackReader {
219
+ let tuple = [] as c.TupleItem[];
220
+ while (getMethodResult.stack.remaining) {
221
+ tuple.push(getMethodResult.stack.pop());
222
+ }
223
+ if (tuple.length !== expectedN) {
224
+ throw new Error(`expected ${expectedN} stack width, got ${tuple.length}`);
225
+ }
226
+ return new StackReader(tuple);
227
+ }
228
+
229
+ private popExpecting<ItemT>(itemType: string): ItemT {
230
+ const item = this.tuple.shift();
231
+ if (item?.type !== itemType) {
232
+ throw new Error(`not '${itemType}' on a stack`);
233
+ }
234
+ return item as ItemT;
235
+ }
236
+
237
+ readBigInt(): bigint {
238
+ return this.popExpecting<c.TupleItemInt>('int').value;
239
+ }
240
+
241
+ readBoolean(): boolean {
242
+ return this.popExpecting<c.TupleItemInt>('int').value !== 0n;
243
+ }
244
+
245
+ readCell(): c.Cell {
246
+ return this.popExpecting<c.TupleItemCell>('cell').cell;
247
+ }
248
+
249
+ readSlice(): c.Slice {
250
+ return this.popExpecting<c.TupleItemSlice>('slice').cell.beginParse();
251
+ }
252
+
253
+ // {{if:stackReadsBuilder}}
254
+ readBuilder(): c.Builder {
255
+ return beginCell().storeSlice(this.popExpecting<c.TupleItemBuilder>('builder').cell.beginParse());
256
+ }
257
+ // {{/if:stackReadsBuilder}}
258
+
259
+ // {{if:stackReadsUnknown}}
260
+ readUnknown(): c.TupleItem {
261
+ // `unknown` from Tolk is left as a raw tuple item
262
+ return this.tuple.shift()!;
263
+ }
264
+ // {{/if:stackReadsUnknown}}
265
+
266
+ // {{if:stackReadsArrayOf}}
267
+ readArrayOf<T>(readFn_T: (nestedReader: StackReader) => T): T[] {
268
+ const subItems = this.popExpecting<c.Tuple>('tuple').items;
269
+ const subReader = new StackReader(subItems);
270
+ // array len N => N subItems => N calls to readFn_T
271
+ return [...subItems].map(_ => readFn_T(subReader))
272
+ }
273
+ // {{/if:stackReadsArrayOf}}
274
+
275
+ // {{if:stackReadsLispListOf}}
276
+ readLispListOf<T>(readFn_T: (nestedReader: StackReader) => T): T[] {
277
+ // read `[1 [2 [3 null]]]` to `[1 2 3]`
278
+ let pairReader: StackReader = this;
279
+ let outArr = [] as T[];
280
+ while (true) {
281
+ if (pairReader.tuple[0].type === 'null') {
282
+ pairReader.tuple.shift();
283
+ break;
284
+ }
285
+ let headAndTail = pairReader.popExpecting<c.Tuple>('tuple').items;
286
+ if (headAndTail.length !== 2) {
287
+ throw new Error(`malformed lisp_list, expected 2 stack width, got ${headAndTail.length}`);
288
+ }
289
+ pairReader = new StackReader(headAndTail);
290
+ outArr.push(readFn_T(pairReader));
291
+ }
292
+ return outArr;
293
+ }
294
+ // {{/if:stackReadsLispListOf}}
295
+
296
+ // {{if:stackReadsSnakeString}}
297
+ readSnakeString(): string {
298
+ return this.readCell().beginParse().loadStringTail();
299
+ }
300
+ // {{/if:stackReadsSnakeString}}
301
+
302
+ // {{if:stackReadsTuple}}
303
+ readTuple<T>(expectedN: number, readFn_T: (nestedReader: StackReader) => T): T {
304
+ const subItems = this.popExpecting<c.Tuple>('tuple').items;
305
+ if (subItems.length !== expectedN) {
306
+ throw new Error(`expected ${expectedN} items in a tuple, got ${subItems.length}`);
307
+ }
308
+ return readFn_T(new StackReader(subItems));
309
+ }
310
+ // {{/if:stackReadsTuple}}
311
+
312
+ // {{if:stackReadsNullLiteral}}
313
+ readNullLiteral(): null {
314
+ this.popExpecting<c.TupleItemNull>('null');
315
+ return null;
316
+ }
317
+ // {{/if:stackReadsNullLiteral}}
318
+
319
+ // {{if:stackReadsNullable}}
320
+ readNullable<T>(readFn_T: (r: StackReader) => T): T | null {
321
+ if (this.tuple[0].type === 'null') {
322
+ this.tuple.shift();
323
+ return null;
324
+ }
325
+ return readFn_T(this);
326
+ }
327
+ // {{/if:stackReadsNullable}}
328
+
329
+ // {{if:stackReadsWideNullable}}
330
+ readWideNullable<T>(stackW: number, readFn_T: (r: StackReader) => T): T | null {
331
+ const slotTypeId = this.tuple[stackW - 1];
332
+ if (slotTypeId?.type !== 'int') {
333
+ throw new Error(`not 'int' on a stack`);
334
+ }
335
+ if (slotTypeId.value === 0n) {
336
+ this.tuple = this.tuple.slice(stackW);
337
+ return null;
338
+ }
339
+ const valueT = readFn_T(this);
340
+ this.tuple.shift();
341
+ return valueT;
342
+ }
343
+ // {{/if:stackReadsWideNullable}}
344
+
345
+ // {{if:stackReadsUnionType}}
346
+ readUnionType<T>(stackW: number, infoForTypeId: Record<number, [number, string | null, (r: StackReader) => any]>): T {
347
+ const slotTypeId = this.tuple[stackW - 1];
348
+ if (slotTypeId?.type !== 'int') {
349
+ throw new Error(`not 'int' on a stack`);
350
+ }
351
+ const info = infoForTypeId[Number(slotTypeId.value)]; // [stackWidth, label, readFn_T{i}]
352
+ if (info == null) {
353
+ throw new Error(`unexpected UTag=${slotTypeId.value}`);
354
+ }
355
+ const label = info[1];
356
+ this.tuple = this.tuple.slice(stackW - 1 - info[0]);
357
+ const valueT = info[2](this);
358
+ this.tuple.shift();
359
+ return label == null ? valueT : { $: label, value: valueT } as T;
360
+ }
361
+ // {{/if:stackReadsUnionType}}
362
+
363
+ // {{if:stackReadsCellRef}}
364
+ readCellRef<T>(loadFn_T: LoadCallback<T>): CellRef<T> {
365
+ return { ref: loadFn_T(this.readCell().beginParse()) };
366
+ }
367
+ // {{/if:stackReadsCellRef}}
368
+
369
+ // {{if:stackReadsMapKV}}
370
+ readDictionary<K extends c.DictionaryKeyTypes, V>(keySerializer: c.DictionaryKey<K>, valueSerializer: c.DictionaryValue<V>): c.Dictionary<K, V> {
371
+ if (this.tuple[0].type === 'null') {
372
+ this.tuple.shift();
373
+ return c.Dictionary.empty<K, V>(keySerializer, valueSerializer);
374
+ }
375
+ return c.Dictionary.loadDirect<K, V>(keySerializer, valueSerializer, this.readCell());
376
+ }
377
+ // {{/if:stackReadsMapKV}}
378
+ }
379
+
380
+ // {{if:has_customPackUnpack}}
381
+ // ————————————————————————————————————————————
382
+ // custom packToBuilder and unpackFromSlice
383
+ //
384
+
385
+ type CustomPackToBuilderFn<T> = (self: T, b: c.Builder) => void
386
+ type CustomUnpackFromSliceFn<T> = (s: c.Slice) => T
387
+
388
+ let customSerializersRegistry: Map<string, [CustomPackToBuilderFn<any> | null, CustomUnpackFromSliceFn<any> | null]> = new Map;
389
+
390
+ function ensureCustomSerializerRegistered(typeName: string) {
391
+ if (!customSerializersRegistry.has(typeName)) {
392
+ 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);`);
393
+ }
394
+ }
395
+
396
+ function invokeCustomPackToBuilder<T>(typeName: string, self: T, b: c.Builder) {
397
+ ensureCustomSerializerRegistered(typeName);
398
+ customSerializersRegistry.get(typeName)![0]!(self, b);
399
+ }
400
+
401
+ function invokeCustomUnpackFromSlice<T>(typeName: string, s: c.Slice): T {
402
+ ensureCustomSerializerRegistered(typeName);
403
+ return customSerializersRegistry.get(typeName)![1]!(s);
404
+ }
405
+ // {{/if:has_customPackUnpack}}
406
+
407
+ // ————————————————————————————————————————————
408
+ // auto-generated serializers to/from cells
409
+ //
410
+
411
+ type coins = bigint
412
+
413
+ // {{intNAliases}}
414
+
415
+ // {{uintNAliases}}
416
+
417
+ // {{if:has_varIntN}}
418
+ // {{varIntNAliases}}
419
+ // {{/if:has_varIntN}}
420
+
421
+ // {{if:has_bitsN}}
422
+ // {{sliceAliases}}
423
+ // {{/if:has_bitsN}}
424
+
425
+ // {{packUnpackSerializers}}
426
+
427
+ // ————————————————————————————————————————————
428
+ // class CONTRACT_CLASS_NAME
429
+ //
430
+
431
+ interface ExtraSendOptions {
432
+ bounce?: boolean // default: false
433
+ sendMode?: SendMode // default: SendMode.PAY_GAS_SEPARATELY
434
+ extraCurrencies?: c.ExtraCurrency // default: empty dict
435
+ }
436
+
437
+ interface DeployedAddrOptions {
438
+ workchain?: number // default: 0 (basechain)
439
+ toShard?: { fixedPrefixLength: number; closeTo: c.Address }
440
+ overrideContractCode?: c.Cell
441
+ }
442
+
443
+ function calculateDeployedAddress(code: c.Cell, data: c.Cell, options: DeployedAddrOptions): c.Address {
444
+ const stateInitCell = beginCell().store(c.storeStateInit({
445
+ code,
446
+ data,
447
+ splitDepth: options.toShard?.fixedPrefixLength,
448
+ special: null, // todo will somebody need special?
449
+ libraries: null, // todo will somebody need libraries?
450
+ })).endCell();
451
+
452
+ let addrHash = stateInitCell.hash();
453
+ if (options.toShard) {
454
+ const shardDepth = options.toShard.fixedPrefixLength;
455
+ addrHash = beginCell() // todo any way to do it better? N bits from closeTo + 256-N from stateInitCell
456
+ .storeBits(new c.BitString(options.toShard.closeTo.hash, 0, shardDepth))
457
+ .storeBits(new c.BitString(stateInitCell.hash(), shardDepth, 256 - shardDepth))
458
+ .endCell()
459
+ .beginParse().loadBuffer(32);
460
+ }
461
+
462
+ return new c.Address(options.workchain ?? 0, addrHash);
463
+ }
464
+
465
+ export class CONTRACT_CLASS_NAME implements c.Contract {
466
+ static CodeCell = c.Cell.fromBase64('{{codeBoc64}}');
467
+
468
+ static Errors = {
469
+ // {{errorCodes}}
470
+ }
471
+
472
+ readonly address: c.Address
473
+ readonly init?: { code: c.Cell, data: c.Cell }
474
+
475
+ private constructor(address: c.Address, init?: { code: c.Cell, data: c.Cell }) {
476
+ this.address = address;
477
+ this.init = init;
478
+ }
479
+
480
+ // {{if:has_customPackUnpack}}
481
+ static registerCustomPackUnpack<T>(
482
+ typeName: string,
483
+ packToBuilderFn: CustomPackToBuilderFn<T> | null,
484
+ unpackFromSliceFn: CustomUnpackFromSliceFn<T> | null,
485
+ ) {
486
+ if (customSerializersRegistry.has(typeName)) {
487
+ throw new Error(`Custom pack/unpack for 'CONTRACT_CLASS_NAME.${typeName}' already registered`);
488
+ }
489
+ customSerializersRegistry.set(typeName, [packToBuilderFn, unpackFromSliceFn]);
490
+ }
491
+ // {{/if:has_customPackUnpack}}
492
+
493
+ static fromAddress(address: c.Address) {
494
+ return new CONTRACT_CLASS_NAME(address);
495
+ }
496
+
497
+ // {{fromStorageMethod}}
498
+
499
+ // {{createCellsMethods}}
500
+
501
+ // {{if:has_sendDeploy}}
502
+ async sendDeploy(provider: ContractProvider, via: Sender, msgValue: coins, extraOptions?: ExtraSendOptions) {
503
+ return provider.internal(via, {
504
+ value: msgValue,
505
+ body: c.Cell.EMPTY,
506
+ ...extraOptions
507
+ });
508
+ }
509
+ // {{/if:has_sendDeploy}}
510
+
511
+ // {{sendMethods}}
512
+
513
+ // {{getMethods}}
514
+ }
@@ -0,0 +1,5 @@
1
+ import type { ContractABI } from './abi';
2
+
3
+ export async function convertTolkFileToABI(_absFileName: string): Promise<ContractABI> {
4
+ throw new Error('Compiling .tolk files is not supported in this package build. Pass ABI JSON directly to the CLI.');
5
+ }