144 lines
4.0 KiB
Go
144 lines
4.0 KiB
Go
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()
|
|
}
|