UNPKG

nexa-wallet-sdk

Version:

Wallet SDK for the Nexa blockchain

1,094 lines (1,056 loc) 207 kB
import {SighashType as $5cbb3ff6642afc2e$re_export$SighashType, Networks as $633cp$Networks, HDPrivateKey as $633cp$HDPrivateKey, TransactionBuilder as $633cp$TransactionBuilder, Message as $633cp$Message, AddressType as $633cp$AddressType, Address as $633cp$Address, CommonUtils as $633cp$CommonUtils, BufferWriter as $633cp$BufferWriter, Hash as $633cp$Hash, GroupToken as $633cp$GroupToken, TxSigner as $633cp$TxSigner, TxSignature as $633cp$TxSignature, ScriptTemplateInput as $633cp$ScriptTemplateInput, ScriptFactory as $633cp$ScriptFactory, Script as $633cp$Script, UnitUtils as $633cp$UnitUtils, Transaction as $633cp$Transaction, BNExtended as $633cp$BNExtended, BufferUtils as $633cp$BufferUtils, Output as $633cp$Output} from "libnexa-ts"; import {generateMnemonic as $633cp$generateMnemonic, wordlists as $633cp$wordlists, mnemonicToSeedSync as $633cp$mnemonicToSeedSync, validateMnemonic as $633cp$validateMnemonic} from "bip39"; import {isNil as $633cp$isNil, isString as $633cp$isString, isBuffer as $633cp$isBuffer, isArray as $633cp$isArray, parseInt as $633cp$parseInt, isObject as $633cp$isObject} from "lodash-es"; import {ConnectionStatus as $633cp$ConnectionStatus, ElectrumClient as $633cp$ElectrumClient} from "@vgrunner/electrum-cash"; import $633cp$jsbigdecimal from "js-big-decimal"; import {DAppProvider as $633cp$DAppProvider, JsonRpcError as $633cp$JsonRpcError, JsonRpcErrorCode as $633cp$JsonRpcErrorCode, WalletProvider as $633cp$WalletProvider} from "wallet-comms-sdk"; var $parcel$global = globalThis; // @ts-ignore var $bbe36848c5b6746e$exports = {}; $bbe36848c5b6746e$exports = JSON.parse("{\"name\":\"nexa-wallet-sdk\",\"version\":\"0.6.3\",\"type\":\"module\",\"source\":\"src/index.ts\",\"types\":\"dist/index.d.ts\",\"main\":\"dist/index.cjs\",\"module\":\"dist/index.mjs\",\"browser\":\"dist/index.web.mjs\",\"exports\":{\"types\":\"./dist/index.d.ts\",\"node\":{\"import\":\"./dist/index.mjs\",\"require\":\"./dist/index.cjs\"},\"browser\":\"./dist/index.web.mjs\",\"default\":\"./dist/index.mjs\"},\"scripts\":{\"build\":\"parcel build\",\"lint\":\"eslint .\",\"fix-lint\":\"eslint --fix .\",\"dev\":\"parcel watch\",\"test\":\"vitest run\",\"clean\":\"rm -rf dist .parcel-cache\",\"docs\":\"typedoc\",\"docs:serve\":\"typedoc && npx serve docs -l 8080\",\"docs:mkdocs\":\"typedoc && mkdocs serve\",\"docs:build\":\"typedoc && mkdocs build\",\"docs:setup\":\"./scripts/setup-docs.sh\",\"wallet-cli\":\"node examples/wallet-cli.cjs\"},\"repository\":{\"type\":\"git\",\"url\":\"git+ssh://git@gitlab.com/nexa/wallet-sdk-ts.git\"},\"keywords\":[\"nexa\",\"wallet\",\"web3\",\"crypto\",\"dapp\",\"walletcomms\",\"walletsdk\"],\"contributors\":[{\"name\":\"Dolaned\"},{\"name\":\"Griffith\"},{\"name\":\"Vgrunner\"},{\"name\":\"myendy\"}],\"author\":\"Dolaned\",\"license\":\"MIT\",\"bugs\":{\"url\":\"https://gitlab.com/nexa/wallet-sdk-ts/issues\"},\"homepage\":\"https://gitlab.com/nexa/wallet-sdk-ts#readme\",\"description\":\"Wallet SDK for the Nexa blockchain\",\"devDependencies\":{\"@parcel/bundler-library\":\"^2.16.0\",\"@parcel/packager-ts\":\"^2.15.4\",\"@parcel/transformer-typescript-types\":\"^2.15.4\",\"@types/lodash-es\":\"^4.17.12\",\"@types/node\":\"^22.13.1\",\"eslint\":\"^9.20.1\",\"parcel\":\"^2.15.4\",\"typedoc\":\"^0.28.7\",\"typedoc-plugin-markdown\":\"^4.7.0\",\"typedoc-plugin-rename-defaults\":\"^0.7.3\",\"typescript\":\"^5.8.3\",\"typescript-eslint\":\"^8.24.1\",\"vitest\":\"^3.0.8\"},\"targets\":{\"main\":{\"context\":\"node\",\"outputFormat\":\"commonjs\",\"distDir\":\"dist\",\"isLibrary\":true,\"includeNodeModules\":[\"lodash-es\"]},\"module\":{\"context\":\"node\",\"outputFormat\":\"esmodule\",\"distDir\":\"dist\",\"isLibrary\":true},\"browser\":{\"context\":\"browser\",\"outputFormat\":\"esmodule\",\"distDir\":\"dist\",\"isLibrary\":true}},\"dependencies\":{\"@vgrunner/electrum-cash\":\"^2.0.12\",\"bip39\":\"^3.1.0\",\"js-big-decimal\":\"^2.2.0\",\"libnexa-ts\":\"^2.1.0\",\"lodash-es\":\"^4.17.21\",\"prompt-sync\":\"^4.2.0\",\"wallet-comms-sdk\":\"^0.7.2\"},\"files\":[\"dist\"],\"directories\":{\"test\":\"tests\"},\"@parcel/resolver-default\":{\"packageExports\":true}}"); const $a0b58ced4ea5a401$export$1f6f962b0b96558 = { WS: 'ws', WSS: 'wss', TCP: "tcp", TCP_TLS: "tcp_tls" }; class $30c92dd8e96ca60d$export$ba81aefc89aef50c { constructor(){} /** * Get Rostum Server Version */ async getVersion() { return await this.execute('server.version'); } /** * Get the block tip of the network / chain we are currently connected to */ async getBlockTip() { return await this.execute('blockchain.headers.tip'); } /** * Get the nexa balance of an address without the token balances * @param address */ async getBalance(address) { return await this.execute('blockchain.address.get_balance', address, 'exclude_tokens'); } /** * Get The transaction history for an address * @param address */ async getTransactionHistory(address) { return await this.execute('blockchain.address.get_history', address); } /** * Get the block height or block has of when the address was first used * @param address */ async getFirstUse(address) { return await this.execute('blockchain.address.get_first_use', address); } /** * Get a single transaction object * @param id * @param verbose */ async getTransaction(id, verbose = true) { return await this.execute('blockchain.transaction.get', id, verbose); } /** * Get a single unspent output including group data * @param outpoint */ async getUtxo(outpoint) { return await this.execute('blockchain.utxo.get', outpoint); } /** * Get Utxos only containing nexa information * @param address */ async getNexaUtxos(address) { return await this.execute('blockchain.address.listunspent', address, 'exclude_tokens'); } /** * Get all the utxo's for a token at an address * @param address * @param token */ async getTokenUtxos(address, token) { let listunspent = await this.execute('token.address.listunspent', address, null, token); return listunspent.unspent; } /** * Get the token balances for an address * @param address * @param token */ async getTokensBalance(address, token) { if (token) return await this.execute('token.address.get_balance', address, null, token); return await this.execute('token.address.get_balance', address); } /** * Get the token genesis for a token * @param token */ async getTokenGenesis(token) { return await this.execute('token.genesis.info', token); } /** * Subscribe to address call back notifications, handy for updating the user when they receive nexa or tokens in * their wallet * @param addresses * @param callback */ async subscribeToAddresses(addresses, callback) { for (const addr of addresses)await this.client?.subscribe(callback, 'blockchain.address.subscribe', addr); } /** * Unsubscribe from address notifications to prevent memory leaks * @param addresses * @param callback */ async unsubscribeFromAddresses(addresses, callback) { for (const addr of addresses)await this.client?.unsubscribe(callback, 'blockchain.address.subscribe', addr); } /** * Broadcast a presigned transaction hash * @param txHex */ async broadcast(txHex) { return await this.execute('blockchain.transaction.broadcast', txHex); } /** * Get the latency of the server connection */ async getLatency() { try { let start = Date.now(); let res = await this.getBlockTip(); if (res) return Date.now() - start; return 0; } catch { return 0; } } /** * Create initial connection with the rostrum server * @param netOrParams - Network identifier or RostrumParams object * @param params - RostrumParams object (for backward compatibility) * @param electrumClient - Optional pre-configured ElectrumClient instance */ async connect(netOrParams, params, electrumClient) { try { let connectionParams; // Handle backward compatibility: connect(params) or connect(network, params) if (netOrParams && typeof netOrParams === 'object' && 'host' in netOrParams && 'port' in netOrParams && 'scheme' in netOrParams) // First parameter is RostrumParams connectionParams = netOrParams; else if (params) // Second parameter contains RostrumParams, ignore network connectionParams = params; else { // Use network to determine default params const network = netOrParams ? (0, $633cp$Networks).get(netOrParams) : (0, $633cp$Networks).mainnet; if (network === (0, $633cp$Networks).mainnet) connectionParams = { host: 'electrum.nexa.org', port: 20004, scheme: (0, $a0b58ced4ea5a401$export$1f6f962b0b96558).WSS }; else if (network === (0, $633cp$Networks).testnet) connectionParams = { host: 'testnet-electrum.nexa.org', port: 30004, scheme: (0, $a0b58ced4ea5a401$export$1f6f962b0b96558).WSS }; else // Default fallback for other networks (like regtest) connectionParams = { host: 'localhost', port: 30004, scheme: (0, $a0b58ced4ea5a401$export$1f6f962b0b96558).WS }; } if (electrumClient) { this.client = electrumClient; if (this.client.connection.status == (0, $633cp$ConnectionStatus).DISCONNECTED) await this.client.connect(); } else { this.client = new (0, $633cp$ElectrumClient)("com.nexa.wallet-sdk", "1.4.3", connectionParams.host, connectionParams.port, connectionParams.scheme, 30000, 10000, true); await this.client.connect(); } } catch (e) { if (e instanceof Error) console.info(e.message); else console.error(e); throw e; } } /** * Disconnect from the rostrum server * @param force */ async disconnect(force) { try { return await this.client.disconnect(force); } catch (e) { console.log(e); return false; } } /** * internal function to call commands against the rostrum API * @param method * @param parameters * @private */ async execute(method, ...parameters) { let res = await this.client.request(method, ...parameters); if (res instanceof Error) throw res; return res; } } const $30c92dd8e96ca60d$export$eaa49f0478d81b9d = new $30c92dd8e96ca60d$export$ba81aefc89aef50c(); class $51649cc8d0caebe5$export$c54c8796e94a37a0 { get transactions() { return this._transactions; } constructor(_bip44Account){ this._tokenBalances = {}; this._tokenAuthorities = {}; this._transactions = new Map(); this._bip44Account = _bip44Account; this._balance = { confirmed: 0, unconfirmed: 0 }; this._tokenBalances = {}; this._tokenAuthorities = {}; } get balance() { return this._balance; } set balance(value) { this._balance = value; } get tokenBalances() { return this._tokenBalances; } set tokenBalances(value) { this._tokenBalances = value; } get tokenAuthorities() { return this._tokenAuthorities; } set tokenAuthorities(value) { this._tokenAuthorities = value; } async fetchAndClassifyTransactions(transactionAddress, fromHeight) { const transactions = await (0, $f10b40ff0fa7ccfb$export$a2ed4b531376a5a4)([ transactionAddress ], fromHeight ?? 0); const txPromises = Array.from(transactions.txs.values()).map((tx)=>(0, $f10b40ff0fa7ccfb$export$9c6f4f51acbc89b9)(tx, [ transactionAddress ])); const txEntities = await Promise.all(txPromises); for (let txEntity of txEntities)this.transactions.set(txEntity.txId, txEntity); return this.transactions; } } class $5ef3d149a7ae4b51$export$2e2bcd8739ae039 extends (0, $51649cc8d0caebe5$export$c54c8796e94a37a0) { constructor(bip44Account, accountIndex, addressKey){ super(bip44Account); this._accountIndex = accountIndex; this._accountKey = addressKey; } // this is used in AccountStore.ts to get the key to be used in the map for this account getAccountStoreKey() { return String(this._bip44Account + '.' + this._accountIndex); } getAccountType() { return (0, $f10b40ff0fa7ccfb$export$b8ca5fa4899cbfc7).DAPP_ACCOUNT; } getNewAddress() { return this._accountKey.address; } getNewChangeAddress() { return this.getNewAddress(); } get accountIndexes() { return { rIndex: this._accountIndex, cIndex: 0 }; } get accountKeys() { return { receiveKeys: [ this._accountKey ], changeKeys: [] // Empty for single-key accounts }; } async loadBalances() { const { balances: balances, authorities: authorities } = await (0, $f10b40ff0fa7ccfb$export$e4fb0bc90aacba9e)([ this._accountKey ]); let tokenBalances = [ this._accountKey ].map((k)=>k.tokensBalance); super.balance = (0, $f10b40ff0fa7ccfb$export$a26005fb5b8d1e4a)(balances); super.tokenBalances = (0, $f10b40ff0fa7ccfb$export$dec515296f176dbe)(tokenBalances); super.tokenAuthorities = authorities; } getKeyFromAddress(address) { if (address !== this._accountKey.address) throw new Error(`Address ${address} does not belong to this account`); return this._accountKey; } async getTransactions(fromHeight, address) { const transactionAddress = address ?? this._accountKey.address; return this.fetchAndClassifyTransactions(transactionAddress, fromHeight); } getAddresses() { return [ this._accountKey ]; } hasChangeAddresses() { return false; } getPrimaryAddressKey() { return this._accountKey; } } class $3213756e8a8eb72f$export$2e2bcd8739ae039 extends (0, $51649cc8d0caebe5$export$c54c8796e94a37a0) { constructor(bip44Account, accountIndexes, accountKeys){ super(bip44Account); if (accountIndexes.rIndex < 0) throw new Error(`Can not create nexa account with an rindex of ${accountIndexes.rIndex}. must be >= 0.`); if (accountIndexes.cIndex < 0) throw new Error(`Can not create nexa account with an cindex of ${accountIndexes.cIndex}. must be >= 0.`); this._accountIndexes = accountIndexes; this._accountKeys = accountKeys; } // this is used in AccountStore.ts to get the key to be used in the map for this account getAccountStoreKey() { return String(this._bip44Account); } getAccountType() { return (0, $f10b40ff0fa7ccfb$export$b8ca5fa4899cbfc7).NEXA_ACCOUNT; } getNewAddress() { return this._accountKeys.receiveKeys[this._accountKeys.receiveKeys.length - 1]?.address ?? ''; } getNewChangeAddress() { return this._accountKeys.changeKeys[this._accountKeys.changeKeys.length - 1]?.address ?? ''; } get accountIndexes() { return this._accountIndexes; } get accountKeys() { return this._accountKeys; } async loadBalances() { const { balances: balances, authorities: authorities } = await (0, $f10b40ff0fa7ccfb$export$e4fb0bc90aacba9e)(this._accountKeys.receiveKeys.concat(this._accountKeys.changeKeys)); let tokenBalances = this._accountKeys.receiveKeys.concat(this._accountKeys.changeKeys).map((k)=>k.tokensBalance); super.balance = (0, $f10b40ff0fa7ccfb$export$a26005fb5b8d1e4a)(balances); super.tokenBalances = (0, $f10b40ff0fa7ccfb$export$dec515296f176dbe)(tokenBalances); super.tokenAuthorities = authorities; } getKeyFromAddress(address) { const allKeys = this._accountKeys.receiveKeys.concat(this._accountKeys.changeKeys); const keyFound = allKeys.find((key)=>key.address === address); return keyFound; } async getTransactions(fromHeight, address) { let receiveAddresses = this.accountKeys.receiveKeys.map((ak)=>ak.address); let changeAddresses = this.accountKeys.changeKeys.map((ak)=>ak.address); let allAddresses = receiveAddresses.concat(changeAddresses); // If specific address provided, only fetch for that address if (address != null) { const transactions = await (0, $f10b40ff0fa7ccfb$export$a2ed4b531376a5a4)([ address ], fromHeight ?? 0); const txPromises = Array.from(transactions.txs.values()).map((tx)=>(0, $f10b40ff0fa7ccfb$export$9c6f4f51acbc89b9)(tx, allAddresses)); const txEntities = await Promise.all(txPromises); for (let txEntity of txEntities)this.transactions.set(txEntity.txId, txEntity); return this.transactions; } // Fetch from both receive and change addresses let rTxs = (0, $f10b40ff0fa7ccfb$export$a2ed4b531376a5a4)(receiveAddresses, fromHeight ?? 0); let cTxs = (0, $f10b40ff0fa7ccfb$export$a2ed4b531376a5a4)(changeAddresses, fromHeight ?? 0); let [rData, cData] = await Promise.all([ rTxs, cTxs ]); // Combine transaction data, avoiding duplicates let txHistory = rData.txs; for (let tx of cData.txs.values())txHistory.set(tx.tx_hash, tx); // Classify all transactions in parallel const txPromises = Array.from(txHistory.values()).map((tx)=>(0, $f10b40ff0fa7ccfb$export$9c6f4f51acbc89b9)(tx, allAddresses)); const txEntities = await Promise.all(txPromises); for (let txEntity of txEntities)this.transactions.set(txEntity.txId, txEntity); return this.transactions; } getAddresses() { return this._accountKeys.receiveKeys.concat(this._accountKeys.changeKeys); } hasChangeAddresses() { return true; // BIP44 accounts always support change addresses } getPrimaryAddressKey() { // For DefaultAccount, return the first receive key as the primary key if (this._accountKeys.receiveKeys.length === 0) throw new Error("No receive keys available in account"); return this._accountKeys.receiveKeys[0]; } } class $fcf0a0849682f4b5$export$2e2bcd8739ae039 extends (0, $51649cc8d0caebe5$export$c54c8796e94a37a0) { constructor(bip44Account, accountIndex, addressKey){ super(bip44Account); this._accountIndex = accountIndex; this._accountKey = addressKey; } // this is used in AccountStore.ts to get the key to be used in the map for this account getAccountStoreKey() { return String(this._bip44Account + '.' + this._accountIndex); } getAccountType() { return (0, $f10b40ff0fa7ccfb$export$b8ca5fa4899cbfc7).VAULT_ACCOUNT; } getNewAddress() { return this._accountKey.address; } getNewChangeAddress() { return this.getNewAddress(); } get accountIndexes() { return { rIndex: this._accountIndex, cIndex: 0 }; } get accountKeys() { return { receiveKeys: [ this._accountKey ], changeKeys: [] // Empty for single-key accounts }; } async loadBalances() { const { balances: balances, authorities: authorities } = await (0, $f10b40ff0fa7ccfb$export$e4fb0bc90aacba9e)([ this._accountKey ]); let tokenBalances = [ this._accountKey ].map((k)=>k.tokensBalance); super.balance = (0, $f10b40ff0fa7ccfb$export$a26005fb5b8d1e4a)(balances); super.tokenBalances = (0, $f10b40ff0fa7ccfb$export$dec515296f176dbe)(tokenBalances); super.tokenAuthorities = authorities; } getKeyFromAddress(address) { if (address !== this._accountKey.address) throw new Error(`Address ${address} does not belong to this account`); return this._accountKey; } async getTransactions(fromHeight, address) { const transactionAddress = address ?? this._accountKey.address; return this.fetchAndClassifyTransactions(transactionAddress, fromHeight); } getAddresses() { return [ this._accountKey ]; } hasChangeAddresses() { return false; } getPrimaryAddressKey() { return this._accountKey; } } const $424cf91992355440$export$8ba128bc85947a2a = 9223372036854775807n; function $424cf91992355440$export$78d0476e8d098ba7() { return Math.floor(Date.now() / 1000); } function $424cf91992355440$export$c8733ae29fb53302(arg) { return !arg || arg.length === 0; } function $424cf91992355440$export$78e516cc94be797b(amount, decimals) { let val = new (0, $633cp$jsbigdecimal)(amount).divide(new (0, $633cp$jsbigdecimal)(Math.pow(10, decimals)), decimals).getPrettyValue(); if (val.match(/\./)) val = val.replace(/\.?0+$/, ''); return val; } function $424cf91992355440$export$9ad78026dec58d6(amount, decimals) { return new (0, $633cp$jsbigdecimal)(amount).multiply(new (0, $633cp$jsbigdecimal)(Math.pow(10, decimals))).getValue(); } function $424cf91992355440$export$23010fd5dda8dec1(address) { if ((0, $633cp$CommonUtils).isHexa(address)) return Buffer.from(address, 'hex'); return (0, $633cp$Address).fromString(address).data; } function $424cf91992355440$export$254a5c7330bbfd41(token) { if ((0, $633cp$CommonUtils).isHexa(token)) return token; return $424cf91992355440$export$23010fd5dda8dec1(token).toString('hex'); } function $424cf91992355440$export$f12d707d2b261fb6(txIdem, outputIndex) { const writer = new (0, $633cp$BufferWriter)(undefined); const outpoint = writer.write(Buffer.from(txIdem, 'hex').reverse()).writeUInt32LE(outputIndex).toBuffer(); return (0, $633cp$Hash).sha256(outpoint).reverse().toString('hex'); } function $3091f185ded8655f$export$7f7cffd29bf2d96d(authFlags, permission) { if (authFlags > 0) return false; let flags = BigInt.asUintN(64, BigInt(authFlags)); switch(permission){ case 'authorise': return (0, $633cp$GroupToken).allowsRenew(flags); case 'mint': return (0, $633cp$GroupToken).allowsMint(flags); case 'melt': return (0, $633cp$GroupToken).allowsMelt(flags); case 'rescript': return (0, $633cp$GroupToken).allowsRescript(flags); case 'subgroup': return (0, $633cp$GroupToken).allowsSubgroup(flags); default: return false; } } function $3091f185ded8655f$export$636fb0b03b94ac81(authFlags, withSubgroup = true) { if (authFlags > 0) return 0n; let flags = BigInt.asUintN(64, BigInt(authFlags)); let newFlags = (0, $633cp$GroupToken).authFlags.AUTHORITY; if ((0, $633cp$GroupToken).allowsRenew(flags)) newFlags |= (0, $633cp$GroupToken).authFlags.BATON; if ((0, $633cp$GroupToken).allowsMint(flags)) newFlags |= (0, $633cp$GroupToken).authFlags.MINT; if ((0, $633cp$GroupToken).allowsMelt(flags)) newFlags |= (0, $633cp$GroupToken).authFlags.MELT; if ((0, $633cp$GroupToken).allowsRescript(flags)) newFlags |= (0, $633cp$GroupToken).authFlags.RESCRIPT; if ((0, $633cp$GroupToken).allowsSubgroup(flags) && withSubgroup) newFlags |= (0, $633cp$GroupToken).authFlags.SUBGROUP; return newFlags; } function $3091f185ded8655f$export$e240c810a53c3a0c(perms) { let newFlags = (0, $633cp$GroupToken).authFlags.AUTHORITY; for (let perm of perms)switch(perm){ case 'authorise': newFlags |= (0, $633cp$GroupToken).authFlags.BATON; break; case 'mint': newFlags |= (0, $633cp$GroupToken).authFlags.MINT; break; case 'melt': newFlags |= (0, $633cp$GroupToken).authFlags.MELT; break; case 'rescript': newFlags |= (0, $633cp$GroupToken).authFlags.RESCRIPT; break; case 'subgroup': newFlags |= (0, $633cp$GroupToken).authFlags.SUBGROUP; break; } return newFlags; } function $3091f185ded8655f$export$c949c84578b9e236(authFlags) { if (authFlags > 0) return []; const permissions = []; const flags = BigInt.asUintN(64, BigInt(authFlags)); if ((0, $633cp$GroupToken).allowsRenew(flags)) permissions.push('authorise'); if ((0, $633cp$GroupToken).allowsMint(flags)) permissions.push('mint'); if ((0, $633cp$GroupToken).allowsMelt(flags)) permissions.push('melt'); if ((0, $633cp$GroupToken).allowsRescript(flags)) permissions.push('rescript'); if ((0, $633cp$GroupToken).allowsSubgroup(flags)) permissions.push('subgroup'); return permissions; } var $f10b40ff0fa7ccfb$export$dcc1fb6ad5308e56 = /*#__PURE__*/ function(TxTokenType) { TxTokenType[TxTokenType["NO_GROUP"] = 0] = "NO_GROUP"; TxTokenType[TxTokenType["CREATE"] = 1] = "CREATE"; TxTokenType[TxTokenType["MINT"] = 2] = "MINT"; TxTokenType[TxTokenType["MELT"] = 3] = "MELT"; TxTokenType[TxTokenType["RENEW"] = 4] = "RENEW"; TxTokenType[TxTokenType["TRANSFER"] = 5] = "TRANSFER"; return TxTokenType; }({}); var $f10b40ff0fa7ccfb$export$b8ca5fa4899cbfc7 = /*#__PURE__*/ function(AccountType) { AccountType[AccountType["NEXA_ACCOUNT"] = 0] = "NEXA_ACCOUNT"; AccountType[AccountType["VAULT_ACCOUNT"] = 1] = "VAULT_ACCOUNT"; AccountType[AccountType["DAPP_ACCOUNT"] = 2] = "DAPP_ACCOUNT"; return AccountType; }({}); function $f10b40ff0fa7ccfb$export$8d986bd2866fe6ab(address, network, type = (0, $633cp$AddressType).PayToScriptTemplate) { return (0, $633cp$Address).isValid(address, network, type); } function $f10b40ff0fa7ccfb$export$11f4ae2b4ff9633d(mnemonic, passphrase) { const seed = $633cp$mnemonicToSeedSync(mnemonic, passphrase); const masterKey = (0, $633cp$HDPrivateKey).fromSeed(seed); return masterKey.deriveChild(44, true).deriveChild(29223, true); } function $f10b40ff0fa7ccfb$export$b3a12d67e2f5f8c9(masterKey, account) { return masterKey.deriveChild(account, true); } function $f10b40ff0fa7ccfb$export$d6e8eb22902c6b88(accountKey, fromRIndex, rIndex, fromCIndex, cIndex) { if (fromRIndex < 0) throw new Error(`Can not generate keys with fromRIndex ${fromRIndex}. must be >= 0.`); if (fromCIndex < 0) throw new Error(`Can not generate keys with fromCIndex ${fromCIndex}. must be >= 0.`); let receive = accountKey.deriveChild(0, false); let change = accountKey.deriveChild(1, false); let rKeys = [], cKeys = []; for(let index = fromRIndex; index < rIndex; index++){ let k = receive.deriveChild(index, false); let addr = k.privateKey.toAddress().toString(); rKeys.push({ key: k, address: addr, balance: "0", tokensBalance: {} }); } for(let index = fromCIndex; index < cIndex; index++){ let k = change.deriveChild(index, false); let addr = k.privateKey.toAddress().toString(); cKeys.push({ key: k, address: addr, balance: "0", tokensBalance: {} }); } return { receiveKeys: rKeys, changeKeys: cKeys }; } function $f10b40ff0fa7ccfb$export$1e0ce394ebe84ca9(accountKey, rIndex) { let receive = accountKey.deriveChild(0, false); let k = receive.deriveChild(rIndex, false); let addr = k.privateKey.toAddress().toString(); return { key: k, address: addr, balance: "0", tokensBalance: {} }; } async function $f10b40ff0fa7ccfb$var$discoverUsedAccountIndexes(deriveKey) { let lastUsed = -1, index = 0, toScan = 20; while(toScan > 0){ toScan--; let rAddr = deriveKey.deriveChild(index, false).privateKey.toAddress().toString(); let isUsed = await $f10b40ff0fa7ccfb$var$isAddressUsed(rAddr); if (isUsed) { lastUsed = index; toScan = 20; } index++; } // return the last used index, returns -1 if no indexes are used return lastUsed; } async function $f10b40ff0fa7ccfb$export$4aeb2c92e53ab137(accountKey) { let receiveKey = accountKey.deriveChild(0, false); let changeKey = accountKey.deriveChild(1, false); let rIndexPromise = $f10b40ff0fa7ccfb$var$discoverUsedAccountIndexes(receiveKey); let cIndexPromise = $f10b40ff0fa7ccfb$var$discoverUsedAccountIndexes(changeKey); let [rIndex, cIndex] = await Promise.all([ rIndexPromise, cIndexPromise ]); // get the index that is the last used nexa addr let indexes = { rIndex: rIndex, cIndex: cIndex }; return indexes; } async function $f10b40ff0fa7ccfb$export$f421913908d4303e(masterKey) { let accounts = []; let index = 0; while(true){ const nexaAccountKey = $f10b40ff0fa7ccfb$export$b3a12d67e2f5f8c9(masterKey, index); const indexes = await $f10b40ff0fa7ccfb$export$4aeb2c92e53ab137(nexaAccountKey); if (indexes.rIndex < 0 && indexes.cIndex < 0) break; if (indexes.rIndex < 0) indexes.rIndex = 0; if (indexes.cIndex < 0) indexes.cIndex = 0; // make account after break check, otherwise we might push an empty account const nexaAccount = new (0, $3213756e8a8eb72f$export$2e2bcd8739ae039)(index, indexes, $f10b40ff0fa7ccfb$export$d6e8eb22902c6b88(nexaAccountKey, indexes.rIndex + 1, indexes.rIndex + 20, indexes.cIndex + 1, indexes.cIndex + 20)); await nexaAccount.loadBalances(); accounts.push(nexaAccount); if (index == 0) index = 100; else index++; } if (accounts.length == 0) { // default account was unused but we need to populate at least one account, // make the default account here let defaultNexaAccountKey = $f10b40ff0fa7ccfb$export$b3a12d67e2f5f8c9(masterKey, 0); // get the last used indexes, -1 means unused let defaultIndexes = { rIndex: 0, cIndex: 0 }; const defaultAccount = new (0, $3213756e8a8eb72f$export$2e2bcd8739ae039)(0, defaultIndexes, $f10b40ff0fa7ccfb$export$d6e8eb22902c6b88(defaultNexaAccountKey, defaultIndexes.rIndex, defaultIndexes.rIndex + 20, defaultIndexes.cIndex, defaultIndexes.cIndex + 20)); await defaultAccount.loadBalances(); accounts.push(defaultAccount); } return accounts; } async function $f10b40ff0fa7ccfb$var$findUsedVaultAccounts(masterKey) { // all vaults are in bip44 account 1 let vaultAccountKey = $f10b40ff0fa7ccfb$export$b3a12d67e2f5f8c9(masterKey, 1); // all vaults are in the external chain let vaultChain = vaultAccountKey.deriveChild(0, false); // get the index that is the last used vault return await $f10b40ff0fa7ccfb$var$discoverUsedAccountIndexes(vaultChain); } async function $f10b40ff0fa7ccfb$export$eb24265dd203eccb(masterKey) { let accounts = []; // all vaults are in bip44 account 1 let vaultAccountKey = $f10b40ff0fa7ccfb$export$b3a12d67e2f5f8c9(masterKey, 1); // find the next unused vault let lastUsedVaultIndex = await $f10b40ff0fa7ccfb$var$findUsedVaultAccounts(masterKey); // if all vaults unused, generate at least the first vault account if (lastUsedVaultIndex < 0) lastUsedVaultIndex = 0; // for each vault found, make the DefaultAccount for that vault for(let index = 0; index <= lastUsedVaultIndex; index++){ const vaultAccount = new (0, $fcf0a0849682f4b5$export$2e2bcd8739ae039)(1, index, $f10b40ff0fa7ccfb$export$1e0ce394ebe84ca9(vaultAccountKey, index)); await vaultAccount.loadBalances(); accounts.push(vaultAccount); } return accounts; } async function $f10b40ff0fa7ccfb$var$findUsedDappAccounts(masterKey) { // all dApp accounts are in bip44 account 2 let dappAccountKey = $f10b40ff0fa7ccfb$export$b3a12d67e2f5f8c9(masterKey, 2); // all dApp accounts use the external chain let dappChain = dappAccountKey.deriveChild(0, false); // get the index that is the next unused dApp account return await $f10b40ff0fa7ccfb$var$discoverUsedAccountIndexes(dappChain); } async function $f10b40ff0fa7ccfb$export$e3d879d0e09f52c3(masterKey) { let accounts = []; // all dApp accounts are in bip44 account 2 let dappAccountKey = $f10b40ff0fa7ccfb$export$b3a12d67e2f5f8c9(masterKey, 2); // find the next unused dapp account let lastUsedDappIndex = await $f10b40ff0fa7ccfb$var$findUsedDappAccounts(masterKey); // if all dapp accounts unused, generate at least the first dapp account if (lastUsedDappIndex < 0) lastUsedDappIndex = 0; // for each dApp account found, make the DefaultAccount for that dApp account // for each vault found, make the DefaultAccount for that vault for(let index = 0; index <= lastUsedDappIndex; index++){ const dappAccount = new (0, $5ef3d149a7ae4b51$export$2e2bcd8739ae039)(2, index, $f10b40ff0fa7ccfb$export$1e0ce394ebe84ca9(dappAccountKey, index)); await dappAccount.loadBalances(); accounts.push(dappAccount); } return accounts; } async function $f10b40ff0fa7ccfb$export$4e4f91181d6bd31c(masterKey) { let accounts = []; // accounts 0, 100+ const nexaAccounts = await $f10b40ff0fa7ccfb$export$f421913908d4303e(masterKey); // vaults in bip44 account 1 const vaultAccounts = await $f10b40ff0fa7ccfb$export$eb24265dd203eccb(masterKey); // dApp accounts in bip44 account 2 const dappAccounts = await $f10b40ff0fa7ccfb$export$e3d879d0e09f52c3(masterKey); // 3 - 99 are reserved and will go here when added accounts = accounts.concat(nexaAccounts); accounts = accounts.concat(vaultAccounts); accounts = accounts.concat(dappAccounts); return accounts; } async function $f10b40ff0fa7ccfb$var$isAddressUsed(address) { try { let firstUse = await (0, $30c92dd8e96ca60d$export$eaa49f0478d81b9d).getFirstUse(address); return firstUse.tx_hash && firstUse.tx_hash !== ""; } catch (e) { if (e instanceof Error && e.message.includes("not found")) return false; throw e; } } async function $f10b40ff0fa7ccfb$var$getKeyTokenBalanceAndAuthorities(address) { const tokensBalance = await (0, $30c92dd8e96ca60d$export$eaa49f0478d81b9d).getTokensBalance(address); const balance = {}; const authorities = {}; // Get all unique token IDs from both confirmed and unconfirmed const allTokenIds = new Set([ ...Object.keys(tokensBalance.confirmed), ...Object.keys(tokensBalance.unconfirmed) ]); // Process each token to get both balance and check for authorities for (const tokenId of allTokenIds){ const confirmedAmount = tokensBalance.confirmed[tokenId] || 0; const unconfirmedAmount = tokensBalance.unconfirmed[tokenId] || 0; // Add to balance if non-zero if (confirmedAmount !== 0 || unconfirmedAmount !== 0) balance[tokenId] = { confirmed: BigInt(confirmedAmount).toString(), unconfirmed: BigInt(unconfirmedAmount).toString() }; // Check for authorities by getting token UTXOs try { const tokenUtxos = await (0, $30c92dd8e96ca60d$export$eaa49f0478d81b9d).getTokenUtxos(address, tokenId); if (tokenUtxos && tokenUtxos.length > 0) { // Look for authorities (negative amounts) const authUtxos = tokenUtxos.filter((utxo)=>{ const amount = parseInt(String(utxo.token_amount || '0')); return amount < 0; }); // Add permissions and address to each authority UTXO and organize by token ID if (authUtxos.length > 0) { const authoritiesWithPermissions = authUtxos.map((utxo)=>({ ...utxo, permissions: (0, $3091f185ded8655f$export$c949c84578b9e236)(parseInt(String(utxo.token_amount || '0'))), address: address })); authorities[tokenId] = authoritiesWithPermissions; } } } catch (error) { console.warn(`Error checking authorities for token ${tokenId} on address ${address}:`, error); } } return { balance: balance, authorities: authorities }; } async function $f10b40ff0fa7ccfb$var$getAndUpdateAddressKeyBalance(key) { let balance = await (0, $30c92dd8e96ca60d$export$eaa49f0478d81b9d).getBalance(key.address); key.balance = (BigInt(balance.confirmed) + BigInt(balance.unconfirmed)).toString(); const { balance: tokenBalance, authorities: authorities } = await $f10b40ff0fa7ccfb$var$getKeyTokenBalanceAndAuthorities(key.address); key.tokensBalance = tokenBalance; return { balance: balance, authorities: authorities }; } async function $f10b40ff0fa7ccfb$export$e4fb0bc90aacba9e(keys) { let promises = []; keys.forEach((key)=>{ promises.push($f10b40ff0fa7ccfb$var$getAndUpdateAddressKeyBalance(key)); }); const results = await Promise.all(promises); const balances = results.map((r)=>r.balance); // Combine authorities from all addresses, merging by token ID const combinedAuthorities = {}; results.forEach((result)=>{ Object.keys(result.authorities).forEach((tokenId)=>{ if (combinedAuthorities[tokenId]) combinedAuthorities[tokenId] = combinedAuthorities[tokenId].concat(result.authorities[tokenId]); else combinedAuthorities[tokenId] = result.authorities[tokenId]; }); }); return { balances: balances, authorities: combinedAuthorities }; } function $f10b40ff0fa7ccfb$export$a26005fb5b8d1e4a(balances) { let confirmed = new (0, $633cp$jsbigdecimal)(0), unconfirmed = new (0, $633cp$jsbigdecimal)(0); balances.forEach((b)=>{ confirmed = confirmed.add(new (0, $633cp$jsbigdecimal)(b.confirmed)); unconfirmed = unconfirmed.add(new (0, $633cp$jsbigdecimal)(b.unconfirmed)); }); return { confirmed: confirmed.getValue(), unconfirmed: unconfirmed.getValue() }; } function $f10b40ff0fa7ccfb$export$dec515296f176dbe(balances) { let tokensBalance = {}; balances.forEach((b)=>{ for(const key in b)if (tokensBalance[key]) { tokensBalance[key].confirmed = (BigInt(tokensBalance[key].confirmed) + BigInt(b[key].confirmed)).toString(); tokensBalance[key].unconfirmed = (BigInt(tokensBalance[key].unconfirmed) + BigInt(b[key].unconfirmed)).toString(); } else tokensBalance[key] = { confirmed: b[key].confirmed, unconfirmed: b[key].unconfirmed }; }); return tokensBalance; } async function $f10b40ff0fa7ccfb$export$a2ed4b531376a5a4(addresses, fromHeight) { let index = 0, i = 0, data = new Map(), maxHeight = fromHeight; for (let address of addresses){ i++; let txHistory = await (0, $30c92dd8e96ca60d$export$eaa49f0478d81b9d).getTransactionHistory(address); if (txHistory && txHistory.length > 0) { index = i; for (let tx of txHistory)if (tx.height === 0 || tx.height > fromHeight) { maxHeight = Math.max(maxHeight, tx.height); data.set(tx.tx_hash, tx); } } } return { index: index, txs: data, lastHeight: maxHeight }; } async function $f10b40ff0fa7ccfb$var$rescanAddressesHistory(addresses) { let index = 0, i = 0, minHeight = Number.MAX_SAFE_INTEGER; for (let address of addresses){ i++; let txHistory = await (0, $30c92dd8e96ca60d$export$eaa49f0478d81b9d).getTransactionHistory(address); if (!(0, $633cp$isNil)(txHistory)) { index = i; let heights = txHistory.filter((tx)=>tx.height > 0).map((h)=>h.height); if (!(0, $633cp$isNil)(heights)) minHeight = Math.min(minHeight, ...heights); } } return { index: index > 0 ? index + 1 : 0, height: minHeight == Number.MAX_SAFE_INTEGER ? 0 : minHeight }; } async function $f10b40ff0fa7ccfb$export$ef13479e8d3251d7(accountType, masterKey) { if (accountType == 0) { let defaultNexaAccountKey = $f10b40ff0fa7ccfb$export$b3a12d67e2f5f8c9(masterKey, 0); const defaultIndexes = await $f10b40ff0fa7ccfb$export$4aeb2c92e53ab137(defaultNexaAccountKey); if (defaultIndexes.rIndex < 0 && defaultIndexes.cIndex < 0) return 0; else // account 0 was not empty for(let index = 100;; index++){ const nexaAccountKey = $f10b40ff0fa7ccfb$export$b3a12d67e2f5f8c9(masterKey, index); const indexes = await $f10b40ff0fa7ccfb$export$4aeb2c92e53ab137(nexaAccountKey); if (indexes.rIndex < 0 && indexes.cIndex < 0) return index; } } else if (accountType == 1) { // find the next unused vault const lastUsedVault = await $f10b40ff0fa7ccfb$var$findUsedVaultAccounts(masterKey); return lastUsedVault + 1; } else if (accountType == 2) { // find the next unused dapp account const lastUsedDappAccount = await $f10b40ff0fa7ccfb$var$findUsedDappAccounts(masterKey); return lastUsedDappAccount + 1; } else throw new Error("Can not get next account index. Invalid accountType."); } async function $f10b40ff0fa7ccfb$export$9c6f4f51acbc89b9(txHistory, myAddresses) { let t = await (0, $30c92dd8e96ca60d$export$eaa49f0478d81b9d).getTransaction(txHistory.tx_hash); let outputs = t.vout.filter((utxo)=>!(0, $633cp$isNil)(utxo.scriptPubKey.addresses)); let isOutgoing = t.vin.length > 0 && myAddresses.includes(t.vin[0].addresses[0]); let isIncoming = !isOutgoing || outputs.every((utxo)=>myAddresses.includes(utxo.scriptPubKey.addresses[0])); let isConfirmed = t.height > 0; let txEntry = {}; txEntry.txId = t.txid; txEntry.txIdem = t.txidem; txEntry.height = isConfirmed ? t.height : 0; txEntry.time = isConfirmed ? t.time : (0, $424cf91992355440$export$78d0476e8d098ba7)(); txEntry.fee = t.fee_satoshi; if (isOutgoing && isIncoming) { txEntry.state = 'both'; txEntry.value = "0"; txEntry.payTo = "Payment to yourself"; } else if (isIncoming) { txEntry.state = 'incoming'; let utxos = outputs.filter((utxo)=>myAddresses.includes(utxo.scriptPubKey.addresses[0])); let amount = new (0, $633cp$jsbigdecimal)(0); utxos.forEach((utxo)=>{ amount = amount.add(new (0, $633cp$jsbigdecimal)(utxo.value_satoshi)); }); txEntry.value = amount.getValue(); txEntry.payTo = utxos[0].scriptPubKey.addresses[0]; } else if (isOutgoing) { txEntry.state = 'outgoing'; let utxos = outputs.filter((utxo)=>!myAddresses.includes(utxo.scriptPubKey.addresses[0])); let amount = new (0, $633cp$jsbigdecimal)(0); utxos.forEach((utxo)=>{ amount = amount.add(new (0, $633cp$jsbigdecimal)(utxo.value_satoshi)); }); txEntry.value = amount.getValue(); txEntry.payTo = utxos[0].scriptPubKey.addresses[0]; } let [txType, txGroup, tokenAmount, extraGroup] = $f10b40ff0fa7ccfb$var$classifyTokenTransaction(t.vin, outputs, txEntry.state, myAddresses); txEntry.txGroupType = txType; txEntry.token = txGroup; txEntry.tokenAmount = tokenAmount; txEntry.extraGroup = extraGroup; return txEntry; } function $f10b40ff0fa7ccfb$var$classifyTokenTransaction(vin, vout, txState, myAddresses) { let groupInputs = vin.filter((input)=>!(0, $424cf91992355440$export$c8733ae29fb53302)(input.group)); let groupOutputs = vout.filter((output)=>!(0, $424cf91992355440$export$c8733ae29fb53302)(output.scriptPubKey.group)); if ((0, $424cf91992355440$export$c8733ae29fb53302)(groupInputs) && (0, $424cf91992355440$export$c8733ae29fb53302)(groupOutputs)) return [ 0, "none", "0", "none" ]; let myGroupInputs = groupInputs.filter((input)=>myAddresses.includes(input.addresses[0])); let myGroupOutputs = groupOutputs.filter((output)=>myAddresses.includes(output.scriptPubKey.addresses[0])); if ((0, $424cf91992355440$export$c8733ae29fb53302)(myGroupInputs) && (0, $424cf91992355440$export$c8733ae29fb53302)(myGroupOutputs)) return [ 0, "none", "0", "none" ]; if ((0, $424cf91992355440$export$c8733ae29fb53302)(groupInputs)) { let group = myGroupOutputs.find((output)=>BigInt(output.scriptPubKey.groupQuantity) < 0n)?.scriptPubKey.group ?? "none"; return [ 1, group, "0", "none" ]; } if ((0, $424cf91992355440$export$c8733ae29fb53302)(groupOutputs)) { if (txState === 'incoming') return [ 0, "none", "0", "none" ]; let inputs = myGroupInputs.filter((input)=>BigInt(input.groupQuantity) > 0n); if (!(0, $424cf91992355440$export$c8733ae29fb53302)(inputs)) { let amount = new (0, $633cp$jsbigdecimal)(0); inputs.forEach((utxo)=>{ amount = amount.add(new (0, $633cp$jsbigdecimal)(utxo.groupQuantity)); }); let group = inputs[0].group; let extraGroup = myGroupInputs.find((input)=>BigInt(input.groupQuantity) < 0n && inputs[0].group != input.group)?.group ?? "none"; return [ 3, group, amount.getValue(), extraGroup ]; } let group = myGroupInputs.find((input)=>BigInt(input.groupQuantity) < 0n)?.group ?? "none"; let extraGroup = myGroupInputs.find((input)=>BigInt(input.groupQuantity) < 0n && group != input.group)?.group ?? "none"; return [ 3, group, "0", extraGroup ]; } let tokenInputs = groupInputs.filter((input)=>BigInt(input.groupQuantity) > 0n); let tokenOutputs = groupOutputs.filter((output)=>BigInt(output.scriptPubKey.groupQuantity) > 0n); if ((0, $424cf91992355440$export$c8733ae29fb53302)(tokenInputs) && (0, $424cf91992355440$export$c8733ae29fb53302)(tokenOutputs)) { let group = groupInputs.find((input)=>BigInt(input.groupQuantity) < 0n)?.group ?? "none"; let extraGroup = groupOutputs.find((output)=>BigInt(output.scriptPubKey.groupQuantity) < 0n && group != output.scriptPubKey.group)?.scriptPubKey.group ?? "none"; return [ 4, extraGroup !== 'none' ? extraGroup : group, "0", extraGroup !== 'none' ? group : extraGroup ]; } if ((0, $424cf91992355440$export$c8733ae29fb53302)(tokenInputs)) { let group = tokenOutputs[0].scriptPubKey.group; let amount = new (0, $633cp$jsbigdecimal)(0); tokenOutputs.forEach((utxo)=>{ amount = amount.add(new (0, $633cp$jsbigdecimal)(utxo.scriptPubKey.groupQuantity)); }); let extraGroup = groupInputs.find((input)=>BigInt(input.groupQuantity) < 0n && group != input.group)?.group ?? "none"; return [ 2, group, amount.getValue(), extraGroup ]; } if ((0, $424cf91992355440$export$c8733ae29fb53302)(tokenOutputs)) { let group = tokenInputs[0].group; let amount = new (0, $633cp$jsbigdecimal)(0); tokenInputs.forEach((utxo)=>{ amount = amount.add(new (0, $633cp$jsbigdecimal)(utxo.groupQuantity)); }); let extraGroup = groupInputs.find((input)=>BigInt(input.groupQuantity) < 0n && group != input.group)?.group ?? "none"; return [ 3, group, amount.getValue(), extraGroup ]; } let outQuantitySum = tokenOutputs.map((output)=>BigInt(output.scriptPubKey.groupQuantity)).reduce((a, b)=>a + b, 0n); let inQuantitySum = tokenInputs.map((input)=>BigInt(input.groupQuantity)).reduce((a, b)=>a + b, 0n); if (outQuantitySum > inQuantitySum) { let group = tokenOutputs[0].scriptPubKey.group; let extraGroup = groupInputs.find((input)=>BigInt(input.groupQuantity) < 0n && group != input.group)?.group ?? "none"; return [ 2, group, (outQuantitySum - inQuantitySum).toString(), extraGroup ]; } if (inQuantitySum > outQuantitySum) { let group = tokenInputs[0].group; let extraGroup = groupInputs.find((input)=>BigInt(input.groupQuantity) < 0n && group != input.group)?.group ?? "none"; return [ 3, group, (inQuantitySum - outQuantitySum).toString(), extraGroup ]; } let group = tokenOutputs[0].scriptPubKey.group; let amount = ""; if (txState === 'incoming') amount = tokenOutputs.filter((output)=>myAddresses.includes(output.scriptPubKey.addresses[0])).map((output)=>BigInt(output.scriptPubKey.groupQuantity)).reduce((a, b)=>a + b, 0n).toString(); else if (txState === 'outgoing') amount = tokenOutputs.filter((out