UNPKG

@stacks/cli

Version:
1,089 lines • 142 kB
"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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.loadConfig = exports.checkArgs = exports.getCommandArgs = exports.CLIOptAsStringArray = exports.CLIOptAsBool = exports.CLIOptAsString = exports.getCLIOpts = exports.printUsage = exports.makeUsageString = exports.makeCommandUsageString = exports.makeAllCommandsHelp = exports.makeAllCommandsList = exports.USAGE = exports.CLI_ARGS = exports.DEFAULT_MAX_ID_SEARCH_INDEX = exports.DEFAULT_CONFIG_TESTNET_PATH = exports.DEFAULT_CONFIG_PATH = exports.BOOLEAN_PATTERN = exports.TXID_PATTERN = exports.SUBDOMAIN_PATTERN = exports.URL_PATTERN = exports.ZONEFILE_HASH_PATTERN = exports.INT_PATTERN = exports.PUBLIC_KEY_PATTERN = exports.PRIVATE_KEY_PATTERN_ANY = exports.PRIVATE_KEY_SEGWIT_P2SH_PATTERN = exports.PRIVATE_KEY_MULTISIG_PATTERN = exports.PRIVATE_KEY_NOSIGN_PATTERN = exports.PRIVATE_KEY_UNCOMPRESSED_PATTERN = exports.PRIVATE_KEY_PATTERN = exports.STACKS_ADDRESS_PATTERN = exports.ID_ADDRESS_PATTERN = exports.ADDRESS_PATTERN = exports.C32_ADDRESS_CHARS = exports.ADDRESS_CHARS = exports.NAMESPACE_PATTERN = exports.NAME_PATTERN = void 0; const ajv_1 = __importDefault(require("ajv")); const process = __importStar(require("process")); const path = __importStar(require("path")); const os = __importStar(require("os")); const fs = __importStar(require("fs")); exports.NAME_PATTERN = '^([0-9a-z_.+-]{3,37})$'; exports.NAMESPACE_PATTERN = '^([0-9a-z_-]{1,19})$'; exports.ADDRESS_CHARS = '[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{1,35}'; exports.C32_ADDRESS_CHARS = '[0123456789ABCDEFGHJKMNPQRSTVWXYZ]+'; exports.ADDRESS_PATTERN = `^(${exports.ADDRESS_CHARS})$`; exports.ID_ADDRESS_PATTERN = `^ID-${exports.ADDRESS_CHARS}$`; exports.STACKS_ADDRESS_PATTERN = `^(${exports.C32_ADDRESS_CHARS})$`; exports.PRIVATE_KEY_PATTERN = '^([0-9a-f]{64,66})$'; exports.PRIVATE_KEY_UNCOMPRESSED_PATTERN = '^([0-9a-f]{64})$'; exports.PRIVATE_KEY_NOSIGN_PATTERN = `^nosign:${exports.ADDRESS_CHARS}$`; exports.PRIVATE_KEY_MULTISIG_PATTERN = '^([0-9]+),([0-9a-f]{64,66},)*([0-9a-f]{64,66})$'; exports.PRIVATE_KEY_SEGWIT_P2SH_PATTERN = '^segwit:p2sh:([0-9]+),([0-9a-f]{64,66},)*([0-9a-f]{64,66})$'; exports.PRIVATE_KEY_PATTERN_ANY = `${exports.PRIVATE_KEY_PATTERN}|${exports.PRIVATE_KEY_MULTISIG_PATTERN}|${exports.PRIVATE_KEY_SEGWIT_P2SH_PATTERN}|${exports.PRIVATE_KEY_NOSIGN_PATTERN}`; exports.PUBLIC_KEY_PATTERN = '^([0-9a-f]{66,130})$'; exports.INT_PATTERN = '^-?[0-9]+$'; exports.ZONEFILE_HASH_PATTERN = '^([0-9a-f]{40})$'; exports.URL_PATTERN = '^http[s]?://.+$'; exports.SUBDOMAIN_PATTERN = '^([0-9a-z_+-]{1,37}).([0-9a-z_.+-]{3,37})$'; exports.TXID_PATTERN = '^([0-9a-f]{64})$'; exports.BOOLEAN_PATTERN = '^(0|1|true|false)$'; const LOG_CONFIG_DEFAULTS = { level: 'info', handleExceptions: true, timestamp: true, stringify: true, colorize: true, json: true, }; const CONFIG_DEFAULTS = { blockstackAPIUrl: 'https://api.hiro.so', blockstackNodeUrl: 'https://api.hiro.so', broadcastServiceUrl: 'https://api.hiro.so/v2/transactions', utxoServiceUrl: 'https://blockchain.info', logConfig: LOG_CONFIG_DEFAULTS, }; const CONFIG_LOCALNET_DEFAULTS = { blockstackAPIUrl: `http://localhost:20443`, blockstackNodeUrl: `http://localhost:20443`, broadcastServiceUrl: `http://localhost:20443/v2/transactions`, utxoServiceUrl: `http://localhost:18332`, logConfig: Object.assign({}, LOG_CONFIG_DEFAULTS, { level: 'debug' }), }; const CONFIG_TESTNET_DEFAULTS = { blockstackAPIUrl: `https://api.testnet.hiro.so`, blockstackNodeUrl: `https://api.testnet.hiro.so`, broadcastServiceUrl: `https://api.testnet.hiro.so/v2/transactions`, utxoServiceUrl: `https://blockchain.info`, logConfig: Object.assign({}, LOG_CONFIG_DEFAULTS, { level: 'debug' }), }; exports.DEFAULT_CONFIG_PATH = '~/.blockstack-cli.conf'; exports.DEFAULT_CONFIG_TESTNET_PATH = path.join(os.homedir(), '.blockstack-cli-testnet.conf'); exports.DEFAULT_MAX_ID_SEARCH_INDEX = 256; exports.CLI_ARGS = { type: 'object', properties: { announce: { type: 'array', items: [ { name: 'message_hash', type: 'string', realtype: 'zonefile_hash', pattern: exports.ZONEFILE_HASH_PATTERN, }, { name: 'owner_key', type: 'string', realtype: 'private_key', pattern: `${exports.PRIVATE_KEY_PATTERN_ANY}`, }, ], minItems: 2, maxItems: 2, help: 'Broadcast a message on the blockchain for subscribers to read. ' + 'The `MESSAGE_HASH` argument must be the hash of a previously-announced zone file. ' + 'The `OWNER_KEY` used to sign the transaction must correspond to the Blockstack ID ' + 'to which other users have already subscribed. `OWNER_KEY` can be a single private key ' + 'or a serialized multisig private key bundle.\n' + '\n' + 'If this command succeeds, it will print a transaction ID. The rest of the Blockstack peer ' + 'network will process it once the transaction reaches 7 confirmations.\n' + '\n' + 'Examples:\n' + '```console\n' + ' $ # Tip: You can obtain the owner key with the get_owner_keys command\n' + ' $ export OWNER_KEY="136ff26efa5db6f06b28f9c8c7a0216a1a52598045162abfe435d13036154a1b01"\n' + ' $ stx announce 737c631c7c5d911c6617993c21fba731363f1cfe "$OWNER_KEY"\n' + ' d51749aeec2803e91a2f8bdec8d3e413491fd816b4962372b214ab74acb0bba8\n' + '\n' + ' $ export OWNER_KEY="2,136ff26efa5db6f06b28f9c8c7a0216a1a52598045162abfe435d13036154a1b01,1885cba486a42960499d1f137ef3a475725ceb11f45d74631f9928280196f67401,2418981c7f3a91d4467a65a518e14fafa30e07e6879c11fab7106ea72b49a7cb01"\n' + ' $ stx announce 737c631c7c5d911c6617993c21fba731363f1cfe "$OWNER_KEY"\n' + ' 8136a1114098893b28a693e8d84451abf99ee37ef8766f4bc59808eed76968c9\n' + '```\n' + '\n', group: 'Peer Services', }, authenticator: { type: 'array', items: [ { name: 'app_gaia_hub', type: 'string', realtype: 'url', pattern: exports.URL_PATTERN, }, { name: 'backup_phrase', type: 'string', realtype: '12_words_or_ciphertext', pattern: '.+', }, { name: 'profile_gaia_hub', type: 'string', realtype: 'url', pattern: exports.URL_PATTERN, }, { name: 'port', type: 'string', realtype: 'portnum', pattern: '^[0-9]+', }, ], minItems: 2, maxItems: 4, help: 'Run an authentication endpoint for the set of names owned ' + 'by the given backup phrase. Send applications the given Gaia hub URL on sign-in, ' + 'so the application will use it to read/write user data.\n' + '\n' + 'You can supply your encrypted backup phrase instead of the raw backup phrase. If so, ' + 'then you will be prompted for your password before any authentication takes place.\n' + '\n' + 'Example:\n' + '```console\n' + ' $ export BACKUP_PHRASE="oak indicate inside poet please share dinner monitor glow hire source perfect"\n' + ' $ export APP_GAIA_HUB="https://1.2.3.4"\n' + ' $ export PROFILE_GAIA_HUB="https://hub.blockstack.org"\n' + ' $ stx authenticator "$APP_GAIA_HUB" "$BACKUP_PHRASE" "$PROFILE_GAIA_HUB" 8888\n' + ' Press Ctrl+C to exit\n' + ' Authentication server started on 8888\n' + '```\n', group: 'Authentication', }, balance: { type: 'array', items: [ { name: 'address', type: 'string', realtype: 'address', pattern: `${exports.ADDRESS_PATTERN}|${exports.STACKS_ADDRESS_PATTERN}`, }, ], minItems: 1, maxItems: 1, help: 'Query the balance of an account. Returns the balances of each kind of token ' + 'that the account owns. The balances will be in the *smallest possible units* of the ' + 'token (i.e. satoshis for BTC, microStacks for Stacks, etc.).\n' + '\n' + 'Example:\n' + '```console\n' + ' $ stx balance 16pm276FpJYpm7Dv3GEaRqTVvGPTdceoY4\n' + ' {\n' + ' "BTC": "123456"\n' + ' "STACKS": "123456"\n' + ' }\n' + ' $ stx balance SPZY1V53Z4TVRHHW9Z7SFG8CZNRAG7BD8WJ6SXD0\n' + ' {\n' + ' "BTC": "123456"\n' + ' "STACKS": "123456"\n' + ' }' + '```\n', group: 'Account Management', }, can_stack: { type: 'array', items: [ { name: 'amount', type: 'string', realtype: 'integer', pattern: '^[0-9]+$', }, { name: 'cycles', type: 'string', realtype: 'integer', pattern: '^[0-9]+$', }, { name: 'pox_address', type: 'string', realtype: 'address', pattern: `${exports.ADDRESS_PATTERN}`, }, { name: 'stx_address', type: 'string', realtype: 'address', pattern: `${exports.STACKS_ADDRESS_PATTERN}`, }, ], minItems: 4, maxItems: 4, help: 'Check if specified account can stack a number of Stacks tokens for given number of cycles.\n' + '\n' + 'Example:\n' + '```console\n' + ' $ stx can_stack 10000000 20 16pm276FpJYpm7Dv3GEaRqTVvGPTdceoY4 SPZY1V53Z4TVRHHW9Z7SFG8CZNRAG7BD8WJ6SXD0\n' + ' {\n' + ' "eligible": true\n' + ' }\n' + '```\n', group: 'Account Management', }, call_contract_func: { type: 'array', items: [ { name: 'contract_address', type: 'string', realtype: 'address', pattern: `${exports.STACKS_ADDRESS_PATTERN}`, }, { name: 'contract_name', type: 'string', realtype: 'string', pattern: '^[a-zA-Z]([a-zA-Z0-9]|[-_])*$', }, { name: 'function_name', type: 'string', realtype: 'string', pattern: '^[a-zA-Z]([a-zA-Z0-9]|[-_!?])*$', }, { name: 'fee', type: 'string', realtype: 'integer', pattern: '^[0-9]+$', }, { name: 'nonce', type: 'string', realtype: 'integer', pattern: '^[0-9]+$', }, { name: 'payment_key', type: 'string', realtype: 'private_key', pattern: `${exports.PRIVATE_KEY_PATTERN_ANY}`, }, { name: 'function_args', type: 'string', realtype: 'string', pattern: '.+', }, ], minItems: 6, maxItems: 7, help: 'Call a function in a deployed Clarity smart contract.\n' + '\n' + 'If the command succeeds, it prints out a transaction ID.' + '\n' + 'Example:\n' + '```console\n' + ' $ export PAYMENT="bfeffdf57f29b0cc1fab9ea197bb1413da2561fe4b83e962c7f02fbbe2b1cd5401"\n' + ' $ stx call_contract_func SPBMRFRPPGCDE3F384WCJPK8PQJGZ8K9QKK7F59X contract_name' + ' contract_function 1 0 "$PAYMENT"\n' + ' {\n' + " txid: '0x2e33ad647a9cedacb718ce247967dc705bc0c878db899fdba5eae2437c6fa1e1'," + " transaction: 'https://explorer.hiro.so/txid/0x2e33ad647a9cedacb718ce247967dc705bc0c878db899fdba5eae2437c6fa1e1'" + ' }\n' + '```\n' + '\n' + 'You can also provide function arguments directly instead of being prompted for them:\n' + '```console\n' + ' $ stx call_contract_func SPBMRFRPPGCDE3F384WCJPK8PQJGZ8K9QKK7F59X contract_name' + ' contract_function 1 0 "$PAYMENT" \'u100, true, "some-string", { a: u"str-utf8", b: 2 }\'\n' + '```\n' + '\n', group: 'Account Management', }, call_read_only_contract_func: { type: 'array', items: [ { name: 'contract_address', type: 'string', realtype: 'address', pattern: `${exports.STACKS_ADDRESS_PATTERN}`, }, { name: 'contract_name', type: 'string', realtype: 'string', pattern: '^[a-zA-Z]([a-zA-Z0-9]|[-_])*$', }, { name: 'function_name', type: 'string', realtype: 'string', pattern: '^[a-zA-Z]([a-zA-Z0-9]|[-_!?])*$', }, { name: 'sender_address', type: 'string', realtype: 'address', pattern: `${exports.STACKS_ADDRESS_PATTERN}`, }, ], minItems: 4, maxItems: 4, help: 'Call a read-only function in a deployed Clarity smart contract.\n' + '\n' + 'If the command succeeds, it prints out a Clarity value.' + '\n' + 'Example:\n' + '```console\n' + ' $ stx call_read_only_contract_func SPBMRFRPPGCDE3F384WCJPK8PQJGZ8K9QKK7F59X contract_name' + ' contract_function SPBMRFRPPGCDE3F384WCJPK8PQJGZ8K9QKK7F59X\n' + ' {\n' + " txid: '0x2e33ad647a9cedacb718ce247967dc705bc0c878db899fdba5eae2437c6fa1e1'," + " transaction: 'https://explorer.hiro.so/txid/0x2e33ad647a9cedacb718ce247967dc705bc0c878db899fdba5eae2437c6fa1e1'" + ' }\n' + '```\n' + '\n', group: 'Account Management', }, decode_cv: { type: 'array', items: [ { name: 'clarity_value', type: 'string', realtype: 'string', pattern: '-|^(0x|0X)?[a-fA-F0-9]+$', }, { name: 'format', type: 'string', realtype: 'format', pattern: '^(repr|pretty|json)$', }, ], minItems: 1, maxItems: 4, help: 'Decode a serialized Clarity value.\n' + '\n' + 'Example:\n' + '\n' + '```console\n' + ' $ stx decode_cv 0x050011deadbeef11ababffff11deadbeef11ababffff\n' + ' S08XXBDYXW8TQAZZZW8XXBDYXW8TQAZZZZ88551S\n' + ' $ stx decode_cv --format json SPA2MZWV9N67TBYVWTE0PSSKMJ2F6YXW7CBE6YPW\n' + ' {"type":"principal","value":"S08XXBDYXW8TQAZZZW8XXBDYXW8TQAZZZZ88551S"}\n' + ' $ echo 0x050011deadbeef11ababffff11deadbeef11ababffff | stx decode_cv -\n' + ' S08XXBDYXW8TQAZZZW8XXBDYXW8TQAZZZZ88551S\n' + '```\n', group: 'Utilities', }, convert_address: { type: 'array', items: [ { name: 'address', type: 'string', realtype: 'address', pattern: `${exports.ADDRESS_PATTERN}|${exports.STACKS_ADDRESS_PATTERN}`, }, ], minItems: 1, maxItems: 1, help: 'Convert a Bitcoin address to a Stacks address and vice versa.\n' + '\n' + 'Example:\n' + '\n' + '```console\n' + ' $ stx convert_address 12qdRgXxgNBNPnDeEChy3fYTbSHQ8nfZfD\n' + ' {\n' + ' "mainnet": {\n' + ' "STACKS": "SPA2MZWV9N67TBYVWTE0PSSKMJ2F6YXW7CBE6YPW",\n' + ' "BTC": "12qdRgXxgNBNPnDeEChy3fYTbSHQ8nfZfD"\n' + ' }\n' + ' }\n' + ' $ stx convert_address SPA2MZWV9N67TBYVWTE0PSSKMJ2F6YXW7CBE6YPW\n' + ' {\n' + ' "mainnet": {\n' + ' "STACKS": "SPA2MZWV9N67TBYVWTE0PSSKMJ2F6YXW7CBE6YPW",\n' + ' "BTC": "12qdRgXxgNBNPnDeEChy3fYTbSHQ8nfZfD"\n' + ' }\n' + ' }\n' + ' $ stx convert_address SPA2MZWV9N67TBYVWTE0PSSKMJ2F6YXW7CBE6YPW -t\n' + ' {\n' + ' "mainnet": {\n' + ' "STACKS": "SPA2MZWV9N67TBYVWTE0PSSKMJ2F6YXW7CBE6YPW",\n' + ' "BTC": "12qdRgXxgNBNPnDeEChy3fYTbSHQ8nfZfD"\n' + ' },\n' + ' "testnet": {\n' + ' "STACKS": "STA2MZWV9N67TBYVWTE0PSSKMJ2F6YXW7DX96QAM",\n' + ' "BTC": "mhMaijcwVPcdAthFwmgLsaknTRt72GqQYo"\n' + ' }\n' + ' }\n' + ' $ stx convert_address STA2MZWV9N67TBYVWTE0PSSKMJ2F6YXW7DX96QAM\n' + ' {\n' + ' "mainnet": {\n' + ' "STACKS": "SPA2MZWV9N67TBYVWTE0PSSKMJ2F6YXW7CBE6YPW",\n' + ' "BTC": "12qdRgXxgNBNPnDeEChy3fYTbSHQ8nfZfD"\n' + ' },\n' + ' "testnet": {\n' + ' "STACKS": "STA2MZWV9N67TBYVWTE0PSSKMJ2F6YXW7DX96QAM",\n' + ' "BTC": "mhMaijcwVPcdAthFwmgLsaknTRt72GqQYo"\n' + ' }\n' + ' }\n' + '```\n', group: 'Account Management', }, decrypt_keychain: { type: 'array', items: [ { name: 'encrypted_backup_phrase', type: 'string', realtype: 'encrypted_backup_phrase', pattern: '^[^ ]+$', }, { name: 'password', type: 'string', realtype: 'password', pattern: '.+', }, ], minItems: 1, maxItems: 2, help: 'Decrypt an encrypted backup phrase with a password. Decrypts to a 12-word ' + 'backup phrase if done correctly. The password will be prompted if not given.\n' + '\n' + 'Example:\n' + '\n' + '```console\n' + ' $ # password is "asdf"\n' + ' $ stx decrypt_keychain "bfMDtOucUGcJXjZo6vkrZWgEzue9fzPsZ7A6Pl4LQuxLI1xsVF0VPgBkMsnSLCmYS5YHh7R3mNtMmX45Bq9sNGPfPsseQMR0fD9XaHi+tBg=\n' + ' Enter password:\n' + ' section amount spend resemble spray verify night immune tattoo best emotion parrot\n' + '```\n', group: 'Key Management', }, deploy_contract: { type: 'array', items: [ { name: 'source_file', type: 'string', realtype: 'path', pattern: '.+', }, { name: 'contract_name', type: 'string', realtype: 'string', pattern: '^[a-zA-Z]([a-zA-Z0-9]|[-_])*$', }, { name: 'fee', type: 'string', realtype: 'integer', pattern: '^[0-9]+$', }, { name: 'nonce', type: 'string', realtype: 'integer', pattern: '^[0-9]+$', }, { name: 'payment_key', type: 'string', realtype: 'private_key', pattern: `${exports.PRIVATE_KEY_PATTERN_ANY}`, }, ], minItems: 5, maxItems: 5, help: 'Deploys a Clarity smart contract on the network.\n' + '\n' + 'If the command succeeds, it prints out a transaction ID.' + '\n' + 'Example:\n' + '```console\n' + ' $ export PAYMENT="bfeffdf57f29b0cc1fab9ea197bb1413da2561fe4b83e962c7f02fbbe2b1cd5401"\n' + ' $ stx deploy_contract ./my_contract.clar my_contract 1 0 "$PAYMENT"\n' + ' {\n' + " txid: '0x2e33ad647a9cedacb718ce247967dc705bc0c878db899fdba5eae2437c6fa1e1'," + " transaction: 'https://explorer.hiro.so/txid/0x2e33ad647a9cedacb718ce247967dc705bc0c878db899fdba5eae2437c6fa1e1'" + ' }\n' + '```\n' + '\n', group: 'Account Management', }, docs: { type: 'array', items: [ { name: 'format', type: 'string', realtype: 'output_format', pattern: '^json$', }, ], minItems: 0, maxItems: 1, help: 'Dump the documentation for all commands as JSON to standard out.', group: 'CLI', }, encrypt_keychain: { type: 'array', items: [ { name: 'backup_phrase', type: 'string', realtype: 'backup_phrase', pattern: '.+', }, { name: 'password', type: 'string', realtype: 'password', pattern: '.+', }, ], minItems: 1, maxItems: 2, help: 'Encrypt a 12-word backup phrase, which can be decrypted later with the ' + '`decrypt_backup_phrase` command. The password will be prompted if not given.\n' + '\n' + 'Example:\n' + '\n' + '```console\n' + ' $ # password is "asdf"\n' + ' $ stx encrypt_keychain "section amount spend resemble spray verify night immune tattoo best emotion parrot"\n' + ' Enter password:\n' + ' Enter password again:\n' + ' M+DnBHYb1fgw4N3oZ+5uTEAua5bAWkgTW/SjmmBhGGbJtjOtqVV+RrLJEJOgT35hBon4WKdGWye2vTdgqDo7+HIobwJwkQtN2YF9g3zPsKk=' + '```\n', group: 'Key Management', }, faucet: { type: 'array', items: [ { name: 'address', type: 'string', realtype: 'address', pattern: `${exports.ADDRESS_PATTERN}|${exports.STACKS_ADDRESS_PATTERN}`, }, ], minItems: 1, maxItems: 1, help: 'Encrypt a 12-word backup phrase, which can be decrypted later with the ' + '`decrypt_backup_phrase` command. The password will be prompted if not given.\n' + '\n' + 'Example:\n' + '\n' + '```console\n' + ' $ # password is "asdf"\n' + ' $ blockstack-cli encrypt_keychain "section amount spend resemble spray verify night immune tattoo best emotion parrot"\n' + ' Enter password:\n' + ' Enter password again:\n' + ' M+DnBHYb1fgw4N3oZ+5uTEAua5bAWkgTW/SjmmBhGGbJtjOtqVV+RrLJEJOgT35hBon4WKdGWye2vTdgqDo7+HIobwJwkQtN2YF9g3zPsKk=' + '```\n', group: 'Key Management', }, gaia_dump_bucket: { type: 'array', items: [ { name: 'name_or_id_address', type: 'string', realtype: 'name_or_id_address', pattern: `${exports.ID_ADDRESS_PATTERN}|${exports.NAME_PATTERN}|${exports.SUBDOMAIN_PATTERN}`, }, { name: 'app_origin', type: 'string', realtype: 'url', pattern: exports.URL_PATTERN, }, { name: 'gaia_hub', type: 'string', realtype: 'url', pattern: exports.URL_PATTERN, }, { name: 'backup_phrase', type: 'string', realtype: '12_words_or_ciphertext', }, { name: 'dump_dir', type: 'string', realtype: 'path', pattern: '.+', }, ], minItems: 5, maxItems: 5, help: 'Download the contents of a Gaia hub bucket to a given directory. The `GAIA_HUB` argument ' + 'must correspond to the *write* endpoint of the Gaia hub -- that is, you should be able to fetch ' + '`$GAIA_HUB/hub_info`. If `DUMP_DIR` does not exist, it will be created.\n' + '\n' + 'Example:\n' + '\n' + '```console\n' + ' $ export BACKUP_PHRASE="section amount spend resemble spray verify night immune tattoo best emotion parrot\n' + ' $ stx gaia_dump_bucket hello.id.blockstack https://sample.app https://hub.blockstack.org "$BACKUP_PHRASE" ./backups\n' + ' Download 3 files...\n' + ' Download hello_world to ./backups/hello_world\n' + ' Download dir/format to ./backups/dir\\x2fformat\n' + ' Download /.dotfile to ./backups/\\x2f.dotfile\n' + ' 3\n' + '```\n', group: 'Gaia', }, gaia_getfile: { type: 'array', items: [ { name: 'blockstack_id', type: 'string', realtype: 'blockstack_id', pattern: `${exports.NAME_PATTERN}|${exports.SUBDOMAIN_PATTERN}$`, }, { name: 'app_origin', type: 'string', realtype: 'url', pattern: exports.URL_PATTERN, }, { name: 'filename', type: 'string', realtype: 'filename', pattern: '.+', }, { name: 'app_private_key', type: 'string', realtype: 'private_key', pattern: exports.PRIVATE_KEY_UNCOMPRESSED_PATTERN, }, { name: 'decrypt', type: 'string', realtype: 'boolean', pattern: exports.BOOLEAN_PATTERN, }, { name: 'verify', type: 'string', realtype: 'boolean', pattern: exports.BOOLEAN_PATTERN, }, ], minItems: 3, maxItems: 6, help: "Get a file from another user's Gaia hub. Prints the file data to stdout. If you " + 'want to read an encrypted file, and/or verify a signed file, then you must pass an app ' + 'private key, and pass 1 for `DECRYPT` and/or `VERIFY`. If the file is encrypted, and you do not ' + 'pass an app private key, then this command downloads the ciphertext. If the file is signed, ' + 'and you want to download its data and its signature, then you must run this command twice -- ' + 'once to get the file contents at `FILENAME`, and once to get the signature (whose name will be `FILENAME`.sig).\n' + '\n' + 'Gaia is a key-value store, so it does not have any built-in notion of directories. However, ' + 'most underlying storage systems do -- directory separators in the name of a file in ' + "Gaia may be internally treated as first-class directories (it depends on the Gaia hub's driver)." + 'As such, repeated directory separators will be treated as a single directory separator by this command. ' + 'For example, the file name `a/b.txt`, `/a/b.txt`, and `///a////b.txt` will be treated as identical.\n' + '\n' + 'Example without encryption:\n' + '\n' + '```console\n' + ' $ # Get an unencrypted, unsigned file\n' + ' $ stx gaia_getfile ryan.id http://public.ykliao.com statuses.json\n' + ' [{"id":0,"text":"Hello, Blockstack!","created_at":1515786983492}]\n' + '\n' + 'Example with encryption:\n' + '\n' + ' $ # Get an encrypted file without decrypting\n' + ' $ stx gaia_getfile ryan.id https://app.graphitedocs.com documentscollection.json\n' + ' ' + ' $ # Get an encrypted file, and decrypt it\n' + ' $ # Tip: You can obtain the app key with the get_app_keys command\n' + ' $ export APP_KEY="3ac770e8c3d88b1003bf4a0a148ceb920a6172bdade8e0325a1ed1480ab4fb19"\n' + ' $ stx gaia_getfile ryan.id https://app.graphitedocs.com documentscollection.json "$APP_KEY" 1 0\n' + '```\n', group: 'Gaia', }, gaia_putfile: { type: 'array', items: [ { name: 'gaia_hub', type: 'string', realtype: 'url', pattern: exports.URL_PATTERN, }, { name: 'app_private_key', type: 'string', realtype: 'private_key', pattern: exports.PRIVATE_KEY_UNCOMPRESSED_PATTERN, }, { name: 'data_path', type: 'string', realtype: 'path', pattern: '.+', }, { name: 'gaia_filename', type: 'string', realtype: 'filename', pattern: '.+', }, { name: 'encrypt', type: 'string', realtype: 'boolean', pattern: exports.BOOLEAN_PATTERN, }, { name: 'sign', type: 'string', realtype: 'boolean', pattern: exports.BOOLEAN_PATTERN, }, ], minItems: 4, maxItems: 6, help: 'Put a file into a given Gaia hub, authenticating with the given app private key. ' + 'Optionally encrypt and/or sign the data with the given app private key. If the file is ' + 'successfully stored, this command prints out the URLs at which it can be fetched.\n' + '\n' + 'Gaia is a key-value store, so it does not have any built-in notion of directories. However, ' + 'most underlying storage systems do -- directory separators in the name of a file in ' + "Gaia may be internally treated as first-class directories (it depends on the Gaia hub's driver)." + 'As such, repeated directory separators will be treated as a single directory separator by this command. ' + 'For example, the file name `a/b.txt`, `/a/b.txt`, and `///a////b.txt` will be treated as identical.\n' + '\n' + 'Example:\n' + '\n' + '```console\n' + ' $ # Store 4 versions of a file: plaintext, encrypted, signed, and encrypted+signed\n' + ' $ # Tip: You can obtain the app key with the get_app_keys command.\n' + ' $ export APP_KEY="3ac770e8c3d88b1003bf4a0a148ceb920a6172bdade8e0325a1ed1480ab4fb19"\n' + ' $ stx gaia_putfile https://hub.blockstack.org "$APP_KEY" /path/to/file.txt file.txt\n' + ' {\n' + ' "urls": "https://gaia.blockstack.org/hub/19KAzYp4kSKozeAGMUsnuqkEGdgQQLEvwo/file.txt"\n' + ' }\n' + ' $ stx gaia_putfile https://hub.blockstack.org "$APP_KEY" /path/to/file.txt file-encrypted.txt 1\n' + ' {\n' + ' "urls": "https://gaia.blockstack.org/hub/19KAzYp4kSKozeAGMUsnuqkEGdgQQLEvwo/file-encrypted.txt"\n' + ' }\n' + ' $ stx gaia_putfile https://hub.blockstack.org "$APP_KEY" /path/to/file.txt file-signed.txt 0 1\n' + ' {\n' + ' "urls": "https://gaia.blockstack.org/hub/19KAzYp4kSKozeAGMUsnuqkEGdgQQLEvwo/file-signed.txt"\n' + ' }\n' + ' $ stx gaia_putfile https://hub.blockstack.org "$APP_KEY" /path/to/file.txt file-encrypted-signed.txt 1 1\n' + ' {\n' + ' "urls": "https://gaia.blockstack.org/hub/19KAzYp4kSKozeAGMUsnuqkEGdgQQLEvwo/file-encrypted-signed.txt"\n' + ' }\n' + '```\n', group: 'Gaia', }, gaia_deletefile: { type: 'array', items: [ { name: 'gaia_hub', type: 'string', realtype: 'url', pattern: exports.URL_PATTERN, }, { name: 'app_private_key', type: 'string', realtype: 'private_key', pattern: exports.PRIVATE_KEY_UNCOMPRESSED_PATTERN, }, { name: 'gaia_filename', type: 'string', realtype: 'filename', pattern: '.+', }, { name: 'was_signed', type: 'string', realtype: 'boolean', pattern: exports.BOOLEAN_PATTERN, }, ], minItems: 3, maxItems: 4, help: 'Delete a file in a Gaia hub, as well as its signature metadata (which is stored in a separate file).' + '\n' + 'Example:\n' + '\n' + '```console\n' + ' $ # Tip: You can obtain the app key with the get_app_keys command.\n' + ' $ export APP_KEY="3ac770e8c3d88b1003bf4a0a148ceb920a6172bdade8e0325a1ed1480ab4fb19"\n' + ' $ stx gaia_deletefile https://hub.blockstack.org "$APP_KEY" file.txt false\n' + ' ok' + '```\n', group: 'Gaia', }, gaia_listfiles: { type: 'array', items: [ { name: 'gaia_hub', type: 'string', realtype: 'url', pattern: exports.URL_PATTERN, }, { name: 'app_private_key', type: 'string', realtype: 'private_key', pattern: exports.PRIVATE_KEY_UNCOMPRESSED_PATTERN, }, ], minItems: 2, maxItems: 3, help: 'List all the files in a Gaia hub bucket. You must have the private key for the bucket ' + 'in order to list its contents. The command prints each file name on its own line, and when ' + 'finished, it prints the number of files listed.\n' + '\n' + 'Example:\n' + '\n' + '```console\n' + ' $ # Tip: You can obtain the app key with the get_app_keys command.\n' + ' $ export APP_KEY="3ac770e8c3d88b1003bf4a0a148ceb920a6172bdade8e0325a1ed1480ab4fb19"\n' + ' $ stx gaia_listfiles "https://hub.blockstack.org" "$APP_KEY"\n' + ' hello_world\n' + ' dir/format\n' + ' /.dotfile\n' + ' 3\n' + '```\n', group: 'Gaia', }, gaia_restore_bucket: { type: 'array', items: [ { name: 'name_or_id_address', type: 'string', realtype: 'name_or_id_address', pattern: `${exports.ID_ADDRESS_PATTERN}|${exports.NAME_PATTERN}|${exports.SUBDOMAIN_PATTERN}`, }, { name: 'app_origin', type: 'string', realtype: 'url', pattern: exports.URL_PATTERN, }, { name: 'gaia_hub', type: 'string', realtype: 'url', pattern: exports.URL_PATTERN, }, { name: 'backup_phrase', type: 'string', realtype: '12_words_or_ciphertext', }, { name: 'dump_dir', type: 'string', realtype: 'path', pattern: '.+', }, ], minItems: 5, maxItems: 5, help: 'Upload the contents of a previously-dumped Gaia bucket to a new Gaia hub. The `GAIA_HUB` argument ' + 'must correspond to the *write* endpoint of the Gaia hub -- that is, you should be able to fetch ' + '`$GAIA_HUB/hub_info`. `DUMP_DIR` must contain the file contents created by a previous successful run of the gaia_dump_bucket command, ' + 'and both `NAME_OR_ID_ADDRESS` and `APP_ORIGIN` must be the same as they were when it was run.\n' + '\n' + 'Example:\n' + '\n' + '```console\n' + ' $ export BACKUP_PHRASE="section amount spend resemble spray verify night immune tattoo best emotion parrot"\n' + ' $ stx gaia_restore_bucket hello.id.blockstack https://sample.app https://new.gaia.hub "$BACKUP_PHRASE" ./backups\n' + ' Uploaded ./backups/hello_world to https://new.gaia.hub/hub/1Lr8ggSgdmfcb4764woYutUfFqQMjEoKHc/hello_world\n' + ' Uploaded ./backups/dir\\x2fformat to https://new.gaia.hub/hub/1Lr8ggSgdmfcb4764woYutUfFqQMjEoKHc/dir/format\n' + ' Uploaded ./backups/\\x2f.dotfile to https://new.gaia.hub/hub/1Lr8ggSgdmfcb4764woYutUfFqQMjEoKHc//.dotfile\n' + ' 3\n' + '```\n', group: 'Gaia', }, gaia_sethub: { type: 'array', items: [ { name: 'blockstack_id', type: 'string', realtype: 'blockstack_id', pattern: `^${exports.NAME_PATTERN}|${exports.SUBDOMAIN_PATTERN}$`, }, { name: 'owner_gaia_hub', type: 'string', realtype: 'url', pattern: exports.URL_PATTERN, }, { name: 'app_origin', type: 'string', realtype: 'url', pattern: exports.URL_PATTERN, }, { name: 'app_gaia_hub', type: 'string', realtype: 'url', pattern: exports.URL_PATTERN, }, { name: 'backup_phrase', type: 'string', realtype: '12_words_or_ciphertext', }, ], minItems: 5, maxItems: 5, help: 'Set the Gaia hub for a particular application for a Blockstack ID. If the command succeeds, ' + 'the URLs to your updated profile will be printed and your profile will contain an entry in its "apps" ' + 'key that links the given `APP_ORIGIN` to the given `APP_GAIA_HUB`.\n' + '\n' + 'NOTE: Both `OWNER_GAIA_HUB` and `APP_GAIA_HUB` must be the *write* endpoints of their respective Gaia hubs.\n' + '\n' + 'Your 12-word phrase (in either raw or encrypted form) is required to re-sign and store your ' + 'profile and to generate an app-specific key and Gaia bucket. If you give the encrypted backup phrase, you will be prompted for a password.\n' + '\n' + 'Example:\n' + '\n' + '```console\n' + ' $ export BACKUP_PHRASE="soap fog wealth upon actual blossom neither timber phone exile monkey vocal"\n' + ' $ stx gaia_sethub hello_world.id https://hub.blockstack.org https://my.cool.app https://my.app.gaia.hub "$BACKUP_PHRASE"\n' + ' {\n' + ' "profileUrls": {\n' + ' "error": null,\n' + ' "dataUrls": [\n' + ' "https://gaia.blockstack.org/hub/1ArdkA2oLaKnbNbLccBaFhEV4pYju8hJ82/profile.json"\n' + ' ]\n' + ' }\n' + ' }\n' + ' \n' + ' $ # You can check the new apps entry with curl and jq as follows:\n' + ' $ curl -sL https://gaia.blockstack.org/hub/1ArdkA2oLaKnbNbLccBaFhEV4pYju8hJ82/profile.json | jq ".[0].decodedToken.payload.claim.apps"\n' + ' {\n' + ' "https://my.cool.app": "https://my.app.gaia.hub/hub/1EqzyQLJ15KG1WQmi5cf1HtmSeqS1Wb8tY/"\n' + ' }\n' + '```\n' + '\n', group: 'Gaia', }, get_account_history: { type: 'array', items: [ { name: 'address', type: 'string', realtype: 'address', pattern: exports.STACKS_ADDRESS_PATTERN, }, { name: 'page', type: 'string', realtype: 'integer', pattern: '^[0-9]+$', }, ], minItems: 2, maxItems: 2, help: 'Query the history of account debits and credits over a given block range. ' + 'Returns the history one page at a time. An empty result indicates that the page ' + 'number has exceeded the number of historic operations in the given block range.\n' + '\n' + 'Example:\n' + '\n' + '```console\n' + ' $ stx get_account_history SP2H7VMY13ESQDAD5808QEY1EMGESMHZWBJRTN2YA 0\n' + ' [\n' + ' {\n' + ' "address": "SP2H7VMY13ESQDAD5808QEY1EMGESMHZWBJRTN2YA",\n' + ' "block_id": 56789\n' + ' "credit_value": "100000000000",\n' + ' "debit_value": "0",\n' + ' "lock_transfer_block_id": 0,\n' + ' "txid": "0e5db84d94adff5b771262b9df015164703b39bb4a70bf499a1602b858a0a5a1",\n' + ' "type": "STACKS",\n' + ' "vtxindex": 0\n' + ' },\n' + ' {\n' + ' "address": "SP2H7VMY13ESQDAD5808QEY1EMGESMHZWBJRTN2YA",\n' + ' "block_id": 56790,\n' + ' "credit_value": "100000000000",\n' + ' "debit_value": "64000000000",\n' + ' "lock_transfer_block_id": 0,\n' + ' "txid": "5a0c67144626f7bd4514e4de3f3bbf251383ca13887444f326bac4bc8b8060ee",\n' + ' "type": "STACKS",\n' + ' "vtxindex": 1\n' + ' },\n' + ' {\n' + ' "address": "SP2H7VMY13ESQDAD5808QEY1EMGESMHZWBJRTN2YA",\n' + ' "block_id": 56791,\n' + ' "credit_value": "100000000000",\n' + ' "debit_value": "70400000000",\n' + ' "lock_transfer_block_id": 0,\n' + ' "txid": "e54c271d6a9feb4d1859d32bc99ffd713493282adef5b4fbf50bca9e33fc0ecc",\n' + ' "type": "STACKS",\n' + ' "vtxindex": 2\n' + ' },\n' + ' {\n' + ' "address": "SP2H7VMY13ESQDAD5808QEY1EMGESMHZWBJRTN2YA",\n' + ' "block_id": 56792,\n' + ' "credit_value": "100000000000",\n' + ' "debit_value": "76800000000",\n' + ' "lock_transfer_block_id": 0,\n' + ' "txid": "06e0d313261baefec1e59783e256ab487e17e0e776e2fdab0920cc624537e3c8",\n' + ' "type": "STACKS",\n' + ' "vtxindex": 3\n' + ' }\n' + ' ]\n' + '```\n' + '\n', group: 'Account Management', }, get_account_at: { type: 'array', items: [ { name: 'address', type: 'string', r