UNPKG

@cityofzion/neon-nep5

Version:
209 lines 9.05 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; 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.getTokens = exports.getToken = exports.getTokenBalances = exports.getTokenBalance = void 0; const neon_core_1 = require("@cityofzion/neon-core"); const abi = __importStar(require("./abi")); const log = neon_core_1.logging.default("nep5"); /** * Workaround for contracts such as SWTH returning Integer instead of ByteArray. */ function NumberParser(item) { switch (item.type) { case "Integer": return new neon_core_1.u.Fixed8(item.value).div(100000000); case "ByteArray": return neon_core_1.u.Fixed8.fromReverseHex(item.value); default: throw new Error(`Received invalid type ${item.type}`); } } const parseTokenInfo = neon_core_1.rpc.buildParser(neon_core_1.rpc.StringParser, neon_core_1.rpc.StringParser, neon_core_1.rpc.IntegerParser, NumberParser); const parseTokenInfoAndBalance = neon_core_1.rpc.buildParser(neon_core_1.rpc.StringParser, neon_core_1.rpc.StringParser, neon_core_1.rpc.IntegerParser, NumberParser, NumberParser); /** * Get the balance of a single token for a single address. * @param url Url of the NEO node to query. * @param scriptHash ScriptHash of the NEP5 contract. * @param address the Address to query for the balance. */ function getTokenBalance(url, scriptHash, address) { return __awaiter(this, void 0, void 0, function* () { const client = typeof url === "string" ? new neon_core_1.rpc.RPCClient(url) : url; const sb = new neon_core_1.sc.ScriptBuilder(); abi.decimals(scriptHash)(sb); abi.balanceOf(scriptHash, address)(sb); const script = sb.str; try { const res = yield client.invokeScript(script); const decimals = neon_core_1.rpc.IntegerParser(res.stack[0]); return NumberParser(res.stack[1]).mul(Math.pow(10, 8 - decimals)); } catch (err) { log.error(`getTokenBalance failed with : ${err.message}`); throw err; } }); } exports.getTokenBalance = getTokenBalance; /** * Get token balances for an address. * @param url URL of the NEO node to query. * @param scriptHashArray Array of contract scriptHashes. * @param address Address to query for balance of tokens. */ function getTokenBalances(url, scriptHashArray, address) { return __awaiter(this, void 0, void 0, function* () { const sb = new neon_core_1.sc.ScriptBuilder(); scriptHashArray.forEach((scriptHash) => { abi.symbol(scriptHash)(sb); abi.decimals(scriptHash)(sb); abi.balanceOf(scriptHash, address)(sb); }); const client = typeof url === "string" ? new neon_core_1.rpc.RPCClient(url) : url; const res = yield client.invokeScript(sb.str); const tokenList = {}; if (!res || !res.stack || res.stack.length !== 3 * scriptHashArray.length) { throw new Error("Stack returned was invalid"); } try { for (let i = 0; i < res.stack.length; i += 3) { try { const symbol = neon_core_1.rpc.StringParser(res.stack[i]); const decimals = neon_core_1.rpc.IntegerParser(res.stack[i + 1]); tokenList[symbol] = NumberParser(res.stack[i + 2]).mul(Math.pow(10, 8 - decimals)); } catch (e) { log.error(`single call in getTokenBalances failed with : ${e.message}`); throw e; } } return tokenList; } catch (err) { log.error(`getTokenBalances failed with : ${err.message}`); throw err; } }); } exports.getTokenBalances = getTokenBalances; /** * Retrieves the complete information about a token. * @param url RPC Node url to query. * @param scriptHash ScriptHash of the NEP5 contract. * @param address Optional address to query the balance for. If provided, the returned object will include the balance property. */ function getToken(url, scriptHash, address) { return __awaiter(this, void 0, void 0, function* () { const parser = address ? parseTokenInfoAndBalance : parseTokenInfo; const sb = new neon_core_1.sc.ScriptBuilder(); abi.name(scriptHash)(sb); abi.symbol(scriptHash)(sb); abi.decimals(scriptHash)(sb); abi.totalSupply(scriptHash)(sb); if (address) { abi.balanceOf(scriptHash, address)(sb); } const script = sb.str; try { const client = typeof url === "string" ? new neon_core_1.rpc.RPCClient(url) : url; const res = parser(yield client.invokeScript(script)); const result = { name: res[0], symbol: res[1], decimals: res[2], totalSupply: res[3].mul(Math.pow(10, 8 - res[2])).toNumber(), }; if (address) { result.balance = res[4].mul(Math.pow(10, 8 - res[2])); } return result; } catch (err) { log.error(`getToken failed with : ${err.message}`); throw err; } }); } exports.getToken = getToken; /** * Retrieves the complete information about a list of tokens. * @param url RPC Node url to query. * @param scriptHashArray Array of NEP5 contract scriptHashes. * @param address Optional address to query the balance for. If provided, the returned object will include the balance property. */ function getTokens(url, scriptHashArray, address) { return __awaiter(this, void 0, void 0, function* () { try { const sb = new neon_core_1.sc.ScriptBuilder(); scriptHashArray.forEach((scriptHash) => { abi.name(scriptHash)(sb); abi.symbol(scriptHash)(sb); abi.decimals(scriptHash)(sb); abi.totalSupply(scriptHash)(sb); if (address) { abi.balanceOf(scriptHash, address)(sb); } }); const client = typeof url === "string" ? new neon_core_1.rpc.RPCClient(url) : url; const res = yield client.invokeScript(sb.str); const result = []; const step = address ? 5 : 4; for (let i = 0; i < res.stack.length; i += step) { const name = neon_core_1.rpc.StringParser(res.stack[i]); const symbol = neon_core_1.rpc.StringParser(res.stack[i + 1]); const decimals = neon_core_1.rpc.IntegerParser(res.stack[i + 2]); const totalSupply = NumberParser(res.stack[i + 3]) .mul(Math.pow(10, 8 - decimals)) .toNumber(); const balance = address ? NumberParser(res.stack[i + 4]).mul(Math.pow(10, 8 - decimals)) : undefined; const obj = { name, symbol, decimals, totalSupply, balance, }; if (!obj.balance) { delete obj.balance; } result.push(obj); } return result; } catch (err) { log.error(`getTokens failed with : ${err.message}`); throw err; } }); } exports.getTokens = getTokens; //# sourceMappingURL=main.js.map