avail-js-sdk
Version:
Avail library of functions to interact with blockchain and manipulate transactions
192 lines (191 loc) • 7.85 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
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.extractData = exports.decodeHexAppId = exports.decodeU8IntAppId = exports.splitStringIntoArray = exports.getKeyringFromSeed = exports.generateKeyring = exports.formatNumberToBalance = exports.isValidAddress = void 0;
exports.fromHexToAscii = fromHexToAscii;
exports.decodeError = decodeError;
const keyring_1 = require("@polkadot/keyring");
const util_1 = require("@polkadot/util");
__exportStar(require("./types"), exports);
/**
*
* This function checks if a given address is valid.
*
* @param {string} address The address to validate.
*
* @returns {boolean} A boolean value indicating whether the address is valid or not.
*/
const isValidAddress = (address) => {
try {
(0, keyring_1.encodeAddress)((0, util_1.isHex)(address) ? (0, util_1.hexToU8a)(address) : (0, keyring_1.decodeAddress)(address));
return true;
}
catch (error) {
return false;
}
};
exports.isValidAddress = isValidAddress;
/**
* Formats a number to balance.
*
* @param {number | string} value The number value to format.
* @param {number} [decimals] The number of decimal places to include in the formatted balance. Defaults to 18.
*
* @returns {BN} The converted BN value.
*/
const formatNumberToBalance = (value, decimals = 18) => {
const MAX_NUMBER_VALUES = 10;
const [integerPart, fractionalPart] = value.toString().split(".");
if (typeof value === "number" &&
((integerPart && integerPart.length > MAX_NUMBER_VALUES) ||
(fractionalPart && fractionalPart.length > MAX_NUMBER_VALUES))) {
throw new Error("For big representation of number, please use a string instead of a number");
}
const integerBN = new util_1.BN(integerPart).mul(new util_1.BN(10).pow(new util_1.BN(decimals)));
if (!fractionalPart)
return integerBN;
const fractionalBN = new util_1.BN(`${fractionalPart}${"0".repeat(decimals)}`.slice(0, decimals));
return integerBN.add(fractionalBN);
};
exports.formatNumberToBalance = formatNumberToBalance;
/**
* Generates a new keyring.
*
* @returns {Keyring} The newly generated Keyring instance.
*/
const generateKeyring = () => {
return new keyring_1.Keyring({ type: "sr25519" });
};
exports.generateKeyring = generateKeyring;
/**
* Retrieves a keyring pair from a given seed.
*
* @param {string} seed The seed value used to generate the keypair.
* @returns {KeyringPair} The KeyringPair generated from the seed.
*/
const getKeyringFromSeed = (seed) => {
const keyring = (0, exports.generateKeyring)();
return keyring.addFromUri(seed);
};
exports.getKeyringFromSeed = getKeyringFromSeed;
/**
* Splits a string into an array of substrings of a specified chunk size.
*
* @param {string} inputString The input string to split.
* @param {number} chunkSize The size of each chunk. Default is 2.
* @returns {string[]} An array of substrings.
*/
const splitStringIntoArray = (inputString, chunkSize = 2) => {
const result = [];
for (let i = 0; i < inputString.length; i += chunkSize) {
result.push(inputString.substring(i, i + chunkSize));
}
return result;
};
exports.splitStringIntoArray = splitStringIntoArray;
/**
* Decodes a Uint8Array into a decimal value.
*
* @param {Uint8Array} value The Uint8Array to decode.
* @returns {string} The decoded hex-encoded App ID as a string.
*/
const decodeU8IntAppId = (value) => {
const hexAppId = (0, util_1.u8aToHex)(value, undefined, false);
return (0, exports.decodeHexAppId)(hexAppId);
};
exports.decodeU8IntAppId = decodeU8IntAppId;
/**
* Decodes a hex-encoded App ID string into a decimal value.
*
* @param {string} value The hex-encoded App ID string to decode.
* @returns {string} The decoded decimal value as a string.
* @throws {Error} If the input value has an invalid length.
*/
const decodeHexAppId = (value) => {
if (value.length <= 1 || value.length % 2 !== 0)
throw new Error("Invalid length");
const v = value.startsWith("0x") ? value.substring(2) : value;
const array = (0, exports.splitStringIntoArray)(v);
let s = BigInt(0);
array.forEach((x, i) => {
s += BigInt(parseInt(x, 16)) << BigInt(i * 8);
});
const result = (s >> BigInt(array.length <= 4 ? 2 : 8)).toString();
return result;
};
exports.decodeHexAppId = decodeHexAppId;
/**
* Extracts the data from a da submission
*
* @param {ApiPromise} api the api to interact with the chain.
* @param {string} blockHash the hash of the block to query at.
* @param {string} extrinsicHash the hash of the extrinsic to query at.
* @return {Promise<string>} the bytes representing the data
* @throws {Error} If the api is not connected, the block is empty or non existant, the extrinsic hash is non existant
*/
const extractData = (api, blockHash, extrinsicHash) => __awaiter(void 0, void 0, void 0, function* () {
const block = yield api.rpc.chain.getBlock(blockHash);
const extrinsics = block.block.extrinsics.filter((x) => x.hash.toString() === extrinsicHash);
if (extrinsics.length === 0)
throw new Error("Extrinsic not found in block");
const extrinsic = extrinsics[0];
const { method: { args }, } = extrinsic;
let dataHex = args.map((x) => x.toString()).join(", ");
if (dataHex.startsWith("0x"))
dataHex = dataHex.slice(2);
let data = "";
for (let n = 0; n < dataHex.length; n += 2) {
data += String.fromCharCode(parseInt(dataHex.substring(n, n + 2), 16));
}
return data;
});
exports.extractData = extractData;
/**
* Converts a hexadecimal string to an ASCII string.
*
* @param {string} hex - The hexadecimal string to convert.
* @return {string} The converted ASCII string.
*/
function fromHexToAscii(hex) {
let str = "";
for (let n = 0; n < hex.length; n += 2) {
str += String.fromCharCode(parseInt(hex.substring(n, n + 2), 16));
}
return `${str}`;
}
/**
* Decodes a runtime error from the Substrate chain.
*
* @param {ApiPromise} api - The API instance to interact with the chain.
* @param {any} error - The error object to decode.
* @return {string} The decoded error message in the format "section.method: description".
*/
function decodeError(api, error) {
if (!error.isModule) {
return error.toString();
}
const { docs, method, section } = api.registry.findMetaError(error.asModule);
return `${section}.${method}: ${docs.join(" ")}`;
}