OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-lab / tests / integration / demo-transaction-history.js

166 lines · javascript ref:
#!/usr/bin/env node

/**
 * Transaction History Demonstration
 *
 * Visual demo of Bitcoin transaction history syncing across devices
 * This test leaves the tmux session open for inspection
 */

import { TmuxOrchestrator } from '../../lib/tmux-orchestrator.js'
import fs from 'fs'

const agents = JSON.parse(fs.readFileSync('agents.json', 'utf8')).agents

export default async function demoTransactionHistory(agentConfigs = agents, options = {}) {
  const test = new TmuxOrchestrator('tx-history-demo', agentConfigs)

  try {
    await test.connect()
    await test.createSession()

    await test.log('🎬 Transaction History Demonstration', 'blue')
    await test.log('Showing Bitcoin + Ethereum transaction history across devices', 'blue')
    await test.log('', 'blue')

    // Navigate to wallet directory on both devices
    await test.sendKeys(test.paneMap.get('tabertron'), 'cd /storage/projects/code/hypercore-kb/hyper-fleeky/hyper-wallet')
    await test.sendKeys(test.paneMap.get('ashatron'), 'cd /home/fleeky/projects/code/hypercore-kb/hyper-fleeky/hyper-wallet')
    await test.sleep(1000)

    // Step 1: Sync Bitcoin transactions on tabertron
    await test.log('📋 Step 1: Syncing Bitcoin transaction history on tabertron', 'blue')
    await test.log('', 'blue')

    await test.sendKeys(test.paneMap.get('tabertron'), 'echo "🔄 Syncing Bitcoin transactions from blockchain..."')
    await test.sleep(500)
    await test.sendKeys(test.paneMap.get('tabertron'), 'bare hyper-wallet-autobase.cjs sync-history testnet-bitcoin')

    await test.log('⏳ Waiting for blockchain query...', 'yellow')
    await test.sleep(15000)

    // Step 2: Display Bitcoin history on tabertron
    await test.log('📋 Step 2: Displaying Bitcoin transaction history on tabertron', 'blue')
    await test.log('', 'blue')

    await test.sendKeys(test.paneMap.get('tabertron'), 'echo ""')
    await test.sleep(500)
    await test.sendKeys(test.paneMap.get('tabertron'), 'echo "📜 Bitcoin Transaction History (Tabertron):"')
    await test.sleep(500)
    await test.sendKeys(test.paneMap.get('tabertron'), 'bare hyper-wallet-autobase.cjs history testnet-bitcoin')

    await test.sleep(3000)

    const tabertronHistory = await test.capturePane(test.paneMap.get('tabertron'), 100)
    const txCountMatch = tabertronHistory.match(/Total: (\d+) transaction/)
    const btcTxCount = txCountMatch ? parseInt(txCountMatch[1]) : 0

    if (btcTxCount > 0) {
      await test.log(`✅ Tabertron has ${btcTxCount} Bitcoin transaction${btcTxCount === 1 ? '' : 's'}`, 'green')
    } else {
      await test.log('⚠️  No Bitcoin transactions found on tabertron', 'yellow')
    }

    // Step 3: Display Bitcoin history on ashatron
    await test.log('📋 Step 3: Displaying Bitcoin transaction history on ashatron', 'blue')
    await test.log('   (Should auto-sync via Autobase)', 'blue')
    await test.log('', 'blue')

    await test.sendKeys(test.paneMap.get('ashatron'), 'echo ""')
    await test.sleep(500)
    await test.sendKeys(test.paneMap.get('ashatron'), 'echo "📜 Bitcoin Transaction History (Ashatron):"')
    await test.sleep(500)
    await test.sendKeys(test.paneMap.get('ashatron'), 'bare hyper-wallet-autobase.cjs history testnet-bitcoin')

    await test.sleep(5000)

    const ashatronHistory = await test.capturePane(test.paneMap.get('ashatron'), 100)
    const ashaTxCountMatch = ashatronHistory.match(/Total: (\d+) transaction/)
    const ashaBtcTxCount = ashaTxCountMatch ? parseInt(ashaTxCountMatch[1]) : 0

    if (ashaBtcTxCount === btcTxCount && btcTxCount > 0) {
      await test.log(`✅ Ashatron also has ${ashaBtcTxCount} Bitcoin transaction${ashaBtcTxCount === 1 ? '' : 's'} - SYNCED!`, 'green')
    } else if (ashaBtcTxCount === 0 && btcTxCount === 0) {
      await test.log('✅ Both devices have 0 transactions (no blockchain activity yet)', 'green')
    } else {
      await test.log(`⚠️  Sync mismatch: tabertron=${btcTxCount}, ashatron=${ashaBtcTxCount}`, 'yellow')
    }

    // Step 4: Try Ethereum sync (will show API key message or transactions)
    await test.log('📋 Step 4: Attempting Ethereum transaction sync', 'blue')
    await test.log('', 'blue')

    await test.sendKeys(test.paneMap.get('tabertron'), 'echo ""')
    await test.sleep(500)
    await test.sendKeys(test.paneMap.get('tabertron'), 'echo "🔄 Syncing Ethereum transactions..."')
    await test.sleep(500)
    await test.sendKeys(test.paneMap.get('tabertron'), 'bare hyper-wallet-autobase.cjs sync-history testnet-ethereum')

    await test.sleep(5000)

    const ethSyncOutput = await test.capturePane(test.paneMap.get('tabertron'), 100)

    if (ethSyncOutput.includes('API key required')) {
      await test.log('💡 Ethereum history requires Etherscan API key (see instructions on screen)', 'yellow')
    } else if (ethSyncOutput.includes('New transactions:')) {
      await test.log('✅ Ethereum transactions synced!', 'green')

      // Show Ethereum history if we got transactions
      await test.sleep(2000)
      await test.sendKeys(test.paneMap.get('tabertron'), 'echo ""')
      await test.sleep(500)
      await test.sendKeys(test.paneMap.get('tabertron'), 'echo "📜 Ethereum Transaction History (Tabertron):"')
      await test.sleep(500)
      await test.sendKeys(test.paneMap.get('tabertron'), 'bare hyper-wallet-autobase.cjs history testnet-ethereum')
      await test.sleep(3000)
    }

    // Final display: Show side-by-side comparison
    await test.log('', 'blue')
    await test.log('=' .repeat(60), 'green')
    await test.log('🎉 Transaction History Demonstration Complete', 'green')
    await test.log('=' .repeat(60), 'green')
    await test.log('', 'green')
    await test.log('📊 Summary:', 'blue')
    await test.log(`  • Tabertron Bitcoin transactions: ${btcTxCount}`, 'blue')
    await test.log(`  • Ashatron Bitcoin transactions: ${ashaBtcTxCount}`, 'blue')
    await test.log(`  • Multi-device sync: ${btcTxCount === ashaBtcTxCount ? '✅ Working' : '⚠️  Check logs'}`, 'blue')
    await test.log('', 'blue')
    await test.log('👀 Tmux session left open for inspection', 'yellow')
    await test.log(`   Attach: tmux attach -t ${test.sessionName}`, 'yellow')
    await test.log('   Use Ctrl+B then arrow keys to switch panes', 'yellow')
    await test.log('   Type "exit" in each pane to close', 'yellow')
    await test.log('', 'yellow')

    return test.sessionName

  } catch (error) {
    await test.log(`\n❌ Demo failed: ${error.message}`, 'red')
    console.error(error)
    throw error
  } finally {
    // DON'T cleanup - leave session open for inspection
    await test.log('📌 Session remains active for viewing', 'blue')
  }
}

// Run if called directly
if (import.meta.url === `file://${process.argv[1]}`) {
  demoTransactionHistory()
    .then(sessionName => {
      console.log(`\n✅ Demo complete - tmux session still open!`)
      console.log(`\n📺 To view the demonstration:`)
      console.log(`   tmux attach -t ${sessionName}`)
      console.log(`\n⌨️  Tmux controls:`)
      console.log(`   Ctrl+B then ←/→  - Switch between panes`)
      console.log(`   Ctrl+B then [    - Scroll mode (use arrows, q to exit)`)
      console.log(`   Type "exit"      - Close current pane`)
      console.log(`\n🎬 Both devices showing transaction history side-by-side!`)
      process.exit(0)
    })
    .catch(error => {
      console.error('\n❌ Demo failed:', error)
      process.exit(1)
    })
}