├── programs └── staking │ ├── src │ ├── create.rs │ ├── constants.rs │ ├── instructions │ │ ├── mod.rs │ │ ├── set_pause.rs │ │ ├── harvest.rs │ │ ├── configure.rs │ │ ├── emergency.rs │ │ ├── purchase_boost.rs │ │ ├── stake.rs │ │ ├── create_pool.rs │ │ └── withdraw.rs │ ├── errors.rs │ ├── events.rs │ ├── utils.rs │ ├── lib.rs │ └── state.rs │ ├── Xargo.toml │ └── Cargo.toml ├── .gitignore ├── .prettierignore ├── spl-programs ├── token.so ├── metadata.so └── associatedtoken.so ├── 1.json ├── id.json ├── tsconfig.json ├── PoBHFK2GkGwW4Yu4PkTAtGAUjABLDHTRB6VRoeca4bK.json ├── Cargo.toml ├── migrations └── deploy.ts ├── Anchor.toml ├── package.json ├── README.md ├── lib ├── constant.ts ├── util.ts └── scripts.ts ├── tests ├── constant.ts ├── utils.ts └── staking.ts ├── cli ├── scripts.ts └── command.ts └── Cargo.lock /programs/staking/src/create.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | 4 | -------------------------------------------------------------------------------- /programs/staking/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 | -------------------------------------------------------------------------------- /spl-programs/token.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cutupdev/Solana-Token-Staking-Smart-Contract/HEAD/spl-programs/token.so -------------------------------------------------------------------------------- /spl-programs/metadata.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cutupdev/Solana-Token-Staking-Smart-Contract/HEAD/spl-programs/metadata.so -------------------------------------------------------------------------------- /spl-programs/associatedtoken.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cutupdev/Solana-Token-Staking-Smart-Contract/HEAD/spl-programs/associatedtoken.so -------------------------------------------------------------------------------- /1.json: -------------------------------------------------------------------------------- 1 | [55,157,197,115,172,207,246,91,71,212,158,104,26,95,155,234,143,30,254,148,201,94,201,153,178,118,252,33,204,75,114,176,74,130,6,97,188,183,172,94,152,56,172,10,106,42,14,205,10,233,52,109,42,163,91,248,36,139,44,233,172,206,32,246] -------------------------------------------------------------------------------- /id.json: -------------------------------------------------------------------------------- 1 | [139,77,152,195,135,34,126,205,159,149,229,199,66,166,124,154,171,14,219,72,49,130,120,10,160,216,92,218,167,231,128,153,12,62,216,17,67,232,94,228,21,80,151,114,165,49,249,25,149,173,168,47,11,128,182,229,50,253,132,220,60,102,196,153] -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /PoBHFK2GkGwW4Yu4PkTAtGAUjABLDHTRB6VRoeca4bK.json: -------------------------------------------------------------------------------- 1 | [237,175,172,126,99,197,60,136,239,41,80,140,85,238,57,250,253,230,1,193,218,106,153,76,27,147,251,110,184,167,54,56,182,138,133,200,50,174,198,248,171,215,57,166,100,183,217,201,244,34,172,216,172,167,49,157,254,187,242,74,155,49,205,27] -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /programs/staking/src/constants.rs: -------------------------------------------------------------------------------- 1 | pub const CONFIG: &str = "config"; 2 | pub const GLOBAL: &str = "global"; 3 | pub const USER_POOL: &str = "user_pool"; 4 | pub const SEED_STAKING_POOL: &str = "staking_pool"; 5 | pub const METADATA: &str = "metadata"; 6 | pub const LAMPORT_DECIMALS: u8 = 9; 7 | pub const ADMIN_WALLET: &str = "8BCNHQyDp7mwnCD5hg1U3qfAiZPyqK7JXA4v5hfYFHhH"; -------------------------------------------------------------------------------- /programs/staking/src/instructions/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod configure; 2 | pub use configure::*; 3 | pub mod create_pool; 4 | pub use create_pool::*; 5 | pub mod emergency; 6 | pub use emergency::*; 7 | pub mod harvest; 8 | pub use harvest::*; 9 | pub mod purchase_boost; 10 | pub use purchase_boost::*; 11 | pub mod set_pause; 12 | pub use set_pause::*; 13 | pub mod stake; 14 | pub use stake::*; 15 | pub mod withdraw; 16 | pub use withdraw::*; 17 | -------------------------------------------------------------------------------- /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/staking/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "staking" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "staking" 10 | 11 | [features] 12 | default = [] 13 | cpi = ["no-entrypoint"] 14 | no-entrypoint = [] 15 | no-idl = [] 16 | no-log-ix-name = [] 17 | idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build"] 18 | 19 | [dependencies] 20 | anchor-lang = { version = "0.30.1", features = ["init-if-needed"] } 21 | anchor-spl = { version = "0.30.1", features = ["metadata"] } 22 | solana-program = "1.18.18" 23 | spl-token = "=4.0.3" 24 | -------------------------------------------------------------------------------- /Anchor.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | anchor_version = "0.30.1" 3 | 4 | [features] 5 | resolution = true 6 | skip-lint = false 7 | 8 | [programs.devnet] 9 | staking = "D2dTLQp2w485kQDwDvngfDo2GV1r7DdeGgYWxjAaDkPv" 10 | 11 | [registry] 12 | url = "https://api.apr.dev" 13 | 14 | [provider] 15 | cluster = "https://devnet.helius-rpc.com/?api-key=3b5315ac-170e-4e0e-a60e-4ff5b444fbcf" 16 | wallet = "./id.json" 17 | 18 | [scripts] 19 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 20 | 21 | [test] 22 | startup_wait = 5000 23 | shutdown_wait = 2000 24 | upgradeable = false 25 | 26 | [[test.genesis]] 27 | address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" 28 | program = "spl-programs/metadata.so" 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "license": "ISC", 3 | "scripts": { 4 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 5 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check", 6 | "test": "mocha -r ts-node/register tests/**/*.ts", 7 | "script": "ts-node ./cli/command.ts" 8 | }, 9 | "dependencies": { 10 | "@coral-xyz/anchor": "^0.30.1", 11 | "@project-serum/serum": "^0.13.65", 12 | "@raydium-io/raydium-sdk": "^1.3.1-beta.58", 13 | "@solana/spl-token": "^0.4.8", 14 | "@solana/web3.js": "^1.68.0", 15 | "bs58": "^6.0.0", 16 | "commander": "^13.1.0", 17 | "dotenv": "^16.4.5" 18 | }, 19 | "devDependencies": { 20 | "@types/bn.js": "^5.1.0", 21 | "@types/chai": "^4.3.0", 22 | "@types/mocha": "^9.0.0", 23 | "chai": "^4.3.4", 24 | "mocha": "^9.0.3", 25 | "prettier": "^2.6.2", 26 | "ts-mocha": "^10.0.0", 27 | "typescript": "^4.3.5" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /programs/staking/src/instructions/set_pause.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | use crate::{ 3 | constants::{CONFIG, SEED_STAKING_POOL, ADMIN_WALLET}, 4 | errors::StakingError, 5 | state::{Config, Pool}, 6 | events::PauseEvent, 7 | }; 8 | use std::str::FromStr; 9 | 10 | #[derive(Accounts)] 11 | #[instruction(pool_id: u64)] 12 | pub struct SetPause<'info> { 13 | #[account(mut)] 14 | payer: Signer<'info>, 15 | 16 | #[account( 17 | seeds = [CONFIG.as_bytes()], 18 | bump, 19 | )] 20 | global_config: Box>, 21 | 22 | // staking pool pda 23 | #[account( 24 | mut, 25 | seeds = [SEED_STAKING_POOL.as_bytes(), pool_id.to_le_bytes().as_ref()], 26 | bump 27 | )] 28 | pub staking_pool: Box>, 29 | } 30 | 31 | impl <'info> SetPause<'info> { 32 | pub fn process(&mut self, pool_id: u64) -> Result { 33 | 34 | 35 | 36 | Ok(1) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /programs/staking/src/errors.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | pub use StakingError::*; 4 | 5 | #[error_code] 6 | pub enum StakingError { 7 | #[msg("ValueTooSmall")] 8 | ValueTooSmall, 9 | 10 | #[msg("ValueTooLarge")] 11 | ValueTooLarge, 12 | 13 | #[msg("ValueInvalid")] 14 | ValueInvalid, 15 | 16 | #[msg("IncorrectConfigAccount")] 17 | IncorrectConfigAccount, 18 | 19 | #[msg("AlreadyConfigured")] 20 | AlreadyConfigured, 21 | 22 | #[msg("AlreadyStaked")] 23 | AlreadyStaked, 24 | 25 | #[msg("AlreadyBoosted")] 26 | AlreadyBoosted, 27 | 28 | #[msg("NotEnoughBoosted")] 29 | NotEnoughBoosted, 30 | 31 | #[msg("IncorrectAuthority")] 32 | IncorrectAuthority, 33 | 34 | #[msg("Overflow or underflow occured")] 35 | OverflowOrUnderflowOccurred, 36 | 37 | #[msg("Amount is invalid")] 38 | InvalidAmount, 39 | 40 | #[msg("Token mint is not same with pool.token_mint")] 41 | InvalidPool, 42 | 43 | #[msg("Pool is paused")] 44 | PoolPaused, 45 | 46 | #[msg("Mint address is mismatched")] 47 | MintMismatched, 48 | 49 | #[msg("Incorrect user wallet address")] 50 | IncorrectUserWallet, 51 | 52 | #[msg("Can not withdraw now")] 53 | CanNotWithdraw, 54 | 55 | #[msg("Return amount is too small compared to the minimum received amount")] 56 | ReturnAmountTooSmall, 57 | } 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Solana-Token-Staking-Smart-Contract 2 | Token staking smart contract on solana. It supports multi-staking pool creation, user staking, reward claiming so on. Admin can create pool and can set staking token, APY, boost so on about new staking pool. So users can stake to any pool supporting specific token that they have. Also users can claim reward by sol. It's not full code for staking smart contract, feel free to reach out of me when you need smart contract development[telegram: https://t.me/DevCutup or whatsapp: https://wa.me/13137423660]. 3 | 4 | ## How to use it 5 | ### Ready to use 6 | ```bash 7 | # Clone the repository 8 | git clone https://github.com/cutupdev/Solana-Token-Staking-Smart-Contract.git 9 | 10 | # Navigate to project directory 11 | cd Solana-Token-Staking-Smart-Contract 12 | 13 | # Install dependencies 14 | npm install 15 | 16 | # Configure environment variables 17 | # Create a .env file with your settings (see .env.example Setup section) 18 | # Make sure your system supports rust and anchor 19 | ``` 20 | ### Test case 21 | ```bash 22 | # Run test case 23 | anchor build 24 | anchor test 25 | 26 | # Run cli test case 27 | yarn script ... 28 | 29 | # Reference cli/command.ts 30 | ``` 31 | 32 | - Program address 33 | D2dTLQp2w485kQDwDvngfDo2GV1r7DdeGgYWxjAaDkPv 34 | 35 | ### Contact 36 | - Telegram: https://t.me/DevCutup 37 | - Whatsapp: https://wa.me/13137423660 38 | - Twitter: https://x.com/devcutup 39 | -------------------------------------------------------------------------------- /programs/staking/src/events.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | #[event] 4 | pub struct CreateEvent { 5 | pub token_mint: Pubkey, 6 | pub duration: u64, 7 | pub lock_period: u64, 8 | pub pool_date: u64, 9 | pub boost_trigger_amount: u64, 10 | pub boost_purchase_amount: u64, 11 | pub apy: u16, 12 | pub boost_apy_percent: u16, 13 | pub penalty_fee: u16, 14 | pub boost_duration: u64, 15 | pub reward_token: Pubkey, 16 | pub pool_id: u64, 17 | } 18 | 19 | #[event] 20 | pub struct PauseEvent { 21 | pub pool_id: u64, 22 | pub paused: u8 23 | } 24 | 25 | #[event] 26 | pub struct EmergencyEvent { 27 | pub admin: Pubkey 28 | } 29 | 30 | #[event] 31 | pub struct ConfigEvent { 32 | pub admin: Pubkey 33 | } 34 | 35 | #[event] 36 | pub struct StakeEvent { 37 | pub user: Pubkey, 38 | pub staked_amount: u64, 39 | pub pool_id: u64, 40 | pub deposit_timestamps: u64, 41 | } 42 | 43 | #[event] 44 | pub struct HarvestEvent { 45 | pub user: Pubkey, 46 | pub staked_amount: u64, 47 | pub reward_amount: u64, 48 | pub pool_id: u64, 49 | } 50 | 51 | #[event] 52 | pub struct WithdrawEvent { 53 | pub user: Pubkey, 54 | pub staked_amount: u64, 55 | pub reward_amount: u64, 56 | pub withdraw_amount: u64, 57 | pub is_penalty: bool, 58 | pub pool_id: u64, 59 | } 60 | 61 | #[event] 62 | pub struct PurchaseEvent { 63 | pub user: Pubkey, 64 | pub purchase_amount: u64, 65 | pub pool_id: u64, 66 | pub boost_timestamps: u64, 67 | } 68 | 69 | #[event] 70 | pub struct BoostEvent { 71 | pub user: Pubkey, 72 | pub staked_amount: u64, 73 | } -------------------------------------------------------------------------------- /lib/constant.ts: -------------------------------------------------------------------------------- 1 | import { MAINNET_PROGRAM_ID, DEVNET_PROGRAM_ID } from "@raydium-io/raydium-sdk"; 2 | import { Cluster, PublicKey } from "@solana/web3.js"; 3 | 4 | export const SEED_CONFIG = "config"; 5 | export const SEED_BONDING_CURVE = "bonding_curve"; 6 | 7 | export const TEST_DURATION = 31_536_000; 8 | export const TEST_LOCK_PERIOD = 2_592_000; 9 | export const TEST_BOOST_TRIGGER_AMOUNT = 120_000; 10 | export const TEST_BOOST_PURCHASE_AMOUNT = 10_000; 11 | export const TEST_APY = 30; 12 | export const TEST_BOOST_APY_PERCENT = 60; 13 | export const TEST_PENALTY_FEE = 50; 14 | export const TEST_BOOST_DURATION = 2_592_000; 15 | export const TEST_DECIMALS = 6; 16 | export const TEST_POOL_ID = 0; 17 | export const TEST_TOKEN_PRICE = 10; 18 | export const TEST_SOL_PRICE = 200; 19 | // export const 20 | 21 | const cluster: Cluster = "devnet"; 22 | 23 | export const raydiumProgramId = 24 | cluster.toString() == "mainnet-beta" ? MAINNET_PROGRAM_ID : DEVNET_PROGRAM_ID; 25 | 26 | export const ammProgram = 27 | cluster.toString() == "mainnet-beta" 28 | ? new PublicKey("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8") // mainnet-beta 29 | : new PublicKey("HWy1jotHpo6UqeQxx49dpYYdQB8wj9Qk9MdxwjLvDHB8"); // devnet 30 | 31 | export const marketProgram = 32 | cluster.toString() == "mainnet-beta" 33 | ? new PublicKey("srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX") // mainnet-beta 34 | : new PublicKey("EoTcMgcDRTJVZDMZWBoU6rhYHZfkNTVEAfz3uUJRcYGj"); // devnet 35 | 36 | export const feeDestination = 37 | cluster.toString() == "mainnet-beta" 38 | ? new PublicKey("7YttLkHDoNj9wyDur5pM1ejNaAvT9X4eqaYcHQqtj2G5") // Mainnet 39 | : new PublicKey("3XMrhbv989VxAMi3DErLV9eJht1pHppW5LbKxe9fkEFR"); // Devnet 40 | -------------------------------------------------------------------------------- /tests/constant.ts: -------------------------------------------------------------------------------- 1 | import { MAINNET_PROGRAM_ID, DEVNET_PROGRAM_ID } from "@raydium-io/raydium-sdk"; 2 | import { Cluster, PublicKey } from "@solana/web3.js"; 3 | 4 | export const SEED_CONFIG = "config"; 5 | export const SEED_STAKING_POOL = "staking_pool"; 6 | export const USER_POOL = "user_pool"; 7 | 8 | export const TEST_DURATION = 31_536_000; 9 | export const TEST_LOCK_PERIOD = 2_592_000; 10 | export const TEST_BOOST_TRIGGER_AMOUNT = 120_000; 11 | export const TEST_BOOST_PURCHASE_AMOUNT = 10_000; 12 | export const TEST_APY = 30; 13 | export const TEST_BOOST_APY_PERCENT = 60; 14 | export const TEST_PENALTY_FEE = 50; 15 | export const TEST_BOOST_DURATION = 2_592_000; 16 | export const TEST_DECIMALS = 6; 17 | export const TEST_POOL_ID = 0; 18 | export const TEST_TOKEN_PRICE = 10; 19 | export const TEST_SOL_PRICE = 200; 20 | 21 | // export const RPC_URL = "https://devnet.helius-rpc.com/?api-key=8827c745-52e2-4a9c-a5c5-f0da69716f4e"; 22 | export const RPC_URL = 'http://localhost:8899' 23 | // export const 24 | 25 | const cluster: Cluster = "devnet"; 26 | 27 | export const raydiumProgramId = 28 | cluster.toString() == "mainnet-beta" ? MAINNET_PROGRAM_ID : DEVNET_PROGRAM_ID; 29 | 30 | export const ammProgram = 31 | cluster.toString() == "mainnet-beta" 32 | ? new PublicKey("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8") // mainnet-beta 33 | : new PublicKey("HWy1jotHpo6UqeQxx49dpYYdQB8wj9Qk9MdxwjLvDHB8"); // devnet 34 | 35 | export const marketProgram = 36 | cluster.toString() == "mainnet-beta" 37 | ? new PublicKey("srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX") // mainnet-beta 38 | : new PublicKey("EoTcMgcDRTJVZDMZWBoU6rhYHZfkNTVEAfz3uUJRcYGj"); // devnet 39 | 40 | export const feeDestination = 41 | cluster.toString() == "mainnet-beta" 42 | ? new PublicKey("7YttLkHDoNj9wyDur5pM1ejNaAvT9X4eqaYcHQqtj2G5") // Mainnet 43 | : new PublicKey("3XMrhbv989VxAMi3DErLV9eJht1pHppW5LbKxe9fkEFR"); // Devnet 44 | -------------------------------------------------------------------------------- /programs/staking/src/instructions/harvest.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | constants::{GLOBAL, SEED_STAKING_POOL, USER_POOL, CONFIG}, 3 | errors::*, 4 | events::HarvestEvent, 5 | state::{Pool, User, UserAccount, Config}, 6 | utils::sol_transfer_with_signer, 7 | }; 8 | use anchor_lang::{prelude::*, system_program}; 9 | use anchor_spl::token::Mint; 10 | 11 | #[derive(Accounts)] 12 | #[instruction(pool_id: u64)] 13 | pub struct Harvest<'info> { 14 | #[account(mut)] 15 | user: Signer<'info>, 16 | 17 | // #[account(mut)] 18 | // backend_wallet: Signer<'info>, 19 | 20 | #[account( 21 | seeds = [CONFIG.as_bytes()], 22 | bump, 23 | )] 24 | global_config: Box>, 25 | 26 | #[account( 27 | mut, 28 | seeds = [USER_POOL.as_bytes(), &user.key().to_bytes(), &staking_pool.key().to_bytes()], 29 | bump, 30 | )] 31 | user_pool: Box>, 32 | 33 | /// CHECK: global vault pda which stores SOL 34 | #[account( 35 | mut, 36 | seeds = [GLOBAL.as_bytes()], 37 | bump, 38 | )] 39 | pub global_vault: AccountInfo<'info>, 40 | 41 | #[account( 42 | mut, 43 | seeds = [SEED_STAKING_POOL.as_bytes(), pool_id.to_le_bytes().as_ref()], 44 | bump, 45 | )] 46 | pub staking_pool: Box>, 47 | 48 | // User staking token mint 49 | /// CHECK: should be same with the address with staking token mint 50 | #[account(mut)] 51 | pub staking_token: Box>, 52 | 53 | #[account(address = system_program::ID)] 54 | pub system_program: Program<'info, System>, 55 | } 56 | 57 | impl<'info> Harvest<'info> { 58 | pub fn process( 59 | &mut self, 60 | pool_id: u64, 61 | sol_price: f64, 62 | token_price: f64, 63 | global_vault_bump: u8, 64 | ) -> Result<()> { 65 | 66 | 67 | Ok(()) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /programs/staking/src/instructions/configure.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::{prelude::*, system_program, Discriminator}; 2 | use anchor_spl::{ 3 | associated_token::AssociatedToken, 4 | token::{Mint, Token, TokenAccount}, 5 | }; 6 | // use std::str::FromStr; 7 | use crate::{ 8 | constants::{CONFIG, GLOBAL, ADMIN_WALLET}, 9 | errors::StakingError, 10 | state::Config, 11 | utils::sol_transfer_from_user, 12 | events::ConfigEvent 13 | }; 14 | use borsh::BorshDeserialize; 15 | use std::str::FromStr; 16 | 17 | #[derive(Accounts)] 18 | pub struct Configure<'info> { 19 | #[account(mut)] 20 | payer: Signer<'info>, 21 | 22 | /// CHECK: initialization handled inside the instruction 23 | #[account( 24 | init_if_needed, 25 | payer = payer, 26 | space = Config::DATA_SIZE, 27 | seeds = [CONFIG.as_bytes()], 28 | bump, 29 | )] 30 | config: Box>, 31 | 32 | /// CHECK: global vault pda which stores quote token 33 | #[account( 34 | mut, 35 | seeds = [GLOBAL.as_bytes()], 36 | bump, 37 | )] 38 | pub global_vault: AccountInfo<'info>, 39 | 40 | #[account( 41 | init_if_needed, 42 | payer = payer, 43 | associated_token::mint = native_mint, 44 | associated_token::authority = global_vault 45 | )] 46 | global_wsol_account: Box>, 47 | 48 | #[account( 49 | address = spl_token::native_mint::ID 50 | )] 51 | native_mint: Box>, 52 | 53 | #[account(address = system_program::ID)] 54 | system_program: Program<'info, System>, 55 | 56 | token_program: Program<'info, Token>, 57 | 58 | associated_token_program: Program<'info, AssociatedToken>, 59 | } 60 | 61 | impl<'info> Configure<'info> { 62 | pub fn process(&mut self, new_config: Config, config_bump: u8) -> Result<()> { 63 | 64 | 65 | 66 | Ok(()) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tests/utils.ts: -------------------------------------------------------------------------------- 1 | 2 | import { 3 | PublicKey, 4 | } from "@solana/web3.js"; 5 | 6 | import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token"; 7 | 8 | export const sleep = (ms: number) => { 9 | return new Promise((resolve) => { 10 | setTimeout(resolve, ms); 11 | }); 12 | }; 13 | 14 | export const getAssociatedTokenAccount = ( 15 | ownerPubkey: PublicKey, 16 | mintPk: PublicKey 17 | ): PublicKey => { 18 | let associatedTokenAccountPubkey = (PublicKey.findProgramAddressSync( 19 | [ 20 | ownerPubkey.toBytes(), 21 | TOKEN_PROGRAM_ID.toBytes(), 22 | mintPk.toBytes(), // mint address 23 | ], 24 | ASSOCIATED_TOKEN_PROGRAM_ID 25 | ))[0]; 26 | 27 | return associatedTokenAccountPubkey; 28 | } 29 | 30 | export function convertToFloat(value: number, decimals: number): number { 31 | return value / Math.pow(10, decimals); 32 | } 33 | 34 | export function convertFromFloat(value: number, decimals: number): number { 35 | return value * Math.pow(10, decimals); 36 | } 37 | 38 | export function calculateAmountOutBuy( 39 | reserveLamport: number, 40 | adjustedAmount: number, 41 | tokenOneDecimals: number, 42 | reserveToken: number 43 | ): number { 44 | // Calculate the denominator sum which is (y + dy) 45 | const denominatorSum = reserveLamport + adjustedAmount; 46 | 47 | // Convert to float for division 48 | const denominatorSumFloat = convertToFloat(denominatorSum, tokenOneDecimals); 49 | const adjustedAmountFloat = convertToFloat(adjustedAmount, tokenOneDecimals); 50 | 51 | // (y + dy) / dy 52 | const divAmt = denominatorSumFloat / (adjustedAmountFloat); 53 | 54 | // Convert reserveToken to float with 9 decimals 55 | const reserveTokenFloat = convertToFloat(reserveToken, 9); 56 | 57 | // Calculate dx = xdy / (y + dy) 58 | const amountOutInFloat = reserveTokenFloat / (divAmt); 59 | 60 | // Convert the result back to the original decimal format 61 | const amountOut = convertFromFloat(amountOutInFloat, 9); 62 | 63 | return amountOut; 64 | } -------------------------------------------------------------------------------- /programs/staking/src/instructions/emergency.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::{prelude::*, system_program}; 2 | use anchor_spl::{ 3 | associated_token::{self, AssociatedToken}, 4 | token::{self, Mint, Token, TokenAccount} 5 | }; 6 | use std::str::FromStr; 7 | 8 | 9 | use crate::{ 10 | constants::{ADMIN_WALLET, CONFIG, GLOBAL}, 11 | errors::StakingError, 12 | state::Config, 13 | utils::{ 14 | sol_transfer_with_signer, token_transfer_with_signer, 15 | }, 16 | events::EmergencyEvent 17 | }; 18 | 19 | #[derive(Accounts)] 20 | pub struct Emergency<'info> { 21 | #[account(mut)] 22 | payer: Signer<'info>, 23 | 24 | #[account( 25 | seeds = [CONFIG.as_bytes()], 26 | bump, 27 | )] 28 | global_config: Box>, 29 | 30 | /// CHECK: global vault pda which stores quote token 31 | #[account( 32 | mut, 33 | seeds = [GLOBAL.as_bytes()], 34 | bump, 35 | )] 36 | pub global_vault: AccountInfo<'info>, 37 | 38 | #[account( 39 | mut, 40 | associated_token::mint = native_mint, 41 | associated_token::authority = global_vault 42 | )] 43 | global_wsol_account: Box>, 44 | 45 | /// CHECK: ata of team wallet 46 | #[account( 47 | mut, 48 | seeds = [ 49 | payer.key().as_ref(), 50 | spl_token::id().as_ref(), 51 | native_mint.key().as_ref(), 52 | ], 53 | bump, 54 | seeds::program = anchor_spl::associated_token::ID 55 | )] 56 | admin_wsol_ata: AccountInfo<'info>, 57 | 58 | #[account( 59 | address = spl_token::native_mint::ID 60 | )] 61 | native_mint: Box>, 62 | 63 | #[account(address = system_program::ID)] 64 | system_program: Program<'info, System>, 65 | 66 | #[account(address = token::ID)] 67 | token_program: Program<'info, Token>, 68 | 69 | #[account(address = associated_token::ID)] 70 | pub associated_token_program: Program<'info, AssociatedToken>, 71 | } 72 | 73 | impl<'info> Emergency<'info> { 74 | pub fn process(&mut self, global_vault_bump: u8) -> Result<()> { 75 | 76 | 77 | Ok(()) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /programs/staking/src/instructions/purchase_boost.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::{system_program, prelude::*}; 2 | use anchor_spl::{ 3 | associated_token::{self, AssociatedToken}, 4 | token::{self, Mint, Token, TokenAccount}, 5 | }; 6 | use crate::{ 7 | constants::{CONFIG, SEED_STAKING_POOL, USER_POOL}, errors::StakingError, events::PurchaseEvent, errors::ValueInvalid, state::{Config, Pool, User}, 8 | utils::token_transfer_user 9 | }; 10 | 11 | #[derive(Accounts)] 12 | #[instruction(pool_id: u64)] 13 | pub struct PurchaseBoost<'info> { 14 | #[account(mut)] 15 | user: Signer<'info>, 16 | 17 | #[account( 18 | mut, 19 | seeds = [USER_POOL.as_bytes(), &user.key().to_bytes(), &staking_pool.key().to_bytes()], 20 | bump, 21 | )] 22 | user_pool: Box>, 23 | 24 | #[account( 25 | seeds = [CONFIG.as_bytes()], 26 | bump, 27 | )] 28 | global_config: Box>, 29 | 30 | #[account( 31 | mut, 32 | seeds = [SEED_STAKING_POOL.as_bytes(), pool_id.to_le_bytes().as_ref()], 33 | bump, 34 | )] 35 | pub staking_pool: Box>, 36 | 37 | /// CHECK: ATA for the staking token account 38 | #[account( 39 | mut, 40 | seeds = [ 41 | staking_pool.key().as_ref(), 42 | spl_token::id().as_ref(), 43 | staking_token.key().as_ref(), 44 | ], 45 | bump, 46 | seeds::program = anchor_spl::associated_token::ID 47 | )] 48 | staking_token_account: AccountInfo<'info>, 49 | 50 | // User staking token account 51 | /// CHECK: should be same with the address with staking token mint 52 | #[account( 53 | mut, 54 | associated_token::mint = staking_token, 55 | associated_token::authority = user 56 | )] 57 | pub user_staking_ata: Box>, 58 | 59 | // User staking token mint 60 | /// CHECK: should be same with the address with staking token mint 61 | #[account(mut)] 62 | pub staking_token: Box>, 63 | 64 | #[account(address = system_program::ID)] 65 | pub system_program: Program<'info, System>, 66 | 67 | #[account(address = token::ID)] 68 | pub token_program: Program<'info, Token>, 69 | 70 | #[account(address = associated_token::ID)] 71 | pub associated_token_program: Program<'info, AssociatedToken>, 72 | } 73 | 74 | impl<'info> PurchaseBoost<'info> { 75 | pub fn process( 76 | &mut self, 77 | pool_id: u64, 78 | amount: u64, 79 | ) -> Result { 80 | 81 | 82 | Ok(amount) 83 | } 84 | 85 | } -------------------------------------------------------------------------------- /programs/staking/src/utils.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | use anchor_spl::token::{self, Token}; 3 | use solana_program::program::{invoke, invoke_signed}; 4 | use std::ops::{Div, Mul}; 5 | 6 | pub fn convert_to_float(value: u64, decimals: u8) -> f64 { 7 | (value as f64).div(f64::powf(10.0, decimals as f64)) 8 | } 9 | 10 | pub fn convert_from_float(value: f64, decimals: u8) -> u64 { 11 | value.mul(f64::powf(10.0, decimals as f64)) as u64 12 | } 13 | 14 | // transfer sol from user 15 | pub fn sol_transfer_from_user<'info>( 16 | signer: &Signer<'info>, 17 | destination: AccountInfo<'info>, 18 | system_program: &Program<'info, System>, 19 | amount: u64, 20 | ) -> Result<()> { 21 | let ix = solana_program::system_instruction::transfer(signer.key, destination.key, amount); 22 | invoke( 23 | &ix, 24 | &[ 25 | signer.to_account_info(), 26 | destination, 27 | system_program.to_account_info(), 28 | ], 29 | )?; 30 | Ok(()) 31 | } 32 | 33 | // transfer sol from PDA 34 | pub fn sol_transfer_with_signer<'info>( 35 | source: AccountInfo<'info>, 36 | destination: AccountInfo<'info>, 37 | system_program: &Program<'info, System>, 38 | signers_seeds: &[&[&[u8]]], 39 | amount: u64, 40 | ) -> Result<()> { 41 | let ix = solana_program::system_instruction::transfer(source.key, destination.key, amount); 42 | invoke_signed( 43 | &ix, 44 | &[source, destination, system_program.to_account_info()], 45 | signers_seeds, 46 | )?; 47 | Ok(()) 48 | } 49 | 50 | // transfer token from user 51 | pub fn token_transfer_user<'info>( 52 | from: AccountInfo<'info>, 53 | authority: &Signer<'info>, 54 | to: AccountInfo<'info>, 55 | token_program: &Program<'info, Token>, 56 | amount: u64, 57 | ) -> Result<()> { 58 | let cpi_ctx: CpiContext<_> = CpiContext::new( 59 | token_program.to_account_info(), 60 | token::Transfer { 61 | from, 62 | to, 63 | authority: authority.to_account_info(), 64 | }, 65 | ); 66 | token::transfer(cpi_ctx, amount)?; 67 | 68 | Ok(()) 69 | } 70 | 71 | // transfer token from PDA 72 | pub fn token_transfer_with_signer<'info>( 73 | from: AccountInfo<'info>, 74 | authority: AccountInfo<'info>, 75 | to: AccountInfo<'info>, 76 | token_program: &Program<'info, Token>, 77 | signer_seeds: &[&[&[u8]]], 78 | amount: u64, 79 | ) -> Result<()> { 80 | let cpi_ctx: CpiContext<_> = CpiContext::new_with_signer( 81 | token_program.to_account_info(), 82 | token::Transfer { 83 | from, 84 | to, 85 | authority, 86 | }, 87 | signer_seeds, 88 | ); 89 | token::transfer(cpi_ctx, amount)?; 90 | 91 | Ok(()) 92 | } 93 | -------------------------------------------------------------------------------- /programs/staking/src/instructions/stake.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::{system_program, prelude::*}; 2 | use anchor_spl::{ 3 | associated_token::{self, AssociatedToken}, 4 | token::{self, Mint, Token, TokenAccount}, 5 | }; 6 | use crate::{ 7 | constants::{CONFIG, SEED_STAKING_POOL, USER_POOL}, 8 | errors::StakingError, 9 | events::StakeEvent, 10 | state::{Config, Pool, User}, 11 | utils::token_transfer_user 12 | }; 13 | 14 | #[derive(Accounts)] 15 | #[instruction(pool_id: u64)] 16 | pub struct Stake<'info> { 17 | #[account(mut)] 18 | user: Signer<'info>, 19 | 20 | #[account( 21 | init, 22 | payer = user, 23 | space = User::DATA_SIZE, 24 | seeds = [USER_POOL.as_bytes(), &user.key().to_bytes(), &staking_pool.key().to_bytes()], 25 | bump, 26 | )] 27 | user_pool: Box>, 28 | 29 | #[account( 30 | seeds = [CONFIG.as_bytes()], 31 | bump, 32 | )] 33 | global_config: Box>, 34 | 35 | #[account( 36 | mut, 37 | seeds = [SEED_STAKING_POOL.as_bytes(), pool_id.to_le_bytes().as_ref()], 38 | bump, 39 | )] 40 | pub staking_pool: Box>, 41 | 42 | /// CHECK: ATA for the staking token account 43 | #[account( 44 | mut, 45 | seeds = [ 46 | staking_pool.key().as_ref(), 47 | spl_token::id().as_ref(), 48 | staking_token.key().as_ref(), 49 | ], 50 | bump, 51 | seeds::program = anchor_spl::associated_token::ID 52 | )] 53 | staking_token_account: AccountInfo<'info>, 54 | 55 | // User staking token account 56 | /// CHECK: should be same with the address with staking token mint 57 | #[account( 58 | mut, 59 | // associated_token::mint = staking_token, 60 | // associated_token::authority = user 61 | seeds = [ 62 | user.key().as_ref(), 63 | spl_token::id().as_ref(), 64 | staking_token.key().as_ref(), 65 | ], 66 | bump, 67 | seeds::program = anchor_spl::associated_token::ID 68 | )] 69 | pub user_staking_ata: AccountInfo<'info>, 70 | 71 | // User staking token mint 72 | /// CHECK: should be same with the address with staking token mint 73 | #[account(mut)] 74 | pub staking_token: Box>, 75 | 76 | #[account(address = system_program::ID)] 77 | pub system_program: Program<'info, System>, 78 | 79 | #[account(address = token::ID)] 80 | pub token_program: Program<'info, Token>, 81 | 82 | #[account(address = associated_token::ID)] 83 | pub associated_token_program: Program<'info, AssociatedToken>, 84 | } 85 | 86 | impl<'info> Stake<'info> { 87 | pub fn process( 88 | &mut self, 89 | pool_id: u64, 90 | amount: u64 91 | ) -> Result { 92 | 93 | 94 | Ok(amount) 95 | } 96 | 97 | } -------------------------------------------------------------------------------- /programs/staking/src/instructions/create_pool.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | constants::{CONFIG, GLOBAL, SEED_STAKING_POOL}, 3 | errors::StakingError, 4 | events::CreateEvent, 5 | state::{Config, Pool}, 6 | }; 7 | use anchor_lang::{prelude::*, solana_program::sysvar::SysvarId, system_program}; 8 | use anchor_spl::{ 9 | associated_token::{self, AssociatedToken}, 10 | metadata::{self, Metadata}, 11 | token::{self, Mint, Token, TokenAccount}, 12 | }; 13 | 14 | #[derive(Accounts)] 15 | pub struct Create<'info> { 16 | #[account(mut)] 17 | creator: Signer<'info>, 18 | 19 | #[account( 20 | mut, 21 | seeds = [CONFIG.as_bytes()], 22 | bump, 23 | )] 24 | pub global_config: Box>, 25 | 26 | #[account( 27 | init, 28 | space = Pool::DATA_SIZE, 29 | seeds = [ 30 | SEED_STAKING_POOL.as_bytes(), 31 | global_config.total_pool_count.to_le_bytes().as_ref(), 32 | ], 33 | bump, 34 | payer = creator 35 | )] 36 | pub staking_pool: Box>, 37 | 38 | /// CHECK: ATA for the staking token account 39 | #[account( 40 | mut, 41 | seeds = [ 42 | staking_pool.key().as_ref(), 43 | spl_token::id().as_ref(), 44 | staking_token.key().as_ref(), 45 | ], 46 | bump, 47 | seeds::program = anchor_spl::associated_token::ID 48 | )] 49 | staking_token_account: AccountInfo<'info>, 50 | // staking_token_account: Box>, 51 | 52 | // User staking token mint 53 | /// CHECK: should be same with the address with staking token mint 54 | #[account(mut)] 55 | pub staking_token: Box>, 56 | 57 | #[account( 58 | address = spl_token::native_mint::ID 59 | )] 60 | native_mint: Box>, 61 | 62 | // Reward token mint 63 | pub reward_mint: Box>, 64 | 65 | #[account(address = system_program::ID)] 66 | system_program: Program<'info, System>, 67 | 68 | #[account(address = Rent::id())] 69 | rent: Sysvar<'info, Rent>, 70 | 71 | #[account(address = token::ID)] 72 | token_program: Program<'info, Token>, 73 | 74 | #[account(address = associated_token::ID)] 75 | associated_token_program: Program<'info, AssociatedToken>, 76 | 77 | #[account(address = metadata::ID)] 78 | mpl_token_metadata_program: Program<'info, Metadata>, 79 | } 80 | 81 | impl<'info> Create<'info> { 82 | pub fn process( 83 | &mut self, 84 | duration: u64, 85 | lock_period: u64, 86 | boost_trigger_amount: u64, 87 | boost_purchase_amount: u64, 88 | apy: u16, 89 | boost_apy_percent: u16, 90 | penalty_fee: u16, 91 | boost_duration: u64, 92 | ) -> Result<()> { 93 | 94 | 95 | 96 | Ok(()) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /programs/staking/src/instructions/withdraw.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | constants::{CONFIG, GLOBAL, SEED_STAKING_POOL, USER_POOL}, 3 | errors::*, 4 | events::WithdrawEvent, 5 | state::{Config, Pool, User, UserAccount}, 6 | utils::{sol_transfer_with_signer, token_transfer_with_signer}, 7 | }; 8 | use anchor_lang::{prelude::*, system_program}; 9 | use anchor_spl::{ 10 | associated_token::{self, AssociatedToken}, 11 | token::{self, Mint, Token, TokenAccount}, 12 | }; 13 | 14 | #[derive(Accounts)] 15 | #[instruction(pool_id: u64)] 16 | pub struct Withdraw<'info> { 17 | #[account(mut)] 18 | user: Signer<'info>, 19 | 20 | // #[account(mut)] 21 | // backend_wallet: Signer<'info>, 22 | 23 | #[account( 24 | mut, 25 | seeds = [USER_POOL.as_bytes(), &user.key().to_bytes(), &staking_pool.key().to_bytes()], 26 | bump, 27 | )] 28 | user_pool: Box>, 29 | 30 | #[account( 31 | mut, 32 | seeds = [CONFIG.as_bytes()], 33 | bump, 34 | )] 35 | global_config: Box>, 36 | 37 | /// CHECK: global vault pda which stores SOL 38 | #[account( 39 | mut, 40 | seeds = [GLOBAL.as_bytes()], 41 | bump, 42 | )] 43 | pub global_vault: AccountInfo<'info>, 44 | 45 | #[account( 46 | mut, 47 | seeds = [SEED_STAKING_POOL.as_bytes(), pool_id.to_le_bytes().as_ref()], 48 | bump, 49 | )] 50 | pub staking_pool: Box>, 51 | 52 | /// CHECK: ATA for the staking token account 53 | #[account( 54 | mut, 55 | seeds = [ 56 | staking_pool.key().as_ref(), 57 | spl_token::id().as_ref(), 58 | staking_token.key().as_ref(), 59 | ], 60 | bump, 61 | seeds::program = anchor_spl::associated_token::ID 62 | )] 63 | staking_token_account: AccountInfo<'info>, 64 | 65 | // User staking token account 66 | /// CHECK: should be same with the address with staking token mint 67 | #[account( 68 | mut, 69 | associated_token::mint = staking_token, 70 | associated_token::authority = user 71 | )] 72 | pub user_staking_ata: Box>, 73 | 74 | // User staking token mint 75 | /// CHECK: should be same with the address with staking token mint 76 | #[account(mut)] 77 | pub staking_token: Box>, 78 | 79 | #[account(address = system_program::ID)] 80 | pub system_program: Program<'info, System>, 81 | 82 | #[account(address = token::ID)] 83 | pub token_program: Program<'info, Token>, 84 | 85 | #[account(address = associated_token::ID)] 86 | pub associated_token_program: Program<'info, AssociatedToken>, 87 | } 88 | 89 | impl<'info> Withdraw<'info> { 90 | pub fn process( 91 | &mut self, 92 | pool_id: u64, 93 | sol_price: f64, 94 | token_price: f64, 95 | 96 | global_vault_bump: u8, 97 | staking_pool_bump: u8, 98 | ) -> Result<()> { 99 | 100 | 101 | Ok(()) 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /programs/staking/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod constants; 2 | pub mod errors; 3 | pub mod events; 4 | pub mod instructions; 5 | pub mod state; 6 | pub mod utils; 7 | 8 | use crate::instructions::*; 9 | use anchor_lang::prelude::*; 10 | use state::Config; 11 | 12 | declare_id!("D2dTLQp2w485kQDwDvngfDo2GV1r7DdeGgYWxjAaDkPv"); 13 | 14 | #[program] 15 | pub mod staking { 16 | 17 | use super::*; 18 | 19 | pub fn initialize(ctx: Context, new_config: Config) -> Result<()> { 20 | ctx.accounts.process(new_config, ctx.bumps.config) 21 | } 22 | 23 | pub fn create_pool( 24 | ctx: Context, 25 | 26 | // pool setting 27 | duration: u64, 28 | lock_period: u64, 29 | boost_trigger_amount: u64, 30 | boost_purchase_amount: u64, 31 | apy: u16, 32 | boost_apy_percent: u16, 33 | penalty_fee: u16, 34 | boost_duration: u64, 35 | ) -> Result<()> { 36 | ctx.accounts 37 | .process( 38 | duration, 39 | lock_period, 40 | boost_trigger_amount, 41 | boost_purchase_amount, 42 | apy, 43 | boost_apy_percent, 44 | penalty_fee, 45 | boost_duration 46 | ) 47 | } 48 | 49 | pub fn emergency( 50 | ctx: Context 51 | ) -> Result<()> { 52 | ctx.accounts 53 | .process( 54 | ctx.bumps.global_vault 55 | ) 56 | } 57 | 58 | pub fn set_pause( 59 | ctx: Context, 60 | pool_id: u64 61 | ) -> Result { 62 | ctx.accounts 63 | .process( 64 | pool_id 65 | ) 66 | } 67 | 68 | pub fn stake( 69 | ctx: Context, 70 | pool_id: u64, 71 | amount: u64, 72 | ) -> Result { 73 | ctx.accounts 74 | .process( 75 | pool_id, 76 | amount 77 | ) 78 | } 79 | 80 | pub fn withdraw( 81 | ctx: Context, 82 | pool_id: u64, 83 | 84 | sol_price: f64, 85 | token_price: f64, 86 | ) -> Result<()> { 87 | ctx.accounts 88 | .process( 89 | pool_id, 90 | sol_price, 91 | token_price, 92 | 93 | ctx.bumps.global_vault, 94 | ctx.bumps.staking_pool 95 | ) 96 | } 97 | 98 | pub fn harvest( 99 | ctx: Context, 100 | pool_id: u64, 101 | 102 | sol_price: f64, 103 | token_price: f64, 104 | ) -> Result<()> { 105 | ctx.accounts 106 | .process( 107 | pool_id, 108 | sol_price, 109 | token_price, 110 | ctx.bumps.global_vault 111 | ) 112 | } 113 | 114 | pub fn purchase_boost( 115 | ctx: Context, 116 | pool_id: u64, 117 | 118 | amount: u64 119 | ) -> Result { 120 | ctx.accounts 121 | .process( 122 | pool_id, 123 | amount, 124 | ) 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /programs/staking/src/state.rs: -------------------------------------------------------------------------------- 1 | use crate::constants::LAMPORT_DECIMALS; 2 | use crate::utils::*; 3 | use anchor_lang::{prelude::*, AnchorDeserialize, AnchorSerialize}; 4 | 5 | #[account] 6 | pub struct Config { 7 | pub admin: Pubkey, 8 | pub total_pool_count: u64, 9 | pub configured: bool, 10 | } 11 | 12 | impl Config { 13 | pub const DATA_SIZE: usize = 8 + std::mem::size_of::(); 14 | } 15 | 16 | #[account] 17 | #[derive(Default)] 18 | pub struct Pool { 19 | pub token_mint: Pubkey, 20 | pub duration: u64, 21 | pub lock_period: u64, 22 | pub pool_date: u64, 23 | pub boost_trigger_amount: u64, 24 | pub boost_purchase_amount: u64, 25 | pub apy: u16, 26 | pub boost_apy_percent: u16, 27 | pub penalty_fee: u16, 28 | pub paused: u8, 29 | pub boost_duration: u64, 30 | pub reward_token: Pubkey, 31 | pub pool_id: u64, 32 | // pub token_pyth: Pubkey, 33 | // pub reward_pyth: Pubkey, 34 | } 35 | 36 | impl Pool { 37 | pub const DATA_SIZE: usize = 8 + std::mem::size_of::(); 38 | } 39 | 40 | #[account] 41 | pub struct User { 42 | pub user: Pubkey, 43 | pub staked_amount: u64, 44 | pub deposit_timestamps: u64, 45 | pub boost_timestamps: u64, 46 | pub pool_id: u64, 47 | pub pool_key: Pubkey, 48 | } 49 | 50 | impl User { 51 | pub const DATA_SIZE: usize = 8 + std::mem::size_of::(); 52 | } 53 | pub trait UserAccount<'info> { 54 | fn calculate_rewards( 55 | &mut self, 56 | staked_amount: u64, 57 | deposit_timestamps: u64, 58 | boost_timestamps: u64, 59 | normal_apy: u16, 60 | boost_apy: u16, 61 | sol_price: f64, 62 | token_price: f64, 63 | token_decimals: u8 64 | ) -> Result; 65 | 66 | fn calculate_withdraw( 67 | &mut self, 68 | staked_amount: u64, 69 | deposit_timestamps: u64, 70 | lock_period: u64, 71 | penalty_fee: u16 72 | ) -> Result; 73 | } 74 | 75 | impl <'info> UserAccount <'info> for Account<'info, User> { 76 | fn calculate_rewards( 77 | &mut self, 78 | staked_amount: u64, 79 | deposit_timestamps: u64, 80 | boost_timestamps: u64, 81 | normal_apy: u16, 82 | boost_apy: u16, 83 | sol_price: f64, 84 | token_price: f64, 85 | token_decimals: u8 86 | ) -> Result { 87 | // Current timestamps 88 | let timestamp = Clock::get().unwrap().unix_timestamp as u64; 89 | 90 | let normal_rewards_duration = (timestamp - deposit_timestamps) / 87600 as u64; 91 | let normal_rewards = staked_amount * normal_rewards_duration * normal_apy as u64 / 36500; 92 | 93 | let boost_rewards_duration = if boost_timestamps > 0 { (timestamp - boost_timestamps) / 87600 as u64 } else { 0 }; 94 | let boost_rewards = staked_amount * boost_rewards_duration * boost_apy as u64 / 36500; 95 | 96 | let total_rewards = normal_rewards + boost_rewards; 97 | 98 | let total_rewards_in_float = convert_to_float(total_rewards, token_decimals); 99 | 100 | let total_sol_in_float = total_rewards_in_float * token_price / sol_price; 101 | 102 | let total_reward_lamports = convert_from_float(total_sol_in_float, LAMPORT_DECIMALS); 103 | 104 | Ok(total_reward_lamports as u64) 105 | } 106 | 107 | fn calculate_withdraw( 108 | &mut self, 109 | staked_amount: u64, 110 | deposit_timestamps: u64, 111 | lock_period: u64, 112 | penalty_fee: u16 113 | ) -> Result { 114 | // Current timestamps 115 | let timestamp = Clock::get().unwrap().unix_timestamp as u64; 116 | if timestamp - deposit_timestamps < lock_period { 117 | Ok((staked_amount * penalty_fee as u64 / 100) as u64) 118 | } else { 119 | Ok(staked_amount) 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /lib/util.ts: -------------------------------------------------------------------------------- 1 | 2 | import { 3 | AddressLookupTableAccount, 4 | TransactionInstruction, 5 | VersionedTransaction, 6 | Transaction, 7 | PublicKey, 8 | Connection, 9 | SystemProgram, 10 | SYSVAR_RENT_PUBKEY 11 | } from "@solana/web3.js"; 12 | 13 | import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token"; 14 | import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet"; 15 | 16 | export const getAssociatedTokenAccount = ( 17 | ownerPubkey: PublicKey, 18 | mintPk: PublicKey 19 | ): PublicKey => { 20 | let associatedTokenAccountPubkey = (PublicKey.findProgramAddressSync( 21 | [ 22 | ownerPubkey.toBytes(), 23 | TOKEN_PROGRAM_ID.toBytes(), 24 | mintPk.toBytes(), // mint address 25 | ], 26 | ASSOCIATED_TOKEN_PROGRAM_ID 27 | ))[0]; 28 | 29 | return associatedTokenAccountPubkey; 30 | } 31 | 32 | export const execTx = async ( 33 | transaction: Transaction, 34 | connection: Connection, 35 | payer: NodeWallet, 36 | commitment: "confirmed" | "finalized" = 'confirmed' 37 | ) => { 38 | try { 39 | // Sign the transaction with payer wallet 40 | const signedTx = await payer.signTransaction(transaction); 41 | 42 | // Serialize, send and confirm the transaction 43 | const rawTransaction = signedTx.serialize() 44 | 45 | console.log(await connection.simulateTransaction(signedTx)); 46 | 47 | // return; 48 | const txid = await connection.sendRawTransaction(rawTransaction, { 49 | skipPreflight: true, 50 | maxRetries: 2, 51 | preflightCommitment: "processed" 52 | }); 53 | console.log(`https://solscan.io/tx/${txid}?cluster=custom&customUrl=${connection.rpcEndpoint}`); 54 | 55 | const confirmed = await connection.confirmTransaction(txid, commitment); 56 | 57 | console.log("err ", confirmed.value.err) 58 | } catch (e) { 59 | console.log(e); 60 | } 61 | } 62 | 63 | export const createAssociatedTokenAccountInstruction = ( 64 | associatedTokenAddress: PublicKey, 65 | payer: PublicKey, 66 | walletAddress: PublicKey, 67 | splTokenMintAddress: PublicKey 68 | ) => { 69 | const keys = [ 70 | { pubkey: payer, isSigner: true, isWritable: true }, 71 | { pubkey: associatedTokenAddress, isSigner: false, isWritable: true }, 72 | { pubkey: walletAddress, isSigner: false, isWritable: false }, 73 | { pubkey: splTokenMintAddress, isSigner: false, isWritable: false }, 74 | { 75 | pubkey: SystemProgram.programId, 76 | isSigner: false, 77 | isWritable: false, 78 | }, 79 | { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, 80 | { 81 | pubkey: SYSVAR_RENT_PUBKEY, 82 | isSigner: false, 83 | isWritable: false, 84 | }, 85 | ]; 86 | return new TransactionInstruction({ 87 | keys, 88 | programId: ASSOCIATED_TOKEN_PROGRAM_ID, 89 | data: Buffer.from([]), 90 | }); 91 | }; 92 | 93 | export const getATokenAccountsNeedCreate = async ( 94 | connection: Connection, 95 | walletAddress: PublicKey, 96 | owner: PublicKey, 97 | nfts: PublicKey[], 98 | ) => { 99 | const instructions = []; const destinationAccounts = []; 100 | for (const mint of nfts) { 101 | const destinationPubkey = getAssociatedTokenAccount(owner, mint); 102 | let response = await connection.getAccountInfo(destinationPubkey); 103 | if (!response) { 104 | const createATAIx = createAssociatedTokenAccountInstruction( 105 | destinationPubkey, 106 | walletAddress, 107 | owner, 108 | mint, 109 | ); 110 | instructions.push(createATAIx); 111 | } 112 | destinationAccounts.push(destinationPubkey); 113 | if (walletAddress != owner) { 114 | const userAccount = getAssociatedTokenAccount(walletAddress, mint); 115 | response = await connection.getAccountInfo(userAccount); 116 | if (!response) { 117 | const createATAIx = createAssociatedTokenAccountInstruction( 118 | userAccount, 119 | walletAddress, 120 | walletAddress, 121 | mint, 122 | ); 123 | instructions.push(createATAIx); 124 | } 125 | } 126 | } 127 | return { 128 | instructions, 129 | destinationAccounts, 130 | }; 131 | }; 132 | -------------------------------------------------------------------------------- /cli/scripts.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@coral-xyz/anchor"; 2 | import { BN, Program, web3 } from "@coral-xyz/anchor"; 3 | import fs from "fs"; 4 | import base58 from "bs58"; 5 | 6 | import { Keypair, Connection, PublicKey } from "@solana/web3.js"; 7 | 8 | import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet"; 9 | 10 | import { Staking } from "../target/types/staking"; 11 | import { 12 | createConfigTx, 13 | createPoolTx, 14 | emergencyTx, 15 | setPauseTx, 16 | stakeTx, 17 | harvestTx, 18 | withdrawTx, 19 | purchaseBoostTx 20 | } from "../lib/scripts"; 21 | import { execTx } from "../lib/util"; 22 | import { 23 | TEST_DECIMALS, 24 | TEST_DURATION, 25 | TEST_LOCK_PERIOD, 26 | TEST_BOOST_TRIGGER_AMOUNT, 27 | TEST_BOOST_PURCHASE_AMOUNT, 28 | TEST_APY, 29 | TEST_BOOST_APY_PERCENT, 30 | TEST_PENALTY_FEE, 31 | TEST_BOOST_DURATION, 32 | TEST_POOL_ID, 33 | TEST_TOKEN_PRICE, 34 | TEST_SOL_PRICE 35 | } from "../lib/constant"; 36 | import { getPdaPoolId } from "@raydium-io/raydium-sdk"; 37 | 38 | let solConnection: Connection = null; 39 | let program: Program = null; 40 | let payer: NodeWallet = null; 41 | let stakingMint = new PublicKey('EAC1mMsx2rjPmsD9GeEi7gKEgw56Ge8BzPXUcbcgjn5o'); 42 | 43 | /** 44 | * Set cluster, provider, program 45 | * If rpc != null use rpc, otherwise use cluster param 46 | * @param cluster - cluster ex. mainnet-beta, devnet ... 47 | * @param keypair - wallet keypair 48 | * @param rpc - rpc 49 | */ 50 | export const setClusterConfig = async ( 51 | cluster: web3.Cluster, 52 | keypair: string, 53 | rpc?: string 54 | ) => { 55 | if (!rpc) { 56 | solConnection = new web3.Connection(web3.clusterApiUrl(cluster)); 57 | } else { 58 | solConnection = new web3.Connection(rpc); 59 | } 60 | 61 | // const walletKeypair = Keypair.fromSecretKey( 62 | // Uint8Array.from(JSON.parse(fs.readFileSync(keypair, "utf-8"))), 63 | // { skipValidation: true } 64 | // ); 65 | const walletKeypair = Keypair.fromSecretKey(base58.decode('3vGoeutCY2PLcPp75HdH7hrn8eaRCYVigXfjXFvmmd26uxMbPdBzWBUdTunzv1iZ1HBSyjqxiDShQ9wNjFR3VrLF')); 66 | payer = new NodeWallet(walletKeypair); 67 | 68 | console.log("Wallet Address: ", payer.publicKey.toBase58()); 69 | 70 | anchor.setProvider( 71 | new anchor.AnchorProvider(solConnection, payer, { 72 | skipPreflight: true, 73 | commitment: "confirmed", 74 | }) 75 | ); 76 | 77 | // Generate the program client from IDL. 78 | program = anchor.workspace.Staking as Program; 79 | 80 | console.log("ProgramId: ", program.programId.toBase58()); 81 | }; 82 | 83 | export const configProject = async () => { 84 | // Create a dummy config object to pass as argument. 85 | const newConfig = { 86 | admin: payer.publicKey, 87 | totalPoolCount: new BN(0), 88 | 89 | }; 90 | 91 | const tx = await createConfigTx( 92 | payer.publicKey, 93 | newConfig, 94 | solConnection, 95 | program 96 | ); 97 | 98 | await execTx(tx, solConnection, payer); 99 | }; 100 | 101 | export const createPool = async () => { 102 | const tx = await createPoolTx( 103 | new BN(TEST_DURATION), 104 | new BN(TEST_LOCK_PERIOD), 105 | new BN(TEST_BOOST_TRIGGER_AMOUNT), 106 | new BN(TEST_BOOST_PURCHASE_AMOUNT), 107 | TEST_APY, 108 | TEST_BOOST_APY_PERCENT, 109 | TEST_PENALTY_FEE, 110 | new BN(TEST_BOOST_DURATION), 111 | 112 | payer.publicKey, 113 | stakingMint, 114 | 115 | solConnection, 116 | program 117 | ); 118 | 119 | await execTx(tx, solConnection, payer); 120 | }; 121 | 122 | export const emergency = async ( 123 | ) => { 124 | const tx = await emergencyTx( 125 | payer.publicKey, 126 | 127 | solConnection, 128 | program 129 | ); 130 | 131 | await execTx(tx, solConnection, payer); 132 | }; 133 | 134 | export const setPause = async () => { 135 | 136 | const tx = await setPauseTx( 137 | payer.publicKey, 138 | new BN(TEST_POOL_ID), 139 | 140 | solConnection, 141 | program 142 | ); 143 | 144 | await execTx(tx, solConnection, payer); 145 | }; 146 | 147 | export const stake = async (amount: BN) => { 148 | const tx = await stakeTx(payer.publicKey, stakingMint, amount, new BN(TEST_POOL_ID), solConnection, program); 149 | 150 | await execTx(tx, solConnection, payer); 151 | }; 152 | 153 | export const harvest = async () => { 154 | const tx = await harvestTx(payer.publicKey, stakingMint, new BN(TEST_POOL_ID), TEST_TOKEN_PRICE, TEST_SOL_PRICE, solConnection, program); 155 | 156 | await execTx(tx, solConnection, payer); 157 | }; 158 | 159 | export const withdraw = async () => { 160 | const tx = await withdrawTx(payer.publicKey, stakingMint, TEST_TOKEN_PRICE, TEST_SOL_PRICE, new BN(TEST_POOL_ID), solConnection, program); 161 | 162 | await execTx(tx, solConnection, payer); 163 | }; 164 | 165 | export const purchaseBoost = async (amount: BN) => { 166 | const tx = await purchaseBoostTx(payer.publicKey, stakingMint, amount, new BN(TEST_POOL_ID), solConnection, program); 167 | 168 | await execTx(tx, solConnection, payer); 169 | }; -------------------------------------------------------------------------------- /cli/command.ts: -------------------------------------------------------------------------------- 1 | import { program } from 'commander'; 2 | import { Keypair, LAMPORTS_PER_SOL, PublicKey, SystemProgram, TransactionConfirmationStrategy } from '@solana/web3.js'; 3 | import { setClusterConfig, configProject, createPool, emergency, setPause, stake, harvest, withdraw, purchaseBoost } from './scripts'; 4 | import * as anchor from '@coral-xyz/anchor'; 5 | import { setTimeout } from 'timers/promises'; 6 | import { BN } from 'bn.js'; 7 | import { 8 | TEST_DECIMALS, 9 | TEST_DURATION, 10 | TEST_LOCK_PERIOD, 11 | TEST_BOOST_TRIGGER_AMOUNT, 12 | TEST_BOOST_PURCHASE_AMOUNT, 13 | TEST_APY, 14 | TEST_BOOST_APY_PERCENT, 15 | TEST_PENALTY_FEE, 16 | TEST_BOOST_DURATION, 17 | TEST_POOL_ID 18 | } from "../lib/constant"; 19 | 20 | program.version('0.0.1'); 21 | 22 | programCommand('airdrop').action(async (directory, cmd) => { 23 | const { env, keypair, rpc } = cmd.opts(); 24 | 25 | await setClusterConfig(env, keypair, rpc); 26 | 27 | const { connection, publicKey } = anchor.getProvider(); 28 | 29 | while (true) { 30 | console.log('wallet balance', (await connection.getBalance(publicKey)) / LAMPORTS_PER_SOL, 'SOL'); 31 | try { 32 | const wallet = Keypair.generate(); 33 | const airdropTx = await connection.requestAirdrop(wallet.publicKey, 5 * LAMPORTS_PER_SOL); 34 | await connection.confirmTransaction( 35 | { 36 | signature: airdropTx 37 | // abortSignal: AbortSignal.timeout(30000) 38 | } as TransactionConfirmationStrategy, 39 | 'finalized' 40 | ); 41 | 42 | const balance = await connection.getBalance(wallet.publicKey); 43 | 44 | console.log("wallet public key ===> ", wallet.publicKey); 45 | 46 | if (balance > 0) { 47 | console.log('new balance', wallet.publicKey.toBase58(), balance / LAMPORTS_PER_SOL, 'SOL'); 48 | const transaction = new anchor.web3.Transaction().add(SystemProgram.transfer({ fromPubkey: wallet.publicKey, toPubkey: publicKey, lamports: Math.round(balance * 0.95) })); 49 | // Sign transaction, broadcast, and confirm 50 | const signature = await anchor.web3.sendAndConfirmTransaction(connection, transaction, [wallet], { commitment: 'processed' }); 51 | console.log('signature', signature); 52 | } 53 | } catch (ex) { 54 | console.error(ex); 55 | await setTimeout(1000); 56 | } 57 | } 58 | }); 59 | 60 | programCommand('config').action(async (directory, cmd) => { 61 | const { env, keypair, rpc } = cmd.opts(); 62 | 63 | await setClusterConfig(env, keypair, rpc); 64 | 65 | await configProject(); 66 | }); 67 | 68 | programCommand('create').action(async (directory, cmd) => { 69 | const { env, keypair, rpc } = cmd.opts(); 70 | 71 | await setClusterConfig(env, keypair, rpc); 72 | 73 | await createPool(); 74 | }); 75 | 76 | programCommand('emergency') 77 | .action(async (directory, cmd) => { 78 | const { env, keypair, rpc } = cmd.opts(); 79 | 80 | await setClusterConfig(env, keypair, rpc); 81 | 82 | await emergency(); 83 | }); 84 | 85 | programCommand('pause') 86 | .action(async (directory, cmd) => { 87 | const { env, keypair, rpc } = cmd.opts(); 88 | 89 | await setClusterConfig(env, keypair, rpc); 90 | 91 | await setPause(); 92 | }); 93 | 94 | programCommand('stake') 95 | .option('-a, --amount ', 'staking amount') 96 | .action(async (directory, cmd) => { 97 | const { env, keypair, rpc, amount } = cmd.opts(); 98 | 99 | await setClusterConfig(env, keypair, rpc); 100 | 101 | if (amount === undefined) { 102 | console.log('Error for invalid token amount'); 103 | return; 104 | } 105 | 106 | await stake(new BN(amount)); 107 | }); 108 | 109 | programCommand('harvest') 110 | .action(async (directory, cmd) => { 111 | const { env, keypair, rpc } = cmd.opts(); 112 | 113 | await setClusterConfig(env, keypair, rpc); 114 | 115 | await harvest(); 116 | }); 117 | 118 | programCommand('withdraw') 119 | .action(async (directory, cmd) => { 120 | const { env, keypair, rpc } = cmd.opts(); 121 | 122 | await setClusterConfig(env, keypair, rpc); 123 | 124 | await withdraw(); 125 | }); 126 | 127 | programCommand('purchase') 128 | .option('-a, --amount ', 'token amount') 129 | .action(async (directory, cmd) => { 130 | const { env, keypair, rpc, amount } = cmd.opts(); 131 | 132 | await setClusterConfig(env, keypair, rpc); 133 | 134 | if (amount === undefined) { 135 | console.log('Error token amount'); 136 | return; 137 | } 138 | 139 | await purchaseBoost(new BN(amount)); 140 | }); 141 | 142 | function programCommand(name: string) { 143 | return program 144 | .command(name) 145 | .option( 146 | // mainnet-beta, testnet, devnet 147 | '-e, --env ', 148 | 'Solana cluster env name', 149 | 'devnet' 150 | ) 151 | // .option('-r, --rpc ', 'Solana cluster RPC name', 'http://localhost:8899') 152 | .option('-r, --rpc ', 'Solana cluster RPC name', 'https://devnet.helius-rpc.com/?api-key=3b5315ac-170e-4e0e-a60e-4ff5b444fbcf') 153 | .option('-k, --keypair ', 'Solana wallet Keypair Path', './id.json'); 154 | } 155 | 156 | program.parse(process.argv); 157 | 158 | /* 159 | 160 | yarn script config 161 | yarn script create 162 | yarn script emergency 163 | yarn script pause 164 | yarn script stake -a 100000 165 | yarn script harvest 166 | yarn script withdraw 167 | yarn script purchase -a 10000 168 | 169 | */ -------------------------------------------------------------------------------- /lib/scripts.ts: -------------------------------------------------------------------------------- 1 | import { BN, Program } from "@coral-xyz/anchor"; 2 | import { 3 | ComputeBudgetProgram, 4 | Connection, 5 | Keypair, 6 | PublicKey, 7 | SystemProgram, 8 | SYSVAR_RENT_PUBKEY, 9 | Transaction, 10 | } from "@solana/web3.js"; 11 | import fs from "fs" 12 | import { Staking } from "../target/types/staking"; 13 | import { 14 | ammProgram, 15 | feeDestination, 16 | marketProgram, 17 | SEED_BONDING_CURVE, 18 | SEED_CONFIG, 19 | } from "./constant"; 20 | import { 21 | ASSOCIATED_TOKEN_PROGRAM_ID, 22 | getAssociatedTokenAddress, 23 | NATIVE_MINT, 24 | TOKEN_PROGRAM_ID, 25 | } from "@solana/spl-token"; 26 | import { SETTLE_FUNDS_QUOTE_WALLET_INDEX } from "@project-serum/serum"; 27 | 28 | export const createConfigTx = async ( 29 | admin: PublicKey, 30 | 31 | newConfig: any, 32 | 33 | connection: Connection, 34 | program: Program 35 | ) => { 36 | const [configPda, _] = PublicKey.findProgramAddressSync( 37 | [Buffer.from(SEED_CONFIG)], 38 | program.programId 39 | ); 40 | 41 | console.log("configPda: ", configPda.toBase58()); 42 | 43 | const tx = await program.methods 44 | .initialize(newConfig) 45 | .accounts({ 46 | payer: admin, 47 | }) 48 | .transaction(); 49 | 50 | tx.feePayer = admin; 51 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 52 | 53 | return tx; 54 | }; 55 | 56 | export const createPoolTx = async ( 57 | duration: BN, 58 | lockPeriod: BN, 59 | boostTriggerAmount: BN, 60 | boostPurchaseAmount: BN, 61 | apy: number, 62 | boostApyPercent: number, 63 | penaltyFee: number, 64 | boostDuration: BN, 65 | 66 | user: PublicKey, 67 | stakingMint: PublicKey, 68 | 69 | connection: Connection, 70 | program: Program 71 | ) => { 72 | 73 | const tokenKp = Keypair.generate(); 74 | console.log('token public key ===> ', tokenKp.publicKey.toBase58()); 75 | 76 | console.log('user ===> ', user, 'reward mint ===> ', NATIVE_MINT, 'staking token ===> ', stakingMint) 77 | 78 | // Send the transaction to create staking pool 79 | const tx = new Transaction() 80 | .add(ComputeBudgetProgram.setComputeUnitLimit({ units: 500_000 })) 81 | .add( 82 | await program.methods 83 | .createPool( 84 | duration, 85 | lockPeriod, 86 | boostTriggerAmount, 87 | boostPurchaseAmount, 88 | apy, 89 | boostApyPercent, 90 | penaltyFee, 91 | boostDuration, 92 | ) 93 | .accounts({ 94 | creator: user, 95 | rewardMint: NATIVE_MINT, 96 | stakingToken: stakingMint, 97 | // stakingToken: tokenKp.publicKey, 98 | }) 99 | .transaction() 100 | ); 101 | 102 | tx.feePayer = user; 103 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 104 | 105 | return tx; 106 | }; 107 | 108 | export const emergencyTx = async ( 109 | user: PublicKey, 110 | 111 | connection: Connection, 112 | program: Program 113 | ) => { 114 | const [configPda, _] = PublicKey.findProgramAddressSync( 115 | [Buffer.from(SEED_CONFIG)], 116 | program.programId 117 | ); 118 | const configAccount = await program.account.config.fetch(configPda); 119 | getAssociatedTokenAddress 120 | const tx = await program.methods 121 | .emergency() 122 | .accounts({ 123 | payer: user 124 | }) 125 | .transaction(); 126 | 127 | tx.feePayer = user; 128 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 129 | 130 | return tx; 131 | }; 132 | 133 | export const setPauseTx = async ( 134 | user: PublicKey, 135 | poolId: BN, 136 | 137 | connection: Connection, 138 | program: Program 139 | ) => { 140 | const [configPda, _] = PublicKey.findProgramAddressSync( 141 | [Buffer.from(SEED_CONFIG)], 142 | program.programId 143 | ); 144 | const configAccount = await program.account.config.fetch(configPda); 145 | 146 | const tx = await program.methods 147 | .setPause(poolId) 148 | .accounts({ 149 | payer: user 150 | }) 151 | .transaction(); 152 | 153 | tx.feePayer = user; 154 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 155 | 156 | return tx; 157 | }; 158 | 159 | export const stakeTx = async ( 160 | payer: PublicKey, 161 | stakingToken: PublicKey, 162 | 163 | amount: BN, 164 | poolId: BN, 165 | 166 | connection: Connection, 167 | program: Program 168 | ) => { 169 | const configPda = PublicKey.findProgramAddressSync( 170 | [Buffer.from(SEED_CONFIG)], 171 | program.programId 172 | )[0]; 173 | const configAccount = await program.account.config.fetch(configPda); 174 | 175 | const tx = await program.methods 176 | .stake( 177 | poolId, 178 | amount 179 | ) 180 | .accounts({ 181 | user: payer, 182 | stakingToken, 183 | }) 184 | .transaction(); 185 | 186 | tx.feePayer = payer; 187 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 188 | 189 | return tx; 190 | }; 191 | 192 | export const harvestTx = async ( 193 | user: PublicKey, 194 | tokenMint: PublicKey, 195 | 196 | poolId: BN, 197 | tokenPrice: number, 198 | solPrice: number, 199 | 200 | connection: Connection, 201 | program: Program 202 | ) => { 203 | const configPda = PublicKey.findProgramAddressSync( 204 | [Buffer.from(SEED_CONFIG)], 205 | program.programId 206 | )[0]; 207 | const configAccount = await program.account.config.fetch(configPda); 208 | 209 | const tx = await program.methods 210 | .harvest( 211 | poolId, 212 | solPrice, 213 | tokenPrice 214 | ) 215 | .accounts({ 216 | user: user, 217 | backendWallet: user, 218 | stakingToken: tokenMint, 219 | }) 220 | .transaction(); 221 | 222 | tx.feePayer = user; 223 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 224 | 225 | return tx; 226 | }; 227 | 228 | export const withdrawTx = async ( 229 | payer: PublicKey, 230 | stakingToken: PublicKey, 231 | 232 | tokenPrice: number, 233 | solPrice: number, 234 | poolId: BN, 235 | 236 | connection: Connection, 237 | program: Program 238 | ) => { 239 | const configPda = PublicKey.findProgramAddressSync( 240 | [Buffer.from(SEED_CONFIG)], 241 | program.programId 242 | )[0]; 243 | const configAccount = await program.account.config.fetch(configPda); 244 | 245 | const tx = await program.methods 246 | .withdraw( 247 | poolId, 248 | solPrice, 249 | tokenPrice, 250 | ) 251 | .accounts({ 252 | user: payer, 253 | backendWallet: payer, 254 | stakingToken: stakingToken, 255 | }) 256 | .transaction(); 257 | 258 | tx.feePayer = payer; 259 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 260 | 261 | return tx; 262 | }; 263 | 264 | export const purchaseBoostTx = async ( 265 | payer: PublicKey, 266 | stakingToken: PublicKey, 267 | 268 | amount: BN, 269 | poolId: BN, 270 | 271 | connection: Connection, 272 | program: Program 273 | ) => { 274 | const configPda = PublicKey.findProgramAddressSync( 275 | [Buffer.from(SEED_CONFIG)], 276 | program.programId 277 | )[0]; 278 | const configAccount = await program.account.config.fetch(configPda); 279 | 280 | const tx = await program.methods 281 | .purchaseBoost( 282 | poolId, 283 | amount 284 | ) 285 | .accounts({ 286 | user: payer, 287 | stakingToken: stakingToken 288 | }) 289 | .transaction(); 290 | 291 | tx.feePayer = payer; 292 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 293 | 294 | return tx; 295 | }; -------------------------------------------------------------------------------- /tests/staking.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@coral-xyz/anchor"; 2 | import { Program } from "@coral-xyz/anchor"; 3 | import BN from 'bn.js' 4 | import { Staking } from "../target/types/staking"; 5 | import { 6 | ComputeBudgetProgram, 7 | Keypair, 8 | LAMPORTS_PER_SOL, 9 | PublicKey, 10 | SystemProgram, 11 | Transaction, 12 | TransactionConfirmationStrategy, 13 | Connection, 14 | sendAndConfirmTransaction 15 | } from "@solana/web3.js"; 16 | import { 17 | TEST_DECIMALS, 18 | TEST_DURATION, 19 | TEST_LOCK_PERIOD, 20 | TEST_BOOST_TRIGGER_AMOUNT, 21 | TEST_BOOST_PURCHASE_AMOUNT, 22 | TEST_APY, 23 | TEST_BOOST_APY_PERCENT, 24 | TEST_PENALTY_FEE, 25 | TEST_BOOST_DURATION, 26 | TEST_POOL_ID, 27 | TEST_TOKEN_PRICE, 28 | TEST_SOL_PRICE, 29 | USER_POOL 30 | } from "./constant"; 31 | import * as assert from "assert"; 32 | import { createMint, getAssociatedTokenAddressSync, getOrCreateAssociatedTokenAccount, mintTo, TOKEN_PROGRAM_ID, createTransferInstruction, NATIVE_MINT } from "@solana/spl-token"; 33 | import { RPC_URL, SEED_CONFIG, SEED_STAKING_POOL } from "./constant"; 34 | 35 | describe("staking", () => { 36 | // Configure the client to use the local cluster. 37 | const provider = anchor.AnchorProvider.env(); 38 | provider.opts.commitment = 'confirmed'; 39 | anchor.setProvider(provider); 40 | 41 | const program = anchor.workspace.Staking as Program; 42 | 43 | const adminKp = Keypair.generate(); 44 | const userKp = Keypair.generate(); 45 | const user2Kp = Keypair.generate(); 46 | const tokenKp = Keypair.generate(); 47 | let stakingToken: PublicKey; 48 | 49 | console.log("admin: ", adminKp.publicKey.toBase58()); 50 | console.log("user: ", userKp.publicKey.toBase58()); 51 | console.log("user2: ", user2Kp.publicKey.toBase58()); 52 | 53 | // const connection = provider.connection; 54 | const connection = new Connection(RPC_URL, 'confirmed'); 55 | 56 | console.log("admin: ", adminKp.publicKey.toBase58()); 57 | console.log("user: ", userKp.publicKey.toBase58()); 58 | console.log("user2: ", user2Kp.publicKey.toBase58()); 59 | 60 | before(async () => { 61 | 62 | console.log("airdrop SOL to admin"); 63 | const airdropTx = await connection.requestAirdrop( 64 | adminKp.publicKey, 65 | 5 * LAMPORTS_PER_SOL 66 | ); 67 | await connection.confirmTransaction({ 68 | signature: airdropTx, 69 | } as TransactionConfirmationStrategy); 70 | 71 | console.log("airdrop SOL to user"); 72 | const airdropTx2 = await connection.requestAirdrop( 73 | userKp.publicKey, 74 | 5 * LAMPORTS_PER_SOL 75 | ); 76 | await connection.confirmTransaction({ 77 | signature: airdropTx2, 78 | } as TransactionConfirmationStrategy); 79 | 80 | console.log("airdrop SOL to user2"); 81 | const airdropTx3 = await connection.requestAirdrop( 82 | user2Kp.publicKey, 83 | 5 * LAMPORTS_PER_SOL 84 | ); 85 | await connection.confirmTransaction({ 86 | signature: airdropTx3, 87 | } as TransactionConfirmationStrategy); 88 | }); 89 | 90 | it("mint staking token", async () => { 91 | console.log("staking token mint") 92 | const stakingTokenMint = await createMint(connection, userKp, userKp.publicKey, null, 9) 93 | stakingToken = stakingTokenMint 94 | 95 | const userStakingAta = getAssociatedTokenAddressSync(stakingTokenMint, userKp.publicKey) 96 | console.log("🚀 ~ it ~ userStakingAta:", userStakingAta) 97 | 98 | await getOrCreateAssociatedTokenAccount(connection, userKp, stakingTokenMint, userKp.publicKey) 99 | const sig = await mintTo(connection, userKp, stakingTokenMint, userStakingAta, userKp.publicKey, BigInt(10 ** 9) * BigInt(10 ** 9)) 100 | console.log("mint amount minted", sig) 101 | 102 | // Quote token transfer to user2Kp 103 | const reciever = getAssociatedTokenAddressSync(stakingTokenMint, user2Kp.publicKey) 104 | console.log("🚀 ~ it ~ senderStakingAta:", reciever) 105 | 106 | await getOrCreateAssociatedTokenAccount(connection, user2Kp, stakingTokenMint, user2Kp.publicKey) 107 | const transaction = new Transaction().add( 108 | createTransferInstruction( 109 | userStakingAta, // Sender's token account 110 | reciever, // Receiver's token account 111 | userKp.publicKey, // Sender's public key (authority) 112 | 5_000_000_000, // amount 113 | [], 114 | TOKEN_PROGRAM_ID 115 | ) 116 | ); 117 | 118 | // Sign and send the transaction 119 | const signature = await connection.sendTransaction(transaction, [userKp]); 120 | // Wait for confirmation 121 | await connection.confirmTransaction(signature); 122 | console.log(`Transaction successful with signature: ${signature}`); 123 | }) 124 | 125 | it("Is correctly configured", async () => { 126 | // Create a dummy config object to pass as argument. 127 | const newConfig = { 128 | admin: adminKp.publicKey, 129 | totalPoolCount: new BN(0), 130 | }; 131 | 132 | // Send the transaction to configure the program. 133 | const tx = await program.methods 134 | .initialize(newConfig) 135 | .accounts({ 136 | payer: adminKp.publicKey, 137 | }) 138 | .signers([adminKp]) 139 | .rpc(); 140 | 141 | console.log("config tx signature:", tx); 142 | 143 | // get PDA for the config account using the seed "config". 144 | const [configPda, _] = PublicKey.findProgramAddressSync( 145 | [Buffer.from(SEED_CONFIG)], 146 | program.programId 147 | ); 148 | 149 | // Log PDA details for debugging. 150 | console.log("config PDA:", configPda.toString()); 151 | 152 | // Fetch the updated config account to validate the changes. 153 | const configAccount = await program.account.config.fetch(configPda); 154 | 155 | // Assertions to verify configuration 156 | assert.equal( 157 | configAccount.admin.toString(), 158 | adminKp.publicKey.toString() 159 | ); 160 | assert.equal(configAccount.totalPoolCount, 0); 161 | }); 162 | 163 | it("Is the staking pool created", async () => { 164 | console.log("token: ", tokenKp.publicKey.toBase58()); 165 | // get PDA for the config account using the seed "config". 166 | const [configPda] = PublicKey.findProgramAddressSync( 167 | [Buffer.from(SEED_CONFIG)], 168 | program.programId 169 | ); 170 | const configAccount = await program.account.config.fetch(configPda); 171 | console.log(configAccount, '=====================') 172 | // Send the transaction to launch a token 173 | 174 | console.log("🚀 ~ it ~ stakingToken:", stakingToken.toBase58()) 175 | console.log("🚀 ~ it ~ adminKp:", adminKp.publicKey.toBase58()) 176 | const tx = await program.methods 177 | .createPool( 178 | new BN(TEST_DURATION), 179 | new BN(TEST_LOCK_PERIOD), 180 | new BN(TEST_BOOST_TRIGGER_AMOUNT), 181 | new BN(TEST_BOOST_PURCHASE_AMOUNT), 182 | TEST_APY, 183 | TEST_BOOST_APY_PERCENT, 184 | TEST_PENALTY_FEE, 185 | new BN(TEST_BOOST_DURATION), 186 | ) 187 | .accounts({ 188 | creator: adminKp.publicKey, 189 | rewardMint: NATIVE_MINT, 190 | stakingToken: stakingToken, 191 | }) 192 | .signers([adminKp]) 193 | .transaction(); 194 | 195 | tx.feePayer = adminKp.publicKey 196 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash 197 | console.log(await connection.simulateTransaction(tx)) 198 | const sig = await sendAndConfirmTransaction(connection, tx, [adminKp]) 199 | 200 | console.log("tx signature:", sig); 201 | 202 | 203 | const configAccountAfterCreation = await program.account.config.fetch(configPda); 204 | 205 | // Assertions to verify configuration 206 | console.log("config account created pool totla pool number, ", configAccountAfterCreation.totalPoolCount) 207 | // assert.equal(configAccountAfterCreation.totalPoolCount, 1); 208 | const [stakingPool1] = PublicKey.findProgramAddressSync( 209 | [ 210 | Buffer.from(SEED_STAKING_POOL), 211 | new BN(TEST_POOL_ID).toArrayLike(Buffer, 'le', 8), 212 | ], 213 | program.programId 214 | ); 215 | const [stakingPool2] = PublicKey.findProgramAddressSync( 216 | [ 217 | Buffer.from(SEED_STAKING_POOL), 218 | new BN(TEST_POOL_ID).toBuffer('le', 8), 219 | ], 220 | program.programId 221 | ); 222 | 223 | const stakingPoolInfo = await program.account.pool.fetch(stakingPool1) 224 | console.log("🚀 ~ it ~ stakingPool1:", stakingPool1.toBase58()) 225 | console.log("🚀 ~ it ~ stakingPool2:", stakingPool2.toBase58()) 226 | console.log("🚀 ~ it ~ stakingPoolInfo:", stakingPoolInfo) 227 | }); 228 | 229 | // it("Is the emergency happened", async () => { 230 | // console.log("token: ", tokenKp.publicKey.toBase58()); 231 | // // get PDA for the config account using the seed "config". 232 | // const [configPda] = PublicKey.findProgramAddressSync( 233 | // [Buffer.from(SEED_CONFIG)], 234 | // program.programId 235 | // ); 236 | // const configAccount = await program.account.config.fetch(configPda); 237 | // console.log(configAccount, '=====================') 238 | // // Send the transaction to launch a token 239 | 240 | // console.log("🚀 ~ it ~ stakingToken:", stakingToken.toBase58()) 241 | // console.log("🚀 ~ it ~ adminKp:", adminKp.publicKey.toBase58()) 242 | // const tx = await program.methods 243 | // .emergency() 244 | // .accounts({ 245 | // payer: adminKp.publicKey 246 | // }) 247 | // .signers([adminKp]) 248 | // .transaction(); 249 | 250 | // tx.feePayer = adminKp.publicKey 251 | // tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash 252 | // console.log(await connection.simulateTransaction(tx)) 253 | // const sig = await sendAndConfirmTransaction(connection, tx, [adminKp]) 254 | 255 | // console.log("tx signature:", sig); 256 | 257 | // const configAccountAfterEmergency = await program.account.config.fetch(configPda); 258 | 259 | // // Assertions to verify configuration 260 | // console.log("config account after emergency, ", configAccountAfterEmergency); 261 | // }); 262 | 263 | // it("Is the setPaused happened", async () => { 264 | // console.log("token: ", tokenKp.publicKey.toBase58()); 265 | // // get PDA for the config account using the seed "config". 266 | // const [configPda] = PublicKey.findProgramAddressSync( 267 | // [Buffer.from(SEED_CONFIG)], 268 | // program.programId 269 | // ); 270 | // const configAccount = await program.account.config.fetch(configPda); 271 | // console.log(configAccount, '=====================') 272 | // // Send the transaction to launch a token 273 | 274 | // console.log("🚀 ~ it ~ adminKp:", adminKp.publicKey.toBase58()) 275 | // const tx = await program.methods 276 | // .setPause( 277 | // TEST_POOL_ID 278 | // ) 279 | // .accounts({ 280 | // payer: adminKp.publicKey 281 | // }) 282 | // .signers([adminKp]) 283 | // .transaction(); 284 | 285 | // tx.feePayer = adminKp.publicKey 286 | // tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash 287 | // console.log(await connection.simulateTransaction(tx)) 288 | // const sig = await sendAndConfirmTransaction(connection, tx, [adminKp]) 289 | 290 | // console.log("tx signature:", sig); 291 | 292 | // const configAccountAfterPause = await program.account.config.fetch(configPda); 293 | 294 | // // Assertions to verify configuration 295 | // console.log("config account after pause, ", configAccountAfterPause); 296 | 297 | // // const [stakingPool] = PublicKey.findProgramAddressSync( 298 | // // [ 299 | // // Buffer.from(SEED_STAKING_POOL), 300 | // // new BN(TEST_POOL_ID).toArrayLike(Buffer, 'le', 8) 301 | // // ], 302 | // // program.programId 303 | // // ); 304 | // // const stakingPoolInfo = await program.account.pool.fetch(stakingPool) 305 | // // console.log("🚀 ~ it ~ stakingPoolInfo:", stakingPoolInfo) 306 | // }); 307 | 308 | it("Is the stake correctly", async () => { 309 | console.log("token: ", tokenKp.publicKey.toBase58()); 310 | // get PDA for the config account using the seed "config". 311 | const [configPda] = PublicKey.findProgramAddressSync( 312 | [Buffer.from(SEED_CONFIG)], 313 | program.programId 314 | ); 315 | const configAccountBefore = await program.account.config.fetch(configPda); 316 | console.log(configAccountBefore, '=====================') 317 | // Send the transaction to launch a token 318 | 319 | console.log("🚀 ~ it ~ stakingToken:", stakingToken.toBase58()) 320 | console.log("🚀 ~ it ~ adminKp:", adminKp.publicKey.toBase58()) 321 | const tx = await program.methods 322 | .stake( 323 | new BN(TEST_POOL_ID), 324 | new BN(1000), 325 | ) 326 | .accounts({ 327 | user: userKp.publicKey, 328 | stakingToken: stakingToken, 329 | }) 330 | .signers([userKp]) 331 | .transaction(); 332 | 333 | tx.feePayer = userKp.publicKey 334 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash 335 | console.log(await connection.simulateTransaction(tx)) 336 | const sig = await sendAndConfirmTransaction(connection, tx, [userKp]) 337 | 338 | console.log("tx signature:", sig); 339 | 340 | const configAccountAfter = await program.account.config.fetch(configPda); 341 | console.log("🚀 ~ it ~ configAccountAfter:", configAccountAfter) 342 | 343 | const [stakingPool] = PublicKey.findProgramAddressSync( 344 | [ 345 | Buffer.from(SEED_STAKING_POOL), 346 | new BN(TEST_POOL_ID).toArrayLike(Buffer, 'le', 8) 347 | ], 348 | program.programId 349 | ); 350 | const stakingPoolInfo = await program.account.pool.fetch(stakingPool) 351 | console.log("🚀 ~ it ~ stakingPoolInfo:", stakingPoolInfo) 352 | 353 | const [userPool] = PublicKey.findProgramAddressSync( 354 | [Buffer.from(USER_POOL), userKp.publicKey.toBuffer(), stakingPool.toBuffer()], 355 | program.programId 356 | ) 357 | const userPoolInfo = await program.account.user.fetch(userPool) 358 | console.log("🚀 ~ it ~ userPoolInfo:", userPoolInfo) 359 | }); 360 | 361 | it("Is the harvest correctly", async () => { 362 | // get PDA for the config account using the seed "config". 363 | const [configPda] = PublicKey.findProgramAddressSync( 364 | [Buffer.from(SEED_CONFIG)], 365 | program.programId 366 | ); 367 | const configAccountBefore = await program.account.config.fetch(configPda); 368 | console.log(configAccountBefore, '=====================') 369 | // Send the transaction to launch a token 370 | 371 | console.log("🚀 ~ it ~ stakingToken:", stakingToken.toBase58()) 372 | console.log("🚀 ~ it ~ adminKp:", adminKp.publicKey.toBase58()) 373 | const tx = await program.methods 374 | .harvest( 375 | new BN(TEST_POOL_ID), 376 | TEST_SOL_PRICE, 377 | TEST_TOKEN_PRICE, 378 | ) 379 | .accounts({ 380 | user: userKp.publicKey, 381 | stakingToken: stakingToken, 382 | }) 383 | .signers([userKp]) 384 | .transaction(); 385 | 386 | tx.feePayer = userKp.publicKey 387 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash 388 | console.log(await connection.simulateTransaction(tx)) 389 | const sig = await sendAndConfirmTransaction(connection, tx, [userKp]) 390 | 391 | console.log("tx signature:", sig); 392 | 393 | const configAccountAfter = await program.account.config.fetch(configPda); 394 | console.log("🚀 ~ it ~ configAccountAfter:", configAccountAfter) 395 | 396 | const [stakingPool] = PublicKey.findProgramAddressSync( 397 | [ 398 | Buffer.from(SEED_STAKING_POOL), 399 | new BN(0).toArrayLike(Buffer, 'le', 8) 400 | ], 401 | program.programId 402 | ); 403 | const stakingPoolInfo = await program.account.pool.fetch(stakingPool) 404 | console.log("🚀 ~ it ~ stakingPoolInfo:", stakingPoolInfo) 405 | 406 | const [userPool] = PublicKey.findProgramAddressSync( 407 | [Buffer.from(USER_POOL), userKp.publicKey.toBuffer(), stakingPool.toBuffer()], 408 | program.programId 409 | ) 410 | const userPoolInfo = await program.account.user.fetch(userPool) 411 | console.log("🚀 ~ it ~ userPoolInfo:", userPoolInfo) 412 | }); 413 | 414 | it("Is the withdraw correctly", async () => { 415 | // get PDA for the config account using the seed "config". 416 | const [configPda] = PublicKey.findProgramAddressSync( 417 | [Buffer.from(SEED_CONFIG)], 418 | program.programId 419 | ); 420 | const configAccountBefore = await program.account.config.fetch(configPda); 421 | console.log(configAccountBefore, '=====================') 422 | // Send the transaction to launch a token 423 | 424 | console.log("🚀 ~ it ~ stakingToken:", stakingToken.toBase58()) 425 | console.log("🚀 ~ it ~ adminKp:", adminKp.publicKey.toBase58()) 426 | const tx = await program.methods 427 | .withdraw( 428 | new BN(TEST_POOL_ID), 429 | TEST_SOL_PRICE, 430 | TEST_TOKEN_PRICE, 431 | ) 432 | .accounts({ 433 | user: userKp.publicKey, 434 | stakingToken: stakingToken, 435 | }) 436 | .signers([userKp]) 437 | .transaction(); 438 | 439 | tx.feePayer = userKp.publicKey 440 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash 441 | console.log(await connection.simulateTransaction(tx)) 442 | const sig = await sendAndConfirmTransaction(connection, tx, [userKp]) 443 | 444 | console.log("tx signature:", sig); 445 | 446 | const configAccountAfter = await program.account.config.fetch(configPda); 447 | console.log("🚀 ~ it ~ configAccountAfter:", configAccountAfter) 448 | 449 | const [stakingPool] = PublicKey.findProgramAddressSync( 450 | [ 451 | Buffer.from(SEED_STAKING_POOL), 452 | new BN(0).toArrayLike(Buffer, 'le', 8) 453 | ], 454 | program.programId 455 | ); 456 | const stakingPoolInfo = await program.account.pool.fetch(stakingPool) 457 | console.log("🚀 ~ it ~ stakingPoolInfo:", stakingPoolInfo) 458 | 459 | const [userPool] = PublicKey.findProgramAddressSync( 460 | [Buffer.from(USER_POOL), userKp.publicKey.toBuffer(), stakingPool.toBuffer()], 461 | program.programId 462 | ) 463 | const userPoolInfo = await program.account.user.fetch(userPool) 464 | console.log("🚀 ~ it ~ userPoolInfo:", userPoolInfo) 465 | }); 466 | 467 | it("Is the purchase boost correctly", async () => { 468 | // get PDA for the config account using the seed "config". 469 | const [configPda] = PublicKey.findProgramAddressSync( 470 | [Buffer.from(SEED_CONFIG)], 471 | program.programId 472 | ); 473 | const configAccountBefore = await program.account.config.fetch(configPda); 474 | console.log(configAccountBefore, '=====================') 475 | // Send the transaction to launch a token 476 | 477 | console.log("🚀 ~ it ~ stakingToken:", stakingToken.toBase58()) 478 | console.log("🚀 ~ it ~ adminKp:", adminKp.publicKey.toBase58()) 479 | const tx = await program.methods 480 | .purchaseBoost( 481 | new BN(TEST_POOL_ID), 482 | new BN(TEST_BOOST_PURCHASE_AMOUNT) 483 | ) 484 | .accounts({ 485 | user: userKp.publicKey, 486 | stakingToken: stakingToken, 487 | }) 488 | .signers([userKp]) 489 | .transaction(); 490 | 491 | tx.feePayer = userKp.publicKey 492 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash 493 | console.log(await connection.simulateTransaction(tx)) 494 | const sig = await sendAndConfirmTransaction(connection, tx, [userKp]) 495 | 496 | console.log("tx signature:", sig); 497 | 498 | const configAccountAfter = await program.account.config.fetch(configPda); 499 | console.log("🚀 ~ it ~ configAccountAfter:", configAccountAfter) 500 | 501 | const [stakingPool] = PublicKey.findProgramAddressSync( 502 | [ 503 | Buffer.from(SEED_STAKING_POOL), 504 | new BN(0).toArrayLike(Buffer, 'le', 8) 505 | ], 506 | program.programId 507 | ); 508 | const stakingPoolInfo = await program.account.pool.fetch(stakingPool) 509 | console.log("🚀 ~ it ~ stakingPoolInfo:", stakingPoolInfo) 510 | 511 | const [userPool] = PublicKey.findProgramAddressSync( 512 | [Buffer.from(USER_POOL), userKp.publicKey.toBuffer(), stakingPool.toBuffer()], 513 | program.programId 514 | ) 515 | const userPoolInfo = await program.account.user.fetch(userPool) 516 | console.log("🚀 ~ it ~ userPoolInfo:", userPoolInfo) 517 | }); 518 | }); 519 | -------------------------------------------------------------------------------- /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.1" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "47fe28365b33e8334dd70ae2f34a43892363012fe239cf37d2ee91693575b1f8" 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.1" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "3c288d496168268d198d9b53ee9f4f9d260a55ba4df9877ea1d4486ad6109e0f" 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.1" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "49b77b6948d0eeaaa129ce79eea5bbbb9937375a9241d909ca8fb9e006bb6e90" 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.1" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "4d20bb569c5a557c86101b944721d865e1fd0a4c67c381d31a44a84f07f84828" 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.1" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "4cebd8d0671a3a9dc3160c48598d652c34c77de6be4d44345b8b514323284d57" 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.1" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "efb2a5eb0860e661ab31aff7bb5e0288357b176380e985bade4ccb395981b42d" 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.1" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "04368b5abef4266250ca8d1d12f4dff860242681e4ec22b885dcfe354fd35aa1" 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.1" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "e0bb0e0911ad4a70cab880cdd6287fe1e880a1a9d8e4e6defa8e9044b9796a6c" 165 | dependencies = [ 166 | "anchor-syn", 167 | "borsh-derive-internal 0.10.4", 168 | "proc-macro2", 169 | "quote", 170 | "syn 1.0.109", 171 | ] 172 | 173 | [[package]] 174 | name = "anchor-derive-space" 175 | version = "0.30.1" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "5ef415ff156dc82e9ecb943189b0cb241b3a6bfc26a180234dc21bd3ef3ce0cb" 178 | dependencies = [ 179 | "proc-macro2", 180 | "quote", 181 | "syn 1.0.109", 182 | ] 183 | 184 | [[package]] 185 | name = "anchor-lang" 186 | version = "0.30.1" 187 | source = "registry+https://github.com/rust-lang/crates.io-index" 188 | checksum = "6620c9486d9d36a4389cab5e37dc34a42ed0bfaa62e6a75a2999ce98f8f2e373" 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.4", 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.1" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "31cf97b4e6f7d6144a05e435660fcf757dbc3446d38d0e2b851d11ed13625bba" 215 | dependencies = [ 216 | "anchor-lang-idl-spec", 217 | "anyhow", 218 | "heck", 219 | "regex", 220 | "serde", 221 | "serde_json", 222 | "sha2 0.10.8", 223 | ] 224 | 225 | [[package]] 226 | name = "anchor-lang-idl-spec" 227 | version = "0.1.0" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "2bdf143115440fe621bdac3a29a1f7472e09f6cd82b2aa569429a0c13f103838" 230 | dependencies = [ 231 | "anyhow", 232 | "serde", 233 | ] 234 | 235 | [[package]] 236 | name = "anchor-spl" 237 | version = "0.30.1" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "04bd077c34449319a1e4e0bc21cea572960c9ae0d0fefda0dd7c52fcc3c647a3" 240 | dependencies = [ 241 | "anchor-lang", 242 | "mpl-token-metadata", 243 | "spl-associated-token-account", 244 | "spl-pod", 245 | "spl-token", 246 | "spl-token-2022", 247 | "spl-token-group-interface", 248 | "spl-token-metadata-interface", 249 | ] 250 | 251 | [[package]] 252 | name = "anchor-syn" 253 | version = "0.30.1" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "f99daacb53b55cfd37ce14d6c9905929721137fd4c67bbab44a19802aecb622f" 256 | dependencies = [ 257 | "anyhow", 258 | "bs58 0.5.1", 259 | "cargo_toml", 260 | "heck", 261 | "proc-macro2", 262 | "quote", 263 | "serde", 264 | "serde_json", 265 | "sha2 0.10.8", 266 | "syn 1.0.109", 267 | "thiserror", 268 | ] 269 | 270 | [[package]] 271 | name = "anyhow" 272 | version = "1.0.96" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" 275 | 276 | [[package]] 277 | name = "ark-bn254" 278 | version = "0.4.0" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" 281 | dependencies = [ 282 | "ark-ec", 283 | "ark-ff", 284 | "ark-std", 285 | ] 286 | 287 | [[package]] 288 | name = "ark-ec" 289 | version = "0.4.2" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" 292 | dependencies = [ 293 | "ark-ff", 294 | "ark-poly", 295 | "ark-serialize", 296 | "ark-std", 297 | "derivative", 298 | "hashbrown 0.13.2", 299 | "itertools", 300 | "num-traits", 301 | "zeroize", 302 | ] 303 | 304 | [[package]] 305 | name = "ark-ff" 306 | version = "0.4.2" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" 309 | dependencies = [ 310 | "ark-ff-asm", 311 | "ark-ff-macros", 312 | "ark-serialize", 313 | "ark-std", 314 | "derivative", 315 | "digest 0.10.7", 316 | "itertools", 317 | "num-bigint", 318 | "num-traits", 319 | "paste", 320 | "rustc_version", 321 | "zeroize", 322 | ] 323 | 324 | [[package]] 325 | name = "ark-ff-asm" 326 | version = "0.4.2" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" 329 | dependencies = [ 330 | "quote", 331 | "syn 1.0.109", 332 | ] 333 | 334 | [[package]] 335 | name = "ark-ff-macros" 336 | version = "0.4.2" 337 | source = "registry+https://github.com/rust-lang/crates.io-index" 338 | checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" 339 | dependencies = [ 340 | "num-bigint", 341 | "num-traits", 342 | "proc-macro2", 343 | "quote", 344 | "syn 1.0.109", 345 | ] 346 | 347 | [[package]] 348 | name = "ark-poly" 349 | version = "0.4.2" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" 352 | dependencies = [ 353 | "ark-ff", 354 | "ark-serialize", 355 | "ark-std", 356 | "derivative", 357 | "hashbrown 0.13.2", 358 | ] 359 | 360 | [[package]] 361 | name = "ark-serialize" 362 | version = "0.4.2" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" 365 | dependencies = [ 366 | "ark-serialize-derive", 367 | "ark-std", 368 | "digest 0.10.7", 369 | "num-bigint", 370 | ] 371 | 372 | [[package]] 373 | name = "ark-serialize-derive" 374 | version = "0.4.2" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" 377 | dependencies = [ 378 | "proc-macro2", 379 | "quote", 380 | "syn 1.0.109", 381 | ] 382 | 383 | [[package]] 384 | name = "ark-std" 385 | version = "0.4.0" 386 | source = "registry+https://github.com/rust-lang/crates.io-index" 387 | checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" 388 | dependencies = [ 389 | "num-traits", 390 | "rand 0.8.5", 391 | ] 392 | 393 | [[package]] 394 | name = "arrayref" 395 | version = "0.3.9" 396 | source = "registry+https://github.com/rust-lang/crates.io-index" 397 | checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" 398 | 399 | [[package]] 400 | name = "arrayvec" 401 | version = "0.7.6" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" 404 | 405 | [[package]] 406 | name = "assert_matches" 407 | version = "1.5.0" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" 410 | 411 | [[package]] 412 | name = "atty" 413 | version = "0.2.14" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 416 | dependencies = [ 417 | "hermit-abi", 418 | "libc", 419 | "winapi", 420 | ] 421 | 422 | [[package]] 423 | name = "autocfg" 424 | version = "1.4.0" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 427 | 428 | [[package]] 429 | name = "base64" 430 | version = "0.12.3" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" 433 | 434 | [[package]] 435 | name = "base64" 436 | version = "0.21.7" 437 | source = "registry+https://github.com/rust-lang/crates.io-index" 438 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 439 | 440 | [[package]] 441 | name = "bincode" 442 | version = "1.3.3" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 445 | dependencies = [ 446 | "serde", 447 | ] 448 | 449 | [[package]] 450 | name = "bitflags" 451 | version = "2.9.0" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" 454 | dependencies = [ 455 | "serde", 456 | ] 457 | 458 | [[package]] 459 | name = "bitmaps" 460 | version = "2.1.0" 461 | source = "registry+https://github.com/rust-lang/crates.io-index" 462 | checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" 463 | dependencies = [ 464 | "typenum", 465 | ] 466 | 467 | [[package]] 468 | name = "blake3" 469 | version = "1.6.1" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | checksum = "675f87afced0413c9bb02843499dbbd3882a237645883f71a2b59644a6d2f753" 472 | dependencies = [ 473 | "arrayref", 474 | "arrayvec", 475 | "cc", 476 | "cfg-if", 477 | "constant_time_eq", 478 | "digest 0.10.7", 479 | ] 480 | 481 | [[package]] 482 | name = "block-buffer" 483 | version = "0.9.0" 484 | source = "registry+https://github.com/rust-lang/crates.io-index" 485 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 486 | dependencies = [ 487 | "block-padding", 488 | "generic-array", 489 | ] 490 | 491 | [[package]] 492 | name = "block-buffer" 493 | version = "0.10.4" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 496 | dependencies = [ 497 | "generic-array", 498 | ] 499 | 500 | [[package]] 501 | name = "block-padding" 502 | version = "0.2.1" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" 505 | 506 | [[package]] 507 | name = "borsh" 508 | version = "0.9.3" 509 | source = "registry+https://github.com/rust-lang/crates.io-index" 510 | checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" 511 | dependencies = [ 512 | "borsh-derive 0.9.3", 513 | "hashbrown 0.11.2", 514 | ] 515 | 516 | [[package]] 517 | name = "borsh" 518 | version = "0.10.4" 519 | source = "registry+https://github.com/rust-lang/crates.io-index" 520 | checksum = "115e54d64eb62cdebad391c19efc9dce4981c690c85a33a12199d99bb9546fee" 521 | dependencies = [ 522 | "borsh-derive 0.10.4", 523 | "hashbrown 0.13.2", 524 | ] 525 | 526 | [[package]] 527 | name = "borsh" 528 | version = "1.5.5" 529 | source = "registry+https://github.com/rust-lang/crates.io-index" 530 | checksum = "5430e3be710b68d984d1391c854eb431a9d548640711faa54eecb1df93db91cc" 531 | dependencies = [ 532 | "borsh-derive 1.5.5", 533 | "cfg_aliases", 534 | ] 535 | 536 | [[package]] 537 | name = "borsh-derive" 538 | version = "0.9.3" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" 541 | dependencies = [ 542 | "borsh-derive-internal 0.9.3", 543 | "borsh-schema-derive-internal 0.9.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 = "0.10.4" 552 | source = "registry+https://github.com/rust-lang/crates.io-index" 553 | checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" 554 | dependencies = [ 555 | "borsh-derive-internal 0.10.4", 556 | "borsh-schema-derive-internal 0.10.4", 557 | "proc-macro-crate 0.1.5", 558 | "proc-macro2", 559 | "syn 1.0.109", 560 | ] 561 | 562 | [[package]] 563 | name = "borsh-derive" 564 | version = "1.5.5" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "f8b668d39970baad5356d7c83a86fee3a539e6f93bf6764c97368243e17a0487" 567 | dependencies = [ 568 | "once_cell", 569 | "proc-macro-crate 3.2.0", 570 | "proc-macro2", 571 | "quote", 572 | "syn 2.0.98", 573 | ] 574 | 575 | [[package]] 576 | name = "borsh-derive-internal" 577 | version = "0.9.3" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" 580 | dependencies = [ 581 | "proc-macro2", 582 | "quote", 583 | "syn 1.0.109", 584 | ] 585 | 586 | [[package]] 587 | name = "borsh-derive-internal" 588 | version = "0.10.4" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | checksum = "65d6ba50644c98714aa2a70d13d7df3cd75cd2b523a2b452bf010443800976b3" 591 | dependencies = [ 592 | "proc-macro2", 593 | "quote", 594 | "syn 1.0.109", 595 | ] 596 | 597 | [[package]] 598 | name = "borsh-schema-derive-internal" 599 | version = "0.9.3" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" 602 | dependencies = [ 603 | "proc-macro2", 604 | "quote", 605 | "syn 1.0.109", 606 | ] 607 | 608 | [[package]] 609 | name = "borsh-schema-derive-internal" 610 | version = "0.10.4" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" 613 | dependencies = [ 614 | "proc-macro2", 615 | "quote", 616 | "syn 1.0.109", 617 | ] 618 | 619 | [[package]] 620 | name = "bs58" 621 | version = "0.4.0" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" 624 | 625 | [[package]] 626 | name = "bs58" 627 | version = "0.5.1" 628 | source = "registry+https://github.com/rust-lang/crates.io-index" 629 | checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" 630 | dependencies = [ 631 | "tinyvec", 632 | ] 633 | 634 | [[package]] 635 | name = "bumpalo" 636 | version = "3.17.0" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" 639 | 640 | [[package]] 641 | name = "bv" 642 | version = "0.11.1" 643 | source = "registry+https://github.com/rust-lang/crates.io-index" 644 | checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" 645 | dependencies = [ 646 | "feature-probe", 647 | "serde", 648 | ] 649 | 650 | [[package]] 651 | name = "bytemuck" 652 | version = "1.21.0" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" 655 | dependencies = [ 656 | "bytemuck_derive", 657 | ] 658 | 659 | [[package]] 660 | name = "bytemuck_derive" 661 | version = "1.8.1" 662 | source = "registry+https://github.com/rust-lang/crates.io-index" 663 | checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" 664 | dependencies = [ 665 | "proc-macro2", 666 | "quote", 667 | "syn 2.0.98", 668 | ] 669 | 670 | [[package]] 671 | name = "byteorder" 672 | version = "1.5.0" 673 | source = "registry+https://github.com/rust-lang/crates.io-index" 674 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 675 | 676 | [[package]] 677 | name = "cargo_toml" 678 | version = "0.19.2" 679 | source = "registry+https://github.com/rust-lang/crates.io-index" 680 | checksum = "a98356df42a2eb1bd8f1793ae4ee4de48e384dd974ce5eac8eee802edb7492be" 681 | dependencies = [ 682 | "serde", 683 | "toml 0.8.20", 684 | ] 685 | 686 | [[package]] 687 | name = "cc" 688 | version = "1.2.16" 689 | source = "registry+https://github.com/rust-lang/crates.io-index" 690 | checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" 691 | dependencies = [ 692 | "jobserver", 693 | "libc", 694 | "shlex", 695 | ] 696 | 697 | [[package]] 698 | name = "cfg-if" 699 | version = "1.0.0" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 702 | 703 | [[package]] 704 | name = "cfg_aliases" 705 | version = "0.2.1" 706 | source = "registry+https://github.com/rust-lang/crates.io-index" 707 | checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 708 | 709 | [[package]] 710 | name = "chrono" 711 | version = "0.4.40" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" 714 | dependencies = [ 715 | "num-traits", 716 | ] 717 | 718 | [[package]] 719 | name = "cipher" 720 | version = "0.3.0" 721 | source = "registry+https://github.com/rust-lang/crates.io-index" 722 | checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" 723 | dependencies = [ 724 | "generic-array", 725 | ] 726 | 727 | [[package]] 728 | name = "console_error_panic_hook" 729 | version = "0.1.7" 730 | source = "registry+https://github.com/rust-lang/crates.io-index" 731 | checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" 732 | dependencies = [ 733 | "cfg-if", 734 | "wasm-bindgen", 735 | ] 736 | 737 | [[package]] 738 | name = "console_log" 739 | version = "0.2.2" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" 742 | dependencies = [ 743 | "log", 744 | "web-sys", 745 | ] 746 | 747 | [[package]] 748 | name = "constant_time_eq" 749 | version = "0.3.1" 750 | source = "registry+https://github.com/rust-lang/crates.io-index" 751 | checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" 752 | 753 | [[package]] 754 | name = "cpufeatures" 755 | version = "0.2.17" 756 | source = "registry+https://github.com/rust-lang/crates.io-index" 757 | checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" 758 | dependencies = [ 759 | "libc", 760 | ] 761 | 762 | [[package]] 763 | name = "crossbeam-deque" 764 | version = "0.8.6" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" 767 | dependencies = [ 768 | "crossbeam-epoch", 769 | "crossbeam-utils", 770 | ] 771 | 772 | [[package]] 773 | name = "crossbeam-epoch" 774 | version = "0.9.18" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 777 | dependencies = [ 778 | "crossbeam-utils", 779 | ] 780 | 781 | [[package]] 782 | name = "crossbeam-utils" 783 | version = "0.8.21" 784 | source = "registry+https://github.com/rust-lang/crates.io-index" 785 | checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" 786 | 787 | [[package]] 788 | name = "crunchy" 789 | version = "0.2.3" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" 792 | 793 | [[package]] 794 | name = "crypto-common" 795 | version = "0.1.6" 796 | source = "registry+https://github.com/rust-lang/crates.io-index" 797 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 798 | dependencies = [ 799 | "generic-array", 800 | "typenum", 801 | ] 802 | 803 | [[package]] 804 | name = "crypto-mac" 805 | version = "0.8.0" 806 | source = "registry+https://github.com/rust-lang/crates.io-index" 807 | checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" 808 | dependencies = [ 809 | "generic-array", 810 | "subtle", 811 | ] 812 | 813 | [[package]] 814 | name = "ctr" 815 | version = "0.8.0" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" 818 | dependencies = [ 819 | "cipher", 820 | ] 821 | 822 | [[package]] 823 | name = "curve25519-dalek" 824 | version = "3.2.1" 825 | source = "registry+https://github.com/rust-lang/crates.io-index" 826 | checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" 827 | dependencies = [ 828 | "byteorder", 829 | "digest 0.9.0", 830 | "rand_core 0.5.1", 831 | "serde", 832 | "subtle", 833 | "zeroize", 834 | ] 835 | 836 | [[package]] 837 | name = "darling" 838 | version = "0.20.10" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" 841 | dependencies = [ 842 | "darling_core", 843 | "darling_macro", 844 | ] 845 | 846 | [[package]] 847 | name = "darling_core" 848 | version = "0.20.10" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" 851 | dependencies = [ 852 | "fnv", 853 | "ident_case", 854 | "proc-macro2", 855 | "quote", 856 | "strsim", 857 | "syn 2.0.98", 858 | ] 859 | 860 | [[package]] 861 | name = "darling_macro" 862 | version = "0.20.10" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" 865 | dependencies = [ 866 | "darling_core", 867 | "quote", 868 | "syn 2.0.98", 869 | ] 870 | 871 | [[package]] 872 | name = "derivation-path" 873 | version = "0.2.0" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" 876 | 877 | [[package]] 878 | name = "derivative" 879 | version = "2.2.0" 880 | source = "registry+https://github.com/rust-lang/crates.io-index" 881 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 882 | dependencies = [ 883 | "proc-macro2", 884 | "quote", 885 | "syn 1.0.109", 886 | ] 887 | 888 | [[package]] 889 | name = "digest" 890 | version = "0.9.0" 891 | source = "registry+https://github.com/rust-lang/crates.io-index" 892 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 893 | dependencies = [ 894 | "generic-array", 895 | ] 896 | 897 | [[package]] 898 | name = "digest" 899 | version = "0.10.7" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 902 | dependencies = [ 903 | "block-buffer 0.10.4", 904 | "crypto-common", 905 | "subtle", 906 | ] 907 | 908 | [[package]] 909 | name = "ed25519" 910 | version = "1.5.3" 911 | source = "registry+https://github.com/rust-lang/crates.io-index" 912 | checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" 913 | dependencies = [ 914 | "signature", 915 | ] 916 | 917 | [[package]] 918 | name = "ed25519-dalek" 919 | version = "1.0.1" 920 | source = "registry+https://github.com/rust-lang/crates.io-index" 921 | checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" 922 | dependencies = [ 923 | "curve25519-dalek", 924 | "ed25519", 925 | "rand 0.7.3", 926 | "serde", 927 | "sha2 0.9.9", 928 | "zeroize", 929 | ] 930 | 931 | [[package]] 932 | name = "ed25519-dalek-bip32" 933 | version = "0.2.0" 934 | source = "registry+https://github.com/rust-lang/crates.io-index" 935 | checksum = "9d2be62a4061b872c8c0873ee4fc6f101ce7b889d039f019c5fa2af471a59908" 936 | dependencies = [ 937 | "derivation-path", 938 | "ed25519-dalek", 939 | "hmac 0.12.1", 940 | "sha2 0.10.8", 941 | ] 942 | 943 | [[package]] 944 | name = "either" 945 | version = "1.14.0" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d" 948 | 949 | [[package]] 950 | name = "env_logger" 951 | version = "0.9.3" 952 | source = "registry+https://github.com/rust-lang/crates.io-index" 953 | checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" 954 | dependencies = [ 955 | "atty", 956 | "humantime", 957 | "log", 958 | "regex", 959 | "termcolor", 960 | ] 961 | 962 | [[package]] 963 | name = "equivalent" 964 | version = "1.0.2" 965 | source = "registry+https://github.com/rust-lang/crates.io-index" 966 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 967 | 968 | [[package]] 969 | name = "feature-probe" 970 | version = "0.1.1" 971 | source = "registry+https://github.com/rust-lang/crates.io-index" 972 | checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" 973 | 974 | [[package]] 975 | name = "fnv" 976 | version = "1.0.7" 977 | source = "registry+https://github.com/rust-lang/crates.io-index" 978 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 979 | 980 | [[package]] 981 | name = "generic-array" 982 | version = "0.14.7" 983 | source = "registry+https://github.com/rust-lang/crates.io-index" 984 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 985 | dependencies = [ 986 | "serde", 987 | "typenum", 988 | "version_check", 989 | ] 990 | 991 | [[package]] 992 | name = "getrandom" 993 | version = "0.1.16" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 996 | dependencies = [ 997 | "cfg-if", 998 | "js-sys", 999 | "libc", 1000 | "wasi 0.9.0+wasi-snapshot-preview1", 1001 | "wasm-bindgen", 1002 | ] 1003 | 1004 | [[package]] 1005 | name = "getrandom" 1006 | version = "0.2.15" 1007 | source = "registry+https://github.com/rust-lang/crates.io-index" 1008 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 1009 | dependencies = [ 1010 | "cfg-if", 1011 | "js-sys", 1012 | "libc", 1013 | "wasi 0.11.0+wasi-snapshot-preview1", 1014 | "wasm-bindgen", 1015 | ] 1016 | 1017 | [[package]] 1018 | name = "hashbrown" 1019 | version = "0.11.2" 1020 | source = "registry+https://github.com/rust-lang/crates.io-index" 1021 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 1022 | dependencies = [ 1023 | "ahash 0.7.8", 1024 | ] 1025 | 1026 | [[package]] 1027 | name = "hashbrown" 1028 | version = "0.13.2" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" 1031 | dependencies = [ 1032 | "ahash 0.8.11", 1033 | ] 1034 | 1035 | [[package]] 1036 | name = "hashbrown" 1037 | version = "0.15.2" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 1040 | 1041 | [[package]] 1042 | name = "heck" 1043 | version = "0.3.3" 1044 | source = "registry+https://github.com/rust-lang/crates.io-index" 1045 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 1046 | dependencies = [ 1047 | "unicode-segmentation", 1048 | ] 1049 | 1050 | [[package]] 1051 | name = "hermit-abi" 1052 | version = "0.1.19" 1053 | source = "registry+https://github.com/rust-lang/crates.io-index" 1054 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 1055 | dependencies = [ 1056 | "libc", 1057 | ] 1058 | 1059 | [[package]] 1060 | name = "hmac" 1061 | version = "0.8.1" 1062 | source = "registry+https://github.com/rust-lang/crates.io-index" 1063 | checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" 1064 | dependencies = [ 1065 | "crypto-mac", 1066 | "digest 0.9.0", 1067 | ] 1068 | 1069 | [[package]] 1070 | name = "hmac" 1071 | version = "0.12.1" 1072 | source = "registry+https://github.com/rust-lang/crates.io-index" 1073 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 1074 | dependencies = [ 1075 | "digest 0.10.7", 1076 | ] 1077 | 1078 | [[package]] 1079 | name = "hmac-drbg" 1080 | version = "0.3.0" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" 1083 | dependencies = [ 1084 | "digest 0.9.0", 1085 | "generic-array", 1086 | "hmac 0.8.1", 1087 | ] 1088 | 1089 | [[package]] 1090 | name = "humantime" 1091 | version = "2.1.0" 1092 | source = "registry+https://github.com/rust-lang/crates.io-index" 1093 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 1094 | 1095 | [[package]] 1096 | name = "ident_case" 1097 | version = "1.0.1" 1098 | source = "registry+https://github.com/rust-lang/crates.io-index" 1099 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 1100 | 1101 | [[package]] 1102 | name = "im" 1103 | version = "15.1.0" 1104 | source = "registry+https://github.com/rust-lang/crates.io-index" 1105 | checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" 1106 | dependencies = [ 1107 | "bitmaps", 1108 | "rand_core 0.6.4", 1109 | "rand_xoshiro", 1110 | "rayon", 1111 | "serde", 1112 | "sized-chunks", 1113 | "typenum", 1114 | "version_check", 1115 | ] 1116 | 1117 | [[package]] 1118 | name = "indexmap" 1119 | version = "2.7.1" 1120 | source = "registry+https://github.com/rust-lang/crates.io-index" 1121 | checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" 1122 | dependencies = [ 1123 | "equivalent", 1124 | "hashbrown 0.15.2", 1125 | ] 1126 | 1127 | [[package]] 1128 | name = "itertools" 1129 | version = "0.10.5" 1130 | source = "registry+https://github.com/rust-lang/crates.io-index" 1131 | checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" 1132 | dependencies = [ 1133 | "either", 1134 | ] 1135 | 1136 | [[package]] 1137 | name = "itoa" 1138 | version = "1.0.14" 1139 | source = "registry+https://github.com/rust-lang/crates.io-index" 1140 | checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" 1141 | 1142 | [[package]] 1143 | name = "jobserver" 1144 | version = "0.1.32" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" 1147 | dependencies = [ 1148 | "libc", 1149 | ] 1150 | 1151 | [[package]] 1152 | name = "js-sys" 1153 | version = "0.3.77" 1154 | source = "registry+https://github.com/rust-lang/crates.io-index" 1155 | checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" 1156 | dependencies = [ 1157 | "once_cell", 1158 | "wasm-bindgen", 1159 | ] 1160 | 1161 | [[package]] 1162 | name = "keccak" 1163 | version = "0.1.5" 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" 1165 | checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" 1166 | dependencies = [ 1167 | "cpufeatures", 1168 | ] 1169 | 1170 | [[package]] 1171 | name = "lazy_static" 1172 | version = "1.5.0" 1173 | source = "registry+https://github.com/rust-lang/crates.io-index" 1174 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 1175 | 1176 | [[package]] 1177 | name = "libc" 1178 | version = "0.2.170" 1179 | source = "registry+https://github.com/rust-lang/crates.io-index" 1180 | checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" 1181 | 1182 | [[package]] 1183 | name = "libsecp256k1" 1184 | version = "0.6.0" 1185 | source = "registry+https://github.com/rust-lang/crates.io-index" 1186 | checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" 1187 | dependencies = [ 1188 | "arrayref", 1189 | "base64 0.12.3", 1190 | "digest 0.9.0", 1191 | "hmac-drbg", 1192 | "libsecp256k1-core", 1193 | "libsecp256k1-gen-ecmult", 1194 | "libsecp256k1-gen-genmult", 1195 | "rand 0.7.3", 1196 | "serde", 1197 | "sha2 0.9.9", 1198 | "typenum", 1199 | ] 1200 | 1201 | [[package]] 1202 | name = "libsecp256k1-core" 1203 | version = "0.2.2" 1204 | source = "registry+https://github.com/rust-lang/crates.io-index" 1205 | checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" 1206 | dependencies = [ 1207 | "crunchy", 1208 | "digest 0.9.0", 1209 | "subtle", 1210 | ] 1211 | 1212 | [[package]] 1213 | name = "libsecp256k1-gen-ecmult" 1214 | version = "0.2.1" 1215 | source = "registry+https://github.com/rust-lang/crates.io-index" 1216 | checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" 1217 | dependencies = [ 1218 | "libsecp256k1-core", 1219 | ] 1220 | 1221 | [[package]] 1222 | name = "libsecp256k1-gen-genmult" 1223 | version = "0.2.1" 1224 | source = "registry+https://github.com/rust-lang/crates.io-index" 1225 | checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" 1226 | dependencies = [ 1227 | "libsecp256k1-core", 1228 | ] 1229 | 1230 | [[package]] 1231 | name = "light-poseidon" 1232 | version = "0.2.0" 1233 | source = "registry+https://github.com/rust-lang/crates.io-index" 1234 | checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" 1235 | dependencies = [ 1236 | "ark-bn254", 1237 | "ark-ff", 1238 | "num-bigint", 1239 | "thiserror", 1240 | ] 1241 | 1242 | [[package]] 1243 | name = "lock_api" 1244 | version = "0.4.12" 1245 | source = "registry+https://github.com/rust-lang/crates.io-index" 1246 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 1247 | dependencies = [ 1248 | "autocfg", 1249 | "scopeguard", 1250 | ] 1251 | 1252 | [[package]] 1253 | name = "log" 1254 | version = "0.4.26" 1255 | source = "registry+https://github.com/rust-lang/crates.io-index" 1256 | checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" 1257 | 1258 | [[package]] 1259 | name = "memchr" 1260 | version = "2.7.4" 1261 | source = "registry+https://github.com/rust-lang/crates.io-index" 1262 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 1263 | 1264 | [[package]] 1265 | name = "memmap2" 1266 | version = "0.5.10" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" 1269 | dependencies = [ 1270 | "libc", 1271 | ] 1272 | 1273 | [[package]] 1274 | name = "memoffset" 1275 | version = "0.9.1" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" 1278 | dependencies = [ 1279 | "autocfg", 1280 | ] 1281 | 1282 | [[package]] 1283 | name = "merlin" 1284 | version = "3.0.0" 1285 | source = "registry+https://github.com/rust-lang/crates.io-index" 1286 | checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" 1287 | dependencies = [ 1288 | "byteorder", 1289 | "keccak", 1290 | "rand_core 0.6.4", 1291 | "zeroize", 1292 | ] 1293 | 1294 | [[package]] 1295 | name = "mpl-token-metadata" 1296 | version = "4.1.2" 1297 | source = "registry+https://github.com/rust-lang/crates.io-index" 1298 | checksum = "caf0f61b553e424a6234af1268456972ee66c2222e1da89079242251fa7479e5" 1299 | dependencies = [ 1300 | "borsh 0.10.4", 1301 | "num-derive 0.3.3", 1302 | "num-traits", 1303 | "solana-program", 1304 | "thiserror", 1305 | ] 1306 | 1307 | [[package]] 1308 | name = "num-bigint" 1309 | version = "0.4.6" 1310 | source = "registry+https://github.com/rust-lang/crates.io-index" 1311 | checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" 1312 | dependencies = [ 1313 | "num-integer", 1314 | "num-traits", 1315 | ] 1316 | 1317 | [[package]] 1318 | name = "num-derive" 1319 | version = "0.3.3" 1320 | source = "registry+https://github.com/rust-lang/crates.io-index" 1321 | checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" 1322 | dependencies = [ 1323 | "proc-macro2", 1324 | "quote", 1325 | "syn 1.0.109", 1326 | ] 1327 | 1328 | [[package]] 1329 | name = "num-derive" 1330 | version = "0.4.2" 1331 | source = "registry+https://github.com/rust-lang/crates.io-index" 1332 | checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" 1333 | dependencies = [ 1334 | "proc-macro2", 1335 | "quote", 1336 | "syn 2.0.98", 1337 | ] 1338 | 1339 | [[package]] 1340 | name = "num-integer" 1341 | version = "0.1.46" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 1344 | dependencies = [ 1345 | "num-traits", 1346 | ] 1347 | 1348 | [[package]] 1349 | name = "num-traits" 1350 | version = "0.2.19" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1353 | dependencies = [ 1354 | "autocfg", 1355 | ] 1356 | 1357 | [[package]] 1358 | name = "num_enum" 1359 | version = "0.7.3" 1360 | source = "registry+https://github.com/rust-lang/crates.io-index" 1361 | checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" 1362 | dependencies = [ 1363 | "num_enum_derive", 1364 | ] 1365 | 1366 | [[package]] 1367 | name = "num_enum_derive" 1368 | version = "0.7.3" 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" 1370 | checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" 1371 | dependencies = [ 1372 | "proc-macro-crate 3.2.0", 1373 | "proc-macro2", 1374 | "quote", 1375 | "syn 2.0.98", 1376 | ] 1377 | 1378 | [[package]] 1379 | name = "once_cell" 1380 | version = "1.20.3" 1381 | source = "registry+https://github.com/rust-lang/crates.io-index" 1382 | checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" 1383 | 1384 | [[package]] 1385 | name = "opaque-debug" 1386 | version = "0.3.1" 1387 | source = "registry+https://github.com/rust-lang/crates.io-index" 1388 | checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" 1389 | 1390 | [[package]] 1391 | name = "parking_lot" 1392 | version = "0.12.3" 1393 | source = "registry+https://github.com/rust-lang/crates.io-index" 1394 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1395 | dependencies = [ 1396 | "lock_api", 1397 | "parking_lot_core", 1398 | ] 1399 | 1400 | [[package]] 1401 | name = "parking_lot_core" 1402 | version = "0.9.10" 1403 | source = "registry+https://github.com/rust-lang/crates.io-index" 1404 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1405 | dependencies = [ 1406 | "cfg-if", 1407 | "libc", 1408 | "redox_syscall", 1409 | "smallvec", 1410 | "windows-targets", 1411 | ] 1412 | 1413 | [[package]] 1414 | name = "paste" 1415 | version = "1.0.15" 1416 | source = "registry+https://github.com/rust-lang/crates.io-index" 1417 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 1418 | 1419 | [[package]] 1420 | name = "pbkdf2" 1421 | version = "0.4.0" 1422 | source = "registry+https://github.com/rust-lang/crates.io-index" 1423 | checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" 1424 | dependencies = [ 1425 | "crypto-mac", 1426 | ] 1427 | 1428 | [[package]] 1429 | name = "pbkdf2" 1430 | version = "0.11.0" 1431 | source = "registry+https://github.com/rust-lang/crates.io-index" 1432 | checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" 1433 | dependencies = [ 1434 | "digest 0.10.7", 1435 | ] 1436 | 1437 | [[package]] 1438 | name = "percent-encoding" 1439 | version = "2.3.1" 1440 | source = "registry+https://github.com/rust-lang/crates.io-index" 1441 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1442 | 1443 | [[package]] 1444 | name = "polyval" 1445 | version = "0.5.3" 1446 | source = "registry+https://github.com/rust-lang/crates.io-index" 1447 | checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" 1448 | dependencies = [ 1449 | "cfg-if", 1450 | "cpufeatures", 1451 | "opaque-debug", 1452 | "universal-hash", 1453 | ] 1454 | 1455 | [[package]] 1456 | name = "ppv-lite86" 1457 | version = "0.2.20" 1458 | source = "registry+https://github.com/rust-lang/crates.io-index" 1459 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 1460 | dependencies = [ 1461 | "zerocopy", 1462 | ] 1463 | 1464 | [[package]] 1465 | name = "proc-macro-crate" 1466 | version = "0.1.5" 1467 | source = "registry+https://github.com/rust-lang/crates.io-index" 1468 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" 1469 | dependencies = [ 1470 | "toml 0.5.11", 1471 | ] 1472 | 1473 | [[package]] 1474 | name = "proc-macro-crate" 1475 | version = "3.2.0" 1476 | source = "registry+https://github.com/rust-lang/crates.io-index" 1477 | checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" 1478 | dependencies = [ 1479 | "toml_edit", 1480 | ] 1481 | 1482 | [[package]] 1483 | name = "proc-macro2" 1484 | version = "1.0.93" 1485 | source = "registry+https://github.com/rust-lang/crates.io-index" 1486 | checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" 1487 | dependencies = [ 1488 | "unicode-ident", 1489 | ] 1490 | 1491 | [[package]] 1492 | name = "qstring" 1493 | version = "0.7.2" 1494 | source = "registry+https://github.com/rust-lang/crates.io-index" 1495 | checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" 1496 | dependencies = [ 1497 | "percent-encoding", 1498 | ] 1499 | 1500 | [[package]] 1501 | name = "qualifier_attr" 1502 | version = "0.2.2" 1503 | source = "registry+https://github.com/rust-lang/crates.io-index" 1504 | checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" 1505 | dependencies = [ 1506 | "proc-macro2", 1507 | "quote", 1508 | "syn 2.0.98", 1509 | ] 1510 | 1511 | [[package]] 1512 | name = "quote" 1513 | version = "1.0.38" 1514 | source = "registry+https://github.com/rust-lang/crates.io-index" 1515 | checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" 1516 | dependencies = [ 1517 | "proc-macro2", 1518 | ] 1519 | 1520 | [[package]] 1521 | name = "rand" 1522 | version = "0.7.3" 1523 | source = "registry+https://github.com/rust-lang/crates.io-index" 1524 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 1525 | dependencies = [ 1526 | "getrandom 0.1.16", 1527 | "libc", 1528 | "rand_chacha 0.2.2", 1529 | "rand_core 0.5.1", 1530 | "rand_hc", 1531 | ] 1532 | 1533 | [[package]] 1534 | name = "rand" 1535 | version = "0.8.5" 1536 | source = "registry+https://github.com/rust-lang/crates.io-index" 1537 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1538 | dependencies = [ 1539 | "libc", 1540 | "rand_chacha 0.3.1", 1541 | "rand_core 0.6.4", 1542 | ] 1543 | 1544 | [[package]] 1545 | name = "rand_chacha" 1546 | version = "0.2.2" 1547 | source = "registry+https://github.com/rust-lang/crates.io-index" 1548 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 1549 | dependencies = [ 1550 | "ppv-lite86", 1551 | "rand_core 0.5.1", 1552 | ] 1553 | 1554 | [[package]] 1555 | name = "rand_chacha" 1556 | version = "0.3.1" 1557 | source = "registry+https://github.com/rust-lang/crates.io-index" 1558 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1559 | dependencies = [ 1560 | "ppv-lite86", 1561 | "rand_core 0.6.4", 1562 | ] 1563 | 1564 | [[package]] 1565 | name = "rand_core" 1566 | version = "0.5.1" 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" 1568 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1569 | dependencies = [ 1570 | "getrandom 0.1.16", 1571 | ] 1572 | 1573 | [[package]] 1574 | name = "rand_core" 1575 | version = "0.6.4" 1576 | source = "registry+https://github.com/rust-lang/crates.io-index" 1577 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1578 | dependencies = [ 1579 | "getrandom 0.2.15", 1580 | ] 1581 | 1582 | [[package]] 1583 | name = "rand_hc" 1584 | version = "0.2.0" 1585 | source = "registry+https://github.com/rust-lang/crates.io-index" 1586 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1587 | dependencies = [ 1588 | "rand_core 0.5.1", 1589 | ] 1590 | 1591 | [[package]] 1592 | name = "rand_xoshiro" 1593 | version = "0.6.0" 1594 | source = "registry+https://github.com/rust-lang/crates.io-index" 1595 | checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" 1596 | dependencies = [ 1597 | "rand_core 0.6.4", 1598 | ] 1599 | 1600 | [[package]] 1601 | name = "rayon" 1602 | version = "1.10.0" 1603 | source = "registry+https://github.com/rust-lang/crates.io-index" 1604 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" 1605 | dependencies = [ 1606 | "either", 1607 | "rayon-core", 1608 | ] 1609 | 1610 | [[package]] 1611 | name = "rayon-core" 1612 | version = "1.12.1" 1613 | source = "registry+https://github.com/rust-lang/crates.io-index" 1614 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" 1615 | dependencies = [ 1616 | "crossbeam-deque", 1617 | "crossbeam-utils", 1618 | ] 1619 | 1620 | [[package]] 1621 | name = "redox_syscall" 1622 | version = "0.5.9" 1623 | source = "registry+https://github.com/rust-lang/crates.io-index" 1624 | checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" 1625 | dependencies = [ 1626 | "bitflags", 1627 | ] 1628 | 1629 | [[package]] 1630 | name = "regex" 1631 | version = "1.11.1" 1632 | source = "registry+https://github.com/rust-lang/crates.io-index" 1633 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 1634 | dependencies = [ 1635 | "aho-corasick", 1636 | "memchr", 1637 | "regex-automata", 1638 | "regex-syntax", 1639 | ] 1640 | 1641 | [[package]] 1642 | name = "regex-automata" 1643 | version = "0.4.9" 1644 | source = "registry+https://github.com/rust-lang/crates.io-index" 1645 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 1646 | dependencies = [ 1647 | "aho-corasick", 1648 | "memchr", 1649 | "regex-syntax", 1650 | ] 1651 | 1652 | [[package]] 1653 | name = "regex-syntax" 1654 | version = "0.8.5" 1655 | source = "registry+https://github.com/rust-lang/crates.io-index" 1656 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 1657 | 1658 | [[package]] 1659 | name = "rustc-hash" 1660 | version = "1.1.0" 1661 | source = "registry+https://github.com/rust-lang/crates.io-index" 1662 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1663 | 1664 | [[package]] 1665 | name = "rustc_version" 1666 | version = "0.4.1" 1667 | source = "registry+https://github.com/rust-lang/crates.io-index" 1668 | checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 1669 | dependencies = [ 1670 | "semver", 1671 | ] 1672 | 1673 | [[package]] 1674 | name = "rustversion" 1675 | version = "1.0.19" 1676 | source = "registry+https://github.com/rust-lang/crates.io-index" 1677 | checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" 1678 | 1679 | [[package]] 1680 | name = "ryu" 1681 | version = "1.0.19" 1682 | source = "registry+https://github.com/rust-lang/crates.io-index" 1683 | checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" 1684 | 1685 | [[package]] 1686 | name = "scopeguard" 1687 | version = "1.2.0" 1688 | source = "registry+https://github.com/rust-lang/crates.io-index" 1689 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1690 | 1691 | [[package]] 1692 | name = "semver" 1693 | version = "1.0.25" 1694 | source = "registry+https://github.com/rust-lang/crates.io-index" 1695 | checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" 1696 | 1697 | [[package]] 1698 | name = "serde" 1699 | version = "1.0.218" 1700 | source = "registry+https://github.com/rust-lang/crates.io-index" 1701 | checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" 1702 | dependencies = [ 1703 | "serde_derive", 1704 | ] 1705 | 1706 | [[package]] 1707 | name = "serde_bytes" 1708 | version = "0.11.15" 1709 | source = "registry+https://github.com/rust-lang/crates.io-index" 1710 | checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" 1711 | dependencies = [ 1712 | "serde", 1713 | ] 1714 | 1715 | [[package]] 1716 | name = "serde_derive" 1717 | version = "1.0.218" 1718 | source = "registry+https://github.com/rust-lang/crates.io-index" 1719 | checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" 1720 | dependencies = [ 1721 | "proc-macro2", 1722 | "quote", 1723 | "syn 2.0.98", 1724 | ] 1725 | 1726 | [[package]] 1727 | name = "serde_json" 1728 | version = "1.0.139" 1729 | source = "registry+https://github.com/rust-lang/crates.io-index" 1730 | checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" 1731 | dependencies = [ 1732 | "itoa", 1733 | "memchr", 1734 | "ryu", 1735 | "serde", 1736 | ] 1737 | 1738 | [[package]] 1739 | name = "serde_spanned" 1740 | version = "0.6.8" 1741 | source = "registry+https://github.com/rust-lang/crates.io-index" 1742 | checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" 1743 | dependencies = [ 1744 | "serde", 1745 | ] 1746 | 1747 | [[package]] 1748 | name = "serde_with" 1749 | version = "2.3.3" 1750 | source = "registry+https://github.com/rust-lang/crates.io-index" 1751 | checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" 1752 | dependencies = [ 1753 | "serde", 1754 | "serde_with_macros", 1755 | ] 1756 | 1757 | [[package]] 1758 | name = "serde_with_macros" 1759 | version = "2.3.3" 1760 | source = "registry+https://github.com/rust-lang/crates.io-index" 1761 | checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" 1762 | dependencies = [ 1763 | "darling", 1764 | "proc-macro2", 1765 | "quote", 1766 | "syn 2.0.98", 1767 | ] 1768 | 1769 | [[package]] 1770 | name = "sha2" 1771 | version = "0.9.9" 1772 | source = "registry+https://github.com/rust-lang/crates.io-index" 1773 | checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" 1774 | dependencies = [ 1775 | "block-buffer 0.9.0", 1776 | "cfg-if", 1777 | "cpufeatures", 1778 | "digest 0.9.0", 1779 | "opaque-debug", 1780 | ] 1781 | 1782 | [[package]] 1783 | name = "sha2" 1784 | version = "0.10.8" 1785 | source = "registry+https://github.com/rust-lang/crates.io-index" 1786 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1787 | dependencies = [ 1788 | "cfg-if", 1789 | "cpufeatures", 1790 | "digest 0.10.7", 1791 | ] 1792 | 1793 | [[package]] 1794 | name = "sha3" 1795 | version = "0.9.1" 1796 | source = "registry+https://github.com/rust-lang/crates.io-index" 1797 | checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" 1798 | dependencies = [ 1799 | "block-buffer 0.9.0", 1800 | "digest 0.9.0", 1801 | "keccak", 1802 | "opaque-debug", 1803 | ] 1804 | 1805 | [[package]] 1806 | name = "sha3" 1807 | version = "0.10.8" 1808 | source = "registry+https://github.com/rust-lang/crates.io-index" 1809 | checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" 1810 | dependencies = [ 1811 | "digest 0.10.7", 1812 | "keccak", 1813 | ] 1814 | 1815 | [[package]] 1816 | name = "shlex" 1817 | version = "1.3.0" 1818 | source = "registry+https://github.com/rust-lang/crates.io-index" 1819 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1820 | 1821 | [[package]] 1822 | name = "signature" 1823 | version = "1.6.4" 1824 | source = "registry+https://github.com/rust-lang/crates.io-index" 1825 | checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" 1826 | 1827 | [[package]] 1828 | name = "siphasher" 1829 | version = "0.3.11" 1830 | source = "registry+https://github.com/rust-lang/crates.io-index" 1831 | checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" 1832 | 1833 | [[package]] 1834 | name = "sized-chunks" 1835 | version = "0.6.5" 1836 | source = "registry+https://github.com/rust-lang/crates.io-index" 1837 | checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" 1838 | dependencies = [ 1839 | "bitmaps", 1840 | "typenum", 1841 | ] 1842 | 1843 | [[package]] 1844 | name = "smallvec" 1845 | version = "1.14.0" 1846 | source = "registry+https://github.com/rust-lang/crates.io-index" 1847 | checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" 1848 | 1849 | [[package]] 1850 | name = "solana-frozen-abi" 1851 | version = "1.18.26" 1852 | source = "registry+https://github.com/rust-lang/crates.io-index" 1853 | checksum = "03ab2c30c15311b511c0d1151e4ab6bc9a3e080a37e7c6e7c2d96f5784cf9434" 1854 | dependencies = [ 1855 | "block-buffer 0.10.4", 1856 | "bs58 0.4.0", 1857 | "bv", 1858 | "either", 1859 | "generic-array", 1860 | "im", 1861 | "lazy_static", 1862 | "log", 1863 | "memmap2", 1864 | "rustc_version", 1865 | "serde", 1866 | "serde_bytes", 1867 | "serde_derive", 1868 | "sha2 0.10.8", 1869 | "solana-frozen-abi-macro", 1870 | "subtle", 1871 | "thiserror", 1872 | ] 1873 | 1874 | [[package]] 1875 | name = "solana-frozen-abi-macro" 1876 | version = "1.18.26" 1877 | source = "registry+https://github.com/rust-lang/crates.io-index" 1878 | checksum = "c142f779c3633ac83c84d04ff06c70e1f558c876f13358bed77ba629c7417932" 1879 | dependencies = [ 1880 | "proc-macro2", 1881 | "quote", 1882 | "rustc_version", 1883 | "syn 2.0.98", 1884 | ] 1885 | 1886 | [[package]] 1887 | name = "solana-logger" 1888 | version = "1.18.26" 1889 | source = "registry+https://github.com/rust-lang/crates.io-index" 1890 | checksum = "121d36ffb3c6b958763312cbc697fbccba46ee837d3a0aa4fc0e90fcb3b884f3" 1891 | dependencies = [ 1892 | "env_logger", 1893 | "lazy_static", 1894 | "log", 1895 | ] 1896 | 1897 | [[package]] 1898 | name = "solana-program" 1899 | version = "1.18.26" 1900 | source = "registry+https://github.com/rust-lang/crates.io-index" 1901 | checksum = "c10f4588cefd716b24a1a40dd32c278e43a560ab8ce4de6b5805c9d113afdfa1" 1902 | dependencies = [ 1903 | "ark-bn254", 1904 | "ark-ec", 1905 | "ark-ff", 1906 | "ark-serialize", 1907 | "base64 0.21.7", 1908 | "bincode", 1909 | "bitflags", 1910 | "blake3", 1911 | "borsh 0.10.4", 1912 | "borsh 0.9.3", 1913 | "borsh 1.5.5", 1914 | "bs58 0.4.0", 1915 | "bv", 1916 | "bytemuck", 1917 | "cc", 1918 | "console_error_panic_hook", 1919 | "console_log", 1920 | "curve25519-dalek", 1921 | "getrandom 0.2.15", 1922 | "itertools", 1923 | "js-sys", 1924 | "lazy_static", 1925 | "libc", 1926 | "libsecp256k1", 1927 | "light-poseidon", 1928 | "log", 1929 | "memoffset", 1930 | "num-bigint", 1931 | "num-derive 0.4.2", 1932 | "num-traits", 1933 | "parking_lot", 1934 | "rand 0.8.5", 1935 | "rustc_version", 1936 | "rustversion", 1937 | "serde", 1938 | "serde_bytes", 1939 | "serde_derive", 1940 | "serde_json", 1941 | "sha2 0.10.8", 1942 | "sha3 0.10.8", 1943 | "solana-frozen-abi", 1944 | "solana-frozen-abi-macro", 1945 | "solana-sdk-macro", 1946 | "thiserror", 1947 | "tiny-bip39", 1948 | "wasm-bindgen", 1949 | "zeroize", 1950 | ] 1951 | 1952 | [[package]] 1953 | name = "solana-sdk" 1954 | version = "1.18.26" 1955 | source = "registry+https://github.com/rust-lang/crates.io-index" 1956 | checksum = "580ad66c2f7a4c3cb3244fe21440546bd500f5ecb955ad9826e92a78dded8009" 1957 | dependencies = [ 1958 | "assert_matches", 1959 | "base64 0.21.7", 1960 | "bincode", 1961 | "bitflags", 1962 | "borsh 1.5.5", 1963 | "bs58 0.4.0", 1964 | "bytemuck", 1965 | "byteorder", 1966 | "chrono", 1967 | "derivation-path", 1968 | "digest 0.10.7", 1969 | "ed25519-dalek", 1970 | "ed25519-dalek-bip32", 1971 | "generic-array", 1972 | "hmac 0.12.1", 1973 | "itertools", 1974 | "js-sys", 1975 | "lazy_static", 1976 | "libsecp256k1", 1977 | "log", 1978 | "memmap2", 1979 | "num-derive 0.4.2", 1980 | "num-traits", 1981 | "num_enum", 1982 | "pbkdf2 0.11.0", 1983 | "qstring", 1984 | "qualifier_attr", 1985 | "rand 0.7.3", 1986 | "rand 0.8.5", 1987 | "rustc_version", 1988 | "rustversion", 1989 | "serde", 1990 | "serde_bytes", 1991 | "serde_derive", 1992 | "serde_json", 1993 | "serde_with", 1994 | "sha2 0.10.8", 1995 | "sha3 0.10.8", 1996 | "siphasher", 1997 | "solana-frozen-abi", 1998 | "solana-frozen-abi-macro", 1999 | "solana-logger", 2000 | "solana-program", 2001 | "solana-sdk-macro", 2002 | "thiserror", 2003 | "uriparse", 2004 | "wasm-bindgen", 2005 | ] 2006 | 2007 | [[package]] 2008 | name = "solana-sdk-macro" 2009 | version = "1.18.26" 2010 | source = "registry+https://github.com/rust-lang/crates.io-index" 2011 | checksum = "1b75d0f193a27719257af19144fdaebec0415d1c9e9226ae4bd29b791be5e9bd" 2012 | dependencies = [ 2013 | "bs58 0.4.0", 2014 | "proc-macro2", 2015 | "quote", 2016 | "rustversion", 2017 | "syn 2.0.98", 2018 | ] 2019 | 2020 | [[package]] 2021 | name = "solana-security-txt" 2022 | version = "1.1.1" 2023 | source = "registry+https://github.com/rust-lang/crates.io-index" 2024 | checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" 2025 | 2026 | [[package]] 2027 | name = "solana-zk-token-sdk" 2028 | version = "1.18.26" 2029 | source = "registry+https://github.com/rust-lang/crates.io-index" 2030 | checksum = "7cbdf4249b6dfcbba7d84e2b53313698043f60f8e22ce48286e6fbe8a17c8d16" 2031 | dependencies = [ 2032 | "aes-gcm-siv", 2033 | "base64 0.21.7", 2034 | "bincode", 2035 | "bytemuck", 2036 | "byteorder", 2037 | "curve25519-dalek", 2038 | "getrandom 0.1.16", 2039 | "itertools", 2040 | "lazy_static", 2041 | "merlin", 2042 | "num-derive 0.4.2", 2043 | "num-traits", 2044 | "rand 0.7.3", 2045 | "serde", 2046 | "serde_json", 2047 | "sha3 0.9.1", 2048 | "solana-program", 2049 | "solana-sdk", 2050 | "subtle", 2051 | "thiserror", 2052 | "zeroize", 2053 | ] 2054 | 2055 | [[package]] 2056 | name = "spl-associated-token-account" 2057 | version = "3.0.4" 2058 | source = "registry+https://github.com/rust-lang/crates.io-index" 2059 | checksum = "143109d789171379e6143ef23191786dfaac54289ad6e7917cfb26b36c432b10" 2060 | dependencies = [ 2061 | "assert_matches", 2062 | "borsh 1.5.5", 2063 | "num-derive 0.4.2", 2064 | "num-traits", 2065 | "solana-program", 2066 | "spl-token", 2067 | "spl-token-2022", 2068 | "thiserror", 2069 | ] 2070 | 2071 | [[package]] 2072 | name = "spl-discriminator" 2073 | version = "0.2.5" 2074 | source = "registry+https://github.com/rust-lang/crates.io-index" 2075 | checksum = "210101376962bb22bb13be6daea34656ea1cbc248fce2164b146e39203b55e03" 2076 | dependencies = [ 2077 | "bytemuck", 2078 | "solana-program", 2079 | "spl-discriminator-derive", 2080 | ] 2081 | 2082 | [[package]] 2083 | name = "spl-discriminator-derive" 2084 | version = "0.2.0" 2085 | source = "registry+https://github.com/rust-lang/crates.io-index" 2086 | checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" 2087 | dependencies = [ 2088 | "quote", 2089 | "spl-discriminator-syn", 2090 | "syn 2.0.98", 2091 | ] 2092 | 2093 | [[package]] 2094 | name = "spl-discriminator-syn" 2095 | version = "0.2.0" 2096 | source = "registry+https://github.com/rust-lang/crates.io-index" 2097 | checksum = "8c1f05593b7ca9eac7caca309720f2eafb96355e037e6d373b909a80fe7b69b9" 2098 | dependencies = [ 2099 | "proc-macro2", 2100 | "quote", 2101 | "sha2 0.10.8", 2102 | "syn 2.0.98", 2103 | "thiserror", 2104 | ] 2105 | 2106 | [[package]] 2107 | name = "spl-memo" 2108 | version = "4.0.4" 2109 | source = "registry+https://github.com/rust-lang/crates.io-index" 2110 | checksum = "a49f49f95f2d02111ded31696ab38a081fab623d4c76bd4cb074286db4560836" 2111 | dependencies = [ 2112 | "solana-program", 2113 | ] 2114 | 2115 | [[package]] 2116 | name = "spl-pod" 2117 | version = "0.2.5" 2118 | source = "registry+https://github.com/rust-lang/crates.io-index" 2119 | checksum = "c52d84c55efeef8edcc226743dc089d7e3888b8e3474569aa3eff152b37b9996" 2120 | dependencies = [ 2121 | "borsh 1.5.5", 2122 | "bytemuck", 2123 | "solana-program", 2124 | "solana-zk-token-sdk", 2125 | "spl-program-error", 2126 | ] 2127 | 2128 | [[package]] 2129 | name = "spl-program-error" 2130 | version = "0.4.4" 2131 | source = "registry+https://github.com/rust-lang/crates.io-index" 2132 | checksum = "e45a49acb925db68aa501b926096b2164adbdcade7a0c24152af9f0742d0a602" 2133 | dependencies = [ 2134 | "num-derive 0.4.2", 2135 | "num-traits", 2136 | "solana-program", 2137 | "spl-program-error-derive", 2138 | "thiserror", 2139 | ] 2140 | 2141 | [[package]] 2142 | name = "spl-program-error-derive" 2143 | version = "0.4.1" 2144 | source = "registry+https://github.com/rust-lang/crates.io-index" 2145 | checksum = "e6d375dd76c517836353e093c2dbb490938ff72821ab568b545fd30ab3256b3e" 2146 | dependencies = [ 2147 | "proc-macro2", 2148 | "quote", 2149 | "sha2 0.10.8", 2150 | "syn 2.0.98", 2151 | ] 2152 | 2153 | [[package]] 2154 | name = "spl-tlv-account-resolution" 2155 | version = "0.6.5" 2156 | source = "registry+https://github.com/rust-lang/crates.io-index" 2157 | checksum = "fab8edfd37be5fa17c9e42c1bff86abbbaf0494b031b37957f2728ad2ff842ba" 2158 | dependencies = [ 2159 | "bytemuck", 2160 | "solana-program", 2161 | "spl-discriminator", 2162 | "spl-pod", 2163 | "spl-program-error", 2164 | "spl-type-length-value", 2165 | ] 2166 | 2167 | [[package]] 2168 | name = "spl-token" 2169 | version = "4.0.3" 2170 | source = "registry+https://github.com/rust-lang/crates.io-index" 2171 | checksum = "b9eb465e4bf5ce1d498f05204c8089378c1ba34ef2777ea95852fc53a1fd4fb2" 2172 | dependencies = [ 2173 | "arrayref", 2174 | "bytemuck", 2175 | "num-derive 0.4.2", 2176 | "num-traits", 2177 | "num_enum", 2178 | "solana-program", 2179 | "thiserror", 2180 | ] 2181 | 2182 | [[package]] 2183 | name = "spl-token-2022" 2184 | version = "3.0.5" 2185 | source = "registry+https://github.com/rust-lang/crates.io-index" 2186 | checksum = "4c39e416aeb1ea0b22f3b2bbecaf7e38a92a1aa8f4a0c5785c94179694e846a0" 2187 | dependencies = [ 2188 | "arrayref", 2189 | "bytemuck", 2190 | "num-derive 0.4.2", 2191 | "num-traits", 2192 | "num_enum", 2193 | "solana-program", 2194 | "solana-security-txt", 2195 | "solana-zk-token-sdk", 2196 | "spl-memo", 2197 | "spl-pod", 2198 | "spl-token", 2199 | "spl-token-group-interface", 2200 | "spl-token-metadata-interface", 2201 | "spl-transfer-hook-interface", 2202 | "spl-type-length-value", 2203 | "thiserror", 2204 | ] 2205 | 2206 | [[package]] 2207 | name = "spl-token-group-interface" 2208 | version = "0.2.5" 2209 | source = "registry+https://github.com/rust-lang/crates.io-index" 2210 | checksum = "014817d6324b1e20c4bbc883e8ee30a5faa13e59d91d1b2b95df98b920150c17" 2211 | dependencies = [ 2212 | "bytemuck", 2213 | "solana-program", 2214 | "spl-discriminator", 2215 | "spl-pod", 2216 | "spl-program-error", 2217 | ] 2218 | 2219 | [[package]] 2220 | name = "spl-token-metadata-interface" 2221 | version = "0.3.5" 2222 | source = "registry+https://github.com/rust-lang/crates.io-index" 2223 | checksum = "f3da00495b602ebcf5d8ba8b3ecff1ee454ce4c125c9077747be49c2d62335ba" 2224 | dependencies = [ 2225 | "borsh 1.5.5", 2226 | "solana-program", 2227 | "spl-discriminator", 2228 | "spl-pod", 2229 | "spl-program-error", 2230 | "spl-type-length-value", 2231 | ] 2232 | 2233 | [[package]] 2234 | name = "spl-transfer-hook-interface" 2235 | version = "0.6.5" 2236 | source = "registry+https://github.com/rust-lang/crates.io-index" 2237 | checksum = "a9b5c08a89838e5a2931f79b17f611857f281a14a2100968a3ccef352cb7414b" 2238 | dependencies = [ 2239 | "arrayref", 2240 | "bytemuck", 2241 | "solana-program", 2242 | "spl-discriminator", 2243 | "spl-pod", 2244 | "spl-program-error", 2245 | "spl-tlv-account-resolution", 2246 | "spl-type-length-value", 2247 | ] 2248 | 2249 | [[package]] 2250 | name = "spl-type-length-value" 2251 | version = "0.4.6" 2252 | source = "registry+https://github.com/rust-lang/crates.io-index" 2253 | checksum = "c872f93d0600e743116501eba2d53460e73a12c9a496875a42a7d70e034fe06d" 2254 | dependencies = [ 2255 | "bytemuck", 2256 | "solana-program", 2257 | "spl-discriminator", 2258 | "spl-pod", 2259 | "spl-program-error", 2260 | ] 2261 | 2262 | [[package]] 2263 | name = "staking" 2264 | version = "0.1.0" 2265 | dependencies = [ 2266 | "anchor-lang", 2267 | "anchor-spl", 2268 | "solana-program", 2269 | "spl-token", 2270 | ] 2271 | 2272 | [[package]] 2273 | name = "strsim" 2274 | version = "0.11.1" 2275 | source = "registry+https://github.com/rust-lang/crates.io-index" 2276 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 2277 | 2278 | [[package]] 2279 | name = "subtle" 2280 | version = "2.4.1" 2281 | source = "registry+https://github.com/rust-lang/crates.io-index" 2282 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 2283 | 2284 | [[package]] 2285 | name = "syn" 2286 | version = "1.0.109" 2287 | source = "registry+https://github.com/rust-lang/crates.io-index" 2288 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 2289 | dependencies = [ 2290 | "proc-macro2", 2291 | "quote", 2292 | "unicode-ident", 2293 | ] 2294 | 2295 | [[package]] 2296 | name = "syn" 2297 | version = "2.0.98" 2298 | source = "registry+https://github.com/rust-lang/crates.io-index" 2299 | checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" 2300 | dependencies = [ 2301 | "proc-macro2", 2302 | "quote", 2303 | "unicode-ident", 2304 | ] 2305 | 2306 | [[package]] 2307 | name = "termcolor" 2308 | version = "1.4.1" 2309 | source = "registry+https://github.com/rust-lang/crates.io-index" 2310 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 2311 | dependencies = [ 2312 | "winapi-util", 2313 | ] 2314 | 2315 | [[package]] 2316 | name = "thiserror" 2317 | version = "1.0.69" 2318 | source = "registry+https://github.com/rust-lang/crates.io-index" 2319 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 2320 | dependencies = [ 2321 | "thiserror-impl", 2322 | ] 2323 | 2324 | [[package]] 2325 | name = "thiserror-impl" 2326 | version = "1.0.69" 2327 | source = "registry+https://github.com/rust-lang/crates.io-index" 2328 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 2329 | dependencies = [ 2330 | "proc-macro2", 2331 | "quote", 2332 | "syn 2.0.98", 2333 | ] 2334 | 2335 | [[package]] 2336 | name = "tiny-bip39" 2337 | version = "0.8.2" 2338 | source = "registry+https://github.com/rust-lang/crates.io-index" 2339 | checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" 2340 | dependencies = [ 2341 | "anyhow", 2342 | "hmac 0.8.1", 2343 | "once_cell", 2344 | "pbkdf2 0.4.0", 2345 | "rand 0.7.3", 2346 | "rustc-hash", 2347 | "sha2 0.9.9", 2348 | "thiserror", 2349 | "unicode-normalization", 2350 | "wasm-bindgen", 2351 | "zeroize", 2352 | ] 2353 | 2354 | [[package]] 2355 | name = "tinyvec" 2356 | version = "1.8.1" 2357 | source = "registry+https://github.com/rust-lang/crates.io-index" 2358 | checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" 2359 | dependencies = [ 2360 | "tinyvec_macros", 2361 | ] 2362 | 2363 | [[package]] 2364 | name = "tinyvec_macros" 2365 | version = "0.1.1" 2366 | source = "registry+https://github.com/rust-lang/crates.io-index" 2367 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 2368 | 2369 | [[package]] 2370 | name = "toml" 2371 | version = "0.5.11" 2372 | source = "registry+https://github.com/rust-lang/crates.io-index" 2373 | checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" 2374 | dependencies = [ 2375 | "serde", 2376 | ] 2377 | 2378 | [[package]] 2379 | name = "toml" 2380 | version = "0.8.20" 2381 | source = "registry+https://github.com/rust-lang/crates.io-index" 2382 | checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" 2383 | dependencies = [ 2384 | "serde", 2385 | "serde_spanned", 2386 | "toml_datetime", 2387 | "toml_edit", 2388 | ] 2389 | 2390 | [[package]] 2391 | name = "toml_datetime" 2392 | version = "0.6.8" 2393 | source = "registry+https://github.com/rust-lang/crates.io-index" 2394 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 2395 | dependencies = [ 2396 | "serde", 2397 | ] 2398 | 2399 | [[package]] 2400 | name = "toml_edit" 2401 | version = "0.22.24" 2402 | source = "registry+https://github.com/rust-lang/crates.io-index" 2403 | checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" 2404 | dependencies = [ 2405 | "indexmap", 2406 | "serde", 2407 | "serde_spanned", 2408 | "toml_datetime", 2409 | "winnow", 2410 | ] 2411 | 2412 | [[package]] 2413 | name = "typenum" 2414 | version = "1.18.0" 2415 | source = "registry+https://github.com/rust-lang/crates.io-index" 2416 | checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" 2417 | 2418 | [[package]] 2419 | name = "unicode-ident" 2420 | version = "1.0.17" 2421 | source = "registry+https://github.com/rust-lang/crates.io-index" 2422 | checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" 2423 | 2424 | [[package]] 2425 | name = "unicode-normalization" 2426 | version = "0.1.24" 2427 | source = "registry+https://github.com/rust-lang/crates.io-index" 2428 | checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" 2429 | dependencies = [ 2430 | "tinyvec", 2431 | ] 2432 | 2433 | [[package]] 2434 | name = "unicode-segmentation" 2435 | version = "1.12.0" 2436 | source = "registry+https://github.com/rust-lang/crates.io-index" 2437 | checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" 2438 | 2439 | [[package]] 2440 | name = "universal-hash" 2441 | version = "0.4.1" 2442 | source = "registry+https://github.com/rust-lang/crates.io-index" 2443 | checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" 2444 | dependencies = [ 2445 | "generic-array", 2446 | "subtle", 2447 | ] 2448 | 2449 | [[package]] 2450 | name = "uriparse" 2451 | version = "0.6.4" 2452 | source = "registry+https://github.com/rust-lang/crates.io-index" 2453 | checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" 2454 | dependencies = [ 2455 | "fnv", 2456 | "lazy_static", 2457 | ] 2458 | 2459 | [[package]] 2460 | name = "version_check" 2461 | version = "0.9.5" 2462 | source = "registry+https://github.com/rust-lang/crates.io-index" 2463 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 2464 | 2465 | [[package]] 2466 | name = "wasi" 2467 | version = "0.9.0+wasi-snapshot-preview1" 2468 | source = "registry+https://github.com/rust-lang/crates.io-index" 2469 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 2470 | 2471 | [[package]] 2472 | name = "wasi" 2473 | version = "0.11.0+wasi-snapshot-preview1" 2474 | source = "registry+https://github.com/rust-lang/crates.io-index" 2475 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2476 | 2477 | [[package]] 2478 | name = "wasm-bindgen" 2479 | version = "0.2.100" 2480 | source = "registry+https://github.com/rust-lang/crates.io-index" 2481 | checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" 2482 | dependencies = [ 2483 | "cfg-if", 2484 | "once_cell", 2485 | "rustversion", 2486 | "wasm-bindgen-macro", 2487 | ] 2488 | 2489 | [[package]] 2490 | name = "wasm-bindgen-backend" 2491 | version = "0.2.100" 2492 | source = "registry+https://github.com/rust-lang/crates.io-index" 2493 | checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" 2494 | dependencies = [ 2495 | "bumpalo", 2496 | "log", 2497 | "proc-macro2", 2498 | "quote", 2499 | "syn 2.0.98", 2500 | "wasm-bindgen-shared", 2501 | ] 2502 | 2503 | [[package]] 2504 | name = "wasm-bindgen-macro" 2505 | version = "0.2.100" 2506 | source = "registry+https://github.com/rust-lang/crates.io-index" 2507 | checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" 2508 | dependencies = [ 2509 | "quote", 2510 | "wasm-bindgen-macro-support", 2511 | ] 2512 | 2513 | [[package]] 2514 | name = "wasm-bindgen-macro-support" 2515 | version = "0.2.100" 2516 | source = "registry+https://github.com/rust-lang/crates.io-index" 2517 | checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" 2518 | dependencies = [ 2519 | "proc-macro2", 2520 | "quote", 2521 | "syn 2.0.98", 2522 | "wasm-bindgen-backend", 2523 | "wasm-bindgen-shared", 2524 | ] 2525 | 2526 | [[package]] 2527 | name = "wasm-bindgen-shared" 2528 | version = "0.2.100" 2529 | source = "registry+https://github.com/rust-lang/crates.io-index" 2530 | checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" 2531 | dependencies = [ 2532 | "unicode-ident", 2533 | ] 2534 | 2535 | [[package]] 2536 | name = "web-sys" 2537 | version = "0.3.77" 2538 | source = "registry+https://github.com/rust-lang/crates.io-index" 2539 | checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" 2540 | dependencies = [ 2541 | "js-sys", 2542 | "wasm-bindgen", 2543 | ] 2544 | 2545 | [[package]] 2546 | name = "winapi" 2547 | version = "0.3.9" 2548 | source = "registry+https://github.com/rust-lang/crates.io-index" 2549 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2550 | dependencies = [ 2551 | "winapi-i686-pc-windows-gnu", 2552 | "winapi-x86_64-pc-windows-gnu", 2553 | ] 2554 | 2555 | [[package]] 2556 | name = "winapi-i686-pc-windows-gnu" 2557 | version = "0.4.0" 2558 | source = "registry+https://github.com/rust-lang/crates.io-index" 2559 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2560 | 2561 | [[package]] 2562 | name = "winapi-util" 2563 | version = "0.1.9" 2564 | source = "registry+https://github.com/rust-lang/crates.io-index" 2565 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 2566 | dependencies = [ 2567 | "windows-sys", 2568 | ] 2569 | 2570 | [[package]] 2571 | name = "winapi-x86_64-pc-windows-gnu" 2572 | version = "0.4.0" 2573 | source = "registry+https://github.com/rust-lang/crates.io-index" 2574 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2575 | 2576 | [[package]] 2577 | name = "windows-sys" 2578 | version = "0.59.0" 2579 | source = "registry+https://github.com/rust-lang/crates.io-index" 2580 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2581 | dependencies = [ 2582 | "windows-targets", 2583 | ] 2584 | 2585 | [[package]] 2586 | name = "windows-targets" 2587 | version = "0.52.6" 2588 | source = "registry+https://github.com/rust-lang/crates.io-index" 2589 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2590 | dependencies = [ 2591 | "windows_aarch64_gnullvm", 2592 | "windows_aarch64_msvc", 2593 | "windows_i686_gnu", 2594 | "windows_i686_gnullvm", 2595 | "windows_i686_msvc", 2596 | "windows_x86_64_gnu", 2597 | "windows_x86_64_gnullvm", 2598 | "windows_x86_64_msvc", 2599 | ] 2600 | 2601 | [[package]] 2602 | name = "windows_aarch64_gnullvm" 2603 | version = "0.52.6" 2604 | source = "registry+https://github.com/rust-lang/crates.io-index" 2605 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2606 | 2607 | [[package]] 2608 | name = "windows_aarch64_msvc" 2609 | version = "0.52.6" 2610 | source = "registry+https://github.com/rust-lang/crates.io-index" 2611 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2612 | 2613 | [[package]] 2614 | name = "windows_i686_gnu" 2615 | version = "0.52.6" 2616 | source = "registry+https://github.com/rust-lang/crates.io-index" 2617 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2618 | 2619 | [[package]] 2620 | name = "windows_i686_gnullvm" 2621 | version = "0.52.6" 2622 | source = "registry+https://github.com/rust-lang/crates.io-index" 2623 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2624 | 2625 | [[package]] 2626 | name = "windows_i686_msvc" 2627 | version = "0.52.6" 2628 | source = "registry+https://github.com/rust-lang/crates.io-index" 2629 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2630 | 2631 | [[package]] 2632 | name = "windows_x86_64_gnu" 2633 | version = "0.52.6" 2634 | source = "registry+https://github.com/rust-lang/crates.io-index" 2635 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2636 | 2637 | [[package]] 2638 | name = "windows_x86_64_gnullvm" 2639 | version = "0.52.6" 2640 | source = "registry+https://github.com/rust-lang/crates.io-index" 2641 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2642 | 2643 | [[package]] 2644 | name = "windows_x86_64_msvc" 2645 | version = "0.52.6" 2646 | source = "registry+https://github.com/rust-lang/crates.io-index" 2647 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2648 | 2649 | [[package]] 2650 | name = "winnow" 2651 | version = "0.7.3" 2652 | source = "registry+https://github.com/rust-lang/crates.io-index" 2653 | checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" 2654 | dependencies = [ 2655 | "memchr", 2656 | ] 2657 | 2658 | [[package]] 2659 | name = "zerocopy" 2660 | version = "0.7.35" 2661 | source = "registry+https://github.com/rust-lang/crates.io-index" 2662 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 2663 | dependencies = [ 2664 | "byteorder", 2665 | "zerocopy-derive", 2666 | ] 2667 | 2668 | [[package]] 2669 | name = "zerocopy-derive" 2670 | version = "0.7.35" 2671 | source = "registry+https://github.com/rust-lang/crates.io-index" 2672 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 2673 | dependencies = [ 2674 | "proc-macro2", 2675 | "quote", 2676 | "syn 2.0.98", 2677 | ] 2678 | 2679 | [[package]] 2680 | name = "zeroize" 2681 | version = "1.3.0" 2682 | source = "registry+https://github.com/rust-lang/crates.io-index" 2683 | checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" 2684 | dependencies = [ 2685 | "zeroize_derive", 2686 | ] 2687 | 2688 | [[package]] 2689 | name = "zeroize_derive" 2690 | version = "1.4.2" 2691 | source = "registry+https://github.com/rust-lang/crates.io-index" 2692 | checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" 2693 | dependencies = [ 2694 | "proc-macro2", 2695 | "quote", 2696 | "syn 2.0.98", 2697 | ] 2698 | --------------------------------------------------------------------------------