├── programs └── presale │ ├── Xargo.toml │ ├── src │ ├── instructions │ │ ├── mod.rs │ │ ├── set_live.rs │ │ ├── change_admin.rs │ │ ├── start_presale.rs │ │ ├── set_stage.rs │ │ ├── init_user.rs │ │ ├── initialize.rs │ │ ├── set_vault_address.rs │ │ ├── buy_with_stable_coin.rs │ │ └── buy.rs │ ├── error.rs │ ├── state.rs │ ├── constant.rs │ ├── util.rs │ └── lib.rs │ └── Cargo.toml ├── .gitignore ├── .prettierignore ├── tests ├── constant.ts ├── keys │ ├── vault.json │ ├── token.json │ ├── usdt.json │ └── usdc.json ├── utils.ts ├── config.ts ├── airdrop-tokens.ts ├── create-mints.ts └── presale.ts ├── admin.json ├── tsconfig.json ├── Cargo.toml ├── lib ├── constant.ts ├── types.ts ├── scripts.ts ├── util.ts └── executor.ts ├── migrations └── deploy.ts ├── kinobi.ts ├── Anchor.toml ├── package.json ├── README.md ├── cli ├── scripts.ts └── command.ts └── Cargo.lock /programs/presale/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .anchor 2 | .DS_Store 3 | target 4 | **/*.rs.bk 5 | node_modules 6 | test-ledger 7 | .yarn 8 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .anchor 2 | .DS_Store 3 | target 4 | node_modules 5 | dist 6 | build 7 | test-ledger 8 | -------------------------------------------------------------------------------- /tests/constant.ts: -------------------------------------------------------------------------------- 1 | 2 | export const GLOBAL_SEED = "presale-global"; 3 | export const USER_SEED = "presale-user"; 4 | export const LAMPORTS_PER_SOL = 1_000_000_000; 5 | -------------------------------------------------------------------------------- /admin.json: -------------------------------------------------------------------------------- 1 | [81,99,195,27,164,118,59,127,20,94,217,221,71,1,146,36,212,208,240,42,33,236,137,5,80,172,96,47,125,233,234,150,29,61,176,238,150,82,135,199,12,53,9,221,87,237,65,122,126,47,248,174,118,233,73,163,31,116,150,178,232,133,90,250] -------------------------------------------------------------------------------- /tests/keys/vault.json: -------------------------------------------------------------------------------- 1 | [52,106,243,38,26,79,155,146,243,8,20,167,27,80,94,67,41,164,201,127,254,246,170,54,150,91,77,76,51,112,2,98,182,181,96,135,11,82,185,39,119,124,41,200,39,193,75,93,7,13,246,81,147,231,224,114,164,219,94,68,251,206,68,196] -------------------------------------------------------------------------------- /tests/keys/token.json: -------------------------------------------------------------------------------- 1 | [130,104,47,75,35,15,97,159,243,26,60,58,242,134,95,196,67,133,92,85,180,209,247,133,88,240,32,251,157,171,127,43,66,95,133,141,116,40,6,212,203,27,86,75,144,52,88,219,96,105,223,201,69,100,50,172,161,12,238,8,161,108,171,29] -------------------------------------------------------------------------------- /tests/keys/usdt.json: -------------------------------------------------------------------------------- 1 | [174,216,136,130,32,158,134,212,100,225,106,79,40,205,65,2,146,163,34,140,32,213,17,236,62,170,91,136,200,70,124,150,13,139,115,168,129,5,20,132,192,186,216,208,36,177,222,100,73,158,187,42,86,0,224,184,193,216,186,23,22,159,5,59] -------------------------------------------------------------------------------- /tests/keys/usdc.json: -------------------------------------------------------------------------------- 1 | [153,107,175,165,68,171,43,23,120,156,140,181,188,125,125,175,227,37,43,88,210,123,40,22,241,133,250,136,239,188,215,103,13,139,114,127,7,98,238,101,176,226,206,5,57,213,96,232,40,184,162,212,191,186,72,73,188,154,13,194,253,56,16,82] -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai", "node"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es2022", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | resolver = "2" 6 | 7 | [profile.release] 8 | overflow-checks = true 9 | lto = "fat" 10 | codegen-units = 1 11 | [profile.release.build-override] 12 | opt-level = 3 13 | incremental = false 14 | codegen-units = 1 15 | -------------------------------------------------------------------------------- /lib/constant.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PublicKey 3 | } from "@solana/web3.js"; 4 | 5 | export const GLOBAL_STATE_SEED = "presale-global"; 6 | 7 | export const NUM_STAGES = 10; 8 | 9 | export const USDC_ADDRESS = new PublicKey("usdRLypwfSeEUw4DhUcscCcju6zzBviXymFBRjcBXTw"); 10 | export const USDT_ADDRESS = new PublicKey("usderEuWoVkjMcc3bEYkGopx78La8mHzt6YGdmErrpz"); 11 | -------------------------------------------------------------------------------- /lib/types.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from '@coral-xyz/anchor'; 2 | import { PublicKey } from '@solana/web3.js' 3 | 4 | export interface GlobalState { 5 | admin: PublicKey, 6 | vault: PublicKey, 7 | token: PublicKey, 8 | totalAmount: anchor.BN, 9 | tokenSold: anchor.BN, 10 | tokenSoldUsd: anchor.BN, 11 | isLive: Boolean, 12 | stageIterator: number, 13 | remainTokens: anchor.BN[] 14 | } 15 | -------------------------------------------------------------------------------- /migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@coral-xyz/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | }; 13 | -------------------------------------------------------------------------------- /programs/presale/src/instructions/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod initialize; 2 | pub use initialize::*; 3 | pub mod change_admin; 4 | pub use change_admin::*; 5 | pub mod set_vault_address; 6 | pub use set_vault_address::*; 7 | pub mod start_presale; 8 | pub use start_presale::*; 9 | pub mod set_live; 10 | pub use set_live::*; 11 | pub mod set_stage; 12 | pub use set_stage::*; 13 | pub mod init_user; 14 | pub use init_user::*; 15 | pub mod buy; 16 | pub use buy::*; 17 | pub mod buy_with_stable_coin; 18 | pub use buy_with_stable_coin::*; -------------------------------------------------------------------------------- /kinobi.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Visitor, 3 | createFromIdls, 4 | renderJavaScriptVisitor 5 | } from "@metaplex-foundation/kinobi"; 6 | import path from "path"; 7 | 8 | // Instantiate Kinobi. 9 | const kinobi = createFromIdls([path.join(__dirname, "target/idl", "presale-kinobi.json")]); 10 | 11 | // Update the Kinobi tree using visitors... 12 | 13 | // Render JavaScript. 14 | const jsDir = path.join(__dirname, "clients", "ts", "src", "generated"); 15 | 16 | kinobi.accept(renderJavaScriptVisitor(jsDir) as Visitor); 17 | -------------------------------------------------------------------------------- /programs/presale/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "presale" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "presale" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build"] 18 | 19 | [dependencies] 20 | anchor-lang = { version = "0.30.0", features = ["init-if-needed"] } 21 | anchor-spl = "0.30.0" 22 | pyth-sdk-solana = "0.10.1" 23 | solana-program = "1.17.34" 24 | -------------------------------------------------------------------------------- /Anchor.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | 3 | [features] 4 | resolution = true 5 | skip-lint = false 6 | 7 | [programs.localnet] 8 | presale = "6En2g3XUQgZSBEgBE1DF1sVeRik4KNvug151Zswz8oR5" 9 | 10 | [registry] 11 | url = "https://api.apr.dev" 12 | 13 | [provider] 14 | cluster = "localnet" 15 | wallet = "admin.json" 16 | 17 | [scripts] 18 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/presale.ts" 19 | 20 | [test] 21 | startup_wait = 5000 22 | 23 | [test.validator] 24 | url = "https://api.mainnet-beta.solana.com" 25 | 26 | [[test.validator.clone]] 27 | address = "H6ARHf6YXhGYeQfUzQNGk6rDNnLBQKrenN712K4AQJEG" 28 | -------------------------------------------------------------------------------- /tests/utils.ts: -------------------------------------------------------------------------------- 1 | import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token"; 2 | import { 3 | Connection, 4 | Keypair, 5 | PublicKey, 6 | Signer 7 | } from "@solana/web3.js"; 8 | 9 | export const getAssociatedTokenAccount = ( 10 | ownerPubkey: PublicKey, 11 | mintPk: PublicKey 12 | ): PublicKey => { 13 | let associatedTokenAccountPubkey = (PublicKey.findProgramAddressSync( 14 | [ 15 | ownerPubkey.toBytes(), 16 | TOKEN_PROGRAM_ID.toBytes(), 17 | mintPk.toBytes(), // mint address 18 | ], 19 | ASSOCIATED_TOKEN_PROGRAM_ID 20 | ))[0]; 21 | 22 | return associatedTokenAccountPubkey; 23 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 4 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check", 5 | "script": "ts-node ./cli/command.ts" 6 | }, 7 | "dependencies": { 8 | "@coral-xyz/anchor": "^0.30.0", 9 | "@metaplex-foundation/kinobi": "^0.18.8-alpha.0", 10 | "@solana/spl-token": "^0.4.6", 11 | "commander": "^12.1.0", 12 | "jito-ts": "^4.1.0" 13 | }, 14 | "devDependencies": { 15 | "@types/bn.js": "^5.1.0", 16 | "@types/chai": "^4.3.0", 17 | "@types/mocha": "^9.0.0", 18 | "chai": "^4.3.4", 19 | "mocha": "^9.0.3", 20 | "prettier": "^2.6.2", 21 | "ts-mocha": "^10.0.0", 22 | "typescript": "^4.3.5" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /programs/presale/src/instructions/set_live.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | 3 | #[derive(Accounts)] 4 | pub struct SetLive<'info> { 5 | #[account( 6 | mut, 7 | constraint = global_state.admin == *admin.key @PresaleError::InvalidAdmin 8 | )] 9 | pub admin: Signer<'info>, 10 | 11 | // Global state 12 | #[account( 13 | mut, 14 | seeds = [GLOBAL_SEED], 15 | bump 16 | )] 17 | pub global_state: Account<'info, GlobalState>, 18 | } 19 | 20 | impl SetLive<'_> { 21 | pub fn process_instruction(ctx: Context, live: bool) -> Result<()> { 22 | let global_state = &mut ctx.accounts.global_state; 23 | 24 | // set is_live as live 25 | global_state.is_live = live; 26 | 27 | Ok(()) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /programs/presale/src/error.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | 3 | #[error_code] 4 | pub enum PresaleError { 5 | #[msg("Admin address dismatch")] 6 | InvalidAdmin, 7 | 8 | #[msg("Token address dismatch")] 9 | InvalidToken, 10 | 11 | #[msg("Token amount is not enough for all stages")] 12 | NotEnoughToken, 13 | 14 | #[msg("Presale number is not correct")] 15 | PresaleNumberInvalid, 16 | 17 | #[msg("Presale is not started")] 18 | PresaleNotStarted, 19 | 20 | #[msg("Presale is ended")] 21 | PresaleEnded, 22 | 23 | #[msg("Presale is paused")] 24 | PresalePaused, 25 | 26 | #[msg("Pyth feed address is not right")] 27 | InvalidPriceFeed, 28 | 29 | #[msg("Stable token address is not right")] 30 | InvalidStableToken, 31 | } 32 | -------------------------------------------------------------------------------- /programs/presale/src/instructions/change_admin.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | 3 | #[derive(Accounts)] 4 | pub struct ChangeAdmin<'info> { 5 | // Current admin 6 | #[account( 7 | mut, 8 | constraint = global_state.admin == *admin.key @PresaleError::InvalidAdmin 9 | )] 10 | pub admin: Signer<'info>, 11 | 12 | // Stores admin address 13 | #[account( 14 | mut, 15 | seeds = [GLOBAL_SEED], 16 | bump 17 | )] 18 | pub global_state: Account<'info, GlobalState>, 19 | } 20 | 21 | pub fn process_change_admin(ctx: Context, new_admin: Pubkey) -> Result<()> { 22 | let global_state = &mut ctx.accounts.global_state; 23 | 24 | // Don't need check admin since it signed the transaction 25 | global_state.admin = new_admin; 26 | 27 | Ok(()) 28 | } 29 | -------------------------------------------------------------------------------- /programs/presale/src/instructions/start_presale.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | 3 | #[derive(Accounts)] 4 | pub struct StartPresale<'info> { 5 | #[account( 6 | mut, 7 | constraint = global_state.admin == *admin.key @PresaleError::InvalidAdmin 8 | )] 9 | pub admin: Signer<'info>, 10 | 11 | // Global state 12 | #[account( 13 | mut, 14 | seeds = [GLOBAL_SEED], 15 | bump 16 | )] 17 | pub global_state: Account<'info, GlobalState> 18 | } 19 | 20 | impl StartPresale<'_> { 21 | pub fn process_instruction(ctx: Context) -> Result<()> { 22 | let global_state = &mut ctx.accounts.global_state; 23 | 24 | // set is_live and stage_iterator 25 | global_state.is_live = true; 26 | global_state.stage_iterator = 0; 27 | 28 | Ok(()) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /programs/presale/src/instructions/set_stage.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | 3 | #[derive(Accounts)] 4 | pub struct SetStage<'info> { 5 | #[account( 6 | mut, 7 | constraint = global_state.admin == *admin.key @PresaleError::InvalidAdmin 8 | )] 9 | pub admin: Signer<'info>, 10 | 11 | // Global state 12 | #[account( 13 | mut, 14 | seeds = [GLOBAL_SEED], 15 | bump 16 | )] 17 | pub global_state: Account<'info, GlobalState>, 18 | } 19 | 20 | impl SetStage<'_> { 21 | pub fn process_instruction(ctx: Context, stage: u8) -> Result<()> { 22 | let global_state = &mut ctx.accounts.global_state; 23 | 24 | // check stage number is eligible 25 | require!(stage < NUM_STAGES, PresaleError::PresaleNumberInvalid); 26 | 27 | // set as next stage 28 | global_state.stage_iterator = stage; 29 | 30 | Ok(()) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/config.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@coral-xyz/anchor"; 2 | import fs from "fs"; 3 | import { 4 | Connection, 5 | Keypair 6 | } from "@solana/web3.js"; 7 | import { Program } from "@coral-xyz/anchor"; 8 | import { Presale } from "../target/types/presale"; 9 | 10 | // Configure the client to use the local cluster. 11 | export const connection = new Connection("http://127.0.0.1:8899", "confirmed"); 12 | 13 | anchor.setProvider(anchor.AnchorProvider.env()); 14 | export const program = anchor.workspace.Presale as Program; 15 | 16 | export const usdcKp = Keypair.fromSecretKey(new Uint8Array(JSON.parse(fs.readFileSync("./tests/keys/usdc.json", "utf-8")))); 17 | export const usdtKp = Keypair.fromSecretKey(new Uint8Array(JSON.parse(fs.readFileSync("./tests/keys/usdt.json", "utf-8")))); 18 | 19 | export const vaultKp = Keypair.fromSecretKey(new Uint8Array(JSON.parse(fs.readFileSync("./tests/keys/vault.json", "utf-8")))); 20 | -------------------------------------------------------------------------------- /programs/presale/src/instructions/init_user.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | 3 | #[derive(Accounts)] 4 | pub struct InitUser<'info> { 5 | #[account(mut)] 6 | pub user: Signer<'info>, 7 | 8 | // User pool stores user's buy info 9 | #[account( 10 | init, 11 | space = 8 + std::mem::size_of::(), 12 | seeds = [user.key().as_ref(), USER_SEED.as_ref()], 13 | bump, 14 | payer = user 15 | )] 16 | pub user_state: Account<'info, UserState>, 17 | 18 | // Needed to init new account 19 | pub system_program: Program<'info, System> 20 | } 21 | 22 | impl InitUser<'_> { 23 | pub fn process_instruction(ctx: Context) -> Result<()> { 24 | let user_state = &mut ctx.accounts.user_state; 25 | 26 | user_state.user = ctx.accounts.user.key(); 27 | 28 | user_state.tokens = 0; 29 | user_state.paid_sol = 0; 30 | user_state.paid_usd = 0; 31 | 32 | Ok(()) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/airdrop-tokens.ts: -------------------------------------------------------------------------------- 1 | import { usdcKp, connection } from "./config"; 2 | import { getOrCreateAssociatedTokenAccount, mintTo } from "@solana/spl-token"; 3 | import { 4 | Connection, 5 | Signer, 6 | PublicKey, 7 | Keypair 8 | } from "@solana/web3.js"; 9 | 10 | export const airdropToken = async (mintKp: Keypair, authority: Keypair, payer: Signer, user: PublicKey, amount: number) => { 11 | const userAta = await getOrCreateAssociatedTokenAccount( 12 | connection, 13 | payer, 14 | mintKp.publicKey, 15 | user 16 | ); 17 | 18 | await mintTo( 19 | connection, 20 | payer, 21 | mintKp.publicKey, 22 | userAta.address, 23 | authority, 24 | amount, 25 | [] 26 | ); 27 | 28 | const balance = (await connection.getTokenAccountBalance(userAta.address)).value.amount; 29 | console.log(`minted - address: ${mintKp.publicKey.toBase58()} amount: ${balance} to: ${user.toBase58()}`); 30 | } 31 | -------------------------------------------------------------------------------- /programs/presale/src/instructions/initialize.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | 3 | #[derive(Accounts)] 4 | pub struct Initialize<'info> { 5 | #[account(mut)] 6 | pub admin: Signer<'info>, 7 | 8 | // Global state 9 | #[account( 10 | init, 11 | space = 8 + std::mem::size_of::(), 12 | seeds = [GLOBAL_SEED], 13 | bump, 14 | payer = admin 15 | )] 16 | pub global_state: Account<'info, GlobalState>, 17 | 18 | // Needed to init new account 19 | pub system_program: Program<'info, System>, 20 | } 21 | 22 | impl Initialize<'_> { 23 | pub fn process_instruction(ctx: Context) -> Result<()> { 24 | let global_state = &mut ctx.accounts.global_state; 25 | 26 | msg!("{}", global_state.key()); 27 | 28 | // initialize global state 29 | global_state.admin = ctx.accounts.admin.key(); 30 | global_state.vault = Pubkey::default(); 31 | 32 | global_state.token_sold = 0; 33 | global_state.token_sold_usd = 0; 34 | 35 | global_state.is_live = false; 36 | 37 | global_state.stage_iterator = 0; 38 | 39 | 40 | global_state.remain_tokens = [0; NUM_STAGES as usize]; 41 | 42 | // Update remain_tokens from STAGES 43 | global_state.update_remain_tokens(); 44 | 45 | Ok(()) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /programs/presale/src/state.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | 3 | /** 4 | * Stores global state of the program 5 | */ 6 | #[account] 7 | #[derive(Default)] 8 | pub struct GlobalState { 9 | // admin address of this program 10 | pub admin: Pubkey, 11 | 12 | // address of multi sig wallet 13 | pub vault: Pubkey, 14 | 15 | 16 | // total tokens sold 17 | pub token_sold: u64, 18 | 19 | // total USD recived 20 | pub token_sold_usd: u64, 21 | 22 | 23 | // presale is live or not? 24 | pub is_live: bool, 25 | 26 | 27 | // stage number of current stage 28 | pub stage_iterator: u8, 29 | 30 | // remain token amounts on each stage 31 | pub remain_tokens: [u64; NUM_STAGES as usize] 32 | } 33 | 34 | impl GlobalState { 35 | // Function to update remain_tokens from STAGES 36 | pub fn update_remain_tokens(&mut self) { 37 | for (i, stage) in STAGES.iter().enumerate() { 38 | self.remain_tokens[i] = stage.amount; 39 | } 40 | } 41 | } 42 | 43 | 44 | /** 45 | * Stores user info 46 | */ 47 | #[account] 48 | #[derive(Default)] 49 | pub struct UserState { 50 | // user address 51 | pub user: Pubkey, 52 | 53 | // token amount user bought 54 | pub tokens: u64, 55 | 56 | // SOL amount user paid 57 | pub paid_sol: u64, 58 | 59 | // stable coin user paid 60 | pub paid_usd: u64 61 | } 62 | -------------------------------------------------------------------------------- /tests/create-mints.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Connection, 3 | Keypair, 4 | PublicKey , 5 | Signer 6 | } from "@solana/web3.js"; 7 | import { createMint } from "@solana/spl-token"; 8 | import { connection, usdcKp, usdtKp } from "./config"; 9 | 10 | export const createMints = async (payer: Keypair) => { 11 | 12 | // create USDC account if it's not exist 13 | 14 | let usdcInfo = await connection.getAccountInfo(usdcKp.publicKey); 15 | if (!usdcInfo) { 16 | await createMintAcct( 17 | usdcKp, 18 | payer, 19 | usdcKp.publicKey 20 | ); 21 | 22 | console.log(`created USDC address: ${usdcKp.publicKey.toBase58()}`); 23 | } else { 24 | console.log(`exist USDC address: ${usdcKp.publicKey.toBase58()}`); 25 | } 26 | 27 | // create USDT account if it's not exist 28 | 29 | let usdtInfo = await connection.getAccountInfo(usdtKp.publicKey); 30 | if (!usdtInfo) { 31 | await createMintAcct( 32 | usdtKp, 33 | payer, 34 | usdtKp.publicKey 35 | ); 36 | 37 | console.log(`created USDT address: ${usdtKp.publicKey.toBase58()}`); 38 | } else { 39 | console.log(`exist USDT address: ${usdtKp.publicKey.toBase58()}`); 40 | } 41 | } 42 | 43 | const createMintAcct = async (mintKp: Keypair, payer: Signer, authorityToAssign: PublicKey): Promise => { 44 | return await createMint( 45 | connection, 46 | payer, // payer 47 | authorityToAssign, // mint authority 48 | null, // freeze authority 49 | 6, // decimals 50 | mintKp // address of the mint 51 | ); 52 | } 53 | -------------------------------------------------------------------------------- /programs/presale/src/constant.rs: -------------------------------------------------------------------------------- 1 | use solana_program::{pubkey, pubkey::Pubkey}; 2 | 3 | // seeds 4 | pub const GLOBAL_SEED: &[u8] = b"presale-global"; 5 | pub const USER_SEED: &[u8] = b"presale-user"; 6 | 7 | // address of stable coins 8 | // pub const USDC_ADDRESS: Pubkey = pubkey!("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); 9 | // pub const USDT_ADDRESS: Pubkey = pubkey!("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"); 10 | 11 | // test addresses 12 | pub const USDC_ADDRESS: Pubkey = pubkey!("usdRLypwfSeEUw4DhUcscCcju6zzBviXymFBRjcBXTw"); 13 | pub const USDT_ADDRESS: Pubkey = pubkey!("usderEuWoVkjMcc3bEYkGopx78La8mHzt6YGdmErrpz"); 14 | 15 | pub const NUM_STAGES: u8 = 10; 16 | 17 | // stage data: stage_num, price, amounts 18 | pub struct Stage { 19 | pub index: u8, 20 | pub price: u64, 21 | pub amount: u64, 22 | } 23 | 24 | pub const STAGES: [Stage; 10] = [ 25 | Stage { index: 1, price: 2_000_000, amount: 2_500_000 }, 26 | Stage { index: 2, price: 3_000_000, amount: 2_500_000 }, 27 | Stage { index: 3, price: 4_000_000, amount: 6_250_000 }, 28 | Stage { index: 4, price: 5_000_000, amount: 27_500_000 }, 29 | Stage { index: 5, price: 5_500_000, amount: 37_500_000 }, 30 | Stage { index: 6, price: 6_000_000, amount: 41_250_000 }, 31 | Stage { index: 7, price: 6_500_000, amount: 37_500_000 }, 32 | Stage { index: 8, price: 7_000_000, amount: 35_000_000 }, 33 | Stage { index: 9, price: 8_000_000, amount: 7_500_000 }, 34 | Stage { index: 10, price: 9_000_000, amount: 2_500_000 }, 35 | ]; 36 | 37 | pub const TOKEN_DECIMALS: u64 = 1_000_000; 38 | 39 | // pyth price feed on solana mainnet-beta 40 | pub const SOL_USD_FEED: Pubkey = pubkey!("H6ARHf6YXhGYeQfUzQNGk6rDNnLBQKrenN712K4AQJEG"); 41 | pub const STALENESS_THRESHOLD: u64 = 60; // staleness threshold in seconds 42 | -------------------------------------------------------------------------------- /programs/presale/src/util.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | use anchor_spl::token; 3 | use solana_program::program::{invoke, invoke_signed}; 4 | 5 | // transfer sol from PDA 6 | pub fn sol_transfer_with_signer<'a>( 7 | source: AccountInfo<'a>, 8 | destination: AccountInfo<'a>, 9 | system_program: AccountInfo<'a>, 10 | signers: &[&[&[u8]]; 1], 11 | amount: u64, 12 | ) -> Result<()> { 13 | let ix = solana_program::system_instruction::transfer(source.key, destination.key, amount); 14 | invoke_signed(&ix, &[source, destination, system_program], signers)?; 15 | Ok(()) 16 | } 17 | 18 | // transfer sol from user 19 | pub fn sol_transfer_user<'a>( 20 | source: AccountInfo<'a>, 21 | destination: AccountInfo<'a>, 22 | system_program: AccountInfo<'a>, 23 | amount: u64, 24 | ) -> Result<()> { 25 | let ix = solana_program::system_instruction::transfer(source.key, destination.key, amount); 26 | invoke(&ix, &[source, destination, system_program])?; 27 | Ok(()) 28 | } 29 | 30 | 31 | // transfer token from user 32 | pub fn token_transfer_user<'a>( 33 | from: AccountInfo<'a>, 34 | authority: AccountInfo<'a>, 35 | to: AccountInfo<'a>, 36 | token_program: AccountInfo<'a>, 37 | amount: u64, 38 | ) -> Result<()> { 39 | let cpi_ctx: CpiContext<_> = CpiContext::new( 40 | token_program, 41 | token::Transfer { 42 | from, 43 | authority, 44 | to, 45 | }, 46 | ); 47 | token::transfer(cpi_ctx, amount)?; 48 | 49 | Ok(()) 50 | } 51 | 52 | // transfer token from PDA 53 | pub fn token_transfer_with_signer<'a>( 54 | from: AccountInfo<'a>, 55 | authority: AccountInfo<'a>, 56 | to: AccountInfo<'a>, 57 | token_program: AccountInfo<'a>, 58 | signers: &[&[&[u8]]], 59 | amount: u64, 60 | ) -> Result<()> { 61 | let cpi_ctx: CpiContext<_> = CpiContext::new_with_signer( 62 | token_program, 63 | token::Transfer { 64 | from, 65 | authority, 66 | to, 67 | }, 68 | signers, 69 | ); 70 | token::transfer(cpi_ctx, amount)?; 71 | 72 | Ok(()) 73 | } 74 | -------------------------------------------------------------------------------- /programs/presale/src/instructions/set_vault_address.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | use anchor_spl::{ 3 | associated_token::AssociatedToken, 4 | token::{ Mint, Token, TokenAccount } 5 | }; 6 | 7 | #[derive(Accounts)] 8 | pub struct SetVaultAddress<'info> { 9 | #[account( 10 | mut, 11 | constraint = global_state.admin == *admin.key @PresaleError::InvalidAdmin 12 | )] 13 | pub admin: Signer<'info>, 14 | 15 | // Global state 16 | #[account( 17 | mut, 18 | seeds = [GLOBAL_SEED], 19 | bump 20 | )] 21 | pub global_state: Account<'info, GlobalState>, 22 | 23 | 24 | /// CHECK: new vault address(multi-sig wallet) 25 | pub vault: AccountInfo<'info>, 26 | 27 | 28 | // USDC ata of vault 29 | #[account( 30 | init_if_needed, 31 | payer = admin, 32 | associated_token::mint = usdc_mint, 33 | 34 | // Authority is set to vault 35 | associated_token::authority = vault, 36 | )] 37 | pub usdc_vault: Box>, 38 | 39 | // The mint of $USDC because it's needed from above ⬆ token::mint = ... 40 | #[account( 41 | address = USDC_ADDRESS, 42 | )] 43 | pub usdc_mint: Account<'info, Mint>, 44 | 45 | 46 | // USDT ata of vault 47 | #[account( 48 | init_if_needed, 49 | payer = admin, 50 | associated_token::mint = usdt_mint, 51 | 52 | // Authority is set to vault 53 | associated_token::authority = vault, 54 | )] 55 | pub usdt_vault: Box>, 56 | 57 | // The mint of $USDT because it's needed from above ⬆ token::mint = ... 58 | #[account( 59 | address = USDT_ADDRESS, 60 | )] 61 | pub usdt_mint: Account<'info, Mint>, 62 | 63 | 64 | pub token_program: Program<'info, Token>, 65 | pub associated_token_program: Program<'info, AssociatedToken>, 66 | 67 | // Needed to init new account 68 | pub system_program: Program<'info, System>, 69 | } 70 | 71 | impl SetVaultAddress<'_> { 72 | pub fn process_instruction(ctx: Context) -> Result<()> { 73 | let global_state = &mut ctx.accounts.global_state; 74 | 75 | // set new vault address 76 | global_state.vault = ctx.accounts.vault.key(); 77 | 78 | Ok(()) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /programs/presale/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | pub mod error; 4 | pub mod instructions; 5 | pub mod constant; 6 | pub mod state; 7 | pub mod util; 8 | use constant::*; 9 | use error::*; 10 | use instructions::*; 11 | use state::*; 12 | use util::*; 13 | 14 | declare_id!("6En2g3XUQgZSBEgBE1DF1sVeRik4KNvug151Zswz8oR5"); 15 | 16 | #[program] 17 | pub mod presale { 18 | use super::*; 19 | 20 | // called by contract deployer only 1 time to initialize global values 21 | // send SOL to global_account and initialize the global states 22 | pub fn initialize( 23 | ctx: Context 24 | ) -> Result<()> { 25 | Initialize::process_instruction(ctx) 26 | } 27 | 28 | // Admin can hand over admin role 29 | pub fn change_admin(ctx: Context, new_admin: Pubkey) -> Result<()> { 30 | change_admin::process_change_admin(ctx, new_admin) 31 | } 32 | 33 | // Admin can set the vault address 34 | pub fn set_vault_address( 35 | ctx: Context 36 | ) -> Result<()> { 37 | SetVaultAddress::process_instruction(ctx) 38 | } 39 | 40 | // Admin can start the presale 41 | pub fn start_presale( 42 | ctx: Context 43 | ) -> Result<()> { 44 | StartPresale::process_instruction(ctx) 45 | } 46 | 47 | // Admin can start the pause/resume presale 48 | // @param - live: pause presale if true, resume presale 49 | pub fn set_live( 50 | ctx: Context, 51 | live: bool 52 | ) -> Result<()> { 53 | SetLive::process_instruction(ctx, live) 54 | } 55 | 56 | // Admin can set the stage number 57 | pub fn set_stage( 58 | ctx: Context, 59 | stage: u8 60 | ) -> Result<()> { 61 | SetStage::process_instruction(ctx, stage) 62 | } 63 | 64 | // Initialize user state 65 | pub fn init_user( 66 | ctx: Context 67 | ) -> Result<()> { 68 | InitUser::process_instruction(ctx) 69 | } 70 | 71 | // Buy with SOL 72 | pub fn buy( 73 | ctx: Context, 74 | sol_amount: u64 75 | ) -> Result<()> { 76 | Buy::process_instruction(ctx, sol_amount) 77 | } 78 | 79 | // Buy with USDC/USDT 80 | pub fn buy_with_stable_coin( 81 | ctx: Context, 82 | stable_token_amount: u64 83 | ) -> Result<()> { 84 | BuyWithStableCoin::process_instruction(ctx, stable_token_amount) 85 | } 86 | } 87 | 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spl token presale smart contract 2 | This is token presale smart contract. This is full-working project. As a novice of solana smart contract, it might be one of good source code for you. Feel free to reach out of me if you have any question or custom requirements[telegram: https://t.me/DevCutup or whatsapp: https://wa.me/13137423660]. 3 | 4 | 5 | ## How to use it 6 | 7 | ### Install Dependencies 8 | 9 | - Install `node` and `yarn` 10 | 11 | - Install `rust`, `solana` and `anchor` 12 | 13 | https://www.anchor-lang.com/docs/installation 14 |
15 | 16 | ### How to deploy this program? 17 | 18 | First of all, you have to clone this repo to your PC. 19 | In the folder `token-presale` 20 | 21 | 1. Install node modules using `yarn` 22 | 23 | 2. Build program using anchor cli `anchor build` 24 | 25 | 3. Get program address using solana cli. 26 | 27 | `solana-keygen pubkey ./target/deploy/presale-keypair.json` 28 | 29 | You can get the pubkey of the program. e.g. `BE4G...5qhv` 30 | 31 | 4. Change program address in the code to `BE4G...5qhv` 32 | 33 | in `lib.rs` 34 | ``` 35 | declare_id!("BE4G...5qhv"); 36 | ``` 37 | in `Anchor.toml` 38 | ``` 39 | presale = "BE4G...5qhv" 40 | ``` 41 | 42 | 5. Change provider settings in `Anchor.toml` 43 | ``` 44 | cluster = "localnet" 45 | wallet = "./admin.json" 46 | ``` 47 | 48 | 6. run `anchor build` again 49 | 50 | 7. deploy program using anchor cli `anchor deploy` 51 |
52 | 53 | ### Test case 54 | 55 | ./tests/presal.ts is test script for each instruction 56 | 57 | 58 | run `anchor test` to check test the smart contract 59 | 60 | #### Test on devnet 61 | 62 | You should build and deploy on devnet first. 63 | 64 | Check the program address and USDC, USDT address. 65 | 66 | #### - Initialize project 67 | 68 | `yarn script init -t ` 69 | 70 | e.g. yarn script init -t 5U6PVxcjCWo361vFwS6cfB65Br4T5jECA6vsVAtm5urt 71 | 72 | #### - Set DAO wallet address 73 | 74 | `yarn script set-vault -v ` 75 | 76 | e.g. yarn script set-vault -v DJDcV3UxP55KqHUKsTSBve7xssRYtbQ5eSG8uWND2HQ7 77 | 78 | #### - Deposit token to the program 79 | 80 | `yarn script deposit-token -t -a ` 81 | 82 | e.g. yarn script deposit-token -t 5U6PVxcjCWo361vFwS6cfB65Br4T5jECA6vsVAtm5urt -a 200000000000000 83 | 84 | 85 | #### - Start presale 86 | 87 | `yarn script start-presale -t ` 88 | 89 | e.g. yarn script start-presale -t 5U6PVxcjCWo361vFwS6cfB65Br4T5jECA6vsVAtm5urt 90 | 91 | #### - Set stage 92 | 93 | `yarn script set-stage -s ` 94 | 95 | e.g. yarn script set-stage -s 1 96 | 97 | ### Contact Information 98 | - Telegram: https://t.me/DevCutup 99 | - Whatsapp: https://wa.me/13137423660 100 | - Twitter: https://x.com/devcutup 101 | -------------------------------------------------------------------------------- /cli/scripts.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@coral-xyz/anchor"; 2 | import { Program, Provider, web3 } from '@coral-xyz/anchor'; 3 | import fs from 'fs'; 4 | 5 | import { 6 | PublicKey, 7 | Keypair, 8 | Connection, 9 | } from '@solana/web3.js'; 10 | 11 | import NodeWallet from '@coral-xyz/anchor/dist/cjs/nodewallet'; 12 | 13 | import { Presale } from "../target/types/presale"; 14 | import { createDepositPresaleToken, createInitializeTx, createSetStageTx, createSetVaultAddressTx, createStartPresaleTx } from '../lib/scripts'; 15 | import { execTx } from "../lib/util"; 16 | 17 | let solConnection: Connection = null; 18 | let program: Program = null; 19 | let provider: Provider = null; 20 | let payer: NodeWallet = null; 21 | 22 | /** 23 | * Set cluster, provider, program 24 | * If rpc != null use rpc, otherwise use cluster param 25 | * @param cluster - cluster ex. mainnet-beta, devnet ... 26 | * @param keypair - wallet keypair 27 | * @param rpc - rpc 28 | */ 29 | export const setClusterConfig = async ( 30 | cluster: web3.Cluster, 31 | keypair: string, 32 | rpc?: string 33 | ) => { 34 | 35 | if (!rpc) { 36 | solConnection = new web3.Connection(web3.clusterApiUrl(cluster)); 37 | } else { 38 | solConnection = new web3.Connection(rpc); 39 | } 40 | 41 | const walletKeypair = Keypair.fromSecretKey( 42 | Uint8Array.from(JSON.parse(fs.readFileSync(keypair, 'utf-8'))), 43 | { skipValidation: true }); 44 | const wallet = new NodeWallet(walletKeypair); 45 | 46 | // Configure the client to use the local cluster. 47 | anchor.setProvider(new anchor.AnchorProvider( 48 | solConnection, 49 | wallet, 50 | { skipPreflight: true, commitment: 'confirmed' })); 51 | payer = wallet; 52 | 53 | provider = anchor.getProvider(); 54 | console.log('Wallet Address: ', wallet.publicKey.toBase58()); 55 | 56 | // Generate the program client from IDL. 57 | program = anchor.workspace.Presale as Program; 58 | 59 | console.log('ProgramId: ', program.programId.toBase58()); 60 | } 61 | 62 | /** 63 | * Initialize program 64 | * Called by admin right after the program deployment 65 | * to initialize global state 66 | */ 67 | export const initProject = async ( 68 | token: PublicKey 69 | ) => { 70 | const tx = await createInitializeTx(payer.publicKey, token, program); 71 | 72 | tx.recentBlockhash = (await solConnection.getLatestBlockhash()).blockhash; 73 | 74 | await execTx(tx, solConnection, payer); 75 | } 76 | 77 | export const setVaultAddress = async ( 78 | vault: PublicKey 79 | ) => { 80 | const tx = await createSetVaultAddressTx(payer.publicKey, vault, program); 81 | 82 | tx.recentBlockhash = (await solConnection.getLatestBlockhash()).blockhash; 83 | 84 | await execTx(tx, solConnection, payer); 85 | } 86 | 87 | export const depositPresaleToken = async ( 88 | token: PublicKey, 89 | amount: number 90 | ) => { 91 | const tx = await createDepositPresaleToken(payer.publicKey, token, amount, program); 92 | 93 | tx.recentBlockhash = (await solConnection.getLatestBlockhash()).blockhash; 94 | 95 | await execTx(tx, solConnection, payer); 96 | } 97 | 98 | export const startPresale = async ( 99 | token: PublicKey 100 | ) => { 101 | const tx = await createStartPresaleTx(payer.publicKey, token, program); 102 | 103 | tx.recentBlockhash = (await solConnection.getLatestBlockhash()).blockhash; 104 | 105 | await execTx(tx, solConnection, payer); 106 | } 107 | 108 | export const setStage = async ( 109 | stageNum: number 110 | ) => { 111 | const tx = await createSetStageTx(payer.publicKey, stageNum, program); 112 | 113 | tx.recentBlockhash = (await solConnection.getLatestBlockhash()).blockhash; 114 | 115 | await execTx(tx, solConnection, payer); 116 | } 117 | -------------------------------------------------------------------------------- /cli/command.ts: -------------------------------------------------------------------------------- 1 | import { program } from "commander"; 2 | import { PublicKey } from "@solana/web3.js"; 3 | import { 4 | depositPresaleToken, 5 | initProject, 6 | setClusterConfig, 7 | setStage, 8 | setVaultAddress, 9 | startPresale, 10 | } from "./scripts"; 11 | 12 | program.version("0.0.1"); 13 | 14 | programCommand("init") 15 | .option("-t, --token ", "token to use in the program") 16 | .action(async (directory, cmd) => { 17 | const { env, keypair, rpc, token } = cmd.opts(); 18 | 19 | console.log("Solana Cluster:", env); 20 | console.log("Keypair Path:", keypair); 21 | console.log("RPC URL:", rpc); 22 | 23 | await setClusterConfig(env, keypair, rpc); 24 | 25 | if (token === undefined) { 26 | console.log("Error token address"); 27 | return; 28 | } 29 | 30 | await initProject(new PublicKey(token)); 31 | }); 32 | 33 | programCommand("set-vault") 34 | .option("-v, --vault ", "dao wallet address") 35 | .action(async (directory, cmd) => { 36 | const { env, keypair, rpc, vault } = cmd.opts(); 37 | 38 | console.log("Solana Cluster:", env); 39 | console.log("Keypair Path:", keypair); 40 | console.log("RPC URL:", rpc); 41 | 42 | await setClusterConfig(env, keypair, rpc); 43 | 44 | if (vault === undefined) { 45 | console.log("Error vault address"); 46 | return; 47 | } 48 | 49 | await setVaultAddress(new PublicKey(vault)); 50 | }); 51 | 52 | programCommand("deposit-token") 53 | .option("-t, --token ", "token address that's used in the program") 54 | .option("-a, --amount ", "amount to be dposited") 55 | .action(async (directory, cmd) => { 56 | const { env, keypair, rpc, token, amount } = cmd.opts(); 57 | 58 | console.log("Solana Cluster:", env); 59 | console.log("Keypair Path:", keypair); 60 | console.log("RPC URL:", rpc); 61 | 62 | await setClusterConfig(env, keypair, rpc); 63 | 64 | if (token === undefined) { 65 | console.log("Error vault address"); 66 | return; 67 | } 68 | 69 | if (amount === undefined || amount < 0) { 70 | console.log("Error stable coin amount"); 71 | return; 72 | } 73 | 74 | await depositPresaleToken(new PublicKey(token), amount); 75 | }); 76 | 77 | programCommand("start-presale") 78 | .option("-t, --token ", "token address that's used in the program") 79 | .action(async (directory, cmd) => { 80 | const { env, keypair, rpc, token } = cmd.opts(); 81 | 82 | console.log("Solana Cluster:", env); 83 | console.log("Keypair Path:", keypair); 84 | console.log("RPC URL:", rpc); 85 | 86 | await setClusterConfig(env, keypair, rpc); 87 | 88 | if (token === undefined) { 89 | console.log("Error vault address"); 90 | return; 91 | } 92 | 93 | await startPresale(new PublicKey(token)); 94 | }); 95 | 96 | programCommand("set-stage") 97 | .option("-s, --stage ", "stage number") 98 | .action(async (directory, cmd) => { 99 | const { env, keypair, rpc, stage } = cmd.opts(); 100 | 101 | console.log("Solana Cluster:", env); 102 | console.log("Keypair Path:", keypair); 103 | console.log("RPC URL:", rpc); 104 | 105 | await setClusterConfig(env, keypair, rpc); 106 | 107 | await setStage(stage); 108 | }); 109 | 110 | function programCommand(name: string) { 111 | return program 112 | .command(name) 113 | .option( 114 | // mainnet-beta, testnet, devnet 115 | "-e, --env ", 116 | "Solana cluster env name", 117 | "devnet" 118 | ) 119 | .option( 120 | "-r, --rpc ", 121 | "Solana cluster RPC name", 122 | "https://api.devnet.solana.com" 123 | ) 124 | .option( 125 | "-k, --keypair ", 126 | "Solana wallet Keypair Path", 127 | "admin.json" 128 | ); 129 | } 130 | 131 | program.parse(process.argv); 132 | 133 | /* 134 | 135 | yarn script init -t 5U6PVxcjCWo361vFwS6cfB65Br4T5jECA6vsVAtm5urt 136 | yarn script set-vault -v DJDcV3UxP55KqHUKsTSBve7xssRYtbQ5eSG8uWND2HQ7 137 | yarn script deposit-token -t 5U6PVxcjCWo361vFwS6cfB65Br4T5jECA6vsVAtm5urt -a 200000000000000 138 | yarn script start-presale -t 5U6PVxcjCWo361vFwS6cfB65Br4T5jECA6vsVAtm5urt 139 | yarn script set-stage -s 1 140 | 141 | */ 142 | -------------------------------------------------------------------------------- /programs/presale/src/instructions/buy_with_stable_coin.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | use anchor_spl::{ 3 | associated_token::AssociatedToken, 4 | token::{ Mint, Token, TokenAccount } 5 | }; 6 | 7 | #[derive(Accounts)] 8 | pub struct BuyWithStableCoin<'info> { 9 | #[account( 10 | mut 11 | )] 12 | pub user: Signer<'info>, 13 | 14 | // Global state 15 | #[account( 16 | mut, 17 | seeds = [GLOBAL_SEED], 18 | bump 19 | )] 20 | pub global_state: Account<'info, GlobalState>, 21 | 22 | // User pool stores user's buy info 23 | #[account( 24 | mut, 25 | seeds = [user.key().as_ref(), USER_SEED.as_ref()], 26 | bump 27 | )] 28 | pub user_state: Account<'info, UserState>, 29 | 30 | 31 | /// CHECK: vault address(multi-sig wallet) 32 | pub vault: AccountInfo<'info>, 33 | 34 | 35 | // stable coin ata of user 36 | #[account( 37 | mut, 38 | associated_token::mint = stable_coin, 39 | associated_token::authority = user, 40 | )] 41 | pub stable_coin_user: Box>, 42 | 43 | // stable coin ata of vault 44 | #[account( 45 | mut, 46 | associated_token::mint = stable_coin, 47 | associated_token::authority = vault, 48 | )] 49 | pub stable_coin_vault: Box>, 50 | 51 | // token address of stable coin(USDC/USDT) 52 | /// CHECK: 53 | pub stable_coin: Account<'info, Mint>, 54 | 55 | 56 | pub token_program: Program<'info, Token>, 57 | pub associated_token_program: Program<'info, AssociatedToken>, 58 | } 59 | 60 | impl BuyWithStableCoin<'_> { 61 | pub fn process_instruction(ctx: Context, mut stable_coin_amount: u64) -> Result<()> { 62 | let global_state = &mut ctx.accounts.global_state; 63 | let stage_iterator = global_state.stage_iterator; 64 | 65 | // check presale is live 66 | if global_state.is_live == false { 67 | match stage_iterator { 68 | 0 => return Err(error!(PresaleError::PresaleNotStarted)), 69 | stage if stage > NUM_STAGES => return Err(error!(PresaleError::PresaleEnded)), 70 | _ => return Err(error!(PresaleError::PresalePaused)), 71 | } 72 | } 73 | 74 | 75 | // check stable coin address 76 | require!(ctx.accounts.stable_coin.key() == USDC_ADDRESS || ctx.accounts.stable_coin.key() == USDT_ADDRESS, PresaleError::InvalidStableToken); 77 | 78 | // calculate token amount from stable_coin_amount and token price 79 | let mut token_amount = stable_coin_amount / STAGES[stage_iterator as usize].price; 80 | msg!("token amount: {}", token_amount); 81 | 82 | 83 | // check if enough token remain 84 | if global_state.remain_tokens[stage_iterator as usize] < token_amount { 85 | // fix token_amount and stable_coin_amount 86 | token_amount = global_state.remain_tokens[stage_iterator as usize]; 87 | stable_coin_amount = STAGES[stage_iterator as usize].price * token_amount; 88 | 89 | // go to next stage 90 | global_state.stage_iterator = stage_iterator + 1; 91 | 92 | // end presale if current stage is the last one 93 | if stage_iterator == NUM_STAGES { 94 | global_state.is_live = false; 95 | } 96 | } 97 | 98 | 99 | // minus remain tokens in the current stage 100 | global_state.remain_tokens[stage_iterator as usize] -= token_amount; 101 | 102 | // add total tokens sold 103 | global_state.token_sold += token_amount; 104 | 105 | // add total USD received 106 | global_state.token_sold_usd += stable_coin_amount; 107 | 108 | // add user info 109 | let user_state = &mut ctx.accounts.user_state; 110 | user_state.tokens += token_amount; 111 | user_state.paid_usd += stable_coin_amount; 112 | 113 | // transfer stable coin to vault 114 | token_transfer_user( 115 | ctx.accounts.stable_coin_user.to_account_info(), 116 | ctx.accounts.user.to_account_info(), 117 | ctx.accounts.stable_coin_vault.to_account_info(), 118 | ctx.accounts.token_program.to_account_info(), 119 | stable_coin_amount, 120 | ) 121 | 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /programs/presale/src/instructions/buy.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | 3 | use pyth_sdk_solana::state::SolanaPriceAccount; 4 | use solana_program::native_token::LAMPORTS_PER_SOL; 5 | 6 | #[derive(Accounts)] 7 | pub struct Buy<'info> { 8 | #[account( 9 | mut 10 | )] 11 | pub user: Signer<'info>, 12 | 13 | // Global state 14 | #[account( 15 | mut, 16 | seeds = [GLOBAL_SEED], 17 | bump 18 | )] 19 | pub global_state: Account<'info, GlobalState>, 20 | 21 | // User pool stores user's buy info 22 | #[account( 23 | mut, 24 | seeds = [user.key().as_ref(), USER_SEED.as_ref()], 25 | bump 26 | )] 27 | pub user_state: Account<'info, UserState>, 28 | 29 | #[account( 30 | mut 31 | )] 32 | /// CHECK: vault address(multi-sig wallet) 33 | pub vault: AccountInfo<'info>, 34 | 35 | 36 | #[account(address = SOL_USD_FEED @PresaleError::InvalidPriceFeed)] 37 | /// CHECK: 38 | pub price_feed: AccountInfo<'info>, 39 | 40 | // Needed to transfer SOL 41 | pub system_program: Program<'info, System> 42 | } 43 | 44 | impl Buy<'_> { 45 | pub fn process_instruction(ctx: Context, mut sol_amount: u64) -> Result<()> { 46 | let global_state = &mut ctx.accounts.global_state; 47 | let stage_iterator = global_state.stage_iterator; 48 | 49 | // check presale is live 50 | if global_state.is_live == false { 51 | match stage_iterator { 52 | 0 => return Err(error!(PresaleError::PresaleNotStarted)), 53 | stage if stage > NUM_STAGES => return Err(error!(PresaleError::PresaleEnded)), 54 | _ => return Err(error!(PresaleError::PresalePaused)), 55 | } 56 | } 57 | 58 | 59 | // get SOL price 60 | // Retrieve Pyth price 61 | let price_account_info = &ctx.accounts.price_feed; 62 | let price_feed: pyth_sdk_solana::PriceFeed = SolanaPriceAccount::account_info_to_feed(price_account_info).unwrap(); 63 | let timestamp = Clock::get()?.unix_timestamp; 64 | let asset_price = price_feed.get_price_no_older_than(timestamp, 60).unwrap().price; 65 | 66 | // Scale price to expected decimals 67 | // let asset_expo = asset_price.expo; 68 | // asset_price = asset_price.scale_to_exponent(asset_expo).unwrap(); 69 | 70 | msg!("SOL/USD price: {}", asset_price); 71 | 72 | // calculate token amount from sol_amount and token price 73 | let mut token_amount = (asset_price as f64 / 100.0 / STAGES[stage_iterator as usize].price as f64 * (sol_amount / LAMPORTS_PER_SOL) as f64) as u64; 74 | msg!("token amount: {}", token_amount); 75 | 76 | 77 | // check if enough token remain 78 | if global_state.remain_tokens[stage_iterator as usize] < token_amount { 79 | msg!("not enough tokens in this stage"); 80 | 81 | // fix token_amount and sol_amount 82 | token_amount = global_state.remain_tokens[stage_iterator as usize]; 83 | sol_amount = (STAGES[stage_iterator as usize].price as f64 / (asset_price as f64 / 100.0) * (LAMPORTS_PER_SOL * token_amount) as f64) as u64; 84 | 85 | // go to next stage 86 | global_state.stage_iterator = stage_iterator + 1; 87 | 88 | // end presale if current stage is the last one 89 | if stage_iterator == NUM_STAGES { 90 | global_state.is_live = false; 91 | } 92 | } 93 | 94 | 95 | // minus remain tokens in the current stage 96 | global_state.remain_tokens[stage_iterator as usize] -= token_amount; 97 | 98 | // add total tokens sold 99 | global_state.token_sold += token_amount; 100 | 101 | // add total USD received 102 | global_state.token_sold_usd += asset_price as u64 * sol_amount; 103 | 104 | // add user info 105 | let user_state = &mut ctx.accounts.user_state; 106 | user_state.tokens += token_amount; 107 | user_state.paid_sol += sol_amount; 108 | 109 | // transfer SOL to vault 110 | sol_transfer_user( 111 | ctx.accounts.user.to_account_info().clone(), 112 | ctx.accounts.vault.to_account_info().clone(), 113 | ctx.accounts.system_program.to_account_info().clone(), 114 | sol_amount 115 | ) 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /lib/scripts.ts: -------------------------------------------------------------------------------- 1 | import { BN, Program } from "@coral-xyz/anchor"; 2 | import { 3 | PublicKey, 4 | Transaction, 5 | ComputeBudgetProgram 6 | } from "@solana/web3.js"; 7 | 8 | import { 9 | getAssociatedTokenAccount 10 | } from "./util"; 11 | import { GLOBAL_STATE_SEED, USDC_ADDRESS, USDT_ADDRESS } from "./constant"; 12 | import { Presale } from "../target/types/presale"; 13 | 14 | export const createInitializeTx = async ( 15 | admin: PublicKey, 16 | token: PublicKey, 17 | program: Program 18 | ) => { 19 | const [globalState, bump] = PublicKey.findProgramAddressSync( 20 | [Buffer.from(GLOBAL_STATE_SEED)], 21 | program.programId 22 | ); 23 | console.log("globalState: ", globalState.toBase58()); 24 | 25 | const tokenVault = getAssociatedTokenAccount(globalState, token); 26 | console.log("tokenVault: ", tokenVault.toBase58()); 27 | 28 | const tx = new Transaction(); 29 | 30 | tx.add(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1_000_000 })) 31 | .add(ComputeBudgetProgram.setComputeUnitLimit({ units: 65_000 })) 32 | .add( 33 | await program.methods 34 | .initialize() 35 | .accounts({ 36 | admin, 37 | token, 38 | tokenVault 39 | }) 40 | .transaction() 41 | ); 42 | 43 | tx.feePayer = admin; 44 | 45 | return tx; 46 | }; 47 | 48 | export const createSetVaultAddressTx = async ( 49 | admin: PublicKey, 50 | vault: PublicKey, 51 | program: Program 52 | ) => { 53 | const [globalState, bump] = PublicKey.findProgramAddressSync( 54 | [Buffer.from(GLOBAL_STATE_SEED)], 55 | program.programId 56 | ); 57 | console.log("globalState: ", globalState.toBase58()); 58 | 59 | const usdcVault = getAssociatedTokenAccount(vault, USDC_ADDRESS); 60 | console.log("usdcVault: ", usdcVault.toBase58()); 61 | 62 | const usdtVault = getAssociatedTokenAccount(vault, USDT_ADDRESS); 63 | console.log("usdtVault: ", usdtVault.toBase58()); 64 | 65 | const tx = new Transaction(); 66 | 67 | tx.add(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1_000_000 })) 68 | .add(ComputeBudgetProgram.setComputeUnitLimit({ units: 120_000 })) 69 | .add( 70 | await program.methods 71 | .setVaultAddress() 72 | .accounts({ 73 | admin, 74 | vault, 75 | usdcVault, 76 | usdtVault 77 | }) 78 | .transaction() 79 | ); 80 | 81 | tx.feePayer = admin; 82 | 83 | return tx; 84 | }; 85 | 86 | export const createDepositPresaleToken = async ( 87 | admin: PublicKey, 88 | token: PublicKey, 89 | amount: number, 90 | program: Program 91 | ) => { 92 | const [globalState, bump] = PublicKey.findProgramAddressSync( 93 | [Buffer.from(GLOBAL_STATE_SEED)], 94 | program.programId 95 | ); 96 | console.log("globalState: ", globalState.toBase58()); 97 | 98 | const tokenAdmin = getAssociatedTokenAccount(admin, token); 99 | console.log("tokenAdmin: ", tokenAdmin.toBase58()); 100 | 101 | const tokenVault = getAssociatedTokenAccount(globalState, token); 102 | console.log("tokenVault: ", tokenVault.toBase58()); 103 | 104 | const tx = new Transaction(); 105 | 106 | tx.add(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1_000_000 })) 107 | .add(ComputeBudgetProgram.setComputeUnitLimit({ units: 65_000 })) 108 | .add( 109 | await program.methods 110 | .depositPresaleToken(new BN(amount)) 111 | .accounts({ 112 | admin, 113 | token, 114 | tokenAdmin, 115 | tokenVault 116 | }) 117 | .transaction() 118 | ); 119 | 120 | tx.feePayer = admin; 121 | 122 | return tx; 123 | }; 124 | 125 | export const createStartPresaleTx = async ( 126 | admin: PublicKey, 127 | token: PublicKey, 128 | program: Program 129 | ) => { 130 | const [globalState, bump] = PublicKey.findProgramAddressSync( 131 | [Buffer.from(GLOBAL_STATE_SEED)], 132 | program.programId 133 | ); 134 | console.log("globalState: ", globalState.toBase58()); 135 | 136 | const tokenVault = getAssociatedTokenAccount(globalState, token); 137 | console.log("tokenVault: ", tokenVault.toBase58()); 138 | 139 | const tx = new Transaction(); 140 | 141 | tx.add(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1_000_000 })) 142 | .add(ComputeBudgetProgram.setComputeUnitLimit({ units: 65_000 })) 143 | .add( 144 | await program.methods 145 | .startPresale() 146 | .accounts({ 147 | admin, 148 | token, 149 | tokenVault 150 | }) 151 | .transaction() 152 | ); 153 | 154 | tx.feePayer = admin; 155 | 156 | return tx; 157 | }; 158 | 159 | export const createSetStageTx = async ( 160 | admin: PublicKey, 161 | stageNum: number, 162 | program: Program 163 | ) => { 164 | 165 | const tx = new Transaction(); 166 | 167 | tx.add(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1_000_000 })) 168 | .add(ComputeBudgetProgram.setComputeUnitLimit({ units: 65_000 })) 169 | .add( 170 | await program.methods 171 | .setStage(stageNum) 172 | .accounts({ 173 | admin 174 | }) 175 | .transaction() 176 | ); 177 | 178 | tx.feePayer = admin; 179 | 180 | return tx; 181 | }; 182 | -------------------------------------------------------------------------------- /lib/util.ts: -------------------------------------------------------------------------------- 1 | 2 | import { 3 | AddressLookupTableAccount, 4 | TransactionInstruction, 5 | VersionedTransaction, 6 | TransactionMessage, 7 | Transaction, 8 | Connection, 9 | SimulateTransactionConfig, 10 | SystemProgram, 11 | SYSVAR_RENT_PUBKEY 12 | } from "@solana/web3.js"; 13 | 14 | import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet"; 15 | 16 | import { 17 | PublicKey, 18 | } from "@solana/web3.js"; 19 | import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token"; 20 | 21 | export const getAssociatedTokenAccount = ( 22 | ownerPubkey: PublicKey, 23 | mintPk: PublicKey 24 | ): PublicKey => { 25 | let associatedTokenAccountPubkey = (PublicKey.findProgramAddressSync( 26 | [ 27 | ownerPubkey.toBytes(), 28 | TOKEN_PROGRAM_ID.toBytes(), 29 | mintPk.toBytes(), // mint address 30 | ], 31 | ASSOCIATED_TOKEN_PROGRAM_ID 32 | ))[0]; 33 | 34 | return associatedTokenAccountPubkey; 35 | } 36 | 37 | export const getAdressLookupTableAccounts = async ( 38 | keys: string[], 39 | connection: Connection 40 | ): Promise => { 41 | const addressLookupTableAccountInfos = 42 | await connection.getMultipleAccountsInfo( 43 | keys.map((key) => new PublicKey(key)) 44 | ); 45 | 46 | return addressLookupTableAccountInfos.reduce((acc, accountInfo, index) => { 47 | const addressLookupTableAddress = keys[index]; 48 | if (accountInfo) { 49 | const addressLookupTableAccount = new AddressLookupTableAccount({ 50 | key: new PublicKey(addressLookupTableAddress), 51 | state: AddressLookupTableAccount.deserialize(accountInfo.data), 52 | }); 53 | acc.push(addressLookupTableAccount); 54 | } 55 | 56 | return acc; 57 | }, new Array()); 58 | }; 59 | 60 | export const instructionDataToTransactionInstruction = ( 61 | instructionPayload: any 62 | ) => { 63 | if (instructionPayload === null) { 64 | return null; 65 | } 66 | 67 | return new TransactionInstruction({ 68 | programId: new PublicKey(instructionPayload.programId), 69 | keys: instructionPayload.accounts.map((key) => ({ 70 | pubkey: new PublicKey(key.pubkey), 71 | isSigner: key.isSigner, 72 | isWritable: key.isWritable, 73 | })), 74 | data: Buffer.from(instructionPayload.data, "base64"), 75 | }); 76 | }; 77 | 78 | export const createAssociatedTokenAccountInstruction = ( 79 | associatedTokenAddress: PublicKey, 80 | payer: PublicKey, 81 | walletAddress: PublicKey, 82 | splTokenMintAddress: PublicKey 83 | ) => { 84 | const keys = [ 85 | { pubkey: payer, isSigner: true, isWritable: true }, 86 | { pubkey: associatedTokenAddress, isSigner: false, isWritable: true }, 87 | { pubkey: walletAddress, isSigner: false, isWritable: false }, 88 | { pubkey: splTokenMintAddress, isSigner: false, isWritable: false }, 89 | { 90 | pubkey: SystemProgram.programId, 91 | isSigner: false, 92 | isWritable: false, 93 | }, 94 | { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, 95 | { 96 | pubkey: SYSVAR_RENT_PUBKEY, 97 | isSigner: false, 98 | isWritable: false, 99 | }, 100 | ]; 101 | return new TransactionInstruction({ 102 | keys, 103 | programId: ASSOCIATED_TOKEN_PROGRAM_ID, 104 | data: Buffer.from([]), 105 | }); 106 | }; 107 | 108 | export const getATokenAccountsNeedCreate = async ( 109 | connection: Connection, 110 | walletAddress: PublicKey, 111 | owner: PublicKey, 112 | nfts: PublicKey[], 113 | ) => { 114 | const instructions = []; const destinationAccounts = []; 115 | for (const mint of nfts) { 116 | const destinationPubkey = getAssociatedTokenAccount(owner, mint); 117 | let response = await connection.getAccountInfo(destinationPubkey); 118 | if (!response) { 119 | const createATAIx = createAssociatedTokenAccountInstruction( 120 | destinationPubkey, 121 | walletAddress, 122 | owner, 123 | mint, 124 | ); 125 | instructions.push(createATAIx); 126 | } 127 | destinationAccounts.push(destinationPubkey); 128 | if (walletAddress != owner) { 129 | const userAccount = getAssociatedTokenAccount(walletAddress, mint); 130 | response = await connection.getAccountInfo(userAccount); 131 | if (!response) { 132 | const createATAIx = createAssociatedTokenAccountInstruction( 133 | userAccount, 134 | walletAddress, 135 | walletAddress, 136 | mint, 137 | ); 138 | instructions.push(createATAIx); 139 | } 140 | } 141 | } 142 | return { 143 | instructions, 144 | destinationAccounts, 145 | }; 146 | }; 147 | 148 | export const execTx = async ( 149 | transaction: Transaction | VersionedTransaction, 150 | connection: Connection, 151 | payer: NodeWallet 152 | ) => { 153 | try { 154 | 155 | // Add recent blockhash if it's not a versioned transaction 156 | if (transaction instanceof Transaction) { 157 | transaction.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 158 | } 159 | 160 | // Sign the transaction with payer wallet 161 | const signedTx = await payer.signTransaction(transaction); 162 | 163 | console.log("accounts: ", (signedTx as Transaction).compileMessage().accountKeys.length); 164 | 165 | // Serialize, send and confirm the transaction 166 | const rawTransaction = signedTx.serialize() 167 | 168 | const result = await connection.simulateTransaction(transaction as Transaction); 169 | console.log('simulate result'); 170 | console.log(result); 171 | 172 | if (result.value.err) return; 173 | 174 | const txid = await connection.sendRawTransaction(rawTransaction, { 175 | skipPreflight: true, 176 | maxRetries: 2, 177 | preflightCommitment: "processed" 178 | }); 179 | console.log(`https://solscan.io/tx/${txid}`); 180 | 181 | const confirmed = await connection.confirmTransaction(txid, "confirmed"); 182 | 183 | console.log("err ", confirmed.value.err) 184 | } catch (e) { 185 | console.log(e); 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /tests/presale.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@coral-xyz/anchor"; 2 | import { 3 | Keypair, 4 | PublicKey 5 | } from "@solana/web3.js"; 6 | 7 | import { GLOBAL_SEED, USER_SEED, LAMPORTS_PER_SOL } from "./constant"; 8 | import { connection, program, usdcKp, usdtKp, vaultKp } from "./config"; 9 | import { createMints } from "./create-mints"; 10 | import { airdropToken } from "./airdrop-tokens"; 11 | import { getAssociatedTokenAccount } from "./utils"; 12 | import { BN } from "bn.js"; 13 | import { expect } from 'chai'; 14 | 15 | describe("presale", () => { 16 | 17 | const adminKp = Keypair.generate(); 18 | const userKp = Keypair.generate(); 19 | 20 | console.log("admin: ", adminKp.publicKey.toBase58()); 21 | console.log("user: ", userKp.publicKey.toBase58()); 22 | 23 | before(async () => { 24 | console.log("airdrop SOL to admin") 25 | const airdropTx = await connection.requestAirdrop( 26 | adminKp.publicKey, 27 | 5 * LAMPORTS_PER_SOL 28 | ); 29 | await connection.confirmTransaction(airdropTx); 30 | 31 | console.log("airdrop SOL to user") 32 | const airdropTx2 = await connection.requestAirdrop( 33 | userKp.publicKey, 34 | 5 * LAMPORTS_PER_SOL 35 | ); 36 | await connection.confirmTransaction(airdropTx2); 37 | 38 | console.log("airdrop SOL to vault") 39 | const airdropTx3 = await connection.requestAirdrop( 40 | vaultKp.publicKey, 41 | 5 * LAMPORTS_PER_SOL 42 | ); 43 | await connection.confirmTransaction(airdropTx3); 44 | 45 | console.log("create USDC/USDT"); 46 | await createMints(adminKp); 47 | 48 | console.log("airdrop tokens"); 49 | await airdropToken(usdcKp, usdcKp, adminKp, userKp.publicKey, 1_000_000_000); 50 | await airdropToken(usdtKp, usdtKp, adminKp, userKp.publicKey, 1_000_000_000); 51 | }); 52 | 53 | it("Is initialized!", async () => { 54 | const [globalStateAddr, _] = PublicKey.findProgramAddressSync( 55 | [Buffer.from(GLOBAL_SEED)], 56 | program.programId 57 | ); 58 | console.log("globalStateAddr: ", globalStateAddr.toBase58()); 59 | 60 | const tx = await program.methods.initialize() 61 | .accounts({ 62 | admin: adminKp.publicKey, 63 | }) 64 | .signers([adminKp]) 65 | .rpc(); 66 | console.log("initialize tx: ", tx); 67 | 68 | const globalState = await program.account.globalState.fetch(globalStateAddr); 69 | const sum = globalState.remainTokens.reduce((acc, num) => acc + num.toNumber(), 0); 70 | console.log("total tokens needed: ", sum); 71 | }); 72 | 73 | it("Set vault address", async () => { 74 | const usdcVault = getAssociatedTokenAccount(vaultKp.publicKey, usdcKp.publicKey); 75 | const usdtVault = getAssociatedTokenAccount(vaultKp.publicKey, usdtKp.publicKey); 76 | console.log("vault: ", vaultKp.publicKey.toBase58()); 77 | console.log("usdcVault: ", usdcVault.toBase58()); 78 | console.log("usdtVault: ", usdtVault.toBase58()); 79 | 80 | const tx = await program.methods.setVaultAddress() 81 | .accounts({ 82 | admin: adminKp.publicKey, 83 | vault: vaultKp.publicKey, 84 | usdcVault, 85 | usdtVault 86 | }) 87 | .signers([adminKp]) 88 | .rpc(); 89 | console.log("set dao wallet tx: ", tx); 90 | 91 | const [globalStateAddr, _] = PublicKey.findProgramAddressSync( 92 | [Buffer.from(GLOBAL_SEED)], 93 | program.programId 94 | ); 95 | const globalState = await program.account.globalState.fetch(globalStateAddr); 96 | console.log("multi-sig wallet addr: ", globalState.vault.toBase58()); 97 | }); 98 | 99 | it("Start presale", async () => { 100 | const [globalStateAddr, _] = PublicKey.findProgramAddressSync( 101 | [Buffer.from(GLOBAL_SEED)], 102 | program.programId 103 | ); 104 | 105 | console.log("globalStateAddr: ", globalStateAddr.toBase58()); 106 | 107 | const tx = await program.methods.startPresale() 108 | .accounts({ 109 | admin: adminKp.publicKey 110 | }) 111 | .signers([adminKp]) 112 | .rpc(); 113 | 114 | console.log("start presale tx: ", tx); 115 | 116 | const globalState = await program.account.globalState.fetch(globalStateAddr); 117 | expect(globalState.isLive).to.equal(true); 118 | expect(globalState.stageIterator).to.equal(0); 119 | }); 120 | 121 | it("Admin can set the stage number", async () => { 122 | 123 | const [globalStateAddr, _] = PublicKey.findProgramAddressSync( 124 | [Buffer.from(GLOBAL_SEED)], 125 | program.programId 126 | ); 127 | 128 | const tx = await program.methods.setStage(1) 129 | .accounts({ 130 | admin: adminKp.publicKey, 131 | }) 132 | .signers([adminKp]) 133 | .rpc({commitment: "confirmed"}); 134 | 135 | console.log("set stage tx: ", tx); 136 | const globalState = await program.account.globalState.fetch(globalStateAddr, "confirmed"); 137 | expect(globalState.stageIterator).to.equal(1); 138 | 139 | // set presale stage back to 0 140 | const tx2 = await program.methods.setStage(0) 141 | .accounts({ 142 | admin: adminKp.publicKey, 143 | }) 144 | .signers([adminKp]) 145 | .rpc({commitment: "confirmed"}); 146 | 147 | console.log("set stage tx: ", tx2) 148 | }); 149 | 150 | it("Initialize user state", async () => { 151 | const [userStateAddr, _userIx] = PublicKey.findProgramAddressSync( 152 | [userKp.publicKey.toBuffer(), Buffer.from(USER_SEED)], 153 | program.programId 154 | ); 155 | 156 | console.log("userStateAddr: ", userStateAddr.toBase58()); 157 | 158 | const tx = await program.methods.initUser() 159 | .accounts({ 160 | user: userKp.publicKey, 161 | 162 | }) 163 | .signers([userKp]) 164 | .rpc(); 165 | 166 | console.log("init user tx: ", tx); 167 | 168 | const userState = await program.account.userState.fetch(userStateAddr); 169 | expect(userState).to.not.be.null; 170 | }); 171 | 172 | it("User buys token with SOL", async () => { 173 | const [globalStateAddr, _] = PublicKey.findProgramAddressSync( 174 | [Buffer.from(GLOBAL_SEED)], 175 | program.programId 176 | ); 177 | const [userStateAddr, _userIx] = PublicKey.findProgramAddressSync( 178 | [userKp.publicKey.toBuffer(), Buffer.from(USER_SEED)], 179 | program.programId 180 | ); 181 | 182 | console.log("globalStateAddr: ", globalStateAddr.toBase58()); 183 | console.log("userStateAddr: ", userStateAddr.toBase58()); 184 | 185 | const userState = await program.account.userState.fetch(userStateAddr, "confirmed"); 186 | const balanceBefore = Number(userState.tokens); 187 | 188 | const buyAmount = 1_000_000_000; // 1 SOL 189 | 190 | const tx = await program.methods.buy(new BN(buyAmount)) 191 | .accounts({ 192 | user: userKp.publicKey, 193 | vault: vaultKp.publicKey, 194 | }) 195 | .signers([userKp]) 196 | .rpc({commitment: "confirmed"}); 197 | 198 | console.log("buy with SOL tx: ", tx); 199 | 200 | const userStateAfter = await program.account.userState.fetch(userStateAddr, "confirmed"); 201 | const balanceAfter = Number(userStateAfter.tokens); 202 | 203 | console.log("bought token amout: ", balanceAfter - balanceBefore); 204 | }); 205 | 206 | it("User buys token with USDC", async () => { 207 | const [globalStateAddr, _] = PublicKey.findProgramAddressSync( 208 | [Buffer.from(GLOBAL_SEED)], 209 | program.programId 210 | ); 211 | const [userStateAddr, _userIx] = PublicKey.findProgramAddressSync( 212 | [userKp.publicKey.toBuffer(), Buffer.from(USER_SEED)], 213 | program.programId 214 | ); 215 | const stableCoinUser = getAssociatedTokenAccount(userKp.publicKey, usdcKp.publicKey); 216 | const stableCoinVault = getAssociatedTokenAccount(vaultKp.publicKey, usdcKp.publicKey); 217 | 218 | console.log("globalStateAddr: ", globalStateAddr.toBase58()); 219 | console.log("stableCoinUser: ", stableCoinUser.toBase58()); 220 | console.log("stableCoinVault: ", stableCoinVault.toBase58()); 221 | 222 | const userState = await program.account.userState.fetch(userStateAddr, "confirmed"); 223 | const balanceBefore = Number(userState.tokens); 224 | 225 | const buyAmount = 1_000_000_000; // 1000 USDC 226 | 227 | const tx = await program.methods.buyWithStableCoin(new BN(buyAmount)) 228 | .accounts({ 229 | user: userKp.publicKey, 230 | vault: vaultKp.publicKey, 231 | stableCoin: usdcKp.publicKey, 232 | stableCoinUser, 233 | stableCoinVault 234 | }) 235 | .signers([userKp]) 236 | .rpc({commitment: "confirmed"}); 237 | 238 | console.log("buy with USDC tx: ", tx); 239 | 240 | const userStateAfter = await program.account.userState.fetch(userStateAddr, "confirmed"); 241 | const balanceAfter = Number(userStateAfter.tokens); 242 | 243 | console.log("bought token amout: ", balanceAfter - balanceBefore); 244 | }); 245 | 246 | it("Get all user info", async () => { 247 | 248 | const userInfos = await program.account.userState.all(); 249 | console.log(userInfos); 250 | }); 251 | 252 | }); 253 | -------------------------------------------------------------------------------- /lib/executor.ts: -------------------------------------------------------------------------------- 1 | // Jito Bundling part 2 | 3 | import { 4 | Connection, 5 | Keypair, 6 | PublicKey, 7 | VersionedTransaction, 8 | } from "@solana/web3.js"; 9 | import base58 from "bs58"; 10 | import { 11 | SearcherClient, 12 | searcherClient, 13 | } from "jito-ts/dist/sdk/block-engine/searcher"; 14 | import { Bundle } from "jito-ts/dist/sdk/block-engine/types"; 15 | import { isError } from "jito-ts/dist/sdk/block-engine/utils"; 16 | 17 | import dotenv from "dotenv"; 18 | dotenv.config(); 19 | 20 | const JITO_AUTH_KEYPAIR = process.env.JITO_AUTH_KEYPAIR || ""; 21 | const BLOCK_ENGINE_URL = process.env.BLOCK_ENGINE_URL || ""; 22 | const JITO_FEE = process.env.JITO_FEE || ""; 23 | 24 | export async function bundle( 25 | txs: VersionedTransaction[], 26 | keypair: Keypair, 27 | connection: Connection 28 | ) { 29 | try { 30 | const txNum = Math.ceil(txs.length / 3); 31 | let successNum = 0; 32 | 33 | for (let i = 0; i < txNum; i++) { 34 | const upperIndex = (i + 1) * 3; 35 | const downIndex = i * 3; 36 | const newTxs = []; 37 | 38 | for (let j = downIndex; j < upperIndex; j++) { 39 | if (txs[j]) newTxs.push(txs[j]); 40 | } 41 | 42 | let success = await bull_dozer(newTxs, keypair, connection); 43 | 44 | if (success && success > 0) 45 | successNum += 1; 46 | } 47 | 48 | return successNum; 49 | } catch (error) { 50 | console.log(error); 51 | } 52 | return 0; 53 | } 54 | 55 | export async function bull_dozer( 56 | txs: VersionedTransaction[], 57 | keypair: Keypair, 58 | connection: Connection 59 | ) { 60 | try { 61 | // console.log("bull_dozer"); 62 | const bundleTransactionLimit = parseInt("4"); 63 | 64 | const jito_auth_keypair_array = JITO_AUTH_KEYPAIR.split(","); 65 | const keyapair_num = Math.floor( 66 | Math.random() * jito_auth_keypair_array.length 67 | ); 68 | const jito_auth_keypair = jito_auth_keypair_array[keyapair_num]; 69 | const jitoKey = Keypair.fromSecretKey(base58.decode(jito_auth_keypair)); 70 | // console.log("jitoKey", jitoKey); 71 | 72 | const blockengine_url_array = BLOCK_ENGINE_URL.split(","); 73 | const blockengine_num = Math.floor( 74 | Math.random() * blockengine_url_array.length 75 | ); 76 | const blockengine_url = blockengine_url_array[blockengine_num]; 77 | // console.log("blockengine_url", blockengine_url); 78 | const search = searcherClient(blockengine_url, jitoKey); 79 | 80 | const txid = base58.encode(txs[0].signatures[0]); 81 | 82 | const ret = await build_bundle( 83 | search, 84 | bundleTransactionLimit, 85 | txs, 86 | keypair, 87 | connection 88 | ); 89 | 90 | if (ret == null) return 0; 91 | 92 | const bundleId = ret 93 | if(bundleId instanceof Bundle){ 94 | console.log("error getting bundle id") 95 | return 96 | } 97 | 98 | // const bundle_result = await onBundleResult(search, txid, bundleId, connection); 99 | // return bundle_result; 100 | 101 | const latestBlockhash = await connection.getLatestBlockhash("confirmed"); 102 | 103 | const confirmed = await connection.confirmTransaction({ 104 | signature: txid, 105 | blockhash: latestBlockhash.blockhash, 106 | lastValidBlockHeight: latestBlockhash.lastValidBlockHeight 107 | }, "confirmed"); 108 | 109 | if (confirmed.value.err) 110 | return 0; 111 | 112 | txs.map((tx) => console.log(`TX Confirmed: https://solscan.io/tx/${base58.encode(tx.signatures[0])}`)); 113 | 114 | return 1; 115 | } catch (error) { 116 | console.log(error); 117 | } 118 | return 0; 119 | } 120 | 121 | async function build_bundle( 122 | search: SearcherClient, 123 | bundleTransactionLimit: number, 124 | txs: VersionedTransaction[], 125 | keypair: Keypair, 126 | connection: Connection 127 | ) { 128 | const accounts = await search.getTipAccounts(); 129 | // console.log("tip account:", accounts); 130 | const _tipAccount = 131 | accounts[Math.min(Math.floor(Math.random() * accounts.length), 3)]; 132 | const tipAccount = new PublicKey(_tipAccount); 133 | 134 | const bund = new Bundle([], bundleTransactionLimit); 135 | const resp = await connection.getLatestBlockhash("confirmed"); 136 | bund.addTransactions(...txs); 137 | 138 | const maybeBundle = bund.addTipTx( 139 | keypair, 140 | Number(JITO_FEE), 141 | tipAccount, 142 | resp.blockhash 143 | ); 144 | // console.log({ maybeBundle }); 145 | 146 | if (isError(maybeBundle)) { 147 | throw maybeBundle; 148 | } 149 | 150 | try { 151 | const result = await search.sendBundle(maybeBundle); 152 | 153 | console.log(`bundle: https://explorer.jito.wtf/bundle/${result}`); 154 | 155 | return result 156 | } catch (e) { 157 | console.log(e); 158 | console.log("error in sending bundle\n"); 159 | } 160 | 161 | return maybeBundle; 162 | } 163 | 164 | export const onBundleResult = ( 165 | c: SearcherClient, 166 | txSig: string, 167 | targetBundleId: string, 168 | connection: Connection): Promise => { 169 | 170 | 171 | return new Promise((resolve) => { 172 | 173 | let state = 0; 174 | let isResolved = false; 175 | 176 | //tx signature listener plz save my sanity 177 | let sigSubId = connection.onSignature(txSig, (res) => { 178 | if (isResolved) { 179 | connection.removeSignatureListener(sigSubId); 180 | return; 181 | } 182 | if (!res.err) { 183 | isResolved = true 184 | console.log(`TX Confirmed: https://solscan.io/tx/${txSig}`); 185 | resolve(1); 186 | } 187 | }, 'confirmed'); 188 | 189 | 190 | //SUPER FUCKING BUGGY LISTENER HOLY FUCK I HATE THIS SOO MCUH 191 | const listener = c.onBundleResult( 192 | //@ts-ignore 193 | (result) => { 194 | if (isResolved) return state; 195 | 196 | 197 | const bundleId = result.bundleId; 198 | const isAccepted = result.accepted; 199 | const isRejected = result.rejected; 200 | 201 | if (targetBundleId != bundleId) { return 0 } 202 | 203 | //if (bundleId == targetBundleId) 204 | 205 | if (isResolved == false) { 206 | 207 | if (isAccepted) { 208 | 209 | console.log("bundle accepted, ID:", bundleId, 210 | " Slot: ", result?.accepted?.slot); 211 | state += 1; 212 | isResolved = true; 213 | resolve(state); // Resolve with 'first' when a bundle is accepted 214 | return 0 215 | } 216 | 217 | if (isRejected) { 218 | console.log('Failed to send Bundle.'); 219 | isResolved = true; 220 | 221 | if (isRejected.simulationFailure) { 222 | if (isRejected.simulationFailure.msg?.toLowerCase().includes('partially') || isRejected.simulationFailure.msg?.toLowerCase().includes('been processed')) { 223 | resolve(1); 224 | return 0 225 | } 226 | const details = isRejected.simulationFailure.msg ?? ''; 227 | console.log(details); 228 | //addBundleErrorEntry('Simulation Failure', details, { bundleId: bundleId }) 229 | } 230 | 231 | if (isRejected.internalError) { 232 | if (isRejected.internalError.msg?.toLowerCase().includes('partially')) { 233 | resolve(1); 234 | return 0 235 | } 236 | const details = isRejected.internalError.msg ?? ''; 237 | console.log(details); 238 | //addBundleErrorEntry('Internal Error', details, { bundleId: bundleId }) 239 | } 240 | 241 | if (isRejected.stateAuctionBidRejected) { 242 | if (isRejected.stateAuctionBidRejected.msg?.toLowerCase().includes('partially')) { 243 | resolve(1); 244 | return 0 245 | } 246 | const details = isRejected.stateAuctionBidRejected.msg ?? ''; 247 | console.log(details); 248 | //addBundleErrorEntry('State Auction Bid Rejected', details, { bundleId: bundleId }) 249 | } 250 | 251 | if (isRejected.droppedBundle) { 252 | if (isRejected.droppedBundle.msg?.toLowerCase().includes('partially') || isRejected.droppedBundle.msg?.toLowerCase().includes('been processed')) { 253 | resolve(1); 254 | return 0 255 | } 256 | const details = isRejected.droppedBundle.msg ?? ''; 257 | console.log(details); 258 | //addBundleErrorEntry('Dropped Bundle', details, { bundleId: bundleId }) 259 | } 260 | 261 | if (isRejected.winningBatchBidRejected) { 262 | if (isRejected.winningBatchBidRejected.msg?.toLowerCase().includes('partially')) { 263 | resolve(1); 264 | return 0 265 | } 266 | const details = isRejected.winningBatchBidRejected.msg ?? ''; 267 | console.log(details); 268 | //addBundleErrorEntry('Winning Batch Bid Rejected', details, { bundleId: bundleId }) 269 | } 270 | resolve(state); 271 | } 272 | } 273 | }, 274 | (e) => { 275 | //resolve([state, listener]); 276 | //console.error(chalk.red(e)); 277 | console.log('error in bundle sub', e); 278 | resolve(state); 279 | } 280 | ); 281 | 282 | setTimeout(() => { 283 | resolve(state); 284 | isResolved = true 285 | }, 35000); 286 | }); 287 | }; 288 | 289 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aead" 7 | version = "0.4.3" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" 10 | dependencies = [ 11 | "generic-array", 12 | ] 13 | 14 | [[package]] 15 | name = "aes" 16 | version = "0.7.5" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" 19 | dependencies = [ 20 | "cfg-if", 21 | "cipher", 22 | "cpufeatures", 23 | "opaque-debug", 24 | ] 25 | 26 | [[package]] 27 | name = "aes-gcm-siv" 28 | version = "0.10.3" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "589c637f0e68c877bbd59a4599bbe849cac8e5f3e4b5a3ebae8f528cd218dcdc" 31 | dependencies = [ 32 | "aead", 33 | "aes", 34 | "cipher", 35 | "ctr", 36 | "polyval", 37 | "subtle", 38 | "zeroize", 39 | ] 40 | 41 | [[package]] 42 | name = "ahash" 43 | version = "0.7.8" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" 46 | dependencies = [ 47 | "getrandom 0.2.15", 48 | "once_cell", 49 | "version_check", 50 | ] 51 | 52 | [[package]] 53 | name = "ahash" 54 | version = "0.8.11" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" 57 | dependencies = [ 58 | "cfg-if", 59 | "once_cell", 60 | "version_check", 61 | "zerocopy", 62 | ] 63 | 64 | [[package]] 65 | name = "aho-corasick" 66 | version = "1.1.3" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 69 | dependencies = [ 70 | "memchr", 71 | ] 72 | 73 | [[package]] 74 | name = "anchor-attribute-access-control" 75 | version = "0.30.0" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "dd7368e171b3a317885dc08ec0f74eed9d0ad6c726cc819593aed81440dca926" 78 | dependencies = [ 79 | "anchor-syn", 80 | "proc-macro2", 81 | "quote", 82 | "syn 1.0.109", 83 | ] 84 | 85 | [[package]] 86 | name = "anchor-attribute-account" 87 | version = "0.30.0" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "f527df85a8cba3f2bea04e46ed71b66e525ea378c7fec538aa205f4520b73e31" 90 | dependencies = [ 91 | "anchor-syn", 92 | "bs58 0.5.1", 93 | "proc-macro2", 94 | "quote", 95 | "syn 1.0.109", 96 | ] 97 | 98 | [[package]] 99 | name = "anchor-attribute-constant" 100 | version = "0.30.0" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "3eb1dc1845cf8636c2e046a274ca074dabd3884ac8ed11cc4ed64b7e8ef5a318" 103 | dependencies = [ 104 | "anchor-syn", 105 | "quote", 106 | "syn 1.0.109", 107 | ] 108 | 109 | [[package]] 110 | name = "anchor-attribute-error" 111 | version = "0.30.0" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "7f382e41514c59a77ffa7bb1a47df9a0359564a749b6934485c742c11962e540" 114 | dependencies = [ 115 | "anchor-syn", 116 | "quote", 117 | "syn 1.0.109", 118 | ] 119 | 120 | [[package]] 121 | name = "anchor-attribute-event" 122 | version = "0.30.0" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "473a122aeed3f6b666438236338d2ef7833ee5fdc5688e1baa80185d61088a53" 125 | dependencies = [ 126 | "anchor-syn", 127 | "proc-macro2", 128 | "quote", 129 | "syn 1.0.109", 130 | ] 131 | 132 | [[package]] 133 | name = "anchor-attribute-program" 134 | version = "0.30.0" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "7f88c7ffe2eb40aeac43ffd0d74a6671581158aedfaa0552330a2ef92fa5c889" 137 | dependencies = [ 138 | "anchor-lang-idl", 139 | "anchor-syn", 140 | "anyhow", 141 | "bs58 0.5.1", 142 | "heck", 143 | "proc-macro2", 144 | "quote", 145 | "serde_json", 146 | "syn 1.0.109", 147 | ] 148 | 149 | [[package]] 150 | name = "anchor-derive-accounts" 151 | version = "0.30.0" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "ed9b97c99dcec135aae0ff908c14bcfcd3e78cfc16a0c6f245135038f0e6d390" 154 | dependencies = [ 155 | "anchor-syn", 156 | "quote", 157 | "syn 1.0.109", 158 | ] 159 | 160 | [[package]] 161 | name = "anchor-derive-serde" 162 | version = "0.30.0" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "bbece98f6ad9c37070edc0841326c9623a249346cd74f433e7cef69b14f7f31d" 165 | dependencies = [ 166 | "anchor-syn", 167 | "borsh-derive-internal 0.10.3", 168 | "proc-macro2", 169 | "quote", 170 | "syn 1.0.109", 171 | ] 172 | 173 | [[package]] 174 | name = "anchor-derive-space" 175 | version = "0.30.0" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "8badbe2648bc99a85ee05a7a5f9512e5e2af8ffac71476a69350cb278057ac53" 178 | dependencies = [ 179 | "proc-macro2", 180 | "quote", 181 | "syn 1.0.109", 182 | ] 183 | 184 | [[package]] 185 | name = "anchor-lang" 186 | version = "0.30.0" 187 | source = "registry+https://github.com/rust-lang/crates.io-index" 188 | checksum = "e41feb9c1cd9f4b0fad1c004fc8f289183f3ce27e9db38fa6e434470c716fb1e" 189 | dependencies = [ 190 | "anchor-attribute-access-control", 191 | "anchor-attribute-account", 192 | "anchor-attribute-constant", 193 | "anchor-attribute-error", 194 | "anchor-attribute-event", 195 | "anchor-attribute-program", 196 | "anchor-derive-accounts", 197 | "anchor-derive-serde", 198 | "anchor-derive-space", 199 | "anchor-lang-idl", 200 | "arrayref", 201 | "base64 0.21.7", 202 | "bincode", 203 | "borsh 0.10.3", 204 | "bytemuck", 205 | "getrandom 0.2.15", 206 | "solana-program", 207 | "thiserror", 208 | ] 209 | 210 | [[package]] 211 | name = "anchor-lang-idl" 212 | version = "0.1.0" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "b29da81eae478b1bb846749b06b8a2cb9c6f9ed26ca793b0c916793fdf36adab" 215 | dependencies = [ 216 | "anchor-syn", 217 | "anyhow", 218 | "regex", 219 | "serde", 220 | "serde_json", 221 | ] 222 | 223 | [[package]] 224 | name = "anchor-spl" 225 | version = "0.30.0" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "0dcee54a30b27ea8317ca647759b5d9701a8c7caaaa0c922c6d3c306a7278a7a" 228 | dependencies = [ 229 | "anchor-lang", 230 | "spl-associated-token-account", 231 | "spl-pod", 232 | "spl-token", 233 | "spl-token-2022", 234 | "spl-token-group-interface", 235 | "spl-token-metadata-interface", 236 | ] 237 | 238 | [[package]] 239 | name = "anchor-syn" 240 | version = "0.30.0" 241 | source = "registry+https://github.com/rust-lang/crates.io-index" 242 | checksum = "ac53f2378bc08e89e20c2b893c01986ffd34cfbc69a17e35bd6f754753e9fdad" 243 | dependencies = [ 244 | "anyhow", 245 | "bs58 0.5.1", 246 | "cargo_toml", 247 | "heck", 248 | "proc-macro2", 249 | "quote", 250 | "serde", 251 | "serde_json", 252 | "sha2 0.10.8", 253 | "syn 1.0.109", 254 | "thiserror", 255 | ] 256 | 257 | [[package]] 258 | name = "anyhow" 259 | version = "1.0.86" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" 262 | 263 | [[package]] 264 | name = "ark-bn254" 265 | version = "0.4.0" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" 268 | dependencies = [ 269 | "ark-ec", 270 | "ark-ff", 271 | "ark-std", 272 | ] 273 | 274 | [[package]] 275 | name = "ark-ec" 276 | version = "0.4.2" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" 279 | dependencies = [ 280 | "ark-ff", 281 | "ark-poly", 282 | "ark-serialize", 283 | "ark-std", 284 | "derivative", 285 | "hashbrown 0.13.2", 286 | "itertools", 287 | "num-traits", 288 | "zeroize", 289 | ] 290 | 291 | [[package]] 292 | name = "ark-ff" 293 | version = "0.4.2" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" 296 | dependencies = [ 297 | "ark-ff-asm", 298 | "ark-ff-macros", 299 | "ark-serialize", 300 | "ark-std", 301 | "derivative", 302 | "digest 0.10.7", 303 | "itertools", 304 | "num-bigint", 305 | "num-traits", 306 | "paste", 307 | "rustc_version", 308 | "zeroize", 309 | ] 310 | 311 | [[package]] 312 | name = "ark-ff-asm" 313 | version = "0.4.2" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" 316 | dependencies = [ 317 | "quote", 318 | "syn 1.0.109", 319 | ] 320 | 321 | [[package]] 322 | name = "ark-ff-macros" 323 | version = "0.4.2" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" 326 | dependencies = [ 327 | "num-bigint", 328 | "num-traits", 329 | "proc-macro2", 330 | "quote", 331 | "syn 1.0.109", 332 | ] 333 | 334 | [[package]] 335 | name = "ark-poly" 336 | version = "0.4.2" 337 | source = "registry+https://github.com/rust-lang/crates.io-index" 338 | checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" 339 | dependencies = [ 340 | "ark-ff", 341 | "ark-serialize", 342 | "ark-std", 343 | "derivative", 344 | "hashbrown 0.13.2", 345 | ] 346 | 347 | [[package]] 348 | name = "ark-serialize" 349 | version = "0.4.2" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" 352 | dependencies = [ 353 | "ark-serialize-derive", 354 | "ark-std", 355 | "digest 0.10.7", 356 | "num-bigint", 357 | ] 358 | 359 | [[package]] 360 | name = "ark-serialize-derive" 361 | version = "0.4.2" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" 364 | dependencies = [ 365 | "proc-macro2", 366 | "quote", 367 | "syn 1.0.109", 368 | ] 369 | 370 | [[package]] 371 | name = "ark-std" 372 | version = "0.4.0" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" 375 | dependencies = [ 376 | "num-traits", 377 | "rand 0.8.5", 378 | ] 379 | 380 | [[package]] 381 | name = "arrayref" 382 | version = "0.3.7" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" 385 | 386 | [[package]] 387 | name = "arrayvec" 388 | version = "0.7.4" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" 391 | 392 | [[package]] 393 | name = "assert_matches" 394 | version = "1.5.0" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" 397 | 398 | [[package]] 399 | name = "atty" 400 | version = "0.2.14" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 403 | dependencies = [ 404 | "hermit-abi", 405 | "libc", 406 | "winapi", 407 | ] 408 | 409 | [[package]] 410 | name = "autocfg" 411 | version = "1.3.0" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" 414 | 415 | [[package]] 416 | name = "base64" 417 | version = "0.12.3" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" 420 | 421 | [[package]] 422 | name = "base64" 423 | version = "0.21.7" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 426 | 427 | [[package]] 428 | name = "bincode" 429 | version = "1.3.3" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 432 | dependencies = [ 433 | "serde", 434 | ] 435 | 436 | [[package]] 437 | name = "bitflags" 438 | version = "2.5.0" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" 441 | dependencies = [ 442 | "serde", 443 | ] 444 | 445 | [[package]] 446 | name = "bitmaps" 447 | version = "2.1.0" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" 450 | dependencies = [ 451 | "typenum", 452 | ] 453 | 454 | [[package]] 455 | name = "blake3" 456 | version = "1.5.1" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" 459 | dependencies = [ 460 | "arrayref", 461 | "arrayvec", 462 | "cc", 463 | "cfg-if", 464 | "constant_time_eq", 465 | "digest 0.10.7", 466 | ] 467 | 468 | [[package]] 469 | name = "block-buffer" 470 | version = "0.9.0" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 473 | dependencies = [ 474 | "block-padding", 475 | "generic-array", 476 | ] 477 | 478 | [[package]] 479 | name = "block-buffer" 480 | version = "0.10.4" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 483 | dependencies = [ 484 | "generic-array", 485 | ] 486 | 487 | [[package]] 488 | name = "block-padding" 489 | version = "0.2.1" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" 492 | 493 | [[package]] 494 | name = "borsh" 495 | version = "0.9.3" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" 498 | dependencies = [ 499 | "borsh-derive 0.9.3", 500 | "hashbrown 0.11.2", 501 | ] 502 | 503 | [[package]] 504 | name = "borsh" 505 | version = "0.10.3" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" 508 | dependencies = [ 509 | "borsh-derive 0.10.3", 510 | "hashbrown 0.13.2", 511 | ] 512 | 513 | [[package]] 514 | name = "borsh" 515 | version = "1.5.0" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "dbe5b10e214954177fb1dc9fbd20a1a2608fe99e6c832033bdc7cea287a20d77" 518 | dependencies = [ 519 | "borsh-derive 1.5.0", 520 | "cfg_aliases", 521 | ] 522 | 523 | [[package]] 524 | name = "borsh-derive" 525 | version = "0.9.3" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" 528 | dependencies = [ 529 | "borsh-derive-internal 0.9.3", 530 | "borsh-schema-derive-internal 0.9.3", 531 | "proc-macro-crate 0.1.5", 532 | "proc-macro2", 533 | "syn 1.0.109", 534 | ] 535 | 536 | [[package]] 537 | name = "borsh-derive" 538 | version = "0.10.3" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" 541 | dependencies = [ 542 | "borsh-derive-internal 0.10.3", 543 | "borsh-schema-derive-internal 0.10.3", 544 | "proc-macro-crate 0.1.5", 545 | "proc-macro2", 546 | "syn 1.0.109", 547 | ] 548 | 549 | [[package]] 550 | name = "borsh-derive" 551 | version = "1.5.0" 552 | source = "registry+https://github.com/rust-lang/crates.io-index" 553 | checksum = "d7a8646f94ab393e43e8b35a2558b1624bed28b97ee09c5d15456e3c9463f46d" 554 | dependencies = [ 555 | "once_cell", 556 | "proc-macro-crate 3.1.0", 557 | "proc-macro2", 558 | "quote", 559 | "syn 2.0.66", 560 | "syn_derive", 561 | ] 562 | 563 | [[package]] 564 | name = "borsh-derive-internal" 565 | version = "0.9.3" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" 568 | dependencies = [ 569 | "proc-macro2", 570 | "quote", 571 | "syn 1.0.109", 572 | ] 573 | 574 | [[package]] 575 | name = "borsh-derive-internal" 576 | version = "0.10.3" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" 579 | dependencies = [ 580 | "proc-macro2", 581 | "quote", 582 | "syn 1.0.109", 583 | ] 584 | 585 | [[package]] 586 | name = "borsh-schema-derive-internal" 587 | version = "0.9.3" 588 | source = "registry+https://github.com/rust-lang/crates.io-index" 589 | checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" 590 | dependencies = [ 591 | "proc-macro2", 592 | "quote", 593 | "syn 1.0.109", 594 | ] 595 | 596 | [[package]] 597 | name = "borsh-schema-derive-internal" 598 | version = "0.10.3" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" 601 | dependencies = [ 602 | "proc-macro2", 603 | "quote", 604 | "syn 1.0.109", 605 | ] 606 | 607 | [[package]] 608 | name = "bs58" 609 | version = "0.4.0" 610 | source = "registry+https://github.com/rust-lang/crates.io-index" 611 | checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" 612 | 613 | [[package]] 614 | name = "bs58" 615 | version = "0.5.1" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" 618 | dependencies = [ 619 | "tinyvec", 620 | ] 621 | 622 | [[package]] 623 | name = "bumpalo" 624 | version = "3.16.0" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 627 | 628 | [[package]] 629 | name = "bv" 630 | version = "0.11.1" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" 633 | dependencies = [ 634 | "feature-probe", 635 | "serde", 636 | ] 637 | 638 | [[package]] 639 | name = "bytemuck" 640 | version = "1.16.0" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" 643 | dependencies = [ 644 | "bytemuck_derive", 645 | ] 646 | 647 | [[package]] 648 | name = "bytemuck_derive" 649 | version = "1.6.1" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | checksum = "369cfaf2a5bed5d8f8202073b2e093c9f508251de1551a0deb4253e4c7d80909" 652 | dependencies = [ 653 | "proc-macro2", 654 | "quote", 655 | "syn 2.0.66", 656 | ] 657 | 658 | [[package]] 659 | name = "byteorder" 660 | version = "1.5.0" 661 | source = "registry+https://github.com/rust-lang/crates.io-index" 662 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 663 | 664 | [[package]] 665 | name = "cargo_toml" 666 | version = "0.19.2" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "a98356df42a2eb1bd8f1793ae4ee4de48e384dd974ce5eac8eee802edb7492be" 669 | dependencies = [ 670 | "serde", 671 | "toml 0.8.13", 672 | ] 673 | 674 | [[package]] 675 | name = "cc" 676 | version = "1.0.98" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" 679 | dependencies = [ 680 | "jobserver", 681 | "libc", 682 | "once_cell", 683 | ] 684 | 685 | [[package]] 686 | name = "cfg-if" 687 | version = "1.0.0" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 690 | 691 | [[package]] 692 | name = "cfg_aliases" 693 | version = "0.1.1" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" 696 | 697 | [[package]] 698 | name = "chrono" 699 | version = "0.4.38" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" 702 | dependencies = [ 703 | "num-traits", 704 | ] 705 | 706 | [[package]] 707 | name = "cipher" 708 | version = "0.3.0" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" 711 | dependencies = [ 712 | "generic-array", 713 | ] 714 | 715 | [[package]] 716 | name = "console_error_panic_hook" 717 | version = "0.1.7" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" 720 | dependencies = [ 721 | "cfg-if", 722 | "wasm-bindgen", 723 | ] 724 | 725 | [[package]] 726 | name = "console_log" 727 | version = "0.2.2" 728 | source = "registry+https://github.com/rust-lang/crates.io-index" 729 | checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" 730 | dependencies = [ 731 | "log", 732 | "web-sys", 733 | ] 734 | 735 | [[package]] 736 | name = "constant_time_eq" 737 | version = "0.3.0" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" 740 | 741 | [[package]] 742 | name = "cpufeatures" 743 | version = "0.2.12" 744 | source = "registry+https://github.com/rust-lang/crates.io-index" 745 | checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" 746 | dependencies = [ 747 | "libc", 748 | ] 749 | 750 | [[package]] 751 | name = "crossbeam-deque" 752 | version = "0.8.5" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" 755 | dependencies = [ 756 | "crossbeam-epoch", 757 | "crossbeam-utils", 758 | ] 759 | 760 | [[package]] 761 | name = "crossbeam-epoch" 762 | version = "0.9.18" 763 | source = "registry+https://github.com/rust-lang/crates.io-index" 764 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 765 | dependencies = [ 766 | "crossbeam-utils", 767 | ] 768 | 769 | [[package]] 770 | name = "crossbeam-utils" 771 | version = "0.8.20" 772 | source = "registry+https://github.com/rust-lang/crates.io-index" 773 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 774 | 775 | [[package]] 776 | name = "crunchy" 777 | version = "0.2.2" 778 | source = "registry+https://github.com/rust-lang/crates.io-index" 779 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 780 | 781 | [[package]] 782 | name = "crypto-common" 783 | version = "0.1.6" 784 | source = "registry+https://github.com/rust-lang/crates.io-index" 785 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 786 | dependencies = [ 787 | "generic-array", 788 | "typenum", 789 | ] 790 | 791 | [[package]] 792 | name = "crypto-mac" 793 | version = "0.8.0" 794 | source = "registry+https://github.com/rust-lang/crates.io-index" 795 | checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" 796 | dependencies = [ 797 | "generic-array", 798 | "subtle", 799 | ] 800 | 801 | [[package]] 802 | name = "ctr" 803 | version = "0.8.0" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" 806 | dependencies = [ 807 | "cipher", 808 | ] 809 | 810 | [[package]] 811 | name = "curve25519-dalek" 812 | version = "3.2.1" 813 | source = "registry+https://github.com/rust-lang/crates.io-index" 814 | checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" 815 | dependencies = [ 816 | "byteorder", 817 | "digest 0.9.0", 818 | "rand_core 0.5.1", 819 | "serde", 820 | "subtle", 821 | "zeroize", 822 | ] 823 | 824 | [[package]] 825 | name = "darling" 826 | version = "0.20.9" 827 | source = "registry+https://github.com/rust-lang/crates.io-index" 828 | checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" 829 | dependencies = [ 830 | "darling_core", 831 | "darling_macro", 832 | ] 833 | 834 | [[package]] 835 | name = "darling_core" 836 | version = "0.20.9" 837 | source = "registry+https://github.com/rust-lang/crates.io-index" 838 | checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" 839 | dependencies = [ 840 | "fnv", 841 | "ident_case", 842 | "proc-macro2", 843 | "quote", 844 | "strsim", 845 | "syn 2.0.66", 846 | ] 847 | 848 | [[package]] 849 | name = "darling_macro" 850 | version = "0.20.9" 851 | source = "registry+https://github.com/rust-lang/crates.io-index" 852 | checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" 853 | dependencies = [ 854 | "darling_core", 855 | "quote", 856 | "syn 2.0.66", 857 | ] 858 | 859 | [[package]] 860 | name = "derivation-path" 861 | version = "0.2.0" 862 | source = "registry+https://github.com/rust-lang/crates.io-index" 863 | checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" 864 | 865 | [[package]] 866 | name = "derivative" 867 | version = "2.2.0" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 870 | dependencies = [ 871 | "proc-macro2", 872 | "quote", 873 | "syn 1.0.109", 874 | ] 875 | 876 | [[package]] 877 | name = "digest" 878 | version = "0.9.0" 879 | source = "registry+https://github.com/rust-lang/crates.io-index" 880 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 881 | dependencies = [ 882 | "generic-array", 883 | ] 884 | 885 | [[package]] 886 | name = "digest" 887 | version = "0.10.7" 888 | source = "registry+https://github.com/rust-lang/crates.io-index" 889 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 890 | dependencies = [ 891 | "block-buffer 0.10.4", 892 | "crypto-common", 893 | "subtle", 894 | ] 895 | 896 | [[package]] 897 | name = "dyn-clone" 898 | version = "1.0.17" 899 | source = "registry+https://github.com/rust-lang/crates.io-index" 900 | checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" 901 | 902 | [[package]] 903 | name = "ed25519" 904 | version = "1.5.3" 905 | source = "registry+https://github.com/rust-lang/crates.io-index" 906 | checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" 907 | dependencies = [ 908 | "signature", 909 | ] 910 | 911 | [[package]] 912 | name = "ed25519-dalek" 913 | version = "1.0.1" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" 916 | dependencies = [ 917 | "curve25519-dalek", 918 | "ed25519", 919 | "rand 0.7.3", 920 | "serde", 921 | "sha2 0.9.9", 922 | "zeroize", 923 | ] 924 | 925 | [[package]] 926 | name = "ed25519-dalek-bip32" 927 | version = "0.2.0" 928 | source = "registry+https://github.com/rust-lang/crates.io-index" 929 | checksum = "9d2be62a4061b872c8c0873ee4fc6f101ce7b889d039f019c5fa2af471a59908" 930 | dependencies = [ 931 | "derivation-path", 932 | "ed25519-dalek", 933 | "hmac 0.12.1", 934 | "sha2 0.10.8", 935 | ] 936 | 937 | [[package]] 938 | name = "either" 939 | version = "1.12.0" 940 | source = "registry+https://github.com/rust-lang/crates.io-index" 941 | checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" 942 | 943 | [[package]] 944 | name = "env_logger" 945 | version = "0.9.3" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" 948 | dependencies = [ 949 | "atty", 950 | "humantime", 951 | "log", 952 | "regex", 953 | "termcolor", 954 | ] 955 | 956 | [[package]] 957 | name = "equivalent" 958 | version = "1.0.1" 959 | source = "registry+https://github.com/rust-lang/crates.io-index" 960 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 961 | 962 | [[package]] 963 | name = "feature-probe" 964 | version = "0.1.1" 965 | source = "registry+https://github.com/rust-lang/crates.io-index" 966 | checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" 967 | 968 | [[package]] 969 | name = "fnv" 970 | version = "1.0.7" 971 | source = "registry+https://github.com/rust-lang/crates.io-index" 972 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 973 | 974 | [[package]] 975 | name = "generic-array" 976 | version = "0.14.7" 977 | source = "registry+https://github.com/rust-lang/crates.io-index" 978 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 979 | dependencies = [ 980 | "serde", 981 | "typenum", 982 | "version_check", 983 | ] 984 | 985 | [[package]] 986 | name = "getrandom" 987 | version = "0.1.16" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 990 | dependencies = [ 991 | "cfg-if", 992 | "js-sys", 993 | "libc", 994 | "wasi 0.9.0+wasi-snapshot-preview1", 995 | "wasm-bindgen", 996 | ] 997 | 998 | [[package]] 999 | name = "getrandom" 1000 | version = "0.2.15" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 1003 | dependencies = [ 1004 | "cfg-if", 1005 | "js-sys", 1006 | "libc", 1007 | "wasi 0.11.0+wasi-snapshot-preview1", 1008 | "wasm-bindgen", 1009 | ] 1010 | 1011 | [[package]] 1012 | name = "hashbrown" 1013 | version = "0.11.2" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 1016 | dependencies = [ 1017 | "ahash 0.7.8", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "hashbrown" 1022 | version = "0.13.2" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" 1025 | dependencies = [ 1026 | "ahash 0.8.11", 1027 | ] 1028 | 1029 | [[package]] 1030 | name = "hashbrown" 1031 | version = "0.14.5" 1032 | source = "registry+https://github.com/rust-lang/crates.io-index" 1033 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 1034 | 1035 | [[package]] 1036 | name = "heck" 1037 | version = "0.3.3" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 1040 | dependencies = [ 1041 | "unicode-segmentation", 1042 | ] 1043 | 1044 | [[package]] 1045 | name = "hermit-abi" 1046 | version = "0.1.19" 1047 | source = "registry+https://github.com/rust-lang/crates.io-index" 1048 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 1049 | dependencies = [ 1050 | "libc", 1051 | ] 1052 | 1053 | [[package]] 1054 | name = "hex" 1055 | version = "0.4.3" 1056 | source = "registry+https://github.com/rust-lang/crates.io-index" 1057 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 1058 | dependencies = [ 1059 | "serde", 1060 | ] 1061 | 1062 | [[package]] 1063 | name = "hmac" 1064 | version = "0.8.1" 1065 | source = "registry+https://github.com/rust-lang/crates.io-index" 1066 | checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" 1067 | dependencies = [ 1068 | "crypto-mac", 1069 | "digest 0.9.0", 1070 | ] 1071 | 1072 | [[package]] 1073 | name = "hmac" 1074 | version = "0.12.1" 1075 | source = "registry+https://github.com/rust-lang/crates.io-index" 1076 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 1077 | dependencies = [ 1078 | "digest 0.10.7", 1079 | ] 1080 | 1081 | [[package]] 1082 | name = "hmac-drbg" 1083 | version = "0.3.0" 1084 | source = "registry+https://github.com/rust-lang/crates.io-index" 1085 | checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" 1086 | dependencies = [ 1087 | "digest 0.9.0", 1088 | "generic-array", 1089 | "hmac 0.8.1", 1090 | ] 1091 | 1092 | [[package]] 1093 | name = "humantime" 1094 | version = "2.1.0" 1095 | source = "registry+https://github.com/rust-lang/crates.io-index" 1096 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 1097 | 1098 | [[package]] 1099 | name = "ident_case" 1100 | version = "1.0.1" 1101 | source = "registry+https://github.com/rust-lang/crates.io-index" 1102 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 1103 | 1104 | [[package]] 1105 | name = "im" 1106 | version = "15.1.0" 1107 | source = "registry+https://github.com/rust-lang/crates.io-index" 1108 | checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" 1109 | dependencies = [ 1110 | "bitmaps", 1111 | "rand_core 0.6.4", 1112 | "rand_xoshiro", 1113 | "rayon", 1114 | "serde", 1115 | "sized-chunks", 1116 | "typenum", 1117 | "version_check", 1118 | ] 1119 | 1120 | [[package]] 1121 | name = "indexmap" 1122 | version = "2.2.6" 1123 | source = "registry+https://github.com/rust-lang/crates.io-index" 1124 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 1125 | dependencies = [ 1126 | "equivalent", 1127 | "hashbrown 0.14.5", 1128 | ] 1129 | 1130 | [[package]] 1131 | name = "itertools" 1132 | version = "0.10.5" 1133 | source = "registry+https://github.com/rust-lang/crates.io-index" 1134 | checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" 1135 | dependencies = [ 1136 | "either", 1137 | ] 1138 | 1139 | [[package]] 1140 | name = "itoa" 1141 | version = "1.0.11" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 1144 | 1145 | [[package]] 1146 | name = "jobserver" 1147 | version = "0.1.31" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" 1150 | dependencies = [ 1151 | "libc", 1152 | ] 1153 | 1154 | [[package]] 1155 | name = "js-sys" 1156 | version = "0.3.69" 1157 | source = "registry+https://github.com/rust-lang/crates.io-index" 1158 | checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" 1159 | dependencies = [ 1160 | "wasm-bindgen", 1161 | ] 1162 | 1163 | [[package]] 1164 | name = "keccak" 1165 | version = "0.1.5" 1166 | source = "registry+https://github.com/rust-lang/crates.io-index" 1167 | checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" 1168 | dependencies = [ 1169 | "cpufeatures", 1170 | ] 1171 | 1172 | [[package]] 1173 | name = "lazy_static" 1174 | version = "1.4.0" 1175 | source = "registry+https://github.com/rust-lang/crates.io-index" 1176 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1177 | 1178 | [[package]] 1179 | name = "libc" 1180 | version = "0.2.155" 1181 | source = "registry+https://github.com/rust-lang/crates.io-index" 1182 | checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" 1183 | 1184 | [[package]] 1185 | name = "libsecp256k1" 1186 | version = "0.6.0" 1187 | source = "registry+https://github.com/rust-lang/crates.io-index" 1188 | checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" 1189 | dependencies = [ 1190 | "arrayref", 1191 | "base64 0.12.3", 1192 | "digest 0.9.0", 1193 | "hmac-drbg", 1194 | "libsecp256k1-core", 1195 | "libsecp256k1-gen-ecmult", 1196 | "libsecp256k1-gen-genmult", 1197 | "rand 0.7.3", 1198 | "serde", 1199 | "sha2 0.9.9", 1200 | "typenum", 1201 | ] 1202 | 1203 | [[package]] 1204 | name = "libsecp256k1-core" 1205 | version = "0.2.2" 1206 | source = "registry+https://github.com/rust-lang/crates.io-index" 1207 | checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" 1208 | dependencies = [ 1209 | "crunchy", 1210 | "digest 0.9.0", 1211 | "subtle", 1212 | ] 1213 | 1214 | [[package]] 1215 | name = "libsecp256k1-gen-ecmult" 1216 | version = "0.2.1" 1217 | source = "registry+https://github.com/rust-lang/crates.io-index" 1218 | checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" 1219 | dependencies = [ 1220 | "libsecp256k1-core", 1221 | ] 1222 | 1223 | [[package]] 1224 | name = "libsecp256k1-gen-genmult" 1225 | version = "0.2.1" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" 1228 | dependencies = [ 1229 | "libsecp256k1-core", 1230 | ] 1231 | 1232 | [[package]] 1233 | name = "light-poseidon" 1234 | version = "0.2.0" 1235 | source = "registry+https://github.com/rust-lang/crates.io-index" 1236 | checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" 1237 | dependencies = [ 1238 | "ark-bn254", 1239 | "ark-ff", 1240 | "num-bigint", 1241 | "thiserror", 1242 | ] 1243 | 1244 | [[package]] 1245 | name = "lock_api" 1246 | version = "0.4.12" 1247 | source = "registry+https://github.com/rust-lang/crates.io-index" 1248 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 1249 | dependencies = [ 1250 | "autocfg", 1251 | "scopeguard", 1252 | ] 1253 | 1254 | [[package]] 1255 | name = "log" 1256 | version = "0.4.21" 1257 | source = "registry+https://github.com/rust-lang/crates.io-index" 1258 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 1259 | 1260 | [[package]] 1261 | name = "memchr" 1262 | version = "2.7.2" 1263 | source = "registry+https://github.com/rust-lang/crates.io-index" 1264 | checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" 1265 | 1266 | [[package]] 1267 | name = "memmap2" 1268 | version = "0.5.10" 1269 | source = "registry+https://github.com/rust-lang/crates.io-index" 1270 | checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" 1271 | dependencies = [ 1272 | "libc", 1273 | ] 1274 | 1275 | [[package]] 1276 | name = "memoffset" 1277 | version = "0.9.1" 1278 | source = "registry+https://github.com/rust-lang/crates.io-index" 1279 | checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" 1280 | dependencies = [ 1281 | "autocfg", 1282 | ] 1283 | 1284 | [[package]] 1285 | name = "merlin" 1286 | version = "3.0.0" 1287 | source = "registry+https://github.com/rust-lang/crates.io-index" 1288 | checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" 1289 | dependencies = [ 1290 | "byteorder", 1291 | "keccak", 1292 | "rand_core 0.6.4", 1293 | "zeroize", 1294 | ] 1295 | 1296 | [[package]] 1297 | name = "num-bigint" 1298 | version = "0.4.5" 1299 | source = "registry+https://github.com/rust-lang/crates.io-index" 1300 | checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" 1301 | dependencies = [ 1302 | "num-integer", 1303 | "num-traits", 1304 | ] 1305 | 1306 | [[package]] 1307 | name = "num-derive" 1308 | version = "0.3.3" 1309 | source = "registry+https://github.com/rust-lang/crates.io-index" 1310 | checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" 1311 | dependencies = [ 1312 | "proc-macro2", 1313 | "quote", 1314 | "syn 1.0.109", 1315 | ] 1316 | 1317 | [[package]] 1318 | name = "num-derive" 1319 | version = "0.4.2" 1320 | source = "registry+https://github.com/rust-lang/crates.io-index" 1321 | checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" 1322 | dependencies = [ 1323 | "proc-macro2", 1324 | "quote", 1325 | "syn 2.0.66", 1326 | ] 1327 | 1328 | [[package]] 1329 | name = "num-integer" 1330 | version = "0.1.46" 1331 | source = "registry+https://github.com/rust-lang/crates.io-index" 1332 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 1333 | dependencies = [ 1334 | "num-traits", 1335 | ] 1336 | 1337 | [[package]] 1338 | name = "num-traits" 1339 | version = "0.2.19" 1340 | source = "registry+https://github.com/rust-lang/crates.io-index" 1341 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1342 | dependencies = [ 1343 | "autocfg", 1344 | ] 1345 | 1346 | [[package]] 1347 | name = "num_enum" 1348 | version = "0.7.2" 1349 | source = "registry+https://github.com/rust-lang/crates.io-index" 1350 | checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" 1351 | dependencies = [ 1352 | "num_enum_derive", 1353 | ] 1354 | 1355 | [[package]] 1356 | name = "num_enum_derive" 1357 | version = "0.7.2" 1358 | source = "registry+https://github.com/rust-lang/crates.io-index" 1359 | checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" 1360 | dependencies = [ 1361 | "proc-macro-crate 3.1.0", 1362 | "proc-macro2", 1363 | "quote", 1364 | "syn 2.0.66", 1365 | ] 1366 | 1367 | [[package]] 1368 | name = "once_cell" 1369 | version = "1.19.0" 1370 | source = "registry+https://github.com/rust-lang/crates.io-index" 1371 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 1372 | 1373 | [[package]] 1374 | name = "opaque-debug" 1375 | version = "0.3.1" 1376 | source = "registry+https://github.com/rust-lang/crates.io-index" 1377 | checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" 1378 | 1379 | [[package]] 1380 | name = "parking_lot" 1381 | version = "0.12.3" 1382 | source = "registry+https://github.com/rust-lang/crates.io-index" 1383 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1384 | dependencies = [ 1385 | "lock_api", 1386 | "parking_lot_core", 1387 | ] 1388 | 1389 | [[package]] 1390 | name = "parking_lot_core" 1391 | version = "0.9.10" 1392 | source = "registry+https://github.com/rust-lang/crates.io-index" 1393 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1394 | dependencies = [ 1395 | "cfg-if", 1396 | "libc", 1397 | "redox_syscall", 1398 | "smallvec", 1399 | "windows-targets", 1400 | ] 1401 | 1402 | [[package]] 1403 | name = "paste" 1404 | version = "1.0.15" 1405 | source = "registry+https://github.com/rust-lang/crates.io-index" 1406 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 1407 | 1408 | [[package]] 1409 | name = "pbkdf2" 1410 | version = "0.4.0" 1411 | source = "registry+https://github.com/rust-lang/crates.io-index" 1412 | checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" 1413 | dependencies = [ 1414 | "crypto-mac", 1415 | ] 1416 | 1417 | [[package]] 1418 | name = "pbkdf2" 1419 | version = "0.11.0" 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" 1421 | checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" 1422 | dependencies = [ 1423 | "digest 0.10.7", 1424 | ] 1425 | 1426 | [[package]] 1427 | name = "percent-encoding" 1428 | version = "2.3.1" 1429 | source = "registry+https://github.com/rust-lang/crates.io-index" 1430 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1431 | 1432 | [[package]] 1433 | name = "polyval" 1434 | version = "0.5.3" 1435 | source = "registry+https://github.com/rust-lang/crates.io-index" 1436 | checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" 1437 | dependencies = [ 1438 | "cfg-if", 1439 | "cpufeatures", 1440 | "opaque-debug", 1441 | "universal-hash", 1442 | ] 1443 | 1444 | [[package]] 1445 | name = "ppv-lite86" 1446 | version = "0.2.17" 1447 | source = "registry+https://github.com/rust-lang/crates.io-index" 1448 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1449 | 1450 | [[package]] 1451 | name = "presale" 1452 | version = "0.1.0" 1453 | dependencies = [ 1454 | "anchor-lang", 1455 | "anchor-spl", 1456 | "pyth-sdk-solana", 1457 | "solana-program", 1458 | ] 1459 | 1460 | [[package]] 1461 | name = "proc-macro-crate" 1462 | version = "0.1.5" 1463 | source = "registry+https://github.com/rust-lang/crates.io-index" 1464 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" 1465 | dependencies = [ 1466 | "toml 0.5.11", 1467 | ] 1468 | 1469 | [[package]] 1470 | name = "proc-macro-crate" 1471 | version = "3.1.0" 1472 | source = "registry+https://github.com/rust-lang/crates.io-index" 1473 | checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" 1474 | dependencies = [ 1475 | "toml_edit 0.21.1", 1476 | ] 1477 | 1478 | [[package]] 1479 | name = "proc-macro-error" 1480 | version = "1.0.4" 1481 | source = "registry+https://github.com/rust-lang/crates.io-index" 1482 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 1483 | dependencies = [ 1484 | "proc-macro-error-attr", 1485 | "proc-macro2", 1486 | "quote", 1487 | "version_check", 1488 | ] 1489 | 1490 | [[package]] 1491 | name = "proc-macro-error-attr" 1492 | version = "1.0.4" 1493 | source = "registry+https://github.com/rust-lang/crates.io-index" 1494 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 1495 | dependencies = [ 1496 | "proc-macro2", 1497 | "quote", 1498 | "version_check", 1499 | ] 1500 | 1501 | [[package]] 1502 | name = "proc-macro2" 1503 | version = "1.0.83" 1504 | source = "registry+https://github.com/rust-lang/crates.io-index" 1505 | checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" 1506 | dependencies = [ 1507 | "unicode-ident", 1508 | ] 1509 | 1510 | [[package]] 1511 | name = "pyth-sdk" 1512 | version = "0.8.0" 1513 | source = "registry+https://github.com/rust-lang/crates.io-index" 1514 | checksum = "1e7aeef4d5f0a9c98ff5af2ddd84a8b89919c512188305b497a9eb9afa97a949" 1515 | dependencies = [ 1516 | "borsh 0.10.3", 1517 | "borsh-derive 0.10.3", 1518 | "getrandom 0.2.15", 1519 | "hex", 1520 | "schemars", 1521 | "serde", 1522 | ] 1523 | 1524 | [[package]] 1525 | name = "pyth-sdk-solana" 1526 | version = "0.10.1" 1527 | source = "registry+https://github.com/rust-lang/crates.io-index" 1528 | checksum = "7f913de6eb29d8def199af3beaee645e84c5281327d58777eff3fdd9f1d37105" 1529 | dependencies = [ 1530 | "borsh 0.10.3", 1531 | "borsh-derive 0.10.3", 1532 | "bytemuck", 1533 | "num-derive 0.3.3", 1534 | "num-traits", 1535 | "pyth-sdk", 1536 | "serde", 1537 | "solana-program", 1538 | "thiserror", 1539 | ] 1540 | 1541 | [[package]] 1542 | name = "qstring" 1543 | version = "0.7.2" 1544 | source = "registry+https://github.com/rust-lang/crates.io-index" 1545 | checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" 1546 | dependencies = [ 1547 | "percent-encoding", 1548 | ] 1549 | 1550 | [[package]] 1551 | name = "qualifier_attr" 1552 | version = "0.2.2" 1553 | source = "registry+https://github.com/rust-lang/crates.io-index" 1554 | checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" 1555 | dependencies = [ 1556 | "proc-macro2", 1557 | "quote", 1558 | "syn 2.0.66", 1559 | ] 1560 | 1561 | [[package]] 1562 | name = "quote" 1563 | version = "1.0.36" 1564 | source = "registry+https://github.com/rust-lang/crates.io-index" 1565 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 1566 | dependencies = [ 1567 | "proc-macro2", 1568 | ] 1569 | 1570 | [[package]] 1571 | name = "rand" 1572 | version = "0.7.3" 1573 | source = "registry+https://github.com/rust-lang/crates.io-index" 1574 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 1575 | dependencies = [ 1576 | "getrandom 0.1.16", 1577 | "libc", 1578 | "rand_chacha 0.2.2", 1579 | "rand_core 0.5.1", 1580 | "rand_hc", 1581 | ] 1582 | 1583 | [[package]] 1584 | name = "rand" 1585 | version = "0.8.5" 1586 | source = "registry+https://github.com/rust-lang/crates.io-index" 1587 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1588 | dependencies = [ 1589 | "libc", 1590 | "rand_chacha 0.3.1", 1591 | "rand_core 0.6.4", 1592 | ] 1593 | 1594 | [[package]] 1595 | name = "rand_chacha" 1596 | version = "0.2.2" 1597 | source = "registry+https://github.com/rust-lang/crates.io-index" 1598 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 1599 | dependencies = [ 1600 | "ppv-lite86", 1601 | "rand_core 0.5.1", 1602 | ] 1603 | 1604 | [[package]] 1605 | name = "rand_chacha" 1606 | version = "0.3.1" 1607 | source = "registry+https://github.com/rust-lang/crates.io-index" 1608 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1609 | dependencies = [ 1610 | "ppv-lite86", 1611 | "rand_core 0.6.4", 1612 | ] 1613 | 1614 | [[package]] 1615 | name = "rand_core" 1616 | version = "0.5.1" 1617 | source = "registry+https://github.com/rust-lang/crates.io-index" 1618 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1619 | dependencies = [ 1620 | "getrandom 0.1.16", 1621 | ] 1622 | 1623 | [[package]] 1624 | name = "rand_core" 1625 | version = "0.6.4" 1626 | source = "registry+https://github.com/rust-lang/crates.io-index" 1627 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1628 | dependencies = [ 1629 | "getrandom 0.2.15", 1630 | ] 1631 | 1632 | [[package]] 1633 | name = "rand_hc" 1634 | version = "0.2.0" 1635 | source = "registry+https://github.com/rust-lang/crates.io-index" 1636 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1637 | dependencies = [ 1638 | "rand_core 0.5.1", 1639 | ] 1640 | 1641 | [[package]] 1642 | name = "rand_xoshiro" 1643 | version = "0.6.0" 1644 | source = "registry+https://github.com/rust-lang/crates.io-index" 1645 | checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" 1646 | dependencies = [ 1647 | "rand_core 0.6.4", 1648 | ] 1649 | 1650 | [[package]] 1651 | name = "rayon" 1652 | version = "1.10.0" 1653 | source = "registry+https://github.com/rust-lang/crates.io-index" 1654 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" 1655 | dependencies = [ 1656 | "either", 1657 | "rayon-core", 1658 | ] 1659 | 1660 | [[package]] 1661 | name = "rayon-core" 1662 | version = "1.12.1" 1663 | source = "registry+https://github.com/rust-lang/crates.io-index" 1664 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" 1665 | dependencies = [ 1666 | "crossbeam-deque", 1667 | "crossbeam-utils", 1668 | ] 1669 | 1670 | [[package]] 1671 | name = "redox_syscall" 1672 | version = "0.5.1" 1673 | source = "registry+https://github.com/rust-lang/crates.io-index" 1674 | checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" 1675 | dependencies = [ 1676 | "bitflags", 1677 | ] 1678 | 1679 | [[package]] 1680 | name = "regex" 1681 | version = "1.10.4" 1682 | source = "registry+https://github.com/rust-lang/crates.io-index" 1683 | checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" 1684 | dependencies = [ 1685 | "aho-corasick", 1686 | "memchr", 1687 | "regex-automata", 1688 | "regex-syntax", 1689 | ] 1690 | 1691 | [[package]] 1692 | name = "regex-automata" 1693 | version = "0.4.6" 1694 | source = "registry+https://github.com/rust-lang/crates.io-index" 1695 | checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" 1696 | dependencies = [ 1697 | "aho-corasick", 1698 | "memchr", 1699 | "regex-syntax", 1700 | ] 1701 | 1702 | [[package]] 1703 | name = "regex-syntax" 1704 | version = "0.8.3" 1705 | source = "registry+https://github.com/rust-lang/crates.io-index" 1706 | checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" 1707 | 1708 | [[package]] 1709 | name = "rustc-hash" 1710 | version = "1.1.0" 1711 | source = "registry+https://github.com/rust-lang/crates.io-index" 1712 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1713 | 1714 | [[package]] 1715 | name = "rustc_version" 1716 | version = "0.4.0" 1717 | source = "registry+https://github.com/rust-lang/crates.io-index" 1718 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1719 | dependencies = [ 1720 | "semver", 1721 | ] 1722 | 1723 | [[package]] 1724 | name = "rustversion" 1725 | version = "1.0.17" 1726 | source = "registry+https://github.com/rust-lang/crates.io-index" 1727 | checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" 1728 | 1729 | [[package]] 1730 | name = "ryu" 1731 | version = "1.0.18" 1732 | source = "registry+https://github.com/rust-lang/crates.io-index" 1733 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 1734 | 1735 | [[package]] 1736 | name = "schemars" 1737 | version = "0.8.21" 1738 | source = "registry+https://github.com/rust-lang/crates.io-index" 1739 | checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" 1740 | dependencies = [ 1741 | "dyn-clone", 1742 | "schemars_derive", 1743 | "serde", 1744 | "serde_json", 1745 | ] 1746 | 1747 | [[package]] 1748 | name = "schemars_derive" 1749 | version = "0.8.21" 1750 | source = "registry+https://github.com/rust-lang/crates.io-index" 1751 | checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" 1752 | dependencies = [ 1753 | "proc-macro2", 1754 | "quote", 1755 | "serde_derive_internals", 1756 | "syn 2.0.66", 1757 | ] 1758 | 1759 | [[package]] 1760 | name = "scopeguard" 1761 | version = "1.2.0" 1762 | source = "registry+https://github.com/rust-lang/crates.io-index" 1763 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1764 | 1765 | [[package]] 1766 | name = "semver" 1767 | version = "1.0.23" 1768 | source = "registry+https://github.com/rust-lang/crates.io-index" 1769 | checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" 1770 | 1771 | [[package]] 1772 | name = "serde" 1773 | version = "1.0.202" 1774 | source = "registry+https://github.com/rust-lang/crates.io-index" 1775 | checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" 1776 | dependencies = [ 1777 | "serde_derive", 1778 | ] 1779 | 1780 | [[package]] 1781 | name = "serde_bytes" 1782 | version = "0.11.14" 1783 | source = "registry+https://github.com/rust-lang/crates.io-index" 1784 | checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" 1785 | dependencies = [ 1786 | "serde", 1787 | ] 1788 | 1789 | [[package]] 1790 | name = "serde_derive" 1791 | version = "1.0.202" 1792 | source = "registry+https://github.com/rust-lang/crates.io-index" 1793 | checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" 1794 | dependencies = [ 1795 | "proc-macro2", 1796 | "quote", 1797 | "syn 2.0.66", 1798 | ] 1799 | 1800 | [[package]] 1801 | name = "serde_derive_internals" 1802 | version = "0.29.1" 1803 | source = "registry+https://github.com/rust-lang/crates.io-index" 1804 | checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" 1805 | dependencies = [ 1806 | "proc-macro2", 1807 | "quote", 1808 | "syn 2.0.66", 1809 | ] 1810 | 1811 | [[package]] 1812 | name = "serde_json" 1813 | version = "1.0.117" 1814 | source = "registry+https://github.com/rust-lang/crates.io-index" 1815 | checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" 1816 | dependencies = [ 1817 | "itoa", 1818 | "ryu", 1819 | "serde", 1820 | ] 1821 | 1822 | [[package]] 1823 | name = "serde_spanned" 1824 | version = "0.6.6" 1825 | source = "registry+https://github.com/rust-lang/crates.io-index" 1826 | checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" 1827 | dependencies = [ 1828 | "serde", 1829 | ] 1830 | 1831 | [[package]] 1832 | name = "serde_with" 1833 | version = "2.3.3" 1834 | source = "registry+https://github.com/rust-lang/crates.io-index" 1835 | checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" 1836 | dependencies = [ 1837 | "serde", 1838 | "serde_with_macros", 1839 | ] 1840 | 1841 | [[package]] 1842 | name = "serde_with_macros" 1843 | version = "2.3.3" 1844 | source = "registry+https://github.com/rust-lang/crates.io-index" 1845 | checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" 1846 | dependencies = [ 1847 | "darling", 1848 | "proc-macro2", 1849 | "quote", 1850 | "syn 2.0.66", 1851 | ] 1852 | 1853 | [[package]] 1854 | name = "sha2" 1855 | version = "0.9.9" 1856 | source = "registry+https://github.com/rust-lang/crates.io-index" 1857 | checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" 1858 | dependencies = [ 1859 | "block-buffer 0.9.0", 1860 | "cfg-if", 1861 | "cpufeatures", 1862 | "digest 0.9.0", 1863 | "opaque-debug", 1864 | ] 1865 | 1866 | [[package]] 1867 | name = "sha2" 1868 | version = "0.10.8" 1869 | source = "registry+https://github.com/rust-lang/crates.io-index" 1870 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1871 | dependencies = [ 1872 | "cfg-if", 1873 | "cpufeatures", 1874 | "digest 0.10.7", 1875 | ] 1876 | 1877 | [[package]] 1878 | name = "sha3" 1879 | version = "0.9.1" 1880 | source = "registry+https://github.com/rust-lang/crates.io-index" 1881 | checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" 1882 | dependencies = [ 1883 | "block-buffer 0.9.0", 1884 | "digest 0.9.0", 1885 | "keccak", 1886 | "opaque-debug", 1887 | ] 1888 | 1889 | [[package]] 1890 | name = "sha3" 1891 | version = "0.10.8" 1892 | source = "registry+https://github.com/rust-lang/crates.io-index" 1893 | checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" 1894 | dependencies = [ 1895 | "digest 0.10.7", 1896 | "keccak", 1897 | ] 1898 | 1899 | [[package]] 1900 | name = "signature" 1901 | version = "1.6.4" 1902 | source = "registry+https://github.com/rust-lang/crates.io-index" 1903 | checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" 1904 | 1905 | [[package]] 1906 | name = "siphasher" 1907 | version = "0.3.11" 1908 | source = "registry+https://github.com/rust-lang/crates.io-index" 1909 | checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" 1910 | 1911 | [[package]] 1912 | name = "sized-chunks" 1913 | version = "0.6.5" 1914 | source = "registry+https://github.com/rust-lang/crates.io-index" 1915 | checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" 1916 | dependencies = [ 1917 | "bitmaps", 1918 | "typenum", 1919 | ] 1920 | 1921 | [[package]] 1922 | name = "smallvec" 1923 | version = "1.13.2" 1924 | source = "registry+https://github.com/rust-lang/crates.io-index" 1925 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1926 | 1927 | [[package]] 1928 | name = "solana-frozen-abi" 1929 | version = "1.18.14" 1930 | source = "registry+https://github.com/rust-lang/crates.io-index" 1931 | checksum = "d353eac7a178cd8a2ceaf5d304719d4a30c1d3f24f303145d5b029b8cc7c35f0" 1932 | dependencies = [ 1933 | "block-buffer 0.10.4", 1934 | "bs58 0.4.0", 1935 | "bv", 1936 | "either", 1937 | "generic-array", 1938 | "im", 1939 | "lazy_static", 1940 | "log", 1941 | "memmap2", 1942 | "rustc_version", 1943 | "serde", 1944 | "serde_bytes", 1945 | "serde_derive", 1946 | "sha2 0.10.8", 1947 | "solana-frozen-abi-macro", 1948 | "subtle", 1949 | "thiserror", 1950 | ] 1951 | 1952 | [[package]] 1953 | name = "solana-frozen-abi-macro" 1954 | version = "1.18.14" 1955 | source = "registry+https://github.com/rust-lang/crates.io-index" 1956 | checksum = "bc87189dcb2d2da407831fc983e4f05e70c58be12b5c713e9a05f873edb42637" 1957 | dependencies = [ 1958 | "proc-macro2", 1959 | "quote", 1960 | "rustc_version", 1961 | "syn 2.0.66", 1962 | ] 1963 | 1964 | [[package]] 1965 | name = "solana-logger" 1966 | version = "1.18.14" 1967 | source = "registry+https://github.com/rust-lang/crates.io-index" 1968 | checksum = "8d857a115710eeb1c5ac98a340141f0c49cc31854168767d0c5b855e212632a5" 1969 | dependencies = [ 1970 | "env_logger", 1971 | "lazy_static", 1972 | "log", 1973 | ] 1974 | 1975 | [[package]] 1976 | name = "solana-program" 1977 | version = "1.18.14" 1978 | source = "registry+https://github.com/rust-lang/crates.io-index" 1979 | checksum = "ad73ff4d5c8d4943988ef18924f5fbd96881410ab20d5a0bfa32bb44d7d4cfce" 1980 | dependencies = [ 1981 | "ark-bn254", 1982 | "ark-ec", 1983 | "ark-ff", 1984 | "ark-serialize", 1985 | "base64 0.21.7", 1986 | "bincode", 1987 | "bitflags", 1988 | "blake3", 1989 | "borsh 0.10.3", 1990 | "borsh 0.9.3", 1991 | "borsh 1.5.0", 1992 | "bs58 0.4.0", 1993 | "bv", 1994 | "bytemuck", 1995 | "cc", 1996 | "console_error_panic_hook", 1997 | "console_log", 1998 | "curve25519-dalek", 1999 | "getrandom 0.2.15", 2000 | "itertools", 2001 | "js-sys", 2002 | "lazy_static", 2003 | "libc", 2004 | "libsecp256k1", 2005 | "light-poseidon", 2006 | "log", 2007 | "memoffset", 2008 | "num-bigint", 2009 | "num-derive 0.4.2", 2010 | "num-traits", 2011 | "parking_lot", 2012 | "rand 0.8.5", 2013 | "rustc_version", 2014 | "rustversion", 2015 | "serde", 2016 | "serde_bytes", 2017 | "serde_derive", 2018 | "serde_json", 2019 | "sha2 0.10.8", 2020 | "sha3 0.10.8", 2021 | "solana-frozen-abi", 2022 | "solana-frozen-abi-macro", 2023 | "solana-sdk-macro", 2024 | "thiserror", 2025 | "tiny-bip39", 2026 | "wasm-bindgen", 2027 | "zeroize", 2028 | ] 2029 | 2030 | [[package]] 2031 | name = "solana-sdk" 2032 | version = "1.18.14" 2033 | source = "registry+https://github.com/rust-lang/crates.io-index" 2034 | checksum = "4f518a377209223b09a0fb62abd53add4a11313a1e85f535f559fbcc0227117a" 2035 | dependencies = [ 2036 | "assert_matches", 2037 | "base64 0.21.7", 2038 | "bincode", 2039 | "bitflags", 2040 | "borsh 1.5.0", 2041 | "bs58 0.4.0", 2042 | "bytemuck", 2043 | "byteorder", 2044 | "chrono", 2045 | "derivation-path", 2046 | "digest 0.10.7", 2047 | "ed25519-dalek", 2048 | "ed25519-dalek-bip32", 2049 | "generic-array", 2050 | "hmac 0.12.1", 2051 | "itertools", 2052 | "js-sys", 2053 | "lazy_static", 2054 | "libsecp256k1", 2055 | "log", 2056 | "memmap2", 2057 | "num-derive 0.4.2", 2058 | "num-traits", 2059 | "num_enum", 2060 | "pbkdf2 0.11.0", 2061 | "qstring", 2062 | "qualifier_attr", 2063 | "rand 0.7.3", 2064 | "rand 0.8.5", 2065 | "rustc_version", 2066 | "rustversion", 2067 | "serde", 2068 | "serde_bytes", 2069 | "serde_derive", 2070 | "serde_json", 2071 | "serde_with", 2072 | "sha2 0.10.8", 2073 | "sha3 0.10.8", 2074 | "siphasher", 2075 | "solana-frozen-abi", 2076 | "solana-frozen-abi-macro", 2077 | "solana-logger", 2078 | "solana-program", 2079 | "solana-sdk-macro", 2080 | "thiserror", 2081 | "uriparse", 2082 | "wasm-bindgen", 2083 | ] 2084 | 2085 | [[package]] 2086 | name = "solana-sdk-macro" 2087 | version = "1.18.14" 2088 | source = "registry+https://github.com/rust-lang/crates.io-index" 2089 | checksum = "2975b2c2ed6f06d2ffbb2e6b3e7fdd9ca6b2570a76d49a2173f393e6e84c9c71" 2090 | dependencies = [ 2091 | "bs58 0.4.0", 2092 | "proc-macro2", 2093 | "quote", 2094 | "rustversion", 2095 | "syn 2.0.66", 2096 | ] 2097 | 2098 | [[package]] 2099 | name = "solana-security-txt" 2100 | version = "1.1.1" 2101 | source = "registry+https://github.com/rust-lang/crates.io-index" 2102 | checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" 2103 | 2104 | [[package]] 2105 | name = "solana-zk-token-sdk" 2106 | version = "1.18.14" 2107 | source = "registry+https://github.com/rust-lang/crates.io-index" 2108 | checksum = "7cefc9878a202bf9606745e56712f7d56878ea31b29f2f89785b4b801b264322" 2109 | dependencies = [ 2110 | "aes-gcm-siv", 2111 | "base64 0.21.7", 2112 | "bincode", 2113 | "bytemuck", 2114 | "byteorder", 2115 | "curve25519-dalek", 2116 | "getrandom 0.1.16", 2117 | "itertools", 2118 | "lazy_static", 2119 | "merlin", 2120 | "num-derive 0.4.2", 2121 | "num-traits", 2122 | "rand 0.7.3", 2123 | "serde", 2124 | "serde_json", 2125 | "sha3 0.9.1", 2126 | "solana-program", 2127 | "solana-sdk", 2128 | "subtle", 2129 | "thiserror", 2130 | "zeroize", 2131 | ] 2132 | 2133 | [[package]] 2134 | name = "spl-associated-token-account" 2135 | version = "3.0.2" 2136 | source = "registry+https://github.com/rust-lang/crates.io-index" 2137 | checksum = "a2e688554bac5838217ffd1fab7845c573ff106b6336bf7d290db7c98d5a8efd" 2138 | dependencies = [ 2139 | "assert_matches", 2140 | "borsh 1.5.0", 2141 | "num-derive 0.4.2", 2142 | "num-traits", 2143 | "solana-program", 2144 | "spl-token", 2145 | "spl-token-2022", 2146 | "thiserror", 2147 | ] 2148 | 2149 | [[package]] 2150 | name = "spl-discriminator" 2151 | version = "0.2.2" 2152 | source = "registry+https://github.com/rust-lang/crates.io-index" 2153 | checksum = "34d1814406e98b08c5cd02c1126f83fd407ad084adce0b05fda5730677822eac" 2154 | dependencies = [ 2155 | "bytemuck", 2156 | "solana-program", 2157 | "spl-discriminator-derive", 2158 | ] 2159 | 2160 | [[package]] 2161 | name = "spl-discriminator-derive" 2162 | version = "0.2.0" 2163 | source = "registry+https://github.com/rust-lang/crates.io-index" 2164 | checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" 2165 | dependencies = [ 2166 | "quote", 2167 | "spl-discriminator-syn", 2168 | "syn 2.0.66", 2169 | ] 2170 | 2171 | [[package]] 2172 | name = "spl-discriminator-syn" 2173 | version = "0.2.0" 2174 | source = "registry+https://github.com/rust-lang/crates.io-index" 2175 | checksum = "8c1f05593b7ca9eac7caca309720f2eafb96355e037e6d373b909a80fe7b69b9" 2176 | dependencies = [ 2177 | "proc-macro2", 2178 | "quote", 2179 | "sha2 0.10.8", 2180 | "syn 2.0.66", 2181 | "thiserror", 2182 | ] 2183 | 2184 | [[package]] 2185 | name = "spl-memo" 2186 | version = "4.0.1" 2187 | source = "registry+https://github.com/rust-lang/crates.io-index" 2188 | checksum = "58e9bae02de3405079a057fe244c867a08f92d48327d231fc60da831f94caf0a" 2189 | dependencies = [ 2190 | "solana-program", 2191 | ] 2192 | 2193 | [[package]] 2194 | name = "spl-pod" 2195 | version = "0.2.2" 2196 | source = "registry+https://github.com/rust-lang/crates.io-index" 2197 | checksum = "046ce669f48cf2eca1ec518916d8725596bfb655beb1c74374cf71dc6cb773c9" 2198 | dependencies = [ 2199 | "borsh 1.5.0", 2200 | "bytemuck", 2201 | "solana-program", 2202 | "solana-zk-token-sdk", 2203 | "spl-program-error", 2204 | ] 2205 | 2206 | [[package]] 2207 | name = "spl-program-error" 2208 | version = "0.4.1" 2209 | source = "registry+https://github.com/rust-lang/crates.io-index" 2210 | checksum = "49065093ea91f57b9b2bd81493ff705e2ad4e64507a07dbc02b085778e02770e" 2211 | dependencies = [ 2212 | "num-derive 0.4.2", 2213 | "num-traits", 2214 | "solana-program", 2215 | "spl-program-error-derive", 2216 | "thiserror", 2217 | ] 2218 | 2219 | [[package]] 2220 | name = "spl-program-error-derive" 2221 | version = "0.4.1" 2222 | source = "registry+https://github.com/rust-lang/crates.io-index" 2223 | checksum = "e6d375dd76c517836353e093c2dbb490938ff72821ab568b545fd30ab3256b3e" 2224 | dependencies = [ 2225 | "proc-macro2", 2226 | "quote", 2227 | "sha2 0.10.8", 2228 | "syn 2.0.66", 2229 | ] 2230 | 2231 | [[package]] 2232 | name = "spl-tlv-account-resolution" 2233 | version = "0.6.3" 2234 | source = "registry+https://github.com/rust-lang/crates.io-index" 2235 | checksum = "cace91ba08984a41556efe49cbf2edca4db2f577b649da7827d3621161784bf8" 2236 | dependencies = [ 2237 | "bytemuck", 2238 | "solana-program", 2239 | "spl-discriminator", 2240 | "spl-pod", 2241 | "spl-program-error", 2242 | "spl-type-length-value", 2243 | ] 2244 | 2245 | [[package]] 2246 | name = "spl-token" 2247 | version = "4.0.1" 2248 | source = "registry+https://github.com/rust-lang/crates.io-index" 2249 | checksum = "95ae123223633a389f95d1da9d49c2d0a50d499e7060b9624626a69e536ad2a4" 2250 | dependencies = [ 2251 | "arrayref", 2252 | "bytemuck", 2253 | "num-derive 0.4.2", 2254 | "num-traits", 2255 | "num_enum", 2256 | "solana-program", 2257 | "thiserror", 2258 | ] 2259 | 2260 | [[package]] 2261 | name = "spl-token-2022" 2262 | version = "3.0.2" 2263 | source = "registry+https://github.com/rust-lang/crates.io-index" 2264 | checksum = "e5412f99ae7ee6e0afde00defaa354e6228e47e30c0e3adf553e2e01e6abb584" 2265 | dependencies = [ 2266 | "arrayref", 2267 | "bytemuck", 2268 | "num-derive 0.4.2", 2269 | "num-traits", 2270 | "num_enum", 2271 | "solana-program", 2272 | "solana-security-txt", 2273 | "solana-zk-token-sdk", 2274 | "spl-memo", 2275 | "spl-pod", 2276 | "spl-token", 2277 | "spl-token-group-interface", 2278 | "spl-token-metadata-interface", 2279 | "spl-transfer-hook-interface", 2280 | "spl-type-length-value", 2281 | "thiserror", 2282 | ] 2283 | 2284 | [[package]] 2285 | name = "spl-token-group-interface" 2286 | version = "0.2.3" 2287 | source = "registry+https://github.com/rust-lang/crates.io-index" 2288 | checksum = "d419b5cfa3ee8e0f2386fd7e02a33b3ec8a7db4a9c7064a2ea24849dc4a273b6" 2289 | dependencies = [ 2290 | "bytemuck", 2291 | "solana-program", 2292 | "spl-discriminator", 2293 | "spl-pod", 2294 | "spl-program-error", 2295 | ] 2296 | 2297 | [[package]] 2298 | name = "spl-token-metadata-interface" 2299 | version = "0.3.3" 2300 | source = "registry+https://github.com/rust-lang/crates.io-index" 2301 | checksum = "30179c47e93625680dabb620c6e7931bd12d62af390f447bc7beb4a3a9b5feee" 2302 | dependencies = [ 2303 | "borsh 1.5.0", 2304 | "solana-program", 2305 | "spl-discriminator", 2306 | "spl-pod", 2307 | "spl-program-error", 2308 | "spl-type-length-value", 2309 | ] 2310 | 2311 | [[package]] 2312 | name = "spl-transfer-hook-interface" 2313 | version = "0.6.3" 2314 | source = "registry+https://github.com/rust-lang/crates.io-index" 2315 | checksum = "66a98359769cd988f7b35c02558daa56d496a7e3bd8626e61f90a7c757eedb9b" 2316 | dependencies = [ 2317 | "arrayref", 2318 | "bytemuck", 2319 | "solana-program", 2320 | "spl-discriminator", 2321 | "spl-pod", 2322 | "spl-program-error", 2323 | "spl-tlv-account-resolution", 2324 | "spl-type-length-value", 2325 | ] 2326 | 2327 | [[package]] 2328 | name = "spl-type-length-value" 2329 | version = "0.4.3" 2330 | source = "registry+https://github.com/rust-lang/crates.io-index" 2331 | checksum = "422ce13429dbd41d2cee8a73931c05fda0b0c8ca156a8b0c19445642550bb61a" 2332 | dependencies = [ 2333 | "bytemuck", 2334 | "solana-program", 2335 | "spl-discriminator", 2336 | "spl-pod", 2337 | "spl-program-error", 2338 | ] 2339 | 2340 | [[package]] 2341 | name = "strsim" 2342 | version = "0.11.1" 2343 | source = "registry+https://github.com/rust-lang/crates.io-index" 2344 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 2345 | 2346 | [[package]] 2347 | name = "subtle" 2348 | version = "2.4.1" 2349 | source = "registry+https://github.com/rust-lang/crates.io-index" 2350 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 2351 | 2352 | [[package]] 2353 | name = "syn" 2354 | version = "1.0.109" 2355 | source = "registry+https://github.com/rust-lang/crates.io-index" 2356 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 2357 | dependencies = [ 2358 | "proc-macro2", 2359 | "quote", 2360 | "unicode-ident", 2361 | ] 2362 | 2363 | [[package]] 2364 | name = "syn" 2365 | version = "2.0.66" 2366 | source = "registry+https://github.com/rust-lang/crates.io-index" 2367 | checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" 2368 | dependencies = [ 2369 | "proc-macro2", 2370 | "quote", 2371 | "unicode-ident", 2372 | ] 2373 | 2374 | [[package]] 2375 | name = "syn_derive" 2376 | version = "0.1.8" 2377 | source = "registry+https://github.com/rust-lang/crates.io-index" 2378 | checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" 2379 | dependencies = [ 2380 | "proc-macro-error", 2381 | "proc-macro2", 2382 | "quote", 2383 | "syn 2.0.66", 2384 | ] 2385 | 2386 | [[package]] 2387 | name = "termcolor" 2388 | version = "1.4.1" 2389 | source = "registry+https://github.com/rust-lang/crates.io-index" 2390 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 2391 | dependencies = [ 2392 | "winapi-util", 2393 | ] 2394 | 2395 | [[package]] 2396 | name = "thiserror" 2397 | version = "1.0.61" 2398 | source = "registry+https://github.com/rust-lang/crates.io-index" 2399 | checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" 2400 | dependencies = [ 2401 | "thiserror-impl", 2402 | ] 2403 | 2404 | [[package]] 2405 | name = "thiserror-impl" 2406 | version = "1.0.61" 2407 | source = "registry+https://github.com/rust-lang/crates.io-index" 2408 | checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" 2409 | dependencies = [ 2410 | "proc-macro2", 2411 | "quote", 2412 | "syn 2.0.66", 2413 | ] 2414 | 2415 | [[package]] 2416 | name = "tiny-bip39" 2417 | version = "0.8.2" 2418 | source = "registry+https://github.com/rust-lang/crates.io-index" 2419 | checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" 2420 | dependencies = [ 2421 | "anyhow", 2422 | "hmac 0.8.1", 2423 | "once_cell", 2424 | "pbkdf2 0.4.0", 2425 | "rand 0.7.3", 2426 | "rustc-hash", 2427 | "sha2 0.9.9", 2428 | "thiserror", 2429 | "unicode-normalization", 2430 | "wasm-bindgen", 2431 | "zeroize", 2432 | ] 2433 | 2434 | [[package]] 2435 | name = "tinyvec" 2436 | version = "1.6.0" 2437 | source = "registry+https://github.com/rust-lang/crates.io-index" 2438 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 2439 | dependencies = [ 2440 | "tinyvec_macros", 2441 | ] 2442 | 2443 | [[package]] 2444 | name = "tinyvec_macros" 2445 | version = "0.1.1" 2446 | source = "registry+https://github.com/rust-lang/crates.io-index" 2447 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 2448 | 2449 | [[package]] 2450 | name = "toml" 2451 | version = "0.5.11" 2452 | source = "registry+https://github.com/rust-lang/crates.io-index" 2453 | checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" 2454 | dependencies = [ 2455 | "serde", 2456 | ] 2457 | 2458 | [[package]] 2459 | name = "toml" 2460 | version = "0.8.13" 2461 | source = "registry+https://github.com/rust-lang/crates.io-index" 2462 | checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" 2463 | dependencies = [ 2464 | "serde", 2465 | "serde_spanned", 2466 | "toml_datetime", 2467 | "toml_edit 0.22.13", 2468 | ] 2469 | 2470 | [[package]] 2471 | name = "toml_datetime" 2472 | version = "0.6.6" 2473 | source = "registry+https://github.com/rust-lang/crates.io-index" 2474 | checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" 2475 | dependencies = [ 2476 | "serde", 2477 | ] 2478 | 2479 | [[package]] 2480 | name = "toml_edit" 2481 | version = "0.21.1" 2482 | source = "registry+https://github.com/rust-lang/crates.io-index" 2483 | checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" 2484 | dependencies = [ 2485 | "indexmap", 2486 | "toml_datetime", 2487 | "winnow 0.5.40", 2488 | ] 2489 | 2490 | [[package]] 2491 | name = "toml_edit" 2492 | version = "0.22.13" 2493 | source = "registry+https://github.com/rust-lang/crates.io-index" 2494 | checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" 2495 | dependencies = [ 2496 | "indexmap", 2497 | "serde", 2498 | "serde_spanned", 2499 | "toml_datetime", 2500 | "winnow 0.6.8", 2501 | ] 2502 | 2503 | [[package]] 2504 | name = "typenum" 2505 | version = "1.17.0" 2506 | source = "registry+https://github.com/rust-lang/crates.io-index" 2507 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 2508 | 2509 | [[package]] 2510 | name = "unicode-ident" 2511 | version = "1.0.12" 2512 | source = "registry+https://github.com/rust-lang/crates.io-index" 2513 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 2514 | 2515 | [[package]] 2516 | name = "unicode-normalization" 2517 | version = "0.1.23" 2518 | source = "registry+https://github.com/rust-lang/crates.io-index" 2519 | checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" 2520 | dependencies = [ 2521 | "tinyvec", 2522 | ] 2523 | 2524 | [[package]] 2525 | name = "unicode-segmentation" 2526 | version = "1.11.0" 2527 | source = "registry+https://github.com/rust-lang/crates.io-index" 2528 | checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" 2529 | 2530 | [[package]] 2531 | name = "universal-hash" 2532 | version = "0.4.1" 2533 | source = "registry+https://github.com/rust-lang/crates.io-index" 2534 | checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" 2535 | dependencies = [ 2536 | "generic-array", 2537 | "subtle", 2538 | ] 2539 | 2540 | [[package]] 2541 | name = "uriparse" 2542 | version = "0.6.4" 2543 | source = "registry+https://github.com/rust-lang/crates.io-index" 2544 | checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" 2545 | dependencies = [ 2546 | "fnv", 2547 | "lazy_static", 2548 | ] 2549 | 2550 | [[package]] 2551 | name = "version_check" 2552 | version = "0.9.4" 2553 | source = "registry+https://github.com/rust-lang/crates.io-index" 2554 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 2555 | 2556 | [[package]] 2557 | name = "wasi" 2558 | version = "0.9.0+wasi-snapshot-preview1" 2559 | source = "registry+https://github.com/rust-lang/crates.io-index" 2560 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 2561 | 2562 | [[package]] 2563 | name = "wasi" 2564 | version = "0.11.0+wasi-snapshot-preview1" 2565 | source = "registry+https://github.com/rust-lang/crates.io-index" 2566 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2567 | 2568 | [[package]] 2569 | name = "wasm-bindgen" 2570 | version = "0.2.92" 2571 | source = "registry+https://github.com/rust-lang/crates.io-index" 2572 | checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" 2573 | dependencies = [ 2574 | "cfg-if", 2575 | "wasm-bindgen-macro", 2576 | ] 2577 | 2578 | [[package]] 2579 | name = "wasm-bindgen-backend" 2580 | version = "0.2.92" 2581 | source = "registry+https://github.com/rust-lang/crates.io-index" 2582 | checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" 2583 | dependencies = [ 2584 | "bumpalo", 2585 | "log", 2586 | "once_cell", 2587 | "proc-macro2", 2588 | "quote", 2589 | "syn 2.0.66", 2590 | "wasm-bindgen-shared", 2591 | ] 2592 | 2593 | [[package]] 2594 | name = "wasm-bindgen-macro" 2595 | version = "0.2.92" 2596 | source = "registry+https://github.com/rust-lang/crates.io-index" 2597 | checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" 2598 | dependencies = [ 2599 | "quote", 2600 | "wasm-bindgen-macro-support", 2601 | ] 2602 | 2603 | [[package]] 2604 | name = "wasm-bindgen-macro-support" 2605 | version = "0.2.92" 2606 | source = "registry+https://github.com/rust-lang/crates.io-index" 2607 | checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" 2608 | dependencies = [ 2609 | "proc-macro2", 2610 | "quote", 2611 | "syn 2.0.66", 2612 | "wasm-bindgen-backend", 2613 | "wasm-bindgen-shared", 2614 | ] 2615 | 2616 | [[package]] 2617 | name = "wasm-bindgen-shared" 2618 | version = "0.2.92" 2619 | source = "registry+https://github.com/rust-lang/crates.io-index" 2620 | checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" 2621 | 2622 | [[package]] 2623 | name = "web-sys" 2624 | version = "0.3.69" 2625 | source = "registry+https://github.com/rust-lang/crates.io-index" 2626 | checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" 2627 | dependencies = [ 2628 | "js-sys", 2629 | "wasm-bindgen", 2630 | ] 2631 | 2632 | [[package]] 2633 | name = "winapi" 2634 | version = "0.3.9" 2635 | source = "registry+https://github.com/rust-lang/crates.io-index" 2636 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2637 | dependencies = [ 2638 | "winapi-i686-pc-windows-gnu", 2639 | "winapi-x86_64-pc-windows-gnu", 2640 | ] 2641 | 2642 | [[package]] 2643 | name = "winapi-i686-pc-windows-gnu" 2644 | version = "0.4.0" 2645 | source = "registry+https://github.com/rust-lang/crates.io-index" 2646 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2647 | 2648 | [[package]] 2649 | name = "winapi-util" 2650 | version = "0.1.8" 2651 | source = "registry+https://github.com/rust-lang/crates.io-index" 2652 | checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" 2653 | dependencies = [ 2654 | "windows-sys", 2655 | ] 2656 | 2657 | [[package]] 2658 | name = "winapi-x86_64-pc-windows-gnu" 2659 | version = "0.4.0" 2660 | source = "registry+https://github.com/rust-lang/crates.io-index" 2661 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2662 | 2663 | [[package]] 2664 | name = "windows-sys" 2665 | version = "0.52.0" 2666 | source = "registry+https://github.com/rust-lang/crates.io-index" 2667 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2668 | dependencies = [ 2669 | "windows-targets", 2670 | ] 2671 | 2672 | [[package]] 2673 | name = "windows-targets" 2674 | version = "0.52.5" 2675 | source = "registry+https://github.com/rust-lang/crates.io-index" 2676 | checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" 2677 | dependencies = [ 2678 | "windows_aarch64_gnullvm", 2679 | "windows_aarch64_msvc", 2680 | "windows_i686_gnu", 2681 | "windows_i686_gnullvm", 2682 | "windows_i686_msvc", 2683 | "windows_x86_64_gnu", 2684 | "windows_x86_64_gnullvm", 2685 | "windows_x86_64_msvc", 2686 | ] 2687 | 2688 | [[package]] 2689 | name = "windows_aarch64_gnullvm" 2690 | version = "0.52.5" 2691 | source = "registry+https://github.com/rust-lang/crates.io-index" 2692 | checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" 2693 | 2694 | [[package]] 2695 | name = "windows_aarch64_msvc" 2696 | version = "0.52.5" 2697 | source = "registry+https://github.com/rust-lang/crates.io-index" 2698 | checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" 2699 | 2700 | [[package]] 2701 | name = "windows_i686_gnu" 2702 | version = "0.52.5" 2703 | source = "registry+https://github.com/rust-lang/crates.io-index" 2704 | checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" 2705 | 2706 | [[package]] 2707 | name = "windows_i686_gnullvm" 2708 | version = "0.52.5" 2709 | source = "registry+https://github.com/rust-lang/crates.io-index" 2710 | checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" 2711 | 2712 | [[package]] 2713 | name = "windows_i686_msvc" 2714 | version = "0.52.5" 2715 | source = "registry+https://github.com/rust-lang/crates.io-index" 2716 | checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" 2717 | 2718 | [[package]] 2719 | name = "windows_x86_64_gnu" 2720 | version = "0.52.5" 2721 | source = "registry+https://github.com/rust-lang/crates.io-index" 2722 | checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" 2723 | 2724 | [[package]] 2725 | name = "windows_x86_64_gnullvm" 2726 | version = "0.52.5" 2727 | source = "registry+https://github.com/rust-lang/crates.io-index" 2728 | checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" 2729 | 2730 | [[package]] 2731 | name = "windows_x86_64_msvc" 2732 | version = "0.52.5" 2733 | source = "registry+https://github.com/rust-lang/crates.io-index" 2734 | checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" 2735 | 2736 | [[package]] 2737 | name = "winnow" 2738 | version = "0.5.40" 2739 | source = "registry+https://github.com/rust-lang/crates.io-index" 2740 | checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 2741 | dependencies = [ 2742 | "memchr", 2743 | ] 2744 | 2745 | [[package]] 2746 | name = "winnow" 2747 | version = "0.6.8" 2748 | source = "registry+https://github.com/rust-lang/crates.io-index" 2749 | checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" 2750 | dependencies = [ 2751 | "memchr", 2752 | ] 2753 | 2754 | [[package]] 2755 | name = "zerocopy" 2756 | version = "0.7.34" 2757 | source = "registry+https://github.com/rust-lang/crates.io-index" 2758 | checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" 2759 | dependencies = [ 2760 | "zerocopy-derive", 2761 | ] 2762 | 2763 | [[package]] 2764 | name = "zerocopy-derive" 2765 | version = "0.7.34" 2766 | source = "registry+https://github.com/rust-lang/crates.io-index" 2767 | checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" 2768 | dependencies = [ 2769 | "proc-macro2", 2770 | "quote", 2771 | "syn 2.0.66", 2772 | ] 2773 | 2774 | [[package]] 2775 | name = "zeroize" 2776 | version = "1.3.0" 2777 | source = "registry+https://github.com/rust-lang/crates.io-index" 2778 | checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" 2779 | dependencies = [ 2780 | "zeroize_derive", 2781 | ] 2782 | 2783 | [[package]] 2784 | name = "zeroize_derive" 2785 | version = "1.4.2" 2786 | source = "registry+https://github.com/rust-lang/crates.io-index" 2787 | checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" 2788 | dependencies = [ 2789 | "proc-macro2", 2790 | "quote", 2791 | "syn 2.0.66", 2792 | ] 2793 | --------------------------------------------------------------------------------