import BN from "bn.js"; import { base64ToBytes } from "../utils/utils"; const { Cell } = require("../boc/cell"); export type Pair = | ["num", string | number] | ["list", any] | ["tuple", any] | ["cell", any] | ["tvm.Slice", string] | ["tvm.Cell", string]; interface Result { exit_code: number; stack: Pair[]; } class ProviderError extends Error { result: Result; constructor(message: string, result: Result) { super(message); this.result = result; } } export class TonHttpProviderUtils { static parseObject(x: any): any { const typeName = x["@type"]; switch (typeName) { case "tvm.list": case "tvm.tuple": return x.elements.map(TonHttpProviderUtils.parseObject); case "tvm.cell": return Cell.oneFromBoc(base64ToBytes(x.bytes)); case "tvm.stackEntryCell": return TonHttpProviderUtils.parseObject(x.cell); case "tvm.stackEntryTuple": return TonHttpProviderUtils.parseObject(x.tuple); case "tvm.stackEntryNumber": return TonHttpProviderUtils.parseObject(x.number); case "tvm.numberDecimal": return new BN(x.number, 10); default: throw new Error("unknown type " + typeName); } } /** * @param pair {any[]} * @return {any} */ static parseResponseStack(pair: Pair) { const typeName = pair[0]; const value = pair[1]; switch (typeName) { case "num": return new BN(value.replace(/0x/, ""), 16); case "list": case "tuple": return TonHttpProviderUtils.parseObject(value); case "cell": const contentBytes = base64ToBytes(value.bytes); return Cell.oneFromBoc(contentBytes); default: throw new Error("unknown type " + typeName); } } static parseResponse(result: Result) { if (result.exit_code !== 0) { const err = new ProviderError( `Http provider parse response error ${JSON.stringify(result)}`, result ); throw err; } const arr = result.stack.map(TonHttpProviderUtils.parseResponseStack); return arr.length === 1 ? arr[0] : arr; } static makeArg(arg: BN | Number | any) { if (arg instanceof BN || arg instanceof Number) { return ["num", arg]; } else { throw new Error("unknown arg type " + arg); } } static makeArgs(args: (BN | Number | any)[]) { return args.map(this.makeArg); } }