diff --git a/crates/by-chain/icepick-solana/src/lib.rs b/crates/by-chain/icepick-solana/src/lib.rs index a7a5f09..2ff4035 100644 --- a/crates/by-chain/icepick-solana/src/lib.rs +++ b/crates/by-chain/icepick-solana/src/lib.rs @@ -1,6 +1,6 @@ //! Solana support for Icepick. //! -//! # Command Line Arguments +//! # Command Line Operations //! //! The first thing you'll want is a wallet. For this, you can run the command //! `icepick sol generate-wallet`. The output of the command will be a request to derive a key, @@ -34,10 +34,28 @@ //! //! # On an offline system //! blockhash=$(jq -r .blob sdcard/blockhash.json) -//! icepick sol transfer $amount $to_address $from_address $blockhash | icepick sol sign > sdcard/signed.json +//! icepick sol transfer $amount $to_address $from_address $blockhash | icepick sol sign > sdcard/transfer.json //! //! # On the online system, again -//! icepick sol broadcast < sdcard/signed.json +//! icepick sol broadcast --cluster devnet < sdcard/transfer.json +//! ``` +//! +//! You may also want to transfer tokens on the Solana blockchain. You'll first need an account for +//! the token (let's use IPDBG, a devnet token I built for testing): +//! +//! ```sh +//! # On an online system +//! # 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 +//! +//! # On an offline system +//! blockhash=$(jq -r .blob sdcard/blockhash.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 +//! +//! # On an online system +//! icepick sol broadcast --cluster devnet < sdcard/create-account.json //! ``` use icepick_module::{ @@ -101,6 +119,12 @@ pub struct GenerateWallet { #[serde(rename_all = "kebab-case")] pub struct GetWalletAddress {} +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub struct GetTokenAddress { + token: String, +} + #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "kebab-case")] pub struct Transfer { @@ -153,6 +177,7 @@ pub enum Operation { GetBlockhash(GetBlockhash), GenerateWallet(GenerateWallet), GetWalletAddress(GetWalletAddress), + GetTokenAddress(GetTokenAddress), Transfer(Transfer), CreateTokenAccount(CreateTokenAccount), Sign(Sign), @@ -239,6 +264,15 @@ impl Module for Solana { description: "Get the address for a given wallet.".to_string(), arguments: vec![], }, + icepick_module::help::Operation { + name: "get-token-address".to_string(), + description: "Get the address for a given token.".to_string(), + arguments: vec![Argument { + name: "token".to_string(), + description: "The token to look up".to_string(), + r#type: ArgumentType::Required, + }], + }, icepick_module::help::Operation { name: "transfer".to_string(), description: "Transfer SOL from a Keyfork wallet to an external wallet." @@ -342,6 +376,20 @@ impl Module for Solana { "blob": pubkey.to_string(), })) } + Operation::GetTokenAddress(GetTokenAddress { token }) => { + let addr = match token.as_str() { + // Only exists on devnet + "IPDBG" => Some("3V6hm5ifSLSWLZ86NpTxo5iVguGq9qCUtry6bn5PtT23"), + // Only exists on mainnet + "PYTH" => Some("HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3"), + _ => None, + }; + addr.map(|v| serde_json::Value::String(v.to_string())) + .unwrap_or(serde_json::Value::Null); + Ok(serde_json::json!({ + "blob": addr, + })) + } Operation::Transfer(Transfer { amount, from_account,