@tezos-x/octez.js-michel-codec 0.9.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.
Files changed (41) hide show
  1. package/README.md +174 -0
  2. package/dist/lib/base58.js +255 -0
  3. package/dist/lib/binary.js +1272 -0
  4. package/dist/lib/errors.js +90 -0
  5. package/dist/lib/formatters.js +60 -0
  6. package/dist/lib/global-constants.js +12 -0
  7. package/dist/lib/macros.js +548 -0
  8. package/dist/lib/micheline-emitter.js +132 -0
  9. package/dist/lib/micheline-parser.js +403 -0
  10. package/dist/lib/micheline.js +5 -0
  11. package/dist/lib/michelson-contract.js +93 -0
  12. package/dist/lib/michelson-typecheck.js +1752 -0
  13. package/dist/lib/michelson-types.js +83 -0
  14. package/dist/lib/michelson-validator.js +835 -0
  15. package/dist/lib/octez.js-michel-codec.js +38 -0
  16. package/dist/lib/scan.js +128 -0
  17. package/dist/lib/utils.js +321 -0
  18. package/dist/lib/version.js +8 -0
  19. package/dist/octez.js-michel-codec.es6.js +5790 -0
  20. package/dist/octez.js-michel-codec.es6.js.map +1 -0
  21. package/dist/octez.js-michel-codec.umd.js +5854 -0
  22. package/dist/octez.js-michel-codec.umd.js.map +1 -0
  23. package/dist/types/base58.d.ts +13 -0
  24. package/dist/types/binary.d.ts +127 -0
  25. package/dist/types/errors.d.ts +57 -0
  26. package/dist/types/formatters.d.ts +6 -0
  27. package/dist/types/global-constants.d.ts +3 -0
  28. package/dist/types/macros.d.ts +13 -0
  29. package/dist/types/micheline-emitter.d.ts +17 -0
  30. package/dist/types/micheline-parser.d.ts +130 -0
  31. package/dist/types/micheline.d.ts +44 -0
  32. package/dist/types/michelson-contract.d.ts +24 -0
  33. package/dist/types/michelson-typecheck.d.ts +38 -0
  34. package/dist/types/michelson-types.d.ts +147 -0
  35. package/dist/types/michelson-validator.d.ts +66 -0
  36. package/dist/types/octez.js-michel-codec.d.ts +16 -0
  37. package/dist/types/scan.d.ts +26 -0
  38. package/dist/types/utils.d.ts +77 -0
  39. package/dist/types/version.d.ts +4 -0
  40. package/package.json +94 -0
  41. package/signature.json +315 -0
