@ton3/liteclient
Version:
TON Blockchain LiteClient
159 lines • 5.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Stack = void 0;
const ton3_core_1 = require("ton3-core");
const INT64_MIN = -0x8000000000000000n;
const INT64_MAX = 0x7fffffffffffffffn;
class Stack {
static serialize(values) {
const builder = new ton3_core_1.Builder();
builder.storeUint(values.length, 24);
Stack.serializeStackList(builder, values);
return builder.cell();
}
static serializeStackList(builder, list) {
if (!list.length)
return;
const rest = new ton3_core_1.Builder();
Stack.serializeStackList(rest, list.slice(0, list.length - 1));
builder.storeRef(rest.cell());
Stack.serializeStackValue(builder, list[list.length - 1]);
}
static serializeStackValue(builder, value) {
if (value === null) {
return builder.storeUint(0x00, 8);
}
if (typeof value === 'number') {
if (isNaN(value)) {
return builder.storeInt(0x02ff, 16);
}
else {
return builder.storeUint(0x01, 8).storeInt(value, 64);
}
}
if (typeof value === 'bigint') {
if (value >= INT64_MIN && value <= INT64_MAX) {
return builder.storeUint(0x01, 8).storeInt(value, 64);
}
else {
return builder.storeUint(0x0100, 15).storeInt(value, 257);
}
}
if (value instanceof ton3_core_1.Cell) {
return builder.storeUint(0x03, 8).storeRef(value);
}
if (value instanceof ton3_core_1.Slice) {
return builder
.storeUint(0x04, 8)
.storeUint(0, 10)
.storeUint(value.bits.length, 10)
.storeUint(0, 3)
.storeUint(value.refs.length, 3)
.storeRef(new ton3_core_1.Builder().storeSlice(value).cell());
}
if (value instanceof ton3_core_1.Builder) {
return builder.storeUint(0x05, 8).storeRef(value.cell());
}
if (Array.isArray(value)) {
let head = null;
let tail = null;
for (let i = 0; i < value.length; i++) {
[head, tail] = [tail, head];
if (i > 1) {
head = new ton3_core_1.Builder().storeRef(tail).storeRef(head).cell();
}
const tailBuilder = new ton3_core_1.Builder();
Stack.serializeStackValue(tailBuilder, value[i]);
tail = tailBuilder.cell();
}
builder.storeUint(0x07, 8).storeUint(value.length, 16);
if (head) {
builder.storeRef(head);
}
if (tail) {
builder.storeRef(tail);
}
return builder;
}
throw new Error('Stack value type is not supported.');
}
static deserialize(cell) {
const slice = ton3_core_1.Slice.parse(cell);
const depth = slice.loadUint(24);
return Stack.deserializeStackList(depth, slice);
}
static deserializeStackList(depth, slice) {
const stack = [];
for (let i = 0; i < depth; i++) {
const rest = slice.loadRef();
const value = Stack.deserializeStackValue(slice);
stack.unshift(value);
slice = ton3_core_1.Slice.parse(rest);
}
return stack;
}
static deserializeStackValue(slice) {
const type = slice.loadUint(8);
switch (type) {
case 0x00:
return null;
case 0x01:
return slice.loadBigInt(64);
case 0x02:
if (slice.loadUint(7)) {
slice.loadBit();
return NaN;
}
return slice.loadBigInt(64);
case 0x03:
return slice.loadRef();
case 0x04:
return Stack.deserializeStackValueSlice(slice);
case 0x05:
const cell = slice.loadRef();
return new ton3_core_1.Builder().storeSlice(ton3_core_1.Slice.parse(cell));
case 0x06:
throw new Error('Continuations are not supported yet.');
case 0x07:
return Stack.deserializeStackValueTuple(slice);
default:
throw new Error('Stack value type is not supported.');
}
}
static deserializeStackValueSlice(slice) {
const startBits = slice.loadUint(10);
const endBits = slice.loadUint(10);
const startRefs = slice.loadUint(3);
const endRefs = slice.loadUint(3);
const cell = slice.loadRef();
return ton3_core_1.Slice.parse(new ton3_core_1.Cell({
bits: cell.bits.slice(startBits, endBits),
refs: slice.refs.slice(startRefs, endRefs),
type: ton3_core_1.CellType.Ordinary,
}));
}
static deserializeStackValueTuple(slice) {
const length = slice.loadUint(16);
const items = [];
if (length === 0) {
return [];
}
if (length === 1) {
const tail = slice.loadRef();
return [Stack.deserializeStackValue(ton3_core_1.Slice.parse(tail))];
}
let head = ton3_core_1.Slice.parse(slice.loadRef());
let tail = ton3_core_1.Slice.parse(slice.loadRef());
items.unshift(Stack.deserializeStackValue(tail));
for (let i = 0; i < length - 2; i++) {
const current = head;
head = ton3_core_1.Slice.parse(current.loadRef());
tail = ton3_core_1.Slice.parse(current.loadRef());
items.unshift(Stack.deserializeStackValue(tail));
}
items.unshift(Stack.deserializeStackValue(head));
return items;
}
}
exports.Stack = Stack;
//# sourceMappingURL=stack.js.map