package main import ( "flag" "fmt" "os" "btcphrasechecker/bitcoin" "btcphrasechecker/types" "github.com/tyler-smith/go-bip39" ) const ( defaultAddressCount = 20 ) func main() { mnemonic := flag.String("mnemonic", "", "BIP39 mnemonic phrase") passphrase := flag.String("passphrase", "", "Optional passphrase") addressCount := flag.Int("count", defaultAddressCount, "Number of addresses to check per derivation path") chain := flag.String("chain", "bitcoin", "Blockchain to analyze (bitcoin)") flag.Parse() if *mnemonic == "" { fmt.Println("Usage: btcphrasechecker -mnemonic \"your mnemonic phrase\" [-passphrase \"optional passphrase\"] [-count 20] [-chain bitcoin]") os.Exit(1) } // Validate mnemonic if !bip39.IsMnemonicValid(*mnemonic) { fmt.Println("Error: Invalid mnemonic phrase") os.Exit(1) } // Generate seed from mnemonic seed := bip39.NewSeed(*mnemonic, *passphrase) // Analyze based on chain switch types.Chain(*chain) { case types.ChainBitcoin: if err := analyzeBitcoin(seed, *addressCount); err != nil { fmt.Printf("Error analyzing Bitcoin wallet: %v\n", err) os.Exit(1) } default: fmt.Printf("Error: Unsupported chain '%s'\n", *chain) os.Exit(1) } } func analyzeBitcoin(seed []byte, addressCount int) error { // Perform wallet analysis summary, err := bitcoin.AnalyzeWallet(seed, addressCount, true) if err != nil { return err } // Fetch transaction history for active addresses if len(summary.ActiveAddresses) > 0 { fmt.Println("Fetching transaction history...") fmt.Println() if err := bitcoin.FetchTransactionHistory(summary); err != nil { return err } } // Display summary displaySummary(summary) // Display transaction history if len(summary.TransactionHistory) > 0 { displayTransactionHistory(summary) } return nil } func displaySummary(summary *types.WalletSummary) { fmt.Println("======================") fmt.Println("Summary") fmt.Println("======================") fmt.Printf("Total Balance: %.8f BTC\n", float64(summary.TotalBalance)/100000000.0) fmt.Printf("Total Received: %.8f BTC (%d transactions)\n", float64(summary.TotalReceived)/100000000.0, summary.ReceiveTxCount) fmt.Printf("Total Sent: %.8f BTC (%d transactions)\n", float64(summary.TotalSent)/100000000.0, summary.SendTxCount) fmt.Printf("Total Transactions: %d\n", summary.TotalTxCount) fmt.Printf("Active Addresses: %d\n", len(summary.ActiveAddresses)) fmt.Println() if len(summary.ActiveAddresses) > 0 { fmt.Println("Active Addresses Summary:") fmt.Println("-----------------------------------------------------------") for _, addr := range summary.ActiveAddresses { fmt.Printf(" %s\n", addr.Address) fmt.Printf(" Path: %s\n", addr.Path) fmt.Printf(" Balance: %.8f BTC\n", float64(addr.Balance)/100000000.0) fmt.Printf(" Received: %.8f BTC\n", float64(addr.Received)/100000000.0) fmt.Printf(" Sent: %.8f BTC\n", float64(addr.Sent)/100000000.0) fmt.Printf(" Txs: %d\n", addr.TxCount) fmt.Println() } } } func displayTransactionHistory(summary *types.WalletSummary) { fmt.Println("======================") fmt.Println("Transaction History") fmt.Println("======================") fmt.Printf("%-20s %-12s %-10s %-15s %-15s %s\n", "Date", "Type", "Confirmed", "Amount (BTC)", "Balance (BTC)", "TxID") fmt.Println("---------------------------------------------------------------------------------------------------------------------------") for _, tx := range summary.TransactionHistory { dateStr := tx.Time.Format("2006-01-02 15:04:05") confirmedStr := "No" if tx.Confirmed { confirmedStr = "Yes" } typeSymbol := "" switch tx.Type { case "received": typeSymbol = "+ Received" case "sent": typeSymbol = "- Sent" case "self": typeSymbol = "↔ Self" } fmt.Printf("%-20s %-12s %-10s %14.8f %14.8f %s\n", dateStr, typeSymbol, confirmedStr, float64(tx.Amount)/100000000.0, float64(tx.Balance)/100000000.0, tx.TxID[:16]+"...") } fmt.Println() }