load_keypair_and_pubkey_from_json function added to load wallet key
This commit is contained in:
4
.env
4
.env
@@ -4,3 +4,7 @@ YELLOWSTONE_COMMITMENT=processed
|
||||
BUNDLER=5jYaYv7HoiFVrY9bAcruj6dH8fCBseky4sBmnTFGSaeW
|
||||
|
||||
RUST_LOG=info
|
||||
|
||||
BIN_PATH=logs/frames/bin/1762440223791_slot378317940_4t6rKnrWTjmM_tx.bin
|
||||
# Wallet
|
||||
WALLET_PATH=keys/wallet_01.json
|
||||
2921
Cargo.lock
generated
2921
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
24
Cargo.toml
24
Cargo.toml
@@ -4,18 +4,34 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
# utilidades
|
||||
anyhow = "1"
|
||||
futures = "0.3"
|
||||
tokio = { version = "1.39", features = ["rt-multi-thread", "macros", "signal", "fs"] }
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
|
||||
# TLS / HTTP libs si las necesitas luego (reqwest usa rustls)
|
||||
reqwest = { version = "0.12", features = ["rustls-tls", "json"] }
|
||||
|
||||
# openssl si lo necesitas para otras cosas (dejamos vendored)
|
||||
openssl = { version = "0.10", features = ["vendored"] }
|
||||
|
||||
yellowstone-grpc-client = "4"
|
||||
yellowstone-grpc-proto = "4"
|
||||
tonic = "0.11"
|
||||
# Yellowstone gRPC (stack moderno)
|
||||
yellowstone-grpc-client = "9"
|
||||
yellowstone-grpc-proto = "9"
|
||||
|
||||
# gRPC core
|
||||
tonic = "0.14"
|
||||
|
||||
# Solana SDK (rama 2.x compatible con la unidad moderna de crates)
|
||||
solana-sdk = "2.3"
|
||||
|
||||
# utilidades
|
||||
bs58 = "0.5"
|
||||
|
||||
dotenvy = "0.15"
|
||||
|
||||
# serialización
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
||||
|
||||
73
README.md
Normal file
73
README.md
Normal file
@@ -0,0 +1,73 @@
|
||||
┌───────────────────────────────────────────┐
|
||||
│ ENTRADAS │
|
||||
│ │
|
||||
LIVE │ (A) Yellowstone Geyser -> txu │
|
||||
(suscripción) ───▶│ (SubscribeUpdateTransaction) │
|
||||
│ │
|
||||
REPLAY │ (B) Archivo tx.bin (VersionedTx bincode) │
|
||||
(logs/frames/bin) └───────────────┬───────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌───────────────────────────────────────────┐
|
||||
│ main.rs │
|
||||
│ - configura adapters[] │
|
||||
│ - configura RPC │
|
||||
│ - selecciona fuente: (A) o (B) │
|
||||
└───────────────┬───────────────────────────┘
|
||||
│
|
||||
(A) txu │ (B) tx.bin
|
||||
directo │ load_versioned_tx
|
||||
▼
|
||||
┌───────────────────────────────────────────┐
|
||||
│ engine.rs │
|
||||
│ to_snapshot() -> TxuSnapshot │
|
||||
│ - version (legacy/v0) │
|
||||
│ - account_keys + (ALT lookups opc.) │
|
||||
│ - instrucciones (orden + data) │
|
||||
│ - compute budget ixs │
|
||||
└───────────────┬───────────────────────────┘
|
||||
│ TxuSnapshot
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ protocols.rs │
|
||||
│ adapters[] = [ Meteora, PumpFun, Bonk, ... ] │
|
||||
│ │
|
||||
│ ┌──────────────┐ probe() ┌─────────────────────┐ │
|
||||
│ │ Meteora │◀───────────▶│ TxuSnapshot │ │
|
||||
│ └─────┬────────┘ └─────────────────────┘ │
|
||||
│ │ (si reconoce) │
|
||||
│ ▼ │
|
||||
│ extract_plan() -> SwapPlan │
|
||||
│ - PDAs/vaults del pool (NO cambiar) │
|
||||
│ - mints/cantidades (si las decodificas) │
|
||||
│ - ixs crudas (incl. ComputeBudget) │
|
||||
│ │
|
||||
│ build_message(SwapPlan, my_owner) -> PreparedMessage │
|
||||
│ - sustituye: payer + ATAs del bundler → TUS ATAs │
|
||||
│ - conserva: PDAs/vaults/Program IDs │
|
||||
│ - WSOL/ATA lifecycle (si faltan, marca crear) │
|
||||
│ - v0+ALT: reutiliza ALT o expande claves │
|
||||
└─────────┬───────────────────────────────────────────────┘
|
||||
│ PreparedMessage (mensaje SIN firmar)
|
||||
▼
|
||||
┌───────────────────────────────────────┐
|
||||
│ main.rs │
|
||||
│ - inyecta recent_blockhash (RPC) │
|
||||
│ - agrega ixs extra (create ATA/WSOL)│
|
||||
│ - firma con tu Keypair │
|
||||
└───────────────┬──────────────────────┘
|
||||
│ VersionedTransaction firmado
|
||||
▼
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ rpc.rs │
|
||||
│ getLatestBlockhash() │
|
||||
│ simulateTransaction() ──▶ (CUs, logs, errores) │
|
||||
│ sendTransaction() ──▶ signature (base58) │
|
||||
└───────────────────┬──────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────────────┐
|
||||
│ Resultado │
|
||||
│ - ok: firma/slot │
|
||||
│ - fail: motivo/log │
|
||||
└────────────────────────────┘
|
||||
1
keys/wallet_01.json
Normal file
1
keys/wallet_01.json
Normal file
@@ -0,0 +1 @@
|
||||
[250,118,51,30,164,231,4,233,107,88,82,182,111,68,193,6,75,94,233,74,200,39,61,212,169,83,85,44,13,115,143,28,28,74,241,97,180,111,148,237,203,166,51,118,205,220,37,62,156,192,29,119,181,64,141,133,29,54,139,114,3,149,115,0]
|
||||
BIN
keys/wallet_01.json:Zone.Identifier
Normal file
BIN
keys/wallet_01.json:Zone.Identifier
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
logs/frames/bin/1762440223791_slot378317940_4t6rKnrWTjmM_tx.bin
Normal file
BIN
logs/frames/bin/1762440223791_slot378317940_4t6rKnrWTjmM_tx.bin
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
12
src/main.rs
12
src/main.rs
@@ -8,8 +8,10 @@ use tracing_subscriber::EnvFilter;
|
||||
use sniper_bot::listener;
|
||||
use sniper_bot::listener::YellowstoneSource;
|
||||
|
||||
use sniper_bot::utils::save_tx_update;
|
||||
|
||||
use sniper_bot::utils::{
|
||||
save_tx_update,
|
||||
load_keypair_and_pubkey_from_json,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +22,12 @@ async fn main() -> Result<()> {
|
||||
// Load environment variables from .env file
|
||||
dotenv().ok();
|
||||
let bundler = std::env::var("BUNDLER")?;
|
||||
let wallet_path = std::env::var("WALLET_PATH")?;
|
||||
|
||||
// Wallet
|
||||
let (kp, my_owner) = load_keypair_and_pubkey_from_json(&wallet_path)?;
|
||||
println!("🔑 Owner: {my_owner}");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
45
src/utils.rs
45
src/utils.rs
@@ -1,12 +1,53 @@
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::fs as std_fs;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use bs58;
|
||||
use tokio::fs;
|
||||
use yellowstone_grpc_proto::geyser::SubscribeUpdateTransaction;
|
||||
use yellowstone_grpc_proto::prost::Message;
|
||||
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::signature::{Keypair, Signer};
|
||||
|
||||
|
||||
/// Carga un keypair desde un JSON (array de 64 u 32 enteros) y devuelve (Keypair, Pubkey).
|
||||
/// - 64 bytes: clave secreta completa (secret + public) -> `Keypair::from_bytes`.
|
||||
/// - 32 bytes: semilla ed25519 -> `Keypair::from_seed`.
|
||||
pub fn load_keypair_and_pubkey_from_json<P: AsRef<Path>>(path: P) -> Result<(Keypair, Pubkey)> {
|
||||
let path_ref = path.as_ref();
|
||||
let data = std_fs::read_to_string(path_ref)
|
||||
.with_context(|| format!("Leyendo wallet JSON: {}", path_ref.display()))?;
|
||||
|
||||
// Parse JSON array of integers into Vec<u8>
|
||||
let vec_bytes: Vec<u8> = serde_json::from_str(&data)
|
||||
.with_context(|| "Parseando JSON de la wallet (se espera array de enteros)")?;
|
||||
|
||||
let kp = match vec_bytes.len() {
|
||||
64 => {
|
||||
// from_bytes returns Result<Keypair, _>
|
||||
Keypair::try_from(&vec_bytes[..])
|
||||
.map_err(|e| anyhow!("Keypair::try_from falló (¿array de 64 bytes válido?): {e}"))?
|
||||
}
|
||||
32 => {
|
||||
let mut seed = [0u8; 32];
|
||||
seed.copy_from_slice(&vec_bytes);
|
||||
// new_from_array exists in solana-keypair and constructs from a 32-byte secret
|
||||
Keypair::new_from_array(seed)
|
||||
}
|
||||
n => {
|
||||
return Err(anyhow!(
|
||||
"Formato de wallet no soportado: se esperaban 64 o 32 bytes, recibidos {n}"
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
let pubkey = kp.pubkey();
|
||||
Ok((kp, pubkey))
|
||||
}
|
||||
|
||||
// Save file from tx received
|
||||
pub async fn save_tx_update(txu: &SubscribeUpdateTransaction) -> Result<(PathBuf, PathBuf)> {
|
||||
|
||||
Reference in New Issue
Block a user