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

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_amount="$(jq -r .token_amount /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
echo "Do these values look correct? If not, press ctrl-c. Otherwise, press Enter."
@ -22,5 +23,5 @@ read _
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