OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-wallet / deprecated / cli.js

212 lines · javascript ref:
#!/usr/bin/env pear

// cli.js - Hyper Wallet CLI Entry Point
//
// Self-custodial P2P cryptocurrency wallet
// Built on Holepunchto + Tether WDK

import WalletContext from './lib/wallet-context.js'
import { loadMnemonic, isInitialized } from './lib/secure-storage.js'

// Hard-coded config for now (TODO: load from file)
const defaultConfig = {
  storagePath: '~/.hyper-wallet/storage',
  network: 'testnet',
  protocols: ['wdk'],
  wdk: {
    chains: ['ethereum', 'bitcoin'],
    networks: {
      ethereum: {
        name: 'sepolia',
        provider: 'https://ethereum-sepolia-rpc.publicnode.com',
        chainId: 11155111
      },
      bitcoin: {
        network: 'testnet',
        host: 'electrum.blockstream.info',
        port: 60001
      }
    }
  }
}

// Command handlers
import cmdInit from './cmd/init.js'
import cmdWhoami from './cmd/whoami.js'
import cmdBalance from './cmd/balance.js'
import cmdSend from './cmd/send.js'
import cmdReceive from './cmd/receive.js'
import cmdHistory from './cmd/history.js'
import { getEnabledProtocols } from './protocols/index.js'

async function main() {
  const args = process.argv.slice(2)
  const command = args[0]

  // Load config (merge default + user config if exists)
  const config = defaultConfig

  // Create wallet context
  const context = new WalletContext(config)

  try {
    switch (command) {
      case 'init': {
        const importMnemonic = args.includes('--import') ?
          args[args.indexOf('--import') + 1] : null

        const handler = cmdInit(context)[0]
        await handler({ import: importMnemonic })
        break
      }

      case 'whoami': {
        // Check if wallet is initialized
        if (!(await isInitialized())) {
          console.error('❌ Wallet not initialized. Run: hyper-wallet init')
          process.exit(1)
        }

        // Load existing wallet
        await context.init(await loadMnemonic())

        const enabled = getEnabledProtocols(config)
        await context.loadProtocols(enabled)

        const handler = cmdWhoami(context)[0]
        await handler({})
        break
      }

      case 'balance': {
        // Check if wallet is initialized
        if (!(await isInitialized())) {
          console.error('❌ Wallet not initialized. Run: hyper-wallet init')
          process.exit(1)
        }

        // Load existing wallet
        await context.init(await loadMnemonic())

        const enabled = getEnabledProtocols(config)
        await context.loadProtocols(enabled)

        const protocol = args[1]
        const handler = cmdBalance(context, enabled)[0]
        await handler({ protocol })
        break
      }

      case 'send': {
        // Check if wallet is initialized
        if (!(await isInitialized())) {
          console.error('❌ Wallet not initialized. Run: hyper-wallet init')
          process.exit(1)
        }

        // Load existing wallet
        await context.init(await loadMnemonic())

        const enabled = getEnabledProtocols(config)
        await context.loadProtocols(enabled)

        const handler = cmdSend(context, enabled)[0]
        await handler(args.slice(1))
        break
      }

      case 'receive': {
        // Check if wallet is initialized
        if (!(await isInitialized())) {
          console.error('❌ Wallet not initialized. Run: hyper-wallet init')
          process.exit(1)
        }

        // Load existing wallet
        await context.init(await loadMnemonic())

        const enabled = getEnabledProtocols(config)
        await context.loadProtocols(enabled)

        const handler = cmdReceive(context, enabled)[0]
        await handler(args.slice(1))
        break
      }

      case 'history': {
        // Check if wallet is initialized
        if (!(await isInitialized())) {
          console.error('❌ Wallet not initialized. Run: hyper-wallet init')
          process.exit(1)
        }

        // Load existing wallet
        await context.init(await loadMnemonic())

        const enabled = getEnabledProtocols(config)
        await context.loadProtocols(enabled)

        const handler = cmdHistory(context, enabled)[0]
        await handler(args.slice(1))
        break
      }

      case 'help':
      case '--help':
      case '-h':
      default:
        showHelp()
        break
    }
  } catch (err) {
    console.error('❌ Error:', err.message)
    if (process.env.DEBUG) {
      console.error(err.stack)
    }
    process.exit(1)
  } finally {
    await context.close()
  }
}

/**
 * Show help message
 */
function showHelp() {
  console.log(`
hyper-wallet - Self-custodial P2P cryptocurrency wallet

USAGE:
  hyper-wallet <command> [options]

COMMANDS:
  init              Initialize new wallet
  init --import     Import existing wallet from mnemonic
  whoami            Show wallet identity and addresses
  balance           Show balances across all protocols
  balance <proto>   Show balance for specific protocol
  send <to> <amt>   Send payment
  receive [chain]   Generate receiving address
  history [proto]   Show transaction history
  help              Show this help message

EXAMPLES:
  hyper-wallet init
  hyper-wallet whoami
  hyper-wallet balance
  hyper-wallet receive wdk ethereum
  hyper-wallet send 0x123... 0.1
  hyper-wallet history wdk

Supported protocols: wdk (Tether WDK - Lightning, USDT, Bitcoin, ETH+)

Documentation: See docs/architecture/ARCHITECTURE.md and GETTING_STARTED.md
`)
}

// Run CLI
main().catch(err => {
  console.error('Fatal error:', err)
  process.exit(1)
})