broadcast transaction

This commit is contained in:
Ryan Heywood 2024-11-27 10:55:28 -05:00
parent bedccf4b14
commit 14f0be8921
Signed by: ryan
GPG Key ID: 8E401478A3FBEF72
3 changed files with 1574 additions and 276 deletions

1787
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -8,5 +8,6 @@ ed25519-dalek = "=1.0.1"
icepick-module = { version = "0.1.0", path = "../../icepick-module" }
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
solana-sdk = { version = "2.1.1", path = "../../../vendor/solana-sdk" }
solana-rpc-client = { version = "2.1.1", default-features = false }
solana-sdk = { version = "2.1.1" }
thiserror = "2.0.3"

View File

@ -12,6 +12,10 @@ const LAMPORTS_PER_SOL: u64 = 1_000_000_000;
#[derive(thiserror::Error, Debug)]
pub enum Error {}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct GetBlockhash {}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct GenerateWallet {
@ -39,6 +43,10 @@ pub struct Transfer {
#[serde(rename_all = "kebab-case")]
pub struct Sign {}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct Broadcast {}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "kebab-case")]
pub struct Request {
@ -56,10 +64,12 @@ pub struct Request {
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "operation", content = "values", rename_all = "kebab-case")]
pub enum Operation {
GetBlockhash(GetBlockhash),
GenerateWallet(GenerateWallet),
GetWalletAddress(GetWalletAddress),
Transfer(Transfer),
Sign(Sign),
Broadcast(Broadcast),
}
pub struct Solana;
@ -117,6 +127,11 @@ impl Module for Solana {
r#type: ArgumentType::Required,
};
vec![
icepick_module::help::Operation {
name: "get-blockhash".to_string(),
description: "Get the latest blockhash".to_string(),
arguments: vec![],
},
icepick_module::help::Operation {
name: "generate-wallet".to_string(),
description: "Generate the derivation index for a wallet.".to_string(),
@ -177,11 +192,24 @@ impl Module for Solana {
description: "Sign a previously-generated transaction.".to_string(),
arguments: vec![],
},
icepick_module::help::Operation {
name: "broadcast".to_string(),
description: "Broadcast a signed transaction".to_string(),
arguments: vec![],
},
]
}
fn handle_request(request: Self::Request) -> Result<serde_json::Value, Self::Error> {
match request.operation {
Operation::GetBlockhash(_) => {
let devnet = "https://api.devnet.solana.com";
let client = solana_rpc_client::rpc_client::RpcClient::new(devnet);
let response = client.get_latest_blockhash().unwrap();
Ok(serde_json::json!({
"blob": response.to_string(),
}))
}
Operation::GenerateWallet(GenerateWallet { account }) => {
let account = u32::from_str(&account).expect("account index");
Ok(serde_json::json!({
@ -274,9 +302,39 @@ impl Module for Solana {
.try_sign(&keys, hash)
.expect("not enough keys provided");
Ok(serde_json::json!({
"blob": transaction
"blob": transaction,
}))
}
Operation::Broadcast(_) => {
let blob = request.blob.expect("passed in instruction blob");
let transaction: solana_sdk::transaction::Transaction =
serde_json::from_value(blob).expect("valid message blob");
transaction.verify().expect("invalid signatures");
// TODO: make this a CLI option
let devnet = "https://api.devnet.solana.com";
let client = solana_rpc_client::rpc_client::RpcClient::new(devnet);
let _simulated_response = client.simulate_transaction(&transaction).unwrap();
let response = client.send_and_confirm_transaction(&transaction);
Ok(
match response {
Ok(s) => {
serde_json::json!({
"blob": {
"status": "send_and_confirm",
"succcess": s.to_string(),
}
})
}
Err(e) => {
serde_json::json!({
"blob": {
"status": "send_and_confirm",
"error": e.to_string(),
}
})
}
})
}
}
}
}