UNPKG

@kubectl/caminojs

Version:
986 lines 209 kB
"use strict"; 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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AVMAPI = void 0; /** * @packageDocumentation * @module API-AVM */ const bn_js_1 = __importDefault(require("bn.js")); const buffer_1 = require("buffer/"); const bintools_1 = __importDefault(require("../../utils/bintools")); const utxos_1 = require("./utxos"); const constants_1 = require("./constants"); const keychain_1 = require("./keychain"); const tx_1 = require("./tx"); const payload_1 = require("../../utils/payload"); const helperfunctions_1 = require("../../utils/helperfunctions"); const jrpcapi_1 = require("../../common/jrpcapi"); const constants_2 = require("../../utils/constants"); const output_1 = require("../../common/output"); const errors_1 = require("../../utils/errors"); const utils_1 = require("../../utils"); /** * @ignore */ const bintools = bintools_1.default.getInstance(); const serialization = utils_1.Serialization.getInstance(); /** * Class for interacting with a node endpoint that is using the AVM. * * @category RPCAPIs * * @remarks This extends the [[JRPCAPI]] class. This class should not be directly called. Instead, use the [[Avalanche.addAPI]] function to register this interface with Avalanche. */ class AVMAPI extends jrpcapi_1.JRPCAPI { /** * This class should not be instantiated directly. Instead use the [[Avalanche.addAP`${I}`]] method. * * @param core A reference to the Avalanche class * @param baseURL Defaults to the string "/ext/bc/X" as the path to blockchain's baseURL * @param blockchainID The Blockchain"s ID. Defaults to an empty string: "" */ constructor(core, baseURL = "/ext/bc/X", blockchainID = "") { super(core, baseURL); /** * @ignore */ this.keychain = new keychain_1.KeyChain("", ""); this.blockchainAlias = undefined; this.blockchainID = undefined; this.AVAXAssetID = undefined; this.txFee = undefined; this.creationTxFee = undefined; this.mintTxFee = undefined; /** * Gets the alias for the blockchainID if it exists, otherwise returns `undefined`. * * @returns The alias for the blockchainID */ this.getBlockchainAlias = () => { if (typeof this.blockchainAlias === "undefined") { this.blockchainAlias = this.core.getNetwork().X.alias; } return this.blockchainAlias; }; /** * Gets the blockchainID and returns it. * * @returns The blockchainID */ this.getBlockchainID = () => this.blockchainID; /** * Takes an address string and returns its {@link https://github.com/feross/buffer|Buffer} representation if valid. * * @returns A {@link https://github.com/feross/buffer|Buffer} for the address if valid, undefined if not valid. */ this.parseAddress = (addr) => { const alias = this.getBlockchainAlias(); const blockchainID = this.getBlockchainID(); return bintools.parseAddress(addr, blockchainID, alias, constants_1.AVMConstants.ADDRESSLENGTH); }; this.addressFromBuffer = (address) => { const chainID = this.getBlockchainAlias() ? this.getBlockchainAlias() : this.getBlockchainID(); const type = "bech32"; const hrp = this.core.getHRP(); return serialization.bufferToType(address, type, hrp, chainID); }; /** * Fetches the AVAX AssetID and returns it in a Promise. * * @param refresh This function caches the response. Refresh = true will bust the cache. * * @returns The the provided string representing the AVAX AssetID */ this.getAVAXAssetID = (refresh = false) => __awaiter(this, void 0, void 0, function* () { if (typeof this.AVAXAssetID === "undefined" || refresh) { const asset = yield this.getAssetDescription(this.core.getPrimaryAssetAlias()); this.AVAXAssetID = asset.assetID; } return this.AVAXAssetID; }); /** * Overrides the defaults and sets the cache to a specific AVAX AssetID * * @param avaxAssetID A cb58 string or Buffer representing the AVAX AssetID * * @returns The the provided string representing the AVAX AssetID */ this.setAVAXAssetID = (avaxAssetID) => { if (typeof avaxAssetID === "string") { avaxAssetID = bintools.cb58Decode(avaxAssetID); } this.AVAXAssetID = avaxAssetID; }; /** * Gets the default tx fee for this chain. * * @returns The default tx fee as a {@link https://github.com/indutny/bn.js/|BN} */ this.getDefaultTxFee = () => { return new bn_js_1.default(this.core.getNetwork().X.txFee); }; /** * Gets the tx fee for this chain. * * @returns The tx fee as a {@link https://github.com/indutny/bn.js/|BN} */ this.getTxFee = () => { if (typeof this.txFee === "undefined") { this.txFee = this.getDefaultTxFee(); } return this.txFee; }; /** * Sets the tx fee for this chain. * * @param fee The tx fee amount to set as {@link https://github.com/indutny/bn.js/|BN} */ this.setTxFee = (fee) => { this.txFee = fee; }; /** * Gets the default creation fee for this chain. * * @returns The default creation fee as a {@link https://github.com/indutny/bn.js/|BN} */ this.getDefaultCreationTxFee = () => { return new bn_js_1.default(this.core.getNetwork().X.creationTxFee); }; /** * Gets the default mint fee for this chain. * * @returns The default mint fee as a {@link https://github.com/indutny/bn.js/|BN} */ this.getDefaultMintTxFee = () => { var _a; return new bn_js_1.default((_a = this.core.getNetwork().X.mintTxFee) !== null && _a !== void 0 ? _a : 0); }; /** * Gets the mint fee for this chain. * * @returns The mint fee as a {@link https://github.com/indutny/bn.js/|BN} */ this.getMintTxFee = () => { if (typeof this.mintTxFee === "undefined") { this.mintTxFee = this.getDefaultMintTxFee(); } return this.mintTxFee; }; /** * Gets the creation fee for this chain. * * @returns The creation fee as a {@link https://github.com/indutny/bn.js/|BN} */ this.getCreationTxFee = () => { if (typeof this.creationTxFee === "undefined") { this.creationTxFee = this.getDefaultCreationTxFee(); } return this.creationTxFee; }; /** * Sets the mint fee for this chain. * * @param fee The mint fee amount to set as {@link https://github.com/indutny/bn.js/|BN} */ this.setMintTxFee = (fee) => { this.mintTxFee = fee; }; /** * Sets the creation fee for this chain. * * @param fee The creation fee amount to set as {@link https://github.com/indutny/bn.js/|BN} */ this.setCreationTxFee = (fee) => { this.creationTxFee = fee; }; /** * Gets a reference to the keychain for this class. * * @returns The instance of [[KeyChain]] for this class */ this.keyChain = () => this.keychain; /** * @ignore */ this.newKeyChain = () => { // warning, overwrites the old keychain const alias = this.getBlockchainAlias(); if (alias) { this.keychain = new keychain_1.KeyChain(this.core.getHRP(), alias); } else { this.keychain = new keychain_1.KeyChain(this.core.getHRP(), this.blockchainID); } return this.keychain; }; /** * Helper function which determines if a tx is a goose egg transaction. * * @param utx An UnsignedTx * * @returns boolean true if passes goose egg test and false if fails. * * @remarks * A "Goose Egg Transaction" is when the fee far exceeds a reasonable amount */ this.checkGooseEgg = (utx, outTotal = new bn_js_1.default(0)) => __awaiter(this, void 0, void 0, function* () { const avaxAssetID = yield this.getAVAXAssetID(); const outputTotal = outTotal.gt(new bn_js_1.default(0)) ? outTotal : utx.getOutputTotal(avaxAssetID); const fee = utx.getBurn(avaxAssetID); if (fee.lte(constants_2.ONEAVAX.mul(new bn_js_1.default(10))) || fee.lte(outputTotal)) { return true; } else { return false; } }); /** * Gets the balance of a particular asset on a blockchain. * * @param address The address to pull the asset balance from * @param assetID The assetID to pull the balance from * @param includePartial If includePartial=false, returns only the balance held solely * * @returns Promise with the balance of the assetID as a {@link https://github.com/indutny/bn.js/|BN} on the provided address for the blockchain. */ this.getBalance = (address, assetID, includePartial = false) => __awaiter(this, void 0, void 0, function* () { if (typeof this.parseAddress(address) === "undefined") { /* istanbul ignore next */ throw new errors_1.AddressError("Error - AVMAPI.getBalance: Invalid address format"); } const params = { address, assetID, includePartial }; const response = yield this.callMethod("avm.getBalance", params); return response.data.result; }); /** * Creates an address (and associated private keys) on a user on a blockchain. * * @param username Name of the user to create the address under * @param password Password to unlock the user and encrypt the private key * * @returns Promise for a string representing the address created by the vm. */ this.createAddress = (username, password) => __awaiter(this, void 0, void 0, function* () { const params = { username, password }; const response = yield this.callMethod("avm.createAddress", params); return response.data.result.address; }); /** * Create a new fixed-cap, fungible asset. A quantity of it is created at initialization and there no more is ever created. * * @param username The user paying the transaction fee (in $AVAX) for asset creation * @param password The password for the user paying the transaction fee (in $AVAX) for asset creation * @param name The human-readable name for the asset * @param symbol Optional. The shorthand symbol for the asset. Between 0 and 4 characters * @param denomination Optional. Determines how balances of this asset are displayed by user interfaces. Default is 0 * @param initialHolders An array of objects containing the field "address" and "amount" to establish the genesis values for the new asset * * ```js * Example initialHolders: * [ * { * "address": "X-avax1kj06lhgx84h39snsljcey3tpc046ze68mek3g5", * "amount": 10000 * }, * { * "address": "X-avax1am4w6hfrvmh3akduzkjthrtgtqafalce6an8cr", * "amount": 50000 * } * ] * ``` * * @returns Returns a Promise string containing the base 58 string representation of the ID of the newly created asset. */ this.createFixedCapAsset = (username, password, name, symbol, denomination, initialHolders) => __awaiter(this, void 0, void 0, function* () { const params = { name, symbol, denomination, username, password, initialHolders }; const response = yield this.callMethod("avm.createFixedCapAsset", params); return response.data.result.assetID; }); /** * Create a new variable-cap, fungible asset. No units of the asset exist at initialization. Minters can mint units of this asset using createMintTx, signMintTx and sendMintTx. * * @param username The user paying the transaction fee (in $AVAX) for asset creation * @param password The password for the user paying the transaction fee (in $AVAX) for asset creation * @param name The human-readable name for the asset * @param symbol Optional. The shorthand symbol for the asset -- between 0 and 4 characters * @param denomination Optional. Determines how balances of this asset are displayed by user interfaces. Default is 0 * @param minterSets is a list where each element specifies that threshold of the addresses in minters may together mint more of the asset by signing a minting transaction * * ```js * Example minterSets: * [ * { * "minters":[ * "X-avax1am4w6hfrvmh3akduzkjthrtgtqafalce6an8cr" * ], * "threshold": 1 * }, * { * "minters": [ * "X-avax1am4w6hfrvmh3akduzkjthrtgtqafalce6an8cr", * "X-avax1kj06lhgx84h39snsljcey3tpc046ze68mek3g5", * "X-avax1yell3e4nln0m39cfpdhgqprsd87jkh4qnakklx" * ], * "threshold": 2 * } * ] * ``` * * @returns Returns a Promise string containing the base 58 string representation of the ID of the newly created asset. */ this.createVariableCapAsset = (username, password, name, symbol, denomination, minterSets) => __awaiter(this, void 0, void 0, function* () { const params = { name, symbol, denomination, username, password, minterSets }; const response = yield this.callMethod("avm.createVariableCapAsset", params); return response.data.result.assetID; }); /** * Creates a family of NFT Asset. No units of the asset exist at initialization. Minters can mint units of this asset using createMintTx, signMintTx and sendMintTx. * * @param username The user paying the transaction fee (in $AVAX) for asset creation * @param password The password for the user paying the transaction fee (in $AVAX) for asset creation * @param from Optional. An array of addresses managed by the node's keystore for this blockchain which will fund this transaction * @param changeAddr Optional. An address to send the change * @param name The human-readable name for the asset * @param symbol Optional. The shorthand symbol for the asset -- between 0 and 4 characters * @param minterSets is a list where each element specifies that threshold of the addresses in minters may together mint more of the asset by signing a minting transaction * * @returns Returns a Promise string containing the base 58 string representation of the ID of the newly created asset. */ this.createNFTAsset = (username, password, from = undefined, changeAddr, name, symbol, minterSet) => __awaiter(this, void 0, void 0, function* () { const params = { username, password, name, symbol, minterSet }; const caller = "createNFTAsset"; from = this._cleanAddressArray(from, caller); if (typeof from !== "undefined") { params["from"] = from; } if (typeof changeAddr !== "undefined") { if (typeof this.parseAddress(changeAddr) === "undefined") { /* istanbul ignore next */ throw new errors_1.AddressError("Error - AVMAPI.createNFTAsset: Invalid address format"); } params["changeAddr"] = changeAddr; } const response = yield this.callMethod("avm.createNFTAsset", params); return response.data.result.assetID; }); /** * Create an unsigned transaction to mint more of an asset. * * @param amount The units of the asset to mint * @param assetID The ID of the asset to mint * @param to The address to assign the units of the minted asset * @param minters Addresses of the minters responsible for signing the transaction * * @returns Returns a Promise string containing the base 58 string representation of the unsigned transaction. */ this.mint = (username, password, amount, assetID, to, minters) => __awaiter(this, void 0, void 0, function* () { let asset; let amnt; if (typeof assetID !== "string") { asset = bintools.cb58Encode(assetID); } else { asset = assetID; } if (typeof amount === "number") { amnt = new bn_js_1.default(amount); } else { amnt = amount; } const params = { username: username, password: password, amount: amnt, assetID: asset, to, minters }; const response = yield this.callMethod("avm.mint", params); return response.data.result.txID; }); /** * Mint non-fungible tokens which were created with AVMAPI.createNFTAsset * * @param username The user paying the transaction fee (in $AVAX) for asset creation * @param password The password for the user paying the transaction fee (in $AVAX) for asset creation * @param from Optional. An array of addresses managed by the node's keystore for this blockchain which will fund this transaction * @param changeAddr Optional. An address to send the change * @param assetID The asset id which is being sent * @param to Address on X-Chain of the account to which this NFT is being sent * @param encoding Optional. is the encoding format to use for the payload argument. Can be either "cb58" or "hex". Defaults to "hex". * * @returns ID of the transaction */ this.mintNFT = (username, password, from = undefined, changeAddr = undefined, payload, assetID, to, encoding = "hex") => __awaiter(this, void 0, void 0, function* () { let asset; if (typeof this.parseAddress(to) === "undefined") { /* istanbul ignore next */ throw new errors_1.AddressError("Error - AVMAPI.mintNFT: Invalid address format"); } if (typeof assetID !== "string") { asset = bintools.cb58Encode(assetID); } else { asset = assetID; } const params = { username, password, assetID: asset, payload, to, encoding }; const caller = "mintNFT"; from = this._cleanAddressArray(from, caller); if (typeof from !== "undefined") { params["from"] = from; } if (typeof changeAddr !== "undefined") { if (typeof this.parseAddress(changeAddr) === "undefined") { /* istanbul ignore next */ throw new errors_1.AddressError("Error - AVMAPI.mintNFT: Invalid address format"); } params["changeAddr"] = changeAddr; } const response = yield this.callMethod("avm.mintNFT", params); return response.data.result.txID; }); /** * Send NFT from one account to another on X-Chain * * @param username The user paying the transaction fee (in $AVAX) for asset creation * @param password The password for the user paying the transaction fee (in $AVAX) for asset creation * @param from Optional. An array of addresses managed by the node's keystore for this blockchain which will fund this transaction * @param changeAddr Optional. An address to send the change * @param assetID The asset id which is being sent * @param groupID The group this NFT is issued to. * @param to Address on X-Chain of the account to which this NFT is being sent * * @returns ID of the transaction */ this.sendNFT = (username, password, from = undefined, changeAddr = undefined, assetID, groupID, to) => __awaiter(this, void 0, void 0, function* () { let asset; if (typeof this.parseAddress(to) === "undefined") { /* istanbul ignore next */ throw new errors_1.AddressError("Error - AVMAPI.sendNFT: Invalid address format"); } if (typeof assetID !== "string") { asset = bintools.cb58Encode(assetID); } else { asset = assetID; } const params = { username, password, assetID: asset, groupID, to }; const caller = "sendNFT"; from = this._cleanAddressArray(from, caller); if (typeof from !== "undefined") { params["from"] = from; } if (typeof changeAddr !== "undefined") { if (typeof this.parseAddress(changeAddr) === "undefined") { /* istanbul ignore next */ throw new errors_1.AddressError("Error - AVMAPI.sendNFT: Invalid address format"); } params["changeAddr"] = changeAddr; } const response = yield this.callMethod("avm.sendNFT", params); return response.data.result.txID; }); /** * Exports the private key for an address. * * @param username The name of the user with the private key * @param password The password used to decrypt the private key * @param address The address whose private key should be exported * * @returns Promise with the decrypted private key as store in the database */ this.exportKey = (username, password, address) => __awaiter(this, void 0, void 0, function* () { if (typeof this.parseAddress(address) === "undefined") { /* istanbul ignore next */ throw new errors_1.AddressError("Error - AVMAPI.exportKey: Invalid address format"); } const params = { username, password, address }; const response = yield this.callMethod("avm.exportKey", params); return response.data.result.privateKey; }); /** * Imports a private key into the node's keystore under an user and for a blockchain. * * @param username The name of the user to store the private key * @param password The password that unlocks the user * @param privateKey A string representing the private key in the vm's format * * @returns The address for the imported private key. */ this.importKey = (username, password, privateKey) => __awaiter(this, void 0, void 0, function* () { const params = { username, password, privateKey }; const response = yield this.callMethod("avm.importKey", params); return response.data.result.address; }); /** * Send ANT (Avalanche Native Token) assets including AVAX from the X-Chain to an account on the P-Chain or C-Chain. * * After calling this method, you must call the P-Chain's `import` or the C-Chain’s `import` method to complete the transfer. * * @param username The Keystore user that controls the P-Chain or C-Chain account specified in `to` * @param password The password of the Keystore user * @param to The account on the P-Chain or C-Chain to send the asset to. * @param amount Amount of asset to export as a {@link https://github.com/indutny/bn.js/|BN} * @param assetID The asset id which is being sent * * @returns String representing the transaction id */ this.export = (username, password, to, amount, assetID) => __awaiter(this, void 0, void 0, function* () { const params = { username, password, to, amount: amount, assetID }; const response = yield this.callMethod("avm.export", params); return response.data.result.txID; }); /** * Send ANT (Avalanche Native Token) assets including AVAX from an account on the P-Chain or C-Chain to an address on the X-Chain. This transaction * must be signed with the key of the account that the asset is sent from and which pays * the transaction fee. * * @param username The Keystore user that controls the account specified in `to` * @param password The password of the Keystore user * @param to The address of the account the asset is sent to. * @param sourceChain The chainID where the funds are coming from. Ex: "C" * * @returns Promise for a string for the transaction, which should be sent to the network * by calling issueTx. */ this.import = (username, password, to, sourceChain) => __awaiter(this, void 0, void 0, function* () { const params = { username, password, to, sourceChain }; const response = yield this.callMethod("avm.import", params); return response.data.result.txID; }); /** * Lists all the addresses under a user. * * @param username The user to list addresses * @param password The password of the user to list the addresses * * @returns Promise of an array of address strings in the format specified by the blockchain. */ this.listAddresses = (username, password) => __awaiter(this, void 0, void 0, function* () { const params = { username, password }; const response = yield this.callMethod("avm.listAddresses", params); return response.data.result.addresses; }); /** * Retrieves all assets for an address on a server and their associated balances. * * @param address The address to get a list of assets * * @returns Promise of an object mapping assetID strings with {@link https://github.com/indutny/bn.js/|BN} balance for the address on the blockchain. */ this.getAllBalances = (address) => __awaiter(this, void 0, void 0, function* () { if (typeof this.parseAddress(address) === "undefined") { /* istanbul ignore next */ throw new errors_1.AddressError("Error - AVMAPI.getAllBalances: Invalid address format"); } const params = { address }; const response = yield this.callMethod("avm.getAllBalances", params); return response.data.result.balances; }); /** * Retrieves an assets name and symbol. * * @param assetID Either a {@link https://github.com/feross/buffer|Buffer} or an b58 serialized string for the AssetID or its alias. * * @returns Returns a Promise object with keys "name" and "symbol". */ this.getAssetDescription = (assetID) => __awaiter(this, void 0, void 0, function* () { let asset; if (typeof assetID !== "string") { asset = bintools.cb58Encode(assetID); } else { asset = assetID; } const params = { assetID: asset }; const response = yield this.callMethod("avm.getAssetDescription", params); return { name: response.data.result.name, symbol: response.data.result.symbol, assetID: bintools.cb58Decode(response.data.result.assetID), denomination: parseInt(response.data.result.denomination, 10) }; }); /** * Returns the transaction data of a provided transaction ID by calling the node's `getTx` method. * * @param txID The string representation of the transaction ID * @param encoding sets the format of the returned transaction. Can be, "cb58", "hex" or "json". Defaults to "cb58". * * @returns Returns a Promise string or object containing the bytes retrieved from the node */ this.getTx = (txID, encoding = "hex") => __awaiter(this, void 0, void 0, function* () { const params = { txID, encoding }; const response = yield this.callMethod("avm.getTx", params); return response.data.result.tx; }); /** * Returns the status of a provided transaction ID by calling the node's `getTxStatus` method. * * @param txID The string representation of the transaction ID * * @returns Returns a Promise string containing the status retrieved from the node */ this.getTxStatus = (txID) => __awaiter(this, void 0, void 0, function* () { const params = { txID }; const response = yield this.callMethod("avm.getTxStatus", params); return response.data.result.status; }); /** * Retrieves the UTXOs related to the addresses provided from the node's `getUTXOs` method. * * @param addresses An array of addresses as cb58 strings or addresses as {@link https://github.com/feross/buffer|Buffer}s * @param sourceChain A string for the chain to look for the UTXO's. Default is to use this chain, but if exported UTXOs exist from other chains, this can used to pull them instead. * @param limit Optional. Returns at most [limit] addresses. If [limit] == 0 or > [maxUTXOsToFetch], fetches up to [maxUTXOsToFetch]. * @param startIndex Optional. [StartIndex] defines where to start fetching UTXOs (for pagination.) * UTXOs fetched are from addresses equal to or greater than [StartIndex.Address] * For address [StartIndex.Address], only UTXOs with IDs greater than [StartIndex.Utxo] will be returned. * @param persistOpts Options available to persist these UTXOs in local storage * * @remarks * persistOpts is optional and must be of type [[PersistanceOptions]] * */ this.getUTXOs = (addresses, sourceChain = undefined, limit = 0, startIndex = undefined, persistOpts = undefined, encoding = "hex") => __awaiter(this, void 0, void 0, function* () { if (typeof addresses === "string") { addresses = [addresses]; } const params = { addresses: addresses, limit, encoding }; if (typeof startIndex !== "undefined" && startIndex) { params.startIndex = startIndex; } if (typeof sourceChain !== "undefined") { params.sourceChain = sourceChain; } const response = yield this.callMethod("avm.getUTXOs", params); const utxos = new utxos_1.UTXOSet(); let data = response.data.result.utxos; if (persistOpts && typeof persistOpts === "object") { if (this.db.has(persistOpts.getName())) { const selfArray = this.db.get(persistOpts.getName()); if (Array.isArray(selfArray)) { utxos.addArray(data); const utxoSet = new utxos_1.UTXOSet(); utxoSet.addArray(selfArray); utxoSet.mergeByRule(utxos, persistOpts.getMergeRule()); data = utxoSet.getAllUTXOStrings(); } } this.db.set(persistOpts.getName(), data, persistOpts.getOverwrite()); } if (data.length > 0 && data[0].substring(0, 2) === "0x") { const cb58Strs = []; data.forEach((str) => { cb58Strs.push(bintools.cb58Encode(new buffer_1.Buffer(str.slice(2), "hex"))); }); utxos.addArray(cb58Strs, false); } else { utxos.addArray(data, false); } response.data.result.utxos = utxos; return response.data.result; }); /** * Helper function which creates an unsigned transaction. For more granular control, you may create your own * [[UnsignedTx]] manually (with their corresponding [[TransferableInput]]s, [[TransferableOutput]]s, and [[TransferOperation]]s). * * @param utxoset A set of UTXOs that the transaction is built on * @param amount The amount of AssetID to be spent in its smallest denomination, represented as {@link https://github.com/indutny/bn.js/|BN}. * @param assetID The assetID of the value being sent * @param toAddresses The addresses to send the funds * @param fromAddresses The addresses being used to send the funds from the UTXOs provided * @param changeAddresses The addresses that can spend the change remaining from the spent UTXOs * @param memo Optional CB58 Buffer or String which contains arbitrary bytes, up to 256 bytes * @param asOf Optional. The timestamp to verify the transaction against as a {@link https://github.com/indutny/bn.js/|BN} * @param locktime Optional. The locktime field created in the resulting outputs * @param threshold Optional. The number of signatures required to spend the funds in the resultant UTXO * * @returns An unsigned transaction ([[UnsignedTx]]) which contains a [[BaseTx]]. * * @remarks * This helper exists because the endpoint API should be the primary point of entry for most functionality. */ this.buildBaseTx = (utxoset, amount, assetID = undefined, toAddresses, fromAddresses, changeAddresses, memo = undefined, asOf = (0, helperfunctions_1.UnixNow)(), locktime = new bn_js_1.default(0), threshold = 1) => __awaiter(this, void 0, void 0, function* () { const caller = "buildBaseTx"; const to = this._cleanAddressArray(toAddresses, caller).map((a) => bintools.stringToAddress(a)); const from = this._cleanAddressArray(fromAddresses, caller).map((a) => bintools.stringToAddress(a)); const change = this._cleanAddressArray(changeAddresses, caller).map((a) => bintools.stringToAddress(a)); if (typeof assetID === "string") { assetID = bintools.cb58Decode(assetID); } if (memo instanceof payload_1.PayloadBase) { memo = memo.getPayload(); } const networkID = this.core.getNetworkID(); const blockchainIDBuf = bintools.cb58Decode(this.blockchainID); const fee = this.getTxFee(); const feeAssetID = yield this.getAVAXAssetID(); const builtUnsignedTx = utxoset.buildBaseTx(networkID, blockchainIDBuf, amount, assetID, to, from, change, fee, feeAssetID, memo, asOf, locktime, threshold); if (!(yield this.checkGooseEgg(builtUnsignedTx))) { /* istanbul ignore next */ throw new errors_1.GooseEggCheckError("Error - AVMAPI.buildBaseTx:Failed Goose Egg Check"); } return builtUnsignedTx; }); /** * Helper function which creates an unsigned NFT Transfer. For more granular control, you may create your own * [[UnsignedTx]] manually (with their corresponding [[TransferableInput]]s, [[TransferableOutput]]s, and [[TransferOperation]]s). * * @param utxoset A set of UTXOs that the transaction is built on * @param toAddresses The addresses to send the NFT * @param fromAddresses The addresses being used to send the NFT from the utxoID provided * @param changeAddresses The addresses that can spend the change remaining from the spent UTXOs * @param utxoid A base58 utxoID or an array of base58 utxoIDs for the nfts this transaction is sending * @param memo Optional CB58 Buffer or String which contains arbitrary bytes, up to 256 bytes * @param asOf Optional. The timestamp to verify the transaction against as a {@link https://github.com/indutny/bn.js/|BN} * @param locktime Optional. The locktime field created in the resulting outputs * @param threshold Optional. The number of signatures required to spend the funds in the resultant UTXO * * @returns An unsigned transaction ([[UnsignedTx]]) which contains a [[NFTTransferTx]]. * * @remarks * This helper exists because the endpoint API should be the primary point of entry for most functionality. */ this.buildNFTTransferTx = (utxoset, toAddresses, fromAddresses, changeAddresses, utxoid, memo = undefined, asOf = (0, helperfunctions_1.UnixNow)(), locktime = new bn_js_1.default(0), threshold = 1) => __awaiter(this, void 0, void 0, function* () { const caller = "buildNFTTransferTx"; const to = this._cleanAddressArray(toAddresses, caller).map((a) => bintools.stringToAddress(a)); const from = this._cleanAddressArray(fromAddresses, caller).map((a) => bintools.stringToAddress(a)); const change = this._cleanAddressArray(changeAddresses, caller).map((a) => bintools.stringToAddress(a)); if (memo instanceof payload_1.PayloadBase) { memo = memo.getPayload(); } const avaxAssetID = yield this.getAVAXAssetID(); let utxoidArray = []; if (typeof utxoid === "string") { utxoidArray = [utxoid]; } else if (Array.isArray(utxoid)) { utxoidArray = utxoid; } const builtUnsignedTx = utxoset.buildNFTTransferTx(this.core.getNetworkID(), bintools.cb58Decode(this.blockchainID), to, from, change, utxoidArray, this.getTxFee(), avaxAssetID, memo, asOf, locktime, threshold); if (!(yield this.checkGooseEgg(builtUnsignedTx))) { /* istanbul ignore next */ throw new errors_1.GooseEggCheckError("Error - AVMAPI.buildNFTTransferTx:Failed Goose Egg Check"); } return builtUnsignedTx; }); /** * Helper function which creates an unsigned Import Tx. For more granular control, you may create your own * [[UnsignedTx]] manually (with their corresponding [[TransferableInput]]s, [[TransferableOutput]]s, and [[TransferOperation]]s). * * @param utxoset A set of UTXOs that the transaction is built on * @param ownerAddresses The addresses being used to import * @param sourceChain The chainid for where the import is coming from * @param toAddresses The addresses to send the funds * @param fromAddresses The addresses being used to send the funds from the UTXOs provided * @param changeAddresses The addresses that can spend the change remaining from the spent UTXOs * @param memo Optional CB58 Buffer or String which contains arbitrary bytes, up to 256 bytes * @param asOf Optional. The timestamp to verify the transaction against as a {@link https://github.com/indutny/bn.js/|BN} * @param locktime Optional. The locktime field created in the resulting outputs * @param threshold Optional. The number of signatures required to spend the funds in the resultant UTXO * * @returns An unsigned transaction ([[UnsignedTx]]) which contains a [[ImportTx]]. * * @remarks * This helper exists because the endpoint API should be the primary point of entry for most functionality. */ this.buildImportTx = (utxoset, ownerAddresses, sourceChain, toAddresses, fromAddresses, changeAddresses = undefined, memo = undefined, asOf = (0, helperfunctions_1.UnixNow)(), locktime = new bn_js_1.default(0), threshold = 1) => __awaiter(this, void 0, void 0, function* () { const caller = "buildImportTx"; const to = this._cleanAddressArray(toAddresses, caller).map((a) => bintools.stringToAddress(a)); const from = this._cleanAddressArray(fromAddresses, caller).map((a) => bintools.stringToAddress(a)); const change = this._cleanAddressArray(changeAddresses, caller).map((a) => bintools.stringToAddress(a)); let srcChain = undefined; if (typeof sourceChain === "undefined") { throw new errors_1.ChainIdError("Error - AVMAPI.buildImportTx: Source ChainID is undefined."); } else if (typeof sourceChain === "string") { srcChain = sourceChain; sourceChain = bintools.cb58Decode(sourceChain); } else if (!(sourceChain instanceof buffer_1.Buffer)) { throw new errors_1.ChainIdError("Error - AVMAPI.buildImportTx: Invalid destinationChain type: " + typeof sourceChain); } const atomicUTXOs = (yield this.getUTXOs(ownerAddresses, srcChain, 0, undefined)).utxos; const avaxAssetID = yield this.getAVAXAssetID(); const atomics = atomicUTXOs.getAllUTXOs(); if (atomics.length === 0) { throw new errors_1.NoAtomicUTXOsError("Error - AVMAPI.buildImportTx: No atomic UTXOs to import from " + srcChain + " using addresses: " + ownerAddresses.join(", ")); } if (memo instanceof payload_1.PayloadBase) { memo = memo.getPayload(); } const builtUnsignedTx = utxoset.buildImportTx(this.core.getNetworkID(), bintools.cb58Decode(this.blockchainID), to, from, change, atomics, sourceChain, this.getTxFee(), avaxAssetID, memo, asOf, locktime, threshold); if (!(yield this.checkGooseEgg(builtUnsignedTx))) { /* istanbul ignore next */ throw new errors_1.GooseEggCheckError("Error - AVMAPI.buildImportTx:Failed Goose Egg Check"); } return builtUnsignedTx; }); /** * Helper function which creates an unsigned Export Tx. For more granular control, you may create your own * [[UnsignedTx]] manually (with their corresponding [[TransferableInput]]s, [[TransferableOutput]]s, and [[TransferOperation]]s). * * @param utxoset A set of UTXOs that the transaction is built on * @param amount The amount being exported as a {@link https://github.com/indutny/bn.js/|BN} * @param destinationChain The chainid for where the assets will be sent. * @param toAddresses The addresses to send the funds * @param fromAddresses The addresses being used to send the funds from the UTXOs provided * @param changeAddresses The addresses that can spend the change remaining from the spent UTXOs * @param memo Optional CB58 Buffer or String which contains arbitrary bytes, up to 256 bytes * @param asOf Optional. The timestamp to verify the transaction against as a {@link https://github.com/indutny/bn.js/|BN} * @param locktime Optional. The locktime field created in the resulting outputs * @param threshold Optional. The number of signatures required to spend the funds in the resultant UTXO * @param assetID Optional. The assetID of the asset to send. Defaults to AVAX assetID. * Regardless of the asset which you"re exporting, all fees are paid in AVAX. * * @returns An unsigned transaction ([[UnsignedTx]]) which contains an [[ExportTx]]. */ this.buildExportTx = (utxoset, amount, destinationChain, toAddresses, fromAddresses, changeAddresses = undefined, memo = undefined, asOf = (0, helperfunctions_1.UnixNow)(), locktime = new bn_js_1.default(0), threshold = 1, assetID = undefined) => __awaiter(this, void 0, void 0, function* () { const prefixes = {}; toAddresses.map((a) => { prefixes[a.split("-")[0]] = true; }); if (Object.keys(prefixes).length !== 1) { throw new errors_1.AddressError("Error - AVMAPI.buildExportTx: To addresses must have the same chainID prefix."); } if (typeof destinationChain === "undefined") { throw new errors_1.ChainIdError("Error - AVMAPI.buildExportTx: Destination ChainID is undefined."); } else if (typeof destinationChain === "string") { destinationChain = bintools.cb58Decode(destinationChain); // } else if (!(destinationChain instanceof buffer_1.Buffer)) { throw new errors_1.ChainIdError("Error - AVMAPI.buildExportTx: Invalid destinationChain type: " + typeof destinationChain); } if (destinationChain.length !== 32) { throw new errors_1.ChainIdError("Error - AVMAPI.buildExportTx: Destination ChainID must be 32 bytes in length."); } const to = []; toAddresses.map((a) => { to.push(bintools.stringToAddress(a)); }); const caller = "buildExportTx"; const from = this._cleanAddressArray(fromAddresses, caller).map((a) => bintools.stringToAddress(a)); const change = this._cleanAddressArray(changeAddresses, caller).map((a) => bintools.stringToAddress(a)); if (memo instanceof payload_1.PayloadBase) { memo = memo.getPayload(); } const avaxAssetID = yield this.getAVAXAssetID(); if (typeof assetID === "undefined") { assetID = bintools.cb58Encode(avaxAssetID); } const networkID = this.core.getNetworkID(); const blockchainID = bintools.cb58Decode(this.blockchainID); const assetIDBuf = bintools.cb58Decode(assetID); const fee = this.getTxFee(); const builtUnsignedTx = utxoset.buildExportTx(networkID, blockchainID, amount, assetIDBuf, to, from, change, destinationChain, fee, avaxAssetID, memo, asOf, locktime, threshold); if (!(yield this.checkGooseEgg(builtUnsignedTx))) { /* istanbul ignore next */ throw new errors_1.GooseEggCheckError("Error - AVMAPI.buildExportTx:Failed Goose Egg Check"); } return builtUnsignedTx; }); /** * Creates an unsigned transaction. For more granular control, you may create your own * [[UnsignedTx]] manually (with their corresponding [[TransferableInput]]s, [[TransferableOutput]]s, and [[TransferOperation]]s). * * @param utxoset A set of UTXOs that the transaction is built on * @param fromAddresses The addresses being used to send the funds from the UTXOs {@link https://github.com/feross/b