@tonclient/core
Version:
TON Client for Java Script
261 lines • 10 kB
JavaScript
;
/*
* Copyright 2018-2020 TON Labs LTD.
*
* Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use
* this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific TON DEV software governing permissions and
* limitations under the License.
*
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TonClient = void 0;
const modules_1 = require("./modules");
const bin_1 = require("./bin");
class TonClient {
constructor(config) {
this.context = null;
this.config = config !== null && config !== void 0 ? config : {};
this.client = new modules_1.ClientModule(this);
this.crypto = new modules_1.CryptoModule(this);
this.abi = new modules_1.AbiModule(this);
this.boc = new modules_1.BocModule(this);
this.processing = new modules_1.ProcessingModule(this);
this.utils = new modules_1.UtilsModule(this);
this.net = new modules_1.NetModule(this);
this.tvm = new modules_1.TvmModule(this);
this.proofs = new modules_1.ProofsModule(this);
}
static set default(client) {
this._default = client;
}
static get default() {
if (this._default === null) {
this._default = new TonClient(this._defaultConfig);
}
return this._default;
}
static set defaultConfig(config) {
this._defaultConfig = config;
}
static get defaultConfig() {
return this._defaultConfig;
}
static useBinaryLibrary(loader) {
(0, bin_1.useLibrary)(loader);
}
static toKey(d) {
return toHex(d, 256);
}
static toHash64(d) {
return toHex(d, 64);
}
static toHash128(d) {
return toHex(d, 128);
}
static toHash256(d) {
return toHex(d, 256);
}
static toHash512(d) {
return toHex(d, 512);
}
static toHex(dec, bits = 0) {
return toHex(dec, bits);
}
close() {
const context = this.context;
if (context !== null) {
this.context = null;
(0, bin_1.getBridge)().destroyContext(context);
}
}
resolveError(functionName, params, err) {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
if (err.code !== 23 || !((_a = err.data) === null || _a === void 0 ? void 0 : _a.suggest_use_helper_for)) {
return err;
}
try {
const [modName, funcName] = functionName.split(".");
const api = (yield this.client.get_api_reference()).api;
const allTypesArray = api.modules.reduce((accumulator, element) => accumulator.concat(element.types), []);
const allTypesDict = {};
allTypesArray.forEach((element) => allTypesDict[element.name] = element);
const module = api.modules.find((x) => x.name === modName);
const func = module.functions.find((x) => x.name === funcName);
const param = func.params[1];
// If there is only context param (or AppObject second param), there is nothing to analyze
if (!param || param.generic_name == "AppObject") {
return err;
}
const paramTypeInfo = allTypesDict[param.ref_name];
walkParameters(paramTypeInfo, params, "");
function walkParameters(valueTypeInfo, value, path) {
switch (valueTypeInfo.type) {
case "Array":
if (Array.isArray(value)) {
value.forEach(v => walkParameters(valueTypeInfo.array_item, v, `${path}[i]`));
}
break;
case "Struct":
valueTypeInfo.struct_fields.forEach((sf) => walkParameters(sf, value[sf.name], path ? `${path}.${sf.name}` : sf.name));
break;
case "Optional":
if (value) {
walkParameters(valueTypeInfo.optional_inner, value, path);
}
break;
case "Ref":
if (valueTypeInfo.ref_name != "Value" &&
valueTypeInfo.ref_name != "API" &&
valueTypeInfo.ref_name != "AbiParam") {
walkParameters(allTypesDict[valueTypeInfo.ref_name], value, path);
}
break;
case "EnumOfTypes":
if (valueTypeInfo.enum_types.some((et) => et.name == value.type)) {
return;
}
let parameterName = valueTypeInfo.name.toLowerCase();
let helperFunctions = [];
valueTypeInfo.enum_types.forEach((et) => helperFunctions.push(parameterName + et.name));
err.message = `Consider using one of the helper methods (${helperFunctions.join(", ")}) for the \"${path}\" parameter\n` + err.message;
break;
default:
break;
}
}
}
catch (e) {
err.message = (_b = e.message) !== null && _b !== void 0 ? _b : `${e}`;
}
return err;
});
}
request(functionName, functionParams, responseHandler) {
return __awaiter(this, void 0, void 0, function* () {
let context;
if (this.context !== null) {
context = this.context;
}
else {
context = yield (0, bin_1.getBridge)().createContext(this.config);
this.context = context;
}
return (0, bin_1.getBridge)()
.request(context, functionName, functionParams, responseHandler !== null && responseHandler !== void 0 ? responseHandler : (() => { }))
.catch((reason) => __awaiter(this, void 0, void 0, function* () {
throw yield this.resolveError(functionName, functionParams, reason);
}));
});
}
resolve_app_request(app_request_id, result) {
return __awaiter(this, void 0, void 0, function* () {
if (app_request_id) {
yield this.client.resolve_app_request({
app_request_id,
result: {
type: "Ok",
result,
},
});
}
});
}
reject_app_request(app_request_id, error) {
return __awaiter(this, void 0, void 0, function* () {
if (app_request_id) {
yield this.client.resolve_app_request({
app_request_id,
result: {
type: "Error",
text: error.message,
},
});
}
});
}
}
exports.TonClient = TonClient;
TonClient._defaultConfig = {};
TonClient._default = null;
// Converts value to hex
function toHex(value, bits) {
let hex;
if (typeof value === "number" || typeof value === "bigint") {
hex = value.toString(16);
}
else if (typeof value === "string") {
if (value.startsWith("0x")) {
hex = value.substr(2);
}
else {
hex = decToHex(value);
}
}
else {
hex = value.toString();
}
let len = bits / 4;
while (hex.length > len && hex.startsWith("0")) {
hex = hex.substr(1);
}
return hex.padStart(len, "0");
}
function decToHex(dec) {
var _a;
let bigNum = [];
for (let i = 0; i < dec.length; i += 1) {
const d = ((_a = dec.codePointAt(i)) !== null && _a !== void 0 ? _a : 0) - 48;
const mul8 = shl(bigNum, 3);
const mul2 = shl(bigNum, 1);
const mul10 = add(mul8, mul2);
bigNum = add(mul10, [d]);
}
let hex = "";
for (let i = bigNum.length - 1; i >= 0; i -= 1) {
hex += bigNum[i].toString(16).padStart(4, "0");
}
return hex;
}
function shl(bigNum, bits) {
let rest = 0;
const result = [];
for (let i = 0; i < bigNum.length; i += 1) {
let v = (bigNum[i] << bits) + rest;
result.push(v & 0xFFFF);
rest = (v >> 16) & 0xFFFF;
}
if (rest > 0) {
result.push(rest);
}
return result;
}
function add(a, b) {
let rest = 0;
const result = [];
const len = Math.max(a.length, b.length);
for (let i = 0; i < len; i += 1) {
let v = (i < a.length ? a[i] : 0) + (i < b.length ? b[i] : 0) + rest;
result.push(v & 0xFFFF);
rest = (v >> 16) & 0xFFFF;
}
if (rest > 0) {
result.push(rest);
}
return result;
}
//# sourceMappingURL=client.js.map