#!/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)
})