Not working
This commit is contained in:
parent
3318602fd2
commit
73fe72f829
789
Cargo.lock
generated
789
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
10
Cargo.toml
10
Cargo.toml
@ -1,12 +1,20 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana_scanner"
|
name = "solana_scanner"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
solana-client = "1.17"
|
solana-client = "1.17"
|
||||||
solana-sdk = "1.17"
|
solana-sdk = "1.17"
|
||||||
bs58 = "0.5.0"
|
bs58 = "0.5.0"
|
||||||
|
solana-commitment-config = "2.2.1"
|
||||||
|
solana-transaction-status-client-types = "2.2.4"
|
||||||
|
solana-transaction-status = "1.18.26"
|
||||||
|
spl-token = "8.0.0"
|
||||||
|
base64 = "0.22.1"
|
||||||
|
bincode = "1.3.3"
|
||||||
|
hex = "0.4"
|
||||||
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
|
|||||||
241
src/main.rs
241
src/main.rs
@ -4,33 +4,30 @@ use bs58;
|
|||||||
use solana_sdk::instruction::Instruction;
|
use solana_sdk::instruction::Instruction;
|
||||||
use solana_sdk::message::Message;
|
use solana_sdk::message::Message;
|
||||||
use solana_client::rpc_response::RpcConfirmedTransactionStatusWithSignature;
|
use solana_client::rpc_response::RpcConfirmedTransactionStatusWithSignature;
|
||||||
use solana_client::rpc_response::EncodedConfirmedTransactionWithStatusMeta;
|
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::Transaction;
|
||||||
|
use solana_transaction_status::UiTransactionEncoding;
|
||||||
|
use solana_sdk::signature::Signature;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use spl_token::state::Mint;
|
||||||
|
use solana_transaction_status::EncodedTransaction::{Json, Binary};
|
||||||
|
use solana_transaction_status::UiMessage::{Parsed, Raw};
|
||||||
|
use base64::prelude::*;
|
||||||
|
use solana_sdk::message::VersionedMessage;
|
||||||
|
use solana_sdk::transaction::VersionedTransaction;
|
||||||
|
use hex;
|
||||||
|
|
||||||
fn base58_to_pubkey(address: &str) -> Result<Pubkey, Box<dyn std::error::Error>> {
|
|
||||||
let decoded = bs58::decode(address).into_vec()?;
|
|
||||||
if decoded.len() != 32 {
|
|
||||||
return Err("Address must be 32 bytes long".into());
|
|
||||||
}
|
|
||||||
let mut bytes = [0u8; 32];
|
|
||||||
bytes.copy_from_slice(&decoded);
|
|
||||||
Ok(Pubkey::new_from_array(bytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_token_creation(instruction: &Instruction) -> bool {
|
use solana_transaction_status_client_types::option_serializer;
|
||||||
// L'instruction de création de token a un discriminant de 0
|
|
||||||
if instruction.data.len() < 1 {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
instruction.data[0] == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let rpc_url = "https://api.mainnet-beta.solana.com";
|
let rpc_url = "https://api.mainnet-beta.solana.com";
|
||||||
let client = RpcClient::new(rpc_url.to_string());
|
let client = RpcClient::new(rpc_url.to_string());
|
||||||
|
|
||||||
// Adresse du programme Token (SPL Token Program)
|
// Adresse du programme Token (SPL Token Program)
|
||||||
let token_program_address = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA";
|
let token_program_address = "TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM";
|
||||||
|
|
||||||
|
let buy_router_address = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P";
|
||||||
|
|
||||||
match base58_to_pubkey(token_program_address) {
|
match base58_to_pubkey(token_program_address) {
|
||||||
Ok(token_program) => {
|
Ok(token_program) => {
|
||||||
@ -42,31 +39,34 @@ fn main() {
|
|||||||
match transactions {
|
match transactions {
|
||||||
Ok(sigs) => {
|
Ok(sigs) => {
|
||||||
println!("Nombre total de transactions trouvées : {}", sigs.len());
|
println!("Nombre total de transactions trouvées : {}", sigs.len());
|
||||||
for sig in sigs.iter().take(10) { // Limiter à 10 transactions pour commencer
|
for sig in sigs.iter().take(1000) { // Limiter à 10 transactions pour commencer
|
||||||
// Récupérer les détails de la transaction
|
// Convertir la signature en Signature
|
||||||
match client.get_transaction(&sig.signature, solana_client::rpc_config::RpcTransactionConfig {
|
let signature = Signature::from_str(&sig.signature).unwrap();
|
||||||
encoding: Some(solana_client::rpc_config::RpcTransactionEncoding::Base64),
|
|
||||||
commitment: Some(solana_client::rpc_config::RpcTransactionLogsConfig {
|
|
||||||
commitment: Some(solana_client::rpc_config::CommitmentConfig::confirmed()),
|
|
||||||
max_supported_transaction_version: Some(0),
|
|
||||||
}),
|
|
||||||
max_supported_transaction_version: Some(0),
|
|
||||||
}) {
|
|
||||||
Ok(tx) => {
|
|
||||||
println!(tx.transaction.meta);
|
|
||||||
|
|
||||||
//if let Some(meta) = tx.transaction.meta {
|
|
||||||
//println!(meta);
|
let config = solana_client::rpc_config::RpcTransactionConfig {
|
||||||
|
encoding: Some(UiTransactionEncoding::Base64),
|
||||||
|
commitment: Some(solana_sdk::commitment_config::CommitmentConfig::confirmed()),
|
||||||
|
max_supported_transaction_version: Some(0),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Récupérer les détails de la transaction
|
||||||
|
match client.get_transaction_with_config(&signature, config) {
|
||||||
|
Ok(tx) => {
|
||||||
|
if let Some(meta) = tx.transaction.meta {
|
||||||
|
if let solana_transaction_status::option_serializer::OptionSerializer::Some(inner_instructions) = meta.inner_instructions {
|
||||||
//Vérifier si c'est une création de token
|
//Vérifier si c'est une création de token
|
||||||
//let is_token_creation = meta.inner_instructions.iter().any(|inner| {
|
let is_token_creation = inner_instructions.iter().any(|inner| {
|
||||||
// inner.instructions.iter().any(|ix| {
|
inner.instructions.iter().any(|ix| {
|
||||||
//if let Ok(instruction) = ix.try_into() {
|
//println!("ix: {:?}", ix);
|
||||||
//is_token_creation(&instruction)
|
match ix {
|
||||||
//} else {
|
solana_transaction_status::UiInstruction::Compiled(instruction) => {
|
||||||
// false
|
is_token_creation(instruction)
|
||||||
//}
|
},
|
||||||
// })
|
_ => false
|
||||||
//});
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
// if is_token_creation {
|
// if is_token_creation {
|
||||||
// println!("Création de token trouvée :");
|
// println!("Création de token trouvée :");
|
||||||
@ -76,7 +76,80 @@ fn main() {
|
|||||||
// println!(" Status: {:?}", meta.err);
|
// println!(" Status: {:?}", meta.err);
|
||||||
// println!("---");
|
// println!("---");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
//println!("tx.transaction.transaction: {:?}", tx.transaction.transaction);
|
||||||
|
|
||||||
|
match tx.transaction.transaction {
|
||||||
|
Binary(data, encoding) => {
|
||||||
|
let decoded = BASE64_STANDARD.decode(data).unwrap();
|
||||||
|
|
||||||
|
// Try to deserialize as a VersionedTransaction
|
||||||
|
if let Ok(versioned_tx) = bincode::deserialize::<VersionedTransaction>(&decoded) {
|
||||||
|
|
||||||
|
// dbg!(&versioned_tx);
|
||||||
|
|
||||||
|
// Try to deserialize the message
|
||||||
|
if let Ok(message) = bincode::deserialize::<VersionedMessage>(&versioned_tx.message.serialize()) {
|
||||||
|
|
||||||
|
let account_keys = versioned_tx.message.static_account_keys();
|
||||||
|
|
||||||
|
println!("\nAccount Keys in Transaction:");
|
||||||
|
println!(" Payer (account_keys[0]): {}", account_keys[0]);
|
||||||
|
println!(" Mint Account (account_keys[1]): {}", account_keys[1]);
|
||||||
|
println!(" Rent Account (account_keys[2]): {}", account_keys[2]);
|
||||||
|
println!(" Mint Authority (account_keys[3]): {}", account_keys[3]);
|
||||||
|
println!(" Token Program (account_keys[4]): {}", account_keys[4]);
|
||||||
|
// println!("Instructions: {:?}", message.compiled_instructions);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
match get_token_info(&client, account_keys[1].to_string().as_str()) {
|
||||||
|
Ok(token_info) => {
|
||||||
|
display_token_info(&token_info);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("Erreur lors de la récupération des informations du token : {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not a versioned transaction, try as a legacy transaction
|
||||||
|
if let Ok(legacy_tx) = bincode::deserialize::<Transaction>(&decoded) {
|
||||||
|
// dbg!(&legacy_tx);
|
||||||
|
|
||||||
|
}
|
||||||
|
println!("--------------------------------");
|
||||||
|
// match json_transaction.message {
|
||||||
|
// Parsed(msg) => {
|
||||||
|
// println!("binary msg: {:?}", msg);
|
||||||
|
|
||||||
|
// // println!("Token trouvé : {}", &msg);
|
||||||
|
// // println!("Supply total : {}", &msg.supply);
|
||||||
|
// // println!("Decimals : {}", &msg.decimals);
|
||||||
|
|
||||||
|
|
||||||
|
// },
|
||||||
|
// Raw(msg) => {
|
||||||
|
// println!("Raw msg: {:?}", msg);
|
||||||
|
// // println!("Token trouvé : {}", &msg);
|
||||||
|
// // println!("Supply total : {}", &msg.supply);
|
||||||
|
// // println!("Decimals : {}", &msg.decimals);
|
||||||
|
|
||||||
|
|
||||||
// }
|
// }
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(err) => eprintln!("Erreur lors de la récupération de la transaction : {:?}", err),
|
Err(err) => eprintln!("Erreur lors de la récupération de la transaction : {:?}", err),
|
||||||
}
|
}
|
||||||
@ -89,3 +162,89 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn base58_to_pubkey(address: &str) -> Result<Pubkey, Box<dyn std::error::Error>> {
|
||||||
|
let decoded = bs58::decode(address).into_vec()?;
|
||||||
|
if decoded.len() != 32 {
|
||||||
|
return Err("Address must be 32 bytes long".into());
|
||||||
|
}
|
||||||
|
let mut bytes = [0u8; 32];
|
||||||
|
bytes.copy_from_slice(&decoded);
|
||||||
|
Ok(Pubkey::new_from_array(bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_token_creation(instruction: &solana_transaction_status::UiCompiledInstruction) -> bool {
|
||||||
|
// L'instruction de création de token a un discriminant de 0
|
||||||
|
if instruction.data.len() < 1 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// instruction.data == "0".to_string()
|
||||||
|
println!("instruction: {:?}", instruction);
|
||||||
|
true
|
||||||
|
//instruction.data[0] == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct TokenInfo {
|
||||||
|
mint_address: String,
|
||||||
|
transaction_signature: String,
|
||||||
|
slot: u64,
|
||||||
|
block_time: Option<i64>,
|
||||||
|
decimals: u8,
|
||||||
|
mint_authority: Option<String>,
|
||||||
|
freeze_authority: Option<String>,
|
||||||
|
supply: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_token_info(client: &RpcClient, mint_address: &str) -> Result<TokenInfo, Box<dyn std::error::Error>> {
|
||||||
|
let mint_pubkey = Pubkey::from_str(mint_address)?;
|
||||||
|
|
||||||
|
// Get the account data
|
||||||
|
let account = client.get_account(&mint_pubkey)?;
|
||||||
|
|
||||||
|
// Afficher les données brutes en hexadécimal pour le débogage
|
||||||
|
println!("Données brutes en hex: {}", hex::encode(&account.data));
|
||||||
|
|
||||||
|
// Décoder les données en utilisant Mint::unpack
|
||||||
|
let mint = Mint::unpack(&account.data)?;
|
||||||
|
|
||||||
|
// Afficher les informations décodées
|
||||||
|
println!("\nInformations du token décodées:");
|
||||||
|
println!("Decimals: {}", mint.decimals);
|
||||||
|
println!("Supply: {}", mint.supply);
|
||||||
|
println!("Mint Authority: {:?}", mint.mint_authority);
|
||||||
|
println!("Freeze Authority: {:?}", mint.freeze_authority);
|
||||||
|
|
||||||
|
Ok(TokenInfo {
|
||||||
|
mint_address: mint_address.to_string(),
|
||||||
|
transaction_signature: "".to_string(),
|
||||||
|
slot: 0,
|
||||||
|
block_time: None,
|
||||||
|
decimals: mint.decimals,
|
||||||
|
mint_authority: mint.mint_authority.map(|pk| pk.to_string()),
|
||||||
|
freeze_authority: mint.freeze_authority.map(|pk| pk.to_string()),
|
||||||
|
supply: mint.supply,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_token_info(token: &TokenInfo) {
|
||||||
|
println!("\nToken Information:");
|
||||||
|
println!(" Mint Address: {}", token.mint_address);
|
||||||
|
println!(" Decimals: {}", token.decimals);
|
||||||
|
println!(" Supply: {}", token.supply);
|
||||||
|
match &token.mint_authority {
|
||||||
|
Some(auth) => println!(" Mint Authority: {}", auth),
|
||||||
|
None => println!(" Mint Authority: None (immutable)"),
|
||||||
|
}
|
||||||
|
match &token.freeze_authority {
|
||||||
|
Some(auth) => println!(" Freeze Authority: {}", auth),
|
||||||
|
None => println!(" Freeze Authority: None (unfrozen)"),
|
||||||
|
}
|
||||||
|
println!(" Transaction: {}", token.transaction_signature);
|
||||||
|
println!(" Slot: {}", token.slot);
|
||||||
|
if let Some(time) = token.block_time {
|
||||||
|
println!(" Block Time: {}", time);
|
||||||
|
}
|
||||||
|
println!("---");
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user