diff --git a/crates/by-chain/icepick-solana/src/lib.rs b/crates/by-chain/icepick-solana/src/lib.rs index bb735e5..2a30399 100644 --- a/crates/by-chain/icepick-solana/src/lib.rs +++ b/crates/by-chain/icepick-solana/src/lib.rs @@ -238,9 +238,11 @@ pub struct Inspect { #[derive(Serialize, Deserialize, Debug)] pub struct Sign { blockhash: String, - transaction: solana_sdk::transaction::Transaction, + instructions: Vec, #[serde(default)] signing_keys: Vec<[u8; Keypair::SECRET_KEY_LENGTH]>, + #[serde(default)] + payer_address: Option, } #[derive(Serialize, Deserialize, Debug)] @@ -987,9 +989,9 @@ impl Module for Solana { derivation_accounts, mut instructions, }) => { - use solana_sdk::{hash::Hash, message::Message, transaction::Transaction}; + use solana_sdk::hash::Hash; - let (hash, transaction) = match hashable { + let hash = match hashable { // We already have the account from GetNonceAccountData, // which also gives us the authority and the nonce itself. Hashable::Nonce { @@ -1005,21 +1007,14 @@ impl Module for Solana { system_instruction::advance_nonce_account(&account_pk, &authority_pk); instructions.insert(0, increment_nonce); - let message = Message::new(&instructions, None); - let transaction = Transaction::new_unsigned(message); - (hash, transaction) - } - Hashable::Blockhash { blockhash } => { - let blockhash = Hash::from_str(&blockhash).unwrap(); - let message = Message::new(&instructions, None); - let transaction = Transaction::new_unsigned(message); - (blockhash, transaction) + hash } + Hashable::Blockhash { blockhash } => Hash::from_str(&blockhash).unwrap(), }; Ok(serde_json::json!({ "blob": { "hash": hash, - "transaction": transaction, + "instructions": instructions, }, "derivation_accounts": derivation_accounts, })) @@ -1035,9 +1030,12 @@ impl Module for Solana { } Operation::Sign(Sign { blockhash, - mut transaction, + instructions, signing_keys, + payer_address, }) => { + use solana_sdk::{message::Message, transaction::Transaction}; + let keys = request .derived_keys .unwrap_or_default() @@ -1046,10 +1044,21 @@ impl Module for Solana { .map(|k| Self::keypair_from_bytes(*k)) .collect::>(); + let payer_pk = payer_address + .as_deref() + .map(Pubkey::from_str) + .transpose() + .unwrap(); + + let message = + Message::new(&instructions, Some(&payer_pk.unwrap_or(keys[0].pubkey()))); + let mut transaction = Transaction::new_unsigned(message); + let hash = solana_sdk::hash::Hash::from_str(&blockhash).unwrap(); transaction .try_sign(&keys, hash) .expect("not enough keys provided"); + Ok(serde_json::json!({ "blob": { "transaction": transaction, @@ -1065,7 +1074,15 @@ impl Module for Solana { transaction.verify().expect("invalid signatures"); let client = solana_rpc_client::rpc_client::RpcClient::new(cluster_url); - let _simulated_response = client.simulate_transaction(&transaction).unwrap(); + let simulated_response = client.simulate_transaction(&transaction).unwrap(); + if let Some(err) = simulated_response.value.err { + return Ok(serde_json::json!({ + "blob": { + "status": "simulate_transaction", + "error": err.to_string(), + } + })) + } let response = client.send_and_confirm_transaction(&transaction); let cluster_suffix = { if cluster == Cluster::MainnetBeta { diff --git a/crates/icepick/workflows/sol/generate-nonce-account.yaml b/crates/icepick/workflows/sol/generate-nonce-account.yaml index 2ac4680..eb946fd 100644 --- a/crates/icepick/workflows/sol/generate-nonce-account.yaml +++ b/crates/icepick/workflows/sol/generate-nonce-account.yaml @@ -46,12 +46,12 @@ step: derivation_accounts: "derivation_accounts" blockhash: "blockhash" outputs: - transaction: "unsigned_transaction" + instructions: "nonced_instructions" - type: "sol-sign" inputs: blockhash: "blockhash" signing_keys: "private_keys" - transaction: "unsigned_transaction" + instructions: "nonced_instructions" outputs: transaction: "signed_transaction" - type: "sol-broadcast" diff --git a/crates/icepick/workflows/sol/transfer-token.yaml b/crates/icepick/workflows/sol/transfer-token.yaml index eee24c6..1cd2952 100644 --- a/crates/icepick/workflows/sol/transfer-token.yaml +++ b/crates/icepick/workflows/sol/transfer-token.yaml @@ -46,10 +46,10 @@ step: nonce_authority: nonce_authority nonce_data: nonce_data outputs: - transaction: unsigned_transaction + instructions: nonced_instructions - type: sol-sign inputs: - transaction: unsigned_transaction + instructions: nonced_instructions blockhash: nonce_data outputs: transaction: transaction diff --git a/crates/icepick/workflows/sol/transfer.yaml b/crates/icepick/workflows/sol/transfer.yaml index ac5c069..1e3259c 100644 --- a/crates/icepick/workflows/sol/transfer.yaml +++ b/crates/icepick/workflows/sol/transfer.yaml @@ -35,11 +35,11 @@ step: nonce_authority: "nonce_authority" nonce_data: "nonce_data" outputs: - transaction: "unsigned_transaction" + instructions: "nonced_instructions" - type: "sol-sign" inputs: blockhash: "nonce_data" - transaction: "unsigned_transaction" + instructions: "nonced_instructions" outputs: transaction: "signed_transaction" - type: "internal-save-file"