token metadata
This commit is contained in:
		
							parent
							
								
									bfb4a03b88
								
							
						
					
					
						commit
						85e0215869
					
				
							
								
								
									
										49
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										49
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -2104,6 +2104,7 @@ dependencies = [ | ||||
|  "hyper 1.4.1", | ||||
|  "hyper-rustls 0.27.3", | ||||
|  "hyper-util", | ||||
|  "mpl-token-metadata", | ||||
|  "prost", | ||||
|  "prost-types", | ||||
|  "public-ip", | ||||
| @ -2879,6 +2880,19 @@ version = "1.12.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "mpl-token-metadata" | ||||
| version = "5.1.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "989e6a3000e761d3b2d685662a3a9ee99826f9369fb033bd1bc7011b1cf02ed9" | ||||
| dependencies = [ | ||||
|  "borsh 0.10.4", | ||||
|  "num-derive 0.3.3", | ||||
|  "num-traits", | ||||
|  "solana-program", | ||||
|  "thiserror", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "multimap" | ||||
| version = "0.10.0" | ||||
| @ -2968,6 +2982,17 @@ version = "0.1.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "num-derive" | ||||
| version = "0.3.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn 1.0.109", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "num-derive" | ||||
| version = "0.4.2" | ||||
| @ -4471,7 +4496,7 @@ dependencies = [ | ||||
|  "log", | ||||
|  "memoffset", | ||||
|  "num-bigint 0.4.6", | ||||
|  "num-derive", | ||||
|  "num-derive 0.4.2", | ||||
|  "num-traits", | ||||
|  "parking_lot", | ||||
|  "rand 0.8.5", | ||||
| @ -4500,7 +4525,7 @@ dependencies = [ | ||||
|  "itertools 0.12.1", | ||||
|  "libc", | ||||
|  "log", | ||||
|  "num-derive", | ||||
|  "num-derive 0.4.2", | ||||
|  "num-traits", | ||||
|  "percentage", | ||||
|  "rand 0.8.5", | ||||
| @ -4586,7 +4611,7 @@ dependencies = [ | ||||
|  "console", | ||||
|  "dialoguer", | ||||
|  "log", | ||||
|  "num-derive", | ||||
|  "num-derive 0.4.2", | ||||
|  "num-traits", | ||||
|  "parking_lot", | ||||
|  "qstring", | ||||
| @ -4906,7 +4931,7 @@ checksum = "cfd8e539a9963c2914ff8426dfe92351a902892aea465cd507e36d638ca0b7d6" | ||||
| dependencies = [ | ||||
|  "bincode", | ||||
|  "log", | ||||
|  "num-derive", | ||||
|  "num-derive 0.4.2", | ||||
|  "num-traits", | ||||
|  "rustc_version", | ||||
|  "serde", | ||||
| @ -4933,7 +4958,7 @@ dependencies = [ | ||||
|  "itertools 0.12.1", | ||||
|  "lazy_static", | ||||
|  "merlin", | ||||
|  "num-derive", | ||||
|  "num-derive 0.4.2", | ||||
|  "num-traits", | ||||
|  "rand 0.7.3", | ||||
|  "serde", | ||||
| @ -4963,7 +4988,7 @@ dependencies = [ | ||||
|  "itertools 0.12.1", | ||||
|  "lazy_static", | ||||
|  "merlin", | ||||
|  "num-derive", | ||||
|  "num-derive 0.4.2", | ||||
|  "num-traits", | ||||
|  "rand 0.7.3", | ||||
|  "serde", | ||||
| @ -5017,7 +5042,7 @@ checksum = "68034596cf4804880d265f834af1ff2f821ad5293e41fa0f8f59086c181fc38e" | ||||
| dependencies = [ | ||||
|  "assert_matches", | ||||
|  "borsh 1.5.1", | ||||
|  "num-derive", | ||||
|  "num-derive 0.4.2", | ||||
|  "num-traits", | ||||
|  "solana-program", | ||||
|  "spl-token", | ||||
| @ -5032,7 +5057,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "714b53f7312c2802c62f14bc8a07916c2c872761e3d6be97e99fd432be7799ca" | ||||
| dependencies = [ | ||||
|  "borsh 1.5.1", | ||||
|  "num-derive", | ||||
|  "num-derive 0.4.2", | ||||
|  "num-traits", | ||||
|  "solana-program", | ||||
|  "spl-associated-token-account-client", | ||||
| @ -5128,7 +5153,7 @@ version = "0.5.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d7b28bed65356558133751cc32b48a7a5ddfc59ac4e941314630bbed1ac10532" | ||||
| dependencies = [ | ||||
|  "num-derive", | ||||
|  "num-derive 0.4.2", | ||||
|  "num-traits", | ||||
|  "solana-program", | ||||
|  "spl-program-error-derive", | ||||
| @ -5183,7 +5208,7 @@ checksum = "70a0f06ac7f23dc0984931b1fe309468f14ea58e32660439c1cef19456f5d0e3" | ||||
| dependencies = [ | ||||
|  "arrayref", | ||||
|  "bytemuck", | ||||
|  "num-derive", | ||||
|  "num-derive 0.4.2", | ||||
|  "num-traits", | ||||
|  "num_enum", | ||||
|  "solana-program", | ||||
| @ -5198,7 +5223,7 @@ checksum = "d9c10f3483e48679619c76598d4e4aebb955bc49b0a5cc63323afbf44135c9bf" | ||||
| dependencies = [ | ||||
|  "arrayref", | ||||
|  "bytemuck", | ||||
|  "num-derive", | ||||
|  "num-derive 0.4.2", | ||||
|  "num-traits", | ||||
|  "num_enum", | ||||
|  "solana-program", | ||||
| @ -5222,7 +5247,7 @@ checksum = "c0b788a8c34a917b68b4ed2cdec255d03cc09ccba21545dac39c08a97fce640f" | ||||
| dependencies = [ | ||||
|  "arrayref", | ||||
|  "bytemuck", | ||||
|  "num-derive", | ||||
|  "num-derive 0.4.2", | ||||
|  "num-traits", | ||||
|  "num_enum", | ||||
|  "solana-program", | ||||
|  | ||||
| @ -22,6 +22,7 @@ solana-program = "2.0" | ||||
| solana-sdk = "2.0" | ||||
| spl-associated-token-account = "5.0" | ||||
| spl-token = "6.0" | ||||
| mpl-token-metadata = "5.0" | ||||
| tokio = { version = "1.40", features = ["macros", "rt-multi-thread", "fs"] } # this can be "full" | ||||
| tokio-stream = { version = "0.1", features = ["sync"] } | ||||
| # sgx poc dependencies | ||||
|  | ||||
							
								
								
									
										131
									
								
								src/solana.rs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										131
									
								
								src/solana.rs
									
									
									
									
									
								
							| @ -1,5 +1,10 @@ | ||||
| #![allow(dead_code)] | ||||
| use crate::{grpc::challenge::Keys, persistence::KeysFile}; | ||||
| use mpl_token_metadata::{ | ||||
|     instructions::{CreateMetadataAccountV3, CreateMetadataAccountV3InstructionArgs}, | ||||
|     types::DataV2, | ||||
|     ID as mpl_token_metadata_id, | ||||
| }; | ||||
| use solana_client::nonblocking::rpc_client::RpcClient; | ||||
| use solana_program::program_pack::Pack; | ||||
| use solana_sdk::{ | ||||
| @ -127,40 +132,48 @@ impl TryFrom<KeysFile> for SolClient { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| async fn wait_for_enough_sol(client: &RpcClient, pubkey: &Pubkey) { | ||||
|     println!("Waiting for at least 0.01 SOL in address {pubkey}"); | ||||
|     loop { | ||||
| async fn create_token(client: &RpcClient, payer_keypair: &Keypair) -> Pubkey { | ||||
|     // #1 top up the payer
 | ||||
|     println!("Waiting for at least 0.01 SOL in address {}", payer_keypair.pubkey()); | ||||
|     while !has_enough_lamports(client, &payer_keypair.pubkey(), 10_000_000).await { | ||||
|         sleep(Duration::from_secs(30)).await; | ||||
|     } | ||||
| 
 | ||||
|     // #2 create token mint
 | ||||
|     println!("Creating Token Mint"); | ||||
|     let mut mint_pubkey = None; | ||||
|     while mint_pubkey.is_none() { | ||||
|         sleep(Duration::from_secs(30)).await; | ||||
|         mint_pubkey = create_mint(client, payer_keypair).await; | ||||
|     } | ||||
|     let mint_pubkey = mint_pubkey.unwrap(); | ||||
|     println!("Token Mint created: {mint_pubkey}"); | ||||
| 
 | ||||
|     // #3 create token meta
 | ||||
|     println!("Creating Token Metadata"); | ||||
|     while !create_meta(client, payer_keypair, &mint_pubkey).await { | ||||
|         sleep(Duration::from_secs(30)).await; | ||||
|     } | ||||
|     println!("Token Metadata created"); | ||||
| 
 | ||||
|     mint_pubkey | ||||
| } | ||||
| 
 | ||||
| async fn has_enough_lamports(client: &RpcClient, pubkey: &Pubkey, threshold: u64) -> bool { | ||||
|     match client.get_balance(pubkey).await { | ||||
|         Ok(balance) => { | ||||
|                 println!("Got {balance} lamports."); | ||||
|                 if balance > 10_000_000 { | ||||
|                     return; | ||||
|                 } | ||||
|             println!("{pubkey} needs {threshold} and has {balance}"); | ||||
|             balance >= threshold | ||||
|         } | ||||
|         Err(e) => { | ||||
|             println!("Could not get balance: {e:?}"); | ||||
|             } | ||||
|         } | ||||
|         sleep(Duration::from_secs(30)).await; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| async fn create_token(client: &RpcClient, keypair: &Keypair) -> Pubkey { | ||||
|     loop { | ||||
|         wait_for_enough_sol(client, &keypair.pubkey()).await; | ||||
|         match create_token_int(client, keypair).await { | ||||
|             None => sleep(Duration::from_secs(30)).await, | ||||
|             Some(pubkey) => { | ||||
|                 println!("Mint created: {pubkey}"); | ||||
|                 return pubkey; | ||||
|             } | ||||
|             false | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| async fn create_token_int(client: &RpcClient, keypair: &Keypair) -> Option<Pubkey> { | ||||
| async fn create_mint(client: &RpcClient, payer_keypair: &Keypair) -> Option<Pubkey> { | ||||
|     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) | ||||
|         .await | ||||
| @ -168,7 +181,7 @@ async fn create_token_int(client: &RpcClient, keypair: &Keypair) -> Option<Pubke | ||||
|         .ok()?; | ||||
| 
 | ||||
|     let create_mint_account_ix = system_instruction::create_account( | ||||
|         &payer.pubkey(), | ||||
|         &payer_keypair.pubkey(), | ||||
|         &mint_keypair.pubkey(), | ||||
|         mint_rent, | ||||
|         Mint::LEN as u64, | ||||
| @ -176,7 +189,7 @@ async fn create_token_int(client: &RpcClient, keypair: &Keypair) -> Option<Pubke | ||||
|     ); | ||||
| 
 | ||||
|     let init_mint_ix = | ||||
|         initialize_mint(&spl_token::id(), &mint_keypair.pubkey(), &payer.pubkey(), None, 9) | ||||
|         initialize_mint(&spl_token::id(), &mint_keypair.pubkey(), &payer_keypair.pubkey(), None, 9) | ||||
|             .map_err(|e| println!("Can't initialize mint: {e}")) | ||||
|             .ok()?; | ||||
| 
 | ||||
| @ -185,10 +198,11 @@ async fn create_token_int(client: &RpcClient, keypair: &Keypair) -> Option<Pubke | ||||
|         .await | ||||
|         .map_err(|e| println!("Can't get latest blockhash: {e}")) | ||||
|         .ok()?; | ||||
| 
 | ||||
|     let tx = Transaction::new_signed_with_payer( | ||||
|         &[create_mint_account_ix, init_mint_ix], | ||||
|         Some(&payer.pubkey()), | ||||
|         &[&payer, &mint_keypair], | ||||
|         Some(&payer_keypair.pubkey()), | ||||
|         &[&payer_keypair, &mint_keypair], | ||||
|         recent_blockhash, | ||||
|     ); | ||||
| 
 | ||||
| @ -202,3 +216,64 @@ async fn create_token_int(client: &RpcClient, keypair: &Keypair) -> Option<Pubke | ||||
|         }) | ||||
|         .ok() | ||||
| } | ||||
| 
 | ||||
| async fn create_meta(client: &RpcClient, payer_keypair: &Keypair, mint_pubkey: &Pubkey) -> bool { | ||||
|     create_meta_int(client, payer_keypair, mint_pubkey).await.is_some() | ||||
| } | ||||
| 
 | ||||
| async fn create_meta_int( | ||||
|     client: &RpcClient, | ||||
|     payer_keypair: &Keypair, | ||||
|     mint_pubkey: &Pubkey, | ||||
| ) -> Option<()> { | ||||
|     let metadata_seeds = &[b"metadata", mpl_token_metadata_id.as_ref(), mint_pubkey.as_ref()]; | ||||
|     let (metadata_pda, _bump) = | ||||
|         Pubkey::find_program_address(metadata_seeds, &mpl_token_metadata_id); | ||||
| 
 | ||||
|     let data_v2 = DataV2 { | ||||
|         name: "DeTEE Hacker Challenge Token".to_string(), | ||||
|         symbol: "DTHC".to_string(), | ||||
|         uri: "https://detee.ltd/dthc/meta.json".to_string(), | ||||
|         seller_fee_basis_points: 0, // usually for NFTs, can be 0 for fungible
 | ||||
|         creators: None, // or Some(vec![Creator { ... }]) if you want to specify creators
 | ||||
|         collection: None, | ||||
|         uses: None, | ||||
|     }; | ||||
| 
 | ||||
|     let create_metadata_account_ix = CreateMetadataAccountV3 { | ||||
|         metadata: metadata_pda, | ||||
|         mint: *mint_pubkey, | ||||
|         mint_authority: payer_keypair.pubkey(), | ||||
|         payer: payer_keypair.pubkey(), | ||||
|         update_authority: (payer_keypair.pubkey(), true), | ||||
|         system_program: solana_program::system_program::id(), | ||||
|         rent: None, | ||||
|     } | ||||
|     .instruction(CreateMetadataAccountV3InstructionArgs { | ||||
|         data: data_v2, | ||||
|         is_mutable: true, | ||||
|         collection_details: None, | ||||
|     }); | ||||
| 
 | ||||
|     let recent_blockhash = client | ||||
|         .get_latest_blockhash() | ||||
|         .await | ||||
|         .map_err(|e| println!("Can't get latest blockhash: {e}")) | ||||
|         .ok()?; | ||||
| 
 | ||||
|     let tx = Transaction::new_signed_with_payer( | ||||
|         &[create_metadata_account_ix], | ||||
|         Some(&payer_keypair.pubkey()), | ||||
|         &[&payer_keypair], | ||||
|         recent_blockhash, | ||||
|     ); | ||||
| 
 | ||||
|     client | ||||
|         .send_and_confirm_transaction(&tx) | ||||
|         .await | ||||
|         .map_err(|e| println!("Can't execute transaction: {e}")) | ||||
|         .map(|s| { | ||||
|             println!("Transaction signature: {}", s); | ||||
|         }) | ||||
|         .ok() | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user