UNPKG

atomicals-js

Version:
943 lines (942 loc) 125 kB
#!/usr/bin/env node "use strict"; 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 __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 }); const commander_1 = require("commander"); const dotenv = __importStar(require("dotenv")); const qrcode = __importStar(require("qrcode-terminal")); const _1 = require("."); const electrum_api_1 = require("./api/electrum-api"); const command_interface_1 = require("./commands/command.interface"); const address_helpers_1 = require("./utils/address-helpers"); const atomical_format_helpers_1 = require("./utils/atomical-format-helpers"); const file_utils_1 = require("./utils/file-utils"); const validate_cli_inputs_1 = require("./utils/validate-cli-inputs"); const validate_wallet_storage_1 = require("./utils/validate-wallet-storage"); dotenv.config(); ///////////////////////////////////////////////////////////////////////////////////////////// // General Helper Functions ///////////////////////////////////////////////////////////////////////////////////////////// function printSuccess(data) { console.log(JSON.stringify(data, null, 2)); } function printFailure(data) { console.log(JSON.stringify(data, null, 2)); } function handleResultLogging(result) { if (!result || !result.success || !result.data) { printFailure(result); process.exit(1); } else { printSuccess(result.data); } } function getRandomBitwork4() { const r = Math.floor(1000 + Math.random() * 9000); return r + ''; } function getRandomBitwork(num) { const r = Math.floor(Math.pow(10, num - 1) + Math.random() * 9 * Math.pow(10, num - 1)); return r + ''; } function groupAtomicalsUtxosByAtomicalId(atomical_utxos) { const sorted = {}; // console.log('atomical_utxos', JSON.stringify(atomical_utxos, null, 2)); for (const utxo of atomical_utxos) { for (const atomicalId of utxo['atomicals']) { sorted[atomicalId] = sorted[atomicalId] || []; sorted[atomicalId].push(Object.assign(Object.assign({}, utxo), { atomicals: undefined })); } } return sorted; } function showWalletFTBalancesDetails(obj, showutxos = false, accumulated) { const atomicalsUtxosByAtomicalId = groupAtomicalsUtxosByAtomicalId(obj.atomicals_utxos); for (const atomicalId in obj.atomicals_balances) { if (!obj.atomicals_balances.hasOwnProperty(atomicalId)) { continue; } const atomical = obj.atomicals_balances[atomicalId]; if (atomical['type'] !== 'FT') { continue; } console.log('-----'); console.log('Atomical id:', atomicalId); console.log('Atomical number:', atomical['atomical_number']); console.log('Atomical type:', atomical['type']); console.log('Atomical subtype:', atomical['subtype']); console.log('Requested ticker:', atomical['request_ticker']); console.log('Requested ticker status:', atomical['request_ticker_status']['status']); console.log('Ticker:', atomical['ticker']); console.log('Confirmed balance:', atomical['confirmed']); console.log('UTXOs for Atomical:', atomicalsUtxosByAtomicalId[atomicalId].length); accumulated[atomical['ticker']] = accumulated[atomical['ticker']] || 0; accumulated[atomical['ticker']] += atomical['confirmed']; if (showutxos) console.log(JSON.stringify(atomicalsUtxosByAtomicalId[atomicalId], null, 2)); } return accumulated; } function showWalletDetails(obj, type, showExtra = false, showBalancesOnly = false) { if (showBalancesOnly) { const atomicalsUtxosByAtomicalId = groupAtomicalsUtxosByAtomicalId(obj.atomicals_utxos); for (const atomicalId in obj.atomicals_balances) { if (!obj.atomicals_balances.hasOwnProperty(atomicalId)) { continue; } const atomical = obj.atomicals_balances[atomicalId]; if (atomical['type'] !== 'FT') { continue; } console.log('-----'); console.log('Atomical id:', atomicalId); console.log('Atomical number:', atomical['atomical_number']); console.log('Atomical type:', atomical['type']); console.log('Atomical subtype:', atomical['subtype']); console.log('Requested ticker:', atomical['request_ticker']); console.log('Requested ticker status:', atomical['request_ticker_status']['status']); console.log('Ticker:', atomical['ticker']); console.log('Confirmed balance:', atomical['confirmed']); console.log('UTXOs for Atomical:', atomicalsUtxosByAtomicalId[atomicalId].length); } return; } if (showExtra) { console.log(JSON.stringify(obj, null, 2)); } else { const atomicals_balances_summarized = {}; for (const atomicalId in obj.atomicals_balances) { if (!obj.atomicals_balances.hasOwnProperty(atomicalId)) { continue; } if (type !== "all" && obj.atomicals_balances[atomicalId]['type'].toLowerCase() !== type) { continue; } atomicals_balances_summarized[atomicalId] = Object.assign(Object.assign({}, obj.atomicals_balances[atomicalId]), { data: undefined }); } const summaryOnly = { address: obj.address, scripthash: obj.scripthash, atomicals_count: obj.atomicals_count, // atomicals_utxos: obj.atomicals_utxos, atomicals_balances: atomicals_balances_summarized, total_confirmed: obj.total_confirmed, total_unconfirmed: obj.total_unconfirmed, atomicals_confirmed: obj.atomicals_confirmed, atomicals_unconfirmed: obj.atomicals_unconfirmed, regular_confirmed: obj.regular_confirmed, regular_unconfirmed: obj.regular_unconfirmed, regular_utxo_count: obj.regular_utxo_count, // regular_utxos: obj.regular_utxos, }; console.log(JSON.stringify(summaryOnly, null, 2)); } } function resolveWalletAliasNew(walletInfo, alias, defaultValue) { if (!alias) { return defaultValue; } if (walletInfo[alias]) { return walletInfo[alias]; } if (walletInfo.imported[alias]) { return walletInfo.imported[alias]; } throw 'No wallet alias or valid address found: ' + alias; } function resolveAddress(walletInfo, aliasOrAddress, defaultValue) { if (!aliasOrAddress) { return defaultValue; } if (walletInfo[aliasOrAddress]) { return walletInfo[aliasOrAddress]; } if (walletInfo.imported[aliasOrAddress]) { return walletInfo.imported[aliasOrAddress]; } // As a last effort try and return the address try { (0, address_helpers_1.detectAddressTypeToScripthash)(aliasOrAddress); return { address: aliasOrAddress }; } catch (err) { // Do nothing, but at least we tried. } throw 'No wallet alias or valid address found: ' + aliasOrAddress; } ///////////////////////////////////////////////////////////////////////////////////////////// // Start of Command Line Options Definitions ///////////////////////////////////////////////////////////////////////////////////////////// const program = new commander_1.Command(); program .name('Atomicals CLI Utility') .description('Command line utility for interacting with Atomicals') .version(require('../package.json').version); program.command('server-version') .description('Get electrumx server version info') .action((options) => __awaiter(void 0, void 0, void 0, function* () { try { const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const result = yield atomicals.serverVersion(); console.log('result', result); } catch (error) { console.log(error); } })); ///////////////////////////////////////////////////////////////////////////////////////////// // Wallet and Local Wallet Commands ///////////////////////////////////////////////////////////////////////////////////////////// program.command('wallet-create') .description('Creates and displays new 12-word secret mnemonic phrase along with the primary and funding addresses') .action((options) => __awaiter(void 0, void 0, void 0, function* () { const result = yield _1.Atomicals.walletCreate(); console.log('Generated mnemonic phrase:', result); console.log(`phrase: ${result.data.wallet.phrase}`); console.log(`Primary address (P2TR): ${result.data.wallet.primary.address}`); console.log(`Primary address WIF: ${result.data.wallet.primary.WIF}`); console.log(`Primary address path: ${result.data.wallet.primary.path}`); console.log(`Funding address (P2TR): ${result.data.wallet.funding.address}`); console.log(`Funding address WIF: ${result.data.wallet.funding.WIF}`); console.log(`Funding address path: ${result.data.wallet.funding.path}`); console.log(JSON.stringify(result, null, 2)); console.log(`------------------------------------------------------`); })); program.command('wallet-decode') .description('Decode secret mnemonic phrase to display derive address and key at provided path') .argument('<phrase>', 'string') .option('-p, --path <string>', 'Derivation path to use', address_helpers_1.defaultDerivedPath) .option('--passphrase <string>', 'Passphrase for the wallet') .action((phrase, options) => __awaiter(void 0, void 0, void 0, function* () { let path = options.path; let passphrase = options.passphrase; const result = yield _1.Atomicals.walletPhraseDecode(phrase, path, passphrase); console.log('Provided mnemonic phrase:'); console.log(`phrase: ${result.data.phrase}`); console.log(`Requested Derivation Path: ${path}`); console.log(`Address: ${result.data.address}`); console.log(`Address path: ${result.data.path}`); console.log(`Address WIF: ${result.data.WIF}`); console.log(result); console.log(`------------------------------------------------------`); })); program.command('wallet-init') .description('Initializes a new wallet at wallet.json') .option('--phrase <string>', 'Provide a wallet phrase') .option('--path <string>', 'Provide a path base', address_helpers_1.defaultDerivedPath.substring(0, 11)) .option('--passphrase <string>', 'Provide a passphrase for the wallet') .option('--n <number>', 'Provider number of alias') .action((options) => __awaiter(void 0, void 0, void 0, function* () { try { const result = yield _1.Atomicals.walletInit(options.phrase, options.path, options.passphrase, options.n ? parseInt(options.n, 10) : undefined); console.log('Wallet created at wallet.json'); console.log(`phrase: ${result.data.phrase}`); console.log(`Primary address (P2TR): ${result.data.primary.address}`); console.log(`Primary address WIF: ${result.data.primary.WIF}`); console.log(`Primary address path: ${result.data.primary.path}`); console.log(`Funding address (P2TR): ${result.data.funding.address}`); console.log(`Funding address WIF: ${result.data.funding.WIF}`); console.log(`Funding address path: ${result.data.funding.path}`); console.log(`Full Data: ${JSON.stringify(result.data, null, 2)}`); console.log(`------------------------------------------------------`); } catch (err) { console.log('Error', err); } })); program.command('wallet-import') .description('Import a wallet by WIF and assign it to provided alias') .argument('<wif>', 'string') .argument('<alias>', 'string') .action((wif, alias, options) => __awaiter(void 0, void 0, void 0, function* () { try { yield (0, validate_wallet_storage_1.validateWalletStorage)(); yield _1.Atomicals.walletImport(wif, alias); console.log('Success! wallet.json updated'); } catch (error) { console.log(error); } })); program.command('address-script') .description('Encodes an address or wallet alias as the hex output script') .argument('<addressOrAlias>', 'string') .action((addressOrAlias, options) => __awaiter(void 0, void 0, void 0, function* () { const walletInfo = yield (0, validate_wallet_storage_1.validateWalletStorage)(); const result = (0, address_helpers_1.performAddressAliasReplacement)(walletInfo, addressOrAlias || undefined); console.log('Address:', result.address); console.log('Script:', result.output.toString('hex')); console.log('Scripthash:', result.scripthash.toString()); console.log(`------------------------------------------------------`); })); program.command('script-address') .description('Decodes a script as an address') .argument('<script>', 'string') .action((script, options) => __awaiter(void 0, void 0, void 0, function* () { const result = (0, address_helpers_1.detectScriptToAddressType)(script); console.log('Address:', result); console.log(`------------------------------------------------------`); })); program.command('outpoint-compact') .description('Decodes hex outpoint to compact location id form') .argument('<hex>', 'string') .action((hex, options) => __awaiter(void 0, void 0, void 0, function* () { const result = (0, atomical_format_helpers_1.outpointToCompactId)(hex); console.log('result:', result); console.log(`------------------------------------------------------`); })); program.command('compact-outpoint') .description('Encodes the compact id to outpoint hex format') .argument('<compactId>', 'string') .action((compactId, options) => __awaiter(void 0, void 0, void 0, function* () { const result = (0, atomical_format_helpers_1.compactIdToOutpoint)(compactId); console.log('result:', result); console.log(`------------------------------------------------------`); })); program.command('address') .description('Get balances and Atomicals stored at an address') .argument('<address>', 'string') .option('--history', 'Verbose output to include history or not') .action((address, options) => __awaiter(void 0, void 0, void 0, function* () { var _a; try { const walletInfo = yield (0, validate_wallet_storage_1.validateWalletStorage)(); const history = options.history; const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const receive = (0, address_helpers_1.performAddressAliasReplacement)(walletInfo, address || undefined); const result = yield atomicals.addressInfo(receive.address, history); qrcode.generate((_a = result.data) === null || _a === void 0 ? void 0 : _a.address, { small: false }); handleResultLogging(result); } catch (error) { console.log(error); } })); program.command('wallets') .description('Get balances and atomicals stored at internal wallets') .option('--history', 'Shows history of txids for each wallet if enabled') .option('--all', 'Shows all loaded wallets and not just the primary and funding') .option('--extra', 'Show extended wallet information such as specific utxos. Default is to only show a summary.') .option('--balances', 'Show FT token balances') .option('--noqr', 'Hide QR codes') .option('--alias <string>', 'Restrict to only showing one of the imported wallets identified by the alias') .option('--type <string>', 'Show NFT or FT types only. By default shows both. Not compatible with --balances and --extra') .option('--identify <string>', 'Restrict to only showing one of the imported wallets identified by the address (if it is found)') .option('--address <string>', 'Show the data and a QR code for an arbitrary address. Not expected to be loaded into local wallets.') .action((options) => __awaiter(void 0, void 0, void 0, function* () { var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; try { const all = options.all; const history = options.history; const alias = options.alias ? options.alias : null; const extra = options.extra ? options.extra : null; const address = options.address ? options.address : null; const noqr = options.noqr ? options.noqr : null; const balancesOnly = options.balances ? options.balances : null; const identify = options.identify ? options.identify : null; const show = options.address ? options.address : null; const type = options.type ? options.type.toLowerCase() : 'all'; if (type !== 'all' && type !== 'nft' && type != 'ft') { throw `Invalid type ${type}`; } const walletInfo = yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const electrum = electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || ''); const atomicals = new _1.Atomicals(electrum); const keepElectrumAlive = true; if (alias) { if (!walletInfo.imported || !walletInfo.imported[alias]) { throw `No wallet with alias ${alias}`; } let result = yield atomicals.walletInfo(walletInfo.imported[alias].address, history, keepElectrumAlive); console.log("\n========================================================================================================"); console.log(`Wallet Information - ${alias} Address - ${(_b = result.data) === null || _b === void 0 ? void 0 : _b.address}`); console.log("========================================================================================================"); if (!noqr) { qrcode.generate((_c = result.data) === null || _c === void 0 ? void 0 : _c.address, { small: false }); } showWalletDetails(result.data, type, extra, balancesOnly); } else if (identify) { console.log("\n========================================================================================================"); console.log(`Request Identify Wallet: ${identify}`); console.log("========================================================================================================"); let foundWallet = false; for (const walletAlias in walletInfo.imported) { if (!walletInfo.imported[walletAlias]) { continue; } if (walletInfo.imported[walletAlias].address === identify) { foundWallet = true; let result = yield atomicals.walletInfo(walletInfo.imported[walletAlias].address, history, keepElectrumAlive); console.log("\n========================================================================================================"); console.log(`Wallet Information - ${walletAlias} Address`); console.log("========================================================================================================"); if (!noqr) { qrcode.generate((_d = result.data) === null || _d === void 0 ? void 0 : _d.address, { small: false }); } showWalletDetails(result.data, type, extra, balancesOnly); } } if (!foundWallet) { console.log(`No imported wallet found with address ${identify}`); } } else if (show) { console.log("\n========================================================================================================"); console.log(`Request Show Address: ${show}`); console.log("========================================================================================================"); let result = yield atomicals.walletInfo(show, history, keepElectrumAlive); console.log("\n========================================================================================================"); console.log(`Address Information - ${show} Address - ${(_e = result.data) === null || _e === void 0 ? void 0 : _e.address}`); console.log("========================================================================================================"); if (!noqr) { qrcode.generate((_f = result.data) === null || _f === void 0 ? void 0 : _f.address, { small: false }); } showWalletDetails(result.data, type, extra, balancesOnly); } else { // Just show the primary and funding address let result = yield atomicals.walletInfo(walletInfo.primary.address, history, keepElectrumAlive); console.log('walletInfo result', result); console.log("\n========================================================================================================"); console.log(`1. Wallet Information - Primary Address - ${(_g = result.data) === null || _g === void 0 ? void 0 : _g.address}`); console.log("========================================================================================================"); if (!noqr) { qrcode.generate((_h = result.data) === null || _h === void 0 ? void 0 : _h.address, { small: false }); } showWalletDetails(result.data, type, extra, balancesOnly); result = yield atomicals.walletInfo(walletInfo.funding.address, history, keepElectrumAlive); console.log("\n========================================================================================================"); console.log(`2. Wallet Information - Funding Address - ${(_j = result.data) === null || _j === void 0 ? void 0 : _j.address}`); console.log("========================================================================================================"); if (!noqr) { qrcode.generate((_k = result.data) === null || _k === void 0 ? void 0 : _k.address, { small: false }); } showWalletDetails(result.data, type, extra, balancesOnly); if (all) { let counter = 3; if (walletInfo.imported) { for (const walletAlias in walletInfo.imported) { if (!walletInfo.imported.hasOwnProperty(walletAlias)) { continue; } result = yield atomicals.walletInfo(walletInfo.imported[walletAlias].address, history, keepElectrumAlive); console.log("\n========================================================================================================"); console.log(`${counter}. Wallet Information - ${walletAlias} Address - ${(_l = result.data) === null || _l === void 0 ? void 0 : _l.address}`); console.log("========================================================================================================"); if (!noqr) { qrcode.generate((_m = result.data) === null || _m === void 0 ? void 0 : _m.address, { small: false }); } showWalletDetails(result.data, type, extra, balancesOnly); counter++; } } } } console.log("\n\n"); yield electrum.close(); } catch (error) { console.log(error); } })); program.command('balances') .description('Get balances and atomicals stored at internal wallets') .option('--noqr', 'Hide QR codes') .option('--utxos', 'Show utxos too') .option('--all', 'Shows all loaded wallets and not just the primary and funding') .option('--alias <string>', 'Restrict to only showing one of the imported wallets identified by the alias') .option('--address <string>', 'Restrict to only showing by address. Using this option with --alias has no effect.') .action((options) => __awaiter(void 0, void 0, void 0, function* () { var _o, _p, _q, _r, _s, _t, _u, _v, _w, _x; try { const alias = options.alias ? options.alias : null; const noqr = options.noqr ? options.noqr : null; const address = options.address ? options.address : null; const all = options.all; const utxos = options.utxos; const balancesOnly = true; const walletInfo = yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const electrum = electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || ''); const atomicals = new _1.Atomicals(electrum); const keepElectrumAlive = true; let accumulated = {}; if (alias) { if (!walletInfo.imported || !walletInfo.imported[alias]) { throw `No wallet with alias ${alias}`; } let result = yield atomicals.walletInfo(walletInfo.imported[alias].address, false, keepElectrumAlive); console.log("\n========================================================================================================"); console.log(`Wallet Information - ${alias} Address - ${(_o = result.data) === null || _o === void 0 ? void 0 : _o.address}`); console.log("========================================================================================================"); if (!noqr) { qrcode.generate((_p = result.data) === null || _p === void 0 ? void 0 : _p.address, { small: false }); } accumulated = showWalletFTBalancesDetails(result.data, utxos, accumulated); } else if (address) { let result = yield atomicals.walletInfo(address, false, keepElectrumAlive); console.log("\n========================================================================================================"); console.log(`Wallet Information - Address - ${(_q = result.data) === null || _q === void 0 ? void 0 : _q.address}`); console.log("========================================================================================================"); if (!noqr) { qrcode.generate((_r = result.data) === null || _r === void 0 ? void 0 : _r.address, { small: false }); } accumulated = showWalletFTBalancesDetails(result.data, utxos, accumulated); } else { // Just show the primary and funding address let result = yield atomicals.walletInfo(walletInfo.primary.address, false, keepElectrumAlive); console.log("\n========================================================================================================"); console.log(`1. Wallet Information - Primary Address - ${(_s = result.data) === null || _s === void 0 ? void 0 : _s.address}`); console.log("========================================================================================================"); if (!noqr) { qrcode.generate((_t = result.data) === null || _t === void 0 ? void 0 : _t.address, { small: false }); } accumulated = showWalletFTBalancesDetails(result.data, utxos, accumulated); result = yield atomicals.walletInfo(walletInfo.funding.address, false, keepElectrumAlive); console.log("\n========================================================================================================"); console.log(`2. Wallet Information - Funding Address - ${(_u = result.data) === null || _u === void 0 ? void 0 : _u.address}`); console.log("========================================================================================================"); if (!noqr) { qrcode.generate((_v = result.data) === null || _v === void 0 ? void 0 : _v.address, { small: false }); } accumulated = showWalletFTBalancesDetails(result.data, utxos, accumulated); if (all) { let counter = 3; if (walletInfo.imported) { for (const walletAlias in walletInfo.imported) { if (!walletInfo.imported.hasOwnProperty(walletAlias)) { continue; } result = yield atomicals.walletInfo(walletInfo.imported[walletAlias].address, false, keepElectrumAlive); console.log("\n========================================================================================================"); console.log(`${counter}. Wallet Information - ${walletAlias} Address - ${(_w = result.data) === null || _w === void 0 ? void 0 : _w.address}`); console.log("========================================================================================================"); if (!noqr) { qrcode.generate((_x = result.data) === null || _x === void 0 ? void 0 : _x.address, { small: false }); } accumulated = showWalletFTBalancesDetails(result.data, utxos, accumulated); counter++; } } } } console.log("\n\n"); console.log(accumulated); yield electrum.close(); } catch (error) { console.log(error); } })); program.command('address-utxos') .description('List all utxos owned by an address') .argument('<address>', 'string') .action((address, options) => __awaiter(void 0, void 0, void 0, function* () { try { const walletInfo = yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); // address = performAddressAliasReplacement(walletInfo, address); const receive = (0, address_helpers_1.performAddressAliasReplacement)(walletInfo, address || undefined); const result = yield atomicals.getUtxos(receive.address); handleResultLogging(result); } catch (error) { console.log(error); } })); program.command('address-history') .description('List address history of an address') .argument('<address>', 'string') .action((address, options) => __awaiter(void 0, void 0, void 0, function* () { try { const walletInfo = yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const receive = (0, address_helpers_1.performAddressAliasReplacement)(walletInfo, address || undefined); const result = yield atomicals.getHistory(receive.address); handleResultLogging(result); } catch (error) { console.log(error); } })); program.command('tx') .description('Get any transaction') .argument('<txid>', 'string') .option('--verbose', 'Verbose output') .action((txid, options) => __awaiter(void 0, void 0, void 0, function* () { try { yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const result = yield atomicals.getTx(txid); console.log(JSON.stringify(result, null, 2)); } catch (error) { console.log(error); } })); ///////////////////////////////////////////////////////////////////////////////////////////// // Name Retrieval Commands (Tickers, (Sub)Realms, Containers) ///////////////////////////////////////////////////////////////////////////////////////////// /** * Resolve a realm or subrealm * * @param realm_or_subrealm Realm or subrealm to resolve * @param options */ const resolveRealmAction = (realm_or_subrealm, options) => __awaiter(void 0, void 0, void 0, function* () { try { const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const result = yield atomicals.getAtomicalByRealm(realm_or_subrealm); console.log(JSON.stringify(result, null, 2)); } catch (error) { console.log(error); } }); program.command('get-ticker') .description('Get Atomical by ticker name') .argument('<ticker>', 'string') .option('--verbose', 'Verbose to show extended information.') .action((ticker, options) => __awaiter(void 0, void 0, void 0, function* () { try { const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const result = yield atomicals.getAtomicalByTicker(ticker); console.log(JSON.stringify(result, null, 2)); } catch (error) { console.log(error); } })); program.command('get-container') .description('Get Atomical by container name') .argument('<container>', 'string') .option('--verbose', 'Verbose to show extended information.') .action((container, options) => __awaiter(void 0, void 0, void 0, function* () { try { const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const result = yield atomicals.getAtomicalByContainer(container); console.log(JSON.stringify(result, null, 2)); } catch (error) { console.log(error); } })); program.command('get-container-items') .description('Get the items in the container') .argument('<container>', 'string') .argument('<limit>', 'number') .argument('<offset>', 'number') .option('--verbose', 'Verbose output') .action((container, limit, offset, options) => __awaiter(void 0, void 0, void 0, function* () { try { const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const result = yield atomicals.getContainerItems(container, parseInt(limit, 10), parseInt(offset, 10)); console.log(JSON.stringify(result, null, 2)); } catch (error) { console.log(error); } })); program.command('get-container-item') .description('Get an item in the container') .argument('<container>', 'string') .argument('<itemId>', 'string') .option('--verbose', 'Verbose output') .action((container, itemId, options) => __awaiter(void 0, void 0, void 0, function* () { try { const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const modifiedStripped = container.indexOf('#') === 0 ? container.substring(1) : container; const result = yield atomicals.getAtomicalByContainerItem(modifiedStripped, itemId); console.log(JSON.stringify(result, null, 2)); } catch (error) { console.log(error); } })); program.command('validate-container-item') .description('Validate a container item from the manifest') .argument('<containerName>', 'string') .argument('<itemName>', 'string') .argument('<manifestFile>', 'string') .option('--sealed --no-sealed', 'Validate the item without checking if the container is sealed.') .action((containerName, itemName, manifestFile, options) => __awaiter(void 0, void 0, void 0, function* () { try { const walletInfo = yield (0, validate_wallet_storage_1.validateWalletStorage)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const result = yield atomicals.getAtomicalByContainerItemValidated(containerName, itemName, manifestFile, options.sealed); handleResultLogging(result); } catch (error) { console.log(error); } })); program.command('resolve') .description(`Resolve a realm or subrealm. Alias for 'get-realm'`) .argument('<realm_or_subrealm>', 'string') .option('--verbose', 'Verbose to show extended information.') .action((realm_or_subrealm, options) => __awaiter(void 0, void 0, void 0, function* () { yield resolveRealmAction(realm_or_subrealm, options); })); program.command('get-realm') .description(`Resolve a realm or subrealm. Alias for 'resolve'`) .argument('<realm_or_subrealm>', 'string') .option('--verbose', 'Verbose to show extended information.') .action((realm_or_subrealm, options) => __awaiter(void 0, void 0, void 0, function* () { yield resolveRealmAction(realm_or_subrealm, options); })); program.command('realm-info') .description('Get realm and subrealm information of an atomical') .argument('<atomicalIdAlias>', 'string') .option('--verbose', 'Verbose output') .action((atomicalAliasOrId, options) => __awaiter(void 0, void 0, void 0, function* () { try { yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const verbose = options.verbose; const modifiedStripped = atomicalAliasOrId.indexOf('+') === 0 ? atomicalAliasOrId.substring(1) : atomicalAliasOrId; const result = yield atomicals.getRealmInfo(modifiedStripped, verbose); console.log(JSON.stringify(result, null, 2)); } catch (error) { console.log(error); } })); program.command('summary-subrealms') .description('Show summary of owned subrealms by wallet') .option('--owner <string>', 'Provide alternate wallet alias to query') .option('--filter <string>', 'Filter by status') .action((options) => __awaiter(void 0, void 0, void 0, function* () { try { const walletInfo = yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); let ownerWalletAddress = resolveAddress(walletInfo, options.owner, walletInfo.primary).address; const filter = options.filter ? options.filter : undefined; const result = yield atomicals.summarySubrealms(ownerWalletAddress, filter); handleResultLogging(result); } catch (error) { console.log(error); } })); program.command('summary-containers') .description('Show summary of owned containers by wallet') .option('--owner <string>', 'Provide alternate wallet alias to query') .option('--filter <string>', 'Filter by status') .action((options) => __awaiter(void 0, void 0, void 0, function* () { try { const walletInfo = yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); let ownerWalletAddress = resolveAddress(walletInfo, options.owner, walletInfo.primary).address; const filter = options.filter ? options.filter : undefined; const result = yield atomicals.summaryContainers(ownerWalletAddress, filter); handleResultLogging(result); } catch (error) { console.log(error); } })); program.command('summary-realms') .description('Show summary of owned realms by wallet') .option('--owner <string>', 'Provide alternate wallet alias to query') .option('--filter <string>', 'Filter by status') .action((options) => __awaiter(void 0, void 0, void 0, function* () { try { const walletInfo = yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); let ownerWalletAddress = resolveAddress(walletInfo, options.owner, walletInfo.primary).address; const filter = options.filter ? options.filter : undefined; const result = yield atomicals.summaryRealms(ownerWalletAddress, filter); handleResultLogging(result); } catch (error) { console.log(error); } })); program.command('summary-tickers') .description('Show summary of owned tokens by tickers by wallet') .option('--owner <string>', 'Provide alternate wallet alias to query') .option('--filter <string>', 'Filter by status') .action((options) => __awaiter(void 0, void 0, void 0, function* () { try { const walletInfo = yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); let ownerWalletAddress = resolveAddress(walletInfo, options.owner, walletInfo.primary).address; const filter = options.filter ? options.filter : undefined; const result = yield atomicals.summaryTickers(ownerWalletAddress, filter); handleResultLogging(result); } catch (error) { console.log(error); } })); program.command('find-tickers') .description('Search tickers') .option('--q <string>', 'Search query') .option('--asc <string>', 'Sort by ascending', 'true') .action((options) => __awaiter(void 0, void 0, void 0, function* () { try { yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const verbose = options.verbose; const q = options.q ? options.q : null; const asc = options.asc === 'true'; const result = yield atomicals.searchTickers(q, verbose, asc); handleResultLogging(result); } catch (error) { console.log(error); } })); program.command('find-realms') .description('Search realms') .option('--q <string>', 'Search query') .option('--asc <string>', 'Sort by ascending', 'true') .action((options) => __awaiter(void 0, void 0, void 0, function* () { try { yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const verbose = options.verbose; const q = options.q ? options.q : null; const asc = options.asc === 'true'; const result = yield atomicals.searchRealms(q, verbose, asc); handleResultLogging(result); } catch (error) { console.log(error); } })); program.command('find-containers') .description('Search containers') .option('--q <string>', 'Search query') .option('--asc <string>', 'Sort by ascending', 'true') .action((options) => __awaiter(void 0, void 0, void 0, function* () { try { yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const verbose = options.verbose; const q = options.q ? options.q : null; const asc = options.asc === 'true'; const result = yield atomicals.searchContainers(q, verbose, asc); handleResultLogging(result); } catch (error) { console.log(error); } })); program.command('await-utxo') .description('Finds utxo by address') .argument('<address>', 'string') .argument('<amount>', 'number') .action((address, amount, options) => __awaiter(void 0, void 0, void 0, function* () { try { yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); const result = yield atomicals.awaitUtxo(address, parseInt(amount, 10)); handleResultLogging(result); } catch (error) { console.log(error); } })); program.command('diff') .action((options) => __awaiter(void 0, void 0, void 0, function* () { const a = []; const b = []; let diffs = b.filter(x => !a.includes(x)); console.log(JSON.stringify(diffs, null, 2)); })); ///////////////////////////////////////////////////////////////////////////////////////////// // Modify, Updates, Events, Delete... ///////////////////////////////////////////////////////////////////////////////////////////// program.command('set') .description('Set (update) an existing Atomical with data.') .argument('<atomicalIdAlias>', 'string') .argument('<jsonFilename>', 'string') .option('--rbf', 'Whether to enable RBF for transactions.') .option('--funding <string>', 'Use wallet alias WIF key to be used for funding') .option('--owner <string>', 'Use wallet alias WIF key to move the Atomical') .option('--satsbyte <number>', 'Satoshis per byte in fees', '-1') .option('--satsoutput <number>', 'Satoshis to put into output', '1000') .option('--disableautoencode', 'Disables auto encoding of $b variables') .option('--bitworkc <string>', 'Whether to add any bitwork proof of work to the commit tx') .action((atomicalId, jsonFilename, options) => __awaiter(void 0, void 0, void 0, function* () { try { const walletInfo = yield (0, validate_wallet_storage_1.validateWalletStorage)(); const config = (0, validate_cli_inputs_1.validateCliInputs)(); const atomicals = new _1.Atomicals(electrum_api_1.ElectrumApi.createClient(process.env.ELECTRUMX_PROXY_BASE_URL || '')); let fundingWalletRecord = resolveWalletAliasNew(walletInfo, options.funding, walletInfo.funding); let ownerWalletRecord = resolveWalletAliasNew(walletInfo, options.owner, walletInfo.primary); const result = yield atomicals.setInteractive({ rbf: options.rbf, satsbyte: parseInt(options.satsbyte, 10), satsoutput: parseInt(options.satsoutput, 10), disableautoencode: !!options.disableautoencode, bitworkc: options.bitworkc ? options.bitworkc : '8', }, atomicalId, jsonFilename, fundingWalletRecord, ownerWalletRecord); handleResultLogging(result); } catch (error) { console.log(error); } })); program.command('set-container-data') .description('Update container data with json file contents') .argument('<containerName>', 'string') .argument('<jsonFilename>', 'string') .option('--rbf', 'Whether to enable RBF for tr