solana: add decimals support, revert commit w/ wrong None/None bindings

This commit is contained in:
Ryan Heywood 2024-12-17 15:16:13 -05:00
parent 756c8419ae
commit 0bfc117a1b
Signed by: ryan
GPG Key ID: 8E401478A3FBEF72
2 changed files with 40 additions and 29 deletions

View File

@ -50,8 +50,8 @@
//! //!
//! # 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) //! icepick sol get-token-info IPDBG > sdcard/ipdbg.json
//! token_address=$(jq -r .blob sdcard/ipdbg.json) //! token_address=$(jq -r .blob.token_address sdcard/ipdbg.json)
//! icepick sol create-token-account $wallet_address $token_address | icepick sol sign $blockhash > 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
@ -123,7 +123,7 @@ pub struct GetWalletAddress {}
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
pub struct GetTokenAddress { pub struct GetTokenInfo {
token: String, token: String,
} }
@ -155,6 +155,7 @@ pub struct TransferToken {
to_address: String, to_address: String,
from_account: Option<String>, from_account: Option<String>,
from_address: String, from_address: String,
decimals: String,
fee: Option<String>, fee: Option<String>,
fee_payer: Option<String>, fee_payer: Option<String>,
fee_payer_address: Option<String>, fee_payer_address: Option<String>,
@ -192,7 +193,7 @@ pub enum Operation {
GetBlockhash(GetBlockhash), GetBlockhash(GetBlockhash),
GenerateWallet(GenerateWallet), GenerateWallet(GenerateWallet),
GetWalletAddress(GetWalletAddress), GetWalletAddress(GetWalletAddress),
GetTokenAddress(GetTokenAddress), GetTokenInfo(GetTokenInfo),
Transfer(Transfer), Transfer(Transfer),
CreateTokenAccount(CreateTokenAccount), CreateTokenAccount(CreateTokenAccount),
TransferToken(TransferToken), TransferToken(TransferToken),
@ -276,7 +277,7 @@ impl Module for Solana {
arguments: vec![], arguments: vec![],
}, },
icepick_module::help::Operation { icepick_module::help::Operation {
name: "get-token-address".to_string(), name: "get-token-info".to_string(),
description: "Get the address for a given token.".to_string(), description: "Get the address for a given token.".to_string(),
arguments: vec![Argument { arguments: vec![Argument {
name: "token".to_string(), name: "token".to_string(),
@ -370,6 +371,11 @@ 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,
}, },
Argument {
name: "decimals".to_string(),
description: "The decimals of the token.".to_string(),
r#type: ArgumentType::Required,
},
fee.clone(), fee.clone(),
fee_payer.clone(), fee_payer.clone(),
fee_payer_address.clone(), fee_payer_address.clone(),
@ -419,19 +425,26 @@ impl Module for Solana {
"blob": pubkey.to_string(), "blob": pubkey.to_string(),
})) }))
} }
Operation::GetTokenAddress(GetTokenAddress { token }) => { Operation::GetTokenInfo(GetTokenInfo { token }) => {
let addr = match token.as_str() { let values = match token.as_str() {
// Only exists on devnet // Only exists on devnet
"IPDBG" => Some("3V6hm5ifSLSWLZ86NpTxo5iVguGq9qCUtry6bn5PtT23"), "IPDBG" => Some(("3V6hm5ifSLSWLZ86NpTxo5iVguGq9qCUtry6bn5PtT23", 9u8)),
// Only exists on mainnet // Only exists on mainnet
"PYTH" => Some("HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3"), "PYTH" => Some(("HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3", 6u8)),
_ => None, _ => None,
}; };
addr.map(|v| serde_json::Value::String(v.to_string()))
.unwrap_or(serde_json::Value::Null); Ok(match values {
Ok(serde_json::json!({ Some((address, decimals)) => serde_json::json!({
"blob": addr, "blob": {
})) "token_address": address,
"token_decimals": decimals,
}
}),
None => serde_json::json!({
"blob": null,
}),
})
} }
Operation::Transfer(Transfer { Operation::Transfer(Transfer {
amount, amount,
@ -462,7 +475,7 @@ impl Module for Solana {
Pubkey::from_str(address).unwrap(), Pubkey::from_str(address).unwrap(),
)) ))
} }
(&None, &None) => { (None, None) => {
// Use the transaction account // Use the transaction account
None None
} }
@ -510,10 +523,8 @@ impl Module for Solana {
&token_pubkey, &token_pubkey,
&TOKEN_ID, &TOKEN_ID,
); );
let message = solana_sdk::message::Message::new( let message =
&[instruction], solana_sdk::message::Message::new(&[instruction], Some(&funder_pubkey));
Some(&funder_pubkey),
);
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)]
Ok(serde_json::json!({ Ok(serde_json::json!({
@ -527,15 +538,16 @@ impl Module for Solana {
to_address, to_address,
from_account, from_account,
from_address, from_address,
decimals,
fee, fee,
fee_payer, fee_payer,
fee_payer_address, fee_payer_address,
}) => { }) => {
// TODO: deduplicate code used in Transfer // TODO: deduplicate code used in Transfer
// no transfer between types of currency, the only amount is the amount let amount = f64::from_str(&amount).expect("float amount");
// of the lowest denomination. no floats, like with SOL / lamports. let decimals = u8::from_str(&decimals).expect("decimals");
let amount = u64::from_str(&amount).expect("integer amount"); let amount: u64 = (amount * 10u64.pow(decimals as u32) as f64) as u64;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use spl_associated_token_account::get_associated_token_address; use spl_associated_token_account::get_associated_token_address;
@ -568,7 +580,6 @@ impl Module for Solana {
let from_token_address = get_associated_token_address(&from_pk, &token_pk); let from_token_address = get_associated_token_address(&from_pk, &token_pk);
let to_token_address = get_associated_token_address(&to_pk, &token_pk); let to_token_address = get_associated_token_address(&to_pk, &token_pk);
let decimals = 9u8;
let mut instruction = spl_token_2022::instruction::transfer_checked( let mut instruction = spl_token_2022::instruction::transfer_checked(
&token_program_id, // token program id &token_program_id, // token program id
&from_token_address, // source, as token address &from_token_address, // source, as token address
@ -578,8 +589,7 @@ impl Module for Solana {
// 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 amount, // amount
amount * 10u64.pow(decimals as u32), // amount
decimals, // decimals decimals, // decimals
) )
.unwrap(); .unwrap();

View File

@ -14,7 +14,8 @@ to_address="$(jq -r .to_address /data/input.json)"
token_name="$(jq -r .token_name /data/input.json)" token_name="$(jq -r .token_name /data/input.json)"
token_amount="$(jq -r .token_amount /data/input.json)" token_amount="$(jq -r .token_amount /data/input.json)"
blockhash="$(jq -r .blockhash /data/input.json)" blockhash="$(jq -r .blockhash /data/input.json)"
token_address="$(icepick sol get-token-address "$token_name" | jq -r .blob)" token_address="$(icepick sol get-token-address "$token_name" | jq -r .blob.token_address)"
token_decimals="$(icepick sol get-token-address "$token_name" | jq -r .blob.token_decimals)"
jq . /data/input.json jq . /data/input.json
echo "Do these values look correct? If not, press ctrl-c. Otherwise, press Enter." echo "Do these values look correct? If not, press ctrl-c. Otherwise, press Enter."
@ -22,5 +23,5 @@ read _
echo "Creating and signing transaction" echo "Creating and signing transaction"
icepick sol transfer-token "$token_amount" "$token_address" "$to_address" "$from_address" | icepick sol sign "$blockhash" > /data/output.json.tmp icepick sol transfer-token "$token_amount" "$token_address" "$to_address" "$from_address" "$token_decimals" | icepick sol sign "$blockhash" > /data/output.json.tmp
mv /data/output.json.tmp /data/output.json mv /data/output.json.tmp /data/output.json