icepick sol sign: hoist blockhash argument from other commands

This commit is contained in:
Ryan Heywood 2024-12-09 13:54:19 -05:00
parent 85e9d34fa8
commit 767e7a7df2
Signed by: ryan
GPG Key ID: 8E401478A3FBEF72
1 changed files with 17 additions and 32 deletions

View File

@ -34,7 +34,7 @@
//! //!
//! # On an offline system //! # On an offline system
//! blockhash=$(jq -r .blob sdcard/blockhash.json) //! blockhash=$(jq -r .blob sdcard/blockhash.json)
//! icepick sol transfer $amount $to_address $from_address $blockhash | icepick sol sign > sdcard/transfer.json //! icepick sol transfer $amount $to_address $from_address | icepick sol sign $blockhash > sdcard/transfer.json
//! //!
//! # On the online system, again //! # On the online system, again
//! icepick sol broadcast --cluster devnet < sdcard/transfer.json //! icepick sol broadcast --cluster devnet < sdcard/transfer.json
@ -46,13 +46,13 @@
//! ```sh //! ```sh
//! # On an online system //! # On an online system
//! # Assume we have the wallet address as $wallet_address //! # Assume we have the wallet address as $wallet_address
//! icepick sol get-token-address IPDBG > sdcard/ipdbg.json
//! icepick sol get-blockhash > sdcard/blockhash.json //! icepick sol get-blockhash > sdcard/blockhash.json
//! //!
//! # On an offline system //! # On an offline system
//! blockhash=$(jq -r .blob sdcard/blockhash.json) //! blockhash=$(jq -r .blob sdcard/blockhash.json)
//! token_address=$(icepick sol get-token-address IPDBG)
//! token_address=$(jq -r .blob sdcard/ipdbg.json) //! token_address=$(jq -r .blob sdcard/ipdbg.json)
//! icepick sol create-token-account $wallet_address $token_address $blockhash | icepick sol sign > sdcard/create-account.json //! icepick sol create-token-account $wallet_address $token_address | icepick sol sign $blockhash > sdcard/create-account.json
//! //!
//! # On an online system //! # On an online system
//! icepick sol broadcast --cluster devnet < sdcard/create-account.json //! icepick sol broadcast --cluster devnet < sdcard/create-account.json
@ -129,7 +129,6 @@ pub struct GetTokenAddress {
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
pub struct Transfer { pub struct Transfer {
amount: String, amount: String,
blockhash: String,
to_address: String, to_address: String,
from_account: Option<String>, from_account: Option<String>,
from_address: String, from_address: String,
@ -144,7 +143,6 @@ pub struct CreateTokenAccount {
funder_address: Option<String>, funder_address: Option<String>,
wallet_address: String, wallet_address: String,
token_address: String, token_address: String,
blockhash: String,
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
@ -152,7 +150,6 @@ pub struct CreateTokenAccount {
pub struct TransferToken { pub struct TransferToken {
amount: String, amount: String,
token_address: String, token_address: String,
blockhash: String,
to_address: String, to_address: String,
from_account: Option<String>, from_account: Option<String>,
from_address: String, from_address: String,
@ -163,7 +160,9 @@ pub struct TransferToken {
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
pub struct Sign {} pub struct Sign {
blockhash: String,
}
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
@ -244,11 +243,6 @@ impl Module for Solana {
description: "The derivation account used to pay the fee.".to_string(), description: "The derivation account used to pay the fee.".to_string(),
r#type: ArgumentType::Optional, r#type: ArgumentType::Optional,
}; };
let blockhash = Argument {
name: "blockhash".to_string(),
description: "A recent blockhash".to_string(),
r#type: ArgumentType::Required,
};
let from_address = Argument { let from_address = Argument {
name: "from-address".to_string(), name: "from-address".to_string(),
description: concat!( description: concat!(
@ -305,7 +299,6 @@ impl Module for Solana {
r#type: ArgumentType::Required, r#type: ArgumentType::Required,
}, },
from_address.clone(), from_address.clone(),
blockhash.clone(),
fee.clone(), fee.clone(),
fee_payer.clone(), fee_payer.clone(),
fee_payer_address.clone(), fee_payer_address.clone(),
@ -322,7 +315,6 @@ impl Module for Solana {
}, },
account.clone(), account.clone(),
from_address.clone(), from_address.clone(),
blockhash.clone(),
fee.clone(), fee.clone(),
fee_payer.clone(), fee_payer.clone(),
fee_payer_address.clone(), fee_payer_address.clone(),
@ -343,7 +335,6 @@ impl Module for Solana {
description: "The address of the token.".to_string(), description: "The address of the token.".to_string(),
r#type: ArgumentType::Required, r#type: ArgumentType::Required,
}, },
blockhash.clone(),
Argument { Argument {
name: "funder-address".to_string(), name: "funder-address".to_string(),
description: "The address of the funder (signer).".to_string(), description: "The address of the funder (signer).".to_string(),
@ -377,7 +368,6 @@ impl Module for Solana {
description: "The address to send the tokens from; will be used to verify the derivation account.".to_string(), description: "The address to send the tokens from; will be used to verify the derivation account.".to_string(),
r#type: ArgumentType::Required, r#type: ArgumentType::Required,
}, },
blockhash.clone(),
fee.clone(), fee.clone(),
fee_payer.clone(), fee_payer.clone(),
fee_payer_address.clone(), fee_payer_address.clone(),
@ -386,7 +376,11 @@ impl Module for Solana {
icepick_module::help::Operation { icepick_module::help::Operation {
name: "sign".to_string(), name: "sign".to_string(),
description: "Sign a previously-generated transaction.".to_string(), description: "Sign a previously-generated transaction.".to_string(),
arguments: vec![], arguments: vec![Argument {
name: "blockhash".to_string(),
description: "A recent blockhash".to_string(),
r#type: ArgumentType::Required,
}],
}, },
icepick_module::help::Operation { icepick_module::help::Operation {
name: "broadcast".to_string(), name: "broadcast".to_string(),
@ -442,7 +436,6 @@ impl Module for Solana {
from_account, from_account,
to_address, to_address,
from_address, from_address,
blockhash,
fee: _, fee: _,
fee_payer, fee_payer,
fee_payer_address, fee_payer_address,
@ -476,11 +469,9 @@ impl Module for Solana {
}; };
let instruction = let instruction =
solana_sdk::system_instruction::transfer(&from_pk, &to_pk, amount); solana_sdk::system_instruction::transfer(&from_pk, &to_pk, amount);
let hash = solana_sdk::hash::Hash::from_str(&blockhash).unwrap(); let message = solana_sdk::message::Message::new(
let message = solana_sdk::message::Message::new_with_blockhash(
&[instruction], &[instruction],
payer_account_and_pk.map(|v| v.1).as_ref(), payer_account_and_pk.map(|v| v.1).as_ref(),
&hash,
); );
let transaction = solana_sdk::transaction::Transaction::new_unsigned(message); let transaction = solana_sdk::transaction::Transaction::new_unsigned(message);
// TODO: error handling from_str // TODO: error handling from_str
@ -501,7 +492,6 @@ impl Module for Solana {
funder_address, funder_address,
wallet_address, wallet_address,
token_address, token_address,
blockhash,
}) => { }) => {
// TODO: allow changing derivation account of funder_address // TODO: allow changing derivation account of funder_address
use sata::instruction::create_associated_token_account; use sata::instruction::create_associated_token_account;
@ -518,11 +508,9 @@ impl Module for Solana {
&token_pubkey, &token_pubkey,
&TOKEN_ID, &TOKEN_ID,
); );
let hash = solana_sdk::hash::Hash::from_str(&blockhash).unwrap(); let message = solana_sdk::message::Message::new(
let message = solana_sdk::message::Message::new_with_blockhash(
&[instruction], &[instruction],
Some(&funder_pubkey), Some(&funder_pubkey),
&hash,
); );
let transaction = solana_sdk::transaction::Transaction::new_unsigned(message); let transaction = solana_sdk::transaction::Transaction::new_unsigned(message);
#[allow(clippy::identity_op)] #[allow(clippy::identity_op)]
@ -534,7 +522,6 @@ impl Module for Solana {
Operation::TransferToken(TransferToken { Operation::TransferToken(TransferToken {
amount, amount,
token_address, token_address,
blockhash,
to_address, to_address,
from_account, from_account,
from_address, from_address,
@ -588,7 +575,7 @@ impl Module for Solana {
&from_pk, // authority, as source sol address &from_pk, // authority, as source sol address
// TODO: signers should be [] when not using multisig // TODO: signers should be [] when not using multisig
// but should contain all signers when multisig // but should contain all signers when multisig
&[], // signers &[], // signers
// TODO: make amount floatable // TODO: make amount floatable
amount * 10u64.pow(decimals as u32), // amount amount * 10u64.pow(decimals as u32), // amount
decimals, // decimals decimals, // decimals
@ -606,11 +593,9 @@ impl Module for Solana {
} }
} }
} }
let hash = solana_sdk::hash::Hash::from_str(&blockhash).unwrap(); let message = solana_sdk::message::Message::new(
let message = solana_sdk::message::Message::new_with_blockhash(
&[instruction], &[instruction],
payer_account_and_pk.map(|v| v.1).as_ref(), payer_account_and_pk.map(|v| v.1).as_ref(),
&hash,
); );
// message.header.num_readonly_signed_accounts = 0; // message.header.num_readonly_signed_accounts = 0;
let transaction = let transaction =
@ -626,7 +611,7 @@ impl Module for Solana {
"derivation-accounts": [0u32 | 1 << 31], "derivation-accounts": [0u32 | 1 << 31],
})) }))
} }
Operation::Sign(_) => { Operation::Sign(Sign { blockhash }) => {
let blob = request.blob.expect("passed in instruction blob"); let blob = request.blob.expect("passed in instruction blob");
let mut transaction: solana_sdk::transaction::Transaction = let mut transaction: solana_sdk::transaction::Transaction =
serde_json::from_value(blob).expect("valid message blob"); serde_json::from_value(blob).expect("valid message blob");
@ -637,7 +622,7 @@ impl Module for Solana {
.map(|k| Self::keypair_from_bytes(*k)) .map(|k| Self::keypair_from_bytes(*k))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let hash = transaction.message.recent_blockhash; let hash = solana_sdk::hash::Hash::from_str(&blockhash).unwrap();
transaction transaction
.try_sign(&keys, hash) .try_sign(&keys, hash)
.expect("not enough keys provided"); .expect("not enough keys provided");