hood-cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/program.ts","../src/commands/price.ts","../src/context.ts","../src/config.ts","../src/errors.ts","../src/keystore.ts","../src/prompt.ts","../src/ui/ansi.ts","../src/output.ts","../src/action.ts","../src/prices.ts","../src/resolve.ts","../src/ui/table.ts","../src/ui/live.ts","../src/ui/spinner.ts","../src/format.ts","../src/commands/stocks.ts","../src/pmap.ts","../src/commands/coins.ts","../src/commands/launches.ts","../src/commands/portfolio.ts","../src/commands/tx.ts","../src/blockscout.ts","../src/commands/token.ts","../src/commands/watch.ts","../src/commands/swap.ts","../src/spend-cap.ts","../src/commands/transfer.ts","../src/commands/faucet.ts","../src/commands/deploy-token.ts","../src/generated/erc20.ts","../src/commands/config.ts","../src/cli.ts"],"sourcesContent":["/**\n * Program construction, separated from `cli.ts`'s execution so tests can\n * introspect the option/command wiring without triggering a real parse (and\n * its network calls) as a side effect of importing the module.\n */\nimport { Command } from 'commander'\nimport { readFileSync } from 'node:fs'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, join } from 'node:path'\nimport { priceCommand } from './commands/price.js'\nimport { stocksCommand } from './commands/stocks.js'\nimport { coinsCommand } from './commands/coins.js'\nimport { launchesCommand } from './commands/launches.js'\nimport { portfolioCommand } from './commands/portfolio.js'\nimport { txCommand } from './commands/tx.js'\nimport { tokenCommand } from './commands/token.js'\nimport { watchCommand } from './commands/watch.js'\nimport { swapCommand } from './commands/swap.js'\nimport { transferCommand } from './commands/transfer.js'\nimport { faucetCommand } from './commands/faucet.js'\nimport { deployTokenCommand } from './commands/deploy-token.js'\nimport { configCommand } from './commands/config.js'\n\nfunction readVersion(): string {\n const here = dirname(fileURLToPath(import.meta.url))\n const pkg = JSON.parse(readFileSync(join(here, '..', 'package.json'), 'utf8')) as { version: string }\n return pkg.version\n}\n\n/** Build the fully-wired `hood` commander program (does not parse or run). */\nexport function createProgram(): Command {\n const program = new Command()\n\n program\n .name('hood')\n .description('The command-line toolkit for Robinhood Chain (4663) — instant reads, guarded writes.')\n .version(readVersion(), '-v, --version')\n .option('--json', 'machine-readable JSON output')\n .option('--network <net>', 'mainnet | testnet', 'mainnet')\n .option('--rpc <url>', 'override the RPC endpoint')\n .option('--verbose', 'show raw error causes')\n .option('--yes', 'skip interactive confirmation on writes (still requires --execute)')\n .option('--acknowledge-eligibility', 'affirm Stock Token acquisition eligibility (non-US/CA/UK/CH)')\n .option('--no-color', 'disable ANSI colour')\n .showHelpAfterError('(run `hood --help` for usage)')\n .configureOutput({\n outputError: (str, write) => write(str),\n })\n\n program.addCommand(priceCommand())\n program.addCommand(stocksCommand())\n program.addCommand(coinsCommand())\n program.addCommand(launchesCommand())\n program.addCommand(portfolioCommand())\n program.addCommand(txCommand())\n program.addCommand(tokenCommand())\n program.addCommand(watchCommand())\n program.addCommand(swapCommand())\n program.addCommand(transferCommand())\n program.addCommand(faucetCommand())\n program.addCommand(deployTokenCommand())\n program.addCommand(configCommand())\n\n return program\n}\n","import { Command } from 'commander'\nimport { getStockToken } from 'hoodchain'\nimport { runWith } from '../action.js'\nimport type { Context } from '../context.js'\nimport { getPriceRow, type PriceRow } from '../prices.js'\nimport { resolveToken } from '../resolve.js'\nimport { printResult } from '../output.js'\nimport { renderKeyValue } from '../ui/table.js'\nimport { liveRegion } from '../ui/live.js'\nimport { withSpinner } from '../ui/spinner.js'\nimport { accent, bold, dim, gray } from '../ui/ansi.js'\nimport { usd, pct, age, addr } from '../format.js'\nimport { EXIT } from '../errors.js'\n\nexport function priceCommand(): Command {\n return new Command('price')\n .description('Chainlink oracle price + DEX price + premium for a Stock Token')\n .argument('<symbol>', 'ticker (AAPL) or token address')\n .option('--watch', 'live-updating view (repaints in place)', false)\n .option('--interval <ms>', 'refresh interval for --watch', '4000')\n .option('--max-age <seconds>', 'max acceptable Chainlink answer age')\n .option('--no-dex', 'skip the Uniswap price probe (oracle only)')\n .action((symbol: string, opts, command) =>\n runWith(command, async (ctx) => {\n await price(ctx, symbol, opts)\n }),\n )\n}\n\ninterface PriceOpts {\n watch: boolean\n interval: string\n maxAge?: string\n dex: boolean\n}\n\nasync function price(ctx: Context, symbol: string, opts: PriceOpts): Promise<void> {\n const client = ctx.read()\n const token = await resolveToken(client, symbol)\n const maxAgeSeconds = opts.maxAge ? Number(opts.maxAge) : undefined\n\n const fetchRow = () =>\n getPriceRow(client, token.symbol, token.address, {\n maxAgeSeconds,\n withDex: opts.dex,\n decimals: token.decimals,\n })\n\n if (!opts.watch) {\n const row = await withSpinner(`Pricing ${token.symbol}…`, () => fetchRow())\n printResult(row, () => renderPrice(row, token.symbol, ctx.network), ctx.json)\n if (row.oracleUsd === null && row.dexUsd === null) process.exitCode = EXIT.NOT_FOUND\n return\n }\n\n // --watch: repaint in place. JSON mode streams one object per tick.\n const interval = Math.max(1000, Number(opts.interval) || 4000)\n const region = liveRegion()\n const tick = async () => {\n try {\n const row = await fetchRow()\n if (ctx.json) process.stdout.write(JSON.stringify(row, (_k, v) => (typeof v === 'bigint' ? v.toString() : v)) + '\\n')\n else region.render(renderPrice(row, token.symbol, ctx.network, true))\n } catch {\n /* transient RPC hiccup — keep the last frame, retry next tick */\n }\n }\n await tick()\n const timer = setInterval(tick, interval)\n const shutdown = () => {\n clearInterval(timer)\n region.stop()\n process.exit(0)\n }\n process.on('SIGINT', shutdown)\n process.on('SIGTERM', shutdown)\n await new Promise(() => {}) // run until interrupted\n}\n\nfunction renderPrice(row: PriceRow, symbol: string, network: string, watch = false): string {\n const pairs: [string, string][] = []\n pairs.push(['Oracle', row.oracleUsd !== null ? bold(usd(row.oracleUsd)) : dim('no fresh feed')])\n if (row.oracleAgeSeconds !== null) pairs.push(['Updated', dim(age(row.oracleAgeSeconds) + ' ago')])\n pairs.push(['DEX', row.dexUsd !== null ? usd(row.dexUsd) : dim('no pool')])\n pairs.push(['Premium', row.premium !== null ? pct(row.premium) : dim('—')])\n pairs.push(['Token', gray(addr(row.address))])\n\n const header = `${accent('◈')} ${bold(symbol)} ${dim('· Robinhood Chain ' + network)}`\n const foot = watch ? '\\n' + dim(' ⟳ live · Ctrl-C to stop') : ''\n return `${header}\\n${renderKeyValue(pairs, { labelWidth: 8 })}${foot}`\n}\n","/**\n * Runtime context shared by every command: resolved network, RPC, output mode,\n * and lazy read/wallet clients built from config + global flags.\n */\nimport { createHoodClient, type HoodClient, type HoodNetwork } from 'hoodchain'\nimport { privateKeyToAccount } from 'viem/accounts'\nimport { http, isHex } from 'viem'\nimport { loadConfig, defaultKeystorePath, type HoodConfig } from './config.js'\nimport { decryptKeystore, keystoreExists } from './keystore.js'\nimport { readPassword } from './prompt.js'\nimport { walletError } from './errors.js'\n\n/** Global flags parsed by commander and threaded into every command. */\nexport interface GlobalOptions {\n json?: boolean\n network?: HoodNetwork\n rpc?: string\n verbose?: boolean\n yes?: boolean\n acknowledgeEligibility?: boolean\n}\n\nexport interface Context {\n config: HoodConfig\n network: HoodNetwork\n json: boolean\n verbose: boolean\n /** `--yes`: skip the interactive confirm on writes (still requires `--execute`). */\n assumeYes: boolean\n /** `--acknowledge-eligibility`: operator affirms non-US Stock-Token eligibility. */\n acknowledgeEligibility: boolean\n /** A read-only client (cached). */\n read(): HoodClient\n /** A wallet-backed client (loads + decrypts the key on first use). */\n wallet(): Promise<HoodClient>\n /** The resolved RPC URL, if any (else the SDK public default). */\n rpcUrl?: string\n}\n\n/** Resolve the RPC URL from flags → config → SDK default (undefined). */\nexport function resolveRpcUrl(config: HoodConfig, network: HoodNetwork, override?: string): string | undefined {\n if (override) return override\n if (network === 'testnet') return config.testnetRpc\n if (config.alchemyKey) return `https://robinhood-mainnet.g.alchemy.com/v2/${config.alchemyKey}`\n return config.rpc\n}\n\n/**\n * The public RPC throttles bursty callers (log scans, wide multicalls) with\n * 429s. viem's http() default retry (3 attempts, ~150ms base) gives up too\n * fast for that — widen it so `hood stocks` / `hood launches` ride out a\n * rate-limit window instead of surfacing a network error to the user.\n */\nfunction buildTransport(rpcUrl?: string) {\n return http(rpcUrl, { retryCount: 5, retryDelay: 500, timeout: 20_000 })\n}\n\n/** Build the shared context from the global flags. */\nexport function createContext(opts: GlobalOptions): Context {\n const config = loadConfig()\n const network: HoodNetwork = opts.network ?? config.network ?? 'mainnet'\n const rpcUrl = resolveRpcUrl(config, network, opts.rpc)\n\n let readClient: HoodClient | null = null\n let walletClient: HoodClient | null = null\n\n return {\n config,\n network,\n json: !!opts.json,\n verbose: !!opts.verbose,\n assumeYes: !!opts.yes,\n acknowledgeEligibility: !!opts.acknowledgeEligibility,\n rpcUrl,\n read() {\n if (!readClient) {\n readClient = createHoodClient({ chain: network, transport: buildTransport(rpcUrl) })\n }\n return readClient\n },\n async wallet() {\n if (walletClient) return walletClient\n const account = await loadAccount(config)\n walletClient = createHoodClient({\n chain: network,\n transport: buildTransport(rpcUrl),\n account,\n acknowledgeStockTokenEligibility: !!opts.acknowledgeEligibility,\n })\n return walletClient\n },\n }\n}\n\n/**\n * Resolve the signing account. Precedence:\n * 1. `ROBINHOOD_CHAIN_PRIVATE_KEY` env var (CI / power users).\n * 2. The encrypted keystore configured with `hood config set wallet`.\n */\nasync function loadAccount(config: HoodConfig) {\n const envKey = process.env.ROBINHOOD_CHAIN_PRIVATE_KEY\n if (envKey) {\n const key = envKey.startsWith('0x') ? envKey : `0x${envKey}`\n if (!isHex(key) || key.length !== 66) {\n throw walletError('ROBINHOOD_CHAIN_PRIVATE_KEY is not a valid 32-byte hex key.')\n }\n return privateKeyToAccount(key as `0x${string}`)\n }\n\n const keystorePath = config.walletKeystore ?? defaultKeystorePath()\n if (!keystoreExists(keystorePath)) {\n throw walletError('No wallet configured.', 'Run `hood config set wallet`, or set ROBINHOOD_CHAIN_PRIVATE_KEY.')\n }\n const password = await readPassword()\n const privateKey = decryptKeystore(keystorePath, password)\n return privateKeyToAccount(privateKey)\n}\n","/**\n * Persistent CLI config. Stored as JSON at `$HOOD_CONFIG_DIR` or\n * `~/.config/hood/config.json`. NEVER holds a private key — the wallet lives in\n * a separate password-encrypted keystore (see `keystore.ts`).\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport { usageError } from './errors.js'\n\nexport interface HoodConfig {\n /** Default network for every command. @defaultValue 'mainnet' */\n network?: 'mainnet' | 'testnet'\n /** Custom mainnet RPC URL. */\n rpc?: string\n /** Custom testnet RPC URL. */\n testnetRpc?: string\n /** Alchemy API key — builds `https://robinhood-mainnet.g.alchemy.com/v2/{key}`. */\n alchemyKey?: string\n /** Path to the encrypted wallet keystore. */\n walletKeystore?: string\n /** Cached wallet address for display (never the key). */\n walletAddress?: string\n /** Hard USD spend cap for a single swap/transfer (guard rail). */\n maxSpendUsd?: number\n}\n\n/** The set of keys a user may `hood config set`. `wallet` is handled specially. */\nexport const CONFIG_KEYS = ['network', 'rpc', 'testnetRpc', 'alchemyKey', 'maxSpendUsd'] as const\n\nexport function configDir(): string {\n return process.env.HOOD_CONFIG_DIR ?? join(homedir(), '.config', 'hood')\n}\n\nexport function configPath(): string {\n return join(configDir(), 'config.json')\n}\n\nexport function defaultKeystorePath(): string {\n return join(configDir(), 'keystore.json')\n}\n\n/** Read the config, returning `{}` when none exists. */\nexport function loadConfig(): HoodConfig {\n const path = configPath()\n if (!existsSync(path)) return {}\n try {\n return JSON.parse(readFileSync(path, 'utf8')) as HoodConfig\n } catch (err) {\n throw usageError(`Config at ${path} is not valid JSON.`, 'Delete it or fix it by hand.')\n }\n}\n\n/** Persist the config, creating the directory (0700) on first write. */\nexport function saveConfig(config: HoodConfig): void {\n const path = configPath()\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 })\n writeFileSync(path, JSON.stringify(config, null, 2) + '\\n', { mode: 0o600 })\n}\n\n/** Validate + coerce a `config set <key> <value>` pair. */\nexport function setConfigValue(config: HoodConfig, key: string, value: string): HoodConfig {\n const next = { ...config }\n switch (key) {\n case 'network':\n if (value !== 'mainnet' && value !== 'testnet') throw usageError('network must be \"mainnet\" or \"testnet\".')\n next.network = value\n break\n case 'rpc':\n next.rpc = value\n break\n case 'testnetRpc':\n next.testnetRpc = value\n break\n case 'alchemyKey':\n next.alchemyKey = value\n break\n case 'maxSpendUsd': {\n const n = Number(value)\n if (!Number.isFinite(n) || n < 0) throw usageError('maxSpendUsd must be a non-negative number.')\n next.maxSpendUsd = n\n break\n }\n default:\n throw usageError(`Unknown config key \"${key}\".`, `Valid keys: ${CONFIG_KEYS.join(', ')}, wallet.`)\n }\n return next\n}\n\n/** A redacted view of the config for `config list` (masks the alchemy key). */\nexport function redactedConfig(config: HoodConfig): Record<string, unknown> {\n return {\n network: config.network ?? 'mainnet',\n rpc: config.rpc ?? null,\n testnetRpc: config.testnetRpc ?? null,\n alchemyKey: config.alchemyKey ? maskKey(config.alchemyKey) : null,\n walletAddress: config.walletAddress ?? null,\n walletKeystore: config.walletKeystore ?? (config.walletAddress ? defaultKeystorePath() : null),\n maxSpendUsd: config.maxSpendUsd ?? null,\n }\n}\n\nfunction maskKey(key: string): string {\n if (key.length <= 6) return '••••'\n return `${key.slice(0, 3)}…${key.slice(-3)}`\n}\n","/**\n * CLI error model. Every failure carries a meaningful exit code and a\n * human-first message; `--verbose` surfaces the raw cause underneath.\n */\n\n/** Meaningful, documented process exit codes. */\nexport const EXIT = {\n OK: 0,\n /** Generic runtime failure. */\n ERROR: 1,\n /** Bad usage / invalid arguments. */\n USAGE: 2,\n /** Network / RPC unreachable or timed out. */\n NETWORK: 3,\n /** A guard rail refused the action (eligibility, spend cap, unconfirmed). */\n GUARD: 4,\n /** The requested resource was not found (unknown symbol, missing tx). */\n NOT_FOUND: 5,\n /** Wallet required but not configured / wrong password. */\n WALLET: 6,\n} as const\n\nexport type ExitCode = (typeof EXIT)[keyof typeof EXIT]\n\n/** An error the CLI knows how to present: message + exit code + optional hint. */\nexport class CliError extends Error {\n readonly exitCode: ExitCode\n readonly hint?: string\n override readonly cause?: unknown\n\n constructor(message: string, options: { exitCode?: ExitCode; hint?: string; cause?: unknown } = {}) {\n super(message)\n this.name = 'CliError'\n this.exitCode = options.exitCode ?? EXIT.ERROR\n this.hint = options.hint\n this.cause = options.cause\n }\n}\n\n/** Convenience constructors. */\nexport const usageError = (m: string, hint?: string) => new CliError(m, { exitCode: EXIT.USAGE, hint })\nexport const guardError = (m: string, hint?: string) => new CliError(m, { exitCode: EXIT.GUARD, hint })\nexport const notFoundError = (m: string, hint?: string) => new CliError(m, { exitCode: EXIT.NOT_FOUND, hint })\nexport const walletError = (m: string, hint?: string) => new CliError(m, { exitCode: EXIT.WALLET, hint })\n\n/**\n * Map an unknown thrown value (SDK error, viem error, network error) to a\n * CliError with a human message. Preserves the original as `cause`.\n */\nexport function toCliError(err: unknown): CliError {\n if (err instanceof CliError) return err\n const message = err instanceof Error ? err.message : String(err)\n const name = err instanceof Error ? err.name : ''\n\n // hoodchain SDK errors carry a stable `name`.\n switch (name) {\n case 'UnknownSymbolError':\n return new CliError(message, { exitCode: EXIT.NOT_FOUND, cause: err, hint: 'Run `hood stocks` to list every Stock Token symbol.' })\n case 'FeedNotFoundError':\n return new CliError(message, { exitCode: EXIT.NOT_FOUND, cause: err, hint: 'This token has no Chainlink feed — try `hood token <address>` for on-chain data.' })\n case 'StaleFeedError':\n return new CliError(message, { exitCode: EXIT.ERROR, cause: err, hint: 'Stock feeds pause outside market hours (24/5). Pass --max-age to widen the window.' })\n case 'NoRouteError':\n return new CliError(message, { exitCode: EXIT.NOT_FOUND, cause: err, hint: 'No Uniswap v3 pool with liquidity connects these tokens on this network.' })\n case 'StockTokenEligibilityError':\n return new CliError('Stock Token acquisition is gated.', {\n exitCode: EXIT.GUARD,\n cause: err,\n hint: 'Stock Tokens are tokenized securities and may not be sold to US persons. Re-run with --acknowledge-eligibility if you are eligible.',\n })\n case 'NoAccountError':\n return new CliError('This action needs a wallet.', {\n exitCode: EXIT.WALLET,\n cause: err,\n hint: 'Configure one with `hood config set wallet`, or set ROBINHOOD_CHAIN_PRIVATE_KEY.',\n })\n case 'FeedConnectionError':\n return new CliError(message, { exitCode: EXIT.NETWORK, cause: err })\n }\n\n // viem / transport network failures.\n if (/fetch failed|ECONNREFUSED|ETIMEDOUT|ENOTFOUND|socket hang up|network|timeout/i.test(message)) {\n return new CliError('Could not reach the Robinhood Chain RPC.', {\n exitCode: EXIT.NETWORK,\n cause: err,\n hint: 'Check your connection, or set a custom RPC with `hood config set rpc <url>`.',\n })\n }\n\n return new CliError(message, { exitCode: EXIT.ERROR, cause: err })\n}\n","/**\n * Password-encrypted wallet keystore. The private key is encrypted with\n * AES-256-GCM under a scrypt-derived key and written to disk; the plaintext key\n * never touches the config or the filesystem. This is the same primitive set as\n * the Web3 Secret Storage spec (scrypt KDF + authenticated cipher), kept\n * minimal and dependency-free on Node's built-in `crypto`.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { randomBytes, scryptSync, createCipheriv, createDecipheriv, timingSafeEqual } from 'node:crypto'\nimport { walletError } from './errors.js'\n\ninterface KeystoreFile {\n version: 1\n address: `0x${string}`\n kdf: 'scrypt'\n kdfparams: { N: number; r: number; p: number; keylen: number; salt: string }\n cipher: 'aes-256-gcm'\n iv: string\n ciphertext: string\n tag: string\n}\n\nconst SCRYPT = { N: 1 << 15, r: 8, p: 1, keylen: 32 } as const\n\nfunction deriveKey(password: string, salt: Buffer): Buffer {\n // maxmem raised so N=2^15 doesn't hit the default 32MB ceiling.\n return scryptSync(password, salt, SCRYPT.keylen, {\n N: SCRYPT.N,\n r: SCRYPT.r,\n p: SCRYPT.p,\n maxmem: 128 * 1024 * 1024,\n })\n}\n\n/** Encrypt a private key under `password` and write the keystore to `path`. */\nexport function writeKeystore(path: string, privateKey: `0x${string}`, address: `0x${string}`, password: string): void {\n if (password.length < 8) throw walletError('Wallet password must be at least 8 characters.')\n const salt = randomBytes(32)\n const iv = randomBytes(12)\n const key = deriveKey(password, salt)\n const cipher = createCipheriv('aes-256-gcm', key, iv)\n const plaintext = Buffer.from(privateKey.replace(/^0x/, ''), 'hex')\n const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()])\n const tag = cipher.getAuthTag()\n\n const file: KeystoreFile = {\n version: 1,\n address,\n kdf: 'scrypt',\n kdfparams: { ...SCRYPT, salt: salt.toString('hex') },\n cipher: 'aes-256-gcm',\n iv: iv.toString('hex'),\n ciphertext: ciphertext.toString('hex'),\n tag: tag.toString('hex'),\n }\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 })\n writeFileSync(path, JSON.stringify(file, null, 2) + '\\n', { mode: 0o600 })\n}\n\n/** Read the address a keystore holds without decrypting it. */\nexport function keystoreAddress(path: string): `0x${string}` {\n const file = readKeystoreFile(path)\n return file.address\n}\n\n/** Decrypt the private key from a keystore. Throws on a wrong password. */\nexport function decryptKeystore(path: string, password: string): `0x${string}` {\n const file = readKeystoreFile(path)\n const salt = Buffer.from(file.kdfparams.salt, 'hex')\n const key = deriveKey(password, salt)\n const decipher = createDecipheriv('aes-256-gcm', key, Buffer.from(file.iv, 'hex'))\n decipher.setAuthTag(Buffer.from(file.tag, 'hex'))\n try {\n const plaintext = Buffer.concat([\n decipher.update(Buffer.from(file.ciphertext, 'hex')),\n decipher.final(),\n ])\n return `0x${plaintext.toString('hex')}`\n } catch {\n throw walletError('Wrong wallet password.', 'The keystore could not be decrypted.')\n }\n}\n\n/** Constant-time equality helper (used when confirming a password twice). */\nexport function passwordsMatch(a: string, b: string): boolean {\n const ba = Buffer.from(a)\n const bb = Buffer.from(b)\n if (ba.length !== bb.length) return false\n return timingSafeEqual(ba, bb)\n}\n\nexport function keystoreExists(path: string): boolean {\n return existsSync(path)\n}\n\nfunction readKeystoreFile(path: string): KeystoreFile {\n if (!existsSync(path)) throw walletError(`No keystore at ${path}.`, 'Create one with `hood config set wallet`.')\n try {\n const file = JSON.parse(readFileSync(path, 'utf8')) as KeystoreFile\n if (file.version !== 1 || file.cipher !== 'aes-256-gcm') throw new Error('unsupported keystore')\n return file\n } catch (err) {\n if (err instanceof Error && err.name === 'CliError') throw err\n throw walletError(`Keystore at ${path} is corrupt or unsupported.`)\n }\n}\n","/**\n * Interactive prompts on the controlling TTY: a yes/no confirm gate and a\n * hidden password reader. Both read from `/dev/tty`-equivalent stdin so they\n * work even when stdout is piped, and both fail closed on a non-interactive\n * stdin (a script must pass explicit flags rather than hang).\n */\nimport { createInterface } from 'node:readline'\nimport { bold, dim, yellow } from './ui/ansi.js'\nimport { guardError } from './errors.js'\n\n/** Whether we can prompt (stdin is a TTY). */\nexport function canPrompt(): boolean {\n return !!process.stdin.isTTY\n}\n\n/**\n * Ask a yes/no question. Returns true only on an explicit yes. On a\n * non-interactive stdin it throws a guard error rather than blocking.\n */\nexport async function confirm(question: string): Promise<boolean> {\n if (!canPrompt()) {\n throw guardError('Confirmation required but stdin is not a terminal.', 'Re-run in an interactive shell, or pass --yes to skip the prompt.')\n }\n const rl = createInterface({ input: process.stdin, output: process.stderr })\n try {\n const answer = await new Promise<string>((resolve) => {\n rl.question(`${yellow('?')} ${bold(question)} ${dim('[y/N]')} `, resolve)\n })\n return /^y(es)?$/i.test(answer.trim())\n } finally {\n rl.close()\n }\n}\n\n/**\n * Read a password without echoing it. Falls back to the env var when provided\n * so automation never has to type into a TTY.\n */\nexport async function readPassword(label = 'Wallet password:', envVar = 'HOOD_WALLET_PASSWORD'): Promise<string> {\n const fromEnv = process.env[envVar]\n if (fromEnv) return fromEnv\n if (!canPrompt()) {\n throw guardError('A wallet password is required.', `Set ${envVar} or run in an interactive terminal.`)\n }\n\n return new Promise<string>((resolve, reject) => {\n const stdin = process.stdin\n process.stderr.write(`${dim(label)} `)\n stdin.setRawMode?.(true)\n stdin.resume()\n stdin.setEncoding('utf8')\n\n let value = ''\n const onData = (chunk: string) => {\n for (const ch of chunk) {\n if (ch === '\\n' || ch === '\\r' || ch === '\u0004') {\n cleanup()\n process.stderr.write('\\n')\n resolve(value)\n return\n }\n if (ch === '\u0003') {\n // Ctrl-C\n cleanup()\n process.stderr.write('\\n')\n reject(guardError('Aborted.'))\n return\n }\n if (ch === '' || ch === '\\b') {\n value = value.slice(0, -1)\n } else {\n value += ch\n }\n }\n }\n const cleanup = () => {\n stdin.setRawMode?.(false)\n stdin.pause()\n stdin.removeListener('data', onData)\n }\n stdin.on('data', onData)\n })\n}\n","/**\n * Chalk-free ANSI styling. Small, dependency-free, and TTY-aware.\n *\n * Colour is enabled when stdout is a TTY, `NO_COLOR` is unset, and the\n * terminal is not `dumb`. `--no-color` (or a non-TTY pipe) forces plain text,\n * so `hood ... --json | jq` and log files stay clean. `FORCE_COLOR=1`\n * overrides the TTY check (the same convention chalk/supports-color use) —\n * used by the docs session-capture script to record a colourised transcript\n * from a piped subprocess.\n */\n\nlet colorEnabled = process.env.FORCE_COLOR\n ? process.env.FORCE_COLOR !== '0'\n : !!process.stdout.isTTY && !process.env.NO_COLOR && process.env.TERM !== 'dumb'\n\n/** Force colour on or off (wired to the global `--no-color` flag). */\nexport function setColorEnabled(enabled: boolean): void {\n colorEnabled = enabled\n}\n\n/** Whether ANSI colour is currently active. */\nexport function colorIsEnabled(): boolean {\n return colorEnabled\n}\n\nconst wrap = (open: number, close: number) => (s: string | number): string =>\n colorEnabled ? `\\x1b[${open}m${s}\\x1b[${close}m` : String(s)\n\nexport const bold = wrap(1, 22)\nexport const dim = wrap(2, 22)\nexport const italic = wrap(3, 23)\nexport const underline = wrap(4, 24)\n\nexport const red = wrap(31, 39)\nexport const green = wrap(32, 39)\nexport const yellow = wrap(33, 39)\nexport const blue = wrap(34, 39)\nexport const magenta = wrap(35, 39)\nexport const cyan = wrap(36, 39)\nexport const white = wrap(37, 39)\nexport const gray = wrap(90, 39)\n\n/** The one brand accent — a warm gradient rendered as 256-colour when able. */\nexport function accent(s: string): string {\n return colorEnabled ? `\\x1b[38;5;79m${s}\\x1b[39m` : s\n}\n\n/** Strip every ANSI escape from a string (for width math and non-TTY output). */\nexport function stripAnsi(s: string): string {\n // eslint-disable-next-line no-control-regex\n return s.replace(/\\x1b\\[[0-9;]*m/g, '')\n}\n\n/** Visible width of a string, ignoring ANSI escapes. */\nexport function width(s: string): string['length'] {\n return stripAnsi(s).length\n}\n\n/** Pad `s` to `len` visible columns (ANSI-aware). */\nexport function padEnd(s: string, len: number): string {\n const w = width(s)\n return w >= len ? s : s + ' '.repeat(len - w)\n}\n\n/** Right-align `s` to `len` visible columns (ANSI-aware). */\nexport function padStart(s: string, len: number): string {\n const w = width(s)\n return w >= len ? s : ' '.repeat(len - w) + s\n}\n\n/** Truncate to `len` visible columns with an ellipsis (ANSI-unaware — use on plain text). */\nexport function truncate(s: string, len: number): string {\n if (s.length <= len) return s\n if (len <= 1) return s.slice(0, len)\n return s.slice(0, len - 1) + '…'\n}\n","/**\n * Output boundary: every command prints through here so `--json` is uniform,\n * exit codes are consistent, and errors get a human message + optional hint.\n */\nimport { bold, dim, red, yellow } from './ui/ansi.js'\nimport { CliError, EXIT, toCliError } from './errors.js'\n\n/** Serialise bigints so `JSON.stringify` never throws on chain data. */\nfunction jsonReplacer(_key: string, value: unknown): unknown {\n return typeof value === 'bigint' ? value.toString() : value\n}\n\n/** Print a machine-readable JSON payload to stdout. */\nexport function printJson(data: unknown): void {\n process.stdout.write(JSON.stringify(data, jsonReplacer, 2) + '\\n')\n}\n\n/** Print a human-facing string block to stdout. */\nexport function printHuman(block: string): void {\n process.stdout.write(block + '\\n')\n}\n\n/**\n * Print a result either as JSON (`--json`) or via the human renderer.\n * `json` is the structured payload; `human` renders the same data for a person.\n */\nexport function printResult(json: unknown, human: () => string, asJson: boolean): void {\n if (asJson) printJson(json)\n else printHuman(human())\n}\n\n/** A dim note to stderr (never pollutes stdout / JSON). */\nexport function note(message: string): void {\n process.stderr.write(dim(message) + '\\n')\n}\n\n/** A warning to stderr. */\nexport function warn(message: string): void {\n process.stderr.write(yellow('! ' + message) + '\\n')\n}\n\n/**\n * Present a fatal error and return its exit code. Honours `--json` (emits a\n * `{ error, hint }` object) and `--verbose` (appends the raw cause).\n */\nexport function presentError(err: unknown, opts: { json: boolean; verbose: boolean }): number {\n const cli: CliError = toCliError(err)\n if (opts.json) {\n printJson({ error: cli.message, hint: cli.hint ?? null, exitCode: cli.exitCode })\n } else {\n process.stderr.write(red(bold('✗ ') + cli.message) + '\\n')\n if (cli.hint) process.stderr.write(dim(' ' + cli.hint) + '\\n')\n if (opts.verbose && cli.cause) {\n const cause = cli.cause instanceof Error ? (cli.cause.stack ?? cli.cause.message) : String(cli.cause)\n process.stderr.write(dim('\\n' + cause) + '\\n')\n } else if (cli.cause && cli.exitCode !== EXIT.GUARD) {\n process.stderr.write(dim(' Run with --verbose for the raw cause.') + '\\n')\n }\n }\n return cli.exitCode\n}\n","/**\n * Bridges commander actions to the CLI runtime: resolves global flags, builds\n * the shared context, honours `--no-color`, and funnels every thrown error\n * through the single presenter so exit codes stay consistent.\n */\nimport type { Command } from 'commander'\nimport { createContext, type Context, type GlobalOptions } from './context.js'\nimport { presentError } from './output.js'\nimport { setColorEnabled } from './ui/ansi.js'\nimport type { HoodNetwork } from 'hoodchain'\n\nfunction toGlobalOptions(raw: Record<string, unknown>): GlobalOptions {\n return {\n json: !!raw.json,\n network: raw.network as HoodNetwork | undefined,\n rpc: raw.rpc as string | undefined,\n verbose: !!raw.verbose,\n yes: !!raw.yes,\n acknowledgeEligibility: !!raw.acknowledgeEligibility,\n }\n}\n\n/** Run a command body with a resolved context and unified error handling. */\nexport async function runWith(command: Command, fn: (ctx: Context) => Promise<void>): Promise<void> {\n const raw = command.optsWithGlobals()\n if (raw.color === false) setColorEnabled(false)\n const ctx = createContext(toGlobalOptions(raw))\n try {\n await fn(ctx)\n } catch (err) {\n process.exitCode = presentError(err, { json: ctx.json, verbose: ctx.verbose })\n }\n}\n","/**\n * Pricing helpers shared by `price` and `stocks`: the Chainlink oracle price,\n * the realised Uniswap v3 price (sell one token → USDG), and the premium the\n * DEX trades at over the oracle.\n */\nimport { formatUnits, parseUnits, type Address } from 'viem'\nimport {\n getQuote,\n quoteSwap,\n MAINNET_ADDRESSES,\n TESTNET_ADDRESSES,\n USDG_DECIMALS,\n type HoodClient,\n type StockQuote,\n} from 'hoodchain'\n\nexport interface PriceRow {\n symbol: string\n address: Address\n /** Chainlink oracle price per token (USD), or null when no fresh feed. */\n oracleUsd: number | null\n /** Age of the oracle answer (seconds), or null. */\n oracleAgeSeconds: number | null\n /** Realised DEX price for selling one token into USDG (USD), or null. */\n dexUsd: number | null\n /** (dex − oracle) / oracle, or null when either side is missing. */\n premium: number | null\n}\n\nfunction usdgAddress(client: HoodClient): Address {\n return client.network === 'testnet' ? TESTNET_ADDRESSES.usdg : MAINNET_ADDRESSES.usdg\n}\n\n/**\n * The realised on-DEX price of one whole token in USDG, via a QuoterV2\n * simulation. Returns null when no route with liquidity exists.\n */\nexport async function getDexPriceUsd(\n client: HoodClient,\n token: Address,\n decimals = 18,\n): Promise<number | null> {\n const usdg = usdgAddress(client)\n if (token.toLowerCase() === usdg.toLowerCase()) return 1\n try {\n const quote = await quoteSwap(client, {\n tokenIn: token,\n tokenOut: usdg,\n amountIn: parseUnits('1', decimals),\n })\n return Number(formatUnits(quote.amountOut, USDG_DECIMALS))\n } catch {\n return null\n }\n}\n\n/** Chainlink quote, tolerant of a missing/stale feed (returns null). */\nexport async function getOracleQuote(\n client: HoodClient,\n symbol: string,\n maxAgeSeconds?: number,\n): Promise<StockQuote | null> {\n try {\n return await getQuote(client, symbol, maxAgeSeconds ? { maxAgeSeconds } : {})\n } catch {\n return null\n }\n}\n\n/** Assemble a full price row (oracle + DEX + premium) for one symbol. */\nexport async function getPriceRow(\n client: HoodClient,\n symbol: string,\n address: Address,\n options: { maxAgeSeconds?: number; withDex?: boolean; decimals?: number } = {},\n): Promise<PriceRow> {\n const [oracle, dexUsd] = await Promise.all([\n getOracleQuote(client, symbol, options.maxAgeSeconds),\n options.withDex === false ? Promise.resolve(null) : getDexPriceUsd(client, address, options.decimals),\n ])\n const oracleUsd = oracle?.priceUsd ?? null\n const premium = oracleUsd && dexUsd ? (dexUsd - oracleUsd) / oracleUsd : null\n return {\n symbol,\n address,\n oracleUsd,\n oracleAgeSeconds: oracle?.ageSeconds ?? null,\n dexUsd,\n premium,\n }\n}\n","/**\n * Resolve a user-supplied token reference — a ticker (`AAPL`, `USDG`, `WETH`),\n * a special name, or a raw `0x` address — into an on-chain token descriptor.\n * Symbols resolve without a network round-trip; raw addresses are read from the\n * ERC-20 contract.\n */\nimport { getAddress, isAddress, type Address } from 'viem'\nimport {\n MAINNET_ADDRESSES,\n TESTNET_ADDRESSES,\n TESTNET_STOCK_TOKENS,\n USDG_DECIMALS,\n STOCK_TOKEN_DECIMALS,\n erc20Abi,\n getStockToken,\n getStockTokenByAddress,\n isStockTokenSymbol,\n isStockTokenAddress,\n type HoodClient,\n} from 'hoodchain'\nimport { notFoundError, usageError } from './errors.js'\n\nexport interface ResolvedToken {\n address: Address\n symbol: string\n decimals: number\n /** Whether this is a canonical Stock Token (drives the eligibility gate). */\n isStock: boolean\n /** Whether it carries a Chainlink feed (mainnet stocks only). */\n hasFeed: boolean\n}\n\n/** Resolve a token reference for the client's network. */\nexport async function resolveToken(client: HoodClient, input: string): Promise<ResolvedToken> {\n const raw = input.trim()\n const upper = raw.toUpperCase()\n const testnet = client.network === 'testnet'\n\n // Stablecoin + wrapped native shorthands.\n if (upper === 'USDG') {\n return {\n address: testnet ? TESTNET_ADDRESSES.usdg : MAINNET_ADDRESSES.usdg,\n symbol: 'USDG',\n decimals: USDG_DECIMALS,\n isStock: false,\n hasFeed: false,\n }\n }\n if (upper === 'WETH' || upper === 'ETH') {\n return {\n address: testnet ? TESTNET_ADDRESSES.weth : MAINNET_ADDRESSES.weth,\n symbol: 'WETH',\n decimals: 18,\n isStock: false,\n hasFeed: false,\n }\n }\n\n // Stock tickers.\n if (testnet) {\n const t = (TESTNET_STOCK_TOKENS as Record<string, Address>)[upper]\n if (t) return { address: t, symbol: upper, decimals: STOCK_TOKEN_DECIMALS, isStock: true, hasFeed: false }\n } else if (isStockTokenSymbol(upper)) {\n const token = getStockToken(upper)\n return {\n address: token.address,\n symbol: token.symbol,\n decimals: token.decimals,\n isStock: true,\n hasFeed: token.feed !== null,\n }\n }\n\n // Raw address — read metadata on-chain.\n if (isAddress(raw)) {\n const address = getAddress(raw)\n const known = client.network === 'mainnet' ? getStockTokenByAddress(address) : null\n if (known) {\n return {\n address,\n symbol: known.symbol,\n decimals: known.decimals,\n isStock: true,\n hasFeed: known.feed !== null,\n }\n }\n const [symbol, decimals] = await Promise.all([\n client.public\n .readContract({ address, abi: erc20Abi, functionName: 'symbol' })\n .catch(() => 'TOKEN') as Promise<string>,\n client.public\n .readContract({ address, abi: erc20Abi, functionName: 'decimals' })\n .catch(() => 18) as Promise<number>,\n ])\n return {\n address,\n symbol,\n decimals: Number(decimals),\n isStock: client.network === 'mainnet' ? isStockTokenAddress(address) : false,\n hasFeed: false,\n }\n }\n\n if (raw.startsWith('0x')) throw usageError(`\"${raw}\" is not a valid address.`)\n throw notFoundError(\n `Unknown token \"${raw}\".`,\n testnet\n ? `Testnet tokens: USDG, WETH, ${Object.keys(TESTNET_STOCK_TOKENS).join(', ')}, or a 0x address.`\n : 'Use a Stock Token ticker (run `hood stocks`), USDG, WETH, or a 0x address.',\n )\n}\n","/**\n * Aligned table renderer. Column-aware padding, right-alignment for numeric\n * columns, dim rules, and a graceful narrow-terminal fallback that drops\n * lower-priority columns before it ever wraps.\n */\nimport { dim, gray, padEnd, padStart, width } from './ansi.js'\n\n/** A column definition. */\nexport interface Column<Row> {\n /** Header label. */\n header: string\n /** Cell renderer — returns the already-styled string. */\n cell: (row: Row) => string\n /** Right-align (numbers) instead of left (text). @defaultValue false */\n align?: 'left' | 'right'\n /**\n * Drop priority when the terminal is too narrow: lower numbers drop first.\n * The first column is never dropped. @defaultValue 100\n */\n priority?: number\n /** Hard minimum width for this column. */\n min?: number\n}\n\nexport interface TableOptions {\n /** Terminal width to fit into. @defaultValue process.stdout.columns ?? 80 */\n maxWidth?: number\n /** Gap between columns. @defaultValue 2 */\n gap?: number\n}\n\n/** Render rows as an aligned table string (no trailing newline). */\nexport function renderTable<Row>(\n rows: Row[],\n columns: Column<Row>[],\n options: TableOptions = {},\n): string {\n const gap = options.gap ?? 2\n const maxWidth = options.maxWidth ?? process.stdout.columns ?? 80\n\n // Measure every column at full width.\n const measured = columns.map((col) => {\n const cells = rows.map((r) => col.cell(r))\n const contentWidth = Math.max(width(col.header), ...cells.map((c) => width(c)), 0)\n return { col, cells, contentWidth: Math.max(contentWidth, col.min ?? 0) }\n })\n\n // Drop low-priority columns (never the first) until it fits.\n const sep = ' '.repeat(gap)\n const totalWidth = (cols: typeof measured) =>\n cols.reduce((sum, m) => sum + m.contentWidth, 0) + gap * Math.max(0, cols.length - 1)\n\n let visible = measured\n if (totalWidth(visible) > maxWidth && visible.length > 1) {\n const dropOrder = visible\n .map((m, i) => ({ i, priority: m.col.priority ?? 100 }))\n .filter((x) => x.i !== 0)\n .sort((a, b) => a.priority - b.priority)\n const dropped = new Set<number>()\n for (const { i } of dropOrder) {\n if (totalWidth(visible.filter((_, idx) => !dropped.has(idx))) <= maxWidth) break\n dropped.add(i)\n }\n visible = measured.filter((_, idx) => !dropped.has(idx))\n }\n\n const line = (getCell: (m: (typeof visible)[number], rowIdx: number) => string, rowIdx: number) =>\n visible\n .map((m) => {\n const raw = getCell(m, rowIdx)\n return m.col.align === 'right'\n ? padStart(raw, m.contentWidth)\n : padEnd(raw, m.contentWidth)\n })\n .join(sep)\n\n const headerLine = visible\n .map((m) =>\n m.col.align === 'right'\n ? padStart(dim(m.col.header), m.contentWidth)\n : padEnd(dim(m.col.header), m.contentWidth),\n )\n .join(sep)\n\n const rule = gray('─'.repeat(Math.min(totalWidth(visible), maxWidth)))\n\n const body = rows.map((_, rowIdx) => line((m) => m.cells[rowIdx] as string, rowIdx))\n return [headerLine, rule, ...body].join('\\n')\n}\n\n/** A simple two-column key/value block (for `tx`, `token`, single-record views). */\nexport function renderKeyValue(pairs: [string, string][], options: { labelWidth?: number } = {}): string {\n const labelWidth = options.labelWidth ?? Math.max(...pairs.map(([k]) => width(k)), 0)\n return pairs.map(([k, v]) => `${padEnd(dim(k), labelWidth)} ${v}`).join('\\n')\n}\n","/**\n * Flicker-free live region for `--watch` / `--follow`.\n *\n * Instead of clearing the whole screen each tick (which flickers and destroys\n * scrollback), it repaints only the lines it previously drew: cursor up N,\n * rewrite each line with a clear-to-EOL, and clear any leftover lines when the\n * block shrinks. On a non-TTY it simply appends each frame with a separator so\n * piped output stays readable.\n */\nexport interface LiveRegion {\n /** Draw a full frame (a multi-line string). Diffs against the last frame. */\n render: (frame: string) => void\n /** Append a line below the live region without disturbing it (event log). */\n log?: (line: string) => void\n /** Restore the cursor and stop. */\n stop: () => void\n}\n\n/** Create a live region on stdout. */\nexport function liveRegion(): LiveRegion {\n const tty = !!process.stdout.isTTY\n\n if (!tty) {\n let first = true\n return {\n render: (frame) => {\n if (!first) process.stdout.write('\\n')\n first = false\n process.stdout.write(frame + '\\n')\n },\n stop: () => {},\n }\n }\n\n let prevLines = 0\n // Hide the cursor while animating; restore on stop / SIGINT.\n process.stdout.write('\\x1b[?25l')\n let stopped = false\n const stop = () => {\n if (stopped) return\n stopped = true\n process.stdout.write('\\x1b[?25h')\n }\n process.on('exit', stop)\n\n const render = (frame: string) => {\n const lines = frame.split('\\n')\n let out = ''\n if (prevLines > 0) out += `\\x1b[${prevLines}A` // cursor up to the block's top\n for (const line of lines) out += `\\r\\x1b[K${line}\\n`\n // Clear any leftover lines from a taller previous frame.\n for (let i = lines.length; i < prevLines; i++) out += '\\r\\x1b[K\\n'\n // Move the cursor back up over the cleared tail so the next frame lines up.\n const extra = Math.max(0, prevLines - lines.length)\n if (extra > 0) out += `\\x1b[${extra}A`\n process.stdout.write(out)\n prevLines = lines.length\n }\n\n return { render, stop }\n}\n","/**\n * A minimal network spinner. TTY-only: on a pipe or with `--json` it degrades\n * to a single dim status line on stderr (so it never pollutes stdout data).\n */\nimport { dim } from './ansi.js'\n\nconst FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']\n\nexport interface Spinner {\n /** Update the label without interrupting the animation. */\n update: (text: string) => void\n /** Stop and clear the line. */\n stop: () => void\n /** Stop, clear, and print a final dim status to stderr. */\n succeed: (text?: string) => void\n fail: (text?: string) => void\n}\n\n/** Start a spinner writing to stderr. Returns a no-op handle when non-TTY. */\nexport function spinner(text: string): Spinner {\n if (!process.stderr.isTTY) {\n process.stderr.write(dim(text) + '\\n')\n return {\n update: () => {},\n stop: () => {},\n succeed: (t) => t && process.stderr.write(dim(t) + '\\n'),\n fail: (t) => t && process.stderr.write(dim(t) + '\\n'),\n }\n }\n\n let label = text\n let i = 0\n const render = () => {\n process.stderr.write(`\\r\\x1b[K${dim(FRAMES[i % FRAMES.length] + ' ' + label)}`)\n i += 1\n }\n render()\n const timer = setInterval(render, 80)\n\n const clear = () => {\n clearInterval(timer)\n process.stderr.write('\\r\\x1b[K')\n }\n return {\n update: (t) => {\n label = t\n },\n stop: clear,\n succeed: (t) => {\n clear()\n if (t) process.stderr.write(dim('✓ ' + t) + '\\n')\n },\n fail: (t) => {\n clear()\n if (t) process.stderr.write(dim('✗ ' + t) + '\\n')\n },\n }\n}\n\n/** Run `fn` under a spinner, always clearing it (even on throw). */\nexport async function withSpinner<T>(text: string, fn: (s: Spinner) => Promise<T>): Promise<T> {\n const s = spinner(text)\n try {\n const result = await fn(s)\n s.stop()\n return result\n } catch (err) {\n s.stop()\n throw err\n }\n}\n","/**\n * Human formatting: money, percentages, counts, addresses, ages, token amounts.\n * Colour semantics are deliberately narrow — green/red only ever mean the sign\n * of a number, never decoration.\n */\nimport { formatUnits, type Address } from 'viem'\nimport { dim, green, red } from './ui/ansi.js'\n\n/** `315.5` → `$315.50`. Scales precision for sub-dollar values. */\nexport function usd(value: number): string {\n if (!Number.isFinite(value)) return '—'\n const abs = Math.abs(value)\n const digits = abs === 0 ? 2 : abs < 0.01 ? 6 : abs < 1 ? 4 : 2\n return (\n '$' +\n value.toLocaleString('en-US', {\n minimumFractionDigits: digits,\n maximumFractionDigits: digits,\n })\n )\n}\n\n/** Plain number with grouping, `maxFrac` decimals. */\nexport function num(value: number, maxFrac = 4): string {\n if (!Number.isFinite(value)) return '—'\n return value.toLocaleString('en-US', { maximumFractionDigits: maxFrac })\n}\n\n/** Compact large counts: `1_234_567` → `1.23M`. */\nexport function compact(value: number): string {\n if (!Number.isFinite(value)) return '—'\n return Intl.NumberFormat('en-US', { notation: 'compact', maximumFractionDigits: 2 }).format(value)\n}\n\n/**\n * Signed percentage, coloured by sign. `pct(0.0123)` → green `+1.23%`.\n * Pass a ratio (0.01 = 1%), not an already-scaled percentage.\n */\nexport function pct(ratio: number): string {\n if (!Number.isFinite(ratio)) return dim('—')\n const p = ratio * 100\n const sign = p > 0 ? '+' : ''\n const s = `${sign}${p.toFixed(2)}%`\n if (p > 0) return green(s)\n if (p < 0) return red(s)\n return s\n}\n\n/** `0x1234…abcd` — the standard middle-truncated address. */\nexport function shortAddress(address: string): string {\n if (address.length <= 12) return address\n return `${address.slice(0, 6)}…${address.slice(-4)}`\n}\n\n/** Alias with the `Address` type for call-site clarity. */\nexport function addr(a: Address): string {\n return shortAddress(a)\n}\n\n/** Seconds → `3m`, `2h 5m`, `1d 4h`. */\nexport function age(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) return '—'\n const s = Math.floor(seconds)\n if (s < 60) return `${s}s`\n const m = Math.floor(s / 60)\n if (m < 60) return `${m}m`\n const h = Math.floor(m / 60)\n if (h < 24) return `${h}h ${m % 60}m`\n const d = Math.floor(h / 24)\n return `${d}d ${h % 24}h`\n}\n\n/** Unix seconds → local ISO-ish timestamp. */\nexport function timestamp(unixSeconds: number): string {\n if (!unixSeconds) return '—'\n return new Date(unixSeconds * 1000).toISOString().replace('T', ' ').replace('.000Z', 'Z')\n}\n\n/**\n * Format a raw token amount for display, trimming trailing zeros and capping\n * significant fractional digits so a `parseUnits('1', 18)` reads as `1`.\n */\nexport function tokenAmount(raw: bigint, decimals: number, maxFrac = 6): string {\n const full = formatUnits(raw, decimals)\n if (!full.includes('.')) return full\n const [whole, frac] = full.split('.')\n const trimmed = (frac ?? '').slice(0, maxFrac).replace(/0+$/, '')\n return trimmed ? `${whole}.${trimmed}` : (whole as string)\n}\n","import { Command } from 'commander'\nimport { listStockTokens, listPricedStockTokens, type StockToken } from 'hoodchain'\nimport { runWith } from '../action.js'\nimport type { Context } from '../context.js'\nimport { getOracleQuote, getDexPriceUsd } from '../prices.js'\nimport { printResult } from '../output.js'\nimport { renderTable, type Column } from '../ui/table.js'\nimport { withSpinner } from '../ui/spinner.js'\nimport { accent, bold, dim, gray, truncate } from '../ui/ansi.js'\nimport { usd, pct, age, addr, num } from '../format.js'\nimport { usageError } from '../errors.js'\nimport { pMap } from '../pmap.js'\n\ntype SortKey = 'symbol' | 'price' | 'premium'\n\ninterface StockRow {\n symbol: string\n name: string\n address: string\n oracleUsd: number | null\n ageSeconds: number | null\n dexUsd: number | null\n premium: number | null\n}\n\nexport function stocksCommand(): Command {\n return new Command('stocks')\n .description('The full Stock Token board with live Chainlink prices')\n .option('--sort <key>', 'sort by symbol | price | premium (premium implies --dex)', 'symbol')\n .option('--dex', 'also probe Uniswap for DEX price + premium (slower)', false)\n .option('--priced', 'only tokens with a live Chainlink feed', false)\n .option('--limit <n>', 'show at most n rows')\n .action((opts, command) =>\n runWith(command, async (ctx) => {\n await stocks(ctx, opts)\n }),\n )\n}\n\ninterface StocksOpts {\n sort: string\n dex: boolean\n priced: boolean\n limit?: string\n}\n\nasync function stocks(ctx: Context, opts: StocksOpts): Promise<void> {\n const sort = opts.sort as SortKey\n if (!['symbol', 'price', 'premium'].includes(sort)) {\n throw usageError(`--sort must be one of: symbol, price, premium (got \"${opts.sort}\").`)\n }\n const withDex = opts.dex || sort === 'premium'\n const client = ctx.read()\n const tokens: StockToken[] = opts.priced || sort === 'premium' ? listPricedStockTokens() : listStockTokens()\n\n const rows = await withSpinner(\n withDex ? `Pricing ${tokens.length} tokens (oracle + DEX)…` : `Pricing ${tokens.length} tokens…`,\n () =>\n pMap(\n tokens,\n async (t): Promise<StockRow> => {\n const oracle = t.feed ? await getOracleQuote(client, t.symbol) : null\n const dexUsd = withDex ? await getDexPriceUsd(client, t.address, t.decimals) : null\n const premium = oracle && dexUsd ? (dexUsd - oracle.priceUsd) / oracle.priceUsd : null\n return {\n symbol: t.symbol,\n name: t.name.replace(/\\s*•\\s*Robinhood Token$/, ''),\n address: t.address,\n oracleUsd: oracle?.priceUsd ?? null,\n ageSeconds: oracle?.ageSeconds ?? null,\n dexUsd,\n premium,\n }\n },\n withDex ? 6 : 16,\n ),\n )\n\n sortRows(rows, sort)\n const limited = opts.limit ? rows.slice(0, Math.max(0, Number(opts.limit))) : rows\n\n printResult(\n { network: ctx.network, count: limited.length, tokens: limited },\n () => renderBoard(limited, withDex, ctx.network),\n ctx.json,\n )\n}\n\nfunction sortRows(rows: StockRow[], sort: SortKey): void {\n if (sort === 'symbol') rows.sort((a, b) => a.symbol.localeCompare(b.symbol))\n else if (sort === 'price') rows.sort((a, b) => (b.oracleUsd ?? -1) - (a.oracleUsd ?? -1))\n else rows.sort((a, b) => (b.premium ?? -Infinity) - (a.premium ?? -Infinity))\n}\n\nfunction renderBoard(rows: StockRow[], withDex: boolean, network: string): string {\n const columns: Column<StockRow>[] = [\n { header: 'SYMBOL', cell: (r) => bold(r.symbol), priority: 100 },\n { header: 'PRICE', align: 'right', priority: 90, cell: (r) => (r.oracleUsd !== null ? usd(r.oracleUsd) : dim('—')) },\n { header: 'AGE', align: 'right', priority: 40, cell: (r) => (r.ageSeconds !== null ? dim(age(r.ageSeconds)) : dim('—')) },\n { header: 'NAME', priority: 20, cell: (r) => dim(truncate(r.name, 24)) },\n ]\n if (withDex) {\n columns.splice(2, 0, { header: 'DEX', align: 'right', priority: 70, cell: (r) => (r.dexUsd !== null ? usd(r.dexUsd) : dim('—')) })\n columns.splice(3, 0, { header: 'PREMIUM', align: 'right', priority: 80, cell: (r) => (r.premium !== null ? pct(r.premium) : dim('—')) })\n }\n columns.push({ header: 'ADDRESS', priority: 10, cell: (r) => gray(addr(r.address as `0x${string}`)) })\n\n const priced = rows.filter((r) => r.oracleUsd !== null).length\n const header = `${accent('◈')} ${bold('Stock Tokens')} ${dim(`· ${network} · ${rows.length} shown · ${priced} priced`)}`\n return `${header}\\n${renderTable(rows, columns)}`\n}\n","/**\n * Bounded-concurrency async map. Keeps the public RPC happy (no 500-call\n * bursts) while still running work in parallel. Preserves input order.\n */\nexport async function pMap<In, Out>(\n items: readonly In[],\n mapper: (item: In, index: number) => Promise<Out>,\n concurrency = 8,\n): Promise<Out[]> {\n const results = new Array<Out>(items.length)\n let cursor = 0\n const limit = Math.max(1, Math.min(concurrency, items.length || 1))\n\n async function worker(): Promise<void> {\n while (cursor < items.length) {\n const index = cursor++\n results[index] = await mapper(items[index] as In, index)\n }\n }\n\n await Promise.all(Array.from({ length: limit }, worker))\n return results\n}\n","import { Command } from 'commander'\nimport { formatEther, type Address } from 'viem'\nimport {\n getRecentLaunches,\n erc20Abi,\n ODYSSEY_ADDRESSES,\n odysseyTradedEvent,\n type Launch,\n} from 'hoodchain'\nimport { runWith } from '../action.js'\nimport type { Context } from '../context.js'\nimport { printResult } from '../output.js'\nimport { renderTable, type Column } from '../ui/table.js'\nimport { withSpinner } from '../ui/spinner.js'\nimport { accent, bold, dim, gray, green } from '../ui/ansi.js'\nimport { addr, num } from '../format.js'\nimport { usageError } from '../errors.js'\nimport { pMap } from '../pmap.js'\n\nconst ODYSSEY_FACTORIES: Address[] = [\n ODYSSEY_ADDRESSES.bondingCurveFactory,\n ODYSSEY_ADDRESSES.reflectionFactory,\n ODYSSEY_ADDRESSES.instantFactory,\n]\n\ninterface CoinRow {\n token: string\n symbol: string\n creator: string | null\n pool: string | null\n block: string\n trades: number | null\n volumeEth: number | null\n}\n\nexport function coinsCommand(): Command {\n return new Command('coins')\n .description('Memecoin screener — newest or trending launches')\n .option('--new', 'newest launches (default)', false)\n .option('--trending', 'rank by bonding-curve trade activity', false)\n .option('--lookback <blocks>', 'blocks to scan', '50000')\n .option('--limit <n>', 'rows to show', '20')\n .option('--names', 'resolve token symbols on-chain', false)\n .action((opts, command) =>\n runWith(command, async (ctx) => {\n await coins(ctx, opts)\n }),\n )\n}\n\ninterface CoinsOpts {\n new: boolean\n trending: boolean\n lookback: string\n limit: string\n names: boolean\n}\n\nasync function coins(ctx: Context, opts: CoinsOpts): Promise<void> {\n if (ctx.network !== 'mainnet') throw usageError('The launchpads live on mainnet — run without --network testnet.')\n const client = ctx.read()\n const limit = Math.max(1, Number(opts.limit) || 20)\n const lookback = BigInt(opts.lookback || '50000')\n const trending = opts.trending\n\n const rows = trending\n ? await withSpinner('Ranking by curve activity…', () => trendingRows(ctx, lookback, limit, opts.names))\n : await withSpinner('Fetching newest launches…', () => newRows(ctx, lookback, limit, opts.names))\n\n printResult(\n { network: ctx.network, mode: trending ? 'trending' : 'new', count: rows.length, coins: rows },\n () => renderScreener(rows, trending),\n ctx.json,\n )\n}\n\nasync function newRows(ctx: Context, lookback: bigint, limit: number, names: boolean): Promise<CoinRow[]> {\n const launches = await getRecentLaunches(ctx.read(), { lookbackBlocks: lookback })\n const recent = launches.slice(-limit).reverse()\n return pMap(recent, (l) => launchToRow(ctx, l, names), names ? 8 : 1)\n}\n\nasync function trendingRows(ctx: Context, lookback: bigint, limit: number, names: boolean): Promise<CoinRow[]> {\n const client = ctx.read()\n const latest = await client.public.getBlockNumber()\n const fromBlock = latest > lookback ? latest - lookback : 0n\n const chunk = 10_000n\n\n const agg = new Map<string, { trades: number; volume: bigint; lastBlock: bigint }>()\n for (let start = fromBlock; start <= latest; start += chunk) {\n const end = start + chunk - 1n > latest ? latest : start + chunk - 1n\n const logs = await client.public.getLogs({\n address: ODYSSEY_FACTORIES,\n event: odysseyTradedEvent,\n fromBlock: start,\n toBlock: end,\n })\n for (const log of logs) {\n const token = (log.args.token as Address).toLowerCase()\n const quote = (log.args.quoteAmount as bigint) ?? 0n\n const prev = agg.get(token) ?? { trades: 0, volume: 0n, lastBlock: 0n }\n prev.trades += 1\n prev.volume += quote\n if (log.blockNumber > prev.lastBlock) prev.lastBlock = log.blockNumber\n agg.set(token, prev)\n }\n }\n\n const ranked = [...agg.entries()]\n .map(([token, v]) => ({ token, ...v }))\n .sort((a, b) => (b.trades !== a.trades ? b.trades - a.trades : b.volume > a.volume ? 1 : -1))\n .slice(0, limit)\n\n return pMap(\n ranked,\n async (r): Promise<CoinRow> => ({\n token: r.token,\n symbol: names ? await symbolOf(ctx, r.token as Address) : '',\n creator: null,\n pool: null,\n block: r.lastBlock.toString(),\n trades: r.trades,\n volumeEth: Number(formatEther(r.volume)),\n }),\n names ? 8 : 1,\n )\n}\n\nasync function launchToRow(ctx: Context, l: Launch, names: boolean): Promise<CoinRow> {\n return {\n token: l.token,\n symbol: names ? await symbolOf(ctx, l.token) : '',\n creator: l.creator,\n pool: l.pool,\n block: l.blockNumber.toString(),\n trades: null,\n volumeEth: null,\n }\n}\n\nfunction symbolOf(ctx: Context, token: Address): Promise<string> {\n return ctx\n .read()\n .public.readContract({ address: token, abi: erc20Abi, functionName: 'symbol' })\n .then((s) => String(s))\n .catch(() => '')\n}\n\nfunction renderScreener(rows: CoinRow[], trending: boolean): string {\n const header = `${accent('◈')} ${bold(trending ? 'Trending coins' : 'New coins')} ${dim('· ' + rows.length)}`\n if (rows.length === 0) {\n return `${header}\\n${dim(trending ? 'No curve trades in the scanned window.' : 'No launches in the scanned window — widen --lookback.')}`\n }\n const columns: Column<CoinRow>[] = [\n { header: 'TOKEN', priority: 100, cell: (r) => (r.symbol ? bold(r.symbol) : gray(addr(r.token as Address))) },\n { header: 'ADDRESS', priority: 50, cell: (r) => gray(addr(r.token as Address)) },\n ]\n if (trending) {\n columns.push({ header: 'TRADES', align: 'right', priority: 95, cell: (r) => green(String(r.trades)) })\n columns.push({ header: 'VOL (ETH)', align: 'right', priority: 90, cell: (r) => num(r.volumeEth ?? 0, 4) })\n } else {\n columns.push({ header: 'CREATOR', priority: 40, cell: (r) => (r.creator ? gray(addr(r.creator as Address)) : dim('—')) })\n columns.push({ header: 'POOL', priority: 30, cell: (r) => (r.pool ? gray(addr(r.pool as Address)) : dim('curve')) })\n }\n columns.push({ header: 'BLOCK', align: 'right', priority: 20, cell: (r) => dim('#' + r.block) })\n return `${header}\\n${renderTable(rows, columns)}`\n}\n","import { Command } from 'commander'\nimport { getRecentLaunches, watchLaunches, erc20Abi, type Launch, type LaunchpadName } from 'hoodchain'\nimport type { Address } from 'viem'\nimport { runWith } from '../action.js'\nimport type { Context } from '../context.js'\nimport { printResult } from '../output.js'\nimport { renderTable, type Column } from '../ui/table.js'\nimport { withSpinner } from '../ui/spinner.js'\nimport { liveRegion } from '../ui/live.js'\nimport { accent, bold, dim, gray, green } from '../ui/ansi.js'\nimport { addr } from '../format.js'\nimport { usageError } from '../errors.js'\nimport { pMap } from '../pmap.js'\n\ninterface LaunchRow {\n launchpad: LaunchpadName\n token: string\n symbol: string\n creator: string\n pool: string | null\n block: string\n tx: string\n}\n\nexport function launchesCommand(): Command {\n return new Command('launches')\n .description('Recent memecoin launches from NOXA and The Odyssey')\n .option('--follow', 'stream new launches live', false)\n .option('--launchpad <name>', 'noxa | odyssey (default: both)')\n .option('--lookback <blocks>', 'blocks to scan for the snapshot', '30000')\n .option('--limit <n>', 'max rows in the snapshot', '25')\n .option('--names', 'resolve each token symbol on-chain', false)\n .action((opts, command) =>\n runWith(command, async (ctx) => {\n await launches(ctx, opts)\n }),\n )\n}\n\ninterface LaunchesOpts {\n follow: boolean\n launchpad?: string\n lookback: string\n limit: string\n names: boolean\n}\n\nfunction validLaunchpad(v?: string): LaunchpadName | undefined {\n if (!v) return undefined\n if (v !== 'noxa' && v !== 'odyssey') throw usageError('--launchpad must be \"noxa\" or \"odyssey\".')\n return v\n}\n\nasync function launches(ctx: Context, opts: LaunchesOpts): Promise<void> {\n const client = ctx.read()\n const launchpad = validLaunchpad(opts.launchpad)\n\n if (opts.follow) {\n if (ctx.network !== 'mainnet') throw usageError('Launch watching runs on mainnet (the launchpads are mainnet-only).')\n await follow(ctx, launchpad, opts.names)\n return\n }\n\n const raw = await withSpinner('Scanning launchpad logs…', () =>\n getRecentLaunches(client, { lookbackBlocks: BigInt(opts.lookback || '30000'), launchpad }),\n )\n const recent = raw.slice(-Math.max(1, Number(opts.limit) || 25)).reverse()\n const rows = await withSpinner('Building feed…', () =>\n pMap(recent, (l) => toRow(ctx, l, opts.names), opts.names ? 8 : 1),\n )\n\n printResult(\n { network: ctx.network, count: rows.length, launches: rows },\n () => renderFeed(rows, ctx.network),\n ctx.json,\n )\n}\n\nasync function toRow(ctx: Context, l: Launch, resolveNames: boolean): Promise<LaunchRow> {\n let symbol = ''\n if (resolveNames) {\n symbol = await ctx\n .read()\n .public.readContract({ address: l.token, abi: erc20Abi, functionName: 'symbol' })\n .then((s) => String(s))\n .catch(() => '')\n }\n return {\n launchpad: l.launchpad,\n token: l.token,\n symbol,\n creator: l.creator,\n pool: l.pool,\n block: l.blockNumber.toString(),\n tx: l.transactionHash,\n }\n}\n\nasync function follow(ctx: Context, launchpad: LaunchpadName | undefined, resolveNames: boolean): Promise<void> {\n const client = ctx.read()\n process.stderr.write(dim(`Watching ${launchpad ?? 'NOXA + Odyssey'} for new launches — Ctrl-C to stop\\n`))\n const unwatch = watchLaunches(\n client,\n (l) => {\n void toRow(ctx, l, resolveNames).then((r) => {\n if (ctx.json) {\n process.stdout.write(JSON.stringify(r) + '\\n')\n } else {\n const name = r.symbol ? bold(r.symbol) + ' ' : ''\n process.stdout.write(\n `${green('▲')} ${dim(r.launchpad.padEnd(7))} ${name}${gray(addr(r.token as Address))} ${dim('by')} ${gray(addr(r.creator as Address))} ${dim('#' + r.block)}\\n`,\n )\n }\n })\n },\n { launchpad, onError: (e) => process.stderr.write(dim(`(watch retry: ${e.message})\\n`)) },\n )\n const shutdown = () => {\n unwatch()\n process.exit(0)\n }\n process.on('SIGINT', shutdown)\n process.on('SIGTERM', shutdown)\n await new Promise(() => {})\n}\n\nfunction renderFeed(rows: LaunchRow[], network: string): string {\n const header = `${accent('◈')} ${bold('Launches')} ${dim(`· ${network} · ${rows.length}`)}`\n if (rows.length === 0) {\n return `${header}\\n${dim('No launches in the scanned window. Widen it with --lookback, or --follow to stream new ones.')}`\n }\n const columns: Column<LaunchRow>[] = [\n { header: 'BLOCK', align: 'right', priority: 90, cell: (r) => dim('#' + r.block) },\n { header: 'PAD', priority: 100, cell: (r) => (r.launchpad === 'noxa' ? accent('NOXA') : bold('Odyssey')) },\n { header: 'TOKEN', priority: 95, cell: (r) => (r.symbol ? bold(r.symbol) : gray(addr(r.token as Address))) },\n { header: 'ADDRESS', priority: 50, cell: (r) => gray(addr(r.token as Address)) },\n { header: 'CREATOR', priority: 40, cell: (r) => gray(addr(r.creator as Address)) },\n { header: 'POOL', priority: 30, cell: (r) => (r.pool ? gray(addr(r.pool as Address)) : dim('curve')) },\n ]\n return `${header}\\n${renderTable(rows, columns)}`\n}\n","import { Command } from 'commander'\nimport { formatEther, getAddress, isAddress, type Address } from 'viem'\nimport { getPortfolio, getUsdgBalance, formatUsdg, type StockPosition } from 'hoodchain'\nimport { runWith } from '../action.js'\nimport type { Context } from '../context.js'\nimport { printResult } from '../output.js'\nimport { renderTable, renderKeyValue, type Column } from '../ui/table.js'\nimport { withSpinner } from '../ui/spinner.js'\nimport { accent, bold, dim, gray } from '../ui/ansi.js'\nimport { usd, num, addr } from '../format.js'\nimport { usageError } from '../errors.js'\n\nexport function portfolioCommand(): Command {\n return new Command('portfolio')\n .description('Multiplier-correct Stock Token positions + USD totals for an address')\n .argument('<address>', 'wallet address to inspect')\n .option('--max-age <seconds>', 'max acceptable Chainlink answer age')\n .action((address: string, opts, command) =>\n runWith(command, async (ctx) => {\n await portfolio(ctx, address, opts)\n }),\n )\n}\n\nasync function portfolio(ctx: Context, address: string, opts: { maxAge?: string }): Promise<void> {\n if (!isAddress(address)) throw usageError(`\"${address}\" is not a valid address.`)\n const owner = getAddress(address)\n const client = ctx.read()\n const maxAgeSeconds = opts.maxAge ? Number(opts.maxAge) : undefined\n\n const { port, usdg, eth } = await withSpinner(`Reading ${addr(owner)}…`, async () => {\n const [port, usdg, eth] = await Promise.all([\n getPortfolio(client, owner, maxAgeSeconds ? { maxAgeSeconds } : {}),\n getUsdgBalance(client, owner),\n client.public.getBalance({ address: owner }),\n ])\n return { port, usdg, eth }\n })\n\n const held = port.positions.filter((p) => p.balance > 0n)\n const usdgFloat = Number(formatUsdg(usdg))\n const grandTotal = port.totalUsd + usdgFloat\n\n const json = {\n owner,\n network: ctx.network,\n eth: formatEther(eth),\n usdg: formatUsdg(usdg),\n stockValueUsd: port.totalUsd,\n totalUsd: grandTotal,\n unpricedSymbols: port.unpricedSymbols,\n positions: held.map((p) => ({\n symbol: p.symbol,\n address: p.address,\n balance: p.balanceTokens,\n shareEquivalent: p.shareEquivalent,\n priceUsd: p.quote?.priceUsd ?? null,\n valueUsd: p.valueUsd,\n })),\n }\n\n printResult(json, () => renderPortfolio(owner, held, eth, usdgFloat, port.totalUsd, grandTotal, port.unpricedSymbols, ctx.network), ctx.json)\n}\n\nfunction renderPortfolio(\n owner: Address,\n held: StockPosition[],\n eth: bigint,\n usdg: number,\n stockUsd: number,\n total: number,\n unpriced: string[],\n network: string,\n): string {\n const header = `${accent('◈')} ${bold('Portfolio')} ${dim('· ' + addr(owner) + ' · ' + network)}`\n\n const summary = renderKeyValue(\n [\n ['ETH', num(Number(formatEther(eth)), 6)],\n ['USDG', usd(usdg)],\n ['Stocks', usd(stockUsd)],\n ['Total', bold(usd(total))],\n ],\n { labelWidth: 7 },\n )\n\n if (held.length === 0) {\n return `${header}\\n${summary}\\n\\n${dim('No Stock Token positions. Fund with `hood swap --sell USDG --buy <ticker>`.')}`\n }\n\n const sorted = [...held].sort((a, b) => (b.valueUsd ?? -1) - (a.valueUsd ?? -1))\n const columns: Column<StockPosition>[] = [\n { header: 'SYMBOL', priority: 100, cell: (p) => bold(p.symbol) },\n { header: 'BALANCE', align: 'right', priority: 90, cell: (p) => num(p.balanceTokens, 4) },\n { header: 'SHARES', align: 'right', priority: 60, cell: (p) => num(p.shareEquivalent, 4) },\n { header: 'PRICE', align: 'right', priority: 70, cell: (p) => (p.quote ? usd(p.quote.priceUsd) : dim('—')) },\n { header: 'VALUE', align: 'right', priority: 95, cell: (p) => (p.valueUsd !== null ? bold(usd(p.valueUsd)) : dim('unpriced')) },\n { header: 'ADDRESS', priority: 20, cell: (p) => gray(addr(p.address)) },\n ]\n\n const footNote =\n unpriced.length > 0 ? '\\n' + dim(`Unpriced (no fresh feed): ${unpriced.join(', ')}`) : ''\n return `${header}\\n${summary}\\n\\n${renderTable(sorted, columns)}${footNote}`\n}\n","import { Command } from 'commander'\nimport { decodeEventLog, formatEther, formatGwei, isHash, type Address, type Hash } from 'viem'\nimport { erc20Abi, getStockTokenByAddress } from 'hoodchain'\nimport { runWith } from '../action.js'\nimport type { Context } from '../context.js'\nimport { printResult } from '../output.js'\nimport { renderKeyValue } from '../ui/table.js'\nimport { withSpinner } from '../ui/spinner.js'\nimport { accent, bold, dim, gray, green, red } from '../ui/ansi.js'\nimport { addr, num, tokenAmount, timestamp } from '../format.js'\nimport { fetchTx, txUrl } from '../blockscout.js'\nimport { notFoundError, usageError } from '../errors.js'\nimport { pMap } from '../pmap.js'\n\ninterface TransferLine {\n token: Address\n symbol: string | null\n from: Address\n to: Address\n value: string\n}\n\nexport function txCommand(): Command {\n return new Command('tx')\n .description('Decode a transaction: status, transfers, gas, method')\n .argument('<hash>', 'transaction hash')\n .action((hash: string, _opts, command) =>\n runWith(command, async (ctx) => {\n await tx(ctx, hash)\n }),\n )\n}\n\nasync function tx(ctx: Context, hash: string): Promise<void> {\n if (!isHash(hash)) throw usageError(`\"${hash}\" is not a 32-byte transaction hash.`)\n const client = ctx.read()\n\n const { transaction, receipt, block, meta } = await withSpinner('Fetching transaction…', async () => {\n const transaction = await client.public.getTransaction({ hash: hash as Hash }).catch(() => null)\n if (!transaction) throw notFoundError(`No transaction ${hash} on ${ctx.network}.`)\n const [receipt, meta] = await Promise.all([\n client.public.getTransactionReceipt({ hash: hash as Hash }).catch(() => null),\n fetchTx(ctx.network, hash),\n ])\n const block = receipt\n ? await client.public.getBlock({ blockNumber: receipt.blockNumber }).catch(() => null)\n : null\n return { transaction, receipt, block, meta }\n })\n\n interface RawTransfer {\n token: Address\n from: Address\n to: Address\n rawValue: bigint\n knownSymbol: string | null\n knownDecimals: number | null\n }\n const raw: RawTransfer[] = []\n for (const log of receipt?.logs ?? []) {\n try {\n const decoded = decodeEventLog({ abi: erc20Abi, data: log.data, topics: log.topics })\n if (decoded.eventName !== 'Transfer') continue\n const args = decoded.args as unknown as { from: Address; to: Address; value: bigint }\n const known = ctx.network === 'mainnet' ? getStockTokenByAddress(log.address) : null\n raw.push({\n token: log.address,\n from: args.from,\n to: args.to,\n rawValue: args.value,\n knownSymbol: known?.symbol ?? null,\n knownDecimals: known?.decimals ?? null,\n })\n } catch {\n /* not an ERC-20 Transfer — skip */\n }\n }\n\n // Resolve symbol + decimals for unknown tokens (WETH, USDG, memecoins, …)\n // straight off the contract, so amounts read in real units, not raw wei.\n const unknownAddresses = [...new Set(raw.filter((r) => r.knownSymbol === null).map((r) => r.token.toLowerCase()))]\n const resolved = new Map<string, { symbol: string; decimals: number }>()\n await pMap(\n unknownAddresses,\n async (lower) => {\n const address = raw.find((r) => r.token.toLowerCase() === lower)!.token\n const [symbol, decimals] = await Promise.all([\n client.public.readContract({ address, abi: erc20Abi, functionName: 'symbol' }).catch(() => 'TOKEN'),\n client.public.readContract({ address, abi: erc20Abi, functionName: 'decimals' }).catch(() => 18),\n ])\n resolved.set(lower, { symbol: String(symbol), decimals: Number(decimals) })\n },\n 8,\n )\n\n const transfers: TransferLine[] = raw.map((r) => {\n const known = r.knownSymbol !== null && r.knownDecimals !== null\n const meta = known ? { symbol: r.knownSymbol as string, decimals: r.knownDecimals as number } : resolved.get(r.token.toLowerCase())\n return {\n token: r.token,\n symbol: meta?.symbol ?? null,\n from: r.from,\n to: r.to,\n value: meta ? tokenAmount(r.rawValue, meta.decimals) : r.rawValue.toString(),\n }\n })\n\n const status = receipt ? (receipt.status === 'success' ? 'success' : 'reverted') : 'pending'\n const gasUsed = receipt?.gasUsed ?? 0n\n const gasPrice = receipt?.effectiveGasPrice ?? transaction.gasPrice ?? 0n\n const feeEth = formatEther(gasUsed * gasPrice)\n\n const json = {\n hash,\n network: ctx.network,\n status,\n block: receipt?.blockNumber?.toString() ?? null,\n timestamp: block ? Number(block.timestamp) : null,\n from: transaction.from,\n to: transaction.to,\n valueEth: formatEther(transaction.value),\n nonce: transaction.nonce,\n method: meta?.decoded_input?.method_call ?? meta?.method ?? null,\n gasUsed: gasUsed.toString(),\n gasPriceGwei: formatGwei(gasPrice),\n feeEth,\n transfers,\n explorer: txUrl(ctx.network, hash),\n }\n\n printResult(json, () => renderTx(json, status, transfers), ctx.json)\n}\n\nfunction renderTx(\n j: { hash: string; from: Address | null; to: Address | null; valueEth: string; nonce: number; method: string | null; block: string | null; timestamp: number | null; gasUsed: string; gasPriceGwei: string; feeEth: string; explorer: string },\n status: string,\n transfers: TransferLine[],\n): string {\n const statusBadge = status === 'success' ? green('● success') : status === 'reverted' ? red('● reverted') : dim('● pending')\n const header = `${accent('◈')} ${bold('Transaction')} ${dim(addr(j.hash as `0x${string}`))} ${statusBadge}`\n\n const pairs: [string, string][] = [\n ['From', gray(j.from ? addr(j.from) : '—')],\n ['To', gray(j.to ? addr(j.to) : dim('contract creation'))],\n ['Value', j.valueEth === '0' ? dim('0 ETH') : bold(num(Number(j.valueEth), 8) + ' ETH')],\n ['Method', j.method ? bold(j.method) : dim('—')],\n ['Block', j.block ? '#' + j.block : dim('pending')],\n ['When', j.timestamp ? dim(timestamp(j.timestamp)) : dim('—')],\n ['Gas used', dim(num(Number(j.gasUsed), 0) + ` @ ${num(Number(j.gasPriceGwei), 4)} gwei`)],\n ['Fee', num(Number(j.feeEth), 8) + ' ETH'],\n ['Explorer', gray(j.explorer)],\n ]\n\n let out = `${header}\\n${renderKeyValue(pairs, { labelWidth: 9 })}`\n if (transfers.length) {\n const lines = transfers.map(\n (t) =>\n ` ${gray(addr(t.from))} ${dim('→')} ${gray(addr(t.to))} ${bold(t.value)} ${t.symbol ? accent(t.symbol) : gray(addr(t.token))}`,\n )\n out += `\\n\\n${dim('Token transfers')}\\n${lines.join('\\n')}`\n }\n return out\n}\n","/**\n * Thin Blockscout v2 API client. Used to enrich RPC data with decoded method\n * names, token metadata, and holder counts. Every call is best-effort: on any\n * failure it resolves to `null` so the RPC-only path still works offline of the\n * explorer.\n */\nimport type { HoodNetwork } from 'hoodchain'\nimport { MAINNET_EXPLORER_URL } from 'hoodchain'\n\nconst TESTNET_EXPLORER_URL = 'https://explorer.testnet.chain.robinhood.com'\n\nexport function explorerBase(network: HoodNetwork): string {\n return network === 'testnet' ? TESTNET_EXPLORER_URL : MAINNET_EXPLORER_URL\n}\n\n/** A browser link to a transaction. */\nexport function txUrl(network: HoodNetwork, hash: string): string {\n return `${explorerBase(network)}/tx/${hash}`\n}\n\n/** A browser link to an address/token. */\nexport function addressUrl(network: HoodNetwork, address: string): string {\n return `${explorerBase(network)}/address/${address}`\n}\n\nasync function get<T>(network: HoodNetwork, path: string, timeoutMs = 6000): Promise<T | null> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n const res = await fetch(`${explorerBase(network)}/api/v2${path}`, {\n signal: controller.signal,\n headers: { accept: 'application/json' },\n })\n if (!res.ok) return null\n return (await res.json()) as T\n } catch {\n return null\n } finally {\n clearTimeout(timer)\n }\n}\n\nexport interface BlockscoutTx {\n method?: string | null\n decoded_input?: { method_call?: string; parameters?: { name: string; type: string; value: unknown }[] } | null\n status?: string\n result?: string\n fee?: { value?: string } | null\n gas_used?: string\n revert_reason?: unknown\n exchange_rate?: string | null\n to?: { hash?: string; name?: string | null; is_contract?: boolean } | null\n from?: { hash?: string } | null\n}\n\nexport function fetchTx(network: HoodNetwork, hash: string): Promise<BlockscoutTx | null> {\n return get<BlockscoutTx>(network, `/transactions/${hash}`)\n}\n\nexport interface BlockscoutToken {\n name?: string | null\n symbol?: string | null\n decimals?: string | null\n total_supply?: string | null\n holders?: string | null\n holders_count?: string | null\n type?: string | null\n icon_url?: string | null\n}\n\nexport function fetchToken(network: HoodNetwork, address: string): Promise<BlockscoutToken | null> {\n return get<BlockscoutToken>(network, `/tokens/${address}`)\n}\n","import { Command } from 'commander'\nimport { getMultiplier, erc20Abi } from 'hoodchain'\nimport { runWith } from '../action.js'\nimport type { Context } from '../context.js'\nimport { getOracleQuote, getDexPriceUsd } from '../prices.js'\nimport { printResult } from '../output.js'\nimport { renderKeyValue } from '../ui/table.js'\nimport { withSpinner } from '../ui/spinner.js'\nimport { accent, bold, dim, gray } from '../ui/ansi.js'\nimport { usd, num, addr, age } from '../format.js'\nimport { fetchToken, addressUrl } from '../blockscout.js'\nimport { resolveToken } from '../resolve.js'\n\nexport function tokenCommand(): Command {\n return new Command('token')\n .description('Inspect a token: metadata, supply, multiplier, price')\n .argument('<address>', 'token address or ticker')\n .action((address: string, _opts, command) =>\n runWith(command, async (ctx) => {\n await token(ctx, address)\n }),\n )\n}\n\nasync function token(ctx: Context, input: string): Promise<void> {\n const client = ctx.read()\n const resolved = await resolveToken(client, input)\n\n const { meta, multiplier, oracle, dexUsd, totalSupply } = await withSpinner(`Reading ${resolved.symbol}…`, async () => {\n const [meta, multiplier, oracle, dexUsd, totalSupply] = await Promise.all([\n fetchToken(ctx.network, resolved.address),\n resolved.isStock ? getMultiplier(client, resolved.symbol) : Promise.resolve(null),\n resolved.hasFeed ? getOracleQuote(client, resolved.symbol) : Promise.resolve(null),\n getDexPriceUsd(client, resolved.address, resolved.decimals),\n client.public\n .readContract({ address: resolved.address, abi: erc20Abi, functionName: 'totalSupply' })\n .catch(() => null) as Promise<bigint | null>,\n ])\n return { meta, multiplier, oracle, dexUsd, totalSupply }\n })\n\n const json = {\n address: resolved.address,\n symbol: meta?.symbol ?? resolved.symbol,\n name: meta?.name ?? null,\n decimals: resolved.decimals,\n isStockToken: resolved.isStock,\n totalSupply: totalSupply !== null ? Number(totalSupply) / 10 ** resolved.decimals : null,\n holders: meta?.holders_count ? Number(meta.holders_count) : meta?.holders ? Number(meta.holders) : null,\n uiMultiplier: multiplier !== null ? Number(multiplier) / 1e18 : null,\n oracleUsd: oracle?.priceUsd ?? null,\n oracleAgeSeconds: oracle?.ageSeconds ?? null,\n dexUsd,\n explorer: addressUrl(ctx.network, resolved.address),\n }\n\n printResult(json, () => renderToken(json, resolved.isStock), ctx.json)\n}\n\nfunction renderToken(\n j: {\n address: string\n symbol: string\n name: string | null\n decimals: number\n isStockToken: boolean\n totalSupply: number | null\n holders: number | null\n uiMultiplier: number | null\n oracleUsd: number | null\n oracleAgeSeconds: number | null\n dexUsd: number | null\n explorer: string\n },\n isStock: boolean,\n): string {\n const header = `${accent('◈')} ${bold(j.symbol)} ${dim(j.name ? '· ' + j.name : '')}`\n const pairs: [string, string][] = [\n ['Address', gray(addr(j.address as `0x${string}`))],\n ['Decimals', String(j.decimals)],\n ['Supply', j.totalSupply !== null ? num(j.totalSupply, 0) : dim('—')],\n ['Holders', j.holders !== null ? num(j.holders, 0) : dim('—')],\n ]\n if (isStock) {\n pairs.push(['Multiplier', j.uiMultiplier !== null ? `${num(j.uiMultiplier, 6)}×` : dim('n/a')])\n pairs.push(['Oracle', j.oracleUsd !== null ? bold(usd(j.oracleUsd)) : dim('no feed')])\n if (j.oracleAgeSeconds !== null) pairs.push(['Updated', dim(age(j.oracleAgeSeconds) + ' ago')])\n }\n pairs.push(['DEX price', j.dexUsd !== null ? usd(j.dexUsd) : dim('no pool')])\n pairs.push(['Explorer', gray(j.explorer)])\n return `${header}\\n${renderKeyValue(pairs, { labelWidth: 10 })}`\n}\n","import { Command } from 'commander'\nimport { formatEther, getAddress, isAddress, type Address } from 'viem'\nimport { watchTransfers } from 'hoodchain'\nimport { runWith } from '../action.js'\nimport type { Context } from '../context.js'\nimport { accent, bold, dim, gray, green, red } from '../ui/ansi.js'\nimport { addr, tokenAmount } from '../format.js'\nimport { resolveToken } from '../resolve.js'\nimport { usageError } from '../errors.js'\n\nexport function watchCommand(): Command {\n return new Command('watch')\n .description('Live activity stream for an address or a token (ERC-20 transfers + native ETH)')\n .argument('<addrOrToken>', 'wallet address, token address, or ticker to watch')\n .option('--token', 'treat the argument as a token (stream ALL transfers of it)', false)\n .action((target: string, opts, command) =>\n runWith(command, async (ctx) => {\n await watch(ctx, target, opts)\n }),\n )\n}\n\nasync function watch(ctx: Context, target: string, opts: { token: boolean }): Promise<void> {\n const client = ctx.read()\n\n if (opts.token || !isAddress(target)) {\n const token = await resolveToken(client, target)\n process.stderr.write(dim(`Watching ${token.symbol} transfers (${addr(token.address)}) — Ctrl-C to stop\\n`))\n const unwatch = watchTransfers(client, { token: token.address }, (t) => {\n if (ctx.json) {\n process.stdout.write(JSON.stringify({ ...t, value: t.value.toString() }) + '\\n')\n } else {\n process.stdout.write(\n `${gray(addr(t.from))} ${dim('→')} ${gray(addr(t.to))} ${bold(tokenAmount(t.value, token.decimals))} ${accent(token.symbol)} ${dim('#' + t.blockNumber)}\\n`,\n )\n }\n })\n return runUntilInterrupt(unwatch)\n }\n\n // Address mode: stream native ETH in/out plus every Stock Token transfer touching it.\n if (ctx.network !== 'mainnet') throw usageError('Address-mode watch needs the mainnet Stock Token registry — pass --token for a specific testnet token.')\n const owner = getAddress(target)\n process.stderr.write(dim(`Watching ${addr(owner)} for activity — Ctrl-C to stop\\n`))\n\n const unwatchEth = client.public.watchBlocks({\n onBlock: async (block) => {\n // Cheap native-ETH activity check: scan the block's transactions touching owner.\n for (const txHash of block.transactions) {\n const tx = await client.public.getTransaction({ hash: txHash }).catch(() => null)\n if (!tx) continue\n if (tx.from.toLowerCase() !== owner.toLowerCase() && tx.to?.toLowerCase() !== owner.toLowerCase()) continue\n if (tx.value === 0n) continue\n const out = tx.from.toLowerCase() === owner.toLowerCase()\n const line = `${out ? red('↑') : green('↓')} ${bold(formatEther(tx.value))} ETH ${dim(out ? 'to' : 'from')} ${gray(addr(out ? (tx.to as Address) : tx.from))} ${dim('#' + block.number)}`\n if (ctx.json) process.stdout.write(JSON.stringify({ kind: 'eth', hash: tx.hash, from: tx.from, to: tx.to, valueEth: formatEther(tx.value), block: block.number.toString() }) + '\\n')\n else process.stdout.write(line + '\\n')\n }\n },\n })\n\n // Stream Stock Token transfers touching the address (widest-reach single watcher: USDG).\n const { MAINNET_ADDRESSES } = await import('hoodchain')\n const unwatchUsdg = watchTransfers(client, { token: MAINNET_ADDRESSES.usdg }, (t) => {\n if (t.from.toLowerCase() !== owner.toLowerCase() && t.to.toLowerCase() !== owner.toLowerCase()) return\n const out = t.from.toLowerCase() === owner.toLowerCase()\n if (ctx.json) {\n process.stdout.write(JSON.stringify({ kind: 'usdg', ...t, value: t.value.toString() }) + '\\n')\n } else {\n process.stdout.write(\n `${out ? red('↑') : green('↓')} ${bold(tokenAmount(t.value, 6))} USDG ${dim(out ? 'to' : 'from')} ${gray(addr(out ? t.to : t.from))} ${dim('#' + t.blockNumber)}\\n`,\n )\n }\n })\n\n return runUntilInterrupt(() => {\n unwatchEth()\n unwatchUsdg()\n })\n}\n\nfunction runUntilInterrupt(unwatch: () => void): Promise<void> {\n const shutdown = () => {\n unwatch()\n process.exit(0)\n }\n process.on('SIGINT', shutdown)\n process.on('SIGTERM', shutdown)\n return new Promise(() => {})\n}\n","import { Command } from 'commander'\nimport { formatUnits, parseUnits } from 'viem'\nimport { quoteSwap, buildSwapTx, ensureApproval, StockTokenEligibilityError } from 'hoodchain'\nimport { runWith } from '../action.js'\nimport type { Context } from '../context.js'\nimport { resolveToken } from '../resolve.js'\nimport { printResult } from '../output.js'\nimport { renderKeyValue } from '../ui/table.js'\nimport { withSpinner } from '../ui/spinner.js'\nimport { confirm } from '../prompt.js'\nimport { accent, bold, dim, gray, green, yellow } from '../ui/ansi.js'\nimport { num, addr } from '../format.js'\nimport { txUrl } from '../blockscout.js'\nimport { guardError, usageError } from '../errors.js'\nimport { checkSpendCap } from '../spend-cap.js'\nimport { getDexPriceUsd } from '../prices.js'\nimport { warn } from '../output.js'\n\nexport function swapCommand(): Command {\n return new Command('swap')\n .description('Quote (default) or execute a Uniswap v3 swap between two tokens')\n .requiredOption('--sell <token>', 'ticker or address to sell (e.g. USDG)')\n .requiredOption('--buy <token>', 'ticker or address to buy')\n .requiredOption('--amount <amount>', 'amount of --sell to spend, in whole tokens')\n .option('--slippage <bps>', 'slippage tolerance in basis points', '50')\n .option('--execute', 'sign and send (default: quote only)', false)\n .action((opts, command) =>\n runWith(command, async (ctx) => {\n await swap(ctx, opts)\n }),\n )\n}\n\ninterface SwapOpts {\n sell: string\n buy: string\n amount: string\n slippage: string\n execute: boolean\n}\n\nasync function swap(ctx: Context, opts: SwapOpts): Promise<void> {\n const slippageBps = Number(opts.slippage)\n if (!Number.isFinite(slippageBps) || slippageBps < 0 || slippageBps > 5000) {\n throw usageError('--slippage must be a basis-point value between 0 and 5000 (50%).')\n }\n\n const client = opts.execute ? await ctx.wallet() : ctx.read()\n const [tokenIn, tokenOut] = await Promise.all([resolveToken(client, opts.sell), resolveToken(client, opts.buy)])\n const amountIn = parseUnits(opts.amount, tokenIn.decimals)\n if (amountIn <= 0n) throw usageError('--amount must be greater than zero.')\n\n const quote = await withSpinner(`Quoting ${tokenIn.symbol} → ${tokenOut.symbol}…`, () =>\n quoteSwap(client, { tokenIn: tokenIn.address, tokenOut: tokenOut.address, amountIn }),\n )\n\n const amountOut = formatUnits(quote.amountOut, tokenOut.decimals)\n const minOut = formatUnits((quote.amountOut * BigInt(10_000 - slippageBps)) / 10_000n, tokenOut.decimals)\n const rate = Number(amountOut) / Number(opts.amount)\n\n const summary = {\n network: ctx.network,\n sell: { symbol: tokenIn.symbol, amount: opts.amount },\n buy: { symbol: tokenOut.symbol, amount: amountOut, minimum: minOut },\n rate,\n hops: quote.route.fees.length,\n slippageBps,\n }\n\n if (!opts.execute) {\n printResult(summary, () => renderQuote(summary, false), ctx.json)\n return\n }\n\n // maxSpendUsd guard rail: estimate what's being sold in USD (USDG is 1:1;\n // anything else prices off its own DEX quote) and refuse over the cap.\n const estimatedUsd = await estimateSpendUsd(client, tokenIn.symbol, tokenIn.address, tokenIn.decimals, Number(opts.amount))\n if (ctx.config.maxSpendUsd !== undefined && estimatedUsd === null) {\n warn(`Could not verify this swap against your $${ctx.config.maxSpendUsd} spend cap (no price route for ${tokenIn.symbol}) — proceeding.`)\n }\n checkSpendCap({ maxSpendUsd: ctx.config.maxSpendUsd, estimatedUsd })\n\n // Write path: money-moving action — render the confirmation table and stop\n // for explicit yes/no before signing, per CLAUDE.md's irreversible-action gate.\n if (!ctx.json) process.stdout.write(renderQuote(summary, true) + '\\n\\n')\n if (!ctx.assumeYes) {\n const ok = await confirm(`Swap ${opts.amount} ${tokenIn.symbol} for ~${num(Number(amountOut), 6)} ${tokenOut.symbol}?`)\n if (!ok) throw guardError('Swap cancelled.')\n }\n\n try {\n const approvalHash = await withSpinner(`Checking ${tokenIn.symbol} allowance…`, () =>\n ensureApproval(client, tokenIn.address, amountIn),\n )\n if (approvalHash && !ctx.json) process.stderr.write(dim(`Approved router: ${txUrl(ctx.network, approvalHash)}\\n`))\n\n const tx = buildSwapTx(client, quote, { slippageBps })\n const hash = await withSpinner('Sending swap…', () =>\n client.wallet!.sendTransaction({ to: tx.to, data: tx.data, value: tx.value, account: client.account!, chain: client.chain }),\n )\n const receipt = await withSpinner('Confirming…', () => client.public.waitForTransactionReceipt({ hash }))\n\n const result = { ...summary, hash, status: receipt.status, explorer: txUrl(ctx.network, hash) }\n printResult(result, () => renderResult(result), ctx.json)\n if (receipt.status !== 'success') process.exitCode = 1\n } catch (err) {\n if (err instanceof StockTokenEligibilityError) {\n throw guardError(\n 'Stock Token acquisition is gated for non-affirmed operators.',\n 'Re-run with --acknowledge-eligibility if you are eligible (not a US/CA/UK/CH person).',\n )\n }\n throw err\n }\n}\n\nasync function estimateSpendUsd(\n client: Parameters<typeof getDexPriceUsd>[0],\n symbol: string,\n address: `0x${string}`,\n decimals: number,\n amount: number,\n): Promise<number | null> {\n if (symbol === 'USDG') return amount\n const perToken = await getDexPriceUsd(client, address, decimals)\n return perToken !== null ? perToken * amount : null\n}\n\nfunction renderQuote(\n s: { network: string; sell: { symbol: string; amount: string }; buy: { symbol: string; amount: string; minimum: string }; rate: number; hops: number; slippageBps: number },\n confirming: boolean,\n): string {\n const header = confirming\n ? `${yellow('⚠')} ${bold('Confirm swap')} ${dim('· ' + s.network)}`\n : `${accent('◈')} ${bold('Swap quote')} ${dim('· ' + s.network + ' · add --execute to send')}`\n const pairs: [string, string][] = [\n ['Sell', bold(s.sell.amount) + ' ' + s.sell.symbol],\n ['Buy', bold(`~${s.buy.amount}`) + ' ' + s.buy.symbol],\n ['Min. received', dim(s.buy.minimum + ' ' + s.buy.symbol + ` (${(s.slippageBps / 100).toFixed(2)}% slippage)`)],\n ['Rate', `1 ${s.sell.symbol} ≈ ${num(s.rate, 6)} ${s.buy.symbol}`],\n ['Route', dim(s.hops === 1 ? 'direct pool' : `${s.hops}-hop route`)],\n ]\n return `${header}\\n${renderKeyValue(pairs, { labelWidth: 14 })}`\n}\n\nfunction renderResult(r: { hash: string; status: string; explorer: string; buy: { symbol: string; amount: string } }): string {\n const badge = r.status === 'success' ? green('✓ swap confirmed') : dim('✗ reverted')\n return `${badge}\\n${renderKeyValue(\n [\n ['Received', bold(`~${r.buy.amount}`) + ' ' + r.buy.symbol],\n ['Tx', gray(addr(r.hash as `0x${string}`))],\n ['Explorer', gray(r.explorer)],\n ],\n { labelWidth: 9 },\n )}`\n}\n","/**\n * The `maxSpendUsd` guard rail (`hood config set maxSpendUsd <n>`): a hard\n * ceiling on the USD value of a single swap or transfer. The USD-estimation\n * step is network-bound (oracle/DEX price lookups) and lives in the command\n * modules; this function is the pure decision so it is unit-testable without\n * a live RPC.\n */\nimport { guardError } from './errors.js'\n\nexport interface SpendCapCheck {\n /** The configured cap, or undefined when no cap is set (no-op). */\n maxSpendUsd: number | undefined\n /** Estimated USD value of the spend, or null when it could not be priced. */\n estimatedUsd: number | null\n}\n\n/**\n * Throws a GUARD error when `estimatedUsd` exceeds `maxSpendUsd`. A `null`\n * estimate (unpriceable token) never blocks — callers should surface a\n * warning instead, since refusing an unpriceable send would make the cap\n * unusable for memecoins with no oracle or liquid pool.\n */\nexport function checkSpendCap({ maxSpendUsd, estimatedUsd }: SpendCapCheck): void {\n if (maxSpendUsd === undefined) return\n if (estimatedUsd === null) return\n if (estimatedUsd > maxSpendUsd) {\n throw guardError(\n `This spends ~$${estimatedUsd.toFixed(2)}, which exceeds your configured cap of $${maxSpendUsd.toFixed(2)}.`,\n 'Raise the cap with `hood config set maxSpendUsd <n>`, or reduce --amount.',\n )\n }\n}\n","import { Command } from 'commander'\nimport { formatEther, formatUnits, getAddress, isAddress, parseEther, parseUnits } from 'viem'\nimport { erc20Abi } from 'hoodchain'\nimport { runWith } from '../action.js'\nimport type { Context } from '../context.js'\nimport { resolveToken } from '../resolve.js'\nimport { printResult } from '../output.js'\nimport { renderKeyValue } from '../ui/table.js'\nimport { withSpinner } from '../ui/spinner.js'\nimport { confirm } from '../prompt.js'\nimport { bold, dim, gray, green, yellow } from '../ui/ansi.js'\nimport { addr } from '../format.js'\nimport { txUrl } from '../blockscout.js'\nimport { guardError, usageError } from '../errors.js'\nimport { checkSpendCap } from '../spend-cap.js'\nimport { getDexPriceUsd } from '../prices.js'\nimport { MAINNET_ADDRESSES, TESTNET_ADDRESSES } from 'hoodchain'\nimport { warn } from '../output.js'\n\nexport function transferCommand(): Command {\n return new Command('transfer')\n .description('Send ETH or an ERC-20 token to an address')\n .requiredOption('--to <address>', 'recipient address')\n .requiredOption('--amount <amount>', 'amount to send, in whole tokens')\n .option('--token <token>', 'ticker or address to send (default: native ETH)')\n .action((opts, command) =>\n runWith(command, async (ctx) => {\n await transfer(ctx, opts)\n }),\n )\n}\n\ninterface TransferOpts {\n to: string\n amount: string\n token?: string\n}\n\nasync function transfer(ctx: Context, opts: TransferOpts): Promise<void> {\n if (!isAddress(opts.to)) throw usageError(`\"${opts.to}\" is not a valid recipient address.`)\n const to = getAddress(opts.to)\n const client = await ctx.wallet()\n\n const isNative = !opts.token\n const symbol = isNative ? 'ETH' : (await resolveToken(client, opts.token as string)).symbol\n const tokenInfo = isNative ? null : await resolveToken(client, opts.token as string)\n const amount = isNative ? parseEther(opts.amount) : parseUnits(opts.amount, tokenInfo!.decimals)\n if (amount <= 0n) throw usageError('--amount must be greater than zero.')\n\n const balance = isNative\n ? await client.public.getBalance({ address: client.account!.address })\n : await client.public.readContract({ address: tokenInfo!.address, abi: erc20Abi, functionName: 'balanceOf', args: [client.account!.address] })\n if (balance < amount) {\n throw guardError(\n `Insufficient balance: hold ${formatBalance(balance, isNative, tokenInfo?.decimals)} ${symbol}, need ${opts.amount}.`,\n )\n }\n\n // maxSpendUsd guard rail: USDG is 1:1, native ETH/other tokens price off\n // their own DEX quote against USDG.\n const spendToken = isNative ? (ctx.network === 'testnet' ? TESTNET_ADDRESSES.weth : MAINNET_ADDRESSES.weth) : tokenInfo!.address\n const estimatedUsd = await estimateSpendUsd(client, symbol, spendToken, isNative ? 18 : tokenInfo!.decimals, Number(opts.amount))\n if (ctx.config.maxSpendUsd !== undefined && estimatedUsd === null) {\n warn(`Could not verify this transfer against your $${ctx.config.maxSpendUsd} spend cap (no price route for ${symbol}) — proceeding.`)\n }\n checkSpendCap({ maxSpendUsd: ctx.config.maxSpendUsd, estimatedUsd })\n\n if (!ctx.json) {\n process.stdout.write(\n renderConfirm({ to, amount: opts.amount, symbol, network: ctx.network }) + '\\n\\n',\n )\n }\n if (!ctx.assumeYes) {\n const ok = await confirm(`Send ${opts.amount} ${symbol} to ${addr(to)}?`)\n if (!ok) throw guardError('Transfer cancelled.')\n }\n\n const hash = await withSpinner('Sending…', () =>\n isNative\n ? client.wallet!.sendTransaction({ to, value: amount, account: client.account!, chain: client.chain })\n : client.wallet!.writeContract({ address: tokenInfo!.address, abi: erc20Abi, functionName: 'transfer', args: [to, amount], account: client.account!, chain: client.chain }),\n )\n const receipt = await withSpinner('Confirming…', () => client.public.waitForTransactionReceipt({ hash }))\n\n const result = { to, amount: opts.amount, symbol, hash, status: receipt.status, explorer: txUrl(ctx.network, hash) }\n printResult(result, () => renderResult(result), ctx.json)\n if (receipt.status !== 'success') process.exitCode = 1\n}\n\nasync function estimateSpendUsd(\n client: Parameters<typeof getDexPriceUsd>[0],\n symbol: string,\n address: `0x${string}`,\n decimals: number,\n amount: number,\n): Promise<number | null> {\n if (symbol === 'USDG') return amount\n const perToken = await getDexPriceUsd(client, address, decimals)\n return perToken !== null ? perToken * amount : null\n}\n\nfunction formatBalance(balance: bigint, isNative: boolean, decimals?: number): string {\n return isNative ? formatEther(balance) : formatUnits(balance, decimals ?? 18)\n}\n\nfunction renderConfirm(s: { to: string; amount: string; symbol: string; network: string }): string {\n const header = `${yellow('⚠')} ${bold('Confirm transfer')} ${dim('· ' + s.network)}`\n const pairs: [string, string][] = [\n ['Amount', bold(s.amount) + ' ' + s.symbol],\n ['To', gray(s.to)],\n ]\n return `${header}\\n${renderKeyValue(pairs, { labelWidth: 7 })}`\n}\n\nfunction renderResult(r: { to: string; amount: string; symbol: string; hash: string; status: string; explorer: string }): string {\n const badge = r.status === 'success' ? green('✓ transfer confirmed') : dim('✗ reverted')\n return `${badge}\\n${renderKeyValue(\n [\n ['Sent', bold(r.amount) + ' ' + r.symbol + ' → ' + addr(r.to as `0x${string}`)],\n ['Tx', gray(addr(r.hash as `0x${string}`))],\n ['Explorer', gray(r.explorer)],\n ],\n { labelWidth: 9 },\n )}`\n}\n","import { Command } from 'commander'\nimport { formatEther, formatUnits } from 'viem'\nimport { TESTNET_ADDRESSES, TESTNET_STOCK_TOKENS, erc20Abi } from 'hoodchain'\nimport { runWith } from '../action.js'\nimport type { Context } from '../context.js'\nimport { printResult } from '../output.js'\nimport { renderKeyValue } from '../ui/table.js'\nimport { withSpinner } from '../ui/spinner.js'\nimport { accent, bold, dim, gray, underline } from '../ui/ansi.js'\nimport { num } from '../format.js'\nimport { usageError } from '../errors.js'\n\nconst FAUCET_URL = 'https://faucet.testnet.chain.robinhood.com/'\nconst CHAINLINK_FAUCET_URL = 'https://faucets.chain.link/robinhood-testnet'\n\nexport function faucetCommand(): Command {\n return new Command('faucet')\n .description('Print testnet faucet instructions + current testnet balances')\n .action((_opts, command) =>\n runWith(command, async (ctx) => {\n await faucet(ctx)\n }),\n )\n}\n\nasync function faucet(ctx: Context): Promise<void> {\n if (ctx.network !== 'testnet') {\n throw usageError('The faucet is testnet-only.', 'Re-run with --network testnet.')\n }\n\n let address: string | null = null\n let balances: { eth: string; tokens: { symbol: string; balance: string }[] } | null = null\n try {\n const client = await ctx.wallet()\n address = client.account!.address\n balances = await withSpinner('Reading testnet balances…', async () => {\n const owner = client.account!.address\n const [eth, ...tokenBalances] = await Promise.all([\n client.public.getBalance({ address: owner }),\n ...Object.entries(TESTNET_STOCK_TOKENS).map(([symbol, token]) =>\n client.public\n .readContract({ address: token, abi: erc20Abi, functionName: 'balanceOf', args: [owner] })\n .then((b) => ({ symbol, balance: formatUnits(b, 18) })),\n ),\n ])\n return { eth: formatEther(eth), tokens: tokenBalances }\n })\n } catch {\n // No wallet configured — instructions only, no balance section.\n }\n\n const json = {\n network: 'testnet',\n chainId: 46630,\n faucetUrl: FAUCET_URL,\n chainlinkFaucetUrl: CHAINLINK_FAUCET_URL,\n note: 'The faucet requires Cloudflare Turnstile + Google Sign-In in a real browser and cannot be automated from a CLI. One claim per 24h drips testnet ETH plus 5 of each: TSLA, AMZN, PLTR, NFLX, AMD.',\n address,\n balances,\n }\n\n printResult(json, () => renderFaucet(json), ctx.json)\n}\n\nfunction renderFaucet(j: {\n faucetUrl: string\n chainlinkFaucetUrl: string\n address: string | null\n balances: { eth: string; tokens: { symbol: string; balance: string }[] } | null\n}): string {\n const header = `${accent('◈')} ${bold('Testnet faucet')} ${dim('· chain 46630')}`\n const instructions = [\n dim('The faucet needs a browser session (Cloudflare Turnstile + Google Sign-In) —'),\n dim('this cannot be automated from a CLI. Claim once per 24h at:'),\n '',\n ` ${underline(j.faucetUrl)}`,\n ` ${dim('Chainlink ETH top-up:')} ${underline(j.chainlinkFaucetUrl)}`,\n '',\n dim('Each claim drips testnet ETH + 5 of each: TSLA, AMZN, PLTR, NFLX, AMD.'),\n ].join('\\n')\n\n if (!j.address || !j.balances) {\n return `${header}\\n${instructions}\\n\\n${dim('No wallet configured — run `hood config set wallet` to see your testnet balances here.')}`\n }\n\n const rows: [string, string][] = [['ETH', num(Number(j.balances.eth), 6)]]\n for (const t of j.balances.tokens) rows.push([t.symbol, num(Number(t.balance), 4)])\n\n return `${header}\\n${instructions}\\n\\n${dim('Wallet ' + j.address)}\\n${renderKeyValue(rows, { labelWidth: 6 })}`\n}\n","import { Command } from 'commander'\nimport { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { encodeDeployData, isAddress } from 'viem'\nimport { runWith } from '../action.js'\nimport type { Context } from '../context.js'\nimport { HOOD_TOKEN_ABI, HOOD_TOKEN_BYTECODE, HOOD_TOKEN_COMPILER } from '../generated/erc20.js'\nimport { printResult } from '../output.js'\nimport { renderKeyValue } from '../ui/table.js'\nimport { withSpinner } from '../ui/spinner.js'\nimport { confirm } from '../prompt.js'\nimport { accent, bold, dim, gray, green, yellow } from '../ui/ansi.js'\nimport { addr, num } from '../format.js'\nimport { txUrl, addressUrl } from '../blockscout.js'\nimport { guardError, usageError } from '../errors.js'\n\ninterface TokenConfig {\n name: string\n symbol: string\n decimals?: number\n initialSupply: number\n}\n\nexport function deployTokenCommand(): Command {\n return new Command('deploy-token')\n .description('Deploy a fixed-supply ERC-20 from a JSON config (direct-rail, no launchpad)')\n .requiredOption('--config <path>', 'path to a JSON file: { name, symbol, decimals?, initialSupply }')\n .option('--execute', 'sign and send (default: print the plan only)', false)\n .action((opts, command) =>\n runWith(command, async (ctx) => {\n await deployToken(ctx, opts)\n }),\n )\n}\n\ninterface DeployOpts {\n config: string\n execute: boolean\n}\n\nasync function deployToken(ctx: Context, opts: DeployOpts): Promise<void> {\n const config = readConfig(opts.config)\n const decimals = config.decimals ?? 18\n\n const deployData = encodeDeployData({\n abi: HOOD_TOKEN_ABI,\n bytecode: HOOD_TOKEN_BYTECODE,\n args: [config.name, config.symbol, decimals, BigInt(config.initialSupply)],\n })\n\n const plan = {\n network: ctx.network,\n name: config.name,\n symbol: config.symbol,\n decimals,\n initialSupply: config.initialSupply,\n compiler: HOOD_TOKEN_COMPILER.version,\n bytecodeBytes: (deployData.length - 2) / 2,\n }\n\n if (!opts.execute) {\n printResult(plan, () => renderPlan(plan, false), ctx.json)\n return\n }\n\n const client = await ctx.wallet()\n if (!ctx.json) process.stdout.write(renderPlan(plan, true) + '\\n\\n')\n if (!ctx.assumeYes) {\n const ok = await confirm(`Deploy ${config.symbol} (${num(config.initialSupply, 0)} supply) on ${ctx.network}? This costs gas and cannot be undone.`)\n if (!ok) throw guardError('Deploy cancelled.')\n }\n\n const hash = await withSpinner('Deploying…', () =>\n client.wallet!.deployContract({\n abi: HOOD_TOKEN_ABI,\n bytecode: HOOD_TOKEN_BYTECODE,\n args: [config.name, config.symbol, decimals, BigInt(config.initialSupply)],\n account: client.account!,\n chain: client.chain,\n }),\n )\n const receipt = await withSpinner('Confirming…', () => client.public.waitForTransactionReceipt({ hash }))\n\n if (!receipt.contractAddress) {\n throw guardError('Deployment transaction confirmed but returned no contract address.', 'Check the transaction on the explorer.')\n }\n\n const result = {\n ...plan,\n hash,\n status: receipt.status,\n address: receipt.contractAddress,\n explorer: txUrl(ctx.network, hash),\n tokenExplorer: addressUrl(ctx.network, receipt.contractAddress),\n }\n printResult(result, () => renderResult(result), ctx.json)\n if (receipt.status !== 'success') process.exitCode = 1\n}\n\nfunction readConfig(path: string): TokenConfig {\n let raw: string\n try {\n raw = readFileSync(resolve(path), 'utf8')\n } catch {\n throw usageError(`Could not read config file \"${path}\".`)\n }\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch {\n throw usageError(`\"${path}\" is not valid JSON.`)\n }\n const c = parsed as Partial<TokenConfig>\n if (typeof c.name !== 'string' || !c.name.trim()) throw usageError('Config \"name\" must be a non-empty string.')\n if (typeof c.symbol !== 'string' || !c.symbol.trim()) throw usageError('Config \"symbol\" must be a non-empty string.')\n if (c.decimals !== undefined && (!Number.isInteger(c.decimals) || c.decimals < 0 || c.decimals > 255)) {\n throw usageError('Config \"decimals\" must be an integer 0-255.')\n }\n if (!Number.isInteger(c.initialSupply) || (c.initialSupply as number) <= 0) {\n throw usageError('Config \"initialSupply\" must be a positive whole-token integer.')\n }\n return { name: c.name, symbol: c.symbol, decimals: c.decimals, initialSupply: c.initialSupply as number }\n}\n\nfunction renderPlan(\n p: { network: string; name: string; symbol: string; decimals: number; initialSupply: number; compiler: string; bytecodeBytes: number },\n confirming: boolean,\n): string {\n const header = confirming\n ? `${yellow('⚠')} ${bold('Confirm deploy')} ${dim('· ' + p.network)}`\n : `${accent('◈')} ${bold('Deploy plan')} ${dim('· ' + p.network + ' · add --execute to send')}`\n const pairs: [string, string][] = [\n ['Name', bold(p.name)],\n ['Symbol', bold(p.symbol)],\n ['Decimals', String(p.decimals)],\n ['Supply', num(p.initialSupply, 0) + ' ' + p.symbol],\n ['Compiler', dim(p.compiler)],\n ['Bytecode', dim(p.bytecodeBytes + ' bytes')],\n ]\n return `${header}\\n${renderKeyValue(pairs, { labelWidth: 9 })}`\n}\n\nfunction renderResult(r: { address: string; hash: string; status: string; explorer: string; tokenExplorer: string; symbol: string }): string {\n const badge = r.status === 'success' ? green('✓ deployed') : dim('✗ reverted')\n return `${badge}\\n${renderKeyValue(\n [\n ['Token', bold(r.symbol) + ' ' + gray(addr(r.address as `0x${string}`))],\n ['Tx', gray(addr(r.hash as `0x${string}`))],\n ['Explorer', gray(r.tokenExplorer)],\n ],\n { labelWidth: 9 },\n )}`\n}\n","// AUTO-GENERATED by scripts/compile-erc20.mjs from contracts/ERC20.sol — do not edit.\n// Compiler: 0.8.36+commit.8a079791.Emscripten.clang, optimizer 200 runs, evmVersion paris.\nimport type { Abi } from 'viem'\n\nexport const HOOD_TOKEN_ABI = [{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"_decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"_initialSupply\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}] as const satisfies Abi\n\nexport const HOOD_TOKEN_BYTECODE = '0x60a060405234801561001057600080fd5b50604051610b29380380610b2983398101604081905261002f91610182565b600061003b85826102a1565b50600161004884826102a1565b5060ff8216608081905260009061006090600a610462565b61006a9083610475565b6002819055336000818152600360205260408082208490555192935090917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906100b79085815260200190565b60405180910390a3505050505061048c565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126100f057600080fd5b81516001600160401b03811115610109576101096100c9565b604051601f8201601f19908116603f011681016001600160401b0381118282101715610137576101376100c9565b60405281815283820160200185101561014f57600080fd5b60005b8281101561016e57602081860181015183830182015201610152565b506000918101602001919091529392505050565b6000806000806080858703121561019857600080fd5b84516001600160401b038111156101ae57600080fd5b6101ba878288016100df565b602087015190955090506001600160401b038111156101d857600080fd5b6101e4878288016100df565b935050604085015160ff811681146101fb57600080fd5b6060959095015193969295505050565b600181811c9082168061021f57607f821691505b60208210810361023f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561029c578282111561029c57806000526020600020601f840160051c6020851015610273575060005b90810190601f840160051c0360005b8181101561029857600083820155600101610282565b5050505b505050565b81516001600160401b038111156102ba576102ba6100c9565b6102ce816102c8845461020b565b84610245565b6020601f82116001811461030257600083156102ea5750848201515b600019600385901b1c1916600184901b17845561035c565b600084815260208120601f198516915b828110156103325787850151825560209485019460019092019101610312565b50848210156103505786840151600019600387901b60f8161c191681555b505060018360011b0184555b5050505050565b634e487b7160e01b600052601160045260246000fd5b6001815b60018411156103b45780850481111561039857610398610363565b60018416156103a657908102905b60019390931c92800261037d565b935093915050565b6000826103cb5750600161045c565b816103d85750600061045c565b81600181146103ee57600281146103f857610414565b600191505061045c565b60ff84111561040957610409610363565b50506001821b61045c565b5060208310610133831016604e8410600b8410161715610437575081810a61045c565b6104446000198484610379565b806000190482111561045857610458610363565b0290505b92915050565b600061046e83836103bc565b9392505050565b808202811582820484141761045c5761045c610363565b6080516106826104a7600039600061010801526106826000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063313ce56711610066578063313ce5671461010357806370a082311461013c57806395d89b411461015c578063a9059cbb14610164578063dd62ed3e1461017757600080fd5b806306fdde0314610098578063095ea7b3146100b657806318160ddd146100d957806323b872dd146100f0575b600080fd5b6100a06101a2565b6040516100ad91906104d2565b60405180910390f35b6100c96100c436600461053c565b610230565b60405190151581526020016100ad565b6100e260025481565b6040519081526020016100ad565b6100c96100fe366004610566565b61029d565b61012a7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016100ad565b6100e261014a3660046105a3565b60036020526000908152604090205481565b6100a0610362565b6100c961017236600461053c565b61036f565b6100e26101853660046105be565b600460209081526000928352604080842090915290825290205481565b600080546101af906105f1565b80601f01602080910402602001604051908101604052809291908181526020018280546101db906105f1565b80156102285780601f106101fd57610100808354040283529160200191610228565b820191906000526020600020905b81548152906001019060200180831161020b57829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061028b9086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383166000908152600460209081526040808320338452909152812054600019811461034e578281101561031f5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064015b60405180910390fd5b610329838261062b565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b610359858585610383565b95945050505050565b600180546101af906105f1565b600061037c338484610383565b9392505050565b60006001600160a01b0383166103e75760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610316565b6001600160a01b0384166000908152600360205260409020548281101561045f5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610316565b6001600160a01b0380861660008181526003602052604080822087860390559287168082529083902080548701905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906104bf9087815260200190565b60405180910390a3506001949350505050565b602081526000825180602084015260005b8181101561050057602081860181015160408684010152016104e3565b506000604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461053757600080fd5b919050565b6000806040838503121561054f57600080fd5b61055883610520565b946020939093013593505050565b60008060006060848603121561057b57600080fd5b61058484610520565b925061059260208501610520565b929592945050506040919091013590565b6000602082840312156105b557600080fd5b61037c82610520565b600080604083850312156105d157600080fd5b6105da83610520565b91506105e860208401610520565b90509250929050565b600181811c9082168061060557607f821691505b60208210810361062557634e487b7160e01b600052602260045260246000fd5b50919050565b8181038181111561029757634e487b7160e01b600052601160045260246000fdfea2646970667358221220471bc2210cddfb1cf75b9da206267431454db88507c132d3528fab99e5907b0864736f6c63430008240033' as const\n\nexport const HOOD_TOKEN_COMPILER = {\"name\":\"solc\",\"version\":\"0.8.36+commit.8a079791.Emscripten.clang\",\"optimizer\":{\"enabled\":true,\"runs\":200},\"evmVersion\":\"paris\"} as const\n","import { Command } from 'commander'\nimport { getAddress } from 'viem'\nimport { privateKeyToAccount, generatePrivateKey } from 'viem/accounts'\nimport {\n loadConfig,\n saveConfig,\n setConfigValue,\n redactedConfig,\n defaultKeystorePath,\n CONFIG_KEYS,\n type HoodConfig,\n} from '../config.js'\nimport { writeKeystore, keystoreExists, passwordsMatch } from '../keystore.js'\nimport { readPassword, confirm } from '../prompt.js'\nimport { printJson, printHuman } from '../output.js'\nimport { renderKeyValue } from '../ui/table.js'\nimport { accent, bold, dim, green } from '../ui/ansi.js'\nimport { setColorEnabled } from '../ui/ansi.js'\nimport { guardError, usageError } from '../errors.js'\n\nexport function configCommand(): Command {\n const cmd = new Command('config').description('Manage hood-cli settings (rpc, wallet, network)')\n\n cmd\n .command('set <key> [value]')\n .description(`set a config value (${CONFIG_KEYS.join(', ')}, wallet)`)\n .action(async (key: string, value: string | undefined, _opts, command) => {\n if (command.optsWithGlobals().color === false) setColorEnabled(false)\n const json = !!command.optsWithGlobals().json\n if (key === 'wallet') {\n await setWallet(json, !!command.optsWithGlobals().yes)\n return\n }\n if (value === undefined) throw usageError(`\"hood config set ${key}\" needs a value.`)\n const config = loadConfig()\n const next = setConfigValue(config, key, value)\n saveConfig(next)\n if (json) printJson({ ok: true, key, value })\n else printHuman(`${green('✓')} ${key} = ${value}`)\n })\n\n cmd\n .command('get <key>')\n .description('print one config value')\n .action((key: string, _opts, command) => {\n const json = !!command.optsWithGlobals().json\n const view = redactedConfig(loadConfig())\n if (!(key in view)) throw usageError(`Unknown config key \"${key}\".`, `Valid keys: ${Object.keys(view).join(', ')}.`)\n const value = view[key as keyof typeof view]\n if (json) printJson({ [key]: value })\n else printHuman(String(value ?? dim('unset')))\n })\n\n cmd\n .command('list')\n .description('print the full config (secrets masked)')\n .action((_opts, command) => {\n const json = !!command.optsWithGlobals().json\n const view = redactedConfig(loadConfig())\n if (json) {\n printJson(view)\n return\n }\n const pairs: [string, string][] = Object.entries(view).map(([k, v]) => [k, v === null ? dim('unset') : String(v)])\n printHuman(`${accent('◈')} ${bold('hood config')}\\n${renderKeyValue(pairs, { labelWidth: 14 })}`)\n })\n\n return cmd\n}\n\nasync function setWallet(json: boolean, assumeYes: boolean): Promise<void> {\n const config = loadConfig()\n const keystorePath = config.walletKeystore ?? defaultKeystorePath()\n\n if (keystoreExists(keystorePath) && !assumeYes) {\n const overwrite = await confirm(`A wallet already exists at ${keystorePath}. Overwrite it?`)\n if (!overwrite) throw guardError('Wallet setup cancelled.')\n }\n\n const importKey = process.env.ROBINHOOD_CHAIN_IMPORT_KEY\n const privateKey = importKey\n ? ((importKey.startsWith('0x') ? importKey : `0x${importKey}`) as `0x${string}`)\n : generatePrivateKey()\n const account = privateKeyToAccount(privateKey)\n\n const password = await readPassword('New wallet password (min 8 chars):')\n const confirmPassword = await readPassword('Confirm password:')\n if (!passwordsMatch(password, confirmPassword)) throw guardError('Passwords did not match.')\n\n writeKeystore(keystorePath, privateKey, getAddress(account.address), password)\n const next: HoodConfig = { ...config, walletKeystore: keystorePath, walletAddress: account.address }\n saveConfig(next)\n\n const result = { ok: true, address: account.address, keystore: keystorePath, imported: !!importKey }\n if (json) {\n printJson(result)\n return\n }\n printHuman(\n `${green('✓')} Wallet ${result.imported ? 'imported' : 'generated'}: ${bold(account.address)}\\n` +\n dim(` Encrypted keystore: ${keystorePath}`) +\n (result.imported ? '' : `\\n${dim(' This is a NEW address — fund it before sending anything.')}`),\n )\n}\n","import { createProgram } from './program.js'\nimport { presentError } from './output.js'\n\nconst program = createProgram()\n\nprogram.exitOverride((err) => {\n // commander's own usage/version/help exits — let them through as-is.\n if (err.code === 'commander.helpDisplayed' || err.code === 'commander.version') {\n process.exit(0)\n }\n process.exitCode = 2\n throw err\n})\n\nprocess.on('unhandledRejection', (err) => {\n process.exitCode = presentError(err, { json: process.argv.includes('--json'), verbose: process.argv.includes('--verbose') })\n})\n\ntry {\n await program.parseAsync(process.argv)\n} catch (err) {\n if (process.exitCode === undefined) {\n process.exitCode = presentError(err, { json: process.argv.includes('--json'), verbose: process.argv.includes('--verbose') })\n }\n}\n"],"mappings":"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","names":["Command","readFileSync","dirname","join","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","mkdirSync","dirname","writeFileSync","existsSync","readFileSync","resolve","token","token","formatUnits","formatUnits","token","watch","Command","Command","Command","Command","launches","token","Command","Command","Command","formatEther","getAddress","isAddress","Command","isAddress","getAddress","port","usdg","eth","formatEther","Command","formatEther","Command","transaction","receipt","meta","block","formatEther","Command","Command","meta","multiplier","oracle","dexUsd","totalSupply","Command","formatEther","getAddress","isAddress","Command","isAddress","token","getAddress","tx","formatEther","MAINNET_ADDRESSES","Command","formatUnits","parseUnits","Command","parseUnits","formatUnits","tx","Command","formatEther","formatUnits","getAddress","isAddress","parseUnits","Command","isAddress","getAddress","parseUnits","estimateSpendUsd","renderResult","formatEther","formatUnits","Command","formatEther","formatUnits","Command","token","formatUnits","formatEther","Command","readFileSync","Command","renderResult","readFileSync","Command","getAddress","privateKeyToAccount","Command","privateKeyToAccount","getAddress","dirname","readFileSync","join","program","Command"]}
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ DEFAULT_MAX_FEED_AGE_SECONDS,
4
+ FEED_DECIMALS,
5
+ FeedConnectionError,
6
+ FeedNotFoundError,
7
+ HoodchainError,
8
+ InvalidFeedAnswerError,
9
+ MAINNET_ADDRESSES,
10
+ MAINNET_EXPLORER_URL,
11
+ MAINNET_FEED_URL,
12
+ NOXA_ADDRESSES,
13
+ NoAccountError,
14
+ NoRouteError,
15
+ ODYSSEY_ADDRESSES,
16
+ STOCK_TOKEN_DECIMALS,
17
+ SlippageExceededError,
18
+ StaleFeedError,
19
+ StockTokenEligibilityError,
20
+ TESTNET_ADDRESSES,
21
+ TESTNET_STOCK_TOKENS,
22
+ USDG_DECIMALS,
23
+ UnknownSymbolError,
24
+ V3_FEE_TIERS,
25
+ aggregatorV3Abi,
26
+ approveUsdg,
27
+ buildSwapTx,
28
+ createHoodClient,
29
+ ensureApproval,
30
+ erc20Abi,
31
+ executeSwap,
32
+ formatUsdg,
33
+ getMultiplier,
34
+ getPortfolio,
35
+ getPosition,
36
+ getQuote,
37
+ getRecentLaunches,
38
+ getRegistry,
39
+ getStockToken,
40
+ getStockTokenByAddress,
41
+ getUsdgAllowance,
42
+ getUsdgBalance,
43
+ getUsdgTotalSupply,
44
+ isStockTokenAddress,
45
+ isStockTokenSymbol,
46
+ listPricedStockTokens,
47
+ listStockTokens,
48
+ noxaTokenLaunchedEvent,
49
+ odysseyPoolMigratedEvent,
50
+ odysseyTokenCreatedEvent,
51
+ odysseyTradedEvent,
52
+ parseUsdg,
53
+ quoteSwap,
54
+ quoterV2Abi,
55
+ stockTokenAbi,
56
+ subscribeFeed,
57
+ swapAddresses,
58
+ swapRouter02Abi,
59
+ swapRouterAbi,
60
+ transferUsdg,
61
+ uniswapV3FactoryAbi,
62
+ uniswapV3PoolAbi,
63
+ usdgAddress,
64
+ watchCurveTrades,
65
+ watchGraduations,
66
+ watchLaunches,
67
+ watchTransfers,
68
+ weth9Abi
69
+ } from "./chunk-CWEBZB3L.js";
70
+ export {
71
+ DEFAULT_MAX_FEED_AGE_SECONDS,
72
+ FEED_DECIMALS,
73
+ FeedConnectionError,
74
+ FeedNotFoundError,
75
+ HoodchainError,
76
+ InvalidFeedAnswerError,
77
+ MAINNET_ADDRESSES,
78
+ MAINNET_EXPLORER_URL,
79
+ MAINNET_FEED_URL,
80
+ NOXA_ADDRESSES,
81
+ NoAccountError,
82
+ NoRouteError,
83
+ ODYSSEY_ADDRESSES,
84
+ STOCK_TOKEN_DECIMALS,
85
+ SlippageExceededError,
86
+ StaleFeedError,
87
+ StockTokenEligibilityError,
88
+ TESTNET_ADDRESSES,
89
+ TESTNET_STOCK_TOKENS,
90
+ USDG_DECIMALS,
91
+ UnknownSymbolError,
92
+ V3_FEE_TIERS,
93
+ aggregatorV3Abi,
94
+ approveUsdg,
95
+ buildSwapTx,
96
+ createHoodClient,
97
+ ensureApproval,
98
+ erc20Abi,
99
+ executeSwap,
100
+ formatUsdg,
101
+ getMultiplier,
102
+ getPortfolio,
103
+ getPosition,
104
+ getQuote,
105
+ getRecentLaunches,
106
+ getRegistry,
107
+ getStockToken,
108
+ getStockTokenByAddress,
109
+ getUsdgAllowance,
110
+ getUsdgBalance,
111
+ getUsdgTotalSupply,
112
+ isStockTokenAddress,
113
+ isStockTokenSymbol,
114
+ listPricedStockTokens,
115
+ listStockTokens,
116
+ noxaTokenLaunchedEvent,
117
+ odysseyPoolMigratedEvent,
118
+ odysseyTokenCreatedEvent,
119
+ odysseyTradedEvent,
120
+ parseUsdg,
121
+ quoteSwap,
122
+ quoterV2Abi,
123
+ stockTokenAbi,
124
+ subscribeFeed,
125
+ swapAddresses,
126
+ swapRouter02Abi,
127
+ swapRouterAbi,
128
+ transferUsdg,
129
+ uniswapV3FactoryAbi,
130
+ uniswapV3PoolAbi,
131
+ usdgAddress,
132
+ watchCurveTrades,
133
+ watchGraduations,
134
+ watchLaunches,
135
+ watchTransfers,
136
+ weth9Abi
137
+ };
138
+ //# sourceMappingURL=dist-PVZTS5LZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}