143 lines
4.4 KiB
Rust
143 lines
4.4 KiB
Rust
#![allow(dead_code)]
|
|
use solana_client::rpc_client::RpcClient;
|
|
use solana_program::program_pack::Pack;
|
|
use solana_sdk::{
|
|
pubkey::Pubkey, signature::keypair::Keypair, signer::Signer, system_instruction,
|
|
transaction::Transaction,
|
|
};
|
|
use spl_associated_token_account::{
|
|
get_associated_token_address, instruction::create_associated_token_account,
|
|
};
|
|
use spl_token::{
|
|
instruction::{initialize_mint, mint_to},
|
|
state::Mint,
|
|
};
|
|
use std::error::Error;
|
|
use tokio::time::{sleep, Duration};
|
|
|
|
const RPC_URL: &str = "https://api.devnet.solana.com";
|
|
|
|
pub struct Client {
|
|
client: RpcClient,
|
|
keypair: Keypair,
|
|
token: Pubkey,
|
|
}
|
|
|
|
impl Client {
|
|
pub async fn new() -> Self {
|
|
let client = RpcClient::new(RPC_URL);
|
|
let keypair = Keypair::new();
|
|
let token = create_token(&client, &keypair).await;
|
|
Self { client, keypair, token }
|
|
}
|
|
|
|
pub fn from(keypair: Keypair, token: Pubkey) -> Self {
|
|
Self { client: RpcClient::new(RPC_URL), keypair, token }
|
|
}
|
|
|
|
pub fn mint(&self, recipient: &Pubkey) -> Result<String, Box<dyn std::error::Error>> {
|
|
let associated_token_address = self.create_token_account(recipient)?;
|
|
let mint_to_instruction = mint_to(
|
|
&spl_token::id(),
|
|
&self.token,
|
|
&associated_token_address,
|
|
&self.keypair.pubkey(),
|
|
&[],
|
|
1_000_000_000,
|
|
)?;
|
|
|
|
let transaction = Transaction::new_signed_with_payer(
|
|
&[mint_to_instruction],
|
|
Some(&self.keypair.pubkey()),
|
|
&[&self.keypair],
|
|
self.client.get_latest_blockhash()?,
|
|
);
|
|
let signature = self.client.send_and_confirm_transaction(&transaction)?;
|
|
Ok(signature.to_string())
|
|
}
|
|
|
|
fn create_token_account(&self, recipient: &Pubkey) -> Result<Pubkey, Box<dyn Error>> {
|
|
let address = get_associated_token_address(&recipient, &self.token);
|
|
if self.client.get_account(&address).is_err() {
|
|
let create_token_account_instruction = create_associated_token_account(
|
|
&self.keypair.pubkey(),
|
|
recipient,
|
|
&self.token,
|
|
&spl_token::id(),
|
|
);
|
|
let recent_blockhash = self.client.get_latest_blockhash()?;
|
|
let tx = Transaction::new_signed_with_payer(
|
|
&[create_token_account_instruction],
|
|
Some(&self.keypair.pubkey()),
|
|
&[&self.keypair],
|
|
recent_blockhash,
|
|
);
|
|
self.client.send_and_confirm_transaction(&tx)?;
|
|
}
|
|
Ok(address)
|
|
}
|
|
|
|
pub fn wallet_address(&self) -> String {
|
|
self.keypair.pubkey().to_string()
|
|
}
|
|
|
|
pub fn token_address(&self) -> String {
|
|
self.token.to_string()
|
|
}
|
|
|
|
pub fn get_keypair_base58(&self) -> String {
|
|
self.keypair.to_base58_string()
|
|
}
|
|
}
|
|
|
|
async fn wait_for_sol(client: &RpcClient, pubkey: &Pubkey) {
|
|
println!("Waiting to receive 0.01 SOL in address {pubkey}");
|
|
loop {
|
|
sleep(Duration::from_secs(30)).await;
|
|
match client.get_balance(pubkey) {
|
|
Ok(balance) => {
|
|
println!("Got {balance} lamports.");
|
|
if balance > 10_000_000 {
|
|
return;
|
|
}
|
|
}
|
|
Err(e) => println!("Could not get balance: {e:?}"),
|
|
}
|
|
}
|
|
}
|
|
|
|
async fn create_token(client: &RpcClient, keypair: &Keypair) -> Pubkey {
|
|
wait_for_sol(client, &keypair.pubkey()).await;
|
|
|
|
let mint_keypair = Keypair::new();
|
|
let payer = Keypair::from_base58_string(&keypair.to_base58_string());
|
|
let mint_rent = client.get_minimum_balance_for_rent_exemption(Mint::LEN).unwrap();
|
|
|
|
let create_mint_account_ix = system_instruction::create_account(
|
|
&payer.pubkey(),
|
|
&mint_keypair.pubkey(),
|
|
mint_rent,
|
|
Mint::LEN as u64,
|
|
&spl_token::id(),
|
|
);
|
|
|
|
let init_mint_ix =
|
|
initialize_mint(&spl_token::id(), &mint_keypair.pubkey(), &payer.pubkey(), None, 9)
|
|
.unwrap();
|
|
|
|
let recent_blockhash = client.get_latest_blockhash().unwrap();
|
|
let tx = Transaction::new_signed_with_payer(
|
|
&[create_mint_account_ix, init_mint_ix],
|
|
Some(&payer.pubkey()),
|
|
&[&payer, &mint_keypair],
|
|
recent_blockhash,
|
|
);
|
|
|
|
let signature = client.send_and_confirm_transaction(&tx).unwrap();
|
|
|
|
println!("Mint created: {}", mint_keypair.pubkey());
|
|
println!("Transaction signature: {}", signature);
|
|
|
|
mint_keypair.pubkey()
|
|
}
|