@@ -0,0 +1,1752 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.MichelsonInstructionError = void 0;
15
+ exports.assertTypeAnnotationsValid = assertTypeAnnotationsValid;
16
+ exports.contractSection = contractSection;
17
+ exports.contractViews = contractViews;
18
+ exports.contractEntryPoint = contractEntryPoint;
19
+ exports.contractEntryPoints = contractEntryPoints;
20
+ exports.assertContractValid = assertContractValid;
21
+ exports.assertDataValid = assertDataValid;
22
+ exports.functionType = functionType;
23
+ exports.assertTypesEqual = assertTypesEqual;
24
+ exports.isTypeAnnotationsValid = isTypeAnnotationsValid;
25
+ exports.isContractValid = isContractValid;
26
+ exports.isDataValid = isDataValid;
27
+ exports.isTypeEqual = isTypeEqual;
28
+ const michelson_types_1 = require("./michelson-types");
29
+ const utils_1 = require("./utils");
30
+ const base58_1 = require("./base58");
31
+ const binary_1 = require("./binary");
32
+ const michelson_validator_1 = require("./michelson-validator");
33
+ class MichelsonInstructionError extends utils_1.MichelsonError {
34
+ /**
35
+ * @param val Value of a type node caused the error
36
+ * @param stackState Current stack state
37
+ * @param message An error message
38
+ */
39
+ constructor(val, stackState, message) {
40
+ super(val, message);
41
+ this.val = val;
42
+ this.stackState = stackState;
43
+ this.message = message;
44
+ this.name = 'MichelsonInstructionError';
45
+ }
46
+ }
47
+ exports.MichelsonInstructionError = MichelsonInstructionError;
48
+ // 'sequence as a pair' edo syntax helpers
49
+ function typeID(t) {
50
+ return Array.isArray(t) ? 'pair' : t.prim;
51
+ }
52
+ function typeArgs(t) {
53
+ return ('prim' in t ? t.args : t);
54
+ }
55
+ function assertScalarTypesEqual(a, b, field = false) {
56
+ if (typeID(a) !== typeID(b)) {
57
+ throw new utils_1.MichelsonTypeError(a, `types mismatch: ${typeID(a)} != ${typeID(b)}`, undefined);
58
+ }
59
+ const ann = [(0, utils_1.unpackAnnotations)(a), (0, utils_1.unpackAnnotations)(b)];
60
+ if (ann[0].t && ann[1].t && ann[0].t[0] !== ann[1].t[0]) {
61
+ throw new utils_1.MichelsonTypeError(a, `${typeID(a)}: type names mismatch: ${ann[0].t[0]} != ${ann[1].t[0]}`, undefined);
62
+ }
63
+ if (field && ann[0].f && ann[1].f && ann[0].f[0] !== ann[1].f[0]) {
64
+ throw new utils_1.MichelsonTypeError(a, `${typeID(a)}: field names mismatch: ${ann[0].f[0]} != ${ann[1].f}`, undefined);
65
+ }
66
+ if ((0, utils_1.isPairType)(a)) {
67
+ const aArgs = (0, utils_1.unpackComb)('pair', a);
68
+ const bArgs = (0, utils_1.unpackComb)('pair', b);
69
+ assertScalarTypesEqual(aArgs.args[0], bArgs.args[0], true);
70
+ assertScalarTypesEqual(aArgs.args[1], bArgs.args[1], true);
71
+ return;
72
+ }
73
+ switch (a.prim) {
74
+ case 'option':
75
+ case 'list':
76
+ case 'contract':
77
+ case 'set':
78
+ case 'ticket':
79
+ assertScalarTypesEqual(a.args[0], b.args[0]);
80
+ break;
81
+ case 'or':
82
+ assertScalarTypesEqual(a.args[0], b.args[0], true);
83
+ assertScalarTypesEqual(a.args[1], b.args[1], true);
84
+ break;
85
+ case 'lambda':
86
+ case 'map':
87
+ case 'big_map':
88
+ assertScalarTypesEqual(a.args[0], b.args[0]);
89
+ assertScalarTypesEqual(a.args[1], b.args[1]);
90
+ break;
91
+ case 'sapling_state':
92
+ case 'sapling_transaction':
93
+ if (parseInt(a.args[0].int, 10) !== parseInt(b.args[0].int, 10)) {
94
+ throw new utils_1.MichelsonTypeError(a, `${typeID(a)}: type argument mismatch: ${a.args[0].int} != ${b.args[0].int}`, undefined);
95
+ }
96
+ }
97
+ }
98
+ function assertStacksEqual(a, b) {
99
+ if (a.length !== b.length) {
100
+ throw new utils_1.MichelsonTypeError(a, `stack length mismatch: ${a.length} != ${b.length}`, undefined);
101
+ }
102
+ for (let i = 0; i < a.length; i++) {
103
+ assertScalarTypesEqual(a[i], b[i]);
104
+ }
105
+ }
106
+ function assertTypeAnnotationsValid(t, field = false) {
107
+ var _a, _b, _c;
108
+ if (!Array.isArray(t)) {
109
+ const ann = (0, utils_1.unpackAnnotations)(t);
110
+ if ((((_a = ann.t) === null || _a === void 0 ? void 0 : _a.length) || 0) > 1) {
111
+ throw new utils_1.MichelsonTypeError(t, `${t.prim}: at most one type annotation allowed: ${t.annots}`, undefined);
112
+ }
113
+ if (field) {
114
+ if ((((_b = ann.f) === null || _b === void 0 ? void 0 : _b.length) || 0) > 1) {
115
+ throw new utils_1.MichelsonTypeError(t, `${t.prim}: at most one field annotation allowed: ${t.annots}`, undefined);
116
+ }
117
+ }
118
+ else {
119
+ if ((((_c = ann.f) === null || _c === void 0 ? void 0 : _c.length) || 0) > 0) {
120
+ throw new utils_1.MichelsonTypeError(t, `${t.prim}: field annotations aren't allowed: ${t.annots}`, undefined);
121
+ }
122
+ }
123
+ }
124
+ if ((0, utils_1.isPairType)(t)) {
125
+ const args = typeArgs(t);
126
+ for (const a of args) {
127
+ assertTypeAnnotationsValid(a, true);
128
+ }
129
+ return;
130
+ }
131
+ switch (t.prim) {
132
+ case 'option':
133
+ case 'list':
134
+ case 'contract':
135
+ case 'set':
136
+ assertTypeAnnotationsValid(t.args[0]);
137
+ break;
138
+ case 'or':
139
+ for (const a of t.args) {
140
+ assertTypeAnnotationsValid(a, true);
141
+ }
142
+ break;
143
+ case 'lambda':
144
+ case 'map':
145
+ case 'big_map':
146
+ assertTypeAnnotationsValid(t.args[0]);
147
+ assertTypeAnnotationsValid(t.args[1]);
148
+ }
149
+ }
150
+ // Data integrity check
151
+ function _compareMichelsonData(t, a, b) {
152
+ if ((0, utils_1.isPairType)(t)) {
153
+ if ((0, utils_1.isPairData)(a) && (0, utils_1.isPairData)(b)) {
154
+ (0, michelson_validator_1.assertDataListIfAny)(a);
155
+ (0, michelson_validator_1.assertDataListIfAny)(b);
156
+ const tComb = (0, utils_1.unpackComb)('pair', t);
157
+ const aComb = (0, utils_1.unpackComb)('Pair', a);
158
+ const bComb = (0, utils_1.unpackComb)('Pair', b);
159
+ const x = _compareMichelsonData(tComb.args[0], aComb.args[0], bComb.args[0]);
160
+ if (x !== 0) {
161
+ return x;
162
+ }
163
+ return _compareMichelsonData(tComb.args[0], aComb.args[1], bComb.args[1]);
164
+ }
165
+ }
166
+ else {
167
+ switch (t.prim) {
168
+ case 'int':
169
+ case 'nat':
170
+ case 'mutez':
171
+ if ('int' in a && 'int' in b) {
172
+ return new utils_1.LongInteger(a.int).cmp(new utils_1.LongInteger(b.int));
173
+ }
174
+ break;
175
+ case 'string':
176
+ if ('string' in a && 'string' in b) {
177
+ const x = a.string.localeCompare(b.string);
178
+ return x < 0 ? -1 : x > 0 ? 1 : 0;
179
+ }
180
+ break;
181
+ case 'bytes':
182
+ if ('bytes' in a && 'bytes' in b) {
183
+ const aa = (0, utils_1.parseBytes)(a.bytes);
184
+ const bb = (0, utils_1.parseBytes)(b.bytes);
185
+ if (aa !== null && bb !== null) {
186
+ return (0, utils_1.compareBytes)(aa, bb);
187
+ }
188
+ }
189
+ break;
190
+ case 'bool':
191
+ if ('prim' in a &&
192
+ 'prim' in b &&
193
+ (a.prim === 'True' || a.prim === 'False') &&
194
+ (b.prim === 'True' || b.prim === 'False')) {
195
+ return a.prim === b.prim ? 0 : a.prim === 'False' ? -1 : 1;
196
+ }
197
+ break;
198
+ case 'key':
199
+ case 'key_hash':
200
+ case 'address':
201
+ case 'signature':
202
+ case 'chain_id':
203
+ if (('string' in a || 'bytes' in a) && ('string' in b || 'bytes' in b)) {
204
+ return (0, utils_1.compareBytes)('string' in a ? (0, base58_1.decodeBase58Check)(a.string) : (0, utils_1.parseBytes)(a.bytes) || [], 'string' in b ? (0, base58_1.decodeBase58Check)(b.string) : (0, utils_1.parseBytes)(b.bytes) || []);
205
+ }
206
+ break;
207
+ case 'timestamp':
208
+ if (('string' in a || 'int' in a) && ('string' in b || 'int' in b)) {
209
+ const aa = (0, utils_1.parseDate)(a);
210
+ const bb = (0, utils_1.parseDate)(b);
211
+ if (aa !== null && bb !== null) {
212
+ const x = aa.valueOf() - bb.valueOf();
213
+ return x < 0 ? -1 : x > 0 ? 1 : 0;
214
+ }
215
+ }
216
+ break;
217
+ case 'unit':
218
+ if ('prim' in a && 'prim' in b && a.prim === 'Unit' && b.prim === 'Unit') {
219
+ return 0;
220
+ }
221
+ }
222
+ }
223
+ // Unlikely, types are expected to be verified before the function call
224
+ throw new utils_1.MichelsonTypeError(t, `${typeID(t)}: not comparable values: ${JSON.stringify(a)}, ${JSON.stringify(b)}`, undefined);
225
+ }
226
+ // Simplified version of assertMichelsonInstruction() for previously validated data
227
+ function isFunction(d) {
228
+ if (!Array.isArray(d)) {
229
+ return false;
230
+ }
231
+ for (const v of d) {
232
+ if (!((Array.isArray(v) && isFunction(v)) || ('prim' in v && (0, michelson_validator_1.isInstruction)(v)))) {
233
+ return false;
234
+ }
235
+ }
236
+ return true;
237
+ }
238
+ function assertDataValidInternal(d, t, ctx) {
239
+ if ((0, utils_1.isPairType)(t)) {
240
+ if ((0, utils_1.isPairData)(d)) {
241
+ (0, michelson_validator_1.assertDataListIfAny)(d);
242
+ const dc = (0, utils_1.unpackComb)('Pair', d);
243
+ const tc = (0, utils_1.unpackComb)('pair', t);
244
+ assertDataValidInternal(dc.args[0], tc.args[0], ctx);
245
+ assertDataValidInternal(dc.args[1], tc.args[1], ctx);
246
+ return;
247
+ }
248
+ throw new utils_1.MichelsonTypeError(t, `pair expected: ${JSON.stringify(d)}`, d);
249
+ }
250
+ switch (t.prim) {
251
+ // Atomic literals
252
+ case 'int':
253
+ if ('int' in d && (0, utils_1.isDecimal)(d.int)) {
254
+ return;
255
+ }
256
+ throw new utils_1.MichelsonTypeError(t, `integer value expected: ${JSON.stringify(d)}`, d);
257
+ case 'nat':
258
+ case 'mutez':
259
+ if ('int' in d && (0, utils_1.isNatural)(d.int)) {
260
+ return;
261
+ }
262
+ throw new utils_1.MichelsonTypeError(t, `natural value expected: ${JSON.stringify(d)}`, d);
263
+ case 'string':
264
+ if ('string' in d) {
265
+ return;
266
+ }
267
+ throw new utils_1.MichelsonTypeError(t, `string value expected: ${JSON.stringify(d)}`, d);
268
+ case 'bytes':
269
+ case 'bls12_381_g1':
270
+ case 'bls12_381_g2':
271
+ if ('bytes' in d && (0, utils_1.parseBytes)(d.bytes) !== null) {
272
+ return;
273
+ }
274
+ throw new utils_1.MichelsonTypeError(t, `bytes value expected: ${JSON.stringify(d)}`, d);
275
+ case 'bool':
276
+ if ('prim' in d && (d.prim === 'True' || d.prim === 'False')) {
277
+ return;
278
+ }
279
+ throw new utils_1.MichelsonTypeError(t, `boolean value expected: ${JSON.stringify(d)}`, d);
280
+ case 'key_hash':
281
+ if ('string' in d &&
282
+ (0, utils_1.checkDecodeTezosID)(d.string, 'ED25519PublicKeyHash', 'SECP256K1PublicKeyHash', 'P256PublicKeyHash') !== null) {
283
+ return;
284
+ }
285
+ else if ('bytes' in d) {
286
+ try {
287
+ (0, binary_1.decodePublicKeyHashBytes)(d);
288
+ return;
289
+ }
290
+ catch (err) {
291
+ // ignore message
292
+ }
293
+ }
294
+ throw new utils_1.MichelsonTypeError(t, `key hash expected: ${JSON.stringify(d)}`, d);
295
+ case 'timestamp':
296
+ if (('string' in d || 'int' in d) && (0, utils_1.parseDate)(d) !== null) {
297
+ return;
298
+ }
299
+ throw new utils_1.MichelsonTypeError(t, `timestamp expected: ${JSON.stringify(d)}`, d);
300
+ case 'address':
301
+ if ('string' in d) {
302
+ let address = d.string;
303
+ const ep = d.string.indexOf('%');
304
+ if (ep >= 0) {
305
+ // trim entry point
306
+ address = d.string.slice(0, ep);
307
+ }
308
+ if ((0, utils_1.checkDecodeTezosID)(address, 'ED25519PublicKeyHash', 'SECP256K1PublicKeyHash', 'P256PublicKeyHash', 'ContractHash', 'RollupAddress') !== null) {
309
+ return;
310
+ }
311
+ }
312
+ else if ('bytes' in d) {
313
+ try {
314
+ (0, binary_1.decodeAddressBytes)(d);
315
+ return;
316
+ }
317
+ catch (err) {
318
+ // ignore message
319
+ }
320
+ }
321
+ throw new utils_1.MichelsonTypeError(t, `address expected: ${JSON.stringify(d)}`, d);
322
+ case 'key':
323
+ if ('string' in d &&
324
+ (0, utils_1.checkDecodeTezosID)(d.string, 'ED25519PublicKey', 'SECP256K1PublicKey', 'P256PublicKey') !==
325
+ null) {
326
+ return;
327
+ }
328
+ else if ('bytes' in d) {
329
+ try {
330
+ (0, binary_1.decodePublicKeyBytes)(d);
331
+ return;
332
+ }
333
+ catch (err) {
334
+ // ignore message
335
+ }
336
+ }
337
+ throw new utils_1.MichelsonTypeError(t, `public key expected: ${JSON.stringify(d)}`, d);
338
+ case 'unit':
339
+ if ('prim' in d && d.prim === 'Unit') {
340
+ return;
341
+ }
342
+ throw new utils_1.MichelsonTypeError(t, `unit value expected: ${JSON.stringify(d)}`, d);
343
+ case 'signature':
344
+ if ('bytes' in d ||
345
+ ('string' in d &&
346
+ (0, utils_1.checkDecodeTezosID)(d.string, 'ED25519Signature', 'SECP256K1Signature', 'P256Signature', 'GenericSignature') !== null)) {
347
+ return;
348
+ }
349
+ throw new utils_1.MichelsonTypeError(t, `signature expected: ${JSON.stringify(d)}`, d);
350
+ case 'chain_id':
351
+ if ('bytes' in d || 'string' in d) {
352
+ const x = 'string' in d ? (0, base58_1.decodeBase58Check)(d.string) : (0, utils_1.parseBytes)(d.bytes);
353
+ if (x !== null) {
354
+ return;
355
+ }
356
+ }
357
+ throw new utils_1.MichelsonTypeError(t, `chain id expected: ${JSON.stringify(d)}`, d);
358
+ // Complex types
359
+ case 'option':
360
+ if ('prim' in d) {
361
+ if (d.prim === 'None') {
362
+ return;
363
+ }
364
+ else if (d.prim === 'Some') {
365
+ assertDataValidInternal(d.args[0], t.args[0], ctx);
366
+ return;
367
+ }
368
+ }
369
+ throw new utils_1.MichelsonTypeError(t, `option expected: ${JSON.stringify(d)}`, d);
370
+ case 'list':
371
+ case 'set':
372
+ if ((0, michelson_validator_1.assertDataListIfAny)(d)) {
373
+ //let prev: MichelsonData | undefined;
374
+ for (const v of d) {
375
+ assertDataValidInternal(v, t.args[0], ctx);
376
+ }
377
+ return;
378
+ }
379
+ throw new utils_1.MichelsonTypeError(t, `${t.prim} expected: ${JSON.stringify(d)}`, d);
380
+ case 'or':
381
+ if ('prim' in d) {
382
+ if (d.prim === 'Left') {
383
+ assertDataValidInternal(d.args[0], t.args[0], ctx);
384
+ return;
385
+ }
386
+ else if (d.prim === 'Right') {
387
+ assertDataValidInternal(d.args[0], t.args[1], ctx);
388
+ return;
389
+ }
390
+ }
391
+ throw new utils_1.MichelsonTypeError(t, `union (or) expected: ${JSON.stringify(d)}`, d);
392
+ case 'lambda':
393
+ if (isFunction(d)) {
394
+ const ret = functionTypeInternal(d, [t.args[0]], ctx);
395
+ if ('failed' in ret) {
396
+ throw new utils_1.MichelsonTypeError(t, `function is failed with error type: ${ret.failed}`, d);
397
+ }
398
+ if (ret.length !== 1) {
399
+ throw new utils_1.MichelsonTypeError(t, 'function must return a value', d);
400
+ }
401
+ assertScalarTypesEqual(t.args[1], ret[0]);
402
+ return;
403
+ }
404
+ throw new utils_1.MichelsonTypeError(t, `function expected: ${JSON.stringify(d)}`, d);
405
+ case 'map':
406
+ case 'big_map':
407
+ if (Array.isArray(d)) {
408
+ //let prev: MichelsonMapElt | undefined;
409
+ for (const v of d) {
410
+ if (!('prim' in v) || v.prim !== 'Elt') {
411
+ throw new utils_1.MichelsonTypeError(t, `map elements expected: ${JSON.stringify(d)}`, d);
412
+ }
413
+ assertDataValidInternal(v.args[0], t.args[0], ctx);
414
+ assertDataValidInternal(v.args[1], t.args[1], ctx);
415
+ }
416
+ return;
417
+ }
418
+ throw new utils_1.MichelsonTypeError(t, `${t.prim} expected: ${JSON.stringify(d)}`, d);
419
+ case 'bls12_381_fr':
420
+ if (('int' in d && (0, utils_1.isDecimal)(d.int)) || ('bytes' in d && (0, utils_1.parseBytes)(d.bytes) !== null)) {
421
+ return;
422
+ }
423
+ throw new utils_1.MichelsonTypeError(t, `BLS12-381 element expected: ${JSON.stringify(d)}`, d);
424
+ case 'sapling_state':
425
+ if (Array.isArray(d)) {
426
+ return;
427
+ }
428
+ throw new utils_1.MichelsonTypeError(t, `sapling state expected: ${JSON.stringify(d)}`, d);
429
+ case 'ticket':
430
+ if ('prim' in d && d.prim === 'Ticket') {
431
+ assertDataValidInternal(d.args[0], { prim: 'address' }, ctx);
432
+ assertTypesEqual(d.args[1], t.args[0]);
433
+ assertDataValidInternal(d.args[2], t.args[0], ctx);
434
+ assertDataValidInternal(d.args[3], { prim: 'nat' }, ctx);
435
+ return;
436
+ }
437
+ else if ((0, utils_1.isPairData)(d)) {
438
+ // backward compatibility
439
+ assertDataValidInternal(d, {
440
+ prim: 'pair',
441
+ args: [{ prim: 'address' }, t.args[0], { prim: 'nat' }],
442
+ }, ctx);
443
+ return;
444
+ }
445
+ throw new utils_1.MichelsonTypeError(t, `ticket expected: ${JSON.stringify(d)}`, d);
446
+ default:
447
+ throw new utils_1.MichelsonTypeError(t, `type ${typeID(t)} don't have Michelson literal representation`, d);
448
+ }
449
+ }
450
+ function instructionListType(inst, stack, ctx) {
451
+ let ret = stack;
452
+ let s = stack;
453
+ let i = 0;
454
+ for (const op of inst) {
455
+ const ft = functionTypeInternal(op, s, ctx);
456
+ ret = ft;
457
+ if ('failed' in ft) {
458
+ break;
459
+ }
460
+ s = ft;
461
+ i++;
462
+ }
463
+ if ('failed' in ret &&
464
+ ret.level == 0 &&
465
+ (!('prim' in ret.failed) || ret.failed.prim !== 'never') &&
466
+ i !== inst.length - 1) {
467
+ throw new MichelsonInstructionError(inst, ret, 'FAIL must appear in a tail position');
468
+ }
469
+ if ((ctx === null || ctx === void 0 ? void 0 : ctx.traceCallback) !== undefined) {
470
+ const trace = {
471
+ op: inst,
472
+ in: stack,
473
+ out: ret,
474
+ };
475
+ ctx.traceCallback(trace);
476
+ }
477
+ return 'failed' in ret ? { failed: ret.failed, level: ret.level + 1 } : ret;
478
+ }
479
+ function functionTypeInternal(inst, stack, ctx) {
480
+ const proto = (ctx === null || ctx === void 0 ? void 0 : ctx.protocol) || michelson_types_1.DefaultProtocol;
481
+ if (Array.isArray(inst)) {
482
+ return instructionListType(inst, stack, ctx);
483
+ }
484
+ const instruction = inst; // Make it const for type guarding
485
+ // make sure the stack has enough number of arguments of specific types
486
+ function args(n, ...typeIds) {
487
+ if (stack.length < typeIds.length + n) {
488
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: stack must have at least ${typeIds.length} element(s)`);
489
+ }
490
+ let i = n;
491
+ for (const ids of typeIds) {
492
+ if (ids !== null && ids.length !== 0) {
493
+ let ii = 0;
494
+ while (ii < ids.length && ids[ii] !== typeID(stack[i])) {
495
+ ii++;
496
+ }
497
+ if (ii === ids.length) {
498
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: stack type mismatch: [${i}] expected to be ${ids}, got ${typeID(stack[i])} instead`);
499
+ }
500
+ }
501
+ i++;
502
+ }
503
+ return stack.slice(n, typeIds.length + n);
504
+ }
505
+ function rethrow(fn) {
506
+ return (...args) => {
507
+ try {
508
+ return fn(...args);
509
+ }
510
+ catch (err) {
511
+ if (err instanceof utils_1.MichelsonError) {
512
+ throw new MichelsonInstructionError(instruction, stack, err.message);
513
+ }
514
+ else {
515
+ throw err;
516
+ }
517
+ }
518
+ };
519
+ }
520
+ function rethrowTypeGuard(fn) {
521
+ return (arg) => {
522
+ try {
523
+ return fn(arg);
524
+ }
525
+ catch (err) {
526
+ if (err instanceof utils_1.MichelsonError) {
527
+ throw new MichelsonInstructionError(instruction, stack, err.message);
528
+ }
529
+ else {
530
+ throw err;
531
+ }
532
+ }
533
+ };
534
+ }
535
+ const argAnn = rethrow(utils_1.unpackAnnotations);
536
+ const ensureStacksEqual = rethrow(assertStacksEqual);
537
+ const ensureTypesEqual = rethrow(assertScalarTypesEqual);
538
+ const ensureComparableType = rethrowTypeGuard(michelson_validator_1.assertMichelsonComparableType);
539
+ const ensurePackableType = rethrowTypeGuard(michelson_validator_1.assertMichelsonPackableType);
540
+ const ensureStorableType = rethrowTypeGuard(michelson_validator_1.assertMichelsonStorableType);
541
+ const ensurePushableType = rethrowTypeGuard(michelson_validator_1.assertMichelsonPushableType);
542
+ const ensureBigMapStorableType = rethrowTypeGuard(michelson_validator_1.assertMichelsonBigMapStorableType);
543
+ // unpack instruction annotations and assert their maximum number
544
+ function instructionAnn(num, opt) {
545
+ const a = argAnn(instruction, Object.assign(Object.assign({}, opt), { emptyFields: num.f !== undefined && num.f > 1, emptyVar: num.v !== undefined && num.v > 1 }));
546
+ const assertNum = (a, n, type) => {
547
+ if (a && a.length > (n || 0)) {
548
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: at most ${n || 0} ${type} annotations allowed`);
549
+ }
550
+ };
551
+ assertNum(a.f, num.f, 'field');
552
+ assertNum(a.t, num.t, 'type');
553
+ assertNum(a.v, num.v, 'variable');
554
+ return a;
555
+ }
556
+ // also keeps annotation class if null is provided
557
+ function annotate(tt, a) {
558
+ const tx = tt;
559
+ const t = Array.isArray(tx) ? { prim: 'pair', args: tx } : tx;
560
+ const src = argAnn(t);
561
+ const ann = a.v !== undefined || a.t !== undefined || a.f !== undefined
562
+ ? [
563
+ ...((a.v === null ? src.v : a.v) || []),
564
+ ...((a.t === null ? src.t : a.t) || []),
565
+ ...((a.f === null ? src.f : a.f) || []),
566
+ ]
567
+ : undefined;
568
+ const { annots: _annots } = t, rest = __rest(t, ["annots"]);
569
+ return Object.assign(Object.assign({}, rest), (ann && ann.length !== 0 && { annots: ann }));
570
+ }
571
+ // shortcut to copy at most one variable annotation from the instruction to the type
572
+ function annotateVar(t, def) {
573
+ const ia = instructionAnn({ v: 1 });
574
+ return annotate(t, {
575
+ v: ia.v !== undefined ? ia.v : def !== undefined ? [def] : null,
576
+ t: null,
577
+ });
578
+ }
579
+ // annotate CAR/CDR/UNPAIR/GET
580
+ function annotateField(arg, field, insAnn, n, defField) {
581
+ var _a, _b, _c, _d;
582
+ const fieldAnn = (_a = argAnn(field).f) === null || _a === void 0 ? void 0 : _a[0]; // field's field annotation
583
+ const insFieldAnn = (_b = insAnn.f) === null || _b === void 0 ? void 0 : _b[n];
584
+ if (insFieldAnn !== undefined &&
585
+ insFieldAnn !== '%' &&
586
+ fieldAnn !== undefined &&
587
+ insFieldAnn !== fieldAnn) {
588
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: field names doesn't match: ${insFieldAnn} !== ${fieldAnn}`);
589
+ }
590
+ const insVarAnn = (_c = insAnn.v) === null || _c === void 0 ? void 0 : _c[n]; // nth instruction's variable annotation
591
+ const varAnn = (_d = argAnn(arg).v) === null || _d === void 0 ? void 0 : _d[0]; // instruction argument's variable annotation
592
+ return annotate(field, {
593
+ t: null,
594
+ v: insVarAnn
595
+ ? insVarAnn === '@%'
596
+ ? fieldAnn
597
+ ? ['@' + fieldAnn.slice(1)]
598
+ : undefined
599
+ : insVarAnn === '@%%'
600
+ ? varAnn
601
+ ? ['@' + varAnn.slice(1) + '.' + (fieldAnn ? fieldAnn.slice(1) : defField)]
602
+ : fieldAnn
603
+ ? ['@' + fieldAnn.slice(1)]
604
+ : undefined
605
+ : [insVarAnn]
606
+ : null,
607
+ });
608
+ }
609
+ // comb helper functions
610
+ function getN(src, n, i = n) {
611
+ const p = (0, utils_1.unpackComb)('pair', src);
612
+ if (i === 1) {
613
+ return [p.args[0]];
614
+ }
615
+ else if (i === 2) {
616
+ return p.args;
617
+ }
618
+ const right = p.args[1];
619
+ if ((0, utils_1.isPairType)(right)) {
620
+ return [p.args[0], ...getN(right, n, i - 1)];
621
+ }
622
+ else {
623
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: at least ${n} fields are expected`);
624
+ }
625
+ }
626
+ function getNth(src, n, i = n) {
627
+ if (i === 0) {
628
+ return src;
629
+ }
630
+ const p = (0, utils_1.unpackComb)('pair', src);
631
+ if (i === 1) {
632
+ return p.args[0];
633
+ }
634
+ const right = p.args[1];
635
+ if ((0, utils_1.isPairType)(right)) {
636
+ return getNth(right, n, i - 2);
637
+ }
638
+ else if (i === 2) {
639
+ return right;
640
+ }
641
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: at least ${n + 1} fields are expected`);
642
+ }
643
+ function updateNth(src, x, n, i = n) {
644
+ if (i === 0) {
645
+ return x;
646
+ }
647
+ const p = (0, utils_1.unpackComb)('pair', src);
648
+ if (i === 1) {
649
+ return Object.assign(Object.assign({}, p), { args: [x, p.args[1]] });
650
+ }
651
+ const right = p.args[1];
652
+ if ((0, utils_1.isPairType)(right)) {
653
+ return Object.assign(Object.assign({}, p), { args: [p.args[0], updateNth(right, x, n, i - 2)] });
654
+ }
655
+ else if (i === 2) {
656
+ return Object.assign(Object.assign({}, p), { args: [p.args[0], x] });
657
+ }
658
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: at least ${n + 1} fields are expected`);
659
+ }
660
+ const varSuffix = (a, suffix) => [
661
+ '@' + (a.v ? a.v[0].slice(1) + '.' : '') + suffix,
662
+ ];
663
+ function branchType(br0, br1) {
664
+ if ('failed' in br0 || 'failed' in br1) {
665
+ return 'failed' in br0 ? br1 : br0;
666
+ }
667
+ else {
668
+ ensureStacksEqual(br0, br1);
669
+ return br0;
670
+ }
671
+ }
672
+ const retStack = ((instruction) => {
673
+ var _a, _b, _c, _d, _e;
674
+ switch (instruction.prim) {
675
+ case 'DUP': {
676
+ const n = instruction.args ? parseInt(instruction.args[0].int, 10) : 1;
677
+ if (n === 0) {
678
+ throw new MichelsonInstructionError(instruction, stack, 'DUP 0 is forbidden');
679
+ }
680
+ const s = args(n - 1, null)[0];
681
+ if (typeID(s) === 'ticket') {
682
+ throw new MichelsonInstructionError(instruction, stack, "ticket can't be DUPed");
683
+ }
684
+ return [s, ...stack];
685
+ }
686
+ case 'SWAP': {
687
+ const s = args(0, null, null);
688
+ instructionAnn({});
689
+ return [s[1], s[0], ...stack.slice(2)];
690
+ }
691
+ case 'SOME':
692
+ return [
693
+ annotate({ prim: 'option', args: [args(0, null)[0]] }, instructionAnn({ t: 1, v: 1 })),
694
+ ...stack.slice(1),
695
+ ];
696
+ case 'UNIT':
697
+ return [annotate({ prim: 'unit' }, instructionAnn({ v: 1, t: 1 })), ...stack];
698
+ case 'PAIR': {
699
+ const n = instruction.args ? parseInt(instruction.args[0].int, 10) : 2;
700
+ if (n < 2) {
701
+ throw new MichelsonInstructionError(instruction, stack, `PAIR ${n} is forbidden`);
702
+ }
703
+ const s = args(0, ...new Array(n).fill(null));
704
+ const ia = instructionAnn({ f: n, t: 1, v: 1 }, { specialFields: true });
705
+ const trim = (s) => {
706
+ const i = s.lastIndexOf('.');
707
+ return s.slice(i > 0 ? i + 1 : 1);
708
+ };
709
+ const retArgs = s.map((v, i) => {
710
+ var _a;
711
+ const va = argAnn(v);
712
+ const f = ia.f && ia.f.length > i && ia.f[i] !== '%'
713
+ ? ia.f[i] === '%@'
714
+ ? va.v
715
+ ? ['%' + trim(((_a = va.v) === null || _a === void 0 ? void 0 : _a[0]) || '')]
716
+ : undefined
717
+ : [ia.f[i]]
718
+ : undefined;
719
+ return annotate(v, { v: null, t: null, f });
720
+ });
721
+ return [
722
+ annotate({
723
+ prim: 'pair',
724
+ args: retArgs,
725
+ }, { t: ia.t, v: ia.v }),
726
+ ...stack.slice(n),
727
+ ];
728
+ }
729
+ case 'UNPAIR': {
730
+ const n = instruction.args ? parseInt(instruction.args[0].int, 10) : 2;
731
+ if (n < 2) {
732
+ throw new MichelsonInstructionError(instruction, stack, `UNPAIR ${n} is forbidden`);
733
+ }
734
+ const s = args(0, ['pair'])[0];
735
+ const ia = instructionAnn({ f: 2, v: 2 }, { specialVar: true });
736
+ const fields = getN(s, n);
737
+ return [
738
+ ...fields.map((field, i) => annotateField(s, field, ia, i, i === 0 ? 'car' : 'cdr')),
739
+ ...stack.slice(1),
740
+ ];
741
+ }
742
+ case 'CAR':
743
+ case 'CDR': {
744
+ const s = (0, utils_1.unpackComb)('pair', args(0, ['pair'])[0]);
745
+ const field = s.args[instruction.prim === 'CAR' ? 0 : 1];
746
+ const ia = instructionAnn({ f: 1, v: 1 }, { specialVar: true });
747
+ return [
748
+ annotateField(s, field, ia, 0, instruction.prim.toLocaleLowerCase()),
749
+ ...stack.slice(1),
750
+ ];
751
+ }
752
+ case 'CONS': {
753
+ const s = args(0, null, ['list']);
754
+ ensureTypesEqual(s[0], s[1].args[0]);
755
+ return [annotateVar({ prim: 'list', args: [s[1].args[0]] }), ...stack.slice(2)];
756
+ }
757
+ case 'SIZE':
758
+ args(0, ['string', 'list', 'set', 'map', 'bytes']);
759
+ return [annotateVar({ prim: 'nat' }), ...stack.slice(1)];
760
+ case 'MEM': {
761
+ const s = args(0, null, ['set', 'map', 'big_map']);
762
+ ensureComparableType(s[0]);
763
+ ensureTypesEqual(s[0], s[1].args[0]);
764
+ return [annotateVar({ prim: 'bool' }), ...stack.slice(2)];
765
+ }
766
+ case 'GET':
767
+ if (instruction.args) {
768
+ // comb operation
769
+ const n = parseInt(instruction.args[0].int, 10);
770
+ const s = args(0, ['pair'])[0];
771
+ return [annotateVar(getNth(s, n)), ...stack.slice(1)];
772
+ }
773
+ else {
774
+ // map operation
775
+ const s = args(0, null, ['map', 'big_map']);
776
+ ensureComparableType(s[0]);
777
+ ensureTypesEqual(s[0], s[1].args[0]);
778
+ return [annotateVar({ prim: 'option', args: [s[1].args[1]] }), ...stack.slice(2)];
779
+ }
780
+ case 'UPDATE':
781
+ if (instruction.args) {
782
+ // comb operation
783
+ const n = parseInt(instruction.args[0].int, 10);
784
+ const s = args(0, null, ['pair']);
785
+ return [annotateVar(updateNth(s[1], s[0], n)), ...stack.slice(2)];
786
+ }
787
+ else {
788
+ // map operation
789
+ const s0 = args(0, null, ['bool', 'option']);
790
+ ensureComparableType(s0[0]);
791
+ if (s0[1].prim === 'bool') {
792
+ const s1 = args(2, ['set']);
793
+ ensureTypesEqual(s0[0], s1[0].args[0]);
794
+ return [
795
+ annotateVar({
796
+ prim: 'set',
797
+ args: [annotate(s0[0], { t: null })],
798
+ }),
799
+ ...stack.slice(3),
800
+ ];
801
+ }
802
+ const s1 = args(2, ['map', 'big_map']);
803
+ ensureTypesEqual(s0[0], s1[0].args[0]);
804
+ if (s1[0].prim === 'map') {
805
+ return [
806
+ annotateVar({
807
+ prim: 'map',
808
+ args: [annotate(s0[0], { t: null }), annotate(s0[1].args[0], { t: null })],
809
+ }),
810
+ ...stack.slice(3),
811
+ ];
812
+ }
813
+ ensureBigMapStorableType(s0[1].args[0]);
814
+ return [
815
+ annotateVar({
816
+ prim: 'big_map',
817
+ args: [annotate(s0[0], { t: null }), annotate(s0[1].args[0], { t: null })],
818
+ }),
819
+ ...stack.slice(3),
820
+ ];
821
+ }
822
+ case 'GET_AND_UPDATE': {
823
+ const ia = instructionAnn({ v: 2 });
824
+ const s = args(0, null, ['option'], ['map', 'big_map']);
825
+ ensureComparableType(s[0]);
826
+ ensureTypesEqual(s[0], s[2].args[0]);
827
+ ensureTypesEqual(s[1].args[0], s[2].args[1]);
828
+ const va = (_a = ia.v) === null || _a === void 0 ? void 0 : _a.map((v) => (v !== '@' ? [v] : undefined));
829
+ if (s[2].prim === 'map') {
830
+ return [
831
+ annotate({ prim: 'option', args: [s[2].args[1]] }, { v: va === null || va === void 0 ? void 0 : va[0] }),
832
+ annotate({
833
+ prim: 'map',
834
+ args: [annotate(s[0], { t: null }), annotate(s[1].args[0], { t: null })],
835
+ }, { v: va === null || va === void 0 ? void 0 : va[1] }),
836
+ ...stack.slice(3),
837
+ ];
838
+ }
839
+ ensureBigMapStorableType(s[1].args[0]);
840
+ return [
841
+ annotate({ prim: 'option', args: [s[2].args[1]] }, { v: va === null || va === void 0 ? void 0 : va[0] }),
842
+ annotate({
843
+ prim: 'big_map',
844
+ args: [annotate(s[0], { t: null }), annotate(s[1].args[0], { t: null })],
845
+ }, { v: va === null || va === void 0 ? void 0 : va[1] }),
846
+ ...stack.slice(3),
847
+ ];
848
+ }
849
+ case 'EXEC': {
850
+ const s = args(0, null, ['lambda']);
851
+ ensureTypesEqual(s[0], s[1].args[0]);
852
+ return [annotateVar(s[1].args[1]), ...stack.slice(2)];
853
+ }
854
+ case 'APPLY': {
855
+ const s = args(0, null, ['lambda']);
856
+ ensureStorableType(s[0]);
857
+ ensurePushableType(s[0]);
858
+ if (!(0, utils_1.isPairType)(s[1].args[0])) {
859
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: function's argument must be a pair: ${typeID(s[1].args[0])}`);
860
+ }
861
+ const pt = s[1].args[0];
862
+ ensureTypesEqual(s[0], typeArgs(pt)[0]);
863
+ return [
864
+ annotateVar({ prim: 'lambda', args: [typeArgs(pt)[1], s[1].args[1]] }),
865
+ ...stack.slice(2),
866
+ ];
867
+ }
868
+ case 'FAILWITH': {
869
+ const s = args(0, null)[0];
870
+ if (!(0, michelson_types_1.ProtoInferiorTo)(proto, michelson_types_1.Protocol.PtEdo2Zk)) {
871
+ ensurePackableType(s);
872
+ }
873
+ return { failed: s, level: 0 };
874
+ }
875
+ case 'NEVER':
876
+ args(0, ['never']);
877
+ return { failed: { prim: 'never' }, level: 0 };
878
+ case 'RENAME':
879
+ return [annotateVar(args(0, null)[0]), ...stack.slice(1)];
880
+ case 'CONCAT': {
881
+ const s0 = args(0, ['string', 'list', 'bytes']);
882
+ if (s0[0].prim === 'list') {
883
+ if (typeID(s0[0].args[0]) !== 'string' && typeID(s0[0].args[0]) !== 'bytes') {
884
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: can't concatenate list of ${typeID(s0[0].args[0])}'s`);
885
+ }
886
+ return [annotateVar(s0[0].args[0]), ...stack.slice(1)];
887
+ }
888
+ const s1 = args(1, ['string', 'bytes']);
889
+ if (s0[0].prim !== s1[0].prim) {
890
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: can't concatenate ${s0[0].prim} with ${s1[0].prim}`);
891
+ }
892
+ return [annotateVar(s1[0]), ...stack.slice(2)];
893
+ }
894
+ case 'SLICE':
895
+ return [
896
+ annotateVar({ prim: 'option', args: [args(0, ['nat'], ['nat'], ['string', 'bytes'])[2]] }, '@slice'),
897
+ ...stack.slice(3),
898
+ ];
899
+ case 'PACK': {
900
+ const s = args(0, null)[0];
901
+ ensurePackableType(s);
902
+ return [annotateVar({ prim: 'bytes' }, '@packed'), ...stack.slice(1)];
903
+ }
904
+ case 'ADD': {
905
+ const s = args(0, ['nat', 'int', 'timestamp', 'mutez', 'bls12_381_g1', 'bls12_381_g2', 'bls12_381_fr'], ['nat', 'int', 'timestamp', 'mutez', 'bls12_381_g1', 'bls12_381_g2', 'bls12_381_fr']);
906
+ if ((s[0].prim === 'nat' && s[1].prim === 'int') ||
907
+ (s[0].prim === 'int' && s[1].prim === 'nat')) {
908
+ return [annotateVar({ prim: 'int' }), ...stack.slice(2)];
909
+ }
910
+ else if ((s[0].prim === 'int' && s[1].prim === 'timestamp') ||
911
+ (s[0].prim === 'timestamp' && s[1].prim === 'int')) {
912
+ return [annotateVar({ prim: 'timestamp' }), ...stack.slice(2)];
913
+ }
914
+ else if ((s[0].prim === 'int' ||
915
+ s[0].prim === 'nat' ||
916
+ s[0].prim === 'mutez' ||
917
+ s[0].prim === 'bls12_381_g1' ||
918
+ s[0].prim === 'bls12_381_g2' ||
919
+ s[0].prim === 'bls12_381_fr') &&
920
+ s[0].prim === s[1].prim) {
921
+ return [annotateVar(s[0]), ...stack.slice(2)];
922
+ }
923
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: can't add ${s[0].prim} to ${s[1].prim}`);
924
+ }
925
+ case 'SUB': {
926
+ const s = (0, michelson_types_1.ProtoInferiorTo)(proto, michelson_types_1.Protocol.PsiThaCa)
927
+ ? args(0, ['nat', 'int', 'timestamp', 'mutez'], ['nat', 'int', 'timestamp', 'mutez'])
928
+ : args(0, ['nat', 'int', 'timestamp'], ['nat', 'int', 'timestamp']);
929
+ if (((s[0].prim === 'nat' || s[0].prim === 'int') &&
930
+ (s[1].prim === 'nat' || s[1].prim === 'int')) ||
931
+ (s[0].prim === 'timestamp' && s[1].prim === 'timestamp')) {
932
+ return [annotateVar({ prim: 'int' }), ...stack.slice(2)];
933
+ }
934
+ else if (s[0].prim === 'timestamp' && s[1].prim === 'int') {
935
+ return [annotateVar({ prim: 'timestamp' }), ...stack.slice(2)];
936
+ }
937
+ else if (s[0].prim === 'mutez' && s[1].prim === 'mutez') {
938
+ return [annotateVar({ prim: 'mutez' }), ...stack.slice(2)];
939
+ }
940
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: can't subtract ${s[0].prim} from ${s[1].prim}`);
941
+ }
942
+ case 'SUB_MUTEZ': {
943
+ const _s = args(0, ['mutez'], ['mutez']);
944
+ return [annotateVar({ prim: 'option', args: [{ prim: 'mutez' }] }), ...stack.slice(2)];
945
+ }
946
+ case 'MUL': {
947
+ const s = args(0, ['nat', 'int', 'mutez', 'bls12_381_g1', 'bls12_381_g2', 'bls12_381_fr'], ['nat', 'int', 'mutez', 'bls12_381_g1', 'bls12_381_g2', 'bls12_381_fr']);
948
+ if ((s[0].prim === 'nat' && s[1].prim === 'int') ||
949
+ (s[0].prim === 'int' && s[1].prim === 'nat')) {
950
+ return [annotateVar({ prim: 'int' }), ...stack.slice(2)];
951
+ }
952
+ else if ((s[0].prim === 'nat' && s[1].prim === 'mutez') ||
953
+ (s[0].prim === 'mutez' && s[1].prim === 'nat')) {
954
+ return [annotateVar({ prim: 'mutez' }), ...stack.slice(2)];
955
+ }
956
+ else if (((s[0].prim === 'bls12_381_g1' ||
957
+ s[0].prim === 'bls12_381_g2' ||
958
+ s[0].prim === 'bls12_381_fr') &&
959
+ s[1].prim === 'bls12_381_fr') ||
960
+ ((s[0].prim === 'nat' || s[0].prim === 'int') && s[0].prim === s[1].prim)) {
961
+ return [annotateVar(s[0]), ...stack.slice(2)];
962
+ }
963
+ else if (((s[0].prim === 'nat' || s[0].prim === 'int') && s[1].prim === 'bls12_381_fr') ||
964
+ ((s[1].prim === 'nat' || s[1].prim === 'int') && s[0].prim === 'bls12_381_fr')) {
965
+ return [annotateVar({ prim: 'bls12_381_fr' }), ...stack.slice(2)];
966
+ }
967
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: can't multiply ${s[0].prim} by ${s[1].prim}`);
968
+ }
969
+ case 'EDIV': {
970
+ const res = (a, b) => ({
971
+ prim: 'option',
972
+ args: [{ prim: 'pair', args: [{ prim: a }, { prim: b }] }],
973
+ });
974
+ const s = args(0, ['nat', 'int', 'mutez'], ['nat', 'int', 'mutez']);
975
+ if (s[0].prim === 'nat' && s[1].prim === 'nat') {
976
+ return [annotateVar(res('nat', 'nat')), ...stack.slice(2)];
977
+ }
978
+ else if ((s[0].prim === 'nat' || s[0].prim === 'int') &&
979
+ (s[1].prim === 'nat' || s[1].prim === 'int')) {
980
+ return [annotateVar(res('int', 'nat')), ...stack.slice(2)];
981
+ }
982
+ else if (s[0].prim === 'mutez' && s[1].prim === 'nat') {
983
+ return [annotateVar(res('mutez', 'mutez')), ...stack.slice(2)];
984
+ }
985
+ else if (s[0].prim === 'mutez' && s[1].prim === 'mutez') {
986
+ return [annotateVar(res('nat', 'mutez')), ...stack.slice(2)];
987
+ }
988
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: can't euclideally divide ${s[0].prim} by ${s[1].prim}`);
989
+ }
990
+ case 'ABS':
991
+ args(0, ['int']);
992
+ return [annotateVar({ prim: 'nat' }), ...stack.slice(1)];
993
+ case 'ISNAT':
994
+ args(0, ['int']);
995
+ return [annotateVar({ prim: 'option', args: [{ prim: 'nat' }] }), ...stack.slice(1)];
996
+ case 'INT':
997
+ args(0, ['nat', 'bls12_381_fr', 'bytes']);
998
+ return [annotateVar({ prim: 'int' }), ...stack.slice(1)];
999
+ case 'BYTES':
1000
+ args(0, ['nat', 'int']);
1001
+ return [annotateVar({ prim: 'bytes' }), ...stack.slice(1)];
1002
+ case 'NAT':
1003
+ args(0, ['bytes']);
1004
+ return [annotateVar({ prim: 'nat' }), ...stack.slice(1)];
1005
+ case 'NEG': {
1006
+ const s = args(0, ['nat', 'int', 'bls12_381_g1', 'bls12_381_g2', 'bls12_381_fr'])[0];
1007
+ if (s.prim === 'nat' || s.prim === 'int') {
1008
+ return [annotateVar({ prim: 'int' }), ...stack.slice(1)];
1009
+ }
1010
+ return [annotateVar(s), ...stack.slice(1)];
1011
+ }
1012
+ case 'LSL':
1013
+ case 'LSR':
1014
+ args(0, ['nat', 'bytes'], ['nat', 'bytes']);
1015
+ return [annotateVar({ prim: 'nat' }), ...stack.slice(2)];
1016
+ case 'OR':
1017
+ case 'XOR': {
1018
+ const s = args(0, ['nat', 'bytes', 'bool'], ['nat', 'bytes', 'bool']);
1019
+ if (s[0].prim !== s[1].prim) {
1020
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: both arguments must be of the same type: ${s[0].prim}, ${s[1].prim}`);
1021
+ }
1022
+ return [annotateVar(s[1]), ...stack.slice(2)];
1023
+ }
1024
+ case 'AND': {
1025
+ const s = args(0, ['nat', 'bytes', 'bool', 'int'], ['nat', 'bytes', 'bool']);
1026
+ if ((s[0].prim !== 'int' || s[1].prim !== 'nat') && s[0].prim !== s[1].prim) {
1027
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: both arguments must be of the same type: ${s[0].prim}, ${s[1].prim}`);
1028
+ }
1029
+ return [annotateVar(s[1]), ...stack.slice(2)];
1030
+ }
1031
+ case 'NOT': {
1032
+ const s = args(0, ['nat', 'bytes', 'bool', 'int'])[0];
1033
+ if (s.prim === 'bool') {
1034
+ return [annotateVar({ prim: 'bool' }), ...stack.slice(1)];
1035
+ }
1036
+ return [annotateVar({ prim: 'int' }), ...stack.slice(1)];
1037
+ }
1038
+ case 'COMPARE': {
1039
+ const s = args(0, null, null);
1040
+ ensureComparableType(s[0]);
1041
+ ensureComparableType(s[1]);
1042
+ return [annotateVar({ prim: 'int' }), ...stack.slice(2)];
1043
+ }
1044
+ case 'EQ':
1045
+ case 'NEQ':
1046
+ case 'LT':
1047
+ case 'GT':
1048
+ case 'LE':
1049
+ case 'GE':
1050
+ args(0, ['int']);
1051
+ return [annotateVar({ prim: 'bool' }), ...stack.slice(1)];
1052
+ case 'SELF': {
1053
+ if ((ctx === null || ctx === void 0 ? void 0 : ctx.contract) === undefined) {
1054
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: contract required`);
1055
+ }
1056
+ const ia = instructionAnn({ f: 1, v: 1 });
1057
+ const ep = contractEntryPoint(ctx.contract, (_b = ia.f) === null || _b === void 0 ? void 0 : _b[0]);
1058
+ if (ep === null) {
1059
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: contract has no entrypoint ${ep}`);
1060
+ }
1061
+ return [
1062
+ annotate({ prim: 'contract', args: [ep] }, { v: ia.v ? ia.v : ['@self'] }),
1063
+ ...stack,
1064
+ ];
1065
+ }
1066
+ case 'TRANSFER_TOKENS': {
1067
+ const s = args(0, null, ['mutez'], ['contract']);
1068
+ ensureTypesEqual(s[0], s[2].args[0]);
1069
+ return [annotateVar({ prim: 'operation' }), ...stack.slice(3)];
1070
+ }
1071
+ case 'SET_DELEGATE': {
1072
+ const s = args(0, ['option'])[0];
1073
+ if (typeID(s.args[0]) !== 'key_hash') {
1074
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: key hash expected: ${typeID(s.args[0])}`);
1075
+ }
1076
+ return [annotateVar({ prim: 'operation' }), ...stack.slice(1)];
1077
+ }
1078
+ case 'IMPLICIT_ACCOUNT':
1079
+ args(0, ['key_hash']);
1080
+ return [annotateVar({ prim: 'contract', args: [{ prim: 'unit' }] }), ...stack.slice(1)];
1081
+ case 'NOW':
1082
+ return [annotateVar({ prim: 'timestamp' }, '@now'), ...stack];
1083
+ case 'AMOUNT':
1084
+ return [annotateVar({ prim: 'mutez' }, '@amount'), ...stack];
1085
+ case 'BALANCE':
1086
+ return [annotateVar({ prim: 'mutez' }, '@balance'), ...stack];
1087
+ case 'CHECK_SIGNATURE':
1088
+ args(0, ['key'], ['signature'], ['bytes']);
1089
+ return [annotateVar({ prim: 'bool' }), ...stack.slice(3)];
1090
+ case 'BLAKE2B':
1091
+ case 'SHA256':
1092
+ case 'SHA512':
1093
+ case 'KECCAK':
1094
+ case 'SHA3':
1095
+ args(0, ['bytes']);
1096
+ return [annotateVar({ prim: 'bytes' }), ...stack.slice(1)];
1097
+ case 'HASH_KEY':
1098
+ args(0, ['key']);
1099
+ return [annotateVar({ prim: 'key_hash' }), ...stack.slice(1)];
1100
+ case 'SOURCE':
1101
+ return [annotateVar({ prim: 'address' }, '@source'), ...stack];
1102
+ case 'SENDER':
1103
+ return [annotateVar({ prim: 'address' }, '@sender'), ...stack];
1104
+ case 'ADDRESS': {
1105
+ const s = args(0, ['contract'])[0];
1106
+ const ia = instructionAnn({ v: 1 });
1107
+ return [
1108
+ annotate({ prim: 'address', [michelson_types_1.refContract]: s }, { v: ia.v ? ia.v : varSuffix(argAnn(s), 'address') }),
1109
+ ...stack.slice(1),
1110
+ ];
1111
+ }
1112
+ case 'SELF_ADDRESS': {
1113
+ const addr = { prim: 'address' };
1114
+ if ((ctx === null || ctx === void 0 ? void 0 : ctx.contract) !== undefined) {
1115
+ addr[michelson_types_1.refContract] = {
1116
+ prim: 'contract',
1117
+ args: [contractSection(ctx.contract, 'parameter').args[0]],
1118
+ };
1119
+ }
1120
+ return [annotateVar(addr, '@address'), ...stack];
1121
+ }
1122
+ case 'CHAIN_ID':
1123
+ return [annotateVar({ prim: 'chain_id' }), ...stack];
1124
+ case 'DROP': {
1125
+ instructionAnn({});
1126
+ const n = instruction.args !== undefined ? parseInt(instruction.args[0].int, 10) : 1;
1127
+ args(n - 1, null);
1128
+ return stack.slice(n);
1129
+ }
1130
+ case 'DIG': {
1131
+ instructionAnn({});
1132
+ const n = parseInt(instruction.args[0].int, 10);
1133
+ return [args(n, null)[0], ...stack.slice(0, n), ...stack.slice(n + 1)];
1134
+ }
1135
+ case 'DUG': {
1136
+ instructionAnn({});
1137
+ const n = parseInt(instruction.args[0].int, 10);
1138
+ return [...stack.slice(1, n + 1), args(0, null)[0], ...stack.slice(n + 1)];
1139
+ }
1140
+ case 'NONE':
1141
+ assertTypeAnnotationsValid(instruction.args[0]);
1142
+ return [
1143
+ annotate({ prim: 'option', args: [instruction.args[0]] }, instructionAnn({ t: 1, v: 1 })),
1144
+ ...stack,
1145
+ ];
1146
+ case 'LEFT':
1147
+ case 'RIGHT': {
1148
+ const s = args(0, null)[0];
1149
+ const ia = instructionAnn({ f: 2, t: 1, v: 1 }, { specialFields: true });
1150
+ const va = argAnn(s);
1151
+ const children = [
1152
+ annotate(s, {
1153
+ t: null,
1154
+ v: null,
1155
+ f: ia.f && ia.f.length > 0 && ia.f[0] !== '%'
1156
+ ? ia.f[0] === '%@'
1157
+ ? va.v
1158
+ ? ['%' + va.v[0].slice(1)]
1159
+ : undefined
1160
+ : ia.f
1161
+ : undefined,
1162
+ }),
1163
+ annotate(instruction.args[0], {
1164
+ t: null,
1165
+ f: ia.f && ia.f.length > 1 && ia.f[1] !== '%' ? ia.f : undefined,
1166
+ }),
1167
+ ];
1168
+ return [
1169
+ annotate({
1170
+ prim: 'or',
1171
+ args: instruction.prim === 'LEFT' ? children : [children[1], children[0]],
1172
+ }, { t: ia.t, v: ia.v }),
1173
+ ...stack.slice(1),
1174
+ ];
1175
+ }
1176
+ case 'NIL':
1177
+ assertTypeAnnotationsValid(instruction.args[0]);
1178
+ return [
1179
+ annotate({ prim: 'list', args: [instruction.args[0]] }, instructionAnn({ t: 1, v: 1 })),
1180
+ ...stack,
1181
+ ];
1182
+ case 'UNPACK':
1183
+ args(0, ['bytes']);
1184
+ assertTypeAnnotationsValid(instruction.args[0]);
1185
+ return [
1186
+ annotateVar({ prim: 'option', args: [instruction.args[0]] }, '@unpacked'),
1187
+ ...stack.slice(1),
1188
+ ];
1189
+ case 'CONTRACT': {
1190
+ const s = args(0, ['address'])[0];
1191
+ assertTypeAnnotationsValid(instruction.args[0]);
1192
+ const ia = instructionAnn({ v: 1, f: 1 });
1193
+ const contract = s[michelson_types_1.refContract];
1194
+ if (contract !== undefined) {
1195
+ const ep = contractEntryPoint(contract, (_c = ia.f) === null || _c === void 0 ? void 0 : _c[0]);
1196
+ if (ep === null) {
1197
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: contract has no entrypoint ${ep}`);
1198
+ }
1199
+ ensureTypesEqual(ep, instruction.args[0]);
1200
+ }
1201
+ return [
1202
+ annotate({ prim: 'option', args: [{ prim: 'contract', args: [instruction.args[0]] }] }, { v: ia.v ? ia.v : varSuffix(argAnn(s), 'contract') }),
1203
+ ...stack.slice(1),
1204
+ ];
1205
+ }
1206
+ case 'CAST': {
1207
+ instructionAnn({});
1208
+ const s = args(0, null)[0];
1209
+ assertTypeAnnotationsValid(instruction.args[0]);
1210
+ ensureTypesEqual(instruction.args[0], s);
1211
+ return [instruction.args[0], ...stack.slice(1)];
1212
+ }
1213
+ case 'IF_NONE': {
1214
+ instructionAnn({});
1215
+ const s = args(0, ['option'])[0];
1216
+ const tail = stack.slice(1);
1217
+ const br0 = functionTypeInternal(instruction.args[0], tail, ctx);
1218
+ const br1 = functionTypeInternal(instruction.args[1], [annotate(s.args[0], { t: null, v: varSuffix(argAnn(s), 'some') }), ...tail], ctx);
1219
+ return branchType(br0, br1);
1220
+ }
1221
+ case 'IF_LEFT': {
1222
+ instructionAnn({});
1223
+ const s = args(0, ['or'])[0];
1224
+ const va = argAnn(s);
1225
+ const lefta = argAnn(s.args[0]);
1226
+ const righta = argAnn(s.args[1]);
1227
+ const tail = stack.slice(1);
1228
+ const br0 = functionTypeInternal(instruction.args[0], [
1229
+ annotate(s.args[0], {
1230
+ t: null,
1231
+ v: varSuffix(va, lefta.f ? lefta.f[0].slice(1) : 'left'),
1232
+ }),
1233
+ ...tail,
1234
+ ], ctx);
1235
+ const br1 = functionTypeInternal(instruction.args[1], [
1236
+ annotate(s.args[1], {
1237
+ t: null,
1238
+ v: varSuffix(va, righta.f ? righta.f[0].slice(1) : 'right'),
1239
+ }),
1240
+ ...tail,
1241
+ ], ctx);
1242
+ return branchType(br0, br1);
1243
+ }
1244
+ case 'IF_CONS': {
1245
+ instructionAnn({});
1246
+ const s = args(0, ['list'])[0];
1247
+ const va = argAnn(s);
1248
+ const tail = stack.slice(1);
1249
+ const br0 = functionTypeInternal(instruction.args[0], [
1250
+ annotate(s.args[0], { t: null, v: varSuffix(va, 'hd') }),
1251
+ annotate(s, { t: null, v: varSuffix(va, 'tl') }),
1252
+ ...tail,
1253
+ ], ctx);
1254
+ const br1 = functionTypeInternal(instruction.args[1], tail, ctx);
1255
+ return branchType(br0, br1);
1256
+ }
1257
+ case 'IF': {
1258
+ instructionAnn({});
1259
+ args(0, ['bool']);
1260
+ const tail = stack.slice(1);
1261
+ const br0 = functionTypeInternal(instruction.args[0], tail, ctx);
1262
+ const br1 = functionTypeInternal(instruction.args[1], tail, ctx);
1263
+ return branchType(br0, br1);
1264
+ }
1265
+ case 'MAP': {
1266
+ const s = args(0, ['list', 'map', 'option'])[0];
1267
+ const tail = stack.slice(1);
1268
+ const elt = s.prim === 'map' ? { prim: 'pair', args: s.args } : s.args[0];
1269
+ const body = functionTypeInternal(instruction.args[0], [annotate(elt, { t: null, v: varSuffix(argAnn(s), 'elt') }), ...tail], ctx);
1270
+ if ('failed' in body) {
1271
+ if (!('prim' in body.failed) || body.failed.prim !== 'never') {
1272
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: FAIL is not allowed in MAP`);
1273
+ }
1274
+ return { failed: body.failed, level: body.level + 1 };
1275
+ }
1276
+ if (body.length < 1) {
1277
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: function must return a value`);
1278
+ }
1279
+ ensureStacksEqual(body.slice(1), tail);
1280
+ return s.prim === 'list'
1281
+ ? [annotateVar({ prim: 'list', args: [body[0]] }), ...tail]
1282
+ : s.prim === 'map'
1283
+ ? [annotateVar({ prim: 'map', args: [s.args[0], body[0]] }), ...tail]
1284
+ : [annotateVar({ prim: 'option', args: [body[0]] }), ...tail];
1285
+ }
1286
+ case 'ITER': {
1287
+ instructionAnn({});
1288
+ const s = args(0, ['set', 'list', 'map'])[0];
1289
+ const tail = stack.slice(1);
1290
+ const elt = s.prim === 'map' ? { prim: 'pair', args: s.args } : s.args[0];
1291
+ const body = functionTypeInternal(instruction.args[0], [annotate(elt, { t: null, v: varSuffix(argAnn(s), 'elt') }), ...tail], ctx);
1292
+ if ('failed' in body) {
1293
+ return { failed: body.failed, level: body.level + 1 };
1294
+ }
1295
+ ensureStacksEqual(body, tail);
1296
+ return tail;
1297
+ }
1298
+ case 'LOOP': {
1299
+ instructionAnn({});
1300
+ args(0, ['bool']);
1301
+ const tail = stack.slice(1);
1302
+ const body = functionTypeInternal(instruction.args[0], tail, ctx);
1303
+ if ('failed' in body) {
1304
+ return { failed: body.failed, level: body.level + 1 };
1305
+ }
1306
+ ensureStacksEqual(body, [{ prim: 'bool' }, ...tail]);
1307
+ return tail;
1308
+ }
1309
+ case 'LOOP_LEFT': {
1310
+ instructionAnn({});
1311
+ const s = args(0, ['or'])[0];
1312
+ const tail = stack.slice(1);
1313
+ const body = functionTypeInternal(instruction.args[0], [annotate(s.args[0], { t: null, v: varSuffix(argAnn(s), 'left') }), ...tail], ctx);
1314
+ if ('failed' in body) {
1315
+ return { failed: body.failed, level: body.level + 1 };
1316
+ }
1317
+ ensureStacksEqual(body, [s, ...tail]);
1318
+ return [annotate(s.args[1], { t: null, v: instructionAnn({ v: 1 }).v }), ...tail];
1319
+ }
1320
+ case 'DIP': {
1321
+ instructionAnn({});
1322
+ const n = instruction.args.length === 2 ? parseInt(instruction.args[0].int, 10) : 1;
1323
+ args(n - 1, null);
1324
+ const head = stack.slice(0, n);
1325
+ const tail = stack.slice(n);
1326
+ // ternary operator is a type guard so use it instead of just `instruction.args.length - 1`
1327
+ const body = instruction.args.length === 2
1328
+ ? functionTypeInternal(instruction.args[1], tail, ctx)
1329
+ : functionTypeInternal(instruction.args[0], tail, ctx);
1330
+ if ('failed' in body) {
1331
+ return { failed: body.failed, level: body.level + 1 };
1332
+ }
1333
+ return [...head, ...body];
1334
+ }
1335
+ case 'CREATE_CONTRACT': {
1336
+ const ia = instructionAnn({ v: 2 });
1337
+ const s = args(0, ['option'], ['mutez'], null);
1338
+ if (typeID(s[0].args[0]) !== 'key_hash') {
1339
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: key hash expected: ${typeID(s[0].args[0])}`);
1340
+ }
1341
+ if (ensureStorableType(s[2])) {
1342
+ assertContractValid(instruction.args[0]);
1343
+ assertScalarTypesEqual(contractSection(instruction.args[0], 'storage').args[0], s[2]);
1344
+ }
1345
+ const va = (_d = ia.v) === null || _d === void 0 ? void 0 : _d.map((v) => (v !== '@' ? [v] : undefined));
1346
+ return [
1347
+ annotate({ prim: 'operation' }, { v: va === null || va === void 0 ? void 0 : va[0] }),
1348
+ annotate({
1349
+ prim: 'address',
1350
+ [michelson_types_1.refContract]: {
1351
+ prim: 'contract',
1352
+ args: [contractSection(instruction.args[0], 'parameter').args[0]],
1353
+ },
1354
+ }, { v: va === null || va === void 0 ? void 0 : va[1] }),
1355
+ ...stack.slice(3),
1356
+ ];
1357
+ }
1358
+ case 'PUSH':
1359
+ assertTypeAnnotationsValid(instruction.args[0]);
1360
+ assertDataValidInternal(instruction.args[1], instruction.args[0], Object.assign(Object.assign({}, ctx), { contract: undefined }));
1361
+ return [annotateVar(instruction.args[0]), ...stack];
1362
+ case 'EMPTY_SET':
1363
+ assertTypeAnnotationsValid(instruction.args[0]);
1364
+ ensureComparableType(instruction.args[0]);
1365
+ return [
1366
+ annotate({ prim: 'set', args: instruction.args }, instructionAnn({ t: 1, v: 1 })),
1367
+ ...stack,
1368
+ ];
1369
+ case 'EMPTY_MAP':
1370
+ assertTypeAnnotationsValid(instruction.args[0]);
1371
+ ensureComparableType(instruction.args[0]);
1372
+ assertTypeAnnotationsValid(instruction.args[1]);
1373
+ return [
1374
+ annotate({ prim: 'map', args: instruction.args }, instructionAnn({ t: 1, v: 1 })),
1375
+ ...stack,
1376
+ ];
1377
+ case 'EMPTY_BIG_MAP':
1378
+ assertTypeAnnotationsValid(instruction.args[0]);
1379
+ ensureComparableType(instruction.args[0]);
1380
+ assertTypeAnnotationsValid(instruction.args[1]);
1381
+ ensureBigMapStorableType(instruction.args[0]);
1382
+ return [
1383
+ annotate({ prim: 'big_map', args: instruction.args }, instructionAnn({ t: 1, v: 1 })),
1384
+ ...stack,
1385
+ ];
1386
+ case 'LAMBDA_REC':
1387
+ case 'LAMBDA': {
1388
+ assertTypeAnnotationsValid(instruction.args[0]);
1389
+ assertTypeAnnotationsValid(instruction.args[1]);
1390
+ const s = [instruction.args[0]];
1391
+ if (instruction.prim === 'LAMBDA_REC') {
1392
+ s.push({ prim: 'lambda', args: [instruction.args[0], instruction.args[1]] });
1393
+ }
1394
+ const body = functionTypeInternal(instruction.args[2], s, Object.assign(Object.assign({}, ctx), { contract: undefined }));
1395
+ if ('failed' in body) {
1396
+ return { failed: body.failed, level: body.level + 1 };
1397
+ }
1398
+ if (body.length !== 1) {
1399
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: function must return a value`);
1400
+ }
1401
+ ensureTypesEqual(instruction.args[1], body[0]);
1402
+ return [
1403
+ annotateVar({ prim: 'lambda', args: [instruction.args[0], instruction.args[1]] }),
1404
+ ...stack,
1405
+ ];
1406
+ }
1407
+ case 'LEVEL':
1408
+ return [annotateVar({ prim: 'nat' }, '@level'), ...stack];
1409
+ case 'TOTAL_VOTING_POWER':
1410
+ return [annotateVar({ prim: 'nat' }), ...stack];
1411
+ case 'VOTING_POWER':
1412
+ args(0, ['key_hash']);
1413
+ return [annotateVar({ prim: 'nat' }), ...stack.slice(1)];
1414
+ case 'TICKET': {
1415
+ const s = args(0, null, ['nat'])[0];
1416
+ ensureComparableType(s);
1417
+ if ((0, michelson_types_1.ProtoInferiorTo)(proto, michelson_types_1.Protocol.PtLimaPtL)) {
1418
+ return [
1419
+ annotate({ prim: 'ticket', args: [s] }, instructionAnn({ t: 1, v: 1 })),
1420
+ ...stack.slice(2),
1421
+ ];
1422
+ }
1423
+ else {
1424
+ return [
1425
+ annotateVar({
1426
+ prim: 'option',
1427
+ args: [annotate({ prim: 'ticket', args: [s] }, instructionAnn({ t: 1, v: 1 }))],
1428
+ }),
1429
+ ...stack.slice(2),
1430
+ ];
1431
+ }
1432
+ }
1433
+ case 'JOIN_TICKETS': {
1434
+ const s = (0, utils_1.unpackComb)('pair', args(0, ['pair'])[0]);
1435
+ if (typeID(s.args[0]) !== 'ticket') {
1436
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: ticket expected: ${typeID(s.args[0])}`);
1437
+ }
1438
+ ensureTypesEqual(s.args[0], s.args[1]);
1439
+ return [
1440
+ annotateVar({
1441
+ prim: 'option',
1442
+ args: [annotate(s.args[0], { t: null })],
1443
+ }),
1444
+ ...stack.slice(1),
1445
+ ];
1446
+ }
1447
+ case 'SPLIT_TICKET': {
1448
+ const s = args(0, ['ticket'], ['pair']);
1449
+ const p = (0, utils_1.unpackComb)('pair', s[1]);
1450
+ if (typeID(p.args[0]) !== 'nat') {
1451
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: nat expected: ${typeID(p.args[0])}`);
1452
+ }
1453
+ ensureTypesEqual(p.args[0], p.args[1]);
1454
+ return [
1455
+ annotateVar({
1456
+ prim: 'option',
1457
+ args: [
1458
+ {
1459
+ prim: 'pair',
1460
+ args: [annotate(s[0], { t: null }), annotate(s[0], { t: null })],
1461
+ },
1462
+ ],
1463
+ }),
1464
+ ...stack.slice(2),
1465
+ ];
1466
+ }
1467
+ case 'READ_TICKET': {
1468
+ const ia = instructionAnn({ v: 2 });
1469
+ const s = args(0, ['ticket'])[0];
1470
+ const va = (_e = ia.v) === null || _e === void 0 ? void 0 : _e.map((v) => (v !== '@' ? [v] : undefined));
1471
+ return [
1472
+ annotate({
1473
+ prim: 'pair',
1474
+ args: [{ prim: 'address' }, annotate(s.args[0], { t: null }), { prim: 'nat' }],
1475
+ }, { v: va === null || va === void 0 ? void 0 : va[0] }),
1476
+ annotate(s, { v: va === null || va === void 0 ? void 0 : va[1], t: null }),
1477
+ ...stack.slice(1),
1478
+ ];
1479
+ }
1480
+ case 'PAIRING_CHECK': {
1481
+ const p = args(0, ['list'])[0].args[0];
1482
+ if (!(0, utils_1.isPairType)(p)) {
1483
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: pair expected: ${typeID(p)}`);
1484
+ }
1485
+ const c = (0, utils_1.unpackComb)('pair', p);
1486
+ if (typeID(c.args[0]) !== 'bls12_381_g1') {
1487
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: bls12_381_g1 expected: ${typeID(c.args[0])}`);
1488
+ }
1489
+ if (typeID(c.args[1]) !== 'bls12_381_g2') {
1490
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: bls12_381_g2 expected: ${typeID(c.args[1])}`);
1491
+ }
1492
+ return [annotateVar({ prim: 'bool' }), ...stack.slice(1)];
1493
+ }
1494
+ case 'SAPLING_EMPTY_STATE':
1495
+ return [
1496
+ annotate({ prim: 'sapling_state', args: [instruction.args[0]] }, instructionAnn({ v: 1, t: 1 })),
1497
+ ...stack,
1498
+ ];
1499
+ case 'SAPLING_VERIFY_UPDATE': {
1500
+ const s = args(0, ['sapling_transaction'], ['sapling_state']);
1501
+ if (parseInt(s[0].args[0].int, 10) !== parseInt(s[1].args[0].int, 10)) {
1502
+ throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: sapling memo size mismatch: ${s[0].args[0].int} != ${s[1].args[0].int}`);
1503
+ }
1504
+ return (0, michelson_types_1.ProtoInferiorTo)(proto, michelson_types_1.Protocol.PtJakarta)
1505
+ ? [
1506
+ annotateVar({
1507
+ prim: 'option',
1508
+ args: [
1509
+ {
1510
+ prim: 'pair',
1511
+ args: [{ prim: 'int' }, annotate(s[1], { t: null })],
1512
+ },
1513
+ ],
1514
+ }),
1515
+ ...stack.slice(2),
1516
+ ]
1517
+ : [
1518
+ annotateVar({
1519
+ prim: 'option',
1520
+ args: [
1521
+ {
1522
+ prim: 'pair',
1523
+ args: [
1524
+ { prim: 'bytes' },
1525
+ {
1526
+ prim: 'pair',
1527
+ args: [{ prim: 'int' }, annotate(s[1], { t: null })],
1528
+ },
1529
+ ],
1530
+ },
1531
+ ],
1532
+ }),
1533
+ ...stack.slice(2),
1534
+ ];
1535
+ }
1536
+ case 'OPEN_CHEST':
1537
+ args(0, ['chest_key'], ['chest'], ['nat']);
1538
+ return [
1539
+ annotateVar({ prim: 'or', args: [{ prim: 'bytes' }, { prim: 'bool' }] }),
1540
+ ...stack.slice(3),
1541
+ ];
1542
+ case 'VIEW': {
1543
+ const s = args(0, null, ['address']);
1544
+ ensurePushableType(s[0]);
1545
+ return [annotateVar({ prim: 'option', args: [instruction.args[1]] }), ...stack.slice(2)];
1546
+ }
1547
+ case 'MIN_BLOCK_TIME':
1548
+ return [annotateVar({ prim: 'nat' }), ...stack];
1549
+ case 'EMIT': {
1550
+ const ia = instructionAnn({ f: 1, t: 1 });
1551
+ if (instruction.args) {
1552
+ const s = args(0, null);
1553
+ ensureTypesEqual(s[0], instruction.args[0]);
1554
+ return [annotate({ prim: 'operation' }, ia), ...stack.slice(1)];
1555
+ }
1556
+ return [annotate({ prim: 'operation' }, ia), ...stack.slice(1)];
1557
+ }
1558
+ case 'IS_IMPLICIT_ACCOUNT':
1559
+ args(0, ['address']);
1560
+ return [annotateVar({ prim: 'option', args: [{ prim: 'key_hash' }] }), ...stack.slice(1)];
1561
+ case 'INDEX_ADDRESS':
1562
+ args(0, ['address']);
1563
+ return [annotateVar({ prim: 'nat' }), ...stack.slice(1)];
1564
+ case 'GET_ADDRESS_INDEX':
1565
+ args(0, ['address']);
1566
+ return [annotateVar({ prim: 'option', args: [{ prim: 'nat' }] }), ...stack.slice(1)];
1567
+ default:
1568
+ throw new utils_1.MichelsonError(instruction, `unexpected instruction: ${instruction.prim}`);
1569
+ }
1570
+ })(instruction);
1571
+ if ((ctx === null || ctx === void 0 ? void 0 : ctx.traceCallback) !== undefined) {
1572
+ const trace = {
1573
+ op: instruction,
1574
+ in: stack,
1575
+ out: retStack,
1576
+ };
1577
+ ctx.traceCallback(trace);
1578
+ }
1579
+ return retStack;
1580
+ }
1581
+ function contractSection(contract, section) {
1582
+ for (const s of contract) {
1583
+ if (s.prim === section) {
1584
+ return s;
1585
+ }
1586
+ }
1587
+ throw new utils_1.MichelsonError(contract, `missing contract section: ${section}`);
1588
+ }
1589
+ function contractViews(contract) {
1590
+ const views = {};
1591
+ for (const s of contract) {
1592
+ if (s.prim === 'view') {
1593
+ views[s.args[0].string] = s;
1594
+ }
1595
+ }
1596
+ return views;
1597
+ }
1598
+ function isContract(v) {
1599
+ if (Array.isArray(v)) {
1600
+ for (const s of v) {
1601
+ if ('prim' in s && (s.prim === 'parameter' || s.prim === 'storage' || s.prim === 'code')) {
1602
+ return true;
1603
+ }
1604
+ }
1605
+ }
1606
+ return false;
1607
+ }
1608
+ function contractEntryPoint(src, ep) {
1609
+ ep = ep || '%default';
1610
+ const entryPoint = contractEntryPoints(src).find((x) => x[0] === ep);
1611
+ if (entryPoint !== undefined) {
1612
+ return entryPoint[1];
1613
+ }
1614
+ else if (ep === '%default') {
1615
+ return isContract(src) ? contractSection(src, 'parameter').args[0] : src;
1616
+ }
1617
+ return null;
1618
+ }
1619
+ function isOrType(t) {
1620
+ return Array.isArray(t) || t.prim === 'or';
1621
+ }
1622
+ function contractEntryPoints(src) {
1623
+ if (isContract(src)) {
1624
+ const param = contractSection(src, 'parameter');
1625
+ const ch = contractEntryPoints(param.args[0]);
1626
+ const a = (0, utils_1.unpackAnnotations)(param);
1627
+ return a.f ? [[a.f[0], param.args[0]], ...ch] : ch;
1628
+ }
1629
+ if (isOrType(src)) {
1630
+ const args = typeArgs(src);
1631
+ const getArg = (n) => {
1632
+ const a = (0, utils_1.unpackAnnotations)(args[n]);
1633
+ if (typeID(args[n]) === 'or') {
1634
+ const ch = contractEntryPoints(args[n]);
1635
+ return a.f ? [[a.f[0], args[n]], ...ch] : ch;
1636
+ }
1637
+ return a.f ? [[a.f[0], args[n]]] : [];
1638
+ };
1639
+ return [...getArg(0), ...getArg(1)];
1640
+ }
1641
+ return [];
1642
+ }
1643
+ // Contract validation
1644
+ function assertContractValid(contract, ctx) {
1645
+ const assertSection = (parameter, storage, ret, code) => {
1646
+ assertTypeAnnotationsValid(parameter, true);
1647
+ assertTypeAnnotationsValid(storage);
1648
+ const arg = {
1649
+ prim: 'pair',
1650
+ args: [
1651
+ Object.assign(Object.assign({}, parameter), { annots: ['@parameter'] }),
1652
+ Object.assign(Object.assign({}, storage), { annots: ['@storage'] }),
1653
+ ],
1654
+ };
1655
+ const out = functionTypeInternal(code, [arg], Object.assign(Object.assign({}, ctx), { contract }));
1656
+ if ('failed' in out) {
1657
+ return out;
1658
+ }
1659
+ try {
1660
+ assertStacksEqual(out, [ret]);
1661
+ }
1662
+ catch (err) {
1663
+ if (err instanceof utils_1.MichelsonError) {
1664
+ throw new MichelsonInstructionError(code, out, err.message);
1665
+ }
1666
+ else {
1667
+ throw err;
1668
+ }
1669
+ }
1670
+ return out;
1671
+ };
1672
+ const parameter = contractSection(contract, 'parameter').args[0];
1673
+ const storage = contractSection(contract, 'storage').args[0];
1674
+ const code = contractSection(contract, 'code').args[0];
1675
+ const expected = {
1676
+ prim: 'pair',
1677
+ args: [{ prim: 'list', args: [{ prim: 'operation' }] }, storage],
1678
+ };
1679
+ const ret = assertSection(parameter, storage, expected, code);
1680
+ for (const view of Object.values(contractViews(contract))) {
1681
+ assertSection(view.args[1], storage, view.args[2], view.args[3]);
1682
+ }
1683
+ return ret;
1684
+ }
1685
+ // Exported wrapper functions
1686
+ function assertDataValid(d, t, ctx) {
1687
+ assertTypeAnnotationsValid(t);
1688
+ assertDataValidInternal(d, t, ctx || null);
1689
+ }
1690
+ function functionType(inst, stack, ctx) {
1691
+ for (const t of stack) {
1692
+ assertTypeAnnotationsValid(t);
1693
+ }
1694
+ if ((ctx === null || ctx === void 0 ? void 0 : ctx.contract) !== undefined) {
1695
+ for (const typesec of ['parameter', 'storage']) {
1696
+ const sec = contractSection(ctx.contract, typesec).args[0];
1697
+ assertTypeAnnotationsValid(sec);
1698
+ }
1699
+ }
1700
+ return functionTypeInternal(inst, stack, ctx || null);
1701
+ }
1702
+ function assertTypesEqual(a, b, field = false) {
1703
+ if (Array.isArray(a)) {
1704
+ // type guards don't work for parametrized generic types
1705
+ for (const v of a) {
1706
+ assertTypeAnnotationsValid(v);
1707
+ }
1708
+ for (const v of b) {
1709
+ assertTypeAnnotationsValid(v);
1710
+ }
1711
+ }
1712
+ else {
1713
+ assertTypeAnnotationsValid(a);
1714
+ assertTypeAnnotationsValid(b);
1715
+ }
1716
+ assertScalarTypesEqual(a, b, field);
1717
+ }
1718
+ function isTypeAnnotationsValid(t, field = false) {
1719
+ try {
1720
+ assertTypeAnnotationsValid(t, field);
1721
+ return true;
1722
+ }
1723
+ catch (_a) {
1724
+ return false;
1725
+ }
1726
+ }
1727
+ function isContractValid(contract, ctx) {
1728
+ try {
1729
+ return assertContractValid(contract, ctx);
1730
+ }
1731
+ catch (_a) {
1732
+ return null;
1733
+ }
1734
+ }
1735
+ function isDataValid(d, t, ctx) {
1736
+ try {
1737
+ assertDataValid(d, t, ctx);
1738
+ return true;
1739
+ }
1740
+ catch (_a) {
1741
+ return false;
1742
+ }
1743
+ }
1744
+ function isTypeEqual(a, b, field = false) {
1745
+ try {
1746
+ assertTypesEqual(a, b, field);
1747
+ return true;
1748
+ }
1749
+ catch (_a) {
1750
+ return false;
1751
+ }
1752
+ }