From c86a458aa1dfd644cf7ed01e48e210ddb721a8d8 Mon Sep 17 00:00:00 2001 From: Abstract Void <33007416+cheliosooo@users.noreply.github.com> Date: Wed, 22 Jan 2025 22:26:13 -0500 Subject: [PATCH 01/88] Robustness & UX fixes (#9) * add jup api retries * fix max ltv calc * fix function name * add switchboard support in program * switchboard support and support more tokens * bump ver * small fixes * fixes * bump ver * wip supporting rebalancing different marginfi groups * fixes * fixes * switchboard tokens support * remove unused arg * fixes * fixes * small fix * rm jito-ts * cleanup * small fix * fixes * bump * fix * fix * fix * fixes * fix * fix * fix * fix * fixes * add test * change command * fixes * remove log * fixes * remove log * fixes * fixes * fixes * fixes * fixes * fixes * fixes * fixes * wip * fixes * fixes * fixes * remove log * fix * fix * fixes * fixes * fixes * fixes * fixes * simulate bundles * local script changes * revert accidental change * small fix * fix * wip * debugging improvements for errors * fix * small fixes * small fixes * local script changes * fix * small fix * fixes * fix * fixes * bundle bug fix * use debt liquidity on repay if needed * temp --- .gitignore | 3 +- generateClients.cjs | 10 +- idls/marginfi.json | 10 +- idls/solauto.json | 5 +- package.json | 13 +- .../generated/types/solauto_rebalance_type.rs | 3 +- programs/solauto/src/clients/marginfi.rs | 267 ++++++------ .../solauto/src/instructions/rebalance.rs | 5 +- .../solauto/src/state/solauto_position.rs | 3 +- programs/solauto/src/types/solauto_manager.rs | 302 +++++--------- programs/solauto/src/utils/rebalance_utils.rs | 19 +- programs/solauto/src/utils/solauto_utils.rs | 3 +- .../solauto/src/utils/validation_utils.rs | 229 +++++----- solauto-sdk/local/logPositions.ts | 232 +++++++++++ solauto-sdk/package.json | 15 +- solauto-sdk/pnpm-lock.yaml | 394 +++++++++++++++--- .../src/clients/referralStateManager.ts | 19 +- solauto-sdk/src/clients/solautoClient.ts | 5 +- .../src/clients/solautoMarginfiClient.ts | 94 +++-- solauto-sdk/src/clients/txHandler.ts | 4 +- solauto-sdk/src/constants/marginfiAccounts.ts | 16 +- .../src/constants/switchboardConstants.ts | 1 + solauto-sdk/src/constants/tokenConstants.ts | 11 +- .../generated/types/solautoRebalanceType.ts | 3 +- .../src/transactions/transactionUtils.ts | 197 ++++++--- .../src/transactions/transactionsManager.ts | 97 +++-- solauto-sdk/src/types/index.ts | 1 + solauto-sdk/src/types/solauto.ts | 1 + solauto-sdk/src/types/transactions.ts | 23 + solauto-sdk/src/utils/accountUtils.ts | 53 ++- solauto-sdk/src/utils/generalUtils.ts | 11 + solauto-sdk/src/utils/jitoUtils.ts | 312 ++++++++++---- solauto-sdk/src/utils/jupiterUtils.ts | 48 ++- solauto-sdk/src/utils/marginfiUtils.ts | 36 +- solauto-sdk/src/utils/numberUtils.ts | 6 + solauto-sdk/src/utils/priceUtils.ts | 66 +-- solauto-sdk/src/utils/solanaUtils.ts | 85 ++-- solauto-sdk/src/utils/solauto/generalUtils.ts | 12 +- .../src/utils/solauto/rebalanceUtils.ts | 114 +++-- solauto-sdk/src/utils/switchboardUtils.ts | 7 +- .../tests/transactions/solautoMarginfi.ts | 33 +- 41 files changed, 1850 insertions(+), 918 deletions(-) create mode 100644 solauto-sdk/local/logPositions.ts create mode 100644 solauto-sdk/src/types/transactions.ts diff --git a/.gitignore b/.gitignore index 044f1fdc..4e897b95 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ target **/node_modules/ .yarn .vscode -dist \ No newline at end of file +dist +.env \ No newline at end of file diff --git a/generateClients.cjs b/generateClients.cjs index 4a75f9de..8f72e429 100644 --- a/generateClients.cjs +++ b/generateClients.cjs @@ -103,11 +103,11 @@ generateSolautoSDK(); // "MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA" // ); -generateRustSDKForAnchorIDL( - "jupiter-sdk", - "jupiter.json", - "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4" -); +// generateRustSDKForAnchorIDL( +// "jupiter-sdk", +// "jupiter.json", +// "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4" +// ); // generateTypescriptSDKForAnchorIDL( // "jupiter-sdk", // "jupiter.json", diff --git a/idls/marginfi.json b/idls/marginfi.json index 1166a744..3d182d26 100644 --- a/idls/marginfi.json +++ b/idls/marginfi.json @@ -2601,16 +2601,10 @@ "name": "None" }, { - "name": "PythLegacy" + "name": "PythEma" }, { - "name": "SwitchboardLegacy" - }, - { - "name": "PythPushOracle" - }, - { - "name": "SwitchboardPull" + "name": "SwitchboardV2" } ] } diff --git a/idls/solauto.json b/idls/solauto.json index a4efc846..c8654f39 100644 --- a/idls/solauto.json +++ b/idls/solauto.json @@ -1519,7 +1519,10 @@ "name": "DoubleRebalanceWithFL" }, { - "name": "SingleRebalanceWithFL" + "name": "FLSwapThenRebalance" + }, + { + "name": "FLRebalanceThenSwap" } ] } diff --git a/package.json b/package.json index 4657b6be..bff6dd7f 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,6 @@ "build:rs:local": "cargo build-sbf -- --package solauto --features local", "build:rs:test": "cargo build-sbf -- --package solauto --features test", "build:rs:prod": "cargo build-sbf", - "verified-build": "solana-verify build --library-name solauto", "build:ts": "cd solauto-sdk && npm run build", "deploy:buffer": "solana program write-buffer target/deploy/solauto.so --buffer ~/.config/solana/buffer.json --max-sign-attempts 50", "deploy:rs:test": "solana program deploy target/deploy/solauto.so --keypair ~/.config/solana/solauto-auth.json --program-id TesTjfQ6TbXv96Tv6fqr95XTZ1LYPxtkafmShN9PjBp --use-rpc --buffer ~/.config/solana/buffer.json --max-sign-attempts 50", @@ -19,11 +18,13 @@ "test:ts:unit": "cd solauto-sdk && pnpm test:unit", "test:ts:txs": "cd solauto-sdk && pnpm test:txs", "test:ts:all": "cd solauto-sdk && pnpm test:all", - "update-lut:solauto": "cd solauto-sdk && pnpm update-lut:solauto", - "update-lut:marginfi": "cd solauto-sdk && pnpm update-lut:marginfi", - "create-token-accounts": "cd solauto-sdk && pnpm create-token-accounts", - "create-ism-accounts": "cd solauto-sdk && pnpm create-sm-accounts", - "solana-verify": "solana-verify verify-from-repo --remote -um --program-id AutoyKBRaHSBHy9RsmXCZMy6nNFAg5FYijrvZyQcNLV https://github.com/haven-fi/solauto --library-name solauto" + "solana-verify": "solana-verify verify-from-repo --remote -um --program-id AutoyKBRaHSBHy9RsmXCZMy6nNFAg5FYijrvZyQcNLV https://github.com/haven-fi/solauto --library-name solauto --base-image solanafoundation/solana-verifiable-build@sha256:f3d3a4adaa8008644fc4535373c6818275c7e35a0b07660890b4a95ef434221e", + "update-lut:solauto": "cd solauto-sdk && npx ts-node local/updateSolautoLUT.ts", + "update-lut:marginfi": "cd solauto-sdk && npx ts-node local/updateMarginfiLUT.ts", + "create-token-accounts": "cd solauto-sdk && npx ts-node local/createTokenAccounts.ts", + "create-ism-accounts": "cd solauto-sdk && npx ts-node local/createISMAccounts.ts", + "prepare-accounts": "pnpm create-token-accounts && pnpm create-ism-accounts && pnpm update-lut:solauto && pnpm update-lut:marginfi", + "log-positions": "cd solauto-sdk && npx ts-node local/logPositions.ts" }, "dependencies": { "@metaplex-foundation/kinobi": "^0.18.5" diff --git a/programs/solauto-sdk/src/generated/types/solauto_rebalance_type.rs b/programs/solauto-sdk/src/generated/types/solauto_rebalance_type.rs index 054d51bb..943dd19b 100644 --- a/programs/solauto-sdk/src/generated/types/solauto_rebalance_type.rs +++ b/programs/solauto-sdk/src/generated/types/solauto_rebalance_type.rs @@ -17,5 +17,6 @@ pub enum SolautoRebalanceType { None, Regular, DoubleRebalanceWithFL, - SingleRebalanceWithFL, + FLSwapThenRebalance, + FLRebalanceThenSwap, } diff --git a/programs/solauto/src/clients/marginfi.rs b/programs/solauto/src/clients/marginfi.rs index 24bf7c0d..0e5d8439 100644 --- a/programs/solauto/src/clients/marginfi.rs +++ b/programs/solauto/src/clients/marginfi.rs @@ -1,43 +1,43 @@ use borsh::BorshDeserialize; use fixed::types::I80F48; +use fixed_macro::types::I80F48; use marginfi_sdk::generated::{ - accounts::{ Bank, MarginfiAccount }, + accounts::{Bank, MarginfiAccount}, instructions::*, - types::{ Balance, OracleSetup }, + types::{Balance, OracleSetup}, }; -use fixed_macro::types::I80F48; use pyth_sdk_solana::state::SolanaPriceAccount; use pyth_solana_receiver_sdk::price_update::PriceUpdateV2; use solana_program::{ - account_info::AccountInfo, - clock::Clock, - entrypoint::ProgramResult, - msg, - program_error::ProgramError, - pubkey::Pubkey, - sysvar::Sysvar, + account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, + program_error::ProgramError, pubkey::Pubkey, sysvar::Sysvar, +}; +use std::{ + cmp::min, + ops::{Div, Mul, Sub}, }; -use std::{ cmp::min, ops::{ Div, Mul, Sub } }; -use switchboard_v2::AggregatorAccountData; use switchboard_on_demand::PullFeedAccountData; +use switchboard_v2::AggregatorAccountData; use crate::{ state::solauto_position::SolautoPosition, types::{ instruction::{ - accounts::{ Context, MarginfiOpenPositionAccounts }, + accounts::{Context, MarginfiOpenPositionAccounts}, SolautoStandardAccounts, }, - lending_protocol::{ LendingProtocolClient, LendingProtocolTokenAccounts }, + lending_protocol::{LendingProtocolClient, LendingProtocolTokenAccounts}, shared::{ - DeserializedAccount, - RefreshStateProps, - RefreshedTokenData, - SolautoError, + DeserializedAccount, RefreshStateProps, RefreshedTokenData, SolautoError, TokenBalanceAmount, }, }, - utils::{ math_utils::{self, i80f48_to_f64}, solana_utils::*, solauto_utils::*, validation_utils::* }, + utils::{ + math_utils::{self, i80f48_to_f64}, + solana_utils::*, + solauto_utils::*, + validation_utils::*, + }, }; pub struct MarginfiBankAccounts<'a> { @@ -60,7 +60,7 @@ impl<'a> MarginfiClient<'a> { pub fn initialize<'c>( ctx: &'c Context<'a, MarginfiOpenPositionAccounts<'a>>, solauto_position: &'c DeserializedAccount<'a, SolautoPosition>, - marignfi_acc_seed_idx: Option + marignfi_acc_seed_idx: Option, ) -> ProgramResult { if account_has_data(ctx.accounts.marginfi_account) { return Ok(()); @@ -75,27 +75,23 @@ impl<'a> MarginfiClient<'a> { authority: marginfi_account_owner, fee_payer: ctx.accounts.signer, system_program: ctx.accounts.system_program, - } + }, ); if marginfi_account_owner.key == solauto_position.account_info.key { let seed_idx_bytes = marignfi_acc_seed_idx.unwrap().to_le_bytes(); let mut marginfi_account_seeds = vec![ solauto_position.account_info.key.as_ref(), - seed_idx_bytes.as_ref() + seed_idx_bytes.as_ref(), ]; - let (_, bump) = Pubkey::find_program_address( - marginfi_account_seeds.as_slice(), - &crate::ID - ); + let (_, bump) = + Pubkey::find_program_address(marginfi_account_seeds.as_slice(), &crate::ID); let binding = [bump]; marginfi_account_seeds.push(&binding); - cpi.invoke_signed( - &[ - solauto_position.data.seeds_with_bump().as_slice(), - marginfi_account_seeds.as_slice(), - ] - ) + cpi.invoke_signed(&[ + solauto_position.data.seeds_with_bump().as_slice(), + marginfi_account_seeds.as_slice(), + ]) } else { cpi.invoke() } @@ -113,7 +109,7 @@ impl<'a> MarginfiClient<'a> { debt_bank: &'a AccountInfo<'a>, debt_price_oracle: Option<&'a AccountInfo<'a>>, debt_tas: LendingProtocolTokenAccounts<'a>, - debt_vault_authority: Option<&'a AccountInfo<'a>> + debt_vault_authority: Option<&'a AccountInfo<'a>>, ) -> Result { let supply = MarginfiBankAccounts { bank: DeserializedAccount::::zerocopy(Some(supply_bank))?.unwrap(), @@ -132,9 +128,10 @@ impl<'a> MarginfiClient<'a> { Ok(Self { signer, program, - marginfi_account: DeserializedAccount:: - ::zerocopy(Some(marginfi_account))? - .unwrap(), + marginfi_account: DeserializedAccount::::zerocopy(Some( + marginfi_account, + ))? + .unwrap(), marginfi_group, supply, debt, @@ -144,7 +141,7 @@ impl<'a> MarginfiClient<'a> { fn get_account_balance( account_balances: &[Balance], bank: &DeserializedAccount, - is_supply: bool + is_supply: bool, ) -> Option { account_balances.iter().find_map(|balance| { if &balance.bank_pk == bank.account_info.key { @@ -162,26 +159,24 @@ impl<'a> MarginfiClient<'a> { pub fn get_max_ltv_and_liq_threshold( supply_bank: &'a AccountInfo<'a>, - debt_bank: &'a AccountInfo<'a> + debt_bank: &'a AccountInfo<'a>, ) -> Result<(f64, f64), ProgramError> { let supply_bank = DeserializedAccount::::zerocopy(Some(supply_bank))?.unwrap(); let debt_bank = DeserializedAccount::::zerocopy(Some(debt_bank))?.unwrap(); - let max_ltv = math_utils - ::i80f48_to_f64(I80F48::from_le_bytes(supply_bank.data.config.asset_weight_init.value)) - .div( - math_utils::i80f48_to_f64( - I80F48::from_le_bytes(debt_bank.data.config.liability_weight_init.value) - ) - ); - - let liq_threshold = math_utils - ::i80f48_to_f64(I80F48::from_le_bytes(supply_bank.data.config.asset_weight_maint.value)) - .div( - math_utils::i80f48_to_f64( - I80F48::from_le_bytes(debt_bank.data.config.liability_weight_maint.value) - ) - ); + let max_ltv = math_utils::i80f48_to_f64(I80F48::from_le_bytes( + supply_bank.data.config.asset_weight_init.value, + )) + .div(math_utils::i80f48_to_f64(I80F48::from_le_bytes( + debt_bank.data.config.liability_weight_init.value, + ))); + + let liq_threshold = math_utils::i80f48_to_f64(I80F48::from_le_bytes( + supply_bank.data.config.asset_weight_maint.value, + )) + .div(math_utils::i80f48_to_f64(I80F48::from_le_bytes( + debt_bank.data.config.liability_weight_maint.value, + ))); Ok((max_ltv, liq_threshold)) } @@ -190,7 +185,7 @@ impl<'a> MarginfiClient<'a> { account_balances: &[Balance], supply_bank: &'a AccountInfo<'a>, price_oracle: &'a AccountInfo<'a>, - mut max_ltv: f64 + mut max_ltv: f64, ) -> Result<(RefreshedTokenData, f64), ProgramError> { let bank = DeserializedAccount::::zerocopy(Some(supply_bank))?.unwrap(); @@ -205,26 +200,21 @@ impl<'a> MarginfiClient<'a> { 0 }; - let total_deposited = I80F48::from_le_bytes(bank.data.total_asset_shares.value).mul( - asset_share_value - ); - let base_unit_deposit_room_available = I80F48::from(bank.data.config.deposit_limit).sub( - total_deposited - ); - - let bank_deposits_usd_value = math_utils - ::from_base_unit::( - math_utils::i80f48_to_f64(total_deposited), - bank.data.mint_decimals - ) - .mul(market_price); - if - bank.data.config.total_asset_value_init_limit != 0 && - bank_deposits_usd_value > (bank.data.config.total_asset_value_init_limit as f64) + let total_deposited = + I80F48::from_le_bytes(bank.data.total_asset_shares.value).mul(asset_share_value); + let base_unit_deposit_room_available = + I80F48::from(bank.data.config.deposit_limit).sub(total_deposited); + + let bank_deposits_usd_value = math_utils::from_base_unit::( + math_utils::i80f48_to_f64(total_deposited), + bank.data.mint_decimals, + ) + .mul(market_price); + if bank.data.config.total_asset_value_init_limit != 0 + && bank_deposits_usd_value > (bank.data.config.total_asset_value_init_limit as f64) { - let discount_factor = (bank.data.config.total_asset_value_init_limit as f64).div( - bank_deposits_usd_value - ); + let discount_factor = + (bank.data.config.total_asset_value_init_limit as f64).div(bank_deposits_usd_value); max_ltv = max_ltv * discount_factor; } @@ -244,7 +234,7 @@ impl<'a> MarginfiClient<'a> { pub fn get_debt_token_usage( account_balances: &[Balance], debt_bank: &'a AccountInfo<'a>, - price_oracle: &'a AccountInfo<'a> + price_oracle: &'a AccountInfo<'a>, ) -> Result { let bank = DeserializedAccount::::zerocopy(Some(debt_bank))?.unwrap(); @@ -259,17 +249,18 @@ impl<'a> MarginfiClient<'a> { 0 }; - let total_deposited = I80F48::from_le_bytes(bank.data.total_asset_shares.value).mul( - I80F48::from_le_bytes(bank.data.asset_share_value.value) - ); - let total_borrows = I80F48::from_le_bytes(bank.data.total_liability_shares.value).mul( - liability_share_value - ); + let total_deposited = I80F48::from_le_bytes(bank.data.total_asset_shares.value) + .mul(I80F48::from_le_bytes(bank.data.asset_share_value.value)); + let total_borrows = I80F48::from_le_bytes(bank.data.total_liability_shares.value) + .mul(liability_share_value); let base_unit_supply_available = total_deposited.sub(total_borrows); let amount_can_be_used = min( - bank.data.config.borrow_limit.saturating_sub(math_utils::i80f48_to_u64(total_borrows)), - math_utils::i80f48_to_u64(base_unit_supply_available) + bank.data + .config + .borrow_limit + .saturating_sub(math_utils::i80f48_to_u64(total_borrows)), + math_utils::i80f48_to_u64(base_unit_supply_available), ); Ok(RefreshedTokenData { @@ -287,25 +278,20 @@ impl<'a> MarginfiClient<'a> { supply_bank: &'a AccountInfo<'a>, supply_price_oracle: &'a AccountInfo<'a>, debt_bank: &'a AccountInfo<'a>, - debt_price_oracle: &'a AccountInfo<'a> + debt_price_oracle: &'a AccountInfo<'a>, ) -> Result { - let (max_ltv, liq_threshold) = MarginfiClient::get_max_ltv_and_liq_threshold( - supply_bank, - debt_bank - )?; + let (max_ltv, liq_threshold) = + MarginfiClient::get_max_ltv_and_liq_threshold(supply_bank, debt_bank)?; let account_balances = &marginfi_account.data.lending_account.balances[..2]; - let debt = MarginfiClient::get_debt_token_usage( - account_balances, - debt_bank, - debt_price_oracle - )?; + let debt = + MarginfiClient::get_debt_token_usage(account_balances, debt_bank, debt_price_oracle)?; let (supply, max_ltv) = MarginfiClient::get_supply_token_usage( account_balances, supply_bank, supply_price_oracle, - max_ltv + max_ltv, )?; Ok(RefreshStateProps { @@ -318,7 +304,7 @@ impl<'a> MarginfiClient<'a> { pub fn load_price( bank: &DeserializedAccount, - price_oracle: &AccountInfo + price_oracle: &AccountInfo, ) -> Result { // TODO: Don't validate this until Marginfi's sorted out their price oracle issues and this is congruent with what they use. // if price_oracle.key != &bank.data.config.oracle_keys[0] { @@ -348,12 +334,12 @@ impl<'a> MarginfiClient<'a> { } else if price_result.expo < 0 { math_utils::from_base_unit::( price_result.price, - price_result.expo.unsigned_abs() + price_result.expo.unsigned_abs(), ) } else { math_utils::to_base_unit::( price_result.price, - price_result.expo.unsigned_abs() + price_result.expo.unsigned_abs(), ) }; @@ -376,12 +362,12 @@ impl<'a> MarginfiClient<'a> { } else if price_result.exponent < 0 { math_utils::from_base_unit::( price_result.price, - price_result.exponent.unsigned_abs() + price_result.exponent.unsigned_abs(), ) } else { math_utils::to_base_unit::( price_result.price, - price_result.exponent.unsigned_abs() + price_result.exponent.unsigned_abs(), ) }; @@ -398,7 +384,7 @@ impl<'a> MarginfiClient<'a> { } else { math_utils::from_base_unit::( sw_decimal.mantissa, - sw_decimal.scale + sw_decimal.scale, ) }; @@ -406,9 +392,8 @@ impl<'a> MarginfiClient<'a> { } OracleSetup::SwitchboardPull => { let data = price_oracle.data.borrow(); - let feed = PullFeedAccountData::parse(data).map_err( - |_| SolautoError::IncorrectAccounts - )?; + let feed = PullFeedAccountData::parse(data) + .map_err(|_| SolautoError::IncorrectAccounts)?; let price = I80F48::from_num(feed.result.value) // 10^18 @@ -423,14 +408,14 @@ impl<'a> MarginfiClient<'a> { pub fn refresh_bank( program: &'a AccountInfo<'a>, marginfi_group: &'a AccountInfo<'a>, - bank: &'a AccountInfo<'a> + bank: &'a AccountInfo<'a>, ) -> ProgramResult { let cpi = LendingPoolAccrueBankInterestCpi::new( program, LendingPoolAccrueBankInterestCpiAccounts { marginfi_group, bank, - } + }, ); cpi.invoke() } @@ -441,12 +426,12 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { validate_token_accounts( &std_accounts.solauto_position, self.supply.token_accounts.position_ta, - self.debt.token_accounts.position_ta + self.debt.token_accounts.position_ta, )?; validate_token_accounts( &std_accounts.solauto_position, self.supply.token_accounts.authority_ta, - self.debt.token_accounts.authority_ta + self.debt.token_accounts.authority_ta, )?; Ok(()) } @@ -454,7 +439,7 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { fn deposit<'c>( &self, base_unit_amount: u64, - std_accounts: &'c Box> + std_accounts: &'c Box>, ) -> ProgramResult { let authority = get_owner(&std_accounts.solauto_position, self.signer); @@ -477,11 +462,15 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { }, LendingAccountDepositInstructionArgs { amount: base_unit_amount, - } + }, ); if !std_accounts.solauto_position.data.self_managed.val { - cpi.invoke_signed(&[std_accounts.solauto_position.data.seeds_with_bump().as_slice()]) + cpi.invoke_signed(&[std_accounts + .solauto_position + .data + .seeds_with_bump() + .as_slice()]) } else { cpi.invoke() } @@ -491,11 +480,15 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { &self, amount: TokenBalanceAmount, destination: &'a AccountInfo<'a>, - std_accounts: &'c Box> + std_accounts: &'c Box>, ) -> ProgramResult { let authority = get_owner(&std_accounts.solauto_position, self.signer); - let base_unit_amount = if let TokenBalanceAmount::Some(num) = amount { num } else { 0 }; + let base_unit_amount = if let TokenBalanceAmount::Some(num) = amount { + num + } else { + 0 + }; let cpi = LendingAccountWithdrawCpi::new( self.program, @@ -512,10 +505,14 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { LendingAccountWithdrawInstructionArgs { amount: base_unit_amount, withdraw_all: Some(amount == TokenBalanceAmount::All), - } + }, ); - let active_balances = self.marginfi_account.data.lending_account.balances + let active_balances = self + .marginfi_account + .data + .lending_account + .balances .iter() .filter(|balance| balance.active == 1) .collect::>(); @@ -525,11 +522,9 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { let mut withdrawing_all = amount == TokenBalanceAmount::All; if !withdrawing_all && active_balances.len() == 1 { let asset_shares = I80F48::from_le_bytes(active_balances[0].asset_shares.value); - let supply_balance = math_utils::i80f48_to_u64( - asset_shares.mul( - I80F48::from_le_bytes(self.supply.bank.data.asset_share_value.value) - ) - ); + let supply_balance = math_utils::i80f48_to_u64(asset_shares.mul( + I80F48::from_le_bytes(self.supply.bank.data.asset_share_value.value), + )); let TokenBalanceAmount::Some(withdraw_amount) = amount else { panic!("Unexpected amount type"); }; @@ -548,8 +543,12 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { if !std_accounts.solauto_position.data.self_managed.val { cpi.invoke_signed_with_remaining_accounts( - &[std_accounts.solauto_position.data.seeds_with_bump().as_slice()], - remaining_accounts.as_slice() + &[std_accounts + .solauto_position + .data + .seeds_with_bump() + .as_slice()], + remaining_accounts.as_slice(), ) } else { cpi.invoke_with_remaining_accounts(remaining_accounts.as_slice()) @@ -560,7 +559,7 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { &self, base_unit_amount: u64, destination: &'a AccountInfo<'a>, - std_accounts: &'c Box> + std_accounts: &'c Box>, ) -> ProgramResult { let authority = get_owner(&std_accounts.solauto_position, self.signer); @@ -578,7 +577,7 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { }, LendingAccountBorrowInstructionArgs { amount: base_unit_amount, - } + }, ); let mut remaining_accounts = Vec::with_capacity(4); @@ -589,8 +588,12 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { if !std_accounts.solauto_position.data.self_managed.val { cpi.invoke_signed_with_remaining_accounts( - &[std_accounts.solauto_position.data.seeds_with_bump().as_slice()], - remaining_accounts.as_slice() + &[std_accounts + .solauto_position + .data + .seeds_with_bump() + .as_slice()], + remaining_accounts.as_slice(), ) } else { cpi.invoke_with_remaining_accounts(remaining_accounts.as_slice()) @@ -600,11 +603,15 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { fn repay<'c>( &self, amount: TokenBalanceAmount, - std_accounts: &'c Box> + std_accounts: &'c Box>, ) -> ProgramResult { let authority = get_owner(&std_accounts.solauto_position, self.signer); - let base_unit_amount = if let TokenBalanceAmount::Some(num) = amount { num } else { 0 }; + let base_unit_amount = if let TokenBalanceAmount::Some(num) = amount { + num + } else { + 0 + }; let signer_token_account = if !std_accounts.solauto_position.data.self_managed.val { self.debt.token_accounts.position_ta.as_ref().unwrap() @@ -626,11 +633,15 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { LendingAccountRepayInstructionArgs { amount: base_unit_amount, repay_all: Some(amount == TokenBalanceAmount::All), - } + }, ); if !std_accounts.solauto_position.data.self_managed.val { - cpi.invoke_signed(&[std_accounts.solauto_position.data.seeds_with_bump().as_slice()]) + cpi.invoke_signed(&[std_accounts + .solauto_position + .data + .seeds_with_bump() + .as_slice()]) } else { cpi.invoke() } diff --git a/programs/solauto/src/instructions/rebalance.rs b/programs/solauto/src/instructions/rebalance.rs index a66ec6c8..5a116227 100644 --- a/programs/solauto/src/instructions/rebalance.rs +++ b/programs/solauto/src/instructions/rebalance.rs @@ -59,9 +59,10 @@ pub fn marginfi_rebalance<'a>( let solauto_manager_accounts = SolautoManagerAccounts::from(supply_tas, debt_tas, ctx.accounts.intermediary_ta, None)?; + let rebalance_type = std_accounts.solauto_position.data.rebalance.rebalance_type; if rebalance_step == RebalanceStep::Initial - || std_accounts.solauto_position.data.rebalance.rebalance_type - == SolautoRebalanceType::SingleRebalanceWithFL + || rebalance_type == SolautoRebalanceType::FLSwapThenRebalance + || rebalance_type == SolautoRebalanceType::FLRebalanceThenSwap { if needs_refresh(&std_accounts.solauto_position, &args)? { refresh::marginfi_refresh_accounts( diff --git a/programs/solauto/src/state/solauto_position.rs b/programs/solauto/src/state/solauto_position.rs index 7ddc3e46..c57eb3ba 100644 --- a/programs/solauto/src/state/solauto_position.rs +++ b/programs/solauto/src/state/solauto_position.rs @@ -317,7 +317,8 @@ pub enum SolautoRebalanceType { None, Regular, DoubleRebalanceWithFL, - SingleRebalanceWithFL, + FLSwapThenRebalance, + FLRebalanceThenSwap, } unsafe impl Zeroable for SolautoRebalanceType {} diff --git a/programs/solauto/src/types/solauto_manager.rs b/programs/solauto/src/types/solauto_manager.rs index 8d5114a5..72815551 100644 --- a/programs/solauto/src/types/solauto_manager.rs +++ b/programs/solauto/src/types/solauto_manager.rs @@ -1,24 +1,28 @@ -use math_utils::{from_bps, to_bps}; +use math_utils::{ from_bps, to_bps }; use solana_program::{ - account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, - program_error::ProgramError, sysvar::Sysvar, + account_info::AccountInfo, + clock::Clock, + entrypoint::ProgramResult, + msg, + program_error::ProgramError, + sysvar::Sysvar, }; use spl_associated_token_account::get_associated_token_address; -use std::{ - cmp::min, - ops::{Add, Div, Mul}, -}; +use std::{ cmp::min, ops::{ Add, Div, Mul } }; use validation_utils::validate_debt_adjustment; use super::{ - instruction::{RebalanceSettings, SolautoAction, SolautoStandardAccounts}, - lending_protocol::{LendingProtocolClient, LendingProtocolTokenAccounts}, - shared::{RebalanceDirection, RefreshStateProps, SolautoError, TokenBalanceAmount, TokenType}, + instruction::{ RebalanceSettings, SolautoAction, SolautoStandardAccounts }, + lending_protocol::{ LendingProtocolClient, LendingProtocolTokenAccounts }, + shared::{ RebalanceDirection, RefreshStateProps, SolautoError, TokenBalanceAmount, TokenType }, }; use crate::{ constants::SOLAUTO_FEES_WALLET, state::solauto_position::{ - AutomationSettings, RebalanceData, SolautoPosition, SolautoRebalanceType, + AutomationSettings, + RebalanceData, + SolautoPosition, + SolautoRebalanceType, }, utils::*, }; @@ -34,7 +38,7 @@ impl<'a> SolautoManagerAccounts<'a> { supply: LendingProtocolTokenAccounts<'a>, debt: LendingProtocolTokenAccounts<'a>, intermediary_ta: Option<&'a AccountInfo<'a>>, - solauto_fees: Option, + solauto_fees: Option ) -> Result { Ok(Self { supply, @@ -57,7 +61,7 @@ impl<'a> SolautoManager<'a> { client: Box + 'a>, accounts: SolautoManagerAccounts<'a>, std_accounts: Box>, - solauto_fees_bps: Option, + solauto_fees_bps: Option ) -> Result { client.validate(&std_accounts)?; Ok(Self { @@ -69,69 +73,57 @@ impl<'a> SolautoManager<'a> { } fn deposit(&mut self, base_unit_amount: u64) -> ProgramResult { + msg!("Depositing {}", base_unit_amount); self.update_usage(base_unit_amount as i64, TokenType::Supply); self.client.deposit(base_unit_amount, &self.std_accounts)?; Ok(()) } fn borrow(&mut self, base_unit_amount: u64, destination: &'a AccountInfo<'a>) -> ProgramResult { + msg!("Borrowing {}", base_unit_amount); self.update_usage(base_unit_amount as i64, TokenType::Debt); - self.client - .borrow(base_unit_amount, destination, &self.std_accounts)?; + self.client.borrow(base_unit_amount, destination, &self.std_accounts)?; Ok(()) } fn withdraw( &mut self, amount: TokenBalanceAmount, - destination: &'a AccountInfo<'a>, + destination: &'a AccountInfo<'a> ) -> ProgramResult { let base_unit_amount = match amount { TokenBalanceAmount::All => { - self.std_accounts - .solauto_position - .data - .state - .supply - .amount_used - .base_unit + self.std_accounts.solauto_position.data.state.supply.amount_used.base_unit } TokenBalanceAmount::Some(num) => num, }; + msg!("Withdrawing {}", base_unit_amount); self.update_usage((base_unit_amount as i64) * -1, TokenType::Supply); - self.client - .withdraw(amount, destination, &self.std_accounts)?; + self.client.withdraw(amount, destination, &self.std_accounts)?; Ok(()) } fn repay(&mut self, amount: TokenBalanceAmount) -> ProgramResult { let base_unit_amount = match amount { TokenBalanceAmount::All => { - self.std_accounts - .solauto_position - .data - .state - .debt - .amount_used - .base_unit + self.std_accounts.solauto_position.data.state.debt.amount_used.base_unit } TokenBalanceAmount::Some(num) => num, }; + msg!("Repaying {}", base_unit_amount); self.update_usage((base_unit_amount as i64) * -1, TokenType::Debt); self.client.repay(amount, &self.std_accounts)?; Ok(()) } fn update_usage(&mut self, base_unit_amount: i64, token_type: TokenType) { - if !self.std_accounts.solauto_position.data.self_managed.val - || self.std_accounts.solauto_position.data.rebalance.active() + if + !self.std_accounts.solauto_position.data.self_managed.val || + self.std_accounts.solauto_position.data.rebalance.active() { - self.std_accounts - .solauto_position - .data - .update_usage(token_type, base_unit_amount); + self.std_accounts.solauto_position.data.update_usage(token_type, base_unit_amount); } } @@ -141,10 +133,7 @@ impl<'a> SolautoManager<'a> { self.deposit(base_unit_amount)?; } SolautoAction::Borrow(base_unit_amount) => { - self.borrow( - base_unit_amount, - self.accounts.debt.position_ta.as_ref().unwrap(), - )?; + self.borrow(base_unit_amount, self.accounts.debt.position_ta.as_ref().unwrap())?; } SolautoAction::Repay(amount) => { self.repay(amount)?; @@ -161,19 +150,11 @@ impl<'a> SolautoManager<'a> { &mut self.std_accounts.solauto_position.data, rebalance_args, self.solauto_fees_bps.as_ref().unwrap(), - Clock::get()?.unix_timestamp as u64, + Clock::get()?.unix_timestamp as u64 )?; if amount_to_dca_in.is_some() { - if self - .std_accounts - .solauto_position - .data - .position - .dca - .token_type - == TokenType::Supply - { + if self.std_accounts.solauto_position.data.position.dca.token_type == TokenType::Supply { self.deposit(amount_to_dca_in.unwrap())?; } else { solana_utils::spl_token_transfer( @@ -182,27 +163,18 @@ impl<'a> SolautoManager<'a> { self.std_accounts.solauto_position.account_info, self.accounts.intermediary_ta.unwrap(), amount_to_dca_in.unwrap(), - Some(&self.std_accounts.solauto_position.data.seeds_with_bump()), + Some(&self.std_accounts.solauto_position.data.seeds_with_bump()) )?; } } - if self - .std_accounts - .solauto_position - .data - .rebalance - .rebalance_type - == SolautoRebalanceType::DoubleRebalanceWithFL - { + let rebalance_type = self.std_accounts.solauto_position.data.rebalance.rebalance_type; + if rebalance_type == SolautoRebalanceType::DoubleRebalanceWithFL { validate_debt_adjustment( &self.std_accounts.solauto_position.data, - self.std_accounts - .solauto_position - .data - .rebalance - .flash_loan_amount, + self.std_accounts.solauto_position.data.rebalance.flash_loan_amount, debt_adjustment_usd, + Some(&rebalance_type) )?; return Ok(()); } @@ -217,7 +189,7 @@ impl<'a> SolautoManager<'a> { let base_unit_amount = math_utils::to_base_unit::( debt_adjustment_usd.abs().div(token.market_price()), - token.decimals, + token.decimals ); if increasing_leverage { @@ -232,19 +204,13 @@ impl<'a> SolautoManager<'a> { rebalance_args.target_in_amount_base_unit.unwrap() } else { min( - self.std_accounts - .solauto_position - .data - .state - .supply - .amount_used - .base_unit, - base_unit_amount, + self.std_accounts.solauto_position.data.state.supply.amount_used.base_unit, + base_unit_amount ) }; self.withdraw( TokenBalanceAmount::Some(final_amount), - self.accounts.intermediary_ta.unwrap(), + self.accounts.intermediary_ta.unwrap() ) } } @@ -254,54 +220,41 @@ impl<'a> SolautoManager<'a> { let rebalance_type = rebalance_data.rebalance_type; let flash_loan_amount = rebalance_data.flash_loan_amount; - if rebalance_type == SolautoRebalanceType::SingleRebalanceWithFL { + if + rebalance_type == SolautoRebalanceType::FLSwapThenRebalance || + rebalance_type == SolautoRebalanceType::FLRebalanceThenSwap + { let (debt_adjustment_usd, _) = rebalance_utils::get_rebalance_values( &mut self.std_accounts.solauto_position.data, rebalance_args, self.solauto_fees_bps.as_ref().unwrap(), - Clock::get()?.unix_timestamp as u64, + Clock::get()?.unix_timestamp as u64 )?; validate_debt_adjustment( &self.std_accounts.solauto_position.data, flash_loan_amount, debt_adjustment_usd, + Some(&rebalance_type) )?; } - let boosting = self - .std_accounts - .solauto_position - .data - .rebalance - .rebalance_direction - == RebalanceDirection::Boost; + let boosting = + self.std_accounts.solauto_position.data.rebalance.rebalance_direction == + RebalanceDirection::Boost; let mut available_balance = if boosting { - solauto_utils::safe_unpack_token_account(self.accounts.supply.position_ta)? - .unwrap() - .data - .amount + solauto_utils + ::safe_unpack_token_account(self.accounts.supply.position_ta)? + .unwrap().data.amount } else { - solauto_utils::safe_unpack_token_account(self.accounts.debt.position_ta)? - .unwrap() - .data - .amount + solauto_utils + ::safe_unpack_token_account(self.accounts.debt.position_ta)? + .unwrap().data.amount }; if !self.std_accounts.solauto_position.data.self_managed.val { - let dca_in_base_unit = self - .std_accounts - .solauto_position - .data - .position - .dca - .dca_in_base_unit; - let dca_token_type = self - .std_accounts - .solauto_position - .data - .position - .dca - .token_type; + let dca_in_base_unit = + self.std_accounts.solauto_position.data.position.dca.dca_in_base_unit; + let dca_token_type = self.std_accounts.solauto_position.data.position.dca.token_type; if boosting && dca_token_type == TokenType::Supply { available_balance -= dca_in_base_unit; } else if !boosting && dca_token_type == TokenType::Debt { @@ -309,15 +262,17 @@ impl<'a> SolautoManager<'a> { } } - let transfer_to_authority_ta = |token_accounts: &LendingProtocolTokenAccounts<'a>, - amount: u64| { + let transfer_to_authority_ta = | + token_accounts: &LendingProtocolTokenAccounts<'a>, + amount: u64 + | { solana_utils::spl_token_transfer( self.std_accounts.token_program, token_accounts.position_ta.clone().unwrap(), self.std_accounts.solauto_position.account_info, token_accounts.authority_ta.clone().unwrap(), amount, - Some(&self.std_accounts.solauto_position.data.seeds_with_bump()), + Some(&self.std_accounts.solauto_position.data.seeds_with_bump()) ) }; @@ -332,21 +287,18 @@ impl<'a> SolautoManager<'a> { if self.std_accounts.solauto_position.data.self_managed.val { transfer_to_authority_ta(&self.accounts.debt, amount_after_fees)?; } - let final_amount = if rebalance_args.target_liq_utilization_rate_bps.is_some() - && rebalance_args.target_liq_utilization_rate_bps.unwrap() == 0 + let final_amount = if + rebalance_args.target_liq_utilization_rate_bps.is_some() && + rebalance_args.target_liq_utilization_rate_bps.unwrap() == 0 { TokenBalanceAmount::All } else { - TokenBalanceAmount::Some(min( - self.std_accounts - .solauto_position - .data - .state - .debt - .amount_used - .base_unit, - amount_after_fees, - )) + TokenBalanceAmount::Some( + min( + self.std_accounts.solauto_position.data.state.debt.amount_used.base_unit, + amount_after_fees + ) + ) }; self.repay(final_amount)?; } else { @@ -356,28 +308,25 @@ impl<'a> SolautoManager<'a> { if flash_loan_amount > 0 { let flash_loan_fee_bps = if boosting { - self.std_accounts - .solauto_position - .data - .state - .supply - .flash_loan_fee_bps + self.std_accounts.solauto_position.data.state.supply.flash_loan_fee_bps } else { - self.std_accounts - .solauto_position - .data - .state - .debt - .flash_loan_fee_bps + self.std_accounts.solauto_position.data.state.debt.flash_loan_fee_bps }; - let final_amount = flash_loan_amount - .add((flash_loan_amount as f64).mul(from_bps(flash_loan_fee_bps)) as u64); + + let final_amount = if rebalance_type == SolautoRebalanceType::FLRebalanceThenSwap { + rebalance_args.target_in_amount_base_unit.unwrap() + } else { + flash_loan_amount.add( + (flash_loan_amount as f64).mul(from_bps(flash_loan_fee_bps)) as u64 + ) + }; + if boosting { self.borrow(final_amount, self.accounts.intermediary_ta.unwrap())?; } else { self.withdraw( TokenBalanceAmount::Some(final_amount), - self.accounts.intermediary_ta.unwrap(), + self.accounts.intermediary_ta.unwrap() )?; } } @@ -394,12 +343,8 @@ impl<'a> SolautoManager<'a> { return Err(SolautoError::IncorrectAccounts.into()); } - let rebalance_direction = self - .std_accounts - .solauto_position - .data - .rebalance - .rebalance_direction; + let rebalance_direction = + self.std_accounts.solauto_position.data.rebalance.rebalance_direction; let token_mint = if rebalance_direction == RebalanceDirection::Boost { self.std_accounts.solauto_position.data.state.supply.mint } else { @@ -411,19 +356,16 @@ impl<'a> SolautoManager<'a> { } else { self.accounts.debt.position_ta.unwrap() }; - let fee_payout = self - .solauto_fees_bps - .as_ref() - .unwrap() - .fetch_fees(rebalance_direction); + let fee_payout = self.solauto_fees_bps.as_ref().unwrap().fetch_fees(rebalance_direction); if fee_payout.total == 0 { return Ok(total_available_balance); } let solauto_fees = (total_available_balance as f64).mul(from_bps(fee_payout.total)) as u64; - if self.std_accounts.solauto_fees_ta.unwrap().key - != &get_associated_token_address(&SOLAUTO_FEES_WALLET, &token_mint) + if + self.std_accounts.solauto_fees_ta.unwrap().key != + &get_associated_token_address(&SOLAUTO_FEES_WALLET, &token_mint) { msg!("Incorrect Solauto fees token account"); return Err(SolautoError::IncorrectAccounts.into()); @@ -434,22 +376,20 @@ impl<'a> SolautoManager<'a> { self.std_accounts.solauto_position.account_info, self.std_accounts.solauto_fees_ta.unwrap(), solauto_fees, - Some(&self.std_accounts.solauto_position.data.seeds_with_bump()), + Some(&self.std_accounts.solauto_position.data.seeds_with_bump()) )?; - let referrer_fees = - (total_available_balance as f64).mul(from_bps(fee_payout.referrer)) as u64; + let referrer_fees = (total_available_balance as f64).mul( + from_bps(fee_payout.referrer) + ) as u64; if referrer_fees > 0 { - if self.std_accounts.referred_by_ta.unwrap().key - != &get_associated_token_address( - &self - .std_accounts - .authority_referral_state + if + self.std_accounts.referred_by_ta.unwrap().key != + &get_associated_token_address( + &self.std_accounts.authority_referral_state .as_ref() - .unwrap() - .data - .referred_by_state, - &token_mint, + .unwrap().data.referred_by_state, + &token_mint ) { msg!("Incorrect referral fee token account"); @@ -461,7 +401,7 @@ impl<'a> SolautoManager<'a> { self.std_accounts.solauto_position.account_info, self.std_accounts.referred_by_ta.unwrap(), referrer_fees, - Some(&self.std_accounts.solauto_position.data.seeds_with_bump()), + Some(&self.std_accounts.solauto_position.data.seeds_with_bump()) )?; } @@ -471,7 +411,7 @@ impl<'a> SolautoManager<'a> { pub fn refresh_position( solauto_position: &mut SolautoPosition, updated_data: RefreshStateProps, - clock: Clock, + clock: Clock ) -> ProgramResult { if solauto_position.self_managed.val { solauto_position.state.supply.mint = updated_data.supply.mint; @@ -487,28 +427,22 @@ impl<'a> SolautoManager<'a> { solauto_position.state.supply.amount_used.base_unit = updated_data.supply.amount_used; solauto_position.state.supply.amount_can_be_used.base_unit = updated_data.supply.amount_can_be_used; - solauto_position - .state - .supply - .update_market_price(updated_data.supply.market_price); + solauto_position.state.supply.update_market_price(updated_data.supply.market_price); solauto_position.state.debt.amount_used.base_unit = updated_data.debt.amount_used; solauto_position.state.debt.amount_can_be_used.base_unit = updated_data.debt.amount_can_be_used; - solauto_position - .state - .debt - .update_market_price(updated_data.debt.market_price); + solauto_position.state.debt.update_market_price(updated_data.debt.market_price); solauto_position.state.net_worth.base_unit = math_utils::net_worth_base_amount( solauto_position.state.supply.amount_used.usd_value(), solauto_position.state.debt.amount_used.usd_value(), solauto_position.state.supply.market_price(), - solauto_position.state.supply.decimals, + solauto_position.state.supply.decimals ); solauto_position.state.net_worth.update_usd_value( updated_data.supply.market_price, - solauto_position.state.supply.decimals, + solauto_position.state.supply.decimals ); solauto_position.refresh_state(); @@ -518,21 +452,16 @@ impl<'a> SolautoManager<'a> { return Ok(()); } - if solauto_position - .position - .setting_params - .automation - .is_active() - { + if solauto_position.position.setting_params.automation.is_active() { let automation = &solauto_position.position.setting_params.automation; if automation.eligible_for_next_period(clock.unix_timestamp as u64) { let current_timestamp = Clock::get()?.unix_timestamp as u64; - solauto_position.position.setting_params.boost_to_bps = automation - .updated_amount_from_automation( + solauto_position.position.setting_params.boost_to_bps = + automation.updated_amount_from_automation( solauto_position.position.setting_params.boost_to_bps, solauto_position.position.setting_params.target_boost_to_bps, - current_timestamp, + current_timestamp ); let new_periods_passed = automation.new_periods_passed(current_timestamp); @@ -541,11 +470,8 @@ impl<'a> SolautoManager<'a> { AutomationSettings::default(); solauto_position.position.setting_params.target_boost_to_bps = 0; } else { - solauto_position - .position - .setting_params - .automation - .periods_passed = new_periods_passed; + solauto_position.position.setting_params.automation.periods_passed = + new_periods_passed; } } } diff --git a/programs/solauto/src/utils/rebalance_utils.rs b/programs/solauto/src/utils/rebalance_utils.rs index da1f301f..36ae3a8b 100644 --- a/programs/solauto/src/utils/rebalance_utils.rs +++ b/programs/solauto/src/utils/rebalance_utils.rs @@ -118,7 +118,7 @@ pub fn validate_rebalance_instructions( jup_swap: ((current_ix_idx as i16) + next_ix) as usize, marginfi_flash_borrow: Some(((current_ix_idx as i16) + prev_ix) as usize), }) - } else if (rebalance_type == SolautoRebalanceType::SingleRebalanceWithFL + } else if (rebalance_type == SolautoRebalanceType::FLSwapThenRebalance || rebalance_type == SolautoRebalanceType::None) && marginfi_start_fl.matches(ix_3_before) && marginfi_borrow.matches(ix_2_before) @@ -127,11 +127,25 @@ pub fn validate_rebalance_instructions( && marginfi_end_fl.matches(ix_2_after) { std_accounts.solauto_position.data.rebalance.rebalance_type = - SolautoRebalanceType::SingleRebalanceWithFL; + SolautoRebalanceType::FLSwapThenRebalance; Ok(RebalanceInstructionIndices { jup_swap: ((current_ix_idx as i16) + prev_ix) as usize, marginfi_flash_borrow: Some(((current_ix_idx as i16) + ix_2_before) as usize), }) + } else if (rebalance_type == SolautoRebalanceType::FLRebalanceThenSwap + || rebalance_type == SolautoRebalanceType::None) + && marginfi_start_fl.matches(ix_2_before) + && marginfi_borrow.matches(prev_ix) + && jup_swap.matches(next_ix) + && marginfi_repay.matches(ix_2_after) + && marginfi_end_fl.matches(ix_3_after) + { + std_accounts.solauto_position.data.rebalance.rebalance_type = + SolautoRebalanceType::FLRebalanceThenSwap; + Ok(RebalanceInstructionIndices { + jup_swap: ((current_ix_idx as i16) + next_ix) as usize, + marginfi_flash_borrow: Some(((current_ix_idx as i16) + prev_ix) as usize), + }) } else { msg!("Incorrect rebalance instructions"); Err(SolautoError::IncorrectInstructions.into()) @@ -394,6 +408,7 @@ pub fn get_rebalance_values( solauto_position, args.target_in_amount_base_unit.unwrap(), debt_adjustment_usd, + None )?; } diff --git a/programs/solauto/src/utils/solauto_utils.rs b/programs/solauto/src/utils/solauto_utils.rs index 5ca2030b..919c1f19 100644 --- a/programs/solauto/src/utils/solauto_utils.rs +++ b/programs/solauto/src/utils/solauto_utils.rs @@ -1,5 +1,6 @@ use solana_program::{ - account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, program_error::ProgramError, program_pack::Pack, pubkey::Pubkey, sysvar::Sysvar + account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, + program_error::ProgramError, program_pack::Pack, pubkey::Pubkey, sysvar::Sysvar, }; use spl_associated_token_account::get_associated_token_address; use spl_token::state::{Account as TokenAccount, Mint}; diff --git a/programs/solauto/src/utils/validation_utils.rs b/programs/solauto/src/utils/validation_utils.rs index 14b748c7..5ad0fd8c 100644 --- a/programs/solauto/src/utils/validation_utils.rs +++ b/programs/solauto/src/utils/validation_utils.rs @@ -1,9 +1,6 @@ -use std::ops::{Div, Mul}; +use std::ops::{ Div, Mul }; -use marginfi_sdk::{ - generated::accounts::{Bank, MarginfiAccount}, - MARGINFI_ID, -}; +use marginfi_sdk::{ generated::accounts::{ Bank, MarginfiAccount }, MARGINFI_ID }; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, @@ -11,26 +8,34 @@ use solana_program::{ program_error::ProgramError, pubkey::Pubkey, system_program::ID as system_program_id, - sysvar::{instructions::ID as ixs_sysvar_id, rent::ID as rent_program_id}, + sysvar::{ instructions::ID as ixs_sysvar_id, rent::ID as rent_program_id }, }; -use spl_associated_token_account::{get_associated_token_address, ID as ata_program_id}; +use spl_associated_token_account::{ get_associated_token_address, ID as ata_program_id }; use spl_token::ID as token_program_id; use crate::{ - constants::{MAX_BASIS_POINTS, MIN_BOOST_GAP_BPS, MIN_REPAY_GAP_BPS, SOLAUTO_MANAGER}, + constants::{ MAX_BASIS_POINTS, MIN_BOOST_GAP_BPS, MIN_REPAY_GAP_BPS, SOLAUTO_MANAGER }, state::{ referral_state::ReferralState, - solauto_position::{AutomationSettings, PositionData, SolautoPosition}, + solauto_position::{ + AutomationSettings, + PositionData, + SolautoPosition, + SolautoRebalanceType, + }, }, types::{ instruction::SolautoStandardAccounts, - shared::{DeserializedAccount, LendingPlatform, SolautoError, TokenType}, + shared::{ DeserializedAccount, LendingPlatform, SolautoError, TokenType }, }, }; use super::{ math_utils::{ - from_base_unit, get_max_boost_to_bps, get_max_repay_from_bps, get_max_repay_to_bps, + from_base_unit, + get_max_boost_to_bps, + get_max_repay_from_bps, + get_max_repay_to_bps, }, solauto_utils::safe_unpack_token_account, }; @@ -39,13 +44,13 @@ pub fn generic_instruction_validation( accounts: &Box, lending_platform: LendingPlatform, authority_signer_only_ix: bool, - solauto_managed_only_ix: bool, + solauto_managed_only_ix: bool ) -> ProgramResult { validate_instruction( accounts.signer, &accounts.solauto_position, authority_signer_only_ix, - solauto_managed_only_ix, + solauto_managed_only_ix )?; validate_lending_program_account(accounts.lending_protocol, lending_platform)?; validate_sysvar_accounts( @@ -53,7 +58,7 @@ pub fn generic_instruction_validation( Some(accounts.token_program), accounts.ata_program, accounts.rent, - accounts.ixs_sysvar, + accounts.ixs_sysvar )?; if accounts.authority_referral_state.is_some() { @@ -61,7 +66,7 @@ pub fn generic_instruction_validation( &accounts.solauto_position.data.authority, accounts.authority_referral_state.as_ref().unwrap(), accounts.referred_by_ta, - true, + true )?; } @@ -73,7 +78,7 @@ pub fn validate_instruction( signer: &AccountInfo, solauto_position: &DeserializedAccount, authority_signer_only_ix: bool, - solauto_managed_only_ix: bool, + solauto_managed_only_ix: bool ) -> ProgramResult { if !signer.is_signer { msg!("Signer account is not a signer"); @@ -84,9 +89,8 @@ pub fn validate_instruction( let authority_signed = || { let expected_solauto_position_address = Pubkey::create_program_address( solauto_position.data.seeds_with_bump().as_slice(), - &crate::ID, - ) - .expect("Ok"); + &crate::ID + ).expect("Ok"); let expected_address_matches = solauto_position.account_info.key == &expected_solauto_position_address; return signer.key == &position_authority && expected_address_matches; @@ -117,7 +121,7 @@ pub fn validate_instruction( pub fn validate_position_settings( solauto_position: &SolautoPosition, - current_unix_timestamp: u64, + current_unix_timestamp: u64 ) -> ProgramResult { let invalid_params = |error_msg| { msg!(error_msg); @@ -130,12 +134,10 @@ pub fn validate_position_settings( } let max_boost_to = get_max_boost_to_bps( solauto_position.state.max_ltv_bps, - solauto_position.state.liq_threshold_bps, + solauto_position.state.liq_threshold_bps ); if data.setting_params.boost_to_bps > max_boost_to { - return invalid_params( - format!("Exceeds the maximum boost-to of {}", max_boost_to).as_str(), - ); + return invalid_params(format!("Exceeds the maximum boost-to of {}", max_boost_to).as_str()); } if data.setting_params.repay_to_bps < data.setting_params.target_boost_to_bps { return invalid_params("repay_to_bps value must be greater than target_boost_to_bps value"); @@ -143,12 +145,12 @@ pub fn validate_position_settings( if data.setting_params.repay_gap < MIN_REPAY_GAP_BPS { return invalid_params( - format!("repay_gap must be {} or greater", MIN_REPAY_GAP_BPS).as_str(), + format!("repay_gap must be {} or greater", MIN_REPAY_GAP_BPS).as_str() ); } if data.setting_params.boost_gap < MIN_BOOST_GAP_BPS { return invalid_params( - format!("boost_gap must be {} or greater", MIN_BOOST_GAP_BPS).as_str(), + format!("boost_gap must be {} or greater", MIN_BOOST_GAP_BPS).as_str() ); } @@ -158,13 +160,13 @@ pub fn validate_position_settings( if data.setting_params.target_boost_to_bps > MAX_BASIS_POINTS { return invalid_params( - format!("target_boost_to_bps must be less than {}", MAX_BASIS_POINTS).as_str(), + format!("target_boost_to_bps must be less than {}", MAX_BASIS_POINTS).as_str() ); } let max_repay_to_bps = get_max_repay_to_bps( solauto_position.state.max_ltv_bps, - solauto_position.state.liq_threshold_bps, + solauto_position.state.liq_threshold_bps ); if data.setting_params.repay_to_bps > max_repay_to_bps { return invalid_params( @@ -173,15 +175,11 @@ pub fn validate_position_settings( } let max_repay_from_bps = get_max_repay_from_bps( solauto_position.state.max_ltv_bps, - solauto_position.state.liq_threshold_bps, + solauto_position.state.liq_threshold_bps ); if data.setting_params.repay_from_bps() > max_repay_from_bps { return invalid_params( - format!( - "repay_to_bps + repay_gap must be equal-to or below {}", - max_repay_from_bps - ) - .as_str(), + format!("repay_to_bps + repay_gap must be equal-to or below {}", max_repay_from_bps).as_str() ); } @@ -190,7 +188,7 @@ pub fn validate_position_settings( pub fn validate_dca_settings( position: &PositionData, - current_unix_timestamp: u64, + current_unix_timestamp: u64 ) -> ProgramResult { if position.dca.is_active() { return Ok(()); @@ -201,7 +199,7 @@ pub fn validate_dca_settings( pub fn validate_automation_settings( automation: &AutomationSettings, - current_unix_timestamp: u64, + current_unix_timestamp: u64 ) -> ProgramResult { let invalid_params = |error_msg| { msg!(error_msg); @@ -216,8 +214,9 @@ pub fn validate_automation_settings( return invalid_params("Interval period must be between 10 minutes and 1 month"); } - if current_unix_timestamp < automation.unix_start_date - || current_unix_timestamp > automation.unix_start_date + automation.interval_seconds + if + current_unix_timestamp < automation.unix_start_date || + current_unix_timestamp > automation.unix_start_date + automation.interval_seconds { return invalid_params("Provided an invalid unix start date"); } @@ -231,7 +230,7 @@ pub fn validate_automation_settings( pub fn validate_lending_program_account( program: &AccountInfo, - lending_platform: LendingPlatform, + lending_platform: LendingPlatform ) -> ProgramResult { match lending_platform { LendingPlatform::Marginfi => { @@ -250,7 +249,7 @@ pub fn validate_sysvar_accounts( token_program: Option<&AccountInfo>, ata_program: Option<&AccountInfo>, rent: Option<&AccountInfo>, - ixs_sysvar: Option<&AccountInfo>, + ixs_sysvar: Option<&AccountInfo> ) -> ProgramResult { if system_program.is_some() && system_program.unwrap().key != &system_program_id { msg!("Incorrect system program account provided"); @@ -279,14 +278,15 @@ pub fn validate_referral_accounts<'a>( referral_state_authority: &Pubkey, authority_referral_state: &DeserializedAccount<'a, ReferralState>, referred_by_ta: Option<&'a AccountInfo<'a>>, - validate_ta: bool, + validate_ta: bool ) -> ProgramResult { let referral_state_pda = Pubkey::create_program_address( authority_referral_state.data.seeds_with_bump().as_slice(), - &crate::ID, + &crate::ID )?; - if &authority_referral_state.data.authority != referral_state_authority - || &referral_state_pda != authority_referral_state.account_info.key + if + &authority_referral_state.data.authority != referral_state_authority || + &referral_state_pda != authority_referral_state.account_info.key { msg!("Invalid referral state account given for the provided authority"); return Err(SolautoError::IncorrectAccounts.into()); @@ -294,8 +294,7 @@ pub fn validate_referral_accounts<'a>( let authority_referred_by_state = &authority_referral_state.data.referred_by_state; - if validate_ta && authority_referred_by_state != &Pubkey::default() && referred_by_ta.is_none() - { + if validate_ta && authority_referred_by_state != &Pubkey::default() && referred_by_ta.is_none() { msg!("Did not provide a referred_by_ta when the authority been referred"); return Err(SolautoError::IncorrectAccounts.into()); } @@ -306,7 +305,7 @@ pub fn validate_referral_accounts<'a>( pub fn validate_marginfi_bank<'a>( marginfi_bank: &'a AccountInfo<'a>, - mint: &Pubkey, + mint: &Pubkey ) -> ProgramResult { if mint == &Pubkey::default() { return Ok(()); @@ -325,13 +324,14 @@ pub fn validate_lending_program_accounts_with_position<'a>( solauto_position: &DeserializedAccount, protocol_user_account: &'a AccountInfo<'a>, protocol_supply_account: &'a AccountInfo<'a>, - protocol_debt_account: &'a AccountInfo<'a>, + protocol_debt_account: &'a AccountInfo<'a> ) -> ProgramResult { let supply_mint = &solauto_position.data.state.supply.mint; let debt_mint = &solauto_position.data.state.debt.mint; - if !solauto_position.data.self_managed.val - && protocol_user_account.key != &solauto_position.data.position.protocol_user_account + if + !solauto_position.data.self_managed.val && + protocol_user_account.key != &solauto_position.data.position.protocol_user_account { msg!("Incorrect protocol-owned account"); return Err(SolautoError::IncorrectAccounts.into()); @@ -350,20 +350,10 @@ pub fn validate_lending_program_accounts_with_position<'a>( pub fn validate_token_accounts<'a, 'b>( solauto_position: &'b DeserializedAccount<'a, SolautoPosition>, source_supply_ta: Option<&'a AccountInfo<'a>>, - source_debt_ta: Option<&'a AccountInfo<'a>>, + source_debt_ta: Option<&'a AccountInfo<'a>> ) -> ProgramResult { - validate_token_account( - solauto_position, - source_supply_ta, - Some(TokenType::Supply), - None, - )?; - validate_token_account( - solauto_position, - source_debt_ta, - Some(TokenType::Debt), - None, - )?; + validate_token_account(solauto_position, source_supply_ta, Some(TokenType::Supply), None)?; + validate_token_account(solauto_position, source_debt_ta, Some(TokenType::Debt), None)?; Ok(()) } @@ -371,7 +361,7 @@ pub fn validate_token_account<'a>( solauto_position: &DeserializedAccount<'a, SolautoPosition>, source_ta: Option<&'a AccountInfo<'a>>, token_type: Option, - token_mint: Option<&Pubkey>, + token_mint: Option<&Pubkey> ) -> ProgramResult { if solauto_position.data.self_managed.val && token_mint.is_none() { return Ok(()); @@ -388,14 +378,19 @@ pub fn validate_token_account<'a>( mint_key }; - let associated_position_ta = - get_associated_token_address(&solauto_position.account_info.key, mint_key); - let associated_authority_ta = - get_associated_token_address(&solauto_position.data.authority, mint_key); + let associated_position_ta = get_associated_token_address( + &solauto_position.account_info.key, + mint_key + ); + let associated_authority_ta = get_associated_token_address( + &solauto_position.data.authority, + mint_key + ); - if source_ta.is_some() - && source_ta.unwrap().key != &associated_position_ta - && source_ta.unwrap().key != &associated_authority_ta + if + source_ta.is_some() && + source_ta.unwrap().key != &associated_position_ta && + source_ta.unwrap().key != &associated_authority_ta { msg!("Incorrect token account {}", source_ta.unwrap().key); return Err(SolautoError::IncorrectAccounts.into()); @@ -407,7 +402,7 @@ pub fn validate_token_account<'a>( pub fn token_account_owned_by<'a>( token_account: &'a AccountInfo<'a>, expected_owner: &Pubkey, - token_mint: Option<&Pubkey>, + token_mint: Option<&Pubkey> ) -> Result { if token_mint.is_some() { return Ok( @@ -415,19 +410,21 @@ pub fn token_account_owned_by<'a>( ); } else { let token_account_data = safe_unpack_token_account(Some(token_account))?.unwrap(); - return Ok(token_account_data.account_info.owner == &token_program_id - && &token_account_data.data.owner == expected_owner); + return Ok( + token_account_data.account_info.owner == &token_program_id && + &token_account_data.data.owner == expected_owner + ); } } pub fn validate_referral_signer( referral_state: &DeserializedAccount, signer: &AccountInfo, - allow_solauto_manager: bool, + allow_solauto_manager: bool ) -> ProgramResult { let referral_state_pda = Pubkey::create_program_address( referral_state.data.seeds_with_bump().as_slice(), - &crate::ID, + &crate::ID )?; if &referral_state_pda != referral_state.account_info.key { msg!("Incorrect referral state account provided"); @@ -438,8 +435,9 @@ pub fn validate_referral_signer( msg!("Missing required referral signer"); return Err(ProgramError::MissingRequiredSignature.into()); } - if signer.key != &referral_state.data.authority - && (!allow_solauto_manager || signer.key != &SOLAUTO_MANAGER) + if + signer.key != &referral_state.data.authority && + (!allow_solauto_manager || signer.key != &SOLAUTO_MANAGER) { msg!("Instruction has not been signed by the right account"); return Err(SolautoError::IncorrectAccounts.into()); @@ -450,20 +448,18 @@ pub fn validate_referral_signer( pub fn validate_no_active_balances<'a>( protocol_account: &'a AccountInfo<'a>, - lending_platform: LendingPlatform, + lending_platform: LendingPlatform ) -> ProgramResult { if lending_platform == LendingPlatform::Marginfi { - let marginfi_account = - DeserializedAccount::::zerocopy(Some(protocol_account))?.unwrap(); - if marginfi_account - .data - .lending_account - .balances - .iter() - .filter(|balance| balance.active == 1) - .collect::>() - .len() - > 0 + let marginfi_account = DeserializedAccount:: + ::zerocopy(Some(protocol_account))? + .unwrap(); + if + marginfi_account.data.lending_account.balances + .iter() + .filter(|balance| balance.active == 1) + .collect::>() + .len() > 0 { msg!( "Marginfi account has active balances. Ensure all debt is repaid and supply tokens are withdrawn before closing position" @@ -482,22 +478,24 @@ pub fn validate_debt_adjustment( solauto_position: &SolautoPosition, provided_base_unit_amount: u64, expected_debt_adjustment_usd: f64, + rebalance_type: Option<&SolautoRebalanceType> ) -> ProgramResult { - let token = if expected_debt_adjustment_usd > 0.0 { + let token = if + expected_debt_adjustment_usd > 0.0 || + (rebalance_type.is_some() && + rebalance_type.unwrap() == &SolautoRebalanceType::FLRebalanceThenSwap) + { solauto_position.state.debt } else { solauto_position.state.supply }; - let amount_usd = from_base_unit::(provided_base_unit_amount, token.decimals) - .mul(token.market_price()); + let amount_usd = from_base_unit::(provided_base_unit_amount, token.decimals).mul( + token.market_price() + ); // Checking if within specified range due to varying price volatility - if (amount_usd - expected_debt_adjustment_usd.abs()) - .abs() - .div(amount_usd) - > 0.75 - { + if (amount_usd - expected_debt_adjustment_usd.abs()).abs().div(amount_usd) > 0.75 { msg!("Base unit amount provided: {}", provided_base_unit_amount); msg!( "Provided debt adjustment was not what was expected (Provided: ${} vs. expected: ${})", @@ -514,7 +512,10 @@ pub fn validate_debt_adjustment( mod tests { use crate::{ state::solauto_position::{ - AutomationSettings, AutomationSettingsInp, PositionState, SolautoSettingsParameters, + AutomationSettings, + AutomationSettingsInp, + PositionState, + SolautoSettingsParameters, SolautoSettingsParametersInp, }, types::shared::PositionType, @@ -536,7 +537,7 @@ mod tests { Pubkey::default(), PositionType::default(), position_data, - position_state, + position_state ); let result = validate_position_settings(&solauto_position, 0); assert!(result.is_err()); @@ -556,14 +557,14 @@ mod tests { boost_gap: MIN_BOOST_GAP_BPS - 10, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { repay_gap: MIN_REPAY_GAP_BPS - 10, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -571,7 +572,7 @@ mod tests { repay_gap: 600, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -579,7 +580,7 @@ mod tests { boost_gap: 1000, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -587,7 +588,7 @@ mod tests { repay_to_bps: 4000, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -595,21 +596,21 @@ mod tests { repay_gap: 500, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { repay_to_bps: 9900, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { target_boost_to_bps: Some(10340), ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); } @@ -631,25 +632,25 @@ mod tests { test_automation_settings( current_timestamp, AutomationSettings::from(AutomationSettingsInp { - unix_start_date: current_timestamp - + default_automation_settings_args.interval_seconds - + 100, + unix_start_date: current_timestamp + + default_automation_settings_args.interval_seconds + + 100, ..default_automation_settings_args - }), + }) ); test_automation_settings( current_timestamp, AutomationSettings::from(AutomationSettingsInp { interval_seconds: 60, ..default_automation_settings_args.clone() - }), + }) ); test_automation_settings( current_timestamp, AutomationSettings::from(AutomationSettingsInp { interval_seconds: 60 * 60 * 24 * 60, ..default_automation_settings_args.clone() - }), + }) ); } } diff --git a/solauto-sdk/local/logPositions.ts b/solauto-sdk/local/logPositions.ts new file mode 100644 index 00000000..73fe6740 --- /dev/null +++ b/solauto-sdk/local/logPositions.ts @@ -0,0 +1,232 @@ +import { publicKey } from "@metaplex-foundation/umi"; +import { + buildHeliusApiUrl, + fetchTokenPrices, + fromBaseUnit, + getSolanaRpcConnection, + getSolautoManagedPositions, + PositionState, + positionStateWithLatestPrices, + retryWithExponentialBackoff, + safeFetchAllSolautoPosition, + safeGetPrice, + SOLAUTO_PROD_PROGRAM, + TOKEN_INFO, + USD_DECIMALS, +} from "../src"; +import { PublicKey } from "@solana/web3.js"; +import { NATIVE_MINT } from "@solana/spl-token"; +import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; +import path from "path"; +import { config } from "dotenv"; +import { safeFetchMarginfiAccount } from "../src/marginfi-sdk"; + +config({ path: path.join(__dirname, ".env") }); + +function getBatches(items: T[], batchSize: number): T[][] { + const batches: T[][] = []; + for (let i = 0; i < items.length; i += batchSize) { + batches.push(items.slice(i, i + batchSize)); + } + return batches; +} + +export function tokenInfo(mint?: PublicKey) { + return TOKEN_INFO[mint ? mint.toString() : PublicKey.default.toString()]; +} + +type StrategyType = "Long" | "Short"; + +function solautoStrategyName(supplyMint?: PublicKey, debtMint?: PublicKey) { + const supplyInfo = tokenInfo(supplyMint); + const debtInfo = tokenInfo(debtMint); + const strat = strategyType( + supplyMint ?? PublicKey.default, + debtMint ?? PublicKey.default + ); + + if (strat === "Long") { + return debtInfo.isStableCoin + ? `${supplyInfo.ticker} Long` + : supplyInfo.ticker + ? `${supplyInfo.ticker}/${debtInfo.ticker} Long` + : ""; + } else { + return `${debtInfo.ticker} Short`; + } +} + +function strategyType( + supplyMint: PublicKey, + debtMint: PublicKey +): StrategyType { + const supplyInfo = tokenInfo(supplyMint); + const debtInfo = tokenInfo(debtMint); + + if (supplyInfo.isLST && debtMint.equals(NATIVE_MINT)) { + // Yield + throw new Error("Not yet supported"); + } else if (debtInfo.isStableCoin) { + return "Long"; + } else if (supplyInfo.isStableCoin) { + return "Short"; + } else { + return "Long"; + } +} + +export function roundToDecimals(value: number, decimals: number = 2): number { + if (!value || isNaN(value)) { + return value; + } + + let roundedValue: number | undefined; + do { + const factor = Math.pow(10, decimals ?? 2); + roundedValue = Math.round(value * factor) / factor; + decimals += 1; + } while (!roundedValue || decimals >= 10); + + return roundedValue; +} + +export function formatNumberToShortForm( + num: number, + decimals?: number +): string { + if (decimals === undefined) { + decimals = 1; + } + if (num >= 1_000_000_000) { + return ( + (num / 1_000_000_000) + .toFixed(decimals) + .replace(new RegExp(`\\.0{${decimals}}$`), "") + "B" + ); + } + if (num >= 1_000_000) { + return ( + (num / 1_000_000) + .toFixed(decimals) + .replace(new RegExp(`\\.0{${decimals}}$`), "") + "M" + ); + } + if (num >= 1_000) { + return ( + (num / 1_000) + .toFixed(decimals) + .replace(new RegExp(`\\.0{${decimals}}$`), "") + "K" + ); + } + return num.toFixed(decimals).replace(new RegExp(`\\.0{${decimals}}$`), ""); +} + +export function formatNumber( + num: number, + decimals?: number, + shortFormAtThreshold?: number, + decimalsAtShortform?: number +): string { + if (shortFormAtThreshold !== undefined && num > shortFormAtThreshold) { + return formatNumberToShortForm(num, decimalsAtShortform); + } else { + return num < 1 + ? roundToDecimals(num, decimals).toString() + : new Intl.NumberFormat("en-US").format( + decimals !== undefined ? roundToDecimals(num, decimals) : num + ); + } +} + +async function main(filterWhitelist: boolean) { + const [_, umi] = getSolanaRpcConnection( + buildHeliusApiUrl(process.env.HELIUS_API_KEY!), + SOLAUTO_PROD_PROGRAM + ); + + let positions = await getSolautoManagedPositions(umi); + + if (filterWhitelist) { + const addressWhitelist = process.env.ADDRESS_WHITELIST?.split(",") ?? []; + positions = positions.filter( + (x) => !addressWhitelist.includes(x.authority.toString()) + ); + } + + const batches = getBatches(positions, 30); + + const solautoPositionsData = ( + await Promise.all( + batches.map(async (pubkeys) => { + return retryWithExponentialBackoff( + async () => + await safeFetchAllSolautoPosition( + umi, + pubkeys.map((x) => publicKey(x.publicKey!)) + ) + ); + }) + ) + ).flat(); + + const tokensUsed = Array.from( + new Set( + positions.flatMap((x) => [ + x.supplyMint!.toString(), + x.debtMint!.toString(), + ]) + ) + ); + + const tokenBatches = getBatches(tokensUsed, 15); + await Promise.all( + tokenBatches.map(async (batch) => { + await fetchTokenPrices(batch.map((x) => new PublicKey(x))); + }) + ); + + console.log("\n\n"); + + const latestStates: PositionState[] = []; + let unhealthyPositions = 0; + for (const pos of solautoPositionsData) { + const latestState = await positionStateWithLatestPrices( + pos.state, + safeGetPrice(pos.state.supply.mint), + safeGetPrice(pos.state.debt.mint) + ); + latestStates.push(latestState); + + const strategy = solautoStrategyName( + toWeb3JsPublicKey(pos.state.supply.mint), + toWeb3JsPublicKey(pos.state.debt.mint) + ); + + const repayFrom = pos.position.settingParams.repayToBps + pos.position.settingParams.repayGap; + const unhealthy = pos.state.liqUtilizationRateBps > repayFrom; + const healthText = unhealthy ? `(Unhealthy: ${pos.state.liqUtilizationRateBps - repayFrom}` : ""; + if (unhealthy) { + unhealthyPositions += 1; + } + + console.log(pos.publicKey.toString(), `(${pos.authority.toString()})`); + console.log( + `${strategy}: $${formatNumber(fromBaseUnit(latestState.netWorth.baseAmountUsdValue, USD_DECIMALS), 2, 10000, 2)} ${healthText}` + ); + } + + console.log("\nTotal positions:", solautoPositionsData.length, unhealthyPositions ? ` (unhealthy: ${unhealthyPositions})` : ""); + console.log( + "Total users:", + Array.from(new Set(solautoPositionsData.map((x) => x.authority.toString()))) + .length + ); + + const tvl = latestStates + .map((x) => fromBaseUnit(x.netWorth.baseAmountUsdValue, USD_DECIMALS)) + .reduce((acc, curr) => acc + curr, 0); + console.log(`Total TVL: $${formatNumber(tvl, 2, 10000, 2)}`); +} + +const filterWhitelist = true; +main(filterWhitelist).then((x) => x); \ No newline at end of file diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 7641e4a4..cee4676f 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.340", + "version": "1.0.447", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", @@ -10,11 +10,7 @@ "build": "rm -rf dist && npx tsc", "test:txs": "ts-mocha -p ./tsconfig.json -t 1000000 tests/transactions/**/*.ts", "test:unit": "ts-mocha -p ./tsconfig.json -t 1000000 tests/unit/**/*.ts", - "test:all": "pnpm test:unit && pnpm test:txs", - "update-lut:solauto": "npx ts-node local/updateSolautoLUT.ts", - "update-lut:marginfi": "npx ts-node local/updateMarginfiLUT.ts", - "create-ism-accounts": "npx ts-node local/createISMAccounts.ts", - "create-token-accounts": "npx ts-node local/createTokenAccounts.ts" + "test:all": "pnpm test:unit && pnpm test:txs" }, "dependencies": { "@coral-xyz/anchor": "^0.30.1", @@ -23,12 +19,15 @@ "@metaplex-foundation/umi-bundle-defaults": "^0.9.1", "@metaplex-foundation/umi-signer-wallet-adapters": "^0.9.1", "@metaplex-foundation/umi-web3js-adapters": "^0.9.1", + "@mrgnlabs/marginfi-client-v2": "^4.0.0", + "@mrgnlabs/mrgn-common": "^1.8.0", "@solana/spl-token": "^0.4.0", - "@solana/web3.js": "^1.95.4", - "@switchboard-xyz/on-demand": "^1.2.51", + "@solana/web3.js": "=1.95.8", + "@switchboard-xyz/on-demand": "=1.2.51", "axios": "^1.7.8", "bs58": "^5.0.0", "cross-fetch": "^4.0.0", + "dotenv": "^16.4.7", "rpc-websockets": "7.11.0" }, "devDependencies": { diff --git a/solauto-sdk/pnpm-lock.yaml b/solauto-sdk/pnpm-lock.yaml index 3b97bbef..396a9536 100644 --- a/solauto-sdk/pnpm-lock.yaml +++ b/solauto-sdk/pnpm-lock.yaml @@ -16,21 +16,27 @@ dependencies: version: 0.9.2 '@metaplex-foundation/umi-bundle-defaults': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-signer-wallet-adapters': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-web3js-adapters': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@mrgnlabs/marginfi-client-v2': + specifier: ^4.0.0 + version: 4.0.0(fastestsmallesttextencoderdecoder@1.0.22) + '@mrgnlabs/mrgn-common': + specifier: ^1.8.0 + version: 1.8.0 '@solana/spl-token': specifier: ^0.4.0 - version: 0.4.8(@solana/web3.js@1.95.5)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + version: 0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/web3.js': - specifier: ^1.95.4 - version: 1.95.5 + specifier: '=1.95.8' + version: 1.95.8 '@switchboard-xyz/on-demand': - specifier: ^1.2.51 + specifier: '=1.2.51' version: 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) axios: specifier: ^1.7.8 @@ -41,6 +47,9 @@ dependencies: cross-fetch: specifier: ^4.0.0 version: 4.0.0 + dotenv: + specifier: ^16.4.7 + version: 16.4.7 rpc-websockets: specifier: 7.11.0 version: 7.11.0 @@ -88,14 +97,38 @@ packages: engines: {node: '>=10'} dev: false + /@coral-xyz/anchor@0.29.0: + resolution: {integrity: sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==} + engines: {node: '>=11'} + dependencies: + '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.95.8) + '@noble/hashes': 1.5.0 + '@solana/web3.js': 1.95.8 + bn.js: 5.2.1 + bs58: 4.0.1 + buffer-layout: 1.2.2 + camelcase: 6.3.0 + cross-fetch: 3.1.8 + crypto-hash: 1.3.0 + eventemitter3: 4.0.7 + pako: 2.1.0 + snake-case: 3.0.4 + superstruct: 0.15.5 + toml: 3.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + /@coral-xyz/anchor@0.30.1: resolution: {integrity: sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==} engines: {node: '>=11'} dependencies: '@coral-xyz/anchor-errors': 0.30.1 - '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.5) + '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.8) '@noble/hashes': 1.5.0 - '@solana/web3.js': 1.95.5 + '@solana/web3.js': 1.95.8 bn.js: 5.2.1 bs58: 4.0.1 buffer-layout: 1.2.2 @@ -113,22 +146,56 @@ packages: - utf-8-validate dev: false - /@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.5): + /@coral-xyz/borsh@0.29.0(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + dependencies: + '@solana/web3.js': 1.95.8 + bn.js: 5.2.1 + buffer-layout: 1.2.2 + dev: false + + /@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.8): resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} engines: {node: '>=10'} peerDependencies: '@solana/web3.js': ^1.68.0 dependencies: - '@solana/web3.js': 1.95.5 + '@solana/web3.js': 1.95.8 bn.js: 5.2.1 buffer-layout: 1.2.2 dev: false + /@grpc/grpc-js@1.12.4: + resolution: {integrity: sha512-NBhrxEWnFh0FxeA0d//YP95lRFsSx2TNLEUQg4/W+5f/BMxcCjgOOIT24iD+ZB/tZw057j44DaIxja7w4XMrhg==} + engines: {node: '>=12.10.0'} + dependencies: + '@grpc/proto-loader': 0.7.13 + '@js-sdsl/ordered-map': 4.4.2 + dev: false + + /@grpc/proto-loader@0.7.13: + resolution: {integrity: sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==} + engines: {node: '>=6'} + hasBin: true + dependencies: + lodash.camelcase: 4.3.0 + long: 5.2.3 + protobufjs: 7.4.0 + yargs: 17.7.2 + dev: false + + /@js-sdsl/ordered-map@4.4.2: + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + dev: false + /@jup-ag/api@6.0.29: resolution: {integrity: sha512-1gUY1txmL/gG14VDZMjeKVqhSzeg4L2cImdC7dGLYB5DP5D5lwpR+FarvhqehEi+63/RWOUKTTU4fablGpeIUQ==} dev: false - /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5): + /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-kV3tfvgvRjVP1p9OFOtH+ibOtN9omVJSwKr0We4/9r45e5LTj+32su0V/rixZUkG1EZzzOYBsxhtIE0kIw/Hrw==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 @@ -136,14 +203,14 @@ packages: dependencies: '@metaplex-foundation/umi': 0.9.2 '@metaplex-foundation/umi-downloader-http': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5) + '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-http-fetch': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-program-repository': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-rpc-chunk-get-accounts': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5) + '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-serializer-data-view': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5) - '@solana/web3.js': 1.95.5 + '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 transitivePeerDependencies: - encoding dev: false @@ -156,16 +223,16 @@ packages: '@metaplex-foundation/umi': 0.9.2 dev: false - /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5): + /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-hhPCxXbYIp4BC4z9gK78sXpWLkNSrfv4ndhF5ruAkdIp7GcRVYKj0QnOUO6lGYGiIkNlw20yoTwOe1CT//OfTQ==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@noble/curves': 1.6.0 - '@solana/web3.js': 1.95.5 + '@solana/web3.js': 1.95.8 dev: false /@metaplex-foundation/umi-http-fetch@0.9.2(@metaplex-foundation/umi@0.9.2): @@ -205,15 +272,15 @@ packages: '@metaplex-foundation/umi': 0.9.2 dev: false - /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5): + /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-MqcsBz8B4wGl6jxsf2Jo/rAEpYReU9VCSR15QSjhvADHMmdFxCIZCCAgE+gDE2Vuanfl437VhOcP3g5Uw8C16Q==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5) - '@solana/web3.js': 1.95.5 + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 dev: false /@metaplex-foundation/umi-serializer-data-view@0.9.2(@metaplex-foundation/umi@0.9.2): @@ -250,36 +317,36 @@ packages: '@metaplex-foundation/umi-serializers-numbers': 0.8.9 dev: false - /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5): + /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-DFG0ZFocKG8briypSkG9bGUTVsWpAgYugsl2BzTygkGExc4evWfF4Sb1F2C2w9FdrA9ESZM1gpLX9xtx5taOXg==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5) - '@solana/web3.js': 1.95.5 + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 dev: false - /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5): + /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-fR1Kf21uylMFd1Smkltmj4jTNxhqSWf416owsJ+T+cvJi2VCOcOwq/3UFzOrpz78fA0RhsajKYKj0HYsRnQI1g==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5) - '@solana/web3.js': 1.95.5 + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 dev: false - /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.5): + /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@solana/web3.js': 1.95.5 + '@solana/web3.js': 1.95.8 buffer: 6.0.3 dev: false @@ -291,6 +358,46 @@ packages: '@metaplex-foundation/umi-serializers': 0.9.0 dev: false + /@mrgnlabs/marginfi-client-v2@4.0.0(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-GnXdGdPgU54w517iDXfKoti1i8jrVyOwhxPKS2Lpqac3QH4NL3b4sSbz+pCBDmjk60gveHzu3IAIGscUpbo1yQ==} + dependencies: + '@coral-xyz/anchor': 0.30.1 + '@mrgnlabs/mrgn-common': 1.8.0 + '@pythnetwork/pyth-solana-receiver': 0.8.2 + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 + '@switchboard-xyz/on-demand': 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) + bignumber.js: 9.1.2 + borsh: 2.0.0 + bs58: 6.0.0 + decimal.js: 10.4.3 + superstruct: 1.0.4 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - utf-8-validate + dev: false + + /@mrgnlabs/mrgn-common@1.8.0: + resolution: {integrity: sha512-6VQ/2Ob8alyI1jsY3RETsWJ5W/myEp+h2yu1mFI/yzKHLffQMlt50FWPSDmCe2TBmkBioW48HOl+PqQf3+Wfbg==} + dependencies: + '@coral-xyz/anchor': 0.30.1 + '@solana/buffer-layout-utils': 0.2.0 + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 + bignumber.js: 9.1.2 + bs58: 6.0.0 + decimal.js: 10.4.3 + numeral: 2.0.6 + superstruct: 1.0.4 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + /@noble/curves@1.6.0: resolution: {integrity: sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==} engines: {node: ^14.21.3 || >=16} @@ -298,6 +405,10 @@ packages: '@noble/hashes': 1.5.0 dev: false + /@noble/ed25519@1.7.3: + resolution: {integrity: sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==} + dev: false + /@noble/hashes@1.5.0: resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} engines: {node: ^14.21.3 || >=16} @@ -346,12 +457,45 @@ packages: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} dev: false + /@pythnetwork/price-service-sdk@1.7.1: + resolution: {integrity: sha512-xr2boVXTyv1KUt/c6llUTfbv2jpud99pWlMJbFaHGUBoygQsByuy7WbjIJKZ+0Blg1itLZl0Lp/pJGGg8SdJoQ==} + dependencies: + bn.js: 5.2.1 + dev: false + + /@pythnetwork/pyth-solana-receiver@0.8.2: + resolution: {integrity: sha512-WrrdwwhSYvvB5vJEL+SfPnfuxgkRKMeKdZvGFFwe6ENrMhrQCM05oDkvNNYfXATLcpQGRAyBu9l1xIxUxixpqw==} + dependencies: + '@coral-xyz/anchor': 0.29.0 + '@noble/hashes': 1.5.0 + '@pythnetwork/price-service-sdk': 1.7.1 + '@pythnetwork/solana-utils': 0.4.2 + '@solana/web3.js': 1.95.8 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@pythnetwork/solana-utils@0.4.2: + resolution: {integrity: sha512-hKo7Bcs/kDWA5Fnqhg9zJSB94NMoUDIDjHjSi/uvZOzwizISUQI6oY3LWd2CXzNh4f8djjY2BS5iNHaM4cm8Bw==} + dependencies: + '@coral-xyz/anchor': 0.29.0 + '@solana/web3.js': 1.95.8 + bs58: 5.0.0 + jito-ts: 3.0.1 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + /@solana/buffer-layout-utils@0.2.0: resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} engines: {node: '>= 10'} dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.95.5 + '@solana/web3.js': 1.95.8 bigint-buffer: 1.1.5 bignumber.js: 9.1.2 transitivePeerDependencies: @@ -619,7 +763,7 @@ packages: - fastestsmallesttextencoderdecoder dev: false - /@solana/spl-token-group@0.0.5(@solana/web3.js@1.95.5)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token-group@0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-CLJnWEcdoUBpQJfx9WEbX3h6nTdNiUzswfFdkABUik7HVwSNA98u5AYvBVK2H93d9PGMOHAak2lHW9xr+zAJGQ==} engines: {node: '>=16'} peerDependencies: @@ -627,13 +771,13 @@ packages: dependencies: '@solana/codecs': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.5 + '@solana/web3.js': 1.95.8 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript dev: false - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.5)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} engines: {node: '>=16'} peerDependencies: @@ -641,13 +785,13 @@ packages: dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.5 + '@solana/web3.js': 1.95.8 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript dev: false - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.5)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} engines: {node: '>=16'} peerDependencies: @@ -655,13 +799,13 @@ packages: dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.5 + '@solana/web3.js': 1.95.8 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript dev: false - /@solana/spl-token@0.3.11(@solana/web3.js@1.95.5)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + /@solana/spl-token@0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} engines: {node: '>=16'} peerDependencies: @@ -669,8 +813,8 @@ packages: dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.5)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.5 + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8 buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -680,7 +824,7 @@ packages: - utf-8-validate dev: false - /@solana/spl-token@0.4.8(@solana/web3.js@1.95.5)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token@0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-RO0JD9vPRi4LsAbMUdNbDJ5/cv2z11MGhtAvFeRzT4+hAGE/FUzRi0tkkWtuCfSIU3twC6CtmAihRp/+XXjWsA==} engines: {node: '>=16'} peerDependencies: @@ -688,9 +832,9 @@ packages: dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.95.5)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.5)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/web3.js': 1.95.5 + '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/web3.js': 1.95.8 buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -707,8 +851,53 @@ packages: buffer: 6.0.3 dev: false - /@solana/web3.js@1.95.5: - resolution: {integrity: sha512-hU9cBrbg1z6gEjLH9vwIckGBVB78Ijm0iZFNk4ocm5OD82piPwuk3MeQ1rfiKD9YQtr95krrcaopb49EmQJlRg==} + /@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-apqMuYwFp1jFi55NxDfvXUX2x1T0Zh07MxhZ/nCCTGys5raSfYUh82zen2BLv8BSDj/JxZ2P/s7jrQZGrX8uAw==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-standard-features': 1.2.0 + '@solana/web3.js': 1.95.8 + '@wallet-standard/base': 1.1.0 + '@wallet-standard/features': 1.1.0 + eventemitter3: 4.0.7 + dev: false + + /@solana/wallet-standard-features@1.2.0: + resolution: {integrity: sha512-tUd9srDLkRpe1BYg7we+c4UhRQkq+XQWswsr/L1xfGmoRDF47BPSXf4zE7ZU2GRBGvxtGt7lwJVAufQyQYhxTQ==} + engines: {node: '>=16'} + dependencies: + '@wallet-standard/base': 1.1.0 + '@wallet-standard/features': 1.1.0 + dev: false + + /@solana/web3.js@1.77.4: + resolution: {integrity: sha512-XdN0Lh4jdY7J8FYMyucxCwzn6Ga2Sr1DHDWRbqVzk7ZPmmpSPOVWHzO67X1cVT+jNi1D6gZi2tgjHgDPuj6e9Q==} + dependencies: + '@babel/runtime': 7.25.7 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.2 + node-fetch: 2.7.0 + rpc-websockets: 7.11.0 + superstruct: 0.14.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@solana/web3.js@1.95.8: + resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} dependencies: '@babel/runtime': 7.25.7 '@noble/curves': 1.6.0 @@ -735,8 +924,8 @@ packages: resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.5)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.5 + '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8 '@types/bn.js': 5.1.6 '@types/node': 18.19.65 '@types/node-fetch': 2.6.12 @@ -764,7 +953,7 @@ packages: resolution: {integrity: sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w==} engines: {node: '>=12'} dependencies: - '@solana/web3.js': 1.95.5 + '@solana/web3.js': 1.95.8 axios: 1.7.8 big.js: 6.2.2 bn.js: 5.2.1 @@ -788,7 +977,7 @@ packages: dependencies: '@brokerloop/ttlcache': 3.2.3 '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 - '@solana/web3.js': 1.95.5 + '@solana/web3.js': 1.95.8 '@solworks/soltoolkit-sdk': 0.0.23(fastestsmallesttextencoderdecoder@1.0.22) '@switchboard-xyz/common': 2.5.5 axios: 1.7.8 @@ -872,6 +1061,18 @@ packages: resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} dev: true + /@wallet-standard/base@1.1.0: + resolution: {integrity: sha512-DJDQhjKmSNVLKWItoKThJS+CsJQjR9AOBOirBVT1F9YpRyC9oYHE+ZnSf8y8bxUphtKqdQMPVQ2mHohYdRvDVQ==} + engines: {node: '>=16'} + dev: false + + /@wallet-standard/features@1.1.0: + resolution: {integrity: sha512-hiEivWNztx73s+7iLxsuD1sOJ28xtRix58W7Xnz4XzzA/pF0+aicnWgjOdA10doVDEDZdUuZCIIqG96SFNlDUg==} + engines: {node: '>=16'} + dependencies: + '@wallet-standard/base': 1.1.0 + dev: false + /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -895,14 +1096,12 @@ packages: /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - dev: true /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} dependencies: color-convert: 2.0.1 - dev: true /anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} @@ -952,6 +1151,10 @@ packages: resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} dev: false + /base-x@5.0.0: + resolution: {integrity: sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==} + dev: false + /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} dev: false @@ -995,6 +1198,10 @@ packages: text-encoding-utf-8: 1.0.2 dev: false + /borsh@2.0.0: + resolution: {integrity: sha512-kc9+BgR3zz9+cjbwM8ODoUB4fs3X3I5A/HtX7LZKxCLaMrEeDFoBpnhZY//DTS1VZBSs6S5v46RZRbZjRFspEg==} + dev: false + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -1025,6 +1232,12 @@ packages: base-x: 4.0.0 dev: false + /bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + dependencies: + base-x: 5.0.0 + dev: false + /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true @@ -1108,16 +1321,23 @@ packages: wrap-ansi: 7.0.0 dev: true + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: false + /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 - dev: true /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true /combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} @@ -1220,9 +1440,13 @@ packages: tslib: 2.7.0 dev: false + /dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + engines: {node: '>=12'} + dev: false + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true /es6-promise@4.2.8: resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} @@ -1237,7 +1461,6 @@ packages: /escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} - dev: true /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} @@ -1323,7 +1546,6 @@ packages: /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - dev: true /get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} @@ -1400,7 +1622,6 @@ packages: /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - dev: true /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} @@ -1458,6 +1679,23 @@ packages: - utf-8-validate dev: false + /jito-ts@3.0.1: + resolution: {integrity: sha512-TSofF7KqcwyaWGjPaSYC8RDoNBY1TPRNBHdrw24bdIi7mQ5bFEDdYK3D//llw/ml8YDvcZlgd644WxhjLTS9yg==} + dependencies: + '@grpc/grpc-js': 1.12.4 + '@noble/ed25519': 1.7.3 + '@solana/web3.js': 1.77.4 + agentkeepalive: 4.5.0 + dotenv: 16.4.7 + jayson: 4.1.2 + node-fetch: 2.7.0 + superstruct: 1.0.4 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + /js-sha256@0.11.0: resolution: {integrity: sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==} dev: false @@ -1493,6 +1731,10 @@ packages: p-locate: 5.0.0 dev: true + /lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + dev: false + /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} dev: false @@ -1635,6 +1877,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /numeral@2.0.6: + resolution: {integrity: sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==} + dev: false + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -1721,7 +1967,6 @@ packages: /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - dev: true /rpc-websockets@7.11.0: resolution: {integrity: sha512-IkLYjayPv6Io8C/TdCL5gwgzd1hFz2vmBZrjMw/SPEXo51ETOhnzgS4Qy5GWi2JQN7HKHa66J3+2mv0fgNh/7w==} @@ -1785,14 +2030,12 @@ packages: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - dev: true /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 - dev: true /strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} @@ -1806,10 +2049,19 @@ packages: engines: {node: '>=8'} dev: true + /superstruct@0.14.2: + resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} + dev: false + /superstruct@0.15.5: resolution: {integrity: sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==} dev: false + /superstruct@1.0.4: + resolution: {integrity: sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==} + engines: {node: '>=14.0.0'} + dev: false + /superstruct@2.0.2: resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} engines: {node: '>=14.0.0'} @@ -1961,7 +2213,6 @@ packages: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - dev: true /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -1999,7 +2250,6 @@ packages: /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - dev: true /yaml@2.6.1: resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==} @@ -2012,6 +2262,11 @@ packages: engines: {node: '>=10'} dev: true + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: false + /yargs-unparser@2.0.0: resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} engines: {node: '>=10'} @@ -2035,6 +2290,19 @@ packages: yargs-parser: 20.2.4 dev: true + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: false + /yn@2.0.0: resolution: {integrity: sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==} engines: {node: '>=4'} diff --git a/solauto-sdk/src/clients/referralStateManager.ts b/solauto-sdk/src/clients/referralStateManager.ts index 9385ddb6..57bf6fd6 100644 --- a/solauto-sdk/src/clients/referralStateManager.ts +++ b/solauto-sdk/src/clients/referralStateManager.ts @@ -32,7 +32,6 @@ export interface ReferralStateManagerArgs { export class ReferralStateManager extends TxHandler { public umi!: Umi; - public signer!: Signer; public referralState!: PublicKey; public referralStateData!: ReferralState | null; @@ -47,27 +46,25 @@ export class ReferralStateManager extends TxHandler { } this.umi = this.umi.use( args.signer - ? signerIdentity(args.signer) + ? signerIdentity(args.signer, true) : walletAdapterIdentity(args.wallet!, true) ); this.signer = this.umi.identity; + this.authority = args.authority ?? toWeb3JsPublicKey(this.signer.publicKey); + + this.referralState = args.referralState ?? getReferralState(this.authority, this.programId); - this.referralState = args.referralState - ? args.referralState - : getReferralState( - args.authority ?? toWeb3JsPublicKey(this.signer.publicKey), - this.programId - ); this.referralStateData = await safeFetchReferralState( this.umi, publicKey(this.referralState), { commitment: "confirmed" } ); - this.authority = this.referralStateData - ? toWeb3JsPublicKey(this.referralStateData.authority) - : toWeb3JsPublicKey(this.signer.publicKey); this.setReferredBy(args.referredByAuthority); + + this.log("Authority:", this.authority.toString()); + this.log("Signer:", this.signer.publicKey.toString()); + this.log("Referral state:", this.referralState.toString()); } defaultLookupTables(): string[] { diff --git a/solauto-sdk/src/clients/solautoClient.ts b/solauto-sdk/src/clients/solautoClient.ts index 2eae7866..62b7d3f1 100644 --- a/solauto-sdk/src/clients/solautoClient.ts +++ b/solauto-sdk/src/clients/solautoClient.ts @@ -63,7 +63,6 @@ export abstract class SolautoClient extends ReferralStateManager { public lendingPlatform?: LendingPlatform; public authority!: PublicKey; - public signer!: Signer; public positionId!: number; public selfManaged!: boolean; @@ -251,6 +250,10 @@ export abstract class SolautoClient extends ReferralStateManager { } | undefined > { + if (this.selfManaged) { + return undefined; + } + const existingLutAccounts = await this.fetchExistingAuthorityLutAccounts(); if ( this.lutAccountsToAdd().every((element) => diff --git a/solauto-sdk/src/clients/solautoMarginfiClient.ts b/solauto-sdk/src/clients/solautoMarginfiClient.ts index 45efdbec..7ac1217b 100644 --- a/solauto-sdk/src/clients/solautoMarginfiClient.ts +++ b/solauto-sdk/src/clients/solautoMarginfiClient.ts @@ -33,9 +33,9 @@ import { marginfiRebalance, marginfiRefreshData, } from "../generated"; -import { getMarginfiAccountPDA, getTokenAccount } from "../utils/accountUtils"; -import { generateRandomU64 } from "../utils/generalUtils"; +import { getTokenAccount } from "../utils/accountUtils"; import { + Bank, MARGINFI_PROGRAM_ID, MarginfiAccount, lendingAccountBorrow, @@ -56,11 +56,12 @@ import { findMarginfiAccounts, getAllMarginfiAccountsByAuthority, getMarginfiAccountPositionState, - getMaxLtvAndLiqThreshold, + getMarginfiMaxLtvAndLiqThreshold, + marginfiAccountEmpty, } from "../utils/marginfiUtils"; -import { bytesToI80F48, fromBaseUnit, toBps } from "../utils/numberUtils"; +import { fromBaseUnit, toBps } from "../utils/numberUtils"; import { QuoteResponse } from "@jup-ag/api"; -import { safeGetPrice } from "../utils"; +import { consoleLog, safeGetPrice } from "../utils"; export interface SolautoMarginfiClientArgs extends SolautoClientArgs { marginfiAccount?: PublicKey | Signer; @@ -69,7 +70,7 @@ export interface SolautoMarginfiClientArgs extends SolautoClientArgs { } export class SolautoMarginfiClient extends SolautoClient { - private initialized: boolean = false; + private initializedFor?: PublicKey; public marginfiProgram!: PublicKey; @@ -99,22 +100,44 @@ export class SolautoMarginfiClient extends SolautoClient { args.marginfiAccount ?? createSignerFromKeypair(this.umi, this.umi.eddsa.generateKeypair()); } else { - this.marginfiAccountSeedIdx = generateRandomU64(); - this.marginfiAccount = this.solautoPositionData - ? toWeb3JsPublicKey( - this.solautoPositionData.position.protocolUserAccount - ) - : getMarginfiAccountPDA( - this.solautoPosition, - this.marginfiAccountSeedIdx, - this.programId - ); + if (this.solautoPositionData) { + this.marginfiAccount = toWeb3JsPublicKey( + this.solautoPositionData.position.protocolUserAccount + ); + } else { + const accounts = await getAllMarginfiAccountsByAuthority( + this.umi, + this.solautoPosition, + args.marginfiGroup ?? new PublicKey(DEFAULT_MARGINFI_GROUP), + false + ); + const reusableAccounts = + accounts.length > 0 + ? ( + await safeFetchAllMarginfiAccount( + this.umi, + accounts.map((x) => publicKey(x.marginfiAccount)) + ) + ).filter((x) => marginfiAccountEmpty(x)) + : []; + this.marginfiAccount = + reusableAccounts.length > 0 + ? toWeb3JsPublicKey(reusableAccounts[0].publicKey) + : createSignerFromKeypair( + this.umi, + this.umi.eddsa.generateKeypair() + ); + } } this.marginfiAccountPk = "publicKey" in this.marginfiAccount ? toWeb3JsPublicKey(this.marginfiAccount.publicKey) : this.marginfiAccount; + if ("publicKey" in this.marginfiAccount) { + this.otherSigners.push(this.marginfiAccount); + } + const marginfiAccountData = !args.new ? await safeFetchMarginfiAccount( this.umi, @@ -149,10 +172,19 @@ export class SolautoMarginfiClient extends SolautoClient { ); this.debtPriceOracle = new PublicKey(this.marginfiDebtAccounts.priceOracle); - if (!this.initialized) { + if ( + !this.initializedFor || + !this.initializedFor.equals(toWeb3JsPublicKey(this.signer.publicKey)) + ) { await this.setIntermediaryMarginfiDetails(); + this.initializedFor = toWeb3JsPublicKey(this.signer.publicKey); } - this.initialized = true; + + consoleLog("Marginfi account:", this.marginfiAccountPk.toString()); + consoleLog( + "Intermediary MF account:", + this.intermediaryMarginfiAccountPk.toString() + ); } async setIntermediaryMarginfiDetails() { @@ -174,16 +206,7 @@ export class SolautoMarginfiClient extends SolautoClient { this.umi, existingMarginfiAccounts.map((x) => publicKey(x.marginfiAccount)) ) - ).filter( - (x) => - x.group.toString() === this.marginfiGroup.toString() && - x.lendingAccount.balances.find( - (y) => - y.bankPk.toString() !== PublicKey.default.toString() && - (Math.round(bytesToI80F48(y.assetShares.value)) != 0 || - Math.round(bytesToI80F48(y.liabilityShares.value)) != 0) - ) === undefined - ) + ).filter((x) => marginfiAccountEmpty(x)) : []; this.intermediaryMarginfiAccountSigner = @@ -198,6 +221,10 @@ export class SolautoMarginfiClient extends SolautoClient { compatibleMarginfiAccounts.length > 0 ? compatibleMarginfiAccounts[0] : undefined; + + if (this.intermediaryMarginfiAccountSigner) { + this.otherSigners.push(this.intermediaryMarginfiAccountSigner); + } } protocolAccount(): PublicKey { @@ -228,7 +255,7 @@ export class SolautoMarginfiClient extends SolautoClient { ) { return [0, 0]; } else { - const [maxLtv, liqThreshold] = await getMaxLtvAndLiqThreshold( + const [maxLtv, liqThreshold] = await getMarginfiMaxLtvAndLiqThreshold( this.umi, this.marginfiGroup, { @@ -538,8 +565,7 @@ export class SolautoMarginfiClient extends SolautoClient { : undefined, rebalanceType, targetLiqUtilizationRateBps: targetLiqUtilizationRateBps ?? null, - targetInAmountBaseUnit: - rebalanceStep === "A" ? parseInt(jupQuote.inAmount) : null, + targetInAmountBaseUnit: parseInt(jupQuote.inAmount), }); } @@ -574,9 +600,9 @@ export class SolautoMarginfiClient extends SolautoClient { } flashRepay(flashLoanDetails: FlashLoanDetails): TransactionBuilder { - const accounts = flashLoanDetails.mint.equals(this.supplyMint) - ? { data: this.marginfiSupplyAccounts, oracle: this.supplyPriceOracle } - : { data: this.marginfiDebtAccounts, oracle: this.debtPriceOracle }; + const accounts = flashLoanDetails.useDebtLiquidity + ? { data: this.marginfiDebtAccounts, oracle: this.debtPriceOracle } + : { data: this.marginfiSupplyAccounts, oracle: this.supplyPriceOracle }; const remainingAccounts: AccountMeta[] = []; let includedFlashLoanToken = false; diff --git a/solauto-sdk/src/clients/txHandler.ts b/solauto-sdk/src/clients/txHandler.ts index 2459f057..91eb28ed 100644 --- a/solauto-sdk/src/clients/txHandler.ts +++ b/solauto-sdk/src/clients/txHandler.ts @@ -1,4 +1,4 @@ -import { Umi } from "@metaplex-foundation/umi"; +import { Signer, Umi } from "@metaplex-foundation/umi"; import { Connection, PublicKey } from "@solana/web3.js"; import { consoleLog, @@ -9,6 +9,8 @@ import { SOLAUTO_PROD_PROGRAM } from "../constants"; export abstract class TxHandler { public connection!: Connection; public umi!: Umi; + public signer!: Signer; + public otherSigners: Signer[] = []; constructor( public rpcUrl: string, diff --git a/solauto-sdk/src/constants/marginfiAccounts.ts b/solauto-sdk/src/constants/marginfiAccounts.ts index 7c6baa0f..a80e0e6c 100644 --- a/solauto-sdk/src/constants/marginfiAccounts.ts +++ b/solauto-sdk/src/constants/marginfiAccounts.ts @@ -49,7 +49,7 @@ export const MARGINFI_ACCOUNTS: { bank: "AwLRW3aPMMftXEjgWhTkYwM9CGBHdtKecvahCJZBwAqY", liquidityVault: "HQ1CGcqRshMhuonTGTnnmgw9ffcXxizGdZ6F6PKffWWi", vaultAuthority: "AEZb1XH5bfLwqk3hBKDuLfWyJKdLTgDPCkgn64BJKcvV", - priceOracle: "DCNeMcAZGU7pAsqu5q2xMKerq35BnUuTkagt1dkR1xB", + priceOracle: "Ceg5oePJv1a6RR541qKeQaTepvERA3i8SvyueX9tT8Sq", }, [tokens.H_SOL]: { bank: "GJCi1uj3kYPZ64puA5sLUiCQfFapxT2xnREzrbDzFkYY", @@ -172,6 +172,20 @@ export const MARGINFI_ACCOUNTS: { priceOracle: USDC_PRICE_ORACLE, }, }, + ["DESG67cExEcw7d6MmENLEzaocR8pLrhfiw9VrNtGWUKD"]: { + [tokens.HMTR]: { + bank: "Br3yzg2WSb81RaFWK9UsKtq8fD5viwooZG34mKqQWxdM", + liquidityVault: "J45Je52qv2rDBuCQWPwp3bjRhf3bGzRWhKZtGDuLooCX", + vaultAuthority: "CKDsAKjNruDSz4tmUairh8PDGD1Rqh9WMTLWERYnnZrH", + priceOracle: SWITCHBOARD_PRICE_FEED_IDS[tokens.HMTR.toString()], + }, + [tokens.USDC]: { + bank: "9yNnhJ8c1vGbu3DMf6eeeUi6TDJ2ddGgaRA88rL2R3rP", + liquidityVault: "4U1UBjXrPrW7JuQ894JbLUBqcb5LFfK9rfkWFwT7EdQ9", + vaultAuthority: "CY74V1r48kuuHA6APD3AaU2oPV1mBqe9srikrQQSHNR6", + priceOracle: USDC_PRICE_ORACLE, + } + } }; export const MARGINFI_ACCOUNTS_LOOKUP_TABLE = diff --git a/solauto-sdk/src/constants/switchboardConstants.ts b/solauto-sdk/src/constants/switchboardConstants.ts index cc8c438e..c4791dfe 100644 --- a/solauto-sdk/src/constants/switchboardConstants.ts +++ b/solauto-sdk/src/constants/switchboardConstants.ts @@ -7,4 +7,5 @@ export const SWITCHBOARD_PRICE_FEED_IDS: { [key: string]: string } = { [tokens.POPCAT]: "FTcFqwCjAgv2VMaowQ9XSBcesVzFzZkaju25nKio6bki", [tokens.RETARDIO]: "EvPXnpMoyrj4B6P55LDP2VpSLkTBWom2SqL4486ToNhM", [tokens.BILLY]: "uBe4er4VSMgYvBNwSbFctSShRXNPkCfaPh7zHMBFeBi", + [tokens.HMTR]: "F2hKL67W4ZDe9k7ZrJKnp2LhWrgqg2JQTkJf2dgBggRD", }; diff --git a/solauto-sdk/src/constants/tokenConstants.ts b/solauto-sdk/src/constants/tokenConstants.ts index bd3b1f95..e0f88fd0 100644 --- a/solauto-sdk/src/constants/tokenConstants.ts +++ b/solauto-sdk/src/constants/tokenConstants.ts @@ -23,6 +23,7 @@ export const WIF = "EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm"; export const POPCAT = "7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr"; export const RETARDIO = "6ogzHhzdrQr9Pgv6hZ2MNze7UrzBMAFyBBWUYp1Fhitx"; export const BILLY = "3B5wuUrMEi5yATD7on46hKfej3pfmd7t1RKgrsN3pump"; +export const HMTR = "7JhmUcZrrfhyt5nTSu3AfsrUq2L9992a7AhwdSDxdoL2"; export const ALL_SUPPORTED_TOKENS = [ NATIVE_MINT.toString(), @@ -47,6 +48,7 @@ export const ALL_SUPPORTED_TOKENS = [ POPCAT, RETARDIO, BILLY, + HMTR, ]; interface TokenInfo { @@ -116,12 +118,12 @@ export const TOKEN_INFO: { [key: string]: TokenInfo } = { decimals: 6, }, [WBTC]: { - ticker: "WBTC", + ticker: "wBTC", decimals: 8, isMajor: true, }, [WETH]: { - ticker: "WETH", + ticker: "wETH", decimals: 8, isMajor: true, }, @@ -168,4 +170,9 @@ export const TOKEN_INFO: { [key: string]: TokenInfo } = { decimals: 6, isMeme: true, }, + [HMTR]: { + ticker: "HMTR", + decimals: 0, + isMeme: true, + }, }; diff --git a/solauto-sdk/src/generated/types/solautoRebalanceType.ts b/solauto-sdk/src/generated/types/solautoRebalanceType.ts index 7984c41b..e460fe67 100644 --- a/solauto-sdk/src/generated/types/solautoRebalanceType.ts +++ b/solauto-sdk/src/generated/types/solautoRebalanceType.ts @@ -12,7 +12,8 @@ export enum SolautoRebalanceType { None, Regular, DoubleRebalanceWithFL, - SingleRebalanceWithFL, + FLSwapThenRebalance, + FLRebalanceThenSwap, } export type SolautoRebalanceTypeArgs = SolautoRebalanceType; diff --git a/solauto-sdk/src/transactions/transactionUtils.ts b/solauto-sdk/src/transactions/transactionUtils.ts index 8dcb9aa8..4cdf1fb1 100644 --- a/solauto-sdk/src/transactions/transactionUtils.ts +++ b/solauto-sdk/src/transactions/transactionUtils.ts @@ -16,6 +16,7 @@ import { import { InvalidRebalanceConditionError, LendingPlatform, + RebalanceDirection, SolautoAction, SolautoRebalanceType, TokenType, @@ -40,6 +41,7 @@ import { getRebalanceValues, } from "../utils/solauto/rebalanceUtils"; import { + consoleLog, currentUnixSeconds, getSolanaAccountCreated, rpcAccountCreated, @@ -72,6 +74,7 @@ import { import { PRICES } from "../constants"; import { TransactionItemInputs } from "../types"; import { safeGetPrice } from "../utils"; +import { BundleSimulationError } from "../types/transactions"; interface wSolTokenUsage { wSolTokenAccount: PublicKey; @@ -596,14 +599,21 @@ export async function getTransactionChores( } export async function requiresRefreshBeforeRebalance(client: SolautoClient) { - if ( + const neverRefreshedBefore = + client.solautoPositionData && + client.solautoPositionData.state.supply.amountCanBeUsed.baseUnit === + BigInt(0) && + client.solautoPositionData.state.debt.amountCanBeUsed.baseUnit === + BigInt(0); + const aboveMaxLtv = client.solautoPositionState!.liqUtilizationRateBps > getMaxLiqUtilizationRateBps( client.solautoPositionState!.maxLtvBps, client.solautoPositionState!.liqThresholdBps, 0.01 - ) - ) { + ); + + if (aboveMaxLtv || neverRefreshedBefore) { return true; } else if (client.solautoPositionData && !client.selfManaged) { if ( @@ -629,7 +639,10 @@ export async function requiresRefreshBeforeRebalance(client: SolautoClient) { client.livePositionUpdates.debtAdjustment === BigInt(0) && utilizationRateDiff >= 10 ) { - client.log("Choosing to refresh before rebalance"); + client.log( + "Choosing to refresh before rebalance. Utilization rate diff:", + utilizationRateDiff + ); return true; } } @@ -701,41 +714,50 @@ export async function buildSolautoRebalanceTransaction( if (flashLoan) { client.log("Flash loan details: ", flashLoan); const addFirstRebalance = values.amountUsdToDcaIn > 0; + + const rebalanceThenSwap = + values.rebalanceDirection === RebalanceDirection.Repay && + flashLoan.useDebtLiquidity; + const rebalanceType = addFirstRebalance ? SolautoRebalanceType.DoubleRebalanceWithFL - : SolautoRebalanceType.SingleRebalanceWithFL; + : rebalanceThenSwap + ? SolautoRebalanceType.FLRebalanceThenSwap + : SolautoRebalanceType.FLSwapThenRebalance; + + client.log("Rebalance type:", rebalanceType); + const firstRebalance = client.rebalance( + "A", + jupQuote, + rebalanceType, + values, + flashLoan, + targetLiqUtilizationRateBps + ); + const lastRebalance = client.rebalance( + "B", + jupQuote, + rebalanceType, + values, + flashLoan, + targetLiqUtilizationRateBps + ); + + const flashBorrowDest = getTokenAccount( + rebalanceThenSwap + ? client.solautoPosition + : toWeb3JsPublicKey(client.signer.publicKey), + rebalanceThenSwap ? swapDetails.outputMint : swapDetails.inputMint + ); tx = tx.add([ setupInstructions, tokenLedgerIx, - client.flashBorrow( - flashLoan, - getTokenAccount( - toWeb3JsPublicKey(client.signer.publicKey), - swapDetails.inputMint - ) - ), - ...(addFirstRebalance - ? [ - client.rebalance( - "A", - jupQuote, - rebalanceType, - values, - flashLoan, - targetLiqUtilizationRateBps - ), - ] - : []), - swapIx, - client.rebalance( - "B", - jupQuote, - rebalanceType, - values, - flashLoan, - targetLiqUtilizationRateBps - ), + client.flashBorrow(flashLoan, flashBorrowDest), + ...(addFirstRebalance ? [firstRebalance] : []), + ...(rebalanceThenSwap + ? [lastRebalance, swapIx] + : [swapIx, lastRebalance]), client.flashRepay(flashLoan), ]); } else { @@ -796,7 +818,7 @@ export async function convertReferralFeesToDestination( .add(setupInstructions) .add( convertReferralFees(referralManager.umi, { - signer: referralManager.umi.identity, + signer: referralManager.signer, intermediaryTa: publicKey( getTokenAccount( toWeb3JsPublicKey(referralManager.umi.identity.publicKey), @@ -813,58 +835,101 @@ export async function convertReferralFeesToDestination( return { tx, lookupTableAddresses }; } -export function getErrorInfo(umi: Umi, tx: TransactionBuilder, error: any) { +export function getErrorInfo( + umi: Umi, + txs: TransactionBuilder[], + error: Error, + simulationSuccessful?: boolean +) { let canBeIgnored = false; let errorName: string | undefined = undefined; let errorInfo: string | undefined = undefined; - try { - let programError: ProgramError | null = null; + let errTxIdx: number | undefined; + let errIxIdx: number | undefined; + let errCode: number | undefined; + let errName: string | undefined; + + const computeIxs = simulationSuccessful ? 2 : 1; // sub ixs to account for computeUnitLimit and computeUnitPrice that get added + try { if (typeof error === "object" && (error as any)["InstructionError"]) { const err = (error as any)["InstructionError"]; - const errIx = tx.getInstructions()[Math.max(0, err[0])]; - const errCode = + + errIxIdx = err[0] - computeIxs; + errCode = typeof err[1] === "object" && "Custom" in err[1] ? err[1]["Custom"] : undefined; - const errName = errCode === undefined ? (err[1] as string) : undefined; - let programName = ""; + errName = errCode === undefined ? (err[1] as string) : undefined; + } else if (error instanceof BundleSimulationError) { + errTxIdx = error.details.transactionIdx; + errIxIdx = error.details.instructionIdx - computeIxs; + errCode = error.details.errorCode; + } - if ( - errIx.programId.toString() === + consoleLog( + "Transaction instructions:", + txs.map((x) => + x + .getInstructions() + .map((y) => y.programId.toString()) + .join(",") + ) + ); + + let programError: ProgramError | null = null; + let programName = ""; + const errIx = + errTxIdx !== undefined && errIxIdx !== undefined + ? txs[errTxIdx].getInstructions()[Math.max(0, errIxIdx)] + : undefined; + + consoleLog("Error transaction index:", errTxIdx); + consoleLog("Error instruction index:", errIxIdx); + consoleLog("Error code:", errCode); + consoleLog("Error instruction program:", errIx?.programId.toString()); + + const solautoError = getSolautoErrorFromCode( + errCode ?? -1, + createSolautoProgram() + ); + const marginfiError = getMarginfiErrorFromCode( + errCode ?? -1, + createMarginfiProgram() + ); + + if ( + errCode && + errIx?.programId.toString() === umi.programs.get("solauto").publicKey.toString() + ) { + programError = solautoError ?? marginfiError; + programName = "Haven"; + if ( + programError?.name === + new InvalidRebalanceConditionError(createSolautoProgram()).name ) { - programError = getSolautoErrorFromCode(errCode, createSolautoProgram()); - programName = "Haven"; - if ( - programError?.name === - new InvalidRebalanceConditionError(createSolautoProgram()).name - ) { - canBeIgnored = true; - } - } else if (errIx.programId === MARGINFI_PROGRAM_ID) { - programName = "Marginfi"; - programError = getMarginfiErrorFromCode( - errCode, - createMarginfiProgram() - ); - } else if (errIx.programId === JUPITER_PROGRAM_ID) { - programName = "Jupiter"; - programError = getJupiterErrorFromCode(errCode, createJupiterProgram()); - } - - if (errName && errCode === undefined) { - errorName = `${programName ?? "Program"} error`; - errorInfo = errName; + canBeIgnored = true; } + } else if (errCode && errIx?.programId === MARGINFI_PROGRAM_ID) { + programName = "Marginfi"; + programError = marginfiError; + } else if (errCode && errIx?.programId === JUPITER_PROGRAM_ID) { + programName = "Jupiter"; + programError = getJupiterErrorFromCode(errCode, createJupiterProgram()); } if (programError) { errorName = programError?.name; errorInfo = programError?.message; + } else if (errName) { + errorName = `${programName ?? "Program"} error`; + errorInfo = errName; } - } catch {} + } catch (e) { + consoleLog(e); + } return { errorName: errorName, diff --git a/solauto-sdk/src/transactions/transactionsManager.ts b/solauto-sdk/src/transactions/transactionsManager.ts index 10a108e6..d9b04545 100644 --- a/solauto-sdk/src/transactions/transactionsManager.ts +++ b/solauto-sdk/src/transactions/transactionsManager.ts @@ -352,7 +352,7 @@ export class TransactionsManager { return priorityFeeSettingValues[ Math.min( priorityFeeSettingValues.length - 1, - currIdx + Math.floor(attemptNum / 2) + currIdx + Math.floor(attemptNum / 3) ) ]; } @@ -387,7 +387,8 @@ export class TransactionsManager { tx, updateLutTxName, attemptNum, - this.getUpdatedPriorityFeeSetting(prevError, attemptNum) + this.getUpdatedPriorityFeeSetting(prevError, attemptNum), + "skip-simulation" ), 3, 150, @@ -403,7 +404,10 @@ export class TransactionsManager { const updateLookupTable = await client.updateLookupTable(); - if (updateLookupTable && updateLookupTable?.new) { + if ( + updateLookupTable && + (updateLookupTable?.new || updateLookupTable.accountsToAdd.length > 4) + ) { await this.updateLut(updateLookupTable.tx, updateLookupTable.new); } this.lookupTables.defaultLuts = client.defaultLookupTables(); @@ -506,14 +510,7 @@ export class TransactionsManager { this.updateStatusForSets(itemSets, TransactionStatus.Queued, 0); this.txHandler.log("Initial item sets:", itemSets.length); - if (this.txType === "only-simulate" && itemSets.length > 1) { - this.txHandler.log( - "Only simulate and more than 1 transaction. Skipping..." - ); - return []; - } - - if (itemSets.length > 1 && this.atomically) { + if (this.atomically) { await this.processTransactionsAtomically(itemSets); } else { let currentIndex = 0; @@ -528,6 +525,7 @@ export class TransactionsManager { private async processTransactionsAtomically(itemSets: TransactionSet[]) { let num = 0; + let transactions: TransactionBuilder[] = []; await retryWithExponentialBackoff( async (attemptNum, prevError) => { @@ -542,7 +540,7 @@ export class TransactionsManager { ); } - let transactions = []; + transactions = []; for (const set of itemSets) { transactions.push(await set.getSingleTransaction()); } @@ -571,21 +569,34 @@ export class TransactionsManager { this.txHandler.umi, this.txHandler.connection, this.txHandler.signer, + this.txHandler.otherSigners, transactions, this.txType, - this.getUpdatedPriorityFeeSetting(prevError, attemptNum) + this.getUpdatedPriorityFeeSetting(prevError, attemptNum), + () => + this.updateStatusForSets( + itemSets, + TransactionStatus.Processing, + attemptNum, + undefined, + true + ) ); } catch (e: any) { error = e as Error; } - if (error || !Boolean(txSigs) || txSigs?.length === 0) { + if ( + error || + (this.txType !== "only-simulate" && + (!Boolean(txSigs) || txSigs?.length === 0)) + ) { this.updateStatusForSets( itemSets, TransactionStatus.Failed, attemptNum, txSigs, - true, + undefined, error?.message ); throw error ? error : new Error("Unknown error"); @@ -602,15 +613,34 @@ export class TransactionsManager { this.retryDelay, this.errorsToThrow ).catch((e: Error) => { + this.txHandler.log("Capturing error info..."); + const errorDetails = getErrorInfo( + this.txHandler.umi, + transactions, + e, + itemSets.filter( + (x) => + this.statuses.find((y) => x.name() === y.name)?.simulationSuccessful + ).length === itemSets.length + ); + + const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`; this.updateStatusForSets( itemSets, - TransactionStatus.Failed, + errorDetails.canBeIgnored + ? TransactionStatus.Skipped + : TransactionStatus.Failed, num, undefined, - true, - e.message + undefined, + errorDetails.errorName || errorDetails.errorInfo + ? errorString + : e.message ); - throw e; + + if (!errorDetails.canBeIgnored) { + throw e; + } }); } @@ -654,19 +684,7 @@ export class TransactionsManager { this.retries, this.retryDelay, this.errorsToThrow - ).catch((e: Error) => { - if (itemSet) { - this.updateStatus( - itemSet.name(), - TransactionStatus.Failed, - num, - undefined, - undefined, - e.message - ); - } - throw e; - }); + ); } private async refreshItemSet( @@ -710,7 +728,8 @@ export class TransactionsManager { tx: TransactionBuilder, txName: string, attemptNum: number, - priorityFeeSetting?: PriorityFeeSetting + priorityFeeSetting?: PriorityFeeSetting, + txType?: TransactionRunType ) { this.updateStatus(txName, TransactionStatus.Processing, attemptNum); try { @@ -718,7 +737,7 @@ export class TransactionsManager { this.txHandler.umi, this.txHandler.connection, tx, - this.txType, + txType ?? this.txType, priorityFeeSetting, () => this.updateStatus( @@ -736,9 +755,15 @@ export class TransactionsManager { txSig ? bs58.encode(txSig) : undefined ); } catch (e: any) { - const errorDetails = getErrorInfo(this.txHandler.umi, tx, e); + this.txHandler.log("Capturing error info..."); + const errorDetails = getErrorInfo( + this.txHandler.umi, + [tx], + e, + this.statuses.find((x) => x.name === txName)?.simulationSuccessful + ); - const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo ?? "unknown"}`; + const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`; this.updateStatus( txName, errorDetails.canBeIgnored diff --git a/solauto-sdk/src/types/index.ts b/solauto-sdk/src/types/index.ts index 5670a221..634ddf08 100644 --- a/solauto-sdk/src/types/index.ts +++ b/solauto-sdk/src/types/index.ts @@ -1,2 +1,3 @@ export * from './accounts'; export * from './solauto'; +export * from './transactions'; diff --git a/solauto-sdk/src/types/solauto.ts b/solauto-sdk/src/types/solauto.ts index 0de25c33..99c73caf 100644 --- a/solauto-sdk/src/types/solauto.ts +++ b/solauto-sdk/src/types/solauto.ts @@ -19,6 +19,7 @@ export enum PriorityFeeSetting { Low = "Low", Default = "Medium", High = "High", + VeryHigh = "VeryHigh", } export const priorityFeeSettingValues = Object.values(PriorityFeeSetting) as PriorityFeeSetting[]; diff --git a/solauto-sdk/src/types/transactions.ts b/solauto-sdk/src/types/transactions.ts new file mode 100644 index 00000000..e8b1ddb2 --- /dev/null +++ b/solauto-sdk/src/types/transactions.ts @@ -0,0 +1,23 @@ +export interface BundleInstructionFailure { + transactionIdx: number; + instructionIdx: number; + errorCode: number; +} + +export class BundleSimulationError extends Error { + public statusCode: number; + public details: BundleInstructionFailure; + + constructor( + message: string, + statusCode: number, + details: BundleInstructionFailure + ) { + super(message); + + this.statusCode = statusCode; + this.details = details; + + Object.setPrototypeOf(this, BundleSimulationError.prototype); + } +} diff --git a/solauto-sdk/src/utils/accountUtils.ts b/solauto-sdk/src/utils/accountUtils.ts index 3d9f1286..9ad08fc7 100644 --- a/solauto-sdk/src/utils/accountUtils.ts +++ b/solauto-sdk/src/utils/accountUtils.ts @@ -1,5 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { AccountLayout as SplTokenAccountLayout, getAssociatedTokenAddressSync } from "@solana/spl-token"; +import { + AccountLayout as SplTokenAccountLayout, + getAssociatedTokenAddressSync, +} from "@solana/spl-token"; import { publicKey, Umi } from "@metaplex-foundation/umi"; export function bufferFromU8(num: number): Buffer { @@ -14,20 +17,24 @@ export function bufferFromU64(num: bigint): Buffer { return buffer; } -export function getTokenAccount(wallet: PublicKey, tokenMint: PublicKey): PublicKey { - return getAssociatedTokenAddressSync( - tokenMint, - wallet, - true - ); +export function getTokenAccount( + wallet: PublicKey, + tokenMint: PublicKey +): PublicKey { + return getAssociatedTokenAddressSync(tokenMint, wallet, true); } -export function getTokenAccounts(wallet: PublicKey, tokenMints: PublicKey[]): PublicKey[] { - return tokenMints.map(x => getTokenAccount(wallet, x)); +export function getTokenAccounts( + wallet: PublicKey, + tokenMints: PublicKey[] +): PublicKey[] { + return tokenMints.map((x) => getTokenAccount(wallet, x)); } export async function getTokenAccountData(umi: Umi, tokenAccount: PublicKey) { - const resp = await umi.rpc.getAccount(publicKey(tokenAccount), { commitment: "confirmed" }); + const resp = await umi.rpc.getAccount(publicKey(tokenAccount), { + commitment: "confirmed", + }); if (resp.exists) { return SplTokenAccountLayout.decode(resp.data); } else { @@ -40,8 +47,14 @@ export function getSolautoPositionAccount( positionId: number, programId: PublicKey ) { + const fakePosition = positionId >= 256; const [positionAccount, _] = PublicKey.findProgramAddressSync( - [bufferFromU8(positionId), authority.toBuffer()], + [ + fakePosition + ? bufferFromU64(BigInt(positionId)) + : bufferFromU8(positionId), + authority.toBuffer(), + ], programId ); @@ -59,21 +72,3 @@ export function getReferralState(authority: PublicKey, programId: PublicKey) { return ReferralState; } - -export function getMarginfiAccountPDA( - solautoPositionAccount: PublicKey, - marginfiAccountSeedIdx: bigint, - programId: PublicKey -) { - const seeds = [ - solautoPositionAccount.toBuffer(), - bufferFromU64(marginfiAccountSeedIdx), - ]; - - const [marginfiAccount, _] = PublicKey.findProgramAddressSync( - seeds, - programId - ); - - return marginfiAccount; -} \ No newline at end of file diff --git a/solauto-sdk/src/utils/generalUtils.ts b/solauto-sdk/src/utils/generalUtils.ts index 373c7787..7f0ee68e 100644 --- a/solauto-sdk/src/utils/generalUtils.ts +++ b/solauto-sdk/src/utils/generalUtils.ts @@ -1,5 +1,6 @@ import { PublicKey } from "@solana/web3.js"; import { MaybeRpcAccount, publicKey, Umi } from "@metaplex-foundation/umi"; +import { LendingPlatform } from "../generated"; export function consoleLog(...args: any[]): void { if ((globalThis as any).LOCAL_TEST) { @@ -98,3 +99,13 @@ export function retryWithExponentialBackoff( return attempt(0); }); } + +export function toEnumValue(enumObj: E, value: number): E[keyof E] | undefined { + const numericValues = Object.values(enumObj).filter(v => typeof v === "number") as number[]; + + if (numericValues.includes(value)) { + return value as E[keyof E]; + } + + return undefined; +} \ No newline at end of file diff --git a/solauto-sdk/src/utils/jitoUtils.ts b/solauto-sdk/src/utils/jitoUtils.ts index 3f03e854..e74268c2 100644 --- a/solauto-sdk/src/utils/jitoUtils.ts +++ b/solauto-sdk/src/utils/jitoUtils.ts @@ -1,4 +1,11 @@ -import { Connection, PublicKey, TransactionExpiredBlockheightExceededError, VersionedTransaction } from "@solana/web3.js"; +import { + Connection, + PublicKey, + SimulatedTransactionResponse, + TransactionExpiredBlockheightExceededError, + VersionedMessage, + VersionedTransaction, +} from "@solana/web3.js"; import { toWeb3JsTransaction } from "@metaplex-foundation/umi-web3js-adapters"; import { JITO_BLOCK_ENGINE } from "../constants/solautoConstants"; import { @@ -6,21 +13,22 @@ import { TransactionBuilder, Umi, WrappedInstruction, + TransactionMessage, } from "@metaplex-foundation/umi"; import { assembleFinalTransaction, - buildIronforgeApiUrl, getComputeUnitPriceEstimate, sendSingleOptimizedTransaction, systemTransferUmiIx, } from "./solanaUtils"; -import { consoleLog } from "./generalUtils"; +import { consoleLog, retryWithExponentialBackoff } from "./generalUtils"; import { PriorityFeeSetting, TransactionRunType } from "../types"; import axios from "axios"; import base58 from "bs58"; +import { BundleSimulationError } from "../types/transactions"; import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes"; -export async function getRandomTipAccount(): Promise { +export function getRandomTipAccount(): PublicKey { const tipAccounts = [ "96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5", "HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe", @@ -35,40 +43,122 @@ export async function getRandomTipAccount(): Promise { return new PublicKey(tipAccounts[randomInt]); } -async function getTipInstruction( +function getTipInstruction( signer: Signer, tipLamports: number -): Promise { +): WrappedInstruction { return systemTransferUmiIx( signer, - await getRandomTipAccount(), + getRandomTipAccount(), BigInt(tipLamports) ); } -// TODO: fix -// async function simulateJitoBundle(umi: Umi, txs: VersionedTransaction[]) { -// const simulationResult = await axios.post( -// `${JITO_BLOCK_ENGINE}/api/v1/bundles`, -// { -// method: "simulateBundle", -// id: 1, -// jsonrpc: "2.0", -// params: [ -// { -// encodedTransactions: txs.map((x) => bs58.encode(x.serialize())), -// preExecutionAccountsConfigs: txs.map((_) => ""), -// postExecutionAccountsConfigs: txs.map((_) => ""), -// skipSigVerify: true, -// }, -// ], -// } -// ); -// } +function parseJitoErrorMessage(message: string) { + const regex = + /Error processing Instruction (\d+): custom program error: (0x[0-9A-Fa-f]+|\d+)/; + const match = message.match(regex); + + if (match) { + const instructionIndex = parseInt(match[1], 10); + + let errorCode: number; + if (match[2].toLowerCase().startsWith("0x")) { + errorCode = parseInt(match[2], 16); + } else { + errorCode = parseInt(match[2], 10); + } + + return { + instructionIndex, + errorCode, + }; + } else { + return null; + } +} + +async function simulateJitoBundle(umi: Umi, txs: VersionedTransaction[]) { + const simulationResult = await retryWithExponentialBackoff(async () => { + const resp = await axios.post( + umi.rpc.getEndpoint(), + { + jsonrpc: "2.0", + id: 1, + method: "simulateBundle", + params: [ + { + encodedTransactions: txs.map((x) => + Buffer.from(x.serialize()).toString("base64") + ), + }, + { + encoding: "base64", + commitment: "confirmed", + preExecutionAccountsConfigs: txs.map((_) => {}), + postExecutionAccountsConfigs: txs.map((_) => {}), + skipSigVerify: true, + }, + ], + }, + { + headers: { + "Content-Type": "application/json", + }, + } + ); + + const res = resp.data as any; + + if (res.result && res.result.value && res.result.value.summary.failed) { + const resValue = res.result.value; + const transactionResults = + resValue.transactionResults as SimulatedTransactionResponse[]; + transactionResults.forEach((x) => { + x.logs?.forEach((y) => { + consoleLog(y); + }); + }); + + const failedTxIdx = transactionResults.length; + const txFailure = resValue.summary.failed.error.TransactionFailure; + + if (txFailure) { + const info = parseJitoErrorMessage(txFailure[1] as string); + if (info) { + throw new BundleSimulationError( + `Failed to simulate transaction: TX: ${failedTxIdx}, IX: ${info.instructionIndex}, Error: ${info.errorCode}`, + 400, + { + transactionIdx: failedTxIdx, + instructionIdx: info.instructionIndex, + errorCode: info.errorCode, + } + ); + } + } + + throw new Error( + txFailure ? txFailure[1] : resValue.summary.failed.toString() + ); + } else if (res.error && res.error.message) { + throw new Error(res.error.message); + } + + return res; + }); + + const transactionResults = + simulationResult.transactionResults as SimulatedTransactionResponse[]; + + return transactionResults; +} async function umiToVersionedTransactions( umi: Umi, - signer: Signer, + blockhash: string, + userSigner: Signer, + otherSigners: Signer[], txs: TransactionBuilder[], sign: boolean, feeEstimates?: number[], @@ -76,19 +166,31 @@ async function umiToVersionedTransactions( ): Promise { let builtTxs = await Promise.all( txs.map(async (tx, i) => { - return ( - await assembleFinalTransaction( - signer, - tx, - feeEstimates ? feeEstimates[i] : undefined, - computeUnitLimits ? computeUnitLimits[i] : undefined - ).setLatestBlockhash(umi) - ).build(umi); + return assembleFinalTransaction( + userSigner, + tx, + feeEstimates ? feeEstimates[i] : undefined, + computeUnitLimits ? computeUnitLimits[i] : undefined + ) + .setBlockhash(blockhash) + .build(umi); }) ); if (sign) { - builtTxs = await signer.signAllTransactions(builtTxs); + builtTxs = await userSigner.signAllTransactions(builtTxs); + for (const signer of otherSigners) { + for (let i = 0; i < builtTxs.length; i++) { + const requiredSigners = getRequiredSigners(builtTxs[i].message); + if ( + requiredSigners + .map((x) => x.publicKey) + .includes(signer.publicKey.toString()) + ) { + builtTxs[i] = await signer.signTransaction(builtTxs[i]); + } + } + } } return builtTxs.map((x) => toWeb3JsTransaction(x)); @@ -121,25 +223,32 @@ async function pollBundleStatus( consoleLog("Statuses:", statuses); const status = statuses.value[0].confirmation_status; if (status === "confirmed") { - return statuses?.value[0].transactions as string[]; + return statuses.value[0].transactions as string[]; + } + const err = statuses.value[0].err; + if (err) { + consoleLog("Jito bundle err:", JSON.stringify(err, null, 2)); + throw new Error(err); } } } - throw new TransactionExpiredBlockheightExceededError("Unable to confirm transaction. Try a higher priority fee."); + throw new TransactionExpiredBlockheightExceededError( + "Unable to confirm transaction. Try a higher priority fee." + ); } -async function sendJitoBundle(transactions: string[]): Promise { +async function sendJitoBundle( + umi: Umi, + transactions: string[] +): Promise { let resp: any; try { - resp = await axios.post<{ result: string }>( - `${JITO_BLOCK_ENGINE}/api/v1/bundles`, - { - jsonrpc: "2.0", - id: 1, - method: "sendBundle", - params: [transactions], - } - ); + resp = await axios.post<{ result: string }>(umi.rpc.getEndpoint(), { + jsonrpc: "2.0", + id: 1, + method: "sendBundle", + params: [transactions], + }); } catch (e: any) { if (e.response.data.error) { console.error("Jito send bundle error:", e.response.data.error); @@ -154,65 +263,124 @@ async function sendJitoBundle(transactions: string[]): Promise { return bundleId ? await pollBundleStatus(bundleId) : []; } +export function getRequiredSigners(message: TransactionMessage) { + const { numRequiredSignatures, numReadonlySignedAccounts } = message.header; + + const numWritableSigners = numRequiredSignatures - numReadonlySignedAccounts; + + const signersInfo = []; + for (let i = 0; i < numRequiredSignatures; i++) { + const publicKey = message.accounts[i].toString(); + const isWritable = i < numWritableSigners; + + signersInfo.push({ + index: i, + publicKey, + isWritable, + }); + } + + return signersInfo; +} + export async function sendJitoBundledTransactions( umi: Umi, connection: Connection, - signer: Signer, + userSigner: Signer, + otherSigners: Signer[], txs: TransactionBuilder[], txType?: TransactionRunType, - priorityFeeSetting: PriorityFeeSetting = PriorityFeeSetting.Min + priorityFeeSetting: PriorityFeeSetting = PriorityFeeSetting.Min, + onAwaitingSign?: () => void ): Promise { if (txs.length === 1) { - const res = await sendSingleOptimizedTransaction( + const resp = await sendSingleOptimizedTransaction( umi, connection, txs[0], txType, - priorityFeeSetting + priorityFeeSetting, + onAwaitingSign ); - return res ? [bs58.encode(res)] : undefined; + return resp ? [bs58.encode(resp)] : undefined; } consoleLog("Sending Jito bundle..."); consoleLog("Transactions: ", txs.length); + consoleLog( + txs.map((tx) => tx.getInstructions().map((x) => x.programId.toString())) + ); consoleLog( "Transaction sizes: ", txs.map((x) => x.getTransactionSize(umi)) ); - txs[0] = txs[0].prepend(await getTipInstruction(signer, 150_000)); + txs[0] = txs[0].prepend(getTipInstruction(userSigner, 150_000)); const feeEstimates = priorityFeeSetting !== PriorityFeeSetting.None ? await Promise.all( txs.map( async (x) => - (await getComputeUnitPriceEstimate(umi, x, priorityFeeSetting)) ?? - 1000000 + (await getComputeUnitPriceEstimate( + umi, + x, + priorityFeeSetting, + true + )) ?? 1000000 ) ) : undefined; - let builtTxs = await umiToVersionedTransactions( - umi, - signer, - txs, - true, // false if simulating first and rebuilding later - feeEstimates - ); + const latestBlockhash = ( + await umi.rpc.getLatestBlockhash({ commitment: "confirmed" }) + ).blockhash; - // const simulationResults = await simulateJitoBundle(umi, builtTxs); + let builtTxs: VersionedTransaction[] = []; + let simulationResults: SimulatedTransactionResponse[] | undefined; + if (txType !== "skip-simulation") { + builtTxs = await umiToVersionedTransactions( + umi, + latestBlockhash, + userSigner, + otherSigners, + txs, + false, + feeEstimates + ); + consoleLog( + builtTxs.map((x) => + x.message.compiledInstructions.map((y) => + x.message.staticAccountKeys[y.programIdIndex].toString() + ) + ) + ); + simulationResults = await simulateJitoBundle(umi, builtTxs); + } if (txType !== "only-simulate") { - // let builtTxs = await umiToVersionedTransactions( - // client.signer, - // txs, - // true, - // feeEstimates, - // simulationResults.map((x) => x.unitsConsumed! * 1.15) - // ); + onAwaitingSign?.(); + + builtTxs = await umiToVersionedTransactions( + umi, + latestBlockhash, + userSigner, + otherSigners, + txs, + true, + feeEstimates, + simulationResults + ? simulationResults.map((x) => x.unitsConsumed! * 1.15) + : undefined + ); + + const serializedTxs = builtTxs.map((x) => x.serialize()); + if (serializedTxs.find((x) => x.length > 1232)) { + throw new Error("A transaction is too large"); + } const txSigs = await sendJitoBundle( - builtTxs.map((x) => base58.encode(x.serialize())) + umi, + serializedTxs.map((x) => base58.encode(x)) ); return txSigs.length > 0 ? txSigs : undefined; } diff --git a/solauto-sdk/src/utils/jupiterUtils.ts b/solauto-sdk/src/utils/jupiterUtils.ts index 1f755a27..63d7ba93 100644 --- a/solauto-sdk/src/utils/jupiterUtils.ts +++ b/solauto-sdk/src/utils/jupiterUtils.ts @@ -25,6 +25,7 @@ export interface JupSwapDetails { slippageIncFactor?: number; exactOut?: boolean; exactIn?: boolean; + addPadding?: boolean; } function createTransactionInstruction( @@ -70,8 +71,8 @@ export async function getJupSwapTransaction( : swapDetails.exactIn ? "ExactIn" : undefined, - slippageBps: memecoinSwap ? 150 : 50, - maxAccounts: !swapDetails.exactOut ? 60 : undefined, + slippageBps: memecoinSwap ? 500 : 300, + maxAccounts: !swapDetails.exactOut ? 45 : undefined, }), 4, 200 @@ -86,15 +87,6 @@ export async function getJupSwapTransaction( quoteResponse.slippageBps = finalPriceSlippageBps; consoleLog(quoteResponse); - if (swapDetails.exactOut) { - quoteResponse.inAmount = ( - parseInt(quoteResponse.inAmount) + - Math.ceil( - parseInt(quoteResponse.inAmount) * fromBps(finalPriceSlippageBps) - ) - ).toString(); - } - consoleLog("Getting jup instructions..."); const instructions = await retryWithExponentialBackoff( async () => @@ -123,6 +115,19 @@ export async function getJupSwapTransaction( priceImpactBps * (1 + (swapDetails.slippageIncFactor ?? 0)); consoleLog("Increased price impact bps:", finalPriceImpactBps); + if (swapDetails.addPadding) { + consoleLog("Raw inAmount:", quoteResponse.inAmount); + const inc = Math.max( + fromBps(finalPriceImpactBps) * 1.1, + fromBps(finalPriceSlippageBps) * 0.05 + ); + consoleLog("Inc:", inc); + quoteResponse.inAmount = Math.round( + parseInt(quoteResponse.inAmount) + parseInt(quoteResponse.inAmount) * inc + ).toString(); + consoleLog("Increased inAmount:", quoteResponse.inAmount); + } + return { jupQuote: quoteResponse, priceImpactBps: finalPriceImpactBps, @@ -147,4 +152,23 @@ export async function getJupSwapTransaction( ) ), }; -} \ No newline at end of file +} + +export async function getJupPriceData(mints: PublicKey[], extraInfo?: boolean) { + const data = await retryWithExponentialBackoff(async () => { + const res = await ( + await fetch( + "https://api.jup.ag/price/v2?ids=" + + mints.map((x) => x.toString()).join(",") + + (extraInfo ? "&showExtraInfo=true" : "") + ) + ).json(); + const result = res.data; + if (!result) { + throw new Error("Failed to get token prices using Jupiter"); + } + return result; + }, 6); + + return data as { [key: string]: any }; +} diff --git a/solauto-sdk/src/utils/marginfiUtils.ts b/solauto-sdk/src/utils/marginfiUtils.ts index ea199afb..1e812df4 100644 --- a/solauto-sdk/src/utils/marginfiUtils.ts +++ b/solauto-sdk/src/utils/marginfiUtils.ts @@ -48,7 +48,7 @@ export function findMarginfiAccounts( throw new Error(`Marginfi accounts not found by the bank: ${bank}`); } -export function calcMaxLtvAndLiqThreshold( +export function calcMarginfiMaxLtvAndLiqThreshold( supplyBank: Bank, debtBank: Bank, supplyPrice: number @@ -83,7 +83,7 @@ export function calcMaxLtvAndLiqThreshold( return [maxLtv, liqThreshold]; } -export async function getMaxLtvAndLiqThreshold( +export async function getMarginfiMaxLtvAndLiqThreshold( umi: Umi, marginfiGroup: PublicKey, supply: { @@ -134,7 +134,11 @@ export async function getMaxLtvAndLiqThreshold( return [0, 0]; } - return calcMaxLtvAndLiqThreshold(supply.bank!, debt.bank, supplyPrice); + return calcMarginfiMaxLtvAndLiqThreshold( + supply.bank!, + debt.bank, + supplyPrice + ); } export async function getAllMarginfiAccountsByAuthority( @@ -412,9 +416,18 @@ export async function getMarginfiAccountPositionState( ); } + if (debtBank === null) { + return undefined; + } + + const supplyMint = TOKEN_INFO[supplyBank.mint.toString()]; + const debtMint = TOKEN_INFO[debtBank.mint.toString()]; + if ( - TOKEN_INFO[supplyBank.mint.toString()].isStableCoin && - (debtBank === null || TOKEN_INFO[debtBank.mint.toString()].isStableCoin) + supplyMint === undefined || + debtMint === undefined || + (!supplyMint.isStableCoin && !debtMint.isStableCoin) || + (supplyMint.isStableCoin && debtMint.isStableCoin) ) { return undefined; } @@ -429,7 +442,7 @@ export async function getMarginfiAccountPositionState( } const supplyPrice = safeGetPrice(supply.mint!)!; - let [maxLtv, liqThreshold] = await getMaxLtvAndLiqThreshold( + let [maxLtv, liqThreshold] = await getMarginfiMaxLtvAndLiqThreshold( umi, marginfiGroup ?? new PublicKey(DEFAULT_MARGINFI_GROUP), { @@ -565,3 +578,14 @@ export function getUpToDateShareValues(bank: Bank): [number, number] { ), ]; } + +export function marginfiAccountEmpty(marginfiAccount: MarginfiAccount) { + return ( + marginfiAccount.lendingAccount.balances.find( + (x) => + x.bankPk.toString() !== PublicKey.default.toString() && + (Math.round(bytesToI80F48(x.assetShares.value)) != 0 || + Math.round(bytesToI80F48(x.liabilityShares.value)) != 0) + ) === undefined + ); +} diff --git a/solauto-sdk/src/utils/numberUtils.ts b/solauto-sdk/src/utils/numberUtils.ts index 4dced0a5..8196f007 100644 --- a/solauto-sdk/src/utils/numberUtils.ts +++ b/solauto-sdk/src/utils/numberUtils.ts @@ -14,10 +14,16 @@ export function getLiqUtilzationRateBps( } export function toBaseUnit(value: number, decimals: number): bigint { + if (!decimals) { + return BigInt(Math.floor(value)); + } return BigInt(Math.round(value * Math.pow(10, decimals))); } export function fromBaseUnit(value: bigint, decimals: number): number { + if (!decimals) { + return Number(value); + } return Number(value) / Math.pow(10, decimals); } diff --git a/solauto-sdk/src/utils/priceUtils.ts b/solauto-sdk/src/utils/priceUtils.ts index a6cfe8e0..8f286116 100644 --- a/solauto-sdk/src/utils/priceUtils.ts +++ b/solauto-sdk/src/utils/priceUtils.ts @@ -10,7 +10,8 @@ import { retryWithExponentialBackoff, zip, } from "./generalUtils"; -import { CrossbarClient } from "@switchboard-xyz/on-demand"; +import * as OnDemand from "@switchboard-xyz/on-demand"; +import { getJupPriceData } from "./jupiterUtils"; export async function fetchTokenPrices(mints: PublicKey[]): Promise { const currentTime = currentUnixSeconds(); @@ -43,7 +44,7 @@ export async function fetchTokenPrices(mints: PublicKey[]): Promise { for (var i = 0; i < mints.length; i++) { PRICES[mints[i].toString()] = { - price: prices[i], + price: Number(prices[i]), time: currentUnixSeconds(), }; } @@ -100,26 +101,37 @@ export async function getSwitchboardPrices( return []; } - const crossbar = new CrossbarClient("https://crossbar.switchboard.xyz"); - let prices = await retryWithExponentialBackoff( - async () => { - const res = await crossbar.simulateSolanaFeeds( - "mainnet", - mints.map((x) => SWITCHBOARD_PRICE_FEED_IDS[x.toString()]) - ); - - const prices = res.flatMap((x) => x.results[0]); - if (prices.find((x) => !x || x === -Infinity)) { - throw new Error("Unable to fetch Switchboard prices"); - } + const { CrossbarClient } = OnDemand; + const crossbar = CrossbarClient.default(); + + let prices: number[] = []; + try { + prices = await retryWithExponentialBackoff( + async () => { + const res = await crossbar.simulateSolanaFeeds( + "mainnet", + mints.map((x) => SWITCHBOARD_PRICE_FEED_IDS[x.toString()]) + ); + + const p = res.flatMap((x) => x.results[0]); + if (p.filter((x) => !x || isNaN(Number(x))).length > 0) { + throw new Error("Unable to fetch Switchboard prices"); + } + + return p; + }, + 2, + 350 + ); + } catch { + consoleLog("Failed to fetch Switchboard prices after multiple retries"); + } - return prices; - }, - 8, - 250 - ); + if (prices.length === 0) { + prices = Array(mints.length).fill(0); + } - const missingPrices = zip(mints, prices).filter((x) => !x[1]); + const missingPrices = zip(mints, prices).filter((x) => !x[1] || isNaN(Number(x))); const jupPrices = zip( missingPrices.map((x) => x[0]), await getJupTokenPrices(missingPrices.map((x) => x[0])) @@ -137,17 +149,9 @@ export async function getJupTokenPrices(mints: PublicKey[]) { return []; } - const data = await retryWithExponentialBackoff(async () => { - const res = ( - await fetch( - "https://api.jup.ag/price/v2?ids=" + - mints.map((x) => x.toString()).join(",") - ) - ).json(); - return res; - }, 6); - - const prices = Object.values(data.data as { [key: string]: any }).map( + const data = await getJupPriceData(mints); + + const prices = Object.values(data).map( (x) => parseFloat(x.price as string) as number ); diff --git a/solauto-sdk/src/utils/solanaUtils.ts b/solauto-sdk/src/utils/solanaUtils.ts index a564a23e..d19a925f 100644 --- a/solauto-sdk/src/utils/solanaUtils.ts +++ b/solauto-sdk/src/utils/solanaUtils.ts @@ -162,7 +162,8 @@ export async function getAddressLookupInputs( lookupTableAddresses: string[] ): Promise { const addressLookupTableAccountInfos = await umi.rpc.getAccounts( - lookupTableAddresses.map((key) => publicKey(key)) + lookupTableAddresses.map((key) => publicKey(key)), + { commitment: "confirmed" } ); return addressLookupTableAccountInfos.reduce((acc, accountInfo, index) => { @@ -288,30 +289,25 @@ async function simulateTransaction( export async function getComputeUnitPriceEstimate( umi: Umi, tx: TransactionBuilder, - prioritySetting: PriorityFeeSetting + prioritySetting: PriorityFeeSetting, + useAccounts?: boolean ): Promise { const web3Transaction = toWeb3JsTransaction( (await tx.setLatestBlockhash(umi, { commitment: "finalized" })).build(umi) ); - let feeEstimate: number | undefined; - try { - const resp = await umi.rpc.call("getPriorityFeeEstimate", [ - { - transaction: bs58.encode(web3Transaction.serialize()), - options: { - priorityLevel: prioritySetting.toString(), - }, - }, - ]); - feeEstimate = Math.round((resp as any).priorityFeeEstimate as number); - } catch (e) { + const accountKeys = tx + .getInstructions() + .flatMap((x) => x.keys.flatMap((x) => x.pubkey.toString())); + + let feeEstimate: number | undefined; try { const resp = await umi.rpc.call("getPriorityFeeEstimate", [ { - accountKeys: tx - .getInstructions() - .flatMap((x) => x.keys.flatMap((x) => x.pubkey.toString())), + transaction: !useAccounts + ? bs58.encode(web3Transaction.serialize()) + : undefined, + accountKeys: useAccounts ? accountKeys : undefined, options: { priorityLevel: prioritySetting.toString(), }, @@ -319,9 +315,20 @@ export async function getComputeUnitPriceEstimate( ]); feeEstimate = Math.round((resp as any).priorityFeeEstimate as number); } catch (e) { - console.error(e); + try { + const resp = await umi.rpc.call("getPriorityFeeEstimate", [ + { + accountKeys, + options: { + priorityLevel: prioritySetting.toString(), + }, + }, + ]); + feeEstimate = Math.round((resp as any).priorityFeeEstimate as number); + } catch (e) { + // console.error(e); + } } - } return feeEstimate; } @@ -385,19 +392,15 @@ export async function sendSingleOptimizedTransaction( consoleLog("Instructions: ", tx.getInstructions().length); consoleLog("Serialized transaction size: ", tx.getTransactionSize(umi)); - let cuPrice: number | undefined; - if (prioritySetting !== PriorityFeeSetting.None) { - cuPrice = await getComputeUnitPriceEstimate( - umi, - tx, - prioritySetting, - ); - if (!cuPrice) { - cuPrice = 1000000; - } - cuPrice = Math.min(cuPrice, 100 * 1_000_000); - consoleLog("Compute unit price: ", cuPrice); - } + const accounts = tx + .getInstructions() + .flatMap((x) => [ + x.programId.toString(), + ...x.keys.map((y) => y.pubkey.toString()), + ]); + consoleLog("Unique account locks: ", Array.from(new Set(accounts)).length); + + const blockhash = await connection.getLatestBlockhash("confirmed"); let computeUnitLimit = undefined; if (txType !== "skip-simulation") { @@ -406,23 +409,31 @@ export async function sendSingleOptimizedTransaction( await simulateTransaction( umi, connection, - await assembleFinalTransaction( + assembleFinalTransaction( umi.identity, tx, - cuPrice, + undefined, 1_400_000 - ).setLatestBlockhash(umi) + ).setBlockhash(blockhash) ), 3 ); - simulationResult.value.err; computeUnitLimit = Math.round(simulationResult.value.unitsConsumed! * 1.15); consoleLog("Compute unit limit: ", computeUnitLimit); } + let cuPrice: number | undefined; + if (prioritySetting !== PriorityFeeSetting.None) { + cuPrice = await getComputeUnitPriceEstimate(umi, tx, prioritySetting); + if (!cuPrice) { + cuPrice = 1_000_000; + } + cuPrice = Math.min(cuPrice, 100 * 1_000_000); + consoleLog("Compute unit price: ", cuPrice); + } + if (txType !== "only-simulate") { onAwaitingSign?.(); - const blockhash = await connection.getLatestBlockhash("confirmed"); const signedTx = await assembleFinalTransaction( umi.identity, tx, diff --git a/solauto-sdk/src/utils/solauto/generalUtils.ts b/solauto-sdk/src/utils/solauto/generalUtils.ts index 271eb697..a183e63f 100644 --- a/solauto-sdk/src/utils/solauto/generalUtils.ts +++ b/solauto-sdk/src/utils/solauto/generalUtils.ts @@ -1,4 +1,4 @@ -import { Connection, PublicKey } from "@solana/web3.js"; +import { PublicKey } from "@solana/web3.js"; import { isOption, isSome, @@ -27,6 +27,7 @@ import { fromBaseUnit, getLiqUtilzationRateBps, toBaseUnit, + toBps, } from "../numberUtils"; import { getReferralState } from "../accountUtils"; import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; @@ -38,6 +39,7 @@ import { import { findMarginfiAccounts, getAllMarginfiAccountsByAuthority, + getMarginfiMaxLtvAndLiqThreshold, } from "../marginfiUtils"; import { RebalanceAction, SolautoPositionDetails } from "../../types/solauto"; import { fetchTokenPrices } from "../priceUtils"; @@ -167,7 +169,11 @@ export function eligibleForRebalance( const boostFrom = boostToBps - positionSettings.boostGap; if (positionState.liqUtilizationRateBps - boostFrom <= bpsDistanceThreshold) { - if (positionState.liqUtilizationRateBps < boostFrom) { + const limitsUpToDate = + positionState.supply.amountCanBeUsed.baseUnit > BigInt(0) || + positionState.debt.amountCanBeUsed.baseUnit > BigInt(0); + + if (limitsUpToDate && positionState.liqUtilizationRateBps < boostFrom) { const values = getRebalanceValues( positionState!, positionSettings, @@ -267,7 +273,7 @@ export async function getSolautoManagedPositions( ? [ { memcmp: { - bytes: new Uint8Array(positionTypeFilter), + bytes: new Uint8Array([positionTypeFilter]), offset: 3, }, }, diff --git a/solauto-sdk/src/utils/solauto/rebalanceUtils.ts b/solauto-sdk/src/utils/solauto/rebalanceUtils.ts index 13cd66b7..8befbe21 100644 --- a/solauto-sdk/src/utils/solauto/rebalanceUtils.ts +++ b/solauto-sdk/src/utils/solauto/rebalanceUtils.ts @@ -16,7 +16,7 @@ import { import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; import { QuoteResponse } from "@jup-ag/api"; import { JupSwapDetails } from "../jupiterUtils"; -import { currentUnixSeconds } from "../generalUtils"; +import { consoleLog, currentUnixSeconds } from "../generalUtils"; import { fromBaseUnit, fromBps, @@ -30,6 +30,7 @@ import { import { USD_DECIMALS } from "../../constants/generalAccounts"; import { RebalanceAction } from "../../types"; import { safeGetPrice } from "../priceUtils"; +import { TOKEN_INFO } from "../../constants"; function getAdditionalAmountToDcaIn(dca: DCASettings): number { if (dca.dcaInBaseUnit === BigInt(0)) { @@ -232,20 +233,14 @@ export function getRebalanceValues( ? "boost" : "repay", rebalanceDirection, - feesUsd: debtAdjustmentUsd * fromBps(adjustmentFeeBps), + feesUsd: Math.abs(debtAdjustmentUsd * fromBps(adjustmentFeeBps)), }; } -export interface FlashLoanDetails { - baseUnitAmount: bigint; - mint: PublicKey; -} - -export function getFlashLoanDetails( +export function rebalanceRequiresFlashLoan( client: SolautoClient, - values: RebalanceValues, - jupQuote: QuoteResponse -): FlashLoanDetails | undefined { + values: RebalanceValues +) { let supplyUsd = fromBaseUnit( client.solautoPositionState!.supply.amountUsed.baseAmountUsdValue, @@ -272,18 +267,58 @@ export function getFlashLoanDetails( debtUsd, client.solautoPositionState!.liqThresholdBps ); + const maxLiqUtilizationRateBps = getMaxLiqUtilizationRateBps( + client.solautoPositionState!.maxLtvBps, + client.solautoPositionState!.liqThresholdBps, + 0.02 + ); const requiresFlashLoan = - supplyUsd <= 0 || - tempLiqUtilizationRateBps > - getMaxLiqUtilizationRateBps( - client.solautoPositionState!.maxLtvBps, - client.solautoPositionState!.liqThresholdBps, - 0.015 - ); + supplyUsd <= 0 || tempLiqUtilizationRateBps > maxLiqUtilizationRateBps; + + consoleLog("Requires flash loan:", requiresFlashLoan); + consoleLog( + "Intermediary liq utilization rate:", + tempLiqUtilizationRateBps, + `$${supplyUsd}`, + `$${debtUsd}`, + "Max:", + maxLiqUtilizationRateBps + ); + + const useDebtLiquidity = + Math.abs(values.debtAdjustmentUsd) * 1.1 <= + fromBaseUnit( + client.solautoPositionState?.debt.amountCanBeUsed.baseAmountUsdValue ?? + BigInt(0), + USD_DECIMALS + ); + return { requiresFlashLoan, useDebtLiquidity }; +} + +export interface FlashLoanDetails { + baseUnitAmount: bigint; + mint: PublicKey; + useDebtLiquidity: boolean; +} + +export function getFlashLoanDetails( + client: SolautoClient, + values: RebalanceValues, + jupQuote: QuoteResponse +): FlashLoanDetails | undefined { + const { requiresFlashLoan, useDebtLiquidity } = rebalanceRequiresFlashLoan( + client, + values + ); let flashLoanToken: PositionTokenUsage | undefined = undefined; let flashLoanTokenPrice = 0; - if (values.rebalanceDirection === RebalanceDirection.Boost) { + + const inAmount = BigInt(parseInt(jupQuote.inAmount)); + const outAmount = BigInt(parseInt(jupQuote.outAmount)); + + const boosting = values.rebalanceDirection === RebalanceDirection.Boost; + if (boosting || useDebtLiquidity) { flashLoanToken = client.solautoPositionState!.debt; flashLoanTokenPrice = safeGetPrice(client.debtMint)!; } else { @@ -291,20 +326,18 @@ export function getFlashLoanDetails( flashLoanTokenPrice = safeGetPrice(client.supplyMint)!; } - const exactAmountBaseUnit = - jupQuote.swapMode === "ExactOut" || jupQuote.swapMode === "ExactIn" - ? BigInt(parseInt(jupQuote.inAmount)) - : undefined; + if (jupQuote.swapMode !== "ExactOut" && jupQuote.swapMode !== "ExactIn") { + throw new Error("Token ledger swap not currently supported"); + } + + const baseUnitAmount = + boosting || (!boosting && !useDebtLiquidity) ? inAmount : outAmount; return requiresFlashLoan ? { - baseUnitAmount: exactAmountBaseUnit - ? exactAmountBaseUnit - : toBaseUnit( - debtAdjustmentUsdAbs / flashLoanTokenPrice, - flashLoanToken.decimals - ), + baseUnitAmount, mint: toWeb3JsPublicKey(flashLoanToken.mint), + useDebtLiquidity, } : undefined; } @@ -344,17 +377,34 @@ export function getJupSwapRebalanceDetails( ) : toBaseUnit(usdToSwap / safeGetPrice(output.mint)!, output.decimals); + const repaying = values.rebalanceDirection === RebalanceDirection.Repay; + + const { requiresFlashLoan, useDebtLiquidity } = rebalanceRequiresFlashLoan( + client, + values + ); + const flashLoanRepayFromDebt = + repaying && requiresFlashLoan && useDebtLiquidity; + const exactOut = - targetLiqUtilizationRateBps === 0 || values.repayingCloseToMaxLtv; + targetLiqUtilizationRateBps === 0 || + values.repayingCloseToMaxLtv || + flashLoanRepayFromDebt; const exactIn = !exactOut; + // const addPadding = targetLiqUtilizationRateBps === 0; + const addPadding = exactOut; + return { inputMint: toWeb3JsPublicKey(input.mint), outputMint: toWeb3JsPublicKey(output.mint), - destinationWallet: client.solautoPosition, - slippageIncFactor: 0.5 + (attemptNum ?? 0) * 0.2, + destinationWallet: flashLoanRepayFromDebt + ? toWeb3JsPublicKey(client.signer.publicKey) + : client.solautoPosition, + slippageIncFactor: 0.2 + (attemptNum ?? 0) * 0.25, amount: exactOut ? outputAmount : inputAmount, exactIn: exactIn, exactOut: exactOut, + addPadding, }; } diff --git a/solauto-sdk/src/utils/switchboardUtils.ts b/solauto-sdk/src/utils/switchboardUtils.ts index 3cca6c85..f0e5adea 100644 --- a/solauto-sdk/src/utils/switchboardUtils.ts +++ b/solauto-sdk/src/utils/switchboardUtils.ts @@ -6,7 +6,7 @@ import { Transaction, VersionedTransaction, } from "@solana/web3.js"; -import { CrossbarClient, PullFeed } from "@switchboard-xyz/on-demand"; +import * as OnDemand from "@switchboard-xyz/on-demand"; import { SWITCHBOARD_PRICE_FEED_IDS } from "../constants/switchboardConstants"; import { TransactionItemInputs } from "../types"; import { Signer, transactionBuilder } from "@metaplex-foundation/umi"; @@ -37,6 +37,7 @@ export function getPullFeed( ); const program = new Program(switchboardIdl as Idl, provider); + const { PullFeed } = OnDemand; return new PullFeed( program, new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()]) @@ -48,7 +49,9 @@ export async function buildSwbSubmitResponseTx( signer: Signer, mint: PublicKey ): Promise { - const crossbar = new CrossbarClient("https://crossbar.switchboard.xyz"); + const { CrossbarClient } = OnDemand; + + const crossbar = CrossbarClient.default(); const feed = getPullFeed(conn, mint, toWeb3JsPublicKey(signer.publicKey)); const [pullIx, responses] = await retryWithExponentialBackoff( async () => diff --git a/solauto-sdk/tests/transactions/solautoMarginfi.ts b/solauto-sdk/tests/transactions/solautoMarginfi.ts index ee5f2062..c9c8552c 100644 --- a/solauto-sdk/tests/transactions/solautoMarginfi.ts +++ b/solauto-sdk/tests/transactions/solautoMarginfi.ts @@ -1,5 +1,9 @@ import { describe, it } from "mocha"; -import { none, publicKey, some } from "@metaplex-foundation/umi"; +import { + none, + publicKey, + some, +} from "@metaplex-foundation/umi"; import { setupTest } from "../shared"; import { SolautoMarginfiClient } from "../../src/clients/solautoMarginfiClient"; import { @@ -9,7 +13,6 @@ import { } from "../../src/generated"; import { buildSolautoRebalanceTransaction } from "../../src/transactions/transactionUtils"; import { - getLiqUtilzationRateBps, maxBoostToBps, maxRepayFromBps, maxRepayToBps, @@ -26,20 +29,24 @@ import { SOLAUTO_TEST_PROGRAM, USDC, } from "../../src/constants"; -import { buildHeliusApiUrl } from "../../src/utils"; +import { + buildHeliusApiUrl, + getSolautoManagedPositions, +} from "../../src/utils"; import { PriorityFeeSetting } from "../../src/types"; +import { buildIronforgeApiUrl } from "../../dist"; describe("Solauto Marginfi tests", async () => { - const signer = setupTest(); - // const signer = setupTest("solauto-manager"); + // const signer = setupTest(); + const signer = setupTest("solauto-manager"); const payForTransactions = false; - const testProgram = true; + const testProgram = false; const positionId = 1; it("open - deposit - borrow - rebalance to 0 - withdraw - close", async () => { const client = new SolautoMarginfiClient( - buildHeliusApiUrl(process.env.HELIUS_API_KEY!), + buildIronforgeApiUrl(process.env.IRONFORGE_API_KEY!), true, testProgram ? SOLAUTO_TEST_PROGRAM : SOLAUTO_PROD_PROGRAM ); @@ -51,16 +58,18 @@ describe("Solauto Marginfi tests", async () => { await client.initialize({ signer, positionId, - authority: new PublicKey("rC5dMP5dmSsfQ66rynzfFzuc122Eex9h1RJHVDkeH6D"), + authority: new PublicKey("He4ka5Q3N1UvZikZvykdi47xyk5PoVP2tcQL5sVp31Sz"), // new: true, // marginfiAccount: new PublicKey( - // "4nNvUXF5YqHFcH2nGweSiuvy1ct7V5FXfoCLKFYUN36z" + // "" // ), - // marginfiGroup: new PublicKey("G1rt3EpQ43K3bY457rhukQGRAo2QxydFAGRKqnjKzyr5"), - // supplyMint: new PublicKey("3B5wuUrMEi5yATD7on46hKfej3pfmd7t1RKgrsN3pump"), + // marginfiGroup: new PublicKey(""), + // supplyMint: new PublicKey(""), // debtMint: new PublicKey(USDC), }); + // console.log(await getSolautoManagedPositions(client.umi)); + const transactionItems: TransactionItem[] = []; // const settingParams: SolautoSettingsParametersInpArgs = { // boostToBps: maxBoostToBps( @@ -159,7 +168,7 @@ describe("Solauto Marginfi tests", async () => { client, undefined, !payForTransactions ? "only-simulate" : "normal", - PriorityFeeSetting.Low, + PriorityFeeSetting.Min, true ).clientSend(transactionItems); From 8836b2d0d5b23259450e8c7e88ac21e7cb426a30 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Tue, 25 Feb 2025 15:54:17 -0500 Subject: [PATCH 02/88] lower fees --- programs/solauto/src/utils/solauto_utils.rs | 6 +++--- solauto-sdk/src/utils/numberUtils.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/programs/solauto/src/utils/solauto_utils.rs b/programs/solauto/src/utils/solauto_utils.rs index 919c1f19..3df6a523 100644 --- a/programs/solauto/src/utils/solauto_utils.rs +++ b/programs/solauto/src/utils/solauto_utils.rs @@ -313,9 +313,9 @@ impl SolautoFeesBps { } pub fn fetch_fees(&self, rebalance_direction: RebalanceDirection) -> FeePayout { let min_size: f64 = 10000.0; // Minimum position size - let max_size: f64 = 500000.0; // Maximum position size - let max_fee_bps: f64 = 200.0; // Fee in basis points for min_size (2%) - let min_fee_bps: f64 = 50.0; // Fee in basis points for max_size (0.5%) + let max_size: f64 = 250000.0; // Maximum position size + let max_fee_bps: f64 = 50.0; // Fee in basis points for min_size (0.5%) + let min_fee_bps: f64 = 25.0; // Fee in basis points for max_size (0.25%) let k = 1.5; let mut fee_bps: f64; diff --git a/solauto-sdk/src/utils/numberUtils.ts b/solauto-sdk/src/utils/numberUtils.ts index 8196f007..0b8e4153 100644 --- a/solauto-sdk/src/utils/numberUtils.ts +++ b/solauto-sdk/src/utils/numberUtils.ts @@ -104,9 +104,9 @@ export function getSolautoFeesBps( total: number; } { const minSize = 10_000; // Minimum position size - const maxSize = 500_000; // Maximum position size - const maxFeeBps = 200; // Fee in basis points for minSize (2%) - const minFeeBps = 50; // Fee in basis points for maxSize (0.5%) + const maxSize = 250_000; // Maximum position size + const maxFeeBps = 50; // Fee in basis points for minSize (0.5%) + const minFeeBps = 25; // Fee in basis points for maxSize (0.25%) const k = 1.5; if ( From cf89d10fba98fcd993813537cd0f3cdb212a829a Mon Sep 17 00:00:00 2001 From: Mitchell <33007416+cheliosooo@users.noreply.github.com> Date: Sun, 27 Apr 2025 16:30:53 -0400 Subject: [PATCH 03/88] Refactor & robustness improvements (#10) - Refactored & cleaned up all rebalancing logic throughout the program & SDK - Added tests for rebalancing logic covering all rebalance cases - Added support for future features like TP/SL, DCA, limit orders, etc. - Cleaned up lots of SDK utils into isolated services - Separated out flash loan logic - Added new transaction tests in SDK - Other minor fixes & improvements - Supported some new breaking changes from marginfi program --- LICENSE | 11 + README.md | 148 +- SECURITY.md | 0 generateClients.cjs | 5 + idls/marginfi.json | 269 ++- .../solauto_v0_333450043.json | 1688 ++++++++++++++ idls/pyth.json | 104 + idls/solauto.json | 467 ++-- package.json | 31 +- pnpm-lock.yaml | 673 ++++-- .../src/generated/errors/marginfi.rs | 199 +- .../instructions/lending_account_borrow.rs | 4 +- .../lending_account_close_balance.rs | 4 +- .../instructions/lending_account_deposit.rs | 22 +- .../lending_account_end_flashloan.rs | 4 +- .../instructions/lending_account_liquidate.rs | 4 +- .../instructions/lending_account_repay.rs | 4 +- .../lending_account_settle_emissions.rs | 4 +- .../lending_account_start_flashloan.rs | 4 +- .../instructions/lending_account_withdraw.rs | 6 +- .../lending_account_withdraw_emissions.rs | 4 +- .../lending_pool_accrue_bank_interest.rs | 4 +- .../instructions/lending_pool_add_bank.rs | 4 +- .../lending_pool_add_bank_with_seed.rs | 4 +- .../lending_pool_collect_bank_fees.rs | 4 +- .../lending_pool_configure_bank.rs | 4 +- .../lending_pool_handle_bankruptcy.rs | 4 +- .../lending_pool_setup_emissions.rs | 4 +- ...ending_pool_update_emissions_parameters.rs | 4 +- .../marginfi_account_initialize.rs | 4 +- .../instructions/marginfi_group_configure.rs | 4 +- .../instructions/marginfi_group_initialize.rs | 4 +- .../instructions/set_account_flag.rs | 4 +- .../instructions/set_new_account_authority.rs | 4 +- .../instructions/unset_account_flag.rs | 4 +- .../generated/types/interest_rate_config.rs | 4 +- .../generated/accounts/solauto_position.rs | 2 +- .../src/generated/errors/solauto.rs | 42 +- .../instructions/claim_referral_fees.rs | 63 +- .../generated/instructions/close_position.rs | 44 +- .../instructions/marginfi_open_position.rs | 18 - .../instructions/marginfi_rebalance.rs | 76 +- .../instructions/marginfi_refresh_data.rs | 53 +- .../solauto-sdk/src/generated/types/mod.rs | 18 +- .../src/generated/types/position_data.rs | 17 +- .../src/generated/types/position_state.rs | 8 +- ...token_usage.rs => position_token_state.rs} | 9 +- .../src/generated/types/price_type.rs | 19 + .../src/generated/types/rebalance_data.rs | 13 +- .../generated/types/rebalance_direction.rs | 1 + .../types/rebalance_instruction_data.rs | 23 + .../generated/types/rebalance_state_values.rs | 22 + .../src/generated/types/rebalance_step.rs | 19 + .../generated/types/solauto_rebalance_type.rs | 1 - .../types/solauto_settings_parameters.rs | 6 +- .../types/solauto_settings_parameters_inp.rs | 3 - .../src/generated/types/swap_type.rs | 19 + .../generated/types/token_balance_change.rs | 18 + .../types/token_balance_change_type.rs | 22 + .../generated/types/update_position_data.rs | 2 +- programs/solauto-sdk/tests/close_position.rs | 21 +- programs/solauto-sdk/tests/general.rs | 103 +- .../tests/marginfi_open_position.rs | 61 +- .../tests/marginfi_protocol_interaction.rs | 2 +- programs/solauto-sdk/tests/test_utils.rs | 43 +- programs/solauto-sdk/tests/update_position.rs | 41 +- .../tests/update_referral_states.rs | 2 +- programs/solauto/README.md | 38 +- programs/solauto/src/clients/marginfi.rs | 213 +- programs/solauto/src/constants.rs | 27 +- programs/solauto/src/entrypoint.rs | 4 +- .../src/instructions/close_position.rs | 14 +- .../solauto/src/instructions/open_position.rs | 11 +- .../solauto/src/instructions/rebalance.rs | 123 +- .../solauto/src/instructions/referral_fees.rs | 42 +- programs/solauto/src/instructions/refresh.rs | 7 +- .../src/instructions/update_position.rs | 68 +- programs/solauto/src/lib.rs | 2 + programs/solauto/src/macros.rs | 52 + programs/solauto/src/processors/marginfi.rs | 58 +- programs/solauto/src/processors/position.rs | 59 +- .../solauto/src/processors/referral_state.rs | 135 +- programs/solauto/src/rebalance/mod.rs | 4 + programs/solauto/src/rebalance/rebalancer.rs | 502 +++++ .../solauto/src/rebalance/rebalancer_tests.rs | 838 +++++++ .../solauto/src/rebalance/solauto_fees.rs | 100 + programs/solauto/src/rebalance/utils.rs | 172 ++ programs/solauto/src/state/automation.rs | 180 ++ programs/solauto/src/state/mod.rs | 1 + .../solauto/src/state/solauto_position.rs | 418 ++-- programs/solauto/src/types/errors.rs | 42 + programs/solauto/src/types/instruction.rs | 27 +- programs/solauto/src/types/mod.rs | 2 + programs/solauto/src/types/shared.rs | 149 +- programs/solauto/src/types/solauto.rs | 35 + programs/solauto/src/types/solauto_manager.rs | 513 ++--- programs/solauto/src/utils/ix_utils.rs | 291 +-- programs/solauto/src/utils/math_utils.rs | 316 ++- programs/solauto/src/utils/mod.rs | 1 - programs/solauto/src/utils/rebalance_utils.rs | 869 -------- programs/solauto/src/utils/solana_utils.rs | 53 +- programs/solauto/src/utils/solauto_utils.rs | 242 +- .../solauto/src/utils/validation_utils.rs | 521 ++--- solauto-sdk/README.md | 104 +- solauto-sdk/local/createISMAccounts.ts | 59 - solauto-sdk/local/createTokenAccounts.ts | 19 +- solauto-sdk/local/logPositions.ts | 190 +- solauto-sdk/local/shared.ts | 65 +- solauto-sdk/local/txSandbox.ts | 116 + solauto-sdk/local/updateMarginfiLUT.ts | 109 +- solauto-sdk/local/updateSolautoLUT.ts | 32 +- solauto-sdk/package.json | 14 +- solauto-sdk/pnpm-lock.yaml | 345 +-- solauto-sdk/src/clients/index.ts | 4 - .../src/clients/solautoMarginfiClient.ts | 732 ------- solauto-sdk/src/clients/txHandler.ts | 36 - solauto-sdk/src/constants/README.md | 7 - ...generalAccounts.ts => generalConstants.ts} | 7 +- solauto-sdk/src/constants/index.ts | 11 +- solauto-sdk/src/constants/marginfiAccounts.ts | 129 +- solauto-sdk/src/constants/pythConstants.ts | 8 + solauto-sdk/src/constants/solautoConstants.ts | 37 +- .../src/constants/switchboardConstants.ts | 43 +- solauto-sdk/src/constants/tokenConstants.ts | 12 +- .../src/generated/accounts/solautoPosition.ts | 4 +- solauto-sdk/src/generated/errors/solauto.ts | 137 +- .../instructions/claimReferralFees.ts | 2 +- .../generated/instructions/closePosition.ts | 6 +- .../instructions/marginfiOpenPosition.ts | 7 - .../instructions/marginfiRebalance.ts | 21 +- .../instructions/marginfiRefreshData.ts | 34 +- solauto-sdk/src/generated/types/index.ts | 9 +- .../src/generated/types/positionData.ts | 35 +- .../src/generated/types/positionState.ts | 24 +- ...ionTokenUsage.ts => positionTokenState.ts} | 29 +- solauto-sdk/src/generated/types/priceType.ts | 22 + .../src/generated/types/rebalanceData.ts | 43 +- .../src/generated/types/rebalanceDirection.ts | 1 + .../types/rebalanceInstructionData.ts | 62 + .../generated/types/rebalanceStateValues.ts | 59 + .../src/generated/types/rebalanceStep.ts | 25 + .../generated/types/solautoRebalanceType.ts | 1 - .../types/solautoSettingsParameters.ts | 29 +- .../types/solautoSettingsParametersInp.ts | 26 +- solauto-sdk/src/generated/types/swapType.ts | 22 + .../src/generated/types/tokenBalanceChange.ts | 46 + .../generated/types/tokenBalanceChangeType.ts | 28 + .../src/generated/types/updatePositionData.ts | 6 +- solauto-sdk/src/idls/switchboard.json | 1950 ++++++++++++++++- solauto-sdk/src/index.ts | 19 +- .../src/marginfi-sdk/errors/marginfi.ts | 705 ++++-- .../instructions/lendingAccountDeposit.ts | 7 + .../marginfi-sdk/types/interestRateConfig.ts | 8 +- .../src/marginfi-sdk/types/oracleSetup.ts | 1 + solauto-sdk/src/pyth-sdk/accounts/index.ts | 9 + .../pyth-sdk/accounts/priceUpdateV2Account.ts | 179 ++ solauto-sdk/src/pyth-sdk/index.ts | 10 + solauto-sdk/src/pyth-sdk/types/index.ts | 10 + .../src/pyth-sdk/types/priceMessage.ts | 58 + .../src/pyth-sdk/types/priceUpdateV2.ts | 46 + .../flashLoans/flProviderAggregator.ts | 87 + .../src/services/flashLoans/flProviderBase.ts | 92 + solauto-sdk/src/services/flashLoans/index.ts | 3 + .../services/flashLoans/marginfiFlProvider.ts | 363 +++ solauto-sdk/src/services/index.ts | 5 + solauto-sdk/src/services/rebalance/index.ts | 3 + .../rebalance/rebalanceSwapManager.ts | 291 +++ .../services/rebalance/rebalanceTxBuilder.ts | 427 ++++ .../src/services/rebalance/rebalanceValues.ts | 253 +++ .../src/services/rebalance/solautoFees.ts | 69 + solauto-sdk/src/services/solauto/index.ts | 4 + .../solauto}/referralStateManager.ts | 61 +- .../solauto}/solautoClient.ts | 412 ++-- .../services/solauto/solautoMarginfiClient.ts | 477 ++++ solauto-sdk/src/services/solauto/txHandler.ts | 70 + solauto-sdk/src/services/swap/index.ts | 1 + .../src/services/swap/jupSwapManager.ts | 206 ++ .../src/services/transactions/index.ts | 3 + .../manager/clientTransactionsManager.ts | 141 ++ .../services/transactions/manager/index.ts | 2 + .../manager}/transactionsManager.ts | 570 ++--- .../transactions/transactionUtils.ts | 416 +--- .../src/services/transactions/types/index.ts | 3 + .../transactions/types/lookupTables.ts | 37 + .../transactions/types/transactionItem.ts | 43 + .../transactions/types/transactionSet.ts | 114 + solauto-sdk/src/solautoPosition/index.ts | 3 + .../marginfiSolautoPositionEx.ts | 171 ++ .../src/solautoPosition/positionUtils.ts | 206 ++ .../src/solautoPosition/solautoPositionEx.ts | 531 +++++ solauto-sdk/src/transactions/index.ts | 2 - solauto-sdk/src/types/accounts.ts | 1 - solauto-sdk/src/types/solauto.ts | 41 +- solauto-sdk/src/utils/generalUtils.ts | 116 +- solauto-sdk/src/utils/index.ts | 22 +- solauto-sdk/src/utils/instructionUtils.ts | 187 ++ solauto-sdk/src/utils/jitoUtils.ts | 238 +- solauto-sdk/src/utils/jupiterUtils.ts | 167 +- .../{marginfiUtils.ts => marginfi/data.ts} | 389 ++-- solauto-sdk/src/utils/marginfi/general.ts | 226 ++ solauto-sdk/src/utils/marginfi/index.ts | 2 + solauto-sdk/src/utils/numberUtils.ts | 205 +- solauto-sdk/src/utils/priceUtils.ts | 239 +- solauto-sdk/src/utils/pythUtils.ts | 37 + solauto-sdk/src/utils/solanaUtils.ts | 228 +- solauto-sdk/src/utils/solauto/index.ts | 2 - .../src/utils/solauto/rebalanceUtils.ts | 410 ---- .../generalUtils.ts => solautoUtils.ts} | 393 +--- solauto-sdk/src/utils/stringUtils.ts | 72 + solauto-sdk/src/utils/switchboardUtils.ts | 64 +- solauto-sdk/tests/transactions/shared.ts | 89 + .../tests/transactions/solautoMarginfi.ts | 180 +- solauto-sdk/tests/unit/accounts.ts | 54 +- solauto-sdk/tests/unit/lookupTables.ts | 70 +- .../tests/unit/rebalanceCalculations.ts | 432 +--- 215 files changed, 17070 insertions(+), 8254 deletions(-) create mode 100644 LICENSE delete mode 100644 SECURITY.md create mode 100644 idls/past-idl-versions/solauto_v0_333450043.json create mode 100644 idls/pyth.json rename programs/solauto-sdk/src/generated/types/{position_token_usage.rs => position_token_state.rs} (87%) create mode 100644 programs/solauto-sdk/src/generated/types/price_type.rs create mode 100644 programs/solauto-sdk/src/generated/types/rebalance_instruction_data.rs create mode 100644 programs/solauto-sdk/src/generated/types/rebalance_state_values.rs create mode 100644 programs/solauto-sdk/src/generated/types/rebalance_step.rs create mode 100644 programs/solauto-sdk/src/generated/types/swap_type.rs create mode 100644 programs/solauto-sdk/src/generated/types/token_balance_change.rs create mode 100644 programs/solauto-sdk/src/generated/types/token_balance_change_type.rs create mode 100644 programs/solauto/src/macros.rs create mode 100644 programs/solauto/src/rebalance/mod.rs create mode 100644 programs/solauto/src/rebalance/rebalancer.rs create mode 100644 programs/solauto/src/rebalance/rebalancer_tests.rs create mode 100644 programs/solauto/src/rebalance/solauto_fees.rs create mode 100644 programs/solauto/src/rebalance/utils.rs create mode 100644 programs/solauto/src/state/automation.rs create mode 100644 programs/solauto/src/types/errors.rs create mode 100644 programs/solauto/src/types/solauto.rs delete mode 100644 programs/solauto/src/utils/rebalance_utils.rs delete mode 100644 solauto-sdk/local/createISMAccounts.ts create mode 100644 solauto-sdk/local/txSandbox.ts delete mode 100644 solauto-sdk/src/clients/index.ts delete mode 100644 solauto-sdk/src/clients/solautoMarginfiClient.ts delete mode 100644 solauto-sdk/src/clients/txHandler.ts delete mode 100644 solauto-sdk/src/constants/README.md rename solauto-sdk/src/constants/{generalAccounts.ts => generalConstants.ts} (53%) rename solauto-sdk/src/generated/types/{positionTokenUsage.ts => positionTokenState.ts} (72%) create mode 100644 solauto-sdk/src/generated/types/priceType.ts create mode 100644 solauto-sdk/src/generated/types/rebalanceInstructionData.ts create mode 100644 solauto-sdk/src/generated/types/rebalanceStateValues.ts create mode 100644 solauto-sdk/src/generated/types/rebalanceStep.ts create mode 100644 solauto-sdk/src/generated/types/swapType.ts create mode 100644 solauto-sdk/src/generated/types/tokenBalanceChange.ts create mode 100644 solauto-sdk/src/generated/types/tokenBalanceChangeType.ts create mode 100644 solauto-sdk/src/pyth-sdk/accounts/index.ts create mode 100644 solauto-sdk/src/pyth-sdk/accounts/priceUpdateV2Account.ts create mode 100644 solauto-sdk/src/pyth-sdk/index.ts create mode 100644 solauto-sdk/src/pyth-sdk/types/index.ts create mode 100644 solauto-sdk/src/pyth-sdk/types/priceMessage.ts create mode 100644 solauto-sdk/src/pyth-sdk/types/priceUpdateV2.ts create mode 100644 solauto-sdk/src/services/flashLoans/flProviderAggregator.ts create mode 100644 solauto-sdk/src/services/flashLoans/flProviderBase.ts create mode 100644 solauto-sdk/src/services/flashLoans/index.ts create mode 100644 solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts create mode 100644 solauto-sdk/src/services/index.ts create mode 100644 solauto-sdk/src/services/rebalance/index.ts create mode 100644 solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts create mode 100644 solauto-sdk/src/services/rebalance/rebalanceTxBuilder.ts create mode 100644 solauto-sdk/src/services/rebalance/rebalanceValues.ts create mode 100644 solauto-sdk/src/services/rebalance/solautoFees.ts create mode 100644 solauto-sdk/src/services/solauto/index.ts rename solauto-sdk/src/{clients => services/solauto}/referralStateManager.ts (81%) rename solauto-sdk/src/{clients => services/solauto}/solautoClient.ts (52%) create mode 100644 solauto-sdk/src/services/solauto/solautoMarginfiClient.ts create mode 100644 solauto-sdk/src/services/solauto/txHandler.ts create mode 100644 solauto-sdk/src/services/swap/index.ts create mode 100644 solauto-sdk/src/services/swap/jupSwapManager.ts create mode 100644 solauto-sdk/src/services/transactions/index.ts create mode 100644 solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts create mode 100644 solauto-sdk/src/services/transactions/manager/index.ts rename solauto-sdk/src/{transactions => services/transactions/manager}/transactionsManager.ts (52%) rename solauto-sdk/src/{ => services}/transactions/transactionUtils.ts (65%) create mode 100644 solauto-sdk/src/services/transactions/types/index.ts create mode 100644 solauto-sdk/src/services/transactions/types/lookupTables.ts create mode 100644 solauto-sdk/src/services/transactions/types/transactionItem.ts create mode 100644 solauto-sdk/src/services/transactions/types/transactionSet.ts create mode 100644 solauto-sdk/src/solautoPosition/index.ts create mode 100644 solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts create mode 100644 solauto-sdk/src/solautoPosition/positionUtils.ts create mode 100644 solauto-sdk/src/solautoPosition/solautoPositionEx.ts delete mode 100644 solauto-sdk/src/transactions/index.ts create mode 100644 solauto-sdk/src/utils/instructionUtils.ts rename solauto-sdk/src/utils/{marginfiUtils.ts => marginfi/data.ts} (60%) create mode 100644 solauto-sdk/src/utils/marginfi/general.ts create mode 100644 solauto-sdk/src/utils/marginfi/index.ts create mode 100644 solauto-sdk/src/utils/pythUtils.ts delete mode 100644 solauto-sdk/src/utils/solauto/index.ts delete mode 100644 solauto-sdk/src/utils/solauto/rebalanceUtils.ts rename solauto-sdk/src/utils/{solauto/generalUtils.ts => solautoUtils.ts} (53%) create mode 100644 solauto-sdk/src/utils/stringUtils.ts create mode 100644 solauto-sdk/tests/transactions/shared.ts diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..2175c7c3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,11 @@ +Copyright 2025 Haven. All rights reserved. + +This source code is made publicly available for transparency, educational, and auditing purposes only. + +You may view and modify the code for personal or internal use. +You may **not** copy, redistribute, or use this code, in whole or in part, for any commercial purpose. + +Unauthorized commercial use or redistribution is strictly prohibited. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. diff --git a/README.md b/README.md index 5e81b39c..848249f5 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ # Solauto -Solauto is a program on the Solana blockchain that lets you manage leveraged longs & shorts on auto-pilot to maximize your gains and eliminate the risk of liquidation. +## Overview -[Go to program documentation](/programs/solauto) +Solauto is a program on the Solana blockchain that lets you manage leveraged longs & shorts on auto-pilot to maximize your gains and eliminate the risk of liquidation. +See the [Program documentation](/programs/solauto/README.md) for more info on the underlying Solana program. ### Repository Dependencies @@ -16,4 +17,145 @@ rustup component add rustfmt pnpm install -g ts-node ``` -Define `HELIUS_API_KEY` environment variable \ No newline at end of file +Define `IRONFORGE_API_KEY` environment variable for running package tests/scripts locally. + +### Building + +```bash +# Build typescript +pnpm build:ts + +# Build Solauto test program +pnpm build:rs:test + +# Build Solauto prod program +pnpm build:rs:prod +``` + +### Testing + +```bash +# If running rust tests, build program first +pnpm build:rs:local + +# Run all rust & typescript tests +pnpm test:all + +# Run all rust tests +pnpm test:rs:all + +# Run all typescript tests +pnpm test:ts:all +``` + +## Solauto Typescript SDK + +The Solauto typescript SDK is made for interacting with the Solauto program. This SDK provides tools for managing, & reading Solauto state data, as well as executing transactions. + +```bash +npm install @haven-fi/solauto-sdk +# or +yarn add @haven-fi/solauto-sdk +# or +pnpm add @haven-fi/solauto-sdk +``` + +## Basic Usage + +```typescript +import { PublicKey } from "@solana/web3.js"; +import * as solauto from "@haven-fi/solauto-sdk"; + +// Create new Solauto client +const client = solauto.getClient(solauto.LendingPlatform.MARGINFI, { + signer: yourSigner, + rpcUrl: "[YOUR_RPC_URL]", +}); + +// Initialize the client +const supplyMint = new PublicKey(NATIVE_MINT); +const debtMint = new PublicKey(USDC); +await client.initializeNewSolautoPosition({ + positionId: 1, + lpPoolAccount: solauto.getMarginfiAccounts().defaultGroup, + supplyMint, + debtMint, +}); + +// Open a position with custom settings +const [maxLtvBps, liqThresholdBps] = + await client.pos.maxLtvAndLiqThresholdBps(); +const settings: solauto.SolautoSettingsParametersInpArgs = { + boostToBps: solauto.maxBoostToBps(maxLtvBps, liqThresholdBps), + boostGap: 50, + repayToBps: solauto.maxRepayToBps(maxLtvBps, liqThresholdBps), + repayGap: 50, +}; + +const supplyUsdToDeposit = 100; +const debtUsdToBorrow = 60; +const [supplyPrice, debtPrice] = await solauto.fetchTokenPrices([ + supplyMint, + debtMint, +]); + +const transactionItems = [ + // Open position + solauto.openSolautoPosition(client, settings), + // Deposit supply (SOL) transaction + solauto.deposit( + client, + toBaseUnit( + supplyUsdToDeposit / supplyPrice, + client.pos.supplyMintInfo.decimals + ) + ), + // Borrow debt (USDC) transaction + solauto.borrow( + client, + toBaseUnit(debtUsdToBorrow / debtPrice, client.pos.debtMintInfo.decimals) + ), + // Rebalance to 0 LTV (repays all debt using collateral) + solauto.rebalance(client, 0), + // Withdraw remaining supply in position + solauto.withdraw(client, "All"), + // Close position + solauto.closeSolautoPosition(client), +]; + +// Send all transactions atomically +const txManager = await new solauto.ClientTransactionsManager({ + txHandler: client, +}); +const statuses = txManager.send(transactionItems); +``` + +## Rebalancing an existing position + +```typescript +import { PublicKey } from "@solana/web3.js"; +import * as solauto from "@haven-fi/solauto-sdk"; + +// Create new Solauto client +const client = solauto.getClient(solauto.LendingPlatform.MARGINFI, { + signer: yourSigner, + rpcUrl: "[YOUR_RPC_URL]", +}); + +// Initialize the client +await client.initializeExistingSolautoPosition({ + positionId: myPositionId, +}); + +const transactionItems = [ + solauto.rebalance( + client, + undefined // Provide target liquidation utilization rate if you want a specific LTV, otherwise it will rebalance according to position's settings (default) + ), +]; + +const txManager = await new solauto.ClientTransactionsManager({ + txHandler: client, +}); +const statuses = txManager.send(transactionItems); +``` diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index e69de29b..00000000 diff --git a/generateClients.cjs b/generateClients.cjs index 8f72e429..bb81b02c 100644 --- a/generateClients.cjs +++ b/generateClients.cjs @@ -113,4 +113,9 @@ generateSolautoSDK(); // "jupiter.json", // "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4" // ); +// generateTypescriptSDKForAnchorIDL( +// "pyth-sdk", +// "pyth.json", +// "pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT" +// ); // cleanJupiterTsSDK(["programs", "errors", "index.ts"]); diff --git a/idls/marginfi.json b/idls/marginfi.json index 3d182d26..ce043b18 100644 --- a/idls/marginfi.json +++ b/idls/marginfi.json @@ -803,6 +803,12 @@ { "name": "amount", "type": "u64" + }, + { + "name": "deposit_up_to_limit", + "type": { + "option": "bool" + } } ] }, @@ -3059,8 +3065,8 @@ "errors": [ { "code": 6000, - "name": "MathError", - "msg": "Math error" + "name": "InternalLogicError", + "msg": "Internal Marginfi logic error" }, { "code": 6001, @@ -3085,7 +3091,7 @@ { "code": 6005, "name": "MissingPythOrBankAccount", - "msg": "Missing Pyth or Bank account" + "msg": "Missing Oracle, Bank, LST mint, or Sol Pool" }, { "code": 6006, @@ -3094,188 +3100,343 @@ }, { "code": 6007, - "name": "InvalidOracleAccount", - "msg": "Invalid Pyth account" - }, - { - "code": 6008, "name": "MissingBankAccount", "msg": "Missing Bank account" }, { - "code": 6009, + "code": 6008, "name": "InvalidBankAccount", "msg": "Invalid Bank account" }, { - "code": 6010, - "name": "BadAccountHealth", - "msg": "Bad account health" + "code": 6009, + "name": "RiskEngineInitRejected", + "msg": "RiskEngine rejected due to either bad health or stale oracles" }, { - "code": 6011, + "code": 6010, "name": "LendingAccountBalanceSlotsFull", "msg": "Lending account balance slots are full" }, { - "code": 6012, + "code": 6011, "name": "BankAlreadyExists", "msg": "Bank already exists" }, { - "code": 6013, - "name": "IllegalLiquidation", - "msg": "Illegal liquidation" + "code": 6012, + "name": "ZeroLiquidationAmount", + "msg": "Amount to liquidate must be positive" }, { - "code": 6014, + "code": 6013, "name": "AccountNotBankrupt", "msg": "Account is not bankrupt" }, { - "code": 6015, + "code": 6014, "name": "BalanceNotBadDebt", "msg": "Account balance is not bad debt" }, { - "code": 6016, + "code": 6015, "name": "InvalidConfig", "msg": "Invalid group config" }, { - "code": 6017, - "name": "StaleOracle", - "msg": "Stale oracle data" - }, - { - "code": 6018, + "code": 6016, "name": "BankPaused", "msg": "Bank paused" }, { - "code": 6019, + "code": 6017, "name": "BankReduceOnly", "msg": "Bank is ReduceOnly mode" }, { - "code": 6020, - "name": "BankAccoutNotFound", + "code": 6018, + "name": "BankAccountNotFound", "msg": "Bank is missing" }, { - "code": 6021, + "code": 6019, "name": "OperationDepositOnly", "msg": "Operation is deposit-only" }, { - "code": 6022, + "code": 6020, "name": "OperationWithdrawOnly", "msg": "Operation is withdraw-only" }, { - "code": 6023, + "code": 6021, "name": "OperationBorrowOnly", "msg": "Operation is borrow-only" }, { - "code": 6024, + "code": 6022, "name": "OperationRepayOnly", "msg": "Operation is repay-only" }, { - "code": 6025, + "code": 6023, "name": "NoAssetFound", "msg": "No asset found" }, { - "code": 6026, + "code": 6024, "name": "NoLiabilityFound", "msg": "No liability found" }, { - "code": 6027, + "code": 6025, "name": "InvalidOracleSetup", "msg": "Invalid oracle setup" }, { - "code": 6028, + "code": 6026, "name": "IllegalUtilizationRatio", "msg": "Invalid bank utilization ratio" }, { - "code": 6029, + "code": 6027, "name": "BankLiabilityCapacityExceeded", "msg": "Bank borrow cap exceeded" }, { - "code": 6030, + "code": 6028, "name": "InvalidPrice", "msg": "Invalid Price" }, { - "code": 6031, + "code": 6029, "name": "IsolatedAccountIllegalState", - "msg": "Account can have only one liablity when account is under isolated risk" + "msg": "Account can have only one liability when account is under isolated risk" }, { - "code": 6032, + "code": 6030, "name": "EmissionsAlreadySetup", "msg": "Emissions already setup" }, { - "code": 6033, + "code": 6031, "name": "OracleNotSetup", "msg": "Oracle is not set" }, { - "code": 6034, + "code": 6032, "name": "InvalidSwitchboardDecimalConversion", - "msg": "Invalid swithcboard decimal conversion" + "msg": "Invalid switchboard decimal conversion" }, { - "code": 6035, + "code": 6033, "name": "CannotCloseOutstandingEmissions", "msg": "Cannot close balance because of outstanding emissions" }, { - "code": 6036, + "code": 6034, "name": "EmissionsUpdateError", "msg": "Update emissions error" }, { - "code": 6037, + "code": 6035, "name": "AccountDisabled", "msg": "Account disabled" }, { - "code": 6038, + "code": 6036, "name": "AccountTempActiveBalanceLimitExceeded", "msg": "Account can't temporarily open 3 balances, please close a balance first" }, { - "code": 6039, + "code": 6037, "name": "AccountInFlashloan", "msg": "Illegal action during flashloan" }, { - "code": 6040, + "code": 6038, "name": "IllegalFlashloan", "msg": "Illegal flashloan" }, { - "code": 6041, + "code": 6039, "name": "IllegalFlag", "msg": "Illegal flag" }, { - "code": 6042, + "code": 6040, "name": "IllegalBalanceState", "msg": "Illegal balance state" }, { - "code": 6043, + "code": 6041, "name": "IllegalAccountAuthorityTransfer", "msg": "Illegal account authority transfer" + }, + { + "code": 6042, + "name": "Unauthorized", + "msg": "Unauthorized" + }, + { + "code": 6043, + "name": "IllegalAction", + "msg": "Invalid account authority" + }, + { + "code": 6044, + "name": "T22MintRequired", + "msg": "Token22 Banks require mint account as first remaining account" + }, + { + "code": 6045, + "name": "InvalidFeeAta", + "msg": "Invalid ATA for global fee account" + }, + { + "code": 6046, + "name": "AddedStakedPoolManually", + "msg": "Use add pool permissionless instead" + }, + { + "code": 6047, + "name": "AssetTagMismatch", + "msg": "Staked SOL accounts can only deposit staked assets and borrow SOL" + }, + { + "code": 6048, + "name": "StakePoolValidationFailed", + "msg": "Stake pool validation failed: check the stake pool, mint, or sol pool" + }, + { + "code": 6049, + "name": "SwitchboardStalePrice", + "msg": "Switchboard oracle: stale price" + }, + { + "code": 6050, + "name": "PythPushStalePrice", + "msg": "Pyth Push oracle: stale price" + }, + { + "code": 6051, + "name": "WrongNumberOfOracleAccounts", + "msg": "Oracle error: wrong number of accounts" + }, + { + "code": 6052, + "name": "WrongOracleAccountKeys", + "msg": "Oracle error: wrong account keys" + }, + { + "code": 6053, + "name": "PythPushWrongAccountOwner", + "msg": "Pyth Push oracle: wrong account owner" + }, + { + "code": 6054, + "name": "StakedPythPushWrongAccountOwner", + "msg": "Staked Pyth Push oracle: wrong account owner" + }, + { + "code": 6055, + "name": "PythPushMismatchedFeedId", + "msg": "Pyth Push oracle: mismatched feed id" + }, + { + "code": 6056, + "name": "PythPushInsufficientVerificationLevel", + "msg": "Pyth Push oracle: insufficient verification level" + }, + { + "code": 6057, + "name": "PythPushFeedIdMustBe32Bytes", + "msg": "Pyth Push oracle: feed id must be 32 Bytes" + }, + { + "code": 6058, + "name": "PythPushFeedIdNonHexCharacter", + "msg": "Pyth Push oracle: feed id contains non-hex characters" + }, + { + "code": 6059, + "name": "SwitchboardWrongAccountOwner", + "msg": "Switchboard oracle: wrong account owner" + }, + { + "code": 6060, + "name": "PythPushInvalidAccount", + "msg": "Pyth Push oracle: invalid account" + }, + { + "code": 6061, + "name": "SwitchboardInvalidAccount", + "msg": "Switchboard oracle: invalid account" + }, + { + "code": 6062, + "name": "MathError", + "msg": "Math error" + }, + { + "code": 6063, + "name": "InvalidEmissionsDestinationAccount", + "msg": "Invalid emissions destination account" + }, + { + "code": 6064, + "name": "SameAssetAndLiabilityBanks", + "msg": "Asset and liability bank cannot be the same" + }, + { + "code": 6065, + "name": "OverliquidationAttempt", + "msg": "Trying to withdraw more assets than available" + }, + { + "code": 6066, + "name": "NoLiabilitiesInLiabilityBank", + "msg": "Liability bank has no liabilities" + }, + { + "code": 6067, + "name": "AssetsInLiabilityBank", + "msg": "Liability bank has assets" + }, + { + "code": 6068, + "name": "HealthyAccount", + "msg": "Account is healthy and cannot be liquidated" + }, + { + "code": 6069, + "name": "ExhaustedLiability", + "msg": "Liability payoff too severe, exhausted liability" + }, + { + "code": 6070, + "name": "TooSeverePayoff", + "msg": "Liability payoff too severe, liability balance has assets" + }, + { + "code": 6071, + "name": "TooSevereLiquidation", + "msg": "Liquidation too severe, account above maintenance requirement" + }, + { + "code": 6072, + "name": "WorseHealthPostLiquidation", + "msg": "Liquidation would worsen account health" + }, + { + "code": 6073, + "name": "ArenaBankLimit", + "msg": "Arena groups can only support two banks" + }, + { + "code": 6074, + "name": "ArenaSettingCannotChange", + "msg": "Arena groups cannot return to non-arena status" } ], "metadata": { diff --git a/idls/past-idl-versions/solauto_v0_333450043.json b/idls/past-idl-versions/solauto_v0_333450043.json new file mode 100644 index 00000000..c8654f39 --- /dev/null +++ b/idls/past-idl-versions/solauto_v0_333450043.json @@ -0,0 +1,1688 @@ +{ + "version": "0.1.0", + "name": "solauto", + "instructions": [ + { + "name": "UpdateReferralStates", + "accounts": [ + { + "name": "signer", + "isMut": false, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "rent", + "isMut": false, + "isSigner": false + }, + { + "name": "signerReferralState", + "isMut": true, + "isSigner": false + }, + { + "name": "referredByState", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "referredByAuthority", + "isMut": false, + "isSigner": false, + "isOptional": true + } + ], + "args": [ + { + "name": "updateReferralStatesArgs", + "type": { + "defined": "UpdateReferralStatesArgs" + } + } + ], + "discriminant": { + "type": "u8", + "value": 0 + } + }, + { + "name": "ConvertReferralFees", + "accounts": [ + { + "name": "signer", + "isMut": false, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "ataProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "rent", + "isMut": false, + "isSigner": false + }, + { + "name": "ixsSysvar", + "isMut": false, + "isSigner": false + }, + { + "name": "referralState", + "isMut": false, + "isSigner": false + }, + { + "name": "referralFeesTa", + "isMut": true, + "isSigner": false + }, + { + "name": "intermediaryTa", + "isMut": true, + "isSigner": false + } + ], + "args": [], + "discriminant": { + "type": "u8", + "value": 1 + } + }, + { + "name": "ClaimReferralFees", + "accounts": [ + { + "name": "signer", + "isMut": false, + "isSigner": true + }, + { + "name": "signerWsolTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "ataProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "rent", + "isMut": false, + "isSigner": false + }, + { + "name": "referralState", + "isMut": false, + "isSigner": false + }, + { + "name": "referralFeesDestTa", + "isMut": true, + "isSigner": false + }, + { + "name": "referralFeesDestMint", + "isMut": false, + "isSigner": false + }, + { + "name": "referralAuthority", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "feesDestinationTa", + "isMut": true, + "isSigner": false, + "isOptional": true + } + ], + "args": [], + "discriminant": { + "type": "u8", + "value": 2 + } + }, + { + "name": "UpdatePosition", + "accounts": [ + { + "name": "signer", + "isMut": false, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "solautoPosition", + "isMut": true, + "isSigner": false + }, + { + "name": "dcaMint", + "isMut": false, + "isSigner": false, + "isOptional": true + }, + { + "name": "positionDcaTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "signerDcaTa", + "isMut": true, + "isSigner": false, + "isOptional": true + } + ], + "args": [ + { + "name": "updatePositionData", + "type": { + "defined": "UpdatePositionData" + } + } + ], + "discriminant": { + "type": "u8", + "value": 3 + } + }, + { + "name": "ClosePosition", + "accounts": [ + { + "name": "signer", + "isMut": false, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "ataProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "solautoPosition", + "isMut": true, + "isSigner": false + }, + { + "name": "protocolAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "positionSupplyTa", + "isMut": true, + "isSigner": false + }, + { + "name": "signerSupplyTa", + "isMut": true, + "isSigner": false + }, + { + "name": "positionDebtTa", + "isMut": true, + "isSigner": false + }, + { + "name": "signerDebtTa", + "isMut": true, + "isSigner": false + } + ], + "args": [], + "discriminant": { + "type": "u8", + "value": 4 + } + }, + { + "name": "CancelDCA", + "accounts": [ + { + "name": "signer", + "isMut": false, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "ataProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "solautoPosition", + "isMut": true, + "isSigner": false + }, + { + "name": "dcaMint", + "isMut": false, + "isSigner": false, + "isOptional": true + }, + { + "name": "positionDcaTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "signerDcaTa", + "isMut": true, + "isSigner": false, + "isOptional": true + } + ], + "args": [], + "discriminant": { + "type": "u8", + "value": 5 + } + }, + { + "name": "MarginfiOpenPosition", + "accounts": [ + { + "name": "signer", + "isMut": false, + "isSigner": true + }, + { + "name": "marginfiProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "ataProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "rent", + "isMut": false, + "isSigner": false + }, + { + "name": "signerReferralState", + "isMut": false, + "isSigner": false + }, + { + "name": "referredByState", + "isMut": false, + "isSigner": false, + "isOptional": true + }, + { + "name": "referredBySupplyTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "solautoPosition", + "isMut": true, + "isSigner": false + }, + { + "name": "marginfiGroup", + "isMut": false, + "isSigner": false + }, + { + "name": "marginfiAccount", + "isMut": true, + "isSigner": false, + "isOptionalSigner": true + }, + { + "name": "supplyMint", + "isMut": false, + "isSigner": false + }, + { + "name": "supplyBank", + "isMut": false, + "isSigner": false + }, + { + "name": "positionSupplyTa", + "isMut": true, + "isSigner": false + }, + { + "name": "debtMint", + "isMut": false, + "isSigner": false + }, + { + "name": "debtBank", + "isMut": false, + "isSigner": false + }, + { + "name": "positionDebtTa", + "isMut": true, + "isSigner": false + }, + { + "name": "signerDebtTa", + "isMut": true, + "isSigner": false, + "isOptional": true + } + ], + "args": [ + { + "name": "marginfiOpenPositionData", + "type": { + "defined": "MarginfiOpenPositionData" + } + } + ], + "discriminant": { + "type": "u8", + "value": 6 + } + }, + { + "name": "MarginfiRefreshData", + "accounts": [ + { + "name": "signer", + "isMut": false, + "isSigner": true + }, + { + "name": "marginfiProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "marginfiGroup", + "isMut": false, + "isSigner": false + }, + { + "name": "marginfiAccount", + "isMut": false, + "isSigner": false + }, + { + "name": "supplyBank", + "isMut": true, + "isSigner": false + }, + { + "name": "supplyPriceOracle", + "isMut": false, + "isSigner": false + }, + { + "name": "debtBank", + "isMut": true, + "isSigner": false + }, + { + "name": "debtPriceOracle", + "isMut": false, + "isSigner": false + }, + { + "name": "solautoPosition", + "isMut": true, + "isSigner": false + } + ], + "args": [], + "discriminant": { + "type": "u8", + "value": 7 + } + }, + { + "name": "MarginfiProtocolInteraction", + "accounts": [ + { + "name": "signer", + "isMut": false, + "isSigner": true + }, + { + "name": "marginfiProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "ataProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "rent", + "isMut": false, + "isSigner": false + }, + { + "name": "solautoPosition", + "isMut": true, + "isSigner": false + }, + { + "name": "marginfiGroup", + "isMut": false, + "isSigner": false + }, + { + "name": "marginfiAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "supplyBank", + "isMut": true, + "isSigner": false + }, + { + "name": "supplyPriceOracle", + "isMut": false, + "isSigner": false, + "isOptional": true + }, + { + "name": "positionSupplyTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "vaultSupplyTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "supplyVaultAuthority", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "debtBank", + "isMut": true, + "isSigner": false + }, + { + "name": "debtPriceOracle", + "isMut": false, + "isSigner": false, + "isOptional": true + }, + { + "name": "positionDebtTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "vaultDebtTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "debtVaultAuthority", + "isMut": true, + "isSigner": false, + "isOptional": true + } + ], + "args": [ + { + "name": "solautoAction", + "type": { + "defined": "SolautoAction" + } + } + ], + "discriminant": { + "type": "u8", + "value": 8 + } + }, + { + "name": "MarginfiRebalance", + "accounts": [ + { + "name": "signer", + "isMut": false, + "isSigner": true + }, + { + "name": "marginfiProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "ixsSysvar", + "isMut": false, + "isSigner": false + }, + { + "name": "solautoFeesTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "authorityReferralState", + "isMut": false, + "isSigner": false + }, + { + "name": "referredByTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "positionAuthority", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "solautoPosition", + "isMut": true, + "isSigner": false + }, + { + "name": "marginfiGroup", + "isMut": false, + "isSigner": false + }, + { + "name": "marginfiAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "intermediaryTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "supplyBank", + "isMut": true, + "isSigner": false + }, + { + "name": "supplyPriceOracle", + "isMut": false, + "isSigner": false, + "isOptional": true + }, + { + "name": "positionSupplyTa", + "isMut": true, + "isSigner": false + }, + { + "name": "authoritySupplyTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "vaultSupplyTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "supplyVaultAuthority", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "debtBank", + "isMut": true, + "isSigner": false + }, + { + "name": "debtPriceOracle", + "isMut": false, + "isSigner": false, + "isOptional": true + }, + { + "name": "positionDebtTa", + "isMut": true, + "isSigner": false + }, + { + "name": "authorityDebtTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "vaultDebtTa", + "isMut": true, + "isSigner": false, + "isOptional": true + }, + { + "name": "debtVaultAuthority", + "isMut": true, + "isSigner": false, + "isOptional": true + } + ], + "args": [ + { + "name": "rebalanceSettings", + "type": { + "defined": "RebalanceSettings" + } + } + ], + "discriminant": { + "type": "u8", + "value": 9 + } + } + ], + "accounts": [ + { + "name": "ReferralState", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bump", + "type": { + "array": [ + "u8", + 1 + ] + } + }, + { + "name": "padding1", + "type": { + "array": [ + "u8", + 7 + ] + } + }, + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "referredByState", + "type": "publicKey" + }, + { + "name": "destFeesMint", + "type": "publicKey" + }, + { + "name": "lookupTable", + "type": "publicKey" + }, + { + "name": "padding", + "type": { + "array": [ + "u8", + 96 + ] + } + } + ] + } + }, + { + "name": "SolautoPosition", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bump", + "type": { + "array": [ + "u8", + 1 + ] + } + }, + { + "name": "positionId", + "type": { + "array": [ + "u8", + 1 + ] + } + }, + { + "name": "selfManaged", + "type": { + "defined": "PodBool" + } + }, + { + "name": "positionType", + "type": { + "defined": "PositionType" + } + }, + { + "name": "padding1", + "type": { + "array": [ + "u8", + 4 + ] + } + }, + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "position", + "type": { + "defined": "PositionData" + } + }, + { + "name": "state", + "type": { + "defined": "PositionState" + } + }, + { + "name": "rebalance", + "type": { + "defined": "RebalanceData" + } + }, + { + "name": "padding", + "type": { + "array": [ + "u32", + 32 + ] + } + } + ] + } + } + ], + "types": [ + { + "name": "AutomationSettingsInp", + "type": { + "kind": "struct", + "fields": [ + { + "name": "targetPeriods", + "type": "u16" + }, + { + "name": "periodsPassed", + "type": "u16" + }, + { + "name": "unixStartDate", + "type": "u64" + }, + { + "name": "intervalSeconds", + "type": "u64" + } + ] + } + }, + { + "name": "AutomationSettings", + "type": { + "kind": "struct", + "fields": [ + { + "name": "targetPeriods", + "type": "u16" + }, + { + "name": "periodsPassed", + "type": "u16" + }, + { + "name": "padding1", + "type": { + "array": [ + "u8", + 4 + ] + } + }, + { + "name": "unixStartDate", + "type": "u64" + }, + { + "name": "intervalSeconds", + "type": "u64" + }, + { + "name": "padding", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, + { + "name": "TokenAmount", + "type": { + "kind": "struct", + "fields": [ + { + "name": "baseUnit", + "type": "u64" + }, + { + "name": "baseAmountUsdValue", + "type": "u64" + } + ] + } + }, + { + "name": "PositionTokenUsage", + "type": { + "kind": "struct", + "fields": [ + { + "name": "mint", + "type": "publicKey" + }, + { + "name": "decimals", + "type": "u8" + }, + { + "name": "padding1", + "type": { + "array": [ + "u8", + 7 + ] + } + }, + { + "name": "amountUsed", + "type": { + "defined": "TokenAmount" + } + }, + { + "name": "amountCanBeUsed", + "type": { + "defined": "TokenAmount" + } + }, + { + "name": "baseAmountMarketPriceUsd", + "type": "u64" + }, + { + "name": "flashLoanFeeBps", + "type": "u16" + }, + { + "name": "borrowFeeBps", + "type": "u16" + }, + { + "name": "padding2", + "type": { + "array": [ + "u8", + 4 + ] + } + }, + { + "name": "padding", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, + { + "name": "DCASettingsInp", + "type": { + "kind": "struct", + "fields": [ + { + "name": "automation", + "type": { + "defined": "AutomationSettingsInp" + } + }, + { + "name": "dcaInBaseUnit", + "type": "u64" + }, + { + "name": "tokenType", + "type": { + "defined": "TokenType" + } + } + ] + } + }, + { + "name": "DCASettings", + "type": { + "kind": "struct", + "fields": [ + { + "name": "automation", + "type": { + "defined": "AutomationSettings" + } + }, + { + "name": "dcaInBaseUnit", + "type": "u64" + }, + { + "name": "tokenType", + "type": { + "defined": "TokenType" + } + }, + { + "name": "padding", + "type": { + "array": [ + "u8", + 31 + ] + } + } + ] + } + }, + { + "name": "SolautoSettingsParametersInp", + "type": { + "kind": "struct", + "fields": [ + { + "name": "boostToBps", + "type": "u16" + }, + { + "name": "boostGap", + "type": "u16" + }, + { + "name": "repayToBps", + "type": "u16" + }, + { + "name": "repayGap", + "type": "u16" + }, + { + "name": "targetBoostToBps", + "type": { + "option": "u16" + } + }, + { + "name": "automation", + "type": { + "option": { + "defined": "AutomationSettingsInp" + } + } + } + ] + } + }, + { + "name": "SolautoSettingsParameters", + "type": { + "kind": "struct", + "fields": [ + { + "name": "boostToBps", + "type": "u16" + }, + { + "name": "boostGap", + "type": "u16" + }, + { + "name": "repayToBps", + "type": "u16" + }, + { + "name": "repayGap", + "type": "u16" + }, + { + "name": "targetBoostToBps", + "type": "u16" + }, + { + "name": "padding1", + "type": { + "array": [ + "u8", + 6 + ] + } + }, + { + "name": "automation", + "type": { + "defined": "AutomationSettings" + } + }, + { + "name": "padding", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, + { + "name": "PositionState", + "type": { + "kind": "struct", + "fields": [ + { + "name": "liqUtilizationRateBps", + "type": "u16" + }, + { + "name": "padding1", + "type": { + "array": [ + "u8", + 6 + ] + } + }, + { + "name": "netWorth", + "type": { + "defined": "TokenAmount" + } + }, + { + "name": "supply", + "type": { + "defined": "PositionTokenUsage" + } + }, + { + "name": "debt", + "type": { + "defined": "PositionTokenUsage" + } + }, + { + "name": "maxLtvBps", + "type": "u16" + }, + { + "name": "liqThresholdBps", + "type": "u16" + }, + { + "name": "padding2", + "type": { + "array": [ + "u8", + 4 + ] + } + }, + { + "name": "lastUpdated", + "type": "u64" + }, + { + "name": "padding", + "type": { + "array": [ + "u32", + 2 + ] + } + } + ] + } + }, + { + "name": "PositionData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "lendingPlatform", + "type": { + "defined": "LendingPlatform" + } + }, + { + "name": "padding1", + "type": { + "array": [ + "u8", + 7 + ] + } + }, + { + "name": "protocolUserAccount", + "type": "publicKey" + }, + { + "name": "protocolSupplyAccount", + "type": "publicKey" + }, + { + "name": "protocolDebtAccount", + "type": "publicKey" + }, + { + "name": "settingParams", + "type": { + "defined": "SolautoSettingsParameters" + } + }, + { + "name": "dca", + "type": { + "defined": "DCASettings" + } + }, + { + "name": "padding", + "type": { + "array": [ + "u32", + 4 + ] + } + } + ] + } + }, + { + "name": "RebalanceData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "rebalanceType", + "type": { + "defined": "SolautoRebalanceType" + } + }, + { + "name": "padding1", + "type": { + "array": [ + "u8", + 7 + ] + } + }, + { + "name": "rebalanceDirection", + "type": { + "defined": "RebalanceDirection" + } + }, + { + "name": "padding2", + "type": { + "array": [ + "u8", + 7 + ] + } + }, + { + "name": "flashLoanAmount", + "type": "u64" + }, + { + "name": "padding", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, + { + "name": "UpdateReferralStatesArgs", + "type": { + "kind": "struct", + "fields": [ + { + "name": "referralFeesDestMint", + "type": { + "option": "publicKey" + } + }, + { + "name": "addressLookupTable", + "type": { + "option": "publicKey" + } + } + ] + } + }, + { + "name": "MarginfiOpenPositionData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "positionType", + "type": { + "defined": "PositionType" + } + }, + { + "name": "positionData", + "type": { + "defined": "UpdatePositionData" + } + }, + { + "name": "marginfiAccountSeedIdx", + "type": { + "option": "u64" + } + } + ] + } + }, + { + "name": "UpdatePositionData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "positionId", + "type": "u8" + }, + { + "name": "settingParams", + "type": { + "option": { + "defined": "SolautoSettingsParametersInp" + } + } + }, + { + "name": "dca", + "type": { + "option": { + "defined": "DCASettingsInp" + } + } + } + ] + } + }, + { + "name": "RebalanceSettings", + "type": { + "kind": "struct", + "fields": [ + { + "name": "rebalanceType", + "type": { + "defined": "SolautoRebalanceType" + } + }, + { + "name": "targetLiqUtilizationRateBps", + "type": { + "option": "u16" + } + }, + { + "name": "targetInAmountBaseUnit", + "type": { + "option": "u64" + } + } + ] + } + }, + { + "name": "PodBool", + "type": { + "kind": "struct", + "fields": [ + { + "name": "val", + "type": "bool" + } + ] + } + }, + { + "name": "SolautoRebalanceType", + "type": { + "kind": "enum", + "variants": [ + { + "name": "None" + }, + { + "name": "Regular" + }, + { + "name": "DoubleRebalanceWithFL" + }, + { + "name": "FLSwapThenRebalance" + }, + { + "name": "FLRebalanceThenSwap" + } + ] + } + }, + { + "name": "SolautoAction", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Deposit", + "fields": [ + "u64" + ] + }, + { + "name": "Borrow", + "fields": [ + "u64" + ] + }, + { + "name": "Repay", + "fields": [ + { + "defined": "TokenBalanceAmount" + } + ] + }, + { + "name": "Withdraw", + "fields": [ + { + "defined": "TokenBalanceAmount" + } + ] + } + ] + } + }, + { + "name": "LendingPlatform", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Marginfi" + } + ] + } + }, + { + "name": "PositionType", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Leverage" + }, + { + "name": "SafeLoan" + } + ] + } + }, + { + "name": "TokenType", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Supply" + }, + { + "name": "Debt" + } + ] + } + }, + { + "name": "RebalanceDirection", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Boost" + }, + { + "name": "Repay" + } + ] + } + }, + { + "name": "TokenBalanceAmount", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Some", + "fields": [ + "u64" + ] + }, + { + "name": "All" + } + ] + } + } + ], + "errors": [ + { + "code": 0, + "name": "IncorrectAccounts", + "msg": "Missing or incorrect accounts provided for the given instruction" + }, + { + "code": 1, + "name": "FailedAccountDeserialization", + "msg": "Failed to deserialize account data" + }, + { + "code": 2, + "name": "InvalidPositionSettings", + "msg": "Invalid position settings provided" + }, + { + "code": 3, + "name": "InvalidDCASettings", + "msg": "Invalid DCA configuration provided" + }, + { + "code": 4, + "name": "InvalidAutomationData", + "msg": "Invalid automation settings provided" + }, + { + "code": 5, + "name": "InvalidRebalanceCondition", + "msg": "Invalid position condition to rebalance" + }, + { + "code": 6, + "name": "InstructionIsCPI", + "msg": "Unable to invoke instruction through a CPI" + }, + { + "code": 7, + "name": "IncorrectInstructions", + "msg": "Incorrect set of instructions in the transaction" + }, + { + "code": 8, + "name": "IncorrectDebtAdjustment", + "msg": "Incorrect swap amount provided. Likely due to high price volatility" + } + ], + "metadata": { + "origin": "shank", + "address": "AutoyKBRaHSBHy9RsmXCZMy6nNFAg5FYijrvZyQcNLV" + } +} \ No newline at end of file diff --git a/idls/pyth.json b/idls/pyth.json new file mode 100644 index 00000000..06ebf4f1 --- /dev/null +++ b/idls/pyth.json @@ -0,0 +1,104 @@ +{ + "address": "pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT", + "instructions": [], + "accounts": [ + { + "name": "PriceUpdateV2Account", + "type": { + "kind": "struct", + "fields": [ + { + "name": "writeAuthority", + "type": "publicKey" + }, + { + "name": "verificationLevel", + "type": "u8" + }, + { + "name": "priceMessage", + "type": { + "defined": "PriceMessage" + } + }, + { + "name": "postedSlot", + "type": "u64" + } + ] + } + } + ], + "types": [ + { + "name": "PriceMessage", + "type": { + "kind": "struct", + "fields": [ + { + "name": "feedId", + "type": "publicKey" + }, + { + "name": "price", + "type": "i64" + }, + { + "name": "conf", + "type": "u64" + }, + { + "name": "exponent", + "type": "i32" + }, + { + "name": "publishTime", + "type": "i64" + }, + { + "name": "prevPublishTime", + "type": "i64" + }, + { + "name": "emaPrice", + "type": "i64" + }, + { + "name": "emaConf", + "type": "u64" + } + ] + } + }, + { + "name": "PriceUpdateV2", + "type": { + "kind": "struct", + "fields": [ + { + "name": "writeAuthority", + "type": "publicKey" + }, + { + "name": "verificationLevel", + "type": "u8" + }, + { + "name": "priceMessage", + "type": { + "defined": "PriceMessage" + } + }, + { + "name": "postedSlot", + "type": "u64" + } + ] + } + } + ], + "metadata": { + "origin": "anchor", + "address": "pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT" + } +} \ No newline at end of file diff --git a/idls/solauto.json b/idls/solauto.json index c8654f39..eff84e1c 100644 --- a/idls/solauto.json +++ b/idls/solauto.json @@ -158,8 +158,7 @@ { "name": "referralAuthority", "isMut": true, - "isSigner": false, - "isOptional": true + "isSigner": false }, { "name": "feesDestinationTa", @@ -258,7 +257,7 @@ "isSigner": false }, { - "name": "protocolAccount", + "name": "lpUserAccount", "isMut": true, "isSigner": false }, @@ -507,7 +506,14 @@ "isSigner": false } ], - "args": [], + "args": [ + { + "name": "priceType", + "type": { + "defined": "PriceType" + } + } + ], "discriminant": { "type": "u8", "value": 7 @@ -911,7 +917,7 @@ "type": { "array": [ "u32", - 32 + 20 ] } } @@ -987,74 +993,48 @@ } }, { - "name": "TokenAmount", + "name": "DCASettingsInp", "type": { "kind": "struct", "fields": [ { - "name": "baseUnit", - "type": "u64" + "name": "automation", + "type": { + "defined": "AutomationSettingsInp" + } }, { - "name": "baseAmountUsdValue", + "name": "dcaInBaseUnit", "type": "u64" + }, + { + "name": "tokenType", + "type": { + "defined": "TokenType" + } } ] } }, { - "name": "PositionTokenUsage", + "name": "DCASettings", "type": { "kind": "struct", "fields": [ { - "name": "mint", - "type": "publicKey" - }, - { - "name": "decimals", - "type": "u8" - }, - { - "name": "padding1", - "type": { - "array": [ - "u8", - 7 - ] - } - }, - { - "name": "amountUsed", - "type": { - "defined": "TokenAmount" - } - }, - { - "name": "amountCanBeUsed", + "name": "automation", "type": { - "defined": "TokenAmount" + "defined": "AutomationSettings" } }, { - "name": "baseAmountMarketPriceUsd", + "name": "dcaInBaseUnit", "type": "u64" }, { - "name": "flashLoanFeeBps", - "type": "u16" - }, - { - "name": "borrowFeeBps", - "type": "u16" - }, - { - "name": "padding2", + "name": "tokenType", "type": { - "array": [ - "u8", - 4 - ] + "defined": "TokenType" } }, { @@ -1062,7 +1042,7 @@ "type": { "array": [ "u8", - 32 + 31 ] } } @@ -1070,48 +1050,70 @@ } }, { - "name": "DCASettingsInp", + "name": "TokenAmount", "type": { "kind": "struct", "fields": [ { - "name": "automation", - "type": { - "defined": "AutomationSettingsInp" - } - }, - { - "name": "dcaInBaseUnit", + "name": "baseUnit", "type": "u64" }, { - "name": "tokenType", - "type": { - "defined": "TokenType" - } + "name": "baseAmountUsdValue", + "type": "u64" } ] } }, { - "name": "DCASettings", + "name": "PositionTokenState", "type": { "kind": "struct", "fields": [ { - "name": "automation", + "name": "mint", + "type": "publicKey" + }, + { + "name": "decimals", + "type": "u8" + }, + { + "name": "padding1", "type": { - "defined": "AutomationSettings" + "array": [ + "u8", + 5 + ] } }, { - "name": "dcaInBaseUnit", + "name": "borrowFeeBps", + "type": "u16" + }, + { + "name": "amountUsed", + "type": { + "defined": "TokenAmount" + } + }, + { + "name": "amountCanBeUsed", + "type": { + "defined": "TokenAmount" + } + }, + { + "name": "baseAmountMarketPriceUsd", "type": "u64" }, { - "name": "tokenType", + "name": "padding2", "type": { - "defined": "TokenType" + "array": [ + "u8", + 8 + ] } }, { @@ -1119,7 +1121,7 @@ "type": { "array": [ "u8", - 31 + 32 ] } } @@ -1146,20 +1148,6 @@ { "name": "repayGap", "type": "u16" - }, - { - "name": "targetBoostToBps", - "type": { - "option": "u16" - } - }, - { - "name": "automation", - "type": { - "option": { - "defined": "AutomationSettingsInp" - } - } } ] } @@ -1185,31 +1173,12 @@ "name": "repayGap", "type": "u16" }, - { - "name": "targetBoostToBps", - "type": "u16" - }, - { - "name": "padding1", - "type": { - "array": [ - "u8", - 6 - ] - } - }, - { - "name": "automation", - "type": { - "defined": "AutomationSettings" - } - }, { "name": "padding", "type": { "array": [ - "u8", - 32 + "u32", + 24 ] } } @@ -1243,13 +1212,13 @@ { "name": "supply", "type": { - "defined": "PositionTokenUsage" + "defined": "PositionTokenState" } }, { "name": "debt", "type": { - "defined": "PositionTokenUsage" + "defined": "PositionTokenState" } }, { @@ -1270,7 +1239,7 @@ } }, { - "name": "lastUpdated", + "name": "lastRefreshed", "type": "u64" }, { @@ -1306,35 +1275,33 @@ } }, { - "name": "protocolUserAccount", + "name": "lpUserAccount", "type": "publicKey" }, { - "name": "protocolSupplyAccount", + "name": "lpSupplyAccount", "type": "publicKey" }, { - "name": "protocolDebtAccount", + "name": "lpDebtAccount", "type": "publicKey" }, { - "name": "settingParams", + "name": "settings", "type": { "defined": "SolautoSettingsParameters" } }, { - "name": "dca", - "type": { - "defined": "DCASettings" - } + "name": "lpPoolAccount", + "type": "publicKey" }, { "name": "padding", "type": { "array": [ "u32", - 4 + 20 ] } } @@ -1342,14 +1309,14 @@ } }, { - "name": "RebalanceData", + "name": "TokenBalanceChange", "type": { "kind": "struct", "fields": [ { - "name": "rebalanceType", + "name": "changeType", "type": { - "defined": "SolautoRebalanceType" + "defined": "TokenBalanceChangeType" } }, { @@ -1361,6 +1328,18 @@ ] } }, + { + "name": "amountUsd", + "type": "u64" + } + ] + } + }, + { + "name": "RebalanceStateValues", + "type": { + "kind": "struct", + "fields": [ { "name": "rebalanceDirection", "type": { @@ -1368,7 +1347,7 @@ } }, { - "name": "padding2", + "name": "padding1", "type": { "array": [ "u8", @@ -1377,15 +1356,102 @@ } }, { - "name": "flashLoanAmount", + "name": "targetSupplyUsd", "type": "u64" }, + { + "name": "targetDebtUsd", + "type": "u64" + }, + { + "name": "tokenBalanceChange", + "type": { + "defined": "TokenBalanceChange" + } + }, { "name": "padding", + "type": { + "array": [ + "u32", + 4 + ] + } + } + ] + } + }, + { + "name": "RebalanceInstructionData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "active", + "type": { + "defined": "PodBool" + } + }, + { + "name": "rebalanceType", + "type": { + "defined": "SolautoRebalanceType" + } + }, + { + "name": "swapType", + "type": { + "defined": "SwapType" + } + }, + { + "name": "padding1", "type": { "array": [ "u8", - 32 + 5 + ] + } + }, + { + "name": "flashLoanAmount", + "type": "u64" + }, + { + "name": "padding", + "type": { + "array": [ + "u32", + 4 + ] + } + } + ] + } + }, + { + "name": "RebalanceData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "ixs", + "type": { + "defined": "RebalanceInstructionData" + } + }, + { + "name": "values", + "type": { + "defined": "RebalanceStateValues" + } + }, + { + "name": "padding", + "type": { + "array": [ + "u32", + 4 ] } } @@ -1428,12 +1494,6 @@ "type": { "defined": "UpdatePositionData" } - }, - { - "name": "marginfiAccountSeedIdx", - "type": { - "option": "u64" - } } ] } @@ -1448,7 +1508,7 @@ "type": "u8" }, { - "name": "settingParams", + "name": "settings", "type": { "option": { "defined": "SolautoSettingsParametersInp" @@ -1477,6 +1537,12 @@ "defined": "SolautoRebalanceType" } }, + { + "name": "swapInAmountBaseUnit", + "type": { + "option": "u64" + } + }, { "name": "targetLiqUtilizationRateBps", "type": { @@ -1484,9 +1550,25 @@ } }, { - "name": "targetInAmountBaseUnit", + "name": "flashLoanFeeBps", "type": { - "option": "u64" + "option": "u16" + } + }, + { + "name": "priceType", + "type": { + "option": { + "defined": "PriceType" + } + } + }, + { + "name": "swapType", + "type": { + "option": { + "defined": "SwapType" + } } } ] @@ -1505,7 +1587,7 @@ } }, { - "name": "SolautoRebalanceType", + "name": "TokenBalanceChangeType", "type": { "kind": "enum", "variants": [ @@ -1513,16 +1595,16 @@ "name": "None" }, { - "name": "Regular" + "name": "PreSwapDeposit" }, { - "name": "DoubleRebalanceWithFL" + "name": "PostSwapDeposit" }, { - "name": "FLSwapThenRebalance" + "name": "PostRebalanceWithdrawSupplyToken" }, { - "name": "FLRebalanceThenSwap" + "name": "PostRebalanceWithdrawDebtToken" } ] } @@ -1607,6 +1689,9 @@ "type": { "kind": "enum", "variants": [ + { + "name": "None" + }, { "name": "Boost" }, @@ -1616,6 +1701,54 @@ ] } }, + { + "name": "RebalanceStep", + "type": { + "kind": "enum", + "variants": [ + { + "name": "PreSwap" + }, + { + "name": "PostSwap" + } + ] + } + }, + { + "name": "SolautoRebalanceType", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Regular" + }, + { + "name": "DoubleRebalanceWithFL" + }, + { + "name": "FLSwapThenRebalance" + }, + { + "name": "FLRebalanceThenSwap" + } + ] + } + }, + { + "name": "SwapType", + "type": { + "kind": "enum", + "variants": [ + { + "name": "ExactIn" + }, + { + "name": "ExactOut" + } + ] + } + }, { "name": "TokenBalanceAmount", "type": { @@ -1632,13 +1765,27 @@ } ] } + }, + { + "name": "PriceType", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Realtime" + }, + { + "name": "Ema" + } + ] + } } ], "errors": [ { "code": 0, "name": "IncorrectAccounts", - "msg": "Missing or incorrect accounts provided for the given instruction" + "msg": "Missing or incorrect accounts provided for the given instructions" }, { "code": 1, @@ -1647,38 +1794,68 @@ }, { "code": 2, - "name": "InvalidPositionSettings", - "msg": "Invalid position settings provided" + "name": "InvalidBoostToSetting", + "msg": "Invalid Boost-to param" }, { "code": 3, + "name": "InvalidBoostGapSetting", + "msg": "Invalid Boost gap param" + }, + { + "code": 4, + "name": "InvalidRepayToSetting", + "msg": "Invalid repay-to param" + }, + { + "code": 5, + "name": "InvalidRepayGapSetting", + "msg": "Invalid repay gap param" + }, + { + "code": 6, + "name": "InvalidRepayFromSetting", + "msg": "Invalid repay-from (repay-to + repay gap)" + }, + { + "code": 7, "name": "InvalidDCASettings", "msg": "Invalid DCA configuration provided" }, { - "code": 4, + "code": 8, "name": "InvalidAutomationData", "msg": "Invalid automation settings provided" }, { - "code": 5, + "code": 9, "name": "InvalidRebalanceCondition", "msg": "Invalid position condition to rebalance" }, { - "code": 6, + "code": 10, "name": "InstructionIsCPI", "msg": "Unable to invoke instruction through a CPI" }, { - "code": 7, + "code": 11, "name": "IncorrectInstructions", - "msg": "Incorrect set of instructions in the transaction" + "msg": "Incorrect set of instructions or instruction data in the transaction" }, { - "code": 8, + "code": 12, "name": "IncorrectDebtAdjustment", "msg": "Incorrect swap amount provided. Likely due to high price volatility" + }, + { + "code": 13, + "name": "InvalidRebalanceMade", + "msg": "Invalid rebalance was made. Target supply USD and target debt USD was not met" + }, + { + "code": 14, + "name": "NonAuthorityProvidedTargetLTV", + "msg": "Cannot provide a target liquidation utilization rate if the instruction is not signed by the position authority" } ], "metadata": { diff --git a/package.json b/package.json index bff6dd7f..1095f5da 100644 --- a/package.json +++ b/package.json @@ -4,30 +4,37 @@ "format:rust": "find ./programs/* -name '*.rs' -exec rustfmt {} +", "build:rs:local": "cargo build-sbf -- --package solauto --features local", "build:rs:test": "cargo build-sbf -- --package solauto --features test", - "build:rs:prod": "cargo build-sbf", + "build:rs:prod": "solana-verify build --library-name solauto --base-image solanafoundation/solana-verifiable-build@sha256:f3d3a4adaa8008644fc4535373c6818275c7e35a0b07660890b4a95ef434221e", "build:ts": "cd solauto-sdk && npm run build", - "deploy:buffer": "solana program write-buffer target/deploy/solauto.so --buffer ~/.config/solana/buffer.json --max-sign-attempts 50", - "deploy:rs:test": "solana program deploy target/deploy/solauto.so --keypair ~/.config/solana/solauto-auth.json --program-id TesTjfQ6TbXv96Tv6fqr95XTZ1LYPxtkafmShN9PjBp --use-rpc --buffer ~/.config/solana/buffer.json --max-sign-attempts 50", + "deploy:buffer": "solana program write-buffer target/deploy/solauto.so --use-rpc --max-sign-attempts 50 --with-compute-unit-price 0.00001", + "deploy:rs:test": "solana program deploy target/deploy/solauto.so --program-id TesTjfQ6TbXv96Tv6fqr95XTZ1LYPxtkafmShN9PjBp --use-rpc --buffer ~/.config/solana/buffer.json --max-sign-attempts 50", "deploy:ts": "cd solauto-sdk && npm publish", "generate": "pnpm generate:idl && pnpm generate:clients", - "generate:idl": "shank idl --crate-root programs/solauto --out-dir idls --out-filename solauto.json", + "generate:idl": "shank idl --crate-root programs/solauto --out-dir idls --out-filename solauto.json -p AutoyKBRaHSBHy9RsmXCZMy6nNFAg5FYijrvZyQcNLV", "generate:clients": "node ./generateClients.cjs && pnpm format:rust", - "test:rs:unit": "cargo test --package solauto -- --nocapture", - "test:rs:solana": "cd programs/solauto-sdk && cargo test-sbf", - "test:rs:all": "pnpm test:rs:unit && pnpm test:rs:solana", + "test:all": "pnpm build:rs:local && pnpm test:rs:all && pnpm test:ts:all", + "test:rs:unit": "cargo test --package solauto", + "test:rs:txs": "cd programs/solauto-sdk && cargo test-sbf", + "test:rs:all": "pnpm test:rs:txs && pnpm test:rs:unit", "test:ts:unit": "cd solauto-sdk && pnpm test:unit", "test:ts:txs": "cd solauto-sdk && pnpm test:txs", "test:ts:all": "cd solauto-sdk && pnpm test:all", - "solana-verify": "solana-verify verify-from-repo --remote -um --program-id AutoyKBRaHSBHy9RsmXCZMy6nNFAg5FYijrvZyQcNLV https://github.com/haven-fi/solauto --library-name solauto --base-image solanafoundation/solana-verifiable-build@sha256:f3d3a4adaa8008644fc4535373c6818275c7e35a0b07660890b4a95ef434221e", + "export-pda-tx": "solana-verify export-pda-tx https://github.com/haven-fi/solauto --program-id AutoyKBRaHSBHy9RsmXCZMy6nNFAg5FYijrvZyQcNLV --uploader B1ZqSSiAe7DKjh444gkxXAgoeyz2dZzBMwziBtt8mJ3T --encoding base58 --compute-unit-price 0 --library-name solauto --base-image solanafoundation/solana-verifiable-build@sha256:f3d3a4adaa8008644fc4535373c6818275c7e35a0b07660890b4a95ef434221e", + "verify-submit-job": "solana-verify remote submit-job --program-id AutoyKBRaHSBHy9RsmXCZMy6nNFAg5FYijrvZyQcNLV --uploader B1ZqSSiAe7DKjh444gkxXAgoeyz2dZzBMwziBtt8mJ3T", + "solana-verify": "solana-verify verify-from-repo --remote -um --skip-build --program-id AutoyKBRaHSBHy9RsmXCZMy6nNFAg5FYijrvZyQcNLV https://github.com/haven-fi/solauto --library-name solauto --base-image solanafoundation/solana-verifiable-build@sha256:f3d3a4adaa8008644fc4535373c6818275c7e35a0b07660890b4a95ef434221e", + "sandbox": "cd solauto-sdk && npx ts-node local/txSandbox.ts", "update-lut:solauto": "cd solauto-sdk && npx ts-node local/updateSolautoLUT.ts", "update-lut:marginfi": "cd solauto-sdk && npx ts-node local/updateMarginfiLUT.ts", "create-token-accounts": "cd solauto-sdk && npx ts-node local/createTokenAccounts.ts", - "create-ism-accounts": "cd solauto-sdk && npx ts-node local/createISMAccounts.ts", - "prepare-accounts": "pnpm create-token-accounts && pnpm create-ism-accounts && pnpm update-lut:solauto && pnpm update-lut:marginfi", - "log-positions": "cd solauto-sdk && npx ts-node local/logPositions.ts" + "prepare-accounts": "pnpm create-token-accounts && pnpm update-lut:solauto && pnpm update-lut:marginfi", + "log-pos": "cd solauto-sdk && npx ts-node local/logPositions.ts", + "log-pos:test": "cd solauto-sdk && npx ts-node local/logPositions.ts --filter=false --env=Staging" }, "dependencies": { - "@metaplex-foundation/kinobi": "^0.18.5" + "@metaplex-foundation/kinobi": "^0.18.5", + "@mrgnlabs/marginfi-client-v2": "^6.0.1", + "@mrgnlabs/mrgn-common": "^2.0.2", + "borsh": "^2.0.0" }, "devDependencies": { "solauto-sdk": "file:solauto-sdk", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1ac11634..4a9acb1a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,15 @@ dependencies: '@metaplex-foundation/kinobi': specifier: ^0.18.5 version: 0.18.5(fastestsmallesttextencoderdecoder@1.0.22) + '@mrgnlabs/marginfi-client-v2': + specifier: ^6.0.1 + version: 6.0.1 + '@mrgnlabs/mrgn-common': + specifier: ^2.0.2 + version: 2.0.2 + borsh: + specifier: ^2.0.0 + version: 2.0.0 devDependencies: solauto-sdk: @@ -24,7 +33,6 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.1 - dev: true /@brokerloop/ttlcache@3.2.3: resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} @@ -32,10 +40,38 @@ packages: '@soncodi/signal': 2.0.7 dev: true + /@common.js/quick-lru@7.0.0: + resolution: {integrity: sha512-DO3vApnH1vLizdWRSqzhg+S956vptHhtO+vw6PP6StJGDtaAGyfKSSPPGYWguJZu/Jlti6l6m6jB8NrKEQexLg==} + engines: {node: '>=18'} + dev: false + /@coral-xyz/anchor-errors@0.30.1: resolution: {integrity: sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==} engines: {node: '>=10'} - dev: true + + /@coral-xyz/anchor@0.29.0: + resolution: {integrity: sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==} + engines: {node: '>=11'} + dependencies: + '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.95.4) + '@noble/hashes': 1.5.0 + '@solana/web3.js': 1.95.4 + bn.js: 5.2.1 + bs58: 4.0.1 + buffer-layout: 1.2.2 + camelcase: 6.3.0 + cross-fetch: 3.1.8 + crypto-hash: 1.3.0 + eventemitter3: 4.0.7 + pako: 2.1.0 + snake-case: 3.0.4 + superstruct: 0.15.5 + toml: 3.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false /@coral-xyz/anchor@0.30.1: resolution: {integrity: sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==} @@ -60,7 +96,17 @@ packages: - bufferutil - encoding - utf-8-validate - dev: true + + /@coral-xyz/borsh@0.29.0(@solana/web3.js@1.95.4): + resolution: {integrity: sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + dependencies: + '@solana/web3.js': 1.95.4 + bn.js: 5.2.1 + buffer-layout: 1.2.2 + dev: false /@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.4): resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} @@ -71,10 +117,32 @@ packages: '@solana/web3.js': 1.95.4 bn.js: 5.2.1 buffer-layout: 1.2.2 - dev: true - /@jup-ag/api@6.0.29: - resolution: {integrity: sha512-1gUY1txmL/gG14VDZMjeKVqhSzeg4L2cImdC7dGLYB5DP5D5lwpR+FarvhqehEi+63/RWOUKTTU4fablGpeIUQ==} + /@grpc/grpc-js@1.13.2: + resolution: {integrity: sha512-nnR5nmL6lxF8YBqb6gWvEgLdLh/Fn+kvAdX5hUOnt48sNSb0riz/93ASd2E5gvanPA41X6Yp25bIfGRp1SMb2g==} + engines: {node: '>=12.10.0'} + dependencies: + '@grpc/proto-loader': 0.7.13 + '@js-sdsl/ordered-map': 4.4.2 + dev: false + + /@grpc/proto-loader@0.7.13: + resolution: {integrity: sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==} + engines: {node: '>=6'} + hasBin: true + dependencies: + lodash.camelcase: 4.3.0 + long: 5.2.3 + protobufjs: 7.4.0 + yargs: 17.7.2 + dev: false + + /@js-sdsl/ordered-map@4.4.2: + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + dev: false + + /@jup-ag/api@6.0.24: + resolution: {integrity: sha512-zIX4WIPb0Kb2UnK2wNIOQBWqPJyMJq/D9dQTf/2qvPb0hfa8XdgbrQAzomHMHnAzw9StMQoybBk+JK/A76xP3w==} dev: true /@metaplex-foundation/beet-solana@0.4.0: @@ -120,7 +188,7 @@ packages: - fastestsmallesttextencoderdecoder dev: false - /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4): + /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-kV3tfvgvRjVP1p9OFOtH+ibOtN9omVJSwKr0We4/9r45e5LTj+32su0V/rixZUkG1EZzzOYBsxhtIE0kIw/Hrw==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 @@ -128,14 +196,14 @@ packages: dependencies: '@metaplex-foundation/umi': 0.9.2 '@metaplex-foundation/umi-downloader-http': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4) + '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-http-fetch': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-program-repository': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-rpc-chunk-get-accounts': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4) + '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-serializer-data-view': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4) - '@solana/web3.js': 1.95.4 + '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 transitivePeerDependencies: - encoding dev: true @@ -148,16 +216,16 @@ packages: '@metaplex-foundation/umi': 0.9.2 dev: true - /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4): + /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-hhPCxXbYIp4BC4z9gK78sXpWLkNSrfv4ndhF5ruAkdIp7GcRVYKj0QnOUO6lGYGiIkNlw20yoTwOe1CT//OfTQ==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@noble/curves': 1.6.0 - '@solana/web3.js': 1.95.4 + '@solana/web3.js': 1.95.8 dev: true /@metaplex-foundation/umi-http-fetch@0.9.2(@metaplex-foundation/umi@0.9.2): @@ -197,15 +265,15 @@ packages: '@metaplex-foundation/umi': 0.9.2 dev: true - /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4): + /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-MqcsBz8B4wGl6jxsf2Jo/rAEpYReU9VCSR15QSjhvADHMmdFxCIZCCAgE+gDE2Vuanfl437VhOcP3g5Uw8C16Q==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4) - '@solana/web3.js': 1.95.4 + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 dev: true /@metaplex-foundation/umi-serializer-data-view@0.9.2(@metaplex-foundation/umi@0.9.2): @@ -242,36 +310,36 @@ packages: '@metaplex-foundation/umi-serializers-numbers': 0.8.9 dev: true - /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4): + /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-DFG0ZFocKG8briypSkG9bGUTVsWpAgYugsl2BzTygkGExc4evWfF4Sb1F2C2w9FdrA9ESZM1gpLX9xtx5taOXg==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4) - '@solana/web3.js': 1.95.4 + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 dev: true - /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4): + /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-fR1Kf21uylMFd1Smkltmj4jTNxhqSWf416owsJ+T+cvJi2VCOcOwq/3UFzOrpz78fA0RhsajKYKj0HYsRnQI1g==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4) - '@solana/web3.js': 1.95.4 + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 dev: true - /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4): + /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@solana/web3.js': 1.95.4 + '@solana/web3.js': 1.95.8 buffer: 6.0.3 dev: true @@ -283,12 +351,58 @@ packages: '@metaplex-foundation/umi-serializers': 0.9.0 dev: true + /@mrgnlabs/marginfi-client-v2@6.0.1: + resolution: {integrity: sha512-I4IdrS+fAIhkcgqXmRfwsuZDRgzSipy1Ok8L8Wm3NGgw6JFvTje6qYJ2rNKdZOpZaTDl2q+kZc/GD5EhJkQrLA==} + dependencies: + '@coral-xyz/anchor': 0.30.1 + '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.4) + '@mrgnlabs/mrgn-common': 2.0.2 + '@pythnetwork/pyth-solana-receiver': 0.8.2 + '@solana/spl-token': 0.1.8 + '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.95.4) + '@solana/web3.js': 1.95.4 + '@switchboard-xyz/on-demand': 1.2.67 + bignumber.js: 9.1.2 + borsh: 2.0.0 + bs58: 6.0.0 + crypto-hash: 3.1.0 + decimal.js: 10.4.3 + superstruct: 1.0.4 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - utf-8-validate + dev: false + + /@mrgnlabs/mrgn-common@2.0.2: + resolution: {integrity: sha512-PypRjfnLPN4HPLz6VOyq7FpcbZPvG1CsZzBX7YMTBBiIZElt8NVk9cMZvTjZS7FzjgBdli0l8L60gt1ZdV2jvg==} + dependencies: + '@coral-xyz/anchor': 0.30.1 + '@solana/buffer-layout': 4.0.1 + '@solana/buffer-layout-utils': 0.2.0 + '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.95.4) + '@solana/web3.js': 1.95.4 + bignumber.js: 9.1.2 + bs58: 6.0.0 + decimal.js: 10.4.3 + numeral: 2.0.6 + superstruct: 1.0.4 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + /@noble/curves@1.6.0: resolution: {integrity: sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==} engines: {node: ^14.21.3 || >=16} dependencies: '@noble/hashes': 1.5.0 - dev: true + + /@noble/ed25519@1.7.3: + resolution: {integrity: sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==} + dev: false /@noble/hashes@1.5.0: resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} @@ -305,46 +419,69 @@ packages: /@protobufjs/aspromise@1.1.2: resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} - dev: true /@protobufjs/base64@1.1.2: resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - dev: true /@protobufjs/codegen@2.0.4: resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} - dev: true /@protobufjs/eventemitter@1.1.0: resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} - dev: true /@protobufjs/fetch@1.1.0: resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/inquire': 1.1.0 - dev: true /@protobufjs/float@1.0.2: resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - dev: true /@protobufjs/inquire@1.1.0: resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} - dev: true /@protobufjs/path@1.1.2: resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} - dev: true /@protobufjs/pool@1.1.0: resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - dev: true /@protobufjs/utf8@1.1.0: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - dev: true + + /@pythnetwork/price-service-sdk@1.8.0: + resolution: {integrity: sha512-tFZ1thj3Zja06DzPIX2dEWSi7kIfIyqreoywvw5NQ3Z1pl5OJHQGMEhxt6Li3UCGSp2ooYZS9wl8/8XfrfrNSA==} + dependencies: + bn.js: 5.2.1 + dev: false + + /@pythnetwork/pyth-solana-receiver@0.8.2: + resolution: {integrity: sha512-WrrdwwhSYvvB5vJEL+SfPnfuxgkRKMeKdZvGFFwe6ENrMhrQCM05oDkvNNYfXATLcpQGRAyBu9l1xIxUxixpqw==} + dependencies: + '@coral-xyz/anchor': 0.29.0 + '@noble/hashes': 1.5.0 + '@pythnetwork/price-service-sdk': 1.8.0 + '@pythnetwork/solana-utils': 0.4.2 + '@solana/web3.js': 1.95.4 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@pythnetwork/solana-utils@0.4.2: + resolution: {integrity: sha512-hKo7Bcs/kDWA5Fnqhg9zJSB94NMoUDIDjHjSi/uvZOzwizISUQI6oY3LWd2CXzNh4f8djjY2BS5iNHaM4cm8Bw==} + dependencies: + '@coral-xyz/anchor': 0.29.0 + '@solana/web3.js': 1.95.4 + bs58: 5.0.0 + jito-ts: 3.0.1 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false /@solana/buffer-layout-utils@0.2.0: resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} @@ -358,14 +495,12 @@ packages: - bufferutil - encoding - utf-8-validate - dev: true /@solana/buffer-layout@4.0.1: resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} engines: {node: '>=5.10'} dependencies: buffer: 6.0.3 - dev: true /@solana/codecs-core@2.0.0-preview.1: resolution: {integrity: sha512-0y3kgFSJAOApNGefEOgLRMiXOHVmcF29Xw3zmR4LDUABvytG3ecKMXGz5oLt3vdaU2CyN3tuUVeGmQjrd0U1kw==} @@ -567,7 +702,7 @@ packages: - fastestsmallesttextencoderdecoder dev: true - /@solana/spl-token-group@0.0.5(@solana/web3.js@1.95.4)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + /@solana/spl-token-group@0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-CLJnWEcdoUBpQJfx9WEbX3h6nTdNiUzswfFdkABUik7HVwSNA98u5AYvBVK2H93d9PGMOHAak2lHW9xr+zAJGQ==} engines: {node: '>=16'} peerDependencies: @@ -575,7 +710,7 @@ packages: dependencies: '@solana/codecs': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.4 + '@solana/web3.js': 1.95.8 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript @@ -595,7 +730,7 @@ packages: - typescript dev: true - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.4)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} engines: {node: '>=16'} peerDependencies: @@ -603,12 +738,28 @@ packages: dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.4 + '@solana/web3.js': 1.95.8 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript dev: true + /@solana/spl-token@0.1.8: + resolution: {integrity: sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==} + engines: {node: '>= 10'} + dependencies: + '@babel/runtime': 7.25.7 + '@solana/web3.js': 1.95.4 + bn.js: 5.2.1 + buffer: 6.0.3 + buffer-layout: 1.2.2 + dotenv: 10.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + /@solana/spl-token@0.3.11(@solana/web3.js@1.95.3)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} engines: {node: '>=16'} @@ -628,7 +779,7 @@ packages: - utf-8-validate dev: true - /@solana/spl-token@0.3.11(@solana/web3.js@1.95.4)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + /@solana/spl-token@0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} engines: {node: '>=16'} peerDependencies: @@ -636,8 +787,8 @@ packages: dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.4)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.4 + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8 buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -647,7 +798,7 @@ packages: - utf-8-validate dev: true - /@solana/spl-token@0.4.8(@solana/web3.js@1.95.4)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + /@solana/spl-token@0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-RO0JD9vPRi4LsAbMUdNbDJ5/cv2z11MGhtAvFeRzT4+hAGE/FUzRi0tkkWtuCfSIU3twC6CtmAihRp/+XXjWsA==} engines: {node: '>=16'} peerDependencies: @@ -655,9 +806,9 @@ packages: dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.95.4)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.4)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.4 + '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8 buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -674,6 +825,51 @@ packages: buffer: 6.0.3 dev: true + /@solana/wallet-adapter-base@0.9.24(@solana/web3.js@1.95.4): + resolution: {integrity: sha512-f3kwHF/2Lx3YgcO37B45MM46YLFy4QkdLemZ+N/0SwLAnSfhq3+Vb9bC5vuoupMJ/onos09TIDeIxRdg/+51kw==} + engines: {node: '>=20'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-standard-features': 1.3.0 + '@solana/web3.js': 1.95.4 + '@wallet-standard/base': 1.1.0 + '@wallet-standard/features': 1.1.0 + eventemitter3: 4.0.7 + dev: false + + /@solana/wallet-standard-features@1.3.0: + resolution: {integrity: sha512-ZhpZtD+4VArf6RPitsVExvgkF+nGghd1rzPjd97GmBximpnt1rsUxMOEyoIEuH3XBxPyNB6Us7ha7RHWQR+abg==} + engines: {node: '>=16'} + dependencies: + '@wallet-standard/base': 1.1.0 + '@wallet-standard/features': 1.1.0 + dev: false + + /@solana/web3.js@1.77.4: + resolution: {integrity: sha512-XdN0Lh4jdY7J8FYMyucxCwzn6Ga2Sr1DHDWRbqVzk7ZPmmpSPOVWHzO67X1cVT+jNi1D6gZi2tgjHgDPuj6e9Q==} + dependencies: + '@babel/runtime': 7.25.7 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.2 + node-fetch: 2.7.0 + rpc-websockets: 7.11.0 + superstruct: 0.14.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + /@solana/web3.js@1.95.3: resolution: {integrity: sha512-O6rPUN0w2fkNqx/Z3QJMB9L225Ex10PRDH8bTaIUPZXMPV0QP8ZpPvjQnXK+upUczlRgzHzd6SjKIha1p+I6og==} dependencies: @@ -720,14 +916,60 @@ packages: - bufferutil - encoding - utf-8-validate + + /@solana/web3.js@1.95.8: + resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} + dependencies: + '@babel/runtime': 7.25.7 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.2 + node-fetch: 2.7.0 + rpc-websockets: 9.0.4 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate dev: true + /@solana/web3.js@1.98.0: + resolution: {integrity: sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==} + dependencies: + '@babel/runtime': 7.25.7 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.2 + node-fetch: 2.7.0 + rpc-websockets: 9.0.4 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + /@solworks/soltoolkit-sdk@0.0.23(fastestsmallesttextencoderdecoder@1.0.22): resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.4)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.4 + '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8 '@types/bn.js': 5.1.6 '@types/node': 18.19.67 '@types/node-fetch': 2.6.12 @@ -772,13 +1014,12 @@ packages: resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} dependencies: tslib: 2.7.0 - dev: true /@switchboard-xyz/common@2.5.5: resolution: {integrity: sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w==} engines: {node: '>=12'} dependencies: - '@solana/web3.js': 1.95.4 + '@solana/web3.js': 1.95.8 axios: 1.7.8 big.js: 6.2.2 bn.js: 5.2.1 @@ -796,13 +1037,55 @@ packages: - utf-8-validate dev: true + /@switchboard-xyz/common@3.0.12: + resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} + engines: {node: '>=20'} + dependencies: + '@solana/web3.js': 1.98.0 + axios: 1.8.4 + big.js: 6.2.2 + bn.js: 5.2.1 + bs58: 6.0.0 + buffer: 6.0.3 + decimal.js: 10.4.3 + js-sha256: 0.11.0 + protobufjs: 7.4.0 + yaml: 2.6.1 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - utf-8-validate + dev: true + + /@switchboard-xyz/common@3.0.13: + resolution: {integrity: sha512-I+18pvqh6Oajz9bYvAJ/swz+XUqRbz7i3dgz/BzasDyxpI4pzIsG4qsnVfIpAnTGsgzhq61Q6W721SnnyFdKuw==} + engines: {node: '>=20'} + dependencies: + '@solana/web3.js': 1.98.0 + axios: 1.8.4 + big.js: 6.2.2 + bn.js: 5.2.1 + bs58: 6.0.0 + buffer: 6.0.3 + decimal.js: 10.4.3 + js-sha256: 0.11.0 + protobufjs: 7.4.0 + yaml: 2.6.1 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - utf-8-validate + dev: false + /@switchboard-xyz/on-demand@1.2.51(fastestsmallesttextencoderdecoder@1.0.22): resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} engines: {node: '>= 18'} dependencies: '@brokerloop/ttlcache': 3.2.3 '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 - '@solana/web3.js': 1.95.4 + '@solana/web3.js': 1.95.8 '@solworks/soltoolkit-sdk': 0.0.23(fastestsmallesttextencoderdecoder@1.0.22) '@switchboard-xyz/common': 2.5.5 axios: 1.7.8 @@ -818,6 +1101,25 @@ packages: - utf-8-validate dev: true + /@switchboard-xyz/on-demand@1.2.67: + resolution: {integrity: sha512-rtGA+9tQHb/xQnUFgVzyaOs2uKgnwP7OqYQLEOjTDdNTEEgU8OTR72ujluOEYB9LMByb7h9SRuOR353vxYQhYA==} + engines: {node: '>= 18'} + deprecated: deprecated in favor of 2.x.x + dependencies: + '@common.js/quick-lru': 7.0.0 + '@coral-xyz/anchor': 0.30.1 + '@switchboard-xyz/common': 3.0.13 + axios: 1.7.8 + bs58: 6.0.0 + buffer: 6.0.3 + js-yaml: 4.1.0 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - utf-8-validate + dev: false + /@types/bn.js@5.1.6: resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} dependencies: @@ -828,7 +1130,6 @@ packages: resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: '@types/node': 20.16.11 - dev: true /@types/node-fetch@2.6.12: resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} @@ -839,7 +1140,6 @@ packages: /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - dev: true /@types/node@18.19.67: resolution: {integrity: sha512-wI8uHusga+0ZugNp0Ol/3BqQfEcCCNfojtO6Oou9iVNGPTL6QNSdnUdqq85fRgIorLhLMuPIKpsN98QE9Nh+KQ==} @@ -851,23 +1151,31 @@ packages: resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} dependencies: undici-types: 6.19.8 - dev: true /@types/uuid@8.3.4: resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} - dev: true /@types/ws@7.4.7: resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} dependencies: '@types/node': 20.16.11 - dev: true /@types/ws@8.5.12: resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} dependencies: '@types/node': 20.16.11 - dev: true + + /@wallet-standard/base@1.1.0: + resolution: {integrity: sha512-DJDQhjKmSNVLKWItoKThJS+CsJQjR9AOBOirBVT1F9YpRyC9oYHE+ZnSf8y8bxUphtKqdQMPVQ2mHohYdRvDVQ==} + engines: {node: '>=16'} + dev: false + + /@wallet-standard/features@1.1.0: + resolution: {integrity: sha512-hiEivWNztx73s+7iLxsuD1sOJ28xtRix58W7Xnz4XzzA/pF0+aicnWgjOdA10doVDEDZdUuZCIIqG96SFNlDUg==} + engines: {node: '>=16'} + dependencies: + '@wallet-standard/base': 1.1.0 + dev: false /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} @@ -875,7 +1183,6 @@ packages: dependencies: jsonparse: 1.3.1 through: 2.3.8 - dev: true /a-sync-waterfall@1.0.1: resolution: {integrity: sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==} @@ -886,7 +1193,11 @@ packages: engines: {node: '>= 8.0.0'} dependencies: humanize-ms: 1.2.1 - dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: false /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} @@ -901,7 +1212,6 @@ packages: /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true /asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} @@ -919,7 +1229,6 @@ packages: /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: true /available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} @@ -936,25 +1245,32 @@ packages: proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - dev: true + + /axios@1.8.4: + resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug /base-x@3.0.10: resolution: {integrity: sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==} dependencies: safe-buffer: 5.2.1 - dev: true /base-x@4.0.0: resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} - dev: true + + /base-x@5.0.1: + resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: true /big.js@6.2.2: resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} - dev: true /bigint-buffer@1.1.5: resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} @@ -962,21 +1278,17 @@ packages: requiresBuild: true dependencies: bindings: 1.5.0 - dev: true /bignumber.js@9.1.2: resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} - dev: true /bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} dependencies: file-uri-to-path: 1.0.0 - dev: true /bn.js@5.2.1: resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} - dev: true /borsh@0.7.0: resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} @@ -984,31 +1296,35 @@ packages: bn.js: 5.2.1 bs58: 4.0.1 text-encoding-utf-8: 1.0.2 - dev: true + + /borsh@2.0.0: + resolution: {integrity: sha512-kc9+BgR3zz9+cjbwM8ODoUB4fs3X3I5A/HtX7LZKxCLaMrEeDFoBpnhZY//DTS1VZBSs6S5v46RZRbZjRFspEg==} + dev: false /bs58@4.0.1: resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} dependencies: base-x: 3.0.10 - dev: true /bs58@5.0.0: resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} dependencies: base-x: 4.0.0 - dev: true + + /bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + dependencies: + base-x: 5.0.1 /buffer-layout@1.2.2: resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==} engines: {node: '>=4.5'} - dev: true /buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - dev: true /bufferutil@4.0.8: resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} @@ -1016,7 +1332,6 @@ packages: requiresBuild: true dependencies: node-gyp-build: 4.8.2 - dev: true /call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} @@ -1031,7 +1346,6 @@ packages: /camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - dev: true /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} @@ -1045,6 +1359,15 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: false + /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1061,7 +1384,6 @@ packages: engines: {node: '>= 0.8'} dependencies: delayed-stream: 1.0.0 - dev: true /commander@12.1.0: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} @@ -1069,7 +1391,6 @@ packages: /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: true /commander@5.1.0: resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} @@ -1086,7 +1407,6 @@ packages: node-fetch: 2.7.0 transitivePeerDependencies: - encoding - dev: true /cross-fetch@4.0.0: resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} @@ -1099,7 +1419,11 @@ packages: /crypto-hash@1.3.0: resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} engines: {node: '>=8'} - dev: true + + /crypto-hash@3.1.0: + resolution: {integrity: sha512-HR8JlZ+Dn54Lc5gGWZJxJitWbOCUzWb9/AlyONGecBnYZ+n/ONvt0gQnEzDNpJMYeRrYO7KogQ4qwyTPKnWKEw==} + engines: {node: '>=18'} + dev: false /debug@4.3.7: resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} @@ -1115,7 +1439,6 @@ packages: /decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} - dev: true /define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} @@ -1137,19 +1460,29 @@ packages: /delay@5.0.0: resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} engines: {node: '>=10'} - dev: true /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - dev: true /dot-case@3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} dependencies: no-case: 3.0.4 tslib: 2.7.0 - dev: true + + /dotenv@10.0.0: + resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==} + engines: {node: '>=10'} + dev: false + + /dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + engines: {node: '>=12'} + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: false /es-define-property@1.0.0: resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} @@ -1163,37 +1496,35 @@ packages: /es6-promise@4.2.8: resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} - dev: true /es6-promisify@5.0.0: resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} dependencies: es6-promise: 4.2.8 - dev: true + + /escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + dev: false /eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - dev: true /eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} - dev: true /eyes@0.1.8: resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} engines: {node: '> 0.1.90'} - dev: true /fast-stable-stringify@1.0.0: resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} - dev: true /fastestsmallesttextencoderdecoder@1.0.22: resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} /file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - dev: true /follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} @@ -1203,7 +1534,6 @@ packages: peerDependenciesMeta: debug: optional: true - dev: true /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -1218,11 +1548,15 @@ packages: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 - dev: true /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: false + /get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -1273,11 +1607,9 @@ packages: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} dependencies: ms: 2.1.3 - dev: true /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: true /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -1302,6 +1634,11 @@ packages: engines: {node: '>= 0.4'} dev: true + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: false + /is-generator-function@1.0.10: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} @@ -1334,7 +1671,6 @@ packages: ws: '*' dependencies: ws: 7.5.10 - dev: true /jayson@4.1.2: resolution: {integrity: sha512-5nzMWDHy6f+koZOuYsArh2AXs73NfWYVlFyJJuCedr93GpY+Ku8qq10ropSXVfHK+H0T6paA88ww+/dV+1fBNA==} @@ -1356,11 +1692,26 @@ packages: transitivePeerDependencies: - bufferutil - utf-8-validate - dev: true + + /jito-ts@3.0.1: + resolution: {integrity: sha512-TSofF7KqcwyaWGjPaSYC8RDoNBY1TPRNBHdrw24bdIi7mQ5bFEDdYK3D//llw/ml8YDvcZlgd644WxhjLTS9yg==} + dependencies: + '@grpc/grpc-js': 1.13.2 + '@noble/ed25519': 1.7.3 + '@solana/web3.js': 1.77.4 + agentkeepalive: 4.5.0 + dotenv: 16.4.7 + jayson: 4.1.2 + node-fetch: 2.7.0 + superstruct: 1.0.4 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false /js-sha256@0.11.0: resolution: {integrity: sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==} - dev: true /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1371,7 +1722,6 @@ packages: hasBin: true dependencies: argparse: 2.0.1 - dev: true /json-stable-stringify@1.1.1: resolution: {integrity: sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==} @@ -1385,7 +1735,6 @@ packages: /json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - dev: true /jsonify@0.0.1: resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} @@ -1394,7 +1743,10 @@ packages: /jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} - dev: true + + /lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + dev: false /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -1402,7 +1754,6 @@ packages: /long@5.2.3: resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} - dev: true /loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} @@ -1415,7 +1766,6 @@ packages: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} dependencies: tslib: 2.7.0 - dev: true /make-synchronized@0.2.9: resolution: {integrity: sha512-4wczOs8SLuEdpEvp3vGo83wh8rjJ78UsIk7DIX5fxdfmfMJGog4bQzxfvOwq7Q3yCHLC4jp1urPHIxRS/A93gA==} @@ -1424,25 +1774,21 @@ packages: /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} - dev: true /mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} dependencies: mime-db: 1.52.0 - dev: true /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: true /no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} dependencies: lower-case: 2.0.2 tslib: 2.7.0 - dev: true /node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} @@ -1454,13 +1800,15 @@ packages: optional: true dependencies: whatwg-url: 5.0.0 - dev: true /node-gyp-build@4.8.2: resolution: {integrity: sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==} hasBin: true requiresBuild: true - dev: true + + /numeral@2.0.6: + resolution: {integrity: sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==} + dev: false /nunjucks@3.2.4: resolution: {integrity: sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==} @@ -1501,7 +1849,6 @@ packages: /pako@2.1.0: resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} - dev: true /possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} @@ -1531,15 +1878,17 @@ packages: '@protobufjs/utf8': 1.1.0 '@types/node': 20.16.11 long: 5.2.3 - dev: true /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: true /regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: false /rpc-websockets@7.11.0: resolution: {integrity: sha512-IkLYjayPv6Io8C/TdCL5gwgzd1hFz2vmBZrjMw/SPEXo51ETOhnzgS4Qy5GWi2JQN7HKHa66J3+2mv0fgNh/7w==} @@ -1551,7 +1900,6 @@ packages: optionalDependencies: bufferutil: 4.0.8 utf-8-validate: 5.0.10 - dev: true /rpc-websockets@9.0.4: resolution: {integrity: sha512-yWZWN0M+bivtoNLnaDbtny4XchdAIF5Q4g/ZsC5UC61Ckbp0QczwO8fg44rV3uYmY4WHd+EZQbn90W1d8ojzqQ==} @@ -1566,11 +1914,9 @@ packages: optionalDependencies: bufferutil: 4.0.8 utf-8-validate: 5.0.10 - dev: true /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true /set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} @@ -1588,16 +1934,38 @@ packages: dependencies: dot-case: 3.0.4 tslib: 2.7.0 - dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: false + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: false + + /superstruct@0.14.2: + resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} + dev: false /superstruct@0.15.5: resolution: {integrity: sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==} - dev: true + + /superstruct@1.0.4: + resolution: {integrity: sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==} + engines: {node: '>=14.0.0'} + dev: false /superstruct@2.0.2: resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} engines: {node: '>=14.0.0'} - dev: true /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} @@ -1608,23 +1976,18 @@ packages: /text-encoding-utf-8@1.0.2: resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} - dev: true /through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true /toml@3.0.0: resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} - dev: true /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: true /tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} - dev: true /typescript@4.9.5: resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} @@ -1638,7 +2001,6 @@ packages: /undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - dev: true /utf-8-validate@5.0.10: resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} @@ -1646,7 +2008,6 @@ packages: requiresBuild: true dependencies: node-gyp-build: 4.8.2 - dev: true /util@0.12.5: resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} @@ -1661,18 +2022,15 @@ packages: /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true - dev: true /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: true /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 - dev: true /which-typed-array@1.1.15: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} @@ -1685,6 +2043,15 @@ packages: has-tostringtag: 1.0.2 dev: true + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: false + /ws@7.5.10: resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} engines: {node: '>=8.3.0'} @@ -1696,7 +2063,6 @@ packages: optional: true utf-8-validate: optional: true - dev: true /ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} @@ -1712,13 +2078,34 @@ packages: dependencies: bufferutil: 4.0.8 utf-8-validate: 5.0.10 - dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: false /yaml@2.6.1: resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==} engines: {node: '>= 14'} hasBin: true - dev: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: false + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: false file:solauto-sdk(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {directory: solauto-sdk, type: directory} @@ -1726,19 +2113,21 @@ packages: name: '@haven-fi/solauto-sdk' dependencies: '@coral-xyz/anchor': 0.30.1 - '@jup-ag/api': 6.0.29 + '@jup-ag/api': 6.0.24 '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-bundle-defaults': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4) - '@metaplex-foundation/umi-signer-wallet-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4) - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.4) - '@solana/spl-token': 0.4.8(@solana/web3.js@1.95.4)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.4 + '@metaplex-foundation/umi-bundle-defaults': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@metaplex-foundation/umi-signer-wallet-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/spl-token': 0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8 '@sqds/multisig': 2.1.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@switchboard-xyz/common': 3.0.12 '@switchboard-xyz/on-demand': 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) '@types/node': 20.16.11 axios: 1.7.8 bs58: 5.0.0 cross-fetch: 4.0.0 + dotenv: 16.4.7 rpc-websockets: 7.11.0 transitivePeerDependencies: - bufferutil diff --git a/programs/marginfi-sdk/src/generated/errors/marginfi.rs b/programs/marginfi-sdk/src/generated/errors/marginfi.rs index dbb182f2..41fe61f4 100644 --- a/programs/marginfi-sdk/src/generated/errors/marginfi.rs +++ b/programs/marginfi-sdk/src/generated/errors/marginfi.rs @@ -10,9 +10,9 @@ use thiserror::Error; #[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)] pub enum MarginfiError { - /// 6000 (0x1770) - Math error - #[error("Math error")] - MathError, + /// 6000 (0x1770) - Internal Marginfi logic error + #[error("Internal Marginfi logic error")] + InternalLogicError, /// 6001 (0x1771) - Invalid bank index #[error("Invalid bank index")] BankNotFound, @@ -25,123 +25,216 @@ pub enum MarginfiError { /// 6004 (0x1774) - Invalid transfer #[error("Invalid transfer")] InvalidTransfer, - /// 6005 (0x1775) - Missing Pyth or Bank account - #[error("Missing Pyth or Bank account")] + /// 6005 (0x1775) - Missing Oracle, Bank, LST mint, or Sol Pool + #[error("Missing Oracle, Bank, LST mint, or Sol Pool")] MissingPythOrBankAccount, /// 6006 (0x1776) - Missing Pyth account #[error("Missing Pyth account")] MissingPythAccount, - /// 6007 (0x1777) - Invalid Pyth account - #[error("Invalid Pyth account")] - InvalidOracleAccount, - /// 6008 (0x1778) - Missing Bank account + /// 6007 (0x1777) - Missing Bank account #[error("Missing Bank account")] MissingBankAccount, - /// 6009 (0x1779) - Invalid Bank account + /// 6008 (0x1778) - Invalid Bank account #[error("Invalid Bank account")] InvalidBankAccount, - /// 6010 (0x177A) - Bad account health - #[error("Bad account health")] - BadAccountHealth, - /// 6011 (0x177B) - Lending account balance slots are full + /// 6009 (0x1779) - RiskEngine rejected due to either bad health or stale oracles + #[error("RiskEngine rejected due to either bad health or stale oracles")] + RiskEngineInitRejected, + /// 6010 (0x177A) - Lending account balance slots are full #[error("Lending account balance slots are full")] LendingAccountBalanceSlotsFull, - /// 6012 (0x177C) - Bank already exists + /// 6011 (0x177B) - Bank already exists #[error("Bank already exists")] BankAlreadyExists, - /// 6013 (0x177D) - Illegal liquidation - #[error("Illegal liquidation")] - IllegalLiquidation, - /// 6014 (0x177E) - Account is not bankrupt + /// 6012 (0x177C) - Amount to liquidate must be positive + #[error("Amount to liquidate must be positive")] + ZeroLiquidationAmount, + /// 6013 (0x177D) - Account is not bankrupt #[error("Account is not bankrupt")] AccountNotBankrupt, - /// 6015 (0x177F) - Account balance is not bad debt + /// 6014 (0x177E) - Account balance is not bad debt #[error("Account balance is not bad debt")] BalanceNotBadDebt, - /// 6016 (0x1780) - Invalid group config + /// 6015 (0x177F) - Invalid group config #[error("Invalid group config")] InvalidConfig, - /// 6017 (0x1781) - Stale oracle data - #[error("Stale oracle data")] - StaleOracle, - /// 6018 (0x1782) - Bank paused + /// 6016 (0x1780) - Bank paused #[error("Bank paused")] BankPaused, - /// 6019 (0x1783) - Bank is ReduceOnly mode + /// 6017 (0x1781) - Bank is ReduceOnly mode #[error("Bank is ReduceOnly mode")] BankReduceOnly, - /// 6020 (0x1784) - Bank is missing + /// 6018 (0x1782) - Bank is missing #[error("Bank is missing")] - BankAccoutNotFound, - /// 6021 (0x1785) - Operation is deposit-only + BankAccountNotFound, + /// 6019 (0x1783) - Operation is deposit-only #[error("Operation is deposit-only")] OperationDepositOnly, - /// 6022 (0x1786) - Operation is withdraw-only + /// 6020 (0x1784) - Operation is withdraw-only #[error("Operation is withdraw-only")] OperationWithdrawOnly, - /// 6023 (0x1787) - Operation is borrow-only + /// 6021 (0x1785) - Operation is borrow-only #[error("Operation is borrow-only")] OperationBorrowOnly, - /// 6024 (0x1788) - Operation is repay-only + /// 6022 (0x1786) - Operation is repay-only #[error("Operation is repay-only")] OperationRepayOnly, - /// 6025 (0x1789) - No asset found + /// 6023 (0x1787) - No asset found #[error("No asset found")] NoAssetFound, - /// 6026 (0x178A) - No liability found + /// 6024 (0x1788) - No liability found #[error("No liability found")] NoLiabilityFound, - /// 6027 (0x178B) - Invalid oracle setup + /// 6025 (0x1789) - Invalid oracle setup #[error("Invalid oracle setup")] InvalidOracleSetup, - /// 6028 (0x178C) - Invalid bank utilization ratio + /// 6026 (0x178A) - Invalid bank utilization ratio #[error("Invalid bank utilization ratio")] IllegalUtilizationRatio, - /// 6029 (0x178D) - Bank borrow cap exceeded + /// 6027 (0x178B) - Bank borrow cap exceeded #[error("Bank borrow cap exceeded")] BankLiabilityCapacityExceeded, - /// 6030 (0x178E) - Invalid Price + /// 6028 (0x178C) - Invalid Price #[error("Invalid Price")] InvalidPrice, - /// 6031 (0x178F) - Account can have only one liablity when account is under isolated risk - #[error("Account can have only one liablity when account is under isolated risk")] + /// 6029 (0x178D) - Account can have only one liability when account is under isolated risk + #[error("Account can have only one liability when account is under isolated risk")] IsolatedAccountIllegalState, - /// 6032 (0x1790) - Emissions already setup + /// 6030 (0x178E) - Emissions already setup #[error("Emissions already setup")] EmissionsAlreadySetup, - /// 6033 (0x1791) - Oracle is not set + /// 6031 (0x178F) - Oracle is not set #[error("Oracle is not set")] OracleNotSetup, - /// 6034 (0x1792) - Invalid swithcboard decimal conversion - #[error("Invalid swithcboard decimal conversion")] + /// 6032 (0x1790) - Invalid switchboard decimal conversion + #[error("Invalid switchboard decimal conversion")] InvalidSwitchboardDecimalConversion, - /// 6035 (0x1793) - Cannot close balance because of outstanding emissions + /// 6033 (0x1791) - Cannot close balance because of outstanding emissions #[error("Cannot close balance because of outstanding emissions")] CannotCloseOutstandingEmissions, - /// 6036 (0x1794) - Update emissions error + /// 6034 (0x1792) - Update emissions error #[error("Update emissions error")] EmissionsUpdateError, - /// 6037 (0x1795) - Account disabled + /// 6035 (0x1793) - Account disabled #[error("Account disabled")] AccountDisabled, - /// 6038 (0x1796) - Account can't temporarily open 3 balances, please close a balance first + /// 6036 (0x1794) - Account can't temporarily open 3 balances, please close a balance first #[error("Account can't temporarily open 3 balances, please close a balance first")] AccountTempActiveBalanceLimitExceeded, - /// 6039 (0x1797) - Illegal action during flashloan + /// 6037 (0x1795) - Illegal action during flashloan #[error("Illegal action during flashloan")] AccountInFlashloan, - /// 6040 (0x1798) - Illegal flashloan + /// 6038 (0x1796) - Illegal flashloan #[error("Illegal flashloan")] IllegalFlashloan, - /// 6041 (0x1799) - Illegal flag + /// 6039 (0x1797) - Illegal flag #[error("Illegal flag")] IllegalFlag, - /// 6042 (0x179A) - Illegal balance state + /// 6040 (0x1798) - Illegal balance state #[error("Illegal balance state")] IllegalBalanceState, - /// 6043 (0x179B) - Illegal account authority transfer + /// 6041 (0x1799) - Illegal account authority transfer #[error("Illegal account authority transfer")] IllegalAccountAuthorityTransfer, + /// 6042 (0x179A) - Unauthorized + #[error("Unauthorized")] + Unauthorized, + /// 6043 (0x179B) - Invalid account authority + #[error("Invalid account authority")] + IllegalAction, + /// 6044 (0x179C) - Token22 Banks require mint account as first remaining account + #[error("Token22 Banks require mint account as first remaining account")] + T22MintRequired, + /// 6045 (0x179D) - Invalid ATA for global fee account + #[error("Invalid ATA for global fee account")] + InvalidFeeAta, + /// 6046 (0x179E) - Use add pool permissionless instead + #[error("Use add pool permissionless instead")] + AddedStakedPoolManually, + /// 6047 (0x179F) - Staked SOL accounts can only deposit staked assets and borrow SOL + #[error("Staked SOL accounts can only deposit staked assets and borrow SOL")] + AssetTagMismatch, + /// 6048 (0x17A0) - Stake pool validation failed: check the stake pool, mint, or sol pool + #[error("Stake pool validation failed: check the stake pool, mint, or sol pool")] + StakePoolValidationFailed, + /// 6049 (0x17A1) - Switchboard oracle: stale price + #[error("Switchboard oracle: stale price")] + SwitchboardStalePrice, + /// 6050 (0x17A2) - Pyth Push oracle: stale price + #[error("Pyth Push oracle: stale price")] + PythPushStalePrice, + /// 6051 (0x17A3) - Oracle error: wrong number of accounts + #[error("Oracle error: wrong number of accounts")] + WrongNumberOfOracleAccounts, + /// 6052 (0x17A4) - Oracle error: wrong account keys + #[error("Oracle error: wrong account keys")] + WrongOracleAccountKeys, + /// 6053 (0x17A5) - Pyth Push oracle: wrong account owner + #[error("Pyth Push oracle: wrong account owner")] + PythPushWrongAccountOwner, + /// 6054 (0x17A6) - Staked Pyth Push oracle: wrong account owner + #[error("Staked Pyth Push oracle: wrong account owner")] + StakedPythPushWrongAccountOwner, + /// 6055 (0x17A7) - Pyth Push oracle: mismatched feed id + #[error("Pyth Push oracle: mismatched feed id")] + PythPushMismatchedFeedId, + /// 6056 (0x17A8) - Pyth Push oracle: insufficient verification level + #[error("Pyth Push oracle: insufficient verification level")] + PythPushInsufficientVerificationLevel, + /// 6057 (0x17A9) - Pyth Push oracle: feed id must be 32 Bytes + #[error("Pyth Push oracle: feed id must be 32 Bytes")] + PythPushFeedIdMustBe32Bytes, + /// 6058 (0x17AA) - Pyth Push oracle: feed id contains non-hex characters + #[error("Pyth Push oracle: feed id contains non-hex characters")] + PythPushFeedIdNonHexCharacter, + /// 6059 (0x17AB) - Switchboard oracle: wrong account owner + #[error("Switchboard oracle: wrong account owner")] + SwitchboardWrongAccountOwner, + /// 6060 (0x17AC) - Pyth Push oracle: invalid account + #[error("Pyth Push oracle: invalid account")] + PythPushInvalidAccount, + /// 6061 (0x17AD) - Switchboard oracle: invalid account + #[error("Switchboard oracle: invalid account")] + SwitchboardInvalidAccount, + /// 6062 (0x17AE) - Math error + #[error("Math error")] + MathError, + /// 6063 (0x17AF) - Invalid emissions destination account + #[error("Invalid emissions destination account")] + InvalidEmissionsDestinationAccount, + /// 6064 (0x17B0) - Asset and liability bank cannot be the same + #[error("Asset and liability bank cannot be the same")] + SameAssetAndLiabilityBanks, + /// 6065 (0x17B1) - Trying to withdraw more assets than available + #[error("Trying to withdraw more assets than available")] + OverliquidationAttempt, + /// 6066 (0x17B2) - Liability bank has no liabilities + #[error("Liability bank has no liabilities")] + NoLiabilitiesInLiabilityBank, + /// 6067 (0x17B3) - Liability bank has assets + #[error("Liability bank has assets")] + AssetsInLiabilityBank, + /// 6068 (0x17B4) - Account is healthy and cannot be liquidated + #[error("Account is healthy and cannot be liquidated")] + HealthyAccount, + /// 6069 (0x17B5) - Liability payoff too severe, exhausted liability + #[error("Liability payoff too severe, exhausted liability")] + ExhaustedLiability, + /// 6070 (0x17B6) - Liability payoff too severe, liability balance has assets + #[error("Liability payoff too severe, liability balance has assets")] + TooSeverePayoff, + /// 6071 (0x17B7) - Liquidation too severe, account above maintenance requirement + #[error("Liquidation too severe, account above maintenance requirement")] + TooSevereLiquidation, + /// 6072 (0x17B8) - Liquidation would worsen account health + #[error("Liquidation would worsen account health")] + WorseHealthPostLiquidation, + /// 6073 (0x17B9) - Arena groups can only support two banks + #[error("Arena groups can only support two banks")] + ArenaBankLimit, + /// 6074 (0x17BA) - Arena groups cannot return to non-arena status + #[error("Arena groups cannot return to non-arena status")] + ArenaSettingCannotChange, } impl solana_program::program_error::PrintProgramError for MarginfiError { diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_account_borrow.rs b/programs/marginfi-sdk/src/generated/instructions/lending_account_borrow.rs index 1965eb3f..b698fbe5 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_account_borrow.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_account_borrow.rs @@ -88,12 +88,12 @@ impl LendingAccountBorrow { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingAccountBorrowInstructionData { +pub struct LendingAccountBorrowInstructionData { discriminator: [u8; 8], } impl LendingAccountBorrowInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [4, 126, 116, 53, 48, 5, 212, 31], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_account_close_balance.rs b/programs/marginfi-sdk/src/generated/instructions/lending_account_close_balance.rs index 75cf5638..0aea68f7 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_account_close_balance.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_account_close_balance.rs @@ -58,12 +58,12 @@ impl LendingAccountCloseBalance { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingAccountCloseBalanceInstructionData { +pub struct LendingAccountCloseBalanceInstructionData { discriminator: [u8; 8], } impl LendingAccountCloseBalanceInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [245, 54, 41, 4, 243, 202, 31, 17], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_account_deposit.rs b/programs/marginfi-sdk/src/generated/instructions/lending_account_deposit.rs index 39409d5f..d3b69219 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_account_deposit.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_account_deposit.rs @@ -82,12 +82,12 @@ impl LendingAccountDeposit { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingAccountDepositInstructionData { +pub struct LendingAccountDepositInstructionData { discriminator: [u8; 8], } impl LendingAccountDepositInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [171, 94, 235, 103, 82, 64, 212, 140], } @@ -98,6 +98,7 @@ impl LendingAccountDepositInstructionData { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct LendingAccountDepositInstructionArgs { pub amount: u64, + pub deposit_up_to_limit: Option, } /// Instruction builder for `LendingAccountDeposit`. @@ -121,6 +122,7 @@ pub struct LendingAccountDepositBuilder { bank_liquidity_vault: Option, token_program: Option, amount: Option, + deposit_up_to_limit: Option, __remaining_accounts: Vec, } @@ -178,6 +180,12 @@ impl LendingAccountDepositBuilder { self.amount = Some(amount); self } + /// `[optional argument]` + #[inline(always)] + pub fn deposit_up_to_limit(&mut self, deposit_up_to_limit: bool) -> &mut Self { + self.deposit_up_to_limit = Some(deposit_up_to_limit); + self + } /// Add an aditional account to the instruction. #[inline(always)] pub fn add_remaining_account( @@ -215,6 +223,7 @@ impl LendingAccountDepositBuilder { }; let args = LendingAccountDepositInstructionArgs { amount: self.amount.clone().expect("amount is not set"), + deposit_up_to_limit: self.deposit_up_to_limit.clone(), }; accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) @@ -406,6 +415,7 @@ impl<'a, 'b> LendingAccountDepositCpiBuilder<'a, 'b> { bank_liquidity_vault: None, token_program: None, amount: None, + deposit_up_to_limit: None, __remaining_accounts: Vec::new(), }); Self { instruction } @@ -468,6 +478,12 @@ impl<'a, 'b> LendingAccountDepositCpiBuilder<'a, 'b> { self.instruction.amount = Some(amount); self } + /// `[optional argument]` + #[inline(always)] + pub fn deposit_up_to_limit(&mut self, deposit_up_to_limit: bool) -> &mut Self { + self.instruction.deposit_up_to_limit = Some(deposit_up_to_limit); + self + } /// Add an additional account to the instruction. #[inline(always)] pub fn add_remaining_account( @@ -511,6 +527,7 @@ impl<'a, 'b> LendingAccountDepositCpiBuilder<'a, 'b> { ) -> solana_program::entrypoint::ProgramResult { let args = LendingAccountDepositInstructionArgs { amount: self.instruction.amount.clone().expect("amount is not set"), + deposit_up_to_limit: self.instruction.deposit_up_to_limit.clone(), }; let instruction = LendingAccountDepositCpi { __program: self.instruction.__program, @@ -562,6 +579,7 @@ struct LendingAccountDepositCpiBuilderInstruction<'a, 'b> { bank_liquidity_vault: Option<&'b solana_program::account_info::AccountInfo<'a>>, token_program: Option<&'b solana_program::account_info::AccountInfo<'a>>, amount: Option, + deposit_up_to_limit: Option, /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. __remaining_accounts: Vec<( &'b solana_program::account_info::AccountInfo<'a>, diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_account_end_flashloan.rs b/programs/marginfi-sdk/src/generated/instructions/lending_account_end_flashloan.rs index 7a8fb312..7e9a4012 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_account_end_flashloan.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_account_end_flashloan.rs @@ -47,12 +47,12 @@ impl LendingAccountEndFlashloan { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingAccountEndFlashloanInstructionData { +pub struct LendingAccountEndFlashloanInstructionData { discriminator: [u8; 8], } impl LendingAccountEndFlashloanInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [105, 124, 201, 106, 153, 2, 8, 156], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_account_liquidate.rs b/programs/marginfi-sdk/src/generated/instructions/lending_account_liquidate.rs index c129fff7..d9564597 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_account_liquidate.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_account_liquidate.rs @@ -101,12 +101,12 @@ impl LendingAccountLiquidate { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingAccountLiquidateInstructionData { +pub struct LendingAccountLiquidateInstructionData { discriminator: [u8; 8], } impl LendingAccountLiquidateInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [214, 169, 151, 213, 251, 167, 86, 219], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_account_repay.rs b/programs/marginfi-sdk/src/generated/instructions/lending_account_repay.rs index f8ce75e6..c33f3d79 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_account_repay.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_account_repay.rs @@ -82,12 +82,12 @@ impl LendingAccountRepay { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingAccountRepayInstructionData { +pub struct LendingAccountRepayInstructionData { discriminator: [u8; 8], } impl LendingAccountRepayInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [79, 209, 172, 177, 222, 51, 173, 151], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_account_settle_emissions.rs b/programs/marginfi-sdk/src/generated/instructions/lending_account_settle_emissions.rs index 781ccff7..5051fcbd 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_account_settle_emissions.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_account_settle_emissions.rs @@ -46,12 +46,12 @@ impl LendingAccountSettleEmissions { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingAccountSettleEmissionsInstructionData { +pub struct LendingAccountSettleEmissionsInstructionData { discriminator: [u8; 8], } impl LendingAccountSettleEmissionsInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [161, 58, 136, 174, 242, 223, 156, 176], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_account_start_flashloan.rs b/programs/marginfi-sdk/src/generated/instructions/lending_account_start_flashloan.rs index 719e73d3..6bfef77a 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_account_start_flashloan.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_account_start_flashloan.rs @@ -59,12 +59,12 @@ impl LendingAccountStartFlashloan { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingAccountStartFlashloanInstructionData { +pub struct LendingAccountStartFlashloanInstructionData { discriminator: [u8; 8], } impl LendingAccountStartFlashloanInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [14, 131, 33, 220, 81, 186, 180, 107], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_account_withdraw.rs b/programs/marginfi-sdk/src/generated/instructions/lending_account_withdraw.rs index fa481ea5..5ee5c446 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_account_withdraw.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_account_withdraw.rs @@ -88,12 +88,12 @@ impl LendingAccountWithdraw { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingAccountWithdrawInstructionData { +pub struct LendingAccountWithdrawInstructionData { discriminator: [u8; 8], } impl LendingAccountWithdrawInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [36, 72, 74, 19, 210, 210, 192, 192], } @@ -395,7 +395,7 @@ impl<'a, 'b> LendingAccountWithdrawCpi<'a, 'b> { accounts, data, }; - let mut account_infos = Box::new(Vec::with_capacity(8 + 1 + remaining_accounts.len())); + let mut account_infos = Vec::with_capacity(8 + 1 + remaining_accounts.len()); account_infos.push(self.__program.clone()); account_infos.push(self.marginfi_group.clone()); account_infos.push(self.marginfi_account.clone()); diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_account_withdraw_emissions.rs b/programs/marginfi-sdk/src/generated/instructions/lending_account_withdraw_emissions.rs index 91b3dd6b..6df91932 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_account_withdraw_emissions.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_account_withdraw_emissions.rs @@ -88,12 +88,12 @@ impl LendingAccountWithdrawEmissions { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingAccountWithdrawEmissionsInstructionData { +pub struct LendingAccountWithdrawEmissionsInstructionData { discriminator: [u8; 8], } impl LendingAccountWithdrawEmissionsInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [234, 22, 84, 214, 118, 176, 140, 170], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_pool_accrue_bank_interest.rs b/programs/marginfi-sdk/src/generated/instructions/lending_pool_accrue_bank_interest.rs index 33e3527e..e8ab51a5 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_pool_accrue_bank_interest.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_pool_accrue_bank_interest.rs @@ -46,12 +46,12 @@ impl LendingPoolAccrueBankInterest { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingPoolAccrueBankInterestInstructionData { +pub struct LendingPoolAccrueBankInterestInstructionData { discriminator: [u8; 8], } impl LendingPoolAccrueBankInterestInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [108, 201, 30, 87, 47, 65, 97, 188], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_pool_add_bank.rs b/programs/marginfi-sdk/src/generated/instructions/lending_pool_add_bank.rs index afc80581..d1a52061 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_pool_add_bank.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_pool_add_bank.rs @@ -123,12 +123,12 @@ impl LendingPoolAddBank { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingPoolAddBankInstructionData { +pub struct LendingPoolAddBankInstructionData { discriminator: [u8; 8], } impl LendingPoolAddBankInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [215, 68, 72, 78, 208, 218, 103, 182], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_pool_add_bank_with_seed.rs b/programs/marginfi-sdk/src/generated/instructions/lending_pool_add_bank_with_seed.rs index acb8407d..5f39ee49 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_pool_add_bank_with_seed.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_pool_add_bank_with_seed.rs @@ -123,12 +123,12 @@ impl LendingPoolAddBankWithSeed { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingPoolAddBankWithSeedInstructionData { +pub struct LendingPoolAddBankWithSeedInstructionData { discriminator: [u8; 8], } impl LendingPoolAddBankWithSeedInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [76, 211, 213, 171, 117, 78, 158, 76], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_pool_collect_bank_fees.rs b/programs/marginfi-sdk/src/generated/instructions/lending_pool_collect_bank_fees.rs index c99a10ba..a9513db8 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_pool_collect_bank_fees.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_pool_collect_bank_fees.rs @@ -76,12 +76,12 @@ impl LendingPoolCollectBankFees { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingPoolCollectBankFeesInstructionData { +pub struct LendingPoolCollectBankFeesInstructionData { discriminator: [u8; 8], } impl LendingPoolCollectBankFeesInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [201, 5, 215, 116, 230, 92, 75, 150], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_pool_configure_bank.rs b/programs/marginfi-sdk/src/generated/instructions/lending_pool_configure_bank.rs index ab64319c..c7eeefd5 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_pool_configure_bank.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_pool_configure_bank.rs @@ -62,12 +62,12 @@ impl LendingPoolConfigureBank { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingPoolConfigureBankInstructionData { +pub struct LendingPoolConfigureBankInstructionData { discriminator: [u8; 8], } impl LendingPoolConfigureBankInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [121, 173, 156, 40, 93, 148, 56, 237], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_pool_handle_bankruptcy.rs b/programs/marginfi-sdk/src/generated/instructions/lending_pool_handle_bankruptcy.rs index f4e582c3..a7a17279 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_pool_handle_bankruptcy.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_pool_handle_bankruptcy.rs @@ -81,12 +81,12 @@ impl LendingPoolHandleBankruptcy { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingPoolHandleBankruptcyInstructionData { +pub struct LendingPoolHandleBankruptcyInstructionData { discriminator: [u8; 8], } impl LendingPoolHandleBankruptcyInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [162, 11, 56, 139, 90, 128, 70, 173], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_pool_setup_emissions.rs b/programs/marginfi-sdk/src/generated/instructions/lending_pool_setup_emissions.rs index e136b0aa..d1325aa6 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_pool_setup_emissions.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_pool_setup_emissions.rs @@ -93,12 +93,12 @@ impl LendingPoolSetupEmissions { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingPoolSetupEmissionsInstructionData { +pub struct LendingPoolSetupEmissionsInstructionData { discriminator: [u8; 8], } impl LendingPoolSetupEmissionsInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [206, 97, 120, 172, 113, 204, 169, 70], } diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_pool_update_emissions_parameters.rs b/programs/marginfi-sdk/src/generated/instructions/lending_pool_update_emissions_parameters.rs index 854c3ca6..5c6696b6 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_pool_update_emissions_parameters.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_pool_update_emissions_parameters.rs @@ -81,12 +81,12 @@ impl LendingPoolUpdateEmissionsParameters { } #[derive(BorshDeserialize, BorshSerialize)] -struct LendingPoolUpdateEmissionsParametersInstructionData { +pub struct LendingPoolUpdateEmissionsParametersInstructionData { discriminator: [u8; 8], } impl LendingPoolUpdateEmissionsParametersInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [55, 213, 224, 168, 153, 53, 197, 40], } diff --git a/programs/marginfi-sdk/src/generated/instructions/marginfi_account_initialize.rs b/programs/marginfi-sdk/src/generated/instructions/marginfi_account_initialize.rs index 2060b68a..9d59e497 100644 --- a/programs/marginfi-sdk/src/generated/instructions/marginfi_account_initialize.rs +++ b/programs/marginfi-sdk/src/generated/instructions/marginfi_account_initialize.rs @@ -65,12 +65,12 @@ impl MarginfiAccountInitialize { } #[derive(BorshDeserialize, BorshSerialize)] -struct MarginfiAccountInitializeInstructionData { +pub struct MarginfiAccountInitializeInstructionData { discriminator: [u8; 8], } impl MarginfiAccountInitializeInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [43, 78, 61, 255, 148, 52, 249, 154], } diff --git a/programs/marginfi-sdk/src/generated/instructions/marginfi_group_configure.rs b/programs/marginfi-sdk/src/generated/instructions/marginfi_group_configure.rs index fbbc3b9d..53933669 100644 --- a/programs/marginfi-sdk/src/generated/instructions/marginfi_group_configure.rs +++ b/programs/marginfi-sdk/src/generated/instructions/marginfi_group_configure.rs @@ -53,12 +53,12 @@ impl MarginfiGroupConfigure { } #[derive(BorshDeserialize, BorshSerialize)] -struct MarginfiGroupConfigureInstructionData { +pub struct MarginfiGroupConfigureInstructionData { discriminator: [u8; 8], } impl MarginfiGroupConfigureInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [62, 199, 81, 78, 33, 13, 236, 61], } diff --git a/programs/marginfi-sdk/src/generated/instructions/marginfi_group_initialize.rs b/programs/marginfi-sdk/src/generated/instructions/marginfi_group_initialize.rs index 21fa0a57..5dc1cc70 100644 --- a/programs/marginfi-sdk/src/generated/instructions/marginfi_group_initialize.rs +++ b/programs/marginfi-sdk/src/generated/instructions/marginfi_group_initialize.rs @@ -52,12 +52,12 @@ impl MarginfiGroupInitialize { } #[derive(BorshDeserialize, BorshSerialize)] -struct MarginfiGroupInitializeInstructionData { +pub struct MarginfiGroupInitializeInstructionData { discriminator: [u8; 8], } impl MarginfiGroupInitializeInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [255, 67, 67, 26, 94, 31, 34, 20], } diff --git a/programs/marginfi-sdk/src/generated/instructions/set_account_flag.rs b/programs/marginfi-sdk/src/generated/instructions/set_account_flag.rs index 09f0da95..84d6f4e7 100644 --- a/programs/marginfi-sdk/src/generated/instructions/set_account_flag.rs +++ b/programs/marginfi-sdk/src/generated/instructions/set_account_flag.rs @@ -56,12 +56,12 @@ impl SetAccountFlag { } #[derive(BorshDeserialize, BorshSerialize)] -struct SetAccountFlagInstructionData { +pub struct SetAccountFlagInstructionData { discriminator: [u8; 8], } impl SetAccountFlagInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [56, 238, 18, 207, 193, 82, 138, 174], } diff --git a/programs/marginfi-sdk/src/generated/instructions/set_new_account_authority.rs b/programs/marginfi-sdk/src/generated/instructions/set_new_account_authority.rs index 6c72ca18..ef380178 100644 --- a/programs/marginfi-sdk/src/generated/instructions/set_new_account_authority.rs +++ b/programs/marginfi-sdk/src/generated/instructions/set_new_account_authority.rs @@ -65,12 +65,12 @@ impl SetNewAccountAuthority { } #[derive(BorshDeserialize, BorshSerialize)] -struct SetNewAccountAuthorityInstructionData { +pub struct SetNewAccountAuthorityInstructionData { discriminator: [u8; 8], } impl SetNewAccountAuthorityInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [153, 162, 50, 84, 182, 201, 74, 179], } diff --git a/programs/marginfi-sdk/src/generated/instructions/unset_account_flag.rs b/programs/marginfi-sdk/src/generated/instructions/unset_account_flag.rs index fd0a80f1..12e24ab0 100644 --- a/programs/marginfi-sdk/src/generated/instructions/unset_account_flag.rs +++ b/programs/marginfi-sdk/src/generated/instructions/unset_account_flag.rs @@ -56,12 +56,12 @@ impl UnsetAccountFlag { } #[derive(BorshDeserialize, BorshSerialize)] -struct UnsetAccountFlagInstructionData { +pub struct UnsetAccountFlagInstructionData { discriminator: [u8; 8], } impl UnsetAccountFlagInstructionData { - fn new() -> Self { + pub fn new() -> Self { Self { discriminator: [56, 81, 56, 85, 92, 49, 255, 70], } diff --git a/programs/marginfi-sdk/src/generated/types/interest_rate_config.rs b/programs/marginfi-sdk/src/generated/types/interest_rate_config.rs index f996df89..ba0ded9f 100644 --- a/programs/marginfi-sdk/src/generated/types/interest_rate_config.rs +++ b/programs/marginfi-sdk/src/generated/types/interest_rate_config.rs @@ -22,5 +22,7 @@ pub struct InterestRateConfig { pub insurance_ir_fee: WrappedI80F48, pub protocol_fixed_fee_apr: WrappedI80F48, pub protocol_ir_fee: WrappedI80F48, - pub padding: [[u64; 2]; 8], + pub protocol_origination_fee: WrappedI80F48, + pub _padding0: [u8; 16], + pub _padding1: [[u8; 32]; 3], } diff --git a/programs/solauto-sdk/src/generated/accounts/solauto_position.rs b/programs/solauto-sdk/src/generated/accounts/solauto_position.rs index 533595f0..79a172ff 100644 --- a/programs/solauto-sdk/src/generated/accounts/solauto_position.rs +++ b/programs/solauto-sdk/src/generated/accounts/solauto_position.rs @@ -30,7 +30,7 @@ pub struct SolautoPosition { pub position: PositionData, pub state: PositionState, pub rebalance: RebalanceData, - pub padding: [u32; 32], + pub padding: [u32; 20], } impl SolautoPosition { diff --git a/programs/solauto-sdk/src/generated/errors/solauto.rs b/programs/solauto-sdk/src/generated/errors/solauto.rs index bd77a38b..88334ec8 100644 --- a/programs/solauto-sdk/src/generated/errors/solauto.rs +++ b/programs/solauto-sdk/src/generated/errors/solauto.rs @@ -10,33 +10,51 @@ use thiserror::Error; #[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)] pub enum SolautoError { - /// 0 (0x0) - Missing or incorrect accounts provided for the given instruction - #[error("Missing or incorrect accounts provided for the given instruction")] + /// 0 (0x0) - Missing or incorrect accounts provided for the given instructions + #[error("Missing or incorrect accounts provided for the given instructions")] IncorrectAccounts, /// 1 (0x1) - Failed to deserialize account data #[error("Failed to deserialize account data")] FailedAccountDeserialization, - /// 2 (0x2) - Invalid position settings provided - #[error("Invalid position settings provided")] - InvalidPositionSettings, - /// 3 (0x3) - Invalid DCA configuration provided + /// 2 (0x2) - Invalid Boost-to param + #[error("Invalid Boost-to param")] + InvalidBoostToSetting, + /// 3 (0x3) - Invalid Boost gap param + #[error("Invalid Boost gap param")] + InvalidBoostGapSetting, + /// 4 (0x4) - Invalid repay-to param + #[error("Invalid repay-to param")] + InvalidRepayToSetting, + /// 5 (0x5) - Invalid repay gap param + #[error("Invalid repay gap param")] + InvalidRepayGapSetting, + /// 6 (0x6) - Invalid repay-from (repay-to + repay gap) + #[error("Invalid repay-from (repay-to + repay gap)")] + InvalidRepayFromSetting, + /// 7 (0x7) - Invalid DCA configuration provided #[error("Invalid DCA configuration provided")] InvalidDCASettings, - /// 4 (0x4) - Invalid automation settings provided + /// 8 (0x8) - Invalid automation settings provided #[error("Invalid automation settings provided")] InvalidAutomationData, - /// 5 (0x5) - Invalid position condition to rebalance + /// 9 (0x9) - Invalid position condition to rebalance #[error("Invalid position condition to rebalance")] InvalidRebalanceCondition, - /// 6 (0x6) - Unable to invoke instruction through a CPI + /// 10 (0xA) - Unable to invoke instruction through a CPI #[error("Unable to invoke instruction through a CPI")] InstructionIsCPI, - /// 7 (0x7) - Incorrect set of instructions in the transaction - #[error("Incorrect set of instructions in the transaction")] + /// 11 (0xB) - Incorrect set of instructions or instruction data in the transaction + #[error("Incorrect set of instructions or instruction data in the transaction")] IncorrectInstructions, - /// 8 (0x8) - Incorrect swap amount provided. Likely due to high price volatility + /// 12 (0xC) - Incorrect swap amount provided. Likely due to high price volatility #[error("Incorrect swap amount provided. Likely due to high price volatility")] IncorrectDebtAdjustment, + /// 13 (0xD) - Invalid rebalance was made. Target supply USD and target debt USD was not met + #[error("Invalid rebalance was made. Target supply USD and target debt USD was not met")] + InvalidRebalanceMade, + /// 14 (0xE) - Cannot provide a target liquidation utilization rate if the instruction is not signed by the position authority + #[error("Cannot provide a target liquidation utilization rate if the instruction is not signed by the position authority")] + NonAuthorityProvidedTargetLTV, } impl solana_program::program_error::PrintProgramError for SolautoError { diff --git a/programs/solauto-sdk/src/generated/instructions/claim_referral_fees.rs b/programs/solauto-sdk/src/generated/instructions/claim_referral_fees.rs index bd639068..b53145a8 100644 --- a/programs/solauto-sdk/src/generated/instructions/claim_referral_fees.rs +++ b/programs/solauto-sdk/src/generated/instructions/claim_referral_fees.rs @@ -28,7 +28,7 @@ pub struct ClaimReferralFees { pub referral_fees_dest_mint: solana_program::pubkey::Pubkey, - pub referral_authority: Option, + pub referral_authority: solana_program::pubkey::Pubkey, pub fees_destination_ta: Option, } @@ -85,17 +85,10 @@ impl ClaimReferralFees { self.referral_fees_dest_mint, false, )); - if let Some(referral_authority) = self.referral_authority { - accounts.push(solana_program::instruction::AccountMeta::new( - referral_authority, - false, - )); - } else { - accounts.push(solana_program::instruction::AccountMeta::new_readonly( - crate::SOLAUTO_ID, - false, - )); - } + accounts.push(solana_program::instruction::AccountMeta::new( + self.referral_authority, + false, + )); if let Some(fees_destination_ta) = self.fees_destination_ta { accounts.push(solana_program::instruction::AccountMeta::new( fees_destination_ta, @@ -144,7 +137,7 @@ impl ClaimReferralFeesInstructionData { /// 6. `[]` referral_state /// 7. `[writable]` referral_fees_dest_ta /// 8. `[]` referral_fees_dest_mint -/// 9. `[writable, optional]` referral_authority +/// 9. `[writable]` referral_authority /// 10. `[writable, optional]` fees_destination_ta #[derive(Default)] pub struct ClaimReferralFeesBuilder { @@ -225,13 +218,12 @@ impl ClaimReferralFeesBuilder { self.referral_fees_dest_mint = Some(referral_fees_dest_mint); self } - /// `[optional account]` #[inline(always)] pub fn referral_authority( &mut self, - referral_authority: Option, + referral_authority: solana_program::pubkey::Pubkey, ) -> &mut Self { - self.referral_authority = referral_authority; + self.referral_authority = Some(referral_authority); self } /// `[optional account]` @@ -285,7 +277,9 @@ impl ClaimReferralFeesBuilder { referral_fees_dest_mint: self .referral_fees_dest_mint .expect("referral_fees_dest_mint is not set"), - referral_authority: self.referral_authority, + referral_authority: self + .referral_authority + .expect("referral_authority is not set"), fees_destination_ta: self.fees_destination_ta, }; @@ -313,7 +307,7 @@ pub struct ClaimReferralFeesCpiAccounts<'a, 'b> { pub referral_fees_dest_mint: &'b solana_program::account_info::AccountInfo<'a>, - pub referral_authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, + pub referral_authority: &'b solana_program::account_info::AccountInfo<'a>, pub fees_destination_ta: Option<&'b solana_program::account_info::AccountInfo<'a>>, } @@ -341,7 +335,7 @@ pub struct ClaimReferralFeesCpi<'a, 'b> { pub referral_fees_dest_mint: &'b solana_program::account_info::AccountInfo<'a>, - pub referral_authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, + pub referral_authority: &'b solana_program::account_info::AccountInfo<'a>, pub fees_destination_ta: Option<&'b solana_program::account_info::AccountInfo<'a>>, } @@ -443,17 +437,10 @@ impl<'a, 'b> ClaimReferralFeesCpi<'a, 'b> { *self.referral_fees_dest_mint.key, false, )); - if let Some(referral_authority) = self.referral_authority { - accounts.push(solana_program::instruction::AccountMeta::new( - *referral_authority.key, - false, - )); - } else { - accounts.push(solana_program::instruction::AccountMeta::new_readonly( - crate::SOLAUTO_ID, - false, - )); - } + accounts.push(solana_program::instruction::AccountMeta::new( + *self.referral_authority.key, + false, + )); if let Some(fees_destination_ta) = self.fees_destination_ta { accounts.push(solana_program::instruction::AccountMeta::new( *fees_destination_ta.key, @@ -494,9 +481,7 @@ impl<'a, 'b> ClaimReferralFeesCpi<'a, 'b> { account_infos.push(self.referral_state.clone()); account_infos.push(self.referral_fees_dest_ta.clone()); account_infos.push(self.referral_fees_dest_mint.clone()); - if let Some(referral_authority) = self.referral_authority { - account_infos.push(referral_authority.clone()); - } + account_infos.push(self.referral_authority.clone()); if let Some(fees_destination_ta) = self.fees_destination_ta { account_infos.push(fees_destination_ta.clone()); } @@ -525,7 +510,7 @@ impl<'a, 'b> ClaimReferralFeesCpi<'a, 'b> { /// 6. `[]` referral_state /// 7. `[writable]` referral_fees_dest_ta /// 8. `[]` referral_fees_dest_mint -/// 9. `[writable, optional]` referral_authority +/// 9. `[writable]` referral_authority /// 10. `[writable, optional]` fees_destination_ta pub struct ClaimReferralFeesCpiBuilder<'a, 'b> { instruction: Box>, @@ -620,13 +605,12 @@ impl<'a, 'b> ClaimReferralFeesCpiBuilder<'a, 'b> { self.instruction.referral_fees_dest_mint = Some(referral_fees_dest_mint); self } - /// `[optional account]` #[inline(always)] pub fn referral_authority( &mut self, - referral_authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, + referral_authority: &'b solana_program::account_info::AccountInfo<'a>, ) -> &mut Self { - self.instruction.referral_authority = referral_authority; + self.instruction.referral_authority = Some(referral_authority); self } /// `[optional account]` @@ -718,7 +702,10 @@ impl<'a, 'b> ClaimReferralFeesCpiBuilder<'a, 'b> { .referral_fees_dest_mint .expect("referral_fees_dest_mint is not set"), - referral_authority: self.instruction.referral_authority, + referral_authority: self + .instruction + .referral_authority + .expect("referral_authority is not set"), fees_destination_ta: self.instruction.fees_destination_ta, }; diff --git a/programs/solauto-sdk/src/generated/instructions/close_position.rs b/programs/solauto-sdk/src/generated/instructions/close_position.rs index 68fb0855..b03aeb5c 100644 --- a/programs/solauto-sdk/src/generated/instructions/close_position.rs +++ b/programs/solauto-sdk/src/generated/instructions/close_position.rs @@ -20,7 +20,7 @@ pub struct ClosePosition { pub solauto_position: solana_program::pubkey::Pubkey, - pub protocol_account: solana_program::pubkey::Pubkey, + pub lp_user_account: solana_program::pubkey::Pubkey, pub position_supply_ta: solana_program::pubkey::Pubkey, @@ -62,7 +62,7 @@ impl ClosePosition { false, )); accounts.push(solana_program::instruction::AccountMeta::new( - self.protocol_account, + self.lp_user_account, false, )); accounts.push(solana_program::instruction::AccountMeta::new( @@ -112,7 +112,7 @@ impl ClosePositionInstructionData { /// 2. `[optional]` token_program (default to `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`) /// 3. `[optional]` ata_program (default to `ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL`) /// 4. `[writable]` solauto_position -/// 5. `[writable]` protocol_account +/// 5. `[writable]` lp_user_account /// 6. `[writable]` position_supply_ta /// 7. `[writable]` signer_supply_ta /// 8. `[writable]` position_debt_ta @@ -124,7 +124,7 @@ pub struct ClosePositionBuilder { token_program: Option, ata_program: Option, solauto_position: Option, - protocol_account: Option, + lp_user_account: Option, position_supply_ta: Option, signer_supply_ta: Option, position_debt_ta: Option, @@ -168,11 +168,11 @@ impl ClosePositionBuilder { self } #[inline(always)] - pub fn protocol_account( + pub fn lp_user_account( &mut self, - protocol_account: solana_program::pubkey::Pubkey, + lp_user_account: solana_program::pubkey::Pubkey, ) -> &mut Self { - self.protocol_account = Some(protocol_account); + self.lp_user_account = Some(lp_user_account); self } #[inline(always)] @@ -236,7 +236,7 @@ impl ClosePositionBuilder { "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" )), solauto_position: self.solauto_position.expect("solauto_position is not set"), - protocol_account: self.protocol_account.expect("protocol_account is not set"), + lp_user_account: self.lp_user_account.expect("lp_user_account is not set"), position_supply_ta: self .position_supply_ta .expect("position_supply_ta is not set"), @@ -261,7 +261,7 @@ pub struct ClosePositionCpiAccounts<'a, 'b> { pub solauto_position: &'b solana_program::account_info::AccountInfo<'a>, - pub protocol_account: &'b solana_program::account_info::AccountInfo<'a>, + pub lp_user_account: &'b solana_program::account_info::AccountInfo<'a>, pub position_supply_ta: &'b solana_program::account_info::AccountInfo<'a>, @@ -287,7 +287,7 @@ pub struct ClosePositionCpi<'a, 'b> { pub solauto_position: &'b solana_program::account_info::AccountInfo<'a>, - pub protocol_account: &'b solana_program::account_info::AccountInfo<'a>, + pub lp_user_account: &'b solana_program::account_info::AccountInfo<'a>, pub position_supply_ta: &'b solana_program::account_info::AccountInfo<'a>, @@ -310,7 +310,7 @@ impl<'a, 'b> ClosePositionCpi<'a, 'b> { token_program: accounts.token_program, ata_program: accounts.ata_program, solauto_position: accounts.solauto_position, - protocol_account: accounts.protocol_account, + lp_user_account: accounts.lp_user_account, position_supply_ta: accounts.position_supply_ta, signer_supply_ta: accounts.signer_supply_ta, position_debt_ta: accounts.position_debt_ta, @@ -372,7 +372,7 @@ impl<'a, 'b> ClosePositionCpi<'a, 'b> { false, )); accounts.push(solana_program::instruction::AccountMeta::new( - *self.protocol_account.key, + *self.lp_user_account.key, false, )); accounts.push(solana_program::instruction::AccountMeta::new( @@ -412,7 +412,7 @@ impl<'a, 'b> ClosePositionCpi<'a, 'b> { account_infos.push(self.token_program.clone()); account_infos.push(self.ata_program.clone()); account_infos.push(self.solauto_position.clone()); - account_infos.push(self.protocol_account.clone()); + account_infos.push(self.lp_user_account.clone()); account_infos.push(self.position_supply_ta.clone()); account_infos.push(self.signer_supply_ta.clone()); account_infos.push(self.position_debt_ta.clone()); @@ -438,7 +438,7 @@ impl<'a, 'b> ClosePositionCpi<'a, 'b> { /// 2. `[]` token_program /// 3. `[]` ata_program /// 4. `[writable]` solauto_position -/// 5. `[writable]` protocol_account +/// 5. `[writable]` lp_user_account /// 6. `[writable]` position_supply_ta /// 7. `[writable]` signer_supply_ta /// 8. `[writable]` position_debt_ta @@ -456,7 +456,7 @@ impl<'a, 'b> ClosePositionCpiBuilder<'a, 'b> { token_program: None, ata_program: None, solauto_position: None, - protocol_account: None, + lp_user_account: None, position_supply_ta: None, signer_supply_ta: None, position_debt_ta: None, @@ -506,11 +506,11 @@ impl<'a, 'b> ClosePositionCpiBuilder<'a, 'b> { self } #[inline(always)] - pub fn protocol_account( + pub fn lp_user_account( &mut self, - protocol_account: &'b solana_program::account_info::AccountInfo<'a>, + lp_user_account: &'b solana_program::account_info::AccountInfo<'a>, ) -> &mut Self { - self.instruction.protocol_account = Some(protocol_account); + self.instruction.lp_user_account = Some(lp_user_account); self } #[inline(always)] @@ -611,10 +611,10 @@ impl<'a, 'b> ClosePositionCpiBuilder<'a, 'b> { .solauto_position .expect("solauto_position is not set"), - protocol_account: self + lp_user_account: self .instruction - .protocol_account - .expect("protocol_account is not set"), + .lp_user_account + .expect("lp_user_account is not set"), position_supply_ta: self .instruction @@ -650,7 +650,7 @@ struct ClosePositionCpiBuilderInstruction<'a, 'b> { token_program: Option<&'b solana_program::account_info::AccountInfo<'a>>, ata_program: Option<&'b solana_program::account_info::AccountInfo<'a>>, solauto_position: Option<&'b solana_program::account_info::AccountInfo<'a>>, - protocol_account: Option<&'b solana_program::account_info::AccountInfo<'a>>, + lp_user_account: Option<&'b solana_program::account_info::AccountInfo<'a>>, position_supply_ta: Option<&'b solana_program::account_info::AccountInfo<'a>>, signer_supply_ta: Option<&'b solana_program::account_info::AccountInfo<'a>>, position_debt_ta: Option<&'b solana_program::account_info::AccountInfo<'a>>, diff --git a/programs/solauto-sdk/src/generated/instructions/marginfi_open_position.rs b/programs/solauto-sdk/src/generated/instructions/marginfi_open_position.rs index 5a44524c..446e2b78 100644 --- a/programs/solauto-sdk/src/generated/instructions/marginfi_open_position.rs +++ b/programs/solauto-sdk/src/generated/instructions/marginfi_open_position.rs @@ -192,7 +192,6 @@ impl MarginfiOpenPositionInstructionData { pub struct MarginfiOpenPositionInstructionArgs { pub position_type: PositionType, pub position_data: UpdatePositionData, - pub marginfi_account_seed_idx: Option, } /// Instruction builder for `MarginfiOpenPosition`. @@ -241,7 +240,6 @@ pub struct MarginfiOpenPositionBuilder { signer_debt_ta: Option, position_type: Option, position_data: Option, - marginfi_account_seed_idx: Option, __remaining_accounts: Vec, } @@ -389,12 +387,6 @@ impl MarginfiOpenPositionBuilder { self.position_data = Some(position_data); self } - /// `[optional argument]` - #[inline(always)] - pub fn marginfi_account_seed_idx(&mut self, marginfi_account_seed_idx: u64) -> &mut Self { - self.marginfi_account_seed_idx = Some(marginfi_account_seed_idx); - self - } /// Add an aditional account to the instruction. #[inline(always)] pub fn add_remaining_account( @@ -457,7 +449,6 @@ impl MarginfiOpenPositionBuilder { .position_data .clone() .expect("position_data is not set"), - marginfi_account_seed_idx: self.marginfi_account_seed_idx.clone(), }; accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) @@ -821,7 +812,6 @@ impl<'a, 'b> MarginfiOpenPositionCpiBuilder<'a, 'b> { signer_debt_ta: None, position_type: None, position_data: None, - marginfi_account_seed_idx: None, __remaining_accounts: Vec::new(), }); Self { instruction } @@ -989,12 +979,6 @@ impl<'a, 'b> MarginfiOpenPositionCpiBuilder<'a, 'b> { self.instruction.position_data = Some(position_data); self } - /// `[optional argument]` - #[inline(always)] - pub fn marginfi_account_seed_idx(&mut self, marginfi_account_seed_idx: u64) -> &mut Self { - self.instruction.marginfi_account_seed_idx = Some(marginfi_account_seed_idx); - self - } /// Add an additional account to the instruction. #[inline(always)] pub fn add_remaining_account( @@ -1047,7 +1031,6 @@ impl<'a, 'b> MarginfiOpenPositionCpiBuilder<'a, 'b> { .position_data .clone() .expect("position_data is not set"), - marginfi_account_seed_idx: self.instruction.marginfi_account_seed_idx.clone(), }; let instruction = MarginfiOpenPositionCpi { __program: self.instruction.__program, @@ -1157,7 +1140,6 @@ struct MarginfiOpenPositionCpiBuilderInstruction<'a, 'b> { signer_debt_ta: Option<&'b solana_program::account_info::AccountInfo<'a>>, position_type: Option, position_data: Option, - marginfi_account_seed_idx: Option, /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. __remaining_accounts: Vec<( &'b solana_program::account_info::AccountInfo<'a>, diff --git a/programs/solauto-sdk/src/generated/instructions/marginfi_rebalance.rs b/programs/solauto-sdk/src/generated/instructions/marginfi_rebalance.rs index 51c587d7..f60a9c17 100644 --- a/programs/solauto-sdk/src/generated/instructions/marginfi_rebalance.rs +++ b/programs/solauto-sdk/src/generated/instructions/marginfi_rebalance.rs @@ -5,7 +5,9 @@ //! [https://github.com/metaplex-foundation/kinobi] //! +use crate::generated::types::PriceType; use crate::generated::types::SolautoRebalanceType; +use crate::generated::types::SwapType; use borsh::BorshDeserialize; use borsh::BorshSerialize; @@ -290,8 +292,11 @@ impl MarginfiRebalanceInstructionData { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct MarginfiRebalanceInstructionArgs { pub rebalance_type: SolautoRebalanceType, + pub swap_in_amount_base_unit: Option, pub target_liq_utilization_rate_bps: Option, - pub target_in_amount_base_unit: Option, + pub flash_loan_fee_bps: Option, + pub price_type: Option, + pub swap_type: Option, } /// Instruction builder for `MarginfiRebalance`. @@ -351,8 +356,11 @@ pub struct MarginfiRebalanceBuilder { vault_debt_ta: Option, debt_vault_authority: Option, rebalance_type: Option, + swap_in_amount_base_unit: Option, target_liq_utilization_rate_bps: Option, - target_in_amount_base_unit: Option, + flash_loan_fee_bps: Option, + price_type: Option, + swap_type: Option, __remaining_accounts: Vec, } @@ -560,6 +568,12 @@ impl MarginfiRebalanceBuilder { } /// `[optional argument]` #[inline(always)] + pub fn swap_in_amount_base_unit(&mut self, swap_in_amount_base_unit: u64) -> &mut Self { + self.swap_in_amount_base_unit = Some(swap_in_amount_base_unit); + self + } + /// `[optional argument]` + #[inline(always)] pub fn target_liq_utilization_rate_bps( &mut self, target_liq_utilization_rate_bps: u16, @@ -569,8 +583,20 @@ impl MarginfiRebalanceBuilder { } /// `[optional argument]` #[inline(always)] - pub fn target_in_amount_base_unit(&mut self, target_in_amount_base_unit: u64) -> &mut Self { - self.target_in_amount_base_unit = Some(target_in_amount_base_unit); + pub fn flash_loan_fee_bps(&mut self, flash_loan_fee_bps: u16) -> &mut Self { + self.flash_loan_fee_bps = Some(flash_loan_fee_bps); + self + } + /// `[optional argument]` + #[inline(always)] + pub fn price_type(&mut self, price_type: PriceType) -> &mut Self { + self.price_type = Some(price_type); + self + } + /// `[optional argument]` + #[inline(always)] + pub fn swap_type(&mut self, swap_type: SwapType) -> &mut Self { + self.swap_type = Some(swap_type); self } /// Add an aditional account to the instruction. @@ -633,8 +659,11 @@ impl MarginfiRebalanceBuilder { .rebalance_type .clone() .expect("rebalance_type is not set"), + swap_in_amount_base_unit: self.swap_in_amount_base_unit.clone(), target_liq_utilization_rate_bps: self.target_liq_utilization_rate_bps.clone(), - target_in_amount_base_unit: self.target_in_amount_base_unit.clone(), + flash_loan_fee_bps: self.flash_loan_fee_bps.clone(), + price_type: self.price_type.clone(), + swap_type: self.swap_type.clone(), }; accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) @@ -1150,8 +1179,11 @@ impl<'a, 'b> MarginfiRebalanceCpiBuilder<'a, 'b> { vault_debt_ta: None, debt_vault_authority: None, rebalance_type: None, + swap_in_amount_base_unit: None, target_liq_utilization_rate_bps: None, - target_in_amount_base_unit: None, + flash_loan_fee_bps: None, + price_type: None, + swap_type: None, __remaining_accounts: Vec::new(), }); Self { instruction } @@ -1375,6 +1407,12 @@ impl<'a, 'b> MarginfiRebalanceCpiBuilder<'a, 'b> { } /// `[optional argument]` #[inline(always)] + pub fn swap_in_amount_base_unit(&mut self, swap_in_amount_base_unit: u64) -> &mut Self { + self.instruction.swap_in_amount_base_unit = Some(swap_in_amount_base_unit); + self + } + /// `[optional argument]` + #[inline(always)] pub fn target_liq_utilization_rate_bps( &mut self, target_liq_utilization_rate_bps: u16, @@ -1384,8 +1422,20 @@ impl<'a, 'b> MarginfiRebalanceCpiBuilder<'a, 'b> { } /// `[optional argument]` #[inline(always)] - pub fn target_in_amount_base_unit(&mut self, target_in_amount_base_unit: u64) -> &mut Self { - self.instruction.target_in_amount_base_unit = Some(target_in_amount_base_unit); + pub fn flash_loan_fee_bps(&mut self, flash_loan_fee_bps: u16) -> &mut Self { + self.instruction.flash_loan_fee_bps = Some(flash_loan_fee_bps); + self + } + /// `[optional argument]` + #[inline(always)] + pub fn price_type(&mut self, price_type: PriceType) -> &mut Self { + self.instruction.price_type = Some(price_type); + self + } + /// `[optional argument]` + #[inline(always)] + pub fn swap_type(&mut self, swap_type: SwapType) -> &mut Self { + self.instruction.swap_type = Some(swap_type); self } /// Add an additional account to the instruction. @@ -1435,11 +1485,14 @@ impl<'a, 'b> MarginfiRebalanceCpiBuilder<'a, 'b> { .rebalance_type .clone() .expect("rebalance_type is not set"), + swap_in_amount_base_unit: self.instruction.swap_in_amount_base_unit.clone(), target_liq_utilization_rate_bps: self .instruction .target_liq_utilization_rate_bps .clone(), - target_in_amount_base_unit: self.instruction.target_in_amount_base_unit.clone(), + flash_loan_fee_bps: self.instruction.flash_loan_fee_bps.clone(), + price_type: self.instruction.price_type.clone(), + swap_type: self.instruction.swap_type.clone(), }; let instruction = MarginfiRebalanceCpi { __program: self.instruction.__program, @@ -1560,8 +1613,11 @@ struct MarginfiRebalanceCpiBuilderInstruction<'a, 'b> { vault_debt_ta: Option<&'b solana_program::account_info::AccountInfo<'a>>, debt_vault_authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, rebalance_type: Option, + swap_in_amount_base_unit: Option, target_liq_utilization_rate_bps: Option, - target_in_amount_base_unit: Option, + flash_loan_fee_bps: Option, + price_type: Option, + swap_type: Option, /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. __remaining_accounts: Vec<( &'b solana_program::account_info::AccountInfo<'a>, diff --git a/programs/solauto-sdk/src/generated/instructions/marginfi_refresh_data.rs b/programs/solauto-sdk/src/generated/instructions/marginfi_refresh_data.rs index 69e352e0..089770a2 100644 --- a/programs/solauto-sdk/src/generated/instructions/marginfi_refresh_data.rs +++ b/programs/solauto-sdk/src/generated/instructions/marginfi_refresh_data.rs @@ -5,6 +5,7 @@ //! [https://github.com/metaplex-foundation/kinobi] //! +use crate::generated::types::PriceType; use borsh::BorshDeserialize; use borsh::BorshSerialize; @@ -30,12 +31,16 @@ pub struct MarginfiRefreshData { } impl MarginfiRefreshData { - pub fn instruction(&self) -> solana_program::instruction::Instruction { - self.instruction_with_remaining_accounts(&[]) + pub fn instruction( + &self, + args: MarginfiRefreshDataInstructionArgs, + ) -> solana_program::instruction::Instruction { + self.instruction_with_remaining_accounts(args, &[]) } #[allow(clippy::vec_init_then_push)] pub fn instruction_with_remaining_accounts( &self, + args: MarginfiRefreshDataInstructionArgs, remaining_accounts: &[solana_program::instruction::AccountMeta], ) -> solana_program::instruction::Instruction { let mut accounts = Vec::with_capacity(9 + remaining_accounts.len()); @@ -76,9 +81,11 @@ impl MarginfiRefreshData { false, )); accounts.extend_from_slice(remaining_accounts); - let data = MarginfiRefreshDataInstructionData::new() + let mut data = MarginfiRefreshDataInstructionData::new() .try_to_vec() .unwrap(); + let mut args = args.try_to_vec().unwrap(); + data.append(&mut args); solana_program::instruction::Instruction { program_id: crate::SOLAUTO_ID, @@ -99,6 +106,12 @@ impl MarginfiRefreshDataInstructionData { } } +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct MarginfiRefreshDataInstructionArgs { + pub price_type: PriceType, +} + /// Instruction builder for `MarginfiRefreshData`. /// /// ### Accounts: @@ -123,6 +136,7 @@ pub struct MarginfiRefreshDataBuilder { debt_bank: Option, debt_price_oracle: Option, solauto_position: Option, + price_type: Option, __remaining_accounts: Vec, } @@ -190,6 +204,11 @@ impl MarginfiRefreshDataBuilder { self.solauto_position = Some(solauto_position); self } + #[inline(always)] + pub fn price_type(&mut self, price_type: PriceType) -> &mut Self { + self.price_type = Some(price_type); + self + } /// Add an aditional account to the instruction. #[inline(always)] pub fn add_remaining_account( @@ -225,8 +244,11 @@ impl MarginfiRefreshDataBuilder { .expect("debt_price_oracle is not set"), solauto_position: self.solauto_position.expect("solauto_position is not set"), }; + let args = MarginfiRefreshDataInstructionArgs { + price_type: self.price_type.clone().expect("price_type is not set"), + }; - accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts) } } @@ -273,12 +295,15 @@ pub struct MarginfiRefreshDataCpi<'a, 'b> { pub debt_price_oracle: &'b solana_program::account_info::AccountInfo<'a>, pub solauto_position: &'b solana_program::account_info::AccountInfo<'a>, + /// The arguments for the instruction. + pub __args: MarginfiRefreshDataInstructionArgs, } impl<'a, 'b> MarginfiRefreshDataCpi<'a, 'b> { pub fn new( program: &'b solana_program::account_info::AccountInfo<'a>, accounts: MarginfiRefreshDataCpiAccounts<'a, 'b>, + args: MarginfiRefreshDataInstructionArgs, ) -> Self { Self { __program: program, @@ -291,6 +316,7 @@ impl<'a, 'b> MarginfiRefreshDataCpi<'a, 'b> { debt_bank: accounts.debt_bank, debt_price_oracle: accounts.debt_price_oracle, solauto_position: accounts.solauto_position, + __args: args, } } #[inline(always)] @@ -370,9 +396,11 @@ impl<'a, 'b> MarginfiRefreshDataCpi<'a, 'b> { is_writable: remaining_account.2, }) }); - let data = MarginfiRefreshDataInstructionData::new() + let mut data = MarginfiRefreshDataInstructionData::new() .try_to_vec() .unwrap(); + let mut args = self.__args.try_to_vec().unwrap(); + data.append(&mut args); let instruction = solana_program::instruction::Instruction { program_id: crate::SOLAUTO_ID, @@ -432,6 +460,7 @@ impl<'a, 'b> MarginfiRefreshDataCpiBuilder<'a, 'b> { debt_bank: None, debt_price_oracle: None, solauto_position: None, + price_type: None, __remaining_accounts: Vec::new(), }); Self { instruction } @@ -508,6 +537,11 @@ impl<'a, 'b> MarginfiRefreshDataCpiBuilder<'a, 'b> { self.instruction.solauto_position = Some(solauto_position); self } + #[inline(always)] + pub fn price_type(&mut self, price_type: PriceType) -> &mut Self { + self.instruction.price_type = Some(price_type); + self + } /// Add an additional account to the instruction. #[inline(always)] pub fn add_remaining_account( @@ -549,6 +583,13 @@ impl<'a, 'b> MarginfiRefreshDataCpiBuilder<'a, 'b> { &self, signers_seeds: &[&[&[u8]]], ) -> solana_program::entrypoint::ProgramResult { + let args = MarginfiRefreshDataInstructionArgs { + price_type: self + .instruction + .price_type + .clone() + .expect("price_type is not set"), + }; let instruction = MarginfiRefreshDataCpi { __program: self.instruction.__program, @@ -590,6 +631,7 @@ impl<'a, 'b> MarginfiRefreshDataCpiBuilder<'a, 'b> { .instruction .solauto_position .expect("solauto_position is not set"), + __args: args, }; instruction.invoke_signed_with_remaining_accounts( signers_seeds, @@ -609,6 +651,7 @@ struct MarginfiRefreshDataCpiBuilderInstruction<'a, 'b> { debt_bank: Option<&'b solana_program::account_info::AccountInfo<'a>>, debt_price_oracle: Option<&'b solana_program::account_info::AccountInfo<'a>>, solauto_position: Option<&'b solana_program::account_info::AccountInfo<'a>>, + price_type: Option, /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. __remaining_accounts: Vec<( &'b solana_program::account_info::AccountInfo<'a>, diff --git a/programs/solauto-sdk/src/generated/types/mod.rs b/programs/solauto-sdk/src/generated/types/mod.rs index 9e9099f0..447e7c40 100644 --- a/programs/solauto-sdk/src/generated/types/mod.rs +++ b/programs/solauto-sdk/src/generated/types/mod.rs @@ -13,16 +13,23 @@ pub(crate) mod r#lending_platform; pub(crate) mod r#pod_bool; pub(crate) mod r#position_data; pub(crate) mod r#position_state; -pub(crate) mod r#position_token_usage; +pub(crate) mod r#position_token_state; pub(crate) mod r#position_type; +pub(crate) mod r#price_type; pub(crate) mod r#rebalance_data; pub(crate) mod r#rebalance_direction; +pub(crate) mod r#rebalance_instruction_data; +pub(crate) mod r#rebalance_state_values; +pub(crate) mod r#rebalance_step; pub(crate) mod r#solauto_action; pub(crate) mod r#solauto_rebalance_type; pub(crate) mod r#solauto_settings_parameters; pub(crate) mod r#solauto_settings_parameters_inp; +pub(crate) mod r#swap_type; pub(crate) mod r#token_amount; pub(crate) mod r#token_balance_amount; +pub(crate) mod r#token_balance_change; +pub(crate) mod r#token_balance_change_type; pub(crate) mod r#token_type; pub(crate) mod r#update_position_data; @@ -34,15 +41,22 @@ pub use self::r#lending_platform::*; pub use self::r#pod_bool::*; pub use self::r#position_data::*; pub use self::r#position_state::*; -pub use self::r#position_token_usage::*; +pub use self::r#position_token_state::*; pub use self::r#position_type::*; +pub use self::r#price_type::*; pub use self::r#rebalance_data::*; pub use self::r#rebalance_direction::*; +pub use self::r#rebalance_instruction_data::*; +pub use self::r#rebalance_state_values::*; +pub use self::r#rebalance_step::*; pub use self::r#solauto_action::*; pub use self::r#solauto_rebalance_type::*; pub use self::r#solauto_settings_parameters::*; pub use self::r#solauto_settings_parameters_inp::*; +pub use self::r#swap_type::*; pub use self::r#token_amount::*; pub use self::r#token_balance_amount::*; +pub use self::r#token_balance_change::*; +pub use self::r#token_balance_change_type::*; pub use self::r#token_type::*; pub use self::r#update_position_data::*; diff --git a/programs/solauto-sdk/src/generated/types/position_data.rs b/programs/solauto-sdk/src/generated/types/position_data.rs index b242e31b..810803c2 100644 --- a/programs/solauto-sdk/src/generated/types/position_data.rs +++ b/programs/solauto-sdk/src/generated/types/position_data.rs @@ -5,7 +5,6 @@ //! [https://github.com/metaplex-foundation/kinobi] //! -use crate::generated::types::DCASettings; use crate::generated::types::LendingPlatform; use crate::generated::types::SolautoSettingsParameters; use borsh::BorshDeserialize; @@ -21,18 +20,22 @@ pub struct PositionData { feature = "serde", serde(with = "serde_with::As::") )] - pub protocol_user_account: Pubkey, + pub lp_user_account: Pubkey, #[cfg_attr( feature = "serde", serde(with = "serde_with::As::") )] - pub protocol_supply_account: Pubkey, + pub lp_supply_account: Pubkey, #[cfg_attr( feature = "serde", serde(with = "serde_with::As::") )] - pub protocol_debt_account: Pubkey, - pub setting_params: SolautoSettingsParameters, - pub dca: DCASettings, - pub padding: [u32; 4], + pub lp_debt_account: Pubkey, + pub settings: SolautoSettingsParameters, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub lp_pool_account: Pubkey, + pub padding: [u32; 20], } diff --git a/programs/solauto-sdk/src/generated/types/position_state.rs b/programs/solauto-sdk/src/generated/types/position_state.rs index 7cb41a62..5e104988 100644 --- a/programs/solauto-sdk/src/generated/types/position_state.rs +++ b/programs/solauto-sdk/src/generated/types/position_state.rs @@ -5,7 +5,7 @@ //! [https://github.com/metaplex-foundation/kinobi] //! -use crate::generated::types::PositionTokenUsage; +use crate::generated::types::PositionTokenState; use crate::generated::types::TokenAmount; use borsh::BorshDeserialize; use borsh::BorshSerialize; @@ -16,11 +16,11 @@ pub struct PositionState { pub liq_utilization_rate_bps: u16, pub padding1: [u8; 6], pub net_worth: TokenAmount, - pub supply: PositionTokenUsage, - pub debt: PositionTokenUsage, + pub supply: PositionTokenState, + pub debt: PositionTokenState, pub max_ltv_bps: u16, pub liq_threshold_bps: u16, pub padding2: [u8; 4], - pub last_updated: u64, + pub last_refreshed: u64, pub padding: [u32; 2], } diff --git a/programs/solauto-sdk/src/generated/types/position_token_usage.rs b/programs/solauto-sdk/src/generated/types/position_token_state.rs similarity index 87% rename from programs/solauto-sdk/src/generated/types/position_token_usage.rs rename to programs/solauto-sdk/src/generated/types/position_token_state.rs index c4ded889..23cbccac 100644 --- a/programs/solauto-sdk/src/generated/types/position_token_usage.rs +++ b/programs/solauto-sdk/src/generated/types/position_token_state.rs @@ -12,19 +12,18 @@ use solana_program::pubkey::Pubkey; #[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct PositionTokenUsage { +pub struct PositionTokenState { #[cfg_attr( feature = "serde", serde(with = "serde_with::As::") )] pub mint: Pubkey, pub decimals: u8, - pub padding1: [u8; 7], + pub padding1: [u8; 5], + pub borrow_fee_bps: u16, pub amount_used: TokenAmount, pub amount_can_be_used: TokenAmount, pub base_amount_market_price_usd: u64, - pub flash_loan_fee_bps: u16, - pub borrow_fee_bps: u16, - pub padding2: [u8; 4], + pub padding2: [u8; 8], pub padding: [u8; 32], } diff --git a/programs/solauto-sdk/src/generated/types/price_type.rs b/programs/solauto-sdk/src/generated/types/price_type.rs new file mode 100644 index 00000000..1591656e --- /dev/null +++ b/programs/solauto-sdk/src/generated/types/price_type.rs @@ -0,0 +1,19 @@ +//! This code was AUTOGENERATED using the kinobi library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun kinobi to update it. +//! +//! [https://github.com/metaplex-foundation/kinobi] +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq, PartialOrd, Hash, FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum PriceType { + Realtime, + Ema, +} diff --git a/programs/solauto-sdk/src/generated/types/rebalance_data.rs b/programs/solauto-sdk/src/generated/types/rebalance_data.rs index 2b6f4256..c4454894 100644 --- a/programs/solauto-sdk/src/generated/types/rebalance_data.rs +++ b/programs/solauto-sdk/src/generated/types/rebalance_data.rs @@ -5,18 +5,15 @@ //! [https://github.com/metaplex-foundation/kinobi] //! -use crate::generated::types::RebalanceDirection; -use crate::generated::types::SolautoRebalanceType; +use crate::generated::types::RebalanceInstructionData; +use crate::generated::types::RebalanceStateValues; use borsh::BorshDeserialize; use borsh::BorshSerialize; #[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct RebalanceData { - pub rebalance_type: SolautoRebalanceType, - pub padding1: [u8; 7], - pub rebalance_direction: RebalanceDirection, - pub padding2: [u8; 7], - pub flash_loan_amount: u64, - pub padding: [u8; 32], + pub ixs: RebalanceInstructionData, + pub values: RebalanceStateValues, + pub padding: [u32; 4], } diff --git a/programs/solauto-sdk/src/generated/types/rebalance_direction.rs b/programs/solauto-sdk/src/generated/types/rebalance_direction.rs index 70154bea..29eff2f2 100644 --- a/programs/solauto-sdk/src/generated/types/rebalance_direction.rs +++ b/programs/solauto-sdk/src/generated/types/rebalance_direction.rs @@ -14,6 +14,7 @@ use num_derive::FromPrimitive; )] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum RebalanceDirection { + None, Boost, Repay, } diff --git a/programs/solauto-sdk/src/generated/types/rebalance_instruction_data.rs b/programs/solauto-sdk/src/generated/types/rebalance_instruction_data.rs new file mode 100644 index 00000000..1a8117e9 --- /dev/null +++ b/programs/solauto-sdk/src/generated/types/rebalance_instruction_data.rs @@ -0,0 +1,23 @@ +//! This code was AUTOGENERATED using the kinobi library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun kinobi to update it. +//! +//! [https://github.com/metaplex-foundation/kinobi] +//! + +use crate::generated::types::PodBool; +use crate::generated::types::SolautoRebalanceType; +use crate::generated::types::SwapType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RebalanceInstructionData { + pub active: PodBool, + pub rebalance_type: SolautoRebalanceType, + pub swap_type: SwapType, + pub padding1: [u8; 5], + pub flash_loan_amount: u64, + pub padding: [u32; 4], +} diff --git a/programs/solauto-sdk/src/generated/types/rebalance_state_values.rs b/programs/solauto-sdk/src/generated/types/rebalance_state_values.rs new file mode 100644 index 00000000..f8b6f606 --- /dev/null +++ b/programs/solauto-sdk/src/generated/types/rebalance_state_values.rs @@ -0,0 +1,22 @@ +//! This code was AUTOGENERATED using the kinobi library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun kinobi to update it. +//! +//! [https://github.com/metaplex-foundation/kinobi] +//! + +use crate::generated::types::RebalanceDirection; +use crate::generated::types::TokenBalanceChange; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RebalanceStateValues { + pub rebalance_direction: RebalanceDirection, + pub padding1: [u8; 7], + pub target_supply_usd: u64, + pub target_debt_usd: u64, + pub token_balance_change: TokenBalanceChange, + pub padding: [u32; 4], +} diff --git a/programs/solauto-sdk/src/generated/types/rebalance_step.rs b/programs/solauto-sdk/src/generated/types/rebalance_step.rs new file mode 100644 index 00000000..ca51ed93 --- /dev/null +++ b/programs/solauto-sdk/src/generated/types/rebalance_step.rs @@ -0,0 +1,19 @@ +//! This code was AUTOGENERATED using the kinobi library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun kinobi to update it. +//! +//! [https://github.com/metaplex-foundation/kinobi] +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq, PartialOrd, Hash, FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum RebalanceStep { + PreSwap, + PostSwap, +} diff --git a/programs/solauto-sdk/src/generated/types/solauto_rebalance_type.rs b/programs/solauto-sdk/src/generated/types/solauto_rebalance_type.rs index 943dd19b..176c2180 100644 --- a/programs/solauto-sdk/src/generated/types/solauto_rebalance_type.rs +++ b/programs/solauto-sdk/src/generated/types/solauto_rebalance_type.rs @@ -14,7 +14,6 @@ use num_derive::FromPrimitive; )] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum SolautoRebalanceType { - None, Regular, DoubleRebalanceWithFL, FLSwapThenRebalance, diff --git a/programs/solauto-sdk/src/generated/types/solauto_settings_parameters.rs b/programs/solauto-sdk/src/generated/types/solauto_settings_parameters.rs index 06f63fce..22094a51 100644 --- a/programs/solauto-sdk/src/generated/types/solauto_settings_parameters.rs +++ b/programs/solauto-sdk/src/generated/types/solauto_settings_parameters.rs @@ -5,7 +5,6 @@ //! [https://github.com/metaplex-foundation/kinobi] //! -use crate::generated::types::AutomationSettings; use borsh::BorshDeserialize; use borsh::BorshSerialize; @@ -16,8 +15,5 @@ pub struct SolautoSettingsParameters { pub boost_gap: u16, pub repay_to_bps: u16, pub repay_gap: u16, - pub target_boost_to_bps: u16, - pub padding1: [u8; 6], - pub automation: AutomationSettings, - pub padding: [u8; 32], + pub padding: [u32; 24], } diff --git a/programs/solauto-sdk/src/generated/types/solauto_settings_parameters_inp.rs b/programs/solauto-sdk/src/generated/types/solauto_settings_parameters_inp.rs index 56bf6c34..a9b45ad4 100644 --- a/programs/solauto-sdk/src/generated/types/solauto_settings_parameters_inp.rs +++ b/programs/solauto-sdk/src/generated/types/solauto_settings_parameters_inp.rs @@ -5,7 +5,6 @@ //! [https://github.com/metaplex-foundation/kinobi] //! -use crate::generated::types::AutomationSettingsInp; use borsh::BorshDeserialize; use borsh::BorshSerialize; @@ -16,6 +15,4 @@ pub struct SolautoSettingsParametersInp { pub boost_gap: u16, pub repay_to_bps: u16, pub repay_gap: u16, - pub target_boost_to_bps: Option, - pub automation: Option, } diff --git a/programs/solauto-sdk/src/generated/types/swap_type.rs b/programs/solauto-sdk/src/generated/types/swap_type.rs new file mode 100644 index 00000000..492c7aa5 --- /dev/null +++ b/programs/solauto-sdk/src/generated/types/swap_type.rs @@ -0,0 +1,19 @@ +//! This code was AUTOGENERATED using the kinobi library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun kinobi to update it. +//! +//! [https://github.com/metaplex-foundation/kinobi] +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq, PartialOrd, Hash, FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum SwapType { + ExactIn, + ExactOut, +} diff --git a/programs/solauto-sdk/src/generated/types/token_balance_change.rs b/programs/solauto-sdk/src/generated/types/token_balance_change.rs new file mode 100644 index 00000000..e296c3c4 --- /dev/null +++ b/programs/solauto-sdk/src/generated/types/token_balance_change.rs @@ -0,0 +1,18 @@ +//! This code was AUTOGENERATED using the kinobi library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun kinobi to update it. +//! +//! [https://github.com/metaplex-foundation/kinobi] +//! + +use crate::generated::types::TokenBalanceChangeType; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct TokenBalanceChange { + pub change_type: TokenBalanceChangeType, + pub padding1: [u8; 7], + pub amount_usd: u64, +} diff --git a/programs/solauto-sdk/src/generated/types/token_balance_change_type.rs b/programs/solauto-sdk/src/generated/types/token_balance_change_type.rs new file mode 100644 index 00000000..a748a9f0 --- /dev/null +++ b/programs/solauto-sdk/src/generated/types/token_balance_change_type.rs @@ -0,0 +1,22 @@ +//! This code was AUTOGENERATED using the kinobi library. +//! Please DO NOT EDIT THIS FILE, instead use visitors +//! to add features, then rerun kinobi to update it. +//! +//! [https://github.com/metaplex-foundation/kinobi] +//! + +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use num_derive::FromPrimitive; + +#[derive( + BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq, PartialOrd, Hash, FromPrimitive, +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum TokenBalanceChangeType { + None, + PreSwapDeposit, + PostSwapDeposit, + PostRebalanceWithdrawSupplyToken, + PostRebalanceWithdrawDebtToken, +} diff --git a/programs/solauto-sdk/src/generated/types/update_position_data.rs b/programs/solauto-sdk/src/generated/types/update_position_data.rs index 1aed1631..894a6ba1 100644 --- a/programs/solauto-sdk/src/generated/types/update_position_data.rs +++ b/programs/solauto-sdk/src/generated/types/update_position_data.rs @@ -14,6 +14,6 @@ use borsh::BorshSerialize; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct UpdatePositionData { pub position_id: u8, - pub setting_params: Option, + pub settings: Option, pub dca: Option, } diff --git a/programs/solauto-sdk/tests/close_position.rs b/programs/solauto-sdk/tests/close_position.rs index 7d988210..c50d5b6f 100644 --- a/programs/solauto-sdk/tests/close_position.rs +++ b/programs/solauto-sdk/tests/close_position.rs @@ -22,7 +22,7 @@ mod close_position { .unwrap() .general.create_referral_state_accounts().await .unwrap(); - data.open_position(Some(data.general.default_setting_params.clone()), None).await.unwrap(); + data.open_position(Some(data.general.default_settings.clone()), None).await.unwrap(); let current_supply_balance = 3445655; data.general @@ -79,7 +79,7 @@ mod close_position { .unwrap() .general.create_referral_state_accounts().await .unwrap(); - data.open_position(Some(data.general.default_setting_params.clone()), None).await.unwrap(); + data.open_position(Some(data.general.default_settings.clone()), None).await.unwrap(); let tx = Transaction::new_signed_with_payer( &[data.general.close_position_ix().signer(temp_account.pubkey()).instruction()], @@ -99,16 +99,14 @@ mod close_position { .unwrap() .general.create_referral_state_accounts().await .unwrap(); - data.open_position(Some(data.general.default_setting_params.clone()), None).await.unwrap(); + data.open_position(Some(data.general.default_settings.clone()), None).await.unwrap(); let temp_account = Keypair::new(); let fake_supply_ta = get_associated_token_address( &temp_account.pubkey(), &data.general.supply_mint.pubkey() ); - data.general - .create_ata(temp_account.pubkey(), &data.general.supply_mint).await - .unwrap(); + data.general.create_ata(temp_account.pubkey(), &data.general.supply_mint).await.unwrap(); // Fake position supply token account let err = data.general @@ -129,19 +127,12 @@ mod close_position { &temp_account.pubkey(), &data.general.debt_mint.pubkey() ); - data.general - .create_ata(temp_account.pubkey(), &data.general.debt_mint).await - .unwrap(); + data.general.create_ata(temp_account.pubkey(), &data.general.debt_mint).await.unwrap(); // Fake position debt token account let err = data.general .execute_instructions( - vec![ - data.general - .close_position_ix() - .position_debt_ta(fake_debt_ta) - .instruction() - ], + vec![data.general.close_position_ix().position_debt_ta(fake_debt_ta).instruction()], None ).await .unwrap_err(); diff --git a/programs/solauto-sdk/tests/general.rs b/programs/solauto-sdk/tests/general.rs index 416836eb..9d5c4e0c 100644 --- a/programs/solauto-sdk/tests/general.rs +++ b/programs/solauto-sdk/tests/general.rs @@ -7,7 +7,6 @@ mod general { use solana_sdk::{ instruction::InstructionError, program_pack::Pack, - pubkey::Pubkey, rent::Rent, signature::Keypair, signer::Signer, @@ -49,7 +48,7 @@ mod general { ); data.general.ctx.banks_client.process_transaction(tx).await.unwrap(); - data.open_position(Some(data.general.default_setting_params.clone()), None).await.unwrap(); + data.open_position(Some(data.general.default_settings.clone()), None).await.unwrap(); } #[tokio::test] @@ -79,7 +78,7 @@ mod general { ); data.general.ctx.banks_client.process_transaction(tx).await.unwrap(); - data.open_position(Some(data.general.default_setting_params.clone()), None).await.unwrap(); + data.open_position(Some(data.general.default_settings.clone()), None).await.unwrap(); let account = data.general.ctx.banks_client.get_account(data.general.position_supply_ta).await.unwrap(); assert!(account.is_some()); @@ -98,7 +97,7 @@ mod general { .general.create_referral_state_accounts().await .unwrap(); - data.open_position(Some(data.general.default_setting_params.clone()), None).await.unwrap(); + data.open_position(Some(data.general.default_settings.clone()), None).await.unwrap(); let solauto_position = data.general.solauto_position.clone(); let mut data = MarginfiTestData::new(&args).await; @@ -111,7 +110,7 @@ mod general { .execute_instructions( vec![ data - .open_position_ix(Some(data.general.default_setting_params.clone()), None) + .open_position_ix(Some(data.general.default_settings.clone()), None) // Pass incorrect solauto position for the given signer .solauto_position(solauto_position) .instruction(), @@ -122,98 +121,4 @@ mod general { assert_instruction_error!(err, InstructionError::MissingRequiredSignature); } - - #[tokio::test] - async fn cancel_dca() { - let args = GeneralArgs::new(); - let mut data = MarginfiTestData::new(&args).await; - data.test_prefixtures().await - .unwrap() - .general.create_referral_state_accounts().await - .unwrap(); - - let dca_amount = 50_000; - data.general - .mint_tokens_to_ta( - data.general.debt_mint, - data.general.signer_debt_ta, - dca_amount - ).await - .unwrap(); - - let active_dca = DCASettingsInp { - automation: AutomationSettingsInp { - unix_start_date: (Utc::now().timestamp() as u64) - 1, - interval_seconds: 60 * 60 * 24, - periods_passed: 0, - target_periods: 5, - }, - dca_in_base_unit: dca_amount, - token_type: TokenType::Debt - }; - data.open_position( - Some(data.general.default_setting_params.clone()), - Some(active_dca.clone()) - ).await.unwrap(); - - data.general - .execute_instructions(vec![data.general.cancel_dca_ix().instruction()], None).await - .unwrap(); - - let solauto_position = data.general.deserialize_account_data::( - data.general.solauto_position - ).await; - assert!(solauto_position.position.dca.automation.target_periods == 0); - assert!(solauto_position.position.dca.dca_in_base_unit == 0); - - let signer_debt_ta = data.general.unpack_account_data::( - data.general.signer_debt_ta - ).await; - assert!(signer_debt_ta.amount == dca_amount); - } - - #[tokio::test] - async fn cancel_dca_incorrect_signer() { - let temp_account = Keypair::new(); - let mut args = GeneralArgs::new(); - args.fund_account(temp_account.pubkey()); - let mut data = MarginfiTestData::new(&args).await; - data.test_prefixtures().await - .unwrap() - .general.create_referral_state_accounts().await - .unwrap(); - - let dca_amount = 50_000; - data.general - .mint_tokens_to_ta( - data.general.debt_mint, - data.general.signer_debt_ta, - dca_amount - ).await - .unwrap(); - - let active_dca = DCASettingsInp { - automation: AutomationSettingsInp { - unix_start_date: (Utc::now().timestamp() as u64) - 1, - interval_seconds: 60 * 60 * 24, - periods_passed: 0, - target_periods: 5, - }, - dca_in_base_unit: dca_amount, - token_type: TokenType::Debt - }; - data.open_position( - Some(data.general.default_setting_params.clone()), - Some(active_dca.clone()) - ).await.unwrap(); - - let tx = Transaction::new_signed_with_payer( - &[data.general.cancel_dca_ix().signer(temp_account.pubkey()).instruction()], - Some(&temp_account.pubkey()), - &[&temp_account], - data.general.ctx.last_blockhash - ); - let err = data.general.ctx.banks_client.process_transaction(tx).await.unwrap_err(); - assert_instruction_error!(err, InstructionError::MissingRequiredSignature); - } } diff --git a/programs/solauto-sdk/tests/marginfi_open_position.rs b/programs/solauto-sdk/tests/marginfi_open_position.rs index d66ce18b..d2bbfcc2 100644 --- a/programs/solauto-sdk/tests/marginfi_open_position.rs +++ b/programs/solauto-sdk/tests/marginfi_open_position.rs @@ -32,15 +32,13 @@ mod open_position { .general.create_referral_state_accounts().await .unwrap(); - let setting_params = SolautoSettingsParametersInp { + let settings = SolautoSettingsParametersInp { boost_to_bps: 5000, boost_gap: 500, repay_to_bps: 7500, repay_gap: 500, - automation: None, - target_boost_to_bps: None, }; - data.open_position(Some(setting_params.clone()), None).await.unwrap(); + data.open_position(Some(settings.clone()), None).await.unwrap(); let solauto_position = data.general.deserialize_account_data::( data.general.solauto_position @@ -50,57 +48,12 @@ mod open_position { assert!(solauto_position.authority == data.general.ctx.payer.pubkey()); let position = &solauto_position.position; - assert!(position.setting_params.boost_to_bps == setting_params.boost_to_bps); + assert!(position.settings.boost_to_bps == settings.boost_to_bps); assert!(position.lending_platform == LendingPlatform::Marginfi); assert!(solauto_position.state.supply.mint == data.general.supply_mint.pubkey()); assert!(solauto_position.state.debt.mint == data.general.debt_mint.pubkey()); - assert!(position.protocol_user_account == data.marginfi_account); - } - - #[tokio::test] - async fn std_open_position_with_dca() { - let args = GeneralArgs::new(); - let mut data = MarginfiTestData::new(&args).await; - data.test_prefixtures().await - .unwrap() - .general.create_referral_state_accounts().await - .unwrap(); - - let dca_amount = 50_000; - data.general - .mint_tokens_to_ta( - data.general.debt_mint, - data.general.signer_debt_ta, - dca_amount - ).await - .unwrap(); - - let active_dca = DCASettingsInp { - automation: AutomationSettingsInp { - unix_start_date: (Utc::now().timestamp() as u64) - 1, - interval_seconds: 60 * 60 * 24, - periods_passed: 0, - target_periods: 5, - }, - dca_in_base_unit: dca_amount, - token_type: TokenType::Debt - }; - data.open_position( - Some(data.general.default_setting_params.clone()), - Some(active_dca.clone()) - ).await.unwrap(); - - let position_account = data.general.deserialize_account_data::( - data.general.solauto_position - ).await; - let position = &position_account.position; - assert!(&position.dca.automation.target_periods == &active_dca.automation.target_periods); - assert!(position.dca.dca_in_base_unit == dca_amount); - - let position_debt_ta = data.general.unpack_account_data::( - data.general.position_debt_ta.clone() - ).await; - assert!(position_debt_ta.amount == dca_amount); + assert!(position.lp_user_account == data.marginfi_account); + assert!(position.lp_pool_account == data.marginfi_group); } #[tokio::test] @@ -117,7 +70,7 @@ mod open_position { let tx = Transaction::new_signed_with_payer( &[ data - .open_position_ix(Some(data.general.default_setting_params.clone()), None) + .open_position_ix(Some(data.general.default_settings.clone()), None) .signer(temp_account.pubkey()) .instruction(), ], @@ -140,7 +93,7 @@ mod open_position { .unwrap(); let mut open_position_ix = data.open_position_ix( - Some(data.general.default_setting_params.clone()), + Some(data.general.default_settings.clone()), None ); diff --git a/programs/solauto-sdk/tests/marginfi_protocol_interaction.rs b/programs/solauto-sdk/tests/marginfi_protocol_interaction.rs index 58e2f3d3..f84b19e0 100644 --- a/programs/solauto-sdk/tests/marginfi_protocol_interaction.rs +++ b/programs/solauto-sdk/tests/marginfi_protocol_interaction.rs @@ -22,7 +22,7 @@ mod marginfi_protocol_interaction { .general.create_referral_state_accounts().await .unwrap(); - data.open_position(Some(data.general.default_setting_params.clone()), None).await.unwrap(); + data.open_position(Some(data.general.default_settings.clone()), None).await.unwrap(); let tx = Transaction::new_signed_with_payer( &[ diff --git a/programs/solauto-sdk/tests/test_utils.rs b/programs/solauto-sdk/tests/test_utils.rs index 1b3564ff..5733909c 100644 --- a/programs/solauto-sdk/tests/test_utils.rs +++ b/programs/solauto-sdk/tests/test_utils.rs @@ -13,11 +13,7 @@ use solana_sdk::{ system_instruction, transaction::Transaction, }; -use solauto::{ - constants::SOLAUTO_FEES_WALLET, - instructions::protocol_interaction, - state::referral_state::ReferralState, -}; +use solauto::{ constants::SOLAUTO_FEES_WALLET, state::referral_state::ReferralState }; use solauto_sdk::{ generated::{ instructions::{ @@ -41,7 +37,6 @@ use solauto_sdk::{ }; use spl_associated_token_account::{ get_associated_token_address, instruction as ata_instruction }; use spl_token::{ instruction as token_instruction, state::Mint }; -use rand::{ Rng, thread_rng }; #[macro_export] macro_rules! assert_instruction_error { @@ -120,7 +115,7 @@ pub struct GeneralTestData<'a> { pub position_debt_ta: Pubkey, pub signer_debt_ta: Pubkey, - pub default_setting_params: SolautoSettingsParametersInp, + pub default_settings: SolautoSettingsParametersInp, } impl<'a> GeneralTestData<'a> { @@ -204,13 +199,11 @@ impl<'a> GeneralTestData<'a> { position_debt_ta, signer_debt_ta, - default_setting_params: SolautoSettingsParametersInp { + default_settings: SolautoSettingsParametersInp { boost_to_bps: 5000, boost_gap: 500, repay_to_bps: 7500, repay_gap: 500, - automation: None, - target_boost_to_bps: None, }, } } @@ -373,7 +366,7 @@ impl<'a> GeneralTestData<'a> { .referral_state(self.signer_referral_state) .referral_fees_dest_ta(self.signer_referral_dest_ta) .referral_fees_dest_mint(self.referral_fees_dest_mint.pubkey()) - .referral_authority(Some(self.ctx.payer.pubkey())) + .referral_authority(self.ctx.payer.pubkey()) .fees_destination_ta( Some( get_associated_token_address( @@ -399,13 +392,13 @@ impl<'a> GeneralTestData<'a> { pub fn update_position_ix( &self, - setting_params: Option, + settings: Option, dca: Option ) -> UpdatePositionBuilder { let mut builder = UpdatePositionBuilder::new(); let position_data = UpdatePositionData { position_id: self.position_id, - setting_params, + settings, dca, }; builder @@ -435,7 +428,7 @@ impl<'a> GeneralTestData<'a> { .signer_supply_ta(self.signer_supply_ta) .position_debt_ta(self.position_debt_ta) .signer_debt_ta(self.signer_debt_ta) - .protocol_account(self.solauto_position); + .lp_user_account(self.solauto_position); builder } @@ -455,7 +448,6 @@ pub struct MarginfiTestData<'a> { pub general: GeneralTestData<'a>, pub marginfi_account: Pubkey, pub marginfi_account_keypair: Option, - pub marginfi_account_seed_idx: Option, pub marginfi_group: Pubkey, } @@ -464,16 +456,11 @@ impl<'a> MarginfiTestData<'a> { let general = GeneralTestData::new(args, MARGINFI_PROGRAM).await; let marginfi_group = Keypair::new().pubkey(); - let marginfi_account_seed_idx = if args.position_id != 0 { - let mut rng = thread_rng(); - let random_number: u64 = rng.gen(); - Some(random_number) - } else { - None - }; let (marginfi_account, marginfi_account_keypair) = if args.position_id != 0 { - let seed_idx = marginfi_account_seed_idx.unwrap().to_le_bytes(); - let marginfi_account_seeds = &[general.solauto_position.as_ref(), seed_idx.as_ref()]; + let marginfi_account_seeds = &[ + general.solauto_position.as_ref(), + marginfi_group.as_ref(), + ]; let (marginfi_account, _) = Pubkey::find_program_address( marginfi_account_seeds.as_slice(), &SOLAUTO_ID @@ -488,7 +475,6 @@ impl<'a> MarginfiTestData<'a> { general, marginfi_account, marginfi_account_keypair, - marginfi_account_seed_idx, marginfi_group, } } @@ -518,13 +504,13 @@ impl<'a> MarginfiTestData<'a> { pub fn open_position_ix( &self, - setting_params: Option, + settings: Option, dca: Option ) -> MarginfiOpenPositionBuilder { let mut builder = MarginfiOpenPositionBuilder::new(); let position_data = UpdatePositionData { position_id: self.general.position_id, - setting_params, + settings, dca, }; builder @@ -545,9 +531,6 @@ impl<'a> MarginfiTestData<'a> { .position_debt_ta(self.general.position_debt_ta) .position_type(PositionType::Leverage) .position_data(position_data); - if self.marginfi_account_seed_idx.is_some() { - builder.marginfi_account_seed_idx(self.marginfi_account_seed_idx.unwrap()); - } builder } diff --git a/programs/solauto-sdk/tests/update_position.rs b/programs/solauto-sdk/tests/update_position.rs index 9c952787..70a570a2 100644 --- a/programs/solauto-sdk/tests/update_position.rs +++ b/programs/solauto-sdk/tests/update_position.rs @@ -36,47 +36,14 @@ mod update_position { ).await .unwrap(); - data.open_position( - Some(data.general.default_setting_params.clone()), + Some(data.general.default_settings.clone()), None ).await.unwrap(); let solauto_position = data.general.deserialize_account_data::( data.general.solauto_position ).await; - assert!(solauto_position.position.dca.automation.target_periods == 0); - assert!(solauto_position.position.dca.dca_in_base_unit == 0); - - // Update position's settings and add a DCA - let dca_out_automation = AutomationSettingsInp { - unix_start_date: (Utc::now().timestamp() as u64) - 1, - interval_seconds: 60 * 60 * 10, - periods_passed: 0, - target_periods: 5, - }; - let new_settings = SolautoSettingsParametersInp { - boost_to_bps: 2000, - boost_gap: 1000, - repay_to_bps: 7500, - repay_gap: 500, - automation: Some(dca_out_automation.clone()), - target_boost_to_bps: Some(0), - }; - let new_dca = DCASettingsInp { - automation: dca_out_automation, - dca_in_base_unit: 0, - token_type: TokenType::Debt - }; - data.general - .update_position(Some(new_settings.clone()), Some(new_dca.clone())).await - .unwrap(); - - let solauto_position = data.general.deserialize_account_data::( - data.general.solauto_position - ).await; - assert!(solauto_position.position.setting_params.automation.target_periods == new_settings.automation.as_ref().unwrap().target_periods); - assert!(solauto_position.position.dca.dca_in_base_unit == new_dca.dca_in_base_unit); } #[tokio::test] @@ -89,12 +56,12 @@ mod update_position { .unwrap() .general.create_referral_state_accounts().await .unwrap(); - data.open_position(Some(data.general.default_setting_params.clone()), None).await.unwrap(); + data.open_position(Some(data.general.default_settings.clone()), None).await.unwrap(); let tx = Transaction::new_signed_with_payer( &[ data.general - .update_position_ix(Some(data.general.default_setting_params.clone()), None) + .update_position_ix(Some(data.general.default_settings.clone()), None) .signer(temp_account.pubkey()) .instruction(), ], @@ -115,7 +82,7 @@ mod update_position { .general.create_referral_state_accounts().await .unwrap(); - data.open_position(Some(data.general.default_setting_params.clone()), None).await.unwrap(); + data.open_position(Some(data.general.default_settings.clone()), None).await.unwrap(); let temp_wallet = Keypair::new().pubkey(); let fake_debt_ta = get_associated_token_address( diff --git a/programs/solauto-sdk/tests/update_referral_states.rs b/programs/solauto-sdk/tests/update_referral_states.rs index 6dcec1f0..44a8f7d2 100644 --- a/programs/solauto-sdk/tests/update_referral_states.rs +++ b/programs/solauto-sdk/tests/update_referral_states.rs @@ -16,10 +16,10 @@ mod update_referral_states { #[tokio::test] async fn update_referral_states() { - // Create referral state for signer let args = GeneralArgs::new(); let mut data = MarginfiTestData::new(&args).await; + // Create referral state for signer data.general .execute_instructions( vec![data.general.update_referral_states_ix().instruction()], diff --git a/programs/solauto/README.md b/programs/solauto/README.md index 70f03553..6501acba 100644 --- a/programs/solauto/README.md +++ b/programs/solauto/README.md @@ -2,14 +2,11 @@ Solauto is a program on the Solana blockchain that lets you manage leveraged longs & shorts on auto-pilot to maximize your gains and eliminate the risk of liquidation. -Solauto is (currently only) built on-top of mrgnlend (Marginfi) - a lending and borrowing platform that allows for a wallet to hold & maintain a leverage position through various instructions (lend, borrow, withdraw, repay). - - ## Definitions -#### Marginfi Account (account state) +#### LP user account (account state) -A Marginfi account is the Solana state data that keeps track of a wallet's supply & debt states, i.e. how much SOL has been lent, how much USDC has been borrowed, etc. +An LP (lending platform) user account is the Solana state data that keeps track of a wallet's supply & debt states, i.e. how much SOL has been lent, how much USDC has been borrowed, etc. #### Solauto referral state (account state) @@ -17,34 +14,29 @@ A Solauto referral state should be 1:1 for each user that interacts with Solauto A referral state also exists to collect referral fees (in token accounts tied to the referral state). Only the pubkey of the referral statecan claim the referral fees collected in that referral state. - #### Solauto position (account state) A Solauto position is state data that keeps track of various pubkeys, setting parameters, and balances. A Solauto position is a PDA, defined by the seeds [position_id (u8), authority (pubkey)]. A Solauto position can be self-managed or not. Any position_id set as 0 is self-managed. Any position_id > 0 is NOT self-managed. -A self-managed position essentially means it does not take ownership (authority) for the Marginfi account being used in the desired transaction. Any NON self-managed position will sign CPI calls through the Solauto position PDA, as the Solauto position WILL be the authority over the Marginfi account. - +A self-managed position essentially means it does not take ownership (authority) for the LP user account being used in the desired transaction. Any NON self-managed position will sign CPI calls through the Solauto position PDA, as the Solauto position WILL be the authority over the LP user account. #### Solauto manager (wallet) A special wallet that can sign specific transactions (such as rebalancing), for any NON self-managed Solauto position, with restrictions on the permissions of what it can do. This wallet handles rebalancing Solauto positions, as well as managing DCA actions over time. - #### Setting parameters The most crucial data on a Solauto position. This defines the ranges at when a rebalance is necessary and allowed. It is defined by 4 values: boost_from, boost_to, repay_from, and repay_to. This is what ensures that a leveraged position through Solauto can never get liquidated. - ## Program infrastructure Solauto uses [shank](https://crates.io/crates/shank) to define the instructions & accounts inside of [src/types/instruction.rs](src/types/instruction.rs). -Solauto also imports instruction & account types from marginfi-sdk and jupiter-sdk. These crates are generated with [metaplex kinobi](https://github.com/metaplex-foundation/kinobi) using the idls generated inside of `idls/...`. These should be updated with the idls located on mainnet at all times. - +Solauto also imports types from marginfi-sdk and jupiter-sdk. These crates are generated with [metaplex kinobi](https://github.com/metaplex-foundation/kinobi) using the idls generated inside of `idls/...`. These should be updated with the idls located on mainnet at all times. ## Instructions -#### Update referral states +#### Update referral states Required to create a referral state before other instructions. Can be updated to set the referred_by or also the lookup table. @@ -76,15 +68,11 @@ The most crucial instruction and the core logic of the program: rebalance the So More info can be found in the [rebalance section.](#rebalance) -#### Cancel DCA - -Cancels the active DCA on the Solauto position. Only allowed to be invoked by the Solauto position authority. - #### Close position Close the Solauto position and return all account rents. Only allowed to be invoked by the Solauto position authority. -#### Update position +#### Update position Update the Solauto position setting parameters or active DCA @@ -94,7 +82,6 @@ A rebalance can be successful under one of the 4 conditions: - A boost (if liq utilization rate is < boost_from) - A repay (if liq utilization rate is > repay_from) -- A DCA period is eligible - A target liquidation utilization rate has been provided, and the position authority is signing If none of the conditions are met, the Solauto rebalance instruction will fail. @@ -103,7 +90,7 @@ If a rebalance is increasing leverage, Solauto will borrow extra debt, move it t If a rebalance is decreasing leverage, Solauto will withdraw some supply, move it to a token account, swap it to the debt token, and then repay debt using that balance. -A rebalance will consist of multiple instructions that must exist together in the same transaction. A rebalance will be one of the 3 available sets, depending on the posiiton's state and what must be done. +A rebalance will consist of multiple instructions that must exist together in the same transaction. A rebalance will be one of the 4 available sets, depending on the posiiton's state and what must be done. 1. Regular @@ -119,14 +106,21 @@ A rebalance will consist of multiple instructions that must exist together in th - Rebalance - flash repay -3. Single rebalance with flash loan +3. Flash loan swap then rebalance - Flash borrow - Jup swap - Rebalance - Flash repay -Depending on the rebalance set type, and the current position's state, the rebalance instruction will behave differently. +3. Flash loan rebalance then swap + +- Flash borrow +- Rebalance +- Jup swap +- Flash repay + +Depending on the rebalance set type, and the current position's state, the rebalance instruction will behave differently. A rebalance instruction will always validate the jup swap data & accounts to ensure there is no fee taken and the destination goes to the right token account. diff --git a/programs/solauto/src/clients/marginfi.rs b/programs/solauto/src/clients/marginfi.rs index 0e5d8439..18c24126 100644 --- a/programs/solauto/src/clients/marginfi.rs +++ b/programs/solauto/src/clients/marginfi.rs @@ -1,13 +1,12 @@ use borsh::BorshDeserialize; use fixed::types::I80F48; -use fixed_macro::types::I80F48; use marginfi_sdk::generated::{ accounts::{Bank, MarginfiAccount}, instructions::*, types::{Balance, OracleSetup}, }; use pyth_sdk_solana::state::SolanaPriceAccount; -use pyth_solana_receiver_sdk::price_update::PriceUpdateV2; +use pyth_solana_receiver_sdk::price_update::{PriceUpdateV2, VerificationLevel}; use solana_program::{ account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, program_error::ProgramError, pubkey::Pubkey, sysvar::Sysvar, @@ -22,24 +21,23 @@ use switchboard_v2::AggregatorAccountData; use crate::{ state::solauto_position::SolautoPosition, types::{ + errors::SolautoError, instruction::{ accounts::{Context, MarginfiOpenPositionAccounts}, SolautoStandardAccounts, }, lending_protocol::{LendingProtocolClient, LendingProtocolTokenAccounts}, shared::{ - DeserializedAccount, RefreshStateProps, RefreshedTokenData, SolautoError, - TokenBalanceAmount, + DeserializedAccount, PriceType, RefreshStateProps, RefreshedTokenState, + TokenBalanceAmount, TokenType, }, }, - utils::{ - math_utils::{self, i80f48_to_f64}, - solana_utils::*, - solauto_utils::*, - validation_utils::*, - }, + utils::{math_utils::*, solana_utils::*, solauto_utils::*, validation_utils::*}, }; +const CONF_INTERVAL_MULTIPLE: f64 = 2.12; +const STD_DEV_MULTIPLE: f64 = 1.96; + pub struct MarginfiBankAccounts<'a> { pub bank: DeserializedAccount<'a, Bank>, pub price_oracle: Option<&'a AccountInfo<'a>>, @@ -50,7 +48,7 @@ pub struct MarginfiBankAccounts<'a> { pub struct MarginfiClient<'a> { signer: &'a AccountInfo<'a>, program: &'a AccountInfo<'a>, - marginfi_account: DeserializedAccount<'a, MarginfiAccount>, + marginfi_account: &'a AccountInfo<'a>, marginfi_group: &'a AccountInfo<'a>, supply: MarginfiBankAccounts<'a>, debt: MarginfiBankAccounts<'a>, @@ -60,7 +58,6 @@ impl<'a> MarginfiClient<'a> { pub fn initialize<'c>( ctx: &'c Context<'a, MarginfiOpenPositionAccounts<'a>>, solauto_position: &'c DeserializedAccount<'a, SolautoPosition>, - marignfi_acc_seed_idx: Option, ) -> ProgramResult { if account_has_data(ctx.accounts.marginfi_account) { return Ok(()); @@ -78,10 +75,9 @@ impl<'a> MarginfiClient<'a> { }, ); if marginfi_account_owner.key == solauto_position.account_info.key { - let seed_idx_bytes = marignfi_acc_seed_idx.unwrap().to_le_bytes(); let mut marginfi_account_seeds = vec![ solauto_position.account_info.key.as_ref(), - seed_idx_bytes.as_ref(), + ctx.accounts.marginfi_group.key.as_ref(), ]; let (_, bump) = Pubkey::find_program_address(marginfi_account_seeds.as_slice(), &crate::ID); @@ -128,10 +124,7 @@ impl<'a> MarginfiClient<'a> { Ok(Self { signer, program, - marginfi_account: DeserializedAccount::::zerocopy(Some( - marginfi_account, - ))? - .unwrap(), + marginfi_account, marginfi_group, supply, debt, @@ -164,17 +157,17 @@ impl<'a> MarginfiClient<'a> { let supply_bank = DeserializedAccount::::zerocopy(Some(supply_bank))?.unwrap(); let debt_bank = DeserializedAccount::::zerocopy(Some(debt_bank))?.unwrap(); - let max_ltv = math_utils::i80f48_to_f64(I80F48::from_le_bytes( + let max_ltv = i80f48_to_f64(I80F48::from_le_bytes( supply_bank.data.config.asset_weight_init.value, )) - .div(math_utils::i80f48_to_f64(I80F48::from_le_bytes( + .div(i80f48_to_f64(I80F48::from_le_bytes( debt_bank.data.config.liability_weight_init.value, ))); - let liq_threshold = math_utils::i80f48_to_f64(I80F48::from_le_bytes( + let liq_threshold = i80f48_to_f64(I80F48::from_le_bytes( supply_bank.data.config.asset_weight_maint.value, )) - .div(math_utils::i80f48_to_f64(I80F48::from_le_bytes( + .div(i80f48_to_f64(I80F48::from_le_bytes( debt_bank.data.config.liability_weight_maint.value, ))); @@ -185,17 +178,19 @@ impl<'a> MarginfiClient<'a> { account_balances: &[Balance], supply_bank: &'a AccountInfo<'a>, price_oracle: &'a AccountInfo<'a>, + price_type: PriceType, mut max_ltv: f64, - ) -> Result<(RefreshedTokenData, f64), ProgramError> { + ) -> Result<(RefreshedTokenState, f64), ProgramError> { let bank = DeserializedAccount::::zerocopy(Some(supply_bank))?.unwrap(); let asset_share_value = I80F48::from_le_bytes(bank.data.asset_share_value.value); - let market_price = MarginfiClient::load_price(&bank, price_oracle)?; + let market_price = + MarginfiClient::load_price(&bank, price_oracle, price_type, TokenType::Supply)?; let supply_shares = MarginfiClient::get_account_balance(account_balances, &bank, true); let base_unit_account_deposits = if supply_shares.is_some() { - math_utils::i80f48_to_u64(supply_shares.unwrap().mul(asset_share_value)) + i80f48_to_u64(supply_shares.unwrap().mul(asset_share_value)) } else { 0 }; @@ -205,11 +200,9 @@ impl<'a> MarginfiClient<'a> { let base_unit_deposit_room_available = I80F48::from(bank.data.config.deposit_limit).sub(total_deposited); - let bank_deposits_usd_value = math_utils::from_base_unit::( - math_utils::i80f48_to_f64(total_deposited), - bank.data.mint_decimals, - ) - .mul(market_price); + let bank_deposits_usd_value = + from_base_unit::(i80f48_to_f64(total_deposited), bank.data.mint_decimals) + .mul(market_price); if bank.data.config.total_asset_value_init_limit != 0 && bank_deposits_usd_value > (bank.data.config.total_asset_value_init_limit as f64) { @@ -219,11 +212,11 @@ impl<'a> MarginfiClient<'a> { } Ok(( - RefreshedTokenData { + RefreshedTokenState { mint: bank.data.mint, decimals: bank.data.mint_decimals, amount_used: base_unit_account_deposits, - amount_can_be_used: math_utils::i80f48_to_u64(base_unit_deposit_room_available), + amount_can_be_used: i80f48_to_u64(base_unit_deposit_room_available), market_price, borrow_fee_bps: None, }, @@ -235,16 +228,18 @@ impl<'a> MarginfiClient<'a> { account_balances: &[Balance], debt_bank: &'a AccountInfo<'a>, price_oracle: &'a AccountInfo<'a>, - ) -> Result { + price_type: PriceType, + ) -> Result { let bank = DeserializedAccount::::zerocopy(Some(debt_bank))?.unwrap(); let liability_share_value = I80F48::from_le_bytes(bank.data.liability_share_value.value); - let market_price = MarginfiClient::load_price(&bank, price_oracle)?; + let market_price = + MarginfiClient::load_price(&bank, price_oracle, price_type, TokenType::Debt)?; let debt_shares = MarginfiClient::get_account_balance(account_balances, &bank, false); let base_unit_account_debt = if debt_shares.is_some() { - math_utils::i80f48_to_u64(debt_shares.unwrap().mul(liability_share_value)) + i80f48_to_u64(debt_shares.unwrap().mul(liability_share_value)) } else { 0 }; @@ -259,38 +254,54 @@ impl<'a> MarginfiClient<'a> { bank.data .config .borrow_limit - .saturating_sub(math_utils::i80f48_to_u64(total_borrows)), - math_utils::i80f48_to_u64(base_unit_supply_available), + .saturating_sub(i80f48_to_u64(total_borrows)), + i80f48_to_u64(base_unit_supply_available), ); - Ok(RefreshedTokenData { + let borrow_fee_bps = i80f48_to_f64(I80F48::from_le_bytes( + bank.data + .config + .interest_rate_config + .protocol_origination_fee + .value, + )) + .mul(10_000.0) + .round() as u16; + + Ok(RefreshedTokenState { mint: bank.data.mint, decimals: bank.data.mint_decimals, amount_used: base_unit_account_debt, amount_can_be_used, market_price, - borrow_fee_bps: None, + borrow_fee_bps: Some(borrow_fee_bps), }) } - pub fn get_updated_state( + pub fn get_updated_state<'b>( marginfi_account: &DeserializedAccount, supply_bank: &'a AccountInfo<'a>, supply_price_oracle: &'a AccountInfo<'a>, debt_bank: &'a AccountInfo<'a>, debt_price_oracle: &'a AccountInfo<'a>, + price_type: PriceType, ) -> Result { let (max_ltv, liq_threshold) = MarginfiClient::get_max_ltv_and_liq_threshold(supply_bank, debt_bank)?; let account_balances = &marginfi_account.data.lending_account.balances[..2]; - let debt = - MarginfiClient::get_debt_token_usage(account_balances, debt_bank, debt_price_oracle)?; + let debt = MarginfiClient::get_debt_token_usage( + account_balances, + debt_bank, + debt_price_oracle, + price_type, + )?; let (supply, max_ltv) = MarginfiClient::get_supply_token_usage( account_balances, supply_bank, supply_price_oracle, + price_type, max_ltv, )?; @@ -305,13 +316,9 @@ impl<'a> MarginfiClient<'a> { pub fn load_price( bank: &DeserializedAccount, price_oracle: &AccountInfo, + price_type: PriceType, + token_type: TokenType, ) -> Result { - // TODO: Don't validate this until Marginfi's sorted out their price oracle issues and this is congruent with what they use. - // if price_oracle.key != &bank.data.config.oracle_keys[0] { - // msg!("Incorrect price oracle provided"); - // return Err(SolautoError::IncorrectAccounts.into()); - // } - let clock = Clock::get()?; let max_price_age = 120; // Default used by Marginfi is 60 @@ -325,22 +332,17 @@ impl<'a> MarginfiClient<'a> { } OracleSetup::PythLegacy => { let price_feed = SolanaPriceAccount::account_info_to_feed(price_oracle)?; - let price_result = price_feed - .get_ema_price_no_older_than(clock.unix_timestamp, max_price_age) - .unwrap(); - - let price = if price_result.expo == 0 { - price_result.price as f64 - } else if price_result.expo < 0 { - math_utils::from_base_unit::( - price_result.price, - price_result.expo.unsigned_abs(), - ) + + let price = if price_type == PriceType::Ema { + let price_result = price_feed + .get_price_no_older_than(clock.unix_timestamp, max_price_age) + .unwrap(); + derive_value(price_result.price, price_result.expo) } else { - math_utils::to_base_unit::( - price_result.price, - price_result.expo.unsigned_abs(), - ) + let price_result = price_feed + .get_price_no_older_than(clock.unix_timestamp, max_price_age) + .unwrap(); + derive_value(price_result.price, price_result.expo) }; Ok(price) @@ -349,29 +351,38 @@ impl<'a> MarginfiClient<'a> { let price_feed_data = price_oracle.try_borrow_data()?; let price_feed = PriceUpdateV2::deserialize(&mut &price_feed_data.as_ref()[8..])?; - let feed_id = &bank.data.config.oracle_keys[0].to_bytes(); - let price_result = price_feed - .get_price_no_older_than(&clock, max_price_age, feed_id) - .map_err(|e| { - msg!("Pyth push oracle error: {:?}", e); - ProgramError::Custom(0) - })?; - - let price = if price_result.exponent == 0 { - price_result.price as f64 - } else if price_result.exponent < 0 { - math_utils::from_base_unit::( - price_result.price, - price_result.exponent.unsigned_abs(), + let (price, conf_interval) = if price_type == PriceType::Ema { + let ema_price = price_feed.price_message.ema_price; + let conf = price_feed.price_message.ema_conf; + let exponent = price_feed.price_message.exponent; + ( + derive_value(ema_price, exponent), + derive_value(conf as i64, exponent), ) } else { - math_utils::to_base_unit::( - price_result.price, - price_result.exponent.unsigned_abs(), + let feed_id = &bank.data.config.oracle_keys[0].to_bytes(); + let price_result = price_feed + .get_price_no_older_than_with_custom_verification_level( + &clock, + max_price_age, + feed_id, + VerificationLevel::Full, + ) + .map_err(|e| { + msg!("Pyth push oracle error: {:?}", e); + ProgramError::Custom(0) + })?; + ( + derive_value(price_result.price, price_result.exponent), + derive_value(price_result.conf as i64, price_result.exponent), ) }; - Ok(price) + Ok(with_conf_interval( + price, + conf_interval.mul(CONF_INTERVAL_MULTIPLE), + token_type, + )) } OracleSetup::SwitchboardLegacy => { let data = price_oracle.data.borrow(); @@ -382,10 +393,7 @@ impl<'a> MarginfiClient<'a> { let price = if sw_decimal.scale == 0 { sw_decimal.mantissa as f64 } else { - math_utils::from_base_unit::( - sw_decimal.mantissa, - sw_decimal.scale, - ) + from_base_unit::(sw_decimal.mantissa, sw_decimal.scale) }; Ok(price) @@ -395,12 +403,15 @@ impl<'a> MarginfiClient<'a> { let feed = PullFeedAccountData::parse(data) .map_err(|_| SolautoError::IncorrectAccounts)?; - let price = I80F48::from_num(feed.result.value) + let price = (feed.result.value as f64) // 10^18 - .checked_div(I80F48!(1000000000000000000)) - .unwrap(); + .div(1000000000000000000.0); + let conf_interval = (feed.result.std_dev as f64) + // 10^18 + .div(1000000000000000000.0) + .mul(STD_DEV_MULTIPLE); - Ok(i80f48_to_f64(price)) + Ok(with_conf_interval(price, conf_interval, token_type)) } } } @@ -453,7 +464,7 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { self.program, LendingAccountDepositCpiAccounts { marginfi_group: self.marginfi_group, - marginfi_account: self.marginfi_account.account_info, + marginfi_account: self.marginfi_account, signer: authority, bank: self.supply.bank.account_info, signer_token_account, @@ -462,6 +473,7 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { }, LendingAccountDepositInstructionArgs { amount: base_unit_amount, + deposit_up_to_limit: Some(true), }, ); @@ -494,7 +506,7 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { self.program, LendingAccountWithdrawCpiAccounts { marginfi_group: self.marginfi_group, - marginfi_account: self.marginfi_account.account_info, + marginfi_account: self.marginfi_account, signer: authority, bank: self.supply.bank.account_info, destination_token_account: destination, @@ -508,9 +520,12 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { }, ); - let active_balances = self - .marginfi_account - .data + let marginfi_account_data = + DeserializedAccount::::zerocopy(Some(self.marginfi_account))? + .unwrap() + .data; + + let active_balances = marginfi_account_data .lending_account .balances .iter() @@ -522,9 +537,9 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { let mut withdrawing_all = amount == TokenBalanceAmount::All; if !withdrawing_all && active_balances.len() == 1 { let asset_shares = I80F48::from_le_bytes(active_balances[0].asset_shares.value); - let supply_balance = math_utils::i80f48_to_u64(asset_shares.mul( - I80F48::from_le_bytes(self.supply.bank.data.asset_share_value.value), - )); + let supply_balance = i80f48_to_u64(asset_shares.mul(I80F48::from_le_bytes( + self.supply.bank.data.asset_share_value.value, + ))); let TokenBalanceAmount::Some(withdraw_amount) = amount else { panic!("Unexpected amount type"); }; @@ -567,7 +582,7 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { self.program, LendingAccountBorrowCpiAccounts { marginfi_group: self.marginfi_group, - marginfi_account: self.marginfi_account.account_info, + marginfi_account: self.marginfi_account, signer: authority, bank: self.debt.bank.account_info, destination_token_account: destination, @@ -623,7 +638,7 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { self.program, LendingAccountRepayCpiAccounts { marginfi_group: self.marginfi_group, - marginfi_account: self.marginfi_account.account_info, + marginfi_account: self.marginfi_account, signer: authority, bank: self.debt.bank.account_info, signer_token_account: signer_token_account, diff --git a/programs/solauto/src/constants.rs b/programs/solauto/src/constants.rs index 3e938222..2e36b314 100644 --- a/programs/solauto/src/constants.rs +++ b/programs/solauto/src/constants.rs @@ -1,22 +1,11 @@ -use solana_program::pubkey::Pubkey; +use solana_program::{pubkey, pubkey::Pubkey}; -// AprYCPiVeKMCgjQ2ZufwChMzvQ5kFjJo2ekTLSkXsQDm -pub const SOLAUTO_FEES_WALLET: Pubkey = Pubkey::new_from_array([ - 145, 251, 126, 53, 245, 169, 146, 209, 147, 243, 95, 78, 165, 119, 126, 212, 48, 177, 204, 152, - 35, 228, 216, 122, 54, 147, 76, 46, 180, 66, 110, 112, -]); +pub const SOLAUTO_FEES_WALLET: Pubkey = pubkey!("AprYCPiVeKMCgjQ2ZufwChMzvQ5kFjJo2ekTLSkXsQDm"); +pub const SOLAUTO_MANAGER: Pubkey = pubkey!("MNGRcX4nc7quPdzBbNKJ4ScK5EE73JnwJVGxuJXhHCY"); +pub const WSOL_MINT: Pubkey = pubkey!("So11111111111111111111111111111111111111112"); -// MNGRcX4nc7quPdzBbNKJ4ScK5EE73JnwJVGxuJXhHCY -pub const SOLAUTO_MANAGER: Pubkey = Pubkey::new_from_array([ - 5, 55, 169, 98, 27, 47, 114, 199, 85, 110, 166, 51, 214, 240, 77, 15, 168, 150, 137, 164, 201, - 23, 114, 118, 157, 17, 1, 163, 52, 164, 52, 29, -]); - -// So11111111111111111111111111111111111111112 -pub const WSOL_MINT: Pubkey = Pubkey::new_from_array([ - 6, 155, 136, 87, 254, 171, 129, 132, 251, 104, 127, 99, 70, 24, 192, 53, 218, 196, 57, 220, 26, - 235, 59, 85, 152, 160, 240, 0, 0, 0, 0, 1, -]); +pub const MARGINFI_PROD_PROGRAM: Pubkey = pubkey!("MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA"); +pub const MARGINFI_STAGING_PROGRAM: Pubkey = pubkey!("stag8sTKds2h4KzjUw3zKTsxbqvT4XKHdaR9X9E6Rct"); pub const USD_DECIMALS: u8 = 9; @@ -25,3 +14,7 @@ pub const MIN_REPAY_GAP_BPS: u16 = 50; pub const MIN_BOOST_GAP_BPS: u16 = 50; pub const MAX_BASIS_POINTS: u16 = 10000; + +pub const REFERRER_PERCENTAGE: f64 = 0.15; + +pub const OFFSET_FROM_MAX_LTV: f64 = 0.005; diff --git a/programs/solauto/src/entrypoint.rs b/programs/solauto/src/entrypoint.rs index ee309313..480a5783 100644 --- a/programs/solauto/src/entrypoint.rs +++ b/programs/solauto/src/entrypoint.rs @@ -31,7 +31,9 @@ pub fn process_instruction<'a>( Instruction::ClosePosition => process_close_position_instruction(accounts), Instruction::CancelDCA => process_cancel_dca(accounts), - Instruction::MarginfiRefreshData => process_marginfi_refresh_data(accounts), + Instruction::MarginfiRefreshData(price_type) => { + process_marginfi_refresh_data(accounts, price_type) + } Instruction::MarginfiProtocolInteraction(action) => { process_marginfi_interaction_instruction(accounts, action) } diff --git a/programs/solauto/src/instructions/close_position.rs b/programs/solauto/src/instructions/close_position.rs index 908a349e..106db22b 100644 --- a/programs/solauto/src/instructions/close_position.rs +++ b/programs/solauto/src/instructions/close_position.rs @@ -5,7 +5,7 @@ use crate::{ state::solauto_position::SolautoPosition, types::{ instruction::accounts::{ClosePositionAccounts, Context}, - shared::DeserializedAccount, + shared::{DeserializedAccount, SplTokenTransferArgs}, }, utils::{solana_utils, solauto_utils}, }; @@ -24,11 +24,13 @@ pub fn close_position_ta<'a>( if position_ta_data.amount > 0 && position_ta_data.mint != WSOL_MINT { solana_utils::spl_token_transfer( ctx.accounts.token_program, - position_ta, - solauto_position.account_info, - signer_ta, - position_ta_data.amount, - Some(solauto_position_seeds), + SplTokenTransferArgs { + source: position_ta, + authority: solauto_position.account_info, + recipient: signer_ta, + amount: position_ta_data.amount, + authority_seeds: Some(solauto_position_seeds), + }, )?; } diff --git a/programs/solauto/src/instructions/open_position.rs b/programs/solauto/src/instructions/open_position.rs index e19850a1..610088d4 100644 --- a/programs/solauto/src/instructions/open_position.rs +++ b/programs/solauto/src/instructions/open_position.rs @@ -15,7 +15,6 @@ use self::solana_utils::account_has_data; pub fn marginfi_open_position<'a>( ctx: Context<'a, MarginfiOpenPositionAccounts<'a>>, mut solauto_position: DeserializedAccount<'a, SolautoPosition>, - marginfi_account_seed_idx: Option, ) -> ProgramResult { initialize_solauto_position( &mut solauto_position, @@ -30,7 +29,7 @@ pub fn marginfi_open_position<'a>( ctx.accounts.signer_debt_ta, )?; - MarginfiClient::initialize(&ctx, &solauto_position, marginfi_account_seed_idx) + MarginfiClient::initialize(&ctx, &solauto_position) } fn initialize_solauto_position<'a, 'b>( @@ -74,13 +73,5 @@ fn initialize_solauto_position<'a, 'b>( debt_mint, )?; - solauto_utils::initiate_dca_in_if_necessary( - token_program, - solauto_position, - Some(position_debt_ta), - signer, - signer_debt_ta, - )?; - ix_utils::update_data(solauto_position) } diff --git a/programs/solauto/src/instructions/rebalance.rs b/programs/solauto/src/instructions/rebalance.rs index 5a116227..0ca6fe95 100644 --- a/programs/solauto/src/instructions/rebalance.rs +++ b/programs/solauto/src/instructions/rebalance.rs @@ -2,23 +2,26 @@ use std::ops::Sub; use marginfi_sdk::generated::accounts::Bank; use solana_program::{ - clock::Clock, entrypoint::ProgramResult, msg, program_error::ProgramError, pubkey::Pubkey, + clock::Clock, entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey, sysvar::Sysvar, }; use crate::{ + check, clients::marginfi::MarginfiClient, - state::solauto_position::{SolautoPosition, SolautoRebalanceType}, + rebalance::solauto_fees::SolautoFeesBps, + state::solauto_position::SolautoPosition, types::{ + errors::SolautoError, instruction::{ accounts::{Context, MarginfiRebalanceAccounts}, RebalanceSettings, SolautoStandardAccounts, }, lending_protocol::{LendingProtocolClient, LendingProtocolTokenAccounts}, - shared::{DeserializedAccount, RebalanceStep}, + shared::{DeserializedAccount, RebalanceStep, SolautoRebalanceType, TokenType}, solauto_manager::{SolautoManager, SolautoManagerAccounts}, }, - utils::{ix_utils, solauto_utils}, + utils::ix_utils, }; use super::refresh; @@ -59,10 +62,14 @@ pub fn marginfi_rebalance<'a>( let solauto_manager_accounts = SolautoManagerAccounts::from(supply_tas, debt_tas, ctx.accounts.intermediary_ta, None)?; - let rebalance_type = std_accounts.solauto_position.data.rebalance.rebalance_type; - if rebalance_step == RebalanceStep::Initial + let rebalance_type = std_accounts + .solauto_position + .data + .rebalance + .ixs + .rebalance_type; + if rebalance_step == RebalanceStep::PreSwap || rebalance_type == SolautoRebalanceType::FLSwapThenRebalance - || rebalance_type == SolautoRebalanceType::FLRebalanceThenSwap { if needs_refresh(&std_accounts.solauto_position, &args)? { refresh::marginfi_refresh_accounts( @@ -74,28 +81,22 @@ pub fn marginfi_rebalance<'a>( ctx.accounts.debt_bank, ctx.accounts.debt_price_oracle.unwrap(), &mut std_accounts.solauto_position, + args.price_type.unwrap().clone(), )?; } else { - std_accounts - .solauto_position - .data - .state - .supply - .update_market_price(MarginfiClient::load_price( - &DeserializedAccount::::zerocopy(Some(ctx.accounts.supply_bank))? - .unwrap(), - ctx.accounts.supply_price_oracle.unwrap(), - )?); - std_accounts - .solauto_position - .data - .state - .debt - .update_market_price(MarginfiClient::load_price( - &DeserializedAccount::::zerocopy(Some(ctx.accounts.debt_bank))?.unwrap(), - ctx.accounts.debt_price_oracle.unwrap(), - )?); - std_accounts.solauto_position.data.refresh_state(); + let supply_price = MarginfiClient::load_price( + &DeserializedAccount::::zerocopy(Some(ctx.accounts.supply_bank))?.unwrap(), + ctx.accounts.supply_price_oracle.unwrap(), + args.price_type.unwrap().clone(), + TokenType::Supply, + )?; + let debt_price = MarginfiClient::load_price( + &DeserializedAccount::::zerocopy(Some(ctx.accounts.debt_bank))?.unwrap(), + ctx.accounts.debt_price_oracle.unwrap(), + args.price_type.unwrap().clone(), + TokenType::Debt, + )?; + update_token_prices(&mut std_accounts, supply_price, debt_price); } } @@ -108,6 +109,26 @@ pub fn marginfi_rebalance<'a>( ) } +fn update_token_prices<'a>( + std_accounts: &mut Box>, + supply_price: f64, + debt_price: f64, +) { + std_accounts + .solauto_position + .data + .state + .supply + .update_market_price(supply_price); + std_accounts + .solauto_position + .data + .state + .debt + .update_market_price(debt_price); + std_accounts.solauto_position.data.refresh_state(); +} + fn needs_refresh( solauto_position: &DeserializedAccount, args: &RebalanceSettings, @@ -118,23 +139,8 @@ fn needs_refresh( let current_timestamp = Clock::get()?.unix_timestamp as u64; - if solauto_position - .data - .position - .setting_params - .automation - .is_active() - { - return Ok(solauto_position - .data - .position - .setting_params - .automation - .eligible_for_next_period(current_timestamp)); - } - - // In case we did a refresh in this same transaction before this ix - if current_timestamp.sub(solauto_position.data.state.last_updated) <= 2 { + // In case we did a refresh recently + if current_timestamp.sub(solauto_position.data.state.last_refreshed) <= 2 { return Ok(false); } @@ -154,16 +160,21 @@ fn rebalance<'a>( rebalance_step: RebalanceStep, args: RebalanceSettings, ) -> ProgramResult { - if args.target_liq_utilization_rate_bps.is_some() - && std_accounts.signer.key != &std_accounts.solauto_position.data.authority - { - msg!( - "Cannot provide a target liquidation utilization rate if the instruction is not signed by the position authority" - ); - return Err(ProgramError::InvalidInstructionData.into()); - } + check!( + args.target_liq_utilization_rate_bps.is_none() + || std_accounts.signer.key == &std_accounts.solauto_position.data.authority, + SolautoError::NonAuthorityProvidedTargetLTV + ); + check!( + std_accounts.authority_referral_state.is_some(), + SolautoError::IncorrectAccounts + ); + check!( + args.flash_loan_fee_bps.unwrap_or(0) <= 150, + SolautoError::IncorrectInstructions + ); - let fees_bps = solauto_utils::SolautoFeesBps::from( + let fees_bps = SolautoFeesBps::from( std_accounts .authority_referral_state .as_ref() @@ -186,11 +197,7 @@ fn rebalance<'a>( std_accounts, Some(fees_bps), )?; - if rebalance_step == RebalanceStep::Initial { - solauto_manager.begin_rebalance(&args)?; - } else { - solauto_manager.finish_rebalance(&args)?; - } + solauto_manager.rebalance(args, rebalance_step)?; ix_utils::update_data(&mut solauto_manager.std_accounts.solauto_position) } diff --git a/programs/solauto/src/instructions/referral_fees.rs b/programs/solauto/src/instructions/referral_fees.rs index c4c0d379..3f3beb44 100644 --- a/programs/solauto/src/instructions/referral_fees.rs +++ b/programs/solauto/src/instructions/referral_fees.rs @@ -6,7 +6,7 @@ use crate::{ state::referral_state::ReferralState, types::{ instruction::accounts::{ClaimReferralFeesAccounts, Context, ConvertReferralFeesAccounts}, - shared::DeserializedAccount, + shared::{DeserializedAccount, SplTokenTransferArgs}, }, utils::solana_utils, }; @@ -19,11 +19,13 @@ pub fn convert_referral_fees( solana_utils::spl_token_transfer( ctx.accounts.token_program, - ctx.accounts.referral_fees_ta, - ctx.accounts.referral_state, - ctx.accounts.intermediary_ta, - balance, - Some(&referral_state.data.seeds_with_bump()), + SplTokenTransferArgs { + source: ctx.accounts.referral_fees_ta, + authority: ctx.accounts.referral_state, + recipient: ctx.accounts.intermediary_ta, + amount: balance, + authority_seeds: Some(&referral_state.data.seeds_with_bump()), + }, )?; Ok(()) @@ -50,11 +52,13 @@ pub fn claim_referral_fees( let account_rent = rent.minimum_balance(TokenAccount::LEN); solana_utils::spl_token_transfer( ctx.accounts.token_program, - ctx.accounts.referral_fees_dest_ta, - ctx.accounts.referral_state, - ctx.accounts.signer_wsol_ta.unwrap(), - account_rent, - Some(referral_state_seeds), + SplTokenTransferArgs { + source: ctx.accounts.referral_fees_dest_ta, + authority: ctx.accounts.referral_state, + recipient: ctx.accounts.signer_wsol_ta.unwrap(), + amount: account_rent, + authority_seeds: Some(referral_state_seeds), + }, )?; solana_utils::close_token_account( @@ -78,7 +82,7 @@ pub fn claim_referral_fees( solana_utils::close_token_account( ctx.accounts.token_program, ctx.accounts.referral_fees_dest_ta, - ctx.accounts.referral_authority.unwrap(), + ctx.accounts.referral_authority, ctx.accounts.referral_state, Some(referral_state_seeds), )?; @@ -96,7 +100,7 @@ pub fn claim_referral_fees( ctx.accounts.token_program, ctx.accounts.system_program, ctx.accounts.signer, - ctx.accounts.referral_authority.unwrap(), + ctx.accounts.referral_authority, ctx.accounts.fees_destination_ta.unwrap(), ctx.accounts.referral_fees_dest_mint, )?; @@ -106,11 +110,13 @@ pub fn claim_referral_fees( solana_utils::spl_token_transfer( ctx.accounts.token_program, - ctx.accounts.referral_fees_dest_ta, - ctx.accounts.referral_state, - ctx.accounts.fees_destination_ta.unwrap(), - balance, - Some(referral_state_seeds), + SplTokenTransferArgs { + source: ctx.accounts.referral_fees_dest_ta, + authority: ctx.accounts.referral_state, + recipient: ctx.accounts.fees_destination_ta.unwrap(), + amount: balance, + authority_seeds: Some(referral_state_seeds), + }, )?; } diff --git a/programs/solauto/src/instructions/refresh.rs b/programs/solauto/src/instructions/refresh.rs index a53be341..f7f1ed5d 100644 --- a/programs/solauto/src/instructions/refresh.rs +++ b/programs/solauto/src/instructions/refresh.rs @@ -6,7 +6,10 @@ use solana_program::{ use crate::{ clients::marginfi::MarginfiClient, state::solauto_position::SolautoPosition, - types::{shared::DeserializedAccount, solauto_manager::SolautoManager}, + types::{ + shared::{DeserializedAccount, PriceType}, + solauto_manager::SolautoManager, + }, utils::ix_utils, }; @@ -19,6 +22,7 @@ pub fn marginfi_refresh_accounts<'a, 'b>( debt_bank: &'a AccountInfo<'a>, debt_price_oracle: &'a AccountInfo<'a>, solauto_position: &'b mut DeserializedAccount, + price_type: PriceType, ) -> ProgramResult { MarginfiClient::refresh_bank(marginfi_program, marginfi_group, supply_bank)?; MarginfiClient::refresh_bank(marginfi_program, marginfi_group, debt_bank)?; @@ -32,6 +36,7 @@ pub fn marginfi_refresh_accounts<'a, 'b>( supply_price_oracle, debt_bank, debt_price_oracle, + price_type, )?; SolautoManager::refresh_position(&mut solauto_position.data, updated_state, Clock::get()?)?; diff --git a/programs/solauto/src/instructions/update_position.rs b/programs/solauto/src/instructions/update_position.rs index 5c616767..b625c163 100644 --- a/programs/solauto/src/instructions/update_position.rs +++ b/programs/solauto/src/instructions/update_position.rs @@ -1,15 +1,15 @@ -use solana_program::{clock::Clock, entrypoint::ProgramResult, msg, sysvar::Sysvar}; +use solana_program::{clock::Clock, entrypoint::ProgramResult, sysvar::Sysvar}; use crate::{ - state::solauto_position::{DCASettings, SolautoPosition, SolautoSettingsParameters}, + state::solauto_position::{SolautoPosition, SolautoSettingsParameters}, types::{ instruction::{ accounts::{Context, UpdatePositionAccounts}, UpdatePositionData, }, - shared::{DeserializedAccount, SolautoError, TokenType}, + shared::DeserializedAccount, }, - utils::{ix_utils, solana_utils, solauto_utils, validation_utils}, + utils::{ix_utils, validation_utils}, }; pub fn update_position<'a>( @@ -17,64 +17,12 @@ pub fn update_position<'a>( mut solauto_position: DeserializedAccount<'a, SolautoPosition>, new_data: UpdatePositionData, ) -> ProgramResult { - if new_data.dca.is_some() { - update_dca(&ctx, &mut solauto_position, &new_data)?; + if new_data.settings.is_some() { + solauto_position.data.position.settings = + SolautoSettingsParameters::from(new_data.settings.unwrap()); } - if new_data.setting_params.is_some() { - solauto_position.data.position.setting_params = - SolautoSettingsParameters::from(new_data.setting_params.unwrap()); - } - - let current_timestamp = Clock::get()?.unix_timestamp as u64; - validation_utils::validate_position_settings(&solauto_position.data, current_timestamp)?; - validation_utils::validate_dca_settings(&solauto_position.data.position, current_timestamp)?; + validation_utils::validate_position_settings(&solauto_position.data)?; ix_utils::update_data(&mut solauto_position) } - -fn update_dca<'a, 'b>( - ctx: &'b Context>, - solauto_position: &'b mut DeserializedAccount<'a, SolautoPosition>, - new_data: &'b UpdatePositionData, -) -> ProgramResult { - let new_dca = new_data.dca.as_ref().unwrap(); - - if solauto_position.data.position.dca.is_active() && solauto_position.data.position.dca.dca_in() - { - msg!("Existing DCA must be canceled first through the cancel DCA instruction"); - return Err(SolautoError::IncorrectInstructions.into()); - } - - solauto_position.data.position.dca = DCASettings::from(new_data.dca.as_ref().unwrap().clone()); - - if new_dca.dca_in_base_unit > 0 { - if (new_dca.token_type == TokenType::Debt - && solauto_position.data.state.debt.mint != *ctx.accounts.dca_mint.unwrap().key) - || (new_dca.token_type == TokenType::Supply - && solauto_position.data.state.supply.mint != *ctx.accounts.dca_mint.unwrap().key) - { - msg!("Incorrect dca mint account provided for the given DCA"); - return Err(SolautoError::IncorrectAccounts.into()); - } - - solana_utils::init_ata_if_needed( - ctx.accounts.token_program, - ctx.accounts.system_program, - ctx.accounts.signer, - solauto_position.account_info, - ctx.accounts.position_dca_ta.unwrap(), - ctx.accounts.dca_mint.unwrap(), - )?; - - solauto_utils::initiate_dca_in_if_necessary( - ctx.accounts.token_program, - solauto_position, - ctx.accounts.position_dca_ta, - ctx.accounts.signer, - ctx.accounts.signer_dca_ta, - )?; - } - - Ok(()) -} diff --git a/programs/solauto/src/lib.rs b/programs/solauto/src/lib.rs index ad684f9b..5bde0348 100644 --- a/programs/solauto/src/lib.rs +++ b/programs/solauto/src/lib.rs @@ -2,7 +2,9 @@ pub mod clients; pub mod constants; pub mod entrypoint; pub mod instructions; +pub mod macros; pub mod processors; +pub mod rebalance; pub mod state; pub mod types; pub mod utils; diff --git a/programs/solauto/src/macros.rs b/programs/solauto/src/macros.rs new file mode 100644 index 00000000..0f6190c2 --- /dev/null +++ b/programs/solauto/src/macros.rs @@ -0,0 +1,52 @@ +#[macro_export] +macro_rules! check { + ($cond:expr, $err:expr) => { + if !($cond) { + let error_code = $err; + solana_program::msg!( + "Error \"{}\" thrown at {}:{}", + error_code, + file!(), + line!() + ); + return Err(error_code.into()); + } + }; + + ( + $cond:expr, + $err:expr, + $($arg:tt)* + ) => { + if !($cond) { + let error_code = $err; + solana_program::msg!( + "Error \"{}\" thrown at {}:{}", + error_code, + file!(), + line!() + ); + solana_program::msg!($($arg)*); + return Err(error_code.into()); + } + }; +} + +#[macro_export] +macro_rules! error_if { + ($cond:expr, $err:expr) => { + if ($cond) { + let error_code = $err; + solana_program::msg!("Error \"{}\" thrown at {}:{}", error_code, file!(), line!()); + return Err(error_code.into()); + } + }; +} + +#[macro_export] +macro_rules! derive_pod_traits { + ($type:ty) => { + unsafe impl Zeroable for $type {} + unsafe impl Pod for $type {} + }; +} diff --git a/programs/solauto/src/processors/marginfi.rs b/programs/solauto/src/processors/marginfi.rs index a8406cbd..69e4a554 100644 --- a/programs/solauto/src/processors/marginfi.rs +++ b/programs/solauto/src/processors/marginfi.rs @@ -1,14 +1,13 @@ -use rebalance_utils::get_rebalance_step; -use solana_program::{ - account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, - program_error::ProgramError, sysvar::Sysvar, -}; +use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, msg}; use crate::{ + check, clients::marginfi::MarginfiClient, instructions::{open_position, protocol_interaction, rebalance, refresh}, + rebalance::utils::set_rebalance_ixs_data, state::{referral_state::ReferralState, solauto_position::SolautoPosition}, types::{ + errors::SolautoError, instruction::{ accounts::{ MarginfiOpenPositionAccounts, MarginfiProtocolInteractionAccounts, @@ -16,7 +15,7 @@ use crate::{ }, MarginfiOpenPositionData, RebalanceSettings, SolautoAction, SolautoStandardAccounts, }, - shared::{DeserializedAccount, LendingPlatform, SolautoError}, + shared::{DeserializedAccount, LendingPlatform, PriceType}, }, utils::*, }; @@ -49,20 +48,12 @@ pub fn process_marginfi_open_position_instruction<'a>( ctx.accounts.debt_mint, ctx.accounts.debt_bank, ctx.accounts.marginfi_account, + ctx.accounts.marginfi_group, max_ltv, liq_threshold, )?; if !solauto_position.data.self_managed.val { - let current_timestamp = Clock::get()?.unix_timestamp as u64; - validation_utils::validate_position_settings(&solauto_position.data, current_timestamp)?; - validation_utils::validate_dca_settings( - &solauto_position.data.position, - current_timestamp, - )?; - } - if solauto_position.data.self_managed.val && args.marginfi_account_seed_idx.is_some() { - msg!("Provided a Marginfi account seed index on a self-managed index"); - return Err(ProgramError::InvalidInstructionData.into()); + validation_utils::validate_position_settings(&solauto_position.data)?; } if ctx.accounts.referred_by_supply_ta.is_some() { @@ -108,14 +99,13 @@ pub fn process_marginfi_open_position_instruction<'a>( false, )?; - open_position::marginfi_open_position( - ctx, - std_accounts.solauto_position, - args.marginfi_account_seed_idx, - ) + open_position::marginfi_open_position(ctx, std_accounts.solauto_position) } -pub fn process_marginfi_refresh_data<'a>(accounts: &'a [AccountInfo<'a>]) -> ProgramResult { +pub fn process_marginfi_refresh_data<'a>( + accounts: &'a [AccountInfo<'a>], + price_type: PriceType, +) -> ProgramResult { msg!("Instruction: Marginfi refresh data"); let ctx = MarginfiRefreshDataAccounts::context(accounts)?; let mut solauto_position = @@ -148,6 +138,7 @@ pub fn process_marginfi_refresh_data<'a>(accounts: &'a [AccountInfo<'a>]) -> Pro ctx.accounts.debt_bank, ctx.accounts.debt_price_oracle, &mut solauto_position, + price_type, ) } @@ -216,23 +207,14 @@ pub fn process_marginfi_rebalance<'a>( false, )?; - // TODO: For DCAing-out - if ctx.accounts.position_authority.is_some() - && &std_accounts.solauto_position.data.authority - != ctx.accounts.position_authority.unwrap().key - { - msg!("Incorrect position authority provided"); - return Err(SolautoError::IncorrectAccounts.into()); - } + check!( + ctx.accounts.position_authority.is_none() + || &std_accounts.solauto_position.data.authority + == ctx.accounts.position_authority.unwrap().key, + SolautoError::IncorrectAccounts + ); - let rebalance_step = get_rebalance_step( - &mut std_accounts, - &args, - vec![ - ctx.accounts.position_supply_ta.key, - ctx.accounts.position_debt_ta.key, - ], - )?; + let rebalance_step = set_rebalance_ixs_data(&mut std_accounts, &args)?; rebalance::marginfi_rebalance(ctx, std_accounts, rebalance_step, args) } diff --git a/programs/solauto/src/processors/position.rs b/programs/solauto/src/processors/position.rs index 8fda5c89..ffc9cba8 100644 --- a/programs/solauto/src/processors/position.rs +++ b/programs/solauto/src/processors/position.rs @@ -1,16 +1,16 @@ -use solana_program::{ - account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, sysvar::Sysvar, -}; +use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, msg}; use crate::{ + check, instructions::{close_position, update_position}, state::solauto_position::SolautoPosition, types::{ + errors::SolautoError, instruction::{ accounts::{CancelDCAAccounts, ClosePositionAccounts, UpdatePositionAccounts}, UpdatePositionData, }, - shared::{DeserializedAccount, SolautoError}, + shared::DeserializedAccount, }, utils::{ix_utils, solauto_utils, validation_utils}, }; @@ -26,7 +26,7 @@ pub fn process_update_position_instruction<'a>( .unwrap(); validation_utils::validate_instruction(ctx.accounts.signer, &solauto_position, true, true)?; - validation_utils::validate_sysvar_accounts( + validation_utils::validate_standard_programs( Some(ctx.accounts.system_program), Some(ctx.accounts.token_program), None, @@ -54,7 +54,7 @@ pub fn process_close_position_instruction<'a>(accounts: &'a [AccountInfo<'a>]) - .unwrap(); validation_utils::validate_instruction(ctx.accounts.signer, &solauto_position, true, true)?; - validation_utils::validate_sysvar_accounts( + validation_utils::validate_standard_programs( Some(ctx.accounts.system_program), Some(ctx.accounts.token_program), Some(ctx.accounts.ata_program), @@ -76,7 +76,7 @@ pub fn process_close_position_instruction<'a>(accounts: &'a [AccountInfo<'a>]) - if !cfg!(feature = "local") { validation_utils::validate_no_active_balances( - ctx.accounts.protocol_account, + ctx.accounts.lp_user_account, solauto_position.data.position.lending_platform, )?; } @@ -85,47 +85,6 @@ pub fn process_close_position_instruction<'a>(accounts: &'a [AccountInfo<'a>]) - } pub fn process_cancel_dca<'a>(accounts: &'a [AccountInfo<'a>]) -> ProgramResult { - msg!("Instruction: Cancel DCA"); - let ctx = CancelDCAAccounts::context(accounts)?; - let mut solauto_position = - DeserializedAccount::::zerocopy(Some(ctx.accounts.solauto_position))? - .unwrap(); - - validation_utils::validate_instruction(ctx.accounts.signer, &solauto_position, true, true)?; - validation_utils::validate_sysvar_accounts( - Some(ctx.accounts.system_program), - Some(ctx.accounts.token_program), - Some(ctx.accounts.ata_program), - None, - None, - )?; - - if !solauto_position.data.position.dca.is_active() { - msg!("No active DCA exists on the provided Solauto position"); - return Err(SolautoError::IncorrectAccounts.into()); - } - - validation_utils::validate_token_account( - &solauto_position, - ctx.accounts.position_dca_ta, - Some(solauto_position.data.position.dca.token_type), - None, - )?; - - solauto_utils::cancel_dca_in( - ctx.accounts.signer, - ctx.accounts.system_program, - ctx.accounts.token_program, - &mut solauto_position, - ctx.accounts.dca_mint, - ctx.accounts.position_dca_ta, - ctx.accounts.signer_dca_ta, - )?; - - validation_utils::validate_position_settings( - &solauto_position.data, - Clock::get()?.unix_timestamp as u64, - )?; - - ix_utils::update_data(&mut solauto_position) + // TODO + Ok(()) } diff --git a/programs/solauto/src/processors/referral_state.rs b/programs/solauto/src/processors/referral_state.rs index 7a6f7fe6..6898c946 100644 --- a/programs/solauto/src/processors/referral_state.rs +++ b/programs/solauto/src/processors/referral_state.rs @@ -7,13 +7,15 @@ use solana_program::{ program_error::ProgramError, sysvar::instructions::{load_current_index_checked, load_instruction_at_checked}, }; -use spl_associated_token_account::get_associated_token_address; use crate::{ + check, constants::WSOL_MINT, + error_if, instructions::referral_fees, state::referral_state::ReferralState, types::{ + errors::SolautoError, instruction::{ accounts::{ ClaimReferralFeesAccounts, ConvertReferralFeesAccounts, @@ -21,7 +23,7 @@ use crate::{ }, UpdateReferralStatesArgs, }, - shared::{DeserializedAccount, SolautoError}, + shared::DeserializedAccount, }, utils::{ix_utils, solauto_utils, validation_utils}, }; @@ -33,19 +35,17 @@ pub fn process_update_referral_states<'a>( msg!("Instruction: Update referral states"); let ctx = UpdateReferralStatesAccounts::context(accounts)?; - if !ctx.accounts.signer.is_signer { - msg!("Missing required referral signer"); - return Err(ProgramError::MissingRequiredSignature.into()); - } - - if ctx.accounts.referred_by_authority.is_some() - && ctx.accounts.referred_by_authority.unwrap().key == ctx.accounts.signer.key - { - msg!("Cannot set the referred by as the same as the referral state authority"); - return Err(SolautoError::IncorrectAccounts.into()); - } + check!( + ctx.accounts.signer.is_signer, + ProgramError::MissingRequiredSignature + ); + check!( + ctx.accounts.referred_by_authority.is_none() + || ctx.accounts.referred_by_authority.unwrap().key != ctx.accounts.signer.key, + SolautoError::IncorrectAccounts + ); - validation_utils::validate_sysvar_accounts( + validation_utils::validate_standard_programs( Some(ctx.accounts.system_program), None, None, @@ -92,7 +92,7 @@ pub fn process_convert_referral_fees<'a>(accounts: &'a [AccountInfo<'a>]) -> Pro DeserializedAccount::::zerocopy(Some(ctx.accounts.referral_state))?.unwrap(); validation_utils::validate_referral_signer(&referral_state, ctx.accounts.signer, true)?; - validation_utils::validate_sysvar_accounts( + validation_utils::validate_standard_programs( Some(ctx.accounts.system_program), Some(ctx.accounts.token_program), Some(ctx.accounts.ata_program), @@ -100,21 +100,21 @@ pub fn process_convert_referral_fees<'a>(accounts: &'a [AccountInfo<'a>]) -> Pro Some(ctx.accounts.ixs_sysvar), )?; - if !validation_utils::token_account_owned_by( - ctx.accounts.referral_fees_ta, - ctx.accounts.referral_state.key, - None, - )? { - msg!("Provided incorrect token account for the given referral state account"); - return Err(SolautoError::IncorrectAccounts.into()); - } + check!( + validation_utils::token_account_owned_by( + ctx.accounts.referral_fees_ta, + ctx.accounts.referral_state.key, + None + )?, + SolautoError::IncorrectAccounts + ); let current_ix_idx = load_current_index_checked(ctx.accounts.ixs_sysvar)?; let current_ix = load_instruction_at_checked(current_ix_idx as usize, ctx.accounts.ixs_sysvar)?; - if current_ix.program_id != crate::ID || get_stack_height() > TRANSACTION_LEVEL_STACK_HEIGHT { - msg!("Instruction is CPI"); - return Err(SolautoError::InstructionIsCPI.into()); - } + error_if!( + current_ix.program_id != crate::ID || get_stack_height() > TRANSACTION_LEVEL_STACK_HEIGHT, + SolautoError::InstructionIsCPI + ); let mut index = current_ix_idx; loop { @@ -126,25 +126,12 @@ pub fn process_convert_referral_fees<'a>(accounts: &'a [AccountInfo<'a>]) -> Pro let jup_swap = ix_utils::InstructionChecker::from_anchor( ctx.accounts.ixs_sysvar, - JUPITER_ID, + vec![JUPITER_ID], vec!["route", "shared_accounts_route"], current_ix_idx, ); - // Continues to break due to the fact that Jupiter keeps changing their program - // ix_utils::validate_jup_instruction( - // ctx.accounts.ixs_sysvar, - // (current_ix_idx + 1) as usize, - // &[&get_associated_token_address( - // ctx.accounts.referral_state.key, - // &referral_state.data.dest_fees_mint, - // )], - // )?; - - if !jup_swap.matches(1) { - msg!("Missing Jup swap as next transaction"); - return Err(SolautoError::IncorrectInstructions.into()); - } + check!(jup_swap.matches(1), SolautoError::IncorrectInstructions); referral_fees::convert_referral_fees(ctx, referral_state) } @@ -157,14 +144,7 @@ pub fn process_claim_referral_fees<'a>(accounts: &'a [AccountInfo<'a>]) -> Progr DeserializedAccount::::zerocopy(Some(ctx.accounts.referral_state))?.unwrap(); validation_utils::validate_referral_signer(&referral_state, ctx.accounts.signer, true)?; - if ctx.accounts.referral_authority.is_some() - && ctx.accounts.referral_authority.unwrap().key != &referral_state.data.authority - { - msg!("Provided incorrect referral authority"); - return Err(SolautoError::IncorrectAccounts.into()); - } - - validation_utils::validate_sysvar_accounts( + validation_utils::validate_standard_programs( Some(ctx.accounts.system_program), Some(ctx.accounts.token_program), None, @@ -172,36 +152,37 @@ pub fn process_claim_referral_fees<'a>(accounts: &'a [AccountInfo<'a>]) -> Progr None, )?; - if ctx.accounts.referral_fees_dest_ta.key - != &get_associated_token_address( + check!( + ctx.accounts.referral_authority.key == &referral_state.data.authority, + SolautoError::IncorrectAccounts + ); + check!( + validation_utils::correct_token_account( + ctx.accounts.referral_fees_dest_ta.key, ctx.accounts.referral_state.key, - &referral_state.data.dest_fees_mint, - ) - { - msg!("Provided incorrect referral_fees_dest_ta account"); - return Err(SolautoError::IncorrectAccounts.into()); - } - - if ctx.accounts.referral_fees_dest_mint.key != &referral_state.data.dest_fees_mint { - msg!("Provided incorrect referral_fees_dest_mint account"); - return Err(SolautoError::IncorrectAccounts.into()); - } - - if referral_state.data.dest_fees_mint != WSOL_MINT && ctx.accounts.fees_destination_ta.is_none() - { - msg!("Missing fees destination token account when the token mint is not wSOL"); - return Err(SolautoError::IncorrectAccounts.into()); - } + &referral_state.data.dest_fees_mint + ), + SolautoError::IncorrectAccounts + ); + check!( + ctx.accounts.referral_fees_dest_mint.key == &referral_state.data.dest_fees_mint, + SolautoError::IncorrectAccounts + ); + error_if!( + referral_state.data.dest_fees_mint != WSOL_MINT + && ctx.accounts.fees_destination_ta.is_none(), + SolautoError::IncorrectAccounts + ); - if ctx.accounts.fees_destination_ta.is_some() - && ctx.accounts.fees_destination_ta.unwrap().key - != &get_associated_token_address( + if ctx.accounts.fees_destination_ta.is_some() { + check!( + validation_utils::correct_token_account( + ctx.accounts.fees_destination_ta.unwrap().key, &referral_state.data.authority, - &referral_state.data.dest_fees_mint, - ) - { - msg!("Provided incorrect fees_destination_ta for the given referral state and destination token mint"); - return Err(SolautoError::IncorrectAccounts.into()); + &referral_state.data.dest_fees_mint + ), + SolautoError::IncorrectAccounts + ); } referral_fees::claim_referral_fees(ctx, referral_state) diff --git a/programs/solauto/src/rebalance/mod.rs b/programs/solauto/src/rebalance/mod.rs new file mode 100644 index 00000000..d5e32b83 --- /dev/null +++ b/programs/solauto/src/rebalance/mod.rs @@ -0,0 +1,4 @@ +pub mod rebalancer; +pub mod rebalancer_tests; +pub mod solauto_fees; +pub mod utils; diff --git a/programs/solauto/src/rebalance/rebalancer.rs b/programs/solauto/src/rebalance/rebalancer.rs new file mode 100644 index 00000000..b6981768 --- /dev/null +++ b/programs/solauto/src/rebalance/rebalancer.rs @@ -0,0 +1,502 @@ +use std::{ + cmp::min, + ops::{Add, Mul}, +}; + +use solana_program::{entrypoint::ProgramResult, msg, program_error::ProgramError, pubkey::Pubkey}; + +use crate::{ + check, + constants::SOLAUTO_FEES_WALLET, + state::solauto_position::{ + PositionTokenState, RebalanceData, SolautoPosition, TokenBalanceChangeType, + }, + types::{ + errors::SolautoError, + instruction::RebalanceSettings, + shared::{ + BareSplTokenTransferArgs, RebalanceDirection, RebalanceStep, SolautoRebalanceType, + SwapType, TokenBalanceAmount, + }, + solauto::{FromLendingPlatformAction, SolautoCpiAction}, + }, + utils::{ + math_utils::{calc_fee_amount, from_bps, from_rounded_usd_value, usd_value_to_base_unit}, + validation_utils::{ + correct_token_account, value_gte_with_threshold, value_lte_with_threshold, + }, + }, +}; + +use super::{ + solauto_fees::SolautoFeesBps, + utils::{eligible_for_rebalance, get_rebalance_values}, +}; + +pub struct TokenAccountData { + pub pk: Pubkey, + pub balance: u64, +} +impl TokenAccountData { + pub fn from(pk: Pubkey, balance: u64) -> Self { + Self { pk, balance } + } + pub fn without_balance(pk: Pubkey) -> Self { + Self { pk, balance: 0 } + } +} + +pub struct SolautoPositionData<'a> { + pub data: &'a mut Box, + pub supply_ta: TokenAccountData, + pub debt_ta: TokenAccountData, +} + +pub struct RebalancerData<'a> { + pub rebalance_args: RebalanceSettings, + pub solauto_position: SolautoPositionData<'a>, + pub intermediary_ta: TokenAccountData, + pub authority_supply_ta: Option, + pub authority_debt_ta: Option, + pub solauto_fees_bps: SolautoFeesBps, + pub solauto_fees_ta: Option, + pub referred_by_state: Option, + pub referred_by_ta: Option, +} + +pub struct RebalanceResult { + pub finished: bool, +} + +pub struct Rebalancer<'a> { + actions: Vec, + pub data: RebalancerData<'a>, +} + +impl<'a> Rebalancer<'a> { + pub fn new(data: RebalancerData<'a>) -> Self { + Self { + actions: Vec::::new(), + data, + } + } + + pub fn actions(&self) -> &Vec { + &self.actions + } + + pub fn reset_actions(&mut self) { + self.actions = Vec::new(); + } + + fn position_data(&self) -> &Box { + &self.data.solauto_position.data + } + + fn position_supply_ta(&self) -> &TokenAccountData { + &self.data.solauto_position.supply_ta + } + + fn position_debt_ta(&self) -> &TokenAccountData { + &self.data.solauto_position.debt_ta + } + + fn rebalance_data(&self) -> &RebalanceData { + &self.position_data().rebalance + } + + fn is_boost(&self) -> bool { + self.rebalance_data().values.rebalance_direction == RebalanceDirection::Boost + } + + fn set_rebalance_data(&mut self) -> ProgramResult { + if self.rebalance_data().values_set() { + return Ok(()); + } + + check!( + self.data + .rebalance_args + .target_liq_utilization_rate_bps + .is_some() + || eligible_for_rebalance(self.position_data()), + SolautoError::InvalidRebalanceCondition + ); + + self.data.solauto_position.data.rebalance.values = get_rebalance_values( + self.position_data(), + &self.data.rebalance_args, + &self.data.solauto_fees_bps, + )?; + + Ok(()) + } + + fn calc_additional_amount( + &self, + rounded_usd_value: u64, + token_usage: PositionTokenState, + max: Option, + ) -> u64 { + let base_unit_amount = usd_value_to_base_unit( + from_rounded_usd_value(rounded_usd_value), + token_usage.decimals, + token_usage.market_price(), + ); + + if max.is_some() { + min(base_unit_amount, max.unwrap()) + } else { + base_unit_amount + } + } + + fn get_dynamic_balance(&self) -> (u64, &TokenAccountData) { + let ta = if self.is_boost() { + self.position_supply_ta() + } else { + self.position_debt_ta() + }; + + let balance = ta.balance; + // Subtract current balances that are attributed to DCA / limit order in + + (balance, ta) + } + + fn transfer_to_authority_if_needed(&mut self, base_unit_amount: u64) { + if self.position_data().self_managed.val { + let (solauto_position_ta, authority_ta) = if self.is_boost() { + (self.position_supply_ta().pk, &self.data.authority_supply_ta) + } else { + (self.position_debt_ta().pk, &self.data.authority_debt_ta) + }; + self.actions.push(SolautoCpiAction::SplTokenTransfer( + BareSplTokenTransferArgs { + from_wallet: self.data.solauto_position.data.pubkey(), + from_wallet_ta: solauto_position_ta, + to_wallet_ta: authority_ta.as_ref().unwrap().pk, + amount: base_unit_amount, + }, + )); + } + } + + fn pull_liquidity_from_lp(&mut self, base_unit_amount: u64, destination_ta: Pubkey) { + if self.is_boost() { + self.actions + .push(SolautoCpiAction::Borrow(FromLendingPlatformAction { + amount: base_unit_amount, + to_wallet_ta: destination_ta, + })); + } else { + self.actions + .push(SolautoCpiAction::Withdraw(FromLendingPlatformAction { + amount: TokenBalanceAmount::Some(base_unit_amount), + to_wallet_ta: destination_ta, + })); + } + } + + fn put_liquidity_in_lp(&mut self, base_unit_amount: u64) { + self.transfer_to_authority_if_needed(base_unit_amount); + + if self.is_boost() { + self.actions + .push(SolautoCpiAction::Deposit(base_unit_amount)); + } else { + let token_balance_amount = if self + .data + .rebalance_args + .target_liq_utilization_rate_bps + .is_some() + && self + .data + .rebalance_args + .target_liq_utilization_rate_bps + .unwrap() + == 0 + { + TokenBalanceAmount::All + } else { + TokenBalanceAmount::Some(min( + self.position_data().state.debt.amount_used.base_unit, + base_unit_amount, + )) + }; + self.actions + .push(SolautoCpiAction::Repay(token_balance_amount)); + } + } + + fn get_additional_amount_before_swap(&mut self) -> u64 { + if !self + .rebalance_data() + .values + .token_balance_change + .requires_one() + { + return 0; + } + + let token_balance_change = self.rebalance_data().values.token_balance_change; + let mut amount = 0; + + let action = match token_balance_change.change_type { + TokenBalanceChangeType::PreSwapDeposit => { + Some(SolautoCpiAction::Deposit(self.calc_additional_amount( + token_balance_change.amount_usd, + self.position_data().state.supply, + Some(self.data.solauto_position.supply_ta.balance), + ))) + } + TokenBalanceChangeType::PostSwapDeposit => { + amount = self.calc_additional_amount( + token_balance_change.amount_usd, + self.position_data().state.debt, + Some(self.data.solauto_position.debt_ta.balance), + ); + Some(SolautoCpiAction::SplTokenTransfer( + BareSplTokenTransferArgs { + amount, + from_wallet: self.data.solauto_position.data.pubkey(), + from_wallet_ta: self.position_debt_ta().pk, + to_wallet_ta: self.data.intermediary_ta.pk, + }, + )) + } + TokenBalanceChangeType::PostRebalanceWithdrawDebtToken => { + amount = self.calc_additional_amount( + token_balance_change.amount_usd, + self.position_data().state.supply, + Some(self.position_supply_ta().balance), + ); + Some(SolautoCpiAction::SplTokenTransfer( + BareSplTokenTransferArgs { + amount, + from_wallet: self.data.solauto_position.data.pubkey(), + from_wallet_ta: self.position_supply_ta().pk, + to_wallet_ta: self.data.intermediary_ta.pk, + }, + )) + } + _ => None, + }; + + if action.is_some() { + self.actions.push(action.unwrap()); + } + + amount + } + + fn get_additional_amount_after_swap(&mut self) -> u64 { + if !self + .rebalance_data() + .values + .token_balance_change + .requires_one() + { + return 0; + } + + let token_balance_change = self.rebalance_data().values.token_balance_change; + let mut amount = 0; + + let action = match token_balance_change.change_type { + TokenBalanceChangeType::PostRebalanceWithdrawSupplyToken => { + amount = self.calc_additional_amount( + token_balance_change.amount_usd, + self.position_data().state.supply, + None, + ); + Some(SolautoCpiAction::SplTokenTransfer( + BareSplTokenTransferArgs { + amount, + from_wallet: self.data.solauto_position.data.pubkey(), + from_wallet_ta: self.position_supply_ta().pk, + to_wallet_ta: self.data.authority_supply_ta.as_ref().unwrap().pk, // TODO: what if this is native mint + }, + )) + } + TokenBalanceChangeType::PostRebalanceWithdrawDebtToken => { + amount = self.calc_additional_amount( + token_balance_change.amount_usd, + self.position_data().state.debt, + None, + ); + Some(SolautoCpiAction::SplTokenTransfer( + BareSplTokenTransferArgs { + amount, + from_wallet: self.data.solauto_position.data.pubkey(), + from_wallet_ta: self.position_debt_ta().pk, + to_wallet_ta: self.data.authority_debt_ta.as_ref().unwrap().pk, // TODO: what if this is native mint + }, + )) + } + _ => None, + }; + + if action.is_some() { + self.actions.push(action.unwrap()); + } + + amount + } + + fn payout_fee( + &mut self, + available_balance: u64, + fee_pct_bps: u16, + token_mint: Pubkey, + position_ta: Pubkey, + destination_wallet: Pubkey, + destination_ta: Pubkey, + ) -> Result { + check!( + correct_token_account(&destination_ta, &destination_wallet, &token_mint), + SolautoError::IncorrectAccounts + ); + + let fee_amount = calc_fee_amount(available_balance, fee_pct_bps); + self.actions.push(SolautoCpiAction::SplTokenTransfer( + BareSplTokenTransferArgs { + from_wallet: self.data.solauto_position.data.pubkey(), + from_wallet_ta: position_ta, + to_wallet_ta: destination_ta, + amount: fee_amount, + }, + )); + + Ok(fee_amount) + } + + fn payout_fees(&mut self, available_balance: u64) -> Result { + let rebalance_direction = &self.rebalance_data().values.rebalance_direction; + let (token_mint, position_ta) = if self.is_boost() { + ( + self.position_data().state.supply.mint, + self.position_supply_ta().pk, + ) + } else { + ( + self.position_data().state.debt.mint, + self.position_debt_ta().pk, + ) + }; + let fee_payout = self.data.solauto_fees_bps.fetch_fees(rebalance_direction); + if fee_payout.total == 0 { + return Ok(available_balance); + } + + let solauto_fees = self.payout_fee( + available_balance, + fee_payout.solauto, + token_mint, + position_ta, + SOLAUTO_FEES_WALLET, + self.data.solauto_fees_ta.unwrap(), + )?; + + let referrer_fees = if self.data.referred_by_state.is_some() + && self.data.referred_by_state.unwrap() != Pubkey::default() + { + self.payout_fee( + available_balance, + fee_payout.referrer, + token_mint, + position_ta, + self.data.referred_by_state.unwrap(), + self.data.referred_by_ta.unwrap(), + )? + } else { + 0 + }; + + Ok(available_balance - solauto_fees - referrer_fees) + } + + fn repay_flash_loan_if_necessary(&mut self) -> ProgramResult { + if matches!( + self.rebalance_data().ixs.rebalance_type, + SolautoRebalanceType::DoubleRebalanceWithFL + | SolautoRebalanceType::FLRebalanceThenSwap + | SolautoRebalanceType::FLSwapThenRebalance + ) { + let flash_loan_amount = self.rebalance_data().ixs.flash_loan_amount; + + let fl_repay_amount = if self.rebalance_data().ixs.swap_type == SwapType::ExactOut { + self.data.rebalance_args.swap_in_amount_base_unit.unwrap() + } else { + check!(flash_loan_amount != 0, SolautoError::IncorrectInstructions); + let flash_loan_fee_bps = self.data.rebalance_args.flash_loan_fee_bps.unwrap_or(0); + flash_loan_amount.add( + (flash_loan_amount as f64) + .mul(from_bps(flash_loan_fee_bps)) + .ceil() as u64, + ) + }; + + self.pull_liquidity_from_lp(fl_repay_amount, self.data.intermediary_ta.pk); + } + + Ok(()) + } + + fn finish_rebalance(&mut self, dynamic_balance: u64) -> ProgramResult { + let amount_to_put_in_lp = self.payout_fees(dynamic_balance)?; + self.put_liquidity_in_lp(amount_to_put_in_lp); + self.repay_flash_loan_if_necessary()?; + Ok(()) + } + + fn pre_swap_rebalance(&mut self) -> Result { + self.set_rebalance_data()?; + + let amount_to_swap = self.data.rebalance_args.swap_in_amount_base_unit.unwrap(); + let additional_amount_to_swap = self.get_additional_amount_before_swap(); + + if self.rebalance_data().ixs.swap_type == SwapType::ExactOut { + let (dynamic_balance, _) = self.get_dynamic_balance(); + self.finish_rebalance(dynamic_balance)?; + Ok(RebalanceResult { finished: true }) + } else { + let amount_to_pull_from_lp = amount_to_swap - additional_amount_to_swap; + self.pull_liquidity_from_lp(amount_to_pull_from_lp, self.data.intermediary_ta.pk); + Ok(RebalanceResult { finished: false }) + } + } + + fn post_swap_rebalance(&mut self) -> Result { + self.set_rebalance_data()?; + + let additional_amount_after_swap = self.get_additional_amount_after_swap(); + let (dynamic_balance, balance_ta) = self.get_dynamic_balance(); + let balance_leftover = dynamic_balance - additional_amount_after_swap; + + if self.rebalance_data().ixs.swap_type == SwapType::ExactOut { + self.actions.push(SolautoCpiAction::SplTokenTransfer( + BareSplTokenTransferArgs { + from_wallet: self.data.solauto_position.data.pubkey(), + from_wallet_ta: balance_ta.pk, + to_wallet_ta: self.data.intermediary_ta.pk, + amount: balance_leftover, + }, + )); + } else { + self.finish_rebalance(balance_leftover)?; + } + + Ok(RebalanceResult { finished: true }) + } + + pub fn rebalance( + &mut self, + rebalance_step: RebalanceStep, + ) -> Result { + match rebalance_step { + RebalanceStep::PreSwap => self.pre_swap_rebalance(), + RebalanceStep::PostSwap => self.post_swap_rebalance(), + } + } +} diff --git a/programs/solauto/src/rebalance/rebalancer_tests.rs b/programs/solauto/src/rebalance/rebalancer_tests.rs new file mode 100644 index 00000000..9c836585 --- /dev/null +++ b/programs/solauto/src/rebalance/rebalancer_tests.rs @@ -0,0 +1,838 @@ +use std::ops::{Div, Mul}; + +use solana_program::pubkey::Pubkey; +use spl_associated_token_account::get_associated_token_address; + +use crate::{ + constants::SOLAUTO_FEES_WALLET, + state::solauto_position::{ + PositionData, PositionState, RebalanceData, SolautoPosition, SolautoSettingsParameters, + SolautoSettingsParametersInp, + }, + types::{ + instruction::RebalanceSettings, + shared::{ + PodBool, PositionType, RebalanceDirection, RefreshedTokenState, SwapType, + TokenBalanceAmount, + }, + solauto::{PositionValues, SolautoCpiAction}, + }, + utils::{ + math_utils::{ + from_base_unit, from_bps, from_rounded_usd_value, get_liq_utilization_rate_bps, + round_to_decimals, to_base_unit, + }, + solauto_utils::update_token_state, + validation_utils, + }, +}; + +use super::{ + rebalancer::{Rebalancer, RebalancerData, SolautoPositionData, TokenAccountData}, + solauto_fees::SolautoFeesBps, +}; + +const TEST_TOKEN_DECIMALS: u8 = 9; +const SOLAUTO_FEE_BPS: u16 = 50; +const BORROW_FEE_BPS: u16 = 50; +const FLASH_LOAN_FEE_BPS: u16 = 50; +const SUPPLY_PRICE: f64 = 100.0; +const DEBT_PRICE: f64 = 1.0; +const MAX_LTV_BPS: u16 = 6400; +const LIQ_THRESHOLD_BPS: u16 = 8181; + +pub struct FakePosition<'a> { + values: &'a PositionValues, + settings: SolautoSettingsParametersInp, + max_ltv_bps: Option, + liq_threshold_bps: Option, +} + +fn create_position<'a>(pos: &FakePosition<'a>) -> Box { + let mut state = PositionState::default(); + state.max_ltv_bps = pos.max_ltv_bps.unwrap_or(6400); + state.liq_threshold_bps = pos.liq_threshold_bps.unwrap_or(8181); + state.liq_utilization_rate_bps = get_liq_utilization_rate_bps( + pos.values.supply_usd, + pos.values.debt_usd, + from_bps(state.liq_threshold_bps), + ); + + let supply_mint = Pubkey::new_unique(); + let debt_mint = Pubkey::new_unique(); + state.supply.mint = supply_mint; + state.debt.mint = debt_mint; + + update_token_state( + &mut state.supply, + &(RefreshedTokenState { + amount_used: to_base_unit(pos.values.supply_usd / SUPPLY_PRICE, TEST_TOKEN_DECIMALS), + amount_can_be_used: 0, + mint: supply_mint, + decimals: TEST_TOKEN_DECIMALS, + market_price: SUPPLY_PRICE, + borrow_fee_bps: None, + }), + ); + update_token_state( + &mut state.debt, + &(RefreshedTokenState { + amount_used: to_base_unit(pos.values.debt_usd / DEBT_PRICE, TEST_TOKEN_DECIMALS), + amount_can_be_used: 0, + mint: debt_mint, + decimals: TEST_TOKEN_DECIMALS, + market_price: DEBT_PRICE, + borrow_fee_bps: Some(BORROW_FEE_BPS), + }), + ); + + let mut position_data = PositionData::default(); + position_data.settings = SolautoSettingsParameters::from(pos.settings); + + let position = SolautoPosition::new( + 1, + Pubkey::new_unique(), + PositionType::Leverage, + position_data, + state, + ); + + Box::new(position) +} + +pub struct FakeRebalance<'a> { + pos: &'a mut Box, + position_supply_ta_balance: Option, + position_debt_ta_balance: Option, + rebalance_direction: RebalanceDirection, +} + +fn create_rebalancer<'a>( + data: FakeRebalance<'a>, + rebalance_args: RebalanceSettings, + flash_loan_amount: Option, +) -> Rebalancer<'a> { + data.pos.rebalance.ixs.rebalance_type = rebalance_args.rebalance_type; + data.pos.rebalance.ixs.flash_loan_amount = flash_loan_amount.unwrap_or(0); + data.pos.rebalance.ixs.active = PodBool::new(true); + data.pos.rebalance.ixs.swap_type = rebalance_args.swap_type.unwrap_or(SwapType::default()); + + let position_supply_ta = + get_associated_token_address(&data.pos.pubkey(), &data.pos.state.supply.mint); + let position_debt_ta = + get_associated_token_address(&data.pos.pubkey(), &data.pos.state.debt.mint); + let position_authority_supply_ta = + get_associated_token_address(&data.pos.authority, &data.pos.state.supply.mint); + let position_authority_debt_ta = + get_associated_token_address(&data.pos.authority, &data.pos.state.debt.mint); + + let fees_mint = if data.rebalance_direction == RebalanceDirection::Boost { + data.pos.state.supply.mint + } else { + data.pos.state.debt.mint + }; + let solauto_fees_ta = get_associated_token_address(&SOLAUTO_FEES_WALLET, &fees_mint); + let solauto_fees = SolautoFeesBps::from_mock(SOLAUTO_FEE_BPS, false); + + let rebalancer = Rebalancer::new(RebalancerData { + rebalance_args, + solauto_position: SolautoPositionData { + data: data.pos, + supply_ta: TokenAccountData::from( + position_supply_ta, + data.position_supply_ta_balance.unwrap_or(0), + ), + debt_ta: TokenAccountData::from( + position_debt_ta, + data.position_debt_ta_balance.unwrap_or(0), + ), + }, + authority_supply_ta: Some(TokenAccountData::without_balance( + position_authority_supply_ta, + )), + authority_debt_ta: Some(TokenAccountData::without_balance( + position_authority_debt_ta, + )), + solauto_fees_bps: solauto_fees, + referred_by_state: None, + referred_by_ta: None, + intermediary_ta: TokenAccountData::without_balance(Pubkey::new_unique()), + solauto_fees_ta: Some(solauto_fees_ta), + }); + + rebalancer +} + +fn credit_token_account<'a>(rebalancer: &mut Rebalancer<'a>, ta_pk: Pubkey, base_unit_amount: i64) { + let credit_ta = |ta: &mut TokenAccountData| { + println!("Crediting token account with {}", base_unit_amount); + if base_unit_amount > 0 { + ta.balance += base_unit_amount as u64; + } else { + ta.balance = ta.balance.saturating_sub((base_unit_amount * -1) as u64); + } + }; + + if ta_pk == rebalancer.data.solauto_position.supply_ta.pk { + credit_ta(&mut rebalancer.data.solauto_position.supply_ta); + } else if ta_pk == rebalancer.data.solauto_position.debt_ta.pk { + credit_ta(&mut rebalancer.data.solauto_position.debt_ta); + } else if ta_pk == rebalancer.data.intermediary_ta.pk { + credit_ta(&mut rebalancer.data.intermediary_ta); + } else if ta_pk == rebalancer.data.authority_supply_ta.as_ref().unwrap().pk { + credit_ta(&mut rebalancer.data.authority_supply_ta.as_mut().unwrap()); + } else if ta_pk == rebalancer.data.authority_debt_ta.as_ref().unwrap().pk { + credit_ta(&mut rebalancer.data.authority_debt_ta.as_mut().unwrap()); + } else { + println!("Couldn't find token account"); + } +} + +fn apply_actions<'a>(rebalancer: &mut Rebalancer<'a>) { + println!("Actions: {}", rebalancer.actions().len()); + + for action in rebalancer.actions().clone() { + match action { + SolautoCpiAction::Deposit(amount) => { + println!("Deposit {}", amount); + rebalancer + .data + .solauto_position + .data + .state + .supply + .update_usage(amount as i64); + credit_token_account( + rebalancer, + rebalancer.data.solauto_position.supply_ta.pk, + (amount as i64) * -1, + ); + } + SolautoCpiAction::Withdraw(data) => { + let base_unit_amount = if let TokenBalanceAmount::Some(amount) = data.amount { + amount + } else { + rebalancer + .data + .solauto_position + .data + .state + .supply + .amount_used + .base_unit + }; + println!("Withdraw {}", base_unit_amount); + rebalancer + .data + .solauto_position + .data + .state + .supply + .update_usage((base_unit_amount as i64) * -1); + credit_token_account(rebalancer, data.to_wallet_ta, base_unit_amount as i64); + } + SolautoCpiAction::Borrow(data) => { + println!("Borrow {}", data.amount); + rebalancer + .data + .solauto_position + .data + .state + .debt + .update_usage(data.amount as i64); + credit_token_account(rebalancer, data.to_wallet_ta, data.amount as i64); + } + SolautoCpiAction::Repay(data) => { + let base_unit_amount = if let TokenBalanceAmount::Some(amount) = data { + amount + } else { + rebalancer + .data + .solauto_position + .data + .state + .debt + .amount_used + .base_unit + }; + println!("Repay {}", base_unit_amount); + rebalancer + .data + .solauto_position + .data + .state + .debt + .update_usage((base_unit_amount as i64) * -1); + credit_token_account( + rebalancer, + rebalancer.data.solauto_position.debt_ta.pk, + (base_unit_amount as i64) * -1, + ); + } + SolautoCpiAction::SplTokenTransfer(args) => { + println!("Transfer from {}", args.amount); + credit_token_account(rebalancer, args.from_wallet_ta, (args.amount as i64) * -1); + credit_token_account(rebalancer, args.to_wallet_ta, args.amount as i64); + } + } + } + + rebalancer.reset_actions(); +} + +fn perform_swap<'a>( + rebalancer: &mut Rebalancer<'a>, + rebalance_direction: &RebalanceDirection, + to_solauto_position_ta: bool, +) -> u64 { + let (input_price, output_price) = if rebalance_direction == &RebalanceDirection::Boost { + (DEBT_PRICE, SUPPLY_PRICE) + } else { + (SUPPLY_PRICE, DEBT_PRICE) + }; + + let swap_usd_value = from_base_unit::( + rebalancer.data.intermediary_ta.balance, + TEST_TOKEN_DECIMALS, + ) + .mul(input_price); + + println!("Swapping ${}", swap_usd_value); + + rebalancer.data.intermediary_ta.balance = 0; + + let output_amount = + to_base_unit::(swap_usd_value.div(output_price), TEST_TOKEN_DECIMALS); + + if to_solauto_position_ta { + if rebalance_direction == &RebalanceDirection::Boost { + credit_token_account( + rebalancer, + rebalancer.data.solauto_position.supply_ta.pk, + output_amount as i64, + ); + } else { + credit_token_account( + rebalancer, + rebalancer.data.solauto_position.debt_ta.pk, + output_amount as i64, + ); + } + } + + output_amount +} + +fn validate_rebalance<'a>(rebalancer: &mut Rebalancer<'a>) { + assert_eq!( + round_to_decimals( + from_rounded_usd_value( + rebalancer + .data + .solauto_position + .data + .rebalance + .values + .target_debt_usd + ), + 4 + ), + round_to_decimals( + rebalancer + .data + .solauto_position + .data + .state + .debt + .amount_used + .usd_value(), + 4 + ), + "Incorrect debt usd. Expected (left) vs. actual (right)" + ); + assert_eq!( + round_to_decimals( + from_rounded_usd_value( + rebalancer + .data + .solauto_position + .data + .rebalance + .values + .target_supply_usd + ), + 4 + ), + round_to_decimals( + rebalancer + .data + .solauto_position + .data + .state + .supply + .amount_used + .usd_value(), + 4 + ), + "Incorrect supply usd. Expected (left) vs. actual (right)" + ); + + assert!(validation_utils::validate_rebalance(rebalancer.data.solauto_position.data).is_ok()); + rebalancer.data.solauto_position.data.rebalance = RebalanceData::default(); +} + +mod tests { + use std::ops::{Add, Div}; + + use crate::{ + types::{ + shared::{RebalanceStep, SolautoRebalanceType, SwapType}, + solauto::RebalanceFeesBps, + }, + utils::math_utils::{get_debt_adjustment, get_max_boost_to_bps, get_max_repay_to_bps}, + }; + + use super::*; + + #[test] + fn test_standard_rebalance_boost() { + let pos_values = PositionValues { + supply_usd: 100.0, + debt_usd: 25.0, + }; + let rebalance_to = 3800; + let rebalance_direction = RebalanceDirection::Boost; + + let settings = SolautoSettingsParametersInp { + boost_gap: 50, + boost_to_bps: rebalance_to, + repay_gap: 50, + repay_to_bps: get_max_repay_to_bps(MAX_LTV_BPS, LIQ_THRESHOLD_BPS), + }; + let mut position = create_position( + &(FakePosition { + values: &pos_values, + settings, + max_ltv_bps: Some(MAX_LTV_BPS), + liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), + }), + ); + let debt_adjustment = get_debt_adjustment( + LIQ_THRESHOLD_BPS, + &pos_values, + rebalance_to, + &(RebalanceFeesBps { + solauto: SOLAUTO_FEE_BPS, + lp_borrow: BORROW_FEE_BPS, + flash_loan: 0, + }), + ); + let rebalance_args = RebalanceSettings { + rebalance_type: SolautoRebalanceType::Regular, + target_liq_utilization_rate_bps: None, + swap_in_amount_base_unit: Some(to_base_unit( + debt_adjustment.debt_adjustment_usd.div(DEBT_PRICE), + TEST_TOKEN_DECIMALS, + )), + flash_loan_fee_bps: None, + swap_type: Some(SwapType::ExactIn), + price_type: None, + }; + let rebalancer = &mut create_rebalancer( + FakeRebalance { + pos: &mut position, + position_supply_ta_balance: None, + position_debt_ta_balance: None, + rebalance_direction: rebalance_direction.clone(), + }, + rebalance_args, + None, + ); + + let res = rebalancer.rebalance(RebalanceStep::PreSwap); + assert!(res.is_ok()); + apply_actions(rebalancer); + + perform_swap(rebalancer, &rebalance_direction, true); + + let res = rebalancer.rebalance(RebalanceStep::PostSwap); + assert!(res.is_ok()); + apply_actions(rebalancer); + + validate_rebalance(rebalancer); + } + + #[test] + fn test_standard_rebalance_repay() { + let pos_values = PositionValues { + supply_usd: 100.0, + debt_usd: 50.0, + }; + let rebalance_to = 5000; + let rebalance_direction = RebalanceDirection::Repay; + + let settings = SolautoSettingsParametersInp { + boost_gap: 50, + boost_to_bps: 2000, + repay_gap: 50, + repay_to_bps: rebalance_to, + }; + let mut position = create_position( + &(FakePosition { + values: &pos_values, + settings, + max_ltv_bps: Some(MAX_LTV_BPS), + liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), + }), + ); + let debt_adjustment = get_debt_adjustment( + LIQ_THRESHOLD_BPS, + &pos_values, + rebalance_to, + &(RebalanceFeesBps { + solauto: SOLAUTO_FEE_BPS, + lp_borrow: BORROW_FEE_BPS, + flash_loan: 0, + }), + ); + let rebalance_args = RebalanceSettings { + rebalance_type: SolautoRebalanceType::Regular, + target_liq_utilization_rate_bps: None, + swap_in_amount_base_unit: Some(to_base_unit( + debt_adjustment.debt_adjustment_usd.abs().div(SUPPLY_PRICE), + TEST_TOKEN_DECIMALS, + )), + flash_loan_fee_bps: None, + swap_type: Some(SwapType::ExactIn), + price_type: None, + }; + let rebalancer = &mut create_rebalancer( + FakeRebalance { + pos: &mut position, + position_supply_ta_balance: None, + position_debt_ta_balance: None, + rebalance_direction: rebalance_direction.clone(), + }, + rebalance_args, + None, + ); + + let res = rebalancer.rebalance(RebalanceStep::PreSwap); + assert!(res.is_ok()); + apply_actions(rebalancer); + + perform_swap(rebalancer, &rebalance_direction, true); + + let res = rebalancer.rebalance(RebalanceStep::PostSwap); + assert!(res.is_ok()); + apply_actions(rebalancer); + + validate_rebalance(rebalancer); + } + + // TODO: when token balance changes pre-swap are needed + // #[test] + // fn test_double_rebalance_fl_boost() {} + + // #[test] + // fn test_double_rebalance_fl_repay() {} + + #[test] + fn test_swap_then_rebalance_boost() { + let pos_values = PositionValues { + supply_usd: 100.0, + debt_usd: 0.0, + }; + let rebalance_to = get_max_boost_to_bps(MAX_LTV_BPS, LIQ_THRESHOLD_BPS); + let rebalance_direction = RebalanceDirection::Boost; + + let settings = SolautoSettingsParametersInp { + boost_gap: 50, + boost_to_bps: rebalance_to, + repay_gap: 50, + repay_to_bps: rebalance_to, + }; + let mut position = create_position( + &(FakePosition { + values: &pos_values, + settings, + max_ltv_bps: Some(MAX_LTV_BPS), + liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), + }), + ); + + let debt_adjustment = get_debt_adjustment( + LIQ_THRESHOLD_BPS, + &pos_values, + rebalance_to, + &(RebalanceFeesBps { + solauto: SOLAUTO_FEE_BPS, + lp_borrow: BORROW_FEE_BPS, + flash_loan: FLASH_LOAN_FEE_BPS, + }), + ); + let flash_borrow = to_base_unit( + debt_adjustment.debt_adjustment_usd.abs().div(DEBT_PRICE), + TEST_TOKEN_DECIMALS, + ); + + let rebalance_args = RebalanceSettings { + rebalance_type: SolautoRebalanceType::FLSwapThenRebalance, + target_liq_utilization_rate_bps: None, + swap_in_amount_base_unit: Some(flash_borrow), + flash_loan_fee_bps: Some(FLASH_LOAN_FEE_BPS), + swap_type: Some(SwapType::ExactIn), + price_type: None, + }; + let rebalancer = &mut create_rebalancer( + FakeRebalance { + pos: &mut position, + position_supply_ta_balance: None, + position_debt_ta_balance: None, + rebalance_direction: rebalance_direction.clone(), + }, + rebalance_args, + Some(flash_borrow), + ); + + credit_token_account( + rebalancer, + rebalancer.data.intermediary_ta.pk, + flash_borrow as i64, + ); + + perform_swap(rebalancer, &rebalance_direction, true); + + let res = rebalancer.rebalance(RebalanceStep::PostSwap); + assert!(res.is_ok()); + apply_actions(rebalancer); + + validate_rebalance(rebalancer); + } + + #[test] + fn test_swap_then_rebalance_repay() { + let pos_values = PositionValues { + supply_usd: 100.0, + debt_usd: 70.0, + }; + let rebalance_to = 1000; + let rebalance_direction = RebalanceDirection::Repay; + + let settings = SolautoSettingsParametersInp { + boost_gap: 50, + boost_to_bps: 3000, + repay_gap: 50, + repay_to_bps: get_max_repay_to_bps(MAX_LTV_BPS, LIQ_THRESHOLD_BPS), + }; + let mut position = create_position( + &(FakePosition { + values: &pos_values, + settings, + max_ltv_bps: Some(MAX_LTV_BPS), + liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), + }), + ); + + let debt_adjustment = get_debt_adjustment( + LIQ_THRESHOLD_BPS, + &pos_values, + rebalance_to, + &(RebalanceFeesBps { + solauto: SOLAUTO_FEE_BPS, + lp_borrow: BORROW_FEE_BPS, + flash_loan: FLASH_LOAN_FEE_BPS, + }), + ); + let flash_borrow = to_base_unit( + debt_adjustment.debt_adjustment_usd.abs().div(SUPPLY_PRICE), + TEST_TOKEN_DECIMALS, + ); + + let rebalance_args = RebalanceSettings { + rebalance_type: SolautoRebalanceType::FLSwapThenRebalance, + target_liq_utilization_rate_bps: Some(rebalance_to), + swap_in_amount_base_unit: Some(flash_borrow), + flash_loan_fee_bps: Some(FLASH_LOAN_FEE_BPS), + swap_type: Some(SwapType::ExactIn), + price_type: None, + }; + let rebalancer = &mut create_rebalancer( + FakeRebalance { + pos: &mut position, + position_supply_ta_balance: None, + position_debt_ta_balance: None, + rebalance_direction: rebalance_direction.clone(), + }, + rebalance_args, + Some(flash_borrow), + ); + + credit_token_account( + rebalancer, + rebalancer.data.intermediary_ta.pk, + flash_borrow as i64, + ); + + perform_swap(rebalancer, &rebalance_direction, true); + + let res = rebalancer.rebalance(RebalanceStep::PostSwap); + assert!(res.is_ok()); + apply_actions(rebalancer); + + validate_rebalance(rebalancer); + } + + // TODO: double rebalance with flash loan exact out swap will not work currently. What needs to change? + + #[test] + fn test_rebalance_then_swap_repay() { + let pos_values = PositionValues { + supply_usd: 100.0, + debt_usd: 70.0, + }; + let rebalance_to = 1000; + let rebalance_direction = RebalanceDirection::Repay; + + let settings = SolautoSettingsParametersInp { + boost_gap: 50, + boost_to_bps: rebalance_to, + repay_gap: 50, + repay_to_bps: rebalance_to, + }; + let mut position = create_position( + &(FakePosition { + values: &pos_values, + settings, + max_ltv_bps: Some(MAX_LTV_BPS), + liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), + }), + ); + + let debt_adjustment = get_debt_adjustment( + LIQ_THRESHOLD_BPS, + &pos_values, + rebalance_to, + &(RebalanceFeesBps { + solauto: SOLAUTO_FEE_BPS, + lp_borrow: BORROW_FEE_BPS, + flash_loan: 0, + }), + ); + + println!("{}", debt_adjustment.debt_adjustment_usd.abs()); + let rebalance_args = RebalanceSettings { + rebalance_type: SolautoRebalanceType::FLRebalanceThenSwap, + target_liq_utilization_rate_bps: None, + swap_in_amount_base_unit: Some(to_base_unit( + debt_adjustment.debt_adjustment_usd.abs().div(SUPPLY_PRICE), + TEST_TOKEN_DECIMALS, + )), + flash_loan_fee_bps: None, + swap_type: Some(SwapType::ExactOut), + price_type: None, + }; + let rebalancer = &mut create_rebalancer( + FakeRebalance { + pos: &mut position, + position_supply_ta_balance: None, + position_debt_ta_balance: None, + rebalance_direction: rebalance_direction.clone(), + }, + rebalance_args, + None, + ); + + let flash_borrow = to_base_unit( + debt_adjustment.debt_adjustment_usd.abs().div(DEBT_PRICE), + TEST_TOKEN_DECIMALS, + ); + credit_token_account( + rebalancer, + rebalancer.data.solauto_position.debt_ta.pk, + flash_borrow, + ); + + let res = rebalancer.rebalance(RebalanceStep::PreSwap); + assert!(res.is_ok()); + apply_actions(rebalancer); + + validate_rebalance(rebalancer); + + let swap_output_amount = perform_swap(rebalancer, &rebalance_direction, false); + + assert_eq!( + round_to_decimals(from_base_unit(swap_output_amount, TEST_TOKEN_DECIMALS), 4), + round_to_decimals(from_base_unit(flash_borrow as u64, TEST_TOKEN_DECIMALS), 4), + "Flash loan repayment (left) doesn't match expected (right)" + ); + } + + #[test] + fn test_target_liq_utilization_rate_rebalance() { + let pos_values = PositionValues { + supply_usd: 100.0, + debt_usd: 25.0, + }; + let rebalance_to = 3500; + let rebalance_direction = RebalanceDirection::Boost; + + let settings = SolautoSettingsParametersInp { + boost_gap: 50, + boost_to_bps: rebalance_to + 300, + repay_gap: 50, + repay_to_bps: get_max_repay_to_bps(MAX_LTV_BPS, LIQ_THRESHOLD_BPS), + }; + let mut position = create_position( + &(FakePosition { + values: &pos_values, + settings, + max_ltv_bps: Some(MAX_LTV_BPS), + liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), + }), + ); + let debt_adjustment = get_debt_adjustment( + LIQ_THRESHOLD_BPS, + &pos_values, + rebalance_to, + &(RebalanceFeesBps { + solauto: SOLAUTO_FEE_BPS, + lp_borrow: BORROW_FEE_BPS, + flash_loan: 0, + }), + ); + let rebalance_args = RebalanceSettings { + rebalance_type: SolautoRebalanceType::Regular, + target_liq_utilization_rate_bps: Some(rebalance_to), + swap_in_amount_base_unit: Some(to_base_unit( + debt_adjustment.debt_adjustment_usd.div(DEBT_PRICE), + TEST_TOKEN_DECIMALS, + )), + flash_loan_fee_bps: None, + swap_type: Some(SwapType::ExactIn), + price_type: None, + }; + let rebalancer = &mut create_rebalancer( + FakeRebalance { + pos: &mut position, + position_supply_ta_balance: None, + position_debt_ta_balance: None, + rebalance_direction: rebalance_direction.clone(), + }, + rebalance_args, + None, + ); + + let res = rebalancer.rebalance(RebalanceStep::PreSwap); + assert!(res.is_ok()); + apply_actions(rebalancer); + + perform_swap(rebalancer, &rebalance_direction, true); + + let res = rebalancer.rebalance(RebalanceStep::PostSwap); + assert!(res.is_ok()); + apply_actions(rebalancer); + + validate_rebalance(rebalancer); + } +} diff --git a/programs/solauto/src/rebalance/solauto_fees.rs b/programs/solauto/src/rebalance/solauto_fees.rs new file mode 100644 index 00000000..3316d3dc --- /dev/null +++ b/programs/solauto/src/rebalance/solauto_fees.rs @@ -0,0 +1,100 @@ +use std::ops::Mul; + +use crate::{constants::REFERRER_PERCENTAGE, types::shared::RebalanceDirection}; + +pub struct FeePayout { + pub solauto: u16, + pub referrer: u16, + pub total: u16, +} + +#[derive(Clone, Copy)] +pub struct SolautoFeesBps { + has_been_referred: bool, + target_liq_utilization_rate_bps: Option, + position_net_worth_usd: f64, + mock_fee_bps: Option, +} +impl SolautoFeesBps { + pub fn from_mock(total_fees_bps: u16, has_been_referred: bool) -> Self { + Self { + mock_fee_bps: Some(total_fees_bps), + has_been_referred: has_been_referred, + target_liq_utilization_rate_bps: None, + position_net_worth_usd: 0.0, + } + } + pub fn from( + has_been_referred: bool, + target_liq_utilization_rate_bps: Option, + position_net_worth_usd: f64, + ) -> Self { + Self { + has_been_referred, + target_liq_utilization_rate_bps, + position_net_worth_usd, + mock_fee_bps: None, + } + } + pub fn fetch_fees(&self, rebalance_direction: &RebalanceDirection) -> FeePayout { + if self.mock_fee_bps.is_some() { + let fee_bps = self.mock_fee_bps.unwrap(); + let (solauto_fee, referrer_fee) = if self.has_been_referred { + ( + (fee_bps as f64).mul(0.85).floor() as u16, + (fee_bps as f64).mul(0.15).floor() as u16, + ) + } else { + (fee_bps, 0) + }; + return FeePayout { + total: fee_bps, + solauto: solauto_fee, + referrer: referrer_fee, + }; + } + + let min_size: f64 = 10000.0; // Minimum position size + let max_size: f64 = 250000.0; // Maximum position size + let max_fee_bps: f64 = 50.0; // Fee in basis points for min_size (0.5%) + let min_fee_bps: f64 = 25.0; // Fee in basis points for max_size (0.25%) + let k = 1.5; + + let mut fee_bps: f64; + if self.target_liq_utilization_rate_bps.is_some() + && self.target_liq_utilization_rate_bps.unwrap() == 0 + { + return FeePayout { + solauto: 0, + referrer: 0, + total: 0, + }; + } + + if self.target_liq_utilization_rate_bps.is_some() { + fee_bps = 15.0; + } else if rebalance_direction == &RebalanceDirection::Repay { + fee_bps = 25.0; + } else if self.position_net_worth_usd <= min_size { + fee_bps = max_fee_bps; + } else if self.position_net_worth_usd >= max_size { + fee_bps = min_fee_bps; + } else { + let t = (self.position_net_worth_usd.ln() - min_size.ln()) + / (max_size.ln() - min_size.ln()); + fee_bps = (min_fee_bps + (max_fee_bps - min_fee_bps) * (1.0 - t.powf(k))).round(); + } + + let mut referrer_fee = 0.0; + if self.has_been_referred { + fee_bps = fee_bps * (1.0 - REFERRER_PERCENTAGE); + referrer_fee = fee_bps.mul(REFERRER_PERCENTAGE).floor(); + } + + FeePayout { + solauto: (fee_bps - referrer_fee) as u16, + referrer: referrer_fee as u16, + total: fee_bps as u16, + } + } +} diff --git a/programs/solauto/src/rebalance/utils.rs b/programs/solauto/src/rebalance/utils.rs new file mode 100644 index 00000000..0042c5da --- /dev/null +++ b/programs/solauto/src/rebalance/utils.rs @@ -0,0 +1,172 @@ +use solana_program::program_error::ProgramError; + +use crate::{ + state::solauto_position::{ + RebalanceInstructionData, RebalanceStateValues, SolautoPosition, TokenBalanceChange, + TokenBalanceChangeType, + }, + types::{ + errors::SolautoError, + instruction::{RebalanceSettings, SolautoStandardAccounts}, + shared::{RebalanceDirection, RebalanceStep, SolautoRebalanceType, SwapType}, + solauto::{PositionValues, RebalanceFeesBps}, + }, + utils::{ + ix_utils::{ + get_flash_borrow_ix_idx, get_marginfi_flash_loan_amount, + validate_rebalance_instructions, + }, + math_utils::{from_rounded_usd_value, get_debt_adjustment}, + }, +}; + +use super::solauto_fees::SolautoFeesBps; + +pub fn set_rebalance_ixs_data( + std_accounts: &mut Box, + args: &RebalanceSettings, +) -> Result { + let has_rebalance_data = std_accounts.solauto_position.data.rebalance.active(); + + if !has_rebalance_data { + validate_rebalance_instructions(std_accounts, args.rebalance_type)?; + + let fl_borrow_ix_idx = get_flash_borrow_ix_idx(std_accounts, args.rebalance_type)?; + let flash_loan_amount = if fl_borrow_ix_idx.is_some() { + get_marginfi_flash_loan_amount(std_accounts.ixs_sysvar.unwrap(), fl_borrow_ix_idx)? + } else { + 0 + }; + + std_accounts.solauto_position.data.rebalance.ixs = RebalanceInstructionData::from( + args.rebalance_type, + flash_loan_amount, + args.swap_type.unwrap_or(SwapType::default()), + ); + } + + let rebalance_step = if !has_rebalance_data + && matches!( + std_accounts + .solauto_position + .data + .rebalance + .ixs + .rebalance_type, + SolautoRebalanceType::Regular + | SolautoRebalanceType::DoubleRebalanceWithFL + | SolautoRebalanceType::FLRebalanceThenSwap + ) { + RebalanceStep::PreSwap + } else { + RebalanceStep::PostSwap + }; + + Ok(rebalance_step) +} + +pub fn eligible_for_rebalance(solauto_position: &Box) -> bool { + // TODO: DCA, limit orders, take profit, stop loss, etc. + + solauto_position.state.liq_utilization_rate_bps <= solauto_position.boost_from_bps() + || solauto_position.state.liq_utilization_rate_bps >= solauto_position.repay_from_bps() +} + +fn get_target_liq_utilization_rate_bps( + solauto_position: &Box, + rebalance_args: &RebalanceSettings, + token_balance_change: &Option, +) -> Result { + if rebalance_args.target_liq_utilization_rate_bps.is_some() { + return Ok(rebalance_args.target_liq_utilization_rate_bps.unwrap()); + } + + if solauto_position.state.liq_utilization_rate_bps >= solauto_position.repay_from_bps() { + return Ok(solauto_position.position.settings.repay_to_bps); + } else if solauto_position.state.liq_utilization_rate_bps <= solauto_position.boost_from_bps() { + return Ok(solauto_position.position.settings.boost_to_bps); + } else if token_balance_change.is_some() { + // TODO: DCA, limit orders, take profit, stop loss, etc. + return Ok(solauto_position.state.liq_utilization_rate_bps); + } + + Err(SolautoError::InvalidRebalanceCondition.into()) +} + +fn get_token_balance_change() -> Option { + // TODO: DCA, limit orders, take profit, stop loss, etc. + None +} + +fn get_adjusted_position_values( + solauto_position: &Box, + token_balance_change: &Option, +) -> PositionValues { + let mut supply_usd = solauto_position.state.supply.amount_used.usd_value(); + let debt_usd = solauto_position.state.debt.amount_used.usd_value(); + + if token_balance_change.is_some() { + let tb = token_balance_change.as_ref().unwrap(); + match tb.change_type { + TokenBalanceChangeType::PreSwapDeposit | TokenBalanceChangeType::PostSwapDeposit => { + supply_usd += from_rounded_usd_value(tb.amount_usd); + } + TokenBalanceChangeType::PostRebalanceWithdrawDebtToken + | TokenBalanceChangeType::PostRebalanceWithdrawSupplyToken => { + supply_usd -= from_rounded_usd_value(tb.amount_usd); + } + _ => {} + } + } + + return PositionValues { + supply_usd, + debt_usd, + }; +} + +fn get_rebalance_direction( + solauto_position: &Box, + target_ltv_bps: u16, +) -> RebalanceDirection { + if solauto_position.state.liq_utilization_rate_bps < target_ltv_bps { + RebalanceDirection::Boost + } else { + RebalanceDirection::Repay + } +} + +pub fn get_rebalance_values( + solauto_position: &Box, + rebalance_args: &RebalanceSettings, + solauto_fees_bps: &SolautoFeesBps, +) -> Result { + let token_balance_change = get_token_balance_change(); + let target_liq_utilization_rate_bps = get_target_liq_utilization_rate_bps( + solauto_position, + rebalance_args, + &token_balance_change, + )?; + let rebalance_direction = + get_rebalance_direction(solauto_position, target_liq_utilization_rate_bps); + let position = get_adjusted_position_values(solauto_position, &token_balance_change); + let fees = RebalanceFeesBps { + solauto: solauto_fees_bps.fetch_fees(&rebalance_direction).total, + lp_borrow: solauto_position.state.debt.borrow_fee_bps, + flash_loan: rebalance_args.flash_loan_fee_bps.unwrap_or(0), + }; + + let debt_adjustment = get_debt_adjustment( + solauto_position.state.liq_threshold_bps, + &position, + target_liq_utilization_rate_bps, + &fees, + ); + + return Ok(RebalanceStateValues::from( + rebalance_direction, + debt_adjustment.end_result.supply_usd, + debt_adjustment.end_result.debt_usd, + token_balance_change, + )); +} diff --git a/programs/solauto/src/state/automation.rs b/programs/solauto/src/state/automation.rs new file mode 100644 index 00000000..e6a2f168 --- /dev/null +++ b/programs/solauto/src/state/automation.rs @@ -0,0 +1,180 @@ +use borsh::{BorshDeserialize, BorshSerialize}; +use bytemuck::{Pod, Zeroable}; +use num_traits::{FromPrimitive, ToPrimitive}; +use shank::ShankType; +use std::{ + cmp::min, + ops::{Add, Div, Mul, Sub}, +}; + +use crate::types::shared::TokenType; + +#[derive(BorshDeserialize, Clone, Debug, Copy, Default)] +pub struct AutomationSettingsInp { + pub target_periods: u16, + pub periods_passed: u16, + pub unix_start_date: u64, + pub interval_seconds: u64, +} + +#[repr(C, align(8))] +#[derive( + ShankType, BorshSerialize, BorshDeserialize, Clone, Debug, Default, Copy, Pod, Zeroable, +)] +pub struct AutomationSettings { + /// The target number of periods + pub target_periods: u16, + /// How many periods have already passed + pub periods_passed: u16, + _padding1: [u8; 4], + /// The unix timestamp (in seconds) start date of DCA + pub unix_start_date: u64, + /// The interval in seconds between each DCA + pub interval_seconds: u64, + _padding: [u8; 32], +} + +impl AutomationSettings { + pub fn from(args: AutomationSettingsInp) -> Self { + Self { + target_periods: args.target_periods, + periods_passed: args.periods_passed, + unix_start_date: args.unix_start_date, + interval_seconds: args.interval_seconds, + _padding1: [0; 4], + _padding: [0; 32], + } + } + #[inline(always)] + pub fn is_active(&self) -> bool { + self.target_periods > 0 + } + #[inline(always)] + pub fn eligible_for_next_period(&self, curr_unix_timestamp: u64) -> bool { + if self.periods_passed == 0 { + curr_unix_timestamp >= self.unix_start_date + } else { + curr_unix_timestamp + >= self + .unix_start_date + .add(self.interval_seconds.mul(self.periods_passed as u64)) + } + } + pub fn updated_amount_from_automation( + &self, + curr_amt: T, + target_amt: T, + curr_unix_timestamp: u64, + ) -> T { + let curr_amt_f64 = curr_amt.to_f64().unwrap(); + let target_amt_f64 = target_amt.to_f64().unwrap(); + let current_rate_diff = curr_amt_f64 - target_amt_f64; + let progress_pct = (1.0).div( + self.target_periods + .sub(self.new_periods_passed(curr_unix_timestamp) - 1) as f64, + ); + let new_amt = curr_amt_f64 - current_rate_diff * progress_pct; + + T::from_f64(new_amt).unwrap() + } + #[inline(always)] + pub fn new_periods_passed(&self, curr_unix_timestamp: u64) -> u16 { + min( + self.target_periods, + (((curr_unix_timestamp.saturating_sub(self.unix_start_date) as f64) + / (self.interval_seconds as f64)) + .floor() as u16) + + 1, + ) + } +} + +#[derive(BorshDeserialize, Clone, Debug, Copy, Default)] +pub struct DCASettingsInp { + pub automation: AutomationSettingsInp, + pub dca_in_base_unit: u64, + pub token_type: TokenType, +} + +#[repr(C, align(8))] +#[derive( + ShankType, BorshSerialize, BorshDeserialize, Clone, Debug, Default, Copy, Pod, Zeroable, +)] +pub struct DCASettings { + pub automation: AutomationSettings, + // Gradually add more to the position during the DCA period. If this is 0, then a DCA-out is assumed. + pub dca_in_base_unit: u64, + pub token_type: TokenType, + _padding: [u8; 31], +} + +impl DCASettings { + pub fn from(args: DCASettingsInp) -> Self { + Self { + automation: AutomationSettings::from(args.automation), + dca_in_base_unit: args.dca_in_base_unit, + token_type: args.token_type, + _padding: [0; 31], + } + } + #[inline(always)] + pub fn dca_in(&self) -> bool { + self.dca_in_base_unit > 0 + } + #[inline(always)] + pub fn is_active(&self) -> bool { + self.automation.is_active() + } +} + +mod tests { + use super::*; + + #[test] + fn validate_period_eligibility() { + let automation = AutomationSettings::from(AutomationSettingsInp { + target_periods: 4, + periods_passed: 3, + unix_start_date: 0, + interval_seconds: 5, + }); + + assert!(automation.eligible_for_next_period(2 * 5 + 4) == false); + assert!(automation.eligible_for_next_period(3 * 5) == true); + } + + #[test] + fn validate_new_periods_passed() { + let automation = AutomationSettings::from(AutomationSettingsInp { + target_periods: 4, + periods_passed: 0, + unix_start_date: 0, + interval_seconds: 5, + }); + + assert!(automation.new_periods_passed(0) == 1); + assert!(automation.new_periods_passed(4 * 5) == 4); + assert!(automation.new_periods_passed(5 * 5) == 4); + } + + #[test] + fn validate_updated_automation_value() { + let mut automation = AutomationSettings::from(AutomationSettingsInp { + target_periods: 4, + periods_passed: 0, + unix_start_date: 0, + interval_seconds: 5, + }); + + assert!(automation.updated_amount_from_automation(10.0, 0.0, 0) == 7.5); + + automation.periods_passed = 1; + assert!(automation.updated_amount_from_automation(7.5, 0.0, 5) == 5.0); + + automation.periods_passed = 2; + assert!(automation.updated_amount_from_automation(5.0, 0.0, 10) == 2.5); + + automation.periods_passed = 3; + assert!(automation.updated_amount_from_automation(2.5, 0.0, 15) == 0.0); + } +} diff --git a/programs/solauto/src/state/mod.rs b/programs/solauto/src/state/mod.rs index 0f2f9df5..052e4f7e 100644 --- a/programs/solauto/src/state/mod.rs +++ b/programs/solauto/src/state/mod.rs @@ -1,2 +1,3 @@ +pub mod automation; pub mod referral_state; pub mod solauto_position; diff --git a/programs/solauto/src/state/solauto_position.rs b/programs/solauto/src/state/solauto_position.rs index c57eb3ba..d9ded2cd 100644 --- a/programs/solauto/src/state/solauto_position.rs +++ b/programs/solauto/src/state/solauto_position.rs @@ -1,103 +1,23 @@ use borsh::{BorshDeserialize, BorshSerialize}; use bytemuck::{Pod, Zeroable}; -use num_traits::{FromPrimitive, ToPrimitive}; use shank::{ShankAccount, ShankType}; use solana_program::{msg, pubkey::Pubkey}; -use std::{ - cmp::min, - ops::{Add, Div, Mul, Sub}, -}; +use std::{cmp::min, ops::Mul}; use crate::{ constants::USD_DECIMALS, - types::shared::{PodBool, PositionType, RebalanceDirection, TokenType}, + derive_pod_traits, + types::shared::{ + LendingPlatform, PodBool, PositionType, RebalanceDirection, SolautoRebalanceType, SwapType, + TokenType, + }, utils::math_utils::{ - from_base_unit, from_bps, get_liq_utilization_rate_bps, net_worth_base_amount, to_base_unit, + base_unit_to_usd_value, from_bps, from_rounded_usd_value, get_liq_utilization_rate_bps, + get_max_boost_to_bps, get_max_repay_from_bps, get_max_repay_to_bps, net_worth_base_amount, + to_base_unit, to_rounded_usd_value, }, }; -use crate::types::shared::LendingPlatform; - -#[derive(BorshDeserialize, Clone, Debug, Copy, Default)] -pub struct AutomationSettingsInp { - pub target_periods: u16, - pub periods_passed: u16, - pub unix_start_date: u64, - pub interval_seconds: u64, -} - -#[repr(C, align(8))] -#[derive( - ShankType, BorshSerialize, BorshDeserialize, Clone, Debug, Default, Copy, Pod, Zeroable, -)] -pub struct AutomationSettings { - /// The target number of periods - pub target_periods: u16, - /// How many periods have already passed - pub periods_passed: u16, - _padding1: [u8; 4], - /// The unix timestamp (in seconds) start date of DCA - pub unix_start_date: u64, - /// The interval in seconds between each DCA - pub interval_seconds: u64, - _padding: [u8; 32], -} - -impl AutomationSettings { - pub fn from(args: AutomationSettingsInp) -> Self { - Self { - target_periods: args.target_periods, - periods_passed: args.periods_passed, - unix_start_date: args.unix_start_date, - interval_seconds: args.interval_seconds, - _padding1: [0; 4], - _padding: [0; 32], - } - } - #[inline(always)] - pub fn is_active(&self) -> bool { - self.target_periods > 0 - } - #[inline(always)] - pub fn eligible_for_next_period(&self, curr_unix_timestamp: u64) -> bool { - if self.periods_passed == 0 { - curr_unix_timestamp >= self.unix_start_date - } else { - curr_unix_timestamp - >= self - .unix_start_date - .add(self.interval_seconds.mul(self.periods_passed as u64)) - } - } - pub fn updated_amount_from_automation( - &self, - curr_amt: T, - target_amt: T, - curr_unix_timestamp: u64, - ) -> T { - let curr_amt_f64 = curr_amt.to_f64().unwrap(); - let target_amt_f64 = target_amt.to_f64().unwrap(); - let current_rate_diff = curr_amt_f64 - target_amt_f64; - let progress_pct = (1.0).div( - self.target_periods - .sub(self.new_periods_passed(curr_unix_timestamp) - 1) as f64, - ); - let new_amt = curr_amt_f64 - current_rate_diff * progress_pct; - - T::from_f64(new_amt).unwrap() - } - #[inline(always)] - pub fn new_periods_passed(&self, curr_unix_timestamp: u64) -> u16 { - min( - self.target_periods, - (((curr_unix_timestamp.saturating_sub(self.unix_start_date) as f64) - / (self.interval_seconds as f64)) - .floor() as u16) - + 1, - ) - } -} - #[repr(C, align(8))] #[derive(ShankType, BorshSerialize, Clone, Debug, Default, Copy, Pod, Zeroable)] pub struct TokenAmount { @@ -109,37 +29,36 @@ pub struct TokenAmount { impl TokenAmount { #[inline(always)] pub fn usd_value(&self) -> f64 { - from_base_unit::(self.base_amount_usd_value, USD_DECIMALS) + from_rounded_usd_value(self.base_amount_usd_value) } pub fn update_usd_value(&mut self, market_price: f64, token_decimals: u8) { - self.base_amount_usd_value = to_base_unit::( - from_base_unit::(self.base_unit, token_decimals).mul(market_price), - USD_DECIMALS, - ); + self.base_amount_usd_value = to_rounded_usd_value(base_unit_to_usd_value( + self.base_unit, + token_decimals, + market_price, + )); } } #[repr(C, align(8))] #[derive(ShankType, BorshSerialize, Clone, Debug, Default, Copy, Pod, Zeroable)] -pub struct PositionTokenUsage { +pub struct PositionTokenState { pub mint: Pubkey, pub decimals: u8, - _padding1: [u8; 7], + _padding1: [u8; 5], + pub borrow_fee_bps: u16, pub amount_used: TokenAmount, pub amount_can_be_used: TokenAmount, /// Denominated by 9 decimal places base_amount_market_price_usd: u64, - // TODO: Flash loan fees are currently not considered in debt adjustment calculations - pub flash_loan_fee_bps: u16, - pub borrow_fee_bps: u16, - _padding2: [u8; 4], + _padding2: [u8; 8], _padding: [u8; 32], } -impl PositionTokenUsage { +impl PositionTokenState { #[inline(always)] pub fn market_price(&self) -> f64 { - from_base_unit::(self.base_amount_market_price_usd, USD_DECIMALS) + from_rounded_usd_value(self.base_amount_market_price_usd) } fn update_usd_values(&mut self) { self.amount_used @@ -171,58 +90,17 @@ impl PositionTokenUsage { } pub fn update_market_price(&mut self, market_price: f64) { msg!("New {} price: {}", self.mint, market_price); - self.base_amount_market_price_usd = - to_base_unit::(market_price, USD_DECIMALS); + self.base_amount_market_price_usd = to_base_unit(market_price, USD_DECIMALS); self.update_usd_values(); } } -#[derive(BorshDeserialize, Clone, Debug, Copy, Default)] -pub struct DCASettingsInp { - pub automation: AutomationSettingsInp, - pub dca_in_base_unit: u64, - pub token_type: TokenType, -} - -#[repr(C, align(8))] -#[derive( - ShankType, BorshSerialize, BorshDeserialize, Clone, Debug, Default, Copy, Pod, Zeroable, -)] -pub struct DCASettings { - pub automation: AutomationSettings, - // Gradually add more to the position during the DCA period. If this is 0, then a DCA-out is assumed. - pub dca_in_base_unit: u64, - pub token_type: TokenType, - _padding: [u8; 31], -} - -impl DCASettings { - pub fn from(args: DCASettingsInp) -> Self { - Self { - automation: AutomationSettings::from(args.automation), - dca_in_base_unit: args.dca_in_base_unit, - token_type: args.token_type, - _padding: [0; 31], - } - } - #[inline(always)] - pub fn dca_in(&self) -> bool { - self.dca_in_base_unit > 0 - } - #[inline(always)] - pub fn is_active(&self) -> bool { - self.automation.is_active() - } -} - #[derive(BorshDeserialize, Clone, Debug, Copy, Default)] pub struct SolautoSettingsParametersInp { pub boost_to_bps: u16, pub boost_gap: u16, pub repay_to_bps: u16, pub repay_gap: u16, - pub target_boost_to_bps: Option, - pub automation: Option, } #[repr(C, align(8))] @@ -238,45 +116,19 @@ pub struct SolautoSettingsParameters { pub repay_to_bps: u16, /// repay_gap basis points above repay_to_bps is the liquidation utilization rate at which to begin a rebalance pub repay_gap: u16, - /// If slowly adjusting the boost_to_bps with automation, this must be set - pub target_boost_to_bps: u16, - _padding1: [u8; 6], - /// Data required if providing a target_boost_to_bps - pub automation: AutomationSettings, - _padding: [u8; 32], + _padding: [u32; 24], } impl SolautoSettingsParameters { pub fn from(args: SolautoSettingsParametersInp) -> Self { - let target_boost_to_bps = if args.target_boost_to_bps.is_some() { - args.target_boost_to_bps.unwrap() - } else { - 0 - }; - let automation = if args.automation.is_some() { - AutomationSettings::from(args.automation.unwrap()) - } else { - AutomationSettings::default() - }; Self { boost_to_bps: args.boost_to_bps, boost_gap: args.boost_gap, repay_to_bps: args.repay_to_bps, repay_gap: args.repay_gap, - target_boost_to_bps, - automation, - _padding1: [0; 6], - _padding: [0; 32], + _padding: [0; 24], } } - #[inline(always)] - pub fn boost_from_bps(&self) -> u16 { - self.boost_to_bps.saturating_sub(self.boost_gap) - } - #[inline(always)] - pub fn repay_from_bps(&self) -> u16 { - self.repay_to_bps.add(self.repay_gap) - } } #[repr(C, align(8))] @@ -287,13 +139,13 @@ pub struct PositionState { /// Denominated by 9 decimal places pub net_worth: TokenAmount, - pub supply: PositionTokenUsage, - pub debt: PositionTokenUsage, + pub supply: PositionTokenState, + pub debt: PositionTokenState, pub max_ltv_bps: u16, pub liq_threshold_bps: u16, _padding2: [u8; 4], - pub last_updated: u64, + pub last_refreshed: u64, _padding: [u32; 2], } @@ -302,43 +154,118 @@ pub struct PositionState { pub struct PositionData { pub lending_platform: LendingPlatform, _padding1: [u8; 7], - pub protocol_user_account: Pubkey, - pub protocol_supply_account: Pubkey, - pub protocol_debt_account: Pubkey, - pub setting_params: SolautoSettingsParameters, - pub dca: DCASettings, - _padding: [u32; 4], + pub lp_user_account: Pubkey, + pub lp_supply_account: Pubkey, + pub lp_debt_account: Pubkey, + pub settings: SolautoSettingsParameters, + pub lp_pool_account: Pubkey, + _padding: [u32; 20], } #[repr(u8)] -#[derive(ShankType, BorshDeserialize, BorshSerialize, Clone, Debug, Default, PartialEq, Copy)] -pub enum SolautoRebalanceType { +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankType, Default, PartialEq, Copy)] +pub enum TokenBalanceChangeType { #[default] None, - Regular, - DoubleRebalanceWithFL, - FLSwapThenRebalance, - FLRebalanceThenSwap, + PreSwapDeposit, + PostSwapDeposit, + PostRebalanceWithdrawSupplyToken, + PostRebalanceWithdrawDebtToken, } - -unsafe impl Zeroable for SolautoRebalanceType {} -unsafe impl Pod for SolautoRebalanceType {} +derive_pod_traits!(TokenBalanceChangeType); #[repr(C, align(8))] #[derive(ShankType, BorshSerialize, Clone, Debug, Default, Copy, Pod, Zeroable)] -pub struct RebalanceData { - pub rebalance_type: SolautoRebalanceType, +pub struct TokenBalanceChange { + pub change_type: TokenBalanceChangeType, _padding1: [u8; 7], + // Denominated in 9 decimal places + pub amount_usd: u64, +} + +impl TokenBalanceChange { + pub fn requires_one(&self) -> bool { + self.change_type != TokenBalanceChangeType::None + } +} + +#[repr(C, align(8))] +#[derive(ShankType, BorshSerialize, Clone, Debug, Default, Copy, Pod, Zeroable)] +pub struct RebalanceStateValues { pub rebalance_direction: RebalanceDirection, - _padding2: [u8; 7], + _padding1: [u8; 7], + // Denominated in 9 decimal places + pub target_supply_usd: u64, + // Denominated in 9 decimal places + pub target_debt_usd: u64, + pub token_balance_change: TokenBalanceChange, + _padding: [u32; 4], +} + +impl RebalanceStateValues { + pub fn from( + rebalance_direction: RebalanceDirection, + target_supply_usd: f64, + target_debt_usd: f64, + token_balance_change: Option, + ) -> Self { + let tb_change = if token_balance_change.is_some() { + token_balance_change.unwrap() + } else { + TokenBalanceChange::default() + }; + Self { + rebalance_direction, + _padding1: [0; 7], + target_supply_usd: to_rounded_usd_value(target_supply_usd), + target_debt_usd: to_rounded_usd_value(target_debt_usd), + token_balance_change: tb_change, + _padding: [0; 4], + } + } +} + +#[repr(C, align(8))] +#[derive(ShankType, BorshSerialize, Clone, Debug, Default, Copy, Pod, Zeroable)] +pub struct RebalanceInstructionData { + pub active: PodBool, + pub rebalance_type: SolautoRebalanceType, + pub swap_type: SwapType, + _padding1: [u8; 5], pub flash_loan_amount: u64, - _padding: [u8; 32], + _padding: [u32; 4], +} +impl RebalanceInstructionData { + pub fn from( + rebalance_type: SolautoRebalanceType, + flash_loan_amount: u64, + swap_type: SwapType, + ) -> Self { + Self { + active: PodBool::new(true), + rebalance_type, + swap_type, + _padding1: [0; 5], + flash_loan_amount, + _padding: [0; 4], + } + } +} + +#[repr(C, align(8))] +#[derive(ShankType, BorshSerialize, Clone, Debug, Default, Copy, Pod, Zeroable)] +pub struct RebalanceData { + pub ixs: RebalanceInstructionData, + pub values: RebalanceStateValues, + _padding: [u32; 4], } impl RebalanceData { - #[inline(always)] pub fn active(&self) -> bool { - self.rebalance_type != SolautoRebalanceType::None + self.ixs.active.val + } + pub fn values_set(&self) -> bool { + self.values.rebalance_direction != RebalanceDirection::None } } @@ -354,11 +281,12 @@ pub struct SolautoPosition { pub position: PositionData, pub state: PositionState, pub rebalance: RebalanceData, - _padding: [u32; 32], + _padding: [u32; 20], } impl SolautoPosition { pub const LEN: usize = 832; + pub fn new( position_id: u8, authority: Pubkey, @@ -378,23 +306,33 @@ impl SolautoPosition { position, state, rebalance: RebalanceData::default(), - _padding: [0; 32], + _padding: [0; 20], } } + + #[inline(always)] + pub fn pubkey(&self) -> Pubkey { + let (pubkey, _) = Pubkey::find_program_address(self.seeds().as_ref(), &crate::ID); + pubkey + } + #[inline(always)] pub fn position_id(&self) -> u8 { self.position_id[0] } + #[inline(always)] pub fn seeds<'a>(&'a self) -> Vec<&'a [u8]> { vec![&self.position_id, self.authority.as_ref()] } + #[inline(always)] pub fn seeds_with_bump<'a>(&'a self) -> Vec<&'a [u8]> { let mut seeds = self.seeds(); seeds.push(&self.bump); seeds } + pub fn refresh_state(&mut self) { let supply_usd = self.state.supply.amount_used.usd_value(); let debt_usd = self.state.debt.amount_used.usd_value(); @@ -415,12 +353,14 @@ impl SolautoPosition { .net_worth .update_usd_value(self.state.supply.market_price(), self.state.supply.decimals); msg!( - "New liquidation utilization rate: {}, (${}, ${})", + "New liquidation utilization rate: {}, (${}, ${}). Max: {}", self.state.liq_utilization_rate_bps, supply_usd, - debt_usd + debt_usd, + get_max_boost_to_bps(self.state.max_ltv_bps, self.state.liq_threshold_bps) ); } + pub fn update_usage(&mut self, token_type: TokenType, base_unit_amount_update: i64) { if token_type == TokenType::Supply { self.state.supply.update_usage(base_unit_amount_update); @@ -437,6 +377,36 @@ impl SolautoPosition { msg!("Supply USD < debt USD"); } } + + #[inline(always)] + pub fn boost_to_bps(&self) -> u16 { + min( + self.position.settings.boost_to_bps, + get_max_boost_to_bps(self.state.max_ltv_bps, self.state.liq_threshold_bps), + ) + } + + #[inline(always)] + pub fn boost_from_bps(&self) -> u16 { + self.boost_to_bps() + .saturating_sub(self.position.settings.boost_gap) + } + + #[inline(always)] + pub fn repay_to_bps(&self) -> u16 { + min( + self.position.settings.repay_to_bps, + get_max_repay_to_bps(self.state.max_ltv_bps, self.state.liq_threshold_bps), + ) + } + + #[inline(always)] + pub fn repay_from_bps(&self) -> u16 { + min( + self.position.settings.repay_to_bps + self.position.settings.repay_gap, + get_max_repay_from_bps(self.state.max_ltv_bps, self.state.liq_threshold_bps), + ) + } } mod tests { @@ -457,52 +427,4 @@ mod tests { ); assert!(std::mem::size_of_val(&solauto_position) == SolautoPosition::LEN); } - - #[test] - fn validate_period_eligibility() { - let automation = AutomationSettings::from(AutomationSettingsInp { - target_periods: 4, - periods_passed: 3, - unix_start_date: 0, - interval_seconds: 5, - }); - - assert!(automation.eligible_for_next_period(2 * 5 + 4) == false); - assert!(automation.eligible_for_next_period(3 * 5) == true); - } - - #[test] - fn validate_new_periods_passed() { - let automation = AutomationSettings::from(AutomationSettingsInp { - target_periods: 4, - periods_passed: 0, - unix_start_date: 0, - interval_seconds: 5, - }); - - assert!(automation.new_periods_passed(0) == 1); - assert!(automation.new_periods_passed(4 * 5) == 4); - assert!(automation.new_periods_passed(5 * 5) == 4); - } - - #[test] - fn validate_updated_automation_value() { - let mut automation = AutomationSettings::from(AutomationSettingsInp { - target_periods: 4, - periods_passed: 0, - unix_start_date: 0, - interval_seconds: 5, - }); - - assert!(automation.updated_amount_from_automation(10.0, 0.0, 0) == 7.5); - - automation.periods_passed = 1; - assert!(automation.updated_amount_from_automation(7.5, 0.0, 5) == 5.0); - - automation.periods_passed = 2; - assert!(automation.updated_amount_from_automation(5.0, 0.0, 10) == 2.5); - - automation.periods_passed = 3; - assert!(automation.updated_amount_from_automation(2.5, 0.0, 15) == 0.0); - } } diff --git a/programs/solauto/src/types/errors.rs b/programs/solauto/src/types/errors.rs new file mode 100644 index 00000000..136ce11b --- /dev/null +++ b/programs/solauto/src/types/errors.rs @@ -0,0 +1,42 @@ +use solana_program::program_error::ProgramError; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum SolautoError { + #[error("Missing or incorrect accounts provided for the given instructions")] + IncorrectAccounts, + #[error("Failed to deserialize account data")] + FailedAccountDeserialization, + #[error("Invalid Boost-to param")] + InvalidBoostToSetting, + #[error("Invalid Boost gap param")] + InvalidBoostGapSetting, + #[error("Invalid repay-to param")] + InvalidRepayToSetting, + #[error("Invalid repay gap param")] + InvalidRepayGapSetting, + #[error("Invalid repay-from (repay-to + repay gap)")] + InvalidRepayFromSetting, + #[error("Invalid DCA configuration provided")] + InvalidDCASettings, + #[error("Invalid automation settings provided")] + InvalidAutomationData, + #[error("Invalid position condition to rebalance")] + InvalidRebalanceCondition, + #[error("Unable to invoke instruction through a CPI")] + InstructionIsCPI, + #[error("Incorrect set of instructions or instruction data in the transaction")] + IncorrectInstructions, + #[error("Incorrect swap amount provided. Likely due to high price volatility")] + IncorrectDebtAdjustment, + #[error("Invalid rebalance was made. Target supply USD and target debt USD was not met")] + InvalidRebalanceMade, + #[error("Cannot provide a target liquidation utilization rate if the instruction is not signed by the position authority")] + NonAuthorityProvidedTargetLTV, +} + +impl From for ProgramError { + fn from(e: SolautoError) -> Self { + ProgramError::Custom(e as u32) + } +} diff --git a/programs/solauto/src/types/instruction.rs b/programs/solauto/src/types/instruction.rs index ac86d0b7..f626208f 100644 --- a/programs/solauto/src/types/instruction.rs +++ b/programs/solauto/src/types/instruction.rs @@ -2,11 +2,13 @@ use borsh::BorshDeserialize; use shank::{ShankContext, ShankInstruction, ShankType}; use solana_program::{account_info::AccountInfo, pubkey::Pubkey}; -use crate::state::{ - referral_state::ReferralState, - solauto_position::{ - DCASettingsInp, SolautoPosition, SolautoRebalanceType, SolautoSettingsParametersInp, +use crate::{ + state::{ + automation::DCASettingsInp, + referral_state::ReferralState, + solauto_position::{SolautoPosition, SolautoSettingsParametersInp}, }, + types::shared::SolautoRebalanceType, }; use super::shared::*; @@ -45,7 +47,7 @@ pub enum Instruction { #[account(name = "referral_state")] #[account(mut, name = "referral_fees_dest_ta")] #[account(name = "referral_fees_dest_mint")] - #[account(mut, optional, name = "referral_authority")] + #[account(mut, name = "referral_authority")] #[account(mut, optional, name = "fees_destination_ta")] ClaimReferralFees, @@ -65,7 +67,7 @@ pub enum Instruction { #[account(name = "token_program")] #[account(name = "ata_program")] #[account(mut, name = "solauto_position")] - #[account(mut, name = "protocol_account")] + #[account(mut, name = "lp_user_account")] #[account(mut, name = "position_supply_ta")] #[account(mut, name = "signer_supply_ta")] #[account(mut, name = "position_debt_ta")] @@ -115,7 +117,7 @@ pub enum Instruction { #[account(mut, name = "debt_bank")] #[account(name = "debt_price_oracle")] #[account(mut, name = "solauto_position")] - MarginfiRefreshData, + MarginfiRefreshData(PriceType), /// Marginfi protocol interaction. Can only be invoked by the authority of the position #[account(signer, name = "signer")] @@ -182,8 +184,6 @@ pub struct UpdateReferralStatesArgs { pub struct MarginfiOpenPositionData { pub position_type: PositionType, pub position_data: UpdatePositionData, - /// Marginfi account seed index if the position is Solauto-managed - pub marginfi_account_seed_idx: Option, } #[derive(BorshDeserialize, Clone, Debug)] @@ -191,7 +191,7 @@ pub struct UpdatePositionData { /// ID of the Solauto position pub position_id: u8, /// Setting parameters for the position - pub setting_params: Option, + pub settings: Option, /// New DCA data to initiate on the position pub dca: Option, } @@ -211,10 +211,13 @@ pub enum SolautoAction { #[derive(BorshDeserialize, Clone, Debug, Default, ShankType)] pub struct RebalanceSettings { pub rebalance_type: SolautoRebalanceType, + /// The in-amount to use in the token swap. Gets validated by the program. + pub swap_in_amount_base_unit: Option, /// Target liq utilization rate. Only used/allowed if signed by the position authority. pub target_liq_utilization_rate_bps: Option, - /// The amount to use in the token swap. Gets validated by the program. - pub target_in_amount_base_unit: Option, + pub flash_loan_fee_bps: Option, + pub price_type: Option, + pub swap_type: Option, } pub struct SolautoStandardAccounts<'a> { diff --git a/programs/solauto/src/types/mod.rs b/programs/solauto/src/types/mod.rs index b676354a..c474fb06 100644 --- a/programs/solauto/src/types/mod.rs +++ b/programs/solauto/src/types/mod.rs @@ -1,4 +1,6 @@ +pub mod errors; pub mod instruction; pub mod lending_protocol; pub mod shared; +pub mod solauto; pub mod solauto_manager; diff --git a/programs/solauto/src/types/shared.rs b/programs/solauto/src/types/shared.rs index 922e8b86..e6945dc1 100644 --- a/programs/solauto/src/types/shared.rs +++ b/programs/solauto/src/types/shared.rs @@ -11,37 +11,18 @@ use solana_program::{ program_pack::{IsInitialized, Pack}, }; use std::fmt; -use thiserror::Error; + +use crate::derive_pod_traits; + +use super::errors::SolautoError; #[repr(u8)] -#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankType, PartialEq, Copy)] +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankType, Default, PartialEq, Copy)] pub enum LendingPlatform { + #[default] Marginfi, } - -unsafe impl Zeroable for LendingPlatform {} -unsafe impl Pod for LendingPlatform {} - -impl Default for LendingPlatform { - fn default() -> Self { - LendingPlatform::Marginfi - } -} - -#[repr(C)] -#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankType, PartialEq, Copy)] -pub struct PodBool { - pub val: bool, -} - -unsafe impl Zeroable for PodBool {} -unsafe impl Pod for PodBool {} - -impl PodBool { - pub fn new(val: bool) -> Self { - Self { val } - } -} +derive_pod_traits!(LendingPlatform); #[repr(u8)] #[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankType, Default, PartialEq, Copy)] @@ -50,9 +31,7 @@ pub enum PositionType { Leverage, SafeLoan, } - -unsafe impl Zeroable for PositionType {} -unsafe impl Pod for PositionType {} +derive_pod_traits!(PositionType); #[repr(u8)] #[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankType, Default, PartialEq, Copy)] @@ -61,9 +40,7 @@ pub enum TokenType { Supply, Debt, } - -unsafe impl Zeroable for TokenType {} -unsafe impl Pod for TokenType {} +derive_pod_traits!(TokenType); impl fmt::Display for TokenType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -75,18 +52,46 @@ impl fmt::Display for TokenType { } #[repr(u8)] -#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, Default, PartialEq, Copy)] +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankType, Default, PartialEq, Copy)] pub enum RebalanceDirection { #[default] + None, Boost, Repay, } +derive_pod_traits!(RebalanceDirection); -unsafe impl Zeroable for RebalanceDirection {} -unsafe impl Pod for RebalanceDirection {} +#[repr(u8)] +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankType, Default, PartialEq, Copy)] +pub enum RebalanceStep { + #[default] + PreSwap, + PostSwap, +} +derive_pod_traits!(RebalanceStep); + +#[repr(u8)] +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankType, Default, PartialEq, Copy)] +pub enum SolautoRebalanceType { + #[default] + Regular, + DoubleRebalanceWithFL, + FLSwapThenRebalance, + FLRebalanceThenSwap, +} +derive_pod_traits!(SolautoRebalanceType); + +#[repr(u8)] +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankType, Default, PartialEq, Copy)] +pub enum SwapType { + #[default] + ExactIn, + ExactOut, +} +derive_pod_traits!(SwapType); #[derive(Debug)] -pub struct RefreshedTokenData { +pub struct RefreshedTokenState { pub mint: Pubkey, pub decimals: u8, pub amount_used: u64, @@ -99,8 +104,8 @@ pub struct RefreshedTokenData { pub struct RefreshStateProps { pub max_ltv: f64, pub liq_threshold: f64, - pub supply: RefreshedTokenData, - pub debt: RefreshedTokenData, + pub supply: RefreshedTokenState, + pub debt: RefreshedTokenState, } #[derive(BorshDeserialize, BorshSerialize, Clone, Debug, PartialEq)] @@ -109,10 +114,42 @@ pub enum TokenBalanceAmount { All, } -#[derive(Debug, PartialEq)] -pub enum RebalanceStep { - Initial, - Final, +pub struct SplTokenTransferArgs<'a, 'b> { + pub source: &'a AccountInfo<'a>, + pub authority: &'a AccountInfo<'a>, + pub recipient: &'a AccountInfo<'a>, + pub amount: u64, + pub authority_seeds: Option<&'b Vec<&'b [u8]>>, +} + +#[derive(Clone)] +pub struct BareSplTokenTransferArgs { + pub from_wallet: Pubkey, + pub from_wallet_ta: Pubkey, + pub to_wallet_ta: Pubkey, + pub amount: u64, +} + +#[repr(C)] +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankType, Default, PartialEq, Copy)] +pub struct PodBool { + pub val: bool, +} + +derive_pod_traits!(PodBool); + +impl PodBool { + pub fn new(val: bool) -> Self { + Self { val } + } +} + +#[repr(u8)] +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankType, Default, PartialEq, Copy)] +pub enum PriceType { + #[default] + Realtime, + Ema, } #[derive(Clone)] @@ -150,31 +187,3 @@ impl<'a, T: Pack + IsInitialized> DeserializedAccount<'a, T> { } } } - -#[derive(Error, Debug)] -pub enum SolautoError { - #[error("Missing or incorrect accounts provided for the given instruction")] - IncorrectAccounts, - #[error("Failed to deserialize account data")] - FailedAccountDeserialization, - #[error("Invalid position settings provided")] - InvalidPositionSettings, - #[error("Invalid DCA configuration provided")] - InvalidDCASettings, - #[error("Invalid automation settings provided")] - InvalidAutomationData, - #[error("Invalid position condition to rebalance")] - InvalidRebalanceCondition, - #[error("Unable to invoke instruction through a CPI")] - InstructionIsCPI, - #[error("Incorrect set of instructions in the transaction")] - IncorrectInstructions, - #[error("Incorrect swap amount provided. Likely due to high price volatility")] - IncorrectDebtAdjustment, -} - -impl From for ProgramError { - fn from(e: SolautoError) -> Self { - ProgramError::Custom(e as u32) - } -} diff --git a/programs/solauto/src/types/solauto.rs b/programs/solauto/src/types/solauto.rs new file mode 100644 index 00000000..fd2f70ad --- /dev/null +++ b/programs/solauto/src/types/solauto.rs @@ -0,0 +1,35 @@ +use solana_program::pubkey::Pubkey; + +use super::shared::{BareSplTokenTransferArgs, TokenBalanceAmount}; + +#[derive(Clone)] +pub struct FromLendingPlatformAction { + pub amount: T, + pub to_wallet_ta: Pubkey, +} + +#[derive(Clone)] +pub enum SolautoCpiAction { + Deposit(u64), + Borrow(FromLendingPlatformAction), + Repay(TokenBalanceAmount), + Withdraw(FromLendingPlatformAction), + SplTokenTransfer(BareSplTokenTransferArgs), +} + +#[derive(Copy, Clone)] +pub struct PositionValues { + pub supply_usd: f64, + pub debt_usd: f64, +} + +pub struct RebalanceFeesBps { + pub solauto: u16, + pub lp_borrow: u16, + pub flash_loan: u16, +} + +pub struct DebtAdjustment { + pub debt_adjustment_usd: f64, + pub end_result: PositionValues, +} diff --git a/programs/solauto/src/types/solauto_manager.rs b/programs/solauto/src/types/solauto_manager.rs index 72815551..d75389e6 100644 --- a/programs/solauto/src/types/solauto_manager.rs +++ b/programs/solauto/src/types/solauto_manager.rs @@ -1,29 +1,23 @@ -use math_utils::{ from_bps, to_bps }; +use math_utils::to_bps; use solana_program::{ - account_info::AccountInfo, - clock::Clock, - entrypoint::ProgramResult, - msg, - program_error::ProgramError, - sysvar::Sysvar, + account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, + program_error::ProgramError, pubkey::Pubkey, }; -use spl_associated_token_account::get_associated_token_address; -use std::{ cmp::min, ops::{ Add, Div, Mul } }; -use validation_utils::validate_debt_adjustment; use super::{ - instruction::{ RebalanceSettings, SolautoAction, SolautoStandardAccounts }, - lending_protocol::{ LendingProtocolClient, LendingProtocolTokenAccounts }, - shared::{ RebalanceDirection, RefreshStateProps, SolautoError, TokenBalanceAmount, TokenType }, + instruction::{RebalanceSettings, SolautoAction, SolautoStandardAccounts}, + lending_protocol::{LendingProtocolClient, LendingProtocolTokenAccounts}, + shared::{ + RebalanceStep, RefreshStateProps, SplTokenTransferArgs, TokenBalanceAmount, TokenType, + }, + solauto::SolautoCpiAction, }; use crate::{ - constants::SOLAUTO_FEES_WALLET, - state::solauto_position::{ - AutomationSettings, - RebalanceData, - SolautoPosition, - SolautoRebalanceType, + rebalance::{ + rebalancer::{Rebalancer, RebalancerData, SolautoPositionData, TokenAccountData}, + solauto_fees::SolautoFeesBps, }, + state::solauto_position::{RebalanceData, SolautoPosition}, utils::*, }; @@ -31,14 +25,14 @@ pub struct SolautoManagerAccounts<'a> { pub supply: LendingProtocolTokenAccounts<'a>, pub debt: LendingProtocolTokenAccounts<'a>, pub intermediary_ta: Option<&'a AccountInfo<'a>>, - pub solauto_fees: Option, + pub solauto_fees: Option, } impl<'a> SolautoManagerAccounts<'a> { pub fn from( supply: LendingProtocolTokenAccounts<'a>, debt: LendingProtocolTokenAccounts<'a>, intermediary_ta: Option<&'a AccountInfo<'a>>, - solauto_fees: Option + solauto_fees: Option, ) -> Result { Ok(Self { supply, @@ -53,7 +47,7 @@ pub struct SolautoManager<'a> { pub client: Box + 'a>, pub accounts: SolautoManagerAccounts<'a>, pub std_accounts: Box>, - pub solauto_fees_bps: Option, + pub solauto_fees_bps: Option, } impl<'a> SolautoManager<'a> { @@ -61,7 +55,7 @@ impl<'a> SolautoManager<'a> { client: Box + 'a>, accounts: SolautoManagerAccounts<'a>, std_accounts: Box>, - solauto_fees_bps: Option + solauto_fees_bps: Option, ) -> Result { client.validate(&std_accounts)?; Ok(Self { @@ -72,6 +66,10 @@ impl<'a> SolautoManager<'a> { }) } + fn position_data(&self) -> &Box { + &self.std_accounts.solauto_position.data + } + fn deposit(&mut self, base_unit_amount: u64) -> ProgramResult { msg!("Depositing {}", base_unit_amount); self.update_usage(base_unit_amount as i64, TokenType::Supply); @@ -82,33 +80,31 @@ impl<'a> SolautoManager<'a> { fn borrow(&mut self, base_unit_amount: u64, destination: &'a AccountInfo<'a>) -> ProgramResult { msg!("Borrowing {}", base_unit_amount); self.update_usage(base_unit_amount as i64, TokenType::Debt); - self.client.borrow(base_unit_amount, destination, &self.std_accounts)?; + self.client + .borrow(base_unit_amount, destination, &self.std_accounts)?; Ok(()) } fn withdraw( &mut self, amount: TokenBalanceAmount, - destination: &'a AccountInfo<'a> + destination: &'a AccountInfo<'a>, ) -> ProgramResult { let base_unit_amount = match amount { - TokenBalanceAmount::All => { - self.std_accounts.solauto_position.data.state.supply.amount_used.base_unit - } + TokenBalanceAmount::All => self.position_data().state.supply.amount_used.base_unit, TokenBalanceAmount::Some(num) => num, }; msg!("Withdrawing {}", base_unit_amount); self.update_usage((base_unit_amount as i64) * -1, TokenType::Supply); - self.client.withdraw(amount, destination, &self.std_accounts)?; + self.client + .withdraw(amount, destination, &self.std_accounts)?; Ok(()) } fn repay(&mut self, amount: TokenBalanceAmount) -> ProgramResult { let base_unit_amount = match amount { - TokenBalanceAmount::All => { - self.std_accounts.solauto_position.data.state.debt.amount_used.base_unit - } + TokenBalanceAmount::All => self.position_data().state.debt.amount_used.base_unit, TokenBalanceAmount::Some(num) => num, }; @@ -119,300 +115,124 @@ impl<'a> SolautoManager<'a> { } fn update_usage(&mut self, base_unit_amount: i64, token_type: TokenType) { - if - !self.std_accounts.solauto_position.data.self_managed.val || - self.std_accounts.solauto_position.data.rebalance.active() - { - self.std_accounts.solauto_position.data.update_usage(token_type, base_unit_amount); + let position_data = self.position_data(); + if !position_data.self_managed.val || position_data.rebalance.active() { + self.std_accounts + .solauto_position + .data + .update_usage(token_type, base_unit_amount); } } - pub fn protocol_interaction(&mut self, action: SolautoAction) -> ProgramResult { - match action { - SolautoAction::Deposit(base_unit_amount) => { - self.deposit(base_unit_amount)?; - } - SolautoAction::Borrow(base_unit_amount) => { - self.borrow(base_unit_amount, self.accounts.debt.position_ta.as_ref().unwrap())?; - } - SolautoAction::Repay(amount) => { - self.repay(amount)?; - } - SolautoAction::Withdraw(amount) => { - self.withdraw(amount, self.accounts.supply.position_ta.as_ref().unwrap())?; - } - } - Ok(()) + fn get_token_account_data(&self, account: Option<&'a AccountInfo<'a>>) -> TokenAccountData { + TokenAccountData::from( + *account.unwrap().key, + solauto_utils::safe_unpack_token_account(account) + .unwrap() + .unwrap() + .data + .amount, + ) } - pub fn begin_rebalance(&mut self, rebalance_args: &RebalanceSettings) -> ProgramResult { - let (debt_adjustment_usd, amount_to_dca_in) = rebalance_utils::get_rebalance_values( - &mut self.std_accounts.solauto_position.data, - rebalance_args, - self.solauto_fees_bps.as_ref().unwrap(), - Clock::get()?.unix_timestamp as u64 - )?; - - if amount_to_dca_in.is_some() { - if self.std_accounts.solauto_position.data.position.dca.token_type == TokenType::Supply { - self.deposit(amount_to_dca_in.unwrap())?; - } else { - solana_utils::spl_token_transfer( - self.std_accounts.token_program, - self.accounts.debt.position_ta.as_ref().unwrap(), - self.std_accounts.solauto_position.account_info, - self.accounts.intermediary_ta.unwrap(), - amount_to_dca_in.unwrap(), - Some(&self.std_accounts.solauto_position.data.seeds_with_bump()) - )?; - } - } - - let rebalance_type = self.std_accounts.solauto_position.data.rebalance.rebalance_type; - if rebalance_type == SolautoRebalanceType::DoubleRebalanceWithFL { - validate_debt_adjustment( - &self.std_accounts.solauto_position.data, - self.std_accounts.solauto_position.data.rebalance.flash_loan_amount, - debt_adjustment_usd, - Some(&rebalance_type) - )?; - return Ok(()); - } - - let increasing_leverage = debt_adjustment_usd > 0.0; - - let token = if increasing_leverage { - Box::new(&self.std_accounts.solauto_position.data.state.debt) - } else { - Box::new(&self.std_accounts.solauto_position.data.state.supply) - }; - - let base_unit_amount = math_utils::to_base_unit::( - debt_adjustment_usd.abs().div(token.market_price()), - token.decimals - ); - - if increasing_leverage { - let final_amount = if rebalance_args.target_in_amount_base_unit.is_some() { - rebalance_args.target_in_amount_base_unit.unwrap() - } else { - base_unit_amount - }; - self.borrow(final_amount, self.accounts.intermediary_ta.unwrap()) - } else { - let final_amount = if rebalance_args.target_in_amount_base_unit.is_some() { - rebalance_args.target_in_amount_base_unit.unwrap() - } else { - min( - self.std_accounts.solauto_position.data.state.supply.amount_used.base_unit, - base_unit_amount - ) - }; - self.withdraw( - TokenBalanceAmount::Some(final_amount), - self.accounts.intermediary_ta.unwrap() - ) - } + fn pk_to_account_info(&self, pk: Pubkey) -> &'a AccountInfo<'a> { + let accounts = [ + Some(self.std_accounts.solauto_position.account_info), + self.accounts.supply.position_ta, + self.accounts.supply.authority_ta, + self.accounts.debt.position_ta, + self.accounts.debt.authority_ta, + self.accounts.intermediary_ta, + self.std_accounts.solauto_fees_ta, + self.std_accounts.referred_by_ta, + ]; + + accounts + .iter() + .find(|acc| acc.is_some() && acc.unwrap().key == &pk) + .unwrap() + .unwrap() } - pub fn finish_rebalance(&mut self, rebalance_args: &RebalanceSettings) -> ProgramResult { - let rebalance_data = &self.std_accounts.solauto_position.data.rebalance; - let rebalance_type = rebalance_data.rebalance_type; - let flash_loan_amount = rebalance_data.flash_loan_amount; - - if - rebalance_type == SolautoRebalanceType::FLSwapThenRebalance || - rebalance_type == SolautoRebalanceType::FLRebalanceThenSwap - { - let (debt_adjustment_usd, _) = rebalance_utils::get_rebalance_values( - &mut self.std_accounts.solauto_position.data, - rebalance_args, - self.solauto_fees_bps.as_ref().unwrap(), - Clock::get()?.unix_timestamp as u64 - )?; - validate_debt_adjustment( - &self.std_accounts.solauto_position.data, - flash_loan_amount, - debt_adjustment_usd, - Some(&rebalance_type) - )?; - } - - let boosting = - self.std_accounts.solauto_position.data.rebalance.rebalance_direction == - RebalanceDirection::Boost; - let mut available_balance = if boosting { - solauto_utils - ::safe_unpack_token_account(self.accounts.supply.position_ta)? - .unwrap().data.amount - } else { - solauto_utils - ::safe_unpack_token_account(self.accounts.debt.position_ta)? - .unwrap().data.amount - }; - - if !self.std_accounts.solauto_position.data.self_managed.val { - let dca_in_base_unit = - self.std_accounts.solauto_position.data.position.dca.dca_in_base_unit; - let dca_token_type = self.std_accounts.solauto_position.data.position.dca.token_type; - if boosting && dca_token_type == TokenType::Supply { - available_balance -= dca_in_base_unit; - } else if !boosting && dca_token_type == TokenType::Debt { - available_balance -= dca_in_base_unit; - } - } - - let transfer_to_authority_ta = | - token_accounts: &LendingProtocolTokenAccounts<'a>, - amount: u64 - | { - solana_utils::spl_token_transfer( - self.std_accounts.token_program, - token_accounts.position_ta.clone().unwrap(), - self.std_accounts.solauto_position.account_info, - token_accounts.authority_ta.clone().unwrap(), - amount, - Some(&self.std_accounts.solauto_position.data.seeds_with_bump()) - ) - }; - - let amount_after_fees = self.payout_fees(available_balance)?; - - if boosting { - if self.std_accounts.solauto_position.data.self_managed.val { - transfer_to_authority_ta(&self.accounts.supply, amount_after_fees)?; - } - self.deposit(amount_after_fees)?; - } else if available_balance > 0 { - if self.std_accounts.solauto_position.data.self_managed.val { - transfer_to_authority_ta(&self.accounts.debt, amount_after_fees)?; - } - let final_amount = if - rebalance_args.target_liq_utilization_rate_bps.is_some() && - rebalance_args.target_liq_utilization_rate_bps.unwrap() == 0 - { - TokenBalanceAmount::All - } else { - TokenBalanceAmount::Some( - min( - self.std_accounts.solauto_position.data.state.debt.amount_used.base_unit, - amount_after_fees - ) - ) - }; - self.repay(final_amount)?; - } else { - msg!("Missing required position liquidity to rebalance position"); - return Err(SolautoError::IncorrectInstructions.into()); - } - - if flash_loan_amount > 0 { - let flash_loan_fee_bps = if boosting { - self.std_accounts.solauto_position.data.state.supply.flash_loan_fee_bps - } else { - self.std_accounts.solauto_position.data.state.debt.flash_loan_fee_bps - }; - - let final_amount = if rebalance_type == SolautoRebalanceType::FLRebalanceThenSwap { - rebalance_args.target_in_amount_base_unit.unwrap() - } else { - flash_loan_amount.add( - (flash_loan_amount as f64).mul(from_bps(flash_loan_fee_bps)) as u64 - ) - }; + fn get_rebalancer(&mut self, rebalance_args: RebalanceSettings) -> Rebalancer { + let position_supply_ta = self.get_token_account_data(self.accounts.supply.position_ta); + let position_debt_ta = self.get_token_account_data(self.accounts.debt.position_ta); - if boosting { - self.borrow(final_amount, self.accounts.intermediary_ta.unwrap())?; - } else { - self.withdraw( - TokenBalanceAmount::Some(final_amount), - self.accounts.intermediary_ta.unwrap() - )?; - } - } - - self.std_accounts.solauto_position.data.rebalance = RebalanceData::default(); - Ok(()) + Rebalancer::new(RebalancerData { + rebalance_args, + solauto_position: SolautoPositionData { + data: &mut self.std_accounts.solauto_position.data, + supply_ta: position_supply_ta, + debt_ta: position_debt_ta, + }, + authority_supply_ta: self.accounts.supply.authority_ta.map_or(None, |acc| { + Some(TokenAccountData::without_balance(*acc.key)) + }), + authority_debt_ta: self.accounts.debt.authority_ta.map_or(None, |acc| { + Some(TokenAccountData::without_balance(*acc.key)) + }), + intermediary_ta: TokenAccountData::without_balance( + *self.accounts.intermediary_ta.unwrap().key, + ), + solauto_fees_bps: self.solauto_fees_bps.unwrap().clone(), + solauto_fees_ta: self + .std_accounts + .solauto_fees_ta + .map_or(None, |acc| Some(*acc.key)), + referred_by_state: self + .std_accounts + .authority_referral_state + .as_ref() + .map_or(None, |acc| Some(acc.data.referred_by_state.clone())), + referred_by_ta: self + .std_accounts + .referred_by_ta + .map_or(None, |acc| Some(*acc.key)), + }) } - fn payout_fees(&self, total_available_balance: u64) -> Result { - if self.std_accounts.authority_referral_state.is_none() { - msg!( - "Missing referral account when we are boosting leverage. Referral accounts are required" - ); - return Err(SolautoError::IncorrectAccounts.into()); - } - - let rebalance_direction = - self.std_accounts.solauto_position.data.rebalance.rebalance_direction; - let token_mint = if rebalance_direction == RebalanceDirection::Boost { - self.std_accounts.solauto_position.data.state.supply.mint - } else { - self.std_accounts.solauto_position.data.state.debt.mint - }; + fn execute_cpi_actions(&mut self, actions: Vec) -> ProgramResult { + let sm = self; - let position_ta = if rebalance_direction == RebalanceDirection::Boost { - self.accounts.supply.position_ta.unwrap() - } else { - self.accounts.debt.position_ta.unwrap() - }; - let fee_payout = self.solauto_fees_bps.as_ref().unwrap().fetch_fees(rebalance_direction); - - if fee_payout.total == 0 { - return Ok(total_available_balance); - } - - let solauto_fees = (total_available_balance as f64).mul(from_bps(fee_payout.total)) as u64; - if - self.std_accounts.solauto_fees_ta.unwrap().key != - &get_associated_token_address(&SOLAUTO_FEES_WALLET, &token_mint) - { - msg!("Incorrect Solauto fees token account"); - return Err(SolautoError::IncorrectAccounts.into()); - } - solana_utils::spl_token_transfer( - self.std_accounts.token_program, - position_ta, - self.std_accounts.solauto_position.account_info, - self.std_accounts.solauto_fees_ta.unwrap(), - solauto_fees, - Some(&self.std_accounts.solauto_position.data.seeds_with_bump()) - )?; - - let referrer_fees = (total_available_balance as f64).mul( - from_bps(fee_payout.referrer) - ) as u64; - if referrer_fees > 0 { - if - self.std_accounts.referred_by_ta.unwrap().key != - &get_associated_token_address( - &self.std_accounts.authority_referral_state - .as_ref() - .unwrap().data.referred_by_state, - &token_mint - ) - { - msg!("Incorrect referral fee token account"); - return Err(SolautoError::IncorrectAccounts.into()); + for action in actions { + match action { + SolautoCpiAction::Deposit(amount) => sm.deposit(amount)?, + SolautoCpiAction::Withdraw(data) => { + sm.withdraw(data.amount, sm.pk_to_account_info(data.to_wallet_ta))?; + } + SolautoCpiAction::Borrow(data) => { + sm.borrow(data.amount, sm.pk_to_account_info(data.to_wallet_ta))?; + } + SolautoCpiAction::Repay(amount) => sm.repay(amount)?, + SolautoCpiAction::SplTokenTransfer(data) => { + let seeds = + if &data.from_wallet == sm.std_accounts.solauto_position.account_info.key { + Some(sm.std_accounts.solauto_position.data.seeds_with_bump()) + } else { + None + }; + solana_utils::spl_token_transfer( + sm.std_accounts.token_program, + SplTokenTransferArgs { + amount: data.amount, + source: sm.pk_to_account_info(data.from_wallet_ta), + authority: sm.pk_to_account_info(data.from_wallet), + recipient: sm.pk_to_account_info(data.to_wallet_ta), + authority_seeds: seeds.as_ref(), + }, + )?; + } } - solana_utils::spl_token_transfer( - self.std_accounts.token_program, - position_ta, - self.std_accounts.solauto_position.account_info, - self.std_accounts.referred_by_ta.unwrap(), - referrer_fees, - Some(&self.std_accounts.solauto_position.data.seeds_with_bump()) - )?; } - - Ok(total_available_balance - solauto_fees - referrer_fees) + Ok(()) } pub fn refresh_position( solauto_position: &mut SolautoPosition, updated_data: RefreshStateProps, - clock: Clock + clock: Clock, ) -> ProgramResult { + // Update mint addresses if self-managed if solauto_position.self_managed.val { solauto_position.state.supply.mint = updated_data.supply.mint; solauto_position.state.debt.mint = updated_data.debt.mint; @@ -421,59 +241,64 @@ impl<'a> SolautoManager<'a> { solauto_position.state.max_ltv_bps = to_bps(updated_data.max_ltv); solauto_position.state.liq_threshold_bps = to_bps(updated_data.liq_threshold); - solauto_position.state.supply.decimals = updated_data.supply.decimals; - solauto_position.state.debt.decimals = updated_data.debt.decimals; - - solauto_position.state.supply.amount_used.base_unit = updated_data.supply.amount_used; - solauto_position.state.supply.amount_can_be_used.base_unit = - updated_data.supply.amount_can_be_used; - solauto_position.state.supply.update_market_price(updated_data.supply.market_price); - - solauto_position.state.debt.amount_used.base_unit = updated_data.debt.amount_used; - solauto_position.state.debt.amount_can_be_used.base_unit = - updated_data.debt.amount_can_be_used; - solauto_position.state.debt.update_market_price(updated_data.debt.market_price); + solauto_utils::update_token_state(&mut solauto_position.state.supply, &updated_data.supply); + solauto_utils::update_token_state(&mut solauto_position.state.debt, &updated_data.debt); solauto_position.state.net_worth.base_unit = math_utils::net_worth_base_amount( solauto_position.state.supply.amount_used.usd_value(), solauto_position.state.debt.amount_used.usd_value(), solauto_position.state.supply.market_price(), - solauto_position.state.supply.decimals + solauto_position.state.supply.decimals, ); solauto_position.state.net_worth.update_usd_value( updated_data.supply.market_price, - solauto_position.state.supply.decimals + solauto_position.state.supply.decimals, ); solauto_position.refresh_state(); - solauto_position.state.last_updated = clock.unix_timestamp as u64; + solauto_position.state.last_refreshed = clock.unix_timestamp as u64; - if solauto_position.self_managed.val { - return Ok(()); + Ok(()) + } + + pub fn protocol_interaction(&mut self, action: SolautoAction) -> ProgramResult { + match action { + SolautoAction::Deposit(base_unit_amount) => { + self.deposit(base_unit_amount)?; + } + SolautoAction::Borrow(base_unit_amount) => { + self.borrow( + base_unit_amount, + self.accounts.debt.position_ta.as_ref().unwrap(), + )?; + } + SolautoAction::Repay(amount) => { + self.repay(amount)?; + } + SolautoAction::Withdraw(amount) => { + self.withdraw(amount, self.accounts.supply.position_ta.as_ref().unwrap())?; + } } + Ok(()) + } - if solauto_position.position.setting_params.automation.is_active() { - let automation = &solauto_position.position.setting_params.automation; + pub fn rebalance( + &mut self, + rebalance_args: RebalanceSettings, + rebalance_step: RebalanceStep, + ) -> ProgramResult { + let (actions, finished) = { + let mut rebalancer = self.get_rebalancer(rebalance_args.clone()); + let rebalance_result = rebalancer.rebalance(rebalance_step)?; + let actions = rebalancer.actions().clone(); + (actions, rebalance_result.finished) + }; - if automation.eligible_for_next_period(clock.unix_timestamp as u64) { - let current_timestamp = Clock::get()?.unix_timestamp as u64; - solauto_position.position.setting_params.boost_to_bps = - automation.updated_amount_from_automation( - solauto_position.position.setting_params.boost_to_bps, - solauto_position.position.setting_params.target_boost_to_bps, - current_timestamp - ); + self.execute_cpi_actions(actions)?; - let new_periods_passed = automation.new_periods_passed(current_timestamp); - if new_periods_passed == automation.target_periods { - solauto_position.position.setting_params.automation = - AutomationSettings::default(); - solauto_position.position.setting_params.target_boost_to_bps = 0; - } else { - solauto_position.position.setting_params.automation.periods_passed = - new_periods_passed; - } - } + if finished { + validation_utils::validate_rebalance(&self.std_accounts.solauto_position.data)?; + self.std_accounts.solauto_position.data.rebalance = RebalanceData::default(); } Ok(()) diff --git a/programs/solauto/src/utils/ix_utils.rs b/programs/solauto/src/utils/ix_utils.rs index 491ba775..ab32fb0a 100644 --- a/programs/solauto/src/utils/ix_utils.rs +++ b/programs/solauto/src/utils/ix_utils.rs @@ -1,26 +1,31 @@ use borsh::{BorshDeserialize, BorshSerialize}; -use jupiter_sdk::generated::instructions::{ - ExactOutRouteInstructionArgs, RouteWithTokenLedgerInstructionArgs, - SharedAccountsExactOutRouteInstructionArgs, SharedAccountsRouteWithTokenLedgerInstructionArgs, -}; +use jupiter_sdk::JUPITER_ID; use marginfi_sdk::generated::instructions::LendingAccountBorrowInstructionArgs; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, hash::hash, - instruction::Instruction, + instruction::{get_stack_height, Instruction, TRANSACTION_LEVEL_STACK_HEIGHT}, msg, program::invoke, program_error::ProgramError, pubkey::Pubkey, sanitize::SanitizeError, serialize_utils::{read_pubkey, read_slice, read_u16}, + sysvar::instructions::load_current_index_checked, }; use super::solana_utils::invoke_instruction; use crate::{ + check, + constants::{MARGINFI_PROD_PROGRAM, MARGINFI_STAGING_PROGRAM}, + error_if, state::solauto_position::SolautoPosition, - types::shared::{DeserializedAccount, SolautoError}, + types::{ + errors::SolautoError, + instruction::{SolautoStandardAccounts, SOLAUTO_REBALANCE_IX_DISCRIMINATORS}, + shared::{DeserializedAccount, SolautoRebalanceType}, + }, }; pub fn update_data(account: &mut DeserializedAccount) -> ProgramResult { @@ -102,8 +107,7 @@ fn pick_ix_data(req: PickIxDataReq) -> Result { let instruction_data_len = read_u16(&mut current, &data)? as usize; let data_start = data_start_idx.unwrap_or(0) as usize; - let data_end = - data_start + (data_len.unwrap_or((instruction_data_len - data_start) as u64) as usize); + let data_end = data_start + (data_len.unwrap_or(instruction_data_len as u64) as usize); current += data_start; let picked_data = read_slice(&mut current, &data, data_end)?; @@ -116,173 +120,20 @@ fn pick_ix_data(req: PickIxDataReq) -> Result { }) } -/// Validates the jup swap: -/// - The swap does NOT have a platform fee -/// - The destination token account is one of the expected destination token accounts -/// -/// Returns the slippage_fee_bps -pub fn validate_jup_instruction<'a>( - ixs_sysvar: &'a AccountInfo<'a>, - ix_idx: usize, - expected_destination_tas: &[&Pubkey], -) -> Result<(Pubkey, u16), ProgramError> { - let resp = pick_ix_data(PickIxDataReq { - ixs_sysvar, - ix_idx, - data_start_idx: Some(0), - data_len: Some(8), // Only pick the data discriminator - account_indices: None, - }) - .expect("Should pick data"); - - let discriminator = - u64::from_le_bytes(resp.data.try_into().expect("Slice with incorrect length")); - - let route_with_token_ledger = get_anchor_ix_discriminator("route_with_token_ledger"); - let shared_accounts_route_with_token_ledger = - get_anchor_ix_discriminator("shared_accounts_route_with_token_ledger"); - let exact_out_route = get_anchor_ix_discriminator("exact_out_route"); - let shared_accounts_exact_out_route = - get_anchor_ix_discriminator("shared_accounts_exact_out_route"); - - let result: Result<(u16, u8, Pubkey, Pubkey), ProgramError> = - if discriminator == route_with_token_ledger { - let resp = pick_ix_data(PickIxDataReq { - ixs_sysvar, - ix_idx, - data_start_idx: Some(8), // Skip data discriminator - data_len: None, - account_indices: Some(vec![2, 4]), - }) - .expect("Should pick data"); - - let args = Box::new(RouteWithTokenLedgerInstructionArgs::deserialize( - &mut resp.data.as_slice(), - )?); - - let return_data = ( - args.slippage_bps, - args.platform_fee_bps, - resp.accounts[0], - resp.accounts[1], - ); - drop(args); - Ok(return_data) - } else if discriminator == shared_accounts_route_with_token_ledger { - let resp = pick_ix_data(PickIxDataReq { - ixs_sysvar, - ix_idx, - data_start_idx: Some(8), // Skip data discriminator - data_len: None, - account_indices: Some(vec![3, 6]), - }) - .expect("Should pick data"); - - let args = Box::new( - SharedAccountsRouteWithTokenLedgerInstructionArgs::deserialize( - &mut resp.data.as_slice(), - )?, - ); - - let return_data = ( - args.slippage_bps, - args.platform_fee_bps, - resp.accounts[0], - resp.accounts[1], - ); - drop(args); - Ok(return_data) - } else if discriminator == exact_out_route { - let resp = pick_ix_data(PickIxDataReq { - ixs_sysvar, - ix_idx, - data_start_idx: Some(8), // Skip data discriminator - data_len: None, - account_indices: Some(vec![2, 4]), - }) - .expect("Should pick data"); - - let args = Box::new(ExactOutRouteInstructionArgs::deserialize( - &mut resp.data.as_slice(), - )?); - - let return_data = ( - args.slippage_bps, - args.platform_fee_bps, - resp.accounts[0], - resp.accounts[1], - ); - drop(args); - Ok(return_data) - } else if discriminator == shared_accounts_exact_out_route { - let resp = pick_ix_data(PickIxDataReq { - ixs_sysvar, - ix_idx, - data_start_idx: Some(8), // Skip data discriminator - data_len: None, - account_indices: Some(vec![3, 6]), - }) - .expect("Should pick data"); - - let args = Box::new(SharedAccountsExactOutRouteInstructionArgs::deserialize( - &mut resp.data.as_slice(), - )?); - - let return_data = ( - args.slippage_bps, - args.platform_fee_bps, - resp.accounts[0], - resp.accounts[1], - ); - drop(args); - Ok(return_data) - } else { - msg!("Unsupported JUP instruction"); - Err(SolautoError::IncorrectInstructions.into()) - }; - - let (slippage_fee_bps, platform_fee, source_ta, destination_ta) = result.unwrap(); - - if platform_fee > 0 { - msg!("Cannot include a platform fee in a token swap"); - return Err(SolautoError::IncorrectInstructions.into()); - } - - if !expected_destination_tas - .iter() - .any(|x| x == &&destination_ta) - { - msg!("Moving funds into an incorrect token account"); - return Err(SolautoError::IncorrectInstructions.into()); - } - - Ok((source_ta, slippage_fee_bps)) -} - pub fn get_marginfi_flash_loan_amount<'a>( ixs_sysvar: &'a AccountInfo<'a>, - ix_idx: usize, - expected_destination_tas: Option<&[&Pubkey]>, + ix_idx: Option, ) -> Result { - let res = pick_ix_data(PickIxDataReq { + let data = pick_ix_data(PickIxDataReq { ixs_sysvar, - ix_idx, + ix_idx: ix_idx.unwrap(), data_start_idx: Some(8), data_len: Some(8), account_indices: Some(vec![4]), }) - .expect("Should pick data"); - let args = LendingAccountBorrowInstructionArgs::deserialize(&mut res.data.as_slice())?; - - if expected_destination_tas.is_some() - && !expected_destination_tas - .unwrap() - .iter() - .any(|x| x == &&res.accounts[0]) - { - msg!("Moving funds into an incorrect token account"); - return Err(SolautoError::IncorrectInstructions.into()); - } + .expect("Should retrieve flash loan amount"); + + let args = LendingAccountBorrowInstructionArgs::deserialize(&mut data.data.as_slice())?; return Ok(args.amount); } @@ -297,7 +148,7 @@ pub fn get_anchor_ix_discriminator(instruction_name: &str) -> u64 { pub struct InstructionChecker<'a> { anchor_program: bool, ixs_sysvar: &'a AccountInfo<'a>, - program_id: Pubkey, + program_ids: Vec, ix_discriminators: Option>, anchor_ix_discriminators: Option>, curr_ix_idx: u16, @@ -305,14 +156,14 @@ pub struct InstructionChecker<'a> { impl<'a> InstructionChecker<'a> { pub fn from( ixs_sysvar: &'a AccountInfo<'a>, - program_id: Pubkey, + program_ids: Vec, ix_discriminators: Option>, curr_ix_idx: u16, ) -> Self { Self { anchor_program: false, ixs_sysvar, - program_id, + program_ids, ix_discriminators, anchor_ix_discriminators: None, curr_ix_idx, @@ -320,7 +171,7 @@ impl<'a> InstructionChecker<'a> { } pub fn from_anchor( ixs_sysvar: &'a AccountInfo<'a>, - program_id: Pubkey, + program_ids: Vec, ix_names: Vec<&str>, curr_ix_idx: u16, ) -> Self { @@ -331,14 +182,14 @@ impl<'a> InstructionChecker<'a> { Self { anchor_program: true, ixs_sysvar, - program_id, + program_ids, ix_discriminators: None, anchor_ix_discriminators: Some(ix_discriminators), curr_ix_idx, } } fn ix_matches(&self, program_id: Pubkey, discriminator_data: &[u8]) -> bool { - if program_id == self.program_id { + if self.program_ids.iter().any(|prog| prog == &program_id) { if self.anchor_program { let discriminator = u64::from_le_bytes( discriminator_data[0..8] @@ -387,3 +238,97 @@ impl<'a> InstructionChecker<'a> { return self.ix_matches(data.program_id, &data.data); } } + +pub fn validate_rebalance_instructions( + std_accounts: &Box, + rebalance_type: SolautoRebalanceType, +) -> ProgramResult { + let ixs_sysvar = std_accounts.ixs_sysvar.unwrap(); + + let current_ix_idx = load_current_index_checked(ixs_sysvar)?; + error_if!( + get_stack_height() > TRANSACTION_LEVEL_STACK_HEIGHT, + SolautoError::InstructionIsCPI + ); + + let solauto_rebalance = InstructionChecker::from( + ixs_sysvar, + vec![crate::ID], + Some(SOLAUTO_REBALANCE_IX_DISCRIMINATORS.to_vec()), + current_ix_idx, + ); + let jup_swap = InstructionChecker::from_anchor( + ixs_sysvar, + vec![JUPITER_ID], + vec![ + "route", + "shared_accounts_route", + "route_with_token_ledger", + "shared_accounts_route_with_token_ledger", + "exact_out_route", + "shared_accounts_exact_out_route", + ], + current_ix_idx, + ); + + let next_ix = 1; + let ix_2_after = 2; + let prev_ix = -1; + + let valid_ixs = match rebalance_type { + SolautoRebalanceType::Regular | SolautoRebalanceType::DoubleRebalanceWithFL => { + jup_swap.matches(next_ix) && solauto_rebalance.matches(ix_2_after) + } + SolautoRebalanceType::FLSwapThenRebalance => jup_swap.matches(prev_ix), + SolautoRebalanceType::FLRebalanceThenSwap => jup_swap.matches(next_ix), + }; + + check!(valid_ixs, SolautoError::IncorrectInstructions); + + Ok(()) +} + +pub fn get_flash_borrow_ix_idx( + std_accounts: &Box, + rebalance_type: SolautoRebalanceType, +) -> Result, ProgramError> { + let ixs_sysvar = std_accounts.ixs_sysvar.unwrap(); + let current_ix_idx = load_current_index_checked(ixs_sysvar)?; + + let prev_ix = -1; + let ix_2_before = -2; + + let marginfi_borrow = InstructionChecker::from_anchor( + ixs_sysvar, + vec![MARGINFI_PROD_PROGRAM, MARGINFI_STAGING_PROGRAM], + vec!["lending_account_borrow"], + current_ix_idx, + ); + + let borrow_ix_idx = match rebalance_type { + SolautoRebalanceType::DoubleRebalanceWithFL => { + if current_ix_idx > 0 && marginfi_borrow.matches(prev_ix) { + Some(((current_ix_idx as i16) + prev_ix) as usize) + } else { + None + } + } + SolautoRebalanceType::FLSwapThenRebalance => { + if current_ix_idx > 1 && marginfi_borrow.matches(ix_2_before) { + Some(((current_ix_idx as i16) + ix_2_before) as usize) + } else { + None + } + } + SolautoRebalanceType::FLRebalanceThenSwap => { + if current_ix_idx > 0 && marginfi_borrow.matches(prev_ix) { + Some(((current_ix_idx as i16) + prev_ix) as usize) + } else { + None + } + } + _ => None, + }; + + Ok(borrow_ix_idx) +} diff --git a/programs/solauto/src/utils/math_utils.rs b/programs/solauto/src/utils/math_utils.rs index c8454b6e..fd6bdd9e 100644 --- a/programs/solauto/src/utils/math_utils.rs +++ b/programs/solauto/src/utils/math_utils.rs @@ -2,10 +2,16 @@ use fixed::types::I80F48; use num_traits::{FromPrimitive, ToPrimitive}; use std::{ cmp::min, - ops::{Div, Mul}, + ops::{Add, Div, Mul, Sub}, }; -use crate::constants::{MAX_BASIS_POINTS, MIN_REPAY_GAP_BPS, USD_DECIMALS}; +use crate::{ + constants::{MAX_BASIS_POINTS, MIN_REPAY_GAP_BPS, OFFSET_FROM_MAX_LTV, USD_DECIMALS}, + types::{ + shared::TokenType, + solauto::{DebtAdjustment, PositionValues, RebalanceFeesBps}, + }, +}; #[inline(always)] pub fn from_base_unit(base_units: T, decimals: U) -> V @@ -20,15 +26,26 @@ where } #[inline(always)] -pub fn to_base_unit(value: T, decimals: U) -> V +pub fn to_base_unit(value: T, decimals: U) -> V where T: ToPrimitive, U: Into, V: FromPrimitive, { let factor = (10u64).pow(decimals.into()) as f64; - let base_units = value.to_f64().unwrap_or(0.0).mul(factor); - V::from_f64(base_units).unwrap() + let base_units = value.to_f64().unwrap_or(0.0) * factor; + let adjusted = if base_units < 0.0 { 0.0 } else { base_units }; + V::from_f64(adjusted).unwrap_or_else(|| V::from_f64(0.0).unwrap()) +} + +#[inline(always)] +pub fn to_rounded_usd_value(usd_value: f64) -> u64 { + to_base_unit(usd_value, USD_DECIMALS) +} + +#[inline(always)] +pub fn from_rounded_usd_value(usd_value: u64) -> f64 { + from_base_unit(usd_value, USD_DECIMALS) } #[inline(always)] @@ -38,6 +55,11 @@ pub fn base_unit_to_usd_value(base_unit: u64, decimals: u8, market_price: f64) - .mul(market_price) } +#[inline(always)] +pub fn usd_value_to_base_unit(usd_value: f64, decimals: u8, market_price: f64) -> u64 { + to_base_unit(usd_value.abs().div(market_price), decimals) +} + #[inline(always)] pub fn from_bps(value_bps: u16) -> f64 { (value_bps as f64).div(MAX_BASIS_POINTS as f64) @@ -50,7 +72,11 @@ pub fn to_bps(value: f64) -> u16 { #[inline(always)] pub fn i80f48_to_u64(value: I80F48) -> u64 { - value.to_num::() + if value < 0.0 { + 0 + } else { + value.to_num::() + } } #[inline(always)] @@ -69,7 +95,7 @@ pub fn get_liq_utilization_rate_bps(supply_usd: f64, debt_usd: f64, liq_threshol #[inline(always)] pub fn net_worth_usd_base_amount(supply_usd: f64, debt_usd: f64) -> u64 { - to_base_unit::(supply_usd - debt_usd, USD_DECIMALS) + to_base_unit(supply_usd - debt_usd, USD_DECIMALS) } #[inline(always)] @@ -84,38 +110,7 @@ pub fn net_worth_base_amount( USD_DECIMALS, ) .div(supply_market_price as f64); - to_base_unit::(supply_net_worth, supply_decimals) -} - -/// Calculates the debt adjustment in USD in order to reach the target_liq_utilization_rate -/// -/// # Parameters -/// * `liq_threshold` - The liquidation threshold of the supplied asset -/// * `total_supply_usd` - Total USD value of supplied asset -/// * `total_debt_usd` - Total USD value of debt asset -/// * `target_liq_utilization_rate_bps` - Target utilization rate -/// * `adjustment_fee_bps` - Adjustment fee. On boosts this would be the Solauto fee. If deleveraging this would be None -/// -/// # Returns -/// The USD value of the debt adjustment. Positive if debt needs to increase, negative if debt needs to decrease. This amount is inclusive of the adjustment fee -/// -pub fn get_std_debt_adjustment_usd( - liq_threshold: f64, - total_supply_usd: f64, - total_debt_usd: f64, - target_liq_utilization_rate_bps: u16, - adjustment_fee_bps: u16, -) -> f64 { - let adjustment_fee = if adjustment_fee_bps > 0 { - from_bps(adjustment_fee_bps) - } else { - 0.0 - }; - - let target_liq_utilization_rate = from_bps(target_liq_utilization_rate_bps); - - (target_liq_utilization_rate * total_supply_usd * liq_threshold - total_debt_usd) - / (1.0 - target_liq_utilization_rate * (1.0 - adjustment_fee) * liq_threshold) + to_base_unit(supply_net_worth, supply_decimals) } #[inline(always)] @@ -132,7 +127,11 @@ pub fn get_max_liq_utilization_rate_bps( pub fn get_max_repay_from_bps(max_ltv_bps: u16, liq_threshold_bps: u16) -> u16 { min( 9000, - get_max_liq_utilization_rate_bps(max_ltv_bps, liq_threshold_bps - 1000, 0.01), + get_max_liq_utilization_rate_bps( + max_ltv_bps, + liq_threshold_bps - 1000, + OFFSET_FROM_MAX_LTV, + ), ) } @@ -140,7 +139,7 @@ pub fn get_max_repay_from_bps(max_ltv_bps: u16, liq_threshold_bps: u16) -> u16 { pub fn get_max_repay_to_bps(max_ltv_bps: u16, liq_threshold_bps: u16) -> u16 { min( get_max_repay_from_bps(max_ltv_bps, liq_threshold_bps) - MIN_REPAY_GAP_BPS, - get_max_liq_utilization_rate_bps(max_ltv_bps, liq_threshold_bps, 0.01), + get_max_liq_utilization_rate_bps(max_ltv_bps, liq_threshold_bps, OFFSET_FROM_MAX_LTV), ) } @@ -148,68 +147,235 @@ pub fn get_max_repay_to_bps(max_ltv_bps: u16, liq_threshold_bps: u16) -> u16 { pub fn get_max_boost_to_bps(max_ltv_bps: u16, liq_threshold_bps: u16) -> u16 { min( get_max_repay_to_bps(max_ltv_bps, liq_threshold_bps), - get_max_liq_utilization_rate_bps(max_ltv_bps, liq_threshold_bps, 0.01), + get_max_liq_utilization_rate_bps(max_ltv_bps, liq_threshold_bps, OFFSET_FROM_MAX_LTV), ) } +pub fn derive_value(price: i64, exponent: i32) -> f64 { + if exponent == 0 { + price as f64 + } else if exponent < 0 { + from_base_unit(price, exponent.unsigned_abs()) + } else { + to_base_unit(price, exponent.unsigned_abs()) + } +} + +#[inline(always)] +pub fn calc_fee_amount(value: u64, fee_pct_bps: u16) -> u64 { + (value as f64).mul(from_bps(fee_pct_bps)) as u64 +} + +pub fn round_to_decimals(value: f64, decimals: u32) -> f64 { + let multiplier = (10_f64).powi(decimals as i32); + (value * multiplier).round() / multiplier +} + +pub fn with_conf_interval(price: f64, conf_interval: f64, token_type: TokenType) -> f64 { + let final_conf = f64::min(conf_interval, price.mul(0.05)); + + if token_type == TokenType::Supply { + price - final_conf + } else { + price + final_conf + } +} + +fn apply_debt_adjustment_usd( + debt_adjustment_usd: f64, + pos: &PositionValues, + fees: &RebalanceFeesBps, +) -> PositionValues { + let mut new_pos = pos.clone(); + let is_boost = debt_adjustment_usd > 0.0; + + let da_minus_solauto_fees = + debt_adjustment_usd.sub(debt_adjustment_usd.mul(from_bps(fees.solauto))); + let da_with_flash_loan = debt_adjustment_usd.mul(1.0 + from_bps(fees.flash_loan)); + + if is_boost { + new_pos.supply_usd += da_minus_solauto_fees; + new_pos.debt_usd += + da_with_flash_loan.mul_add(from_bps(fees.lp_borrow), da_with_flash_loan); + } else { + new_pos.supply_usd += da_with_flash_loan; + new_pos.debt_usd += da_minus_solauto_fees; + } + + new_pos +} + +pub fn get_debt_adjustment( + liq_threshold_bps: u16, + pos: &PositionValues, + target_liq_utilization_rate_bps: u16, + fees: &RebalanceFeesBps, +) -> DebtAdjustment { + let liq_threshold = from_bps(liq_threshold_bps); + let is_boost = get_liq_utilization_rate_bps(pos.supply_usd, pos.debt_usd, liq_threshold) + < target_liq_utilization_rate_bps; + + let target_utilization_rate = from_bps(target_liq_utilization_rate_bps); + let actualized_fee = (1.0).sub(from_bps(fees.solauto)); + let fl_fee = from_bps(fees.flash_loan); + let lp_borrow_fee = from_bps(fees.lp_borrow); + + let debt_adjustment_usd = if is_boost { + (target_utilization_rate * liq_threshold * pos.supply_usd - pos.debt_usd) + / ((1.0).add(lp_borrow_fee).add(fl_fee) + - target_utilization_rate * actualized_fee * liq_threshold) + } else { + (target_utilization_rate * liq_threshold * pos.supply_usd - pos.debt_usd) + / (actualized_fee - target_utilization_rate * liq_threshold * (1.0).add(fl_fee)) + }; + + let new_pos = apply_debt_adjustment_usd(debt_adjustment_usd, pos, fees); + + DebtAdjustment { + debt_adjustment_usd, + end_result: new_pos, + } +} + #[cfg(test)] mod tests { use std::ops::Sub; use super::*; - fn round_to_places(value: f64, places: u32) -> f64 { - let multiplier = (10_f64).powi(places as i32); - (value * multiplier).round() / multiplier + const INIT_ASSET_WEIGHT_1: f64 = 0.8; + const MAINT_ASSET_WEIGHT_1: f64 = 0.9; + const INIT_ASSET_WEIGHT_2: f64 = 0.5; + const MAINT_ASSET_WEIGHT_2: f64 = 0.65; + const INIT_LIAB_WEIGHT_1: f64 = 1.25; + const MAINT_LIAB_WEIGHT_1: f64 = 1.1; + + struct AssetWeights { + pub init_asset_weight: f64, + pub init_debt_weight: f64, + pub maint_asset_weight: f64, + pub maint_debt_weight: f64, + } + + impl AssetWeights { + pub fn max_ltv(&self) -> f64 { + self.init_asset_weight.div(self.init_debt_weight) + } + pub fn liq_threshold(&self) -> f64 { + self.maint_asset_weight.div(self.maint_debt_weight) + } + pub fn max_boost_to_bps(&self) -> u16 { + get_max_boost_to_bps(to_bps(self.max_ltv()), to_bps(self.liq_threshold())) + } } fn test_debt_adjustment_calculation( - mut supply_usd: f64, - mut debt_usd: f64, + weights: &AssetWeights, + supply_usd: f64, + debt_usd: f64, target_liq_utilization_rate: f64, ) { - let supply_weight = 0.899999976158142; - let debt_weight = 1.100000023841858; - let liq_threshold = supply_weight.div(debt_weight); // ~0.81 + let AssetWeights { + maint_asset_weight, + maint_debt_weight, + .. + } = weights; + let liq_threshold = weights.liq_threshold(); - let debt_adjustment = get_std_debt_adjustment_usd( + let is_boost = from_bps(get_liq_utilization_rate_bps( + supply_usd, + debt_usd, liq_threshold, + )) < target_liq_utilization_rate; + + let target_liq_utilization_rate_bps = to_bps(target_liq_utilization_rate); + let position = PositionValues { supply_usd, debt_usd, - to_bps(target_liq_utilization_rate), - 0, + }; + let fees = RebalanceFeesBps { + solauto: 50, + lp_borrow: 50, + flash_loan: 50, + }; + let debt_adjustment = get_debt_adjustment( + to_bps(liq_threshold), + &position, + target_liq_utilization_rate_bps, + &fees, ); - supply_usd += debt_adjustment; - debt_usd += debt_adjustment; + let (new_supply_usd, new_debt_usd) = ( + debt_adjustment.end_result.supply_usd, + debt_adjustment.end_result.debt_usd, + ); let new_liq_utilization_rate_bps = - get_liq_utilization_rate_bps(supply_usd, debt_usd, liq_threshold); - assert!( - round_to_places(from_bps(new_liq_utilization_rate_bps), 2) - == round_to_places(target_liq_utilization_rate, 2) - ); + get_liq_utilization_rate_bps(new_supply_usd, new_debt_usd, liq_threshold); let marginfi_liq_utilization_rate = (1.0).sub( - supply_usd - .mul(supply_weight) - .sub(debt_usd.mul(debt_weight)) - .div(supply_usd.mul(supply_weight)), + new_supply_usd + .mul(maint_asset_weight) + .sub(new_debt_usd.mul(maint_debt_weight)) + .div(new_supply_usd.mul(maint_asset_weight)), ); - assert!( - round_to_places(marginfi_liq_utilization_rate, 4) - == round_to_places(target_liq_utilization_rate, 4) + println!( + "Boost: {}. {}, {}, {}", + is_boost, + target_liq_utilization_rate, + from_bps(new_liq_utilization_rate_bps), + marginfi_liq_utilization_rate + ); + + assert_eq!( + round_to_decimals(from_bps(new_liq_utilization_rate_bps), 3), + round_to_decimals(target_liq_utilization_rate, 3) + ); + assert_eq!( + round_to_decimals(marginfi_liq_utilization_rate, 3), + round_to_decimals(target_liq_utilization_rate, 3) ); } + + fn test_debt_adjustment_for_weights(weights: &AssetWeights) { + test_debt_adjustment_calculation(weights, 100.0, 80.0, 0.8); + test_debt_adjustment_calculation(weights, 10.0, 2.0, 0.1); + test_debt_adjustment_calculation(weights, 30.0, 5.0, 0.5); + test_debt_adjustment_calculation(weights, 44334.0, 24534.0, 0.5); + test_debt_adjustment_calculation(weights, 7644.0, 434.0, 0.8); + test_debt_adjustment_calculation(weights, 10444.0, 7454.0, 0.2); + test_debt_adjustment_calculation(weights, 1340444.0, 7454.0, 0.35); + test_debt_adjustment_calculation(weights, 1000000.0, 519999.0, 0.65); + test_debt_adjustment_calculation( + weights, + 3453.0, + 1345.0, + from_bps(weights.max_boost_to_bps()), + ); + } + + #[test] + fn test_weights_1_debt_adjustment() { + test_debt_adjustment_for_weights( + &(AssetWeights { + init_asset_weight: INIT_ASSET_WEIGHT_1, + init_debt_weight: INIT_LIAB_WEIGHT_1, + maint_asset_weight: MAINT_ASSET_WEIGHT_1, + maint_debt_weight: MAINT_LIAB_WEIGHT_1, + }), + ); + } + #[test] - fn test_std_debt_adjustment() { - test_debt_adjustment_calculation(100.0, 80.0, 0.8); - test_debt_adjustment_calculation(30.0, 24.0, 0.5); - test_debt_adjustment_calculation(44334.0, 24534.0, 0.5); - test_debt_adjustment_calculation(7644.0, 434.0, 0.8); - test_debt_adjustment_calculation(10444.0, 7454.0, 0.2); - test_debt_adjustment_calculation(1340444.0, 7454.0, 0.35); - test_debt_adjustment_calculation(1000000.0, 519999.0, 0.65); + fn test_weights_2_debt_adjustment() { + test_debt_adjustment_for_weights( + &(AssetWeights { + init_asset_weight: INIT_ASSET_WEIGHT_2, + init_debt_weight: INIT_LIAB_WEIGHT_1, + maint_asset_weight: MAINT_ASSET_WEIGHT_2, + maint_debt_weight: MAINT_LIAB_WEIGHT_1, + }), + ); } } diff --git a/programs/solauto/src/utils/mod.rs b/programs/solauto/src/utils/mod.rs index 329cb3e5..340e162f 100644 --- a/programs/solauto/src/utils/mod.rs +++ b/programs/solauto/src/utils/mod.rs @@ -1,6 +1,5 @@ pub mod ix_utils; pub mod math_utils; -pub mod rebalance_utils; pub mod solana_utils; pub mod solauto_utils; pub mod validation_utils; diff --git a/programs/solauto/src/utils/rebalance_utils.rs b/programs/solauto/src/utils/rebalance_utils.rs deleted file mode 100644 index 36ae3a8b..00000000 --- a/programs/solauto/src/utils/rebalance_utils.rs +++ /dev/null @@ -1,869 +0,0 @@ -use jupiter_sdk::JUPITER_ID; -use marginfi_sdk::MARGINFI_ID; -use math_utils::from_bps; -use solana_program::{ - instruction::{get_stack_height, TRANSACTION_LEVEL_STACK_HEIGHT}, - msg, - program_error::ProgramError, - pubkey::Pubkey, - sysvar::instructions::load_current_index_checked, -}; -use std::{cmp::max, ops::Mul}; -use validation_utils::validate_debt_adjustment; - -use crate::{ - state::solauto_position::{DCASettings, PositionData, SolautoPosition, SolautoRebalanceType}, - types::{ - instruction::{ - RebalanceSettings, SolautoStandardAccounts, SOLAUTO_REBALANCE_IX_DISCRIMINATORS, - }, - shared::{RebalanceDirection, RebalanceStep, SolautoError, TokenType}, - }, -}; - -use super::*; - -pub struct RebalanceInstructionIndices { - pub jup_swap: usize, - pub marginfi_flash_borrow: Option, -} - -#[inline(always)] -pub fn validate_rebalance_instructions( - std_accounts: &mut Box, - rebalance_type: SolautoRebalanceType, -) -> Result { - let ixs_sysvar = std_accounts.ixs_sysvar.unwrap(); - - let current_ix_idx = load_current_index_checked(ixs_sysvar)?; - if get_stack_height() > TRANSACTION_LEVEL_STACK_HEIGHT { - msg!("Instruction is CPI"); - return Err(SolautoError::InstructionIsCPI.into()); - } - - let solauto_rebalance = ix_utils::InstructionChecker::from( - ixs_sysvar, - crate::ID, - Some(SOLAUTO_REBALANCE_IX_DISCRIMINATORS.to_vec()), - current_ix_idx, - ); - let jup_swap = ix_utils::InstructionChecker::from_anchor( - ixs_sysvar, - JUPITER_ID, - vec![ - "route", - "shared_accounts_route", - "route_with_token_ledger", - "shared_accounts_route_with_token_ledger", - "exact_out_route", - "shared_accounts_exact_out_route", - ], - current_ix_idx, - ); - let marginfi_start_fl = ix_utils::InstructionChecker::from_anchor( - ixs_sysvar, - MARGINFI_ID, - vec!["lending_account_start_flashloan"], - current_ix_idx, - ); - let marginfi_borrow = ix_utils::InstructionChecker::from_anchor( - ixs_sysvar, - MARGINFI_ID, - vec!["lending_account_borrow"], - current_ix_idx, - ); - let marginfi_end_fl = ix_utils::InstructionChecker::from_anchor( - ixs_sysvar, - MARGINFI_ID, - vec!["lending_account_end_flashloan"], - current_ix_idx, - ); - let marginfi_repay = ix_utils::InstructionChecker::from_anchor( - ixs_sysvar, - MARGINFI_ID, - vec!["lending_account_repay"], - current_ix_idx, - ); - - let next_ix = 1; - let ix_2_after = 2; - let ix_3_after = 3; - let ix_4_after = 4; - let prev_ix = -1; - let ix_2_before = -2; - let ix_3_before = -3; - - if (rebalance_type == SolautoRebalanceType::Regular - || rebalance_type == SolautoRebalanceType::None) - && jup_swap.matches(next_ix) - && solauto_rebalance.matches(ix_2_after) - { - std_accounts.solauto_position.data.rebalance.rebalance_type = SolautoRebalanceType::Regular; - Ok(RebalanceInstructionIndices { - jup_swap: ((current_ix_idx as i16) + next_ix) as usize, - marginfi_flash_borrow: None, - }) - } else if (rebalance_type == SolautoRebalanceType::DoubleRebalanceWithFL - || rebalance_type == SolautoRebalanceType::None) - && marginfi_start_fl.matches(ix_2_before) - && marginfi_borrow.matches(prev_ix) - && jup_swap.matches(next_ix) - && solauto_rebalance.matches(ix_2_after) - && marginfi_repay.matches(ix_3_after) - && marginfi_end_fl.matches(ix_4_after) - { - std_accounts.solauto_position.data.rebalance.rebalance_type = - SolautoRebalanceType::DoubleRebalanceWithFL; - Ok(RebalanceInstructionIndices { - jup_swap: ((current_ix_idx as i16) + next_ix) as usize, - marginfi_flash_borrow: Some(((current_ix_idx as i16) + prev_ix) as usize), - }) - } else if (rebalance_type == SolautoRebalanceType::FLSwapThenRebalance - || rebalance_type == SolautoRebalanceType::None) - && marginfi_start_fl.matches(ix_3_before) - && marginfi_borrow.matches(ix_2_before) - && jup_swap.matches(prev_ix) - && marginfi_repay.matches(next_ix) - && marginfi_end_fl.matches(ix_2_after) - { - std_accounts.solauto_position.data.rebalance.rebalance_type = - SolautoRebalanceType::FLSwapThenRebalance; - Ok(RebalanceInstructionIndices { - jup_swap: ((current_ix_idx as i16) + prev_ix) as usize, - marginfi_flash_borrow: Some(((current_ix_idx as i16) + ix_2_before) as usize), - }) - } else if (rebalance_type == SolautoRebalanceType::FLRebalanceThenSwap - || rebalance_type == SolautoRebalanceType::None) - && marginfi_start_fl.matches(ix_2_before) - && marginfi_borrow.matches(prev_ix) - && jup_swap.matches(next_ix) - && marginfi_repay.matches(ix_2_after) - && marginfi_end_fl.matches(ix_3_after) - { - std_accounts.solauto_position.data.rebalance.rebalance_type = - SolautoRebalanceType::FLRebalanceThenSwap; - Ok(RebalanceInstructionIndices { - jup_swap: ((current_ix_idx as i16) + next_ix) as usize, - marginfi_flash_borrow: Some(((current_ix_idx as i16) + prev_ix) as usize), - }) - } else { - msg!("Incorrect rebalance instructions"); - Err(SolautoError::IncorrectInstructions.into()) - } -} - -pub fn get_rebalance_step( - std_accounts: &mut Box, - args: &RebalanceSettings, - position_tas: Vec<&Pubkey>, -) -> Result { - let has_rebalance_data = std_accounts.solauto_position.data.rebalance.active(); - if !has_rebalance_data { - let ix_indices = validate_rebalance_instructions(std_accounts, args.rebalance_type)?; - - // Deserializing jup swap ix to pull slippage bps causes OOM issues, will return to this in the future if there is a solution. - // let (swap_source_ta, price_slippage_bps) = ix_utils::validate_jup_instruction( - // std_accounts.ixs_sysvar.unwrap(), - // ix_indices.jup_swap, - // position_tas.as_slice(), - // )?; - - if ix_indices.marginfi_flash_borrow.is_some() { - std_accounts - .solauto_position - .data - .rebalance - .flash_loan_amount = ix_utils::get_marginfi_flash_loan_amount( - std_accounts.ixs_sysvar.unwrap(), - ix_indices.marginfi_flash_borrow.unwrap(), - None, // &[&swap_source_ta], - )?; - } - } - - let rebalance_step = if !has_rebalance_data - && (std_accounts.solauto_position.data.rebalance.rebalance_type - == SolautoRebalanceType::Regular - || std_accounts.solauto_position.data.rebalance.rebalance_type - == SolautoRebalanceType::DoubleRebalanceWithFL) - { - RebalanceStep::Initial - } else { - RebalanceStep::Final - }; - - Ok(rebalance_step) -} - -#[inline(always)] -fn get_additional_amount_to_dca_in( - position: &mut PositionData, - current_unix_timestamp: u64, -) -> (Option, Option) { - if !position.dca.dca_in() { - return (None, None); - } - - let updated_dca_balance = position.dca.automation.updated_amount_from_automation( - position.dca.dca_in_base_unit, - 0, - current_unix_timestamp, - ); - let amount_to_dca_in = position - .dca - .dca_in_base_unit - .saturating_sub(updated_dca_balance); - - position.dca.dca_in_base_unit = updated_dca_balance; - - (Some(amount_to_dca_in), Some(position.dca.token_type)) -} - -#[inline(always)] -fn get_target_liq_utilization_rate_from_dca( - solauto_position: &mut SolautoPosition, - current_unix_timestamp: u64, -) -> Result { - let curr_liq_utilization_rate_bps = solauto_position.state.liq_utilization_rate_bps; - let position = &mut solauto_position.position; - - let target_rate_bps = { - if position.dca.dca_in() { - max( - curr_liq_utilization_rate_bps, - position.setting_params.boost_to_bps, - ) - } else { - position.setting_params.boost_to_bps - } - }; - - let new_periods_passed = position - .dca - .automation - .new_periods_passed(current_unix_timestamp); - if new_periods_passed == position.dca.automation.target_periods { - position.dca = DCASettings::default(); - } else { - position.dca.automation.periods_passed = new_periods_passed; - } - - Ok(target_rate_bps) -} - -#[inline(always)] -fn get_std_target_liq_utilization_rate( - solauto_position: &SolautoPosition, -) -> Result { - let setting_params = solauto_position.position.setting_params.clone(); - - let target_rate_bps: Result = - if solauto_position.state.liq_utilization_rate_bps >= setting_params.repay_from_bps() { - Ok(setting_params.repay_to_bps) - } else if solauto_position.state.liq_utilization_rate_bps <= setting_params.boost_from_bps() - { - Ok(setting_params.boost_to_bps) - } else { - msg!( - "Invalid rebalance condition. Current utilizatiion rate is: {}", - solauto_position.state.liq_utilization_rate_bps - ); - return Err(SolautoError::InvalidRebalanceCondition.into()); - }; - - Ok(target_rate_bps.unwrap()) -} - -#[inline(always)] -fn is_dca_instruction( - solauto_position: &SolautoPosition, - current_unix_timestamp: u64, -) -> Result { - let position_data = &solauto_position.position; - - if solauto_position.state.liq_utilization_rate_bps - >= position_data.setting_params.repay_from_bps() - { - return Ok(false); - } - - if !position_data.dca.is_active() { - return Ok(false); - } - - if !position_data - .dca - .automation - .eligible_for_next_period(current_unix_timestamp) - { - if solauto_position.state.liq_utilization_rate_bps - <= position_data.setting_params.boost_from_bps() - { - return Ok(false); - } else { - msg!("DCA rebalance was initiated too early"); - return Err(SolautoError::InvalidRebalanceCondition.into()); - } - } - - Ok(true) -} - -#[inline(always)] -fn get_target_rate_and_dca_amount( - solauto_position: &mut SolautoPosition, - rebalance_args: &RebalanceSettings, - current_unix_timestamp: u64, -) -> Result<(u16, Option, Option), ProgramError> { - if rebalance_args.target_liq_utilization_rate_bps.is_some() { - return Ok(( - rebalance_args.target_liq_utilization_rate_bps.unwrap(), - None, - None, - )); - } - - let dca_instruction = is_dca_instruction(solauto_position, current_unix_timestamp)?; - - let (target_liq_utilization_rate_bps, amount_to_dca_in, dca_token_type) = match dca_instruction - { - true => { - let target_liq_utilization_rate_bps = - get_target_liq_utilization_rate_from_dca(solauto_position, current_unix_timestamp)?; - let (amount_to_dca_in, dca_token_type) = get_additional_amount_to_dca_in( - &mut solauto_position.position, - current_unix_timestamp, - ); - - ( - target_liq_utilization_rate_bps, - amount_to_dca_in, - dca_token_type, - ) - } - false => ( - get_std_target_liq_utilization_rate(solauto_position)?, - None, - None, - ), - }; - - Ok(( - target_liq_utilization_rate_bps, - amount_to_dca_in, - dca_token_type, - )) -} - -pub fn get_rebalance_values( - solauto_position: &mut SolautoPosition, - args: &RebalanceSettings, - solauto_fees_bps: &solauto_utils::SolautoFeesBps, - current_unix_timestamp: u64, -) -> Result<(f64, Option), ProgramError> { - let (target_liq_utilization_rate_bps, amount_to_dca_in, dca_token_type) = - get_target_rate_and_dca_amount(solauto_position, args, current_unix_timestamp)?; - - solauto_position.rebalance.rebalance_direction = if amount_to_dca_in.is_some() - || solauto_position.state.liq_utilization_rate_bps <= target_liq_utilization_rate_bps - { - RebalanceDirection::Boost - } else { - RebalanceDirection::Repay - }; - let fees_bps = solauto_fees_bps.fetch_fees(solauto_position.rebalance.rebalance_direction); - - let amount_to_dca_in_usd = if amount_to_dca_in.is_some() { - let (decimals, market_price) = if dca_token_type.unwrap() == TokenType::Supply { - ( - solauto_position.state.supply.decimals, - solauto_position.state.supply.market_price(), - ) - } else { - ( - solauto_position.state.debt.decimals, - solauto_position.state.debt.market_price(), - ) - }; - - math_utils::from_base_unit::(amount_to_dca_in.unwrap(), decimals) - .mul(market_price) - } else { - 0.0 - }; - - let total_supply_usd = - solauto_position.state.supply.amount_used.usd_value() + amount_to_dca_in_usd; - - let debt_adjustment_usd = math_utils::get_std_debt_adjustment_usd( - from_bps(solauto_position.state.liq_threshold_bps), - total_supply_usd, - solauto_position.state.debt.amount_used.usd_value(), - target_liq_utilization_rate_bps, - fees_bps.total, - ); - - if args.target_in_amount_base_unit.is_some() { - validate_debt_adjustment( - solauto_position, - args.target_in_amount_base_unit.unwrap(), - debt_adjustment_usd, - None - )?; - } - - Ok((debt_adjustment_usd, amount_to_dca_in)) -} - -#[cfg(test)] -mod tests { - use solana_program::pubkey::Pubkey; - use std::ops::{Add, Div, Sub}; - use tests::math_utils::{from_base_unit, to_base_unit}; - - use crate::{ - state::solauto_position::{ - AutomationSettingsInp, DCASettings, DCASettingsInp, PositionState, PositionTokenUsage, - RebalanceData, SolautoSettingsParameters, - }, - types::shared::{PositionType, TokenType}, - utils::math_utils, - }; - - use super::*; - - const BOOST_TO_BPS: u16 = 5000; - const REPAY_TO_BPS: u16 = 7500; - - fn assert_bps_within_margin_of_error(result_bps: u16, expected_bps: u16) { - println!("{}, {}", result_bps, expected_bps); - assert!(result_bps >= expected_bps.saturating_sub(1) && result_bps <= expected_bps + 1); - } - - // CHANGING THESE WILL BREAK TESTS - fn default_setting_params() -> SolautoSettingsParameters { - let mut settings = SolautoSettingsParameters::default(); - settings.boost_to_bps = BOOST_TO_BPS; - settings.boost_gap = 1000; - settings.repay_to_bps = REPAY_TO_BPS; - settings.repay_gap = 500; - settings - } - - fn standard_solauto_position( - setting_params: SolautoSettingsParameters, - active_dca: Option, - current_liq_utilization_rate_bps: u16, - ) -> SolautoPosition { - let mut data = PositionData::default(); - data.setting_params = setting_params; - - data.dca = if active_dca.is_some() { - active_dca.unwrap() - } else { - DCASettings::default() - }; - - let mut position = SolautoPosition::new( - 1, - Pubkey::default(), - PositionType::default(), - data, - PositionState::default(), - ); - - position.state.liq_threshold_bps = 8000; - position.state.max_ltv_bps = 6500; - position.state.liq_utilization_rate_bps = current_liq_utilization_rate_bps; - - let supply_market_price = 100.0; - let supply_amount = 1000.0; - position.state.supply = create_token_usage( - supply_market_price, - 6, - supply_amount.mul(supply_market_price), - ); - - let debt_usd = supply_amount - .mul(supply_market_price) - .mul(from_bps(position.state.liq_threshold_bps)) - .mul(from_bps(current_liq_utilization_rate_bps)); - position.state.debt = create_token_usage(1.0, 6, debt_usd); - - position.rebalance = RebalanceData::default(); - - position - } - - fn create_token_usage( - market_price: f64, - decimals: u8, - amount_used_usd: f64, - ) -> PositionTokenUsage { - let mut token_usage = PositionTokenUsage::default(); - token_usage.decimals = decimals; - token_usage.amount_used.base_unit = - to_base_unit::(amount_used_usd.div(market_price), decimals); - token_usage.update_market_price(market_price); - token_usage - } - - fn test_rebalance( - current_timestamp: Option, - current_liq_utilization_rate_bps: u16, - setting_params: Option, - dca_settings: Option, - mut rebalance_args: Option, - ) -> Result<(SolautoPosition, f64, Option), ProgramError> { - let settings = setting_params.map_or_else(|| default_setting_params(), |settings| settings); - let mut solauto_position = standard_solauto_position( - settings.clone(), - dca_settings.clone(), - current_liq_utilization_rate_bps, - ); - - if rebalance_args.is_none() { - rebalance_args = Some(RebalanceSettings::default()); - } - - let solauto_fees = solauto_utils::SolautoFeesBps::from( - false, - rebalance_args - .clone() - .map_or(None, |args| args.target_liq_utilization_rate_bps), - solauto_position.state.net_worth.usd_value(), - ); - - let (debt_adjustment_usd, amount_to_dca_in) = get_rebalance_values( - &mut solauto_position, - rebalance_args.as_ref().unwrap(), - &solauto_fees, - current_timestamp.map_or_else(|| 0, |timestamp| timestamp), - )?; - - Ok((solauto_position, debt_adjustment_usd, amount_to_dca_in)) - } - - fn rebalance_with_std_validation( - current_timestamp: Option, - current_liq_utilization_rate_bps: u16, - mut expected_liq_utilization_rate_bps: u16, - setting_params: Option, - dca_settings: Option, - rebalance_args: Option, - ) -> Result { - let (mut solauto_position, debt_adjustment_usd, amount_to_dca_in) = test_rebalance( - current_timestamp, - current_liq_utilization_rate_bps, - setting_params, - dca_settings.clone(), - rebalance_args.clone(), - )?; - - let boosting = amount_to_dca_in.is_some() - || current_liq_utilization_rate_bps <= expected_liq_utilization_rate_bps; - if boosting { - expected_liq_utilization_rate_bps = max( - expected_liq_utilization_rate_bps, - current_liq_utilization_rate_bps, - ); - } - let rebalance_direction = if boosting { - RebalanceDirection::Boost - } else { - RebalanceDirection::Repay - }; - - let adjustment_fee_bps = solauto_utils::SolautoFeesBps::from( - false, - rebalance_args.map_or(None, |args| args.target_liq_utilization_rate_bps), - solauto_position.state.net_worth.usd_value(), - ) - .fetch_fees(rebalance_direction) - .total; - - let amount_to_dca_in_usd = if amount_to_dca_in.is_some() { - if dca_settings.as_ref().unwrap().token_type == TokenType::Supply { - from_base_unit::( - amount_to_dca_in.unwrap(), - solauto_position.state.supply.decimals, - ) - .mul(solauto_position.state.supply.market_price()) - } else { - from_base_unit::( - amount_to_dca_in.unwrap(), - solauto_position.state.debt.decimals, - ) - .mul(solauto_position.state.debt.market_price()) - } - } else { - 0.0 - }; - - let expected_debt_adjustment_usd = math_utils::get_std_debt_adjustment_usd( - from_bps(solauto_position.state.liq_threshold_bps), - solauto_position.state.supply.amount_used.usd_value() + amount_to_dca_in_usd, - solauto_position.state.debt.amount_used.usd_value(), - expected_liq_utilization_rate_bps, - adjustment_fee_bps, - ); - println!("{}, {}", debt_adjustment_usd, expected_debt_adjustment_usd); - assert!(debt_adjustment_usd == expected_debt_adjustment_usd); - - // Factor into account the adjustment fee - let mut supply_adjustment = (expected_debt_adjustment_usd + amount_to_dca_in_usd) - .sub(expected_debt_adjustment_usd.mul(from_bps(adjustment_fee_bps))); - if dca_settings.is_some() && dca_settings.as_ref().unwrap().token_type == TokenType::Debt { - supply_adjustment -= amount_to_dca_in_usd.mul(from_bps(adjustment_fee_bps)); - } - let supply_adjustment = supply_adjustment.div(solauto_position.state.supply.market_price()); - - solauto_position.update_usage( - TokenType::Supply, - to_base_unit::(supply_adjustment, solauto_position.state.supply.decimals), - ); - - let debt_adjustment = - expected_debt_adjustment_usd.div(solauto_position.state.debt.market_price()); - solauto_position.update_usage( - TokenType::Debt, - to_base_unit::(debt_adjustment, solauto_position.state.debt.decimals), - ); - - assert_bps_within_margin_of_error( - solauto_position.state.liq_utilization_rate_bps, - expected_liq_utilization_rate_bps, - ); - - Ok(solauto_position) - } - - #[test] - fn test_invalid_rebalance_condition() { - let result = test_rebalance(None, 6250, None, None, None); - assert!(result.is_err()); - assert!(result.unwrap_err() == SolautoError::InvalidRebalanceCondition.into()); - - let result = test_rebalance(None, 4001, None, None, None); - assert!(result.is_err()); - assert!(result.unwrap_err() == SolautoError::InvalidRebalanceCondition.into()); - - let result = test_rebalance(None, 7999, None, None, None); - assert!(result.is_err()); - assert!(result.unwrap_err() == SolautoError::InvalidRebalanceCondition.into()); - } - - #[test] - fn test_repay() { - rebalance_with_std_validation(None, REPAY_TO_BPS + 534, REPAY_TO_BPS, None, None, None) - .unwrap(); - rebalance_with_std_validation(None, REPAY_TO_BPS + 1003, REPAY_TO_BPS, None, None, None) - .unwrap(); - rebalance_with_std_validation(None, REPAY_TO_BPS + 1743, REPAY_TO_BPS, None, None, None) - .unwrap(); - } - - #[test] - fn test_boost() { - rebalance_with_std_validation(None, BOOST_TO_BPS - 3657, BOOST_TO_BPS, None, None, None) - .unwrap(); - rebalance_with_std_validation(None, BOOST_TO_BPS - 2768, BOOST_TO_BPS, None, None, None) - .unwrap(); - rebalance_with_std_validation(None, BOOST_TO_BPS - 1047, BOOST_TO_BPS, None, None, None) - .unwrap(); - } - - #[test] - fn test_authority_rebalance() { - let target_liq_utilization_rate_bps = BOOST_TO_BPS + (REPAY_TO_BPS - BOOST_TO_BPS) / 2; - rebalance_with_std_validation( - None, - BOOST_TO_BPS - 3657, - target_liq_utilization_rate_bps, - None, - None, - Some(RebalanceSettings { - rebalance_type: SolautoRebalanceType::Regular, - target_liq_utilization_rate_bps: Some(target_liq_utilization_rate_bps), - target_in_amount_base_unit: None, - }), - ) - .unwrap(); - } - - fn test_dca_rebalance_with_std_validation( - current_timestamp: Option, - current_liq_utilization_rate_bps: u16, - dca_settings: DCASettings, - setting_params: Option, - ) -> Result { - let settings = - Some(setting_params.map_or_else(|| default_setting_params(), |settings| settings)); - - let expected_liq_utilization_rate_bps = if dca_settings.dca_in() { - max( - current_liq_utilization_rate_bps, - settings.as_ref().unwrap().boost_to_bps, - ) - } else { - settings.as_ref().unwrap().boost_to_bps - }; - - let timestamp = current_timestamp.map_or_else( - || { - dca_settings.automation.unix_start_date.add( - dca_settings - .automation - .interval_seconds - .mul(dca_settings.automation.periods_passed as u64), - ) - }, - |timestamp| timestamp, - ); - let solauto_position = rebalance_with_std_validation( - Some(timestamp), - current_liq_utilization_rate_bps, - expected_liq_utilization_rate_bps, - settings.clone(), - Some(dca_settings.clone()), - None, - )?; - - let new_periods_passed = dca_settings.automation.new_periods_passed(timestamp); - if new_periods_passed == dca_settings.automation.target_periods { - assert!( - !solauto_position.position.dca.is_active(), - "DCA is still active when it shouldn't be" - ); - } else { - assert!( - solauto_position.position.dca.automation.periods_passed == new_periods_passed, - "periods_passed != new_periods_passed" - ); - } - - Ok(solauto_position) - } - - #[test] - fn test_invalid_dca_condition() { - let result = test_dca_rebalance_with_std_validation( - Some(9), - BOOST_TO_BPS + 500, - DCASettings::from(DCASettingsInp { - automation: AutomationSettingsInp { - target_periods: 4, - periods_passed: 2, - unix_start_date: 0, - interval_seconds: 5, - }, - dca_in_base_unit: 0, - token_type: TokenType::Supply, - }), - None, - ); - assert!( - result.is_err() - && result.unwrap_err() == SolautoError::InvalidRebalanceCondition.into() - ); - } - - #[test] - fn test_dca_in() { - let dca_in_base_unit: u64 = 10000000; - - // curr_liq_utilization_rate_bps > setting_params.boost_to_bps - test_dca_rebalance_with_std_validation( - None, - BOOST_TO_BPS + 1000, - DCASettings::from(DCASettingsInp { - automation: AutomationSettingsInp { - target_periods: 10, - periods_passed: 4, - unix_start_date: 0, - interval_seconds: 5, - }, - dca_in_base_unit, - token_type: TokenType::Debt, - }), - None, - ) - .unwrap(); - - // curr_liq_utilization_rate_bps < setting_params.boost_to_bps - test_dca_rebalance_with_std_validation( - None, - BOOST_TO_BPS - 1000, - DCASettings::from(DCASettingsInp { - automation: AutomationSettingsInp { - target_periods: 10, - periods_passed: 4, - unix_start_date: 0, - interval_seconds: 5, - }, - dca_in_base_unit, - token_type: TokenType::Debt, - }), - None, - ) - .unwrap(); - - // curr_liq_utilization_rate_bps == setting_params.boost_to_bps - // last dca period - test_dca_rebalance_with_std_validation( - None, - BOOST_TO_BPS, - DCASettings::from(DCASettingsInp { - automation: AutomationSettingsInp { - target_periods: 10, - periods_passed: 9, - unix_start_date: 0, - interval_seconds: 5, - }, - dca_in_base_unit, - token_type: TokenType::Debt, - }), - None, - ) - .unwrap(); - } - - #[test] - fn test_dca_out() { - // curr_liq_utilization_rate_bps > setting_params.boost_to_bps - test_dca_rebalance_with_std_validation( - None, - BOOST_TO_BPS + 1000, - DCASettings::from(DCASettingsInp { - automation: AutomationSettingsInp { - target_periods: 5, - periods_passed: 3, - unix_start_date: 0, - interval_seconds: 5, - }, - dca_in_base_unit: 0, - token_type: TokenType::Supply, - }), - None, - ) - .unwrap(); - - // curr_liq_utilization_rate_bps < setting_params.boost_to_bps - test_dca_rebalance_with_std_validation( - None, - BOOST_TO_BPS - 1000, - DCASettings::from(DCASettingsInp { - automation: AutomationSettingsInp { - target_periods: 5, - periods_passed: 3, - unix_start_date: 0, - interval_seconds: 5, - }, - dca_in_base_unit: 0, - token_type: TokenType::Supply, - }), - None, - ) - .unwrap(); - } -} diff --git a/programs/solauto/src/utils/solana_utils.rs b/programs/solauto/src/utils/solana_utils.rs index 3fb7aa15..3c4cc00c 100644 --- a/programs/solauto/src/utils/solana_utils.rs +++ b/programs/solauto/src/utils/solana_utils.rs @@ -2,19 +2,20 @@ use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, instruction::Instruction, - msg, program::{invoke, invoke_signed}, pubkey::Pubkey, rent::Rent, system_instruction, sysvar::Sysvar, }; -use spl_associated_token_account::{ - get_associated_token_address, instruction::create_associated_token_account, -}; +use spl_associated_token_account::instruction::create_associated_token_account; use spl_token::instruction as spl_instruction; -use crate::types::shared::SolautoError; +use crate::{ + check, + types::{errors::SolautoError, shared::SplTokenTransferArgs}, + utils::validation_utils::correct_token_account, +}; pub fn account_has_data(account: &AccountInfo) -> bool { !account.data.borrow().is_empty() @@ -40,10 +41,7 @@ pub fn init_account<'a>( account_seed: Option>, space: usize, ) -> ProgramResult { - if account_has_data(account) { - msg!("{} has already been created", account.key); - return Err(SolautoError::IncorrectAccounts.into()); - } + check!(!account_has_data(account), SolautoError::IncorrectAccounts); let rent = &Rent::from_account_info(rent_sysvar)?; let required_lamports = rent @@ -78,15 +76,10 @@ pub fn init_ata_if_needed<'a, 'b>( token_account: &'a AccountInfo<'a>, token_mint: &'a AccountInfo<'a>, ) -> ProgramResult { - if &get_associated_token_address(wallet.key, token_mint.key) != token_account.key { - msg!( - "Token account {} is not correct for the given token mint ({}) & wallet ({})", - token_account.key, - token_mint.key, - wallet.key - ); - return Err(SolautoError::IncorrectAccounts.into()); - } + check!( + correct_token_account(token_account.key, wallet.key, token_mint.key), + SolautoError::IncorrectAccounts + ); if account_has_data(token_account) { return Ok(()); @@ -118,25 +111,25 @@ pub fn system_transfer<'a>( ) } -pub fn spl_token_transfer<'a>( +pub fn spl_token_transfer<'a, 'b>( token_program: &'a AccountInfo<'a>, - source: &'a AccountInfo<'a>, - authority: &'a AccountInfo<'a>, - recipient: &'a AccountInfo<'a>, - amount: u64, - authority_seeds: Option<&Vec<&[u8]>>, + args: SplTokenTransferArgs<'a, 'b>, ) -> ProgramResult { invoke_instruction( &spl_instruction::transfer( token_program.key, - source.key, - recipient.key, - authority.key, + args.source.key, + args.recipient.key, + args.authority.key, &[], - amount, + args.amount, )?, - &[source.clone(), recipient.clone(), authority.clone()], - authority_seeds, + &[ + args.source.clone(), + args.recipient.clone(), + args.authority.clone(), + ], + args.authority_seeds, ) } diff --git a/programs/solauto/src/utils/solauto_utils.rs b/programs/solauto/src/utils/solauto_utils.rs index 3df6a523..a9319718 100644 --- a/programs/solauto/src/utils/solauto_utils.rs +++ b/programs/solauto/src/utils/solauto_utils.rs @@ -1,28 +1,27 @@ use solana_program::{ - account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, - program_error::ProgramError, program_pack::Pack, pubkey::Pubkey, sysvar::Sysvar, + account_info::AccountInfo, clock::Clock, program_error::ProgramError, pubkey::Pubkey, + sysvar::Sysvar, }; -use spl_associated_token_account::get_associated_token_address; use spl_token::state::{Account as TokenAccount, Mint}; -use std::ops::Mul; use super::{ math_utils::to_bps, - solana_utils::{account_has_data, init_account, init_ata_if_needed, spl_token_transfer}, + solana_utils::{account_has_data, init_account}, }; use crate::{ + check, constants::WSOL_MINT, state::{ referral_state::ReferralState, solauto_position::{ - DCASettings, PositionData, PositionState, SolautoPosition, SolautoSettingsParameters, + PositionData, PositionState, PositionTokenState, SolautoPosition, + SolautoSettingsParameters, }, }, types::{ + errors::SolautoError, instruction::UpdatePositionData, - shared::{ - DeserializedAccount, LendingPlatform, PositionType, RebalanceDirection, SolautoError, - }, + shared::{DeserializedAccount, LendingPlatform, PositionType, RefreshedTokenState}, }, }; @@ -44,23 +43,24 @@ pub fn create_new_solauto_position<'a>( update_position_data: UpdatePositionData, lending_platform: LendingPlatform, supply_mint: &'a AccountInfo<'a>, - protocol_supply_account: &'a AccountInfo<'a>, + lp_supply_account: &'a AccountInfo<'a>, debt_mint: &'a AccountInfo<'a>, - protocol_debt_account: &'a AccountInfo<'a>, - protocol_user_account: &'a AccountInfo<'a>, + lp_debt_account: &'a AccountInfo<'a>, + lp_user_account: &'a AccountInfo<'a>, + lp_pool_account: &'a AccountInfo<'a>, max_ltv: f64, liq_threshold: f64, ) -> Result, ProgramError> { - if account_has_data(solauto_position) { - msg!("Cannot open new position on an existing Solauto position"); - return Err(SolautoError::IncorrectAccounts.into()); - } + check!( + !account_has_data(solauto_position), + SolautoError::IncorrectAccounts + ); - let data = if update_position_data.setting_params.is_some() { - if update_position_data.position_id == 0 { - msg!("Position ID 0 is reserved for self-managed positions"); - return Err(ProgramError::InvalidInstructionData.into()); - } + let data = if update_position_data.settings.is_some() { + check!( + update_position_data.position_id > 0, + SolautoError::IncorrectInstructions + ); let supply = DeserializedAccount::::unpack(Some(supply_mint))?.unwrap(); let debt = DeserializedAccount::::unpack(Some(debt_mint))?.unwrap(); @@ -71,19 +71,16 @@ pub fn create_new_solauto_position<'a>( state.debt.decimals = debt.data.decimals; state.max_ltv_bps = to_bps(max_ltv); state.liq_threshold_bps = to_bps(liq_threshold); - state.last_updated = Clock::get()?.unix_timestamp as u64; + state.last_refreshed = Clock::get()?.unix_timestamp as u64; let mut position_data = PositionData::default(); position_data.lending_platform = lending_platform; - position_data.setting_params = - SolautoSettingsParameters::from(*update_position_data.setting_params.as_ref().unwrap()); - position_data.protocol_user_account = *protocol_user_account.key; - position_data.protocol_supply_account = *protocol_supply_account.key; - position_data.protocol_debt_account = *protocol_debt_account.key; - - if update_position_data.dca.is_some() { - position_data.dca = DCASettings::from(*update_position_data.dca.as_ref().unwrap()); - } + position_data.settings = + SolautoSettingsParameters::from(*update_position_data.settings.as_ref().unwrap()); + position_data.lp_user_account = *lp_user_account.key; + position_data.lp_supply_account = *lp_supply_account.key; + position_data.lp_debt_account = *lp_debt_account.key; + position_data.lp_pool_account = *lp_pool_account.key; Box::new(SolautoPosition::new( update_position_data.position_id, @@ -178,183 +175,20 @@ pub fn create_or_update_referral_state<'a>( referral_state_account.data.seeds_with_bump().as_slice(), &crate::ID, )?; - if referral_state.key != &expected_referral_state_address { - msg!("Invalid referral position account given for the provided authority"); - return Err(SolautoError::IncorrectAccounts.into()); - } + check!( + referral_state.key == &expected_referral_state_address, + SolautoError::IncorrectAccounts + ); Ok(referral_state_account) } -pub fn initiate_dca_in_if_necessary<'a, 'b>( - token_program: &'a AccountInfo<'a>, - solauto_position: &'b mut DeserializedAccount<'a, SolautoPosition>, - position_debt_ta: Option<&'a AccountInfo<'a>>, - signer: &'a AccountInfo<'a>, - signer_dca_ta: Option<&'a AccountInfo<'a>>, -) -> ProgramResult { - if solauto_position.data.self_managed.val { - return Ok(()); - } - - let position = &mut solauto_position.data.position; - if !position.dca.is_active() { - return Ok(()); - } - - if !position.dca.dca_in() { - return Ok(()); - } - - if position_debt_ta.is_none() || signer_dca_ta.is_none() { - msg!("Missing required accounts in order to initiate DCA-in"); - return Err(SolautoError::IncorrectAccounts.into()); - } - - if position_debt_ta.unwrap().key - != &get_associated_token_address( - solauto_position.account_info.key, - &solauto_position.data.state.debt.mint, - ) - { - msg!("Incorrect position token account provided"); - return Err(SolautoError::IncorrectAccounts.into()); - } - - let signer_token_account = TokenAccount::unpack(&signer_dca_ta.unwrap().data.borrow())?; - let balance = signer_token_account.amount; - - if position.dca.dca_in_base_unit > balance { - msg!("Provided greater DCA-in value than exists in the signer debt token account"); - return Err(ProgramError::InvalidInstructionData.into()); - } - - spl_token_transfer( - token_program, - signer_dca_ta.unwrap(), - signer, - position_debt_ta.unwrap(), - position.dca.dca_in_base_unit, - None, - )?; - - Ok(()) -} - -pub fn cancel_dca_in<'a, 'b>( - signer: &'a AccountInfo<'a>, - system_program: &'a AccountInfo<'a>, - token_program: &'a AccountInfo<'a>, - solauto_position: &'b mut DeserializedAccount<'a, SolautoPosition>, - dca_mint: Option<&'a AccountInfo<'a>>, - position_dca_ta: Option<&'a AccountInfo<'a>>, - signer_dca_ta: Option<&'a AccountInfo<'a>>, -) -> ProgramResult { - let active_dca = &solauto_position.data.position.dca; - - if active_dca.dca_in() { - if dca_mint.is_none() || position_dca_ta.is_none() || signer_dca_ta.is_none() { - msg!( - "Requires dca_mint, position_dca_ta & signer_dca_ta in order to cancel the active DCA-in" - ); - return Err(SolautoError::IncorrectAccounts.into()); - } - - let dca_ta_current_balance = - TokenAccount::unpack(&position_dca_ta.unwrap().data.borrow())?.amount; - if dca_ta_current_balance == 0 { - return Ok(()); - } - - init_ata_if_needed( - token_program, - system_program, - signer, - signer, - signer_dca_ta.unwrap(), - dca_mint.unwrap(), - )?; - - spl_token_transfer( - token_program, - position_dca_ta.unwrap(), - solauto_position.account_info, - signer_dca_ta.unwrap(), - dca_ta_current_balance, - Some(&solauto_position.data.seeds_with_bump()), - )?; - } - - solauto_position.data.position.dca = DCASettings::default(); - Ok(()) -} - -pub struct FeePayout { - pub solauto: u16, - pub referrer: u16, - pub total: u16, -} -pub struct SolautoFeesBps { - has_been_referred: bool, - target_liq_utilization_rate_bps: Option, - position_net_worth_usd: f64, -} -impl SolautoFeesBps { - pub fn from( - has_been_referred: bool, - target_liq_utilization_rate_bps: Option, - position_net_worth_usd: f64, - ) -> Self { - Self { - has_been_referred, - target_liq_utilization_rate_bps, - position_net_worth_usd, - } - } - pub fn fetch_fees(&self, rebalance_direction: RebalanceDirection) -> FeePayout { - let min_size: f64 = 10000.0; // Minimum position size - let max_size: f64 = 250000.0; // Maximum position size - let max_fee_bps: f64 = 50.0; // Fee in basis points for min_size (0.5%) - let min_fee_bps: f64 = 25.0; // Fee in basis points for max_size (0.25%) - let k = 1.5; - - let mut fee_bps: f64; - if self.target_liq_utilization_rate_bps.is_some() - && self.target_liq_utilization_rate_bps.unwrap() == 0 - { - return FeePayout { - solauto: 0, - referrer: 0, - total: 0, - }; - } - - if self.target_liq_utilization_rate_bps.is_some() - || rebalance_direction == RebalanceDirection::Repay - { - fee_bps = 25.0; - } else if self.position_net_worth_usd <= min_size { - fee_bps = max_fee_bps; - } else if self.position_net_worth_usd >= max_size { - fee_bps = min_fee_bps; - } else { - let t = (self.position_net_worth_usd.ln() - min_size.ln()) - / (max_size.ln() - min_size.ln()); - fee_bps = (min_fee_bps + (max_fee_bps - min_fee_bps) * (1.0 - t.powf(k))).round(); - } - - let mut referrer_fee = 0.0; - if self.has_been_referred { - fee_bps = fee_bps * 0.9; - referrer_fee = fee_bps.mul(0.15).floor() - }; - - FeePayout { - solauto: (fee_bps - referrer_fee) as u16, - referrer: referrer_fee as u16, - total: fee_bps as u16, - } - } +pub fn update_token_state(token_state: &mut PositionTokenState, token_data: &RefreshedTokenState) { + token_state.decimals = token_data.decimals; + token_state.amount_used.base_unit = token_data.amount_used; + token_state.amount_can_be_used.base_unit = token_data.amount_can_be_used; + token_state.update_market_price(token_data.market_price); + token_state.borrow_fee_bps = token_data.borrow_fee_bps.unwrap_or(0); } pub fn safe_unpack_token_account<'a>( diff --git a/programs/solauto/src/utils/validation_utils.rs b/programs/solauto/src/utils/validation_utils.rs index 5ad0fd8c..84c9c861 100644 --- a/programs/solauto/src/utils/validation_utils.rs +++ b/programs/solauto/src/utils/validation_utils.rs @@ -1,6 +1,6 @@ -use std::ops::{ Div, Mul }; +use std::ops::Div; -use marginfi_sdk::{ generated::accounts::{ Bank, MarginfiAccount }, MARGINFI_ID }; +use marginfi_sdk::generated::accounts::{Bank, MarginfiAccount}; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, @@ -8,35 +8,32 @@ use solana_program::{ program_error::ProgramError, pubkey::Pubkey, system_program::ID as system_program_id, - sysvar::{ instructions::ID as ixs_sysvar_id, rent::ID as rent_program_id }, + sysvar::{instructions::ID as ixs_sysvar_id, rent::ID as rent_program_id}, }; -use spl_associated_token_account::{ get_associated_token_address, ID as ata_program_id }; +use spl_associated_token_account::{get_associated_token_address, ID as ata_program_id}; use spl_token::ID as token_program_id; use crate::{ - constants::{ MAX_BASIS_POINTS, MIN_BOOST_GAP_BPS, MIN_REPAY_GAP_BPS, SOLAUTO_MANAGER }, + check, + constants::{ + MARGINFI_PROD_PROGRAM, MARGINFI_STAGING_PROGRAM, MIN_BOOST_GAP_BPS, MIN_REPAY_GAP_BPS, + SOLAUTO_MANAGER, + }, + error_if, state::{ - referral_state::ReferralState, - solauto_position::{ - AutomationSettings, - PositionData, - SolautoPosition, - SolautoRebalanceType, - }, + automation::AutomationSettings, referral_state::ReferralState, + solauto_position::SolautoPosition, }, types::{ + errors::SolautoError, instruction::SolautoStandardAccounts, - shared::{ DeserializedAccount, LendingPlatform, SolautoError, TokenType }, + shared::{DeserializedAccount, LendingPlatform, TokenType}, }, + utils::math_utils::from_rounded_usd_value, }; use super::{ - math_utils::{ - from_base_unit, - get_max_boost_to_bps, - get_max_repay_from_bps, - get_max_repay_to_bps, - }, + math_utils::{get_max_boost_to_bps, get_max_repay_from_bps, get_max_repay_to_bps}, solauto_utils::safe_unpack_token_account, }; @@ -44,21 +41,21 @@ pub fn generic_instruction_validation( accounts: &Box, lending_platform: LendingPlatform, authority_signer_only_ix: bool, - solauto_managed_only_ix: bool + solauto_managed_only_ix: bool, ) -> ProgramResult { validate_instruction( accounts.signer, &accounts.solauto_position, authority_signer_only_ix, - solauto_managed_only_ix + solauto_managed_only_ix, )?; validate_lending_program_account(accounts.lending_protocol, lending_platform)?; - validate_sysvar_accounts( + validate_standard_programs( Some(accounts.system_program), Some(accounts.token_program), accounts.ata_program, accounts.rent, - accounts.ixs_sysvar + accounts.ixs_sysvar, )?; if accounts.authority_referral_state.is_some() { @@ -66,7 +63,7 @@ pub fn generic_instruction_validation( &accounts.solauto_position.data.authority, accounts.authority_referral_state.as_ref().unwrap(), accounts.referred_by_ta, - true + true, )?; } @@ -78,19 +75,17 @@ pub fn validate_instruction( signer: &AccountInfo, solauto_position: &DeserializedAccount, authority_signer_only_ix: bool, - solauto_managed_only_ix: bool + solauto_managed_only_ix: bool, ) -> ProgramResult { - if !signer.is_signer { - msg!("Signer account is not a signer"); - return Err(ProgramError::MissingRequiredSignature.into()); - } + check!(&signer.is_signer, ProgramError::MissingRequiredSignature); let position_authority = solauto_position.data.authority; let authority_signed = || { let expected_solauto_position_address = Pubkey::create_program_address( solauto_position.data.seeds_with_bump().as_slice(), - &crate::ID - ).expect("Ok"); + &crate::ID, + ) + .expect("Ok"); let expected_address_matches = solauto_position.account_info.key == &expected_solauto_position_address; return signer.key == &position_authority && expected_address_matches; @@ -106,100 +101,64 @@ pub fn validate_instruction( return Err(ProgramError::MissingRequiredSignature.into()); } - if solauto_managed_only_ix && solauto_position.data.self_managed.val { - msg!("Cannot perform the desired instruction on a self-managed position"); - return Err(SolautoError::IncorrectAccounts.into()); - } + error_if!( + solauto_managed_only_ix && solauto_position.data.self_managed.val, + SolautoError::IncorrectAccounts + ); - if solauto_position.data.self_managed.val && signer.key == &SOLAUTO_MANAGER { - msg!("Solauto manager cannot sign an instruction on a self-managed position"); - return Err(SolautoError::IncorrectAccounts.into()); - } + error_if!( + solauto_position.data.self_managed.val && signer.key == &SOLAUTO_MANAGER, + SolautoError::IncorrectAccounts + ); Ok(()) } -pub fn validate_position_settings( - solauto_position: &SolautoPosition, - current_unix_timestamp: u64 -) -> ProgramResult { - let invalid_params = |error_msg| { - msg!(error_msg); - Err(SolautoError::InvalidPositionSettings.into()) - }; - - let data = &solauto_position.position; - if data.setting_params.repay_to_bps < data.setting_params.boost_to_bps { - return invalid_params("repay_to_bps value must be greater than boost_to_bps value"); - } - let max_boost_to = get_max_boost_to_bps( +pub fn validate_position_settings(solauto_position: &SolautoPosition) -> ProgramResult { + let max_boost_to_bps = get_max_boost_to_bps( solauto_position.state.max_ltv_bps, - solauto_position.state.liq_threshold_bps + solauto_position.state.liq_threshold_bps, ); - if data.setting_params.boost_to_bps > max_boost_to { - return invalid_params(format!("Exceeds the maximum boost-to of {}", max_boost_to).as_str()); - } - if data.setting_params.repay_to_bps < data.setting_params.target_boost_to_bps { - return invalid_params("repay_to_bps value must be greater than target_boost_to_bps value"); - } - - if data.setting_params.repay_gap < MIN_REPAY_GAP_BPS { - return invalid_params( - format!("repay_gap must be {} or greater", MIN_REPAY_GAP_BPS).as_str() - ); - } - if data.setting_params.boost_gap < MIN_BOOST_GAP_BPS { - return invalid_params( - format!("boost_gap must be {} or greater", MIN_BOOST_GAP_BPS).as_str() - ); - } - - if data.setting_params.automation.is_active() { - validate_automation_settings(&data.setting_params.automation, current_unix_timestamp)?; - } - - if data.setting_params.target_boost_to_bps > MAX_BASIS_POINTS { - return invalid_params( - format!("target_boost_to_bps must be less than {}", MAX_BASIS_POINTS).as_str() - ); - } - let max_repay_to_bps = get_max_repay_to_bps( solauto_position.state.max_ltv_bps, - solauto_position.state.liq_threshold_bps + solauto_position.state.liq_threshold_bps, ); - if data.setting_params.repay_to_bps > max_repay_to_bps { - return invalid_params( - format!("For the given max_ltv and liq_threshold of the supplied asset, repay_to_bps must be lower or equal to {} in order to bring the utilization rate to an allowed position", max_repay_to_bps).as_str() - ); - } let max_repay_from_bps = get_max_repay_from_bps( solauto_position.state.max_ltv_bps, - solauto_position.state.liq_threshold_bps + solauto_position.state.liq_threshold_bps, ); - if data.setting_params.repay_from_bps() > max_repay_from_bps { - return invalid_params( - format!("repay_to_bps + repay_gap must be equal-to or below {}", max_repay_from_bps).as_str() - ); - } + let data = &solauto_position.position; + check!( + data.settings.repay_to_bps >= data.settings.boost_to_bps, + SolautoError::InvalidRepayToSetting + ); + check!( + data.settings.boost_to_bps <= max_boost_to_bps, + SolautoError::InvalidBoostToSetting + ); + check!( + data.settings.repay_gap >= MIN_REPAY_GAP_BPS, + SolautoError::InvalidRepayGapSetting + ); + check!( + data.settings.boost_gap >= MIN_BOOST_GAP_BPS, + SolautoError::InvalidBoostGapSetting + ); + check!( + data.settings.repay_to_bps <= max_repay_to_bps, + SolautoError::InvalidRepayToSetting + ); + check!( + data.settings.repay_to_bps + data.settings.repay_gap <= max_repay_from_bps, + SolautoError::InvalidRepayFromSetting + ); Ok(()) } -pub fn validate_dca_settings( - position: &PositionData, - current_unix_timestamp: u64 -) -> ProgramResult { - if position.dca.is_active() { - return Ok(()); - } - - validate_automation_settings(&position.dca.automation, current_unix_timestamp) -} - pub fn validate_automation_settings( automation: &AutomationSettings, - current_unix_timestamp: u64 + current_unix_timestamp: u64, ) -> ProgramResult { let invalid_params = |error_msg| { msg!(error_msg); @@ -214,9 +173,8 @@ pub fn validate_automation_settings( return invalid_params("Interval period must be between 10 minutes and 1 month"); } - if - current_unix_timestamp < automation.unix_start_date || - current_unix_timestamp > automation.unix_start_date + automation.interval_seconds + if current_unix_timestamp < automation.unix_start_date + || current_unix_timestamp > automation.unix_start_date + automation.interval_seconds { return invalid_params("Provided an invalid unix start date"); } @@ -230,47 +188,47 @@ pub fn validate_automation_settings( pub fn validate_lending_program_account( program: &AccountInfo, - lending_platform: LendingPlatform + lending_platform: LendingPlatform, ) -> ProgramResult { match lending_platform { LendingPlatform::Marginfi => { - if *program.key != MARGINFI_ID { - msg!("Incorrect Marginfi program account"); - return Err(ProgramError::IncorrectProgramId.into()); - } + check!( + *program.key == MARGINFI_PROD_PROGRAM || *program.key == MARGINFI_STAGING_PROGRAM, + SolautoError::IncorrectAccounts + ); } } // We don't need to check more than this, as lending protocols have their own account checks and will fail during CPI if there is an issue with the provided accounts Ok(()) } -pub fn validate_sysvar_accounts( +pub fn validate_standard_programs( system_program: Option<&AccountInfo>, token_program: Option<&AccountInfo>, ata_program: Option<&AccountInfo>, rent: Option<&AccountInfo>, - ixs_sysvar: Option<&AccountInfo> + ixs_sysvar: Option<&AccountInfo>, ) -> ProgramResult { - if system_program.is_some() && system_program.unwrap().key != &system_program_id { - msg!("Incorrect system program account provided"); - return Err(SolautoError::IncorrectAccounts.into()); - } - if token_program.is_some() && token_program.unwrap().key != &token_program_id { - msg!("Incorrect token program account provided"); - return Err(SolautoError::IncorrectAccounts.into()); - } - if ata_program.is_some() && ata_program.unwrap().key != &ata_program_id { - msg!("Incorrect ata program account provided"); - return Err(SolautoError::IncorrectAccounts.into()); - } - if rent.is_some() && rent.unwrap().key != &rent_program_id { - msg!("Incorrect rent program account provided"); - return Err(SolautoError::IncorrectAccounts.into()); - } - if ixs_sysvar.is_some() && ixs_sysvar.unwrap().key != &ixs_sysvar_id { - msg!("Incorrect ixs sysvar program account provided"); - return Err(SolautoError::IncorrectAccounts.into()); - } + check!( + system_program.is_none() || system_program.unwrap().key == &system_program_id, + SolautoError::IncorrectAccounts + ); + check!( + token_program.is_none() || token_program.unwrap().key == &token_program_id, + SolautoError::IncorrectAccounts + ); + check!( + ata_program.is_none() || ata_program.unwrap().key == &ata_program_id, + SolautoError::IncorrectAccounts + ); + check!( + rent.is_none() || rent.unwrap().key == &rent_program_id, + SolautoError::IncorrectAccounts + ); + check!( + ixs_sysvar.is_none() || ixs_sysvar.unwrap().key == &ixs_sysvar_id, + SolautoError::IncorrectAccounts + ); Ok(()) } @@ -278,26 +236,26 @@ pub fn validate_referral_accounts<'a>( referral_state_authority: &Pubkey, authority_referral_state: &DeserializedAccount<'a, ReferralState>, referred_by_ta: Option<&'a AccountInfo<'a>>, - validate_ta: bool + validate_ta: bool, ) -> ProgramResult { let referral_state_pda = Pubkey::create_program_address( authority_referral_state.data.seeds_with_bump().as_slice(), - &crate::ID + &crate::ID, )?; - if - &authority_referral_state.data.authority != referral_state_authority || - &referral_state_pda != authority_referral_state.account_info.key - { - msg!("Invalid referral state account given for the provided authority"); - return Err(SolautoError::IncorrectAccounts.into()); - } + error_if!( + &authority_referral_state.data.authority != referral_state_authority + || &referral_state_pda != authority_referral_state.account_info.key, + SolautoError::IncorrectAccounts + ); let authority_referred_by_state = &authority_referral_state.data.referred_by_state; - if validate_ta && authority_referred_by_state != &Pubkey::default() && referred_by_ta.is_none() { - msg!("Did not provide a referred_by_ta when the authority been referred"); - return Err(SolautoError::IncorrectAccounts.into()); - } + error_if!( + validate_ta + && authority_referred_by_state != &Pubkey::default() + && referred_by_ta.is_none(), + SolautoError::IncorrectAccounts + ); // The referred_by_ta is further validated at payout before transfer Ok(()) @@ -305,42 +263,38 @@ pub fn validate_referral_accounts<'a>( pub fn validate_marginfi_bank<'a>( marginfi_bank: &'a AccountInfo<'a>, - mint: &Pubkey + mint: &Pubkey, ) -> ProgramResult { if mint == &Pubkey::default() { return Ok(()); } let bank = DeserializedAccount::::zerocopy(Some(marginfi_bank))?.unwrap(); - if &bank.data.mint != mint { - msg!("Provided incorrect bank account"); - return Err(SolautoError::IncorrectAccounts.into()); - } + check!(&bank.data.mint == mint, SolautoError::IncorrectAccounts); + Ok(()) } pub fn validate_lending_program_accounts_with_position<'a>( lending_platform: LendingPlatform, solauto_position: &DeserializedAccount, - protocol_user_account: &'a AccountInfo<'a>, - protocol_supply_account: &'a AccountInfo<'a>, - protocol_debt_account: &'a AccountInfo<'a> + lp_user_account: &'a AccountInfo<'a>, + lp_supply_account: &'a AccountInfo<'a>, + lp_debt_account: &'a AccountInfo<'a>, ) -> ProgramResult { let supply_mint = &solauto_position.data.state.supply.mint; let debt_mint = &solauto_position.data.state.debt.mint; - if - !solauto_position.data.self_managed.val && - protocol_user_account.key != &solauto_position.data.position.protocol_user_account - { - msg!("Incorrect protocol-owned account"); - return Err(SolautoError::IncorrectAccounts.into()); - } + error_if!( + !solauto_position.data.self_managed.val + && lp_user_account.key != &solauto_position.data.position.lp_user_account, + SolautoError::IncorrectAccounts + ); match lending_platform { LendingPlatform::Marginfi => { - validate_marginfi_bank(protocol_supply_account, &supply_mint)?; - validate_marginfi_bank(protocol_debt_account, &debt_mint)?; + validate_marginfi_bank(lp_supply_account, &supply_mint)?; + validate_marginfi_bank(lp_debt_account, &debt_mint)?; } } @@ -350,10 +304,20 @@ pub fn validate_lending_program_accounts_with_position<'a>( pub fn validate_token_accounts<'a, 'b>( solauto_position: &'b DeserializedAccount<'a, SolautoPosition>, source_supply_ta: Option<&'a AccountInfo<'a>>, - source_debt_ta: Option<&'a AccountInfo<'a>> + source_debt_ta: Option<&'a AccountInfo<'a>>, ) -> ProgramResult { - validate_token_account(solauto_position, source_supply_ta, Some(TokenType::Supply), None)?; - validate_token_account(solauto_position, source_debt_ta, Some(TokenType::Debt), None)?; + validate_token_account( + solauto_position, + source_supply_ta, + Some(TokenType::Supply), + None, + )?; + validate_token_account( + solauto_position, + source_debt_ta, + Some(TokenType::Debt), + None, + )?; Ok(()) } @@ -361,7 +325,7 @@ pub fn validate_token_account<'a>( solauto_position: &DeserializedAccount<'a, SolautoPosition>, source_ta: Option<&'a AccountInfo<'a>>, token_type: Option, - token_mint: Option<&Pubkey> + token_mint: Option<&Pubkey>, ) -> ProgramResult { if solauto_position.data.self_managed.val && token_mint.is_none() { return Ok(()); @@ -378,23 +342,17 @@ pub fn validate_token_account<'a>( mint_key }; - let associated_position_ta = get_associated_token_address( - &solauto_position.account_info.key, - mint_key - ); - let associated_authority_ta = get_associated_token_address( - &solauto_position.data.authority, - mint_key - ); + let associated_position_ta = + get_associated_token_address(&solauto_position.account_info.key, mint_key); + let associated_authority_ta = + get_associated_token_address(&solauto_position.data.authority, mint_key); - if - source_ta.is_some() && - source_ta.unwrap().key != &associated_position_ta && - source_ta.unwrap().key != &associated_authority_ta - { - msg!("Incorrect token account {}", source_ta.unwrap().key); - return Err(SolautoError::IncorrectAccounts.into()); - } + error_if!( + source_ta.is_some() + && source_ta.unwrap().key != &associated_position_ta + && source_ta.unwrap().key != &associated_authority_ta, + SolautoError::IncorrectAccounts + ); Ok(()) } @@ -402,7 +360,7 @@ pub fn validate_token_account<'a>( pub fn token_account_owned_by<'a>( token_account: &'a AccountInfo<'a>, expected_owner: &Pubkey, - token_mint: Option<&Pubkey> + token_mint: Option<&Pubkey>, ) -> Result { if token_mint.is_some() { return Ok( @@ -410,62 +368,55 @@ pub fn token_account_owned_by<'a>( ); } else { let token_account_data = safe_unpack_token_account(Some(token_account))?.unwrap(); - return Ok( - token_account_data.account_info.owner == &token_program_id && - &token_account_data.data.owner == expected_owner - ); + return Ok(token_account_data.account_info.owner == &token_program_id + && &token_account_data.data.owner == expected_owner); } } pub fn validate_referral_signer( referral_state: &DeserializedAccount, signer: &AccountInfo, - allow_solauto_manager: bool + allow_solauto_manager: bool, ) -> ProgramResult { let referral_state_pda = Pubkey::create_program_address( referral_state.data.seeds_with_bump().as_slice(), - &crate::ID + &crate::ID, )?; - if &referral_state_pda != referral_state.account_info.key { - msg!("Incorrect referral state account provided"); - return Err(SolautoError::IncorrectAccounts.into()); - } + check!(&signer.is_signer, ProgramError::MissingRequiredSignature); + check!( + &referral_state_pda == referral_state.account_info.key, + SolautoError::IncorrectAccounts + ); - if !signer.is_signer { - msg!("Missing required referral signer"); - return Err(ProgramError::MissingRequiredSignature.into()); - } - if - signer.key != &referral_state.data.authority && - (!allow_solauto_manager || signer.key != &SOLAUTO_MANAGER) - { - msg!("Instruction has not been signed by the right account"); - return Err(SolautoError::IncorrectAccounts.into()); - } + error_if!( + signer.key != &referral_state.data.authority + && (!allow_solauto_manager || signer.key != &SOLAUTO_MANAGER), + SolautoError::IncorrectAccounts + ); Ok(()) } pub fn validate_no_active_balances<'a>( - protocol_account: &'a AccountInfo<'a>, - lending_platform: LendingPlatform + lp_user_account: &'a AccountInfo<'a>, + lending_platform: LendingPlatform, ) -> ProgramResult { if lending_platform == LendingPlatform::Marginfi { - let marginfi_account = DeserializedAccount:: - ::zerocopy(Some(protocol_account))? - .unwrap(); - if - marginfi_account.data.lending_account.balances + let marginfi_account = + DeserializedAccount::::zerocopy(Some(lp_user_account))?.unwrap(); + + check!( + marginfi_account + .data + .lending_account + .balances .iter() .filter(|balance| balance.active == 1) .collect::>() - .len() > 0 - { - msg!( - "Marginfi account has active balances. Ensure all debt is repaid and supply tokens are withdrawn before closing position" - ); - return Err(SolautoError::IncorrectAccounts.into()); - } + .len() + == 0, + SolautoError::IncorrectAccounts + ); Ok(()) } else { @@ -474,49 +425,70 @@ pub fn validate_no_active_balances<'a>( } } -pub fn validate_debt_adjustment( - solauto_position: &SolautoPosition, - provided_base_unit_amount: u64, - expected_debt_adjustment_usd: f64, - rebalance_type: Option<&SolautoRebalanceType> -) -> ProgramResult { - let token = if - expected_debt_adjustment_usd > 0.0 || - (rebalance_type.is_some() && - rebalance_type.unwrap() == &SolautoRebalanceType::FLRebalanceThenSwap) - { - solauto_position.state.debt - } else { - solauto_position.state.supply - }; +pub fn validate_rebalance(solauto_position: &SolautoPosition) -> ProgramResult { + let curr_supply_usd = solauto_position.state.supply.amount_used.usd_value(); + let curr_debt_usd = solauto_position.state.debt.amount_used.usd_value(); + + let target_supply_usd = + from_rounded_usd_value(solauto_position.rebalance.values.target_supply_usd); + let target_debt_usd = from_rounded_usd_value(solauto_position.rebalance.values.target_debt_usd); - let amount_usd = from_base_unit::(provided_base_unit_amount, token.decimals).mul( - token.market_price() + msg!( + "Supply expected vs. actual: {}, {}", + target_supply_usd, + curr_supply_usd + ); + msg!( + "Debt expected vs. actual: {}, {}", + target_debt_usd, + curr_debt_usd + ); + check!( + value_gte_with_threshold(curr_supply_usd, target_supply_usd, 0.1), + SolautoError::InvalidRebalanceMade + ); + check!( + value_lte_with_threshold(curr_debt_usd, target_debt_usd, 0.1), + SolautoError::InvalidRebalanceMade ); - // Checking if within specified range due to varying price volatility - if (amount_usd - expected_debt_adjustment_usd.abs()).abs().div(amount_usd) > 0.75 { - msg!("Base unit amount provided: {}", provided_base_unit_amount); - msg!( - "Provided debt adjustment was not what was expected (Provided: ${} vs. expected: ${})", - amount_usd.abs(), - expected_debt_adjustment_usd.abs() - ); - return Err(SolautoError::IncorrectDebtAdjustment.into()); + Ok(()) +} + +pub fn correct_token_account(token_account: &Pubkey, wallet: &Pubkey, mint: &Pubkey) -> bool { + token_account == &get_associated_token_address(wallet, mint) +} + +pub fn value_lte_with_threshold(value: f64, target_value: f64, threshold: f64) -> bool { + if target_value == 0.0 { + return value == 0.0; } + value < target_value || (value - target_value).abs().div(target_value) < threshold +} - Ok(()) +pub fn value_gte_with_threshold(value: f64, target_value: f64, threshold: f64) -> bool { + if target_value == 0.0 { + return value == 0.0; + } + value > target_value || (value - target_value).abs().div(target_value) < threshold +} + +pub fn value_match_with_threshold(value: f64, target_value: f64, threshold: f64) -> bool { + if target_value == 0.0 { + return value == 0.0; + } + (value - target_value).abs().div(target_value) < threshold } #[cfg(test)] mod tests { use crate::{ - state::solauto_position::{ - AutomationSettings, - AutomationSettingsInp, - PositionState, - SolautoSettingsParameters, - SolautoSettingsParametersInp, + state::{ + automation::{AutomationSettings, AutomationSettingsInp}, + solauto_position::{ + PositionData, PositionState, SolautoSettingsParameters, + SolautoSettingsParametersInp, + }, }, types::shared::PositionType, }; @@ -526,7 +498,7 @@ mod tests { fn test_position_settings(settings: SolautoSettingsParameters, liq_threshold_bps: u16) { let mut position_data = PositionData::default(); position_data.lending_platform = LendingPlatform::Marginfi; - position_data.setting_params = settings; + position_data.settings = settings; let mut position_state = PositionState::default(); position_state.max_ltv_bps = 6500; @@ -537,9 +509,9 @@ mod tests { Pubkey::default(), PositionType::default(), position_data, - position_state + position_state, ); - let result = validate_position_settings(&solauto_position, 0); + let result = validate_position_settings(&solauto_position); assert!(result.is_err()); } @@ -557,14 +529,14 @@ mod tests { boost_gap: MIN_BOOST_GAP_BPS - 10, ..default_settings_args }), - default_liq_threshold_bps + default_liq_threshold_bps, ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { repay_gap: MIN_REPAY_GAP_BPS - 10, ..default_settings_args }), - default_liq_threshold_bps + default_liq_threshold_bps, ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -572,7 +544,7 @@ mod tests { repay_gap: 600, ..default_settings_args }), - default_liq_threshold_bps + default_liq_threshold_bps, ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -580,7 +552,7 @@ mod tests { boost_gap: 1000, ..default_settings_args }), - default_liq_threshold_bps + default_liq_threshold_bps, ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -588,7 +560,7 @@ mod tests { repay_to_bps: 4000, ..default_settings_args }), - default_liq_threshold_bps + default_liq_threshold_bps, ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -596,21 +568,14 @@ mod tests { repay_gap: 500, ..default_settings_args }), - default_liq_threshold_bps + default_liq_threshold_bps, ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { repay_to_bps: 9900, ..default_settings_args }), - default_liq_threshold_bps - ); - test_position_settings( - SolautoSettingsParameters::from(SolautoSettingsParametersInp { - target_boost_to_bps: Some(10340), - ..default_settings_args - }), - default_liq_threshold_bps + default_liq_threshold_bps, ); } @@ -632,25 +597,25 @@ mod tests { test_automation_settings( current_timestamp, AutomationSettings::from(AutomationSettingsInp { - unix_start_date: current_timestamp + - default_automation_settings_args.interval_seconds + - 100, + unix_start_date: current_timestamp + + default_automation_settings_args.interval_seconds + + 100, ..default_automation_settings_args - }) + }), ); test_automation_settings( current_timestamp, AutomationSettings::from(AutomationSettingsInp { interval_seconds: 60, ..default_automation_settings_args.clone() - }) + }), ); test_automation_settings( current_timestamp, AutomationSettings::from(AutomationSettingsInp { interval_seconds: 60 * 60 * 24 * 60, ..default_automation_settings_args.clone() - }) + }), ); } } diff --git a/solauto-sdk/README.md b/solauto-sdk/README.md index eed98b40..73c4d0f8 100644 --- a/solauto-sdk/README.md +++ b/solauto-sdk/README.md @@ -1,3 +1,103 @@ -# Solauto SDK +## Solauto Typescript SDK -TODO \ No newline at end of file +Solauto is a program on the Solana blockchain that lets you manage leveraged longs & shorts on auto-pilot to maximize your gains and eliminate the risk of liquidation. The typescript SDK is made for interacting with the Solauto program. This SDK provides tools for managing, & reading Solauto state data, as well as executing transactions. + +## Basic Usage + +```typescript +import { PublicKey } from "@solana/web3.js"; +import * as solauto from "@haven-fi/solauto-sdk"; + +// Create new Solauto client +const client = solauto.getClient(solauto.LendingPlatform.MARGINFI, { + signer: yourSigner, + rpcUrl: "[YOUR_RPC_URL]", +}); + +// Initialize the client +const supplyMint = new PublicKey(NATIVE_MINT); +const debtMint = new PublicKey(USDC); +await client.initializeNewSolautoPosition({ + positionId: 1, + lpPoolAccount: solauto.getMarginfiAccounts().defaultGroup, + supplyMint, + debtMint, +}); + +// Open a position with custom settings +const [maxLtvBps, liqThresholdBps] = + await client.pos.maxLtvAndLiqThresholdBps(); +const settings: solauto.SolautoSettingsParametersInpArgs = { + boostToBps: solauto.maxBoostToBps(maxLtvBps, liqThresholdBps), + boostGap: 50, + repayToBps: solauto.maxRepayToBps(maxLtvBps, liqThresholdBps), + repayGap: 50, +}; + +const supplyUsdToDeposit = 100; +const debtUsdToBorrow = 60; +const [supplyPrice, debtPrice] = await solauto.fetchTokenPrices([ + supplyMint, + debtMint, +]); + +const transactionItems = [ + // Open position + solauto.openSolautoPosition(client, settings), + // Deposit supply (SOL) transaction + solauto.deposit( + client, + toBaseUnit( + supplyUsdToDeposit / supplyPrice, + client.pos.supplyMintInfo.decimals + ) + ), + // Borrow debt (USDC) transaction + solauto.borrow( + client, + toBaseUnit(debtUsdToBorrow / debtPrice, client.pos.debtMintInfo.decimals) + ), + // Rebalance to 0 LTV (repays all debt using collateral) + solauto.rebalance(client, 0), + // Withdraw remaining supply in position + solauto.withdraw(client, "All"), + // Close position + solauto.closeSolautoPosition(client), +]; + +// Send all transactions atomically +const txManager = await new solauto.ClientTransactionsManager({ + txHandler: client, +}); +const statuses = txManager.send(transactionItems); +``` + +## Rebalancing an existing position + +```typescript +import { PublicKey } from "@solana/web3.js"; +import * as solauto from "@haven-fi/solauto-sdk"; + +// Create new Solauto client +const client = solauto.getClient(solauto.LendingPlatform.MARGINFI, { + signer: yourSigner, + rpcUrl: "[YOUR_RPC_URL]", +}); + +// Initialize the client +await client.initializeExistingSolautoPosition({ + positionId: myPositionId, +}); + +const transactionItems = [ + solauto.rebalance( + client, + undefined // Provide target liquidation utilization rate if you want a specific LTV, otherwise it will rebalance according to position's settings (default) + ), +]; + +const txManager = await new solauto.ClientTransactionsManager({ + txHandler: client, +}); +const statuses = txManager.send(transactionItems); +``` diff --git a/solauto-sdk/local/createISMAccounts.ts b/solauto-sdk/local/createISMAccounts.ts deleted file mode 100644 index d4e4041b..00000000 --- a/solauto-sdk/local/createISMAccounts.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { - createSignerFromKeypair, - publicKey, - signerIdentity, - transactionBuilder, -} from "@metaplex-foundation/umi"; -import { - buildHeliusApiUrl, - getSolanaRpcConnection, - sendSingleOptimizedTransaction, -} from "../src/utils/solanaUtils"; -import { marginfiAccountInitialize, safeFetchAllMarginfiAccount } from "../src/marginfi-sdk"; -import { MARGINFI_ACCOUNTS, SOLAUTO_MANAGER } from "../src/constants"; -import { getSecretKey } from "./shared"; -import { updateSolautoLut } from "./updateSolautoLUT"; -import { getAllMarginfiAccountsByAuthority } from "../src/utils"; - -async function createIntermediarySolautoManagerAccounts() { - let [connection, umi] = getSolanaRpcConnection(buildHeliusApiUrl(process.env.HELIUS_API_KEY!)); - - const secretKey = getSecretKey("solauto-manager"); - const signerKeypair = umi.eddsa.createKeypairFromSecretKey(secretKey); - const signer = createSignerFromKeypair(umi, signerKeypair); - - umi = umi.use(signerIdentity(signer)); - - const accounts = await getAllMarginfiAccountsByAuthority(umi, SOLAUTO_MANAGER, undefined, false); - const data = await safeFetchAllMarginfiAccount(umi, accounts.map(x => publicKey(x.marginfiAccount))); - const existingMarginfiGroups = data.map(x => x.group.toString()); - - for (const group of Object.keys(MARGINFI_ACCOUNTS)) { - if (existingMarginfiGroups.includes(group.toString())) { - console.log("Already have Solauto Manager Marginfi Account for group:", group); - continue; - } - - const marginfiAccount = createSignerFromKeypair( - umi, - umi.eddsa.generateKeypair() - ); - - const tx = marginfiAccountInitialize(umi, { - marginfiAccount, - marginfiGroup: publicKey(group), - authority: signer, - feePayer: signer, - }); - - await sendSingleOptimizedTransaction( - umi, - connection, - transactionBuilder().add(tx) - ); - - await updateSolautoLut([marginfiAccount.publicKey.toString()]); - } -} - -createIntermediarySolautoManagerAccounts(); diff --git a/solauto-sdk/local/createTokenAccounts.ts b/solauto-sdk/local/createTokenAccounts.ts index 33248835..5f38efe3 100644 --- a/solauto-sdk/local/createTokenAccounts.ts +++ b/solauto-sdk/local/createTokenAccounts.ts @@ -1,11 +1,16 @@ import { PublicKey } from "@solana/web3.js"; +import { + createSignerFromKeypair, + publicKey, + signerIdentity, + transactionBuilder, +} from "@metaplex-foundation/umi"; import { ALL_SUPPORTED_TOKENS, + LOCAL_IRONFORGE_API_URL, SOLAUTO_FEES_WALLET, - SOLAUTO_MANAGER, } from "../src/constants"; import { - buildHeliusApiUrl, createAssociatedTokenAccountUmiIx, getSolanaRpcConnection, getTokenAccount, @@ -13,17 +18,9 @@ import { zip, } from "../src/utils"; import { getSecretKey } from "./shared"; -import { - createSignerFromKeypair, - publicKey, - signerIdentity, - transactionBuilder, -} from "@metaplex-foundation/umi"; async function createTokenAccounts(wallet: PublicKey) { - let [connection, umi] = getSolanaRpcConnection( - buildHeliusApiUrl(process.env.HELIUS_API_KEY!) - ); + let [connection, umi] = getSolanaRpcConnection(LOCAL_IRONFORGE_API_URL); const secretKey = getSecretKey(); const signerKeypair = umi.eddsa.createKeypairFromSecretKey(secretKey); diff --git a/solauto-sdk/local/logPositions.ts b/solauto-sdk/local/logPositions.ts index 73fe6740..fe9b55c2 100644 --- a/solauto-sdk/local/logPositions.ts +++ b/solauto-sdk/local/logPositions.ts @@ -1,80 +1,19 @@ -import { publicKey } from "@metaplex-foundation/umi"; +import { PublicKey } from "@solana/web3.js"; +import path from "path"; +import { config } from "dotenv"; import { - buildHeliusApiUrl, fetchTokenPrices, - fromBaseUnit, + getPositionExBulk, getSolanaRpcConnection, getSolautoManagedPositions, - PositionState, - positionStateWithLatestPrices, - retryWithExponentialBackoff, - safeFetchAllSolautoPosition, - safeGetPrice, + LOCAL_IRONFORGE_API_URL, + ProgramEnv, SOLAUTO_PROD_PROGRAM, - TOKEN_INFO, - USD_DECIMALS, + SOLAUTO_TEST_PROGRAM, } from "../src"; -import { PublicKey } from "@solana/web3.js"; -import { NATIVE_MINT } from "@solana/spl-token"; -import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; -import path from "path"; -import { config } from "dotenv"; -import { safeFetchMarginfiAccount } from "../src/marginfi-sdk"; config({ path: path.join(__dirname, ".env") }); -function getBatches(items: T[], batchSize: number): T[][] { - const batches: T[][] = []; - for (let i = 0; i < items.length; i += batchSize) { - batches.push(items.slice(i, i + batchSize)); - } - return batches; -} - -export function tokenInfo(mint?: PublicKey) { - return TOKEN_INFO[mint ? mint.toString() : PublicKey.default.toString()]; -} - -type StrategyType = "Long" | "Short"; - -function solautoStrategyName(supplyMint?: PublicKey, debtMint?: PublicKey) { - const supplyInfo = tokenInfo(supplyMint); - const debtInfo = tokenInfo(debtMint); - const strat = strategyType( - supplyMint ?? PublicKey.default, - debtMint ?? PublicKey.default - ); - - if (strat === "Long") { - return debtInfo.isStableCoin - ? `${supplyInfo.ticker} Long` - : supplyInfo.ticker - ? `${supplyInfo.ticker}/${debtInfo.ticker} Long` - : ""; - } else { - return `${debtInfo.ticker} Short`; - } -} - -function strategyType( - supplyMint: PublicKey, - debtMint: PublicKey -): StrategyType { - const supplyInfo = tokenInfo(supplyMint); - const debtInfo = tokenInfo(debtMint); - - if (supplyInfo.isLST && debtMint.equals(NATIVE_MINT)) { - // Yield - throw new Error("Not yet supported"); - } else if (debtInfo.isStableCoin) { - return "Long"; - } else if (supplyInfo.isStableCoin) { - return "Short"; - } else { - return "Long"; - } -} - export function roundToDecimals(value: number, decimals: number = 2): number { if (!value || isNaN(value)) { return value; @@ -138,10 +77,10 @@ export function formatNumber( } } -async function main(filterWhitelist: boolean) { +async function main(filterWhitelist: boolean, programEnv: ProgramEnv = "Prod") { const [_, umi] = getSolanaRpcConnection( - buildHeliusApiUrl(process.env.HELIUS_API_KEY!), - SOLAUTO_PROD_PROGRAM + LOCAL_IRONFORGE_API_URL, + programEnv === "Prod" ? SOLAUTO_PROD_PROGRAM : SOLAUTO_TEST_PROGRAM ); let positions = await getSolautoManagedPositions(umi); @@ -153,21 +92,10 @@ async function main(filterWhitelist: boolean) { ); } - const batches = getBatches(positions, 30); - - const solautoPositionsData = ( - await Promise.all( - batches.map(async (pubkeys) => { - return retryWithExponentialBackoff( - async () => - await safeFetchAllSolautoPosition( - umi, - pubkeys.map((x) => publicKey(x.publicKey!)) - ) - ); - }) - ) - ).flat(); + const positionsEx = await getPositionExBulk( + umi, + positions.map((x) => new PublicKey(x.publicKey!)) + ); const tokensUsed = Array.from( new Set( @@ -177,56 +105,80 @@ async function main(filterWhitelist: boolean) { ]) ) ); - - const tokenBatches = getBatches(tokensUsed, 15); - await Promise.all( - tokenBatches.map(async (batch) => { - await fetchTokenPrices(batch.map((x) => new PublicKey(x))); - }) - ); + await fetchTokenPrices(tokensUsed.map((x) => new PublicKey(x))); console.log("\n\n"); - const latestStates: PositionState[] = []; let unhealthyPositions = 0; - for (const pos of solautoPositionsData) { - const latestState = await positionStateWithLatestPrices( - pos.state, - safeGetPrice(pos.state.supply.mint), - safeGetPrice(pos.state.debt.mint) - ); - latestStates.push(latestState); + let awaitingBoostPositions = 0; - const strategy = solautoStrategyName( - toWeb3JsPublicKey(pos.state.supply.mint), - toWeb3JsPublicKey(pos.state.debt.mint) - ); - - const repayFrom = pos.position.settingParams.repayToBps + pos.position.settingParams.repayGap; - const unhealthy = pos.state.liqUtilizationRateBps > repayFrom; - const healthText = unhealthy ? `(Unhealthy: ${pos.state.liqUtilizationRateBps - repayFrom}` : ""; + const sortedPositions = positionsEx.sort( + (a, b) => a.netWorthUsd() - b.netWorthUsd() + ); + for (const pos of sortedPositions) { + const actionToTake = pos.eligibleForRebalance(0); + + const repayFrom = pos.settings!.repayToBps + pos.settings!.repayGap; + const unhealthy = actionToTake === "repay"; + const healthText = unhealthy + ? `(Unhealthy: ${pos.liqUtilizationRateBps() - repayFrom}bps)` + : ""; if (unhealthy) { unhealthyPositions += 1; } - console.log(pos.publicKey.toString(), `(${pos.authority.toString()})`); + const awaitingBoost = actionToTake === "boost"; + const boostText = awaitingBoost ? " (awaiting boost)" : ""; + if (awaitingBoost) { + awaitingBoostPositions += 1; + } + + console.log( + pos.publicKey.toString(), + `(${pos.authority.toString()} ${pos.positionId})` + ); console.log( - `${strategy}: $${formatNumber(fromBaseUnit(latestState.netWorth.baseAmountUsdValue, USD_DECIMALS), 2, 10000, 2)} ${healthText}` + `${pos.strategyName}: $${formatNumber(pos.netWorthUsd(), 2, 10000, 2)} ${healthText} ${boostText}\n` ); } - console.log("\nTotal positions:", solautoPositionsData.length, unhealthyPositions ? ` (unhealthy: ${unhealthyPositions})` : ""); + console.log( + "\nTotal positions:", + positionsEx.length, + unhealthyPositions ? ` (unhealthy: ${unhealthyPositions})` : "", + awaitingBoostPositions ? ` (awaiting boost: ${awaitingBoostPositions})` : "" + ); console.log( "Total users:", - Array.from(new Set(solautoPositionsData.map((x) => x.authority.toString()))) - .length + Array.from(new Set(positionsEx.map((x) => x.authority.toString()))).length ); - const tvl = latestStates - .map((x) => fromBaseUnit(x.netWorth.baseAmountUsdValue, USD_DECIMALS)) + const tvl = positionsEx + .map((x) => x.supplyUsd()) .reduce((acc, curr) => acc + curr, 0); - console.log(`Total TVL: $${formatNumber(tvl, 2, 10000, 2)}`); + const netWorth = positionsEx + .map((x) => x.netWorthUsd()) + .reduce((acc, curr) => acc + curr, 0); + + console.log(`TVL: $${formatNumber(tvl, 2, 10000, 2)}`); + console.log(`Total net worth: $${formatNumber(netWorth, 2, 10000, 2)}`); } -const filterWhitelist = true; -main(filterWhitelist).then((x) => x); \ No newline at end of file +const args = process.argv.slice(2); // Skip the first 2 (node + script path) + +const parsedArgs: Record = {}; +for (const arg of args) { + if (arg.startsWith("--")) { + const [key, val] = arg.replace(/^--/, "").split("="); + parsedArgs[key] = val ?? true; + } +} + +console.log("Parsed flags:", parsedArgs); + +const filterWhitelist = + "filter" in parsedArgs ? parsedArgs["filter"] === "true" : true; +const programEnv = + "env" in parsedArgs ? (parsedArgs["env"] as ProgramEnv) : undefined; + +main(filterWhitelist, programEnv).then((x) => x); diff --git a/solauto-sdk/local/shared.ts b/solauto-sdk/local/shared.ts index 23f52ae4..c81e1c51 100644 --- a/solauto-sdk/local/shared.ts +++ b/solauto-sdk/local/shared.ts @@ -8,7 +8,11 @@ import { VersionedTransaction, PublicKey, } from "@solana/web3.js"; -import { buildHeliusApiUrl, getSolanaRpcConnection } from "../src/utils/solanaUtils"; +import { + getSolanaRpcConnection, + getBatches, + LOCAL_IRONFORGE_API_URL, +} from "../src"; function loadSecretKey(keypairPath: string) { const secretKey = JSON.parse(fs.readFileSync(keypairPath, "utf8")); @@ -21,20 +25,24 @@ export function getSecretKey(keypairFilename: string = "id"): Uint8Array { ); } -const keypair = Keypair.fromSecretKey(getSecretKey("solauto-auth")); -const [connection, _] = getSolanaRpcConnection(buildHeliusApiUrl(process.env.HELIUS_API_KEY ?? "")); +const keypair = Keypair.fromSecretKey(getSecretKey("solauto-fees")); +const [connection, _] = getSolanaRpcConnection(LOCAL_IRONFORGE_API_URL); -async function createAndSendV0Tx(txInstructions: TransactionInstruction[]) { +export async function createAndSendV0Tx( + txInstructions: TransactionInstruction[], + payer: Keypair, + otherSigners?: Keypair[] +) { let latestBlockhash = await connection.getLatestBlockhash("finalized"); const messageV0 = new TransactionMessage({ - payerKey: keypair.publicKey, + payerKey: payer.publicKey, recentBlockhash: latestBlockhash.blockhash, instructions: txInstructions, }).compileToV0Message(); const transaction = new VersionedTransaction(messageV0); - transaction.sign([keypair]); + transaction.sign([payer, ...(otherSigners ?? [])]); const txid = await connection.sendTransaction(transaction, { maxRetries: 5, @@ -46,7 +54,7 @@ async function createAndSendV0Tx(txInstructions: TransactionInstruction[]) { lastValidBlockHeight: latestBlockhash.lastValidBlockHeight, }); if (confirmation.value.err) { - throw new Error(confirmation.value.err.toString()); + throw confirmation.value.err; } console.log(txid); } @@ -61,25 +69,39 @@ async function addAddressesIfNeeded( .map((x) => new PublicKey(x)); if (addresses.length > 0) { - await createAndSendV0Tx([ - AddressLookupTableProgram.extendLookupTable({ - payer: keypair.publicKey, - authority: keypair.publicKey, - lookupTable: lookupTableAddress, - addresses, - }), - ]); + const batches = getBatches(addresses, 20); + for (const addressBatch of batches) { + console.log(addressBatch.map((x) => x.toString())); + await createAndSendV0Tx( + [ + AddressLookupTableProgram.extendLookupTable({ + payer: keypair.publicKey, + authority: keypair.publicKey, + lookupTable: lookupTableAddress, + addresses: addressBatch, + }), + ], + keypair + ); + } } } +const CACHE: { [key: string]: string[] } = {}; + export async function updateLookupTable( accounts: string[], lookupTableAddress?: PublicKey ) { - let lookupTable = lookupTableAddress - ? await connection.getAddressLookupTable(lookupTableAddress) - : null; - if (lookupTable === null) { + if (lookupTableAddress && !(lookupTableAddress.toString() in CACHE)) { + const lookupTable = + await connection.getAddressLookupTable(lookupTableAddress); + CACHE[lookupTableAddress.toString()] = ( + lookupTable?.value?.state?.addresses ?? [] + ).map((x) => x.toString()); + } + + if (!lookupTableAddress) { const [createLutIx, addr] = AddressLookupTableProgram.createLookupTable({ authority: keypair.publicKey, payer: keypair.publicKey, @@ -87,11 +109,10 @@ export async function updateLookupTable( }); lookupTableAddress = addr; console.log("Lookup Table Address:", lookupTableAddress.toString()); - createAndSendV0Tx([createLutIx]); + await createAndSendV0Tx([createLutIx], keypair); } - const existingAccounts = - lookupTable?.value?.state.addresses.map((x) => x.toString()) ?? []; + const existingAccounts = CACHE[lookupTableAddress.toString()]; console.log("Existing accounts: ", existingAccounts.length); await addAddressesIfNeeded(lookupTableAddress!, existingAccounts, accounts); diff --git a/solauto-sdk/local/txSandbox.ts b/solauto-sdk/local/txSandbox.ts new file mode 100644 index 00000000..add63425 --- /dev/null +++ b/solauto-sdk/local/txSandbox.ts @@ -0,0 +1,116 @@ +import { Keypair, PublicKey } from "@solana/web3.js"; +import { createSignerFromKeypair } from "@metaplex-foundation/umi"; +import { fromWeb3JsKeypair } from "@metaplex-foundation/umi-web3js-adapters"; +import { + ClientTransactionsManager, + consoleLog, + getBatches, + getClient, + getPositionExBulk, + getSolanaRpcConnection, + getSolautoManagedPositions, + LendingPlatform, + LOCAL_IRONFORGE_API_URL, + PriceType, + PriorityFeeSetting, + ProgramEnv, + rebalance, + SOLAUTO_PROD_PROGRAM, + SOLAUTO_TEST_PROGRAM, + SolautoClient, + TransactionItem, +} from "../src"; +import { getSecretKey } from "./shared"; + +const payForTransaction = false; +const testProgram = false; +const lpEnv: ProgramEnv = "Prod"; + +let [, umi] = getSolanaRpcConnection( + LOCAL_IRONFORGE_API_URL, + testProgram ? SOLAUTO_TEST_PROGRAM : SOLAUTO_PROD_PROGRAM, + lpEnv +); + +const signer = createSignerFromKeypair( + umi, + fromWeb3JsKeypair(Keypair.fromSecretKey(getSecretKey("solauto-manager"))) +); + +export async function main() { + const client = getClient(LendingPlatform.Marginfi, { + signer, + showLogs: true, + rpcUrl: LOCAL_IRONFORGE_API_URL, + programId: testProgram ? SOLAUTO_TEST_PROGRAM : SOLAUTO_PROD_PROGRAM, + lpEnv, + }); + + await client.initializeExistingSolautoPosition({ + positionId: 2, + authority: new PublicKey("EBhRj7jbF2EVE21i19JSuCX1BAbnZFYhoKW64HnaZ3kf"), + // lpUserAccount: new PublicKey( + // "GEokw9jqbh6d1xUNA3qaeYFFetbSR5Y1nt7C3chwwgSz" + // ), + }); + + const transactionItems = [rebalance(client)]; + + const txManager = new ClientTransactionsManager({ + txHandler: client, + txRunType: payForTransaction ? "normal" : "only-simulate", + priorityFeeSetting: PriorityFeeSetting.Default, + retryConfig: { totalRetries: 2 }, + }); + const statuses = await txManager.send(transactionItems); + consoleLog(statuses); +} + +async function refreshAll() { + const allPositions = await getSolautoManagedPositions(umi); + const positions = await getPositionExBulk( + umi, + allPositions.map((x) => new PublicKey(x.publicKey!)) + ); + + let client: SolautoClient | undefined; + const transactionItems: TransactionItem[] = []; + for (const pos of positions) { + client = getClient(pos.lendingPlatform, { + signer, + showLogs: true, + rpcUrl: LOCAL_IRONFORGE_API_URL, + programId: testProgram ? SOLAUTO_TEST_PROGRAM : SOLAUTO_PROD_PROGRAM, + lpEnv, + }); + + await client!.initialize({ + positionId: pos.positionId, + authority: pos.authority, + }); + + const ix = client!.refreshIx(PriceType.Realtime); + transactionItems.push( + new TransactionItem( + async () => ({ tx: ix }), + `refresh ${pos.authority} (${pos.positionId})` + ) + ); + } + + const txBatches = getBatches(transactionItems, 15); + + for (const batch of txBatches) { + const txManager = new ClientTransactionsManager({ + txHandler: client!, + txRunType: payForTransaction ? "normal" : "only-simulate", + priorityFeeSetting: PriorityFeeSetting.Default, + retryConfig: { totalRetries: 2 }, + }); + const statuses = await txManager.send(batch); + consoleLog(statuses); + } +} + +main(); +// refreshAll(); diff --git a/solauto-sdk/local/updateMarginfiLUT.ts b/solauto-sdk/local/updateMarginfiLUT.ts index 1a378bbf..e77ae3ec 100644 --- a/solauto-sdk/local/updateMarginfiLUT.ts +++ b/solauto-sdk/local/updateMarginfiLUT.ts @@ -1,35 +1,104 @@ -import { PublicKey } from "@solana/web3.js"; -import { MARGINFI_ACCOUNTS_LOOKUP_TABLE } from "../src/constants/marginfiAccounts"; +import { Keypair } from "@solana/web3.js"; import { - MARGINFI_ACCOUNTS, - DEFAULT_MARGINFI_GROUP, -} from "../src/constants/marginfiAccounts"; -import { MARGINFI_PROGRAM_ID } from "../src/marginfi-sdk"; -import { updateLookupTable } from "./shared"; + createSignerFromKeypair, + publicKey, + signerIdentity, +} from "@metaplex-foundation/umi"; +import { + fromWeb3JsKeypair, + toWeb3JsInstruction, + toWeb3JsKeypair, +} from "@metaplex-foundation/umi-web3js-adapters"; +import { + getEmptyMarginfiAccountsByAuthority, + getSolanaRpcConnection, + SOLAUTO_MANAGER, + marginfiAccountInitialize, + LOCAL_IRONFORGE_API_URL, + getMarginfiAccounts, + getAllBankRelatedAccounts, + umiWithMarginfiProgram, + ProgramEnv, +} from "../src"; +import { createAndSendV0Tx, getSecretKey, updateLookupTable } from "./shared"; + +const programEnv: ProgramEnv = "Prod"; +const mfiAccounts = getMarginfiAccounts(programEnv); -const LOOKUP_TABLE_ADDRESS = new PublicKey(MARGINFI_ACCOUNTS_LOOKUP_TABLE); +const LOOKUP_TABLE_ADDRESS = mfiAccounts.lookupTable; +let [, umi] = getSolanaRpcConnection(LOCAL_IRONFORGE_API_URL); +umi = umiWithMarginfiProgram( + umi.use( + signerIdentity( + createSignerFromKeypair(umi, umi.eddsa.generateKeypair()), + true + ) + ), + programEnv +); + +const solautoManagerKeypair = Keypair.fromSecretKey( + getSecretKey("solauto-manager") +); +const solautoManager = createSignerFromKeypair( + umi, + fromWeb3JsKeypair(solautoManagerKeypair) +); async function addBanks() { - for (const group in MARGINFI_ACCOUNTS) { - for (const key in MARGINFI_ACCOUNTS[group]) { - const accounts = MARGINFI_ACCOUNTS[group][key]; + const accounts = await getAllBankRelatedAccounts( + umi, + mfiAccounts.bankAccounts + ); + await updateLookupTable( + accounts.map((x) => x.toString()), + LOOKUP_TABLE_ADDRESS + ); +} + +async function addImfiAccounts() { + const imfiAccounts = await getEmptyMarginfiAccountsByAuthority( + umi, + SOLAUTO_MANAGER + ); + + const iMfiAccountsPerGrp = 2; + for (const group in mfiAccounts.bankAccounts) { + const emptyAccs = imfiAccounts.filter((x) => x.group.toString() === group); + if (emptyAccs.length >= iMfiAccountsPerGrp) { await updateLookupTable( - [ - group, - accounts.bank, - accounts.liquidityVault, - accounts.vaultAuthority, - accounts.priceOracle, - ], + emptyAccs.map((x) => x.publicKey.toString()), LOOKUP_TABLE_ADDRESS ); + } else { + for (let i = 0; i < iMfiAccountsPerGrp - emptyAccs.length; i++) { + console.log("Creating Imfi account for group:", group); + const iMfiAccountKeypair = umi.eddsa.generateKeypair(); + const iMfiAccount = createSignerFromKeypair(umi, iMfiAccountKeypair); + const umiIx = marginfiAccountInitialize(umi, { + marginfiAccount: iMfiAccount, + marginfiGroup: publicKey(group), + authority: solautoManager, + feePayer: solautoManager, + }); + const ix = toWeb3JsInstruction(umiIx.getInstructions()[0]); + await createAndSendV0Tx([ix], solautoManagerKeypair, [ + toWeb3JsKeypair(iMfiAccountKeypair), + ]); + await updateLookupTable( + [iMfiAccount.publicKey.toString()], + LOOKUP_TABLE_ADDRESS + ); + } } } } updateLookupTable( - [DEFAULT_MARGINFI_GROUP, MARGINFI_PROGRAM_ID], + [mfiAccounts.defaultGroup.toString(), mfiAccounts.program.toString()], LOOKUP_TABLE_ADDRESS ); -addBanks(); +addBanks().then((x) => x); + +addImfiAccounts().then((x) => x); diff --git a/solauto-sdk/local/updateSolautoLUT.ts b/solauto-sdk/local/updateSolautoLUT.ts index d17edc4d..6a764d47 100644 --- a/solauto-sdk/local/updateSolautoLUT.ts +++ b/solauto-sdk/local/updateSolautoLUT.ts @@ -1,23 +1,18 @@ import { PublicKey } from "@solana/web3.js"; -import { getTokenAccounts } from "../src/utils/accountUtils"; import { SOLAUTO_FEES_WALLET, SOLAUTO_MANAGER, -} from "../src/constants/generalAccounts"; -import { ALL_SUPPORTED_TOKENS } from "../src/constants/tokenConstants"; -import { updateLookupTable } from "./shared"; -import { SOLAUTO_LUT, STANDARD_LUT_ACCOUNTS, -} from "../src/constants/solautoConstants"; -import { - buildHeliusApiUrl, - getAllMarginfiAccountsByAuthority, - getSolanaRpcConnection, -} from "../src/utils"; -import { SWITCHBOARD_PRICE_FEED_IDS } from "../src/constants/switchboardConstants"; + SWITCHBOARD_PRICE_FEED_IDS, + ALL_SUPPORTED_TOKENS, + getTokenAccounts, +} from "../src"; +import { updateLookupTable } from "./shared"; -const LOOKUP_TABLE_ADDRESS = new PublicKey(SOLAUTO_LUT); +const LOOKUP_TABLE_ADDRESS = Boolean(SOLAUTO_LUT) + ? new PublicKey(SOLAUTO_LUT) + : undefined; const solautoManagerTokenAccounts = getTokenAccounts( SOLAUTO_MANAGER, ALL_SUPPORTED_TOKENS.map((x) => new PublicKey(x)) @@ -28,22 +23,13 @@ const solautoFeeWalletTokenAccounts = getTokenAccounts( ); export async function updateSolautoLut(additionalAccounts?: string[]) { - const [_, umi] = getSolanaRpcConnection( - buildHeliusApiUrl(process.env.HELIUS_API_KEY!) - ); - const ismAccounts = await getAllMarginfiAccountsByAuthority( - umi, - SOLAUTO_MANAGER - ); - return updateLookupTable( [ ...STANDARD_LUT_ACCOUNTS, ...ALL_SUPPORTED_TOKENS, ...solautoManagerTokenAccounts.map((x) => x.toString()), ...solautoFeeWalletTokenAccounts.map((x) => x.toString()), - ...ismAccounts.map((x) => x.marginfiAccount.toString()), - ...Object.values(SWITCHBOARD_PRICE_FEED_IDS), + ...Object.values(SWITCHBOARD_PRICE_FEED_IDS).map((x) => x.feedId), ...(additionalAccounts ?? []), ], LOOKUP_TABLE_ADDRESS diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index cee4676f..09e334b6 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,36 +1,36 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.447", + "version": "1.0.729", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", "author": "Chelioso", - "license": "MIT", "scripts": { "build": "rm -rf dist && npx tsc", + "test:all": "pnpm test:unit && pnpm test:txs", "test:txs": "ts-mocha -p ./tsconfig.json -t 1000000 tests/transactions/**/*.ts", - "test:unit": "ts-mocha -p ./tsconfig.json -t 1000000 tests/unit/**/*.ts", - "test:all": "pnpm test:unit && pnpm test:txs" + "test:unit": "ts-mocha -p ./tsconfig.json -t 1000000 tests/unit/**/*.ts" }, "dependencies": { "@coral-xyz/anchor": "^0.30.1", - "@jup-ag/api": "^6.0.24", + "@jup-ag/api": "=6.0.24", "@metaplex-foundation/umi": "^0.9.1", "@metaplex-foundation/umi-bundle-defaults": "^0.9.1", "@metaplex-foundation/umi-signer-wallet-adapters": "^0.9.1", "@metaplex-foundation/umi-web3js-adapters": "^0.9.1", - "@mrgnlabs/marginfi-client-v2": "^4.0.0", - "@mrgnlabs/mrgn-common": "^1.8.0", "@solana/spl-token": "^0.4.0", "@solana/web3.js": "=1.95.8", + "@switchboard-xyz/common": "=3.0.12", "@switchboard-xyz/on-demand": "=1.2.51", "axios": "^1.7.8", + "big.js": "^6.2.2", "bs58": "^5.0.0", "cross-fetch": "^4.0.0", "dotenv": "^16.4.7", "rpc-websockets": "7.11.0" }, "devDependencies": { + "@types/big.js": "^6.2.2", "@types/chai": "^4.3.0", "@types/mocha": "^9.1.1", "@types/node": "^20.16.11", diff --git a/solauto-sdk/pnpm-lock.yaml b/solauto-sdk/pnpm-lock.yaml index 396a9536..5003c773 100644 --- a/solauto-sdk/pnpm-lock.yaml +++ b/solauto-sdk/pnpm-lock.yaml @@ -9,8 +9,8 @@ dependencies: specifier: ^0.30.1 version: 0.30.1 '@jup-ag/api': - specifier: ^6.0.24 - version: 6.0.29 + specifier: '=6.0.24' + version: 6.0.24 '@metaplex-foundation/umi': specifier: ^0.9.1 version: 0.9.2 @@ -23,24 +23,24 @@ dependencies: '@metaplex-foundation/umi-web3js-adapters': specifier: ^0.9.1 version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@mrgnlabs/marginfi-client-v2': - specifier: ^4.0.0 - version: 4.0.0(fastestsmallesttextencoderdecoder@1.0.22) - '@mrgnlabs/mrgn-common': - specifier: ^1.8.0 - version: 1.8.0 '@solana/spl-token': specifier: ^0.4.0 version: 0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/web3.js': specifier: '=1.95.8' version: 1.95.8 + '@switchboard-xyz/common': + specifier: '=3.0.12' + version: 3.0.12 '@switchboard-xyz/on-demand': specifier: '=1.2.51' version: 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) axios: specifier: ^1.7.8 version: 1.7.8 + big.js: + specifier: ^6.2.2 + version: 6.2.2 bs58: specifier: ^5.0.0 version: 5.0.0 @@ -55,6 +55,9 @@ dependencies: version: 7.11.0 devDependencies: + '@types/big.js': + specifier: ^6.2.2 + version: 6.2.2 '@types/chai': specifier: ^4.3.0 version: 4.3.20 @@ -97,30 +100,6 @@ packages: engines: {node: '>=10'} dev: false - /@coral-xyz/anchor@0.29.0: - resolution: {integrity: sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==} - engines: {node: '>=11'} - dependencies: - '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.95.8) - '@noble/hashes': 1.5.0 - '@solana/web3.js': 1.95.8 - bn.js: 5.2.1 - bs58: 4.0.1 - buffer-layout: 1.2.2 - camelcase: 6.3.0 - cross-fetch: 3.1.8 - crypto-hash: 1.3.0 - eventemitter3: 4.0.7 - pako: 2.1.0 - snake-case: 3.0.4 - superstruct: 0.15.5 - toml: 3.0.0 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - /@coral-xyz/anchor@0.30.1: resolution: {integrity: sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==} engines: {node: '>=11'} @@ -146,17 +125,6 @@ packages: - utf-8-validate dev: false - /@coral-xyz/borsh@0.29.0(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==} - engines: {node: '>=10'} - peerDependencies: - '@solana/web3.js': ^1.68.0 - dependencies: - '@solana/web3.js': 1.95.8 - bn.js: 5.2.1 - buffer-layout: 1.2.2 - dev: false - /@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.8): resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} engines: {node: '>=10'} @@ -168,31 +136,8 @@ packages: buffer-layout: 1.2.2 dev: false - /@grpc/grpc-js@1.12.4: - resolution: {integrity: sha512-NBhrxEWnFh0FxeA0d//YP95lRFsSx2TNLEUQg4/W+5f/BMxcCjgOOIT24iD+ZB/tZw057j44DaIxja7w4XMrhg==} - engines: {node: '>=12.10.0'} - dependencies: - '@grpc/proto-loader': 0.7.13 - '@js-sdsl/ordered-map': 4.4.2 - dev: false - - /@grpc/proto-loader@0.7.13: - resolution: {integrity: sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==} - engines: {node: '>=6'} - hasBin: true - dependencies: - lodash.camelcase: 4.3.0 - long: 5.2.3 - protobufjs: 7.4.0 - yargs: 17.7.2 - dev: false - - /@js-sdsl/ordered-map@4.4.2: - resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} - dev: false - - /@jup-ag/api@6.0.29: - resolution: {integrity: sha512-1gUY1txmL/gG14VDZMjeKVqhSzeg4L2cImdC7dGLYB5DP5D5lwpR+FarvhqehEi+63/RWOUKTTU4fablGpeIUQ==} + /@jup-ag/api@6.0.24: + resolution: {integrity: sha512-zIX4WIPb0Kb2UnK2wNIOQBWqPJyMJq/D9dQTf/2qvPb0hfa8XdgbrQAzomHMHnAzw9StMQoybBk+JK/A76xP3w==} dev: false /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): @@ -358,46 +303,6 @@ packages: '@metaplex-foundation/umi-serializers': 0.9.0 dev: false - /@mrgnlabs/marginfi-client-v2@4.0.0(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-GnXdGdPgU54w517iDXfKoti1i8jrVyOwhxPKS2Lpqac3QH4NL3b4sSbz+pCBDmjk60gveHzu3IAIGscUpbo1yQ==} - dependencies: - '@coral-xyz/anchor': 0.30.1 - '@mrgnlabs/mrgn-common': 1.8.0 - '@pythnetwork/pyth-solana-receiver': 0.8.2 - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 - '@switchboard-xyz/on-demand': 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) - bignumber.js: 9.1.2 - borsh: 2.0.0 - bs58: 6.0.0 - decimal.js: 10.4.3 - superstruct: 1.0.4 - transitivePeerDependencies: - - bufferutil - - debug - - encoding - - fastestsmallesttextencoderdecoder - - utf-8-validate - dev: false - - /@mrgnlabs/mrgn-common@1.8.0: - resolution: {integrity: sha512-6VQ/2Ob8alyI1jsY3RETsWJ5W/myEp+h2yu1mFI/yzKHLffQMlt50FWPSDmCe2TBmkBioW48HOl+PqQf3+Wfbg==} - dependencies: - '@coral-xyz/anchor': 0.30.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 - bignumber.js: 9.1.2 - bs58: 6.0.0 - decimal.js: 10.4.3 - numeral: 2.0.6 - superstruct: 1.0.4 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - /@noble/curves@1.6.0: resolution: {integrity: sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==} engines: {node: ^14.21.3 || >=16} @@ -405,10 +310,6 @@ packages: '@noble/hashes': 1.5.0 dev: false - /@noble/ed25519@1.7.3: - resolution: {integrity: sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==} - dev: false - /@noble/hashes@1.5.0: resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} engines: {node: ^14.21.3 || >=16} @@ -457,39 +358,6 @@ packages: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} dev: false - /@pythnetwork/price-service-sdk@1.7.1: - resolution: {integrity: sha512-xr2boVXTyv1KUt/c6llUTfbv2jpud99pWlMJbFaHGUBoygQsByuy7WbjIJKZ+0Blg1itLZl0Lp/pJGGg8SdJoQ==} - dependencies: - bn.js: 5.2.1 - dev: false - - /@pythnetwork/pyth-solana-receiver@0.8.2: - resolution: {integrity: sha512-WrrdwwhSYvvB5vJEL+SfPnfuxgkRKMeKdZvGFFwe6ENrMhrQCM05oDkvNNYfXATLcpQGRAyBu9l1xIxUxixpqw==} - dependencies: - '@coral-xyz/anchor': 0.29.0 - '@noble/hashes': 1.5.0 - '@pythnetwork/price-service-sdk': 1.7.1 - '@pythnetwork/solana-utils': 0.4.2 - '@solana/web3.js': 1.95.8 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - - /@pythnetwork/solana-utils@0.4.2: - resolution: {integrity: sha512-hKo7Bcs/kDWA5Fnqhg9zJSB94NMoUDIDjHjSi/uvZOzwizISUQI6oY3LWd2CXzNh4f8djjY2BS5iNHaM4cm8Bw==} - dependencies: - '@coral-xyz/anchor': 0.29.0 - '@solana/web3.js': 1.95.8 - bs58: 5.0.0 - jito-ts: 3.0.1 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - /@solana/buffer-layout-utils@0.2.0: resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} engines: {node: '>= 10'} @@ -777,13 +645,13 @@ packages: - typescript dev: false - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} engines: {node: '>=16'} peerDependencies: '@solana/web3.js': ^1.95.3 dependencies: - '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/spl-type-length-value': 0.1.0 '@solana/web3.js': 1.95.8 transitivePeerDependencies: @@ -791,21 +659,21 @@ packages: - typescript dev: false - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} engines: {node: '>=16'} peerDependencies: '@solana/web3.js': ^1.95.3 dependencies: - '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.0 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript dev: false - /@solana/spl-token@0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + /@solana/spl-token@0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} engines: {node: '>=16'} peerDependencies: @@ -813,8 +681,8 @@ packages: dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8 + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.98.0 buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -851,29 +719,8 @@ packages: buffer: 6.0.3 dev: false - /@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-apqMuYwFp1jFi55NxDfvXUX2x1T0Zh07MxhZ/nCCTGys5raSfYUh82zen2BLv8BSDj/JxZ2P/s7jrQZGrX8uAw==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.77.3 - dependencies: - '@solana/wallet-standard-features': 1.2.0 - '@solana/web3.js': 1.95.8 - '@wallet-standard/base': 1.1.0 - '@wallet-standard/features': 1.1.0 - eventemitter3: 4.0.7 - dev: false - - /@solana/wallet-standard-features@1.2.0: - resolution: {integrity: sha512-tUd9srDLkRpe1BYg7we+c4UhRQkq+XQWswsr/L1xfGmoRDF47BPSXf4zE7ZU2GRBGvxtGt7lwJVAufQyQYhxTQ==} - engines: {node: '>=16'} - dependencies: - '@wallet-standard/base': 1.1.0 - '@wallet-standard/features': 1.1.0 - dev: false - - /@solana/web3.js@1.77.4: - resolution: {integrity: sha512-XdN0Lh4jdY7J8FYMyucxCwzn6Ga2Sr1DHDWRbqVzk7ZPmmpSPOVWHzO67X1cVT+jNi1D6gZi2tgjHgDPuj6e9Q==} + /@solana/web3.js@1.95.8: + resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} dependencies: '@babel/runtime': 7.25.7 '@noble/curves': 1.6.0 @@ -888,16 +735,16 @@ packages: fast-stable-stringify: 1.0.0 jayson: 4.1.2 node-fetch: 2.7.0 - rpc-websockets: 7.11.0 - superstruct: 0.14.2 + rpc-websockets: 9.0.4 + superstruct: 2.0.2 transitivePeerDependencies: - bufferutil - encoding - utf-8-validate dev: false - /@solana/web3.js@1.95.8: - resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} + /@solana/web3.js@1.98.0: + resolution: {integrity: sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==} dependencies: '@babel/runtime': 7.25.7 '@noble/curves': 1.6.0 @@ -924,8 +771,8 @@ packages: resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8 + '@solana/spl-token': 0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.98.0 '@types/bn.js': 5.1.6 '@types/node': 18.19.65 '@types/node-fetch': 2.6.12 @@ -953,8 +800,8 @@ packages: resolution: {integrity: sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w==} engines: {node: '>=12'} dependencies: - '@solana/web3.js': 1.95.8 - axios: 1.7.8 + '@solana/web3.js': 1.98.0 + axios: 1.8.4 big.js: 6.2.2 bn.js: 5.2.1 bs58: 5.0.0 @@ -971,16 +818,38 @@ packages: - utf-8-validate dev: false + /@switchboard-xyz/common@3.0.12: + resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} + engines: {node: '>=20'} + dependencies: + '@solana/web3.js': 1.98.0 + axios: 1.8.4 + big.js: 6.2.2 + bn.js: 5.2.1 + bs58: 6.0.0 + buffer: 6.0.3 + decimal.js: 10.4.3 + js-sha256: 0.11.0 + protobufjs: 7.4.0 + yaml: 2.6.1 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - utf-8-validate + dev: false + /@switchboard-xyz/on-demand@1.2.51(fastestsmallesttextencoderdecoder@1.0.22): resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} engines: {node: '>= 18'} + deprecated: deprecated in favor of 2.x.x dependencies: '@brokerloop/ttlcache': 3.2.3 '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.0 '@solworks/soltoolkit-sdk': 0.0.23(fastestsmallesttextencoderdecoder@1.0.22) '@switchboard-xyz/common': 2.5.5 - axios: 1.7.8 + axios: 1.8.4 big.js: 6.2.2 bs58: 5.0.0 js-yaml: 4.1.0 @@ -993,6 +862,10 @@ packages: - utf-8-validate dev: false + /@types/big.js@6.2.2: + resolution: {integrity: sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==} + dev: true + /@types/bn.js@5.1.6: resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} dependencies: @@ -1061,18 +934,6 @@ packages: resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} dev: true - /@wallet-standard/base@1.1.0: - resolution: {integrity: sha512-DJDQhjKmSNVLKWItoKThJS+CsJQjR9AOBOirBVT1F9YpRyC9oYHE+ZnSf8y8bxUphtKqdQMPVQ2mHohYdRvDVQ==} - engines: {node: '>=16'} - dev: false - - /@wallet-standard/features@1.1.0: - resolution: {integrity: sha512-hiEivWNztx73s+7iLxsuD1sOJ28xtRix58W7Xnz4XzzA/pF0+aicnWgjOdA10doVDEDZdUuZCIIqG96SFNlDUg==} - engines: {node: '>=16'} - dependencies: - '@wallet-standard/base': 1.1.0 - dev: false - /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -1096,12 +957,14 @@ packages: /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + dev: true /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} dependencies: color-convert: 2.0.1 + dev: true /anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} @@ -1137,6 +1000,16 @@ packages: - debug dev: false + /axios@1.8.4: + resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true @@ -1198,10 +1071,6 @@ packages: text-encoding-utf-8: 1.0.2 dev: false - /borsh@2.0.0: - resolution: {integrity: sha512-kc9+BgR3zz9+cjbwM8ODoUB4fs3X3I5A/HtX7LZKxCLaMrEeDFoBpnhZY//DTS1VZBSs6S5v46RZRbZjRFspEg==} - dev: false - /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -1321,23 +1190,16 @@ packages: wrap-ansi: 7.0.0 dev: true - /cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: false - /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 + dev: true /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true /combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} @@ -1447,6 +1309,7 @@ packages: /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true /es6-promise@4.2.8: resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} @@ -1461,6 +1324,7 @@ packages: /escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + dev: true /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} @@ -1546,6 +1410,7 @@ packages: /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + dev: true /get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} @@ -1622,6 +1487,7 @@ packages: /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + dev: true /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} @@ -1679,23 +1545,6 @@ packages: - utf-8-validate dev: false - /jito-ts@3.0.1: - resolution: {integrity: sha512-TSofF7KqcwyaWGjPaSYC8RDoNBY1TPRNBHdrw24bdIi7mQ5bFEDdYK3D//llw/ml8YDvcZlgd644WxhjLTS9yg==} - dependencies: - '@grpc/grpc-js': 1.12.4 - '@noble/ed25519': 1.7.3 - '@solana/web3.js': 1.77.4 - agentkeepalive: 4.5.0 - dotenv: 16.4.7 - jayson: 4.1.2 - node-fetch: 2.7.0 - superstruct: 1.0.4 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - /js-sha256@0.11.0: resolution: {integrity: sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==} dev: false @@ -1731,10 +1580,6 @@ packages: p-locate: 5.0.0 dev: true - /lodash.camelcase@4.3.0: - resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - dev: false - /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} dev: false @@ -1877,10 +1722,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /numeral@2.0.6: - resolution: {integrity: sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==} - dev: false - /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -1967,6 +1808,7 @@ packages: /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + dev: true /rpc-websockets@7.11.0: resolution: {integrity: sha512-IkLYjayPv6Io8C/TdCL5gwgzd1hFz2vmBZrjMw/SPEXo51ETOhnzgS4Qy5GWi2JQN7HKHa66J3+2mv0fgNh/7w==} @@ -2030,12 +1872,14 @@ packages: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + dev: true /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 + dev: true /strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} @@ -2049,19 +1893,10 @@ packages: engines: {node: '>=8'} dev: true - /superstruct@0.14.2: - resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} - dev: false - /superstruct@0.15.5: resolution: {integrity: sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==} dev: false - /superstruct@1.0.4: - resolution: {integrity: sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==} - engines: {node: '>=14.0.0'} - dev: false - /superstruct@2.0.2: resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} engines: {node: '>=14.0.0'} @@ -2213,6 +2048,7 @@ packages: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 + dev: true /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -2250,6 +2086,7 @@ packages: /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + dev: true /yaml@2.6.1: resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==} @@ -2262,11 +2099,6 @@ packages: engines: {node: '>=10'} dev: true - /yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - dev: false - /yargs-unparser@2.0.0: resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} engines: {node: '>=10'} @@ -2290,19 +2122,6 @@ packages: yargs-parser: 20.2.4 dev: true - /yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - dev: false - /yn@2.0.0: resolution: {integrity: sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==} engines: {node: '>=4'} diff --git a/solauto-sdk/src/clients/index.ts b/solauto-sdk/src/clients/index.ts deleted file mode 100644 index 37402211..00000000 --- a/solauto-sdk/src/clients/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './solautoMarginfiClient'; -export * from './solautoClient'; -export * from './referralStateManager'; -export * from './txHandler'; \ No newline at end of file diff --git a/solauto-sdk/src/clients/solautoMarginfiClient.ts b/solauto-sdk/src/clients/solautoMarginfiClient.ts deleted file mode 100644 index 7ac1217b..00000000 --- a/solauto-sdk/src/clients/solautoMarginfiClient.ts +++ /dev/null @@ -1,732 +0,0 @@ -import { - fromWeb3JsPublicKey, - toWeb3JsPublicKey, -} from "@metaplex-foundation/umi-web3js-adapters"; -import { - Signer, - TransactionBuilder, - publicKey, - PublicKey as UmiPublicKey, - transactionBuilder, - createSignerFromKeypair, - AccountMeta, -} from "@metaplex-foundation/umi"; -import { PublicKey, SYSVAR_INSTRUCTIONS_PUBKEY } from "@solana/web3.js"; -import { SolautoClient, SolautoClientArgs } from "./solautoClient"; -import { MarginfiAssetAccounts } from "../types/accounts"; -import { - DEFAULT_MARGINFI_GROUP, - MARGINFI_ACCOUNTS, - MARGINFI_ACCOUNTS_LOOKUP_TABLE, -} from "../constants/marginfiAccounts"; -import { - DCASettingsInpArgs, - LendingPlatform, - PositionState, - PositionType, - RebalanceDirection, - SolautoActionArgs, - SolautoRebalanceTypeArgs, - SolautoSettingsParametersInpArgs, - marginfiOpenPosition, - marginfiProtocolInteraction, - marginfiRebalance, - marginfiRefreshData, -} from "../generated"; -import { getTokenAccount } from "../utils/accountUtils"; -import { - Bank, - MARGINFI_PROGRAM_ID, - MarginfiAccount, - lendingAccountBorrow, - lendingAccountDeposit, - lendingAccountEndFlashloan, - lendingAccountRepay, - lendingAccountStartFlashloan, - lendingAccountWithdraw, - marginfiAccountInitialize, - safeFetchAllMarginfiAccount, - safeFetchMarginfiAccount, -} from "../marginfi-sdk"; -import { - FlashLoanDetails, - RebalanceValues, -} from "../utils/solauto/rebalanceUtils"; -import { - findMarginfiAccounts, - getAllMarginfiAccountsByAuthority, - getMarginfiAccountPositionState, - getMarginfiMaxLtvAndLiqThreshold, - marginfiAccountEmpty, -} from "../utils/marginfiUtils"; -import { fromBaseUnit, toBps } from "../utils/numberUtils"; -import { QuoteResponse } from "@jup-ag/api"; -import { consoleLog, safeGetPrice } from "../utils"; - -export interface SolautoMarginfiClientArgs extends SolautoClientArgs { - marginfiAccount?: PublicKey | Signer; - marginfiAccountSeedIdx?: bigint; - marginfiGroup?: PublicKey; -} - -export class SolautoMarginfiClient extends SolautoClient { - private initializedFor?: PublicKey; - - public marginfiProgram!: PublicKey; - - public marginfiAccountSeedIdx: bigint = BigInt(0); - public marginfiAccount!: PublicKey | Signer; - public marginfiAccountPk!: PublicKey; - public marginfiGroup!: PublicKey; - - public marginfiSupplyAccounts!: MarginfiAssetAccounts; - public marginfiDebtAccounts!: MarginfiAssetAccounts; - - public supplyPriceOracle!: PublicKey; - public debtPriceOracle!: PublicKey; - - // For flash loans - public intermediaryMarginfiAccountSigner?: Signer; - public intermediaryMarginfiAccountPk!: PublicKey; - public intermediaryMarginfiAccount?: MarginfiAccount; - - async initialize(args: SolautoMarginfiClientArgs) { - await super.initialize(args); - - this.lendingPlatform = LendingPlatform.Marginfi; - - if (this.selfManaged) { - this.marginfiAccount = - args.marginfiAccount ?? - createSignerFromKeypair(this.umi, this.umi.eddsa.generateKeypair()); - } else { - if (this.solautoPositionData) { - this.marginfiAccount = toWeb3JsPublicKey( - this.solautoPositionData.position.protocolUserAccount - ); - } else { - const accounts = await getAllMarginfiAccountsByAuthority( - this.umi, - this.solautoPosition, - args.marginfiGroup ?? new PublicKey(DEFAULT_MARGINFI_GROUP), - false - ); - const reusableAccounts = - accounts.length > 0 - ? ( - await safeFetchAllMarginfiAccount( - this.umi, - accounts.map((x) => publicKey(x.marginfiAccount)) - ) - ).filter((x) => marginfiAccountEmpty(x)) - : []; - this.marginfiAccount = - reusableAccounts.length > 0 - ? toWeb3JsPublicKey(reusableAccounts[0].publicKey) - : createSignerFromKeypair( - this.umi, - this.umi.eddsa.generateKeypair() - ); - } - } - this.marginfiAccountPk = - "publicKey" in this.marginfiAccount - ? toWeb3JsPublicKey(this.marginfiAccount.publicKey) - : this.marginfiAccount; - - if ("publicKey" in this.marginfiAccount) { - this.otherSigners.push(this.marginfiAccount); - } - - const marginfiAccountData = !args.new - ? await safeFetchMarginfiAccount( - this.umi, - publicKey(this.marginfiAccountPk), - { commitment: "confirmed" } - ) - : null; - this.marginfiGroup = new PublicKey( - marginfiAccountData - ? marginfiAccountData.group.toString() - : (args.marginfiGroup ?? DEFAULT_MARGINFI_GROUP) - ); - - this.marginfiSupplyAccounts = - MARGINFI_ACCOUNTS[this.marginfiGroup.toString()][ - this.supplyMint.toString() - ]!; - this.marginfiDebtAccounts = - MARGINFI_ACCOUNTS[this.marginfiGroup.toString()][ - this.debtMint.toString() - ]!; - - // TODO: Don't dynamically pull oracle from bank until Marginfi sorts out their price oracle issues. - // const [supplyBank, debtBank] = await safeFetchAllBank(this.umi, [ - // publicKey(this.marginfiSupplyAccounts.bank), - // publicKey(this.marginfiDebtAccounts.bank), - // ]); - // this.supplyPriceOracle = toWeb3JsPublicKey(supplyBank.config.oracleKeys[0]); - // this.debtPriceOracle = toWeb3JsPublicKey(debtBank.config.oracleKeys[0]); - this.supplyPriceOracle = new PublicKey( - this.marginfiSupplyAccounts.priceOracle - ); - this.debtPriceOracle = new PublicKey(this.marginfiDebtAccounts.priceOracle); - - if ( - !this.initializedFor || - !this.initializedFor.equals(toWeb3JsPublicKey(this.signer.publicKey)) - ) { - await this.setIntermediaryMarginfiDetails(); - this.initializedFor = toWeb3JsPublicKey(this.signer.publicKey); - } - - consoleLog("Marginfi account:", this.marginfiAccountPk.toString()); - consoleLog( - "Intermediary MF account:", - this.intermediaryMarginfiAccountPk.toString() - ); - } - - async setIntermediaryMarginfiDetails() { - const existingMarginfiAccounts = ( - await getAllMarginfiAccountsByAuthority( - this.umi, - toWeb3JsPublicKey(this.signer.publicKey), - this.marginfiGroup - ) - ) - .filter((x) => !x.marginfiAccount.equals(this.marginfiAccountPk)) - .sort((a, b) => - a.marginfiAccount.toString().localeCompare(b.marginfiAccount.toString()) - ); - const compatibleMarginfiAccounts = - existingMarginfiAccounts.length > 0 - ? ( - await safeFetchAllMarginfiAccount( - this.umi, - existingMarginfiAccounts.map((x) => publicKey(x.marginfiAccount)) - ) - ).filter((x) => marginfiAccountEmpty(x)) - : []; - - this.intermediaryMarginfiAccountSigner = - compatibleMarginfiAccounts.length > 0 - ? undefined - : createSignerFromKeypair(this.umi, this.umi.eddsa.generateKeypair()); - this.intermediaryMarginfiAccountPk = - compatibleMarginfiAccounts.length > 0 - ? toWeb3JsPublicKey(compatibleMarginfiAccounts[0].publicKey) - : toWeb3JsPublicKey(this.intermediaryMarginfiAccountSigner!.publicKey); - this.intermediaryMarginfiAccount = - compatibleMarginfiAccounts.length > 0 - ? compatibleMarginfiAccounts[0] - : undefined; - - if (this.intermediaryMarginfiAccountSigner) { - this.otherSigners.push(this.intermediaryMarginfiAccountSigner); - } - } - - protocolAccount(): PublicKey { - return this.marginfiAccountPk; - } - - defaultLookupTables(): string[] { - return [MARGINFI_ACCOUNTS_LOOKUP_TABLE, ...super.defaultLookupTables()]; - } - - lutAccountsToAdd(): PublicKey[] { - return [ - ...super.lutAccountsToAdd(), - this.marginfiAccountPk, - ...(this.signer.publicKey.toString() === this.authority.toString() - ? [this.intermediaryMarginfiAccountPk] - : []), - ]; - } - - async maxLtvAndLiqThresholdBps(): Promise<[number, number] | undefined> { - const result = await super.maxLtvAndLiqThresholdBps(); - if (result) { - return result; - } else if ( - this.supplyMint.equals(PublicKey.default) || - this.debtMint.equals(PublicKey.default) - ) { - return [0, 0]; - } else { - const [maxLtv, liqThreshold] = await getMarginfiMaxLtvAndLiqThreshold( - this.umi, - this.marginfiGroup, - { - mint: this.supplyMint, - }, - { - mint: this.debtMint, - } - ); - this.maxLtvBps = toBps(maxLtv); - this.liqThresholdBps = toBps(liqThreshold); - return [this.maxLtvBps, this.liqThresholdBps]; - } - } - - marginfiAccountInitialize(marginfiAccount: Signer): TransactionBuilder { - return marginfiAccountInitialize(this.umi, { - marginfiAccount: marginfiAccount, - marginfiGroup: publicKey(this.marginfiGroup), - authority: this.signer, - feePayer: this.signer, - }); - } - - openPosition( - settingParams?: SolautoSettingsParametersInpArgs, - dca?: DCASettingsInpArgs - ): TransactionBuilder { - return super - .openPosition(settingParams, dca) - .add(this.marginfiOpenPositionIx(settingParams, dca)); - } - - private marginfiOpenPositionIx( - settingParams?: SolautoSettingsParametersInpArgs, - dca?: DCASettingsInpArgs, - positionType?: PositionType - ): TransactionBuilder { - let signerDebtTa: UmiPublicKey | undefined = undefined; - if (dca) { - signerDebtTa = publicKey(this.signerDebtTa); - } - - return marginfiOpenPosition(this.umi, { - signer: this.signer, - marginfiProgram: publicKey(MARGINFI_PROGRAM_ID), - signerReferralState: publicKey(this.referralState), - referredByState: this.referredByState - ? publicKey(this.referredByState) - : undefined, - referredBySupplyTa: this.referredBySupplyTa() - ? publicKey(this.referredBySupplyTa()!) - : undefined, - solautoPosition: publicKey(this.solautoPosition), - marginfiGroup: publicKey(this.marginfiGroup), - marginfiAccount: - "publicKey" in this.marginfiAccount - ? (this.marginfiAccount as Signer) - : publicKey(this.marginfiAccount), - supplyMint: publicKey(this.supplyMint), - supplyBank: publicKey(this.marginfiSupplyAccounts.bank), - positionSupplyTa: publicKey(this.positionSupplyTa), - debtMint: publicKey(this.debtMint), - debtBank: publicKey(this.marginfiDebtAccounts.bank), - positionDebtTa: publicKey(this.positionDebtTa), - signerDebtTa: signerDebtTa, - positionType: positionType ?? PositionType.Leverage, - positionData: { - positionId: this.positionId!, - settingParams: settingParams ?? null, - dca: dca ?? null, - }, - marginfiAccountSeedIdx: !this.selfManaged - ? this.marginfiAccountSeedIdx - : null, - }); - } - - refresh(): TransactionBuilder { - return marginfiRefreshData(this.umi, { - signer: this.signer, - marginfiProgram: publicKey(MARGINFI_PROGRAM_ID), - marginfiGroup: publicKey(this.marginfiGroup), - marginfiAccount: publicKey(this.marginfiAccount), - supplyBank: publicKey(this.marginfiSupplyAccounts.bank), - supplyPriceOracle: publicKey(this.supplyPriceOracle), - debtBank: publicKey(this.marginfiDebtAccounts.bank), - debtPriceOracle: publicKey(this.debtPriceOracle), - solautoPosition: publicKey(this.solautoPosition), - }); - } - - protocolInteraction(args: SolautoActionArgs): TransactionBuilder { - let tx = super.protocolInteraction(args); - - if (this.selfManaged) { - return tx.add(this.marginfiProtocolInteractionIx(args)); - } else { - return tx.add(this.marginfiSolautoProtocolInteractionIx(args)); - } - } - - private marginfiProtocolInteractionIx(args: SolautoActionArgs) { - switch (args.__kind) { - case "Deposit": { - return lendingAccountDeposit(this.umi, { - amount: args.fields[0], - signer: this.signer, - signerTokenAccount: publicKey(this.signerSupplyTa), - marginfiAccount: publicKey(this.marginfiAccountPk), - marginfiGroup: publicKey(this.marginfiGroup), - bank: publicKey(this.marginfiSupplyAccounts.bank), - bankLiquidityVault: publicKey( - this.marginfiSupplyAccounts.liquidityVault - ), - }); - } - case "Borrow": { - return lendingAccountBorrow(this.umi, { - amount: args.fields[0], - signer: this.signer, - destinationTokenAccount: publicKey(this.signerDebtTa), - marginfiAccount: publicKey(this.marginfiAccountPk), - marginfiGroup: publicKey(this.marginfiGroup), - bank: publicKey(this.marginfiDebtAccounts.bank), - bankLiquidityVault: publicKey( - this.marginfiDebtAccounts.liquidityVault - ), - bankLiquidityVaultAuthority: publicKey( - this.marginfiDebtAccounts.vaultAuthority - ), - }); - } - case "Repay": { - return lendingAccountRepay(this.umi, { - amount: - args.fields[0].__kind === "Some" ? args.fields[0].fields[0] : 0, - repayAll: args.fields[0].__kind === "All" ? true : false, - signer: this.signer, - signerTokenAccount: publicKey(this.signerDebtTa), - marginfiAccount: publicKey(this.marginfiAccountPk), - marginfiGroup: publicKey(this.marginfiGroup), - bank: publicKey(this.marginfiDebtAccounts.bank), - bankLiquidityVault: publicKey( - this.marginfiDebtAccounts.liquidityVault - ), - }); - } - case "Withdraw": { - return lendingAccountWithdraw(this.umi, { - amount: - args.fields[0].__kind === "Some" ? args.fields[0].fields[0] : 0, - withdrawAll: args.fields[0].__kind === "All" ? true : false, - signer: this.signer, - destinationTokenAccount: publicKey(this.signerSupplyTa), - marginfiAccount: publicKey(this.marginfiAccountPk), - marginfiGroup: publicKey(this.marginfiGroup), - bank: publicKey(this.marginfiSupplyAccounts.bank), - bankLiquidityVault: publicKey( - this.marginfiSupplyAccounts.liquidityVault - ), - bankLiquidityVaultAuthority: publicKey( - this.marginfiSupplyAccounts.vaultAuthority - ), - }); - } - } - } - - private marginfiSolautoProtocolInteractionIx( - args: SolautoActionArgs - ): TransactionBuilder { - let positionSupplyTa: UmiPublicKey | undefined = undefined; - let vaultSupplyTa: UmiPublicKey | undefined = undefined; - let supplyVaultAuthority: UmiPublicKey | undefined = undefined; - if (args.__kind === "Deposit" || args.__kind === "Withdraw") { - positionSupplyTa = publicKey( - args.__kind === "Withdraw" || this.selfManaged - ? this.signerSupplyTa - : this.positionSupplyTa - ); - vaultSupplyTa = publicKey(this.marginfiSupplyAccounts.liquidityVault); - supplyVaultAuthority = publicKey( - this.marginfiSupplyAccounts.vaultAuthority - ); - } - - let positionDebtTa: UmiPublicKey | undefined = undefined; - let vaultDebtTa: UmiPublicKey | undefined = undefined; - let debtVaultAuthority: UmiPublicKey | undefined = undefined; - if (args.__kind === "Borrow" || args.__kind === "Repay") { - positionDebtTa = publicKey( - args.__kind === "Borrow" || this.selfManaged - ? this.signerDebtTa - : this.positionDebtTa - ); - vaultDebtTa = publicKey(this.marginfiDebtAccounts.liquidityVault); - debtVaultAuthority = publicKey(this.marginfiDebtAccounts.vaultAuthority); - } - - let supplyPriceOracle: UmiPublicKey | undefined = undefined; - let debtPriceOracle: UmiPublicKey | undefined = undefined; - if (args.__kind === "Withdraw" || args.__kind === "Borrow") { - supplyPriceOracle = publicKey(this.supplyPriceOracle); - debtPriceOracle = publicKey(this.debtPriceOracle); - } - - return marginfiProtocolInteraction(this.umi, { - signer: this.signer, - marginfiProgram: publicKey(MARGINFI_PROGRAM_ID), - solautoPosition: publicKey(this.solautoPosition), - marginfiGroup: publicKey(this.marginfiGroup), - marginfiAccount: publicKey(this.marginfiAccountPk), - supplyBank: publicKey(this.marginfiSupplyAccounts.bank), - supplyPriceOracle, - positionSupplyTa, - vaultSupplyTa, - supplyVaultAuthority, - debtBank: publicKey(this.marginfiDebtAccounts.bank), - debtPriceOracle, - positionDebtTa, - vaultDebtTa, - debtVaultAuthority, - solautoAction: args, - }); - } - - rebalance( - rebalanceStep: "A" | "B", - jupQuote: QuoteResponse, - rebalanceType: SolautoRebalanceTypeArgs, - rebalanceValues: RebalanceValues, - flashLoan?: FlashLoanDetails, - targetLiqUtilizationRateBps?: number - ): TransactionBuilder { - const inputIsSupply = new PublicKey(jupQuote.inputMint).equals( - this.supplyMint - ); - const outputIsSupply = new PublicKey(jupQuote.outputMint).equals( - this.supplyMint - ); - const needSupplyAccounts = - (inputIsSupply && rebalanceStep === "A") || - (outputIsSupply && rebalanceStep === "B") || - (inputIsSupply && flashLoan !== undefined && rebalanceStep == "B"); - const needDebtAccounts = - (!inputIsSupply && rebalanceStep === "A") || - (!outputIsSupply && rebalanceStep === "B") || - (!inputIsSupply && flashLoan !== undefined && rebalanceStep == "B"); - - return marginfiRebalance(this.umi, { - signer: this.signer, - marginfiProgram: publicKey(MARGINFI_PROGRAM_ID), - ixsSysvar: publicKey(SYSVAR_INSTRUCTIONS_PUBKEY), - solautoFeesTa: - rebalanceStep === "B" - ? publicKey( - rebalanceValues.rebalanceDirection === RebalanceDirection.Boost - ? this.solautoFeesSupplyTa - : this.solautoFeesDebtTa - ) - : undefined, - authorityReferralState: publicKey(this.referralState), - referredByTa: this.referredByState - ? publicKey( - rebalanceValues.rebalanceDirection === RebalanceDirection.Boost - ? this.referredBySupplyTa()! - : this.referredByDebtTa()! - ) - : undefined, - positionAuthority: - rebalanceValues.rebalanceAction === "dca" - ? publicKey(this.authority) - : undefined, - solautoPosition: publicKey(this.solautoPosition), - marginfiGroup: publicKey(this.marginfiGroup), - marginfiAccount: publicKey(this.marginfiAccountPk), - intermediaryTa: publicKey( - getTokenAccount( - toWeb3JsPublicKey(this.signer.publicKey), - new PublicKey(jupQuote.inputMint) - ) - ), - supplyBank: publicKey(this.marginfiSupplyAccounts.bank), - supplyPriceOracle: publicKey(this.supplyPriceOracle), - positionSupplyTa: publicKey(this.positionSupplyTa), - authoritySupplyTa: this.selfManaged - ? publicKey(getTokenAccount(this.authority, this.supplyMint)) - : undefined, - vaultSupplyTa: needSupplyAccounts - ? publicKey(this.marginfiSupplyAccounts.liquidityVault) - : undefined, - supplyVaultAuthority: needSupplyAccounts - ? publicKey(this.marginfiSupplyAccounts.vaultAuthority) - : undefined, - debtBank: publicKey(this.marginfiDebtAccounts.bank), - debtPriceOracle: publicKey(this.debtPriceOracle), - positionDebtTa: publicKey(this.positionDebtTa), - authorityDebtTa: this.selfManaged - ? publicKey(getTokenAccount(this.authority, this.debtMint)) - : undefined, - vaultDebtTa: needDebtAccounts - ? publicKey(this.marginfiDebtAccounts.liquidityVault) - : undefined, - debtVaultAuthority: needDebtAccounts - ? publicKey(this.marginfiDebtAccounts.vaultAuthority) - : undefined, - rebalanceType, - targetLiqUtilizationRateBps: targetLiqUtilizationRateBps ?? null, - targetInAmountBaseUnit: parseInt(jupQuote.inAmount), - }); - } - - flashBorrow( - flashLoanDetails: FlashLoanDetails, - destinationTokenAccount: PublicKey - ): TransactionBuilder { - const bank = flashLoanDetails.mint.equals(this.supplyMint) - ? this.marginfiSupplyAccounts - : this.marginfiDebtAccounts; - return transactionBuilder() - .add( - lendingAccountStartFlashloan(this.umi, { - endIndex: 0, // We set this after building the transaction - ixsSysvar: publicKey(SYSVAR_INSTRUCTIONS_PUBKEY), - marginfiAccount: publicKey(this.intermediaryMarginfiAccountPk), - signer: this.signer, - }) - ) - .add( - lendingAccountBorrow(this.umi, { - amount: flashLoanDetails.baseUnitAmount, - bank: publicKey(bank.bank), - bankLiquidityVault: publicKey(bank.liquidityVault), - bankLiquidityVaultAuthority: publicKey(bank.vaultAuthority), - destinationTokenAccount: publicKey(destinationTokenAccount), - marginfiAccount: publicKey(this.intermediaryMarginfiAccountPk), - marginfiGroup: publicKey(this.marginfiGroup), - signer: this.signer, - }) - ); - } - - flashRepay(flashLoanDetails: FlashLoanDetails): TransactionBuilder { - const accounts = flashLoanDetails.useDebtLiquidity - ? { data: this.marginfiDebtAccounts, oracle: this.debtPriceOracle } - : { data: this.marginfiSupplyAccounts, oracle: this.supplyPriceOracle }; - - const remainingAccounts: AccountMeta[] = []; - let includedFlashLoanToken = false; - - if (this.intermediaryMarginfiAccount) { - this.intermediaryMarginfiAccount.lendingAccount.balances.forEach( - async (x) => { - if (x.active) { - if (x.bankPk === accounts.data.bank) { - includedFlashLoanToken = true; - } - - // TODO: Don't dynamically pull from bank until Marginfi sorts out their price oracle issues. - // const bankData = await safeFetchBank(this.umi, publicKey(accounts.data.bank)); - // const priceOracle = bankData!.config.oracleKeys[0]; - const priceOracle = publicKey( - findMarginfiAccounts(toWeb3JsPublicKey(x.bankPk)).priceOracle - ); - - remainingAccounts.push( - ...[ - { - pubkey: x.bankPk, - isSigner: false, - isWritable: false, - }, - { - pubkey: priceOracle, - isSigner: false, - isWritable: false, - }, - ] - ); - } - } - ); - } - if (!this.intermediaryMarginfiAccount || !includedFlashLoanToken) { - remainingAccounts.push( - ...[ - { - pubkey: fromWeb3JsPublicKey(new PublicKey(accounts.data.bank)), - isSigner: false, - isWritable: false, - }, - { - pubkey: fromWeb3JsPublicKey(new PublicKey(accounts.oracle)), - isSigner: false, - isWritable: false, - }, - ] - ); - } - - return transactionBuilder() - .add( - lendingAccountRepay(this.umi, { - amount: flashLoanDetails.baseUnitAmount, - repayAll: null, - bank: publicKey(accounts.data.bank), - bankLiquidityVault: publicKey(accounts.data.liquidityVault), - marginfiAccount: publicKey(this.intermediaryMarginfiAccountPk), - marginfiGroup: publicKey(this.marginfiGroup), - signer: this.signer, - signerTokenAccount: publicKey( - getTokenAccount( - toWeb3JsPublicKey(this.signer.publicKey), - flashLoanDetails.mint - ) - ), - }) - ) - .add( - lendingAccountEndFlashloan(this.umi, { - marginfiAccount: publicKey(this.intermediaryMarginfiAccountPk), - signer: this.signer, - }).addRemainingAccounts(remainingAccounts) - ); - } - - async getFreshPositionState(): Promise { - const state = await super.getFreshPositionState(); - if (state) { - return state; - } - - const useDesignatedMint = - !this.selfManaged && - (this.solautoPositionData === null || - !toWeb3JsPublicKey(this.signer.publicKey).equals(this.authority)); - - const freshState = await getMarginfiAccountPositionState( - this.umi, - { pk: this.marginfiAccountPk }, - this.marginfiGroup, - useDesignatedMint ? { mint: this.supplyMint } : undefined, - useDesignatedMint ? { mint: this.debtMint } : undefined, - this.livePositionUpdates - ); - - if (freshState) { - this.log("Fresh state", freshState); - const supplyPrice = safeGetPrice(freshState?.supply.mint)!; - const debtPrice = safeGetPrice(freshState?.debt.mint)!; - this.log("Supply price: ", supplyPrice); - this.log("Debt price: ", debtPrice); - this.log("Liq threshold bps:", freshState.liqThresholdBps); - this.log("Liq utilization rate bps:", freshState.liqUtilizationRateBps); - this.log( - "Supply USD:", - fromBaseUnit( - freshState.supply.amountUsed.baseUnit, - freshState.supply.decimals - ) * supplyPrice - ); - this.log( - "Debt USD:", - fromBaseUnit( - freshState.debt.amountUsed.baseUnit, - freshState.debt.decimals - ) * debtPrice - ); - } - - return freshState; - } -} diff --git a/solauto-sdk/src/clients/txHandler.ts b/solauto-sdk/src/clients/txHandler.ts deleted file mode 100644 index 91eb28ed..00000000 --- a/solauto-sdk/src/clients/txHandler.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Signer, Umi } from "@metaplex-foundation/umi"; -import { Connection, PublicKey } from "@solana/web3.js"; -import { - consoleLog, - getSolanaRpcConnection, -} from "../utils"; -import { SOLAUTO_PROD_PROGRAM } from "../constants"; - -export abstract class TxHandler { - public connection!: Connection; - public umi!: Umi; - public signer!: Signer; - public otherSigners: Signer[] = []; - - constructor( - public rpcUrl: string, - localTest?: boolean, - public programId: PublicKey = SOLAUTO_PROD_PROGRAM - ) { - const [connection, umi] = getSolanaRpcConnection(this.rpcUrl, this.programId); - this.connection = connection; - this.umi = umi; - - if (!(globalThis as any).LOCAL_TEST && localTest) { - (globalThis as any).LOCAL_TEST = Boolean(localTest); - } - } - - log(...args: any[]): void { - consoleLog(...args); - } - - abstract defaultLookupTables(): string[]; - - abstract resetLiveTxUpdates(success?: boolean): Promise; -} diff --git a/solauto-sdk/src/constants/README.md b/solauto-sdk/src/constants/README.md deleted file mode 100644 index 01238c8b..00000000 --- a/solauto-sdk/src/constants/README.md +++ /dev/null @@ -1,7 +0,0 @@ -Instructions for supporting new token: - -- add public key to tokenConstants.ts -- add price feed in pythConstants.ts for it -- create ATA for solauto fees wallet -- `pnpm update-solauto-lut` -- `pnpm test:ts:unit` \ No newline at end of file diff --git a/solauto-sdk/src/constants/generalAccounts.ts b/solauto-sdk/src/constants/generalConstants.ts similarity index 53% rename from solauto-sdk/src/constants/generalAccounts.ts rename to solauto-sdk/src/constants/generalConstants.ts index 4273244c..08682b23 100644 --- a/solauto-sdk/src/constants/generalAccounts.ts +++ b/solauto-sdk/src/constants/generalConstants.ts @@ -1,5 +1,10 @@ import { PublicKey } from "@solana/web3.js"; +import { buildIronforgeApiUrl } from "../utils"; export const USD_DECIMALS = 9; export const SOLAUTO_FEES_WALLET = new PublicKey("AprYCPiVeKMCgjQ2ZufwChMzvQ5kFjJo2ekTLSkXsQDm"); -export const SOLAUTO_MANAGER = new PublicKey("MNGRcX4nc7quPdzBbNKJ4ScK5EE73JnwJVGxuJXhHCY"); \ No newline at end of file +export const SOLAUTO_MANAGER = new PublicKey("MNGRcX4nc7quPdzBbNKJ4ScK5EE73JnwJVGxuJXhHCY"); + +export const LOCAL_IRONFORGE_API_URL = buildIronforgeApiUrl(process.env.IRONFORGE_API_KEY!); + +export const BASIS_POINTS = 10000; diff --git a/solauto-sdk/src/constants/index.ts b/solauto-sdk/src/constants/index.ts index 4e040d41..016ae8d9 100644 --- a/solauto-sdk/src/constants/index.ts +++ b/solauto-sdk/src/constants/index.ts @@ -1,5 +1,6 @@ -export * from './generalAccounts'; -export * from './marginfiAccounts'; -export * from './pythConstants'; -export * from './solautoConstants'; -export * from './tokenConstants'; +export * from "./generalConstants"; +export * from "./marginfiAccounts"; +export * from "./pythConstants"; +export * from "./solautoConstants"; +export * from "./switchboardConstants"; +export * from "./tokenConstants"; diff --git a/solauto-sdk/src/constants/marginfiAccounts.ts b/solauto-sdk/src/constants/marginfiAccounts.ts index a80e0e6c..f9246a75 100644 --- a/solauto-sdk/src/constants/marginfiAccounts.ts +++ b/solauto-sdk/src/constants/marginfiAccounts.ts @@ -1,133 +1,142 @@ +import { PublicKey } from "@solana/web3.js"; import { NATIVE_MINT } from "@solana/spl-token"; import * as tokens from "./tokenConstants"; import { MarginfiAssetAccounts } from "../types/accounts"; -import { PublicKey } from "@solana/web3.js"; -import { SWITCHBOARD_PRICE_FEED_IDS } from "./switchboardConstants"; +import { ProgramEnv } from "../types"; -export const DEFAULT_MARGINFI_GROUP = - "4qp6Fx6tnZkY5Wropq9wUYgtFxXKwE6viZxFHg3rdAG8"; +const MARGINFI_PROD_PROGRAM = new PublicKey( + "MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA" +); +const MARGINFI_STAGING_PROGRAM = new PublicKey( + "stag8sTKds2h4KzjUw3zKTsxbqvT4XKHdaR9X9E6Rct" +); -export const DEFAULT_PUBKEY = PublicKey.default.toString(); +const PROD_DEFAULT_MARGINFI_GROUP = + "4qp6Fx6tnZkY5Wropq9wUYgtFxXKwE6viZxFHg3rdAG8"; -const USDC_PRICE_ORACLE = "Dpw1EAVrSB1ibxiDQyTAW6Zip3J4Btk2x4SgApQCeFbX"; +const STAGING_DEFAULT_MARGINFI_GROUP = + "FCPfpHA69EbS8f9KKSreTRkXbzFpunsKuYf5qNmnJjpo"; -export const MARGINFI_ACCOUNTS: { +export type MarginfiBankAccountsMap = { [group: string]: { [token: string]: MarginfiAssetAccounts }; -} = { - [DEFAULT_MARGINFI_GROUP.toString()]: { +}; + +const MARGINFI_STAGING_ACCOUNTS: MarginfiBankAccountsMap = { + [STAGING_DEFAULT_MARGINFI_GROUP]: { + [NATIVE_MINT.toString()]: { + bank: "3evdJSa25nsUiZzEUzd92UNa13TPRJrje1dRyiQP5Lhp", + liquidityVault: "FVXESa7wCd1tf3o9LGroBc3Ym8Gpcq1HdsLek6oo7Ykv", + vaultAuthority: "DuYk1WGq8UsjW5ThLtaehFLrnJeupTjtF7TaPzja9LBQ", + }, + [tokens.USDC]: { + bank: "Ek5JSFJFD8QgXM6rPDCzf31XhDp1q3xezaWYSkJWqbqc", + liquidityVault: "6n7xXMni5WJKUMb4Vm5Zis6UaUtGF5xEGmagZNVWWoKB", + vaultAuthority: "9mXNyA5yS4WSTpYUa5gi3yBrSJWWM7XNPNDWRzWGjdVe", + }, + [tokens.USDT]: { + bank: "4WFCsVXwfnQvZG52VvPwae7CtL13PUFVWdjkw5YCRBo6", + liquidityVault: "BFSyniKfXU9rHqUvHLKeZMivQsAKWTE7HZ1fW6vZcvJp", + vaultAuthority: "Fgxe3SUMzcNuLtT9Xkv8QhhWXCmu4VxynzUMwCF4HvJd", + }, + }, +}; + +const MARGINFI_PROD_ACCOUNTS: MarginfiBankAccountsMap = { + [PROD_DEFAULT_MARGINFI_GROUP.toString()]: { [NATIVE_MINT.toString()]: { bank: "CCKtUs6Cgwo4aaQUmBPmyoApH2gUDErxNZCAntD6LYGh", liquidityVault: "2eicbpitfJXDwqCuFAmPgDP7t2oUotnAzbGzRKLMgSLe", vaultAuthority: "DD3AeAssFvjqTvRTrRAtpfjkBF8FpVKnFuwnMLN9haXD", - priceOracle: "7UVimffxr9ow1uXYxsr4LHAcV58mLzhmwaeKvJ1pjLiE", }, [tokens.B_SOL]: { bank: "6hS9i46WyTq1KXcoa2Chas2Txh9TJAVr6n1t3tnrE23K", liquidityVault: "2WMipeKDB2CENxbzdmnVrRbsxCA2LY6kCtBe6AAqDP9p", vaultAuthority: "8RcZHucpVHkHWRRdMhJZsxBK9mqKSYnMKGqtF84U8YEo", - priceOracle: "5cN76Xm2Dtx9MnrQqBDeZZRsWruTTcw37UruznAdSvvE", }, [tokens.M_SOL]: { bank: "22DcjMZrMwC5Bpa5AGBsmjc5V9VuQrXG6N9ZtdUNyYGE", liquidityVault: "B6HqNn83a2bLqo4i5ygjLHJgD11ePtQksUyx4MjD55DV", vaultAuthority: "6YxGd65JbXzgFGWjE44jsyVeCnZp7Bb1wfL9jDia1n8w", - priceOracle: "5CKzb9j4ChgLUt8Gfm5CNGLN6khXKiqMbnGAW4cgXgxK", }, [tokens.JITO_SOL]: { bank: "Bohoc1ikHLD7xKJuzTyiTyCwzaL5N7ggJQu75A8mKYM8", liquidityVault: "38VGtXd2pDPq9FMh1z6AVjcHCoHgvWyMhdNyamDTeeks", vaultAuthority: "7Ng54qf7BrCcZLqXmKA9WSR7SVRn4q6RX1YpLksBQ21A", - priceOracle: "AxaxyeDT8JnWERSaTKvFXvPKkEdxnamKSqpWbsSjYg1g", }, [tokens.LST]: { bank: "DMoqjmsuoru986HgfjqrKEvPv8YBufvBGADHUonkadC5", liquidityVault: "DMQUXpb6K5L8osgV4x3NeEPUoJCf2VBgnA8FQusDjSou", vaultAuthority: "6PWVauGLhBFHUJspsnBVZHr56ZnbvmhSD2gS7czBHGpE", - priceOracle: "7aT9A5knp62jVvnEW33xaWopaPHa3Y7ggULyYiUsDhu8", }, [tokens.INF]: { bank: "AwLRW3aPMMftXEjgWhTkYwM9CGBHdtKecvahCJZBwAqY", liquidityVault: "HQ1CGcqRshMhuonTGTnnmgw9ffcXxizGdZ6F6PKffWWi", vaultAuthority: "AEZb1XH5bfLwqk3hBKDuLfWyJKdLTgDPCkgn64BJKcvV", - priceOracle: "Ceg5oePJv1a6RR541qKeQaTepvERA3i8SvyueX9tT8Sq", }, [tokens.H_SOL]: { bank: "GJCi1uj3kYPZ64puA5sLUiCQfFapxT2xnREzrbDzFkYY", liquidityVault: "8M97jkdr4rJtPnQ4yQ9stD6qVwaUvjrBdDPDbHJnPJLf", vaultAuthority: "8x7mgTn5RvHR8Tn3CJqexSuQwrs6MLEy8csuXCDVvvpt", - priceOracle: SWITCHBOARD_PRICE_FEED_IDS[tokens.H_SOL.toString()], }, [tokens.JUP_SOL]: { bank: "8LaUZadNqtzuCG7iCvZd7d5cbquuYfv19KjAg6GPuuCb", liquidityVault: "B1zjqKPoYp9bTMhzFADaAvjyGb49FMitLpi6P3Pa3YR6", vaultAuthority: "93Qqsge2jHVsWLd8vas4cWghrsZJooMUr5JKN5DtcfMX", - priceOracle: SWITCHBOARD_PRICE_FEED_IDS[tokens.JUP_SOL.toString()], }, [tokens.JUP]: { bank: "Guu5uBc8k1WK1U2ihGosNaCy57LSgCkpWAabtzQqrQf8", liquidityVault: "4w49W4fNDn778wsBa6TNq9hvebZKU17ymsptrEZ8zrsm", vaultAuthority: "2MBwwAhL3c73Jy7HkWd9ofzh1bU39JBabrZCFQR2tUof", - priceOracle: "7dbob1psH1iZBS7qPsm3Kwbf5DzSXK8Jyg31CTgTnxH5", }, [tokens.JTO]: { bank: "EdB7YADw4XUt6wErT8kHGCUok4mnTpWGzPUU9rWDebzb", liquidityVault: "3bY1DEkXodGmPMG5f7ABA12228MBG5JdAAKf5cgkB6G1", vaultAuthority: "H2b4f2fGSKFortxwzrMZBnYVfr2yrKVUakg4Md9be3Wv", - priceOracle: "7ajR2zA4MGMMTqRAVjghTKqPPn4kbrj3pYkAVRVwTGzP", }, [tokens.JLP]: { bank: "Amtw3n7GZe5SWmyhMhaFhDTi39zbTkLeWErBsmZXwpDa", liquidityVault: "9xfyL8gxbV77VvhdgFmacHyLEG4h7d2eDWkSMfhXUPQ", vaultAuthority: "F4RSGd4BRXscCqAVG3rFLiPVpo7v6j1drVqnvSM3rBKH", - priceOracle: "B1wxT1VK3i6DqCeXNdTHT5hBAJkLa3rxuTqBc7E7XRXV", }, [tokens.WBTC]: { bank: "BKsfDJCMbYep6gr9pq8PsmJbb5XGLHbAJzUV8vmorz7a", liquidityVault: "CMNdnjfaDQZo3VMoX31wZQBnSGu5FMmb1CnBaU4tApZk", vaultAuthority: "7P2TQHYgVJkXv1VPaREsL5Pi1gnNjVif5aF3pJewZ9kj", - priceOracle: "4cSM2e6rvbGQUFiJbqytoVMi5GgghSMr8LwVrT9VPSPo", }, [tokens.WETH]: { bank: "BkUyfXjbBBALcfZvw76WAFRvYQ21xxMWWeoPtJrUqG3z", liquidityVault: "AxPJtiTEDksJWvCqNHCziK4uUcabqfmwW41dqtZrPFkp", vaultAuthority: "ELXogWuyXrFyUG1vevffVbEhVxdFrHf2GCJTtRGKBWdM", - priceOracle: "42amVS4KgzR9rA28tkVYqVXjq9Qa8dcZQMbH5EYFX6XC", }, [tokens.HNT]: { bank: "JBcir4DPRPYVUpks9hkS1jtHMXejfeBo4xJGv3AYYHg6", liquidityVault: "E8Q7u5e9L9Uykx16em75ERT9wfbBPtkNL8gsRjoP8GB9", vaultAuthority: "AjsyrYpgaH275DBSnvNWdGK33hVycSFuXN87FKnX6fVY", - priceOracle: "4DdmDswskDxXGpwHrXUfn2CNUm9rt21ac79GHNTN3J33", }, [tokens.PYTH]: { bank: "E4td8i8PT2BZkMygzW4MGHCv2KPPs57dvz5W2ZXf9Twu", liquidityVault: "DUrAkkaMAckzes7so9T5frXm9YFFgjAAm3MMwHwTfVJq", vaultAuthority: "9b5KdVnbbfEQ2qhLeFjWvcAx2VWe9XHx7ZgayZyL9a6C", - priceOracle: "8vjchtMuJNY4oFQdTi8yCe6mhCaNBFaUbktT482TpLPS", }, [tokens.USDC]: { bank: "2s37akK2eyBbp8DZgCm7RtsaEz8eJP3Nxd4urLHQv7yB", liquidityVault: "7jaiZR5Sk8hdYN9MxTpczTcwbWpb5WEoxSANuUwveuat", vaultAuthority: "3uxNepDbmkDNq6JhRja5Z8QwbTrfmkKP8AKZV5chYDGG", - priceOracle: USDC_PRICE_ORACLE, }, [tokens.USDT]: { bank: "HmpMfL8942u22htC4EMiWgLX931g3sacXFR6KjuLgKLV", liquidityVault: "77t6Fi9qj4s4z22K1toufHtstM8rEy7Y3ytxik7mcsTy", vaultAuthority: "9r6z6KgkEytHCdQWNxvDQH98PsfU98f1m5PCg47mY2XE", - priceOracle: "HT2PLQBcG5EiCcNSaMHAjSgd9F98ecpATbk4Sk5oYuM", }, [tokens.BONK]: { bank: "DeyH7QxWvnbbaVB4zFrf4hoq7Q8z1ZT14co42BGwGtfM", liquidityVault: "7FdQsXmCW3N5JQbknj3F9Yqq73er9VZJjGhEEMS8Ct2A", vaultAuthority: "26kcZkdjJc94PdhqiLiEaGiLCYgAVVUfpDaZyK4cqih3", - priceOracle: "DBE3N8uNjhKPRHfANdwGvCZghWXyLPdqdSbEW2XFwBiX", }, [tokens.WIF]: { bank: "9dpu8KL5ABYiD3WP2Cnajzg1XaotcJvZspv29Y1Y3tn1", liquidityVault: "4kT3EXc5dDVndUU9mV6EH3Jh3CSEvpcCZjuMkwqrtxUy", vaultAuthority: "9gNrvvZ9RuTyRWooiEEypwcXU6kyXW8yWuhXU8tWUH5L", - priceOracle: "6B23K3tkb51vLZA14jcEQVCA1pfHptzEHFA93V5dYwbT", }, }, ["DQ2jqDJw9uzTwttf6h6r217BQ7kws3jZbJXDkfbCJa1q"]: { @@ -135,13 +144,11 @@ export const MARGINFI_ACCOUNTS: { bank: "845oEvt1oduoBj5zQxTr21cWWaUVnRjGerJuW3yMo2nn", liquidityVault: "At6R64ip51zay4dT6k1WnVGETSMcaiY5vggD5DVTgxri", vaultAuthority: "dNraDCWb5usDSoW4kD1Mi2E9WsNu6EABcQZqnrDfjNb", - priceOracle: SWITCHBOARD_PRICE_FEED_IDS[tokens.POPCAT.toString()], }, [tokens.USDC]: { bank: "EXrnNVfLagt3j4hCHSD9WqK75o6dkZBtjpnrSrSC78MA", liquidityVault: "D9HSUYz3Rg2cTH65dUPaQS1MYxofNTeLecsAjiBgVPur", vaultAuthority: "5ivKgJnxQ9CewJcKYSPQUiQFdfJki6YS87FqohnMSsFM", - priceOracle: USDC_PRICE_ORACLE, }, }, ["EpzY5EYF1A5eFDRfjtsPXSYMPmEx1FXKaXPnouTMF4dm"]: { @@ -149,13 +156,11 @@ export const MARGINFI_ACCOUNTS: { bank: "3J5rKmCi7JXG6qmiobFJyAidVTnnNAMGj4jomfBxKGRM", liquidityVault: "863K9YPVT3xbUGFZevrQJLqMux3UdRkwNQ6usAp4hJyy", vaultAuthority: "Qsv2rnNRdv59AwRU3YmGPMCTdKT41CDAKyYAr4srCJR", - priceOracle: SWITCHBOARD_PRICE_FEED_IDS[tokens.RETARDIO.toString()], }, [tokens.USDC]: { bank: "6cgYhBFWCc5sNHxkvSRhd5H9AdAHR41zKwuF37HmLry5", liquidityVault: "7orVfNL5ZjqvdSaDgYLgBk4i5B3AnwFXNqqAvJbx6DFy", vaultAuthority: "G4Azxk4PYtNRmDZkJppYo3rNAinkZXzYpQPG5dVDh4Nj", - priceOracle: USDC_PRICE_ORACLE, }, }, ["G1rt3EpQ43K3bY457rhukQGRAo2QxydFAGRKqnjKzyr5"]: { @@ -163,13 +168,11 @@ export const MARGINFI_ACCOUNTS: { bank: "Dj3PndQ3j1vuga5ApiFWWAfQ4h3wBtgS2SeLZBT2LD4g", liquidityVault: "BRcRMDVPBQzXNXWtSS6bNotcGxhVsxfiAt1qf8nFVUpx", vaultAuthority: "36SgFh1qBRyj1PEhsn7Kg9Sfwbrn7rHP7kvTM5o5n6AL", - priceOracle: SWITCHBOARD_PRICE_FEED_IDS[tokens.BILLY.toString()], }, [tokens.USDC]: { bank: "A7vBgCowCYeja7GTc3pyqUBdC9Gkue2gWaMjGZW38meM", liquidityVault: "DBGhZ8TJTG2Pacdva27zY9etaro24o1tTA3LToSjYHbx", vaultAuthority: "Cg6BCqkGny7A2AXCV8rikhHXM82wqqfzmdsTobEeTQkH", - priceOracle: USDC_PRICE_ORACLE, }, }, ["DESG67cExEcw7d6MmENLEzaocR8pLrhfiw9VrNtGWUKD"]: { @@ -177,16 +180,64 @@ export const MARGINFI_ACCOUNTS: { bank: "Br3yzg2WSb81RaFWK9UsKtq8fD5viwooZG34mKqQWxdM", liquidityVault: "J45Je52qv2rDBuCQWPwp3bjRhf3bGzRWhKZtGDuLooCX", vaultAuthority: "CKDsAKjNruDSz4tmUairh8PDGD1Rqh9WMTLWERYnnZrH", - priceOracle: SWITCHBOARD_PRICE_FEED_IDS[tokens.HMTR.toString()], }, [tokens.USDC]: { bank: "9yNnhJ8c1vGbu3DMf6eeeUi6TDJ2ddGgaRA88rL2R3rP", liquidityVault: "4U1UBjXrPrW7JuQ894JbLUBqcb5LFfK9rfkWFwT7EdQ9", vaultAuthority: "CY74V1r48kuuHA6APD3AaU2oPV1mBqe9srikrQQSHNR6", - priceOracle: USDC_PRICE_ORACLE, - } - } + }, + }, }; -export const MARGINFI_ACCOUNTS_LOOKUP_TABLE = +const MARGINFI_PROD_ACCOUNTS_LOOKUP_TABLE = "GAjmWmBPcH5Gxbiykasydj6RsCEaCLyHEvK6kHdFigc6"; + +const MARGINFI_STAGING_ACCOUNTS_LOOKUP_TABLE = + "EoEVYjz3MnsX6fKyxrwJkRhzMCHKjj6dvnjTCHoZLMc7"; + +export interface MarginfiProgramAccounts { + program: PublicKey; + defaultGroup: PublicKey; + lookupTable: PublicKey; + bankAccounts: MarginfiBankAccountsMap; +} + +export function getMarginfiAccounts( + programEnv?: ProgramEnv, + marginfiGroup?: PublicKey +): MarginfiProgramAccounts { + if (programEnv === undefined) { + if (Boolean(marginfiGroup)) { + programEnv = Object.keys(MARGINFI_PROD_ACCOUNTS).includes( + marginfiGroup!.toString() + ) + ? "Prod" + : "Staging"; + } else { + programEnv = "Prod"; + } + } + + if (programEnv === "Prod") { + return { + program: MARGINFI_PROD_PROGRAM, + defaultGroup: new PublicKey(PROD_DEFAULT_MARGINFI_GROUP), + lookupTable: new PublicKey(MARGINFI_PROD_ACCOUNTS_LOOKUP_TABLE), + bankAccounts: MARGINFI_PROD_ACCOUNTS, + }; + } else { + return { + program: MARGINFI_STAGING_PROGRAM, + defaultGroup: new PublicKey(STAGING_DEFAULT_MARGINFI_GROUP), + lookupTable: new PublicKey(MARGINFI_STAGING_ACCOUNTS_LOOKUP_TABLE), + bankAccounts: MARGINFI_STAGING_ACCOUNTS, + }; + } +} + +export function isMarginfiProgram(programId: PublicKey) { + return ( + programId.equals(MARGINFI_PROD_PROGRAM) || + programId.equals(MARGINFI_STAGING_PROGRAM) + ); +} diff --git a/solauto-sdk/src/constants/pythConstants.ts b/solauto-sdk/src/constants/pythConstants.ts index a783911e..6db1af73 100644 --- a/solauto-sdk/src/constants/pythConstants.ts +++ b/solauto-sdk/src/constants/pythConstants.ts @@ -1,5 +1,13 @@ import { NATIVE_MINT } from "@solana/spl-token"; import * as tokens from "./tokenConstants"; +import { PublicKey } from "@solana/web3.js"; + +export const PYTH_PUSH_PROGRAM = new PublicKey( + "pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT" +); + +export const PYTH_SPONSORED_SHARD_ID = 0; +export const MARGINFI_SPONSORED_SHARD_ID = 3301; // https://pyth.network/developers/price-feed-ids#solana-stable export const PYTH_PRICE_FEED_IDS = { diff --git a/solauto-sdk/src/constants/solautoConstants.ts b/solauto-sdk/src/constants/solautoConstants.ts index cc8d1e25..c87fb8db 100644 --- a/solauto-sdk/src/constants/solautoConstants.ts +++ b/solauto-sdk/src/constants/solautoConstants.ts @@ -9,7 +9,7 @@ import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, } from "@solana/spl-token"; -import { SOLAUTO_MANAGER } from "./generalAccounts"; +import { SOLAUTO_MANAGER } from "./generalConstants"; import { JUPITER_PROGRAM_ID } from "../jupiter-sdk"; export const SOLAUTO_PROD_PROGRAM = new PublicKey( @@ -19,18 +19,39 @@ export const SOLAUTO_TEST_PROGRAM = new PublicKey( "TesTjfQ6TbXv96Tv6fqr95XTZ1LYPxtkafmShN9PjBp" ); -(globalThis as any).LOCAL_TEST = false; +(globalThis as any).SHOW_LOGS = false; -export const BASIS_POINTS = 10000; - -export const MIN_POSITION_STATE_FRESHNESS_SECS = 5; export const MIN_REPAY_GAP_BPS = 50; export const MIN_BOOST_GAP_BPS = 50; export const MIN_USD_SUPPORTED_POSITION = 1000; -export const PRICES: { [key: string]: { price: number; time: number } } = {}; +export const OFFSET_FROM_MAX_LTV = 0.005; + +export const REFERRER_PERCENTAGE = 0.15; + +interface PriceCache { + realtimePrice: number; + confInterval: number; + emaPrice: number; + emaConfInterval: number; + time: number; +} +export const PRICES: { [key: string]: PriceCache } = {}; -export const SOLAUTO_LUT = "9D4xwZwDf46n9ft5gQxZzq3rBbdRXsXojKQLZbBdskPY"; +export const CHORES_TX_NAME = "account chores"; + +export const JITO_TIP_ACCOUNTS = [ + "96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5", + "HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe", + "Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY", + "ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49", + "DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh", + "ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt", + "DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL", + "3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT", +]; + +export const SOLAUTO_LUT = "8b7KefQDroVLGao71J5H3hFwABeyMCgCrLpXWssNFhk9"; export const STANDARD_LUT_ACCOUNTS = [ PublicKey.default, SOLAUTO_PROD_PROGRAM, @@ -44,5 +65,3 @@ export const STANDARD_LUT_ACCOUNTS = [ SYSVAR_INSTRUCTIONS_PUBKEY, JUPITER_PROGRAM_ID, ].map((x) => x.toString()); - -export const JITO_BLOCK_ENGINE = "https://mainnet.block-engine.jito.wtf"; \ No newline at end of file diff --git a/solauto-sdk/src/constants/switchboardConstants.ts b/solauto-sdk/src/constants/switchboardConstants.ts index c4791dfe..bd2110eb 100644 --- a/solauto-sdk/src/constants/switchboardConstants.ts +++ b/solauto-sdk/src/constants/switchboardConstants.ts @@ -1,11 +1,40 @@ import * as tokens from "./tokenConstants"; +interface SwitchboardFeed { + feedId: string; + feedHash: string; +} + // https://beta.ondemand.switchboard.xyz/solana/mainnet -export const SWITCHBOARD_PRICE_FEED_IDS: { [key: string]: string } = { - [tokens.JUP_SOL]: "HX5WM3qzogAfRCjBUWwnniLByMfFrjm1b5yo4KoWGR27", - [tokens.H_SOL]: "1snBjCaHejZqQsAqkELAKNaqUrDNNCr7zmNX6qaQCzg", - [tokens.POPCAT]: "FTcFqwCjAgv2VMaowQ9XSBcesVzFzZkaju25nKio6bki", - [tokens.RETARDIO]: "EvPXnpMoyrj4B6P55LDP2VpSLkTBWom2SqL4486ToNhM", - [tokens.BILLY]: "uBe4er4VSMgYvBNwSbFctSShRXNPkCfaPh7zHMBFeBi", - [tokens.HMTR]: "F2hKL67W4ZDe9k7ZrJKnp2LhWrgqg2JQTkJf2dgBggRD", +export const SWITCHBOARD_PRICE_FEED_IDS: { [key: string]: SwitchboardFeed } = { + [tokens.JUP_SOL]: { + feedId: "HX5WM3qzogAfRCjBUWwnniLByMfFrjm1b5yo4KoWGR27", + feedHash: + "0xc02f22d47b20b43bafde474328ac027283dbd7bb443660f5ec414c93faec56dc", + }, + [tokens.H_SOL]: { + feedId: "1snBjCaHejZqQsAqkELAKNaqUrDNNCr7zmNX6qaQCzg", + feedHash: + "0x59206aa3da593cd2312bde1930cf3368f6119a650229e147060be4fc2fcd1367", + }, + [tokens.POPCAT]: { + feedId: "FTcFqwCjAgv2VMaowQ9XSBcesVzFzZkaju25nKio6bki", + feedHash: + "0xeb4f9a43024f8f33786b7291404510af8e94a66e1acb44953a3137878ee7033f", + }, + [tokens.RETARDIO]: { + feedId: "EvPXnpMoyrj4B6P55LDP2VpSLkTBWom2SqL4486ToNhM", + feedHash: + "0x982d968a0608046986aec84d95ae884c4dc2140f0b3e14ed7b8161ada573d18b", + }, + [tokens.BILLY]: { + feedId: "uBe4er4VSMgYvBNwSbFctSShRXNPkCfaPh7zHMBFeBi", + feedHash: + "0xbbd0d393111ff1ad7cc1a2f15ce24b61d4d6b3e99e440aa77572bd7f1da9afbe", + }, + [tokens.HMTR]: { + feedId: "F2hKL67W4ZDe9k7ZrJKnp2LhWrgqg2JQTkJf2dgBggRD", + feedHash: + "0x61999c4f8a03208b5b5b50663323b1ef8d0acbb3642ec79053b33b5768605fb5", + }, }; diff --git a/solauto-sdk/src/constants/tokenConstants.ts b/solauto-sdk/src/constants/tokenConstants.ts index e0f88fd0..05c72e13 100644 --- a/solauto-sdk/src/constants/tokenConstants.ts +++ b/solauto-sdk/src/constants/tokenConstants.ts @@ -51,7 +51,7 @@ export const ALL_SUPPORTED_TOKENS = [ HMTR, ]; -interface TokenInfo { +export interface TokenInfo { ticker: string; decimals: number; isStableCoin?: boolean; @@ -118,12 +118,12 @@ export const TOKEN_INFO: { [key: string]: TokenInfo } = { decimals: 6, }, [WBTC]: { - ticker: "wBTC", + ticker: "WBTC", decimals: 8, isMajor: true, }, [WETH]: { - ticker: "wETH", + ticker: "WETH", decimals: 8, isMajor: true, }, @@ -176,3 +176,9 @@ export const TOKEN_INFO: { [key: string]: TokenInfo } = { isMeme: true, }, }; + +export const MAJORS_PRIO = { + [WBTC]: 0, + [WETH]: 1, + [NATIVE_MINT.toString()]: 2, +}; \ No newline at end of file diff --git a/solauto-sdk/src/generated/accounts/solautoPosition.ts b/solauto-sdk/src/generated/accounts/solautoPosition.ts index 442a15d3..ff32c636 100644 --- a/solauto-sdk/src/generated/accounts/solautoPosition.ts +++ b/solauto-sdk/src/generated/accounts/solautoPosition.ts @@ -88,7 +88,7 @@ export function getSolautoPositionAccountDataSerializer(): Serializer< ['position', getPositionDataSerializer()], ['state', getPositionStateSerializer()], ['rebalance', getRebalanceDataSerializer()], - ['padding', array(u32(), { size: 32 })], + ['padding', array(u32(), { size: 20 })], ], { description: 'SolautoPositionAccountData' } ) as Serializer; @@ -188,7 +188,7 @@ export function getSolautoPositionGpaBuilder( position: [40, getPositionDataSerializer()], state: [360, getPositionStateSerializer()], rebalance: [648, getRebalanceDataSerializer()], - padding: [704, array(u32(), { size: 32 })], + padding: [752, array(u32(), { size: 20 })], }) .deserializeUsing((account) => deserializeSolautoPosition(account) diff --git a/solauto-sdk/src/generated/errors/solauto.ts b/solauto-sdk/src/generated/errors/solauto.ts index c9cc38fa..9c5f6767 100644 --- a/solauto-sdk/src/generated/errors/solauto.ts +++ b/solauto-sdk/src/generated/errors/solauto.ts @@ -15,7 +15,7 @@ type ProgramErrorConstructor = new ( const codeToErrorMap: Map = new Map(); const nameToErrorMap: Map = new Map(); -/** IncorrectAccounts: Missing or incorrect accounts provided for the given instruction */ +/** IncorrectAccounts: Missing or incorrect accounts provided for the given instructions */ export class IncorrectAccountsError extends ProgramError { override readonly name: string = 'IncorrectAccounts'; @@ -23,7 +23,7 @@ export class IncorrectAccountsError extends ProgramError { constructor(program: Program, cause?: Error) { super( - 'Missing or incorrect accounts provided for the given instruction', + 'Missing or incorrect accounts provided for the given instructions', program, cause ); @@ -48,89 +48,145 @@ nameToErrorMap.set( FailedAccountDeserializationError ); -/** InvalidPositionSettings: Invalid position settings provided */ -export class InvalidPositionSettingsError extends ProgramError { - override readonly name: string = 'InvalidPositionSettings'; +/** InvalidBoostToSetting: Invalid Boost-to param */ +export class InvalidBoostToSettingError extends ProgramError { + override readonly name: string = 'InvalidBoostToSetting'; readonly code: number = 0x2; // 2 constructor(program: Program, cause?: Error) { - super('Invalid position settings provided', program, cause); + super('Invalid Boost-to param', program, cause); } } -codeToErrorMap.set(0x2, InvalidPositionSettingsError); -nameToErrorMap.set('InvalidPositionSettings', InvalidPositionSettingsError); +codeToErrorMap.set(0x2, InvalidBoostToSettingError); +nameToErrorMap.set('InvalidBoostToSetting', InvalidBoostToSettingError); + +/** InvalidBoostGapSetting: Invalid Boost gap param */ +export class InvalidBoostGapSettingError extends ProgramError { + override readonly name: string = 'InvalidBoostGapSetting'; + + readonly code: number = 0x3; // 3 + + constructor(program: Program, cause?: Error) { + super('Invalid Boost gap param', program, cause); + } +} +codeToErrorMap.set(0x3, InvalidBoostGapSettingError); +nameToErrorMap.set('InvalidBoostGapSetting', InvalidBoostGapSettingError); + +/** InvalidRepayToSetting: Invalid repay-to param */ +export class InvalidRepayToSettingError extends ProgramError { + override readonly name: string = 'InvalidRepayToSetting'; + + readonly code: number = 0x4; // 4 + + constructor(program: Program, cause?: Error) { + super('Invalid repay-to param', program, cause); + } +} +codeToErrorMap.set(0x4, InvalidRepayToSettingError); +nameToErrorMap.set('InvalidRepayToSetting', InvalidRepayToSettingError); + +/** InvalidRepayGapSetting: Invalid repay gap param */ +export class InvalidRepayGapSettingError extends ProgramError { + override readonly name: string = 'InvalidRepayGapSetting'; + + readonly code: number = 0x5; // 5 + + constructor(program: Program, cause?: Error) { + super('Invalid repay gap param', program, cause); + } +} +codeToErrorMap.set(0x5, InvalidRepayGapSettingError); +nameToErrorMap.set('InvalidRepayGapSetting', InvalidRepayGapSettingError); + +/** InvalidRepayFromSetting: Invalid repay-from (repay-to + repay gap) */ +export class InvalidRepayFromSettingError extends ProgramError { + override readonly name: string = 'InvalidRepayFromSetting'; + + readonly code: number = 0x6; // 6 + + constructor(program: Program, cause?: Error) { + super('Invalid repay-from (repay-to + repay gap)', program, cause); + } +} +codeToErrorMap.set(0x6, InvalidRepayFromSettingError); +nameToErrorMap.set('InvalidRepayFromSetting', InvalidRepayFromSettingError); /** InvalidDCASettings: Invalid DCA configuration provided */ export class InvalidDCASettingsError extends ProgramError { override readonly name: string = 'InvalidDCASettings'; - readonly code: number = 0x3; // 3 + readonly code: number = 0x7; // 7 constructor(program: Program, cause?: Error) { super('Invalid DCA configuration provided', program, cause); } } -codeToErrorMap.set(0x3, InvalidDCASettingsError); +codeToErrorMap.set(0x7, InvalidDCASettingsError); nameToErrorMap.set('InvalidDCASettings', InvalidDCASettingsError); /** InvalidAutomationData: Invalid automation settings provided */ export class InvalidAutomationDataError extends ProgramError { override readonly name: string = 'InvalidAutomationData'; - readonly code: number = 0x4; // 4 + readonly code: number = 0x8; // 8 constructor(program: Program, cause?: Error) { super('Invalid automation settings provided', program, cause); } } -codeToErrorMap.set(0x4, InvalidAutomationDataError); +codeToErrorMap.set(0x8, InvalidAutomationDataError); nameToErrorMap.set('InvalidAutomationData', InvalidAutomationDataError); /** InvalidRebalanceCondition: Invalid position condition to rebalance */ export class InvalidRebalanceConditionError extends ProgramError { override readonly name: string = 'InvalidRebalanceCondition'; - readonly code: number = 0x5; // 5 + readonly code: number = 0x9; // 9 constructor(program: Program, cause?: Error) { super('Invalid position condition to rebalance', program, cause); } } -codeToErrorMap.set(0x5, InvalidRebalanceConditionError); +codeToErrorMap.set(0x9, InvalidRebalanceConditionError); nameToErrorMap.set('InvalidRebalanceCondition', InvalidRebalanceConditionError); /** InstructionIsCPI: Unable to invoke instruction through a CPI */ export class InstructionIsCPIError extends ProgramError { override readonly name: string = 'InstructionIsCPI'; - readonly code: number = 0x6; // 6 + readonly code: number = 0xa; // 10 constructor(program: Program, cause?: Error) { super('Unable to invoke instruction through a CPI', program, cause); } } -codeToErrorMap.set(0x6, InstructionIsCPIError); +codeToErrorMap.set(0xa, InstructionIsCPIError); nameToErrorMap.set('InstructionIsCPI', InstructionIsCPIError); -/** IncorrectInstructions: Incorrect set of instructions in the transaction */ +/** IncorrectInstructions: Incorrect set of instructions or instruction data in the transaction */ export class IncorrectInstructionsError extends ProgramError { override readonly name: string = 'IncorrectInstructions'; - readonly code: number = 0x7; // 7 + readonly code: number = 0xb; // 11 constructor(program: Program, cause?: Error) { - super('Incorrect set of instructions in the transaction', program, cause); + super( + 'Incorrect set of instructions or instruction data in the transaction', + program, + cause + ); } } -codeToErrorMap.set(0x7, IncorrectInstructionsError); +codeToErrorMap.set(0xb, IncorrectInstructionsError); nameToErrorMap.set('IncorrectInstructions', IncorrectInstructionsError); /** IncorrectDebtAdjustment: Incorrect swap amount provided. Likely due to high price volatility */ export class IncorrectDebtAdjustmentError extends ProgramError { override readonly name: string = 'IncorrectDebtAdjustment'; - readonly code: number = 0x8; // 8 + readonly code: number = 0xc; // 12 constructor(program: Program, cause?: Error) { super( @@ -140,9 +196,46 @@ export class IncorrectDebtAdjustmentError extends ProgramError { ); } } -codeToErrorMap.set(0x8, IncorrectDebtAdjustmentError); +codeToErrorMap.set(0xc, IncorrectDebtAdjustmentError); nameToErrorMap.set('IncorrectDebtAdjustment', IncorrectDebtAdjustmentError); +/** InvalidRebalanceMade: Invalid rebalance was made. Target supply USD and target debt USD was not met */ +export class InvalidRebalanceMadeError extends ProgramError { + override readonly name: string = 'InvalidRebalanceMade'; + + readonly code: number = 0xd; // 13 + + constructor(program: Program, cause?: Error) { + super( + 'Invalid rebalance was made. Target supply USD and target debt USD was not met', + program, + cause + ); + } +} +codeToErrorMap.set(0xd, InvalidRebalanceMadeError); +nameToErrorMap.set('InvalidRebalanceMade', InvalidRebalanceMadeError); + +/** NonAuthorityProvidedTargetLTV: Cannot provide a target liquidation utilization rate if the instruction is not signed by the position authority */ +export class NonAuthorityProvidedTargetLTVError extends ProgramError { + override readonly name: string = 'NonAuthorityProvidedTargetLTV'; + + readonly code: number = 0xe; // 14 + + constructor(program: Program, cause?: Error) { + super( + 'Cannot provide a target liquidation utilization rate if the instruction is not signed by the position authority', + program, + cause + ); + } +} +codeToErrorMap.set(0xe, NonAuthorityProvidedTargetLTVError); +nameToErrorMap.set( + 'NonAuthorityProvidedTargetLTV', + NonAuthorityProvidedTargetLTVError +); + /** * Attempts to resolve a custom program error from the provided error code. * @category Errors diff --git a/solauto-sdk/src/generated/instructions/claimReferralFees.ts b/solauto-sdk/src/generated/instructions/claimReferralFees.ts index 01bd4fd3..c4527508 100644 --- a/solauto-sdk/src/generated/instructions/claimReferralFees.ts +++ b/solauto-sdk/src/generated/instructions/claimReferralFees.ts @@ -38,7 +38,7 @@ export type ClaimReferralFeesInstructionAccounts = { referralState: PublicKey | Pda; referralFeesDestTa: PublicKey | Pda; referralFeesDestMint: PublicKey | Pda; - referralAuthority?: PublicKey | Pda; + referralAuthority: PublicKey | Pda; feesDestinationTa?: PublicKey | Pda; }; diff --git a/solauto-sdk/src/generated/instructions/closePosition.ts b/solauto-sdk/src/generated/instructions/closePosition.ts index b65ed027..260c559d 100644 --- a/solauto-sdk/src/generated/instructions/closePosition.ts +++ b/solauto-sdk/src/generated/instructions/closePosition.ts @@ -33,7 +33,7 @@ export type ClosePositionInstructionAccounts = { tokenProgram?: PublicKey | Pda; ataProgram?: PublicKey | Pda; solautoPosition: PublicKey | Pda; - protocolAccount: PublicKey | Pda; + lpUserAccount: PublicKey | Pda; positionSupplyTa: PublicKey | Pda; signerSupplyTa: PublicKey | Pda; positionDebtTa: PublicKey | Pda; @@ -102,10 +102,10 @@ export function closePosition( isWritable: true as boolean, value: input.solautoPosition ?? null, }, - protocolAccount: { + lpUserAccount: { index: 5, isWritable: true as boolean, - value: input.protocolAccount ?? null, + value: input.lpUserAccount ?? null, }, positionSupplyTa: { index: 6, diff --git a/solauto-sdk/src/generated/instructions/marginfiOpenPosition.ts b/solauto-sdk/src/generated/instructions/marginfiOpenPosition.ts index 83cd7329..8a74ef8e 100644 --- a/solauto-sdk/src/generated/instructions/marginfiOpenPosition.ts +++ b/solauto-sdk/src/generated/instructions/marginfiOpenPosition.ts @@ -8,8 +8,6 @@ import { Context, - Option, - OptionOrNullable, Pda, PublicKey, Signer, @@ -20,9 +18,7 @@ import { import { Serializer, mapSerializer, - option, struct, - u64, u8, } from '@metaplex-foundation/umi/serializers'; import { @@ -67,13 +63,11 @@ export type MarginfiOpenPositionInstructionData = { discriminator: number; positionType: PositionType; positionData: UpdatePositionData; - marginfiAccountSeedIdx: Option; }; export type MarginfiOpenPositionInstructionDataArgs = { positionType: PositionTypeArgs; positionData: UpdatePositionDataArgs; - marginfiAccountSeedIdx: OptionOrNullable; }; export function getMarginfiOpenPositionInstructionDataSerializer(): Serializer< @@ -90,7 +84,6 @@ export function getMarginfiOpenPositionInstructionDataSerializer(): Serializer< ['discriminator', u8()], ['positionType', getPositionTypeSerializer()], ['positionData', getUpdatePositionDataSerializer()], - ['marginfiAccountSeedIdx', option(u64())], ], { description: 'MarginfiOpenPositionInstructionData' } ), diff --git a/solauto-sdk/src/generated/instructions/marginfiRebalance.ts b/solauto-sdk/src/generated/instructions/marginfiRebalance.ts index 8a012e3c..d7330fd4 100644 --- a/solauto-sdk/src/generated/instructions/marginfiRebalance.ts +++ b/solauto-sdk/src/generated/instructions/marginfiRebalance.ts @@ -31,9 +31,15 @@ import { getAccountMetasAndSigners, } from '../shared'; import { + PriceType, + PriceTypeArgs, SolautoRebalanceType, SolautoRebalanceTypeArgs, + SwapType, + SwapTypeArgs, + getPriceTypeSerializer, getSolautoRebalanceTypeSerializer, + getSwapTypeSerializer, } from '../types'; // Accounts. @@ -69,14 +75,20 @@ export type MarginfiRebalanceInstructionAccounts = { export type MarginfiRebalanceInstructionData = { discriminator: number; rebalanceType: SolautoRebalanceType; + swapInAmountBaseUnit: Option; targetLiqUtilizationRateBps: Option; - targetInAmountBaseUnit: Option; + flashLoanFeeBps: Option; + priceType: Option; + swapType: Option; }; export type MarginfiRebalanceInstructionDataArgs = { rebalanceType: SolautoRebalanceTypeArgs; + swapInAmountBaseUnit: OptionOrNullable; targetLiqUtilizationRateBps: OptionOrNullable; - targetInAmountBaseUnit: OptionOrNullable; + flashLoanFeeBps: OptionOrNullable; + priceType: OptionOrNullable; + swapType: OptionOrNullable; }; export function getMarginfiRebalanceInstructionDataSerializer(): Serializer< @@ -92,8 +104,11 @@ export function getMarginfiRebalanceInstructionDataSerializer(): Serializer< [ ['discriminator', u8()], ['rebalanceType', getSolautoRebalanceTypeSerializer()], + ['swapInAmountBaseUnit', option(u64())], ['targetLiqUtilizationRateBps', option(u16())], - ['targetInAmountBaseUnit', option(u64())], + ['flashLoanFeeBps', option(u16())], + ['priceType', option(getPriceTypeSerializer())], + ['swapType', option(getSwapTypeSerializer())], ], { description: 'MarginfiRebalanceInstructionData' } ), diff --git a/solauto-sdk/src/generated/instructions/marginfiRefreshData.ts b/solauto-sdk/src/generated/instructions/marginfiRefreshData.ts index df633f2c..8994d412 100644 --- a/solauto-sdk/src/generated/instructions/marginfiRefreshData.ts +++ b/solauto-sdk/src/generated/instructions/marginfiRefreshData.ts @@ -25,6 +25,7 @@ import { ResolvedAccountsWithIndices, getAccountMetasAndSigners, } from '../shared'; +import { PriceType, PriceTypeArgs, getPriceTypeSerializer } from '../types'; // Accounts. export type MarginfiRefreshDataInstructionAccounts = { @@ -40,9 +41,14 @@ export type MarginfiRefreshDataInstructionAccounts = { }; // Data. -export type MarginfiRefreshDataInstructionData = { discriminator: number }; +export type MarginfiRefreshDataInstructionData = { + discriminator: number; + priceType: PriceType; +}; -export type MarginfiRefreshDataInstructionDataArgs = {}; +export type MarginfiRefreshDataInstructionDataArgs = { + priceType: PriceTypeArgs; +}; export function getMarginfiRefreshDataInstructionDataSerializer(): Serializer< MarginfiRefreshDataInstructionDataArgs, @@ -53,9 +59,13 @@ export function getMarginfiRefreshDataInstructionDataSerializer(): Serializer< any, MarginfiRefreshDataInstructionData >( - struct([['discriminator', u8()]], { - description: 'MarginfiRefreshDataInstructionData', - }), + struct( + [ + ['discriminator', u8()], + ['priceType', getPriceTypeSerializer()], + ], + { description: 'MarginfiRefreshDataInstructionData' } + ), (value) => ({ ...value, discriminator: 7 }) ) as Serializer< MarginfiRefreshDataInstructionDataArgs, @@ -63,10 +73,15 @@ export function getMarginfiRefreshDataInstructionDataSerializer(): Serializer< >; } +// Args. +export type MarginfiRefreshDataInstructionArgs = + MarginfiRefreshDataInstructionDataArgs; + // Instruction. export function marginfiRefreshData( context: Pick, - input: MarginfiRefreshDataInstructionAccounts + input: MarginfiRefreshDataInstructionAccounts & + MarginfiRefreshDataInstructionArgs ): TransactionBuilder { // Program ID. const programId = context.programs.getPublicKey( @@ -123,6 +138,9 @@ export function marginfiRefreshData( }, } satisfies ResolvedAccountsWithIndices; + // Arguments. + const resolvedArgs: MarginfiRefreshDataInstructionArgs = { ...input }; + // Accounts in order. const orderedAccounts: ResolvedAccount[] = Object.values( resolvedAccounts @@ -136,7 +154,9 @@ export function marginfiRefreshData( ); // Data. - const data = getMarginfiRefreshDataInstructionDataSerializer().serialize({}); + const data = getMarginfiRefreshDataInstructionDataSerializer().serialize( + resolvedArgs as MarginfiRefreshDataInstructionDataArgs + ); // Bytes Created On Chain. const bytesCreatedOnChain = 0; diff --git a/solauto-sdk/src/generated/types/index.ts b/solauto-sdk/src/generated/types/index.ts index aae7f585..c02644bb 100644 --- a/solauto-sdk/src/generated/types/index.ts +++ b/solauto-sdk/src/generated/types/index.ts @@ -14,15 +14,22 @@ export * from './lendingPlatform'; export * from './podBool'; export * from './positionData'; export * from './positionState'; -export * from './positionTokenUsage'; +export * from './positionTokenState'; export * from './positionType'; +export * from './priceType'; export * from './rebalanceData'; export * from './rebalanceDirection'; +export * from './rebalanceInstructionData'; +export * from './rebalanceStateValues'; +export * from './rebalanceStep'; export * from './solautoAction'; export * from './solautoRebalanceType'; export * from './solautoSettingsParameters'; export * from './solautoSettingsParametersInp'; +export * from './swapType'; export * from './tokenAmount'; export * from './tokenBalanceAmount'; +export * from './tokenBalanceChange'; +export * from './tokenBalanceChangeType'; export * from './tokenType'; export * from './updatePositionData'; diff --git a/solauto-sdk/src/generated/types/positionData.ts b/solauto-sdk/src/generated/types/positionData.ts index 386c5d04..b3901e31 100644 --- a/solauto-sdk/src/generated/types/positionData.ts +++ b/solauto-sdk/src/generated/types/positionData.ts @@ -16,13 +16,10 @@ import { u8, } from '@metaplex-foundation/umi/serializers'; import { - DCASettings, - DCASettingsArgs, LendingPlatform, LendingPlatformArgs, SolautoSettingsParameters, SolautoSettingsParametersArgs, - getDCASettingsSerializer, getLendingPlatformSerializer, getSolautoSettingsParametersSerializer, } from '.'; @@ -30,22 +27,22 @@ import { export type PositionData = { lendingPlatform: LendingPlatform; padding1: Array; - protocolUserAccount: PublicKey; - protocolSupplyAccount: PublicKey; - protocolDebtAccount: PublicKey; - settingParams: SolautoSettingsParameters; - dca: DCASettings; + lpUserAccount: PublicKey; + lpSupplyAccount: PublicKey; + lpDebtAccount: PublicKey; + settings: SolautoSettingsParameters; + lpPoolAccount: PublicKey; padding: Array; }; export type PositionDataArgs = { lendingPlatform: LendingPlatformArgs; padding1: Array; - protocolUserAccount: PublicKey; - protocolSupplyAccount: PublicKey; - protocolDebtAccount: PublicKey; - settingParams: SolautoSettingsParametersArgs; - dca: DCASettingsArgs; + lpUserAccount: PublicKey; + lpSupplyAccount: PublicKey; + lpDebtAccount: PublicKey; + settings: SolautoSettingsParametersArgs; + lpPoolAccount: PublicKey; padding: Array; }; @@ -57,12 +54,12 @@ export function getPositionDataSerializer(): Serializer< [ ['lendingPlatform', getLendingPlatformSerializer()], ['padding1', array(u8(), { size: 7 })], - ['protocolUserAccount', publicKeySerializer()], - ['protocolSupplyAccount', publicKeySerializer()], - ['protocolDebtAccount', publicKeySerializer()], - ['settingParams', getSolautoSettingsParametersSerializer()], - ['dca', getDCASettingsSerializer()], - ['padding', array(u32(), { size: 4 })], + ['lpUserAccount', publicKeySerializer()], + ['lpSupplyAccount', publicKeySerializer()], + ['lpDebtAccount', publicKeySerializer()], + ['settings', getSolautoSettingsParametersSerializer()], + ['lpPoolAccount', publicKeySerializer()], + ['padding', array(u32(), { size: 20 })], ], { description: 'PositionData' } ) as Serializer; diff --git a/solauto-sdk/src/generated/types/positionState.ts b/solauto-sdk/src/generated/types/positionState.ts index 684fd19a..895d1dcc 100644 --- a/solauto-sdk/src/generated/types/positionState.ts +++ b/solauto-sdk/src/generated/types/positionState.ts @@ -16,11 +16,11 @@ import { u8, } from '@metaplex-foundation/umi/serializers'; import { - PositionTokenUsage, - PositionTokenUsageArgs, + PositionTokenState, + PositionTokenStateArgs, TokenAmount, TokenAmountArgs, - getPositionTokenUsageSerializer, + getPositionTokenStateSerializer, getTokenAmountSerializer, } from '.'; @@ -28,12 +28,12 @@ export type PositionState = { liqUtilizationRateBps: number; padding1: Array; netWorth: TokenAmount; - supply: PositionTokenUsage; - debt: PositionTokenUsage; + supply: PositionTokenState; + debt: PositionTokenState; maxLtvBps: number; liqThresholdBps: number; padding2: Array; - lastUpdated: bigint; + lastRefreshed: bigint; padding: Array; }; @@ -41,12 +41,12 @@ export type PositionStateArgs = { liqUtilizationRateBps: number; padding1: Array; netWorth: TokenAmountArgs; - supply: PositionTokenUsageArgs; - debt: PositionTokenUsageArgs; + supply: PositionTokenStateArgs; + debt: PositionTokenStateArgs; maxLtvBps: number; liqThresholdBps: number; padding2: Array; - lastUpdated: number | bigint; + lastRefreshed: number | bigint; padding: Array; }; @@ -59,12 +59,12 @@ export function getPositionStateSerializer(): Serializer< ['liqUtilizationRateBps', u16()], ['padding1', array(u8(), { size: 6 })], ['netWorth', getTokenAmountSerializer()], - ['supply', getPositionTokenUsageSerializer()], - ['debt', getPositionTokenUsageSerializer()], + ['supply', getPositionTokenStateSerializer()], + ['debt', getPositionTokenStateSerializer()], ['maxLtvBps', u16()], ['liqThresholdBps', u16()], ['padding2', array(u8(), { size: 4 })], - ['lastUpdated', u64()], + ['lastRefreshed', u64()], ['padding', array(u32(), { size: 2 })], ], { description: 'PositionState' } diff --git a/solauto-sdk/src/generated/types/positionTokenUsage.ts b/solauto-sdk/src/generated/types/positionTokenState.ts similarity index 72% rename from solauto-sdk/src/generated/types/positionTokenUsage.ts rename to solauto-sdk/src/generated/types/positionTokenState.ts index d0df2a93..f7a71836 100644 --- a/solauto-sdk/src/generated/types/positionTokenUsage.ts +++ b/solauto-sdk/src/generated/types/positionTokenState.ts @@ -19,49 +19,46 @@ import { } from '@metaplex-foundation/umi/serializers'; import { TokenAmount, TokenAmountArgs, getTokenAmountSerializer } from '.'; -export type PositionTokenUsage = { +export type PositionTokenState = { mint: PublicKey; decimals: number; padding1: Array; + borrowFeeBps: number; amountUsed: TokenAmount; amountCanBeUsed: TokenAmount; baseAmountMarketPriceUsd: bigint; - flashLoanFeeBps: number; - borrowFeeBps: number; padding2: Array; padding: Uint8Array; }; -export type PositionTokenUsageArgs = { +export type PositionTokenStateArgs = { mint: PublicKey; decimals: number; padding1: Array; + borrowFeeBps: number; amountUsed: TokenAmountArgs; amountCanBeUsed: TokenAmountArgs; baseAmountMarketPriceUsd: number | bigint; - flashLoanFeeBps: number; - borrowFeeBps: number; padding2: Array; padding: Uint8Array; }; -export function getPositionTokenUsageSerializer(): Serializer< - PositionTokenUsageArgs, - PositionTokenUsage +export function getPositionTokenStateSerializer(): Serializer< + PositionTokenStateArgs, + PositionTokenState > { - return struct( + return struct( [ ['mint', publicKeySerializer()], ['decimals', u8()], - ['padding1', array(u8(), { size: 7 })], + ['padding1', array(u8(), { size: 5 })], + ['borrowFeeBps', u16()], ['amountUsed', getTokenAmountSerializer()], ['amountCanBeUsed', getTokenAmountSerializer()], ['baseAmountMarketPriceUsd', u64()], - ['flashLoanFeeBps', u16()], - ['borrowFeeBps', u16()], - ['padding2', array(u8(), { size: 4 })], + ['padding2', array(u8(), { size: 8 })], ['padding', bytes({ size: 32 })], ], - { description: 'PositionTokenUsage' } - ) as Serializer; + { description: 'PositionTokenState' } + ) as Serializer; } diff --git a/solauto-sdk/src/generated/types/priceType.ts b/solauto-sdk/src/generated/types/priceType.ts new file mode 100644 index 00000000..090f4336 --- /dev/null +++ b/solauto-sdk/src/generated/types/priceType.ts @@ -0,0 +1,22 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/metaplex-foundation/kinobi + */ + +import { Serializer, scalarEnum } from '@metaplex-foundation/umi/serializers'; + +export enum PriceType { + Realtime, + Ema, +} + +export type PriceTypeArgs = PriceType; + +export function getPriceTypeSerializer(): Serializer { + return scalarEnum(PriceType, { + description: 'PriceType', + }) as Serializer; +} diff --git a/solauto-sdk/src/generated/types/rebalanceData.ts b/solauto-sdk/src/generated/types/rebalanceData.ts index 57dd778c..e1a5dc93 100644 --- a/solauto-sdk/src/generated/types/rebalanceData.ts +++ b/solauto-sdk/src/generated/types/rebalanceData.ts @@ -9,36 +9,28 @@ import { Serializer, array, - bytes, struct, - u64, - u8, + u32, } from '@metaplex-foundation/umi/serializers'; import { - RebalanceDirection, - RebalanceDirectionArgs, - SolautoRebalanceType, - SolautoRebalanceTypeArgs, - getRebalanceDirectionSerializer, - getSolautoRebalanceTypeSerializer, + RebalanceInstructionData, + RebalanceInstructionDataArgs, + RebalanceStateValues, + RebalanceStateValuesArgs, + getRebalanceInstructionDataSerializer, + getRebalanceStateValuesSerializer, } from '.'; export type RebalanceData = { - rebalanceType: SolautoRebalanceType; - padding1: Array; - rebalanceDirection: RebalanceDirection; - padding2: Array; - flashLoanAmount: bigint; - padding: Uint8Array; + ixs: RebalanceInstructionData; + values: RebalanceStateValues; + padding: Array; }; export type RebalanceDataArgs = { - rebalanceType: SolautoRebalanceTypeArgs; - padding1: Array; - rebalanceDirection: RebalanceDirectionArgs; - padding2: Array; - flashLoanAmount: number | bigint; - padding: Uint8Array; + ixs: RebalanceInstructionDataArgs; + values: RebalanceStateValuesArgs; + padding: Array; }; export function getRebalanceDataSerializer(): Serializer< @@ -47,12 +39,9 @@ export function getRebalanceDataSerializer(): Serializer< > { return struct( [ - ['rebalanceType', getSolautoRebalanceTypeSerializer()], - ['padding1', array(u8(), { size: 7 })], - ['rebalanceDirection', getRebalanceDirectionSerializer()], - ['padding2', array(u8(), { size: 7 })], - ['flashLoanAmount', u64()], - ['padding', bytes({ size: 32 })], + ['ixs', getRebalanceInstructionDataSerializer()], + ['values', getRebalanceStateValuesSerializer()], + ['padding', array(u32(), { size: 4 })], ], { description: 'RebalanceData' } ) as Serializer; diff --git a/solauto-sdk/src/generated/types/rebalanceDirection.ts b/solauto-sdk/src/generated/types/rebalanceDirection.ts index 94f307fd..b9779ee6 100644 --- a/solauto-sdk/src/generated/types/rebalanceDirection.ts +++ b/solauto-sdk/src/generated/types/rebalanceDirection.ts @@ -9,6 +9,7 @@ import { Serializer, scalarEnum } from '@metaplex-foundation/umi/serializers'; export enum RebalanceDirection { + None, Boost, Repay, } diff --git a/solauto-sdk/src/generated/types/rebalanceInstructionData.ts b/solauto-sdk/src/generated/types/rebalanceInstructionData.ts new file mode 100644 index 00000000..c64f62ba --- /dev/null +++ b/solauto-sdk/src/generated/types/rebalanceInstructionData.ts @@ -0,0 +1,62 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/metaplex-foundation/kinobi + */ + +import { + Serializer, + array, + struct, + u32, + u64, + u8, +} from '@metaplex-foundation/umi/serializers'; +import { + PodBool, + PodBoolArgs, + SolautoRebalanceType, + SolautoRebalanceTypeArgs, + SwapType, + SwapTypeArgs, + getPodBoolSerializer, + getSolautoRebalanceTypeSerializer, + getSwapTypeSerializer, +} from '.'; + +export type RebalanceInstructionData = { + active: PodBool; + rebalanceType: SolautoRebalanceType; + swapType: SwapType; + padding1: Array; + flashLoanAmount: bigint; + padding: Array; +}; + +export type RebalanceInstructionDataArgs = { + active: PodBoolArgs; + rebalanceType: SolautoRebalanceTypeArgs; + swapType: SwapTypeArgs; + padding1: Array; + flashLoanAmount: number | bigint; + padding: Array; +}; + +export function getRebalanceInstructionDataSerializer(): Serializer< + RebalanceInstructionDataArgs, + RebalanceInstructionData +> { + return struct( + [ + ['active', getPodBoolSerializer()], + ['rebalanceType', getSolautoRebalanceTypeSerializer()], + ['swapType', getSwapTypeSerializer()], + ['padding1', array(u8(), { size: 5 })], + ['flashLoanAmount', u64()], + ['padding', array(u32(), { size: 4 })], + ], + { description: 'RebalanceInstructionData' } + ) as Serializer; +} diff --git a/solauto-sdk/src/generated/types/rebalanceStateValues.ts b/solauto-sdk/src/generated/types/rebalanceStateValues.ts new file mode 100644 index 00000000..98a2ffbf --- /dev/null +++ b/solauto-sdk/src/generated/types/rebalanceStateValues.ts @@ -0,0 +1,59 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/metaplex-foundation/kinobi + */ + +import { + Serializer, + array, + struct, + u32, + u64, + u8, +} from '@metaplex-foundation/umi/serializers'; +import { + RebalanceDirection, + RebalanceDirectionArgs, + TokenBalanceChange, + TokenBalanceChangeArgs, + getRebalanceDirectionSerializer, + getTokenBalanceChangeSerializer, +} from '.'; + +export type RebalanceStateValues = { + rebalanceDirection: RebalanceDirection; + padding1: Array; + targetSupplyUsd: bigint; + targetDebtUsd: bigint; + tokenBalanceChange: TokenBalanceChange; + padding: Array; +}; + +export type RebalanceStateValuesArgs = { + rebalanceDirection: RebalanceDirectionArgs; + padding1: Array; + targetSupplyUsd: number | bigint; + targetDebtUsd: number | bigint; + tokenBalanceChange: TokenBalanceChangeArgs; + padding: Array; +}; + +export function getRebalanceStateValuesSerializer(): Serializer< + RebalanceStateValuesArgs, + RebalanceStateValues +> { + return struct( + [ + ['rebalanceDirection', getRebalanceDirectionSerializer()], + ['padding1', array(u8(), { size: 7 })], + ['targetSupplyUsd', u64()], + ['targetDebtUsd', u64()], + ['tokenBalanceChange', getTokenBalanceChangeSerializer()], + ['padding', array(u32(), { size: 4 })], + ], + { description: 'RebalanceStateValues' } + ) as Serializer; +} diff --git a/solauto-sdk/src/generated/types/rebalanceStep.ts b/solauto-sdk/src/generated/types/rebalanceStep.ts new file mode 100644 index 00000000..67997c94 --- /dev/null +++ b/solauto-sdk/src/generated/types/rebalanceStep.ts @@ -0,0 +1,25 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/metaplex-foundation/kinobi + */ + +import { Serializer, scalarEnum } from '@metaplex-foundation/umi/serializers'; + +export enum RebalanceStep { + PreSwap, + PostSwap, +} + +export type RebalanceStepArgs = RebalanceStep; + +export function getRebalanceStepSerializer(): Serializer< + RebalanceStepArgs, + RebalanceStep +> { + return scalarEnum(RebalanceStep, { + description: 'RebalanceStep', + }) as Serializer; +} diff --git a/solauto-sdk/src/generated/types/solautoRebalanceType.ts b/solauto-sdk/src/generated/types/solautoRebalanceType.ts index e460fe67..c1fad120 100644 --- a/solauto-sdk/src/generated/types/solautoRebalanceType.ts +++ b/solauto-sdk/src/generated/types/solautoRebalanceType.ts @@ -9,7 +9,6 @@ import { Serializer, scalarEnum } from '@metaplex-foundation/umi/serializers'; export enum SolautoRebalanceType { - None, Regular, DoubleRebalanceWithFL, FLSwapThenRebalance, diff --git a/solauto-sdk/src/generated/types/solautoSettingsParameters.ts b/solauto-sdk/src/generated/types/solautoSettingsParameters.ts index dcb30534..1838d036 100644 --- a/solauto-sdk/src/generated/types/solautoSettingsParameters.ts +++ b/solauto-sdk/src/generated/types/solautoSettingsParameters.ts @@ -9,38 +9,20 @@ import { Serializer, array, - bytes, struct, u16, - u8, + u32, } from '@metaplex-foundation/umi/serializers'; -import { - AutomationSettings, - AutomationSettingsArgs, - getAutomationSettingsSerializer, -} from '.'; export type SolautoSettingsParameters = { boostToBps: number; boostGap: number; repayToBps: number; repayGap: number; - targetBoostToBps: number; - padding1: Array; - automation: AutomationSettings; - padding: Uint8Array; + padding: Array; }; -export type SolautoSettingsParametersArgs = { - boostToBps: number; - boostGap: number; - repayToBps: number; - repayGap: number; - targetBoostToBps: number; - padding1: Array; - automation: AutomationSettingsArgs; - padding: Uint8Array; -}; +export type SolautoSettingsParametersArgs = SolautoSettingsParameters; export function getSolautoSettingsParametersSerializer(): Serializer< SolautoSettingsParametersArgs, @@ -52,10 +34,7 @@ export function getSolautoSettingsParametersSerializer(): Serializer< ['boostGap', u16()], ['repayToBps', u16()], ['repayGap', u16()], - ['targetBoostToBps', u16()], - ['padding1', array(u8(), { size: 6 })], - ['automation', getAutomationSettingsSerializer()], - ['padding', bytes({ size: 32 })], + ['padding', array(u32(), { size: 24 })], ], { description: 'SolautoSettingsParameters' } ) as Serializer; diff --git a/solauto-sdk/src/generated/types/solautoSettingsParametersInp.ts b/solauto-sdk/src/generated/types/solautoSettingsParametersInp.ts index 5790bb8e..faf58089 100644 --- a/solauto-sdk/src/generated/types/solautoSettingsParametersInp.ts +++ b/solauto-sdk/src/generated/types/solautoSettingsParametersInp.ts @@ -6,36 +6,16 @@ * @see https://github.com/metaplex-foundation/kinobi */ -import { Option, OptionOrNullable } from '@metaplex-foundation/umi'; -import { - Serializer, - option, - struct, - u16, -} from '@metaplex-foundation/umi/serializers'; -import { - AutomationSettingsInp, - AutomationSettingsInpArgs, - getAutomationSettingsInpSerializer, -} from '.'; +import { Serializer, struct, u16 } from '@metaplex-foundation/umi/serializers'; export type SolautoSettingsParametersInp = { boostToBps: number; boostGap: number; repayToBps: number; repayGap: number; - targetBoostToBps: Option; - automation: Option; }; -export type SolautoSettingsParametersInpArgs = { - boostToBps: number; - boostGap: number; - repayToBps: number; - repayGap: number; - targetBoostToBps: OptionOrNullable; - automation: OptionOrNullable; -}; +export type SolautoSettingsParametersInpArgs = SolautoSettingsParametersInp; export function getSolautoSettingsParametersInpSerializer(): Serializer< SolautoSettingsParametersInpArgs, @@ -47,8 +27,6 @@ export function getSolautoSettingsParametersInpSerializer(): Serializer< ['boostGap', u16()], ['repayToBps', u16()], ['repayGap', u16()], - ['targetBoostToBps', option(u16())], - ['automation', option(getAutomationSettingsInpSerializer())], ], { description: 'SolautoSettingsParametersInp' } ) as Serializer< diff --git a/solauto-sdk/src/generated/types/swapType.ts b/solauto-sdk/src/generated/types/swapType.ts new file mode 100644 index 00000000..383c0a03 --- /dev/null +++ b/solauto-sdk/src/generated/types/swapType.ts @@ -0,0 +1,22 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/metaplex-foundation/kinobi + */ + +import { Serializer, scalarEnum } from '@metaplex-foundation/umi/serializers'; + +export enum SwapType { + ExactIn, + ExactOut, +} + +export type SwapTypeArgs = SwapType; + +export function getSwapTypeSerializer(): Serializer { + return scalarEnum(SwapType, { + description: 'SwapType', + }) as Serializer; +} diff --git a/solauto-sdk/src/generated/types/tokenBalanceChange.ts b/solauto-sdk/src/generated/types/tokenBalanceChange.ts new file mode 100644 index 00000000..400f5e05 --- /dev/null +++ b/solauto-sdk/src/generated/types/tokenBalanceChange.ts @@ -0,0 +1,46 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/metaplex-foundation/kinobi + */ + +import { + Serializer, + array, + struct, + u64, + u8, +} from '@metaplex-foundation/umi/serializers'; +import { + TokenBalanceChangeType, + TokenBalanceChangeTypeArgs, + getTokenBalanceChangeTypeSerializer, +} from '.'; + +export type TokenBalanceChange = { + changeType: TokenBalanceChangeType; + padding1: Array; + amountUsd: bigint; +}; + +export type TokenBalanceChangeArgs = { + changeType: TokenBalanceChangeTypeArgs; + padding1: Array; + amountUsd: number | bigint; +}; + +export function getTokenBalanceChangeSerializer(): Serializer< + TokenBalanceChangeArgs, + TokenBalanceChange +> { + return struct( + [ + ['changeType', getTokenBalanceChangeTypeSerializer()], + ['padding1', array(u8(), { size: 7 })], + ['amountUsd', u64()], + ], + { description: 'TokenBalanceChange' } + ) as Serializer; +} diff --git a/solauto-sdk/src/generated/types/tokenBalanceChangeType.ts b/solauto-sdk/src/generated/types/tokenBalanceChangeType.ts new file mode 100644 index 00000000..422ddde6 --- /dev/null +++ b/solauto-sdk/src/generated/types/tokenBalanceChangeType.ts @@ -0,0 +1,28 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/metaplex-foundation/kinobi + */ + +import { Serializer, scalarEnum } from '@metaplex-foundation/umi/serializers'; + +export enum TokenBalanceChangeType { + None, + PreSwapDeposit, + PostSwapDeposit, + PostRebalanceWithdrawSupplyToken, + PostRebalanceWithdrawDebtToken, +} + +export type TokenBalanceChangeTypeArgs = TokenBalanceChangeType; + +export function getTokenBalanceChangeTypeSerializer(): Serializer< + TokenBalanceChangeTypeArgs, + TokenBalanceChangeType +> { + return scalarEnum(TokenBalanceChangeType, { + description: 'TokenBalanceChangeType', + }) as Serializer; +} diff --git a/solauto-sdk/src/generated/types/updatePositionData.ts b/solauto-sdk/src/generated/types/updatePositionData.ts index 1d0a6bf2..8acc0805 100644 --- a/solauto-sdk/src/generated/types/updatePositionData.ts +++ b/solauto-sdk/src/generated/types/updatePositionData.ts @@ -24,13 +24,13 @@ import { export type UpdatePositionData = { positionId: number; - settingParams: Option; + settings: Option; dca: Option; }; export type UpdatePositionDataArgs = { positionId: number; - settingParams: OptionOrNullable; + settings: OptionOrNullable; dca: OptionOrNullable; }; @@ -41,7 +41,7 @@ export function getUpdatePositionDataSerializer(): Serializer< return struct( [ ['positionId', u8()], - ['settingParams', option(getSolautoSettingsParametersInpSerializer())], + ['settings', option(getSolautoSettingsParametersInpSerializer())], ['dca', option(getDCASettingsInpSerializer())], ], { description: 'UpdatePositionData' } diff --git a/solauto-sdk/src/idls/switchboard.json b/solauto-sdk/src/idls/switchboard.json index d4a1e928..6996121a 100644 --- a/solauto-sdk/src/idls/switchboard.json +++ b/solauto-sdk/src/idls/switchboard.json @@ -1 +1,1949 @@ -{"address":"SBondMDrcV3K4kxZR1HNVT7osZxAHVHgYXL5Ze1oMUv","metadata":{"name":"sb_on_demand","version":"0.1.0","spec":"0.1.0","description":"Created with Anchor"},"instructions":[{"name":"guardian_quote_verify","discriminator":[168,36,93,156,157,150,148,45],"accounts":[{"name":"guardian","writable":true},{"name":"oracle","writable":true},{"name":"authority","signer":true,"relations":["oracle"]},{"name":"guardian_queue","writable":true,"relations":["state"]},{"name":"state"},{"name":"recent_slothashes","address":"SysvarS1otHashes111111111111111111111111111"}],"args":[{"name":"params","type":{"defined":{"name":"GuardianQuoteVerifyParams"}}}]},{"name":"guardian_register","discriminator":[159,76,53,117,219,29,116,135],"accounts":[{"name":"oracle","writable":true},{"name":"state"},{"name":"guardian_queue","relations":["state"]},{"name":"authority","signer":true,"relations":["state"]}],"args":[{"name":"params","type":{"defined":{"name":"GuardianRegisterParams"}}}]},{"name":"guardian_unregister","discriminator":[215,19,61,120,155,224,120,60],"accounts":[{"name":"oracle","writable":true},{"name":"state"},{"name":"guardian_queue","writable":true,"relations":["state"]},{"name":"authority","signer":true,"relations":["state"]}],"args":[{"name":"params","type":{"defined":{"name":"GuardianUnregisterParams"}}}]},{"name":"oracle_heartbeat","discriminator":[10,175,217,130,111,35,117,54],"accounts":[{"name":"oracle","writable":true},{"name":"oracle_stats","writable":true,"pda":{"seeds":[{"kind":"const","value":[79,114,97,99,108,101,83,116,97,116,115]},{"kind":"account","path":"oracle"}]}},{"name":"oracle_signer","signer":true},{"name":"queue","writable":true,"relations":["oracle","gc_node"]},{"name":"gc_node","writable":true},{"name":"program_state","writable":true},{"name":"payer","writable":true,"signer":true},{"name":"system_program","address":"11111111111111111111111111111111"},{"name":"token_program","address":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"},{"name":"native_mint","address":"So11111111111111111111111111111111111111112"},{"name":"queue_escrow","writable":true},{"name":"stake_program","address":"SBSTk6t52R89MmCdD739Rdd97HdbTQUFHe41vCX7pTt","relations":["program_state"]},{"name":"delegation_pool","writable":true},{"name":"delegation_group","writable":true}],"args":[{"name":"params","type":{"defined":{"name":"OracleHeartbeatParams"}}}]},{"name":"oracle_init","discriminator":[21,158,66,65,60,221,148,61],"accounts":[{"name":"oracle","writable":true,"signer":true},{"name":"oracle_stats","writable":true,"pda":{"seeds":[{"kind":"const","value":[79,114,97,99,108,101,83,116,97,116,115]},{"kind":"account","path":"oracle"}]}},{"name":"program_state","writable":true},{"name":"payer","writable":true,"signer":true},{"name":"system_program","address":"11111111111111111111111111111111"},{"name":"token_program","address":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"},{"name":"lut_signer"},{"name":"lut","writable":true},{"name":"address_lookup_table_program","address":"AddressLookupTab1e1111111111111111111111111"},{"name":"stake_program","relations":["program_state"]},{"name":"stake_pool","relations":["program_state"]}],"args":[{"name":"params","type":{"defined":{"name":"OracleInitParams"}}}]},{"name":"oracle_set_configs","discriminator":[129,111,223,4,191,188,70,180],"accounts":[{"name":"oracle"},{"name":"authority","signer":true,"relations":["oracle"]}],"args":[{"name":"params","type":{"defined":{"name":"OracleSetConfigsParams"}}}]},{"name":"oracle_update_delegation","discriminator":[46,198,113,223,160,189,118,90],"accounts":[{"name":"oracle","writable":true},{"name":"oracle_stats","pda":{"seeds":[{"kind":"const","value":[79,114,97,99,108,101,83,116,97,116,115]},{"kind":"account","path":"oracle"}]}},{"name":"queue","relations":["oracle"]},{"name":"authority","signer":true},{"name":"program_state","writable":true},{"name":"payer","writable":true,"signer":true},{"name":"system_program","address":"11111111111111111111111111111111"},{"name":"token_program","address":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"},{"name":"delegation_pool","writable":true},{"name":"lut_signer"},{"name":"lut","writable":true},{"name":"address_lookup_table_program","address":"AddressLookupTab1e1111111111111111111111111"},{"name":"switch_mint"},{"name":"native_mint","address":"So11111111111111111111111111111111111111112"},{"name":"wsol_vault","writable":true},{"name":"switch_vault","writable":true},{"name":"stake_program","relations":["program_state"]},{"name":"stake_pool"},{"name":"delegation_group"}],"args":[{"name":"params","type":{"defined":{"name":"OracleUpdateDelegationParams"}}}]},{"name":"permission_set","discriminator":[211,122,185,120,129,182,55,103],"accounts":[{"name":"authority","signer":true},{"name":"granter"}],"args":[{"name":"params","type":{"defined":{"name":"PermissionSetParams"}}}]},{"name":"pull_feed_close","discriminator":[19,134,50,142,177,215,196,83],"accounts":[{"name":"pull_feed","writable":true},{"name":"reward_escrow","writable":true},{"name":"lut","writable":true},{"name":"lut_signer"},{"name":"payer","writable":true,"signer":true},{"name":"state"},{"name":"authority","writable":true,"signer":true,"relations":["pull_feed"]},{"name":"token_program","address":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"},{"name":"associated_token_program","address":"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"},{"name":"system_program","address":"11111111111111111111111111111111"},{"name":"address_lookup_table_program","address":"AddressLookupTab1e1111111111111111111111111"}],"args":[{"name":"params","type":{"defined":{"name":"PullFeedCloseParams"}}}]},{"name":"pull_feed_init","discriminator":[198,130,53,198,235,61,143,40],"accounts":[{"name":"pull_feed","writable":true,"signer":true},{"name":"queue"},{"name":"authority"},{"name":"payer","writable":true,"signer":true},{"name":"system_program","address":"11111111111111111111111111111111"},{"name":"program_state"},{"name":"reward_escrow","writable":true,"pda":{"seeds":[{"kind":"account","path":"pull_feed"},{"kind":"const","value":[6,221,246,225,215,101,161,147,217,203,225,70,206,235,121,172,28,180,133,237,95,91,55,145,58,140,245,133,126,255,0,169]},{"kind":"account","path":"wrapped_sol_mint"}],"program":{"kind":"const","value":[140,151,37,143,78,36,137,241,187,61,16,41,20,142,13,131,11,90,19,153,218,255,16,132,4,142,123,216,219,233,248,89]}}},{"name":"token_program","address":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"},{"name":"associated_token_program","address":"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"},{"name":"wrapped_sol_mint","address":"So11111111111111111111111111111111111111112"},{"name":"lut_signer"},{"name":"lut","writable":true},{"name":"address_lookup_table_program","address":"AddressLookupTab1e1111111111111111111111111"}],"args":[{"name":"params","type":{"defined":{"name":"PullFeedInitParams"}}}]},{"name":"pull_feed_set_configs","discriminator":[217,45,11,246,64,26,82,168],"accounts":[{"name":"pull_feed","writable":true},{"name":"authority","signer":true,"relations":["pull_feed"]}],"args":[{"name":"params","type":{"defined":{"name":"PullFeedSetConfigsParams"}}}]},{"name":"pull_feed_submit_response","discriminator":[150,22,215,166,143,93,48,137],"accounts":[{"name":"feed","writable":true},{"name":"queue","relations":["feed"]},{"name":"program_state"},{"name":"recent_slothashes","address":"SysvarS1otHashes111111111111111111111111111"},{"name":"payer","writable":true,"signer":true},{"name":"system_program","address":"11111111111111111111111111111111"},{"name":"reward_vault","writable":true},{"name":"token_program","address":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"},{"name":"token_mint","address":"So11111111111111111111111111111111111111112"}],"args":[{"name":"params","type":{"defined":{"name":"PullFeedSubmitResponseParams"}}}]},{"name":"pull_feed_submit_response_many","discriminator":[47,156,45,25,200,71,37,215],"accounts":[{"name":"queue"},{"name":"program_state"},{"name":"recent_slothashes","address":"SysvarS1otHashes111111111111111111111111111"},{"name":"payer","writable":true,"signer":true},{"name":"system_program","address":"11111111111111111111111111111111"},{"name":"reward_vault","writable":true},{"name":"token_program","address":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"},{"name":"token_mint","address":"So11111111111111111111111111111111111111112"}],"args":[{"name":"params","type":{"defined":{"name":"PullFeedSubmitResponseManyParams"}}}]},{"name":"queue_add_mr_enclave","discriminator":[199,255,81,50,60,133,171,138],"accounts":[{"name":"queue","writable":true},{"name":"authority","signer":true},{"name":"program_authority"},{"name":"state"}],"args":[{"name":"params","type":{"defined":{"name":"QueueAddMrEnclaveParams"}}}]},{"name":"queue_allow_subsidies","discriminator":[94,203,82,157,188,138,202,108],"accounts":[{"name":"queue","writable":true},{"name":"authority","signer":true,"relations":["state"]},{"name":"state","writable":true}],"args":[{"name":"params","type":{"defined":{"name":"QueueAllowSubsidiesParams"}}}]},{"name":"queue_garbage_collect","discriminator":[187,208,104,247,16,91,96,98],"accounts":[{"name":"queue","writable":true},{"name":"oracle","writable":true},{"name":"authority","signer":true},{"name":"state"}],"args":[{"name":"params","type":{"defined":{"name":"QueueGarbageCollectParams"}}}]},{"name":"queue_init","discriminator":[144,18,99,145,133,27,207,13],"accounts":[{"name":"queue","writable":true,"signer":true},{"name":"queue_escrow","writable":true,"pda":{"seeds":[{"kind":"account","path":"queue"},{"kind":"const","value":[6,221,246,225,215,101,161,147,217,203,225,70,206,235,121,172,28,180,133,237,95,91,55,145,58,140,245,133,126,255,0,169]},{"kind":"account","path":"native_mint"}],"program":{"kind":"const","value":[140,151,37,143,78,36,137,241,187,61,16,41,20,142,13,131,11,90,19,153,218,255,16,132,4,142,123,216,219,233,248,89]}}},{"name":"authority"},{"name":"payer","writable":true,"signer":true},{"name":"system_program","address":"11111111111111111111111111111111"},{"name":"token_program","address":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"},{"name":"native_mint","address":"So11111111111111111111111111111111111111112"},{"name":"program_state"},{"name":"lut_signer","writable":true},{"name":"lut","writable":true},{"name":"address_lookup_table_program","address":"AddressLookupTab1e1111111111111111111111111"},{"name":"associated_token_program","address":"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"}],"args":[{"name":"params","type":{"defined":{"name":"QueueInitParams"}}}]},{"name":"queue_init_delegation_group","discriminator":[239,146,75,158,20,166,159,14],"accounts":[{"name":"queue","writable":true},{"name":"payer","writable":true,"signer":true},{"name":"system_program","address":"11111111111111111111111111111111"},{"name":"program_state"},{"name":"lut_signer"},{"name":"lut","writable":true},{"name":"address_lookup_table_program","address":"AddressLookupTab1e1111111111111111111111111"},{"name":"delegation_group","writable":true},{"name":"stake_program","relations":["program_state"]},{"name":"stake_pool"}],"args":[{"name":"params","type":{"defined":{"name":"QueueInitDelegationGroupParams"}}}]},{"name":"queue_remove_mr_enclave","discriminator":[3,64,135,33,190,133,68,252],"accounts":[{"name":"queue","writable":true},{"name":"authority","signer":true},{"name":"program_authority"},{"name":"state"}],"args":[{"name":"params","type":{"defined":{"name":"QueueRemoveMrEnclaveParams"}}}]},{"name":"queue_set_configs","discriminator":[54,183,243,199,49,103,142,48],"accounts":[{"name":"queue","writable":true},{"name":"authority","signer":true},{"name":"state"}],"args":[{"name":"params","type":{"defined":{"name":"QueueSetConfigsParams"}}}]},{"name":"randomness_commit","discriminator":[52,170,152,201,179,133,242,141],"accounts":[{"name":"randomness","writable":true},{"name":"queue","relations":["randomness","oracle"]},{"name":"oracle","writable":true},{"name":"recent_slothashes","address":"SysvarS1otHashes111111111111111111111111111"},{"name":"authority","signer":true,"relations":["randomness"]}],"args":[{"name":"params","type":{"defined":{"name":"RandomnessCommitParams"}}}]},{"name":"randomness_init","discriminator":[9,9,204,33,50,116,113,15],"accounts":[{"name":"randomness","writable":true,"signer":true},{"name":"reward_escrow","writable":true,"pda":{"seeds":[{"kind":"account","path":"randomness"},{"kind":"const","value":[6,221,246,225,215,101,161,147,217,203,225,70,206,235,121,172,28,180,133,237,95,91,55,145,58,140,245,133,126,255,0,169]},{"kind":"account","path":"wrapped_sol_mint"}],"program":{"kind":"const","value":[140,151,37,143,78,36,137,241,187,61,16,41,20,142,13,131,11,90,19,153,218,255,16,132,4,142,123,216,219,233,248,89]}}},{"name":"authority","signer":true},{"name":"queue","writable":true},{"name":"payer","writable":true,"signer":true},{"name":"system_program","address":"11111111111111111111111111111111"},{"name":"token_program","address":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"},{"name":"associated_token_program","address":"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"},{"name":"wrapped_sol_mint","address":"So11111111111111111111111111111111111111112"},{"name":"program_state"},{"name":"lut_signer"},{"name":"lut","writable":true},{"name":"address_lookup_table_program","address":"AddressLookupTab1e1111111111111111111111111"}],"args":[{"name":"params","type":{"defined":{"name":"RandomnessInitParams"}}}]},{"name":"randomness_reveal","discriminator":[197,181,187,10,30,58,20,73],"accounts":[{"name":"randomness","writable":true},{"name":"oracle","relations":["randomness"]},{"name":"queue","relations":["oracle"]},{"name":"stats","writable":true,"pda":{"seeds":[{"kind":"const","value":[79,114,97,99,108,101,82,97,110,100,111,109,110,101,115,115,83,116,97,116,115]},{"kind":"account","path":"oracle"}]}},{"name":"authority","signer":true,"relations":["randomness"]},{"name":"payer","writable":true,"signer":true},{"name":"recent_slothashes","address":"SysvarS1otHashes111111111111111111111111111"},{"name":"system_program","address":"11111111111111111111111111111111"},{"name":"reward_escrow","writable":true},{"name":"token_program","address":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"},{"name":"wrapped_sol_mint","address":"So11111111111111111111111111111111111111112"},{"name":"program_state"}],"args":[{"name":"params","type":{"defined":{"name":"RandomnessRevealParams"}}}]},{"name":"state_init","discriminator":[103,241,106,190,217,153,87,105],"accounts":[{"name":"state","writable":true,"pda":{"seeds":[{"kind":"const","value":[83,84,65,84,69]}]}},{"name":"payer","writable":true,"signer":true},{"name":"system_program","address":"11111111111111111111111111111111"}],"args":[{"name":"params","type":{"defined":{"name":"StateInitParams"}}}]},{"name":"state_set_configs","discriminator":[40,98,76,37,206,9,47,144],"accounts":[{"name":"state","writable":true},{"name":"authority","signer":true,"relations":["state"]},{"name":"queue","writable":true},{"name":"payer","writable":true,"signer":true},{"name":"system_program","address":"11111111111111111111111111111111"}],"args":[{"name":"params","type":{"defined":{"name":"StateSetConfigsParams"}}}]}],"accounts":[{"name":"OracleAccountData","discriminator":[128,30,16,241,170,73,55,54]},{"name":"OracleStatsAccountData","discriminator":[180,157,178,234,240,27,152,179]},{"name":"PullFeedAccountData","discriminator":[196,27,108,196,10,215,219,40]},{"name":"QueueAccountData","discriminator":[217,194,55,127,184,83,138,1]},{"name":"RandomnessAccountData","discriminator":[10,66,229,135,220,239,217,114]},{"name":"State","discriminator":[216,146,107,94,104,75,182,177]}],"events":[{"name":"CostWhitelistEvent","discriminator":[56,107,191,127,116,6,138,149]},{"name":"GarbageCollectionEvent","discriminator":[232,235,2,188,8,143,145,237]},{"name":"GuardianQuoteVerifyEvent","discriminator":[31,37,39,6,214,186,33,115]},{"name":"OracleHeartbeatEvent","discriminator":[52,29,166,2,94,7,188,13]},{"name":"OracleInitEvent","discriminator":[89,193,219,200,1,83,167,24]},{"name":"OracleQuoteOverrideEvent","discriminator":[78,204,191,210,164,196,244,65]},{"name":"OracleQuoteRotateEvent","discriminator":[26,189,196,192,225,127,26,228]},{"name":"OracleQuoteVerifyRequestEvent","discriminator":[203,209,79,0,20,71,226,202]},{"name":"PermissionSetEvent","discriminator":[148,86,123,0,102,20,119,206]},{"name":"PullFeedErrorValueEvent","discriminator":[225,80,192,95,14,12,83,192]},{"name":"PullFeedValueEvents","discriminator":[86,7,231,28,122,161,117,69]},{"name":"QueueAddMrEnclaveEvent","discriminator":[170,186,175,38,216,51,69,175]},{"name":"QueueInitEvent","discriminator":[44,137,99,227,107,8,30,105]},{"name":"QueueRemoveMrEnclaveEvent","discriminator":[4,105,196,60,84,122,203,196]},{"name":"RandomnessCommitEvent","discriminator":[88,60,172,90,112,10,206,147]}],"errors":[{"code":6000,"name":"GenericError"},{"code":6001,"name":"InvalidQuote"},{"code":6002,"name":"InsufficientQueue"},{"code":6003,"name":"QueueFull"},{"code":6004,"name":"InvalidEnclaveSigner"},{"code":6005,"name":"InvalidSigner"},{"code":6006,"name":"MrEnclaveAlreadyExists"},{"code":6007,"name":"MrEnclaveAtCapacity"},{"code":6008,"name":"MrEnclaveDoesntExist"},{"code":6009,"name":"PermissionDenied"},{"code":6010,"name":"InvalidQueue"},{"code":6011,"name":"IncorrectMrEnclave"},{"code":6012,"name":"InvalidAuthority"},{"code":6013,"name":"InvalidMrEnclave"},{"code":6014,"name":"InvalidTimestamp"},{"code":6015,"name":"InvalidOracleIdx"},{"code":6016,"name":"InvalidSecpSignature"},{"code":6017,"name":"InvalidGuardianQueue"},{"code":6018,"name":"InvalidIndex"},{"code":6019,"name":"InvalidOracleQueue"},{"code":6020,"name":"InvalidPermission"},{"code":6021,"name":"InvalidePermissionedAccount"},{"code":6022,"name":"InvalidEpochRotate"},{"code":6023,"name":"InvalidEpochFinalize"},{"code":6024,"name":"InvalidEscrow"},{"code":6025,"name":"IllegalOracle"},{"code":6026,"name":"IllegalExecuteAttempt"},{"code":6027,"name":"IllegalFeedValue"},{"code":6028,"name":"InvalidOracleFeedStats"},{"code":6029,"name":"InvalidStateAuthority"},{"code":6030,"name":"NotEnoughSamples"},{"code":6031,"name":"OracleIsVerified"},{"code":6032,"name":"QueueIsEmpty"},{"code":6033,"name":"SecpRecoverFailure"},{"code":6034,"name":"StaleSample"},{"code":6035,"name":"SwitchboardRandomnessTooOld"},{"code":6036,"name":"EpochIdMismatch"},{"code":6037,"name":"GuardianAlreadyVoted"},{"code":6038,"name":"RandomnessNotRequested"},{"code":6039,"name":"InvalidSlotNumber"},{"code":6040,"name":"RandomnessOracleKeyExpired"},{"code":6041,"name":"InvalidAdvisory"},{"code":6042,"name":"InvalidOracleStats"},{"code":6043,"name":"InvalidStakeProgram"},{"code":6044,"name":"InvalidStakePool"},{"code":6045,"name":"InvalidDelegationPool"},{"code":6046,"name":"UnparsableAccount"},{"code":6047,"name":"InvalidInstruction"},{"code":6048,"name":"OracleAlreadyVerified"},{"code":6049,"name":"GuardianNotVerified"},{"code":6050,"name":"InvalidConstraint"},{"code":6051,"name":"InvalidDelegationGroup"},{"code":6052,"name":"OracleKeyNotFound"},{"code":6053,"name":"GuardianReregisterAttempt"}],"types":[{"name":"CompactResult","serialization":"bytemuck","repr":{"kind":"c"},"type":{"kind":"struct","fields":[{"name":"std_dev","docs":["The standard deviation of the submissions needed for quorom size"],"type":"f32"},{"name":"mean","docs":["The mean of the submissions needed for quorom size"],"type":"f32"},{"name":"slot","docs":["The slot at which this value was signed."],"type":"u64"}]}},{"name":"CostWhitelistEvent","type":{"kind":"struct","fields":[{"name":"feeds","type":{"vec":"pubkey"}},{"name":"reward","type":"u32"}]}},{"name":"CurrentResult","serialization":"bytemuck","repr":{"kind":"c"},"type":{"kind":"struct","fields":[{"name":"value","docs":["The median value of the submissions needed for quorom size"],"type":"i128"},{"name":"std_dev","docs":["The standard deviation of the submissions needed for quorom size"],"type":"i128"},{"name":"mean","docs":["The mean of the submissions needed for quorom size"],"type":"i128"},{"name":"range","docs":["The range of the submissions needed for quorom size"],"type":"i128"},{"name":"min_value","docs":["The minimum value of the submissions needed for quorom size"],"type":"i128"},{"name":"max_value","docs":["The maximum value of the submissions needed for quorom size"],"type":"i128"},{"name":"num_samples","docs":["The number of samples used to calculate this result"],"type":"u8"},{"name":"padding1","type":{"array":["u8",7]}},{"name":"slot","docs":["The slot at which this value was signed."],"type":"u64"},{"name":"min_slot","docs":["The slot at which the first considered submission was made"],"type":"u64"},{"name":"max_slot","docs":["The slot at which the last considered submission was made"],"type":"u64"}]}},{"name":"GarbageCollectionEvent","type":{"kind":"struct","fields":[{"name":"oracle","type":"pubkey"},{"name":"queue","type":"pubkey"}]}},{"name":"GuardianQuoteVerifyEvent","type":{"kind":"struct","fields":[{"name":"quote","type":"pubkey"},{"name":"queue","type":"pubkey"},{"name":"oracle","type":"pubkey"}]}},{"name":"GuardianQuoteVerifyParams","type":{"kind":"struct","fields":[{"name":"timestamp","type":"i64"},{"name":"mr_enclave","type":{"array":["u8",32]}},{"name":"_reserved1","type":"u32"},{"name":"ed25519_key","type":"pubkey"},{"name":"secp256k1_key","type":{"array":["u8",64]}},{"name":"slot","type":"u64"},{"name":"signature","type":{"array":["u8",64]}},{"name":"recovery_id","type":"u8"},{"name":"advisories","type":{"vec":"u32"}}]}},{"name":"GuardianRegisterParams","type":{"kind":"struct","fields":[]}},{"name":"GuardianUnregisterParams","type":{"kind":"struct","fields":[]}},{"name":"MegaSlotInfo","serialization":"bytemuck","repr":{"kind":"c"},"type":{"kind":"struct","fields":[{"name":"reserved1","type":"u64"},{"name":"slot_end","type":"u64"},{"name":"perf_goal","type":"i64"},{"name":"current_signature_count","type":"i64"}]}},{"name":"MultiSubmission","type":{"kind":"struct","fields":[{"name":"values","type":{"vec":"i128"}},{"name":"signature","type":{"array":["u8",64]}},{"name":"recovery_id","type":"u8"}]}},{"name":"OracleAccountData","serialization":"bytemuck","repr":{"kind":"c"},"type":{"kind":"struct","fields":[{"name":"enclave","docs":["Represents the state of the quote verifiers enclave."],"type":{"defined":{"name":"Quote"}}},{"name":"authority","docs":["The authority of the EnclaveAccount which is permitted to make account changes."],"type":"pubkey"},{"name":"queue","docs":["Queue used for attestation to verify a MRENCLAVE measurement."],"type":"pubkey"},{"name":"created_at","docs":["The unix timestamp when the quote was created."],"type":"i64"},{"name":"last_heartbeat","docs":["The last time the quote heartbeated on-chain."],"type":"i64"},{"name":"secp_authority","type":{"array":["u8",64]}},{"name":"gateway_uri","docs":["URI location of the verifier's gateway."],"type":{"array":["u8",64]}},{"name":"permissions","type":"u64"},{"name":"is_on_queue","docs":["Whether the quote is located on the AttestationQueues buffer."],"type":"u8"},{"name":"_padding1","type":{"array":["u8",7]}},{"name":"lut_slot","type":"u64"},{"name":"last_reward_epoch","type":"u64"},{"name":"_ebuf4","type":{"array":["u8",16]}},{"name":"_ebuf3","type":{"array":["u8",32]}},{"name":"_ebuf2","type":{"array":["u8",64]}},{"name":"_ebuf1","type":{"array":["u8",1024]}}]}},{"name":"OracleEpochInfo","serialization":"bytemuck","repr":{"kind":"c"},"type":{"kind":"struct","fields":[{"name":"id","type":"u64"},{"name":"reserved1","type":"u64"},{"name":"slot_end","type":"u64"},{"name":"slash_score","type":"u64"},{"name":"reward_score","type":"u64"},{"name":"stake_score","type":"u64"}]}},{"name":"OracleHeartbeatEvent","type":{"kind":"struct","fields":[{"name":"oracle","type":"pubkey"},{"name":"queue","type":"pubkey"}]}},{"name":"OracleHeartbeatParams","type":{"kind":"struct","fields":[{"name":"gateway_uri","type":{"option":{"array":["u8",64]}}}]}},{"name":"OracleInitEvent","type":{"kind":"struct","fields":[{"name":"oracle","type":"pubkey"}]}},{"name":"OracleInitParams","type":{"kind":"struct","fields":[{"name":"recent_slot","type":"u64"},{"name":"authority","type":"pubkey"},{"name":"queue","type":"pubkey"},{"name":"secp_authority","type":{"option":{"array":["u8",64]}}}]}},{"name":"OracleQuoteOverrideEvent","type":{"kind":"struct","fields":[{"name":"oracle","type":"pubkey"},{"name":"queue","type":"pubkey"}]}},{"name":"OracleQuoteRotateEvent","type":{"kind":"struct","fields":[{"name":"oracle","type":"pubkey"}]}},{"name":"OracleQuoteVerifyRequestEvent","type":{"kind":"struct","fields":[{"name":"quote","type":"pubkey"},{"name":"oracle","type":"pubkey"}]}},{"name":"OracleSetConfigsParams","type":{"kind":"struct","fields":[{"name":"new_authority","type":{"option":"pubkey"}},{"name":"new_secp_authority","type":{"option":{"array":["u8",64]}}}]}},{"name":"OracleStatsAccountData","serialization":"bytemuck","repr":{"kind":"c"},"type":{"kind":"struct","fields":[{"name":"owner","type":"pubkey"},{"name":"oracle","type":"pubkey"},{"name":"finalized_epoch","docs":["The last epoch that has completed. cleared after registered with the","staking program."],"type":{"defined":{"name":"OracleEpochInfo"}}},{"name":"current_epoch","docs":["The current epoch info being used by the oracle. for stake. Will moved","to finalized_epoch as soon as the epoch is over."],"type":{"defined":{"name":"OracleEpochInfo"}}},{"name":"mega_slot_info","type":{"defined":{"name":"MegaSlotInfo"}}},{"name":"last_transfer_slot","type":"u64"},{"name":"bump","type":"u8"},{"name":"padding1","type":{"array":["u8",7]}},{"name":"_ebuf","docs":["Reserved."],"type":{"array":["u8",1024]}}]}},{"name":"OracleSubmission","serialization":"bytemuck","repr":{"kind":"c"},"type":{"kind":"struct","fields":[{"name":"oracle","docs":["The public key of the oracle that submitted this value."],"type":"pubkey"},{"name":"slot","docs":["The slot at which this value was signed."],"type":"u64"},{"name":"padding1","type":{"array":["u8",8]}},{"name":"value","docs":["The value that was submitted."],"type":"i128"}]}},{"name":"OracleUpdateDelegationParams","type":{"kind":"struct","fields":[{"name":"_reserved1","type":"u64"}]}},{"name":"PermissionSetEvent","type":{"kind":"struct","fields":[{"name":"permission","type":"pubkey"}]}},{"name":"PermissionSetParams","type":{"kind":"struct","fields":[{"name":"permission","type":"u8"},{"name":"enable","type":"bool"}]}},{"name":"PullFeedAccountData","docs":["A representation of the data in a pull feed account."],"serialization":"bytemuck","repr":{"kind":"c"},"type":{"kind":"struct","fields":[{"name":"submissions","docs":["The oracle submissions for this feed."],"type":{"array":[{"defined":{"name":"OracleSubmission"}},32]}},{"name":"authority","docs":["The public key of the authority that can update the feed hash that","this account will use for registering updates."],"type":"pubkey"},{"name":"queue","docs":["The public key of the queue which oracles must be bound to in order to","submit data to this feed."],"type":"pubkey"},{"name":"feed_hash","docs":["SHA-256 hash of the job schema oracles will execute to produce data","for this feed."],"type":{"array":["u8",32]}},{"name":"initialized_at","docs":["The slot at which this account was initialized."],"type":"i64"},{"name":"permissions","type":"u64"},{"name":"max_variance","type":"u64"},{"name":"min_responses","type":"u32"},{"name":"name","type":{"array":["u8",32]}},{"name":"padding1","type":{"array":["u8",2]}},{"name":"historical_result_idx","type":"u8"},{"name":"min_sample_size","type":"u8"},{"name":"last_update_timestamp","type":"i64"},{"name":"lut_slot","type":"u64"},{"name":"_reserved1","type":{"array":["u8",32]}},{"name":"result","type":{"defined":{"name":"CurrentResult"}}},{"name":"max_staleness","type":"u32"},{"name":"padding2","type":{"array":["u8",12]}},{"name":"historical_results","type":{"array":[{"defined":{"name":"CompactResult"}},32]}},{"name":"_ebuf4","type":{"array":["u8",8]}},{"name":"_ebuf3","type":{"array":["u8",24]}},{"name":"_ebuf2","type":{"array":["u8",256]}}]}},{"name":"PullFeedCloseParams","type":{"kind":"struct","fields":[]}},{"name":"PullFeedErrorValueEvent","type":{"kind":"struct","fields":[{"name":"feed","type":"pubkey"},{"name":"oracle","type":"pubkey"}]}},{"name":"PullFeedInitParams","type":{"kind":"struct","fields":[{"name":"feed_hash","type":{"array":["u8",32]}},{"name":"max_variance","type":"u64"},{"name":"min_responses","type":"u32"},{"name":"name","type":{"array":["u8",32]}},{"name":"recent_slot","type":"u64"},{"name":"ipfs_hash","type":{"array":["u8",32]}},{"name":"min_sample_size","type":"u8"},{"name":"max_staleness","type":"u32"}]}},{"name":"PullFeedSetConfigsParams","type":{"kind":"struct","fields":[{"name":"feed_hash","type":{"option":{"array":["u8",32]}}},{"name":"authority","type":{"option":"pubkey"}},{"name":"max_variance","type":{"option":"u64"}},{"name":"min_responses","type":{"option":"u32"}},{"name":"name","type":{"option":{"array":["u8",32]}}},{"name":"ipfs_hash","type":{"option":{"array":["u8",32]}}},{"name":"min_sample_size","type":{"option":"u8"}},{"name":"max_staleness","type":{"option":"u32"}}]}},{"name":"PullFeedSubmitResponseManyParams","type":{"kind":"struct","fields":[{"name":"slot","type":"u64"},{"name":"submissions","type":{"vec":{"defined":{"name":"MultiSubmission"}}}}]}},{"name":"PullFeedSubmitResponseParams","type":{"kind":"struct","fields":[{"name":"slot","type":"u64"},{"name":"submissions","type":{"vec":{"defined":{"name":"Submission"}}}}]}},{"name":"PullFeedValueEvents","type":{"kind":"struct","fields":[{"name":"feeds","type":{"vec":"pubkey"}},{"name":"oracles","type":{"vec":"pubkey"}},{"name":"values","type":{"vec":{"vec":"i128"}}},{"name":"reward","type":"u32"}]}},{"name":"QueueAccountData","docs":["An Queue represents a round-robin queue of oracle oracles who attest on-chain","whether a Switchboard Function was executed within an enclave against an expected set of","enclave measurements.","","For an oracle to join the queue, the oracle must first submit their enclave quote on-chain and","wait for an existing oracle to attest their quote. If the oracle's quote matches an expected","measurement within the queues mr_enclaves config, it is granted permissions and will start","being assigned update requests."],"serialization":"bytemuck","repr":{"kind":"c"},"type":{"kind":"struct","fields":[{"name":"authority","docs":["The address of the authority which is permitted to add/remove allowed enclave measurements."],"type":"pubkey"},{"name":"mr_enclaves","docs":["Allowed enclave measurements."],"type":{"array":[{"array":["u8",32]},32]}},{"name":"oracle_keys","docs":["The addresses of the quote oracles who have a valid","verification status and have heartbeated on-chain recently."],"type":{"array":["pubkey",128]}},{"name":"max_quote_verification_age","docs":["The maximum allowable time until a EnclaveAccount needs to be re-verified on-chain."],"type":"i64"},{"name":"last_heartbeat","docs":["The unix timestamp when the last quote oracle heartbeated on-chain."],"type":"i64"},{"name":"node_timeout","type":"i64"},{"name":"oracle_min_stake","docs":["The minimum number of lamports a quote oracle needs to lock-up in order to heartbeat and verify other quotes."],"type":"u64"},{"name":"allow_authority_override_after","type":"i64"},{"name":"mr_enclaves_len","docs":["The number of allowed enclave measurements."],"type":"u32"},{"name":"oracle_keys_len","docs":["The length of valid quote oracles for the given attestation queue."],"type":"u32"},{"name":"reward","docs":["The reward paid to quote oracles for attesting on-chain."],"type":"u32"},{"name":"curr_idx","docs":["Incrementer used to track the current quote oracle permitted to run any available functions."],"type":"u32"},{"name":"gc_idx","docs":["Incrementer used to garbage collect and remove stale quote oracles."],"type":"u32"},{"name":"require_authority_heartbeat_permission","type":"u8"},{"name":"require_authority_verify_permission","type":"u8"},{"name":"require_usage_permissions","type":"u8"},{"name":"signer_bump","type":"u8"},{"name":"mint","type":"pubkey"},{"name":"lut_slot","type":"u64"},{"name":"allow_subsidies","type":"u8"},{"name":"_ebuf6","docs":["Reserved."],"type":{"array":["u8",23]}},{"name":"_ebuf5","type":{"array":["u8",32]}},{"name":"_ebuf4","type":{"array":["u8",64]}},{"name":"_ebuf3","type":{"array":["u8",128]}},{"name":"_ebuf2","type":{"array":["u8",256]}},{"name":"_ebuf1","type":{"array":["u8",512]}}]}},{"name":"QueueAddMrEnclaveEvent","type":{"kind":"struct","fields":[{"name":"queue","type":"pubkey"},{"name":"mr_enclave","type":{"array":["u8",32]}}]}},{"name":"QueueAddMrEnclaveParams","type":{"kind":"struct","fields":[{"name":"mr_enclave","type":{"array":["u8",32]}}]}},{"name":"QueueAllowSubsidiesParams","type":{"kind":"struct","fields":[{"name":"allow_subsidies","type":"u8"}]}},{"name":"QueueGarbageCollectParams","type":{"kind":"struct","fields":[{"name":"idx","type":"u32"}]}},{"name":"QueueInitDelegationGroupParams","type":{"kind":"struct","fields":[]}},{"name":"QueueInitEvent","type":{"kind":"struct","fields":[{"name":"queue","type":"pubkey"}]}},{"name":"QueueInitParams","type":{"kind":"struct","fields":[{"name":"allow_authority_override_after","type":"u32"},{"name":"require_authority_heartbeat_permission","type":"bool"},{"name":"require_usage_permissions","type":"bool"},{"name":"max_quote_verification_age","type":"u32"},{"name":"reward","type":"u32"},{"name":"node_timeout","type":"u32"},{"name":"recent_slot","type":"u64"}]}},{"name":"QueueRemoveMrEnclaveEvent","type":{"kind":"struct","fields":[{"name":"queue","type":"pubkey"},{"name":"mr_enclave","type":{"array":["u8",32]}}]}},{"name":"QueueRemoveMrEnclaveParams","type":{"kind":"struct","fields":[{"name":"mr_enclave","type":{"array":["u8",32]}}]}},{"name":"QueueSetConfigsParams","type":{"kind":"struct","fields":[{"name":"authority","type":{"option":"pubkey"}},{"name":"reward","type":{"option":"u32"}},{"name":"node_timeout","type":{"option":"i64"}}]}},{"name":"Quote","serialization":"bytemuck","repr":{"kind":"c"},"type":{"kind":"struct","fields":[{"name":"enclave_signer","docs":["The address of the signer generated within an enclave."],"type":"pubkey"},{"name":"mr_enclave","docs":["The quotes MRENCLAVE measurement dictating the contents of the secure enclave."],"type":{"array":["u8",32]}},{"name":"verification_status","docs":["The VerificationStatus of the quote."],"type":"u8"},{"name":"padding1","type":{"array":["u8",7]}},{"name":"verification_timestamp","docs":["The unix timestamp when the quote was last verified."],"type":"i64"},{"name":"valid_until","docs":["The unix timestamp when the quotes verification status expires."],"type":"i64"},{"name":"quote_registry","docs":["The off-chain registry where the verifiers quote can be located."],"type":{"array":["u8",32]}},{"name":"registry_key","docs":["Key to lookup the buffer data on IPFS or an alternative decentralized storage solution."],"type":{"array":["u8",64]}},{"name":"secp256k1_signer","docs":["The secp256k1 public key of the enclave signer. Derived from the enclave_signer."],"type":{"array":["u8",64]}},{"name":"last_ed25519_signer","type":"pubkey"},{"name":"last_secp256k1_signer","type":{"array":["u8",64]}},{"name":"last_rotate_slot","type":"u64"},{"name":"guardian_approvers","type":{"array":["pubkey",64]}},{"name":"guardian_approvers_len","type":"u8"},{"name":"padding2","type":{"array":["u8",7]}},{"name":"staging_ed25519_signer","type":"pubkey"},{"name":"staging_secp256k1_signer","type":{"array":["u8",64]}},{"name":"_ebuf4","docs":["Reserved."],"type":{"array":["u8",32]}},{"name":"_ebuf3","type":{"array":["u8",128]}},{"name":"_ebuf2","type":{"array":["u8",256]}},{"name":"_ebuf1","type":{"array":["u8",512]}}]}},{"name":"RandomnessAccountData","serialization":"bytemuck","repr":{"kind":"c"},"type":{"kind":"struct","fields":[{"name":"authority","type":"pubkey"},{"name":"queue","type":"pubkey"},{"name":"seed_slothash","type":{"array":["u8",32]}},{"name":"seed_slot","type":"u64"},{"name":"oracle","type":"pubkey"},{"name":"reveal_slot","type":"u64"},{"name":"value","type":{"array":["u8",32]}},{"name":"lut_slot","type":"u64"},{"name":"_ebuf3","type":{"array":["u8",24]}},{"name":"_ebuf2","type":{"array":["u8",64]}},{"name":"_ebuf1","type":{"array":["u8",128]}},{"name":"active_secp256k1_signer","type":{"array":["u8",64]}},{"name":"active_secp256k1_expiration","type":"i64"}]}},{"name":"RandomnessCommitEvent","type":{"kind":"struct","fields":[{"name":"randomness_account","type":"pubkey"},{"name":"oracle","type":"pubkey"},{"name":"slot","type":"u64"},{"name":"slothash","type":{"array":["u8",32]}}]}},{"name":"RandomnessCommitParams","type":{"kind":"struct","fields":[]}},{"name":"RandomnessInitParams","type":{"kind":"struct","fields":[{"name":"recent_slot","type":"u64"}]}},{"name":"RandomnessRevealParams","type":{"kind":"struct","fields":[{"name":"signature","type":{"array":["u8",64]}},{"name":"recovery_id","type":"u8"},{"name":"value","type":{"array":["u8",32]}}]}},{"name":"State","serialization":"bytemuck","repr":{"kind":"c"},"type":{"kind":"struct","fields":[{"name":"bump","type":"u8"},{"name":"test_only_disable_mr_enclave_check","type":"u8"},{"name":"enable_staking","type":"u8"},{"name":"padding1","type":{"array":["u8",5]}},{"name":"authority","type":"pubkey"},{"name":"guardian_queue","type":"pubkey"},{"name":"reserved1","type":"u64"},{"name":"epoch_length","type":"u64"},{"name":"current_epoch","type":{"defined":{"name":"StateEpochInfo"}}},{"name":"next_epoch","type":{"defined":{"name":"StateEpochInfo"}}},{"name":"finalized_epoch","type":{"defined":{"name":"StateEpochInfo"}}},{"name":"stake_pool","type":"pubkey"},{"name":"stake_program","type":"pubkey"},{"name":"switch_mint","type":"pubkey"},{"name":"sgx_advisories","type":{"array":["u16",32]}},{"name":"advisories_len","type":"u8"},{"name":"padding2","type":"u8"},{"name":"flat_reward_cut_percentage","type":"u8"},{"name":"enable_slashing","type":"u8"},{"name":"subsidy_amount","type":"u32"},{"name":"lut_slot","type":"u64"},{"name":"base_reward","type":"u32"},{"name":"_ebuf6","type":{"array":["u8",28]}},{"name":"_ebuf5","type":{"array":["u8",32]}},{"name":"_ebuf4","type":{"array":["u8",64]}},{"name":"_ebuf3","type":{"array":["u8",128]}},{"name":"_ebuf2","type":{"array":["u8",512]}},{"name":"cost_whitelist","docs":["Cost whitelist by authority"],"type":{"array":["pubkey",32]}}]}},{"name":"StateEpochInfo","serialization":"bytemuck","repr":{"kind":"c"},"type":{"kind":"struct","fields":[{"name":"id","type":"u64"},{"name":"_reserved1","type":"u64"},{"name":"slot_end","type":"u64"}]}},{"name":"StateInitParams","type":{"kind":"struct","fields":[]}},{"name":"StateSetConfigsParams","type":{"kind":"struct","fields":[{"name":"new_authority","type":"pubkey"},{"name":"test_only_disable_mr_enclave_check","type":"u8"},{"name":"stake_pool","type":"pubkey"},{"name":"stake_program","type":"pubkey"},{"name":"add_advisory","type":"u16"},{"name":"rm_advisory","type":"u16"},{"name":"epoch_length","type":"u32"},{"name":"reset_epochs","type":"bool"},{"name":"switch_mint","type":"pubkey"},{"name":"enable_staking","type":"u8"},{"name":"subsidy_amount","type":"u32"},{"name":"base_reward","type":"u32"},{"name":"add_cost_wl","type":"pubkey"},{"name":"rm_cost_wl","type":"pubkey"}]}},{"name":"Submission","type":{"kind":"struct","fields":[{"name":"value","type":"i128"},{"name":"signature","type":{"array":["u8",64]}},{"name":"recovery_id","type":"u8"},{"name":"offset","type":"u8"}]}}]} \ No newline at end of file +{ + "address": "SBondMDrcV3K4kxZR1HNVT7osZxAHVHgYXL5Ze1oMUv", + "metadata": { + "name": "sb_on_demand", + "version": "0.1.0", + "spec": "0.1.0", + "description": "Created with Anchor" + }, + "instructions": [ + { + "name": "guardian_quote_verify", + "discriminator": [168, 36, 93, 156, 157, 150, 148, 45], + "accounts": [ + { "name": "guardian", "writable": true }, + { "name": "oracle", "writable": true }, + { "name": "authority", "signer": true, "relations": ["oracle"] }, + { "name": "guardian_queue", "writable": true, "relations": ["state"] }, + { "name": "state" }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "GuardianQuoteVerifyParams" } } + } + ] + }, + { + "name": "guardian_register", + "discriminator": [159, 76, 53, 117, 219, 29, 116, 135], + "accounts": [ + { "name": "oracle", "writable": true }, + { "name": "state" }, + { "name": "guardian_queue", "relations": ["state"] }, + { "name": "authority", "signer": true, "relations": ["state"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "GuardianRegisterParams" } } + } + ] + }, + { + "name": "guardian_unregister", + "discriminator": [215, 19, 61, 120, 155, 224, 120, 60], + "accounts": [ + { "name": "oracle", "writable": true }, + { "name": "state" }, + { "name": "guardian_queue", "writable": true, "relations": ["state"] }, + { "name": "authority", "signer": true, "relations": ["state"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "GuardianUnregisterParams" } } + } + ] + }, + { + "name": "oracle_heartbeat", + "discriminator": [10, 175, 217, 130, 111, 35, 117, 54], + "accounts": [ + { "name": "oracle", "writable": true }, + { + "name": "oracle_stats", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] + }, + { "kind": "account", "path": "oracle" } + ] + } + }, + { "name": "oracle_signer", "signer": true }, + { + "name": "queue", + "writable": true, + "relations": ["oracle", "gc_node"] + }, + { "name": "gc_node", "writable": true }, + { "name": "program_state", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "native_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "queue_escrow", "writable": true }, + { + "name": "stake_program", + "address": "SBSTk6t52R89MmCdD739Rdd97HdbTQUFHe41vCX7pTt", + "relations": ["program_state"] + }, + { "name": "delegation_pool", "writable": true }, + { "name": "delegation_group", "writable": true } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "OracleHeartbeatParams" } } + } + ] + }, + { + "name": "oracle_init", + "discriminator": [21, 158, 66, 65, 60, 221, 148, 61], + "accounts": [ + { "name": "oracle", "writable": true, "signer": true }, + { + "name": "oracle_stats", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] + }, + { "kind": "account", "path": "oracle" } + ] + } + }, + { "name": "program_state", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + }, + { "name": "stake_program", "relations": ["program_state"] }, + { "name": "stake_pool", "relations": ["program_state"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "OracleInitParams" } } + } + ] + }, + { + "name": "oracle_set_configs", + "discriminator": [129, 111, 223, 4, 191, 188, 70, 180], + "accounts": [ + { "name": "oracle" }, + { "name": "authority", "signer": true, "relations": ["oracle"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "OracleSetConfigsParams" } } + } + ] + }, + { + "name": "oracle_update_delegation", + "discriminator": [46, 198, 113, 223, 160, 189, 118, 90], + "accounts": [ + { "name": "oracle", "writable": true }, + { + "name": "oracle_stats", + "pda": { + "seeds": [ + { + "kind": "const", + "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] + }, + { "kind": "account", "path": "oracle" } + ] + } + }, + { "name": "queue", "relations": ["oracle"] }, + { "name": "authority", "signer": true }, + { "name": "program_state", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { "name": "delegation_pool", "writable": true }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + }, + { "name": "switch_mint" }, + { + "name": "native_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "wsol_vault", "writable": true }, + { "name": "switch_vault", "writable": true }, + { "name": "stake_program", "relations": ["program_state"] }, + { "name": "stake_pool" }, + { "name": "delegation_group" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "OracleUpdateDelegationParams" } } + } + ] + }, + { + "name": "permission_set", + "discriminator": [211, 122, 185, 120, 129, 182, 55, 103], + "accounts": [ + { "name": "authority", "signer": true }, + { "name": "granter" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PermissionSetParams" } } + } + ] + }, + { + "name": "pull_feed_close", + "discriminator": [19, 134, 50, 142, 177, 215, 196, 83], + "accounts": [ + { "name": "pull_feed", "writable": true }, + { "name": "reward_escrow", "writable": true }, + { "name": "lut", "writable": true }, + { "name": "lut_signer" }, + { "name": "payer", "writable": true, "signer": true }, + { "name": "state" }, + { + "name": "authority", + "writable": true, + "signer": true, + "relations": ["pull_feed"] + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedCloseParams" } } + } + ] + }, + { + "name": "pull_feed_init", + "discriminator": [198, 130, 53, 198, 235, 61, 143, 40], + "accounts": [ + { "name": "pull_feed", "writable": true, "signer": true }, + { "name": "queue" }, + { "name": "authority" }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "program_state" }, + { + "name": "reward_escrow", + "writable": true, + "pda": { + "seeds": [ + { "kind": "account", "path": "pull_feed" }, + { + "kind": "const", + "value": [ + 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, + 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, + 245, 133, 126, 255, 0, 169 + ] + }, + { "kind": "account", "path": "wrapped_sol_mint" } + ], + "program": { + "kind": "const", + "value": [ + 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, + 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, + 219, 233, 248, 89 + ] + } + } + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + }, + { + "name": "wrapped_sol_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedInitParams" } } + } + ] + }, + { + "name": "pull_feed_set_configs", + "discriminator": [217, 45, 11, 246, 64, 26, 82, 168], + "accounts": [ + { "name": "pull_feed", "writable": true }, + { "name": "authority", "signer": true, "relations": ["pull_feed"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedSetConfigsParams" } } + } + ] + }, + { + "name": "pull_feed_submit_response", + "discriminator": [150, 22, 215, 166, 143, 93, 48, 137], + "accounts": [ + { "name": "feed", "writable": true }, + { "name": "queue", "relations": ["feed"] }, + { "name": "program_state" }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "reward_vault", "writable": true }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "token_mint", + "address": "So11111111111111111111111111111111111111112" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedSubmitResponseParams" } } + } + ] + }, + { + "name": "pull_feed_submit_response_many", + "discriminator": [47, 156, 45, 25, 200, 71, 37, 215], + "accounts": [ + { "name": "queue" }, + { "name": "program_state" }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "reward_vault", "writable": true }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "token_mint", + "address": "So11111111111111111111111111111111111111112" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedSubmitResponseManyParams" } } + } + ] + }, + { + "name": "queue_add_mr_enclave", + "discriminator": [199, 255, 81, 50, 60, 133, 171, 138], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "authority", "signer": true }, + { "name": "program_authority" }, + { "name": "state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueAddMrEnclaveParams" } } + } + ] + }, + { + "name": "queue_allow_subsidies", + "discriminator": [94, 203, 82, 157, 188, 138, 202, 108], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "authority", "signer": true, "relations": ["state"] }, + { "name": "state", "writable": true } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueAllowSubsidiesParams" } } + } + ] + }, + { + "name": "queue_garbage_collect", + "discriminator": [187, 208, 104, 247, 16, 91, 96, 98], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "oracle", "writable": true }, + { "name": "authority", "signer": true }, + { "name": "state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueGarbageCollectParams" } } + } + ] + }, + { + "name": "queue_init", + "discriminator": [144, 18, 99, 145, 133, 27, 207, 13], + "accounts": [ + { "name": "queue", "writable": true, "signer": true }, + { + "name": "queue_escrow", + "writable": true, + "pda": { + "seeds": [ + { "kind": "account", "path": "queue" }, + { + "kind": "const", + "value": [ + 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, + 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, + 245, 133, 126, 255, 0, 169 + ] + }, + { "kind": "account", "path": "native_mint" } + ], + "program": { + "kind": "const", + "value": [ + 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, + 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, + 219, 233, 248, 89 + ] + } + } + }, + { "name": "authority" }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "native_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "program_state" }, + { "name": "lut_signer", "writable": true }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueInitParams" } } + } + ] + }, + { + "name": "queue_init_delegation_group", + "discriminator": [239, 146, 75, 158, 20, 166, 159, 14], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "program_state" }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + }, + { "name": "delegation_group", "writable": true }, + { "name": "stake_program", "relations": ["program_state"] }, + { "name": "stake_pool" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueInitDelegationGroupParams" } } + } + ] + }, + { + "name": "queue_remove_mr_enclave", + "discriminator": [3, 64, 135, 33, 190, 133, 68, 252], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "authority", "signer": true }, + { "name": "program_authority" }, + { "name": "state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueRemoveMrEnclaveParams" } } + } + ] + }, + { + "name": "queue_set_configs", + "discriminator": [54, 183, 243, 199, 49, 103, 142, 48], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "authority", "signer": true }, + { "name": "state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueSetConfigsParams" } } + } + ] + }, + { + "name": "randomness_commit", + "discriminator": [52, 170, 152, 201, 179, 133, 242, 141], + "accounts": [ + { "name": "randomness", "writable": true }, + { "name": "queue", "relations": ["randomness", "oracle"] }, + { "name": "oracle", "writable": true }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + }, + { "name": "authority", "signer": true, "relations": ["randomness"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "RandomnessCommitParams" } } + } + ] + }, + { + "name": "randomness_init", + "discriminator": [9, 9, 204, 33, 50, 116, 113, 15], + "accounts": [ + { "name": "randomness", "writable": true, "signer": true }, + { + "name": "reward_escrow", + "writable": true, + "pda": { + "seeds": [ + { "kind": "account", "path": "randomness" }, + { + "kind": "const", + "value": [ + 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, + 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, + 245, 133, 126, 255, 0, 169 + ] + }, + { "kind": "account", "path": "wrapped_sol_mint" } + ], + "program": { + "kind": "const", + "value": [ + 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, + 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, + 219, 233, 248, 89 + ] + } + } + }, + { "name": "authority", "signer": true }, + { "name": "queue", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + }, + { + "name": "wrapped_sol_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "program_state" }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "RandomnessInitParams" } } + } + ] + }, + { + "name": "randomness_reveal", + "discriminator": [197, 181, 187, 10, 30, 58, 20, 73], + "accounts": [ + { "name": "randomness", "writable": true }, + { "name": "oracle", "relations": ["randomness"] }, + { "name": "queue", "relations": ["oracle"] }, + { + "name": "stats", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 79, 114, 97, 99, 108, 101, 82, 97, 110, 100, 111, 109, 110, + 101, 115, 115, 83, 116, 97, 116, 115 + ] + }, + { "kind": "account", "path": "oracle" } + ] + } + }, + { "name": "authority", "signer": true, "relations": ["randomness"] }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "reward_escrow", "writable": true }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "wrapped_sol_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "program_state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "RandomnessRevealParams" } } + } + ] + }, + { + "name": "state_init", + "discriminator": [103, 241, 106, 190, 217, 153, 87, 105], + "accounts": [ + { + "name": "state", + "writable": true, + "pda": { + "seeds": [{ "kind": "const", "value": [83, 84, 65, 84, 69] }] + } + }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "StateInitParams" } } + } + ] + }, + { + "name": "state_set_configs", + "discriminator": [40, 98, 76, 37, 206, 9, 47, 144], + "accounts": [ + { "name": "state", "writable": true }, + { "name": "authority", "signer": true, "relations": ["state"] }, + { "name": "queue", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "StateSetConfigsParams" } } + } + ] + } + ], + "accounts": [ + { + "name": "OracleAccountData", + "discriminator": [128, 30, 16, 241, 170, 73, 55, 54] + }, + { + "name": "OracleStatsAccountData", + "discriminator": [180, 157, 178, 234, 240, 27, 152, 179] + }, + { + "name": "PullFeedAccountData", + "discriminator": [196, 27, 108, 196, 10, 215, 219, 40] + }, + { + "name": "QueueAccountData", + "discriminator": [217, 194, 55, 127, 184, 83, 138, 1] + }, + { + "name": "RandomnessAccountData", + "discriminator": [10, 66, 229, 135, 220, 239, 217, 114] + }, + { "name": "State", "discriminator": [216, 146, 107, 94, 104, 75, 182, 177] } + ], + "events": [ + { + "name": "CostWhitelistEvent", + "discriminator": [56, 107, 191, 127, 116, 6, 138, 149] + }, + { + "name": "GarbageCollectionEvent", + "discriminator": [232, 235, 2, 188, 8, 143, 145, 237] + }, + { + "name": "GuardianQuoteVerifyEvent", + "discriminator": [31, 37, 39, 6, 214, 186, 33, 115] + }, + { + "name": "OracleHeartbeatEvent", + "discriminator": [52, 29, 166, 2, 94, 7, 188, 13] + }, + { + "name": "OracleInitEvent", + "discriminator": [89, 193, 219, 200, 1, 83, 167, 24] + }, + { + "name": "OracleQuoteOverrideEvent", + "discriminator": [78, 204, 191, 210, 164, 196, 244, 65] + }, + { + "name": "OracleQuoteRotateEvent", + "discriminator": [26, 189, 196, 192, 225, 127, 26, 228] + }, + { + "name": "OracleQuoteVerifyRequestEvent", + "discriminator": [203, 209, 79, 0, 20, 71, 226, 202] + }, + { + "name": "PermissionSetEvent", + "discriminator": [148, 86, 123, 0, 102, 20, 119, 206] + }, + { + "name": "PullFeedErrorValueEvent", + "discriminator": [225, 80, 192, 95, 14, 12, 83, 192] + }, + { + "name": "PullFeedValueEvents", + "discriminator": [86, 7, 231, 28, 122, 161, 117, 69] + }, + { + "name": "QueueAddMrEnclaveEvent", + "discriminator": [170, 186, 175, 38, 216, 51, 69, 175] + }, + { + "name": "QueueInitEvent", + "discriminator": [44, 137, 99, 227, 107, 8, 30, 105] + }, + { + "name": "QueueRemoveMrEnclaveEvent", + "discriminator": [4, 105, 196, 60, 84, 122, 203, 196] + }, + { + "name": "RandomnessCommitEvent", + "discriminator": [88, 60, 172, 90, 112, 10, 206, 147] + } + ], + "errors": [ + { "code": 6000, "name": "GenericError" }, + { "code": 6001, "name": "InvalidQuote" }, + { "code": 6002, "name": "InsufficientQueue" }, + { "code": 6003, "name": "QueueFull" }, + { "code": 6004, "name": "InvalidEnclaveSigner" }, + { "code": 6005, "name": "InvalidSigner" }, + { "code": 6006, "name": "MrEnclaveAlreadyExists" }, + { "code": 6007, "name": "MrEnclaveAtCapacity" }, + { "code": 6008, "name": "MrEnclaveDoesntExist" }, + { "code": 6009, "name": "PermissionDenied" }, + { "code": 6010, "name": "InvalidQueue" }, + { "code": 6011, "name": "IncorrectMrEnclave" }, + { "code": 6012, "name": "InvalidAuthority" }, + { "code": 6013, "name": "InvalidMrEnclave" }, + { "code": 6014, "name": "InvalidTimestamp" }, + { "code": 6015, "name": "InvalidOracleIdx" }, + { "code": 6016, "name": "InvalidSecpSignature" }, + { "code": 6017, "name": "InvalidGuardianQueue" }, + { "code": 6018, "name": "InvalidIndex" }, + { "code": 6019, "name": "InvalidOracleQueue" }, + { "code": 6020, "name": "InvalidPermission" }, + { "code": 6021, "name": "InvalidePermissionedAccount" }, + { "code": 6022, "name": "InvalidEpochRotate" }, + { "code": 6023, "name": "InvalidEpochFinalize" }, + { "code": 6024, "name": "InvalidEscrow" }, + { "code": 6025, "name": "IllegalOracle" }, + { "code": 6026, "name": "IllegalExecuteAttempt" }, + { "code": 6027, "name": "IllegalFeedValue" }, + { "code": 6028, "name": "InvalidOracleFeedStats" }, + { "code": 6029, "name": "InvalidStateAuthority" }, + { "code": 6030, "name": "NotEnoughSamples" }, + { "code": 6031, "name": "OracleIsVerified" }, + { "code": 6032, "name": "QueueIsEmpty" }, + { "code": 6033, "name": "SecpRecoverFailure" }, + { "code": 6034, "name": "StaleSample" }, + { "code": 6035, "name": "SwitchboardRandomnessTooOld" }, + { "code": 6036, "name": "EpochIdMismatch" }, + { "code": 6037, "name": "GuardianAlreadyVoted" }, + { "code": 6038, "name": "RandomnessNotRequested" }, + { "code": 6039, "name": "InvalidSlotNumber" }, + { "code": 6040, "name": "RandomnessOracleKeyExpired" }, + { "code": 6041, "name": "InvalidAdvisory" }, + { "code": 6042, "name": "InvalidOracleStats" }, + { "code": 6043, "name": "InvalidStakeProgram" }, + { "code": 6044, "name": "InvalidStakePool" }, + { "code": 6045, "name": "InvalidDelegationPool" }, + { "code": 6046, "name": "UnparsableAccount" }, + { "code": 6047, "name": "InvalidInstruction" }, + { "code": 6048, "name": "OracleAlreadyVerified" }, + { "code": 6049, "name": "GuardianNotVerified" }, + { "code": 6050, "name": "InvalidConstraint" }, + { "code": 6051, "name": "InvalidDelegationGroup" }, + { "code": 6052, "name": "OracleKeyNotFound" }, + { "code": 6053, "name": "GuardianReregisterAttempt" } + ], + "types": [ + { + "name": "CompactResult", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "std_dev", + "docs": [ + "The standard deviation of the submissions needed for quorom size" + ], + "type": "f32" + }, + { + "name": "mean", + "docs": ["The mean of the submissions needed for quorom size"], + "type": "f32" + }, + { + "name": "slot", + "docs": ["The slot at which this value was signed."], + "type": "u64" + } + ] + } + }, + { + "name": "CostWhitelistEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "feeds", "type": { "vec": "pubkey" } }, + { "name": "reward", "type": "u32" } + ] + } + }, + { + "name": "CurrentResult", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "value", + "docs": [ + "The median value of the submissions needed for quorom size" + ], + "type": "i128" + }, + { + "name": "std_dev", + "docs": [ + "The standard deviation of the submissions needed for quorom size" + ], + "type": "i128" + }, + { + "name": "mean", + "docs": ["The mean of the submissions needed for quorom size"], + "type": "i128" + }, + { + "name": "range", + "docs": ["The range of the submissions needed for quorom size"], + "type": "i128" + }, + { + "name": "min_value", + "docs": [ + "The minimum value of the submissions needed for quorom size" + ], + "type": "i128" + }, + { + "name": "max_value", + "docs": [ + "The maximum value of the submissions needed for quorom size" + ], + "type": "i128" + }, + { + "name": "num_samples", + "docs": ["The number of samples used to calculate this result"], + "type": "u8" + }, + { "name": "padding1", "type": { "array": ["u8", 7] } }, + { + "name": "slot", + "docs": ["The slot at which this value was signed."], + "type": "u64" + }, + { + "name": "min_slot", + "docs": [ + "The slot at which the first considered submission was made" + ], + "type": "u64" + }, + { + "name": "max_slot", + "docs": [ + "The slot at which the last considered submission was made" + ], + "type": "u64" + } + ] + } + }, + { + "name": "GarbageCollectionEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "oracle", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" } + ] + } + }, + { + "name": "GuardianQuoteVerifyEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "quote", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" } + ] + } + }, + { + "name": "GuardianQuoteVerifyParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "timestamp", "type": "i64" }, + { "name": "mr_enclave", "type": { "array": ["u8", 32] } }, + { "name": "_reserved1", "type": "u32" }, + { "name": "ed25519_key", "type": "pubkey" }, + { "name": "secp256k1_key", "type": { "array": ["u8", 64] } }, + { "name": "slot", "type": "u64" }, + { "name": "signature", "type": { "array": ["u8", 64] } }, + { "name": "recovery_id", "type": "u8" }, + { "name": "advisories", "type": { "vec": "u32" } } + ] + } + }, + { + "name": "GuardianRegisterParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "GuardianUnregisterParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "MegaSlotInfo", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "reserved1", "type": "u64" }, + { "name": "slot_end", "type": "u64" }, + { "name": "perf_goal", "type": "i64" }, + { "name": "current_signature_count", "type": "i64" } + ] + } + }, + { + "name": "MultiSubmission", + "type": { + "kind": "struct", + "fields": [ + { "name": "values", "type": { "vec": "i128" } }, + { "name": "signature", "type": { "array": ["u8", 64] } }, + { "name": "recovery_id", "type": "u8" } + ] + } + }, + { + "name": "OracleAccountData", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "enclave", + "docs": ["Represents the state of the quote verifiers enclave."], + "type": { "defined": { "name": "Quote" } } + }, + { + "name": "authority", + "docs": [ + "The authority of the EnclaveAccount which is permitted to make account changes." + ], + "type": "pubkey" + }, + { + "name": "queue", + "docs": [ + "Queue used for attestation to verify a MRENCLAVE measurement." + ], + "type": "pubkey" + }, + { + "name": "created_at", + "docs": ["The unix timestamp when the quote was created."], + "type": "i64" + }, + { + "name": "last_heartbeat", + "docs": ["The last time the quote heartbeated on-chain."], + "type": "i64" + }, + { "name": "secp_authority", "type": { "array": ["u8", 64] } }, + { + "name": "gateway_uri", + "docs": ["URI location of the verifier's gateway."], + "type": { "array": ["u8", 64] } + }, + { "name": "permissions", "type": "u64" }, + { + "name": "is_on_queue", + "docs": [ + "Whether the quote is located on the AttestationQueues buffer." + ], + "type": "u8" + }, + { "name": "_padding1", "type": { "array": ["u8", 7] } }, + { "name": "lut_slot", "type": "u64" }, + { "name": "last_reward_epoch", "type": "u64" }, + { "name": "_ebuf4", "type": { "array": ["u8", 16] } }, + { "name": "_ebuf3", "type": { "array": ["u8", 32] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 64] } }, + { "name": "_ebuf1", "type": { "array": ["u8", 1024] } } + ] + } + }, + { + "name": "OracleEpochInfo", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "id", "type": "u64" }, + { "name": "reserved1", "type": "u64" }, + { "name": "slot_end", "type": "u64" }, + { "name": "slash_score", "type": "u64" }, + { "name": "reward_score", "type": "u64" }, + { "name": "stake_score", "type": "u64" } + ] + } + }, + { + "name": "OracleHeartbeatEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "oracle", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" } + ] + } + }, + { + "name": "OracleHeartbeatParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "gateway_uri", + "type": { "option": { "array": ["u8", 64] } } + } + ] + } + }, + { + "name": "OracleInitEvent", + "type": { + "kind": "struct", + "fields": [{ "name": "oracle", "type": "pubkey" }] + } + }, + { + "name": "OracleInitParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "recent_slot", "type": "u64" }, + { "name": "authority", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" }, + { + "name": "secp_authority", + "type": { "option": { "array": ["u8", 64] } } + } + ] + } + }, + { + "name": "OracleQuoteOverrideEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "oracle", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" } + ] + } + }, + { + "name": "OracleQuoteRotateEvent", + "type": { + "kind": "struct", + "fields": [{ "name": "oracle", "type": "pubkey" }] + } + }, + { + "name": "OracleQuoteVerifyRequestEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "quote", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" } + ] + } + }, + { + "name": "OracleSetConfigsParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "new_authority", "type": { "option": "pubkey" } }, + { + "name": "new_secp_authority", + "type": { "option": { "array": ["u8", 64] } } + } + ] + } + }, + { + "name": "OracleStatsAccountData", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "owner", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" }, + { + "name": "finalized_epoch", + "docs": [ + "The last epoch that has completed. cleared after registered with the", + "staking program." + ], + "type": { "defined": { "name": "OracleEpochInfo" } } + }, + { + "name": "current_epoch", + "docs": [ + "The current epoch info being used by the oracle. for stake. Will moved", + "to finalized_epoch as soon as the epoch is over." + ], + "type": { "defined": { "name": "OracleEpochInfo" } } + }, + { + "name": "mega_slot_info", + "type": { "defined": { "name": "MegaSlotInfo" } } + }, + { "name": "last_transfer_slot", "type": "u64" }, + { "name": "bump", "type": "u8" }, + { "name": "padding1", "type": { "array": ["u8", 7] } }, + { + "name": "_ebuf", + "docs": ["Reserved."], + "type": { "array": ["u8", 1024] } + } + ] + } + }, + { + "name": "OracleSubmission", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "oracle", + "docs": ["The public key of the oracle that submitted this value."], + "type": "pubkey" + }, + { + "name": "slot", + "docs": ["The slot at which this value was signed."], + "type": "u64" + }, + { "name": "padding1", "type": { "array": ["u8", 8] } }, + { + "name": "value", + "docs": ["The value that was submitted."], + "type": "i128" + } + ] + } + }, + { + "name": "OracleUpdateDelegationParams", + "type": { + "kind": "struct", + "fields": [{ "name": "_reserved1", "type": "u64" }] + } + }, + { + "name": "PermissionSetEvent", + "type": { + "kind": "struct", + "fields": [{ "name": "permission", "type": "pubkey" }] + } + }, + { + "name": "PermissionSetParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "permission", "type": "u8" }, + { "name": "enable", "type": "bool" } + ] + } + }, + { + "name": "PullFeedAccountData", + "docs": ["A representation of the data in a pull feed account."], + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "submissions", + "docs": ["The oracle submissions for this feed."], + "type": { + "array": [{ "defined": { "name": "OracleSubmission" } }, 32] + } + }, + { + "name": "authority", + "docs": [ + "The public key of the authority that can update the feed hash that", + "this account will use for registering updates." + ], + "type": "pubkey" + }, + { + "name": "queue", + "docs": [ + "The public key of the queue which oracles must be bound to in order to", + "submit data to this feed." + ], + "type": "pubkey" + }, + { + "name": "feed_hash", + "docs": [ + "SHA-256 hash of the job schema oracles will execute to produce data", + "for this feed." + ], + "type": { "array": ["u8", 32] } + }, + { + "name": "initialized_at", + "docs": ["The slot at which this account was initialized."], + "type": "i64" + }, + { "name": "permissions", "type": "u64" }, + { "name": "max_variance", "type": "u64" }, + { "name": "min_responses", "type": "u32" }, + { "name": "name", "type": { "array": ["u8", 32] } }, + { "name": "padding1", "type": { "array": ["u8", 2] } }, + { "name": "historical_result_idx", "type": "u8" }, + { "name": "min_sample_size", "type": "u8" }, + { "name": "last_update_timestamp", "type": "i64" }, + { "name": "lut_slot", "type": "u64" }, + { "name": "_reserved1", "type": { "array": ["u8", 32] } }, + { + "name": "result", + "type": { "defined": { "name": "CurrentResult" } } + }, + { "name": "max_staleness", "type": "u32" }, + { "name": "padding2", "type": { "array": ["u8", 12] } }, + { + "name": "historical_results", + "type": { + "array": [{ "defined": { "name": "CompactResult" } }, 32] + } + }, + { "name": "_ebuf4", "type": { "array": ["u8", 8] } }, + { "name": "_ebuf3", "type": { "array": ["u8", 24] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 256] } } + ] + } + }, + { + "name": "PullFeedCloseParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "PullFeedErrorValueEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "feed", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" } + ] + } + }, + { + "name": "PullFeedInitParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "feed_hash", "type": { "array": ["u8", 32] } }, + { "name": "max_variance", "type": "u64" }, + { "name": "min_responses", "type": "u32" }, + { "name": "name", "type": { "array": ["u8", 32] } }, + { "name": "recent_slot", "type": "u64" }, + { "name": "ipfs_hash", "type": { "array": ["u8", 32] } }, + { "name": "min_sample_size", "type": "u8" }, + { "name": "max_staleness", "type": "u32" } + ] + } + }, + { + "name": "PullFeedSetConfigsParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "feed_hash", + "type": { "option": { "array": ["u8", 32] } } + }, + { "name": "authority", "type": { "option": "pubkey" } }, + { "name": "max_variance", "type": { "option": "u64" } }, + { "name": "min_responses", "type": { "option": "u32" } }, + { "name": "name", "type": { "option": { "array": ["u8", 32] } } }, + { + "name": "ipfs_hash", + "type": { "option": { "array": ["u8", 32] } } + }, + { "name": "min_sample_size", "type": { "option": "u8" } }, + { "name": "max_staleness", "type": { "option": "u32" } } + ] + } + }, + { + "name": "PullFeedSubmitResponseManyParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "slot", "type": "u64" }, + { + "name": "submissions", + "type": { "vec": { "defined": { "name": "MultiSubmission" } } } + } + ] + } + }, + { + "name": "PullFeedSubmitResponseParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "slot", "type": "u64" }, + { + "name": "submissions", + "type": { "vec": { "defined": { "name": "Submission" } } } + } + ] + } + }, + { + "name": "PullFeedValueEvents", + "type": { + "kind": "struct", + "fields": [ + { "name": "feeds", "type": { "vec": "pubkey" } }, + { "name": "oracles", "type": { "vec": "pubkey" } }, + { "name": "values", "type": { "vec": { "vec": "i128" } } }, + { "name": "reward", "type": "u32" } + ] + } + }, + { + "name": "QueueAccountData", + "docs": [ + "An Queue represents a round-robin queue of oracle oracles who attest on-chain", + "whether a Switchboard Function was executed within an enclave against an expected set of", + "enclave measurements.", + "", + "For an oracle to join the queue, the oracle must first submit their enclave quote on-chain and", + "wait for an existing oracle to attest their quote. If the oracle's quote matches an expected", + "measurement within the queues mr_enclaves config, it is granted permissions and will start", + "being assigned update requests." + ], + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "authority", + "docs": [ + "The address of the authority which is permitted to add/remove allowed enclave measurements." + ], + "type": "pubkey" + }, + { + "name": "mr_enclaves", + "docs": ["Allowed enclave measurements."], + "type": { "array": [{ "array": ["u8", 32] }, 32] } + }, + { + "name": "oracle_keys", + "docs": [ + "The addresses of the quote oracles who have a valid", + "verification status and have heartbeated on-chain recently." + ], + "type": { "array": ["pubkey", 128] } + }, + { + "name": "max_quote_verification_age", + "docs": [ + "The maximum allowable time until a EnclaveAccount needs to be re-verified on-chain." + ], + "type": "i64" + }, + { + "name": "last_heartbeat", + "docs": [ + "The unix timestamp when the last quote oracle heartbeated on-chain." + ], + "type": "i64" + }, + { "name": "node_timeout", "type": "i64" }, + { + "name": "oracle_min_stake", + "docs": [ + "The minimum number of lamports a quote oracle needs to lock-up in order to heartbeat and verify other quotes." + ], + "type": "u64" + }, + { "name": "allow_authority_override_after", "type": "i64" }, + { + "name": "mr_enclaves_len", + "docs": ["The number of allowed enclave measurements."], + "type": "u32" + }, + { + "name": "oracle_keys_len", + "docs": [ + "The length of valid quote oracles for the given attestation queue." + ], + "type": "u32" + }, + { + "name": "reward", + "docs": [ + "The reward paid to quote oracles for attesting on-chain." + ], + "type": "u32" + }, + { + "name": "curr_idx", + "docs": [ + "Incrementer used to track the current quote oracle permitted to run any available functions." + ], + "type": "u32" + }, + { + "name": "gc_idx", + "docs": [ + "Incrementer used to garbage collect and remove stale quote oracles." + ], + "type": "u32" + }, + { "name": "require_authority_heartbeat_permission", "type": "u8" }, + { "name": "require_authority_verify_permission", "type": "u8" }, + { "name": "require_usage_permissions", "type": "u8" }, + { "name": "signer_bump", "type": "u8" }, + { "name": "mint", "type": "pubkey" }, + { "name": "lut_slot", "type": "u64" }, + { "name": "allow_subsidies", "type": "u8" }, + { + "name": "_ebuf6", + "docs": ["Reserved."], + "type": { "array": ["u8", 23] } + }, + { "name": "_ebuf5", "type": { "array": ["u8", 32] } }, + { "name": "_ebuf4", "type": { "array": ["u8", 64] } }, + { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 256] } }, + { "name": "_ebuf1", "type": { "array": ["u8", 512] } } + ] + } + }, + { + "name": "QueueAddMrEnclaveEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "queue", "type": "pubkey" }, + { "name": "mr_enclave", "type": { "array": ["u8", 32] } } + ] + } + }, + { + "name": "QueueAddMrEnclaveParams", + "type": { + "kind": "struct", + "fields": [{ "name": "mr_enclave", "type": { "array": ["u8", 32] } }] + } + }, + { + "name": "QueueAllowSubsidiesParams", + "type": { + "kind": "struct", + "fields": [{ "name": "allow_subsidies", "type": "u8" }] + } + }, + { + "name": "QueueGarbageCollectParams", + "type": { "kind": "struct", "fields": [{ "name": "idx", "type": "u32" }] } + }, + { + "name": "QueueInitDelegationGroupParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "QueueInitEvent", + "type": { + "kind": "struct", + "fields": [{ "name": "queue", "type": "pubkey" }] + } + }, + { + "name": "QueueInitParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "allow_authority_override_after", "type": "u32" }, + { "name": "require_authority_heartbeat_permission", "type": "bool" }, + { "name": "require_usage_permissions", "type": "bool" }, + { "name": "max_quote_verification_age", "type": "u32" }, + { "name": "reward", "type": "u32" }, + { "name": "node_timeout", "type": "u32" }, + { "name": "recent_slot", "type": "u64" } + ] + } + }, + { + "name": "QueueRemoveMrEnclaveEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "queue", "type": "pubkey" }, + { "name": "mr_enclave", "type": { "array": ["u8", 32] } } + ] + } + }, + { + "name": "QueueRemoveMrEnclaveParams", + "type": { + "kind": "struct", + "fields": [{ "name": "mr_enclave", "type": { "array": ["u8", 32] } }] + } + }, + { + "name": "QueueSetConfigsParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "authority", "type": { "option": "pubkey" } }, + { "name": "reward", "type": { "option": "u32" } }, + { "name": "node_timeout", "type": { "option": "i64" } } + ] + } + }, + { + "name": "Quote", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "enclave_signer", + "docs": ["The address of the signer generated within an enclave."], + "type": "pubkey" + }, + { + "name": "mr_enclave", + "docs": [ + "The quotes MRENCLAVE measurement dictating the contents of the secure enclave." + ], + "type": { "array": ["u8", 32] } + }, + { + "name": "verification_status", + "docs": ["The VerificationStatus of the quote."], + "type": "u8" + }, + { "name": "padding1", "type": { "array": ["u8", 7] } }, + { + "name": "verification_timestamp", + "docs": ["The unix timestamp when the quote was last verified."], + "type": "i64" + }, + { + "name": "valid_until", + "docs": [ + "The unix timestamp when the quotes verification status expires." + ], + "type": "i64" + }, + { + "name": "quote_registry", + "docs": [ + "The off-chain registry where the verifiers quote can be located." + ], + "type": { "array": ["u8", 32] } + }, + { + "name": "registry_key", + "docs": [ + "Key to lookup the buffer data on IPFS or an alternative decentralized storage solution." + ], + "type": { "array": ["u8", 64] } + }, + { + "name": "secp256k1_signer", + "docs": [ + "The secp256k1 public key of the enclave signer. Derived from the enclave_signer." + ], + "type": { "array": ["u8", 64] } + }, + { "name": "last_ed25519_signer", "type": "pubkey" }, + { "name": "last_secp256k1_signer", "type": { "array": ["u8", 64] } }, + { "name": "last_rotate_slot", "type": "u64" }, + { "name": "guardian_approvers", "type": { "array": ["pubkey", 64] } }, + { "name": "guardian_approvers_len", "type": "u8" }, + { "name": "padding2", "type": { "array": ["u8", 7] } }, + { "name": "staging_ed25519_signer", "type": "pubkey" }, + { + "name": "staging_secp256k1_signer", + "type": { "array": ["u8", 64] } + }, + { + "name": "_ebuf4", + "docs": ["Reserved."], + "type": { "array": ["u8", 32] } + }, + { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 256] } }, + { "name": "_ebuf1", "type": { "array": ["u8", 512] } } + ] + } + }, + { + "name": "RandomnessAccountData", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "authority", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" }, + { "name": "seed_slothash", "type": { "array": ["u8", 32] } }, + { "name": "seed_slot", "type": "u64" }, + { "name": "oracle", "type": "pubkey" }, + { "name": "reveal_slot", "type": "u64" }, + { "name": "value", "type": { "array": ["u8", 32] } }, + { "name": "lut_slot", "type": "u64" }, + { "name": "_ebuf3", "type": { "array": ["u8", 24] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 64] } }, + { "name": "_ebuf1", "type": { "array": ["u8", 128] } }, + { + "name": "active_secp256k1_signer", + "type": { "array": ["u8", 64] } + }, + { "name": "active_secp256k1_expiration", "type": "i64" } + ] + } + }, + { + "name": "RandomnessCommitEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "randomness_account", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" }, + { "name": "slot", "type": "u64" }, + { "name": "slothash", "type": { "array": ["u8", 32] } } + ] + } + }, + { + "name": "RandomnessCommitParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "RandomnessInitParams", + "type": { + "kind": "struct", + "fields": [{ "name": "recent_slot", "type": "u64" }] + } + }, + { + "name": "RandomnessRevealParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "signature", "type": { "array": ["u8", 64] } }, + { "name": "recovery_id", "type": "u8" }, + { "name": "value", "type": { "array": ["u8", 32] } } + ] + } + }, + { + "name": "State", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "bump", "type": "u8" }, + { "name": "test_only_disable_mr_enclave_check", "type": "u8" }, + { "name": "enable_staking", "type": "u8" }, + { "name": "padding1", "type": { "array": ["u8", 5] } }, + { "name": "authority", "type": "pubkey" }, + { "name": "guardian_queue", "type": "pubkey" }, + { "name": "reserved1", "type": "u64" }, + { "name": "epoch_length", "type": "u64" }, + { + "name": "current_epoch", + "type": { "defined": { "name": "StateEpochInfo" } } + }, + { + "name": "next_epoch", + "type": { "defined": { "name": "StateEpochInfo" } } + }, + { + "name": "finalized_epoch", + "type": { "defined": { "name": "StateEpochInfo" } } + }, + { "name": "stake_pool", "type": "pubkey" }, + { "name": "stake_program", "type": "pubkey" }, + { "name": "switch_mint", "type": "pubkey" }, + { "name": "sgx_advisories", "type": { "array": ["u16", 32] } }, + { "name": "advisories_len", "type": "u8" }, + { "name": "padding2", "type": "u8" }, + { "name": "flat_reward_cut_percentage", "type": "u8" }, + { "name": "enable_slashing", "type": "u8" }, + { "name": "subsidy_amount", "type": "u32" }, + { "name": "lut_slot", "type": "u64" }, + { "name": "base_reward", "type": "u32" }, + { "name": "_ebuf6", "type": { "array": ["u8", 28] } }, + { "name": "_ebuf5", "type": { "array": ["u8", 32] } }, + { "name": "_ebuf4", "type": { "array": ["u8", 64] } }, + { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 512] } }, + { + "name": "cost_whitelist", + "docs": ["Cost whitelist by authority"], + "type": { "array": ["pubkey", 32] } + } + ] + } + }, + { + "name": "StateEpochInfo", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "id", "type": "u64" }, + { "name": "_reserved1", "type": "u64" }, + { "name": "slot_end", "type": "u64" } + ] + } + }, + { "name": "StateInitParams", "type": { "kind": "struct", "fields": [] } }, + { + "name": "StateSetConfigsParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "new_authority", "type": "pubkey" }, + { "name": "test_only_disable_mr_enclave_check", "type": "u8" }, + { "name": "stake_pool", "type": "pubkey" }, + { "name": "stake_program", "type": "pubkey" }, + { "name": "add_advisory", "type": "u16" }, + { "name": "rm_advisory", "type": "u16" }, + { "name": "epoch_length", "type": "u32" }, + { "name": "reset_epochs", "type": "bool" }, + { "name": "switch_mint", "type": "pubkey" }, + { "name": "enable_staking", "type": "u8" }, + { "name": "subsidy_amount", "type": "u32" }, + { "name": "base_reward", "type": "u32" }, + { "name": "add_cost_wl", "type": "pubkey" }, + { "name": "rm_cost_wl", "type": "pubkey" } + ] + } + }, + { + "name": "Submission", + "type": { + "kind": "struct", + "fields": [ + { "name": "value", "type": "i128" }, + { "name": "signature", "type": { "array": ["u8", 64] } }, + { "name": "recovery_id", "type": "u8" }, + { "name": "offset", "type": "u8" } + ] + } + } + ] +} diff --git a/solauto-sdk/src/index.ts b/solauto-sdk/src/index.ts index 6b6d8600..97be5854 100644 --- a/solauto-sdk/src/index.ts +++ b/solauto-sdk/src/index.ts @@ -1,8 +1,11 @@ -export * from './clients'; -export * from './constants'; -export * from './generated'; -export * from './transactions'; -export * from './types'; -export * from './utils'; -// export * from './marginfi-sdk'; -// export * from './jupiter-sdk'; \ No newline at end of file +export * from "./constants"; +export * from "./generated/accounts"; +export * from "./generated/instructions"; +export * from "./generated/types"; +export * from "./marginfi-sdk/accounts"; +export * from "./marginfi-sdk/instructions"; +export * from "./marginfi-sdk/types"; +export * from "./services"; +export * from "./solautoPosition"; +export * from "./types"; +export * from "./utils"; diff --git a/solauto-sdk/src/marginfi-sdk/errors/marginfi.ts b/solauto-sdk/src/marginfi-sdk/errors/marginfi.ts index 5392606e..a292e474 100644 --- a/solauto-sdk/src/marginfi-sdk/errors/marginfi.ts +++ b/solauto-sdk/src/marginfi-sdk/errors/marginfi.ts @@ -15,18 +15,18 @@ type ProgramErrorConstructor = new ( const codeToErrorMap: Map = new Map(); const nameToErrorMap: Map = new Map(); -/** MathError: Math error */ -export class MathErrorError extends ProgramError { - override readonly name: string = 'MathError'; +/** InternalLogicError: Internal Marginfi logic error */ +export class InternalLogicErrorError extends ProgramError { + override readonly name: string = 'InternalLogicError'; readonly code: number = 0x1770; // 6000 constructor(program: Program, cause?: Error) { - super('Math error', program, cause); + super('Internal Marginfi logic error', program, cause); } } -codeToErrorMap.set(0x1770, MathErrorError); -nameToErrorMap.set('MathError', MathErrorError); +codeToErrorMap.set(0x1770, InternalLogicErrorError); +nameToErrorMap.set('InternalLogicError', InternalLogicErrorError); /** BankNotFound: Invalid bank index */ export class BankNotFoundError extends ProgramError { @@ -83,14 +83,14 @@ export class InvalidTransferError extends ProgramError { codeToErrorMap.set(0x1774, InvalidTransferError); nameToErrorMap.set('InvalidTransfer', InvalidTransferError); -/** MissingPythOrBankAccount: Missing Pyth or Bank account */ +/** MissingPythOrBankAccount: Missing Oracle, Bank, LST mint, or Sol Pool */ export class MissingPythOrBankAccountError extends ProgramError { override readonly name: string = 'MissingPythOrBankAccount'; readonly code: number = 0x1775; // 6005 constructor(program: Program, cause?: Error) { - super('Missing Pyth or Bank account', program, cause); + super('Missing Oracle, Bank, LST mint, or Sol Pool', program, cause); } } codeToErrorMap.set(0x1775, MissingPythOrBankAccountError); @@ -109,69 +109,60 @@ export class MissingPythAccountError extends ProgramError { codeToErrorMap.set(0x1776, MissingPythAccountError); nameToErrorMap.set('MissingPythAccount', MissingPythAccountError); -/** InvalidOracleAccount: Invalid Pyth account */ -export class InvalidOracleAccountError extends ProgramError { - override readonly name: string = 'InvalidOracleAccount'; - - readonly code: number = 0x1777; // 6007 - - constructor(program: Program, cause?: Error) { - super('Invalid Pyth account', program, cause); - } -} -codeToErrorMap.set(0x1777, InvalidOracleAccountError); -nameToErrorMap.set('InvalidOracleAccount', InvalidOracleAccountError); - /** MissingBankAccount: Missing Bank account */ export class MissingBankAccountError extends ProgramError { override readonly name: string = 'MissingBankAccount'; - readonly code: number = 0x1778; // 6008 + readonly code: number = 0x1777; // 6007 constructor(program: Program, cause?: Error) { super('Missing Bank account', program, cause); } } -codeToErrorMap.set(0x1778, MissingBankAccountError); +codeToErrorMap.set(0x1777, MissingBankAccountError); nameToErrorMap.set('MissingBankAccount', MissingBankAccountError); /** InvalidBankAccount: Invalid Bank account */ export class InvalidBankAccountError extends ProgramError { override readonly name: string = 'InvalidBankAccount'; - readonly code: number = 0x1779; // 6009 + readonly code: number = 0x1778; // 6008 constructor(program: Program, cause?: Error) { super('Invalid Bank account', program, cause); } } -codeToErrorMap.set(0x1779, InvalidBankAccountError); +codeToErrorMap.set(0x1778, InvalidBankAccountError); nameToErrorMap.set('InvalidBankAccount', InvalidBankAccountError); -/** BadAccountHealth: Bad account health */ -export class BadAccountHealthError extends ProgramError { - override readonly name: string = 'BadAccountHealth'; +/** RiskEngineInitRejected: RiskEngine rejected due to either bad health or stale oracles */ +export class RiskEngineInitRejectedError extends ProgramError { + override readonly name: string = 'RiskEngineInitRejected'; - readonly code: number = 0x177a; // 6010 + readonly code: number = 0x1779; // 6009 constructor(program: Program, cause?: Error) { - super('Bad account health', program, cause); + super( + 'RiskEngine rejected due to either bad health or stale oracles', + program, + cause + ); } } -codeToErrorMap.set(0x177a, BadAccountHealthError); -nameToErrorMap.set('BadAccountHealth', BadAccountHealthError); +codeToErrorMap.set(0x1779, RiskEngineInitRejectedError); +nameToErrorMap.set('RiskEngineInitRejected', RiskEngineInitRejectedError); /** LendingAccountBalanceSlotsFull: Lending account balance slots are full */ export class LendingAccountBalanceSlotsFullError extends ProgramError { override readonly name: string = 'LendingAccountBalanceSlotsFull'; - readonly code: number = 0x177b; // 6011 + readonly code: number = 0x177a; // 6010 constructor(program: Program, cause?: Error) { super('Lending account balance slots are full', program, cause); } } -codeToErrorMap.set(0x177b, LendingAccountBalanceSlotsFullError); +codeToErrorMap.set(0x177a, LendingAccountBalanceSlotsFullError); nameToErrorMap.set( 'LendingAccountBalanceSlotsFull', LendingAccountBalanceSlotsFullError @@ -181,234 +172,221 @@ nameToErrorMap.set( export class BankAlreadyExistsError extends ProgramError { override readonly name: string = 'BankAlreadyExists'; - readonly code: number = 0x177c; // 6012 + readonly code: number = 0x177b; // 6011 constructor(program: Program, cause?: Error) { super('Bank already exists', program, cause); } } -codeToErrorMap.set(0x177c, BankAlreadyExistsError); +codeToErrorMap.set(0x177b, BankAlreadyExistsError); nameToErrorMap.set('BankAlreadyExists', BankAlreadyExistsError); -/** IllegalLiquidation: Illegal liquidation */ -export class IllegalLiquidationError extends ProgramError { - override readonly name: string = 'IllegalLiquidation'; +/** ZeroLiquidationAmount: Amount to liquidate must be positive */ +export class ZeroLiquidationAmountError extends ProgramError { + override readonly name: string = 'ZeroLiquidationAmount'; - readonly code: number = 0x177d; // 6013 + readonly code: number = 0x177c; // 6012 constructor(program: Program, cause?: Error) { - super('Illegal liquidation', program, cause); + super('Amount to liquidate must be positive', program, cause); } } -codeToErrorMap.set(0x177d, IllegalLiquidationError); -nameToErrorMap.set('IllegalLiquidation', IllegalLiquidationError); +codeToErrorMap.set(0x177c, ZeroLiquidationAmountError); +nameToErrorMap.set('ZeroLiquidationAmount', ZeroLiquidationAmountError); /** AccountNotBankrupt: Account is not bankrupt */ export class AccountNotBankruptError extends ProgramError { override readonly name: string = 'AccountNotBankrupt'; - readonly code: number = 0x177e; // 6014 + readonly code: number = 0x177d; // 6013 constructor(program: Program, cause?: Error) { super('Account is not bankrupt', program, cause); } } -codeToErrorMap.set(0x177e, AccountNotBankruptError); +codeToErrorMap.set(0x177d, AccountNotBankruptError); nameToErrorMap.set('AccountNotBankrupt', AccountNotBankruptError); /** BalanceNotBadDebt: Account balance is not bad debt */ export class BalanceNotBadDebtError extends ProgramError { override readonly name: string = 'BalanceNotBadDebt'; - readonly code: number = 0x177f; // 6015 + readonly code: number = 0x177e; // 6014 constructor(program: Program, cause?: Error) { super('Account balance is not bad debt', program, cause); } } -codeToErrorMap.set(0x177f, BalanceNotBadDebtError); +codeToErrorMap.set(0x177e, BalanceNotBadDebtError); nameToErrorMap.set('BalanceNotBadDebt', BalanceNotBadDebtError); /** InvalidConfig: Invalid group config */ export class InvalidConfigError extends ProgramError { override readonly name: string = 'InvalidConfig'; - readonly code: number = 0x1780; // 6016 + readonly code: number = 0x177f; // 6015 constructor(program: Program, cause?: Error) { super('Invalid group config', program, cause); } } -codeToErrorMap.set(0x1780, InvalidConfigError); +codeToErrorMap.set(0x177f, InvalidConfigError); nameToErrorMap.set('InvalidConfig', InvalidConfigError); -/** StaleOracle: Stale oracle data */ -export class StaleOracleError extends ProgramError { - override readonly name: string = 'StaleOracle'; - - readonly code: number = 0x1781; // 6017 - - constructor(program: Program, cause?: Error) { - super('Stale oracle data', program, cause); - } -} -codeToErrorMap.set(0x1781, StaleOracleError); -nameToErrorMap.set('StaleOracle', StaleOracleError); - /** BankPaused: Bank paused */ export class BankPausedError extends ProgramError { override readonly name: string = 'BankPaused'; - readonly code: number = 0x1782; // 6018 + readonly code: number = 0x1780; // 6016 constructor(program: Program, cause?: Error) { super('Bank paused', program, cause); } } -codeToErrorMap.set(0x1782, BankPausedError); +codeToErrorMap.set(0x1780, BankPausedError); nameToErrorMap.set('BankPaused', BankPausedError); /** BankReduceOnly: Bank is ReduceOnly mode */ export class BankReduceOnlyError extends ProgramError { override readonly name: string = 'BankReduceOnly'; - readonly code: number = 0x1783; // 6019 + readonly code: number = 0x1781; // 6017 constructor(program: Program, cause?: Error) { super('Bank is ReduceOnly mode', program, cause); } } -codeToErrorMap.set(0x1783, BankReduceOnlyError); +codeToErrorMap.set(0x1781, BankReduceOnlyError); nameToErrorMap.set('BankReduceOnly', BankReduceOnlyError); -/** BankAccoutNotFound: Bank is missing */ -export class BankAccoutNotFoundError extends ProgramError { - override readonly name: string = 'BankAccoutNotFound'; +/** BankAccountNotFound: Bank is missing */ +export class BankAccountNotFoundError extends ProgramError { + override readonly name: string = 'BankAccountNotFound'; - readonly code: number = 0x1784; // 6020 + readonly code: number = 0x1782; // 6018 constructor(program: Program, cause?: Error) { super('Bank is missing', program, cause); } } -codeToErrorMap.set(0x1784, BankAccoutNotFoundError); -nameToErrorMap.set('BankAccoutNotFound', BankAccoutNotFoundError); +codeToErrorMap.set(0x1782, BankAccountNotFoundError); +nameToErrorMap.set('BankAccountNotFound', BankAccountNotFoundError); /** OperationDepositOnly: Operation is deposit-only */ export class OperationDepositOnlyError extends ProgramError { override readonly name: string = 'OperationDepositOnly'; - readonly code: number = 0x1785; // 6021 + readonly code: number = 0x1783; // 6019 constructor(program: Program, cause?: Error) { super('Operation is deposit-only', program, cause); } } -codeToErrorMap.set(0x1785, OperationDepositOnlyError); +codeToErrorMap.set(0x1783, OperationDepositOnlyError); nameToErrorMap.set('OperationDepositOnly', OperationDepositOnlyError); /** OperationWithdrawOnly: Operation is withdraw-only */ export class OperationWithdrawOnlyError extends ProgramError { override readonly name: string = 'OperationWithdrawOnly'; - readonly code: number = 0x1786; // 6022 + readonly code: number = 0x1784; // 6020 constructor(program: Program, cause?: Error) { super('Operation is withdraw-only', program, cause); } } -codeToErrorMap.set(0x1786, OperationWithdrawOnlyError); +codeToErrorMap.set(0x1784, OperationWithdrawOnlyError); nameToErrorMap.set('OperationWithdrawOnly', OperationWithdrawOnlyError); /** OperationBorrowOnly: Operation is borrow-only */ export class OperationBorrowOnlyError extends ProgramError { override readonly name: string = 'OperationBorrowOnly'; - readonly code: number = 0x1787; // 6023 + readonly code: number = 0x1785; // 6021 constructor(program: Program, cause?: Error) { super('Operation is borrow-only', program, cause); } } -codeToErrorMap.set(0x1787, OperationBorrowOnlyError); +codeToErrorMap.set(0x1785, OperationBorrowOnlyError); nameToErrorMap.set('OperationBorrowOnly', OperationBorrowOnlyError); /** OperationRepayOnly: Operation is repay-only */ export class OperationRepayOnlyError extends ProgramError { override readonly name: string = 'OperationRepayOnly'; - readonly code: number = 0x1788; // 6024 + readonly code: number = 0x1786; // 6022 constructor(program: Program, cause?: Error) { super('Operation is repay-only', program, cause); } } -codeToErrorMap.set(0x1788, OperationRepayOnlyError); +codeToErrorMap.set(0x1786, OperationRepayOnlyError); nameToErrorMap.set('OperationRepayOnly', OperationRepayOnlyError); /** NoAssetFound: No asset found */ export class NoAssetFoundError extends ProgramError { override readonly name: string = 'NoAssetFound'; - readonly code: number = 0x1789; // 6025 + readonly code: number = 0x1787; // 6023 constructor(program: Program, cause?: Error) { super('No asset found', program, cause); } } -codeToErrorMap.set(0x1789, NoAssetFoundError); +codeToErrorMap.set(0x1787, NoAssetFoundError); nameToErrorMap.set('NoAssetFound', NoAssetFoundError); /** NoLiabilityFound: No liability found */ export class NoLiabilityFoundError extends ProgramError { override readonly name: string = 'NoLiabilityFound'; - readonly code: number = 0x178a; // 6026 + readonly code: number = 0x1788; // 6024 constructor(program: Program, cause?: Error) { super('No liability found', program, cause); } } -codeToErrorMap.set(0x178a, NoLiabilityFoundError); +codeToErrorMap.set(0x1788, NoLiabilityFoundError); nameToErrorMap.set('NoLiabilityFound', NoLiabilityFoundError); /** InvalidOracleSetup: Invalid oracle setup */ export class InvalidOracleSetupError extends ProgramError { override readonly name: string = 'InvalidOracleSetup'; - readonly code: number = 0x178b; // 6027 + readonly code: number = 0x1789; // 6025 constructor(program: Program, cause?: Error) { super('Invalid oracle setup', program, cause); } } -codeToErrorMap.set(0x178b, InvalidOracleSetupError); +codeToErrorMap.set(0x1789, InvalidOracleSetupError); nameToErrorMap.set('InvalidOracleSetup', InvalidOracleSetupError); /** IllegalUtilizationRatio: Invalid bank utilization ratio */ export class IllegalUtilizationRatioError extends ProgramError { override readonly name: string = 'IllegalUtilizationRatio'; - readonly code: number = 0x178c; // 6028 + readonly code: number = 0x178a; // 6026 constructor(program: Program, cause?: Error) { super('Invalid bank utilization ratio', program, cause); } } -codeToErrorMap.set(0x178c, IllegalUtilizationRatioError); +codeToErrorMap.set(0x178a, IllegalUtilizationRatioError); nameToErrorMap.set('IllegalUtilizationRatio', IllegalUtilizationRatioError); /** BankLiabilityCapacityExceeded: Bank borrow cap exceeded */ export class BankLiabilityCapacityExceededError extends ProgramError { override readonly name: string = 'BankLiabilityCapacityExceeded'; - readonly code: number = 0x178d; // 6029 + readonly code: number = 0x178b; // 6027 constructor(program: Program, cause?: Error) { super('Bank borrow cap exceeded', program, cause); } } -codeToErrorMap.set(0x178d, BankLiabilityCapacityExceededError); +codeToErrorMap.set(0x178b, BankLiabilityCapacityExceededError); nameToErrorMap.set( 'BankLiabilityCapacityExceeded', BankLiabilityCapacityExceededError @@ -418,30 +396,30 @@ nameToErrorMap.set( export class InvalidPriceError extends ProgramError { override readonly name: string = 'InvalidPrice'; - readonly code: number = 0x178e; // 6030 + readonly code: number = 0x178c; // 6028 constructor(program: Program, cause?: Error) { super('Invalid Price', program, cause); } } -codeToErrorMap.set(0x178e, InvalidPriceError); +codeToErrorMap.set(0x178c, InvalidPriceError); nameToErrorMap.set('InvalidPrice', InvalidPriceError); -/** IsolatedAccountIllegalState: Account can have only one liablity when account is under isolated risk */ +/** IsolatedAccountIllegalState: Account can have only one liability when account is under isolated risk */ export class IsolatedAccountIllegalStateError extends ProgramError { override readonly name: string = 'IsolatedAccountIllegalState'; - readonly code: number = 0x178f; // 6031 + readonly code: number = 0x178d; // 6029 constructor(program: Program, cause?: Error) { super( - 'Account can have only one liablity when account is under isolated risk', + 'Account can have only one liability when account is under isolated risk', program, cause ); } } -codeToErrorMap.set(0x178f, IsolatedAccountIllegalStateError); +codeToErrorMap.set(0x178d, IsolatedAccountIllegalStateError); nameToErrorMap.set( 'IsolatedAccountIllegalState', IsolatedAccountIllegalStateError @@ -451,39 +429,39 @@ nameToErrorMap.set( export class EmissionsAlreadySetupError extends ProgramError { override readonly name: string = 'EmissionsAlreadySetup'; - readonly code: number = 0x1790; // 6032 + readonly code: number = 0x178e; // 6030 constructor(program: Program, cause?: Error) { super('Emissions already setup', program, cause); } } -codeToErrorMap.set(0x1790, EmissionsAlreadySetupError); +codeToErrorMap.set(0x178e, EmissionsAlreadySetupError); nameToErrorMap.set('EmissionsAlreadySetup', EmissionsAlreadySetupError); /** OracleNotSetup: Oracle is not set */ export class OracleNotSetupError extends ProgramError { override readonly name: string = 'OracleNotSetup'; - readonly code: number = 0x1791; // 6033 + readonly code: number = 0x178f; // 6031 constructor(program: Program, cause?: Error) { super('Oracle is not set', program, cause); } } -codeToErrorMap.set(0x1791, OracleNotSetupError); +codeToErrorMap.set(0x178f, OracleNotSetupError); nameToErrorMap.set('OracleNotSetup', OracleNotSetupError); -/** InvalidSwitchboardDecimalConversion: Invalid swithcboard decimal conversion */ +/** InvalidSwitchboardDecimalConversion: Invalid switchboard decimal conversion */ export class InvalidSwitchboardDecimalConversionError extends ProgramError { override readonly name: string = 'InvalidSwitchboardDecimalConversion'; - readonly code: number = 0x1792; // 6034 + readonly code: number = 0x1790; // 6032 constructor(program: Program, cause?: Error) { - super('Invalid swithcboard decimal conversion', program, cause); + super('Invalid switchboard decimal conversion', program, cause); } } -codeToErrorMap.set(0x1792, InvalidSwitchboardDecimalConversionError); +codeToErrorMap.set(0x1790, InvalidSwitchboardDecimalConversionError); nameToErrorMap.set( 'InvalidSwitchboardDecimalConversion', InvalidSwitchboardDecimalConversionError @@ -493,7 +471,7 @@ nameToErrorMap.set( export class CannotCloseOutstandingEmissionsError extends ProgramError { override readonly name: string = 'CannotCloseOutstandingEmissions'; - readonly code: number = 0x1793; // 6035 + readonly code: number = 0x1791; // 6033 constructor(program: Program, cause?: Error) { super( @@ -503,7 +481,7 @@ export class CannotCloseOutstandingEmissionsError extends ProgramError { ); } } -codeToErrorMap.set(0x1793, CannotCloseOutstandingEmissionsError); +codeToErrorMap.set(0x1791, CannotCloseOutstandingEmissionsError); nameToErrorMap.set( 'CannotCloseOutstandingEmissions', CannotCloseOutstandingEmissionsError @@ -513,33 +491,33 @@ nameToErrorMap.set( export class EmissionsUpdateErrorError extends ProgramError { override readonly name: string = 'EmissionsUpdateError'; - readonly code: number = 0x1794; // 6036 + readonly code: number = 0x1792; // 6034 constructor(program: Program, cause?: Error) { super('Update emissions error', program, cause); } } -codeToErrorMap.set(0x1794, EmissionsUpdateErrorError); +codeToErrorMap.set(0x1792, EmissionsUpdateErrorError); nameToErrorMap.set('EmissionsUpdateError', EmissionsUpdateErrorError); /** AccountDisabled: Account disabled */ export class AccountDisabledError extends ProgramError { override readonly name: string = 'AccountDisabled'; - readonly code: number = 0x1795; // 6037 + readonly code: number = 0x1793; // 6035 constructor(program: Program, cause?: Error) { super('Account disabled', program, cause); } } -codeToErrorMap.set(0x1795, AccountDisabledError); +codeToErrorMap.set(0x1793, AccountDisabledError); nameToErrorMap.set('AccountDisabled', AccountDisabledError); /** AccountTempActiveBalanceLimitExceeded: Account can't temporarily open 3 balances, please close a balance first */ export class AccountTempActiveBalanceLimitExceededError extends ProgramError { override readonly name: string = 'AccountTempActiveBalanceLimitExceeded'; - readonly code: number = 0x1796; // 6038 + readonly code: number = 0x1794; // 6036 constructor(program: Program, cause?: Error) { super( @@ -549,7 +527,7 @@ export class AccountTempActiveBalanceLimitExceededError extends ProgramError { ); } } -codeToErrorMap.set(0x1796, AccountTempActiveBalanceLimitExceededError); +codeToErrorMap.set(0x1794, AccountTempActiveBalanceLimitExceededError); nameToErrorMap.set( 'AccountTempActiveBalanceLimitExceeded', AccountTempActiveBalanceLimitExceededError @@ -559,70 +537,553 @@ nameToErrorMap.set( export class AccountInFlashloanError extends ProgramError { override readonly name: string = 'AccountInFlashloan'; - readonly code: number = 0x1797; // 6039 + readonly code: number = 0x1795; // 6037 constructor(program: Program, cause?: Error) { super('Illegal action during flashloan', program, cause); } } -codeToErrorMap.set(0x1797, AccountInFlashloanError); +codeToErrorMap.set(0x1795, AccountInFlashloanError); nameToErrorMap.set('AccountInFlashloan', AccountInFlashloanError); /** IllegalFlashloan: Illegal flashloan */ export class IllegalFlashloanError extends ProgramError { override readonly name: string = 'IllegalFlashloan'; - readonly code: number = 0x1798; // 6040 + readonly code: number = 0x1796; // 6038 constructor(program: Program, cause?: Error) { super('Illegal flashloan', program, cause); } } -codeToErrorMap.set(0x1798, IllegalFlashloanError); +codeToErrorMap.set(0x1796, IllegalFlashloanError); nameToErrorMap.set('IllegalFlashloan', IllegalFlashloanError); /** IllegalFlag: Illegal flag */ export class IllegalFlagError extends ProgramError { override readonly name: string = 'IllegalFlag'; - readonly code: number = 0x1799; // 6041 + readonly code: number = 0x1797; // 6039 constructor(program: Program, cause?: Error) { super('Illegal flag', program, cause); } } -codeToErrorMap.set(0x1799, IllegalFlagError); +codeToErrorMap.set(0x1797, IllegalFlagError); nameToErrorMap.set('IllegalFlag', IllegalFlagError); /** IllegalBalanceState: Illegal balance state */ export class IllegalBalanceStateError extends ProgramError { override readonly name: string = 'IllegalBalanceState'; - readonly code: number = 0x179a; // 6042 + readonly code: number = 0x1798; // 6040 constructor(program: Program, cause?: Error) { super('Illegal balance state', program, cause); } } -codeToErrorMap.set(0x179a, IllegalBalanceStateError); +codeToErrorMap.set(0x1798, IllegalBalanceStateError); nameToErrorMap.set('IllegalBalanceState', IllegalBalanceStateError); /** IllegalAccountAuthorityTransfer: Illegal account authority transfer */ export class IllegalAccountAuthorityTransferError extends ProgramError { override readonly name: string = 'IllegalAccountAuthorityTransfer'; - readonly code: number = 0x179b; // 6043 + readonly code: number = 0x1799; // 6041 constructor(program: Program, cause?: Error) { super('Illegal account authority transfer', program, cause); } } -codeToErrorMap.set(0x179b, IllegalAccountAuthorityTransferError); +codeToErrorMap.set(0x1799, IllegalAccountAuthorityTransferError); nameToErrorMap.set( 'IllegalAccountAuthorityTransfer', IllegalAccountAuthorityTransferError ); +/** Unauthorized: Unauthorized */ +export class UnauthorizedError extends ProgramError { + override readonly name: string = 'Unauthorized'; + + readonly code: number = 0x179a; // 6042 + + constructor(program: Program, cause?: Error) { + super('Unauthorized', program, cause); + } +} +codeToErrorMap.set(0x179a, UnauthorizedError); +nameToErrorMap.set('Unauthorized', UnauthorizedError); + +/** IllegalAction: Invalid account authority */ +export class IllegalActionError extends ProgramError { + override readonly name: string = 'IllegalAction'; + + readonly code: number = 0x179b; // 6043 + + constructor(program: Program, cause?: Error) { + super('Invalid account authority', program, cause); + } +} +codeToErrorMap.set(0x179b, IllegalActionError); +nameToErrorMap.set('IllegalAction', IllegalActionError); + +/** T22MintRequired: Token22 Banks require mint account as first remaining account */ +export class T22MintRequiredError extends ProgramError { + override readonly name: string = 'T22MintRequired'; + + readonly code: number = 0x179c; // 6044 + + constructor(program: Program, cause?: Error) { + super( + 'Token22 Banks require mint account as first remaining account', + program, + cause + ); + } +} +codeToErrorMap.set(0x179c, T22MintRequiredError); +nameToErrorMap.set('T22MintRequired', T22MintRequiredError); + +/** InvalidFeeAta: Invalid ATA for global fee account */ +export class InvalidFeeAtaError extends ProgramError { + override readonly name: string = 'InvalidFeeAta'; + + readonly code: number = 0x179d; // 6045 + + constructor(program: Program, cause?: Error) { + super('Invalid ATA for global fee account', program, cause); + } +} +codeToErrorMap.set(0x179d, InvalidFeeAtaError); +nameToErrorMap.set('InvalidFeeAta', InvalidFeeAtaError); + +/** AddedStakedPoolManually: Use add pool permissionless instead */ +export class AddedStakedPoolManuallyError extends ProgramError { + override readonly name: string = 'AddedStakedPoolManually'; + + readonly code: number = 0x179e; // 6046 + + constructor(program: Program, cause?: Error) { + super('Use add pool permissionless instead', program, cause); + } +} +codeToErrorMap.set(0x179e, AddedStakedPoolManuallyError); +nameToErrorMap.set('AddedStakedPoolManually', AddedStakedPoolManuallyError); + +/** AssetTagMismatch: Staked SOL accounts can only deposit staked assets and borrow SOL */ +export class AssetTagMismatchError extends ProgramError { + override readonly name: string = 'AssetTagMismatch'; + + readonly code: number = 0x179f; // 6047 + + constructor(program: Program, cause?: Error) { + super( + 'Staked SOL accounts can only deposit staked assets and borrow SOL', + program, + cause + ); + } +} +codeToErrorMap.set(0x179f, AssetTagMismatchError); +nameToErrorMap.set('AssetTagMismatch', AssetTagMismatchError); + +/** StakePoolValidationFailed: Stake pool validation failed: check the stake pool, mint, or sol pool */ +export class StakePoolValidationFailedError extends ProgramError { + override readonly name: string = 'StakePoolValidationFailed'; + + readonly code: number = 0x17a0; // 6048 + + constructor(program: Program, cause?: Error) { + super( + 'Stake pool validation failed: check the stake pool, mint, or sol pool', + program, + cause + ); + } +} +codeToErrorMap.set(0x17a0, StakePoolValidationFailedError); +nameToErrorMap.set('StakePoolValidationFailed', StakePoolValidationFailedError); + +/** SwitchboardStalePrice: Switchboard oracle: stale price */ +export class SwitchboardStalePriceError extends ProgramError { + override readonly name: string = 'SwitchboardStalePrice'; + + readonly code: number = 0x17a1; // 6049 + + constructor(program: Program, cause?: Error) { + super('Switchboard oracle: stale price', program, cause); + } +} +codeToErrorMap.set(0x17a1, SwitchboardStalePriceError); +nameToErrorMap.set('SwitchboardStalePrice', SwitchboardStalePriceError); + +/** PythPushStalePrice: Pyth Push oracle: stale price */ +export class PythPushStalePriceError extends ProgramError { + override readonly name: string = 'PythPushStalePrice'; + + readonly code: number = 0x17a2; // 6050 + + constructor(program: Program, cause?: Error) { + super('Pyth Push oracle: stale price', program, cause); + } +} +codeToErrorMap.set(0x17a2, PythPushStalePriceError); +nameToErrorMap.set('PythPushStalePrice', PythPushStalePriceError); + +/** WrongNumberOfOracleAccounts: Oracle error: wrong number of accounts */ +export class WrongNumberOfOracleAccountsError extends ProgramError { + override readonly name: string = 'WrongNumberOfOracleAccounts'; + + readonly code: number = 0x17a3; // 6051 + + constructor(program: Program, cause?: Error) { + super('Oracle error: wrong number of accounts', program, cause); + } +} +codeToErrorMap.set(0x17a3, WrongNumberOfOracleAccountsError); +nameToErrorMap.set( + 'WrongNumberOfOracleAccounts', + WrongNumberOfOracleAccountsError +); + +/** WrongOracleAccountKeys: Oracle error: wrong account keys */ +export class WrongOracleAccountKeysError extends ProgramError { + override readonly name: string = 'WrongOracleAccountKeys'; + + readonly code: number = 0x17a4; // 6052 + + constructor(program: Program, cause?: Error) { + super('Oracle error: wrong account keys', program, cause); + } +} +codeToErrorMap.set(0x17a4, WrongOracleAccountKeysError); +nameToErrorMap.set('WrongOracleAccountKeys', WrongOracleAccountKeysError); + +/** PythPushWrongAccountOwner: Pyth Push oracle: wrong account owner */ +export class PythPushWrongAccountOwnerError extends ProgramError { + override readonly name: string = 'PythPushWrongAccountOwner'; + + readonly code: number = 0x17a5; // 6053 + + constructor(program: Program, cause?: Error) { + super('Pyth Push oracle: wrong account owner', program, cause); + } +} +codeToErrorMap.set(0x17a5, PythPushWrongAccountOwnerError); +nameToErrorMap.set('PythPushWrongAccountOwner', PythPushWrongAccountOwnerError); + +/** StakedPythPushWrongAccountOwner: Staked Pyth Push oracle: wrong account owner */ +export class StakedPythPushWrongAccountOwnerError extends ProgramError { + override readonly name: string = 'StakedPythPushWrongAccountOwner'; + + readonly code: number = 0x17a6; // 6054 + + constructor(program: Program, cause?: Error) { + super('Staked Pyth Push oracle: wrong account owner', program, cause); + } +} +codeToErrorMap.set(0x17a6, StakedPythPushWrongAccountOwnerError); +nameToErrorMap.set( + 'StakedPythPushWrongAccountOwner', + StakedPythPushWrongAccountOwnerError +); + +/** PythPushMismatchedFeedId: Pyth Push oracle: mismatched feed id */ +export class PythPushMismatchedFeedIdError extends ProgramError { + override readonly name: string = 'PythPushMismatchedFeedId'; + + readonly code: number = 0x17a7; // 6055 + + constructor(program: Program, cause?: Error) { + super('Pyth Push oracle: mismatched feed id', program, cause); + } +} +codeToErrorMap.set(0x17a7, PythPushMismatchedFeedIdError); +nameToErrorMap.set('PythPushMismatchedFeedId', PythPushMismatchedFeedIdError); + +/** PythPushInsufficientVerificationLevel: Pyth Push oracle: insufficient verification level */ +export class PythPushInsufficientVerificationLevelError extends ProgramError { + override readonly name: string = 'PythPushInsufficientVerificationLevel'; + + readonly code: number = 0x17a8; // 6056 + + constructor(program: Program, cause?: Error) { + super('Pyth Push oracle: insufficient verification level', program, cause); + } +} +codeToErrorMap.set(0x17a8, PythPushInsufficientVerificationLevelError); +nameToErrorMap.set( + 'PythPushInsufficientVerificationLevel', + PythPushInsufficientVerificationLevelError +); + +/** PythPushFeedIdMustBe32Bytes: Pyth Push oracle: feed id must be 32 Bytes */ +export class PythPushFeedIdMustBe32BytesError extends ProgramError { + override readonly name: string = 'PythPushFeedIdMustBe32Bytes'; + + readonly code: number = 0x17a9; // 6057 + + constructor(program: Program, cause?: Error) { + super('Pyth Push oracle: feed id must be 32 Bytes', program, cause); + } +} +codeToErrorMap.set(0x17a9, PythPushFeedIdMustBe32BytesError); +nameToErrorMap.set( + 'PythPushFeedIdMustBe32Bytes', + PythPushFeedIdMustBe32BytesError +); + +/** PythPushFeedIdNonHexCharacter: Pyth Push oracle: feed id contains non-hex characters */ +export class PythPushFeedIdNonHexCharacterError extends ProgramError { + override readonly name: string = 'PythPushFeedIdNonHexCharacter'; + + readonly code: number = 0x17aa; // 6058 + + constructor(program: Program, cause?: Error) { + super( + 'Pyth Push oracle: feed id contains non-hex characters', + program, + cause + ); + } +} +codeToErrorMap.set(0x17aa, PythPushFeedIdNonHexCharacterError); +nameToErrorMap.set( + 'PythPushFeedIdNonHexCharacter', + PythPushFeedIdNonHexCharacterError +); + +/** SwitchboardWrongAccountOwner: Switchboard oracle: wrong account owner */ +export class SwitchboardWrongAccountOwnerError extends ProgramError { + override readonly name: string = 'SwitchboardWrongAccountOwner'; + + readonly code: number = 0x17ab; // 6059 + + constructor(program: Program, cause?: Error) { + super('Switchboard oracle: wrong account owner', program, cause); + } +} +codeToErrorMap.set(0x17ab, SwitchboardWrongAccountOwnerError); +nameToErrorMap.set( + 'SwitchboardWrongAccountOwner', + SwitchboardWrongAccountOwnerError +); + +/** PythPushInvalidAccount: Pyth Push oracle: invalid account */ +export class PythPushInvalidAccountError extends ProgramError { + override readonly name: string = 'PythPushInvalidAccount'; + + readonly code: number = 0x17ac; // 6060 + + constructor(program: Program, cause?: Error) { + super('Pyth Push oracle: invalid account', program, cause); + } +} +codeToErrorMap.set(0x17ac, PythPushInvalidAccountError); +nameToErrorMap.set('PythPushInvalidAccount', PythPushInvalidAccountError); + +/** SwitchboardInvalidAccount: Switchboard oracle: invalid account */ +export class SwitchboardInvalidAccountError extends ProgramError { + override readonly name: string = 'SwitchboardInvalidAccount'; + + readonly code: number = 0x17ad; // 6061 + + constructor(program: Program, cause?: Error) { + super('Switchboard oracle: invalid account', program, cause); + } +} +codeToErrorMap.set(0x17ad, SwitchboardInvalidAccountError); +nameToErrorMap.set('SwitchboardInvalidAccount', SwitchboardInvalidAccountError); + +/** MathError: Math error */ +export class MathErrorError extends ProgramError { + override readonly name: string = 'MathError'; + + readonly code: number = 0x17ae; // 6062 + + constructor(program: Program, cause?: Error) { + super('Math error', program, cause); + } +} +codeToErrorMap.set(0x17ae, MathErrorError); +nameToErrorMap.set('MathError', MathErrorError); + +/** InvalidEmissionsDestinationAccount: Invalid emissions destination account */ +export class InvalidEmissionsDestinationAccountError extends ProgramError { + override readonly name: string = 'InvalidEmissionsDestinationAccount'; + + readonly code: number = 0x17af; // 6063 + + constructor(program: Program, cause?: Error) { + super('Invalid emissions destination account', program, cause); + } +} +codeToErrorMap.set(0x17af, InvalidEmissionsDestinationAccountError); +nameToErrorMap.set( + 'InvalidEmissionsDestinationAccount', + InvalidEmissionsDestinationAccountError +); + +/** SameAssetAndLiabilityBanks: Asset and liability bank cannot be the same */ +export class SameAssetAndLiabilityBanksError extends ProgramError { + override readonly name: string = 'SameAssetAndLiabilityBanks'; + + readonly code: number = 0x17b0; // 6064 + + constructor(program: Program, cause?: Error) { + super('Asset and liability bank cannot be the same', program, cause); + } +} +codeToErrorMap.set(0x17b0, SameAssetAndLiabilityBanksError); +nameToErrorMap.set( + 'SameAssetAndLiabilityBanks', + SameAssetAndLiabilityBanksError +); + +/** OverliquidationAttempt: Trying to withdraw more assets than available */ +export class OverliquidationAttemptError extends ProgramError { + override readonly name: string = 'OverliquidationAttempt'; + + readonly code: number = 0x17b1; // 6065 + + constructor(program: Program, cause?: Error) { + super('Trying to withdraw more assets than available', program, cause); + } +} +codeToErrorMap.set(0x17b1, OverliquidationAttemptError); +nameToErrorMap.set('OverliquidationAttempt', OverliquidationAttemptError); + +/** NoLiabilitiesInLiabilityBank: Liability bank has no liabilities */ +export class NoLiabilitiesInLiabilityBankError extends ProgramError { + override readonly name: string = 'NoLiabilitiesInLiabilityBank'; + + readonly code: number = 0x17b2; // 6066 + + constructor(program: Program, cause?: Error) { + super('Liability bank has no liabilities', program, cause); + } +} +codeToErrorMap.set(0x17b2, NoLiabilitiesInLiabilityBankError); +nameToErrorMap.set( + 'NoLiabilitiesInLiabilityBank', + NoLiabilitiesInLiabilityBankError +); + +/** AssetsInLiabilityBank: Liability bank has assets */ +export class AssetsInLiabilityBankError extends ProgramError { + override readonly name: string = 'AssetsInLiabilityBank'; + + readonly code: number = 0x17b3; // 6067 + + constructor(program: Program, cause?: Error) { + super('Liability bank has assets', program, cause); + } +} +codeToErrorMap.set(0x17b3, AssetsInLiabilityBankError); +nameToErrorMap.set('AssetsInLiabilityBank', AssetsInLiabilityBankError); + +/** HealthyAccount: Account is healthy and cannot be liquidated */ +export class HealthyAccountError extends ProgramError { + override readonly name: string = 'HealthyAccount'; + + readonly code: number = 0x17b4; // 6068 + + constructor(program: Program, cause?: Error) { + super('Account is healthy and cannot be liquidated', program, cause); + } +} +codeToErrorMap.set(0x17b4, HealthyAccountError); +nameToErrorMap.set('HealthyAccount', HealthyAccountError); + +/** ExhaustedLiability: Liability payoff too severe, exhausted liability */ +export class ExhaustedLiabilityError extends ProgramError { + override readonly name: string = 'ExhaustedLiability'; + + readonly code: number = 0x17b5; // 6069 + + constructor(program: Program, cause?: Error) { + super('Liability payoff too severe, exhausted liability', program, cause); + } +} +codeToErrorMap.set(0x17b5, ExhaustedLiabilityError); +nameToErrorMap.set('ExhaustedLiability', ExhaustedLiabilityError); + +/** TooSeverePayoff: Liability payoff too severe, liability balance has assets */ +export class TooSeverePayoffError extends ProgramError { + override readonly name: string = 'TooSeverePayoff'; + + readonly code: number = 0x17b6; // 6070 + + constructor(program: Program, cause?: Error) { + super( + 'Liability payoff too severe, liability balance has assets', + program, + cause + ); + } +} +codeToErrorMap.set(0x17b6, TooSeverePayoffError); +nameToErrorMap.set('TooSeverePayoff', TooSeverePayoffError); + +/** TooSevereLiquidation: Liquidation too severe, account above maintenance requirement */ +export class TooSevereLiquidationError extends ProgramError { + override readonly name: string = 'TooSevereLiquidation'; + + readonly code: number = 0x17b7; // 6071 + + constructor(program: Program, cause?: Error) { + super( + 'Liquidation too severe, account above maintenance requirement', + program, + cause + ); + } +} +codeToErrorMap.set(0x17b7, TooSevereLiquidationError); +nameToErrorMap.set('TooSevereLiquidation', TooSevereLiquidationError); + +/** WorseHealthPostLiquidation: Liquidation would worsen account health */ +export class WorseHealthPostLiquidationError extends ProgramError { + override readonly name: string = 'WorseHealthPostLiquidation'; + + readonly code: number = 0x17b8; // 6072 + + constructor(program: Program, cause?: Error) { + super('Liquidation would worsen account health', program, cause); + } +} +codeToErrorMap.set(0x17b8, WorseHealthPostLiquidationError); +nameToErrorMap.set( + 'WorseHealthPostLiquidation', + WorseHealthPostLiquidationError +); + +/** ArenaBankLimit: Arena groups can only support two banks */ +export class ArenaBankLimitError extends ProgramError { + override readonly name: string = 'ArenaBankLimit'; + + readonly code: number = 0x17b9; // 6073 + + constructor(program: Program, cause?: Error) { + super('Arena groups can only support two banks', program, cause); + } +} +codeToErrorMap.set(0x17b9, ArenaBankLimitError); +nameToErrorMap.set('ArenaBankLimit', ArenaBankLimitError); + +/** ArenaSettingCannotChange: Arena groups cannot return to non-arena status */ +export class ArenaSettingCannotChangeError extends ProgramError { + override readonly name: string = 'ArenaSettingCannotChange'; + + readonly code: number = 0x17ba; // 6074 + + constructor(program: Program, cause?: Error) { + super('Arena groups cannot return to non-arena status', program, cause); + } +} +codeToErrorMap.set(0x17ba, ArenaSettingCannotChangeError); +nameToErrorMap.set('ArenaSettingCannotChange', ArenaSettingCannotChangeError); + /** * Attempts to resolve a custom program error from the provided error code. * @category Errors diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountDeposit.ts b/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountDeposit.ts index d9e7dfe0..be96bd2d 100644 --- a/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountDeposit.ts +++ b/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountDeposit.ts @@ -8,6 +8,8 @@ import { Context, + Option, + OptionOrNullable, Pda, PublicKey, Signer, @@ -17,7 +19,9 @@ import { import { Serializer, array, + bool, mapSerializer, + option, struct, u64, u8, @@ -43,10 +47,12 @@ export type LendingAccountDepositInstructionAccounts = { export type LendingAccountDepositInstructionData = { discriminator: Array; amount: bigint; + depositUpToLimit: Option; }; export type LendingAccountDepositInstructionDataArgs = { amount: number | bigint; + depositUpToLimit: OptionOrNullable; }; export function getLendingAccountDepositInstructionDataSerializer(): Serializer< @@ -62,6 +68,7 @@ export function getLendingAccountDepositInstructionDataSerializer(): Serializer< [ ['discriminator', array(u8(), { size: 8 })], ['amount', u64()], + ['depositUpToLimit', option(bool())], ], { description: 'LendingAccountDepositInstructionData' } ), diff --git a/solauto-sdk/src/marginfi-sdk/types/interestRateConfig.ts b/solauto-sdk/src/marginfi-sdk/types/interestRateConfig.ts index 22ad00b4..41b35791 100644 --- a/solauto-sdk/src/marginfi-sdk/types/interestRateConfig.ts +++ b/solauto-sdk/src/marginfi-sdk/types/interestRateConfig.ts @@ -11,6 +11,7 @@ import { array, struct, u128, + u32, } from '@metaplex-foundation/umi/serializers'; import { WrappedI80F48, @@ -26,7 +27,8 @@ export type InterestRateConfig = { insuranceIrFee: WrappedI80F48; protocolFixedFeeApr: WrappedI80F48; protocolIrFee: WrappedI80F48; - padding: Array; + protocolOriginationFee: WrappedI80F48; + padding: Array; }; export type InterestRateConfigArgs = { @@ -37,6 +39,7 @@ export type InterestRateConfigArgs = { insuranceIrFee: WrappedI80F48Args; protocolFixedFeeApr: WrappedI80F48Args; protocolIrFee: WrappedI80F48Args; + protocolOriginationFee: WrappedI80F48Args; padding: Array; }; @@ -53,7 +56,8 @@ export function getInterestRateConfigSerializer(): Serializer< ['insuranceIrFee', getWrappedI80F48Serializer()], ['protocolFixedFeeApr', getWrappedI80F48Serializer()], ['protocolIrFee', getWrappedI80F48Serializer()], - ['padding', array(u128(), { size: 8 })], + ['protocolOriginationFee', getWrappedI80F48Serializer()], + ['padding', array(u32(), { size: 28 })], ], { description: 'InterestRateConfig' } ) as Serializer; diff --git a/solauto-sdk/src/marginfi-sdk/types/oracleSetup.ts b/solauto-sdk/src/marginfi-sdk/types/oracleSetup.ts index d4588edb..2240a90a 100644 --- a/solauto-sdk/src/marginfi-sdk/types/oracleSetup.ts +++ b/solauto-sdk/src/marginfi-sdk/types/oracleSetup.ts @@ -14,6 +14,7 @@ export enum OracleSetup { SwitchboardLegacy, PythPushOracle, SwitchboardPull, + StakedWithPythPush, } export type OracleSetupArgs = OracleSetup; diff --git a/solauto-sdk/src/pyth-sdk/accounts/index.ts b/solauto-sdk/src/pyth-sdk/accounts/index.ts new file mode 100644 index 00000000..6d07a305 --- /dev/null +++ b/solauto-sdk/src/pyth-sdk/accounts/index.ts @@ -0,0 +1,9 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/metaplex-foundation/kinobi + */ + +export * from './priceUpdateV2Account'; diff --git a/solauto-sdk/src/pyth-sdk/accounts/priceUpdateV2Account.ts b/solauto-sdk/src/pyth-sdk/accounts/priceUpdateV2Account.ts new file mode 100644 index 00000000..bd065d65 --- /dev/null +++ b/solauto-sdk/src/pyth-sdk/accounts/priceUpdateV2Account.ts @@ -0,0 +1,179 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/metaplex-foundation/kinobi + */ + +import { + Account, + Context, + Pda, + PublicKey, + RpcAccount, + RpcGetAccountOptions, + RpcGetAccountsOptions, + assertAccountExists, + deserializeAccount, + gpaBuilder, + publicKey as toPublicKey, +} from '@metaplex-foundation/umi'; +import { + Serializer, + array, + mapSerializer, + publicKey as publicKeySerializer, + struct, + u64, + u8, +} from '@metaplex-foundation/umi/serializers'; +import { + PriceMessage, + PriceMessageArgs, + getPriceMessageSerializer, +} from '../types'; + +export type PriceUpdateV2Account = Account; + +export type PriceUpdateV2AccountAccountData = { + discriminator: Array; + writeAuthority: PublicKey; + verificationLevel: number; + priceMessage: PriceMessage; + postedSlot: bigint; +}; + +export type PriceUpdateV2AccountAccountDataArgs = { + writeAuthority: PublicKey; + verificationLevel: number; + priceMessage: PriceMessageArgs; + postedSlot: number | bigint; +}; + +export function getPriceUpdateV2AccountAccountDataSerializer(): Serializer< + PriceUpdateV2AccountAccountDataArgs, + PriceUpdateV2AccountAccountData +> { + return mapSerializer< + PriceUpdateV2AccountAccountDataArgs, + any, + PriceUpdateV2AccountAccountData + >( + struct( + [ + ['discriminator', array(u8(), { size: 8 })], + ['writeAuthority', publicKeySerializer()], + ['verificationLevel', u8()], + ['priceMessage', getPriceMessageSerializer()], + ['postedSlot', u64()], + ], + { description: 'PriceUpdateV2AccountAccountData' } + ), + (value) => ({ + ...value, + discriminator: [93, 77, 250, 192, 211, 157, 97, 248], + }) + ) as Serializer< + PriceUpdateV2AccountAccountDataArgs, + PriceUpdateV2AccountAccountData + >; +} + +export function deserializePriceUpdateV2Account( + rawAccount: RpcAccount +): PriceUpdateV2Account { + return deserializeAccount( + rawAccount, + getPriceUpdateV2AccountAccountDataSerializer() + ); +} + +export async function fetchPriceUpdateV2Account( + context: Pick, + publicKey: PublicKey | Pda, + options?: RpcGetAccountOptions +): Promise { + const maybeAccount = await context.rpc.getAccount( + toPublicKey(publicKey, false), + options + ); + assertAccountExists(maybeAccount, 'PriceUpdateV2Account'); + return deserializePriceUpdateV2Account(maybeAccount); +} + +export async function safeFetchPriceUpdateV2Account( + context: Pick, + publicKey: PublicKey | Pda, + options?: RpcGetAccountOptions +): Promise { + const maybeAccount = await context.rpc.getAccount( + toPublicKey(publicKey, false), + options + ); + return maybeAccount.exists + ? deserializePriceUpdateV2Account(maybeAccount) + : null; +} + +export async function fetchAllPriceUpdateV2Account( + context: Pick, + publicKeys: Array, + options?: RpcGetAccountsOptions +): Promise { + const maybeAccounts = await context.rpc.getAccounts( + publicKeys.map((key) => toPublicKey(key, false)), + options + ); + return maybeAccounts.map((maybeAccount) => { + assertAccountExists(maybeAccount, 'PriceUpdateV2Account'); + return deserializePriceUpdateV2Account(maybeAccount); + }); +} + +export async function safeFetchAllPriceUpdateV2Account( + context: Pick, + publicKeys: Array, + options?: RpcGetAccountsOptions +): Promise { + const maybeAccounts = await context.rpc.getAccounts( + publicKeys.map((key) => toPublicKey(key, false)), + options + ); + return maybeAccounts + .filter((maybeAccount) => maybeAccount.exists) + .map((maybeAccount) => + deserializePriceUpdateV2Account(maybeAccount as RpcAccount) + ); +} + +export function getPriceUpdateV2AccountGpaBuilder( + context: Pick +) { + const programId = context.programs.getPublicKey( + '', + 'pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT' + ); + return gpaBuilder(context, programId) + .registerFields<{ + discriminator: Array; + writeAuthority: PublicKey; + verificationLevel: number; + priceMessage: PriceMessageArgs; + postedSlot: number | bigint; + }>({ + discriminator: [0, array(u8(), { size: 8 })], + writeAuthority: [8, publicKeySerializer()], + verificationLevel: [40, u8()], + priceMessage: [41, getPriceMessageSerializer()], + postedSlot: [125, u64()], + }) + .deserializeUsing((account) => + deserializePriceUpdateV2Account(account) + ) + .whereField('discriminator', [93, 77, 250, 192, 211, 157, 97, 248]); +} + +export function getPriceUpdateV2AccountSize(): number { + return 133; +} diff --git a/solauto-sdk/src/pyth-sdk/index.ts b/solauto-sdk/src/pyth-sdk/index.ts new file mode 100644 index 00000000..ef2456a7 --- /dev/null +++ b/solauto-sdk/src/pyth-sdk/index.ts @@ -0,0 +1,10 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/metaplex-foundation/kinobi + */ + +export * from './accounts'; +export * from './types'; diff --git a/solauto-sdk/src/pyth-sdk/types/index.ts b/solauto-sdk/src/pyth-sdk/types/index.ts new file mode 100644 index 00000000..7ac88f9e --- /dev/null +++ b/solauto-sdk/src/pyth-sdk/types/index.ts @@ -0,0 +1,10 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/metaplex-foundation/kinobi + */ + +export * from './priceMessage'; +export * from './priceUpdateV2'; diff --git a/solauto-sdk/src/pyth-sdk/types/priceMessage.ts b/solauto-sdk/src/pyth-sdk/types/priceMessage.ts new file mode 100644 index 00000000..d887822d --- /dev/null +++ b/solauto-sdk/src/pyth-sdk/types/priceMessage.ts @@ -0,0 +1,58 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/metaplex-foundation/kinobi + */ + +import { PublicKey } from '@metaplex-foundation/umi'; +import { + Serializer, + i32, + i64, + publicKey as publicKeySerializer, + struct, + u64, +} from '@metaplex-foundation/umi/serializers'; + +export type PriceMessage = { + feedId: PublicKey; + price: bigint; + conf: bigint; + exponent: number; + publishTime: bigint; + prevPublishTime: bigint; + emaPrice: bigint; + emaConf: bigint; +}; + +export type PriceMessageArgs = { + feedId: PublicKey; + price: number | bigint; + conf: number | bigint; + exponent: number; + publishTime: number | bigint; + prevPublishTime: number | bigint; + emaPrice: number | bigint; + emaConf: number | bigint; +}; + +export function getPriceMessageSerializer(): Serializer< + PriceMessageArgs, + PriceMessage +> { + return struct( + [ + ['feedId', publicKeySerializer()], + ['price', i64()], + ['conf', u64()], + ['exponent', i32()], + ['publishTime', i64()], + ['prevPublishTime', i64()], + ['emaPrice', i64()], + ['emaConf', u64()], + ], + { description: 'PriceMessage' } + ) as Serializer; +} diff --git a/solauto-sdk/src/pyth-sdk/types/priceUpdateV2.ts b/solauto-sdk/src/pyth-sdk/types/priceUpdateV2.ts new file mode 100644 index 00000000..caa8c835 --- /dev/null +++ b/solauto-sdk/src/pyth-sdk/types/priceUpdateV2.ts @@ -0,0 +1,46 @@ +/** + * This code was AUTOGENERATED using the kinobi library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun kinobi to update it. + * + * @see https://github.com/metaplex-foundation/kinobi + */ + +import { PublicKey } from '@metaplex-foundation/umi'; +import { + Serializer, + publicKey as publicKeySerializer, + struct, + u64, + u8, +} from '@metaplex-foundation/umi/serializers'; +import { PriceMessage, PriceMessageArgs, getPriceMessageSerializer } from '.'; + +export type PriceUpdateV2 = { + writeAuthority: PublicKey; + verificationLevel: number; + priceMessage: PriceMessage; + postedSlot: bigint; +}; + +export type PriceUpdateV2Args = { + writeAuthority: PublicKey; + verificationLevel: number; + priceMessage: PriceMessageArgs; + postedSlot: number | bigint; +}; + +export function getPriceUpdateV2Serializer(): Serializer< + PriceUpdateV2Args, + PriceUpdateV2 +> { + return struct( + [ + ['writeAuthority', publicKeySerializer()], + ['verificationLevel', u8()], + ['priceMessage', getPriceMessageSerializer()], + ['postedSlot', u64()], + ], + { description: 'PriceUpdateV2' } + ) as Serializer; +} diff --git a/solauto-sdk/src/services/flashLoans/flProviderAggregator.ts b/solauto-sdk/src/services/flashLoans/flProviderAggregator.ts new file mode 100644 index 00000000..781850ad --- /dev/null +++ b/solauto-sdk/src/services/flashLoans/flProviderAggregator.ts @@ -0,0 +1,87 @@ +import { PublicKey } from "@solana/web3.js"; +import { Signer, TransactionBuilder, Umi } from "@metaplex-foundation/umi"; +import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; +import { FlProviderBase } from "./flProviderBase"; +import { FlashLoanDetails, ProgramEnv } from "../../types"; +import { TokenType } from "../../generated"; +import { MarginfiFlProvider } from "./marginfiFlProvider"; + +export class FlProviderAggregator extends FlProviderBase { + private marginfiFlProvider!: MarginfiFlProvider; + + constructor( + umi: Umi, + signer: Signer, + authority: PublicKey, + supplyMint: PublicKey, + debtMint: PublicKey, + programEnv?: ProgramEnv + ) { + super(umi, signer, authority, supplyMint, debtMint, programEnv); + this.marginfiFlProvider = new MarginfiFlProvider( + umi, + signer, + authority, + supplyMint, + debtMint, + programEnv + ); + } + + async initialize() { + // TODO: LP + // Once we have more than one, set the right fl provider for each liquidity source + await this.marginfiFlProvider.initialize(); + } + + async flAccountPrereqIxs(): Promise { + return await this.marginfiFlProvider.initializeIMfiAccounts(); + } + + otherSigners(): Signer[] { + // TODO: LP + return [...this.flSigners, ...this.marginfiFlProvider.otherSigners()]; + } + + lutAccountsToAdd(): PublicKey[] { + return toWeb3JsPublicKey(this.signer.publicKey).equals(this.authority) + ? [ + ...super.lutAccountsToAdd(), + ...this.marginfiFlProvider.lutAccountsToAdd(), + ] + : []; + } + + private flProvider(source: TokenType): FlProviderBase { + // TODO: LP + return this.marginfiFlProvider; + } + + liquiditySource(source: TokenType): PublicKey { + return this.flProvider(source).liquiditySource(source); + } + + liquidityAvailable(source: TokenType): bigint { + return this.flProvider(source).liquidityAvailable(source); + } + + flFeeBps(source: TokenType, signerFlashLoan?: boolean): number { + return this.flProvider(source).flFeeBps(source, signerFlashLoan); + } + + flashBorrow( + flashLoan: FlashLoanDetails, + destTokenAccount: PublicKey + ): TransactionBuilder { + return this.flProvider(flashLoan.liquiditySource).flashBorrow( + flashLoan, + destTokenAccount + ); + } + + flashRepay(flashLoan: FlashLoanDetails): TransactionBuilder { + return this.flProvider(flashLoan.liquiditySource).flashRepay( + flashLoan + ); + } +} diff --git a/solauto-sdk/src/services/flashLoans/flProviderBase.ts b/solauto-sdk/src/services/flashLoans/flProviderBase.ts new file mode 100644 index 00000000..df7e6bef --- /dev/null +++ b/solauto-sdk/src/services/flashLoans/flProviderBase.ts @@ -0,0 +1,92 @@ +import { PublicKey } from "@solana/web3.js"; +import { + Signer, + transactionBuilder, + TransactionBuilder, + Umi, +} from "@metaplex-foundation/umi"; +import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; +import { + fromBaseUnit, + getTokenAccount, + safeGetPrice, + splTokenTransferUmiIx, + tokenInfo, +} from "../../utils"; +import { TokenType } from "../../generated"; +import { FlashLoanDetails, ProgramEnv } from "../../types"; + +export abstract class FlProviderBase { + protected flSigners: Signer[] = []; + + constructor( + protected umi: Umi, + protected signer: Signer, + protected authority: PublicKey, + protected supplyMint: PublicKey, + protected debtMint: PublicKey, + protected programEnv: ProgramEnv = "Prod" + ) {} + + abstract initialize(): Promise; + + lutAccountsToAdd(): PublicKey[] { + return []; + } + + otherSigners(): Signer[] { + return this.flSigners; + } + + mint(source: TokenType) { + return source === TokenType.Supply ? this.supplyMint : this.debtMint; + } + + abstract liquidityAvailable(source: TokenType): bigint; + liquidityAvailableUsd(source: TokenType): number { + return ( + fromBaseUnit( + this.liquidityAvailable(source), + tokenInfo(this.mint(source)).decimals + ) * (safeGetPrice(this.mint(source)) ?? 0) + ); + } + + abstract liquiditySource(source: TokenType): PublicKey; + + abstract flFeeBps(source: TokenType, signerFlashLoan?: boolean): number; + abstract flashBorrow( + flashLoan: FlashLoanDetails, + destTokenAccount: PublicKey + ): TransactionBuilder; + abstract flashRepay(flashLoan: FlashLoanDetails): TransactionBuilder; + + protected signerFlashBorrow( + flashLoan: FlashLoanDetails, + destTokenAccount: PublicKey + ): TransactionBuilder { + if ( + !destTokenAccount.equals( + getTokenAccount( + toWeb3JsPublicKey(this.signer.publicKey), + flashLoan.mint + ) + ) + ) { + return transactionBuilder().add( + splTokenTransferUmiIx( + this.signer, + getTokenAccount( + toWeb3JsPublicKey(this.signer.publicKey), + flashLoan.mint + ), + destTokenAccount, + toWeb3JsPublicKey(this.signer.publicKey), + flashLoan.baseUnitAmount + ) + ); + } else { + return transactionBuilder(); + } + } +} diff --git a/solauto-sdk/src/services/flashLoans/index.ts b/solauto-sdk/src/services/flashLoans/index.ts new file mode 100644 index 00000000..8cb35285 --- /dev/null +++ b/solauto-sdk/src/services/flashLoans/index.ts @@ -0,0 +1,3 @@ +export * from "./flProviderAggregator"; +export * from "./flProviderBase"; +export * from "./marginfiFlProvider"; diff --git a/solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts b/solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts new file mode 100644 index 00000000..cf6bb9b0 --- /dev/null +++ b/solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts @@ -0,0 +1,363 @@ +import { PublicKey, SYSVAR_INSTRUCTIONS_PUBKEY } from "@solana/web3.js"; +import { + AccountMeta, + createSignerFromKeypair, + publicKey, + Signer, + transactionBuilder, + TransactionBuilder, +} from "@metaplex-foundation/umi"; +import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; +import { getMarginfiAccounts } from "../../constants"; +import { + Bank, + lendingAccountBorrow, + lendingAccountCloseBalance, + lendingAccountEndFlashloan, + lendingAccountRepay, + lendingAccountStartFlashloan, + MarginfiAccount, + marginfiAccountInitialize, + safeFetchAllBank, +} from "../../marginfi-sdk"; +import { FlProviderBase } from "./flProviderBase"; +import { + bytesToI80F48, + consoleLog, + fetchTokenPrices, + findMarginfiAccounts, + fromBaseUnit, + getBankLiquidityAvailableBaseUnit, + getEmptyMarginfiAccountsByAuthority, + getMarginfiPriceOracle, + getRemainingAccountsForMarginfiHealthCheck, + getTokenAccount, + rpcAccountCreated, + safeGetPrice, + toBps, + tokenInfo, +} from "../../utils"; +import { FlashLoanDetails } from "../../types"; +import { TokenType } from "../../generated"; + +interface IMFIAccount { + signer?: Signer; + accountPk: PublicKey; + accountData?: MarginfiAccount; +} + +export class MarginfiFlProvider extends FlProviderBase { + private existingMarginfiAccounts!: MarginfiAccount[]; + private supplyBankLiquiditySource!: Bank; + private debtBankLiquiditySource!: Bank; + + private supplyImfiAccount!: IMFIAccount; + private debtImfiAccount!: IMFIAccount; + private supplyRemainingAccounts!: AccountMeta[]; + private debtRemainingAccounts!: AccountMeta[]; + + async initialize() { + await this.setAvailableBanks(); + this.existingMarginfiAccounts = await getEmptyMarginfiAccountsByAuthority( + this.umi, + toWeb3JsPublicKey(this.signer.publicKey) + ); + if ( + this.liquidityBank(TokenType.Supply).group.toString() !== + this.liquidityBank(TokenType.Debt).group.toString() + ) { + await this.setIntermediaryAccount([TokenType.Supply]); + await this.setIntermediaryAccount([TokenType.Debt]); + } else { + await this.setIntermediaryAccount([TokenType.Supply, TokenType.Debt]); + } + } + + private async setAvailableBanks() { + const bankAccounts = getMarginfiAccounts(this.programEnv).bankAccounts; + + const availableBanks: string[] = []; + const checkIfUsable = (group: string, mint: string) => { + if (Object.keys(bankAccounts[group]).includes(mint)) { + availableBanks.push(bankAccounts[group][mint].bank); + } + }; + + for (const group of Object.keys(bankAccounts)) { + checkIfUsable(group, this.supplyMint.toString()); + checkIfUsable(group, this.debtMint.toString()); + } + + const banks = await safeFetchAllBank( + this.umi, + availableBanks.map((x) => publicKey(x)) + ); + + if (!safeGetPrice(this.supplyMint) || !safeGetPrice(this.debtMint)) { + await fetchTokenPrices([this.supplyMint, this.debtMint]); + } + + const mapBanksAndBalances = (mint: PublicKey) => + banks + .filter((x) => toWeb3JsPublicKey(x.mint).equals(mint)) + .map((x) => { + return [ + fromBaseUnit( + getBankLiquidityAvailableBaseUnit(x, false), + tokenInfo(mint).decimals + ) * safeGetPrice(mint)!, + x, + ] as const; + }) + .sort((a, b) => b[0] - a[0]); + + const supplyBanks = mapBanksAndBalances(this.supplyMint); + const debtBanks = mapBanksAndBalances(this.debtMint); + + this.supplyBankLiquiditySource = supplyBanks[0][1]; + this.debtBankLiquiditySource = debtBanks[0][1]; + } + + private async setIntermediaryAccount(sources: TokenType[]) { + const compatibleMarginfiAccounts = this.existingMarginfiAccounts.filter( + (x) => x.group.toString() == this.liquidityBank(sources[0]).group + ); + + const signer = + compatibleMarginfiAccounts.length > 0 + ? undefined + : createSignerFromKeypair(this.umi, this.umi.eddsa.generateKeypair()); + const accountPk = + compatibleMarginfiAccounts.length > 0 + ? toWeb3JsPublicKey(compatibleMarginfiAccounts[0].publicKey) + : toWeb3JsPublicKey(signer!.publicKey); + const accountData = + compatibleMarginfiAccounts.length > 0 + ? compatibleMarginfiAccounts[0] + : undefined; + + if (signer) { + this.flSigners.push(signer); + } + + const remainingAccounts = accountData + ? ( + await Promise.all( + accountData.lendingAccount.balances.map((balance) => + getRemainingAccountsForMarginfiHealthCheck(this.umi, balance) + ) + ) + ).flat() + : []; + + for (const s of sources) { + const data: IMFIAccount = { + signer, + accountPk, + accountData, + }; + + const supply = s === TokenType.Supply; + if (supply) { + this.supplyImfiAccount = data; + this.supplyRemainingAccounts = remainingAccounts; + } else { + this.debtImfiAccount = data; + this.debtRemainingAccounts = remainingAccounts; + } + consoleLog( + `${supply ? "Supply" : "Debt"} iMfi account:`, + accountPk.toString() + ); + } + } + + async initializeIMfiAccounts(): Promise { + const supplyImfiAccount = this.iMfiAccount(TokenType.Supply); + const debtImfiAccount = this.iMfiAccount(TokenType.Debt); + + const [supplyImfiRpcAccount, debtImfiRpcAccount] = + await this.umi.rpc.getAccounts([ + publicKey(supplyImfiAccount.accountPk), + publicKey(debtImfiAccount.accountPk), + ]); + + let tx = transactionBuilder(); + + if (!rpcAccountCreated(supplyImfiRpcAccount)) { + tx = tx.add( + marginfiAccountInitialize(this.umi, { + marginfiAccount: supplyImfiAccount.signer!, + marginfiGroup: this.supplyBankLiquiditySource.group, + authority: this.signer, + feePayer: this.signer, + }) + ); + } + + if ( + supplyImfiAccount.accountPk.toString() !== + debtImfiAccount.accountPk.toString() && + !rpcAccountCreated(debtImfiRpcAccount) + ) { + tx = tx.add( + marginfiAccountInitialize(this.umi, { + marginfiAccount: debtImfiAccount.signer!, + marginfiGroup: this.debtBankLiquiditySource.group, + authority: this.signer, + feePayer: this.signer, + }) + ); + } + + return tx; + } + + lutAccountsToAdd(): PublicKey[] { + return [ + ...super.lutAccountsToAdd(), + ...Array.from( + new Set([ + this.iMfiAccount(TokenType.Supply).accountPk.toString(), + this.iMfiAccount(TokenType.Debt).accountPk.toString(), + ]) + ).map((x) => new PublicKey(x)), + ]; + } + + liquiditySource(source: TokenType): PublicKey { + return toWeb3JsPublicKey(this.liquidityBank(source).publicKey); + } + + private liquidityBank(source: TokenType): Bank { + return source === TokenType.Supply + ? this.supplyBankLiquiditySource + : this.debtBankLiquiditySource; + } + + private iMfiAccount(source: TokenType): IMFIAccount { + return source === TokenType.Supply + ? this.supplyImfiAccount + : this.debtImfiAccount; + } + + liquidityAvailable(source: TokenType): bigint { + return getBankLiquidityAvailableBaseUnit(this.liquidityBank(source), false); + } + + flFeeBps(source: TokenType, signerFlashLoan?: boolean): number { + if (signerFlashLoan) { + return 0; + } + + return toBps( + bytesToI80F48( + this.liquidityBank(source).config.interestRateConfig + .protocolOriginationFee.value + ), + "Ceil" + ); + } + + flashBorrow( + flashLoan: FlashLoanDetails, + destTokenAccount: PublicKey + ): TransactionBuilder { + if (flashLoan.signerFlashLoan) { + return this.signerFlashBorrow(flashLoan, destTokenAccount); + } + + const bank = this.liquidityBank(flashLoan.liquiditySource); + const associatedBankAccs = findMarginfiAccounts( + toWeb3JsPublicKey(bank.publicKey) + ); + const iMfiAccount = this.iMfiAccount(flashLoan.liquiditySource)!; + + return transactionBuilder() + .add( + lendingAccountStartFlashloan(this.umi, { + endIndex: 0, // We set this after building the transaction + ixsSysvar: publicKey(SYSVAR_INSTRUCTIONS_PUBKEY), + marginfiAccount: publicKey(iMfiAccount.accountPk), + signer: this.signer, + }) + ) + .add( + lendingAccountBorrow(this.umi, { + amount: flashLoan.baseUnitAmount, + bank: publicKey(bank), + bankLiquidityVault: publicKey(associatedBankAccs.liquidityVault), + bankLiquidityVaultAuthority: publicKey( + associatedBankAccs.vaultAuthority + ), + destinationTokenAccount: publicKey(destTokenAccount), + marginfiAccount: publicKey(iMfiAccount.accountPk), + marginfiGroup: this.liquidityBank(flashLoan.liquiditySource).group, + signer: this.signer, + }) + ); + } + + flashRepay(flashLoan: FlashLoanDetails): TransactionBuilder { + if (flashLoan.signerFlashLoan) { + return transactionBuilder(); + } + + const bank = this.liquidityBank(flashLoan.liquiditySource); + const associatedBankAccs = findMarginfiAccounts( + toWeb3JsPublicKey(bank.publicKey) + ); + const marginfiGroup = toWeb3JsPublicKey( + this.liquidityBank(flashLoan.liquiditySource).group + ); + const iMfiAccount = this.iMfiAccount(flashLoan.liquiditySource)!; + + const remainingAccounts: AccountMeta[] = + flashLoan.liquiditySource === TokenType.Supply + ? this.supplyRemainingAccounts + : this.debtRemainingAccounts; + let iMfiAccountHadPrevFlBalance = remainingAccounts.find( + (x) => x.pubkey.toString() === bank.publicKey.toString() + ); + + return transactionBuilder() + .add( + lendingAccountRepay(this.umi, { + amount: flashLoan.baseUnitAmount, + repayAll: !iMfiAccountHadPrevFlBalance, + bank: bank.publicKey, + bankLiquidityVault: publicKey(associatedBankAccs.liquidityVault), + marginfiAccount: publicKey(iMfiAccount.accountPk), + marginfiGroup: publicKey(marginfiGroup), + signer: this.signer, + signerTokenAccount: publicKey( + getTokenAccount( + toWeb3JsPublicKey(this.signer.publicKey), + flashLoan.mint + ) + ), + }) + ) + .add( + lendingAccountEndFlashloan(this.umi, { + marginfiAccount: publicKey(iMfiAccount.accountPk), + signer: this.signer, + }).addRemainingAccounts(remainingAccounts) + ); + } + + closeBalance( + marginfiAccount: PublicKey, + bank: PublicKey, + marginfiGroup: PublicKey + ) { + return transactionBuilder().add( + lendingAccountCloseBalance(this.umi, { + signer: this.signer, + marginfiAccount: publicKey(marginfiAccount), + bank: publicKey(bank), + marginfiGroup: publicKey(marginfiGroup), + }) + ); + } +} diff --git a/solauto-sdk/src/services/index.ts b/solauto-sdk/src/services/index.ts new file mode 100644 index 00000000..3f508f45 --- /dev/null +++ b/solauto-sdk/src/services/index.ts @@ -0,0 +1,5 @@ +export * from "./flashLoans"; +export * from "./rebalance"; +export * from "./solauto"; +export * from "./swap"; +export * from "./transactions"; diff --git a/solauto-sdk/src/services/rebalance/index.ts b/solauto-sdk/src/services/rebalance/index.ts new file mode 100644 index 00000000..2f84a7b2 --- /dev/null +++ b/solauto-sdk/src/services/rebalance/index.ts @@ -0,0 +1,3 @@ +export * from "./rebalanceTxBuilder"; +export * from "./rebalanceValues"; +export * from "./solautoFees"; diff --git a/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts b/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts new file mode 100644 index 00000000..e8a4b1df --- /dev/null +++ b/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts @@ -0,0 +1,291 @@ +import { QuoteResponse } from "@jup-ag/api"; +import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; +import { FlashLoanRequirements } from "../../types"; +import { SolautoClient } from "../solauto"; +import { JupSwapManager, SwapParams, SwapInput } from "../swap"; +import { applyDebtAdjustmentUsd, RebalanceValues } from "./rebalanceValues"; +import { PriceType, RebalanceDirection, TokenType } from "../../generated"; +import { + bytesToI80F48, + consoleLog, + fromBaseUnit, + fromBps, + getLiqUtilzationRateBps, + isMarginfiPosition, + safeGetPrice, + toBaseUnit, + tokenInfo, +} from "../../utils"; +import { SolautoFeesBps } from "./solautoFees"; + +export class RebalanceSwapManager { + public swapParams!: SwapParams; + public swapQuote?: QuoteResponse; + public flBorrowAmount?: bigint; + + private jupSwapManager!: JupSwapManager; + private solautoFeeBps!: number; + + constructor( + private client: SolautoClient, + private values: RebalanceValues, + private flRequirements?: FlashLoanRequirements, + private targetLiqUtilizationRateBps?: number, + private priceType?: PriceType + ) { + this.jupSwapManager = new JupSwapManager(client.signer); + this.solautoFeeBps = SolautoFeesBps.create( + this.client.isReferred, + this.targetLiqUtilizationRateBps, + this.client.pos.netWorthUsd(this.priceType) + ).getSolautoFeesBps(values.rebalanceDirection).total; + } + + private isBoost() { + return this.values.rebalanceDirection === RebalanceDirection.Boost; + } + + private usdToSwap() { + return Math.abs(this.values.debtAdjustmentUsd); + } + + private swapDetails() { + const input = this.isBoost() + ? this.client.pos.state.debt + : this.client.pos.state.supply; + const output = this.isBoost() + ? this.client.pos.state.supply + : this.client.pos.state.debt; + + const inputPrice = safeGetPrice( + toWeb3JsPublicKey(input.mint), + this.priceType + )!; + const outputPrice = safeGetPrice( + toWeb3JsPublicKey(output.mint), + this.priceType + )!; + + const supplyPrice = this.client.pos.supplyPrice(this.priceType)!; + const debtPrice = this.client.pos.debtPrice(this.priceType)!; + const biasedInputPrice = this.isBoost() ? debtPrice : supplyPrice; + const biasedOutputPrice = this.isBoost() ? supplyPrice : debtPrice; + + let inputAmount = toBaseUnit( + this.usdToSwap() / biasedInputPrice!, + input.decimals + ); + + return { + inputAmount, + input, + inputPrice, + biasedInputPrice, + output, + outputPrice, + biasedOutputPrice, + }; + } + + private postRebalanceLiqUtilizationRateBps( + swapOutputAmountBaseUnit?: bigint, + swapInputAmountBaseUnit?: bigint + ) { + let supplyUsd = this.client.pos.supplyUsd(this.priceType); + let debtUsd = this.client.pos.debtUsd(this.priceType); + // TODO: add token balance change + + const { + input, + biasedInputPrice, + output, + biasedOutputPrice, + } = this.swapDetails(); + + const swapInputAmount = swapInputAmountBaseUnit + ? fromBaseUnit( + swapInputAmountBaseUnit, + tokenInfo(toWeb3JsPublicKey(input.mint)).decimals + ) + : undefined; + + const swapOutputAmount = swapOutputAmountBaseUnit + ? fromBaseUnit( + swapOutputAmountBaseUnit, + tokenInfo(toWeb3JsPublicKey(output.mint)).decimals + ) + : undefined; + + const swapInputUsd = swapInputAmount + ? swapInputAmount * biasedInputPrice + : this.usdToSwap(); + + const swapOutputUsd = swapOutputAmount + ? swapOutputAmount * biasedOutputPrice + : this.usdToSwap(); + + const res = applyDebtAdjustmentUsd( + { + debtAdjustmentUsd: this.isBoost() ? swapInputUsd : swapInputUsd * -1, + debtAdjustmentUsdOutput: this.isBoost() ? swapOutputUsd : swapOutputUsd * -1, + }, + { supplyUsd, debtUsd }, + fromBps(this.client.pos.state.liqThresholdBps), + { + solauto: this.solautoFeeBps, + flashLoan: this.flRequirements?.flFeeBps ?? 0, + lpBorrow: this.client.pos.state.debt.borrowFeeBps, + } + ); + + // if (isMarginfiPosition(this.client.pos)) { + // console.log(res.newPos.supplyUsd, res.newPos.debtUsd); + // console.log( + // res.newPos.supplyUsd * + // bytesToI80F48( + // this.client.pos.supplyBank!.config.assetWeightInit.value + // ), + // res.newPos.debtUsd * + // bytesToI80F48( + // this.client.pos.debtBank!.config.liabilityWeightInit.value + // ) + // ); + // } + + return getLiqUtilzationRateBps( + res.newPos.supplyUsd, + res.newPos.debtUsd, + this.client.pos.state.liqThresholdBps ?? 0 + ); + } + + private async findSufficientQuote( + swapInput: SwapInput, + criteria: { + minOutputAmount?: bigint; + maxLiqUtilizationRateBps?: number; + } + ): Promise { + let swapQuote: QuoteResponse; + let insufficient: boolean = false; + + for (let i = 0; i < 20; i++) { + consoleLog("Finding sufficient quote..."); + swapQuote = await this.jupSwapManager.getQuote(swapInput); + + const outputAmount = parseInt(swapQuote.outAmount); + const postRebalanceRate = this.postRebalanceLiqUtilizationRateBps( + BigInt(outputAmount), + BigInt(parseInt(swapQuote.inAmount)) + ); + const exceedsMinOutput = criteria.minOutputAmount + ? outputAmount < Number(criteria.minOutputAmount) : false; + const exceedsMaxRate = criteria.maxLiqUtilizationRateBps ? postRebalanceRate > criteria.maxLiqUtilizationRateBps : false; + insufficient = exceedsMinOutput || exceedsMaxRate; + + consoleLog(postRebalanceRate, criteria.maxLiqUtilizationRateBps); + if (insufficient) { + consoleLog("Insufficient swap quote:", swapQuote); + + const increment = 0.01 + i * 0.01; + swapInput.amount = this.bigIntWithIncrement( + swapInput.amount, + this.isBoost() ? increment * -1 : increment + ); + } else { + break; + } + } + + return swapQuote!; + } + + private bigIntWithIncrement(num: bigint, inc: number) { + return num + BigInt(Math.round(Number(num) * inc)); + } + + async setSwapParams(attemptNum: number) { + const rebalanceToZero = this.targetLiqUtilizationRateBps === 0; + let { input, output, biasedOutputPrice, inputAmount } = this.swapDetails(); + + let outputAmount = rebalanceToZero + ? output.amountUsed.baseUnit + + BigInt( + Math.round( + Number(output.amountUsed.baseUnit) * + // Add this small percentage to account for the APR on the debt between now and the transaction + 0.0001 + ) + ) + : toBaseUnit(this.usdToSwap() / biasedOutputPrice, output.decimals); + + const flashLoanRepayFromDebt = + !this.isBoost() && + this.flRequirements && + this.flRequirements.liquiditySource === TokenType.Debt; + + const exactOut = flashLoanRepayFromDebt; + const exactIn = !exactOut; + + if (exactIn && (rebalanceToZero || this.values.repayingCloseToMaxLtv)) { + inputAmount = this.bigIntWithIncrement(inputAmount, 0.005); + } + + const swapAmount = exactOut + ? this.flRequirements + ? this.bigIntWithIncrement( + outputAmount, + this.flRequirements.flFeeBps ?? 0 + ) + : outputAmount + : inputAmount; + + const inputMint = toWeb3JsPublicKey(input.mint); + const outputMint = toWeb3JsPublicKey(output.mint); + const swapInput: SwapInput = { + inputMint, + outputMint, + exactIn, + exactOut, + amount: swapAmount, + }; + consoleLog("Swap input:", swapInput); + + if (exactIn) { + this.swapQuote = await this.findSufficientQuote(swapInput, { + minOutputAmount: rebalanceToZero ? outputAmount : undefined, + maxLiqUtilizationRateBps: !rebalanceToZero + ? this.client.pos.maxBoostToBps + : undefined, + }); + } + + if (this.flRequirements) { + this.flBorrowAmount = exactOut + ? outputAmount + : this.swapQuote + ? BigInt(parseInt(this.swapQuote.inAmount)) + : inputAmount; + } + + this.swapParams = { + ...swapInput, + destinationWallet: exactOut + ? toWeb3JsPublicKey(this.client.signer.publicKey) + : this.client.pos.publicKey, + slippageIncFactor: 0.2 + attemptNum * 0.25, + }; + } + + async getSwapTxData() { + const { jupQuote, lookupTableAddresses, setupIx, swapIx } = + await this.jupSwapManager.getJupSwapTxData(this.swapParams); + + return { + swapQuote: jupQuote, + lookupTableAddresses, + setupIx, + swapIx, + }; + } +} diff --git a/solauto-sdk/src/services/rebalance/rebalanceTxBuilder.ts b/solauto-sdk/src/services/rebalance/rebalanceTxBuilder.ts new file mode 100644 index 00000000..57fd60f4 --- /dev/null +++ b/solauto-sdk/src/services/rebalance/rebalanceTxBuilder.ts @@ -0,0 +1,427 @@ +import { PublicKey } from "@solana/web3.js"; +import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; +import { transactionBuilder } from "@metaplex-foundation/umi"; +import { SolautoClient } from "../solauto"; +import { + FlashLoanRequirements, + RebalanceDetails, + TransactionItemInputs, +} from "../../types"; +import { + bytesToI80F48, + consoleLog, + fromBaseUnit, + fromBps, + getMaxLiqUtilizationRateBps, + getTokenAccount, + hasFirstRebalance, + hasLastRebalance, + isMarginfiPosition, + safeGetPrice, + tokenInfo, +} from "../../utils"; +import { + PositionTokenState, + PriceType, + RebalanceDirection, + RebalanceStep, + SolautoRebalanceType, + SwapType, + TokenBalanceChangeType, + TokenType, +} from "../../generated"; +import { + applyDebtAdjustmentUsd, + getRebalanceValues, + RebalanceValues, +} from "./rebalanceValues"; +import { SolautoFeesBps } from "./solautoFees"; +import { RebalanceSwapManager } from "./rebalanceSwapManager"; + +export class RebalanceTxBuilder { + private values!: RebalanceValues; + private rebalanceType!: SolautoRebalanceType; + private swapManager!: RebalanceSwapManager; + private flRequirements?: FlashLoanRequirements; + private priceType: PriceType = PriceType.Realtime; + + constructor( + private client: SolautoClient, + private targetLiqUtilizationRateBps?: number, + private optimizeSize?: boolean, + private bpsDistanceFromRebalance?: number + ) {} + + private shouldProceedWithRebalance() { + if (this.client.pos.selfManaged && !this.targetLiqUtilizationRateBps) { + throw new Error( + "A target rate must be provided for self managed position rebalances" + ); + } + + return ( + this.client.pos.supplyUsd() > 0 && + (this.targetLiqUtilizationRateBps !== undefined || + this.client.pos.eligibleForRebalance(this.bpsDistanceFromRebalance)) + ); + } + + private getRebalanceValues() { + return getRebalanceValues( + this.client.pos, + this.priceType, + this.targetLiqUtilizationRateBps, + SolautoFeesBps.create( + this.client.isReferred, + this.targetLiqUtilizationRateBps, + this.client.pos.netWorthUsd(this.priceType) + ), + this.flRequirements?.flFeeBps ?? 0, + this.bpsDistanceFromRebalance + ); + } + + private getFlLiquiditySource( + supplyLiquidityAvailable: bigint, + debtLiquidityAvailable: bigint + ): TokenType | undefined { + const debtAdjustmentUsd = Math.abs(this.values.debtAdjustmentUsd); + + const insufficientLiquidity = ( + amountNeededUsd: number, + liquidityAvailable: bigint, + tokenMint: PublicKey + ) => { + const liquidityUsd = + fromBaseUnit(liquidityAvailable, tokenInfo(tokenMint).decimals) * + (safeGetPrice(tokenMint) ?? 0); + return amountNeededUsd > liquidityUsd * 0.95; + }; + + const insufficientSupplyLiquidity = insufficientLiquidity( + debtAdjustmentUsd, + supplyLiquidityAvailable, + this.client.pos.supplyMint + ); + + const insufficientDebtLiquidity = insufficientLiquidity( + debtAdjustmentUsd, + debtLiquidityAvailable, + this.client.pos.debtMint + ); + + let useDebtLiquidity = + this.values.rebalanceDirection === RebalanceDirection.Boost || + insufficientSupplyLiquidity; + + if (useDebtLiquidity) { + return !insufficientDebtLiquidity ? TokenType.Debt : undefined; + } else { + return !insufficientSupplyLiquidity ? TokenType.Supply : undefined; + } + } + + private intermediaryLiqUtilizationRateBps() { + if ( + this.client.pos.maxLtvPriceType !== PriceType.Ema || + this.priceType === PriceType.Ema || + this.values.rebalanceDirection === RebalanceDirection.Repay + ) { + return this.values.intermediaryLiqUtilizationRateBps; + } + + const fees = new SolautoFeesBps( + this.client.isReferred, + this.targetLiqUtilizationRateBps, + this.client.pos.netWorthUsd(PriceType.Realtime) + ); + + const { intermediaryLiqUtilizationRateBps } = applyDebtAdjustmentUsd( + { debtAdjustmentUsd: this.values.debtAdjustmentUsd }, + { + supplyUsd: this.client.pos.supplyUsd(PriceType.Ema), + debtUsd: this.client.pos.debtUsd(PriceType.Ema), + }, + fromBps(this.client.pos.state.liqThresholdBps), + { + solauto: fees.getSolautoFeesBps(this.values.rebalanceDirection).total, + lpBorrow: this.client.pos.state.debt.borrowFeeBps, + flashLoan: this.flRequirements?.flFeeBps ?? 0, + } + ); + + return intermediaryLiqUtilizationRateBps; + } + + private async flashLoanRequirements(): Promise< + FlashLoanRequirements | undefined + > { + const intermediaryLiqUtilizationRateBps = + this.intermediaryLiqUtilizationRateBps(); + const maxLtvRateBps = getMaxLiqUtilizationRateBps( + this.client.pos.state.maxLtvBps, + this.client.pos.state.liqThresholdBps, + 0.015 + ); + if (intermediaryLiqUtilizationRateBps < maxLtvRateBps) { + return undefined; + } + + const stdFlLiquiditySource = this.getFlLiquiditySource( + this.client.flProvider.liquidityAvailable(TokenType.Supply), + this.client.flProvider.liquidityAvailable(TokenType.Debt) + ); + + if (stdFlLiquiditySource === undefined || this.optimizeSize) { + const { supplyBalance, debtBalance } = await this.client.signerBalances(); + const signerFlLiquiditySource = this.getFlLiquiditySource( + supplyBalance, + debtBalance + ); + + if (signerFlLiquiditySource) { + return { + liquiditySource: signerFlLiquiditySource, + signerFlashLoan: true, + }; + } else { + throw new Error(`Insufficient liquidity to perform the transaction`); + } + } else { + return { + liquiditySource: stdFlLiquiditySource, + flFeeBps: this.client.flProvider.flFeeBps(stdFlLiquiditySource), + }; + } + } + + private getFlashLoanDetails() { + if (!this.flRequirements) { + throw new Error("Flash loan requirements data needed"); + } + + const boosting = + this.values.rebalanceDirection === RebalanceDirection.Boost; + const useDebtLiquidity = + this.flRequirements.liquiditySource === TokenType.Debt; + + let flashLoanToken: PositionTokenState | undefined = undefined; + if (boosting || useDebtLiquidity) { + flashLoanToken = this.client.pos.state.debt; + } else { + flashLoanToken = this.client.pos.state.supply; + } + + return { + ...this.flRequirements, + baseUnitAmount: this.swapManager.flBorrowAmount!, + mint: toWeb3JsPublicKey(flashLoanToken.mint), + }; + } + + private setRebalanceType() { + if (this.flRequirements) { + const tokenBalanceChangeType = this.values.tokenBalanceChange?.changeType; + const firstRebalanceTokenChanges = + tokenBalanceChangeType === TokenBalanceChangeType.PreSwapDeposit; + const lastRebalanceTokenChanges = [ + TokenBalanceChangeType.PostSwapDeposit, + TokenBalanceChangeType.PostRebalanceWithdrawDebtToken, + TokenBalanceChangeType.PostRebalanceWithdrawSupplyToken, + ].includes(tokenBalanceChangeType ?? TokenBalanceChangeType.None); + + const swapType = this.swapManager.swapParams.exactIn + ? SwapType.ExactIn + : SwapType.ExactOut; + + if ( + (firstRebalanceTokenChanges && swapType === SwapType.ExactIn) || + (lastRebalanceTokenChanges && swapType === SwapType.ExactOut) + ) { + this.rebalanceType = SolautoRebalanceType.DoubleRebalanceWithFL; + } else { + this.rebalanceType = + swapType === SwapType.ExactOut + ? SolautoRebalanceType.FLRebalanceThenSwap + : SolautoRebalanceType.FLSwapThenRebalance; + } + } else { + this.rebalanceType = SolautoRebalanceType.Regular; + } + } + + private getInitialRebalanceValues() { + let rebalanceValues = this.getRebalanceValues(); + if (!rebalanceValues) { + return undefined; + } + + if ( + !this.client.pos.rebalance.validRealtimePricesBoost( + rebalanceValues.debtAdjustmentUsd + ) + ) { + this.priceType = PriceType.Ema; + rebalanceValues = this.getRebalanceValues(); + if (!rebalanceValues) { + return undefined; + } + } + + return rebalanceValues; + } + + private async setRebalanceDetails(attemptNum: number): Promise { + const rebalanceValues = this.getInitialRebalanceValues(); + if (!rebalanceValues) { + return false; + } + this.values = rebalanceValues; + + this.flRequirements = await this.flashLoanRequirements(); + if (this.flRequirements?.flFeeBps) { + this.values = this.getRebalanceValues()!; + } + + this.swapManager = new RebalanceSwapManager( + this.client, + this.values, + this.flRequirements, + this.targetLiqUtilizationRateBps, + this.priceType + ); + await this.swapManager.setSwapParams(attemptNum); + + this.setRebalanceType(); + return true; + } + + private async refreshBeforeRebalance() { + if ( + this.client.pos.selfManaged || + this.client.contextUpdates.supplyAdjustment > BigInt(0) || + this.client.contextUpdates.debtAdjustment > BigInt(0) || + !this.client.pos.exists + ) { + return false; + } + // Rebalance ix will already refresh internally if position is self managed + + const utilizationRateDiff = Math.abs( + await this.client.pos.utilizationRateBpsDrift(this.priceType) + ); + consoleLog("Liq utilization rate diff:", utilizationRateDiff); + + if (utilizationRateDiff >= 5) { + consoleLog("Refreshing before rebalance"); + return true; + } + + consoleLog("Not refreshing before rebalance"); + return false; + } + + private async assembleTransaction(): Promise { + const { swapQuote, lookupTableAddresses, setupIx, swapIx } = + await this.swapManager.getSwapTxData(); + + const flashLoanDetails = this.flRequirements + ? this.getFlashLoanDetails() + : undefined; + + let tx = transactionBuilder(); + + if (await this.refreshBeforeRebalance()) { + tx = tx.add(this.client.refreshIx(this.priceType)); + } + + const rebalanceDetails: RebalanceDetails = { + values: this.values, + rebalanceType: this.rebalanceType, + flashLoan: flashLoanDetails, + swapQuote, + targetLiqUtilizationRateBps: this.targetLiqUtilizationRateBps, + priceType: this.priceType, + }; + consoleLog("Rebalance details:", rebalanceDetails); + consoleLog( + "Prices:", + safeGetPrice(this.client.pos.supplyMint, this.priceType), + this.client.pos.supplyPrice(this.priceType), + safeGetPrice(this.client.pos.debtMint, this.priceType), + this.client.pos.debtPrice(this.priceType) + ); + + if (isMarginfiPosition(this.client.pos)) { + const supply = + this.values.endResult.supplyUsd * + bytesToI80F48(this.client.pos.supplyBank!.config.assetWeightInit.value); + const debt = + this.values.endResult.debtUsd * + bytesToI80F48( + this.client.pos.debtBank!.config.liabilityWeightInit.value + ); + consoleLog("Weighted values", supply, debt); + } + + const firstRebalance = this.client.rebalanceIx( + RebalanceStep.PreSwap, + rebalanceDetails + ); + const lastRebalance = this.client.rebalanceIx( + RebalanceStep.PostSwap, + rebalanceDetails + ); + + if (!flashLoanDetails) { + tx = tx.add([setupIx, firstRebalance, swapIx, lastRebalance]); + } else { + const exactOut = swapQuote.swapMode === "ExactOut"; + const addFirstRebalance = hasFirstRebalance(this.rebalanceType); + const addLastRebalance = hasLastRebalance(this.rebalanceType); + + const flashBorrowDest = exactOut + ? getTokenAccount( + this.client.pos.publicKey, + new PublicKey(swapQuote.outputMint) + ) + : getTokenAccount( + toWeb3JsPublicKey(this.client.signer.publicKey), + new PublicKey(swapQuote.inputMint) + ); + + consoleLog("Flash borrow dest:", flashBorrowDest.toString()); + tx = tx.add([ + setupIx, + this.client.flProvider.flashBorrow(flashLoanDetails, flashBorrowDest), + ...(addFirstRebalance ? [firstRebalance] : []), + swapIx, + ...(addLastRebalance ? [lastRebalance] : []), + this.client.flProvider.flashRepay(flashLoanDetails), + ]); + } + + return { + tx, + lookupTableAddresses, + }; + } + + public async buildRebalanceTx( + attemptNum: number + ): Promise { + await this.client.pos.refreshPositionState(); + + if (!this.shouldProceedWithRebalance()) { + this.client.log("Not eligible for a rebalance"); + return undefined; + } + + const proceed = await this.setRebalanceDetails(attemptNum); + if (!proceed) { + return undefined; + } + + return await this.assembleTransaction(); + } +} diff --git a/solauto-sdk/src/services/rebalance/rebalanceValues.ts b/solauto-sdk/src/services/rebalance/rebalanceValues.ts new file mode 100644 index 00000000..bd4de076 --- /dev/null +++ b/solauto-sdk/src/services/rebalance/rebalanceValues.ts @@ -0,0 +1,253 @@ +import { + PriceType, + RebalanceDirection, + TokenBalanceChange, + TokenBalanceChangeType, +} from "../../generated"; +import { + fromBps, + getLiqUtilzationRateBps, + toBps, +} from "../../utils"; +import { SolautoPositionEx } from "../../solautoPosition"; +import { SolautoFeesBps } from "./solautoFees"; + +export interface PositionValues { + supplyUsd: number; + debtUsd: number; +} + +export interface DebtAdjustment { + debtAdjustmentUsd: number; + endResult: PositionValues; + intermediaryLiqUtilizationRateBps: number; +} + +export interface RebalanceFeesBps { + solauto: number; + lpBorrow: number; + flashLoan: number; +} + +interface ApplyDebtAdjustmentResult { + newPos: PositionValues; + intermediaryLiqUtilizationRateBps: number; +} + +export function applyDebtAdjustmentUsd( + adjustment: { debtAdjustmentUsd: number; debtAdjustmentUsdOutput?: number }, + pos: PositionValues, + liqThreshold: number, + fees?: RebalanceFeesBps +): ApplyDebtAdjustmentResult { + const newPos = { ...pos }; + const isBoost = adjustment.debtAdjustmentUsd > 0; + + if (!adjustment.debtAdjustmentUsdOutput) { + adjustment.debtAdjustmentUsdOutput = adjustment.debtAdjustmentUsd; + } + const daMinusSolautoFees = + adjustment.debtAdjustmentUsdOutput - + adjustment.debtAdjustmentUsdOutput * fromBps(fees?.solauto ?? 0); + + const daWithFlashLoan = + adjustment.debtAdjustmentUsd * (1.0 + fromBps(fees?.flashLoan ?? 0)); + + let intermediaryLiqUtilizationRateBps = 0; + if (isBoost) { + newPos.debtUsd += + daWithFlashLoan * fromBps(fees?.lpBorrow ?? 0) + daWithFlashLoan; + intermediaryLiqUtilizationRateBps = getLiqUtilzationRateBps( + newPos.supplyUsd, + newPos.debtUsd, + toBps(liqThreshold) + ); + newPos.supplyUsd += daMinusSolautoFees; + } else { + newPos.supplyUsd += daWithFlashLoan; + intermediaryLiqUtilizationRateBps = getLiqUtilzationRateBps( + newPos.supplyUsd, + newPos.debtUsd, + toBps(liqThreshold) + ); + newPos.debtUsd += daMinusSolautoFees; + } + + return { newPos, intermediaryLiqUtilizationRateBps }; +} + +export function getDebtAdjustment( + liqThresholdBps: number, + pos: PositionValues, + targetLiqUtilizationRateBps: number, + fees?: RebalanceFeesBps +): DebtAdjustment { + const isBoost = + getLiqUtilzationRateBps(pos.supplyUsd, pos.debtUsd, liqThresholdBps) < + targetLiqUtilizationRateBps; + const liqThreshold = fromBps(liqThresholdBps); + + const targetUtilizationRate = fromBps(targetLiqUtilizationRateBps); + const actualizedFee = 1.0 - fromBps(fees?.solauto ?? 0); + const flFee = fromBps(fees?.flashLoan ?? 0); + const lpBorrowFee = fromBps(fees?.lpBorrow ?? 0); + + const debtAdjustmentUsd = isBoost + ? (targetUtilizationRate * liqThreshold * pos.supplyUsd - pos.debtUsd) / + (1.0 + + lpBorrowFee + + flFee - + targetUtilizationRate * actualizedFee * liqThreshold) + : (targetUtilizationRate * liqThreshold * pos.supplyUsd - pos.debtUsd) / + (actualizedFee - targetUtilizationRate * liqThreshold * (1.0 + flFee)); + + const endResult = applyDebtAdjustmentUsd( + { debtAdjustmentUsd }, + pos, + liqThreshold, + fees + ); + + return { + debtAdjustmentUsd, + endResult: endResult.newPos, + intermediaryLiqUtilizationRateBps: endResult.intermediaryLiqUtilizationRateBps, + }; +} + +function getTokenBalanceChange(): TokenBalanceChange | undefined { + // TODO: DCA, limit orders, take profit, stop loss, etc. + return undefined; +} + +function getTargetLiqUtilizationRateBps( + solautoPosition: SolautoPositionEx, + priceType: PriceType, + targetLiqUtilizationRateBps?: number, + tokenBalanceChange?: TokenBalanceChange, + bpsDistanceFromRebalance?: number +): number | undefined { + if (targetLiqUtilizationRateBps !== undefined) { + return targetLiqUtilizationRateBps; + } + + if ( + solautoPosition.liqUtilizationRateBps(PriceType.Realtime) + (bpsDistanceFromRebalance ?? 0) >= + solautoPosition.repayFromBps + ) { + return solautoPosition.settings!.repayToBps; + } else if ( + solautoPosition.liqUtilizationRateBps(priceType) - (bpsDistanceFromRebalance ?? 0) <= + solautoPosition.boostFromBps + ) { + return solautoPosition.settings!.boostToBps; + } + // TODO: DCA, limit orders, take profit, stop loss, etc. + // else if (tokenBalanceChange !== null) { + // return currentRate; + // } + + return undefined; +} + +function getAdjustedPositionValues( + solautoPosition: SolautoPositionEx, + priceType: PriceType, + tokenBalanceChange: TokenBalanceChange | undefined +): PositionValues { + let supplyUsd = solautoPosition.supplyUsd(priceType); + const debtUsd = solautoPosition.debtUsd(priceType); + + if (tokenBalanceChange) { + const tb = tokenBalanceChange; + switch (tb.changeType) { + case TokenBalanceChangeType.PreSwapDeposit: + case TokenBalanceChangeType.PostSwapDeposit: + supplyUsd += Number(tb.amountUsd); + break; + case TokenBalanceChangeType.PostRebalanceWithdrawDebtToken: + case TokenBalanceChangeType.PostRebalanceWithdrawSupplyToken: + supplyUsd -= Number(tb.amountUsd); + break; + default: + break; + } + } + + return { + supplyUsd, + debtUsd, + }; +} + +function getRebalanceDirection( + solautoPosition: SolautoPositionEx, + targetLtvBps: number, + priceType: number +): RebalanceDirection { + return solautoPosition.liqUtilizationRateBps(priceType) < targetLtvBps + ? RebalanceDirection.Boost + : RebalanceDirection.Repay; +} + +export interface RebalanceValues extends DebtAdjustment { + rebalanceDirection: RebalanceDirection; + tokenBalanceChange?: TokenBalanceChange; + repayingCloseToMaxLtv: boolean; +} + +export function getRebalanceValues( + solautoPosition: SolautoPositionEx, + priceType: PriceType, + targetLiqUtilizationRateBps?: number, + solautoFeeBps?: SolautoFeesBps, + flFeeBps?: number, + bpsDistanceFromRebalance?: number +): RebalanceValues | undefined { + const tokenBalanceChange = getTokenBalanceChange(); + + const targetRate = getTargetLiqUtilizationRateBps( + solautoPosition, + priceType, + targetLiqUtilizationRateBps, + tokenBalanceChange, + bpsDistanceFromRebalance + ); + if (targetRate === undefined) { + return undefined; + } + + const rebalanceDirection = getRebalanceDirection(solautoPosition, targetRate, priceType); + + const position = getAdjustedPositionValues( + solautoPosition, + priceType, + tokenBalanceChange + ); + + const fees: RebalanceFeesBps = { + solauto: solautoFeeBps + ? solautoFeeBps.getSolautoFeesBps(rebalanceDirection).total + : 0, + lpBorrow: solautoPosition.state.debt.borrowFeeBps, + flashLoan: flFeeBps ?? 0, + }; + + const debtAdjustment = getDebtAdjustment( + solautoPosition.state.liqThresholdBps, + position, + targetRate, + fees + ); + + const repayingCloseToMaxLtv = + rebalanceDirection === RebalanceDirection.Repay && + targetRate >= solautoPosition.maxRepayToBps; + + return { + ...debtAdjustment, + rebalanceDirection, + tokenBalanceChange, + repayingCloseToMaxLtv, + }; +} diff --git a/solauto-sdk/src/services/rebalance/solautoFees.ts b/solauto-sdk/src/services/rebalance/solautoFees.ts new file mode 100644 index 00000000..9f58893c --- /dev/null +++ b/solauto-sdk/src/services/rebalance/solautoFees.ts @@ -0,0 +1,69 @@ +import { REFERRER_PERCENTAGE } from "../../constants"; +import { RebalanceDirection } from "../../generated"; + +export class SolautoFeesBps { + constructor( + private isReferred: boolean, + private targetLiqUtilizationRateBps: number | undefined, + private positionNetWorthUsd: number + ) {} + + static create( + isReferred: boolean, + targetLiqUtilizationRateBps: number | undefined, + netWorthUsd: number + ) { + return new SolautoFeesBps( + isReferred, + targetLiqUtilizationRateBps, + netWorthUsd + ); + } + + getSolautoFeesBps(rebalanceDirection: RebalanceDirection) { + const minSize = 10_000; // Minimum position size + const maxSize = 250_000; // Maximum position size + const maxFeeBps = 50; // Fee in basis points for minSize (0.5%) + const minFeeBps = 25; // Fee in basis points for maxSize (0.25%) + const k = 1.5; + + if (this.targetLiqUtilizationRateBps === 0) { + return { + solauto: 0, + referrer: 0, + total: 0, + }; + } + + let feeBps: number = 0; + + if (this.targetLiqUtilizationRateBps !== undefined) { + feeBps = 15; + } else if (rebalanceDirection === RebalanceDirection.Repay) { + feeBps = 25; + } else if (this.positionNetWorthUsd <= minSize) { + feeBps = maxFeeBps; + } else if (this.positionNetWorthUsd >= maxSize) { + feeBps = minFeeBps; + } else { + const t = + (Math.log(this.positionNetWorthUsd) - Math.log(minSize)) / + (Math.log(maxSize) - Math.log(minSize)); + feeBps = Math.round( + minFeeBps + (maxFeeBps - minFeeBps) * (1 - Math.pow(t, k)) + ); + } + + let referrer = 0; + if (this.isReferred) { + feeBps *= 1.0 - REFERRER_PERCENTAGE; + referrer = Math.floor(feeBps * REFERRER_PERCENTAGE); + } + + return { + solauto: feeBps - referrer, + referrer, + total: feeBps, + }; + } +} diff --git a/solauto-sdk/src/services/solauto/index.ts b/solauto-sdk/src/services/solauto/index.ts new file mode 100644 index 00000000..9dccd0aa --- /dev/null +++ b/solauto-sdk/src/services/solauto/index.ts @@ -0,0 +1,4 @@ +export * from "./referralStateManager"; +export * from "./solautoClient"; +export * from "./solautoMarginfiClient"; +export * from "./txHandler"; diff --git a/solauto-sdk/src/clients/referralStateManager.ts b/solauto-sdk/src/services/solauto/referralStateManager.ts similarity index 81% rename from solauto-sdk/src/clients/referralStateManager.ts rename to solauto-sdk/src/services/solauto/referralStateManager.ts index 57bf6fd6..65ba92ab 100644 --- a/solauto-sdk/src/clients/referralStateManager.ts +++ b/solauto-sdk/src/services/solauto/referralStateManager.ts @@ -1,30 +1,18 @@ import { PublicKey } from "@solana/web3.js"; import { NATIVE_MINT } from "@solana/spl-token"; -import { - publicKey, - Signer, - signerIdentity, - TransactionBuilder, - Umi, -} from "@metaplex-foundation/umi"; +import { publicKey, TransactionBuilder, Umi } from "@metaplex-foundation/umi"; import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; -import { - WalletAdapter, - walletAdapterIdentity, -} from "@metaplex-foundation/umi-signer-wallet-adapters"; import { claimReferralFees, ReferralState, safeFetchReferralState, updateReferralStates, -} from "../generated"; -import { getReferralState, getTokenAccount } from "../utils"; +} from "../../generated"; +import { getReferralState, getTokenAccount } from "../../utils"; import { TxHandler } from "./txHandler"; -import { SOLAUTO_LUT } from "../constants"; +import { SOLAUTO_LUT } from "../../constants"; export interface ReferralStateManagerArgs { - signer?: Signer; - wallet?: WalletAdapter; authority?: PublicKey; referralState?: PublicKey; referredByAuthority?: PublicKey; @@ -41,24 +29,17 @@ export class ReferralStateManager extends TxHandler { public referredByState?: PublicKey; async initialize(args: ReferralStateManagerArgs) { - if (!args.signer && !args.wallet) { - throw new Error("Signer or wallet must be provided"); - } - this.umi = this.umi.use( - args.signer - ? signerIdentity(args.signer, true) - : walletAdapterIdentity(args.wallet!, true) - ); - this.signer = this.umi.identity; - this.authority = args.authority ?? toWeb3JsPublicKey(this.signer.publicKey); - - this.referralState = args.referralState ?? getReferralState(this.authority, this.programId); - - this.referralStateData = await safeFetchReferralState( - this.umi, - publicKey(this.referralState), - { commitment: "confirmed" } - ); + this.referralState = + args.referralState ?? + getReferralState( + args.authority ?? toWeb3JsPublicKey(this.signer.publicKey), + this.programId + ); + + await this.refetchReferralState(); + this.authority = this.referralStateData?.authority + ? toWeb3JsPublicKey(this.referralStateData.authority) + : (args.authority ?? toWeb3JsPublicKey(this.signer.publicKey)); this.setReferredBy(args.referredByAuthority); @@ -76,6 +57,14 @@ export class ReferralStateManager extends TxHandler { : [SOLAUTO_LUT]; } + async refetchReferralState() { + this.referralStateData = await safeFetchReferralState( + this.umi, + publicKey(this.referralState), + { commitment: "confirmed" } + ); + } + setReferredBy(referredBy?: PublicKey) { const hasReferredBy = this.referralStateData && @@ -98,6 +87,10 @@ export class ReferralStateManager extends TxHandler { : undefined; } + get isReferred(): boolean { + return Boolean(this.referredByState); + } + updateReferralStatesIx( destFeesMint?: PublicKey, lookupTable?: PublicKey diff --git a/solauto-sdk/src/clients/solautoClient.ts b/solauto-sdk/src/services/solauto/solautoClient.ts similarity index 52% rename from solauto-sdk/src/clients/solautoClient.ts rename to solauto-sdk/src/services/solauto/solautoClient.ts index 62b7d3f1..074ec385 100644 --- a/solauto-sdk/src/clients/solautoClient.ts +++ b/solauto-sdk/src/services/solauto/solautoClient.ts @@ -1,7 +1,6 @@ import "rpc-websockets/dist/lib/client"; import { AddressLookupTableProgram, PublicKey } from "@solana/web3.js"; import { - Signer, TransactionBuilder, isOption, publicKey, @@ -11,73 +10,76 @@ import { } from "@metaplex-foundation/umi"; import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; import { - DCASettings, DCASettingsInpArgs, LendingPlatform, - PositionState, + PositionType, + PriceType, + RebalanceStep, SolautoActionArgs, - SolautoPosition, - SolautoRebalanceTypeArgs, - SolautoSettingsParameters, SolautoSettingsParametersInpArgs, TokenType, UpdatePositionDataArgs, cancelDCA, - closePosition, - safeFetchSolautoPosition, updatePosition, -} from "../generated"; +} from "../../generated"; import { - getSolautoPositionAccount, getTokenAccount, -} from "../utils/accountUtils"; -import { SOLAUTO_FEES_WALLET } from "../constants/generalAccounts"; -import { + getWalletSplBalances, getWrappedInstruction, splTokenTransferUmiIx, -} from "../utils/solanaUtils"; -import { - FlashLoanDetails, - RebalanceValues, -} from "../utils/solauto/rebalanceUtils"; -import { - MIN_POSITION_STATE_FRESHNESS_SECS, - SOLAUTO_LUT, -} from "../constants/solautoConstants"; -import { currentUnixSeconds } from "../utils/generalUtils"; -import { LivePositionUpdates } from "../utils/solauto/generalUtils"; + ContextUpdates, +} from "../../utils"; +import { SOLAUTO_FEES_WALLET, SOLAUTO_LUT } from "../../constants"; +import { ProgramEnv, RebalanceDetails } from "../../types"; import { ReferralStateManager, ReferralStateManagerArgs, } from "./referralStateManager"; -import { QuoteResponse } from "@jup-ag/api"; +import { + getOrCreatePositionEx, + SolautoPositionEx, +} from "../../solautoPosition"; +import { FlProviderAggregator } from "../flashLoans"; export interface SolautoClientArgs extends ReferralStateManagerArgs { - new?: boolean; positionId?: number; supplyMint?: PublicKey; debtMint?: PublicKey; + lpPoolAccount?: PublicKey; + lpUserAccount?: PublicKey; } +export type ExistingSolautoPositionArgs = Required< + Pick +> & + Partial>; + +export type NewSolautoPositionArgs = Required< + Pick< + SolautoClientArgs, + "positionId" | "supplyMint" | "debtMint" | "lpPoolAccount" + > +>; + +export type ExistingSelfManagedPositionArgs = Required< + Pick +>; + +export type NewSelfManagedPositionArgs = Required< + Pick +>; + export abstract class SolautoClient extends ReferralStateManager { - public lendingPlatform?: LendingPlatform; + public lendingPlatform!: LendingPlatform; + public lpEnv!: ProgramEnv; public authority!: PublicKey; - public positionId!: number; - public selfManaged!: boolean; - public solautoPosition!: PublicKey; - public solautoPositionData!: SolautoPosition | null; - public solautoPositionState!: PositionState | undefined; - - public maxLtvBps?: number; - public liqThresholdBps?: number; + public pos!: SolautoPositionEx; - public supplyMint!: PublicKey; public positionSupplyTa!: PublicKey; public signerSupplyTa!: PublicKey; - public debtMint!: PublicKey; public positionDebtTa!: PublicKey; public signerDebtTa!: PublicKey; @@ -86,62 +88,75 @@ export abstract class SolautoClient extends ReferralStateManager { public authorityLutAddress?: PublicKey; - public livePositionUpdates: LivePositionUpdates = new LivePositionUpdates(); + public flProvider!: FlProviderAggregator; + public contextUpdates: ContextUpdates = new ContextUpdates(); + + private signerSupplyBalance: bigint | undefined; + private signerDebtBalance: bigint | undefined; + + async initializeExistingSolautoPosition(args: ExistingSolautoPositionArgs) { + await this.initialize(args); + } + + async initializeNewSolautoPosition(args: NewSolautoPositionArgs) { + await this.initialize(args); + } + + async initializeExistingSelfManagedPosition( + args: ExistingSelfManagedPositionArgs + ) { + await this.initialize(args); + } + + async initializeNewSelfManagedPosition(args: NewSelfManagedPositionArgs) { + await this.initialize(args); + } async initialize(args: SolautoClientArgs) { await super.initialize(args); - this.positionId = args.positionId ?? 0; - this.selfManaged = this.positionId === 0; - this.solautoPosition = getSolautoPositionAccount( + const positionId = args.positionId ?? 0; + this.pos = await getOrCreatePositionEx( + this.umi, this.authority, - this.positionId, - this.programId + positionId, + this.programId, + { + supplyMint: args.supplyMint, + debtMint: args.debtMint, + lpPoolAccount: args.lpPoolAccount, + lpUserAccount: args.lpUserAccount, + lendingPlatform: this.lendingPlatform, + lpEnv: this.lpEnv, + }, + this.contextUpdates ); - this.solautoPositionData = !args.new - ? await safeFetchSolautoPosition( - this.umi, - publicKey(this.solautoPosition), - { commitment: "confirmed" } - ) - : null; - this.solautoPositionState = this.solautoPositionData?.state; - - this.maxLtvBps = undefined; - this.liqThresholdBps = undefined; - this.supplyMint = - args.supplyMint ?? - (this.solautoPositionData && !this.selfManaged - ? toWeb3JsPublicKey(this.solautoPositionData!.state.supply.mint) - : PublicKey.default); this.positionSupplyTa = getTokenAccount( - this.solautoPosition, - this.supplyMint + this.pos.publicKey, + this.pos.supplyMint ); this.signerSupplyTa = getTokenAccount( toWeb3JsPublicKey(this.signer.publicKey), - this.supplyMint + this.pos.supplyMint ); - this.debtMint = - args.debtMint ?? - (this.solautoPositionData && !this.selfManaged - ? toWeb3JsPublicKey(this.solautoPositionData!.state.debt.mint) - : PublicKey.default); - this.positionDebtTa = getTokenAccount(this.solautoPosition, this.debtMint); + this.positionDebtTa = getTokenAccount( + this.pos.publicKey, + this.pos.debtMint + ); this.signerDebtTa = getTokenAccount( toWeb3JsPublicKey(this.signer.publicKey), - this.debtMint + this.pos.debtMint ); this.solautoFeesSupplyTa = getTokenAccount( SOLAUTO_FEES_WALLET, - this.supplyMint + this.pos.supplyMint ); this.solautoFeesDebtTa = getTokenAccount( SOLAUTO_FEES_WALLET, - this.debtMint + this.pos.debtMint ); this.authorityLutAddress = @@ -152,59 +167,54 @@ export abstract class SolautoClient extends ReferralStateManager { ? toWeb3JsPublicKey(this.referralStateData.lookupTable) : undefined; - this.log("Position state: ", this.solautoPositionState); - this.log( - "Position settings: ", - this.solautoPositionData?.position?.settingParams - ); - this.log( - "Position DCA: ", - (this.solautoPositionData?.position?.dca?.automation?.targetPeriods ?? - 0) > 0 - ? this.solautoPositionData?.position?.dca - : undefined + this.flProvider = new FlProviderAggregator( + this.umi, + this.signer, + this.authority, + this.pos.supplyMint, + this.pos.debtMint, + this.lpEnv ); + await this.flProvider.initialize(); + this.otherSigners.push(...this.flProvider.otherSigners()); + + this.log("Position state: ", this.pos.state); + this.log("Position settings: ", this.pos.settings); + this.log("Public key:", this.pos.publicKey.toString()); + this.log("Supply mint:", this.pos.supplyMint.toString()); + this.log("Debt mint:", this.pos.debtMint.toString()); + this.log("LP pool:", this.pos.lpPoolAccount.toString()); } referredBySupplyTa(): PublicKey | undefined { if (this.referredByState !== undefined) { - return getTokenAccount(this.referredByState, this.supplyMint); + return getTokenAccount(this.referredByState, this.pos.supplyMint); } return undefined; } referredByDebtTa(): PublicKey | undefined { if (this.referredByState !== undefined) { - return getTokenAccount(this.referredByState, this.debtMint); + return getTokenAccount(this.referredByState, this.pos.debtMint); } return undefined; } async resetLiveTxUpdates(success?: boolean) { + this.log("Resetting context updates..."); if (success) { - if (!this.solautoPositionData) { - this.solautoPositionData = await safeFetchSolautoPosition( - this.umi, - publicKey(this.solautoPosition), - { commitment: "confirmed" } - ); + if (!this.pos.exists) { + await this.pos.refetchPositionData(); } else { - if (this.livePositionUpdates.activeDca) { - this.solautoPositionData.position.dca = - this.livePositionUpdates.activeDca; + if (this.contextUpdates.settings) { + this.pos.updateSettings(this.contextUpdates.settings); } - if (this.livePositionUpdates.settings) { - this.solautoPositionData.position.settingParams = - this.livePositionUpdates.settings; - } - // All other live position updates can be derived by getting a fresh position state, so we don't need to do anything else form livePositionUpdates + // All other live position updates can be derived by getting a fresh position state, so we don't need to do anything else form contextUpdates } } - this.livePositionUpdates.reset(); + this.contextUpdates.reset(); } - abstract protocolAccount(): PublicKey; - defaultLookupTables(): string[] { return [ SOLAUTO_LUT, @@ -217,18 +227,15 @@ export abstract class SolautoClient extends ReferralStateManager { lutAccountsToAdd(): PublicKey[] { return [ this.authority, - ...(toWeb3JsPublicKey(this.signer.publicKey).equals(this.authority) - ? [this.signerSupplyTa] - : []), - ...(toWeb3JsPublicKey(this.signer.publicKey).equals(this.authority) - ? [this.signerDebtTa] - : []), - this.solautoPosition, + this.signerSupplyTa, + this.signerDebtTa, + this.pos.publicKey, this.positionSupplyTa, this.positionDebtTa, this.referralState, ...(this.referredBySupplyTa() ? [this.referredBySupplyTa()!] : []), ...(this.referredByDebtTa() ? [this.referredByDebtTa()!] : []), + ...this.flProvider.lutAccountsToAdd(), ]; } @@ -250,7 +257,7 @@ export abstract class SolautoClient extends ReferralStateManager { } | undefined > { - if (this.selfManaged) { + if (!toWeb3JsPublicKey(this.signer.publicKey).equals(this.authority)) { return undefined; } @@ -275,7 +282,9 @@ export abstract class SolautoClient extends ReferralStateManager { recentSlot: await this.umi.rpc.getSlot({ commitment: "finalized" }), }); this.authorityLutAddress = lookupTableAddress; - tx = tx.add(getWrappedInstruction(this.signer, createLookupTableInst)); + tx = tx + .add(getWrappedInstruction(this.signer, createLookupTableInst)) + .add(this.updateReferralStatesIx(undefined, this.authorityLutAddress)); } const accountsToAdd: PublicKey[] = this.lutAccountsToAdd().filter( @@ -288,19 +297,22 @@ export abstract class SolautoClient extends ReferralStateManager { return undefined; } - tx = tx.add( - getWrappedInstruction( - this.signer, - AddressLookupTableProgram.extendLookupTable({ - payer: toWeb3JsPublicKey(this.signer.publicKey), - authority: this.authority, - lookupTable: this.authorityLutAddress, - addresses: accountsToAdd, - }) + tx = tx + .add( + getWrappedInstruction( + this.signer, + AddressLookupTableProgram.extendLookupTable({ + payer: toWeb3JsPublicKey(this.signer.publicKey), + authority: this.authority, + lookupTable: this.authorityLutAddress, + addresses: accountsToAdd, + }) + ) ) - ); + .add(await this.flProvider.flAccountPrereqIxs()); this.log("Requires authority LUT update..."); + this.log("Addresses to add:", accountsToAdd.join(", ")); return { tx, new: existingLutAccounts.length === 0, @@ -308,33 +320,32 @@ export abstract class SolautoClient extends ReferralStateManager { }; } - solautoPositionSettings(): SolautoSettingsParameters | undefined { - return ( - this.livePositionUpdates.settings ?? - this.solautoPositionData?.position.settingParams - ); - } - - solautoPositionActiveDca(): DCASettings | undefined { - return ( - this.livePositionUpdates.activeDca ?? - this.solautoPositionData?.position.dca - ); - } - - async maxLtvAndLiqThresholdBps(): Promise<[number, number] | undefined> { - if (this.maxLtvBps !== undefined && this.liqThresholdBps !== undefined) { - return [this.maxLtvBps, this.liqThresholdBps]; + async signerBalances(): Promise<{ + supplyBalance: bigint; + debtBalance: bigint; + }> { + if (!this.signerSupplyBalance || !this.signerDebtBalance) { + [this.signerSupplyBalance, this.signerDebtBalance] = + await getWalletSplBalances( + this.connection, + toWeb3JsPublicKey(this.signer.publicKey), + [this.pos.supplyMint, this.pos.debtMint] + ); } - return undefined; + + return { + supplyBalance: this.signerSupplyBalance, + debtBalance: this.signerDebtBalance, + }; } - openPosition( - settingParams?: SolautoSettingsParametersInpArgs, - dca?: DCASettingsInpArgs + openPositionIx( + settings?: SolautoSettingsParametersInpArgs, + dca?: DCASettingsInpArgs, + positionType?: PositionType ): TransactionBuilder { if (dca && dca.dcaInBaseUnit > 0) { - this.livePositionUpdates.new({ + this.contextUpdates.new({ type: "dcaInBalance", value: { amount: BigInt(dca.dcaInBaseUnit), @@ -342,14 +353,14 @@ export abstract class SolautoClient extends ReferralStateManager { }, }); } - if (settingParams) { - this.livePositionUpdates.new({ + if (settings) { + this.contextUpdates.new({ type: "settings", - value: settingParams, + value: settings, }); } if (dca) { - this.livePositionUpdates.new({ + this.contextUpdates.new({ type: "dca", value: dca, }); @@ -364,41 +375,39 @@ export abstract class SolautoClient extends ReferralStateManager { let signerDcaTa: UmiPublicKey | undefined = undefined; if (isOption(args.dca) && isSome(args.dca)) { if (args.dca.value.tokenType === TokenType.Supply) { - dcaMint = publicKey(this.supplyMint); + dcaMint = publicKey(this.pos.supplyMint); positionDcaTa = publicKey(this.positionSupplyTa); signerDcaTa = publicKey(this.signerSupplyTa); } else { - dcaMint = publicKey(this.debtMint); + dcaMint = publicKey(this.pos.debtMint); positionDcaTa = publicKey(this.positionDebtTa); signerDcaTa = publicKey(this.signerDebtTa); } - let addingToPos = false; if ( isOption(args.dca) && isSome(args.dca) && args.dca.value.dcaInBaseUnit > 0 ) { - this.livePositionUpdates.new({ + this.contextUpdates.new({ type: "dcaInBalance", value: { amount: BigInt(args.dca.value.dcaInBaseUnit), tokenType: args.dca.value.tokenType, }, }); - addingToPos = true; } } - if (isOption(args.settingParams) && isSome(args.settingParams)) { - this.livePositionUpdates.new({ + if (isOption(args.settings) && isSome(args.settings)) { + this.contextUpdates.new({ type: "settings", - value: args.settingParams.value, + value: args.settings.value, }); } if (isOption(args.dca) && isSome(args.dca)) { - this.livePositionUpdates.new({ + this.contextUpdates.new({ type: "dca", value: args.dca.value, }); @@ -406,7 +415,7 @@ export abstract class SolautoClient extends ReferralStateManager { return updatePosition(this.umi, { signer: this.signer, - solautoPosition: publicKey(this.solautoPosition), + solautoPosition: publicKey(this.pos.publicKey), dcaMint, positionDcaTa, signerDcaTa, @@ -414,56 +423,28 @@ export abstract class SolautoClient extends ReferralStateManager { }); } - closePositionIx(): TransactionBuilder { - return closePosition(this.umi, { - signer: this.signer, - solautoPosition: publicKey(this.solautoPosition), - signerSupplyTa: publicKey(this.signerSupplyTa), - positionSupplyTa: publicKey(this.positionSupplyTa), - positionDebtTa: publicKey(this.positionDebtTa), - signerDebtTa: publicKey(this.signerDebtTa), - protocolAccount: publicKey(this.protocolAccount()), - }); - } + abstract closePositionIx(): TransactionBuilder; cancelDCAIx(): TransactionBuilder { let dcaMint: UmiPublicKey | undefined = undefined; let positionDcaTa: UmiPublicKey | undefined = undefined; let signerDcaTa: UmiPublicKey | undefined = undefined; - const currDca = this.solautoPositionActiveDca()!; - if (currDca.dcaInBaseUnit > 0) { - if (currDca.tokenType === TokenType.Supply) { - dcaMint = publicKey(this.supplyMint); - positionDcaTa = publicKey(this.positionSupplyTa); - signerDcaTa = publicKey(this.signerSupplyTa); - } else { - dcaMint = publicKey(this.debtMint); - positionDcaTa = publicKey(this.positionDebtTa); - signerDcaTa = publicKey(this.signerDebtTa); - } - - this.livePositionUpdates.new({ - type: "cancellingDca", - value: this.solautoPositionData!.position.dca.tokenType, - }); - } - return cancelDCA(this.umi, { signer: this.signer, - solautoPosition: publicKey(this.solautoPosition), + solautoPosition: publicKey(this.pos.publicKey), dcaMint, positionDcaTa, signerDcaTa, }); } - abstract refresh(): TransactionBuilder; + abstract refreshIx(priceType?: PriceType): TransactionBuilder; - protocolInteraction(args: SolautoActionArgs): TransactionBuilder { + protocolInteractionIx(args: SolautoActionArgs): TransactionBuilder { let tx = transactionBuilder(); - if (!this.selfManaged) { + if (!this.pos.selfManaged) { if (args.__kind === "Deposit") { tx = tx.add( splTokenTransferUmiIx( @@ -494,8 +475,7 @@ export abstract class SolautoClient extends ReferralStateManager { toWeb3JsPublicKey(this.signer.publicKey), BigInt( Math.round( - Number(this.solautoPositionState!.debt.amountUsed.baseUnit) * - 1.01 + Number(this.pos.state.debt.amountUsed.baseUnit) * 1.01 ) ) ) @@ -505,41 +485,40 @@ export abstract class SolautoClient extends ReferralStateManager { } if (args.__kind === "Deposit") { - this.livePositionUpdates.new({ + this.contextUpdates.new({ type: "supply", value: BigInt(args.fields[0]), }); } else if (args.__kind === "Withdraw") { if (args.fields[0].__kind === "Some") { - this.livePositionUpdates.new({ + this.contextUpdates.new({ type: "supply", value: BigInt(args.fields[0].fields[0]) * BigInt(-1), }); } else { - this.livePositionUpdates.new({ + this.contextUpdates.new({ type: "supply", value: - (this.solautoPositionState?.supply.amountUsed.baseUnit ?? - BigInt(0)) * BigInt(-1), + (this.pos.state.supply.amountUsed.baseUnit ?? BigInt(0)) * + BigInt(-1), }); } } else if (args.__kind === "Borrow") { - this.livePositionUpdates.new({ + this.contextUpdates.new({ type: "debt", value: BigInt(args.fields[0]), }); } else { if (args.fields[0].__kind === "Some") { - this.livePositionUpdates.new({ + this.contextUpdates.new({ type: "debt", value: BigInt(args.fields[0].fields[0]) * BigInt(-1), }); } else { - this.livePositionUpdates.new({ + this.contextUpdates.new({ type: "debt", value: - (this.solautoPositionState?.debt.amountUsed.baseUnit ?? BigInt(0)) * - BigInt(-1), + (this.pos.state.debt.amountUsed.baseUnit ?? BigInt(0)) * BigInt(-1), }); } } @@ -547,33 +526,8 @@ export abstract class SolautoClient extends ReferralStateManager { return tx; } - abstract flashBorrow( - flashLoanDetails: FlashLoanDetails, - destinationTokenAccount: PublicKey + abstract rebalanceIx( + rebalanceStep: RebalanceStep, + data: RebalanceDetails ): TransactionBuilder; - - abstract flashRepay(flashLoanDetails: FlashLoanDetails): TransactionBuilder; - - abstract rebalance( - rebalanceStep: "A" | "B", - jupQuote: QuoteResponse, - rebalanceType: SolautoRebalanceTypeArgs, - rebalanceValues: RebalanceValues, - flashLoan?: FlashLoanDetails, - targetLiqUtilizationRateBps?: number - ): TransactionBuilder; - - async getFreshPositionState(): Promise { - if ( - Boolean(this.solautoPositionData) && - Boolean(this.solautoPositionState) && - Number(this.solautoPositionState!.lastUpdated) > - currentUnixSeconds() - MIN_POSITION_STATE_FRESHNESS_SECS && - !this.livePositionUpdates.hasUpdates() - ) { - return this.solautoPositionState; - } - - return undefined; - } } diff --git a/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts b/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts new file mode 100644 index 00000000..0a5aca49 --- /dev/null +++ b/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts @@ -0,0 +1,477 @@ +import { PublicKey, SYSVAR_INSTRUCTIONS_PUBKEY } from "@solana/web3.js"; +import { + Signer, + TransactionBuilder, + publicKey, + PublicKey as UmiPublicKey, + createSignerFromKeypair, + AccountMeta, +} from "@metaplex-foundation/umi"; +import { + fromWeb3JsPublicKey, + toWeb3JsPublicKey, +} from "@metaplex-foundation/umi-web3js-adapters"; +import { MarginfiAssetAccounts, RebalanceDetails } from "../../types"; +import { getMarginfiAccounts, MarginfiProgramAccounts } from "../../constants"; +import { + DCASettingsInpArgs, + LendingPlatform, + PositionType, + PriceType, + RebalanceDirection, + RebalanceStep, + SolautoActionArgs, + SolautoRebalanceType, + SolautoSettingsParametersInpArgs, + SwapType, + closePosition, + marginfiOpenPosition, + marginfiProtocolInteraction, + marginfiRebalance, + marginfiRefreshData, +} from "../../generated"; +import { + getAllMarginfiAccountsByAuthority, + marginfiAccountEmpty, + getTokenAccount, + hasFirstRebalance, + getRemainingAccountsForMarginfiHealthCheck, + getAccountMeta, +} from "../../utils"; +import { + Bank, + fetchMarginfiAccount, + lendingAccountBorrow, + lendingAccountDeposit, + lendingAccountRepay, + lendingAccountWithdraw, + marginfiAccountInitialize, + safeFetchAllMarginfiAccount, +} from "../../marginfi-sdk"; +import { SolautoClient, SolautoClientArgs } from "./solautoClient"; + +function isSigner(account: PublicKey | Signer): account is Signer { + return "publicKey" in account; +} + +export class SolautoMarginfiClient extends SolautoClient { + public lendingPlatform = LendingPlatform.Marginfi; + + public mfiAccounts!: MarginfiProgramAccounts; + + public marginfiAccount!: PublicKey | Signer; + public marginfiAccountPk!: PublicKey; + public healthCheckRemainingAccounts?: AccountMeta[]; + public marginfiGroup!: PublicKey; + + public marginfiSupplyAccounts!: MarginfiAssetAccounts; + public marginfiDebtAccounts!: MarginfiAssetAccounts; + + public supplyPriceOracle!: PublicKey; + public debtPriceOracle!: PublicKey; + + async initialize(args: SolautoClientArgs) { + await super.initialize(args); + + this.mfiAccounts = getMarginfiAccounts(this.lpEnv); + + this.marginfiGroup = this.pos.lpPoolAccount; + + if (this.pos.selfManaged) { + this.marginfiAccount = + args.lpUserAccount ?? + createSignerFromKeypair(this.umi, this.umi.eddsa.generateKeypair()); + } else { + if (this.pos.exists) { + this.marginfiAccount = this.pos.lpUserAccount!; + } else { + const accounts = await getAllMarginfiAccountsByAuthority( + this.umi, + this.pos.publicKey, + this.marginfiGroup, + false + ); + const reusableAccounts = + accounts.length > 0 + ? ( + await safeFetchAllMarginfiAccount( + this.umi, + accounts.map((x) => publicKey(x.marginfiAccount)) + ) + ).filter((x) => marginfiAccountEmpty(x)) + : []; + this.marginfiAccount = + reusableAccounts.length > 0 + ? toWeb3JsPublicKey(reusableAccounts[0].publicKey) + : createSignerFromKeypair( + this.umi, + this.umi.eddsa.generateKeypair() + ); + } + } + + this.marginfiAccountPk = isSigner(this.marginfiAccount) + ? toWeb3JsPublicKey(this.marginfiAccount.publicKey) + : this.marginfiAccount; + + if (isSigner(this.marginfiAccount)) { + this.otherSigners.push(this.marginfiAccount); + } else if (this.pos.selfManaged) { + const accountData = await fetchMarginfiAccount( + this.umi, + fromWeb3JsPublicKey(this.marginfiAccount as PublicKey) + ); + this.healthCheckRemainingAccounts = ( + await Promise.all( + accountData.lendingAccount.balances.map((balance) => + getRemainingAccountsForMarginfiHealthCheck(this.umi, balance) + ) + ) + ).flat(); + } + + this.marginfiSupplyAccounts = + this.mfiAccounts.bankAccounts[this.marginfiGroup.toString()][ + this.pos.supplyMint.toString() + ]!; + this.marginfiDebtAccounts = + this.mfiAccounts.bankAccounts[this.marginfiGroup.toString()][ + this.pos.debtMint.toString() + ]!; + + [this.supplyPriceOracle, this.debtPriceOracle] = + await this.pos.priceOracles(); + + this.log("Marginfi account:", this.marginfiAccountPk.toString()); + this.log("Supply price oracle:", this.supplyPriceOracle.toString()); + this.log("Debt price oracle:", this.debtPriceOracle.toString()); + } + + defaultLookupTables(): string[] { + return [ + this.mfiAccounts.lookupTable.toString(), + ...super.defaultLookupTables(), + ]; + } + + lutAccountsToAdd(): PublicKey[] { + return [...super.lutAccountsToAdd(), this.marginfiAccountPk]; + } + + marginfiAccountInitialize(marginfiAccount: Signer): TransactionBuilder { + return marginfiAccountInitialize(this.umi, { + marginfiAccount: marginfiAccount, + marginfiGroup: publicKey(this.marginfiGroup), + authority: this.signer, + feePayer: this.signer, + }); + } + + openPositionIx( + settings?: SolautoSettingsParametersInpArgs, + dca?: DCASettingsInpArgs + ): TransactionBuilder { + return super + .openPositionIx(settings, dca) + .add(this.marginfiOpenPositionIx(settings, dca)); + } + + private marginfiOpenPositionIx( + settings?: SolautoSettingsParametersInpArgs, + dca?: DCASettingsInpArgs, + positionType?: PositionType + ): TransactionBuilder { + let signerDebtTa: UmiPublicKey | undefined = undefined; + if (dca) { + signerDebtTa = publicKey(this.signerDebtTa); + } + + return marginfiOpenPosition(this.umi, { + signer: this.signer, + marginfiProgram: publicKey(this.mfiAccounts.program), + signerReferralState: publicKey(this.referralState), + referredByState: this.referredByState + ? publicKey(this.referredByState) + : undefined, + referredBySupplyTa: this.referredBySupplyTa() + ? publicKey(this.referredBySupplyTa()!) + : undefined, + solautoPosition: publicKey(this.pos.publicKey), + marginfiGroup: publicKey(this.marginfiGroup), + marginfiAccount: + "publicKey" in this.marginfiAccount + ? (this.marginfiAccount as Signer) + : publicKey(this.marginfiAccount), + supplyMint: publicKey(this.pos.supplyMint), + supplyBank: publicKey(this.marginfiSupplyAccounts.bank), + positionSupplyTa: publicKey(this.positionSupplyTa), + debtMint: publicKey(this.pos.debtMint), + debtBank: publicKey(this.marginfiDebtAccounts.bank), + positionDebtTa: publicKey(this.positionDebtTa), + signerDebtTa: signerDebtTa, + positionType: positionType ?? PositionType.Leverage, + positionData: { + positionId: this.pos.positionId, + settings: settings ?? null, + dca: dca ?? null, + }, + }); + } + + closePositionIx(): TransactionBuilder { + return closePosition(this.umi, { + signer: this.signer, + solautoPosition: publicKey(this.pos.publicKey), + signerSupplyTa: publicKey(this.signerSupplyTa), + positionSupplyTa: publicKey(this.positionSupplyTa), + positionDebtTa: publicKey(this.positionDebtTa), + signerDebtTa: publicKey(this.signerDebtTa), + lpUserAccount: publicKey(this.marginfiAccountPk), + }); + } + + refreshIx(priceType?: PriceType): TransactionBuilder { + return marginfiRefreshData(this.umi, { + signer: this.signer, + marginfiProgram: publicKey(this.mfiAccounts.program), + marginfiGroup: publicKey(this.marginfiGroup), + marginfiAccount: publicKey(this.marginfiAccount), + supplyBank: publicKey(this.marginfiSupplyAccounts.bank), + supplyPriceOracle: publicKey(this.supplyPriceOracle), + debtBank: publicKey(this.marginfiDebtAccounts.bank), + debtPriceOracle: publicKey(this.debtPriceOracle), + solautoPosition: publicKey(this.pos.publicKey), + priceType: priceType ?? PriceType.Realtime, + }); + } + + protocolInteractionIx(args: SolautoActionArgs): TransactionBuilder { + let tx = super.protocolInteractionIx(args); + + if (this.pos.selfManaged) { + return tx.add(this.marginfiProtocolInteractionIx(args)); + } else { + return tx.add(this.marginfiSolautoProtocolInteractionIx(args)); + } + } + + private marginfiProtocolInteractionIx(args: SolautoActionArgs) { + switch (args.__kind) { + case "Deposit": { + return lendingAccountDeposit(this.umi, { + signer: this.signer, + signerTokenAccount: publicKey(this.signerSupplyTa), + marginfiAccount: publicKey(this.marginfiAccountPk), + marginfiGroup: publicKey(this.marginfiGroup), + bank: publicKey(this.marginfiSupplyAccounts.bank), + bankLiquidityVault: publicKey( + this.marginfiSupplyAccounts.liquidityVault + ), + amount: args.fields[0], + depositUpToLimit: true, + }); + } + case "Borrow": { + const remainingAccounts = this.healthCheckRemainingAccounts ?? []; + if ( + !remainingAccounts.find( + (x) => + x.pubkey.toString() === this.marginfiDebtAccounts.bank.toString() + ) + ) { + remainingAccounts.push( + ...[ + getAccountMeta(new PublicKey(this.marginfiDebtAccounts.bank)), + getAccountMeta(this.debtPriceOracle), + ] + ); + } + return lendingAccountBorrow(this.umi, { + amount: args.fields[0], + signer: this.signer, + destinationTokenAccount: publicKey(this.signerDebtTa), + marginfiAccount: publicKey(this.marginfiAccountPk), + marginfiGroup: publicKey(this.marginfiGroup), + bank: publicKey(this.marginfiDebtAccounts.bank), + bankLiquidityVault: publicKey( + this.marginfiDebtAccounts.liquidityVault + ), + bankLiquidityVaultAuthority: publicKey( + this.marginfiDebtAccounts.vaultAuthority + ), + }).addRemainingAccounts(remainingAccounts); + } + case "Repay": { + return lendingAccountRepay(this.umi, { + amount: + args.fields[0].__kind === "Some" ? args.fields[0].fields[0] : 0, + repayAll: args.fields[0].__kind === "All" ? true : false, + signer: this.signer, + signerTokenAccount: publicKey(this.signerDebtTa), + marginfiAccount: publicKey(this.marginfiAccountPk), + marginfiGroup: publicKey(this.marginfiGroup), + bank: publicKey(this.marginfiDebtAccounts.bank), + bankLiquidityVault: publicKey( + this.marginfiDebtAccounts.liquidityVault + ), + }); + } + case "Withdraw": { + return lendingAccountWithdraw(this.umi, { + amount: + args.fields[0].__kind === "Some" ? args.fields[0].fields[0] : 0, + withdrawAll: args.fields[0].__kind === "All" ? true : false, + signer: this.signer, + destinationTokenAccount: publicKey(this.signerSupplyTa), + marginfiAccount: publicKey(this.marginfiAccountPk), + marginfiGroup: publicKey(this.marginfiGroup), + bank: publicKey(this.marginfiSupplyAccounts.bank), + bankLiquidityVault: publicKey( + this.marginfiSupplyAccounts.liquidityVault + ), + bankLiquidityVaultAuthority: publicKey( + this.marginfiSupplyAccounts.vaultAuthority + ), + }).addRemainingAccounts(this.healthCheckRemainingAccounts ?? []); + } + } + } + + private marginfiSolautoProtocolInteractionIx( + args: SolautoActionArgs + ): TransactionBuilder { + let positionSupplyTa: UmiPublicKey | undefined = undefined; + let vaultSupplyTa: UmiPublicKey | undefined = undefined; + let supplyVaultAuthority: UmiPublicKey | undefined = undefined; + if (args.__kind === "Deposit" || args.__kind === "Withdraw") { + positionSupplyTa = publicKey( + args.__kind === "Withdraw" || this.pos.selfManaged + ? this.signerSupplyTa + : this.positionSupplyTa + ); + vaultSupplyTa = publicKey(this.marginfiSupplyAccounts.liquidityVault); + supplyVaultAuthority = publicKey( + this.marginfiSupplyAccounts.vaultAuthority + ); + } + + let positionDebtTa: UmiPublicKey | undefined = undefined; + let vaultDebtTa: UmiPublicKey | undefined = undefined; + let debtVaultAuthority: UmiPublicKey | undefined = undefined; + if (args.__kind === "Borrow" || args.__kind === "Repay") { + positionDebtTa = publicKey( + args.__kind === "Borrow" || this.pos.selfManaged + ? this.signerDebtTa + : this.positionDebtTa + ); + vaultDebtTa = publicKey(this.marginfiDebtAccounts.liquidityVault); + debtVaultAuthority = publicKey(this.marginfiDebtAccounts.vaultAuthority); + } + + let supplyPriceOracle: UmiPublicKey | undefined = undefined; + let debtPriceOracle: UmiPublicKey | undefined = undefined; + if (args.__kind === "Withdraw" || args.__kind === "Borrow") { + supplyPriceOracle = publicKey(this.supplyPriceOracle); + debtPriceOracle = publicKey(this.debtPriceOracle); + } + + return marginfiProtocolInteraction(this.umi, { + signer: this.signer, + marginfiProgram: publicKey(this.mfiAccounts.program), + solautoPosition: publicKey(this.pos.publicKey), + marginfiGroup: publicKey(this.marginfiGroup), + marginfiAccount: publicKey(this.marginfiAccountPk), + supplyBank: publicKey(this.marginfiSupplyAccounts.bank), + supplyPriceOracle, + positionSupplyTa, + vaultSupplyTa, + supplyVaultAuthority, + debtBank: publicKey(this.marginfiDebtAccounts.bank), + debtPriceOracle, + positionDebtTa, + vaultDebtTa, + debtVaultAuthority, + solautoAction: args, + }); + } + + rebalanceIx( + rebalanceStep: RebalanceStep, + data: RebalanceDetails + ): TransactionBuilder { + const preSwapRebalance = rebalanceStep === RebalanceStep.PreSwap; + const postSwapRebalance = rebalanceStep === RebalanceStep.PostSwap; + + const isFirstRebalance = + (preSwapRebalance && hasFirstRebalance(data.rebalanceType)) || + (postSwapRebalance && + data.rebalanceType === SolautoRebalanceType.FLSwapThenRebalance); + + const addAuthorityTas = + this.pos.selfManaged || data.values.tokenBalanceChange !== undefined; + + return marginfiRebalance(this.umi, { + signer: this.signer, + marginfiProgram: publicKey(this.mfiAccounts.program), + ixsSysvar: publicKey(SYSVAR_INSTRUCTIONS_PUBKEY), + solautoFeesTa: publicKey( + data.values.rebalanceDirection === RebalanceDirection.Boost + ? this.solautoFeesSupplyTa + : this.solautoFeesDebtTa + ), + authorityReferralState: publicKey(this.referralState), + referredByTa: this.referredByState + ? publicKey( + data.values.rebalanceDirection === RebalanceDirection.Boost + ? this.referredBySupplyTa()! + : this.referredByDebtTa()! + ) + : undefined, + positionAuthority: + data.values.tokenBalanceChange !== undefined + ? publicKey(this.authority) + : undefined, + solautoPosition: publicKey(this.pos.publicKey), + marginfiGroup: publicKey(this.marginfiGroup), + marginfiAccount: publicKey(this.marginfiAccountPk), + intermediaryTa: publicKey( + getTokenAccount( + toWeb3JsPublicKey(this.signer.publicKey), + new PublicKey(data.swapQuote.inputMint) + ) + ), + supplyBank: publicKey(this.marginfiSupplyAccounts.bank), + supplyPriceOracle: publicKey(this.supplyPriceOracle), + positionSupplyTa: publicKey(this.positionSupplyTa), + authoritySupplyTa: addAuthorityTas + ? publicKey(getTokenAccount(this.authority, this.pos.supplyMint)) + : undefined, + vaultSupplyTa: publicKey(this.marginfiSupplyAccounts.liquidityVault), + supplyVaultAuthority: publicKey( + this.marginfiSupplyAccounts.vaultAuthority + ), + debtBank: publicKey(this.marginfiDebtAccounts.bank), + debtPriceOracle: publicKey(this.debtPriceOracle), + positionDebtTa: publicKey(this.positionDebtTa), + authorityDebtTa: addAuthorityTas + ? publicKey(getTokenAccount(this.authority, this.pos.debtMint)) + : undefined, + vaultDebtTa: publicKey(this.marginfiDebtAccounts.liquidityVault), + debtVaultAuthority: publicKey(this.marginfiDebtAccounts.vaultAuthority), + rebalanceType: data.rebalanceType, + targetLiqUtilizationRateBps: data.targetLiqUtilizationRateBps ?? null, + swapInAmountBaseUnit: isFirstRebalance + ? parseInt(data.swapQuote.inAmount) + : null, + swapType: + data.swapQuote.swapMode === "ExactOut" && isFirstRebalance + ? SwapType.ExactOut + : null, + priceType: isFirstRebalance ? data.priceType : null, + flashLoanFeeBps: + data.flashLoan?.flFeeBps && isFirstRebalance + ? data.flashLoan.flFeeBps + : null, + }); + } +} diff --git a/solauto-sdk/src/services/solauto/txHandler.ts b/solauto-sdk/src/services/solauto/txHandler.ts new file mode 100644 index 00000000..5cdba227 --- /dev/null +++ b/solauto-sdk/src/services/solauto/txHandler.ts @@ -0,0 +1,70 @@ +import { Connection, PublicKey } from "@solana/web3.js"; +import { Signer, signerIdentity, Umi } from "@metaplex-foundation/umi"; +import { + WalletAdapter, + walletAdapterIdentity, +} from "@metaplex-foundation/umi-signer-wallet-adapters"; +import { consoleLog, getSolanaRpcConnection } from "../../utils"; +import { SOLAUTO_PROD_PROGRAM } from "../../constants"; +import { ProgramEnv } from "../../types"; + +export interface TxHandlerProps { + signer?: Signer; + wallet?: WalletAdapter; + rpcUrl: string; + showLogs?: boolean; + programId?: PublicKey; + lpEnv?: ProgramEnv; +} + +export abstract class TxHandler { + public rpcUrl!: string; + public showLogs = false; + public programId!: PublicKey; + public lpEnv!: ProgramEnv; + + public connection!: Connection; + public umi!: Umi; + public signer!: Signer; + public otherSigners: Signer[] = []; + + constructor(props: TxHandlerProps) { + this.programId = props.programId ?? SOLAUTO_PROD_PROGRAM; + this.lpEnv = props.lpEnv ?? "Prod"; + + this.rpcUrl = props.rpcUrl; + const [connection, umi] = getSolanaRpcConnection( + this.rpcUrl, + this.programId, + this.lpEnv + ); + this.connection = connection; + this.umi = umi; + + if (!props.signer && !props.wallet) { + throw new Error("Signer or wallet must be provided"); + } + this.umi = this.umi.use( + props.signer + ? signerIdentity(props.signer, true) + : walletAdapterIdentity(props.wallet!, true) + ); + this.signer = this.umi.identity; + + if (props.showLogs !== undefined) { + this.showLogs = props.showLogs; + } + + if (!(globalThis as any).SHOW_LOGS && this.showLogs) { + (globalThis as any).SHOW_LOGS = Boolean(this.showLogs); + } + } + + log(...args: any[]): void { + consoleLog(...args); + } + + abstract defaultLookupTables(): string[]; + + abstract resetLiveTxUpdates(success?: boolean): Promise; +} diff --git a/solauto-sdk/src/services/swap/index.ts b/solauto-sdk/src/services/swap/index.ts new file mode 100644 index 00000000..36ff8444 --- /dev/null +++ b/solauto-sdk/src/services/swap/index.ts @@ -0,0 +1 @@ +export * from "./jupSwapManager"; diff --git a/solauto-sdk/src/services/swap/jupSwapManager.ts b/solauto-sdk/src/services/swap/jupSwapManager.ts new file mode 100644 index 00000000..3918524a --- /dev/null +++ b/solauto-sdk/src/services/swap/jupSwapManager.ts @@ -0,0 +1,206 @@ +import { PublicKey } from "@solana/web3.js"; +import { + Signer, + TransactionBuilder, + transactionBuilder, +} from "@metaplex-foundation/umi"; +import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; +import { + createJupiterApiClient, + QuoteResponse, + SwapInstructionsResponse, +} from "@jup-ag/api"; +import { + consoleLog, + retryWithExponentialBackoff, + getWrappedInstruction, + fromBps, + toBps, + getTokenAccount, + jupIxToSolanaIx, + tokenInfo, +} from "../../utils"; +import { TransactionItemInputs } from "../../types"; +import { TokenInfo } from "../../constants"; + +export interface SwapInput { + inputMint: PublicKey; + outputMint: PublicKey; + amount: bigint; + exactIn?: boolean; + exactOut?: boolean; + slippageBps?: number; +} + +export interface SwapParams extends SwapInput { + destinationWallet?: PublicKey; + slippageIncFactor?: number; + wrapAndUnwrapSol?: boolean; +} + +export interface JupSwapTransactionData { + jupQuote: QuoteResponse; + setupIx: TransactionBuilder; + swapIx: TransactionBuilder; + cleanupIx: TransactionBuilder; + lookupTableAddresses: string[]; +} + +export class JupSwapManager { + jupApi = createJupiterApiClient(); + + public jupQuote: QuoteResponse | undefined = undefined; + + constructor(private signer: Signer) {} + + public async getQuote(data: SwapInput): Promise { + const inputMintInfo: TokenInfo | undefined = tokenInfo(data.inputMint); + const outputMintInfo: TokenInfo | undefined = tokenInfo(data.outputMint); + const lowLiquidityMint = + !inputMintInfo || + inputMintInfo?.isMeme || + !outputMintInfo || + outputMintInfo?.isMeme; + const slippageBps = data.slippageBps ?? (lowLiquidityMint ? 250 : 100); + + return await retryWithExponentialBackoff( + async (attemptNum: number) => + await this.jupApi.quoteGet({ + amount: Number(data.amount), + inputMint: data.inputMint.toString(), + outputMint: data.outputMint.toString(), + swapMode: data.exactOut + ? "ExactOut" + : data.exactIn + ? "ExactIn" + : undefined, + slippageBps, + maxAccounts: !data.exactOut + ? (lowLiquidityMint ? 25 : 15) + attemptNum * 5 + : undefined, + }), + 6, + 250 + ); + } + + private async getJupInstructions( + data: SwapParams + ): Promise { + if (!this.jupQuote) { + throw new Error( + "Fetch a quote first before getting Jupiter instructions" + ); + } + + const instructions = await retryWithExponentialBackoff( + async () => { + const res = await this.jupApi.swapInstructionsPost({ + swapRequest: { + userPublicKey: this.signer.publicKey.toString(), + quoteResponse: this.jupQuote!, + wrapAndUnwrapSol: data.wrapAndUnwrapSol ?? false, + useTokenLedger: !data.exactOut && !data.exactIn, + destinationTokenAccount: getTokenAccount( + data.destinationWallet ?? + toWeb3JsPublicKey(this.signer.publicKey), + data.outputMint + ).toString(), + }, + }); + if (!res) { + throw new Error("No instructions retrieved"); + } + return res; + }, + 4, + 200 + ); + if (!instructions.swapInstruction) { + throw new Error("No swap instruction was returned by Jupiter"); + } + return instructions; + } + + priceImpactBps() { + return Math.round(toBps(parseFloat(this.jupQuote!.priceImpactPct))) + 1; + } + + private adaptSlippageToPriceImpact(slippageIncFactor: number) { + const finalPriceSlippageBps = Math.round( + Math.max(20, this.jupQuote!.slippageBps, this.priceImpactBps()) * + (1 + slippageIncFactor) + ); + this.jupQuote!.slippageBps = finalPriceSlippageBps; + } + + private addInAmountSlippagePadding() { + consoleLog("Raw inAmount:", this.jupQuote!.inAmount); + const inc = Math.max( + fromBps(this.priceImpactBps()) * 1.1, + fromBps(this.jupQuote!.slippageBps) * 0.1 + ); + consoleLog("Inc:", inc); + this.jupQuote!.inAmount = Math.round( + parseInt(this.jupQuote!.inAmount) + + parseInt(this.jupQuote!.inAmount) * inc + ).toString(); + consoleLog("Increased inAmount:", this.jupQuote!.inAmount); + } + + async getJupSwapTxData(data: SwapParams): Promise { + if (!this.jupQuote) { + this.jupQuote = await this.getQuote(data); + } + + if (data.slippageIncFactor) { + this.adaptSlippageToPriceImpact(data.slippageIncFactor); + } + consoleLog("Quote:", this.jupQuote); + + const instructions = await this.getJupInstructions(data); + + if (data.exactOut) { + this.addInAmountSlippagePadding(); + } + + return { + jupQuote: this.jupQuote, + lookupTableAddresses: instructions.addressLookupTableAddresses, + setupIx: transactionBuilder( + (instructions.setupInstructions ?? []).map((ix) => + getWrappedInstruction(this.signer, jupIxToSolanaIx(ix)) + ) + ), + swapIx: transactionBuilder([ + getWrappedInstruction( + this.signer, + jupIxToSolanaIx(instructions.swapInstruction) + ), + ]), + cleanupIx: transactionBuilder( + instructions.cleanupInstruction + ? [ + getWrappedInstruction( + this.signer, + jupIxToSolanaIx(instructions.cleanupInstruction) + ), + ] + : [] + ), + }; + } + + async getSwapTx(data: SwapParams): Promise { + const swapData = await this.getJupSwapTxData(data); + + return { + tx: transactionBuilder().add([ + swapData.setupIx, + swapData.swapIx, + swapData.cleanupIx, + ]), + lookupTableAddresses: swapData.lookupTableAddresses, + }; + } +} diff --git a/solauto-sdk/src/services/transactions/index.ts b/solauto-sdk/src/services/transactions/index.ts new file mode 100644 index 00000000..256d07b1 --- /dev/null +++ b/solauto-sdk/src/services/transactions/index.ts @@ -0,0 +1,3 @@ +export * from "./manager"; +export * from "./types"; +export * from "./transactionUtils"; diff --git a/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts b/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts new file mode 100644 index 00000000..f5c4cc34 --- /dev/null +++ b/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts @@ -0,0 +1,141 @@ +import { + transactionBuilder, + TransactionBuilder, +} from "@metaplex-foundation/umi"; +import { SolautoClient } from "../../solauto"; +import { TransactionsManager } from "./transactionsManager"; +import { + buildSwbSubmitResponseTx, + isSwitchboardMint, + retryWithExponentialBackoff, +} from "../../../utils"; +import { TransactionItem } from "../types"; +import { getTransactionChores } from "../transactionUtils"; +import { CHORES_TX_NAME } from "../../../constants"; + +export class ClientTransactionsManager extends TransactionsManager { + private async updateLut(tx: TransactionBuilder, newLut: boolean) { + const lutInputs = await this.lookupTables.getLutInputs(); + const updateLutTxName = `${newLut ? "create" : "update"} lookup table`; + await retryWithExponentialBackoff( + async (attemptNum, prevError) => + await this.sendTransaction( + tx.setAddressLookupTables(lutInputs), + updateLutTxName, + attemptNum, + this.getUpdatedPriorityFeeSetting(prevError, attemptNum), + "skip-simulation" + ), + this.signableRetries, + 150, + this.errorsToThrow + ); + await this.txHandler.refetchReferralState(); + } + + private async addSwbOraclePullTxs(txs: TransactionItem[]) { + const switchboardMints = [ + ...(isSwitchboardMint(this.txHandler.pos.supplyMint) + ? [this.txHandler.pos.supplyMint] + : []), + ...(isSwitchboardMint(this.txHandler.pos.debtMint) + ? [this.txHandler.pos.debtMint] + : []), + ]; + + if (txs.find((x) => x.oracleInteractor) && switchboardMints.length) { + this.txHandler.log("Requires oracle update(s)..."); + const oracleTxs = switchboardMints.map( + (x) => + new TransactionItem( + async () => + await buildSwbSubmitResponseTx( + this.txHandler.connection, + this.txHandler.signer, + x + ), + this.updateOracleTxName + ) + ); + txs.unshift(...oracleTxs); + } + } + + private async addChoreTxs( + txs: TransactionItem[], + updateLutTx?: TransactionBuilder + ) { + let [choresBefore, choresAfter] = await getTransactionChores( + this.txHandler, + transactionBuilder().add( + txs + .filter((x) => x.tx && x.tx.getInstructions().length > 0) + .map((x) => x.tx!) + ) + ); + + if (updateLutTx) { + choresBefore.prepend(updateLutTx); + } + + if (choresBefore.getInstructions().length) { + const chore = new TransactionItem( + async () => ({ tx: choresBefore }), + CHORES_TX_NAME + ); + await chore.initialize(); + txs.unshift(chore); + this.txHandler.log( + "Chores before: ", + choresBefore.getInstructions().length + ); + } + + if (choresAfter.getInstructions().length) { + const chore = new TransactionItem( + async () => ({ tx: choresAfter }), + CHORES_TX_NAME + ); + await chore.initialize(); + txs.push(chore); + this.txHandler.log( + "Chores after: ", + choresAfter.getInstructions().length + ); + } + } + + public async send(transactions: TransactionItem[]) { + const items = [...transactions]; + const client = this.txHandler as SolautoClient; + + const updateLut = await client.updateLookupTable(); + + if (updateLut && (updateLut?.new || updateLut.accountsToAdd.length > 4)) { + await this.updateLut(updateLut.tx, updateLut.new); + } + this.lookupTables.defaultLuts = client.defaultLookupTables(); + + await this.addSwbOraclePullTxs(items); + + for (const item of items) { + await item.initialize(); + } + + await this.addChoreTxs( + items, + updateLut && !updateLut?.new ? updateLut.tx : undefined + ); + + const result = await super.send(items).catch((e) => { + client.resetLiveTxUpdates(false); + throw e; + }); + + if (this.txRunType !== "only-simulate") { + await client.resetLiveTxUpdates(); + } + + return result; + } +} diff --git a/solauto-sdk/src/services/transactions/manager/index.ts b/solauto-sdk/src/services/transactions/manager/index.ts new file mode 100644 index 00000000..c3a4b549 --- /dev/null +++ b/solauto-sdk/src/services/transactions/manager/index.ts @@ -0,0 +1,2 @@ +export * from "./transactionsManager"; +export * from "./clientTransactionsManager"; \ No newline at end of file diff --git a/solauto-sdk/src/transactions/transactionsManager.ts b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts similarity index 52% rename from solauto-sdk/src/transactions/transactionsManager.ts rename to solauto-sdk/src/services/transactions/manager/transactionsManager.ts index d9b04545..dcbe96f4 100644 --- a/solauto-sdk/src/transactions/transactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts @@ -1,37 +1,21 @@ import bs58 from "bs58"; -import { - AddressLookupTableInput, - transactionBuilder, - TransactionBuilder, - Umi, -} from "@metaplex-foundation/umi"; -import { SolautoClient } from "../clients/solautoClient"; -import { - addTxOptimizations, - getAddressLookupInputs, - sendSingleOptimizedTransaction, -} from "../utils/solanaUtils"; -import { - ErrorsToThrow, - retryWithExponentialBackoff, -} from "../utils/generalUtils"; -import { getErrorInfo, getTransactionChores } from "./transactionUtils"; +import { TransactionExpiredBlockheightExceededError } from "@solana/web3.js"; +import { TransactionBuilder } from "@metaplex-foundation/umi"; import { PriorityFeeSetting, priorityFeeSettingValues, - TransactionItemInputs, TransactionRunType, -} from "../types"; -import { ReferralStateManager, TxHandler } from "../clients"; +} from "../../../types"; import { - PublicKey, - TransactionExpiredBlockheightExceededError, -} from "@solana/web3.js"; -import { SWITCHBOARD_PRICE_FEED_IDS } from "../constants/switchboardConstants"; -import { buildSwbSubmitResponseTx, getSwitchboardFeedData } from "../utils"; -import { sendJitoBundledTransactions } from "../utils/jitoUtils"; - -const CHORES_TX_NAME = "account chores"; + consoleLog, + ErrorsToThrow, + retryWithExponentialBackoff, + sendSingleOptimizedTransaction, + sendJitoBundledTransactions, +} from "../../../utils"; +import { TxHandler } from "../../solauto"; +import { getErrorInfo } from "../transactionUtils"; +import { LookupTables, TransactionItem, TransactionSet } from "../types"; export class TransactionTooLargeError extends Error { constructor(message: string) { @@ -41,166 +25,6 @@ export class TransactionTooLargeError extends Error { } } -class LookupTables { - cache: AddressLookupTableInput[] = []; - - constructor( - public defaultLuts: string[], - private umi: Umi - ) {} - - async getLutInputs( - additionalAddresses: string[] - ): Promise { - const addresses = [...this.defaultLuts, ...additionalAddresses]; - const currentCacheAddresses = this.cache.map((x) => x.publicKey.toString()); - - const missingAddresses = addresses.filter( - (x) => !currentCacheAddresses.includes(x) - ); - if (missingAddresses) { - const additionalInputs = await getAddressLookupInputs( - this.umi, - missingAddresses - ); - this.cache.push(...additionalInputs); - } - - return this.cache; - } - - reset() { - this.cache = this.cache.filter((x) => - this.defaultLuts.includes(x.publicKey.toString()) - ); - } -} - -export class TransactionItem { - lookupTableAddresses!: string[]; - tx?: TransactionBuilder; - public initialized: boolean = false; - - constructor( - public fetchTx: ( - attemptNum: number - ) => Promise, - public name?: string - ) {} - - async initialize() { - await this.refetch(0); - this.initialized = true; - } - - async refetch(attemptNum: number) { - const resp = await this.fetchTx(attemptNum); - this.tx = resp?.tx; - this.lookupTableAddresses = resp?.lookupTableAddresses ?? []; - } - - uniqueAccounts(): string[] { - return Array.from( - new Set( - this.tx!.getInstructions() - .map((x) => [ - x.programId.toString(), - ...x.keys.map((y) => y.pubkey.toString()), - ]) - .flat() - ) - ); - } -} - -class TransactionSet { - constructor( - private txHandler: TxHandler, - public lookupTables: LookupTables, - public items: TransactionItem[] = [] - ) {} - - async fitsWith(item: TransactionItem): Promise { - if (!item.tx) { - return true; - } - - const accountLocks = Array.from( - new Set([ - ...this.items.map((x) => x.uniqueAccounts()), - ...item.uniqueAccounts(), - ]) - ).length; - if (accountLocks > 128) { - return false; - } - - const singleTx = await this.getSingleTransaction(); - const tx = addTxOptimizations(this.txHandler.umi.identity, singleTx, 1, 1) - .add(item.tx) - .setAddressLookupTables( - await this.lookupTables.getLutInputs([ - ...this.lutAddresses(), - ...item.lookupTableAddresses, - ]) - ); - - return tx.fitsInOneTransaction(this.txHandler.umi); - } - - add(...items: TransactionItem[]) { - this.items.push( - ...items.filter((x) => x.tx && x.tx.getInstructions().length > 0) - ); - } - - prepend(...items: TransactionItem[]) { - this.items.unshift( - ...items.filter((x) => x.tx && x.tx.getInstructions().length > 0) - ); - } - - async refetchAll(attemptNum: number) { - await this.txHandler.resetLiveTxUpdates(); - for (const item of this.items) { - await item.refetch(attemptNum); - } - } - - async getSingleTransaction(): Promise { - const transactions = this.items - .filter((x) => x.tx && x.tx.getInstructions().length > 0) - .map((x) => x.tx!); - - const lutInputs = await this.lookupTables.getLutInputs(this.lutAddresses()); - return transactionBuilder() - .add(transactions) - .setAddressLookupTables(lutInputs); - } - - lutAddresses(): string[] { - return Array.from( - new Set(this.items.map((x) => x.lookupTableAddresses).flat()) - ); - } - - name(): string { - let names = this.items - .filter((x) => x.tx && Boolean(x.name)) - .map((x) => x.name!.toLowerCase()); - if (names.length > 1) { - names = names.filter((x) => x !== CHORES_TX_NAME); - } - if (names.length >= 3) { - return [names.slice(0, -1).join(", "), names[names.length - 1]].join( - ", and " - ); - } else { - return names.join(" & "); - } - } -} - export enum TransactionStatus { Skipped = "Skipped", Processing = "Processing", @@ -218,24 +42,57 @@ export type TransactionManagerStatuses = { txSig?: string; }[]; -export class TransactionsManager { - private statuses: TransactionManagerStatuses = []; - private lookupTables: LookupTables; - - constructor( - private txHandler: SolautoClient | ReferralStateManager, - private statusCallback?: (statuses: TransactionManagerStatuses) => void, - private txType?: TransactionRunType, - private priorityFeeSetting: PriorityFeeSetting = PriorityFeeSetting.Min, - private atomically: boolean = false, - private errorsToThrow?: ErrorsToThrow, - private retries: number = 4, - private retryDelay: number = 150 - ) { +interface RetryConfig { + signableRetries?: number; + totalRetries?: number; + retryDelay?: number; +} + +export interface TransactionsManagerArgs { + txHandler: T; + statusCallback?: (statuses: TransactionManagerStatuses) => void; + txRunType?: TransactionRunType; + priorityFeeSetting?: PriorityFeeSetting; + atomically?: boolean; + errorsToThrow?: ErrorsToThrow; + retryConfig?: RetryConfig; + abortController?: AbortController; +} + +export class TransactionsManager { + protected txHandler: T; + protected statusCallback?: (statuses: TransactionManagerStatuses) => void; + protected txRunType?: TransactionRunType; + protected priorityFeeSetting: PriorityFeeSetting; + protected atomically: boolean; + protected errorsToThrow?: ErrorsToThrow; + protected statuses: TransactionManagerStatuses = []; + protected lookupTables: LookupTables; + protected signableRetries: number; + protected totalRetries: number; + protected retryDelay: number; + protected abortController?: AbortController; + + updateOracleTxName = "update oracle"; + + constructor(args: TransactionsManagerArgs) { + this.txHandler = args.txHandler; + this.statusCallback = args.statusCallback; + this.txRunType = args.txRunType; + this.priorityFeeSetting = args.priorityFeeSetting ?? PriorityFeeSetting.Min; + this.atomically = args.atomically ?? true; + this.errorsToThrow = args.errorsToThrow; + this.abortController = args.abortController; + this.lookupTables = new LookupTables( this.txHandler.defaultLookupTables(), this.txHandler.umi ); + this.signableRetries = + args.retryConfig?.signableRetries ?? args.retryConfig?.totalRetries ?? 4; + this.totalRetries = + args.retryConfig?.totalRetries ?? args.retryConfig?.signableRetries ?? 4; + this.retryDelay = args.retryConfig?.retryDelay ?? 150; } private async assembleTransactionSets( @@ -244,8 +101,10 @@ export class TransactionsManager { let transactionSets: TransactionSet[] = []; this.txHandler.log(`Reassembling ${items.length} items`); - for (let i = items.length - 1; i >= 0; ) { - let item = items[i]; + const txItems = items.sort((a, b) => a.orderPrio - b.orderPrio); + + for (let i = txItems.length - 1; i >= 0; ) { + let item = txItems[i]; i--; if (!item.tx) { @@ -264,8 +123,8 @@ export class TransactionsManager { item, ]); for (let j = i; j >= 0; j--) { - if (await newSet.fitsWith(items[j])) { - newSet.prepend(items[j]); + if (await newSet.fitsWith(txItems[j])) { + newSet.prepend(txItems[j]); i--; } else { break; @@ -343,7 +202,7 @@ export class TransactionsManager { } } - private getUpdatedPriorityFeeSetting( + protected getUpdatedPriorityFeeSetting( prevError: Error | undefined, attemptNum: number ) { @@ -379,134 +238,22 @@ export class TransactionsManager { }); } - private async updateLut(tx: TransactionBuilder, newLut: boolean) { - const updateLutTxName = `${newLut ? "create" : "update"} lookup table`; - await retryWithExponentialBackoff( - async (attemptNum, prevError) => - await this.sendTransaction( - tx, - updateLutTxName, - attemptNum, - this.getUpdatedPriorityFeeSetting(prevError, attemptNum), - "skip-simulation" - ), - 3, - 150, - this.errorsToThrow - ); - } - - public async clientSend( - transactions: TransactionItem[] - ): Promise { - const items = [...transactions]; - const client = this.txHandler as SolautoClient; - - const updateLookupTable = await client.updateLookupTable(); - - if ( - updateLookupTable && - (updateLookupTable?.new || updateLookupTable.accountsToAdd.length > 4) - ) { - await this.updateLut(updateLookupTable.tx, updateLookupTable.new); - } - this.lookupTables.defaultLuts = client.defaultLookupTables(); - - for (const item of items) { - await item.initialize(); - } - - const allAccounts = items.flatMap((x) => - x.tx - ?.getInstructions() - .flatMap((x) => x.keys.map((x) => x.pubkey.toString())) - ); - const swbOracle = allAccounts.find((x) => - Object.values(SWITCHBOARD_PRICE_FEED_IDS).includes(x ?? "") - ); - if (swbOracle) { - const mint = new PublicKey( - Object.keys(SWITCHBOARD_PRICE_FEED_IDS).find( - (x) => SWITCHBOARD_PRICE_FEED_IDS[x] === swbOracle - )! - ); - const stale = (await getSwitchboardFeedData(client.connection, [mint]))[0] - .stale; - - if (stale) { - this.txHandler.log("Requires oracle update..."); - const swbTx = new TransactionItem( - async () => - buildSwbSubmitResponseTx(client.connection, client.signer, mint), - "Update oracle" - ); - await swbTx.initialize(); - items.unshift(swbTx); - } - } - - let [choresBefore, choresAfter] = await getTransactionChores( - client, - transactionBuilder().add( - items - .filter((x) => x.tx && x.tx.getInstructions().length > 0) - .map((x) => x.tx!) - ) - ); - if (updateLookupTable && !updateLookupTable?.new) { - choresBefore = choresBefore.prepend(updateLookupTable.tx); - } - if (choresBefore.getInstructions().length > 0) { - const chore = new TransactionItem( - async () => ({ tx: choresBefore }), - CHORES_TX_NAME - ); - await chore.initialize(); - items.unshift(chore); - this.txHandler.log( - "Chores before: ", - choresBefore.getInstructions().length - ); - } - if (choresAfter.getInstructions().length > 0) { - const chore = new TransactionItem( - async () => ({ tx: choresAfter }), - CHORES_TX_NAME - ); - await chore.initialize(); - items.push(chore); - this.txHandler.log( - "Chores after: ", - choresAfter.getInstructions().length - ); - } - - const result = await this.send(items).catch((e) => { - client.resetLiveTxUpdates(false); - throw e; - }); - - if (this.txType !== "only-simulate") { - await client.resetLiveTxUpdates(); - } - - return result; - } - public async send( items: TransactionItem[] ): Promise { this.statuses = []; this.lookupTables.reset(); - if (!items[0].initialized) { + const itemSets = await retryWithExponentialBackoff(async () => { for (const item of items) { - await item.initialize(); + if (!item.initialized) { + await item.initialize(); + } } - } + this.txHandler.log("Transaction items:", items.length); + return await this.assembleTransactionSets(items); + }, this.totalRetries); - this.txHandler.log("Transaction items:", items.length); - const itemSets = await this.assembleTransactionSets(items); this.updateStatusForSets(itemSets, TransactionStatus.Queued, 0); this.txHandler.log("Initial item sets:", itemSets.length); @@ -523,21 +270,61 @@ export class TransactionsManager { return this.statuses; } + private shouldProceedToSend(itemSets: TransactionSet[], attemptNum: number) { + if (!itemSets) { + return false; + } + + const newItemSetNames = itemSets.flatMap((x) => + x.items.map((y) => y.name ?? "") + ); + if ( + newItemSetNames.length === 1 && + newItemSetNames[0] === this.updateOracleTxName + ) { + consoleLog("Skipping unnecessary oracle update"); + this.updateStatusForSets(itemSets, TransactionStatus.Skipped, attemptNum); + return false; + } + + return true; + } + private async processTransactionsAtomically(itemSets: TransactionSet[]) { let num = 0; let transactions: TransactionBuilder[] = []; await retryWithExponentialBackoff( async (attemptNum, prevError) => { + if ( + prevError && + this.statuses.filter((x) => x.simulationSuccessful).length > + this.signableRetries + ) { + throw prevError; + } + num = attemptNum; + this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting( + prevError, + attemptNum + ); if (attemptNum > 0) { - for (let i = 0; i < itemSets.length; i++) { - await itemSets[i].refetchAll(attemptNum); - } - itemSets = await this.assembleTransactionSets( - itemSets.flatMap((x) => x.items) + const refreshedSets = await this.refreshItemSets( + itemSets, + attemptNum, + prevError ); + if (!refreshedSets || !refreshedSets.length) { + return; + } else { + itemSets = refreshedSets; + } + } + + if (!this.shouldProceedToSend(itemSets, attemptNum)) { + return; } transactions = []; @@ -561,6 +348,12 @@ export class TransactionsManager { TransactionStatus.Processing, attemptNum ); + for (const itemSet of itemSets) { + await this.debugAccounts( + itemSet, + await itemSet.getSingleTransaction() + ); + } let txSigs: string[] | undefined; let error: Error | undefined; @@ -571,8 +364,8 @@ export class TransactionsManager { this.txHandler.signer, this.txHandler.otherSigners, transactions, - this.txType, - this.getUpdatedPriorityFeeSetting(prevError, attemptNum), + this.txRunType, + this.priorityFeeSetting, () => this.updateStatusForSets( itemSets, @@ -580,7 +373,8 @@ export class TransactionsManager { attemptNum, undefined, true - ) + ), + this.abortController ); } catch (e: any) { error = e as Error; @@ -588,8 +382,9 @@ export class TransactionsManager { if ( error || - (this.txType !== "only-simulate" && - (!Boolean(txSigs) || txSigs?.length === 0)) + (this.txRunType !== "only-simulate" && + (!Boolean(txSigs) || txSigs?.length === 0) && + !this.abortController?.signal.aborted) ) { this.updateStatusForSets( itemSets, @@ -609,7 +404,7 @@ export class TransactionsManager { txSigs ); }, - this.retries, + this.totalRetries, this.retryDelay, this.errorsToThrow ).catch((e: Error) => { @@ -621,10 +416,15 @@ export class TransactionsManager { itemSets.filter( (x) => this.statuses.find((y) => x.name() === y.name)?.simulationSuccessful - ).length === itemSets.length + ).length === itemSets.length, + this.priorityFeeSetting ); const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`; + const errorInfo = + errorDetails.errorName || errorDetails.errorInfo + ? errorString + : e.message; this.updateStatusForSets( itemSets, errorDetails.canBeIgnored @@ -633,13 +433,12 @@ export class TransactionsManager { num, undefined, undefined, - errorDetails.errorName || errorDetails.errorInfo - ? errorString - : e.message + errorInfo ); + consoleLog(errorString); if (!errorDetails.canBeIgnored) { - throw e; + throw new Error(errorInfo); } }); } @@ -649,20 +448,28 @@ export class TransactionsManager { currentIndex: number ) { let itemSet: TransactionSet | undefined = itemSets[currentIndex]; - let num = 0; - await retryWithExponentialBackoff( async (attemptNum, prevError) => { - num = attemptNum; + if ( + prevError && + this.statuses.filter((x) => x.simulationSuccessful).length > + this.signableRetries + ) { + throw prevError; + } if (currentIndex > 0 || attemptNum > 0) { - itemSet = await this.refreshItemSet( + const refreshedSets = await this.refreshItemSets( itemSets, - currentIndex, - attemptNum + attemptNum, + prevError, + currentIndex ); + itemSet = refreshedSets ? refreshedSets[0] : undefined; + } + if (!itemSet || !this.shouldProceedToSend([itemSet], attemptNum)) { + return; } - if (!itemSet) return; const tx = await itemSet.getSingleTransaction(); if (tx.getInstructions().length === 0) { @@ -673,34 +480,48 @@ export class TransactionsManager { ); } else { await this.debugAccounts(itemSet, tx); + this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting(prevError, attemptNum); await this.sendTransaction( tx, itemSet.name(), attemptNum, - this.getUpdatedPriorityFeeSetting(prevError, attemptNum) + this.priorityFeeSetting ); } }, - this.retries, + this.totalRetries, this.retryDelay, this.errorsToThrow ); } - private async refreshItemSet( + private async refreshItemSets( itemSets: TransactionSet[], - currentIndex: number, - attemptNum: number - ): Promise { - const itemSet = itemSets[currentIndex]; - await itemSet.refetchAll(attemptNum); + attemptNum: number, + prevError?: Error, + currentIndex?: number + ): Promise { + if (currentIndex !== undefined) { + const itemSet = itemSets[currentIndex]; + await itemSet.reset(); + await itemSet.refetchAll(attemptNum, prevError); + } else { + await Promise.all(itemSets.map((itemSet) => itemSet.reset())); + for (const itemSet of itemSets) { + await itemSet.refetchAll(attemptNum, prevError); + } + } - const newItemSets = await this.assembleTransactionSets([ - ...itemSet.items, - ...itemSets.slice(currentIndex + 1).flatMap((set) => set.items), - ]); + const newItemSets = await this.assembleTransactionSets( + currentIndex !== undefined + ? [ + ...itemSets[currentIndex].items, + ...itemSets.slice(currentIndex + 1).flatMap((set) => set.items), + ] + : itemSets.flatMap((set) => set.items) + ); - if (newItemSets.length > 1) { + if (currentIndex !== undefined && newItemSets.length > 1) { itemSets.splice( currentIndex, itemSets.length - currentIndex, @@ -721,15 +542,15 @@ export class TransactionsManager { ); } - return newItemSets[0]; + return newItemSets; } - private async sendTransaction( + protected async sendTransaction( tx: TransactionBuilder, txName: string, attemptNum: number, priorityFeeSetting?: PriorityFeeSetting, - txType?: TransactionRunType + txRunType?: TransactionRunType ) { this.updateStatus(txName, TransactionStatus.Processing, attemptNum); try { @@ -737,7 +558,7 @@ export class TransactionsManager { this.txHandler.umi, this.txHandler.connection, tx, - txType ?? this.txType, + txRunType ?? this.txRunType, priorityFeeSetting, () => this.updateStatus( @@ -746,7 +567,8 @@ export class TransactionsManager { attemptNum, undefined, true - ) + ), + this.abortController ); this.updateStatus( txName, @@ -760,10 +582,15 @@ export class TransactionsManager { this.txHandler.umi, [tx], e, - this.statuses.find((x) => x.name === txName)?.simulationSuccessful + this.statuses.find((x) => x.name === txName)?.simulationSuccessful, + priorityFeeSetting ); const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`; + const errorInfo = + errorDetails.errorName || errorDetails.errorInfo + ? errorString + : e.message; this.updateStatus( txName, errorDetails.canBeIgnored @@ -772,13 +599,12 @@ export class TransactionsManager { attemptNum, undefined, undefined, - errorDetails.errorName || errorDetails.errorInfo - ? errorString - : e.message + errorInfo ); + consoleLog(errorString); if (!errorDetails.canBeIgnored) { - throw e; + throw new Error(errorInfo); } } } diff --git a/solauto-sdk/src/transactions/transactionUtils.ts b/solauto-sdk/src/services/transactions/transactionUtils.ts similarity index 65% rename from solauto-sdk/src/transactions/transactionUtils.ts rename to solauto-sdk/src/services/transactions/transactionUtils.ts index 4cdf1fb1..771018cd 100644 --- a/solauto-sdk/src/transactions/transactionUtils.ts +++ b/solauto-sdk/src/services/transactions/transactionUtils.ts @@ -1,3 +1,8 @@ +import { PublicKey, SYSVAR_INSTRUCTIONS_PUBKEY } from "@solana/web3.js"; +import { + ACCOUNT_SIZE as TOKEN_ACCOUNT_SIZE, + NATIVE_MINT, +} from "@solana/spl-token"; import { Instruction, ProgramError, @@ -8,17 +13,12 @@ import { transactionBuilder, } from "@metaplex-foundation/umi"; import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; -import { PublicKey, SYSVAR_INSTRUCTIONS_PUBKEY } from "@solana/web3.js"; -import { - ACCOUNT_SIZE as TOKEN_ACCOUNT_SIZE, - NATIVE_MINT, -} from "@solana/spl-token"; import { InvalidRebalanceConditionError, - LendingPlatform, - RebalanceDirection, + PriceType, SolautoAction, SolautoRebalanceType, + SwapType, TokenType, convertReferralFees, createSolautoProgram, @@ -27,35 +27,21 @@ import { getSolautoErrorFromCode, isSolautoAction, solautoAction, -} from "../generated"; -import { SolautoClient } from "../clients/solautoClient"; +} from "../../generated"; +import { SolautoClient, ReferralStateManager } from "../solauto"; import { closeTokenAccountUmiIx, createAssociatedTokenAccountUmiIx, systemTransferUmiIx, -} from "../utils/solanaUtils"; -import { getJupSwapTransaction } from "../utils/jupiterUtils"; -import { - getFlashLoanDetails, - getJupSwapRebalanceDetails, - getRebalanceValues, -} from "../utils/solauto/rebalanceUtils"; -import { consoleLog, - currentUnixSeconds, getSolanaAccountCreated, rpcAccountCreated, -} from "../utils/generalUtils"; -import { SolautoMarginfiClient } from "../clients/solautoMarginfiClient"; -import { - getMaxLiqUtilizationRateBps, uint8ArrayToBigInt, -} from "../utils/numberUtils"; -import { - eligibleForRebalance, - positionStateWithLatestPrices, -} from "../utils/solauto/generalUtils"; -import { getTokenAccount, getTokenAccountData } from "../utils/accountUtils"; + getTokenAccount, + getTokenAccountData, + isMarginfiClient, + addTxOptimizations, +} from "../../utils"; import { createMarginfiProgram, getLendingAccountBorrowInstructionDataSerializer, @@ -63,18 +49,19 @@ import { getLendingAccountRepayInstructionDataSerializer, getLendingAccountWithdrawInstructionDataSerializer, getMarginfiErrorFromCode, - MARGINFI_PROGRAM_ID, -} from "../marginfi-sdk"; -import { ReferralStateManager } from "../clients"; +} from "../../marginfi-sdk"; +import { JupSwapManager } from "../swap"; import { createJupiterProgram, getJupiterErrorFromCode, JUPITER_PROGRAM_ID, -} from "../jupiter-sdk"; -import { PRICES } from "../constants"; -import { TransactionItemInputs } from "../types"; -import { safeGetPrice } from "../utils"; -import { BundleSimulationError } from "../types/transactions"; +} from "../../jupiter-sdk"; +import { + TransactionItemInputs, + BundleSimulationError, + PriorityFeeSetting, +} from "../../types"; +import { isMarginfiProgram } from "../../constants"; interface wSolTokenUsage { wSolTokenAccount: PublicKey; @@ -90,8 +77,8 @@ function getWSolUsage( }, cancellingDcaIn?: TokenType ): wSolTokenUsage | undefined { - const supplyIsWsol = client.supplyMint.equals(NATIVE_MINT); - const debtIsWsol = client.debtMint.equals(NATIVE_MINT); + const supplyIsWsol = client.pos.supplyMint.equals(NATIVE_MINT); + const debtIsWsol = client.pos.debtMint.equals(NATIVE_MINT); if (!supplyIsWsol && !debtIsWsol) { return undefined; } @@ -154,23 +141,20 @@ async function transactionChoresBefore( ); } - if (client.selfManaged) { - if (client.solautoPositionData === null) { - chores = chores.add(client.openPosition()); - } else if ( - client.lendingPlatform === LendingPlatform.Marginfi && - !(await getSolanaAccountCreated( - client.umi, - (client as SolautoMarginfiClient).marginfiAccountPk - )) + if (client.pos.selfManaged) { + if ( + isMarginfiClient(client) && + !(await getSolanaAccountCreated(client.umi, client.marginfiAccountPk)) ) { chores = chores.add( - (client as SolautoMarginfiClient).marginfiAccountInitialize( - (client as SolautoMarginfiClient).marginfiAccount as Signer - ) + client.marginfiAccountInitialize(client.marginfiAccount as Signer) ); } - // TODO: PF + // TODO: LP + + if (!client.pos.exists) { + chores = chores.add(client.openPositionIx()); + } } const wSolUsage = getWSolUsage( @@ -239,18 +223,19 @@ async function transactionChoresBefore( const tokenAccount = isSolautoAction("Withdraw", solautoAction) ? client.signerSupplyTa : client.signerDebtTa; + if (accountsGettingCreated.includes(tokenAccount.toString())) { continue; } - if (!getSolanaAccountCreated(client.umi, tokenAccount)) { + if (!(await getSolanaAccountCreated(client.umi, tokenAccount))) { chores = chores.add( createAssociatedTokenAccountUmiIx( client.signer, toWeb3JsPublicKey(client.signer.publicKey), isSolautoAction("Withdraw", solautoAction) - ? client.supplyMint - : client.debtMint + ? client.pos.supplyMint + : client.pos.debtMint ) ); accountsGettingCreated.push(tokenAccount.toString()); @@ -279,11 +264,6 @@ export async function rebalanceChoresBefore( client.referredBySupplyTa() && usesAccount(client.referredBySupplyTa()!); const checkReferralDebtTa = client.referredByDebtTa() && usesAccount(client.referredByDebtTa()!); - const checkIntermediaryMfiAccount = - client.lendingPlatform === LendingPlatform.Marginfi && - usesAccount( - (client as SolautoMarginfiClient).intermediaryMarginfiAccountPk - ); const checkSignerSupplyTa = usesAccount(client.signerSupplyTa); const checkSignerDebtTa = usesAccount(client.signerDebtTa); @@ -292,24 +272,14 @@ export async function rebalanceChoresBefore( checkReferralSupplyTa ? client.referredBySupplyTa() : PublicKey.default, ], ...[checkReferralDebtTa ? client.referredByDebtTa() : PublicKey.default], - ...[ - checkIntermediaryMfiAccount - ? (client as SolautoMarginfiClient).intermediaryMarginfiAccountPk - : PublicKey.default, - ], ...[checkSignerSupplyTa ? client.signerSupplyTa : PublicKey.default], ...[checkSignerDebtTa ? client.signerDebtTa : PublicKey.default], ]; - const [ - referredBySupplyTa, - referredByDebtTa, - intermediaryMarginfiAccount, - signerSupplyTa, - signerDebtTa, - ] = await client.umi.rpc.getAccounts( - accountsNeeded.map((x) => publicKey(x ?? PublicKey.default)) - ); + const [referredBySupplyTa, referredByDebtTa, signerSupplyTa, signerDebtTa] = + await client.umi.rpc.getAccounts( + accountsNeeded.map((x) => publicKey(x ?? PublicKey.default)) + ); let chores = transactionBuilder(); @@ -319,7 +289,7 @@ export async function rebalanceChoresBefore( createAssociatedTokenAccountUmiIx( client.signer, client.referredByState!, - client.supplyMint + client.pos.supplyMint ) ); } @@ -330,19 +300,7 @@ export async function rebalanceChoresBefore( createAssociatedTokenAccountUmiIx( client.signer, client.referredByState!, - client.debtMint - ) - ); - } - - if ( - checkIntermediaryMfiAccount && - !rpcAccountCreated(intermediaryMarginfiAccount) - ) { - client.log("Creating intermediary marginfi account"); - chores = chores.add( - (client as SolautoMarginfiClient).marginfiAccountInitialize( - (client as SolautoMarginfiClient).intermediaryMarginfiAccountSigner! + client.pos.debtMint ) ); } @@ -357,7 +315,7 @@ export async function rebalanceChoresBefore( createAssociatedTokenAccountUmiIx( client.signer, toWeb3JsPublicKey(client.signer.publicKey), - client.supplyMint + client.pos.supplyMint ) ); accountsGettingCreated.push(signerSupplyTa.publicKey.toString()); @@ -373,7 +331,7 @@ export async function rebalanceChoresBefore( createAssociatedTokenAccountUmiIx( client.signer, toWeb3JsPublicKey(client.signer.publicKey), - client.debtMint + client.pos.debtMint ) ); accountsGettingCreated.push(signerDebtTa.publicKey.toString()); @@ -420,9 +378,12 @@ function getRebalanceInstructions( try { const serializer = getMarginfiRebalanceInstructionDataSerializer(); const discriminator = serializer.serialize({ - targetInAmountBaseUnit: 0, - rebalanceType: SolautoRebalanceType.None, + swapInAmountBaseUnit: 0, + rebalanceType: SolautoRebalanceType.Regular, + swapType: SwapType.ExactIn, targetLiqUtilizationRateBps: 0, + priceType: PriceType.Realtime, + flashLoanFeeBps: null, })[0]; const [data, _] = serializer.deserialize(x.data); if (data.discriminator === discriminator) { @@ -455,13 +416,14 @@ function getSolautoActions(umi: Umi, tx: TransactionBuilder): SolautoAction[] { } catch {} } - if (x.programId === MARGINFI_PROGRAM_ID) { + if (isMarginfiProgram(toWeb3JsPublicKey(x.programId))) { try { const serializer = getLendingAccountDepositInstructionDataSerializer(); const discriminator = uint8ArrayToBigInt( serializer .serialize({ amount: 0, + depositUpToLimit: true, }) .slice(0, 8) ); @@ -561,7 +523,7 @@ function getSolautoActions(umi: Umi, tx: TransactionBuilder): SolautoAction[] { } catch {} } - // TODO: PF + // TODO: LP }); return solautoActions; @@ -582,7 +544,7 @@ export async function getTransactionChores( client, accountsGettingCreated, solautoActions, - client.livePositionUpdates.dcaInBalance + client.contextUpdates.dcaInBalance ), await rebalanceChoresBefore(client, tx, accountsGettingCreated), ]); @@ -591,206 +553,13 @@ export async function getTransactionChores( transactionChoresAfter( client, solautoActions, - client.livePositionUpdates.cancellingDca + client.contextUpdates.cancellingDca ) ); return [choresBefore, choresAfter]; } -export async function requiresRefreshBeforeRebalance(client: SolautoClient) { - const neverRefreshedBefore = - client.solautoPositionData && - client.solautoPositionData.state.supply.amountCanBeUsed.baseUnit === - BigInt(0) && - client.solautoPositionData.state.debt.amountCanBeUsed.baseUnit === - BigInt(0); - const aboveMaxLtv = - client.solautoPositionState!.liqUtilizationRateBps > - getMaxLiqUtilizationRateBps( - client.solautoPositionState!.maxLtvBps, - client.solautoPositionState!.liqThresholdBps, - 0.01 - ); - - if (aboveMaxLtv || neverRefreshedBefore) { - return true; - } else if (client.solautoPositionData && !client.selfManaged) { - if ( - client.livePositionUpdates.supplyAdjustment > BigInt(0) || - client.livePositionUpdates.debtAdjustment > BigInt(0) - ) { - return false; - } - - const oldStateWithLatestPrices = await positionStateWithLatestPrices( - client.solautoPositionData.state, - PRICES[client.supplyMint.toString()].price, - PRICES[client.debtMint.toString()].price - ); - const utilizationRateDiff = Math.abs( - (client.solautoPositionState?.liqUtilizationRateBps ?? 0) - - oldStateWithLatestPrices.liqUtilizationRateBps - ); - - client.log("Liq utilization rate diff:", utilizationRateDiff); - if ( - client.livePositionUpdates.supplyAdjustment === BigInt(0) && - client.livePositionUpdates.debtAdjustment === BigInt(0) && - utilizationRateDiff >= 10 - ) { - client.log( - "Choosing to refresh before rebalance. Utilization rate diff:", - utilizationRateDiff - ); - return true; - } - } - - // Rebalance ix will already refresh internally if position is self managed, has automation to update, or position state last updated >= 1 day ago - - client.log("Not refreshing before rebalance"); - return false; -} - -export async function buildSolautoRebalanceTransaction( - client: SolautoClient, - targetLiqUtilizationRateBps?: number, - attemptNum?: number -): Promise { - client.solautoPositionState = await client.getFreshPositionState(); - const supplyPrice = safeGetPrice(client.supplyMint) ?? 0; - const debtPrice = safeGetPrice(client.debtMint) ?? 0; - - if ( - (client.solautoPositionState?.supply.amountUsed.baseUnit === BigInt(0) && - client.livePositionUpdates.supplyAdjustment === BigInt(0)) || - (targetLiqUtilizationRateBps === undefined && - !eligibleForRebalance( - client.solautoPositionState!, - client.solautoPositionSettings(), - client.solautoPositionActiveDca(), - currentUnixSeconds(), - supplyPrice, - debtPrice - )) - ) { - client.log("Not eligible for a rebalance"); - return undefined; - } - - const values = getRebalanceValues( - client.solautoPositionState!, - client.solautoPositionSettings(), - client.solautoPositionActiveDca(), - currentUnixSeconds(), - supplyPrice, - debtPrice, - targetLiqUtilizationRateBps - ); - client.log("Rebalance values: ", values); - - const swapDetails = getJupSwapRebalanceDetails( - client, - values, - targetLiqUtilizationRateBps, - attemptNum - ); - const { - jupQuote, - lookupTableAddresses, - setupInstructions, - tokenLedgerIx, - swapIx, - } = await getJupSwapTransaction(client.signer, swapDetails, attemptNum); - const flashLoan = getFlashLoanDetails(client, values, jupQuote); - - let tx = transactionBuilder(); - - if (await requiresRefreshBeforeRebalance(client)) { - tx = tx.add(client.refresh()); - } - - if (flashLoan) { - client.log("Flash loan details: ", flashLoan); - const addFirstRebalance = values.amountUsdToDcaIn > 0; - - const rebalanceThenSwap = - values.rebalanceDirection === RebalanceDirection.Repay && - flashLoan.useDebtLiquidity; - - const rebalanceType = addFirstRebalance - ? SolautoRebalanceType.DoubleRebalanceWithFL - : rebalanceThenSwap - ? SolautoRebalanceType.FLRebalanceThenSwap - : SolautoRebalanceType.FLSwapThenRebalance; - - client.log("Rebalance type:", rebalanceType); - const firstRebalance = client.rebalance( - "A", - jupQuote, - rebalanceType, - values, - flashLoan, - targetLiqUtilizationRateBps - ); - const lastRebalance = client.rebalance( - "B", - jupQuote, - rebalanceType, - values, - flashLoan, - targetLiqUtilizationRateBps - ); - - const flashBorrowDest = getTokenAccount( - rebalanceThenSwap - ? client.solautoPosition - : toWeb3JsPublicKey(client.signer.publicKey), - rebalanceThenSwap ? swapDetails.outputMint : swapDetails.inputMint - ); - - tx = tx.add([ - setupInstructions, - tokenLedgerIx, - client.flashBorrow(flashLoan, flashBorrowDest), - ...(addFirstRebalance ? [firstRebalance] : []), - ...(rebalanceThenSwap - ? [lastRebalance, swapIx] - : [swapIx, lastRebalance]), - client.flashRepay(flashLoan), - ]); - } else { - const rebalanceType = SolautoRebalanceType.Regular; - tx = tx.add([ - setupInstructions, - tokenLedgerIx, - client.rebalance( - "A", - jupQuote, - rebalanceType, - values, - undefined, - targetLiqUtilizationRateBps - ), - swapIx, - client.rebalance( - "B", - jupQuote, - rebalanceType, - values, - undefined, - targetLiqUtilizationRateBps - ), - ]); - } - - return { - tx, - lookupTableAddresses, - }; -} - export async function convertReferralFeesToDestination( referralManager: ReferralStateManager, tokenAccount: PublicKey, @@ -804,8 +573,9 @@ export async function convertReferralFeesToDestination( return undefined; } - const { lookupTableAddresses, setupInstructions, swapIx } = - await getJupSwapTransaction(referralManager.umi.identity, { + const jupSwapManager = new JupSwapManager(referralManager.umi.identity); + const { lookupTableAddresses, setupIx, swapIx, cleanupIx } = + await jupSwapManager.getJupSwapTxData({ amount: tokenAccountData.amount, destinationWallet: referralManager.referralState, inputMint: tokenAccountData.mint, @@ -815,7 +585,7 @@ export async function convertReferralFeesToDestination( }); let tx = transactionBuilder() - .add(setupInstructions) + .add(setupIx) .add( convertReferralFees(referralManager.umi, { signer: referralManager.signer, @@ -839,33 +609,50 @@ export function getErrorInfo( umi: Umi, txs: TransactionBuilder[], error: Error, - simulationSuccessful?: boolean + simulationSuccessful?: boolean, + priorityFeeSetting?: PriorityFeeSetting ) { let canBeIgnored = false; let errorName: string | undefined = undefined; let errorInfo: string | undefined = undefined; - let errTxIdx: number | undefined; + let errTxIdx: number = 0; let errIxIdx: number | undefined; let errCode: number | undefined; let errName: string | undefined; - const computeIxs = simulationSuccessful ? 2 : 1; // sub ixs to account for computeUnitLimit and computeUnitPrice that get added + // sub ixs to account for computeUnitLimit and computeUnitPrice that get added + const getComputeIxs = (txIdx: number) => + addTxOptimizations( + umi, + txs[txIdx], + simulationSuccessful && usePriorityFee(priorityFeeSetting) + ? 1 + : undefined, + 1 + ).getInstructions().length - + txs[txIdx].getInstructions().length - + (txs.length > 1 && txIdx === 0 ? 1 : 0); // Account for jito tip IX try { - if (typeof error === "object" && (error as any)["InstructionError"]) { + if (error instanceof BundleSimulationError) { + errTxIdx = error.details.transactionIdx; + errIxIdx = + error.details.instructionIdx - + getComputeIxs(error.details.transactionIdx); + errCode = error.details.errorCode; + } else if ( + typeof error === "object" && + (error as any)["InstructionError"] + ) { const err = (error as any)["InstructionError"]; - errIxIdx = err[0] - computeIxs; + errIxIdx = err[0] - getComputeIxs(0); errCode = typeof err[1] === "object" && "Custom" in err[1] ? err[1]["Custom"] : undefined; errName = errCode === undefined ? (err[1] as string) : undefined; - } else if (error instanceof BundleSimulationError) { - errTxIdx = error.details.transactionIdx; - errIxIdx = error.details.instructionIdx - computeIxs; - errCode = error.details.errorCode; } consoleLog( @@ -900,7 +687,7 @@ export function getErrorInfo( ); if ( - errCode && + errCode !== undefined && errIx?.programId.toString() === umi.programs.get("solauto").publicKey.toString() ) { @@ -912,10 +699,17 @@ export function getErrorInfo( ) { canBeIgnored = true; } - } else if (errCode && errIx?.programId === MARGINFI_PROGRAM_ID) { + } else if ( + errCode !== undefined && + errIx && + isMarginfiProgram(toWeb3JsPublicKey(errIx.programId)) + ) { programName = "Marginfi"; programError = marginfiError; - } else if (errCode && errIx?.programId === JUPITER_PROGRAM_ID) { + } else if ( + errCode !== undefined && + errIx?.programId === JUPITER_PROGRAM_ID + ) { programName = "Jupiter"; programError = getJupiterErrorFromCode(errCode, createJupiterProgram()); } @@ -931,9 +725,19 @@ export function getErrorInfo( consoleLog(e); } - return { - errorName: errorName, - errorInfo: errorInfo, + const errData = { + errorName, + errorInfo, canBeIgnored, }; + consoleLog(errData); + + return errData; +} + +export function usePriorityFee(priorityFeeSetting?: PriorityFeeSetting) { + return ( + priorityFeeSetting !== undefined && + priorityFeeSetting !== PriorityFeeSetting.None + ); } diff --git a/solauto-sdk/src/services/transactions/types/index.ts b/solauto-sdk/src/services/transactions/types/index.ts new file mode 100644 index 00000000..1026d52d --- /dev/null +++ b/solauto-sdk/src/services/transactions/types/index.ts @@ -0,0 +1,3 @@ +export * from "./lookupTables"; +export * from "./transactionItem"; +export * from "./transactionSet"; \ No newline at end of file diff --git a/solauto-sdk/src/services/transactions/types/lookupTables.ts b/solauto-sdk/src/services/transactions/types/lookupTables.ts new file mode 100644 index 00000000..aa6481da --- /dev/null +++ b/solauto-sdk/src/services/transactions/types/lookupTables.ts @@ -0,0 +1,37 @@ +import { AddressLookupTableInput, Umi } from "@metaplex-foundation/umi"; +import { getAddressLookupInputs } from "../../../utils"; + +export class LookupTables { + cache: AddressLookupTableInput[] = []; + + constructor( + public defaultLuts: string[], + private umi: Umi + ) {} + + async getLutInputs( + additionalAddresses?: string[] + ): Promise { + const addresses = [...this.defaultLuts, ...(additionalAddresses ?? [])]; + const currentCacheAddresses = this.cache.map((x) => x.publicKey.toString()); + + const missingAddresses = addresses.filter( + (x) => !currentCacheAddresses.includes(x) + ); + if (missingAddresses) { + const additionalInputs = await getAddressLookupInputs( + this.umi, + missingAddresses + ); + this.cache.push(...additionalInputs); + } + + return this.cache; + } + + reset() { + this.cache = this.cache.filter((x) => + this.defaultLuts.includes(x.publicKey.toString()) + ); + } +} diff --git a/solauto-sdk/src/services/transactions/types/transactionItem.ts b/solauto-sdk/src/services/transactions/types/transactionItem.ts new file mode 100644 index 00000000..362037a8 --- /dev/null +++ b/solauto-sdk/src/services/transactions/types/transactionItem.ts @@ -0,0 +1,43 @@ +import { TransactionBuilder } from "@metaplex-foundation/umi"; +import { TransactionItemInputs } from "../../../types"; + +export class TransactionItem { + lookupTableAddresses!: string[]; + tx?: TransactionBuilder; + initialized: boolean = false; + orderPrio: number = 0; + + constructor( + public fetchTx: ( + attemptNum: number, + prevError?: Error + ) => Promise, + public name?: string, + public oracleInteractor?: boolean + ) {} + + async initialize() { + await this.refetch(0); + this.initialized = true; + } + + async refetch(attemptNum: number, prevError?: Error) { + const resp = await this.fetchTx(attemptNum, prevError); + this.tx = resp?.tx; + this.lookupTableAddresses = resp?.lookupTableAddresses ?? []; + this.orderPrio = resp?.orderPrio ?? 0; + } + + uniqueAccounts(): string[] { + return Array.from( + new Set( + this.tx!.getInstructions() + .map((x) => [ + x.programId.toString(), + ...x.keys.map((y) => y.pubkey.toString()), + ]) + .flat() + ) + ); + } +} diff --git a/solauto-sdk/src/services/transactions/types/transactionSet.ts b/solauto-sdk/src/services/transactions/types/transactionSet.ts new file mode 100644 index 00000000..ba1ec0ce --- /dev/null +++ b/solauto-sdk/src/services/transactions/types/transactionSet.ts @@ -0,0 +1,114 @@ +import { + AddressLookupTableInput, + transactionBuilder, + TransactionBuilder, +} from "@metaplex-foundation/umi"; +import { TxHandler } from "../../solauto"; +import { LookupTables } from "./lookupTables"; +import { TransactionItem } from "./transactionItem"; +import { addTxOptimizations } from "../../../utils"; +import { CHORES_TX_NAME } from "../../../constants"; + +const MAX_SUPPORTED_ACCOUNT_LOCKS = 64; + +export class TransactionSet { + constructor( + private txHandler: TxHandler, + public lookupTables: LookupTables, + public items: TransactionItem[] = [] + ) {} + + async lutInputs(): Promise { + const lutInputs = await this.lookupTables.getLutInputs(this.lutAddresses()); + + return lutInputs.filter( + (lut, index, self) => + index === + self.findIndex( + (item) => item.publicKey.toString() === lut.publicKey.toString() + ) + ); + } + + async fitsWith(item: TransactionItem): Promise { + if (!item.tx) { + return true; + } + + const accountLocks = Array.from( + new Set([ + ...this.items.map((x) => x.uniqueAccounts()), + ...item.uniqueAccounts(), + ]) + ).length; + if (accountLocks > MAX_SUPPORTED_ACCOUNT_LOCKS) { + return false; + } + + const singleTx = await this.getSingleTransaction(); + const tx = addTxOptimizations(this.txHandler.umi, singleTx, 1, 1) + .add(item.tx) + .setAddressLookupTables( + await this.lookupTables.getLutInputs([ + ...this.lutAddresses(), + ...item.lookupTableAddresses, + ]) + ); + + return tx.fitsInOneTransaction(this.txHandler.umi); + } + + add(...items: TransactionItem[]) { + this.items.push( + ...items.filter((x) => x.tx && x.tx.getInstructions().length > 0) + ); + } + + prepend(...items: TransactionItem[]) { + this.items.unshift( + ...items.filter((x) => x.tx && x.tx.getInstructions().length > 0) + ); + } + + async reset() { + await this.txHandler.resetLiveTxUpdates(); + } + + async refetchAll(attemptNum: number, prevError?: Error) { + for (const item of this.items) { + await item.refetch(attemptNum, prevError); + } + } + + async getSingleTransaction(): Promise { + const transactions = this.items + .filter((x) => x.tx && x.tx.getInstructions().length > 0) + .map((x) => x.tx!); + + return transactionBuilder() + .add(transactions) + .setAddressLookupTables(await this.lutInputs()); + } + + lutAddresses(): string[] { + return Array.from( + new Set(this.items.map((x) => x.lookupTableAddresses).flat()) + ); + } + + name(): string { + let names = this.items + .filter((x) => x.tx && Boolean(x.name)) + .map((x) => x.name!.toLowerCase()); + if (names.length > 1) { + names = names.filter((x) => x !== CHORES_TX_NAME); + } + if (names.length >= 3) { + return [names.slice(0, -1).join(", "), names[names.length - 1]].join( + ", and " + ); + } else { + return names.join(" & "); + } + } +} diff --git a/solauto-sdk/src/solautoPosition/index.ts b/solauto-sdk/src/solautoPosition/index.ts new file mode 100644 index 00000000..7767fc41 --- /dev/null +++ b/solauto-sdk/src/solautoPosition/index.ts @@ -0,0 +1,3 @@ +export * from "./solautoPositionEx"; +export * from "./marginfiSolautoPositionEx"; +export * from "./positionUtils"; diff --git a/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts b/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts new file mode 100644 index 00000000..81a925dc --- /dev/null +++ b/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts @@ -0,0 +1,171 @@ +import { PublicKey } from "@solana/web3.js"; +import { Bank, PriceBias, safeFetchAllBank } from "../marginfi-sdk"; +import { publicKey } from "@metaplex-foundation/umi"; +import { + calcMarginfiMaxLtvAndLiqThresholdBps, + fetchTokenPrices, + fromBaseUnit, + getBankLiquidityAvailableBaseUnit, + getBankLiquidityUsedBaseUnit, + getMarginfiAccountPositionState, + getMarginfiPriceOracle, + safeGetPrice, + tokenInfo, + toRoundedUsdValue, + validPubkey, +} from "../utils"; +import { getMarginfiAccounts } from "../constants"; +import { SolautoPositionEx } from "./solautoPositionEx"; +import { LendingPlatform, PriceType } from "../generated"; + +export class MarginfiSolautoPositionEx extends SolautoPositionEx { + lendingPlatform = LendingPlatform.Marginfi; + maxLtvPriceType = PriceType.Ema; + + public supplyBank: Bank | null = null; + public debtBank: Bank | null = null; + + supplyPrice(priceType?: PriceType): number | undefined { + return ( + this._supplyPrice ?? + safeGetPrice(this.supplyMint, priceType, PriceBias.Low) + ); + } + + debtPrice(priceType?: PriceType): number | undefined { + return ( + this._debtPrice ?? safeGetPrice(this.debtMint, priceType, PriceBias.High) + ); + } + + private getBankAccounts(mint: PublicKey) { + const group = this.lpPoolAccount.toString(); + const bankAccounts = getMarginfiAccounts(this.lpEnv).bankAccounts; + return bankAccounts[group][mint.toString()]; + } + + async getBanks(): Promise { + if (!this.supplyBank || !this.debtBank) { + [this.supplyBank, this.debtBank] = await safeFetchAllBank(this.umi, [ + publicKey(this.lpSupplyAccount), + publicKey(this.lpDebtAccount), + ]); + } + + return [this.supplyBank!, this.debtBank!]; + } + + async priceOracles(): Promise { + const [supplyBank, debtBank] = await this.getBanks(); + + return await Promise.all([ + getMarginfiPriceOracle(this.umi, { data: supplyBank }), + getMarginfiPriceOracle(this.umi, { data: debtBank }), + ]); + } + + async maxLtvAndLiqThresholdBps(): Promise<[number, number]> { + const [supplyBank, debtBank] = await this.getBanks(); + + const [supplyPrice] = await fetchTokenPrices([this.supplyMint]); + const [maxLtvBps, liqThresholdBps] = calcMarginfiMaxLtvAndLiqThresholdBps( + supplyBank, + debtBank, + supplyPrice + ); + + return [maxLtvBps, liqThresholdBps]; + } + + private getUpToDateLiquidityAvailable( + banks: Bank[], + mint: PublicKey, + availableToDeposit: boolean + ) { + const bank = banks.find( + (x) => + x.group.toString() === this.lpPoolAccount.toString() && + x.mint.toString() === mint.toString() + ); + + const baseUnit = getBankLiquidityAvailableBaseUnit( + bank!, + availableToDeposit + ); + return { + baseUnit: baseUnit, + baseAmountUsdValue: toRoundedUsdValue( + fromBaseUnit(baseUnit, tokenInfo(mint).decimals) * + (safeGetPrice(mint) ?? 0) + ), + }; + } + + updateSupplyLiquidityDepositable(banks: Bank[]) { + this._data.state.supply.amountCanBeUsed = + this.getUpToDateLiquidityAvailable(banks, this.supplyMint, true); + } + + updateDebtLiquidityAvailable(banks: Bank[]) { + this._data.state.debt.amountCanBeUsed = this.getUpToDateLiquidityAvailable( + banks, + this.debtMint, + false + ); + } + + get lpSupplyAccount() { + return new PublicKey(this.getBankAccounts(this.supplyMint).bank); + } + + get lpDebtAccount() { + return new PublicKey(this.getBankAccounts(this.debtMint).bank); + } + + get supplyLiquidityAvailable(): number { + return fromBaseUnit( + getBankLiquidityAvailableBaseUnit(this.supplyBank, false), + this.supplyMintInfo.decimals + ); + } + + get supplyUsdWithdrawable(): number { + const deposits = fromBaseUnit( + getBankLiquidityUsedBaseUnit(this.supplyBank, true), + this.supplyMintInfo.decimals + ); + const borrows = fromBaseUnit( + getBankLiquidityUsedBaseUnit(this.supplyBank, false), + this.supplyMintInfo.decimals + ); + return Math.min((deposits - borrows), this.totalSupply) * this.supplyPrice()!; + } + + async refreshPositionState(priceType?: PriceType): Promise { + if (!this.canRefreshPositionState()) { + return; + } + + const useDesignatedMint = + !this.exists || + !this.selfManaged || + (this.selfManaged && !validPubkey(this.lpUserAccount)); + + const resp = await getMarginfiAccountPositionState( + this.umi, + { pk: this.lpUserAccount }, + this._lpPoolAccount, + useDesignatedMint ? { mint: this.supplyMint } : undefined, + useDesignatedMint ? { mint: this.debtMint } : undefined, + this.contextUpdates, + priceType + ); + + if (resp) { + this.supplyBank = resp.supplyBank; + this.debtBank = resp.debtBank; + this._lpPoolAccount = resp.marginfiGroup; + this._data.state = resp.state; + } + } +} diff --git a/solauto-sdk/src/solautoPosition/positionUtils.ts b/solauto-sdk/src/solautoPosition/positionUtils.ts new file mode 100644 index 00000000..ef01da5d --- /dev/null +++ b/solauto-sdk/src/solautoPosition/positionUtils.ts @@ -0,0 +1,206 @@ +import { PublicKey } from "@solana/web3.js"; +import { Umi } from "@metaplex-foundation/umi"; +import { + fromWeb3JsPublicKey, + toWeb3JsPublicKey, +} from "@metaplex-foundation/umi-web3js-adapters"; +import { + LendingPlatform, + PositionState, + safeFetchAllSolautoPosition, + safeFetchSolautoPosition, + SolautoSettingsParameters, + SolautoSettingsParametersInpArgs, +} from "../generated"; +import { + ContextUpdates, + currentUnixSeconds, + getBatches, + getLiqUtilzationRateBps, + getSolautoPositionAccount, + retryWithExponentialBackoff, + toBaseUnit, + tokenInfo, + toRoundedUsdValue, +} from "../utils"; +import { + PositionCustomArgs, + PositionExArgs, + SolautoPositionEx, +} from "./solautoPositionEx"; +import { MarginfiSolautoPositionEx } from "./marginfiSolautoPositionEx"; + +export function createSolautoSettings( + settings: SolautoSettingsParametersInpArgs +): SolautoSettingsParameters { + return { + boostGap: settings.boostGap, + boostToBps: settings.boostToBps, + repayGap: settings.repayGap, + repayToBps: settings.repayToBps, + padding: [], + }; +} + +export async function getPositionExBulk( + umi: Umi, + publicKeys: PublicKey[] +): Promise { + const batches = getBatches(publicKeys, 50); + + const data = ( + await Promise.all( + batches.map(async (pubkeys) => { + return retryWithExponentialBackoff( + async () => + await safeFetchAllSolautoPosition( + umi, + pubkeys.map((x) => fromWeb3JsPublicKey(x)) + ) + ); + }) + ) + ).flat(); + + return data.map((x) => { + switch (x.position.lendingPlatform) { + case LendingPlatform.Marginfi: + return new MarginfiSolautoPositionEx({ + umi, + publicKey: toWeb3JsPublicKey(x.publicKey), + data: x, + }); + // TODO: LP + } + }); +} + +export async function getOrCreatePositionEx( + umi: Umi, + authority: PublicKey, + positionId: number, + programId: PublicKey, + customArgs?: PositionCustomArgs, + contextUpdates?: ContextUpdates +): Promise { + const publicKey = getSolautoPositionAccount(authority, positionId, programId); + const data = await retryWithExponentialBackoff( + async () => + await safeFetchSolautoPosition(umi, fromWeb3JsPublicKey(publicKey)) + ); + + const lendingPlatform = data + ? data.position.lendingPlatform + : customArgs!.lendingPlatform; + + const args: PositionExArgs = { + umi, + publicKey, + authority, + positionId, + programId, + data: data ?? { + state: createFakePositionState( + { + mint: customArgs?.supplyMint ?? PublicKey.default, + }, + { mint: customArgs?.debtMint ?? PublicKey.default }, + 0, + 0 + ), + }, + customArgs, + contextUpdates, + }; + + let position: SolautoPositionEx; + switch (lendingPlatform) { + case LendingPlatform.Marginfi: + position = new MarginfiSolautoPositionEx(args); + // TODO: LP + } + + if (position.selfManaged) { + await position.refreshPositionState(); + } + + return position; +} + +interface AssetProps { + mint: PublicKey; + price?: number; + amountUsed?: number; + amountCanBeUsed?: number; +} + +export function createFakePositionState( + supply: AssetProps, + debt: AssetProps, + maxLtvBps: number, + liqThresholdBps: number +): PositionState { + const supplyDecimals = tokenInfo(supply.mint).decimals; + const debtDecimals = tokenInfo(debt.mint).decimals; + + const supplyUsd = (supply.amountUsed ?? 0) * (supply.price ?? 0); + const debtUsd = (debt.amountUsed ?? 0) * (debt.price ?? 0); + + return { + liqUtilizationRateBps: getLiqUtilzationRateBps( + supplyUsd, + debtUsd, + liqThresholdBps + ), + supply: { + amountUsed: { + baseUnit: toBaseUnit(supply.amountUsed ?? 0, supplyDecimals), + baseAmountUsdValue: toRoundedUsdValue(supplyUsd), + }, + amountCanBeUsed: { + baseUnit: toBaseUnit(supply.amountCanBeUsed ?? 0, supplyDecimals), + baseAmountUsdValue: toRoundedUsdValue( + (supply.amountCanBeUsed ?? 0) * (supply.price ?? 0) + ), + }, + baseAmountMarketPriceUsd: toRoundedUsdValue(supply.price ?? 0), + borrowFeeBps: 0, + decimals: supplyDecimals, + mint: fromWeb3JsPublicKey(supply.mint), + padding1: [], + padding2: [], + padding: new Uint8Array([]), + }, + debt: { + amountUsed: { + baseUnit: toBaseUnit(debt.amountUsed ?? 0, debtDecimals), + baseAmountUsdValue: toRoundedUsdValue(debtUsd), + }, + amountCanBeUsed: { + baseUnit: toBaseUnit(debt.amountCanBeUsed ?? 0, debtDecimals), + baseAmountUsdValue: toRoundedUsdValue( + (debt.amountCanBeUsed ?? 0) * (debt.price ?? 0) + ), + }, + baseAmountMarketPriceUsd: toRoundedUsdValue(debt.price ?? 0), + borrowFeeBps: 0, + decimals: debtDecimals, + mint: fromWeb3JsPublicKey(debt.mint), + padding1: [], + padding2: [], + padding: new Uint8Array([]), + }, + netWorth: { + baseUnit: supply.price + ? toBaseUnit((supplyUsd - debtUsd) / supply.price, supplyDecimals) + : BigInt(0), + baseAmountUsdValue: toRoundedUsdValue(supplyUsd - debtUsd), + }, + maxLtvBps, + liqThresholdBps, + lastRefreshed: BigInt(currentUnixSeconds()), + padding1: [], + padding2: [], + padding: [], + }; +} diff --git a/solauto-sdk/src/solautoPosition/solautoPositionEx.ts b/solauto-sdk/src/solautoPosition/solautoPositionEx.ts new file mode 100644 index 00000000..1d651ada --- /dev/null +++ b/solauto-sdk/src/solautoPosition/solautoPositionEx.ts @@ -0,0 +1,531 @@ +import { PublicKey } from "@solana/web3.js"; +import { Umi } from "@metaplex-foundation/umi"; +import { + fromWeb3JsPublicKey, + toWeb3JsPublicKey, +} from "@metaplex-foundation/umi-web3js-adapters"; +import { + fetchSolautoPosition, + LendingPlatform, + PositionState, + PriceType, + SolautoPosition, + SolautoSettingsParameters, +} from "../generated"; +import { + calcDebtUsd, + calcNetWorth, + calcSupplyUsd, + calcTotalDebt, + calcTotalSupply, + consoleLog, + ContextUpdates, + currentUnixSeconds, + debtLiquidityAvailable, + debtLiquidityUsdAvailable, + getLiqUtilzationRateBps, + getSolautoPositionAccount, + maxBoostToBps, + maxRepayFromBps, + maxRepayToBps, + positionStateWithLatestPrices, + realtimeUsdToEmaUsd, + safeGetPrice, + solautoStrategyName, + supplyLiquidityDepositable, + supplyLiquidityUsdDepositable, + toBaseUnit, + tokenInfo, + toRoundedUsdValue, +} from "../utils"; +import { ProgramEnv, RebalanceAction } from "../types"; +import { + getDebtAdjustment, + getRebalanceValues, + SolautoFeesBps, +} from "../services/rebalance"; +import { TokenInfo } from "../constants"; + +export interface PositionCustomArgs { + lendingPlatform: LendingPlatform; + supplyMint?: PublicKey; + debtMint?: PublicKey; + lpPoolAccount?: PublicKey; + lpUserAccount?: PublicKey; + lpEnv?: ProgramEnv; +} + +interface SolautoPositionExData extends Partial { + state: PositionState; +} + +export interface PositionExArgs { + umi: Umi; + publicKey?: PublicKey; + programId?: PublicKey; + authority?: PublicKey; + positionId?: number; + data: SolautoPositionExData; + customArgs?: PositionCustomArgs; + contextUpdates?: ContextUpdates; +} + +export abstract class SolautoPositionEx { + public umi!: Umi; + protected contextUpdates?: ContextUpdates; + + public publicKey!: PublicKey; + public lendingPlatform!: LendingPlatform; + public positionId!: number; + public authority!: PublicKey; + protected _lpPoolAccount?: PublicKey; + public lpUserAccount?: PublicKey = undefined; + protected lpEnv!: ProgramEnv; + private _supplyMint?: PublicKey; + private _debtMint?: PublicKey; + protected _data!: SolautoPositionExData; + + private readonly firstState!: PositionState; + + protected _supplyPrice?: number; + protected _debtPrice?: number; + + public rebalance!: PositionRebalanceHelper; + public maxLtvPriceType!: PriceType; + + constructor(args: PositionExArgs) { + this.umi = args.umi; + this.contextUpdates = args.contextUpdates; + + this.publicKey = + args.publicKey ?? + getSolautoPositionAccount( + args.authority!, + args.positionId!, + args.programId! + ); + this.positionId = args.positionId ?? args.data.positionId![0]; + this.authority = args.authority ?? toWeb3JsPublicKey(args.data.authority!); + + this._lpPoolAccount = args.customArgs?.lpPoolAccount; + this.lpUserAccount = + args.customArgs?.lpUserAccount ?? + (args.data.position + ? toWeb3JsPublicKey(args.data.position!.lpUserAccount) + : undefined); + this.lpEnv = args.customArgs?.lpEnv ?? "Prod"; + this._supplyMint = args.customArgs?.supplyMint; + this._debtMint = args.customArgs?.debtMint; + + this._data = args.data; + this.firstState = { ...args.data.state }; + + this.rebalance = new PositionRebalanceHelper(this); + } + + get exists() { + return this._data.position !== undefined; + } + + get selfManaged() { + return this.positionId === 0; + } + + get positionType() { + return this._data.positionType; + } + + get strategyName() { + return solautoStrategyName(this.supplyMint, this.debtMint); + } + + get lpPoolAccount() { + return ( + this._lpPoolAccount ?? + toWeb3JsPublicKey(this.data.position!.lpPoolAccount) + ); + } + + liqUtilizationRateBps(priceType?: PriceType): number { + return getLiqUtilzationRateBps( + this.supplyUsd(priceType), + this.debtUsd(priceType), + this.state.liqThresholdBps + ); + } + + protected get data(): SolautoPositionExData { + return this._data; + } + + get state(): PositionState { + return this.data.state; + } + + get settings(): SolautoSettingsParameters | undefined { + return this.contextUpdates?.settings ?? this.data.position?.settings; + } + + updateSettings(settings: SolautoSettingsParameters) { + this.data.position!.settings = settings; + } + + get supplyMint(): PublicKey { + return this._supplyMint ?? toWeb3JsPublicKey(this.state.supply.mint); + } + + get supplyMintInfo(): TokenInfo { + return tokenInfo(this.supplyMint); + } + + get debtMint(): PublicKey { + return this._debtMint ?? toWeb3JsPublicKey(this.state.debt.mint); + } + + get debtMintInfo(): TokenInfo { + return tokenInfo(this.debtMint); + } + + get boostToBps() { + return Math.min(this.settings?.boostToBps ?? 0, this.maxBoostToBps); + } + + get maxBoostToBps() { + return maxBoostToBps(this.state.maxLtvBps, this.state.liqThresholdBps); + } + + get boostFromBps() { + return this.boostToBps - (this.settings?.boostGap ?? 0); + } + + get repayToBps() { + return Math.min(this.settings?.repayToBps ?? 0, this.maxRepayToBps); + } + + get maxRepayToBps() { + return maxRepayToBps(this.state.maxLtvBps, this.state.liqThresholdBps); + } + + get repayFromBps() { + return Math.min( + (this.settings?.repayToBps ?? 0) + (this.settings?.repayGap ?? 0), + this.maxRepayFromBps + ); + } + + get maxRepayFromBps() { + return maxRepayFromBps(this.state.maxLtvBps, this.state.liqThresholdBps); + } + + get netWorth() { + return calcNetWorth(this.state); + } + + netWorthUsd(priceType?: PriceType) { + return this.supplyUsd(priceType) - this.debtUsd(priceType); + } + + get totalSupply() { + return calcTotalSupply(this.state); + } + + supplyUsd(priceType?: PriceType) { + const supplyPrice = this.supplyPrice(priceType); + return supplyPrice + ? calcTotalSupply(this.state) * supplyPrice + : calcSupplyUsd(this.state); + } + + supplyPrice(priceType?: PriceType) { + return this._supplyPrice ?? safeGetPrice(this.supplyMint, priceType); + } + + get totalDebt() { + return calcTotalDebt(this.state); + } + + debtUsd(priceType?: PriceType) { + const debtPrice = this.debtPrice(priceType); + return debtPrice + ? calcTotalDebt(this.state) * debtPrice + : calcDebtUsd(this.state); + } + + debtPrice(priceType?: PriceType) { + return this._debtPrice ?? safeGetPrice(this.debtMint, priceType); + } + + get supplyLiquidityDepositable() { + return supplyLiquidityDepositable(this.state); + } + + get supplyLiquidityUsdDepositable() { + return supplyLiquidityUsdDepositable(this.state); + } + + get supplyLiquidityUsdAvailable() { + return this.supplyLiquidityAvailable * (this.supplyPrice() ?? 0); + } + + get debtLiquidityAvailable() { + return debtLiquidityAvailable(this.state); + } + + get debtLiquidityUsdAvailable() { + return debtLiquidityUsdAvailable(this.state); + } + + abstract get lpSupplyAccount(): PublicKey; + abstract get lpDebtAccount(): PublicKey; + abstract get supplyLiquidityAvailable(): number; + abstract get supplyUsdWithdrawable(): number; + + abstract maxLtvAndLiqThresholdBps(): Promise<[number, number]>; + abstract priceOracles(): Promise; + + get memecoinPosition() { + return tokenInfo(this.supplyMint).isMeme || tokenInfo(this.debtMint).isMeme; + } + + eligibleForRebalance( + bpsDistanceThreshold: number = 0, + skipExtraChecks?: boolean + ): RebalanceAction | undefined { + return this.rebalance.eligibleForRebalance( + bpsDistanceThreshold, + skipExtraChecks + ); + } + + eligibleForRefresh(): boolean { + if (this.selfManaged) return false; + + return ( + currentUnixSeconds() - Number(this.state.lastRefreshed) > 60 * 60 * 24 * 7 + ); + } + + protected canRefreshPositionState() { + if ( + this.state.maxLtvBps === 0 || + currentUnixSeconds() - Number(this.state.lastRefreshed) > 5 || + this.contextUpdates?.positionUpdates() + ) { + return true; + } + } + + abstract refreshPositionState(priceType?: PriceType): Promise; + + async utilizationRateBpsDrift(priceType?: PriceType) { + const supplyPrice = this.supplyPrice(priceType) ?? 0; + const debtPrice = this.debtPrice(priceType) ?? 0; + const oldState = await positionStateWithLatestPrices( + this.firstState, + supplyPrice, + debtPrice + ); + const newState = await positionStateWithLatestPrices( + this.state, + supplyPrice, + debtPrice + ); + + return newState.liqUtilizationRateBps - oldState.liqUtilizationRateBps; + } + + updateSupply(newSupplyUsd: number, supplyPrice?: number) { + this._data.state.supply.amountUsed.baseAmountUsdValue = + toRoundedUsdValue(newSupplyUsd); + this._data.state.supply.amountUsed.baseUnit = toBaseUnit( + newSupplyUsd / (supplyPrice ?? this.supplyPrice() ?? 0), + this.supplyMintInfo.decimals + ); + } + + updateSupplyPrice(price: number) { + this._supplyPrice = price; + } + + updateDebt(newDebtUsd: number, debtPrice?: number) { + this._data.state.debt.amountUsed.baseAmountUsdValue = + toRoundedUsdValue(newDebtUsd); + this._data.state.debt.amountUsed.baseUnit = toBaseUnit( + newDebtUsd / (debtPrice ?? this.debtPrice() ?? 0), + this.debtMintInfo.decimals + ); + } + + updateDebtPrice(price: number) { + this._debtPrice = price; + } + + updateNetWorth(supplyPrice?: number) { + const netWorthUsd = this.supplyUsd() - this.debtUsd(); + this._data.state.netWorth.baseAmountUsdValue = + toRoundedUsdValue(netWorthUsd); + this._data.state.netWorth.baseUnit = toBaseUnit( + netWorthUsd / (supplyPrice ?? this.supplyPrice()!), + this.supplyMintInfo.decimals + ); + } + + updateLiqUtilizationRate( + supplyUsd?: number, + debtUsd?: number, + priceType?: PriceType + ) { + this._data.state.liqUtilizationRateBps = getLiqUtilzationRateBps( + supplyUsd ?? this.supplyUsd(priceType), + debtUsd ?? this.debtUsd(priceType), + this.state.liqThresholdBps + ); + } + + simulateRebalance( + unixTime: number, + supplyPrice: number, + debtPrice: number, + targetLiqUtilizationRateBps?: number, + withSolautoFee?: boolean + ) { + this.updateSupplyPrice(supplyPrice); + this.updateDebtPrice(debtPrice); + + this._data.state.lastRefreshed = BigInt(unixTime); + const rebalance = getRebalanceValues( + this, + PriceType.Realtime, + targetLiqUtilizationRateBps, + withSolautoFee + ? SolautoFeesBps.create( + true, + targetLiqUtilizationRateBps, + this.netWorthUsd() + ) + : undefined + ); + if (!rebalance) { + return undefined; + } + + this.updateSupply(rebalance.endResult.supplyUsd, supplyPrice); + this.updateDebt(rebalance.endResult.debtUsd, debtPrice); + this.updateNetWorth(supplyPrice); + this.updateLiqUtilizationRate( + rebalance.endResult.supplyUsd, + rebalance.endResult.debtUsd + ); + } + + async refetchPositionData() { + this._data = await fetchSolautoPosition( + this.umi, + fromWeb3JsPublicKey(this.publicKey) + ); + } +} + +class PositionRebalanceHelper { + constructor(private pos: SolautoPositionEx) {} + + private sufficientLiquidityToBoost() { + const limitsUpToDate = + this.pos.debtLiquidityUsdAvailable !== 0 || + this.pos.supplyLiquidityUsdDepositable !== 0; + + if (limitsUpToDate) { + const { debtAdjustmentUsd } = getDebtAdjustment( + this.pos.state.liqThresholdBps, + { supplyUsd: this.pos.supplyUsd(), debtUsd: this.pos.debtUsd() }, + this.pos.boostToBps, + { solauto: 50, lpBorrow: 50, flashLoan: 50 } // Overshoot fees + ); + + const sufficientLiquidity = + this.pos.debtLiquidityUsdAvailable * 0.95 > debtAdjustmentUsd && + this.pos.supplyLiquidityUsdDepositable * 0.95 > debtAdjustmentUsd; + + if (!sufficientLiquidity) { + consoleLog("Insufficient liquidity to further boost"); + } + return sufficientLiquidity; + } + + return true; + } + + validRealtimePricesBoost(debtAdjustmentUsd: number) { + const postRebalanceLiqUtilRate = getLiqUtilzationRateBps( + realtimeUsdToEmaUsd( + this.pos.supplyUsd() + debtAdjustmentUsd, + this.pos.supplyMint + ), + realtimeUsdToEmaUsd( + this.pos.debtUsd() + debtAdjustmentUsd, + this.pos.debtMint + ), + this.pos.state.liqThresholdBps + ); + + return postRebalanceLiqUtilRate <= this.pos.maxBoostToBps; + } + + private validBoostFromHere(bpsDistanceThreshold: number = 0) { + const realtimeSupplyUsd = this.pos.supplyUsd(PriceType.Realtime); + const realtimeDebtUsd = this.pos.debtUsd(PriceType.Realtime); + + if ( + (realtimeSupplyUsd === this.pos.supplyUsd(PriceType.Ema) && + realtimeDebtUsd === this.pos.debtUsd(PriceType.Ema)) || + this.pos.maxLtvPriceType !== PriceType.Ema + ) { + return true; + } + + const { debtAdjustmentUsd } = getDebtAdjustment( + this.pos.state.liqThresholdBps, + { + supplyUsd: realtimeSupplyUsd, + debtUsd: realtimeDebtUsd, + }, + this.pos.boostToBps, + { solauto: 25, lpBorrow: 0, flashLoan: 0 } // Undershoot fees + ); + + return ( + this.validRealtimePricesBoost(debtAdjustmentUsd) || + this.pos.liqUtilizationRateBps(PriceType.Ema) - this.pos.boostFromBps <= + bpsDistanceThreshold + ); + } + + eligibleForRebalance( + bpsDistanceThreshold: number, + skipExtraChecks?: boolean + ): RebalanceAction | undefined { + if (this.pos.selfManaged || !this.pos.supplyUsd()) { + return undefined; + } + + const realtimeLiqUtilRateBps = this.pos.liqUtilizationRateBps( + PriceType.Realtime + ); + + if ( + this.pos.repayFromBps - realtimeLiqUtilRateBps <= + bpsDistanceThreshold + ) { + return "repay"; + } else if ( + realtimeLiqUtilRateBps - this.pos.boostFromBps <= bpsDistanceThreshold && + (skipExtraChecks || + (this.validBoostFromHere(bpsDistanceThreshold) && + this.sufficientLiquidityToBoost())) + ) { + return "boost"; + } + + return undefined; + } +} diff --git a/solauto-sdk/src/transactions/index.ts b/solauto-sdk/src/transactions/index.ts deleted file mode 100644 index cd06c8ee..00000000 --- a/solauto-sdk/src/transactions/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './transactionsManager'; -export * from './transactionUtils'; diff --git a/solauto-sdk/src/types/accounts.ts b/solauto-sdk/src/types/accounts.ts index 35da13a3..9dfafb91 100644 --- a/solauto-sdk/src/types/accounts.ts +++ b/solauto-sdk/src/types/accounts.ts @@ -2,5 +2,4 @@ export interface MarginfiAssetAccounts { bank: string; liquidityVault: string; vaultAuthority: string; - priceOracle: string; } diff --git a/solauto-sdk/src/types/solauto.ts b/solauto-sdk/src/types/solauto.ts index 99c73caf..ca85750c 100644 --- a/solauto-sdk/src/types/solauto.ts +++ b/solauto-sdk/src/types/solauto.ts @@ -1,6 +1,14 @@ import { PublicKey } from "@solana/web3.js"; -import { LendingPlatform, PositionType } from "../generated"; +import { + LendingPlatform, + PositionType, + PriceType, + SolautoRebalanceType, + TokenType, +} from "../generated"; import { TransactionBuilder } from "@metaplex-foundation/umi"; +import { RebalanceValues } from "../services/rebalance"; +import { QuoteResponse } from "@jup-ag/api"; export interface SolautoPositionDetails { publicKey?: PublicKey; @@ -8,7 +16,7 @@ export interface SolautoPositionDetails { positionId: number; positionType: PositionType; lendingPlatform: LendingPlatform; - protocolAccount?: PublicKey; + lpUserAccount?: PublicKey; supplyMint?: PublicKey; debtMint?: PublicKey; } @@ -22,7 +30,9 @@ export enum PriorityFeeSetting { VeryHigh = "VeryHigh", } -export const priorityFeeSettingValues = Object.values(PriorityFeeSetting) as PriorityFeeSetting[]; +export const priorityFeeSettingValues = Object.values( + PriorityFeeSetting +) as PriorityFeeSetting[]; export type RebalanceAction = "boost" | "repay" | "dca"; @@ -31,4 +41,29 @@ export type TransactionRunType = "skip-simulation" | "only-simulate" | "normal"; export interface TransactionItemInputs { tx: TransactionBuilder; lookupTableAddresses?: string[]; + orderPrio?: number; } + +export interface FlashLoanRequirements { + liquiditySource: TokenType; + signerFlashLoan?: boolean; + flFeeBps?: number; +} + +export interface FlashLoanDetails extends FlashLoanRequirements { + baseUnitAmount: bigint; + mint: PublicKey; +} + +export interface RebalanceDetails { + values: RebalanceValues; + rebalanceType: SolautoRebalanceType; + flashLoan?: FlashLoanDetails; + swapQuote: QuoteResponse; + targetLiqUtilizationRateBps?: number; + priceType: PriceType; +} + +export type ProgramEnv = "Prod" | "Staging"; + +export type RoundAction = "Floor" | "Round" | "Ceil"; diff --git a/solauto-sdk/src/utils/generalUtils.ts b/solauto-sdk/src/utils/generalUtils.ts index 7f0ee68e..39b7bb1c 100644 --- a/solauto-sdk/src/utils/generalUtils.ts +++ b/solauto-sdk/src/utils/generalUtils.ts @@ -1,12 +1,62 @@ +import axios from "axios"; import { PublicKey } from "@solana/web3.js"; -import { MaybeRpcAccount, publicKey, Umi } from "@metaplex-foundation/umi"; -import { LendingPlatform } from "../generated"; +import { + MaybeRpcAccount, + publicKey, + Umi, + PublicKey as UmiPublicKey, +} from "@metaplex-foundation/umi"; +import { TOKEN_INFO, TokenInfo } from "../constants"; + +export function buildHeliusApiUrl(heliusApiKey: string) { + return `https://mainnet.helius-rpc.com/?api-key=${heliusApiKey}`; +} + +export function buildIronforgeApiUrl(ironforgeApiKey: string) { + return `https://rpc.ironforge.network/mainnet?apiKey=${ironforgeApiKey}`; +} export function consoleLog(...args: any[]): void { - if ((globalThis as any).LOCAL_TEST) { + if ((globalThis as any).SHOW_LOGS) { console.log(...args); } } + +export function tokenInfo(mint?: PublicKey): TokenInfo { + return TOKEN_INFO[mint ? mint.toString() : PublicKey.default.toString()]; +} + +export function findMintByTicker(ticker: string): PublicKey { + for (const key in TOKEN_INFO) { + const account = TOKEN_INFO[key]; + if ( + account.ticker.toString().toLowerCase() === + ticker.toString().toLowerCase() + ) { + return new PublicKey(key); + } + } + throw new Error(`Token mint not found by the ticker: ${ticker}`); +} + +export function tokenInfoByTicker(ticker: string) { + for (const key in TOKEN_INFO) { + const token = TOKEN_INFO[key]; + if (token.ticker.toLowerCase() === ticker.toLowerCase()) { + return token; + } + } + return undefined; +} + +export function getBatches(items: T[], batchSize: number): T[][] { + const batches: T[][] = []; + for (let i = 0; i < items.length; i += batchSize) { + batches.push(items.slice(i, i + batchSize)); + } + return batches; +} + export function generateRandomU8(): number { return Math.floor(Math.random() * 255 + 1); } @@ -100,12 +150,64 @@ export function retryWithExponentialBackoff( }); } -export function toEnumValue(enumObj: E, value: number): E[keyof E] | undefined { - const numericValues = Object.values(enumObj).filter(v => typeof v === "number") as number[]; +export function toEnumValue( + enumObj: E, + value: number +): E[keyof E] | undefined { + const numericValues = Object.values(enumObj).filter( + (v) => typeof v === "number" + ) as number[]; if (numericValues.includes(value)) { return value as E[keyof E]; } - + return undefined; -} \ No newline at end of file +} + +export async function customRpcCall(umi: Umi, method: string, params?: any) { + const data = ( + await axios.post( + umi.rpc.getEndpoint(), + { + jsonrpc: "2.0", + id: 1, + method, + params, + }, + { + headers: { + "Content-Type": "application/json", + }, + } + ) + ).data; + + if ("result" in data) { + return data.result; + } else { + return data; + } +} + +export function u16ToArrayBufferLE(value: number): Uint8Array { + // Create a buffer of 2 bytes + const buffer = new ArrayBuffer(2); + const dataView = new DataView(buffer); + + // Set the Uint16 value in little-endian order + dataView.setUint16(0, value, true); + + // Return the buffer + return new Uint8Array(buffer); +} + +export function validPubkey(pubkey?: PublicKey | UmiPublicKey | string) { + return Boolean(pubkey) && pubkey!.toString() !== PublicKey.default.toString(); +} + +export function createRecord(keys: string[], values: T[]): Record { + return Object.fromEntries( + zip(keys, values).map(([k, v]) => [k.toString(), v]) + ); +} diff --git a/solauto-sdk/src/utils/index.ts b/solauto-sdk/src/utils/index.ts index 52a1506e..6e70de82 100644 --- a/solauto-sdk/src/utils/index.ts +++ b/solauto-sdk/src/utils/index.ts @@ -1,9 +1,13 @@ -export * from './solauto/index'; -export * from './accountUtils'; -export * from './generalUtils'; -export * from './jupiterUtils'; -export * from './marginfiUtils'; -export * from './numberUtils'; -export * from './solanaUtils'; -export * from './priceUtils'; -export * from './switchboardUtils'; \ No newline at end of file +export * from "./accountUtils"; +export * from "./generalUtils"; +export * from "./instructionUtils"; +export * from "./jitoUtils"; +export * from "./jupiterUtils"; +export * from "./marginfi"; +export * from "./numberUtils"; +export * from "./solautoUtils"; +export * from "./solanaUtils"; +export * from "./stringUtils"; +export * from "./priceUtils"; +export * from "./pythUtils"; +export * from "./switchboardUtils"; diff --git a/solauto-sdk/src/utils/instructionUtils.ts b/solauto-sdk/src/utils/instructionUtils.ts new file mode 100644 index 00000000..3e3c7d8f --- /dev/null +++ b/solauto-sdk/src/utils/instructionUtils.ts @@ -0,0 +1,187 @@ +import { OptionOrNullable, transactionBuilder } from "@metaplex-foundation/umi"; +import { + DCASettingsInpArgs, + PositionType, + SolautoSettingsParametersInpArgs, +} from "../generated"; +import { + JupSwapManager, + RebalanceTxBuilder, + SolautoClient, + SwapInput, + TransactionItem, + TransactionTooLargeError, +} from "../services"; +import { PublicKey } from "@solana/web3.js"; +import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; + +export function openSolautoPosition( + client: SolautoClient, + settingParams: SolautoSettingsParametersInpArgs, + dca?: DCASettingsInpArgs, + positionType?: PositionType +) { + return new TransactionItem( + async () => ({ + tx: client!.openPositionIx(settingParams, dca, positionType), + }), + "open position" + ); +} + +export function closeSolautoPosition(client: SolautoClient) { + return new TransactionItem( + async () => ({ + tx: client.closePositionIx(), + }), + "close position" + ); +} + +export function updateSolautoPosition( + client: SolautoClient, + settings: OptionOrNullable, + dca: OptionOrNullable +) { + return new TransactionItem( + async () => ({ + tx: client.updatePositionIx({ + positionId: client.pos.positionId, + settings, + dca, + }), + }), + "update position" + ); +} + +export function cancelSolautoDca(client: SolautoClient) { + return new TransactionItem( + async () => ({ + tx: client.cancelDCAIx(), + }), + "cancel DCA" + ); +} + +export function deposit(client: SolautoClient, baseUnitAmount: bigint) { + return new TransactionItem( + async () => ({ + tx: client.protocolInteractionIx({ + __kind: "Deposit", + fields: [baseUnitAmount], + }), + }), + "deposit" + ); +} + +export function borrow(client: SolautoClient, baseUnitAmount: bigint) { + return new TransactionItem( + async () => ({ + tx: client.protocolInteractionIx({ + __kind: "Borrow", + fields: [baseUnitAmount], + }), + }), + "borrow", + true + ); +} + +export function withdraw(client: SolautoClient, amount: "All" | bigint) { + return new TransactionItem( + async () => ({ + tx: client.protocolInteractionIx({ + __kind: "Withdraw", + fields: [ + amount === "All" + ? { __kind: "All" } + : { __kind: "Some", fields: [amount] }, + ], + }), + }), + "withdraw", + true + ); +} + +export function repay(client: SolautoClient, amount: "All" | bigint) { + return new TransactionItem( + async () => ({ + tx: client.protocolInteractionIx({ + __kind: "Repay", + fields: [ + amount === "All" + ? { __kind: "All" } + : { __kind: "Some", fields: [amount] }, + ], + }), + }), + "repay" + ); +} + +export function rebalance( + client: SolautoClient, + targetLiqUtilizationRateBps?: number, + bpsDistanceFromRebalance?: number +) { + return new TransactionItem( + async (attemptNum, prevError) => + await new RebalanceTxBuilder( + client, + targetLiqUtilizationRateBps, + attemptNum > 2 && prevError instanceof TransactionTooLargeError, + bpsDistanceFromRebalance + ).buildRebalanceTx(attemptNum), + "rebalance", + true + ); +} + +export function swapThenDeposit( + client: SolautoClient, + depositMint: PublicKey, + depositAmountBaseUnit: bigint +) { + return [ + new TransactionItem(async () => { + const swapInput: SwapInput = { + inputMint: depositMint, + outputMint: client.pos.supplyMint, + amount: depositAmountBaseUnit, + exactIn: true, + }; + const jupSwapManager = new JupSwapManager(client.signer); + const { setupIx, swapIx, cleanupIx, lookupTableAddresses } = + await jupSwapManager.getJupSwapTxData({ + ...swapInput, + destinationWallet: toWeb3JsPublicKey(client.signer.publicKey), + wrapAndUnwrapSol: true, + }); + + client.contextUpdates.new({ + type: "jupSwap", + value: jupSwapManager.jupQuote!, + }); + + return { + tx: transactionBuilder().add([setupIx, swapIx, cleanupIx]), + lookupTableAddresses, + orderPrio: -1, + }; + }, "swap"), + new TransactionItem(async () => { + const quoteOutAmount = client.contextUpdates.jupSwap?.outAmount; + return { + tx: transactionBuilder().add( + client.protocolInteractionIx({ + __kind: "Deposit", + fields: [BigInt(Math.round(parseInt(quoteOutAmount!) * 0.995))], + }) + ), + }; + }, "deposit"), + ]; +} diff --git a/solauto-sdk/src/utils/jitoUtils.ts b/solauto-sdk/src/utils/jitoUtils.ts index e74268c2..e145c6a9 100644 --- a/solauto-sdk/src/utils/jitoUtils.ts +++ b/solauto-sdk/src/utils/jitoUtils.ts @@ -3,11 +3,8 @@ import { PublicKey, SimulatedTransactionResponse, TransactionExpiredBlockheightExceededError, - VersionedMessage, VersionedTransaction, } from "@solana/web3.js"; -import { toWeb3JsTransaction } from "@metaplex-foundation/umi-web3js-adapters"; -import { JITO_BLOCK_ENGINE } from "../constants/solautoConstants"; import { Signer, TransactionBuilder, @@ -15,32 +12,27 @@ import { WrappedInstruction, TransactionMessage, } from "@metaplex-foundation/umi"; +import { toWeb3JsTransaction } from "@metaplex-foundation/umi-web3js-adapters"; +import { JITO_TIP_ACCOUNTS } from "../constants"; +import { PriorityFeeSetting, TransactionRunType } from "../types"; +import { BundleSimulationError } from "../types"; import { assembleFinalTransaction, getComputeUnitPriceEstimate, sendSingleOptimizedTransaction, systemTransferUmiIx, } from "./solanaUtils"; -import { consoleLog, retryWithExponentialBackoff } from "./generalUtils"; -import { PriorityFeeSetting, TransactionRunType } from "../types"; -import axios from "axios"; +import { + consoleLog, + customRpcCall, + retryWithExponentialBackoff, +} from "./generalUtils"; import base58 from "bs58"; -import { BundleSimulationError } from "../types/transactions"; -import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes"; +import { usePriorityFee } from "../services"; export function getRandomTipAccount(): PublicKey { - const tipAccounts = [ - "96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5", - "HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe", - "Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY", - "ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49", - "DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh", - "ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt", - "DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL", - "3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT", - ]; - const randomInt = Math.floor(Math.random() * tipAccounts.length); - return new PublicKey(tipAccounts[randomInt]); + const randomInt = Math.floor(Math.random() * JITO_TIP_ACCOUNTS.length); + return new PublicKey(JITO_TIP_ACCOUNTS[randomInt]); } function getTipInstruction( @@ -80,40 +72,24 @@ function parseJitoErrorMessage(message: string) { async function simulateJitoBundle(umi: Umi, txs: VersionedTransaction[]) { const simulationResult = await retryWithExponentialBackoff(async () => { - const resp = await axios.post( - umi.rpc.getEndpoint(), + const res = await customRpcCall(umi, "simulateBundle", [ { - jsonrpc: "2.0", - id: 1, - method: "simulateBundle", - params: [ - { - encodedTransactions: txs.map((x) => - Buffer.from(x.serialize()).toString("base64") - ), - }, - { - encoding: "base64", - commitment: "confirmed", - preExecutionAccountsConfigs: txs.map((_) => {}), - postExecutionAccountsConfigs: txs.map((_) => {}), - skipSigVerify: true, - }, - ], + encodedTransactions: txs.map((x) => + Buffer.from(x.serialize()).toString("base64") + ), }, { - headers: { - "Content-Type": "application/json", - }, - } - ); - - const res = resp.data as any; + encoding: "base64", + commitment: "confirmed", + preExecutionAccountsConfigs: txs.map((_) => {}), + postExecutionAccountsConfigs: txs.map((_) => {}), + skipSigVerify: true, + }, + ]); - if (res.result && res.result.value && res.result.value.summary.failed) { - const resValue = res.result.value; - const transactionResults = - resValue.transactionResults as SimulatedTransactionResponse[]; + if (res.value && res.value.summary.failed) { + const transactionResults = res.value + .transactionResults as SimulatedTransactionResponse[]; transactionResults.forEach((x) => { x.logs?.forEach((y) => { consoleLog(y); @@ -121,7 +97,7 @@ async function simulateJitoBundle(umi: Umi, txs: VersionedTransaction[]) { }); const failedTxIdx = transactionResults.length; - const txFailure = resValue.summary.failed.error.TransactionFailure; + const txFailure = res.value.summary.failed.error.TransactionFailure; if (txFailure) { const info = parseJitoErrorMessage(txFailure[1] as string); @@ -139,14 +115,14 @@ async function simulateJitoBundle(umi: Umi, txs: VersionedTransaction[]) { } throw new Error( - txFailure ? txFailure[1] : resValue.summary.failed.toString() + txFailure ? txFailure[1] : res.value.summary.failed.toString() ); } else if (res.error && res.error.message) { throw new Error(res.error.message); } - return res; - }); + return res.value; + }, 2); const transactionResults = simulationResult.transactionResults as SimulatedTransactionResponse[]; @@ -154,6 +130,26 @@ async function simulateJitoBundle(umi: Umi, txs: VersionedTransaction[]) { return transactionResults; } +export function getAdditionalSigners(message: TransactionMessage) { + const { numRequiredSignatures, numReadonlySignedAccounts } = message.header; + + const numWritableSigners = numRequiredSignatures - numReadonlySignedAccounts; + + const signersInfo = []; + for (let i = 0; i < numRequiredSignatures; i++) { + const publicKey = message.accounts[i].toString(); + const isWritable = i < numWritableSigners; + + signersInfo.push({ + index: i, + publicKey, + isWritable, + }); + } + + return signersInfo; +} + async function umiToVersionedTransactions( umi: Umi, blockhash: string, @@ -167,7 +163,7 @@ async function umiToVersionedTransactions( let builtTxs = await Promise.all( txs.map(async (tx, i) => { return assembleFinalTransaction( - userSigner, + umi, tx, feeEstimates ? feeEstimates[i] : undefined, computeUnitLimits ? computeUnitLimits[i] : undefined @@ -181,7 +177,7 @@ async function umiToVersionedTransactions( builtTxs = await userSigner.signAllTransactions(builtTxs); for (const signer of otherSigners) { for (let i = 0; i < builtTxs.length; i++) { - const requiredSigners = getRequiredSigners(builtTxs[i].message); + const requiredSigners = getAdditionalSigners(builtTxs[i].message); if ( requiredSigners .map((x) => x.publicKey) @@ -196,21 +192,16 @@ async function umiToVersionedTransactions( return builtTxs.map((x) => toWeb3JsTransaction(x)); } -async function getBundleStatus(bundleId: string) { - const res = await axios.post(`${JITO_BLOCK_ENGINE}/api/v1/bundles`, { - jsonrpc: "2.0", - id: 1, - method: "getBundleStatuses", - params: [[bundleId]], - }); - if (res.data.error) { - throw new Error(`Failed to get bundle status: ${res.data.error}`); +async function getBundleStatus(umi: Umi, bundleId: string) { + const res = await customRpcCall(umi, "getBundleStatuses", [[bundleId]]); + if (res.error) { + throw new Error(`Failed to get bundle status: ${res.error}`); } - - return res.data.result; + return res; } async function pollBundleStatus( + umi: Umi, bundleId: string, interval = 1000, timeout = 40000 @@ -218,7 +209,20 @@ async function pollBundleStatus( const endTime = Date.now() + timeout; while (Date.now() < endTime) { await new Promise((resolve) => setTimeout(resolve, interval)); - const statuses = await getBundleStatus(bundleId); + + const statuses = await retryWithExponentialBackoff( + async () => { + const resp = await getBundleStatus(umi, bundleId); + // TODO: remove me + if (resp?.value?.length > 0 && resp.value[0] === null) { + throw new Error("No confirmation status"); + } + return resp; + }, + 3, + 250 + ); + if (statuses?.value?.length > 0) { consoleLog("Statuses:", statuses); const status = statuses.value[0].confirmation_status; @@ -243,12 +247,7 @@ async function sendJitoBundle( ): Promise { let resp: any; try { - resp = await axios.post<{ result: string }>(umi.rpc.getEndpoint(), { - jsonrpc: "2.0", - id: 1, - method: "sendBundle", - params: [transactions], - }); + resp = await customRpcCall(umi, "sendBundle", [transactions]); } catch (e: any) { if (e.response.data.error) { console.error("Jito send bundle error:", e.response.data.error); @@ -258,29 +257,15 @@ async function sendJitoBundle( } } - const bundleId = resp.data.result; - consoleLog("Bundle ID:", bundleId); - return bundleId ? await pollBundleStatus(bundleId) : []; -} - -export function getRequiredSigners(message: TransactionMessage) { - const { numRequiredSignatures, numReadonlySignedAccounts } = message.header; - - const numWritableSigners = numRequiredSignatures - numReadonlySignedAccounts; - - const signersInfo = []; - for (let i = 0; i < numRequiredSignatures; i++) { - const publicKey = message.accounts[i].toString(); - const isWritable = i < numWritableSigners; - - signersInfo.push({ - index: i, - publicKey, - isWritable, - }); + if (resp.error?.message === "All providers failed") { + throw new Error(resp.error.responses[0].response.error.message); + } else if (resp.error) { + throw new Error(resp.error); } - return signersInfo; + const bundleId = resp as string; + consoleLog("Bundle ID:", bundleId); + return bundleId ? await pollBundleStatus(umi, bundleId) : []; } export async function sendJitoBundledTransactions( @@ -288,11 +273,14 @@ export async function sendJitoBundledTransactions( connection: Connection, userSigner: Signer, otherSigners: Signer[], - txs: TransactionBuilder[], + transactions: TransactionBuilder[], txType?: TransactionRunType, priorityFeeSetting: PriorityFeeSetting = PriorityFeeSetting.Min, - onAwaitingSign?: () => void + onAwaitingSign?: () => void, + abortController?: AbortController ): Promise { + const txs = [...transactions]; + if (txs.length === 1) { const resp = await sendSingleOptimizedTransaction( umi, @@ -300,9 +288,10 @@ export async function sendJitoBundledTransactions( txs[0], txType, priorityFeeSetting, - onAwaitingSign + onAwaitingSign, + abortController ); - return resp ? [bs58.encode(resp)] : undefined; + return resp ? [base58.encode(resp)] : undefined; } consoleLog("Sending Jito bundle..."); @@ -316,25 +305,14 @@ export async function sendJitoBundledTransactions( ); txs[0] = txs[0].prepend(getTipInstruction(userSigner, 150_000)); - const feeEstimates = - priorityFeeSetting !== PriorityFeeSetting.None - ? await Promise.all( - txs.map( - async (x) => - (await getComputeUnitPriceEstimate( - umi, - x, - priorityFeeSetting, - true - )) ?? 1000000 - ) - ) - : undefined; const latestBlockhash = ( await umi.rpc.getLatestBlockhash({ commitment: "confirmed" }) ).blockhash; + if (abortController?.signal.aborted) { + return; + } let builtTxs: VersionedTransaction[] = []; let simulationResults: SimulatedTransactionResponse[] | undefined; if (txType !== "skip-simulation") { @@ -345,18 +323,29 @@ export async function sendJitoBundledTransactions( otherSigners, txs, false, - feeEstimates - ); - consoleLog( - builtTxs.map((x) => - x.message.compiledInstructions.map((y) => - x.message.staticAccountKeys[y.programIdIndex].toString() - ) - ) + undefined, + Array(txs.length).map(_ => 1_400_000) ); simulationResults = await simulateJitoBundle(umi, builtTxs); } + const feeEstimates = usePriorityFee(priorityFeeSetting) + ? await Promise.all( + txs.map( + async (x) => + (await getComputeUnitPriceEstimate( + umi, + x, + priorityFeeSetting, + true + )) ?? 1000000 + ) + ) + : undefined; + + if (abortController?.signal.aborted) { + return; + } if (txType !== "only-simulate") { onAwaitingSign?.(); @@ -372,6 +361,13 @@ export async function sendJitoBundledTransactions( ? simulationResults.map((x) => x.unitsConsumed! * 1.15) : undefined ); + consoleLog( + builtTxs.map((x) => + x.message.compiledInstructions.map((y) => + x.message.staticAccountKeys[y.programIdIndex].toString() + ) + ) + ); const serializedTxs = builtTxs.map((x) => x.serialize()); if (serializedTxs.find((x) => x.length > 1232)) { diff --git a/solauto-sdk/src/utils/jupiterUtils.ts b/solauto-sdk/src/utils/jupiterUtils.ts index 63d7ba93..48d58115 100644 --- a/solauto-sdk/src/utils/jupiterUtils.ts +++ b/solauto-sdk/src/utils/jupiterUtils.ts @@ -1,34 +1,8 @@ -import { - Signer, - TransactionBuilder, - transactionBuilder, -} from "@metaplex-foundation/umi"; import { PublicKey, TransactionInstruction } from "@solana/web3.js"; -import { getWrappedInstruction } from "./solanaUtils"; -import { fromBps, toBps } from "./numberUtils"; -import { - createJupiterApiClient, - Instruction, - QuoteResponse, -} from "@jup-ag/api"; -import { getTokenAccount } from "./accountUtils"; -import { consoleLog, retryWithExponentialBackoff } from "./generalUtils"; -import { TOKEN_INFO } from "../constants"; +import { Instruction } from "@jup-ag/api"; +import { retryWithExponentialBackoff } from "./generalUtils"; -const jupApi = createJupiterApiClient(); - -export interface JupSwapDetails { - inputMint: PublicKey; - outputMint: PublicKey; - destinationWallet: PublicKey; - amount: bigint; - slippageIncFactor?: number; - exactOut?: boolean; - exactIn?: boolean; - addPadding?: boolean; -} - -function createTransactionInstruction( +export function jupIxToSolanaIx( instruction: Instruction ): TransactionInstruction { return new TransactionInstruction({ @@ -42,133 +16,32 @@ function createTransactionInstruction( }); } -export interface JupSwapTransaction { - jupQuote: QuoteResponse; - priceImpactBps: number; - lookupTableAddresses: string[]; - setupInstructions: TransactionBuilder; - tokenLedgerIx: TransactionBuilder; - swapIx: TransactionBuilder; -} - -export async function getJupSwapTransaction( - signer: Signer, - swapDetails: JupSwapDetails, - attemptNum?: number -): Promise { - const memecoinSwap = - TOKEN_INFO[swapDetails.inputMint.toString()].isMeme || - TOKEN_INFO[swapDetails.outputMint.toString()].isMeme; - - const quoteResponse = await retryWithExponentialBackoff( - async () => - await jupApi.quoteGet({ - amount: Number(swapDetails.amount), - inputMint: swapDetails.inputMint.toString(), - outputMint: swapDetails.outputMint.toString(), - swapMode: swapDetails.exactOut - ? "ExactOut" - : swapDetails.exactIn - ? "ExactIn" - : undefined, - slippageBps: memecoinSwap ? 500 : 300, - maxAccounts: !swapDetails.exactOut ? 45 : undefined, - }), - 4, - 200 - ); - - const priceImpactBps = - Math.round(toBps(parseFloat(quoteResponse.priceImpactPct))) + 1; - const finalPriceSlippageBps = Math.round( - Math.max(50, quoteResponse.slippageBps, priceImpactBps) * - (1 + (swapDetails.slippageIncFactor ?? 0)) - ); - quoteResponse.slippageBps = finalPriceSlippageBps; - consoleLog(quoteResponse); - - consoleLog("Getting jup instructions..."); - const instructions = await retryWithExponentialBackoff( - async () => - await jupApi.swapInstructionsPost({ - swapRequest: { - userPublicKey: signer.publicKey.toString(), - quoteResponse, - wrapAndUnwrapSol: false, - useTokenLedger: !swapDetails.exactOut && !swapDetails.exactIn, - destinationTokenAccount: getTokenAccount( - swapDetails.destinationWallet, - swapDetails.outputMint - ).toString(), - }, - }), - 4, - 200 - ); - - if (!instructions.swapInstruction) { - throw new Error("No swap instruction was returned by Jupiter"); - } - - consoleLog("Raw price impact bps:", priceImpactBps); - const finalPriceImpactBps = - priceImpactBps * (1 + (swapDetails.slippageIncFactor ?? 0)); - consoleLog("Increased price impact bps:", finalPriceImpactBps); - - if (swapDetails.addPadding) { - consoleLog("Raw inAmount:", quoteResponse.inAmount); - const inc = Math.max( - fromBps(finalPriceImpactBps) * 1.1, - fromBps(finalPriceSlippageBps) * 0.05 - ); - consoleLog("Inc:", inc); - quoteResponse.inAmount = Math.round( - parseInt(quoteResponse.inAmount) + parseInt(quoteResponse.inAmount) * inc - ).toString(); - consoleLog("Increased inAmount:", quoteResponse.inAmount); - } - - return { - jupQuote: quoteResponse, - priceImpactBps: finalPriceImpactBps, - lookupTableAddresses: instructions.addressLookupTableAddresses, - setupInstructions: transactionBuilder().add( - instructions.setupInstructions.map((ix) => - getWrappedInstruction(signer, createTransactionInstruction(ix)) - ) - ), - tokenLedgerIx: transactionBuilder().add( - instructions.tokenLedgerInstruction !== undefined - ? getWrappedInstruction( - signer, - createTransactionInstruction(instructions.tokenLedgerInstruction) - ) - : transactionBuilder() - ), - swapIx: transactionBuilder().add( - getWrappedInstruction( - signer, - createTransactionInstruction(instructions.swapInstruction) - ) - ), - }; -} - -export async function getJupPriceData(mints: PublicKey[], extraInfo?: boolean) { +export async function getJupPriceData(mints: PublicKey[]) { const data = await retryWithExponentialBackoff(async () => { const res = await ( await fetch( "https://api.jup.ag/price/v2?ids=" + mints.map((x) => x.toString()).join(",") + - (extraInfo ? "&showExtraInfo=true" : "") + "&showExtraInfo=true" ) ).json(); const result = res.data; - if (!result) { + if (!result || result === null || typeof result !== "object") { throw new Error("Failed to get token prices using Jupiter"); } - return result; - }, 6); - return data as { [key: string]: any }; + const trueData: { [key: string]: any } = Object.entries( + result as { [key: string]: any } + ).reduce( + (acc, [key, val]) => + !val?.extraInfo?.quotedPrice?.sellAt + ? { ...acc, [key]: { ...val, price: "0" } } + : { ...acc, [key]: val }, + {} + ); + + return trueData; + }, 3); + + return data; } diff --git a/solauto-sdk/src/utils/marginfiUtils.ts b/solauto-sdk/src/utils/marginfi/data.ts similarity index 60% rename from solauto-sdk/src/utils/marginfiUtils.ts rename to solauto-sdk/src/utils/marginfi/data.ts index 1e812df4..31be84f7 100644 --- a/solauto-sdk/src/utils/marginfiUtils.ts +++ b/solauto-sdk/src/utils/marginfi/data.ts @@ -1,89 +1,39 @@ -import { Connection, PublicKey } from "@solana/web3.js"; +import { PublicKey } from "@solana/web3.js"; import { publicKey, Umi } from "@metaplex-foundation/umi"; import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; +import { PositionState, PositionTokenState, PriceType } from "../../generated"; +import { + ALL_SUPPORTED_TOKENS, + getMarginfiAccounts, + TOKEN_INFO, + USD_DECIMALS, +} from "../../constants"; import { Bank, + deserializeMarginfiAccount, getMarginfiAccountSize, - MARGINFI_PROGRAM_ID, MarginfiAccount, + OracleSetup, safeFetchBank, safeFetchMarginfiAccount, -} from "../marginfi-sdk"; -import { currentUnixSeconds } from "./generalUtils"; +} from "../../marginfi-sdk"; +import { ContextUpdates } from "../solautoUtils"; +import { fetchTokenPrices, safeGetPrice } from "../priceUtils"; +import { currentUnixSeconds, validPubkey } from "../generalUtils"; import { bytesToI80F48, + calcNetWorthUsd, fromBaseUnit, getLiqUtilzationRateBps, toBaseUnit, toBps, -} from "./numberUtils"; +} from "../numberUtils"; import { - DEFAULT_MARGINFI_GROUP, - MARGINFI_ACCOUNTS, -} from "../constants/marginfiAccounts"; -import { MarginfiAssetAccounts } from "../types/accounts"; -import { PositionState, PositionTokenUsage } from "../generated"; -import { USD_DECIMALS } from "../constants/generalAccounts"; -import { LivePositionUpdates } from "./solauto/generalUtils"; -import { TOKEN_INFO } from "../constants"; -import { fetchTokenPrices, safeGetPrice } from "./priceUtils"; - -interface AllMarginfiAssetAccounts extends MarginfiAssetAccounts { - mint: PublicKey; -} - -export function findMarginfiAccounts( - bank: PublicKey -): AllMarginfiAssetAccounts { - for (const group in MARGINFI_ACCOUNTS) { - for (const key in MARGINFI_ACCOUNTS[group]) { - const account = MARGINFI_ACCOUNTS[group][key]; - if ( - account.bank.toString().toLowerCase() === bank.toString().toLowerCase() - ) { - return { ...account, mint: new PublicKey(key) }; - } - } - } - throw new Error(`Marginfi accounts not found by the bank: ${bank}`); -} - -export function calcMarginfiMaxLtvAndLiqThreshold( - supplyBank: Bank, - debtBank: Bank, - supplyPrice: number -): [number, number] { - let maxLtv = - bytesToI80F48(supplyBank.config.assetWeightInit.value) / - bytesToI80F48(debtBank.config.liabilityWeightInit.value); - const liqThreshold = - bytesToI80F48(supplyBank.config.assetWeightMaint.value) / - bytesToI80F48(debtBank.config.liabilityWeightMaint.value); - - const totalDepositedUsdValue = - fromBaseUnit( - BigInt( - Math.round( - bytesToI80F48(supplyBank.totalAssetShares.value) * - bytesToI80F48(supplyBank.assetShareValue.value) - ) - ), - supplyBank.mintDecimals - ) * supplyPrice!; - if ( - supplyBank.config.totalAssetValueInitLimit !== BigInt(0) && - totalDepositedUsdValue > supplyBank.config.totalAssetValueInitLimit - ) { - const discount = - Number(supplyBank.config.totalAssetValueInitLimit) / - totalDepositedUsdValue; - maxLtv = maxLtv * Number(discount); - } + calcMarginfiMaxLtvAndLiqThresholdBps, + marginfiAccountEmpty, +} from "./general"; - return [maxLtv, liqThreshold]; -} - -export async function getMarginfiMaxLtvAndLiqThreshold( +export async function getMarginfiMaxLtvAndLiqThresholdBps( umi: Umi, marginfiGroup: PublicKey, supply: { @@ -96,28 +46,30 @@ export async function getMarginfiMaxLtvAndLiqThreshold( }, supplyPrice?: number ): Promise<[number, number]> { - if (!supply.bank && supply.mint.equals(PublicKey.default)) { + if (!supply.bank && !validPubkey(supply.mint)) { return [0, 0]; } + const bankAccounts = getMarginfiAccounts( + undefined, + marginfiGroup + ).bankAccounts; + if (!supply.bank || supply.bank === null) { supply.bank = await safeFetchBank( umi, publicKey( - MARGINFI_ACCOUNTS[marginfiGroup.toString()][supply.mint.toString()].bank + bankAccounts[marginfiGroup.toString()][supply.mint.toString()].bank ), { commitment: "confirmed" } ); } - if ( - (!debt.bank || debt.bank === null) && - !debt.mint.equals(PublicKey.default) - ) { + if ((!debt.bank || debt.bank === null) && !validPubkey(debt.mint)) { debt.bank = await safeFetchBank( umi, publicKey( - MARGINFI_ACCOUNTS[marginfiGroup.toString()][debt.mint.toString()].bank + bankAccounts[marginfiGroup.toString()][debt.mint.toString()].bank ), { commitment: "confirmed" } ); @@ -134,13 +86,47 @@ export async function getMarginfiMaxLtvAndLiqThreshold( return [0, 0]; } - return calcMarginfiMaxLtvAndLiqThreshold( + return calcMarginfiMaxLtvAndLiqThresholdBps( supply.bank!, debt.bank, supplyPrice ); } +export async function getEmptyMarginfiAccountsByAuthority( + umi: Umi, + authority: PublicKey +): Promise { + const marginfiAccounts = await umi.rpc.getProgramAccounts( + umi.programs.get("marginfi").publicKey, + { + commitment: "confirmed", + filters: [ + { + dataSize: getMarginfiAccountSize(), + }, + { + memcmp: { + bytes: new Uint8Array(authority.toBuffer()), + offset: 8 + 32, // Anchor account discriminator + group pubkey + }, + }, + { + // First balance is not active + memcmp: { + bytes: new Uint8Array([0]), + offset: 8 + 32 + 32, + }, + }, + ], + } + ); + + return marginfiAccounts + .map((x) => deserializeMarginfiAccount(x)) + .filter((x) => marginfiAccountEmpty(x)); +} + export async function getAllMarginfiAccountsByAuthority( umi: Umi, authority: PublicKey, @@ -150,7 +136,7 @@ export async function getAllMarginfiAccountsByAuthority( { marginfiAccount: PublicKey; supplyMint?: PublicKey; debtMint?: PublicKey }[] > { const marginfiAccounts = await umi.rpc.getProgramAccounts( - MARGINFI_PROGRAM_ID, + umi.programs.get("marginfi").publicKey, { commitment: "confirmed", dataSlice: { @@ -185,23 +171,15 @@ export async function getAllMarginfiAccountsByAuthority( const positionStates = await Promise.all( marginfiAccounts.map(async (x) => ({ publicKey: x.publicKey, - state: await getMarginfiAccountPositionState(umi, { - pk: toWeb3JsPublicKey(x.publicKey), - }), + state: ( + await getMarginfiAccountPositionState(umi, { + pk: toWeb3JsPublicKey(x.publicKey), + }) + )?.state, })) ); return positionStates - .sort( - (a, b) => - fromBaseUnit( - b.state?.netWorth.baseAmountUsdValue ?? BigInt(0), - USD_DECIMALS - ) - - fromBaseUnit( - a.state?.netWorth.baseAmountUsdValue ?? BigInt(0), - USD_DECIMALS - ) - ) + .sort((a, b) => calcNetWorthUsd(b.state) - calcNetWorthUsd(a.state)) .filter((x) => x.state !== undefined) .map((x) => ({ marginfiAccount: toWeb3JsPublicKey(x.publicKey), @@ -217,39 +195,73 @@ export async function getAllMarginfiAccountsByAuthority( export function getBankLiquidityAvailableBaseUnit( bank: Bank | null, - isAsset: boolean + availableToDeposit: boolean ) { let amountCanBeUsed = 0; if (bank !== null) { const [assetShareValue, liabilityShareValue] = getUpToDateShareValues(bank); + const totalDeposited = bytesToI80F48(bank.totalAssetShares.value) * assetShareValue; - amountCanBeUsed = isAsset + const totalBorrowed = + bytesToI80F48(bank.totalLiabilityShares.value) * liabilityShareValue; + + amountCanBeUsed = availableToDeposit ? Number(bank.config.depositLimit) - totalDeposited - : totalDeposited - - bytesToI80F48(bank.totalLiabilityShares.value) * liabilityShareValue; + : Math.min( + totalDeposited - totalBorrowed, + Math.max(0, Number(bank.config.borrowLimit) - totalBorrowed) + ); + } + + return BigInt(Math.floor(amountCanBeUsed)); +} + +export function getBankLiquidityUsedBaseUnit( + bank: Bank | null, + asset: boolean +) { + let amountUsed = 0; + + if (bank !== null) { + const [assetShareValue, liabilityShareValue] = getUpToDateShareValues(bank); + + const totalDeposited = + bytesToI80F48(bank.totalAssetShares.value) * assetShareValue; + const totalBorrowed = + bytesToI80F48(bank.totalLiabilityShares.value) * liabilityShareValue; + + amountUsed = asset ? totalDeposited : totalBorrowed; } - return amountCanBeUsed; + return BigInt(Math.floor(amountUsed)); } async function getTokenUsage( bank: Bank | null, isAsset: boolean, shares: number, - amountUsedAdjustment?: bigint -): Promise { + amountUsedAdjustment?: bigint, + priceType?: PriceType +): Promise { let amountUsed = 0; - let amountCanBeUsed = 0; + let amountCanBeUsed = BigInt(0); let marketPrice = 0; + let originationFee = 0; if (bank !== null) { - [marketPrice] = await fetchTokenPrices([toWeb3JsPublicKey(bank.mint)]); + [marketPrice] = await fetchTokenPrices( + [toWeb3JsPublicKey(bank.mint)], + priceType + ); const [assetShareValue, liabilityShareValue] = getUpToDateShareValues(bank); const shareValue = isAsset ? assetShareValue : liabilityShareValue; amountUsed = shares * shareValue + Number(amountUsedAdjustment ?? 0); amountCanBeUsed = getBankLiquidityAvailableBaseUnit(bank, isAsset); + originationFee = bytesToI80F48( + bank?.config.interestRateConfig.protocolOriginationFee.value + ); } return { @@ -266,20 +278,16 @@ async function getTokenUsage( : BigInt(0), }, amountCanBeUsed: { - baseUnit: BigInt(Math.round(amountCanBeUsed)), + baseUnit: amountCanBeUsed, baseAmountUsdValue: bank ? toBaseUnit( - fromBaseUnit( - BigInt(Math.round(amountCanBeUsed)), - bank.mintDecimals - ) * marketPrice, + fromBaseUnit(amountCanBeUsed, bank.mintDecimals) * marketPrice, USD_DECIMALS ) : BigInt(0), }, baseAmountMarketPriceUsd: toBaseUnit(marketPrice, USD_DECIMALS), - flashLoanFeeBps: 0, - borrowFeeBps: 0, + borrowFeeBps: isAsset ? 0 : toBps(originationFee), padding1: [], padding2: [], padding: new Uint8Array([]), @@ -293,19 +301,52 @@ interface BankSelection { type BanksCache = { [group: string]: { [mint: string]: Bank } }; +async function getBank( + umi: Umi, + data: BankSelection, + marginfiGroup: PublicKey +) { + const mint = validPubkey(data.mint) ? data.mint!.toString() : undefined; + + return data?.banksCache && mint + ? data.banksCache[marginfiGroup.toString()][mint] + : mint && mint !== PublicKey.default.toString() + ? await safeFetchBank( + umi, + publicKey( + getMarginfiAccounts(undefined, marginfiGroup).bankAccounts[ + marginfiGroup.toString() + ][mint].bank + ), + { commitment: "confirmed" } + ) + : null; +} + export async function getMarginfiAccountPositionState( umi: Umi, - protocolAccount: { pk: PublicKey; data?: MarginfiAccount }, + lpUserAccount: { pk?: PublicKey; data?: MarginfiAccount | null }, marginfiGroup?: PublicKey, supply?: BankSelection, debt?: BankSelection, - livePositionUpdates?: LivePositionUpdates -): Promise { + contextUpdates?: ContextUpdates, + priceType?: PriceType +): Promise< + | { + supplyBank: Bank | null; + debtBank: Bank | null; + marginfiGroup: PublicKey; + state: PositionState; + } + | undefined +> { let marginfiAccount = - protocolAccount.data ?? - (await safeFetchMarginfiAccount(umi, publicKey(protocolAccount.pk), { - commitment: "confirmed", - })); + lpUserAccount.data ?? + (validPubkey(lpUserAccount.pk) + ? await safeFetchMarginfiAccount(umi, publicKey(lpUserAccount.pk!), { + commitment: "confirmed", + }) + : null); if (!supply) { supply = {}; @@ -318,37 +359,15 @@ export async function getMarginfiAccountPositionState( marginfiGroup = toWeb3JsPublicKey(marginfiAccount.group); } - let supplyBank: Bank | null = - supply?.banksCache && supply.mint && marginfiGroup - ? supply.banksCache[marginfiGroup!.toString()][supply?.mint?.toString()] - : supply?.mint && supply?.mint !== PublicKey.default - ? await safeFetchBank( - umi, - publicKey( - MARGINFI_ACCOUNTS[marginfiGroup?.toString() ?? ""][ - supply?.mint.toString() - ].bank - ), - { commitment: "confirmed" } - ) - : null; - let debtBank: Bank | null = - debt?.banksCache && debt.mint && marginfiGroup - ? debt.banksCache[marginfiGroup!.toString()][debt?.mint?.toString()] - : debt?.mint && debt?.mint !== PublicKey.default - ? await safeFetchBank( - umi, - publicKey( - MARGINFI_ACCOUNTS[marginfiGroup?.toString() ?? ""][ - debt?.mint.toString() - ].bank - ), - { commitment: "confirmed" } - ) - : null; + let supplyBank: Bank | null = await getBank(umi, supply, marginfiGroup!); + let debtBank: Bank | null = await getBank(umi, debt, marginfiGroup!); - let supplyUsage: PositionTokenUsage | undefined = undefined; - let debtUsage: PositionTokenUsage | undefined = undefined; + let supplyUsage: PositionTokenState | undefined = undefined; + let debtUsage: PositionTokenState | undefined = undefined; + + if (supply.mint && debt.mint) { + await fetchTokenPrices([supply.mint, debt.mint]); + } if ( marginfiAccount !== null && @@ -381,7 +400,8 @@ export async function getMarginfiAccountPositionState( supplyBank!, true, bytesToI80F48(supplyBalances[0].assetShares.value), - livePositionUpdates?.supplyAdjustment + contextUpdates?.supplyAdjustment, + priceType ); } @@ -398,7 +418,8 @@ export async function getMarginfiAccountPositionState( debtBank!, false, bytesToI80F48(debtBalances[0].liabilityShares.value), - livePositionUpdates?.debtAdjustment + contextUpdates?.debtAdjustment, + priceType ); } } @@ -412,7 +433,7 @@ export async function getMarginfiAccountPositionState( supplyBank, true, 0, - livePositionUpdates?.supplyAdjustment + contextUpdates?.supplyAdjustment ); } @@ -426,8 +447,11 @@ export async function getMarginfiAccountPositionState( if ( supplyMint === undefined || debtMint === undefined || - (!supplyMint.isStableCoin && !debtMint.isStableCoin) || - (supplyMint.isStableCoin && debtMint.isStableCoin) + (supplyMint.isStableCoin && debtMint.isStableCoin) || + !ALL_SUPPORTED_TOKENS.includes(supplyBank.mint.toString()) || + !ALL_SUPPORTED_TOKENS.includes(debtBank.mint.toString()) || + supplyBank.config.oracleSetup === OracleSetup.StakedWithPythPush || + debtBank.config.oracleSetup === OracleSetup.StakedWithPythPush ) { return undefined; } @@ -437,14 +461,17 @@ export async function getMarginfiAccountPositionState( debtBank, false, 0, - livePositionUpdates?.debtAdjustment + contextUpdates?.debtAdjustment ); } - const supplyPrice = safeGetPrice(supply.mint!)!; - let [maxLtv, liqThreshold] = await getMarginfiMaxLtvAndLiqThreshold( + if (!marginfiGroup) { + marginfiGroup = toWeb3JsPublicKey(supplyBank.group); + } + const supplyPrice = safeGetPrice(toWeb3JsPublicKey(supplyBank.mint))!; + let [maxLtvBps, liqThresholdBps] = await getMarginfiMaxLtvAndLiqThresholdBps( umi, - marginfiGroup ?? new PublicKey(DEFAULT_MARGINFI_GROUP), + marginfiGroup, { mint: toWeb3JsPublicKey(supplyBank.mint), bank: supplyBank, @@ -465,26 +492,31 @@ export async function getMarginfiAccountPositionState( ); return { - liqUtilizationRateBps: getLiqUtilzationRateBps( - supplyUsd, - debtUsd, - toBps(liqThreshold) - ), - netWorth: { - baseAmountUsdValue: toBaseUnit(supplyUsd - debtUsd, USD_DECIMALS), - baseUnit: toBaseUnit( - (supplyUsd - debtUsd) / supplyPrice, - supplyUsage!.decimals + supplyBank, + debtBank, + marginfiGroup, + state: { + liqUtilizationRateBps: getLiqUtilzationRateBps( + supplyUsd, + debtUsd, + liqThresholdBps ), + netWorth: { + baseAmountUsdValue: toBaseUnit(supplyUsd - debtUsd, USD_DECIMALS), + baseUnit: toBaseUnit( + (supplyUsd - debtUsd) / supplyPrice, + supplyUsage!.decimals + ), + }, + supply: supplyUsage!, + debt: debtUsage!, + maxLtvBps, + liqThresholdBps, + lastRefreshed: BigInt(currentUnixSeconds()), + padding1: [], + padding2: [], + padding: [], }, - supply: supplyUsage!, - debt: debtUsage!, - maxLtvBps: toBps(maxLtv), - liqThresholdBps: toBps(liqThreshold), - lastUpdated: BigInt(currentUnixSeconds()), - padding1: [], - padding2: [], - padding: [], }; } @@ -578,14 +610,3 @@ export function getUpToDateShareValues(bank: Bank): [number, number] { ), ]; } - -export function marginfiAccountEmpty(marginfiAccount: MarginfiAccount) { - return ( - marginfiAccount.lendingAccount.balances.find( - (x) => - x.bankPk.toString() !== PublicKey.default.toString() && - (Math.round(bytesToI80F48(x.assetShares.value)) != 0 || - Math.round(bytesToI80F48(x.liabilityShares.value)) != 0) - ) === undefined - ); -} diff --git a/solauto-sdk/src/utils/marginfi/general.ts b/solauto-sdk/src/utils/marginfi/general.ts new file mode 100644 index 00000000..c07a550d --- /dev/null +++ b/solauto-sdk/src/utils/marginfi/general.ts @@ -0,0 +1,226 @@ +import { PublicKey } from "@solana/web3.js"; +import { AccountMeta, Program, publicKey, Umi } from "@metaplex-foundation/umi"; +import { + fromWeb3JsPublicKey, + toWeb3JsPublicKey, +} from "@metaplex-foundation/umi-web3js-adapters"; +import { ProgramEnv, MarginfiAssetAccounts } from "../../types"; +import { + getMarginfiAccounts, + MARGINFI_SPONSORED_SHARD_ID, + MarginfiBankAccountsMap, + PYTH_SPONSORED_SHARD_ID, +} from "../../constants"; +import { + Balance, + Bank, + fetchBank, + getMarginfiErrorFromCode, + getMarginfiErrorFromName, + MarginfiAccount, + OracleSetup, + safeFetchAllBank, +} from "../../marginfi-sdk"; +import { bytesToI80F48, fromBaseUnit, toBps } from "../numberUtils"; +import { getTokenAccountData } from "../accountUtils"; +import { + getMostUpToDatePythOracle, + getPythPushOracleAddress, +} from "../pythUtils"; +import { getAccountMeta } from "../solanaUtils"; + +export function createDynamicMarginfiProgram(env?: ProgramEnv): Program { + return { + name: "marginfi", + publicKey: publicKey(getMarginfiAccounts(env ?? "Prod").program), + getErrorFromCode(code: number, cause?: Error) { + return getMarginfiErrorFromCode(code, this, cause); + }, + getErrorFromName(name: string, cause?: Error) { + return getMarginfiErrorFromName(name, this, cause); + }, + isOnCluster() { + return true; + }, + }; +} + +export function umiWithMarginfiProgram(umi: Umi, marginfiEnv?: ProgramEnv) { + return umi.use({ + install(umi) { + umi.programs.add( + createDynamicMarginfiProgram(marginfiEnv ?? "Prod"), + false + ); + }, + }); +} + +export async function getAllBankRelatedAccounts( + umi: Umi, + bankAccountsMap: MarginfiBankAccountsMap +): Promise { + const banks = Object.values(bankAccountsMap).flatMap((group) => + Object.values(group).map((accounts) => accounts.bank) + ); + const banksData = await safeFetchAllBank( + umi, + banks.map((x) => publicKey(x)) + ); + + const oracles = banksData + .map((bank) => { + const oracleKey = toWeb3JsPublicKey(bank.config.oracleKeys[0]); + return bank.config.oracleSetup === OracleSetup.PythPushOracle + ? [ + getPythPushOracleAddress(oracleKey, PYTH_SPONSORED_SHARD_ID), + getPythPushOracleAddress(oracleKey, MARGINFI_SPONSORED_SHARD_ID), + ] + : [oracleKey]; + }) + .flat() + .map((x) => x.toString()); + + const otherAccounts = Object.entries(bankAccountsMap).flatMap( + ([groupName, tokenMap]) => + Object.values(tokenMap).flatMap((accounts) => [ + groupName, + accounts.liquidityVault, + accounts.vaultAuthority, + ]) + ); + + return Array.from(new Set([...banks, ...oracles, ...otherAccounts])) + .filter((x) => x !== PublicKey.default.toString()) + .map((x) => new PublicKey(x)); +} + +export async function fetchBankAddresses(umi: Umi, bankPk: PublicKey) { + const bank = await fetchBank(umi, fromWeb3JsPublicKey(bankPk)); + const liquidityVault = toWeb3JsPublicKey(bank!.liquidityVault); + const vaultAuthority = (await getTokenAccountData(umi, liquidityVault)) + ?.owner; + const priceOracle = await getMarginfiPriceOracle(umi, { data: bank }); + + return { + bank: bankPk, + liquidityVault, + vaultAuthority, + priceOracle, + }; +} + +export async function getMarginfiPriceOracle( + umi: Umi, + bank: { pk?: PublicKey; data?: Bank } +) { + if (!bank.data) { + bank.data = await fetchBank(umi, fromWeb3JsPublicKey(bank.pk!)); + } + + const oracleKey = toWeb3JsPublicKey(bank.data.config.oracleKeys[0]); + const priceOracle = + bank.data.config.oracleSetup === OracleSetup.PythPushOracle + ? await getMostUpToDatePythOracle(umi, [ + getPythPushOracleAddress(oracleKey, PYTH_SPONSORED_SHARD_ID), + getPythPushOracleAddress(oracleKey, MARGINFI_SPONSORED_SHARD_ID), + ]) + : oracleKey; + + return priceOracle; +} + +interface AllMarginfiAssetAccounts extends MarginfiAssetAccounts { + mint: PublicKey; +} + +export function findMarginfiAccounts( + bank: PublicKey +): AllMarginfiAssetAccounts { + const search = (bankAccounts: MarginfiBankAccountsMap) => { + for (const group in bankAccounts) { + for (const key in bankAccounts[group]) { + const account = bankAccounts[group][key]; + if ( + account.bank.toString().toLowerCase() === + bank.toString().toLowerCase() + ) { + return { ...account, mint: new PublicKey(key) }; + } + } + } + }; + + let res = search(getMarginfiAccounts("Prod").bankAccounts); + if (res) { + return res; + } + res = search(getMarginfiAccounts("Staging").bankAccounts); + if (res) { + return res; + } + + throw new Error(`Marginfi accounts not found by the bank: ${bank}`); +} + +export async function getRemainingAccountsForMarginfiHealthCheck( + umi: Umi, + balance: Balance +): Promise { + if (!balance.active) { + return []; + } + const priceOracle = await getMarginfiPriceOracle(umi, { + pk: toWeb3JsPublicKey(balance.bankPk), + }); + return [ + getAccountMeta(toWeb3JsPublicKey(balance.bankPk)), + getAccountMeta(priceOracle), + ]; +} + +export function calcMarginfiMaxLtvAndLiqThresholdBps( + supplyBank: Bank, + debtBank: Bank, + supplyPrice: number +): [number, number] { + let maxLtv = + bytesToI80F48(supplyBank.config.assetWeightInit.value) / + bytesToI80F48(debtBank.config.liabilityWeightInit.value); + const liqThreshold = + bytesToI80F48(supplyBank.config.assetWeightMaint.value) / + bytesToI80F48(debtBank.config.liabilityWeightMaint.value); + + const totalDepositedUsdValue = + fromBaseUnit( + BigInt( + Math.round( + bytesToI80F48(supplyBank.totalAssetShares.value) * + bytesToI80F48(supplyBank.assetShareValue.value) + ) + ), + supplyBank.mintDecimals + ) * supplyPrice!; + if ( + supplyBank.config.totalAssetValueInitLimit !== BigInt(0) && + totalDepositedUsdValue > supplyBank.config.totalAssetValueInitLimit + ) { + const discount = + Number(supplyBank.config.totalAssetValueInitLimit) / + totalDepositedUsdValue; + maxLtv = maxLtv * Number(discount); + } + + return [toBps(maxLtv, "Floor"), toBps(liqThreshold, "Floor")]; +} + +export function marginfiAccountEmpty(marginfiAccount: MarginfiAccount) { + return ( + marginfiAccount.lendingAccount.balances.find( + (x) => + x.bankPk.toString() !== PublicKey.default.toString() && + (bytesToI80F48(x.assetShares.value) > 0.000001 || + bytesToI80F48(x.liabilityShares.value) > 0.000001) + ) === undefined + ); +} diff --git a/solauto-sdk/src/utils/marginfi/index.ts b/solauto-sdk/src/utils/marginfi/index.ts new file mode 100644 index 00000000..28a4ebcf --- /dev/null +++ b/solauto-sdk/src/utils/marginfi/index.ts @@ -0,0 +1,2 @@ +export * from "./data"; +export * from "./general"; \ No newline at end of file diff --git a/solauto-sdk/src/utils/numberUtils.ts b/solauto-sdk/src/utils/numberUtils.ts index 0b8e4153..99b7e11a 100644 --- a/solauto-sdk/src/utils/numberUtils.ts +++ b/solauto-sdk/src/utils/numberUtils.ts @@ -1,5 +1,84 @@ -import { BASIS_POINTS, MIN_REPAY_GAP_BPS } from "../constants"; -import { RebalanceDirection } from "../generated"; +import { PublicKey } from "@solana/web3.js"; +import { + BASIS_POINTS, + MIN_REPAY_GAP_BPS, + OFFSET_FROM_MAX_LTV, + USD_DECIMALS, +} from "../constants"; +import { PositionState, PriceType } from "../generated"; +import { RoundAction } from "../types"; +import { safeGetPrice } from "./priceUtils"; + +export function calcNetWorthUsd(state?: PositionState) { + return fromRoundedUsdValue(state?.netWorth.baseAmountUsdValue ?? BigInt(0)); +} + +export function calcSupplyUsd(state?: PositionState) { + return fromRoundedUsdValue( + state?.supply.amountUsed.baseAmountUsdValue ?? BigInt(0) + ); +} + +export function calcDebtUsd(state?: PositionState) { + return fromRoundedUsdValue( + state?.debt.amountUsed.baseAmountUsdValue ?? BigInt(0) + ); +} + +export function calcNetWorth(state?: PositionState) { + return fromBaseUnit( + state?.netWorth.baseUnit ?? BigInt(0), + state?.supply.decimals ?? 1 + ); +} + +export function calcTotalSupply(state?: PositionState) { + return fromBaseUnit( + state?.supply.amountUsed.baseUnit ?? BigInt(0), + state?.supply.decimals ?? 1 + ); +} + +export function calcTotalDebt(state?: PositionState) { + return fromBaseUnit( + state?.debt.amountUsed.baseUnit ?? BigInt(0), + state?.debt.decimals ?? 1 + ); +} + +export function debtLiquidityAvailable(state?: PositionState) { + return fromBaseUnit( + state?.debt.amountCanBeUsed.baseUnit ?? BigInt(0), + state?.debt.decimals ?? 1 + ); +} + +export function debtLiquidityUsdAvailable(state?: PositionState) { + return fromRoundedUsdValue( + state?.debt.amountCanBeUsed.baseAmountUsdValue ?? BigInt(0) + ); +} + +export function supplyLiquidityDepositable(state?: PositionState) { + return fromBaseUnit( + state?.supply.amountCanBeUsed.baseUnit ?? BigInt(0), + state?.supply.decimals ?? 1 + ); +} + +export function supplyLiquidityUsdDepositable(state?: PositionState) { + return fromRoundedUsdValue( + state?.supply.amountCanBeUsed.baseAmountUsdValue ?? BigInt(0) + ); +} + +export function fromRoundedUsdValue(number: bigint) { + return fromBaseUnit(number, USD_DECIMALS); +} + +export function toRoundedUsdValue(number: number) { + return toBaseUnit(number, USD_DECIMALS); +} export function getLiqUtilzationRateBps( supplyUsd: number, @@ -13,11 +92,15 @@ export function getLiqUtilzationRateBps( return toBps(debtUsd / (supplyUsd * fromBps(liqThresholdBps))); } -export function toBaseUnit(value: number, decimals: number): bigint { +export function toBaseUnit( + value: number, + decimals: number, + roundAction: RoundAction = "Round" +): bigint { if (!decimals) { return BigInt(Math.floor(value)); } - return BigInt(Math.round(value * Math.pow(10, decimals))); + return BigInt(roundNumber(value * Math.pow(10, decimals), roundAction)); } export function fromBaseUnit(value: bigint, decimals: number): number { @@ -31,8 +114,20 @@ export function fromBps(value: number): number { return value / BASIS_POINTS; } -export function toBps(value: number): number { - return Math.round(value * BASIS_POINTS); +export function toBps( + value: number, + roundAction: RoundAction = "Round" +): number { + const bps = value * BASIS_POINTS; + return roundNumber(bps, roundAction); +} + +function roundNumber(number: number, roundAction: RoundAction = "Round") { + return roundAction === "Round" + ? Math.round(number) + : roundAction === "Floor" + ? Math.floor(number) + : Math.ceil(number); } export function bytesToI80F48(bytes: number[]): number { @@ -75,84 +170,6 @@ export function uint8ArrayToBigInt(uint8Array: Uint8Array): bigint { return (BigInt(high) << 32n) | BigInt(low); } -export function getDebtAdjustmentUsd( - liqThresholdBps: number, - supplyUsd: number, - debtUsd: number, - targetLiqUtilizationRateBps: number, - adjustmentFeeBps?: number -) { - const adjustmentFee = - adjustmentFeeBps && adjustmentFeeBps > 0 ? fromBps(adjustmentFeeBps) : 0; - const liqThreshold = fromBps(liqThresholdBps); - const targetLiqUtilizationRate = fromBps(targetLiqUtilizationRateBps); - - const debtAdjustmentUsd = - (targetLiqUtilizationRate * supplyUsd * liqThreshold - debtUsd) / - (1 - targetLiqUtilizationRate * (1 - adjustmentFee) * liqThreshold); - return debtAdjustmentUsd; -} - -export function getSolautoFeesBps( - isReferred: boolean, - targetLiqUtilizationRateBps: number | undefined, - positionNetWorthUsd: number, - rebalanceDirection: RebalanceDirection -): { - solauto: number; - referrer: number; - total: number; -} { - const minSize = 10_000; // Minimum position size - const maxSize = 250_000; // Maximum position size - const maxFeeBps = 50; // Fee in basis points for minSize (0.5%) - const minFeeBps = 25; // Fee in basis points for maxSize (0.25%) - const k = 1.5; - - if ( - targetLiqUtilizationRateBps !== undefined && - targetLiqUtilizationRateBps === 0 - ) { - return { - solauto: 0, - referrer: 0, - total: 0, - }; - } - - let feeBps: number = 0; - - if ( - targetLiqUtilizationRateBps !== undefined || - rebalanceDirection === RebalanceDirection.Repay - ) { - feeBps = 25; - } else if (positionNetWorthUsd <= minSize) { - feeBps = maxFeeBps; - } else if (positionNetWorthUsd >= maxSize) { - feeBps = minFeeBps; - } else { - const t = - (Math.log(positionNetWorthUsd) - Math.log(minSize)) / - (Math.log(maxSize) - Math.log(minSize)); - feeBps = Math.round( - minFeeBps + (maxFeeBps - minFeeBps) * (1 - Math.pow(t, k)) - ); - } - - let referrer = 0; - if (isReferred) { - feeBps *= 0.9; - referrer = Math.floor(feeBps * 0.15); - } - - return { - solauto: feeBps - referrer, - referrer, - total: feeBps, - }; -} - export function getMaxLiqUtilizationRateBps( maxLtvBps: number, liqThresholdBps: number, @@ -167,20 +184,34 @@ export function getMaxLiqUtilizationRateBps( export function maxRepayFromBps(maxLtvBps: number, liqThresholdBps: number) { return Math.min( 9000, - getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps - 1000, 0.01) + getMaxLiqUtilizationRateBps( + maxLtvBps, + liqThresholdBps - 1000, + OFFSET_FROM_MAX_LTV + ) ); } export function maxRepayToBps(maxLtvBps: number, liqThresholdBps: number) { return Math.min( maxRepayFromBps(maxLtvBps, liqThresholdBps) - MIN_REPAY_GAP_BPS, - getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps, 0.01) + getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps, OFFSET_FROM_MAX_LTV) ); } export function maxBoostToBps(maxLtvBps: number, liqThresholdBps: number) { return Math.min( maxRepayToBps(maxLtvBps, liqThresholdBps), - getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps, 0.01) + getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps, OFFSET_FROM_MAX_LTV) + ); +} + +export function realtimeUsdToEmaUsd( + realtimeAmountUsd: number, + mint: PublicKey +) { + return ( + (realtimeAmountUsd / safeGetPrice(mint, PriceType.Realtime)!) * + safeGetPrice(mint, PriceType.Ema)! ); } diff --git a/solauto-sdk/src/utils/priceUtils.ts b/solauto-sdk/src/utils/priceUtils.ts index 8f286116..dffa57b1 100644 --- a/solauto-sdk/src/utils/priceUtils.ts +++ b/solauto-sdk/src/utils/priceUtils.ts @@ -1,60 +1,85 @@ import { PublicKey } from "@solana/web3.js"; import { PublicKey as UmiPublicKey } from "@metaplex-foundation/umi"; -import { PYTH_PRICE_FEED_IDS } from "../constants/pythConstants"; +import * as SwbCommon from "@switchboard-xyz/common"; +import { + PYTH_PRICE_FEED_IDS, + PRICES, + SWITCHBOARD_PRICE_FEED_IDS, +} from "../constants"; import { fromBaseUnit, toBaseUnit } from "./numberUtils"; -import { PRICES } from "../constants/solautoConstants"; -import { SWITCHBOARD_PRICE_FEED_IDS } from "../constants/switchboardConstants"; import { consoleLog, + createRecord, currentUnixSeconds, retryWithExponentialBackoff, - zip, + tokenInfo, } from "./generalUtils"; -import * as OnDemand from "@switchboard-xyz/on-demand"; import { getJupPriceData } from "./jupiterUtils"; +import { PriceType } from "../generated"; +import { PriceBias } from "../marginfi-sdk"; + +interface PriceResult { + realtimePrice: number; + confInterval?: number; + emaPrice?: number; + emaConfInterval?: number; +} -export async function fetchTokenPrices(mints: PublicKey[]): Promise { +export async function fetchTokenPrices( + mints: PublicKey[], + priceType: PriceType = PriceType.Realtime, + priceBias?: PriceBias +): Promise { const currentTime = currentUnixSeconds(); - if ( - !mints.some( - (mint) => - !(mint.toString() in PRICES) || - currentTime - PRICES[mint.toString()].time > 3 + const mintStrs = mints.map((x) => x.toString()); + const cachedPrices: Record = Object.fromEntries( + Object.entries(PRICES).filter( + ([mint, price]) => + mintStrs.includes(mint) && currentTime - price.time <= 3 ) - ) { - return mints.map((mint) => PRICES[mint.toString()].price); - } - - const pythMints = mints.filter((x) => x.toString() in PYTH_PRICE_FEED_IDS); - const switchboardMints = mints.filter( - (x) => x.toString() in SWITCHBOARD_PRICE_FEED_IDS ); - const [pythData, switchboardData] = await Promise.all([ - zip(pythMints, await getPythPrices(pythMints)), - zip(switchboardMints, await getSwitchboardPrices(switchboardMints)), - ]); - - const prices = mints.map((mint) => { - const item = [...pythData, ...switchboardData].find((data) => - data[0].equals(mint) - ); - return item ? item[1] : 0; - }); + const newMints = mintStrs + .filter((x) => !Object.keys(cachedPrices).includes(x)) + .map((x) => new PublicKey(x)); + const pythMints = newMints.filter((x) => + Object.keys(PYTH_PRICE_FEED_IDS).includes(x.toString()) + ); + const switchboardMints = newMints.filter((x) => + Object.keys(SWITCHBOARD_PRICE_FEED_IDS).includes(x.toString()) + ); + const otherMints = newMints.filter( + (x) => !pythMints.includes(x) && !switchboardMints.includes(x) + ); + const newPrices: Record = Object.assign( + {}, + ...(await Promise.all([ + getPythPrices(pythMints), + getSwitchboardPrices(switchboardMints), + getJupTokenPrices(otherMints), + ])) + ); - for (var i = 0; i < mints.length; i++) { - PRICES[mints[i].toString()] = { - price: Number(prices[i]), + for (const mint of newMints) { + const data = newPrices[mint.toString()]; + const realtimePrice = data.realtimePrice; + PRICES[mint.toString()] = { + realtimePrice, + confInterval: data.confInterval ?? 0, + emaPrice: data.emaPrice ?? realtimePrice, + emaConfInterval: data.emaConfInterval ?? 0, time: currentUnixSeconds(), }; } - return prices; + return mints.map((x) => safeGetPrice(x, priceType, priceBias)!); } -export async function getPythPrices(mints: PublicKey[]) { +export async function getPythPrices( + mints: PublicKey[] +): Promise> { if (mints.length === 0) { - return []; + return {}; } const priceFeedIds = mints.map( @@ -66,7 +91,17 @@ export async function getPythPrices(mints: PublicKey[]) { `https://hermes.pyth.network/v2/updates/price/latest?${priceFeedIds.map((x) => `ids%5B%5D=${x}`).join("&")}` ); - const prices: number[] = await retryWithExponentialBackoff( + const deriveValue = (price: number, exponent: number) => { + if (exponent > 0) { + return Number(toBaseUnit(Number(price), exponent)); + } else if (exponent < 0) { + return fromBaseUnit(BigInt(price), Math.abs(exponent)); + } else { + return Number(price); + } + }; + + const prices: PriceResult[] = await retryWithExponentialBackoff( async () => { let resp = await getReq(); let status = resp.status; @@ -76,13 +111,13 @@ export async function getPythPrices(mints: PublicKey[]) { const json = await resp.json(); const prices = json.parsed.map((x: any) => { - if (x.price.expo > 0) { - return Number(toBaseUnit(Number(x.price.price), x.price.expo)); - } else if (x.price.expo < 0) { - return fromBaseUnit(BigInt(x.price.price), Math.abs(x.price.expo)); - } else { - return Number(x.price.price); - } + return { + realtimePrice: deriveValue(x.price.price, x.price.expo), + confInterval: deriveValue(x.price.conf, x.price.expo) * 2.12, + emaPrice: deriveValue(x.ema_price.price, x.ema_price.expo), + emaConfInterval: + deriveValue(x.ema_price.conf, x.ema_price.expo) * 2.12, + }; }); return prices; @@ -91,34 +126,66 @@ export async function getPythPrices(mints: PublicKey[]) { 200 ); - return prices; + return createRecord( + mints.map((x) => x.toString()), + prices + ); +} + +function getSortedPriceData( + prices: Record, + mints: PublicKey[] +) { + const sortedPrices: { [key: string]: any } = {}; + + for (const mint of mints) { + const key = mint.toString(); + if (prices.hasOwnProperty(key)) { + sortedPrices[key] = prices[key]; + } + } + + return sortedPrices; } export async function getSwitchboardPrices( mints: PublicKey[] -): Promise { +): Promise> { if (mints.length === 0) { - return []; + return {}; } - const { CrossbarClient } = OnDemand; + const { CrossbarClient } = SwbCommon; const crossbar = CrossbarClient.default(); - let prices: number[] = []; + let prices: Record = {}; try { prices = await retryWithExponentialBackoff( async () => { - const res = await crossbar.simulateSolanaFeeds( - "mainnet", - mints.map((x) => SWITCHBOARD_PRICE_FEED_IDS[x.toString()]) + const resp = await crossbar.simulateFeeds( + mints.map((x) => SWITCHBOARD_PRICE_FEED_IDS[x.toString()].feedHash) ); - - const p = res.flatMap((x) => x.results[0]); - if (p.filter((x) => !x || isNaN(Number(x))).length > 0) { + + const data = resp.flatMap((x) => x.results[0]); + if ( + data.filter((x) => !x || isNaN(Number(x)) || Number(x) <= 0).length > + 0 + ) { throw new Error("Unable to fetch Switchboard prices"); } - - return p; + + const finalMap: Record = {}; + for (const item of resp) { + for (const [k, v] of Object.entries(SWITCHBOARD_PRICE_FEED_IDS)) { + if (item.feedHash === v.feedHash) { + const price = Number(item.results[0]); + finalMap[k] = { + realtimePrice: price, + }; + } + } + } + return finalMap; }, 2, 350 @@ -127,42 +194,62 @@ export async function getSwitchboardPrices( consoleLog("Failed to fetch Switchboard prices after multiple retries"); } - if (prices.length === 0) { - prices = Array(mints.length).fill(0); - } - - const missingPrices = zip(mints, prices).filter((x) => !x[1] || isNaN(Number(x))); - const jupPrices = zip( - missingPrices.map((x) => x[0]), - await getJupTokenPrices(missingPrices.map((x) => x[0])) - ); - - prices = prices.map((x, i) => - x ? x : jupPrices.find((y) => y[0].toString() === mints[i].toString())![1] + const missingMints = mints.filter((x) => !prices[x.toString()]); + const jupPrices = await getJupTokenPrices( + missingMints.map((x) => new PublicKey(x)) ); - return prices; + return { ...prices, ...jupPrices }; } -export async function getJupTokenPrices(mints: PublicKey[]) { +export async function getJupTokenPrices( + mints: PublicKey[] +): Promise> { if (mints.length == 0) { - return []; + return {}; } - const data = await getJupPriceData(mints); + const data = getSortedPriceData(await getJupPriceData(mints), mints); - const prices = Object.values(data).map( - (x) => parseFloat(x.price as string) as number + const prices: Record = Object.fromEntries( + Object.entries(data).map(([mint, x]) => [ + mint, + x !== null && typeof x === "object" && "price" in x + ? { realtimePrice: parseFloat(x.price as string) } + : { realtimePrice: 0 }, + ]) ); return prices; } export function safeGetPrice( - mint: PublicKey | UmiPublicKey | undefined + mint: PublicKey | UmiPublicKey | string | undefined, + priceType: PriceType = PriceType.Realtime, + priceBias?: PriceBias ): number | undefined { if (mint && mint?.toString() in PRICES) { - return PRICES[mint!.toString()].price; + const priceData = PRICES[mint!.toString()]; + let price = + priceType === PriceType.Ema + ? priceData.emaPrice + : priceData.realtimePrice; + + if (priceBias !== undefined) { + const confInterval = + priceType === PriceType.Ema + ? priceData.emaConfInterval + : priceData.confInterval; + const conf = Math.min(confInterval, price * 0.05); + + if (priceBias === PriceBias.Low) { + price -= conf; + } else { + price += conf; + } + } + + return price; } return undefined; } diff --git a/solauto-sdk/src/utils/pythUtils.ts b/solauto-sdk/src/utils/pythUtils.ts new file mode 100644 index 00000000..95f6d751 --- /dev/null +++ b/solauto-sdk/src/utils/pythUtils.ts @@ -0,0 +1,37 @@ +import { PublicKey } from "@solana/web3.js"; +import { publicKey, Umi } from "@metaplex-foundation/umi"; +import { PYTH_PUSH_PROGRAM } from "../constants"; +import { u16ToArrayBufferLE, zip } from "./generalUtils"; +import { safeFetchAllPriceUpdateV2Account } from "../pyth-sdk"; + +export async function getMostUpToDatePythOracle( + umi: Umi, + oracleKeys: PublicKey[] +) { + const oracles = zip( + oracleKeys, + await safeFetchAllPriceUpdateV2Account( + umi, + oracleKeys.map((x) => publicKey(x)), + { commitment: "confirmed" } + ) + ).sort( + (a, b) => + Number(b[1]?.priceMessage.publishTime ?? 0) - + Number(a[1]?.priceMessage.publishTime ?? 0) + ); + + return oracles[0][0]; +} + +export function getPythPushOracleAddress( + feedId: PublicKey, + shardId: number, + programId: PublicKey = PYTH_PUSH_PROGRAM +): PublicKey { + const shardBytes = u16ToArrayBufferLE(shardId); + return PublicKey.findProgramAddressSync( + [shardBytes, feedId.toBuffer()], + programId + )[0]; +} diff --git a/solauto-sdk/src/utils/solanaUtils.ts b/solauto-sdk/src/utils/solanaUtils.ts index d19a925f..4abdeb2c 100644 --- a/solauto-sdk/src/utils/solanaUtils.ts +++ b/solauto-sdk/src/utils/solanaUtils.ts @@ -1,19 +1,4 @@ import bs58 from "bs58"; -import { - AddressLookupTableInput, - Signer, - TransactionBuilder, - Umi, - WrappedInstruction, - publicKey, - transactionBuilder, -} from "@metaplex-foundation/umi"; -import { - fromWeb3JsInstruction, - toWeb3JsPublicKey, - toWeb3JsTransaction, -} from "@metaplex-foundation/umi-web3js-adapters"; -import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; import { AddressLookupTableAccount, BlockhashWithExpiryBlockHeight, @@ -32,36 +17,51 @@ import { createCloseAccountInstruction, createTransferInstruction, } from "@solana/spl-token"; +import { + AccountMeta, + AddressLookupTableInput, + Signer, + TransactionBuilder, + Umi, + WrappedInstruction, + publicKey, + transactionBuilder, +} from "@metaplex-foundation/umi"; +import { + fromWeb3JsInstruction, + fromWeb3JsPublicKey, + toWeb3JsPublicKey, + toWeb3JsTransaction, +} from "@metaplex-foundation/umi-web3js-adapters"; +import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; +import { PriorityFeeSetting, ProgramEnv, TransactionRunType } from "../types"; +import { + getLendingAccountEndFlashloanInstructionDataSerializer, + getLendingAccountStartFlashloanInstructionDataSerializer, +} from "../marginfi-sdk"; import { getTokenAccount } from "./accountUtils"; import { arraysAreEqual, consoleLog, + customRpcCall, retryWithExponentialBackoff, } from "./generalUtils"; -import { - getLendingAccountEndFlashloanInstructionDataSerializer, - getLendingAccountStartFlashloanInstructionDataSerializer, -} from "../marginfi-sdk"; -import { PriorityFeeSetting, TransactionRunType } from "../types"; -import { createDynamicSolautoProgram } from "./solauto"; -import { SOLAUTO_PROD_PROGRAM } from "../constants"; - -export function buildHeliusApiUrl(heliusApiKey: string) { - return `https://mainnet.helius-rpc.com/?api-key=${heliusApiKey}`; -} - -export function buildIronforgeApiUrl(ironforgeApiKey: string) { - return `https://rpc.ironforge.network/mainnet?apiKey=${ironforgeApiKey}`; -} +import { createDynamicSolautoProgram } from "./solautoUtils"; +import { createDynamicMarginfiProgram } from "./marginfi"; +import { usePriorityFee } from "../services"; export function getSolanaRpcConnection( rpcUrl: string, - programId: PublicKey = SOLAUTO_PROD_PROGRAM + programId?: PublicKey, + lpEnv?: ProgramEnv ): [Connection, Umi] { - const connection = new Connection(rpcUrl, "confirmed"); + const connection = new Connection(rpcUrl, { + commitment: "confirmed", + }); const umi = createUmi(connection).use({ install(umi) { umi.programs.add(createDynamicSolautoProgram(programId), false); + umi.programs.add(createDynamicMarginfiProgram(lpEnv), false); }, }); return [connection, umi]; @@ -157,6 +157,34 @@ export function splTokenTransferUmiIx( ); } +export function getAccountMeta( + pubkey: PublicKey, + isSigner: boolean = false, + isWritable: boolean = false +): AccountMeta { + return { pubkey: fromWeb3JsPublicKey(pubkey), isSigner, isWritable }; +} + +export async function getWalletSplBalances( + conn: Connection, + wallet: PublicKey, + tokenMints: PublicKey[] +): Promise { + return await Promise.all( + tokenMints.map(async (mint) => { + try { + const data = await conn.getTokenAccountBalance( + getTokenAccount(wallet, mint), + "confirmed" + ); + return BigInt(data.value.amount); + } catch { + return 0n; + } + }) + ); +} + export async function getAddressLookupInputs( umi: Umi, lookupTableAddresses: string[] @@ -182,32 +210,41 @@ export async function getAddressLookupInputs( } export function addTxOptimizations( - signer: Signer, - transaction: TransactionBuilder, + umi: Umi, + tx: TransactionBuilder, computeUnitPrice?: number, computeUnitLimit?: number ) { - return transaction - .prepend( - computeUnitPrice !== undefined - ? setComputeUnitPriceUmiIx(signer, computeUnitPrice) - : transactionBuilder() - ) - .prepend( - computeUnitLimit - ? setComputeUnitLimitUmiIx(signer, computeUnitLimit) - : transactionBuilder() - ); + const computePriceIx = + computeUnitPrice !== undefined + ? setComputeUnitPriceUmiIx(umi.identity, computeUnitPrice) + : transactionBuilder(); + const computeLimitIx = computeUnitLimit + ? setComputeUnitLimitUmiIx(umi.identity, computeUnitLimit) + : transactionBuilder(); + + const allOptimizations = tx.prepend(computePriceIx).prepend(computeLimitIx); + const withCuPrice = tx.prepend(computePriceIx); + const withCuLimit = tx.prepend(computeLimitIx); + if (allOptimizations.fitsInOneTransaction(umi)) { + return allOptimizations; + } else if (withCuPrice.fitsInOneTransaction(umi)) { + return withCuPrice; + } else if (withCuLimit.fitsInOneTransaction(umi)) { + return withCuLimit; + } else { + return tx; + } } export function assembleFinalTransaction( - signer: Signer, + umi: Umi, transaction: TransactionBuilder, computeUnitPrice?: number, computeUnitLimit?: number ) { const tx = addTxOptimizations( - signer, + umi, transaction, computeUnitPrice, computeUnitLimit @@ -286,6 +323,17 @@ async function simulateTransaction( return simulationResult; } +export async function getQnComputeUnitPriceEstimate( + umi: Umi, + programId: PublicKey, + blockheight: number = 50 +): Promise { + return await customRpcCall(umi, "qn_estimatePriorityFees", { + last_n_blocks: blockheight, + account: programId.toString(), + }); +} + export async function getComputeUnitPriceEstimate( umi: Umi, tx: TransactionBuilder, @@ -300,14 +348,25 @@ export async function getComputeUnitPriceEstimate( .getInstructions() .flatMap((x) => x.keys.flatMap((x) => x.pubkey.toString())); - let feeEstimate: number | undefined; + let feeEstimate: number | undefined; + try { + const resp = await customRpcCall(umi, "getPriorityFeeEstimate", [ + { + transaction: !useAccounts + ? bs58.encode(web3Transaction.serialize()) + : undefined, + accountKeys: useAccounts ? accountKeys : undefined, + options: { + priorityLevel: prioritySetting.toString(), + }, + }, + ]); + feeEstimate = Math.round((resp as any).priorityFeeEstimate as number); + } catch (e) { try { - const resp = await umi.rpc.call("getPriorityFeeEstimate", [ + const resp = await customRpcCall(umi, "getPriorityFeeEstimate", [ { - transaction: !useAccounts - ? bs58.encode(web3Transaction.serialize()) - : undefined, - accountKeys: useAccounts ? accountKeys : undefined, + accountKeys, options: { priorityLevel: prioritySetting.toString(), }, @@ -315,20 +374,9 @@ export async function getComputeUnitPriceEstimate( ]); feeEstimate = Math.round((resp as any).priorityFeeEstimate as number); } catch (e) { - try { - const resp = await umi.rpc.call("getPriorityFeeEstimate", [ - { - accountKeys, - options: { - priorityLevel: prioritySetting.toString(), - }, - }, - ]); - feeEstimate = Math.round((resp as any).priorityFeeEstimate as number); - } catch (e) { - // console.error(e); - } + // console.error(e); } + } return feeEstimate; } @@ -349,9 +397,7 @@ async function spamSendTransactionUntilConfirmed( ); transactionSignature = txSignature; consoleLog(`Transaction sent`); - } catch (error) { - consoleLog("Error sending transaction:", error); - } + } catch (e) {} }; await sendTx(); @@ -386,11 +432,16 @@ export async function sendSingleOptimizedTransaction( tx: TransactionBuilder, txType?: TransactionRunType, prioritySetting: PriorityFeeSetting = PriorityFeeSetting.Min, - onAwaitingSign?: () => void + onAwaitingSign?: () => void, + abortController?: AbortController ): Promise { consoleLog("Sending single optimized transaction..."); consoleLog("Instructions: ", tx.getInstructions().length); consoleLog("Serialized transaction size: ", tx.getTransactionSize(umi)); + consoleLog( + "Programs: ", + tx.getInstructions().map((x) => x.programId) + ); const accounts = tx .getInstructions() @@ -402,44 +453,39 @@ export async function sendSingleOptimizedTransaction( const blockhash = await connection.getLatestBlockhash("confirmed"); - let computeUnitLimit = undefined; + if (abortController?.signal.aborted) { + return; + } + let cuLimit = undefined; if (txType !== "skip-simulation") { const simulationResult = await retryWithExponentialBackoff( async () => await simulateTransaction( umi, connection, - assembleFinalTransaction( - umi.identity, - tx, - undefined, - 1_400_000 - ).setBlockhash(blockhash) + assembleFinalTransaction(umi, tx, undefined, 1_400_000).setBlockhash( + blockhash + ) ), - 3 + 2 ); - computeUnitLimit = Math.round(simulationResult.value.unitsConsumed! * 1.15); - consoleLog("Compute unit limit: ", computeUnitLimit); + cuLimit = Math.round(simulationResult.value.unitsConsumed! * 1.15); + consoleLog("Compute unit limit: ", cuLimit); } let cuPrice: number | undefined; - if (prioritySetting !== PriorityFeeSetting.None) { + if (usePriorityFee(prioritySetting)) { cuPrice = await getComputeUnitPriceEstimate(umi, tx, prioritySetting); - if (!cuPrice) { - cuPrice = 1_000_000; - } - cuPrice = Math.min(cuPrice, 100 * 1_000_000); + cuPrice = Math.min(cuPrice ?? 0, 100_000_000); consoleLog("Compute unit price: ", cuPrice); } + if (abortController?.signal.aborted) { + return; + } if (txType !== "only-simulate") { onAwaitingSign?.(); - const signedTx = await assembleFinalTransaction( - umi.identity, - tx, - cuPrice, - computeUnitLimit - ) + const signedTx = await assembleFinalTransaction(umi, tx, cuPrice, cuLimit) .setBlockhash(blockhash) .buildAndSign(umi); const txSig = await spamSendTransactionUntilConfirmed( diff --git a/solauto-sdk/src/utils/solauto/index.ts b/solauto-sdk/src/utils/solauto/index.ts deleted file mode 100644 index 80df64d0..00000000 --- a/solauto-sdk/src/utils/solauto/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './generalUtils'; -export * from './rebalanceUtils'; \ No newline at end of file diff --git a/solauto-sdk/src/utils/solauto/rebalanceUtils.ts b/solauto-sdk/src/utils/solauto/rebalanceUtils.ts deleted file mode 100644 index 8befbe21..00000000 --- a/solauto-sdk/src/utils/solauto/rebalanceUtils.ts +++ /dev/null @@ -1,410 +0,0 @@ -import { PublicKey } from "@solana/web3.js"; -import { SolautoClient } from "../../clients/solautoClient"; -import { - DCASettings, - PositionState, - PositionTokenUsage, - RebalanceDirection, - SolautoSettingsParameters, - TokenType, -} from "../../generated"; -import { - eligibleForNextAutomationPeriod, - getAdjustedSettingsFromAutomation, - getUpdatedValueFromAutomation, -} from "./generalUtils"; -import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; -import { QuoteResponse } from "@jup-ag/api"; -import { JupSwapDetails } from "../jupiterUtils"; -import { consoleLog, currentUnixSeconds } from "../generalUtils"; -import { - fromBaseUnit, - fromBps, - getDebtAdjustmentUsd, - getLiqUtilzationRateBps, - getMaxLiqUtilizationRateBps, - getSolautoFeesBps, - maxRepayToBps, - toBaseUnit, -} from "../numberUtils"; -import { USD_DECIMALS } from "../../constants/generalAccounts"; -import { RebalanceAction } from "../../types"; -import { safeGetPrice } from "../priceUtils"; -import { TOKEN_INFO } from "../../constants"; - -function getAdditionalAmountToDcaIn(dca: DCASettings): number { - if (dca.dcaInBaseUnit === BigInt(0)) { - return 0; - } - - const debtBalance = Number(dca.dcaInBaseUnit); - const updatedDebtBalance = getUpdatedValueFromAutomation( - debtBalance, - 0, - dca.automation, - currentUnixSeconds() - ); - - return debtBalance - updatedDebtBalance; -} - -function getStandardTargetLiqUtilizationRateBps( - state: PositionState, - settings: SolautoSettingsParameters -): number { - const adjustedSettings = getAdjustedSettingsFromAutomation( - settings, - currentUnixSeconds() - ); - - const repayFrom = settings.repayToBps + settings.repayGap; - const boostFrom = adjustedSettings.boostToBps - settings.boostGap; - - if (state.liqUtilizationRateBps <= boostFrom) { - return adjustedSettings.boostToBps; - } else if (state.liqUtilizationRateBps >= repayFrom) { - return adjustedSettings.repayToBps; - } else { - throw new Error("Invalid rebalance condition"); - } -} - -function targetLiqUtilizationRateBpsFromDCA( - state: PositionState, - settings: SolautoSettingsParameters, - dca: DCASettings, - currentUnixTime: number -) { - const adjustedSettings = getAdjustedSettingsFromAutomation( - settings, - currentUnixTime - ); - - let targetRateBps = 0; - if (dca.dcaInBaseUnit > BigInt(0)) { - targetRateBps = Math.max( - state.liqUtilizationRateBps, - adjustedSettings.boostToBps - ); - } else { - targetRateBps = adjustedSettings.boostToBps; - } - return targetRateBps; -} - -function isDcaRebalance( - state: PositionState, - settings: SolautoSettingsParameters, - dca: DCASettings | undefined, - currentUnixTime: number -): boolean { - if (dca === undefined || dca.automation.targetPeriods === 0) { - return false; - } - - const adjustedSettings = getAdjustedSettingsFromAutomation( - settings, - currentUnixTime - ); - - if ( - state.liqUtilizationRateBps > - adjustedSettings.repayToBps + adjustedSettings.repayGap - ) { - return false; - } - - if (!eligibleForNextAutomationPeriod(dca.automation, currentUnixTime)) { - return false; - } - - return true; -} - -function getTargetRateAndDcaAmount( - state: PositionState, - settings: SolautoSettingsParameters | undefined, - dca: DCASettings | undefined, - currentUnixTime: number, - targetLiqUtilizationRateBps?: number -): { targetRateBps: number; amountToDcaIn?: number } { - if (targetLiqUtilizationRateBps !== undefined) { - return { - targetRateBps: targetLiqUtilizationRateBps, - }; - } - - if (settings === undefined) { - throw new Error( - "If rebalancing a self-managed position, settings and DCA should be provided" - ); - } - - if (isDcaRebalance(state, settings, dca, currentUnixTime)) { - const targetLiqUtilizationRateBps = targetLiqUtilizationRateBpsFromDCA( - state, - settings, - dca!, - currentUnixTime - ); - const amountToDcaIn = getAdditionalAmountToDcaIn(dca!); - - return { - targetRateBps: targetLiqUtilizationRateBps, - amountToDcaIn, - }; - } else { - return { - targetRateBps: getStandardTargetLiqUtilizationRateBps(state, settings), - }; - } -} - -export interface RebalanceValues { - debtAdjustmentUsd: number; - repayingCloseToMaxLtv: boolean; - amountToDcaIn: number; - amountUsdToDcaIn: number; - dcaTokenType?: TokenType; - rebalanceAction: RebalanceAction; - rebalanceDirection: RebalanceDirection; - feesUsd: number; -} - -export function getRebalanceValues( - state: PositionState, - settings: SolautoSettingsParameters | undefined, - dca: DCASettings | undefined, - currentUnixTime: number, - supplyPrice: number, - debtPrice: number, - targetLiqUtilizationRateBps?: number -): RebalanceValues { - const { targetRateBps, amountToDcaIn } = getTargetRateAndDcaAmount( - state, - settings, - dca, - currentUnixTime, - targetLiqUtilizationRateBps - ); - - const amountUsdToDcaIn = - fromBaseUnit(BigInt(Math.round(amountToDcaIn ?? 0)), state.debt.decimals) * - (dca?.tokenType === TokenType.Debt ? debtPrice : supplyPrice); - - const rebalanceDirection = - amountUsdToDcaIn > 0 || state.liqUtilizationRateBps <= targetRateBps - ? RebalanceDirection.Boost - : RebalanceDirection.Repay; - const adjustmentFeeBps = getSolautoFeesBps( - false, - targetLiqUtilizationRateBps, - fromBaseUnit(state.netWorth.baseAmountUsdValue, USD_DECIMALS), - rebalanceDirection - ).total; - - const supplyUsd = - fromBaseUnit(state.supply.amountUsed.baseAmountUsdValue, USD_DECIMALS) + - amountUsdToDcaIn; - const debtUsd = fromBaseUnit( - state.debt.amountUsed.baseAmountUsdValue, - USD_DECIMALS - ); - let debtAdjustmentUsd = getDebtAdjustmentUsd( - state.liqThresholdBps, - supplyUsd, - debtUsd, - targetRateBps, - adjustmentFeeBps - ); - - const maxRepayTo = maxRepayToBps(state.maxLtvBps, state.liqThresholdBps); - return { - debtAdjustmentUsd, - repayingCloseToMaxLtv: - state.liqUtilizationRateBps > maxRepayTo && targetRateBps >= maxRepayTo, - amountToDcaIn: amountToDcaIn ?? 0, - amountUsdToDcaIn, - dcaTokenType: dca?.tokenType, - rebalanceAction: - (amountToDcaIn ?? 0) > 0 - ? "dca" - : rebalanceDirection === RebalanceDirection.Boost - ? "boost" - : "repay", - rebalanceDirection, - feesUsd: Math.abs(debtAdjustmentUsd * fromBps(adjustmentFeeBps)), - }; -} - -export function rebalanceRequiresFlashLoan( - client: SolautoClient, - values: RebalanceValues -) { - let supplyUsd = - fromBaseUnit( - client.solautoPositionState!.supply.amountUsed.baseAmountUsdValue, - USD_DECIMALS - ) + - (values.dcaTokenType === TokenType.Supply ? values.amountUsdToDcaIn : 0); - let debtUsd = fromBaseUnit( - client.solautoPositionState!.debt.amountUsed.baseAmountUsdValue, - USD_DECIMALS - ); - - const debtAdjustmentUsdAbs = Math.abs(values.debtAdjustmentUsd); - supplyUsd = - values.rebalanceDirection === RebalanceDirection.Repay - ? supplyUsd - debtAdjustmentUsdAbs - : supplyUsd; - debtUsd = - values.rebalanceDirection === RebalanceDirection.Boost - ? debtUsd + debtAdjustmentUsdAbs - : debtUsd; - - const tempLiqUtilizationRateBps = getLiqUtilzationRateBps( - supplyUsd, - debtUsd, - client.solautoPositionState!.liqThresholdBps - ); - const maxLiqUtilizationRateBps = getMaxLiqUtilizationRateBps( - client.solautoPositionState!.maxLtvBps, - client.solautoPositionState!.liqThresholdBps, - 0.02 - ); - const requiresFlashLoan = - supplyUsd <= 0 || tempLiqUtilizationRateBps > maxLiqUtilizationRateBps; - - consoleLog("Requires flash loan:", requiresFlashLoan); - consoleLog( - "Intermediary liq utilization rate:", - tempLiqUtilizationRateBps, - `$${supplyUsd}`, - `$${debtUsd}`, - "Max:", - maxLiqUtilizationRateBps - ); - - const useDebtLiquidity = - Math.abs(values.debtAdjustmentUsd) * 1.1 <= - fromBaseUnit( - client.solautoPositionState?.debt.amountCanBeUsed.baseAmountUsdValue ?? - BigInt(0), - USD_DECIMALS - ); - return { requiresFlashLoan, useDebtLiquidity }; -} - -export interface FlashLoanDetails { - baseUnitAmount: bigint; - mint: PublicKey; - useDebtLiquidity: boolean; -} - -export function getFlashLoanDetails( - client: SolautoClient, - values: RebalanceValues, - jupQuote: QuoteResponse -): FlashLoanDetails | undefined { - const { requiresFlashLoan, useDebtLiquidity } = rebalanceRequiresFlashLoan( - client, - values - ); - - let flashLoanToken: PositionTokenUsage | undefined = undefined; - let flashLoanTokenPrice = 0; - - const inAmount = BigInt(parseInt(jupQuote.inAmount)); - const outAmount = BigInt(parseInt(jupQuote.outAmount)); - - const boosting = values.rebalanceDirection === RebalanceDirection.Boost; - if (boosting || useDebtLiquidity) { - flashLoanToken = client.solautoPositionState!.debt; - flashLoanTokenPrice = safeGetPrice(client.debtMint)!; - } else { - flashLoanToken = client.solautoPositionState!.supply; - flashLoanTokenPrice = safeGetPrice(client.supplyMint)!; - } - - if (jupQuote.swapMode !== "ExactOut" && jupQuote.swapMode !== "ExactIn") { - throw new Error("Token ledger swap not currently supported"); - } - - const baseUnitAmount = - boosting || (!boosting && !useDebtLiquidity) ? inAmount : outAmount; - - return requiresFlashLoan - ? { - baseUnitAmount, - mint: toWeb3JsPublicKey(flashLoanToken.mint), - useDebtLiquidity, - } - : undefined; -} - -export function getJupSwapRebalanceDetails( - client: SolautoClient, - values: RebalanceValues, - targetLiqUtilizationRateBps?: number, - attemptNum?: number -): JupSwapDetails { - const input = - values.rebalanceDirection === RebalanceDirection.Boost - ? client.solautoPositionState!.debt - : client.solautoPositionState!.supply; - const output = - values.rebalanceDirection === RebalanceDirection.Boost - ? client.solautoPositionState!.supply - : client.solautoPositionState!.debt; - - const usdToSwap = - Math.abs(values.debtAdjustmentUsd) + - (values.dcaTokenType === TokenType.Debt ? values.amountUsdToDcaIn : 0); - - const inputAmount = toBaseUnit( - usdToSwap / safeGetPrice(input.mint)!, - input.decimals - ); - const outputAmount = - targetLiqUtilizationRateBps === 0 - ? output.amountUsed.baseUnit + - BigInt( - Math.round( - Number(output.amountUsed.baseUnit) * - // Add this small percentage to account for the APR on the debt between now and the transaction - 0.0001 - ) - ) - : toBaseUnit(usdToSwap / safeGetPrice(output.mint)!, output.decimals); - - const repaying = values.rebalanceDirection === RebalanceDirection.Repay; - - const { requiresFlashLoan, useDebtLiquidity } = rebalanceRequiresFlashLoan( - client, - values - ); - const flashLoanRepayFromDebt = - repaying && requiresFlashLoan && useDebtLiquidity; - - const exactOut = - targetLiqUtilizationRateBps === 0 || - values.repayingCloseToMaxLtv || - flashLoanRepayFromDebt; - const exactIn = !exactOut; - - // const addPadding = targetLiqUtilizationRateBps === 0; - const addPadding = exactOut; - - return { - inputMint: toWeb3JsPublicKey(input.mint), - outputMint: toWeb3JsPublicKey(output.mint), - destinationWallet: flashLoanRepayFromDebt - ? toWeb3JsPublicKey(client.signer.publicKey) - : client.solautoPosition, - slippageIncFactor: 0.2 + (attemptNum ?? 0) * 0.25, - amount: exactOut ? outputAmount : inputAmount, - exactIn: exactIn, - exactOut: exactOut, - addPadding, - }; -} diff --git a/solauto-sdk/src/utils/solauto/generalUtils.ts b/solauto-sdk/src/utils/solautoUtils.ts similarity index 53% rename from solauto-sdk/src/utils/solauto/generalUtils.ts rename to solauto-sdk/src/utils/solautoUtils.ts index a183e63f..f98ef1f4 100644 --- a/solauto-sdk/src/utils/solauto/generalUtils.ts +++ b/solauto-sdk/src/utils/solautoUtils.ts @@ -1,11 +1,7 @@ import { PublicKey } from "@solana/web3.js"; -import { - isOption, - isSome, - Program, - publicKey, - Umi, -} from "@metaplex-foundation/umi"; +import { Program, publicKey, Umi } from "@metaplex-foundation/umi"; +import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; +import { QuoteResponse } from "@jup-ag/api"; import { AutomationSettings, DCASettings, @@ -13,6 +9,7 @@ import { LendingPlatform, PositionState, PositionType, + SolautoRebalanceType, SolautoSettingsParameters, SolautoSettingsParametersInpArgs, TokenType, @@ -21,34 +18,39 @@ import { getSolautoErrorFromName, getSolautoPositionAccountDataSerializer, getSolautoPositionSize, -} from "../../generated"; -import { consoleLog, currentUnixSeconds } from "../generalUtils"; +} from "../generated"; +import { ALL_SUPPORTED_TOKENS, SOLAUTO_PROD_PROGRAM } from "../constants"; +import { SolautoPositionDetails } from "../types"; +import { + SolautoClient, + SolautoMarginfiClient, + TxHandlerProps, +} from "../services"; import { + createSolautoSettings, + MarginfiSolautoPositionEx, + SolautoPositionEx, +} from "../solautoPosition"; +import { getReferralState } from "./accountUtils"; +import { + calcTotalDebt, + calcTotalSupply, fromBaseUnit, getLiqUtilzationRateBps, toBaseUnit, - toBps, -} from "../numberUtils"; -import { getReferralState } from "../accountUtils"; -import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; -import { - ALL_SUPPORTED_TOKENS, - TOKEN_INFO, - USD_DECIMALS, -} from "../../constants"; + toRoundedUsdValue, +} from "./numberUtils"; +import { fetchTokenPrices } from "./priceUtils"; +import { validPubkey } from "./generalUtils"; import { findMarginfiAccounts, getAllMarginfiAccountsByAuthority, - getMarginfiMaxLtvAndLiqThreshold, -} from "../marginfiUtils"; -import { RebalanceAction, SolautoPositionDetails } from "../../types/solauto"; -import { fetchTokenPrices } from "../priceUtils"; -import { getRebalanceValues } from "./rebalanceUtils"; +} from "./marginfi"; -export function createDynamicSolautoProgram(programId: PublicKey): Program { +export function createDynamicSolautoProgram(programId?: PublicKey): Program { return { name: "solauto", - publicKey: publicKey(programId), + publicKey: publicKey(programId ?? SOLAUTO_PROD_PROGRAM), getErrorFromCode(code: number, cause?: Error) { return getSolautoErrorFromCode(code, this, cause); }, @@ -109,121 +111,6 @@ export function getUpdatedValueFromAutomation( return newValue; } -export function getAdjustedSettingsFromAutomation( - settings: SolautoSettingsParameters, - currentUnixTime: number -): SolautoSettingsParameters { - const boostToBps = - settings.automation.targetPeriods > 0 && - eligibleForNextAutomationPeriod(settings.automation, currentUnixTime) - ? getUpdatedValueFromAutomation( - settings.boostToBps, - settings.targetBoostToBps, - settings.automation, - currentUnixTime - ) - : settings.boostToBps; - - return { - ...settings, - boostToBps, - }; -} - -export function eligibleForRebalance( - positionState: PositionState, - positionSettings: SolautoSettingsParameters | undefined, - positionDca: DCASettings | undefined, - currentUnixTime: number, - supplyMintPrice: number, - debtMintPrice: number, - bpsDistanceThreshold = 0 -): RebalanceAction | undefined { - if (!positionSettings) { - return undefined; - } - - if ( - positionDca && - positionDca.automation.targetPeriods > 0 && - eligibleForNextAutomationPeriod(positionDca.automation, currentUnixTime) - ) { - return "dca"; - } - - if (positionState.supply.amountUsed.baseUnit === BigInt(0)) { - return undefined; - } - - const boostToBps = - eligibleForRefresh(positionState, positionSettings, currentUnixTime) && - positionSettings.automation.targetPeriods > 0 - ? getUpdatedValueFromAutomation( - positionSettings.boostToBps, - positionSettings.targetBoostToBps, - positionSettings.automation, - currentUnixTime - ) - : positionSettings.boostToBps; - const repayFrom = positionSettings.repayToBps + positionSettings.repayGap; - const boostFrom = boostToBps - positionSettings.boostGap; - - if (positionState.liqUtilizationRateBps - boostFrom <= bpsDistanceThreshold) { - const limitsUpToDate = - positionState.supply.amountCanBeUsed.baseUnit > BigInt(0) || - positionState.debt.amountCanBeUsed.baseUnit > BigInt(0); - - if (limitsUpToDate && positionState.liqUtilizationRateBps < boostFrom) { - const values = getRebalanceValues( - positionState!, - positionSettings, - positionDca, - currentUnixSeconds(), - supplyMintPrice, - debtMintPrice - ); - const sufficientLiquidity = - fromBaseUnit( - positionState.debt.amountCanBeUsed.baseAmountUsdValue, - USD_DECIMALS - ) * - 0.95 > - values.debtAdjustmentUsd; - if (!sufficientLiquidity) { - consoleLog("Insufficient debt liquidity to further boost"); - } - return sufficientLiquidity ? "boost" : undefined; - } - - return "boost"; - } else if ( - repayFrom - positionState.liqUtilizationRateBps <= - bpsDistanceThreshold - ) { - return "repay"; - } - - return undefined; -} - -export function eligibleForRefresh( - positionState: PositionState, - positionSettings: SolautoSettingsParameters, - currentUnixTime: number -): boolean { - if (positionSettings.automation.targetPeriods > 0) { - return eligibleForNextAutomationPeriod( - positionSettings.automation, - currentUnixTime - ); - } else { - return ( - currentUnixSeconds() - Number(positionState.lastUpdated) > - 60 * 60 * 24 * 7 - ); - } -} - export async function getSolautoManagedPositions( umi: Umi, authority?: PublicKey, @@ -295,14 +182,13 @@ export async function getSolautoManagedPositions( if (position.position.lendingPlatform === LendingPlatform.Marginfi) { tokens = [ findMarginfiAccounts( - toWeb3JsPublicKey(position.position.protocolSupplyAccount) - ).mint, - findMarginfiAccounts( - toWeb3JsPublicKey(position.position.protocolDebtAccount) + toWeb3JsPublicKey(position.position.lpSupplyAccount) ).mint, + findMarginfiAccounts(toWeb3JsPublicKey(position.position.lpDebtAccount)) + .mint, ]; } - // TODO: PF + // TODO: LP return { publicKey: toWeb3JsPublicKey(x.publicKey), @@ -310,7 +196,7 @@ export async function getSolautoManagedPositions( positionId: position.positionId[0], lendingPlatform: position.position.lendingPlatform, positionType: position.positionType, - protocolAccount: toWeb3JsPublicKey(position.position.protocolUserAccount), + lpUserAccount: toWeb3JsPublicKey(position.position.lpUserAccount), supplyMint: tokens![0], debtMint: tokens![1], }; @@ -403,10 +289,7 @@ export async function getAllPositionsByAuthority( true ); marginfiPositions = marginfiPositions.filter( - (x) => - x.supplyMint && - (x.debtMint!.equals(PublicKey.default) || - ALL_SUPPORTED_TOKENS.includes(x.debtMint!.toString())) + (x) => validPubkey(x.supplyMint) && validPubkey(x.debtMint) ); return marginfiPositions.map((x) => ({ publicKey: x.marginfiAccount, @@ -414,7 +297,7 @@ export async function getAllPositionsByAuthority( positionId: 0, positionType: PositionType.Leverage, lendingPlatform: LendingPlatform.Marginfi, - protocolAccount: x.marginfiAccount, + lpUserAccount: x.marginfiAccount, supplyMint: x.supplyMint, debtMint: x.debtMint, })); @@ -436,12 +319,8 @@ export async function positionStateWithLatestPrices( ]); } - const supplyUsd = - fromBaseUnit(state.supply.amountUsed.baseUnit, state.supply.decimals) * - supplyPrice; - const debtUsd = - fromBaseUnit(state.debt.amountUsed.baseUnit, state.debt.decimals) * - debtPrice; + const supplyUsd = calcTotalSupply(state) * supplyPrice; + const debtUsd = calcTotalDebt(state) * debtPrice; return { ...state, liqUtilizationRateBps: getLiqUtilzationRateBps( @@ -451,161 +330,65 @@ export async function positionStateWithLatestPrices( ), netWorth: { baseUnit: toBaseUnit( - (supplyUsd - debtUsd) / supplyPrice, + supplyUsd > 0 ? (supplyUsd - debtUsd) / supplyPrice : 0, state.supply.decimals ), - baseAmountUsdValue: toBaseUnit(supplyUsd - debtUsd, USD_DECIMALS), + baseAmountUsdValue: toRoundedUsdValue(supplyUsd - debtUsd), }, supply: { ...state.supply, + amountCanBeUsed: { + ...state.supply.amountCanBeUsed, + baseAmountUsdValue: toRoundedUsdValue( + fromBaseUnit( + state.supply.amountCanBeUsed.baseUnit, + state.supply.decimals + ) * supplyPrice + ), + }, amountUsed: { ...state.supply.amountUsed, - baseAmountUsdValue: toBaseUnit(supplyUsd, USD_DECIMALS), + baseAmountUsdValue: toRoundedUsdValue(supplyUsd), }, }, debt: { ...state.debt, - amountUsed: { - ...state.debt.amountUsed, - baseAmountUsdValue: toBaseUnit(debtUsd, USD_DECIMALS), - }, - }, - }; -} - -interface AssetProps { - mint: PublicKey; - price?: number; - amountUsed?: number; - amountCanBeUsed?: number; -} - -export function createFakePositionState( - supply: AssetProps, - debt: AssetProps, - maxLtvBps: number, - liqThresholdBps: number -): PositionState { - const supplyDecimals = TOKEN_INFO[supply.mint.toString()].decimals; - const debtDecimals = TOKEN_INFO[debt.mint.toString()].decimals; - - const supplyUsd = (supply.amountUsed ?? 0) * (supply.price ?? 0); - const debtUsd = (debt.amountUsed ?? 0) * (debt.price ?? 0); - - return { - liqUtilizationRateBps: getLiqUtilzationRateBps( - supplyUsd, - debtUsd, - liqThresholdBps - ), - supply: { - amountUsed: { - baseUnit: toBaseUnit(supply.amountUsed ?? 0, supplyDecimals), - baseAmountUsdValue: toBaseUnit(supplyUsd, USD_DECIMALS), - }, amountCanBeUsed: { - baseUnit: toBaseUnit(supply.amountCanBeUsed ?? 0, supplyDecimals), - baseAmountUsdValue: toBaseUnit( - (supply.amountCanBeUsed ?? 0) * (supply.price ?? 0), - USD_DECIMALS + ...state.debt.amountCanBeUsed, + baseAmountUsdValue: toRoundedUsdValue( + fromBaseUnit( + state.debt.amountCanBeUsed.baseUnit, + state.debt.decimals + ) * debtPrice ), }, - baseAmountMarketPriceUsd: toBaseUnit(supply.price ?? 0, USD_DECIMALS), - borrowFeeBps: 0, - decimals: supplyDecimals, - flashLoanFeeBps: 0, - mint: publicKey(supply.mint), - padding1: [], - padding2: [], - padding: new Uint8Array([]), - }, - debt: { amountUsed: { - baseUnit: toBaseUnit(debt.amountUsed ?? 0, debtDecimals), - baseAmountUsdValue: toBaseUnit(debtUsd, USD_DECIMALS), - }, - amountCanBeUsed: { - baseUnit: toBaseUnit(debt.amountCanBeUsed ?? 0, debtDecimals), - baseAmountUsdValue: toBaseUnit( - (debt.amountCanBeUsed ?? 0) * (debt.price ?? 0), - USD_DECIMALS - ), + ...state.debt.amountUsed, + baseAmountUsdValue: toRoundedUsdValue(debtUsd), }, - baseAmountMarketPriceUsd: toBaseUnit(debt.price ?? 0, USD_DECIMALS), - borrowFeeBps: 0, - decimals: debtDecimals, - flashLoanFeeBps: 0, - mint: publicKey(debt.mint), - padding1: [], - padding2: [], - padding: new Uint8Array([]), - }, - netWorth: { - baseUnit: supply.price - ? toBaseUnit((supplyUsd - debtUsd) / supply.price, supplyDecimals) - : BigInt(0), - baseAmountUsdValue: toBaseUnit(supplyUsd - debtUsd, USD_DECIMALS), }, - maxLtvBps, - liqThresholdBps, - lastUpdated: BigInt(currentUnixSeconds()), - padding1: [], - padding2: [], - padding: [], }; } -export function createSolautoSettings( - settings: SolautoSettingsParametersInpArgs -): SolautoSettingsParameters { - return { - automation: - isOption(settings.automation) && isSome(settings.automation) - ? { - ...settings.automation.value, - intervalSeconds: BigInt(settings.automation.value.intervalSeconds), - unixStartDate: BigInt(settings.automation.value.unixStartDate), - padding: new Uint8Array([]), - padding1: [], - } - : { - targetPeriods: 0, - periodsPassed: 0, - intervalSeconds: BigInt(0), - unixStartDate: BigInt(0), - padding: new Uint8Array([]), - padding1: [], - }, - targetBoostToBps: - isOption(settings.targetBoostToBps) && isSome(settings.targetBoostToBps) - ? settings.targetBoostToBps.value - : 0, - boostGap: settings.boostGap, - boostToBps: settings.boostToBps, - repayGap: settings.repayGap, - repayToBps: settings.repayToBps, - padding: new Uint8Array([]), - padding1: [], - }; -} - -type PositionAdjustment = +type ContextAdjustment = | { type: "supply"; value: bigint } | { type: "debt"; value: bigint } | { type: "settings"; value: SolautoSettingsParametersInpArgs } | { type: "dca"; value: DCASettingsInpArgs } | { type: "dcaInBalance"; value: { amount: bigint; tokenType: TokenType } } - | { type: "cancellingDca"; value: TokenType }; + | { type: "cancellingDca"; value: TokenType } + | { type: "jupSwap"; value: QuoteResponse }; -export class LivePositionUpdates { +export class ContextUpdates { public supplyAdjustment = BigInt(0); public debtAdjustment = BigInt(0); public settings: SolautoSettingsParameters | undefined = undefined; - public activeDca: DCASettings | undefined = undefined; + public dca: DCASettings | undefined = undefined; public dcaInBalance?: { amount: bigint; tokenType: TokenType } = undefined; public cancellingDca: TokenType | undefined = undefined; + public jupSwap: QuoteResponse | undefined = undefined; - new(update: PositionAdjustment) { + new(update: ContextAdjustment) { if (update.type === "supply") { this.supplyAdjustment += update.value; } else if (update.type === "debt") { @@ -615,7 +398,7 @@ export class LivePositionUpdates { this.settings = createSolautoSettings(settings); } else if (update.type === "dca") { const dca = update.value; - this.activeDca = { + this.dca = { automation: { ...dca.automation, intervalSeconds: BigInt(dca.automation.intervalSeconds), @@ -631,6 +414,8 @@ export class LivePositionUpdates { this.cancellingDca = update.value; } else if (update.type === "dcaInBalance") { this.dcaInBalance = update.value; + } else if (update.type === "jupSwap") { + this.jupSwap = update.value; } } @@ -638,12 +423,12 @@ export class LivePositionUpdates { this.supplyAdjustment = BigInt(0); this.debtAdjustment = BigInt(0); this.settings = undefined; - this.activeDca = undefined; + this.dca = undefined; this.dcaInBalance = undefined; this.cancellingDca = undefined; } - hasUpdates(): boolean { + positionUpdates(): boolean { return ( this.supplyAdjustment !== BigInt(0) || this.debtAdjustment !== BigInt(0) || @@ -653,3 +438,45 @@ export class LivePositionUpdates { ); } } + +export function getClient( + lendingPlatform: LendingPlatform, + txHandlerProps: TxHandlerProps +) { + if (lendingPlatform === LendingPlatform.Marginfi) { + return new SolautoMarginfiClient(txHandlerProps); + } else { + throw new Error("Lending platform not yet supported"); + // TODO: LP + } +} + +// TODO: LP +export function isMarginfiClient( + client: SolautoClient +): client is SolautoMarginfiClient { + return client.lendingPlatform === LendingPlatform.Marginfi; +} + +// TODO: LP +export function isMarginfiPosition( + pos: SolautoPositionEx +): pos is MarginfiSolautoPositionEx { + return pos.lendingPlatform === LendingPlatform.Marginfi; +} + +export function hasFirstRebalance(rebalanceType: SolautoRebalanceType) { + return [ + SolautoRebalanceType.Regular, + SolautoRebalanceType.DoubleRebalanceWithFL, + SolautoRebalanceType.FLRebalanceThenSwap, + ].includes(rebalanceType); +} + +export function hasLastRebalance(rebalanceType: SolautoRebalanceType) { + return [ + SolautoRebalanceType.Regular, + SolautoRebalanceType.DoubleRebalanceWithFL, + SolautoRebalanceType.FLSwapThenRebalance, + ].includes(rebalanceType); +} diff --git a/solauto-sdk/src/utils/stringUtils.ts b/solauto-sdk/src/utils/stringUtils.ts new file mode 100644 index 00000000..4f6593e4 --- /dev/null +++ b/solauto-sdk/src/utils/stringUtils.ts @@ -0,0 +1,72 @@ +import { PublicKey } from "@solana/web3.js"; +import { NATIVE_MINT } from "@solana/spl-token"; +import { MAJORS_PRIO } from "../constants"; +import { tokenInfo } from "./generalUtils"; + +export const StrategyTypes = ["Long", "Short", "Ratio"] as const; +export type StrategyType = (typeof StrategyTypes)[number]; + +function adjustedTicker(mint?: PublicKey) { + const info = tokenInfo(mint); + + if (info.ticker.toLowerCase() === "wbtc") { + return "BTC"; + } else if (info.ticker.toLowerCase() === "weth") { + return "ETH"; + } else { + return info.ticker; + } +} + +export function ratioMintDetails(supplyMint?: PublicKey, debtMint?: PublicKey) { + if ( + (tokenInfo(supplyMint).isLST && debtMint?.equals(NATIVE_MINT)) || + (supplyMint && + debtMint && + MAJORS_PRIO[supplyMint?.toString() ?? ""] > + MAJORS_PRIO[debtMint?.toString() ?? ""]) + ) { + return { order: [supplyMint, debtMint], strategyName: "Long" }; + } else { + return { order: [debtMint, supplyMint], strategyName: "Short" }; + } +} + +export function ratioName(supplyMint?: PublicKey, debtMint?: PublicKey) { + const { order, strategyName } = ratioMintDetails(supplyMint, debtMint); + return `${adjustedTicker(order[0])}/${adjustedTicker(order[1])} ${strategyName}`; +} + +export function solautoStrategyName( + supplyMint?: PublicKey, + debtMint?: PublicKey +) { + const strat = strategyType( + supplyMint ?? PublicKey.default, + debtMint ?? PublicKey.default + ); + + if (strat === "Long") { + return `${adjustedTicker(supplyMint)} Long`; + } else if (strat === "Ratio") { + return ratioName(supplyMint, debtMint); + } else { + return `${adjustedTicker(debtMint)} Short`; + } +} + +export function strategyType( + supplyMint: PublicKey, + debtMint: PublicKey +): StrategyType { + const supplyInfo = tokenInfo(supplyMint); + const debtInfo = tokenInfo(debtMint); + + if (!supplyInfo.isStableCoin && !debtInfo.isStableCoin) { + return "Ratio"; + } else if (debtInfo.isStableCoin) { + return "Long"; + } else { + return "Short"; + } +} diff --git a/solauto-sdk/src/utils/switchboardUtils.ts b/solauto-sdk/src/utils/switchboardUtils.ts index f0e5adea..7f635d6f 100644 --- a/solauto-sdk/src/utils/switchboardUtils.ts +++ b/solauto-sdk/src/utils/switchboardUtils.ts @@ -1,20 +1,22 @@ -import { AnchorProvider, Idl, Program } from "@coral-xyz/anchor"; -import switchboardIdl from "../idls/switchboard.json"; import { Connection, PublicKey, Transaction, VersionedTransaction, } from "@solana/web3.js"; +import { Signer, transactionBuilder } from "@metaplex-foundation/umi"; +import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; +import { AnchorProvider, Idl, Program } from "@coral-xyz/anchor"; import * as OnDemand from "@switchboard-xyz/on-demand"; -import { SWITCHBOARD_PRICE_FEED_IDS } from "../constants/switchboardConstants"; +import Big from "big.js"; +import switchboardIdl from "../idls/switchboard.json"; +import { PRICES, SWITCHBOARD_PRICE_FEED_IDS } from "../constants"; import { TransactionItemInputs } from "../types"; -import { Signer, transactionBuilder } from "@metaplex-foundation/umi"; import { - fromWeb3JsInstruction, - toWeb3JsPublicKey, -} from "@metaplex-foundation/umi-web3js-adapters"; -import { retryWithExponentialBackoff, zip } from "./generalUtils"; + currentUnixSeconds, + retryWithExponentialBackoff, +} from "./generalUtils"; +import { getWrappedInstruction } from "./solanaUtils"; export function getPullFeed( conn: Connection, @@ -40,7 +42,7 @@ export function getPullFeed( const { PullFeed } = OnDemand; return new PullFeed( program, - new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()]) + new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId) ); } @@ -49,25 +51,37 @@ export async function buildSwbSubmitResponseTx( signer: Signer, mint: PublicKey ): Promise { - const { CrossbarClient } = OnDemand; - - const crossbar = CrossbarClient.default(); const feed = getPullFeed(conn, mint, toWeb3JsPublicKey(signer.publicKey)); const [pullIx, responses] = await retryWithExponentialBackoff( - async () => - await feed.fetchUpdateIx({ - crossbarClient: crossbar, - }), - 8, + async () => { + const res = await feed.fetchUpdateIx({ + chain: "solana", + network: "mainnet-beta", + }); + if (!res[1] || !res[1][0].value) { + throw new Error("Unable to fetch Switchboard pull IX"); + } + return res; + }, + 3, 200 ); + if (!pullIx) { + throw new Error("Unable to fetch SWB crank IX"); + } + + const price = (responses[0].value as Big).toNumber(); + PRICES[mint.toString()] = { + realtimePrice: price, + confInterval: 0, + emaPrice: price, + emaConfInterval: 0, + time: currentUnixSeconds(), + }; + return { - tx: transactionBuilder().add({ - bytesCreatedOnChain: 0, - instruction: fromWeb3JsInstruction(pullIx!), - signers: [signer], - }), + tx: transactionBuilder([getWrappedInstruction(signer, pullIx!)]), lookupTableAddresses: responses .filter((x) => Boolean(x.oracle.lut?.key)) .map((x) => x.oracle.lut!.key.toString()), @@ -100,4 +114,8 @@ export async function getSwitchboardFeedData( ); return results; -} \ No newline at end of file +} + +export function isSwitchboardMint(mint: PublicKey | string) { + return Object.keys(SWITCHBOARD_PRICE_FEED_IDS).includes(mint.toString()); +} diff --git a/solauto-sdk/tests/transactions/shared.ts b/solauto-sdk/tests/transactions/shared.ts new file mode 100644 index 00000000..4394e2ca --- /dev/null +++ b/solauto-sdk/tests/transactions/shared.ts @@ -0,0 +1,89 @@ +import { PublicKey } from "@solana/web3.js"; +import { NATIVE_MINT } from "@solana/spl-token"; +import { Signer } from "@metaplex-foundation/umi"; +import { + consoleLog, + fetchTokenPrices, + getClient, + LendingPlatform, + LOCAL_IRONFORGE_API_URL, + maxBoostToBps, + maxRepayToBps, + SOLAUTO_PROD_PROGRAM, + SOLAUTO_TEST_PROGRAM, + SolautoSettingsParametersInpArgs, + toBaseUnit, + USDC, + deposit, + openSolautoPosition, + borrow, + rebalance, + withdraw, + closeSolautoPosition, + getMarginfiAccounts, + ClientTransactionsManager, +} from "../../src"; + +export async function e2eTransactionTest( + signer: Signer, + testProgram: boolean, + lendingPlatform: LendingPlatform, + withFlashLoan: boolean, + showLogs?: boolean +) { + const client = getClient(lendingPlatform, { + signer, + showLogs, + rpcUrl: LOCAL_IRONFORGE_API_URL, + programId: testProgram ? SOLAUTO_TEST_PROGRAM : SOLAUTO_PROD_PROGRAM, + }); + + const supplyMint = new PublicKey(NATIVE_MINT); + const debtMint = new PublicKey(USDC); + + await client.initializeNewSolautoPosition({ + positionId: 1, + lpPoolAccount: getMarginfiAccounts().defaultGroup, + supplyMint, + debtMint, + }); + + const [maxLtvBps, liqThresholdBps] = + await client.pos.maxLtvAndLiqThresholdBps(); + const settings: SolautoSettingsParametersInpArgs = { + boostToBps: maxBoostToBps(maxLtvBps, liqThresholdBps), + boostGap: 50, + repayToBps: maxRepayToBps(maxLtvBps, liqThresholdBps), + repayGap: 50, + }; + + const supplyUsd = 100; + const debtUsd = withFlashLoan ? 60 : 3; + const [supplyPrice, debtPrice] = await fetchTokenPrices([ + supplyMint, + debtMint, + ]); + + const transactionItems = [ + openSolautoPosition(client, settings), + deposit( + client, + toBaseUnit(supplyUsd / supplyPrice, client.pos.supplyMintInfo.decimals) + ), + borrow( + client, + toBaseUnit(debtUsd / debtPrice, client.pos.debtMintInfo.decimals) + ), + rebalance(client, 0), + withdraw(client, "All"), + closeSolautoPosition(client), + ]; + + const txManager = new ClientTransactionsManager({ + txHandler: client, + txRunType: "only-simulate", + }); + const statuses = await txManager.send(transactionItems); + + consoleLog(statuses); +} diff --git a/solauto-sdk/tests/transactions/solautoMarginfi.ts b/solauto-sdk/tests/transactions/solautoMarginfi.ts index c9c8552c..a04d44f4 100644 --- a/solauto-sdk/tests/transactions/solautoMarginfi.ts +++ b/solauto-sdk/tests/transactions/solautoMarginfi.ts @@ -1,177 +1,29 @@ import { describe, it } from "mocha"; -import { - none, - publicKey, - some, -} from "@metaplex-foundation/umi"; +import { LendingPlatform } from "../../src"; import { setupTest } from "../shared"; -import { SolautoMarginfiClient } from "../../src/clients/solautoMarginfiClient"; -import { - safeFetchSolautoPosition, - solautoAction, - SolautoSettingsParametersInpArgs, -} from "../../src/generated"; -import { buildSolautoRebalanceTransaction } from "../../src/transactions/transactionUtils"; -import { - maxBoostToBps, - maxRepayFromBps, - maxRepayToBps, - toBaseUnit, -} from "../../src/utils/numberUtils"; -import { NATIVE_MINT } from "@solana/spl-token"; -import { - TransactionItem, - TransactionsManager, -} from "../../src/transactions/transactionsManager"; -import { PublicKey } from "@solana/web3.js"; -import { - SOLAUTO_PROD_PROGRAM, - SOLAUTO_TEST_PROGRAM, - USDC, -} from "../../src/constants"; -import { - buildHeliusApiUrl, - getSolautoManagedPositions, -} from "../../src/utils"; -import { PriorityFeeSetting } from "../../src/types"; -import { buildIronforgeApiUrl } from "../../dist"; +import { e2eTransactionTest } from "./shared"; describe("Solauto Marginfi tests", async () => { - // const signer = setupTest(); - const signer = setupTest("solauto-manager"); - - const payForTransactions = false; + const signer = setupTest(); const testProgram = false; - const positionId = 1; it("open - deposit - borrow - rebalance to 0 - withdraw - close", async () => { - const client = new SolautoMarginfiClient( - buildIronforgeApiUrl(process.env.IRONFORGE_API_KEY!), - true, - testProgram ? SOLAUTO_TEST_PROGRAM : SOLAUTO_PROD_PROGRAM + await e2eTransactionTest( + signer, + testProgram, + LendingPlatform.Marginfi, + false, + false ); + }); - const supply = NATIVE_MINT; - const supplyDecimals = 6; - const debtDecimals = 6; - - await client.initialize({ + it("open - deposit - borrow - fl rebalance to 0 - withdraw - close", async () => { + await e2eTransactionTest( signer, - positionId, - authority: new PublicKey("He4ka5Q3N1UvZikZvykdi47xyk5PoVP2tcQL5sVp31Sz"), - // new: true, - // marginfiAccount: new PublicKey( - // "" - // ), - // marginfiGroup: new PublicKey(""), - // supplyMint: new PublicKey(""), - // debtMint: new PublicKey(USDC), - }); - - // console.log(await getSolautoManagedPositions(client.umi)); - - const transactionItems: TransactionItem[] = []; - // const settingParams: SolautoSettingsParametersInpArgs = { - // boostToBps: maxBoostToBps( - // client.solautoPositionState?.maxLtvBps ?? 0, - // client.solautoPositionState?.liqThresholdBps ?? 0 - // ), - // boostGap: 50, - // repayToBps: maxRepayToBps( - // client.solautoPositionState?.maxLtvBps ?? 0, - // client.solautoPositionState?.liqThresholdBps ?? 0 - // ), - // repayGap: 50, - // automation: none(), - // targetBoostToBps: none(), - // }; - - // if (client.solautoPositionData === null) { - // transactionItems.push( - // new TransactionItem(async () => { - // return { - // tx: client.openPosition(settingParams), - // }; - // }, "open position") - // ); - - // const initialSupplyUsd = 150; - // transactionItems.push( - // new TransactionItem(async () => { - // // const [supplyPrice] = await fetchTokenPrices([supply]); - // return { - // tx: client.protocolInteraction( - // solautoAction("Deposit", [toBaseUnit(300, supplyDecimals)]) - // ), - // }; - // }, "deposit") - // ); - // } - - // const maxLtvBps = client.solautoPositionState!.maxLtvBps; - // const liqThresholdBps = client.solautoPositionState!.liqThresholdBps; - // const maxRepayFrom = maxRepayFromBps(maxLtvBps, liqThresholdBps); - // const maxRepayTo = maxRepayToBps(maxLtvBps, liqThresholdBps); - // const maxBoostTo = maxBoostToBps(maxLtvBps, liqThresholdBps); - // transactionItems.push( - // new TransactionItem( - // async () => ({ - // tx: client.updatePositionIx({ - // positionId: client.positionId, - // settingParams: some({ - // ...settingParams, - // }), - // dca: null, - // }), - // }), - // "update position" - // ) - // ); - - transactionItems.push( - new TransactionItem( - async (attemptNum) => - await buildSolautoRebalanceTransaction(client, undefined, attemptNum), - "rebalance" - ) + testProgram, + LendingPlatform.Marginfi, + true, + false ); - - // transactionItems.push( - // new TransactionItem( - // async (attemptNum) => - // await buildSolautoRebalanceTransaction(client, settingParams.boostToBps, attemptNum), - // "rebalance" - // ) - // ); - - // transactionItems.push( - // new TransactionItem( - // async () => ({ - // tx: client.protocolInteraction( - // solautoAction("Withdraw", [{ __kind: "All" }]) - // ), - // }), - // "withdraw" - // ) - // ); - - // transactionItems.push( - // new TransactionItem( - // async () => ({ - // tx: client.closePositionIx(), - // }), - // "close position" - // ) - // ); - - const statuses = await new TransactionsManager( - client, - undefined, - !payForTransactions ? "only-simulate" : "normal", - PriorityFeeSetting.Min, - true - ).clientSend(transactionItems); - - console.log(statuses); }); }); diff --git a/solauto-sdk/tests/unit/accounts.ts b/solauto-sdk/tests/unit/accounts.ts index 4bad2151..d574ab59 100644 --- a/solauto-sdk/tests/unit/accounts.ts +++ b/solauto-sdk/tests/unit/accounts.ts @@ -1,31 +1,22 @@ import { describe, it } from "mocha"; +import { assert } from "chai"; +import { PublicKey } from "@solana/web3.js"; +import { publicKey } from "@metaplex-foundation/umi"; +import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; import { ALL_SUPPORTED_TOKENS, TOKEN_INFO, -} from "../../src/constants/tokenConstants"; -import { - buildHeliusApiUrl, - getSolanaRpcConnection, -} from "../../src/utils/solanaUtils"; -import { publicKey } from "@metaplex-foundation/umi"; -import { assert } from "chai"; -import { - getAllMarginfiAccountsByAuthority, - getTokenAccount, -} from "../../src/utils"; -import { - MARGINFI_ACCOUNTS, SOLAUTO_FEES_WALLET, SOLAUTO_MANAGER, -} from "../../src/constants"; -import { PublicKey } from "@solana/web3.js"; -import { safeFetchAllMarginfiAccount } from "../../src/marginfi-sdk"; -import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; + LOCAL_IRONFORGE_API_URL, + getMarginfiAccounts, + getSolanaRpcConnection, + getEmptyMarginfiAccountsByAuthority, + getTokenAccount, +} from "../../src"; async function hasTokenAccounts(wallet: PublicKey) { - let [_, umi] = getSolanaRpcConnection( - buildHeliusApiUrl(process.env.HELIUS_API_KEY!) - ); + let [_, umi] = getSolanaRpcConnection(LOCAL_IRONFORGE_API_URL); const tokenAccounts = await umi.rpc.getAccounts( ALL_SUPPORTED_TOKENS.map((x) => @@ -50,25 +41,18 @@ describe("Assert Solauto fee token accounts are created", async () => { }); it("ISM accounts for every supported Marginfi group", async () => { - let [_, umi] = getSolanaRpcConnection( - buildHeliusApiUrl(process.env.HELIUS_API_KEY!) - ); + let [_, umi] = getSolanaRpcConnection(LOCAL_IRONFORGE_API_URL); - const ismAccounts = await getAllMarginfiAccountsByAuthority( + const ismAccounts = await getEmptyMarginfiAccountsByAuthority( umi, - SOLAUTO_MANAGER, - undefined, - false - ); - const ismData = await safeFetchAllMarginfiAccount( - umi, - ismAccounts.map((x) => publicKey(x.marginfiAccount)) - ); - const supportedMarginfiGroups = Object.keys(MARGINFI_ACCOUNTS).map( - (x) => new PublicKey(x) + SOLAUTO_MANAGER ); + const supportedMarginfiGroups = Object.keys( + getMarginfiAccounts("Prod").bankAccounts + ).map((x) => new PublicKey(x)); const missingIsmAccounts = supportedMarginfiGroups.filter( - (group) => !ismData.find((x) => group.equals(toWeb3JsPublicKey(x.group))) + (group) => + !ismAccounts.find((x) => group.equals(toWeb3JsPublicKey(x.group))) ); console.log("Missing ISM accounts", missingIsmAccounts); diff --git a/solauto-sdk/tests/unit/lookupTables.ts b/solauto-sdk/tests/unit/lookupTables.ts index 2db90657..4a835d35 100644 --- a/solauto-sdk/tests/unit/lookupTables.ts +++ b/solauto-sdk/tests/unit/lookupTables.ts @@ -1,43 +1,43 @@ import { describe, it } from "mocha"; -import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js"; import { - MARGINFI_ACCOUNTS, - MARGINFI_ACCOUNTS_LOOKUP_TABLE, -} from "../../src/constants/marginfiAccounts"; + getMarginfiAccounts, + LOCAL_IRONFORGE_API_URL, + SOLAUTO_MANAGER, + getAllBankRelatedAccounts, + getEmptyMarginfiAccountsByAuthority, + getSolanaRpcConnection, + ProgramEnv, +} from "../../src"; -const conn = new Connection(clusterApiUrl("mainnet-beta"), "confirmed"); +const [conn, umi] = getSolanaRpcConnection(LOCAL_IRONFORGE_API_URL); + +async function checkLookupTableAccounts(programEnv: ProgramEnv) { + const data = getMarginfiAccounts(programEnv); + const lookupTable = await conn.getAddressLookupTable(data.lookupTable); + if (lookupTable === null) { + throw new Error("Lookup table not found"); + } + + const ismAccounts = ( + await getEmptyMarginfiAccountsByAuthority(umi, SOLAUTO_MANAGER) + ).map((x) => x.publicKey.toString()); + + const bankAccounts = ( + await getAllBankRelatedAccounts(umi, data.bankAccounts) + ).map((x) => x.toString()); + + const accountsRequired = [...ismAccounts, ...bankAccounts]; + + const existingAccounts = + lookupTable.value?.state.addresses.map((x) => x.toString()) ?? []; + + if (accountsRequired.find((x) => !existingAccounts.includes(x.toString()))) { + throw new Error("Marginfi accounts lookup table missing an account"); + } +} describe("Assert lookup tables up-to-date", async () => { it("marginfi accounts LUT should have everything", async () => { - const lookupTable = await conn.getAddressLookupTable( - new PublicKey(MARGINFI_ACCOUNTS_LOOKUP_TABLE) - ); - if (lookupTable === null) { - throw new Error("Lookup table not found"); - } - - const existingAccounts = - lookupTable.value?.state.addresses.map((x) => x.toString()) ?? []; - - for (const group in MARGINFI_ACCOUNTS) { - for (const key in MARGINFI_ACCOUNTS[group]) { - if (key === PublicKey.default.toString()) { - continue; - } - - const accounts = MARGINFI_ACCOUNTS[group][key]; - const addresses = [ - group, - accounts.bank, - accounts.liquidityVault, - accounts.vaultAuthority, - accounts.priceOracle, - ]; - - if (addresses.find((x) => !existingAccounts.includes(x.toString()))) { - throw new Error("Marginfi accounts lookup table missing an account"); - } - } - } + await checkLookupTableAccounts("Prod"); }); }); diff --git a/solauto-sdk/tests/unit/rebalanceCalculations.ts b/solauto-sdk/tests/unit/rebalanceCalculations.ts index 28a5bb3e..55cc712d 100644 --- a/solauto-sdk/tests/unit/rebalanceCalculations.ts +++ b/solauto-sdk/tests/unit/rebalanceCalculations.ts @@ -1,102 +1,51 @@ import { describe, it, before } from "mocha"; +import { assert } from "chai"; import { PublicKey } from "@solana/web3.js"; import { NATIVE_MINT } from "@solana/spl-token"; -import { assert } from "chai"; -import { SolautoMarginfiClient } from "../../src/clients/solautoMarginfiClient"; -import { setupTest } from "../shared"; -import { getRebalanceValues } from "../../src/utils/solauto/rebalanceUtils"; import { publicKey } from "@metaplex-foundation/umi"; -import { SolautoClient } from "../../src/clients/solautoClient"; -import { - DCASettings, - LendingPlatform, - PositionType, - RebalanceDirection, - SolautoRebalanceType, - SolautoSettingsParameters, - TokenType, -} from "../../src/generated"; +import { setupTest } from "../shared"; import { - fromBaseUnit, + LOCAL_IRONFORGE_API_URL, + USDC, fromBps, getLiqUtilzationRateBps, - getSolautoFeesBps, - toBaseUnit, -} from "../../src/utils/numberUtils"; -import { USD_DECIMALS } from "../../src/constants/generalAccounts"; -import { - createFakePositionState, - eligibleForNextAutomationPeriod, - getAdjustedSettingsFromAutomation, - getUpdatedValueFromAutomation, - positionStateWithLatestPrices, -} from "../../src/utils/solauto/generalUtils"; -import { currentUnixSeconds } from "../../src/utils/generalUtils"; -import { USDC } from "../../src/constants/tokenConstants"; -import { - buildHeliusApiUrl, + getClient, fetchTokenPrices, - getSolanaRpcConnection, safeGetPrice, -} from "../../src/utils"; + LendingPlatform, + PriceType, + SolautoSettingsParameters, + getRebalanceValues, + SolautoClient, + SolautoFeesBps, + createFakePositionState, + MarginfiSolautoPositionEx, + getMarginfiAccounts, +} from "../../src"; const signer = setupTest(undefined, true); -const [conn, _] = getSolanaRpcConnection( - buildHeliusApiUrl(process.env.HELIUS_API_URL!) -); function assertAccurateRebalance( client: SolautoClient, expectedLiqUtilizationRateBps: number, - targetLiqUtilizationRateBps?: number, - expectedUsdToDcaIn?: number + targetLiqUtilizationRateBps?: number ) { - const { rebalanceDirection, debtAdjustmentUsd, amountUsdToDcaIn } = - getRebalanceValues( - client.solautoPositionState!, - client.solautoPositionSettings(), - client.solautoPositionActiveDca(), - currentUnixSeconds(), - safeGetPrice(client.supplyMint)!, - safeGetPrice(client.debtMint)!, - targetLiqUtilizationRateBps - ); - - let adjustmentFeeBps = 0; - adjustmentFeeBps = getSolautoFeesBps( - client.referredBy !== undefined, + const { endResult } = getRebalanceValues( + client.pos, + PriceType.Realtime, targetLiqUtilizationRateBps, - fromBaseUnit( - client.solautoPositionState?.netWorth.baseAmountUsdValue ?? BigInt(0), - USD_DECIMALS + SolautoFeesBps.create( + false, + targetLiqUtilizationRateBps, + client.pos.netWorthUsd() ), - rebalanceDirection - ).total; - - assert( - Math.round(amountUsdToDcaIn) === Math.round(expectedUsdToDcaIn ?? 0), - `Expected DCA-in amount does not match ${Math.round( - amountUsdToDcaIn - )}, ${Math.round(expectedUsdToDcaIn ?? 0)}` + 50 ); - const newSupply = - fromBaseUnit( - client.solautoPositionState!.supply.amountUsed.baseAmountUsdValue, - USD_DECIMALS - ) + - (debtAdjustmentUsd - debtAdjustmentUsd * fromBps(adjustmentFeeBps)) + - amountUsdToDcaIn; - const newDebt = - fromBaseUnit( - client.solautoPositionState!.debt.amountUsed.baseAmountUsdValue, - USD_DECIMALS - ) + debtAdjustmentUsd; - const newLiqUtilizationRateBps = getLiqUtilzationRateBps( - newSupply, - newDebt, - client.solautoPositionState!.liqThresholdBps + endResult.supplyUsd, + endResult.debtUsd, + client.pos.state.liqThresholdBps ); assert( Math.round(newLiqUtilizationRateBps) === @@ -109,16 +58,15 @@ async function getFakePosition( supplyPrice: number, debtPrice: number, fakeLiqUtilizationRateBps: number, - settings: SolautoSettingsParameters, - dca?: DCASettings + settings: SolautoSettingsParameters ): Promise { - const client = new SolautoMarginfiClient( - buildHeliusApiUrl(process.env.HELIUS_API_KEY!), - true - ); + const client = getClient(LendingPlatform.Marginfi, { + signer, + rpcUrl: LOCAL_IRONFORGE_API_URL, + }); await client.initialize({ positionId: 1, - signer, + lpPoolAccount: getMarginfiAccounts().defaultGroup, supplyMint: new PublicKey(NATIVE_MINT), debtMint: new PublicKey(USDC), }); @@ -126,81 +74,46 @@ async function getFakePosition( const supplyUsd = 1000; const maxLtvBps = 6400; const liqThresholdBps = 8181; - client.solautoPositionState = await positionStateWithLatestPrices( - createFakePositionState( - { - amountUsed: supplyUsd / supplyPrice, - price: safeGetPrice(NATIVE_MINT)!, - mint: NATIVE_MINT, - }, - { - amountUsed: - (supplyUsd * - fromBps(liqThresholdBps) * - fromBps(fakeLiqUtilizationRateBps)) / - debtPrice, - price: 1, - mint: new PublicKey(USDC), - }, - maxLtvBps, - liqThresholdBps - ) - ); - client.solautoPositionData = { - positionId: [1], - bump: [0], - selfManaged: { - val: false, + const fakeState = createFakePositionState( + { + amountUsed: supplyUsd / supplyPrice, + price: safeGetPrice(NATIVE_MINT)!, + mint: NATIVE_MINT, }, - authority: client.signer.publicKey, - position: { - dca: dca ?? { - automation: { - targetPeriods: 0, - periodsPassed: 0, - unixStartDate: BigInt(0), - intervalSeconds: BigInt(0), - padding1: [], - padding: new Uint8Array([]), - }, - dcaInBaseUnit: BigInt(0), - tokenType: TokenType.Debt, - padding: [], - }, - lendingPlatform: LendingPlatform.Marginfi, - protocolSupplyAccount: publicKey(PublicKey.default), - protocolDebtAccount: publicKey(PublicKey.default), - protocolUserAccount: publicKey(PublicKey.default), - settingParams: settings, - padding1: [], - padding: [], - }, - state: client.solautoPositionState!, - rebalance: { - rebalanceType: SolautoRebalanceType.Regular, - rebalanceDirection: RebalanceDirection.Boost, - flashLoanAmount: BigInt(0), - padding1: [], - padding2: [], - padding: new Uint8Array([]), + { + amountUsed: + (supplyUsd * + fromBps(liqThresholdBps) * + fromBps(fakeLiqUtilizationRateBps)) / + debtPrice, + price: 1, + mint: new PublicKey(USDC), }, - positionType: PositionType.Leverage, - padding1: [], - padding: [], - publicKey: publicKey(PublicKey.default), - header: { - executable: false, - lamports: { - basisPoints: BigInt(0), - decimals: 9, - identifier: "SOL", + maxLtvBps, + liqThresholdBps + ); + + const defaultPk = publicKey(PublicKey.default); + client.pos = new MarginfiSolautoPositionEx({ + umi: client.umi, + publicKey: PublicKey.default, + data: { + state: fakeState, + positionId: [1], + authority: defaultPk, + position: { + lendingPlatform: LendingPlatform.Marginfi, + lpUserAccount: defaultPk, + lpSupplyAccount: defaultPk, + lpDebtAccount: defaultPk, + lpPoolAccount: defaultPk, + settings, + padding: [], + padding1: [], }, - owner: publicKey(PublicKey.default), }, - }; - - client.solautoPositionState!.lastUpdated = BigInt(currentUnixSeconds()); + }); return client; } @@ -218,71 +131,13 @@ async function rebalanceFromFakePosition( settings ); - const adjustedSettings = getAdjustedSettingsFromAutomation( - settings, - currentUnixSeconds() - ); const expectedLiqUtilizationRateBps = - fakeLiqUtilizationRateBps < - adjustedSettings.boostToBps - adjustedSettings.boostGap - ? adjustedSettings.boostToBps - : adjustedSettings.repayToBps; + fakeLiqUtilizationRateBps < settings.boostToBps - settings.boostGap + ? settings.boostToBps + : settings.repayToBps; assertAccurateRebalance(client, expectedLiqUtilizationRateBps); } -async function dcaRebalanceFromFakePosition( - supplyPrice: number, - debtPrice: number, - fakeLiqUtilizationRateBps: number, - settings: SolautoSettingsParameters, - dca: DCASettings -) { - const client = await getFakePosition( - supplyPrice, - debtPrice, - fakeLiqUtilizationRateBps, - settings, - dca - ); - - const adjustedSettings = getAdjustedSettingsFromAutomation( - settings, - currentUnixSeconds() - ); - const expectedLiqUtilizationRateBps = - dca.dcaInBaseUnit > BigInt(0) - ? Math.max(fakeLiqUtilizationRateBps, adjustedSettings.boostToBps) - : adjustedSettings.boostToBps; - - const expectedDcaInAmount = - dca.dcaInBaseUnit > BigInt(0) && - eligibleForNextAutomationPeriod(dca.automation, currentUnixSeconds()) - ? dca.dcaInBaseUnit - - BigInt( - Math.round( - getUpdatedValueFromAutomation( - Number(dca.dcaInBaseUnit), - 0, - dca.automation, - currentUnixSeconds() - ) - ) - ) - : BigInt(0); - const expectedUsdToDcaIn = - fromBaseUnit( - BigInt(Math.round(Number(expectedDcaInAmount))), - client.solautoPositionState!.debt.decimals - ) * debtPrice; - - assertAccurateRebalance( - client, - expectedLiqUtilizationRateBps, - undefined, - expectedUsdToDcaIn - ); -} - describe("Rebalance tests", async () => { let supplyPrice: number, debtPrice: number; @@ -299,17 +154,7 @@ describe("Rebalance tests", async () => { boostGap: 100, repayToBps: 7000, repayGap: 250, - automation: { - targetPeriods: 0, - periodsPassed: 0, - unixStartDate: BigInt(0), - intervalSeconds: BigInt(0), - padding1: [], - padding: new Uint8Array([]), - }, - targetBoostToBps: 0, - padding1: [], - padding: new Uint8Array([]), + padding: [], }); assertAccurateRebalance(client, 5000, 5000); @@ -318,145 +163,14 @@ describe("Rebalance tests", async () => { it("Standard boost or repay", async () => { const settings: SolautoSettingsParameters = { - automation: { - targetPeriods: 0, - periodsPassed: 0, - unixStartDate: BigInt(0), - intervalSeconds: BigInt(0), - padding1: [], - padding: new Uint8Array([]), - }, - targetBoostToBps: 0, boostGap: 1000, boostToBps: 4000, repayGap: 1000, repayToBps: 7500, - padding1: [], - padding: new Uint8Array([]), + padding: [], }; await rebalanceFromFakePosition(supplyPrice, debtPrice, 1000, settings); await rebalanceFromFakePosition(supplyPrice, debtPrice, 9000, settings); }); - - it("Rebalance with settings automation", async () => { - const settings: SolautoSettingsParameters = { - automation: { - targetPeriods: 2, - periodsPassed: 1, - intervalSeconds: BigInt(5), - unixStartDate: BigInt(currentUnixSeconds() - 5), - padding1: [], - padding: new Uint8Array([]), - }, - targetBoostToBps: 5000, - boostGap: 1000, - boostToBps: 4000, - repayGap: 1000, - repayToBps: 7500, - padding1: [], - padding: new Uint8Array([]), - }; - await rebalanceFromFakePosition(supplyPrice, debtPrice, 3500, settings); - - settings.automation.targetPeriods = 5; - await rebalanceFromFakePosition(supplyPrice, debtPrice, 3100, settings); - - settings.automation.periodsPassed = 0; - settings.automation.unixStartDate = BigInt(currentUnixSeconds()); - await rebalanceFromFakePosition(supplyPrice, debtPrice, 3100, settings); - }); - - it("Rebalance DCA out", async () => { - const settings: SolautoSettingsParameters = { - automation: { - targetPeriods: 4, - periodsPassed: 0, - intervalSeconds: BigInt(5), - unixStartDate: BigInt(currentUnixSeconds()), - padding1: [], - padding: new Uint8Array([]), - }, - targetBoostToBps: 0, - boostGap: 1000, - boostToBps: 4000, - repayGap: 1000, - repayToBps: 7500, - padding1: [], - padding: new Uint8Array([]), - }; - const dca: DCASettings = { - automation: { - targetPeriods: 4, - periodsPassed: 0, - intervalSeconds: BigInt(5), - unixStartDate: BigInt(currentUnixSeconds()), - padding1: [], - padding: new Uint8Array([]), - }, - dcaInBaseUnit: BigInt(0), - tokenType: TokenType.Debt, - padding: [], - }; - await dcaRebalanceFromFakePosition( - supplyPrice, - debtPrice, - 3500, - settings, - dca - ); - - settings.boostToBps = 1500; - settings.automation.periodsPassed = 3; - settings.automation.unixStartDate = BigInt(currentUnixSeconds() - 3 * 5); - dca.automation.periodsPassed = 3; - dca.automation.unixStartDate = BigInt(currentUnixSeconds() - 3 * 5); - await dcaRebalanceFromFakePosition( - supplyPrice, - debtPrice, - 3500, - settings, - dca - ); - }); - - it("Rebalance DCA in", async () => { - const settings: SolautoSettingsParameters = { - automation: { - targetPeriods: 3, - periodsPassed: 0, - intervalSeconds: BigInt(5), - unixStartDate: BigInt(currentUnixSeconds()), - padding1: [], - padding: new Uint8Array([]), - }, - targetBoostToBps: 5000, - boostGap: 1000, - boostToBps: 4000, - repayGap: 1000, - repayToBps: 7500, - padding1: [], - padding: new Uint8Array([]), - }; - const dca: DCASettings = { - automation: { - targetPeriods: 4, - periodsPassed: 0, - intervalSeconds: BigInt(5), - unixStartDate: BigInt(currentUnixSeconds()), - padding1: [], - padding: new Uint8Array([]), - }, - dcaInBaseUnit: toBaseUnit(debtPrice * 300, 6), - tokenType: TokenType.Debt, - padding: [], - }; - await dcaRebalanceFromFakePosition( - supplyPrice, - debtPrice, - 3500, - settings, - dca - ); - }); }); From 10d54ef75ab36d1bc01a6de4bbbb349a17309ba1 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sun, 27 Apr 2025 17:09:12 -0400 Subject: [PATCH 04/88] more token info --- solauto-sdk/package.json | 2 +- solauto-sdk/src/constants/tokenConstants.ts | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 09e334b6..bf683164 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.729", + "version": "1.0.730", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/constants/tokenConstants.ts b/solauto-sdk/src/constants/tokenConstants.ts index 05c72e13..7e98f955 100644 --- a/solauto-sdk/src/constants/tokenConstants.ts +++ b/solauto-sdk/src/constants/tokenConstants.ts @@ -53,6 +53,7 @@ export const ALL_SUPPORTED_TOKENS = [ export interface TokenInfo { ticker: string; + name?: string; decimals: number; isStableCoin?: boolean; isLST?: boolean; @@ -67,21 +68,25 @@ export const TOKEN_INFO: { [key: string]: TokenInfo } = { }, [NATIVE_MINT.toString()]: { ticker: "SOL", + name: "Solana", decimals: 9, isMajor: true, }, [B_SOL]: { ticker: "bSOL", + name: "Blaze SOL", decimals: 9, isLST: true, }, [M_SOL]: { ticker: "mSOL", + name: "Marinade SOL", decimals: 9, isLST: true, }, [JITO_SOL]: { ticker: "JitoSOL", + name: "JITO SOL", decimals: 9, isLST: true, }, @@ -92,43 +97,52 @@ export const TOKEN_INFO: { [key: string]: TokenInfo } = { }, [INF]: { ticker: "INF", + name: "Infinity", decimals: 9, isLST: true, }, [H_SOL]: { ticker: "hSOL", + name: "Helius SOL", decimals: 9, isLST: true, }, [JUP_SOL]: { ticker: "JupSOL", + name: "Jupiter SOL", decimals: 9, isLST: true, }, [JUP]: { ticker: "JUP", + name: "Jupiter", decimals: 6, }, [JTO]: { ticker: "JTO", + name: "Jito", decimals: 9, }, [JLP]: { ticker: "JLP", + name: "Jupiter Liquidity Provider", decimals: 6, }, [WBTC]: { ticker: "WBTC", + name: "Wrapped Bitcoin", decimals: 8, isMajor: true, }, [WETH]: { ticker: "WETH", + name: "Wrapped Ethereum", decimals: 8, isMajor: true, }, [HNT]: { ticker: "HNT", + name: "Helium Network Token", decimals: 8, }, [PYTH]: { @@ -137,11 +151,13 @@ export const TOKEN_INFO: { [key: string]: TokenInfo } = { }, [USDC]: { ticker: "USDC", + name: "USD Circle", decimals: 6, isStableCoin: true, }, [USDT]: { ticker: "USDT", + name: "USD Tether", decimals: 6, isStableCoin: true, }, @@ -152,6 +168,7 @@ export const TOKEN_INFO: { [key: string]: TokenInfo } = { }, [WIF]: { ticker: "WIF", + name: "Dog Wif Hat", decimals: 6, isMeme: true, }, @@ -172,6 +189,7 @@ export const TOKEN_INFO: { [key: string]: TokenInfo } = { }, [HMTR]: { ticker: "HMTR", + name: "Hampter", decimals: 0, isMeme: true, }, From 86e7784f9aa9af54f07aba229a81eeac2af7c727 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sun, 27 Apr 2025 21:53:29 -0400 Subject: [PATCH 05/88] fixes --- solauto-sdk/package.json | 2 +- .../services/rebalance/rebalanceTxBuilder.ts | 37 ++++++++++--------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index bf683164..e5f1c198 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.730", + "version": "1.0.732", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/rebalance/rebalanceTxBuilder.ts b/solauto-sdk/src/services/rebalance/rebalanceTxBuilder.ts index 57fd60f4..a106b4d2 100644 --- a/solauto-sdk/src/services/rebalance/rebalanceTxBuilder.ts +++ b/solauto-sdk/src/services/rebalance/rebalanceTxBuilder.ts @@ -82,37 +82,38 @@ export class RebalanceTxBuilder { } private getFlLiquiditySource( + attemptNum: number, supplyLiquidityAvailable: bigint, debtLiquidityAvailable: bigint ): TokenType | undefined { const debtAdjustmentUsd = Math.abs(this.values.debtAdjustmentUsd); - const insufficientLiquidity = ( - amountNeededUsd: number, + const calcLiquidityAvailable = ( liquidityAvailable: bigint, tokenMint: PublicKey - ) => { - const liquidityUsd = - fromBaseUnit(liquidityAvailable, tokenInfo(tokenMint).decimals) * - (safeGetPrice(tokenMint) ?? 0); - return amountNeededUsd > liquidityUsd * 0.95; - }; + ) => + fromBaseUnit(liquidityAvailable, tokenInfo(tokenMint).decimals) * + (safeGetPrice(tokenMint) ?? 0); - const insufficientSupplyLiquidity = insufficientLiquidity( - debtAdjustmentUsd, + const supplyLiquidityUsdAvailable = calcLiquidityAvailable( supplyLiquidityAvailable, this.client.pos.supplyMint ); + const insufficientSupplyLiquidity = + debtAdjustmentUsd > supplyLiquidityUsdAvailable * 0.95; - const insufficientDebtLiquidity = insufficientLiquidity( - debtAdjustmentUsd, + const debtLiquidityUsdAvailable = calcLiquidityAvailable( debtLiquidityAvailable, this.client.pos.debtMint ); + const insufficientDebtLiquidity = + debtAdjustmentUsd > debtLiquidityUsdAvailable * 0.95; let useDebtLiquidity = this.values.rebalanceDirection === RebalanceDirection.Boost || - insufficientSupplyLiquidity; + insufficientSupplyLiquidity || + (attemptNum > 2 && + debtLiquidityUsdAvailable > supplyLiquidityUsdAvailable * 5); if (useDebtLiquidity) { return !insufficientDebtLiquidity ? TokenType.Debt : undefined; @@ -153,9 +154,9 @@ export class RebalanceTxBuilder { return intermediaryLiqUtilizationRateBps; } - private async flashLoanRequirements(): Promise< - FlashLoanRequirements | undefined - > { + private async flashLoanRequirements( + attemptNum: number + ): Promise { const intermediaryLiqUtilizationRateBps = this.intermediaryLiqUtilizationRateBps(); const maxLtvRateBps = getMaxLiqUtilizationRateBps( @@ -168,6 +169,7 @@ export class RebalanceTxBuilder { } const stdFlLiquiditySource = this.getFlLiquiditySource( + attemptNum, this.client.flProvider.liquidityAvailable(TokenType.Supply), this.client.flProvider.liquidityAvailable(TokenType.Debt) ); @@ -175,6 +177,7 @@ export class RebalanceTxBuilder { if (stdFlLiquiditySource === undefined || this.optimizeSize) { const { supplyBalance, debtBalance } = await this.client.signerBalances(); const signerFlLiquiditySource = this.getFlLiquiditySource( + attemptNum, supplyBalance, debtBalance ); @@ -278,7 +281,7 @@ export class RebalanceTxBuilder { } this.values = rebalanceValues; - this.flRequirements = await this.flashLoanRequirements(); + this.flRequirements = await this.flashLoanRequirements(attemptNum); if (this.flRequirements?.flFeeBps) { this.values = this.getRebalanceValues()!; } From 03ec162d82420c255b683a70dd54480d56253456 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Wed, 30 Apr 2025 03:27:59 -0400 Subject: [PATCH 06/88] export function --- solauto-sdk/package.json | 2 +- solauto-sdk/src/utils/stringUtils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index e5f1c198..da3c1875 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.732", + "version": "1.0.733", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/utils/stringUtils.ts b/solauto-sdk/src/utils/stringUtils.ts index 4f6593e4..73e59753 100644 --- a/solauto-sdk/src/utils/stringUtils.ts +++ b/solauto-sdk/src/utils/stringUtils.ts @@ -6,7 +6,7 @@ import { tokenInfo } from "./generalUtils"; export const StrategyTypes = ["Long", "Short", "Ratio"] as const; export type StrategyType = (typeof StrategyTypes)[number]; -function adjustedTicker(mint?: PublicKey) { +export function adjustedTicker(mint?: PublicKey) { const info = tokenInfo(mint); if (info.ticker.toLowerCase() === "wbtc") { From 31d240581af744825bafdfdbd1487e75327a751f Mon Sep 17 00:00:00 2001 From: Chelioso Date: Wed, 30 Apr 2025 14:10:38 -0400 Subject: [PATCH 07/88] fixes --- programs/solauto/src/utils/validation_utils.rs | 4 ++-- solauto-sdk/package.json | 2 +- solauto-sdk/src/services/swap/jupSwapManager.ts | 6 ++---- .../transactions/manager/transactionsManager.ts | 13 ++++++++++--- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/programs/solauto/src/utils/validation_utils.rs b/programs/solauto/src/utils/validation_utils.rs index 84c9c861..131d9cf3 100644 --- a/programs/solauto/src/utils/validation_utils.rs +++ b/programs/solauto/src/utils/validation_utils.rs @@ -444,11 +444,11 @@ pub fn validate_rebalance(solauto_position: &SolautoPosition) -> ProgramResult { curr_debt_usd ); check!( - value_gte_with_threshold(curr_supply_usd, target_supply_usd, 0.1), + value_gte_with_threshold(curr_supply_usd, target_supply_usd, 0.2), SolautoError::InvalidRebalanceMade ); check!( - value_lte_with_threshold(curr_debt_usd, target_debt_usd, 0.1), + value_lte_with_threshold(curr_debt_usd, target_debt_usd, 0.2), SolautoError::InvalidRebalanceMade ); diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index da3c1875..d2f29d4e 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.733", + "version": "1.0.736", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/swap/jupSwapManager.ts b/solauto-sdk/src/services/swap/jupSwapManager.ts index 3918524a..28ae971e 100644 --- a/solauto-sdk/src/services/swap/jupSwapManager.ts +++ b/solauto-sdk/src/services/swap/jupSwapManager.ts @@ -57,10 +57,8 @@ export class JupSwapManager { const inputMintInfo: TokenInfo | undefined = tokenInfo(data.inputMint); const outputMintInfo: TokenInfo | undefined = tokenInfo(data.outputMint); const lowLiquidityMint = - !inputMintInfo || - inputMintInfo?.isMeme || - !outputMintInfo || - outputMintInfo?.isMeme; + (!inputMintInfo?.isMajor && !inputMintInfo?.isLST) || + (!outputMintInfo?.isMajor && !outputMintInfo?.isLST); const slippageBps = data.slippageBps ?? (lowLiquidityMint ? 250 : 100); return await retryWithExponentialBackoff( diff --git a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts index dcbe96f4..3d89fbb7 100644 --- a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts @@ -415,7 +415,9 @@ export class TransactionsManager { e, itemSets.filter( (x) => - this.statuses.find((y) => x.name() === y.name)?.simulationSuccessful + this.statuses.find( + (y) => x.name() === y.name && y.attemptNum === num + )?.simulationSuccessful ).length === itemSets.length, this.priorityFeeSetting ); @@ -480,7 +482,10 @@ export class TransactionsManager { ); } else { await this.debugAccounts(itemSet, tx); - this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting(prevError, attemptNum); + this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting( + prevError, + attemptNum + ); await this.sendTransaction( tx, itemSet.name(), @@ -582,7 +587,9 @@ export class TransactionsManager { this.txHandler.umi, [tx], e, - this.statuses.find((x) => x.name === txName)?.simulationSuccessful, + this.statuses.find( + (x) => x.name === txName && x.attemptNum === attemptNum + )?.simulationSuccessful, priorityFeeSetting ); From f5b4c5b2693b0e6653e74deb64058a16cd82eb22 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Wed, 30 Apr 2025 18:45:27 -0400 Subject: [PATCH 08/88] small fix --- .../src/services/rebalance/rebalanceSwapManager.ts | 2 +- solauto-sdk/src/services/swap/jupSwapManager.ts | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts b/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts index e8a4b1df..b14a5bc7 100644 --- a/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts +++ b/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts @@ -33,7 +33,7 @@ export class RebalanceSwapManager { private targetLiqUtilizationRateBps?: number, private priceType?: PriceType ) { - this.jupSwapManager = new JupSwapManager(client.signer); + this.jupSwapManager = new JupSwapManager(client.signer, true); this.solautoFeeBps = SolautoFeesBps.create( this.client.isReferred, this.targetLiqUtilizationRateBps, diff --git a/solauto-sdk/src/services/swap/jupSwapManager.ts b/solauto-sdk/src/services/swap/jupSwapManager.ts index 28ae971e..6ca7e97d 100644 --- a/solauto-sdk/src/services/swap/jupSwapManager.ts +++ b/solauto-sdk/src/services/swap/jupSwapManager.ts @@ -51,7 +51,10 @@ export class JupSwapManager { public jupQuote: QuoteResponse | undefined = undefined; - constructor(private signer: Signer) {} + constructor( + private signer: Signer, + private limitSize?: boolean + ) {} public async getQuote(data: SwapInput): Promise { const inputMintInfo: TokenInfo | undefined = tokenInfo(data.inputMint); @@ -73,9 +76,10 @@ export class JupSwapManager { ? "ExactIn" : undefined, slippageBps, - maxAccounts: !data.exactOut - ? (lowLiquidityMint ? 25 : 15) + attemptNum * 5 - : undefined, + maxAccounts: + !data.exactOut && this.limitSize + ? (lowLiquidityMint ? 25 : 15) + attemptNum * 5 + : undefined, }), 6, 250 From e49dd6a7294a22d1f7a6e173b6d0e8ce7c98ce83 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Wed, 30 Apr 2025 19:55:41 -0400 Subject: [PATCH 09/88] unused imports --- solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts b/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts index b14a5bc7..6579144c 100644 --- a/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts +++ b/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts @@ -6,12 +6,10 @@ import { JupSwapManager, SwapParams, SwapInput } from "../swap"; import { applyDebtAdjustmentUsd, RebalanceValues } from "./rebalanceValues"; import { PriceType, RebalanceDirection, TokenType } from "../../generated"; import { - bytesToI80F48, consoleLog, fromBaseUnit, fromBps, getLiqUtilzationRateBps, - isMarginfiPosition, safeGetPrice, toBaseUnit, tokenInfo, From 4c3fa12041a2be08e891dc30de4f3039b8ef00da Mon Sep 17 00:00:00 2001 From: Chelioso Date: Thu, 1 May 2025 00:16:36 -0400 Subject: [PATCH 10/88] fixes --- solauto-sdk/package.json | 2 +- solauto-sdk/src/utils/jitoUtils.ts | 47 +++++++++++++++--------------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index d2f29d4e..800e1c55 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.736", + "version": "1.0.737", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/utils/jitoUtils.ts b/solauto-sdk/src/utils/jitoUtils.ts index e145c6a9..ee6f4d6a 100644 --- a/solauto-sdk/src/utils/jitoUtils.ts +++ b/solauto-sdk/src/utils/jitoUtils.ts @@ -160,17 +160,15 @@ async function umiToVersionedTransactions( feeEstimates?: number[], computeUnitLimits?: number[] ): Promise { - let builtTxs = await Promise.all( - txs.map(async (tx, i) => { - return assembleFinalTransaction( - umi, - tx, - feeEstimates ? feeEstimates[i] : undefined, - computeUnitLimits ? computeUnitLimits[i] : undefined - ) - .setBlockhash(blockhash) - .build(umi); - }) + let builtTxs = txs.map((tx, i) => + assembleFinalTransaction( + umi, + tx, + feeEstimates ? feeEstimates[i] : undefined, + computeUnitLimits ? computeUnitLimits[i] : undefined + ) + .setBlockhash(blockhash) + .build(umi) ); if (sign) { @@ -280,7 +278,7 @@ export async function sendJitoBundledTransactions( abortController?: AbortController ): Promise { const txs = [...transactions]; - + if (txs.length === 1) { const resp = await sendSingleOptimizedTransaction( umi, @@ -313,6 +311,7 @@ export async function sendJitoBundledTransactions( if (abortController?.signal.aborted) { return; } + let builtTxs: VersionedTransaction[] = []; let simulationResults: SimulatedTransactionResponse[] | undefined; if (txType !== "skip-simulation") { @@ -324,24 +323,24 @@ export async function sendJitoBundledTransactions( txs, false, undefined, - Array(txs.length).map(_ => 1_400_000) + Array(txs.length).map((_) => 1_400_000) ); simulationResults = await simulateJitoBundle(umi, builtTxs); } const feeEstimates = usePriorityFee(priorityFeeSetting) - ? await Promise.all( - txs.map( - async (x) => - (await getComputeUnitPriceEstimate( - umi, - x, - priorityFeeSetting, - true - )) ?? 1000000 + ? await Promise.all( + txs.map( + async (x) => + (await getComputeUnitPriceEstimate( + umi, + x, + priorityFeeSetting, + true + )) ?? 1000000 + ) ) - ) - : undefined; + : undefined; if (abortController?.signal.aborted) { return; From 773a441bc93a1172fb44810b3d58de81a975ba55 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Thu, 1 May 2025 21:24:53 -0400 Subject: [PATCH 11/88] unused imports --- programs/solauto/src/rebalance/rebalancer.rs | 6 ++---- solauto-sdk/package.json | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/programs/solauto/src/rebalance/rebalancer.rs b/programs/solauto/src/rebalance/rebalancer.rs index b6981768..b6180542 100644 --- a/programs/solauto/src/rebalance/rebalancer.rs +++ b/programs/solauto/src/rebalance/rebalancer.rs @@ -3,7 +3,7 @@ use std::{ ops::{Add, Mul}, }; -use solana_program::{entrypoint::ProgramResult, msg, program_error::ProgramError, pubkey::Pubkey}; +use solana_program::{entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey}; use crate::{ check, @@ -22,9 +22,7 @@ use crate::{ }, utils::{ math_utils::{calc_fee_amount, from_bps, from_rounded_usd_value, usd_value_to_base_unit}, - validation_utils::{ - correct_token_account, value_gte_with_threshold, value_lte_with_threshold, - }, + validation_utils::correct_token_account, }, }; diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 800e1c55..374102d1 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.737", + "version": "1.0.738", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", From e8cdfa5b9aaeaf4e3c98a87ed55a1759aa0baea9 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 2 May 2025 03:39:27 -0400 Subject: [PATCH 12/88] fixes --- solauto-sdk/package.json | 2 +- .../manager/transactionsManager.ts | 508 +++++++++--------- .../services/transactions/transactionUtils.ts | 4 +- solauto-sdk/src/utils/jitoUtils.ts | 3 +- 4 files changed, 251 insertions(+), 266 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 374102d1..aab03d89 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.738", + "version": "1.0.745", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts index 3d89fbb7..99c86301 100644 --- a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts @@ -33,14 +33,16 @@ export enum TransactionStatus { Failed = "Failed", } -export type TransactionManagerStatuses = { +export interface TransactionManagerStatus { name: string; attemptNum: number; status: TransactionStatus; moreInfo?: string; simulationSuccessful?: boolean; txSig?: string; -}[]; +} + +export type TransactionManagerStatuses = TransactionManagerStatus[]; interface RetryConfig { signableRetries?: number; @@ -137,48 +139,34 @@ export class TransactionsManager { return transactionSets; } - private updateStatus( - name: string, - status: TransactionStatus, - attemptNum: number, - txSig?: string, - simulationSuccessful?: boolean, - moreInfo?: string - ) { - if (!this.statuses.filter((x) => x.name === name)) { - this.statuses.push({ - name, - status, - txSig, - attemptNum, - simulationSuccessful, - moreInfo, - }); + private updateStatus(args: TransactionManagerStatus, reset?: boolean) { + if (!this.statuses.filter((x) => x.name === args.name)) { + this.statuses.push(args); } else { const idx = this.statuses.findIndex( - (x) => x.name === name && x.attemptNum === attemptNum + (x) => x.name === args.name && x.attemptNum === args.attemptNum ); if (idx !== -1) { - this.statuses[idx].status = status; - this.statuses[idx].txSig = txSig; - if (simulationSuccessful) { - this.statuses[idx].simulationSuccessful = simulationSuccessful; + this.statuses[idx].status = args.status; + this.statuses[idx].txSig = args.txSig; + if (args.simulationSuccessful) { + this.statuses[idx].simulationSuccessful = args.simulationSuccessful; + } + if (args.moreInfo) { + this.statuses[idx].moreInfo = args.moreInfo; } - if (moreInfo) { - this.statuses[idx].moreInfo = moreInfo; + if (reset) { + this.statuses[idx].txSig = undefined; + this.statuses[idx].simulationSuccessful = undefined; + this.statuses[idx].moreInfo = undefined; } } else { - this.statuses.push({ - name, - status, - txSig, - attemptNum, - simulationSuccessful, - moreInfo, - }); + this.statuses.push(args); } } - this.txHandler.log(`${name} is ${status.toString().toLowerCase()}`); + this.txHandler.log( + `${args.name} ${args.attemptNum} is ${args.status.toString().toLowerCase()}` + ); this.statusCallback?.([...this.statuses]); } @@ -219,21 +207,19 @@ export class TransactionsManager { } private updateStatusForSets( - itemSets: TransactionSet[], - status: TransactionStatus, - attemptNum: number, + txNames: string[], + args: Omit, txSigs?: string[], - simulationSuccessful?: boolean, - moreInfo?: string + reset?: boolean ) { - itemSets.forEach((itemSet, i) => { + txNames.forEach((name, i) => { this.updateStatus( - itemSet.name(), - status, - attemptNum, - txSigs !== undefined ? txSigs[i] : undefined, - simulationSuccessful, - moreInfo + { + name, + txSig: txSigs && txSigs.length > i ? txSigs[i] : undefined, + ...args, + }, + reset ); }); } @@ -254,7 +240,13 @@ export class TransactionsManager { return await this.assembleTransactionSets(items); }, this.totalRetries); - this.updateStatusForSets(itemSets, TransactionStatus.Queued, 0); + this.updateStatusForSets( + itemSets.map((x) => x.name()), + { + status: TransactionStatus.Queued, + attemptNum: 0, + } + ); this.txHandler.log("Initial item sets:", itemSets.length); if (this.atomically) { @@ -271,7 +263,7 @@ export class TransactionsManager { } private shouldProceedToSend(itemSets: TransactionSet[], attemptNum: number) { - if (!itemSets) { + if (itemSets.length === 0) { return false; } @@ -283,19 +275,83 @@ export class TransactionsManager { newItemSetNames[0] === this.updateOracleTxName ) { consoleLog("Skipping unnecessary oracle update"); - this.updateStatusForSets(itemSets, TransactionStatus.Skipped, attemptNum); + this.updateStatusForSets( + itemSets.map((x) => x.name()), + { + status: TransactionStatus.Skipped, + attemptNum, + } + ); return false; } return true; } - private async processTransactionsAtomically(itemSets: TransactionSet[]) { - let num = 0; - let transactions: TransactionBuilder[] = []; + private getTrueAttemptNum(itemSetName: string) { + const prevAttempts = this.statuses.filter( + (x) => x.name === itemSetName && x.status !== TransactionStatus.Queued + ); + const attemptNum = + prevAttempts.length - + prevAttempts.filter((x) => x.status === TransactionStatus.Skipped) + ?.length; + return attemptNum; + } + + private async refreshItemSets( + itemSets: TransactionSet[], + attemptNum: number, + prevError?: Error, + currentIndex?: number + ): Promise { + if (currentIndex !== undefined) { + const itemSet = itemSets[currentIndex]; + await itemSet.reset(); + await itemSet.refetchAll(attemptNum, prevError); + } else { + await Promise.all(itemSets.map((itemSet) => itemSet.reset())); + for (const itemSet of itemSets) { + await itemSet.refetchAll(attemptNum, prevError); + } + } + + const newItemSets = await this.assembleTransactionSets( + currentIndex !== undefined + ? [ + ...itemSets[currentIndex].items, + ...itemSets.slice(currentIndex + 1).flatMap((set) => set.items), + ] + : itemSets.flatMap((set) => set.items) + ); + + if (currentIndex !== undefined && newItemSets.length > 1) { + itemSets.splice( + currentIndex, + itemSets.length - currentIndex, + ...newItemSets + ); + const startOfQueuedStatuses = this.statuses.findIndex( + (x) => x.status === TransactionStatus.Queued + ); + this.statuses.splice( + startOfQueuedStatuses, + this.statuses.length - startOfQueuedStatuses, + ...newItemSets.map((x, i) => ({ + name: x.name(), + attemptNum: i === 0 ? attemptNum : 0, + status: + i === 0 ? TransactionStatus.Processing : TransactionStatus.Queued, + })) + ); + } + + return newItemSets; + } + private async processTransactionsAtomically(itemSets: TransactionSet[]) { await retryWithExponentialBackoff( - async (attemptNum, prevError) => { + async (retryNum, prevError) => { if ( prevError && this.statuses.filter((x) => x.simulationSuccessful).length > @@ -304,13 +360,16 @@ export class TransactionsManager { throw prevError; } - num = attemptNum; + const attemptNum = Math.max( + ...itemSets.map((x) => this.getTrueAttemptNum(x?.name() ?? "")) + ); + this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting( prevError, attemptNum ); - if (attemptNum > 0) { + if (retryNum > 0) { const refreshedSets = await this.refreshItemSets( itemSets, attemptNum, @@ -327,122 +386,86 @@ export class TransactionsManager { return; } - transactions = []; - for (const set of itemSets) { - transactions.push(await set.getSingleTransaction()); - } - transactions = transactions.filter( - (x) => x.getInstructions().length > 0 - ); - if (transactions.length === 0) { - this.updateStatusForSets( - itemSets, - TransactionStatus.Skipped, - attemptNum - ); - return; - } + await this.sendJitoBundle(itemSets, attemptNum); + }, + this.totalRetries, + this.retryDelay, + this.errorsToThrow + ); + } - this.updateStatusForSets( - itemSets, - TransactionStatus.Processing, - attemptNum - ); - for (const itemSet of itemSets) { - await this.debugAccounts( - itemSet, - await itemSet.getSingleTransaction() - ); - } + private async sendJitoBundle(itemSets: TransactionSet[], attemptNum: number) { + let transactions: TransactionBuilder[] = []; + let txNames: string[] = []; - let txSigs: string[] | undefined; - let error: Error | undefined; - try { - txSigs = await sendJitoBundledTransactions( - this.txHandler.umi, - this.txHandler.connection, - this.txHandler.signer, - this.txHandler.otherSigners, - transactions, - this.txRunType, - this.priorityFeeSetting, - () => - this.updateStatusForSets( - itemSets, - TransactionStatus.Processing, - attemptNum, - undefined, - true - ), - this.abortController - ); - } catch (e: any) { - error = e as Error; - } + try { + for (const set of itemSets) { + transactions.push(await set.getSingleTransaction()); + } + transactions = transactions.filter((x) => x.getInstructions().length > 0); - if ( - error || - (this.txRunType !== "only-simulate" && - (!Boolean(txSigs) || txSigs?.length === 0) && - !this.abortController?.signal.aborted) - ) { - this.updateStatusForSets( - itemSets, - TransactionStatus.Failed, - attemptNum, - txSigs, - undefined, - error?.message - ); - throw error ? error : new Error("Unknown error"); - } + txNames = itemSets.map((x) => x.name()); + if (transactions.length === 0) { + this.updateStatusForSets(txNames, { + status: TransactionStatus.Skipped, + attemptNum, + }); + return; + } - this.updateStatusForSets( - itemSets, - TransactionStatus.Successful, + this.updateStatusForSets( + txNames, + { + status: TransactionStatus.Processing, attemptNum, - txSigs - ); - }, - this.totalRetries, - this.retryDelay, - this.errorsToThrow - ).catch((e: Error) => { - this.txHandler.log("Capturing error info..."); - const errorDetails = getErrorInfo( + }, + undefined, + true + ); + for (const itemSet of itemSets) { + await this.debugAccounts(itemSet, await itemSet.getSingleTransaction()); + } + + const txSigs = await sendJitoBundledTransactions( this.txHandler.umi, + this.txHandler.connection, + this.txHandler.signer, + this.txHandler.otherSigners, transactions, - e, - itemSets.filter( - (x) => - this.statuses.find( - (y) => x.name() === y.name && y.attemptNum === num - )?.simulationSuccessful - ).length === itemSets.length, - this.priorityFeeSetting + this.txRunType, + this.priorityFeeSetting, + () => + this.updateStatusForSets(txNames, { + status: TransactionStatus.Processing, + attemptNum, + simulationSuccessful: true, + }), + this.abortController ); - const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`; - const errorInfo = - errorDetails.errorName || errorDetails.errorInfo - ? errorString - : e.message; + if ( + this.txRunType !== "only-simulate" && + (!Boolean(txSigs) || txSigs?.length === 0) && + !this.abortController?.signal.aborted + ) { + this.updateStatusForSets( + txNames, + { + status: TransactionStatus.Failed, + attemptNum, + }, + txSigs + ); + } + this.updateStatusForSets( - itemSets, - errorDetails.canBeIgnored - ? TransactionStatus.Skipped - : TransactionStatus.Failed, - num, - undefined, - undefined, - errorInfo + txNames, + { status: TransactionStatus.Successful, attemptNum }, + txSigs ); - consoleLog(errorString); - - if (!errorDetails.canBeIgnored) { - throw new Error(errorInfo); - } - }); + } catch (e: any) { + this.captureErrorInfo(transactions, txNames, attemptNum, e); + } } private async processTransactionSet( @@ -451,7 +474,7 @@ export class TransactionsManager { ) { let itemSet: TransactionSet | undefined = itemSets[currentIndex]; await retryWithExponentialBackoff( - async (attemptNum, prevError) => { + async (retryNum, prevError) => { if ( prevError && this.statuses.filter((x) => x.simulationSuccessful).length > @@ -460,7 +483,8 @@ export class TransactionsManager { throw prevError; } - if (currentIndex > 0 || attemptNum > 0) { + const attemptNum = this.getTrueAttemptNum(itemSet?.name() ?? ""); + if (currentIndex > 0 || retryNum > 0) { const refreshedSets = await this.refreshItemSets( itemSets, attemptNum, @@ -475,11 +499,11 @@ export class TransactionsManager { const tx = await itemSet.getSingleTransaction(); if (tx.getInstructions().length === 0) { - this.updateStatus( - itemSet.name(), - TransactionStatus.Skipped, - attemptNum - ); + this.updateStatus({ + name: itemSet.name(), + status: TransactionStatus.Skipped, + attemptNum, + }); } else { await this.debugAccounts(itemSet, tx); this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting( @@ -500,64 +524,21 @@ export class TransactionsManager { ); } - private async refreshItemSets( - itemSets: TransactionSet[], - attemptNum: number, - prevError?: Error, - currentIndex?: number - ): Promise { - if (currentIndex !== undefined) { - const itemSet = itemSets[currentIndex]; - await itemSet.reset(); - await itemSet.refetchAll(attemptNum, prevError); - } else { - await Promise.all(itemSets.map((itemSet) => itemSet.reset())); - for (const itemSet of itemSets) { - await itemSet.refetchAll(attemptNum, prevError); - } - } - - const newItemSets = await this.assembleTransactionSets( - currentIndex !== undefined - ? [ - ...itemSets[currentIndex].items, - ...itemSets.slice(currentIndex + 1).flatMap((set) => set.items), - ] - : itemSets.flatMap((set) => set.items) - ); - - if (currentIndex !== undefined && newItemSets.length > 1) { - itemSets.splice( - currentIndex, - itemSets.length - currentIndex, - ...newItemSets - ); - const startOfQueuedStatuses = this.statuses.findIndex( - (x) => x.status === TransactionStatus.Queued - ); - this.statuses.splice( - startOfQueuedStatuses, - this.statuses.length - startOfQueuedStatuses, - ...newItemSets.map((x, i) => ({ - name: x.name(), - attemptNum: i === 0 ? attemptNum : 0, - status: - i === 0 ? TransactionStatus.Processing : TransactionStatus.Queued, - })) - ); - } - - return newItemSets; - } - protected async sendTransaction( tx: TransactionBuilder, - txName: string, + name: string, attemptNum: number, priorityFeeSetting?: PriorityFeeSetting, txRunType?: TransactionRunType ) { - this.updateStatus(txName, TransactionStatus.Processing, attemptNum); + this.updateStatus( + { + name, + status: TransactionStatus.Processing, + attemptNum, + }, + true + ); try { const txSig = await sendSingleOptimizedTransaction( this.txHandler.umi, @@ -566,53 +547,60 @@ export class TransactionsManager { txRunType ?? this.txRunType, priorityFeeSetting, () => - this.updateStatus( - txName, - TransactionStatus.Processing, + this.updateStatus({ + name, + status: TransactionStatus.Processing, attemptNum, - undefined, - true - ), + simulationSuccessful: true, + }), this.abortController ); - this.updateStatus( - txName, - TransactionStatus.Successful, + this.updateStatus({ + name, + status: TransactionStatus.Successful, attemptNum, - txSig ? bs58.encode(txSig) : undefined - ); + txSig: txSig ? bs58.encode(txSig) : undefined, + }); } catch (e: any) { - this.txHandler.log("Capturing error info..."); - const errorDetails = getErrorInfo( - this.txHandler.umi, - [tx], - e, - this.statuses.find( - (x) => x.name === txName && x.attemptNum === attemptNum - )?.simulationSuccessful, - priorityFeeSetting - ); + this.captureErrorInfo([tx], [name], attemptNum, e); + } + } - const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`; - const errorInfo = - errorDetails.errorName || errorDetails.errorInfo - ? errorString - : e.message; - this.updateStatus( - txName, - errorDetails.canBeIgnored - ? TransactionStatus.Skipped - : TransactionStatus.Failed, - attemptNum, - undefined, - undefined, - errorInfo - ); - consoleLog(errorString); + private captureErrorInfo( + transactions: TransactionBuilder[], + txNames: string[], + attemptNum: number, + error: any + ) { + this.txHandler.log("Capturing error info..."); + const errorDetails = getErrorInfo( + this.txHandler.umi, + transactions, + error, + txNames.filter( + (x) => + this.statuses.find((y) => x === y.name && y.attemptNum === attemptNum) + ?.simulationSuccessful + ).length === txNames.length, + this.priorityFeeSetting + ); - if (!errorDetails.canBeIgnored) { - throw new Error(errorInfo); - } + const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`; + const errorInfo = + errorDetails.errorName || errorDetails.errorInfo + ? errorString + : error.message; + this.updateStatusForSets(txNames, { + status: errorDetails.canBeIgnored + ? TransactionStatus.Skipped + : TransactionStatus.Failed, + attemptNum, + moreInfo: errorInfo, + }); + consoleLog(errorString); + + if (!errorDetails.canBeIgnored) { + throw new Error(errorInfo); } } } diff --git a/solauto-sdk/src/services/transactions/transactionUtils.ts b/solauto-sdk/src/services/transactions/transactionUtils.ts index 771018cd..d821b923 100644 --- a/solauto-sdk/src/services/transactions/transactionUtils.ts +++ b/solauto-sdk/src/services/transactions/transactionUtils.ts @@ -637,9 +637,7 @@ export function getErrorInfo( try { if (error instanceof BundleSimulationError) { errTxIdx = error.details.transactionIdx; - errIxIdx = - error.details.instructionIdx - - getComputeIxs(error.details.transactionIdx); + errIxIdx = error.details.instructionIdx - getComputeIxs(errTxIdx); errCode = error.details.errorCode; } else if ( typeof error === "object" && diff --git a/solauto-sdk/src/utils/jitoUtils.ts b/solauto-sdk/src/utils/jitoUtils.ts index ee6f4d6a..e65a623a 100644 --- a/solauto-sdk/src/utils/jitoUtils.ts +++ b/solauto-sdk/src/utils/jitoUtils.ts @@ -211,7 +211,6 @@ async function pollBundleStatus( const statuses = await retryWithExponentialBackoff( async () => { const resp = await getBundleStatus(umi, bundleId); - // TODO: remove me if (resp?.value?.length > 0 && resp.value[0] === null) { throw new Error("No confirmation status"); } @@ -323,7 +322,7 @@ export async function sendJitoBundledTransactions( txs, false, undefined, - Array(txs.length).map((_) => 1_400_000) + Array(txs.length).fill(null).map((_) => 1_400_000) ); simulationResults = await simulateJitoBundle(umi, builtTxs); } From 1d84aeb334d2e3aafc85f2fe0ed08b6fa24f5f28 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 2 May 2025 03:40:25 -0400 Subject: [PATCH 13/88] fix --- .../transactions/manager/transactionsManager.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts index 99c86301..f7f2059d 100644 --- a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts @@ -101,7 +101,7 @@ export class TransactionsManager { items: TransactionItem[] ): Promise { let transactionSets: TransactionSet[] = []; - this.txHandler.log(`Reassembling ${items.length} items`); + consoleLog(`Reassembling ${items.length} items`); const txItems = items.sort((a, b) => a.orderPrio - b.orderPrio); @@ -164,7 +164,7 @@ export class TransactionsManager { this.statuses.push(args); } } - this.txHandler.log( + consoleLog( `${args.name} ${args.attemptNum} is ${args.status.toString().toLowerCase()}` ); this.statusCallback?.([...this.statuses]); @@ -178,13 +178,13 @@ export class TransactionsManager { const accountsNotInLut = ixAccounts.filter( (x) => !lutAccounts.includes(x) ); - this.txHandler.log( + consoleLog( `Program ${ix.programId}, data len: ${ix.data.length}, LUT accounts data: ${ix.keys.filter((x) => lutAccounts.includes(x.pubkey)).length * 3}` ); if (accountsNotInLut.length > 0) { - this.txHandler.log(`${accountsNotInLut.length} accounts not in LUT:`); + consoleLog(`${accountsNotInLut.length} accounts not in LUT:`); for (const key of accountsNotInLut) { - this.txHandler.log(key.toString()); + consoleLog(key.toString()); } } } @@ -236,7 +236,7 @@ export class TransactionsManager { await item.initialize(); } } - this.txHandler.log("Transaction items:", items.length); + consoleLog("Transaction items:", items.length); return await this.assembleTransactionSets(items); }, this.totalRetries); @@ -247,7 +247,7 @@ export class TransactionsManager { attemptNum: 0, } ); - this.txHandler.log("Initial item sets:", itemSets.length); + consoleLog("Initial item sets:", itemSets.length); if (this.atomically) { await this.processTransactionsAtomically(itemSets); @@ -572,7 +572,7 @@ export class TransactionsManager { attemptNum: number, error: any ) { - this.txHandler.log("Capturing error info..."); + consoleLog("Capturing error info..."); const errorDetails = getErrorInfo( this.txHandler.umi, transactions, From 32552d23587010ac1e7990d239974b0832b1d7e2 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 2 May 2025 04:43:20 -0400 Subject: [PATCH 14/88] fix logs --- solauto-sdk/tests/unit/accounts.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/solauto-sdk/tests/unit/accounts.ts b/solauto-sdk/tests/unit/accounts.ts index d574ab59..0eac09c7 100644 --- a/solauto-sdk/tests/unit/accounts.ts +++ b/solauto-sdk/tests/unit/accounts.ts @@ -24,7 +24,6 @@ async function hasTokenAccounts(wallet: PublicKey) { ) ); for (let i = 0; i < tokenAccounts.length; i++) { - console.log(tokenAccounts[i].publicKey.toString()); if (!tokenAccounts[i].exists) { console.log( `Missing ${wallet.toString()} TA for `, @@ -55,7 +54,9 @@ describe("Assert Solauto fee token accounts are created", async () => { !ismAccounts.find((x) => group.equals(toWeb3JsPublicKey(x.group))) ); - console.log("Missing ISM accounts", missingIsmAccounts); + if (missingIsmAccounts.length > 0) { + console.log("Missing ISM accounts", missingIsmAccounts); + } assert(missingIsmAccounts.length === 0); }); }); From 98aa25aa92ac8910429d3ae4e74ef5647c221afd Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 2 May 2025 04:48:29 -0400 Subject: [PATCH 15/88] readmes --- README.md | 6 +++--- solauto-sdk/README.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 848249f5..6852fb18 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ pnpm add @haven-fi/solauto-sdk ```typescript import { PublicKey } from "@solana/web3.js"; +import { NATIVE_MINT } from "@solana/spl-token"; import * as solauto from "@haven-fi/solauto-sdk"; // Create new Solauto client @@ -73,8 +74,8 @@ const client = solauto.getClient(solauto.LendingPlatform.MARGINFI, { }); // Initialize the client -const supplyMint = new PublicKey(NATIVE_MINT); -const debtMint = new PublicKey(USDC); +const supplyMint = NATIVE_MINT; +const debtMint = new PublicKey(solauto.USDC); await client.initializeNewSolautoPosition({ positionId: 1, lpPoolAccount: solauto.getMarginfiAccounts().defaultGroup, @@ -133,7 +134,6 @@ const statuses = txManager.send(transactionItems); ## Rebalancing an existing position ```typescript -import { PublicKey } from "@solana/web3.js"; import * as solauto from "@haven-fi/solauto-sdk"; // Create new Solauto client diff --git a/solauto-sdk/README.md b/solauto-sdk/README.md index 73c4d0f8..23280571 100644 --- a/solauto-sdk/README.md +++ b/solauto-sdk/README.md @@ -6,6 +6,7 @@ Solauto is a program on the Solana blockchain that lets you manage leveraged lon ```typescript import { PublicKey } from "@solana/web3.js"; +import { NATIVE_MINT } from "@solana/spl-token"; import * as solauto from "@haven-fi/solauto-sdk"; // Create new Solauto client @@ -15,8 +16,8 @@ const client = solauto.getClient(solauto.LendingPlatform.MARGINFI, { }); // Initialize the client -const supplyMint = new PublicKey(NATIVE_MINT); -const debtMint = new PublicKey(USDC); +const supplyMint = NATIVE_MINT; +const debtMint = new PublicKey(solauto.USDC); await client.initializeNewSolautoPosition({ positionId: 1, lpPoolAccount: solauto.getMarginfiAccounts().defaultGroup, @@ -75,7 +76,6 @@ const statuses = txManager.send(transactionItems); ## Rebalancing an existing position ```typescript -import { PublicKey } from "@solana/web3.js"; import * as solauto from "@haven-fi/solauto-sdk"; // Create new Solauto client From 241c15c66435cd2d4f7df05a3cfa5aafe6a24952 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 2 May 2025 13:10:44 -0400 Subject: [PATCH 16/88] fix --- solauto-sdk/package.json | 2 +- .../manager/transactionsManager.ts | 24 ++++--------------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index aab03d89..8906fff0 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.745", + "version": "1.0.746", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts index f7f2059d..40a385b8 100644 --- a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts @@ -288,17 +288,6 @@ export class TransactionsManager { return true; } - private getTrueAttemptNum(itemSetName: string) { - const prevAttempts = this.statuses.filter( - (x) => x.name === itemSetName && x.status !== TransactionStatus.Queued - ); - const attemptNum = - prevAttempts.length - - prevAttempts.filter((x) => x.status === TransactionStatus.Skipped) - ?.length; - return attemptNum; - } - private async refreshItemSets( itemSets: TransactionSet[], attemptNum: number, @@ -351,7 +340,7 @@ export class TransactionsManager { private async processTransactionsAtomically(itemSets: TransactionSet[]) { await retryWithExponentialBackoff( - async (retryNum, prevError) => { + async (attemptNum, prevError) => { if ( prevError && this.statuses.filter((x) => x.simulationSuccessful).length > @@ -360,16 +349,12 @@ export class TransactionsManager { throw prevError; } - const attemptNum = Math.max( - ...itemSets.map((x) => this.getTrueAttemptNum(x?.name() ?? "")) - ); - this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting( prevError, attemptNum ); - if (retryNum > 0) { + if (attemptNum > 0) { const refreshedSets = await this.refreshItemSets( itemSets, attemptNum, @@ -474,7 +459,7 @@ export class TransactionsManager { ) { let itemSet: TransactionSet | undefined = itemSets[currentIndex]; await retryWithExponentialBackoff( - async (retryNum, prevError) => { + async (attemptNum, prevError) => { if ( prevError && this.statuses.filter((x) => x.simulationSuccessful).length > @@ -483,8 +468,7 @@ export class TransactionsManager { throw prevError; } - const attemptNum = this.getTrueAttemptNum(itemSet?.name() ?? ""); - if (currentIndex > 0 || retryNum > 0) { + if (currentIndex > 0 || attemptNum > 0) { const refreshedSets = await this.refreshItemSets( itemSets, attemptNum, From b8a7d5e4d463c52209c41a71a78ed399b48ced36 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 2 May 2025 15:44:14 -0400 Subject: [PATCH 17/88] fixes --- solauto-sdk/package.json | 2 +- .../transactions/manager/clientTransactionsManager.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 8906fff0..2bd5a72b 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.746", + "version": "1.0.748", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts b/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts index f5c4cc34..bc8a9dfb 100644 --- a/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts @@ -75,7 +75,7 @@ export class ClientTransactionsManager extends TransactionsManager 4)) { + const updateLutInSepTx = updateLut?.new || (updateLut?.accountsToAdd ?? []).length > 4; + if (updateLut && updateLutInSepTx) { await this.updateLut(updateLut.tx, updateLut.new); } this.lookupTables.defaultLuts = client.defaultLookupTables(); @@ -124,7 +125,7 @@ export class ClientTransactionsManager extends TransactionsManager { From 2f1a7c028289ab5c7450b82b086da4b8e89dffb0 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 2 May 2025 16:41:28 -0400 Subject: [PATCH 18/88] add patch lut --- package.json | 1 + solauto-sdk/local/patchLUT.ts | 93 +++++++++++++++++++ solauto-sdk/local/shared.ts | 1 + solauto-sdk/src/constants/solautoConstants.ts | 3 + solauto-sdk/src/utils/solautoUtils.ts | 2 +- 5 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 solauto-sdk/local/patchLUT.ts diff --git a/package.json b/package.json index 1095f5da..c81239e0 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "sandbox": "cd solauto-sdk && npx ts-node local/txSandbox.ts", "update-lut:solauto": "cd solauto-sdk && npx ts-node local/updateSolautoLUT.ts", "update-lut:marginfi": "cd solauto-sdk && npx ts-node local/updateMarginfiLUT.ts", + "patch-lut": "cd solauto-sdk && npx ts-node local/patchLUT.ts", "create-token-accounts": "cd solauto-sdk && npx ts-node local/createTokenAccounts.ts", "prepare-accounts": "pnpm create-token-accounts && pnpm update-lut:solauto && pnpm update-lut:marginfi", "log-pos": "cd solauto-sdk && npx ts-node local/logPositions.ts", diff --git a/solauto-sdk/local/patchLUT.ts b/solauto-sdk/local/patchLUT.ts new file mode 100644 index 00000000..9ad01fd5 --- /dev/null +++ b/solauto-sdk/local/patchLUT.ts @@ -0,0 +1,93 @@ +import { + fromWeb3JsPublicKey, + toWeb3JsPublicKey, +} from "@metaplex-foundation/umi-web3js-adapters"; +import { + fetchAllReferralState, + getPositionExBulk, + getReferralState, + getSolanaRpcConnection, + getSolautoManagedPositions, + getTokenAccount, + LOCAL_IRONFORGE_API_URL, + PATCH_LUT, + SOLAUTO_PROD_PROGRAM, +} from "../src"; +import { PublicKey } from "@solana/web3.js"; +import { updateLookupTable } from "./shared"; + +let [conn, umi] = getSolanaRpcConnection( + LOCAL_IRONFORGE_API_URL, + SOLAUTO_PROD_PROGRAM +); + +async function getMissingAccounts() { + const allMissingAccounts: string[] = []; + const allPositions = await getSolautoManagedPositions(umi); + const positions = await getPositionExBulk( + umi, + allPositions.map((x) => x.publicKey!) + ); + + const referralStates = positions.map((x) => + getReferralState( + x.authority, + toWeb3JsPublicKey(umi.programs.get("solauto").publicKey) + ) + ); + const referralStatesData = await fetchAllReferralState( + umi, + referralStates.map((x) => fromWeb3JsPublicKey(x)) + ); + + const users = Array.from( + new Set(positions.map((x) => x.authority.toString())) + ); + for (const user of users) { + const authority = new PublicKey(user); + const referralState = referralStatesData.find((x) => + toWeb3JsPublicKey(x.authority).equals(authority) + )!; + const lookupTable = referralState.lookupTable; + + const existingUserLUTAccounts = + ( + await conn.getAddressLookupTable(toWeb3JsPublicKey(lookupTable), { + commitment: "confirmed", + }) + ).value?.state?.addresses ?? []; + + const userPositions = positions.filter((x) => + x.authority.equals(authority) + ); + + let requiredAccounts = userPositions.flatMap((x) => { + return [ + getTokenAccount(authority, x.supplyMint), + getTokenAccount(authority, x.debtMint), + x.publicKey, + x.lpUserAccount!, + getTokenAccount(x.publicKey, x.supplyMint), + getTokenAccount(x.publicKey, x.debtMint), + ].map((x) => x.toString()); + }); + requiredAccounts = Array.from(new Set(requiredAccounts)); + + const missingAccounts = requiredAccounts.filter( + (x) => + existingUserLUTAccounts.find((y) => y.toString() === x) === undefined + ); + + if (missingAccounts.length) { + console.log("\nMissing accounts for", referralState.publicKey.toString()); + console.log(missingAccounts); + allMissingAccounts.push(...missingAccounts); + } + } + + return allMissingAccounts; +} + +getMissingAccounts().then(async (accs) => { + await updateLookupTable(accs, new PublicKey(PATCH_LUT)); +}); diff --git a/solauto-sdk/local/shared.ts b/solauto-sdk/local/shared.ts index c81e1c51..1f162236 100644 --- a/solauto-sdk/local/shared.ts +++ b/solauto-sdk/local/shared.ts @@ -110,6 +110,7 @@ export async function updateLookupTable( lookupTableAddress = addr; console.log("Lookup Table Address:", lookupTableAddress.toString()); await createAndSendV0Tx([createLutIx], keypair); + CACHE[lookupTableAddress.toString()] = []; } const existingAccounts = CACHE[lookupTableAddress.toString()]; diff --git a/solauto-sdk/src/constants/solautoConstants.ts b/solauto-sdk/src/constants/solautoConstants.ts index c87fb8db..eb9a7150 100644 --- a/solauto-sdk/src/constants/solautoConstants.ts +++ b/solauto-sdk/src/constants/solautoConstants.ts @@ -65,3 +65,6 @@ export const STANDARD_LUT_ACCOUNTS = [ SYSVAR_INSTRUCTIONS_PUBKEY, JUPITER_PROGRAM_ID, ].map((x) => x.toString()); + +// TODO: remove me +export const PATCH_LUT = "CmPZfu3tkeoMutytxhVKT7Hemuwd5jM65VdLNGdBddxQ"; \ No newline at end of file diff --git a/solauto-sdk/src/utils/solautoUtils.ts b/solauto-sdk/src/utils/solautoUtils.ts index f98ef1f4..6703aeaf 100644 --- a/solauto-sdk/src/utils/solautoUtils.ts +++ b/solauto-sdk/src/utils/solautoUtils.ts @@ -19,7 +19,7 @@ import { getSolautoPositionAccountDataSerializer, getSolautoPositionSize, } from "../generated"; -import { ALL_SUPPORTED_TOKENS, SOLAUTO_PROD_PROGRAM } from "../constants"; +import { SOLAUTO_PROD_PROGRAM } from "../constants"; import { SolautoPositionDetails } from "../types"; import { SolautoClient, From f03cce374c78fbe3f96fe96b2cfb045363fbd131 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 2 May 2025 17:17:58 -0400 Subject: [PATCH 19/88] add patch lut --- solauto-sdk/package.json | 2 +- solauto-sdk/src/constants/solautoConstants.ts | 12 +++++++++++- solauto-sdk/src/services/solauto/solautoClient.ts | 12 +++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 2bd5a72b..ef3bff57 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.748", + "version": "1.0.749", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/constants/solautoConstants.ts b/solauto-sdk/src/constants/solautoConstants.ts index eb9a7150..fd6e98a7 100644 --- a/solauto-sdk/src/constants/solautoConstants.ts +++ b/solauto-sdk/src/constants/solautoConstants.ts @@ -67,4 +67,14 @@ export const STANDARD_LUT_ACCOUNTS = [ ].map((x) => x.toString()); // TODO: remove me -export const PATCH_LUT = "CmPZfu3tkeoMutytxhVKT7Hemuwd5jM65VdLNGdBddxQ"; \ No newline at end of file +export const PATCH_LUT = "CmPZfu3tkeoMutytxhVKT7Hemuwd5jM65VdLNGdBddxQ"; +export const AUTHORITIES_REQUIRING_PATCH_LUT = [ + "5UqsR2PGzbP8pGPbXEeXx86Gjz2N2UFBAuFZUSVydAEe", + "F2uk8zsKMex8MztU7saFNq6tNbj4esWnKLJXyfo2egax", + "8Vo5ScTZ1qNTYhMEibq2fekRe5DotmdqpcD2nprmRzJg", + "HLDgPtVv2Yyzzze462P89igFnyLxaCM3f9hVFmCuAX97", + "48CDX2mhhj9iAZthMWJKHFV9wvii9cxzDdtQKuAVwqEu", + "BRgwGasCSz1zA4yqdcvurAGV7ZroAJ9bvDNvdYj7az4X", + "9PCRbk8Gvt2zqewLKbxaSyTxA2JMtdQGhMff8EdELXNq", + "C4cnE5kDRRnqfiLuWShvoGNDstq6yk91N2PWTxQ6Hmk2", +]; diff --git a/solauto-sdk/src/services/solauto/solautoClient.ts b/solauto-sdk/src/services/solauto/solautoClient.ts index 074ec385..364428db 100644 --- a/solauto-sdk/src/services/solauto/solautoClient.ts +++ b/solauto-sdk/src/services/solauto/solautoClient.ts @@ -29,7 +29,12 @@ import { splTokenTransferUmiIx, ContextUpdates, } from "../../utils"; -import { SOLAUTO_FEES_WALLET, SOLAUTO_LUT } from "../../constants"; +import { + AUTHORITIES_REQUIRING_PATCH_LUT, + PATCH_LUT, + SOLAUTO_FEES_WALLET, + SOLAUTO_LUT, +} from "../../constants"; import { ProgramEnv, RebalanceDetails } from "../../types"; import { ReferralStateManager, @@ -221,6 +226,11 @@ export abstract class SolautoClient extends ReferralStateManager { ...(this.authorityLutAddress ? [this.authorityLutAddress.toString()] : []), + ...(AUTHORITIES_REQUIRING_PATCH_LUT.includes( + this.pos.authority.toString() + ) + ? [PATCH_LUT] + : []), ]; } From 540bbd57c600518c3adabdd42ab4a873425244ce Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sat, 3 May 2025 15:04:32 -0400 Subject: [PATCH 20/88] some re-organizing files --- generateClients.cjs | 6 +++--- solauto-sdk/src/constants/solautoConstants.ts | 2 +- solauto-sdk/src/externalSdks/index.ts | 3 +++ .../{jupiter-sdk => externalSdks/jupiter}/errors/index.ts | 0 .../{jupiter-sdk => externalSdks/jupiter}/errors/jupiter.ts | 0 .../src/{jupiter-sdk => externalSdks/jupiter}/index.ts | 0 .../{jupiter-sdk => externalSdks/jupiter}/programs/index.ts | 0 .../jupiter}/programs/jupiter.ts | 0 .../marginfi}/accounts/bank.ts | 0 .../marginfi}/accounts/index.ts | 0 .../marginfi}/accounts/marginfiAccount.ts | 0 .../marginfi}/accounts/marginfiGroup.ts | 0 .../{marginfi-sdk => externalSdks/marginfi}/errors/index.ts | 0 .../marginfi}/errors/marginfi.ts | 0 .../src/{marginfi-sdk => externalSdks/marginfi}/index.ts | 0 .../marginfi}/instructions/index.ts | 0 .../marginfi}/instructions/lendingAccountBorrow.ts | 0 .../marginfi}/instructions/lendingAccountCloseBalance.ts | 0 .../marginfi}/instructions/lendingAccountDeposit.ts | 0 .../marginfi}/instructions/lendingAccountEndFlashloan.ts | 0 .../marginfi}/instructions/lendingAccountLiquidate.ts | 0 .../marginfi}/instructions/lendingAccountRepay.ts | 0 .../marginfi}/instructions/lendingAccountSettleEmissions.ts | 0 .../marginfi}/instructions/lendingAccountStartFlashloan.ts | 0 .../marginfi}/instructions/lendingAccountWithdraw.ts | 0 .../instructions/lendingAccountWithdrawEmissions.ts | 0 .../marginfi}/instructions/lendingPoolAccrueBankInterest.ts | 0 .../marginfi}/instructions/lendingPoolAddBank.ts | 0 .../marginfi}/instructions/lendingPoolAddBankWithSeed.ts | 0 .../marginfi}/instructions/lendingPoolCollectBankFees.ts | 0 .../marginfi}/instructions/lendingPoolConfigureBank.ts | 0 .../marginfi}/instructions/lendingPoolHandleBankruptcy.ts | 0 .../marginfi}/instructions/lendingPoolSetupEmissions.ts | 0 .../instructions/lendingPoolUpdateEmissionsParameters.ts | 0 .../marginfi}/instructions/marginfiAccountInitialize.ts | 0 .../marginfi}/instructions/marginfiGroupConfigure.ts | 0 .../marginfi}/instructions/marginfiGroupInitialize.ts | 0 .../marginfi}/instructions/setAccountFlag.ts | 0 .../marginfi}/instructions/setNewAccountAuthority.ts | 0 .../marginfi}/instructions/unsetAccountFlag.ts | 0 .../marginfi}/programs/index.ts | 0 .../marginfi}/programs/marginfi.ts | 0 .../{marginfi-sdk => externalSdks/marginfi}/shared/index.ts | 0 .../marginfi}/types/accountEventHeader.ts | 0 .../marginfi}/types/balance.ts | 0 .../marginfi}/types/balanceDecreaseType.ts | 0 .../marginfi}/types/balanceIncreaseType.ts | 0 .../marginfi}/types/balanceSide.ts | 0 .../marginfi}/types/bankConfig.ts | 0 .../marginfi}/types/bankConfigCompact.ts | 0 .../marginfi}/types/bankOperationalState.ts | 0 .../marginfi}/types/bankVaultType.ts | 0 .../marginfi}/types/groupEventHeader.ts | 0 .../{marginfi-sdk => externalSdks/marginfi}/types/index.ts | 0 .../marginfi}/types/interestRateConfig.ts | 0 .../marginfi}/types/interestRateConfigCompact.ts | 0 .../marginfi}/types/interestRateConfigOpt.ts | 0 .../marginfi}/types/lendingAccount.ts | 0 .../marginfi}/types/liquidationBalances.ts | 0 .../marginfi}/types/oracleConfig.ts | 0 .../marginfi}/types/oraclePriceType.ts | 0 .../marginfi}/types/oracleSetup.ts | 0 .../marginfi}/types/priceBias.ts | 0 .../marginfi}/types/requirementType.ts | 0 .../marginfi}/types/riskRequirementType.ts | 0 .../marginfi}/types/riskTier.ts | 0 .../marginfi}/types/wrappedI80F48.ts | 0 .../src/{pyth-sdk => externalSdks/pyth}/accounts/index.ts | 0 .../pyth}/accounts/priceUpdateV2Account.ts | 0 solauto-sdk/src/{pyth-sdk => externalSdks/pyth}/index.ts | 0 .../src/{pyth-sdk => externalSdks/pyth}/types/index.ts | 0 .../{pyth-sdk => externalSdks/pyth}/types/priceMessage.ts | 0 .../{pyth-sdk => externalSdks/pyth}/types/priceUpdateV2.ts | 0 solauto-sdk/src/index.ts | 6 +++--- solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts | 2 +- solauto-sdk/src/services/solauto/solautoMarginfiClient.ts | 2 +- solauto-sdk/src/services/transactions/transactionUtils.ts | 4 ++-- .../src/solautoPosition/marginfiSolautoPositionEx.ts | 2 +- solauto-sdk/src/utils/marginfi/data.ts | 2 +- solauto-sdk/src/utils/marginfi/general.ts | 2 +- solauto-sdk/src/utils/priceUtils.ts | 2 +- solauto-sdk/src/utils/pythUtils.ts | 2 +- solauto-sdk/src/utils/solanaUtils.ts | 2 +- 83 files changed, 20 insertions(+), 17 deletions(-) create mode 100644 solauto-sdk/src/externalSdks/index.ts rename solauto-sdk/src/{jupiter-sdk => externalSdks/jupiter}/errors/index.ts (100%) rename solauto-sdk/src/{jupiter-sdk => externalSdks/jupiter}/errors/jupiter.ts (100%) rename solauto-sdk/src/{jupiter-sdk => externalSdks/jupiter}/index.ts (100%) rename solauto-sdk/src/{jupiter-sdk => externalSdks/jupiter}/programs/index.ts (100%) rename solauto-sdk/src/{jupiter-sdk => externalSdks/jupiter}/programs/jupiter.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/accounts/bank.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/accounts/index.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/accounts/marginfiAccount.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/accounts/marginfiGroup.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/errors/index.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/errors/marginfi.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/index.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/index.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingAccountBorrow.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingAccountCloseBalance.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingAccountDeposit.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingAccountEndFlashloan.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingAccountLiquidate.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingAccountRepay.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingAccountSettleEmissions.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingAccountStartFlashloan.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingAccountWithdraw.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingAccountWithdrawEmissions.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingPoolAccrueBankInterest.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingPoolAddBank.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingPoolAddBankWithSeed.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingPoolCollectBankFees.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingPoolConfigureBank.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingPoolHandleBankruptcy.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingPoolSetupEmissions.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/lendingPoolUpdateEmissionsParameters.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/marginfiAccountInitialize.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/marginfiGroupConfigure.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/marginfiGroupInitialize.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/setAccountFlag.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/setNewAccountAuthority.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/instructions/unsetAccountFlag.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/programs/index.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/programs/marginfi.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/shared/index.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/accountEventHeader.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/balance.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/balanceDecreaseType.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/balanceIncreaseType.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/balanceSide.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/bankConfig.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/bankConfigCompact.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/bankOperationalState.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/bankVaultType.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/groupEventHeader.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/index.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/interestRateConfig.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/interestRateConfigCompact.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/interestRateConfigOpt.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/lendingAccount.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/liquidationBalances.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/oracleConfig.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/oraclePriceType.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/oracleSetup.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/priceBias.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/requirementType.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/riskRequirementType.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/riskTier.ts (100%) rename solauto-sdk/src/{marginfi-sdk => externalSdks/marginfi}/types/wrappedI80F48.ts (100%) rename solauto-sdk/src/{pyth-sdk => externalSdks/pyth}/accounts/index.ts (100%) rename solauto-sdk/src/{pyth-sdk => externalSdks/pyth}/accounts/priceUpdateV2Account.ts (100%) rename solauto-sdk/src/{pyth-sdk => externalSdks/pyth}/index.ts (100%) rename solauto-sdk/src/{pyth-sdk => externalSdks/pyth}/types/index.ts (100%) rename solauto-sdk/src/{pyth-sdk => externalSdks/pyth}/types/priceMessage.ts (100%) rename solauto-sdk/src/{pyth-sdk => externalSdks/pyth}/types/priceUpdateV2.ts (100%) diff --git a/generateClients.cjs b/generateClients.cjs index bb81b02c..c65890e3 100644 --- a/generateClients.cjs +++ b/generateClients.cjs @@ -98,7 +98,7 @@ generateSolautoSDK(); // "MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA" // ); // generateTypescriptSDKForAnchorIDL( -// "marginfi-sdk", +// "marginfiSdk", // "marginfi.json", // "MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA" // ); @@ -109,12 +109,12 @@ generateSolautoSDK(); // "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4" // ); // generateTypescriptSDKForAnchorIDL( -// "jupiter-sdk", +// "jupiterSdk", // "jupiter.json", // "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4" // ); // generateTypescriptSDKForAnchorIDL( -// "pyth-sdk", +// "pythSdk", // "pyth.json", // "pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT" // ); diff --git a/solauto-sdk/src/constants/solautoConstants.ts b/solauto-sdk/src/constants/solautoConstants.ts index fd6e98a7..e9f6837a 100644 --- a/solauto-sdk/src/constants/solautoConstants.ts +++ b/solauto-sdk/src/constants/solautoConstants.ts @@ -10,7 +10,7 @@ import { TOKEN_PROGRAM_ID, } from "@solana/spl-token"; import { SOLAUTO_MANAGER } from "./generalConstants"; -import { JUPITER_PROGRAM_ID } from "../jupiter-sdk"; +import { JUPITER_PROGRAM_ID } from "../externalSdks/jupiter"; export const SOLAUTO_PROD_PROGRAM = new PublicKey( "AutoyKBRaHSBHy9RsmXCZMy6nNFAg5FYijrvZyQcNLV" diff --git a/solauto-sdk/src/externalSdks/index.ts b/solauto-sdk/src/externalSdks/index.ts new file mode 100644 index 00000000..993974aa --- /dev/null +++ b/solauto-sdk/src/externalSdks/index.ts @@ -0,0 +1,3 @@ +export * from "./jupiter"; +export * from "./marginfi"; +export * from "./pyth"; \ No newline at end of file diff --git a/solauto-sdk/src/jupiter-sdk/errors/index.ts b/solauto-sdk/src/externalSdks/jupiter/errors/index.ts similarity index 100% rename from solauto-sdk/src/jupiter-sdk/errors/index.ts rename to solauto-sdk/src/externalSdks/jupiter/errors/index.ts diff --git a/solauto-sdk/src/jupiter-sdk/errors/jupiter.ts b/solauto-sdk/src/externalSdks/jupiter/errors/jupiter.ts similarity index 100% rename from solauto-sdk/src/jupiter-sdk/errors/jupiter.ts rename to solauto-sdk/src/externalSdks/jupiter/errors/jupiter.ts diff --git a/solauto-sdk/src/jupiter-sdk/index.ts b/solauto-sdk/src/externalSdks/jupiter/index.ts similarity index 100% rename from solauto-sdk/src/jupiter-sdk/index.ts rename to solauto-sdk/src/externalSdks/jupiter/index.ts diff --git a/solauto-sdk/src/jupiter-sdk/programs/index.ts b/solauto-sdk/src/externalSdks/jupiter/programs/index.ts similarity index 100% rename from solauto-sdk/src/jupiter-sdk/programs/index.ts rename to solauto-sdk/src/externalSdks/jupiter/programs/index.ts diff --git a/solauto-sdk/src/jupiter-sdk/programs/jupiter.ts b/solauto-sdk/src/externalSdks/jupiter/programs/jupiter.ts similarity index 100% rename from solauto-sdk/src/jupiter-sdk/programs/jupiter.ts rename to solauto-sdk/src/externalSdks/jupiter/programs/jupiter.ts diff --git a/solauto-sdk/src/marginfi-sdk/accounts/bank.ts b/solauto-sdk/src/externalSdks/marginfi/accounts/bank.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/accounts/bank.ts rename to solauto-sdk/src/externalSdks/marginfi/accounts/bank.ts diff --git a/solauto-sdk/src/marginfi-sdk/accounts/index.ts b/solauto-sdk/src/externalSdks/marginfi/accounts/index.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/accounts/index.ts rename to solauto-sdk/src/externalSdks/marginfi/accounts/index.ts diff --git a/solauto-sdk/src/marginfi-sdk/accounts/marginfiAccount.ts b/solauto-sdk/src/externalSdks/marginfi/accounts/marginfiAccount.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/accounts/marginfiAccount.ts rename to solauto-sdk/src/externalSdks/marginfi/accounts/marginfiAccount.ts diff --git a/solauto-sdk/src/marginfi-sdk/accounts/marginfiGroup.ts b/solauto-sdk/src/externalSdks/marginfi/accounts/marginfiGroup.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/accounts/marginfiGroup.ts rename to solauto-sdk/src/externalSdks/marginfi/accounts/marginfiGroup.ts diff --git a/solauto-sdk/src/marginfi-sdk/errors/index.ts b/solauto-sdk/src/externalSdks/marginfi/errors/index.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/errors/index.ts rename to solauto-sdk/src/externalSdks/marginfi/errors/index.ts diff --git a/solauto-sdk/src/marginfi-sdk/errors/marginfi.ts b/solauto-sdk/src/externalSdks/marginfi/errors/marginfi.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/errors/marginfi.ts rename to solauto-sdk/src/externalSdks/marginfi/errors/marginfi.ts diff --git a/solauto-sdk/src/marginfi-sdk/index.ts b/solauto-sdk/src/externalSdks/marginfi/index.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/index.ts rename to solauto-sdk/src/externalSdks/marginfi/index.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/index.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/index.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/index.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/index.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountBorrow.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountBorrow.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingAccountBorrow.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountBorrow.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountCloseBalance.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountCloseBalance.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingAccountCloseBalance.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountCloseBalance.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountDeposit.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountDeposit.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingAccountDeposit.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountDeposit.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountEndFlashloan.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountEndFlashloan.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingAccountEndFlashloan.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountEndFlashloan.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountLiquidate.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountLiquidate.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingAccountLiquidate.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountLiquidate.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountRepay.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountRepay.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingAccountRepay.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountRepay.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountSettleEmissions.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountSettleEmissions.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingAccountSettleEmissions.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountSettleEmissions.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountStartFlashloan.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountStartFlashloan.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingAccountStartFlashloan.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountStartFlashloan.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountWithdraw.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountWithdraw.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingAccountWithdraw.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountWithdraw.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingAccountWithdrawEmissions.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountWithdrawEmissions.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingAccountWithdrawEmissions.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingAccountWithdrawEmissions.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingPoolAccrueBankInterest.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolAccrueBankInterest.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingPoolAccrueBankInterest.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolAccrueBankInterest.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingPoolAddBank.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolAddBank.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingPoolAddBank.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolAddBank.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingPoolAddBankWithSeed.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolAddBankWithSeed.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingPoolAddBankWithSeed.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolAddBankWithSeed.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingPoolCollectBankFees.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolCollectBankFees.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingPoolCollectBankFees.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolCollectBankFees.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingPoolConfigureBank.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolConfigureBank.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingPoolConfigureBank.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolConfigureBank.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingPoolHandleBankruptcy.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolHandleBankruptcy.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingPoolHandleBankruptcy.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolHandleBankruptcy.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingPoolSetupEmissions.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolSetupEmissions.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingPoolSetupEmissions.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolSetupEmissions.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/lendingPoolUpdateEmissionsParameters.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolUpdateEmissionsParameters.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/lendingPoolUpdateEmissionsParameters.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/lendingPoolUpdateEmissionsParameters.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/marginfiAccountInitialize.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/marginfiAccountInitialize.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/marginfiAccountInitialize.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/marginfiAccountInitialize.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/marginfiGroupConfigure.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/marginfiGroupConfigure.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/marginfiGroupConfigure.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/marginfiGroupConfigure.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/marginfiGroupInitialize.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/marginfiGroupInitialize.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/marginfiGroupInitialize.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/marginfiGroupInitialize.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/setAccountFlag.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/setAccountFlag.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/setAccountFlag.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/setAccountFlag.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/setNewAccountAuthority.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/setNewAccountAuthority.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/setNewAccountAuthority.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/setNewAccountAuthority.ts diff --git a/solauto-sdk/src/marginfi-sdk/instructions/unsetAccountFlag.ts b/solauto-sdk/src/externalSdks/marginfi/instructions/unsetAccountFlag.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/instructions/unsetAccountFlag.ts rename to solauto-sdk/src/externalSdks/marginfi/instructions/unsetAccountFlag.ts diff --git a/solauto-sdk/src/marginfi-sdk/programs/index.ts b/solauto-sdk/src/externalSdks/marginfi/programs/index.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/programs/index.ts rename to solauto-sdk/src/externalSdks/marginfi/programs/index.ts diff --git a/solauto-sdk/src/marginfi-sdk/programs/marginfi.ts b/solauto-sdk/src/externalSdks/marginfi/programs/marginfi.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/programs/marginfi.ts rename to solauto-sdk/src/externalSdks/marginfi/programs/marginfi.ts diff --git a/solauto-sdk/src/marginfi-sdk/shared/index.ts b/solauto-sdk/src/externalSdks/marginfi/shared/index.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/shared/index.ts rename to solauto-sdk/src/externalSdks/marginfi/shared/index.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/accountEventHeader.ts b/solauto-sdk/src/externalSdks/marginfi/types/accountEventHeader.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/accountEventHeader.ts rename to solauto-sdk/src/externalSdks/marginfi/types/accountEventHeader.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/balance.ts b/solauto-sdk/src/externalSdks/marginfi/types/balance.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/balance.ts rename to solauto-sdk/src/externalSdks/marginfi/types/balance.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/balanceDecreaseType.ts b/solauto-sdk/src/externalSdks/marginfi/types/balanceDecreaseType.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/balanceDecreaseType.ts rename to solauto-sdk/src/externalSdks/marginfi/types/balanceDecreaseType.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/balanceIncreaseType.ts b/solauto-sdk/src/externalSdks/marginfi/types/balanceIncreaseType.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/balanceIncreaseType.ts rename to solauto-sdk/src/externalSdks/marginfi/types/balanceIncreaseType.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/balanceSide.ts b/solauto-sdk/src/externalSdks/marginfi/types/balanceSide.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/balanceSide.ts rename to solauto-sdk/src/externalSdks/marginfi/types/balanceSide.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/bankConfig.ts b/solauto-sdk/src/externalSdks/marginfi/types/bankConfig.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/bankConfig.ts rename to solauto-sdk/src/externalSdks/marginfi/types/bankConfig.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/bankConfigCompact.ts b/solauto-sdk/src/externalSdks/marginfi/types/bankConfigCompact.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/bankConfigCompact.ts rename to solauto-sdk/src/externalSdks/marginfi/types/bankConfigCompact.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/bankOperationalState.ts b/solauto-sdk/src/externalSdks/marginfi/types/bankOperationalState.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/bankOperationalState.ts rename to solauto-sdk/src/externalSdks/marginfi/types/bankOperationalState.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/bankVaultType.ts b/solauto-sdk/src/externalSdks/marginfi/types/bankVaultType.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/bankVaultType.ts rename to solauto-sdk/src/externalSdks/marginfi/types/bankVaultType.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/groupEventHeader.ts b/solauto-sdk/src/externalSdks/marginfi/types/groupEventHeader.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/groupEventHeader.ts rename to solauto-sdk/src/externalSdks/marginfi/types/groupEventHeader.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/index.ts b/solauto-sdk/src/externalSdks/marginfi/types/index.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/index.ts rename to solauto-sdk/src/externalSdks/marginfi/types/index.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/interestRateConfig.ts b/solauto-sdk/src/externalSdks/marginfi/types/interestRateConfig.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/interestRateConfig.ts rename to solauto-sdk/src/externalSdks/marginfi/types/interestRateConfig.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/interestRateConfigCompact.ts b/solauto-sdk/src/externalSdks/marginfi/types/interestRateConfigCompact.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/interestRateConfigCompact.ts rename to solauto-sdk/src/externalSdks/marginfi/types/interestRateConfigCompact.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/interestRateConfigOpt.ts b/solauto-sdk/src/externalSdks/marginfi/types/interestRateConfigOpt.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/interestRateConfigOpt.ts rename to solauto-sdk/src/externalSdks/marginfi/types/interestRateConfigOpt.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/lendingAccount.ts b/solauto-sdk/src/externalSdks/marginfi/types/lendingAccount.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/lendingAccount.ts rename to solauto-sdk/src/externalSdks/marginfi/types/lendingAccount.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/liquidationBalances.ts b/solauto-sdk/src/externalSdks/marginfi/types/liquidationBalances.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/liquidationBalances.ts rename to solauto-sdk/src/externalSdks/marginfi/types/liquidationBalances.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/oracleConfig.ts b/solauto-sdk/src/externalSdks/marginfi/types/oracleConfig.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/oracleConfig.ts rename to solauto-sdk/src/externalSdks/marginfi/types/oracleConfig.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/oraclePriceType.ts b/solauto-sdk/src/externalSdks/marginfi/types/oraclePriceType.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/oraclePriceType.ts rename to solauto-sdk/src/externalSdks/marginfi/types/oraclePriceType.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/oracleSetup.ts b/solauto-sdk/src/externalSdks/marginfi/types/oracleSetup.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/oracleSetup.ts rename to solauto-sdk/src/externalSdks/marginfi/types/oracleSetup.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/priceBias.ts b/solauto-sdk/src/externalSdks/marginfi/types/priceBias.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/priceBias.ts rename to solauto-sdk/src/externalSdks/marginfi/types/priceBias.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/requirementType.ts b/solauto-sdk/src/externalSdks/marginfi/types/requirementType.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/requirementType.ts rename to solauto-sdk/src/externalSdks/marginfi/types/requirementType.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/riskRequirementType.ts b/solauto-sdk/src/externalSdks/marginfi/types/riskRequirementType.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/riskRequirementType.ts rename to solauto-sdk/src/externalSdks/marginfi/types/riskRequirementType.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/riskTier.ts b/solauto-sdk/src/externalSdks/marginfi/types/riskTier.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/riskTier.ts rename to solauto-sdk/src/externalSdks/marginfi/types/riskTier.ts diff --git a/solauto-sdk/src/marginfi-sdk/types/wrappedI80F48.ts b/solauto-sdk/src/externalSdks/marginfi/types/wrappedI80F48.ts similarity index 100% rename from solauto-sdk/src/marginfi-sdk/types/wrappedI80F48.ts rename to solauto-sdk/src/externalSdks/marginfi/types/wrappedI80F48.ts diff --git a/solauto-sdk/src/pyth-sdk/accounts/index.ts b/solauto-sdk/src/externalSdks/pyth/accounts/index.ts similarity index 100% rename from solauto-sdk/src/pyth-sdk/accounts/index.ts rename to solauto-sdk/src/externalSdks/pyth/accounts/index.ts diff --git a/solauto-sdk/src/pyth-sdk/accounts/priceUpdateV2Account.ts b/solauto-sdk/src/externalSdks/pyth/accounts/priceUpdateV2Account.ts similarity index 100% rename from solauto-sdk/src/pyth-sdk/accounts/priceUpdateV2Account.ts rename to solauto-sdk/src/externalSdks/pyth/accounts/priceUpdateV2Account.ts diff --git a/solauto-sdk/src/pyth-sdk/index.ts b/solauto-sdk/src/externalSdks/pyth/index.ts similarity index 100% rename from solauto-sdk/src/pyth-sdk/index.ts rename to solauto-sdk/src/externalSdks/pyth/index.ts diff --git a/solauto-sdk/src/pyth-sdk/types/index.ts b/solauto-sdk/src/externalSdks/pyth/types/index.ts similarity index 100% rename from solauto-sdk/src/pyth-sdk/types/index.ts rename to solauto-sdk/src/externalSdks/pyth/types/index.ts diff --git a/solauto-sdk/src/pyth-sdk/types/priceMessage.ts b/solauto-sdk/src/externalSdks/pyth/types/priceMessage.ts similarity index 100% rename from solauto-sdk/src/pyth-sdk/types/priceMessage.ts rename to solauto-sdk/src/externalSdks/pyth/types/priceMessage.ts diff --git a/solauto-sdk/src/pyth-sdk/types/priceUpdateV2.ts b/solauto-sdk/src/externalSdks/pyth/types/priceUpdateV2.ts similarity index 100% rename from solauto-sdk/src/pyth-sdk/types/priceUpdateV2.ts rename to solauto-sdk/src/externalSdks/pyth/types/priceUpdateV2.ts diff --git a/solauto-sdk/src/index.ts b/solauto-sdk/src/index.ts index 97be5854..8d3f84bb 100644 --- a/solauto-sdk/src/index.ts +++ b/solauto-sdk/src/index.ts @@ -2,9 +2,9 @@ export * from "./constants"; export * from "./generated/accounts"; export * from "./generated/instructions"; export * from "./generated/types"; -export * from "./marginfi-sdk/accounts"; -export * from "./marginfi-sdk/instructions"; -export * from "./marginfi-sdk/types"; +export * from "./externalSdks/marginfi/accounts"; +export * from "./externalSdks/marginfi/instructions"; +export * from "./externalSdks/marginfi/types"; export * from "./services"; export * from "./solautoPosition"; export * from "./types"; diff --git a/solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts b/solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts index cf6bb9b0..a9dec13f 100644 --- a/solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts +++ b/solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts @@ -19,7 +19,7 @@ import { MarginfiAccount, marginfiAccountInitialize, safeFetchAllBank, -} from "../../marginfi-sdk"; +} from "../../externalSdks/marginfi"; import { FlProviderBase } from "./flProviderBase"; import { bytesToI80F48, diff --git a/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts b/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts index 0a5aca49..99bcd79a 100644 --- a/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts +++ b/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts @@ -47,7 +47,7 @@ import { lendingAccountWithdraw, marginfiAccountInitialize, safeFetchAllMarginfiAccount, -} from "../../marginfi-sdk"; +} from "../../externalSdks/marginfi"; import { SolautoClient, SolautoClientArgs } from "./solautoClient"; function isSigner(account: PublicKey | Signer): account is Signer { diff --git a/solauto-sdk/src/services/transactions/transactionUtils.ts b/solauto-sdk/src/services/transactions/transactionUtils.ts index d821b923..f0a6c484 100644 --- a/solauto-sdk/src/services/transactions/transactionUtils.ts +++ b/solauto-sdk/src/services/transactions/transactionUtils.ts @@ -49,13 +49,13 @@ import { getLendingAccountRepayInstructionDataSerializer, getLendingAccountWithdrawInstructionDataSerializer, getMarginfiErrorFromCode, -} from "../../marginfi-sdk"; +} from "../../externalSdks/marginfi"; import { JupSwapManager } from "../swap"; import { createJupiterProgram, getJupiterErrorFromCode, JUPITER_PROGRAM_ID, -} from "../../jupiter-sdk"; +} from "../../externalSdks/jupiter"; import { TransactionItemInputs, BundleSimulationError, diff --git a/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts b/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts index 81a925dc..e959157b 100644 --- a/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts +++ b/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts @@ -1,5 +1,5 @@ import { PublicKey } from "@solana/web3.js"; -import { Bank, PriceBias, safeFetchAllBank } from "../marginfi-sdk"; +import { Bank, PriceBias, safeFetchAllBank } from "../externalSdks/marginfi"; import { publicKey } from "@metaplex-foundation/umi"; import { calcMarginfiMaxLtvAndLiqThresholdBps, diff --git a/solauto-sdk/src/utils/marginfi/data.ts b/solauto-sdk/src/utils/marginfi/data.ts index 31be84f7..019f6aa9 100644 --- a/solauto-sdk/src/utils/marginfi/data.ts +++ b/solauto-sdk/src/utils/marginfi/data.ts @@ -16,7 +16,7 @@ import { OracleSetup, safeFetchBank, safeFetchMarginfiAccount, -} from "../../marginfi-sdk"; +} from "../../externalSdks/marginfi"; import { ContextUpdates } from "../solautoUtils"; import { fetchTokenPrices, safeGetPrice } from "../priceUtils"; import { currentUnixSeconds, validPubkey } from "../generalUtils"; diff --git a/solauto-sdk/src/utils/marginfi/general.ts b/solauto-sdk/src/utils/marginfi/general.ts index c07a550d..3d3a1a72 100644 --- a/solauto-sdk/src/utils/marginfi/general.ts +++ b/solauto-sdk/src/utils/marginfi/general.ts @@ -20,7 +20,7 @@ import { MarginfiAccount, OracleSetup, safeFetchAllBank, -} from "../../marginfi-sdk"; +} from "../../externalSdks/marginfi"; import { bytesToI80F48, fromBaseUnit, toBps } from "../numberUtils"; import { getTokenAccountData } from "../accountUtils"; import { diff --git a/solauto-sdk/src/utils/priceUtils.ts b/solauto-sdk/src/utils/priceUtils.ts index dffa57b1..268b44f4 100644 --- a/solauto-sdk/src/utils/priceUtils.ts +++ b/solauto-sdk/src/utils/priceUtils.ts @@ -16,7 +16,7 @@ import { } from "./generalUtils"; import { getJupPriceData } from "./jupiterUtils"; import { PriceType } from "../generated"; -import { PriceBias } from "../marginfi-sdk"; +import { PriceBias } from "../externalSdks/marginfi"; interface PriceResult { realtimePrice: number; diff --git a/solauto-sdk/src/utils/pythUtils.ts b/solauto-sdk/src/utils/pythUtils.ts index 95f6d751..68595692 100644 --- a/solauto-sdk/src/utils/pythUtils.ts +++ b/solauto-sdk/src/utils/pythUtils.ts @@ -2,7 +2,7 @@ import { PublicKey } from "@solana/web3.js"; import { publicKey, Umi } from "@metaplex-foundation/umi"; import { PYTH_PUSH_PROGRAM } from "../constants"; import { u16ToArrayBufferLE, zip } from "./generalUtils"; -import { safeFetchAllPriceUpdateV2Account } from "../pyth-sdk"; +import { safeFetchAllPriceUpdateV2Account } from "../externalSdks/pyth"; export async function getMostUpToDatePythOracle( umi: Umi, diff --git a/solauto-sdk/src/utils/solanaUtils.ts b/solauto-sdk/src/utils/solanaUtils.ts index 4abdeb2c..360fde99 100644 --- a/solauto-sdk/src/utils/solanaUtils.ts +++ b/solauto-sdk/src/utils/solanaUtils.ts @@ -38,7 +38,7 @@ import { PriorityFeeSetting, ProgramEnv, TransactionRunType } from "../types"; import { getLendingAccountEndFlashloanInstructionDataSerializer, getLendingAccountStartFlashloanInstructionDataSerializer, -} from "../marginfi-sdk"; +} from "../externalSdks/marginfi"; import { getTokenAccount } from "./accountUtils"; import { arraysAreEqual, From e712b3c9fcbc5600ce721aa65e899169d4023021 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sat, 3 May 2025 22:10:00 -0400 Subject: [PATCH 21/88] pull price unchecked --- programs/solauto/src/clients/marginfi.rs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/programs/solauto/src/clients/marginfi.rs b/programs/solauto/src/clients/marginfi.rs index 18c24126..9bc6dea0 100644 --- a/programs/solauto/src/clients/marginfi.rs +++ b/programs/solauto/src/clients/marginfi.rs @@ -334,14 +334,10 @@ impl<'a> MarginfiClient<'a> { let price_feed = SolanaPriceAccount::account_info_to_feed(price_oracle)?; let price = if price_type == PriceType::Ema { - let price_result = price_feed - .get_price_no_older_than(clock.unix_timestamp, max_price_age) - .unwrap(); + let price_result = price_feed.get_price_unchecked(); derive_value(price_result.price, price_result.expo) } else { - let price_result = price_feed - .get_price_no_older_than(clock.unix_timestamp, max_price_age) - .unwrap(); + let price_result = price_feed.get_price_unchecked(); derive_value(price_result.price, price_result.expo) }; @@ -361,13 +357,7 @@ impl<'a> MarginfiClient<'a> { ) } else { let feed_id = &bank.data.config.oracle_keys[0].to_bytes(); - let price_result = price_feed - .get_price_no_older_than_with_custom_verification_level( - &clock, - max_price_age, - feed_id, - VerificationLevel::Full, - ) + let price_result = price_feed.get_price_unchecked(feed_id) .map_err(|e| { msg!("Pyth push oracle error: {:?}", e); ProgramError::Custom(0) From 897bba47adb47716329a82acda4f79794b5cb74c Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sat, 3 May 2025 22:10:23 -0400 Subject: [PATCH 22/88] remove unused import --- programs/solauto/src/clients/marginfi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/solauto/src/clients/marginfi.rs b/programs/solauto/src/clients/marginfi.rs index 9bc6dea0..804c98a8 100644 --- a/programs/solauto/src/clients/marginfi.rs +++ b/programs/solauto/src/clients/marginfi.rs @@ -6,7 +6,7 @@ use marginfi_sdk::generated::{ types::{Balance, OracleSetup}, }; use pyth_sdk_solana::state::SolanaPriceAccount; -use pyth_solana_receiver_sdk::price_update::{PriceUpdateV2, VerificationLevel}; +use pyth_solana_receiver_sdk::price_update::PriceUpdateV2; use solana_program::{ account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, program_error::ProgramError, pubkey::Pubkey, sysvar::Sysvar, From 604200bd33cd58cbfd63f4ea17a36e17a429dc54 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sat, 3 May 2025 22:11:55 -0400 Subject: [PATCH 23/88] tweak --- programs/solauto/src/clients/marginfi.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/programs/solauto/src/clients/marginfi.rs b/programs/solauto/src/clients/marginfi.rs index 804c98a8..a1c2c836 100644 --- a/programs/solauto/src/clients/marginfi.rs +++ b/programs/solauto/src/clients/marginfi.rs @@ -357,11 +357,7 @@ impl<'a> MarginfiClient<'a> { ) } else { let feed_id = &bank.data.config.oracle_keys[0].to_bytes(); - let price_result = price_feed.get_price_unchecked(feed_id) - .map_err(|e| { - msg!("Pyth push oracle error: {:?}", e); - ProgramError::Custom(0) - })?; + let price_result = price_feed.get_price_unchecked(feed_id).unwrap(); ( derive_value(price_result.price, price_result.exponent), derive_value(price_result.conf as i64, price_result.exponent), From 1fca7bc0c36a5ec8bf2845c7376eed8a0266ec99 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Wed, 7 May 2025 15:29:02 -0400 Subject: [PATCH 24/88] fixes --- solauto-sdk/local/patchLUT.ts | 4 ++++ solauto-sdk/src/constants/solautoConstants.ts | 17 +++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/solauto-sdk/local/patchLUT.ts b/solauto-sdk/local/patchLUT.ts index 9ad01fd5..14c8cc3d 100644 --- a/solauto-sdk/local/patchLUT.ts +++ b/solauto-sdk/local/patchLUT.ts @@ -43,6 +43,7 @@ async function getMissingAccounts() { const users = Array.from( new Set(positions.map((x) => x.authority.toString())) ); + const usersRequiringPatchLut = []; for (const user of users) { const authority = new PublicKey(user); const referralState = referralStatesData.find((x) => @@ -82,9 +83,12 @@ async function getMissingAccounts() { console.log("\nMissing accounts for", referralState.publicKey.toString()); console.log(missingAccounts); allMissingAccounts.push(...missingAccounts); + usersRequiringPatchLut.push(user); } } + console.log("Users requiring patch LUT:"); + console.log(Array.from(new Set(usersRequiringPatchLut))); return allMissingAccounts; } diff --git a/solauto-sdk/src/constants/solautoConstants.ts b/solauto-sdk/src/constants/solautoConstants.ts index e9f6837a..89522450 100644 --- a/solauto-sdk/src/constants/solautoConstants.ts +++ b/solauto-sdk/src/constants/solautoConstants.ts @@ -69,12 +69,13 @@ export const STANDARD_LUT_ACCOUNTS = [ // TODO: remove me export const PATCH_LUT = "CmPZfu3tkeoMutytxhVKT7Hemuwd5jM65VdLNGdBddxQ"; export const AUTHORITIES_REQUIRING_PATCH_LUT = [ - "5UqsR2PGzbP8pGPbXEeXx86Gjz2N2UFBAuFZUSVydAEe", - "F2uk8zsKMex8MztU7saFNq6tNbj4esWnKLJXyfo2egax", - "8Vo5ScTZ1qNTYhMEibq2fekRe5DotmdqpcD2nprmRzJg", - "HLDgPtVv2Yyzzze462P89igFnyLxaCM3f9hVFmCuAX97", - "48CDX2mhhj9iAZthMWJKHFV9wvii9cxzDdtQKuAVwqEu", - "BRgwGasCSz1zA4yqdcvurAGV7ZroAJ9bvDNvdYj7az4X", - "9PCRbk8Gvt2zqewLKbxaSyTxA2JMtdQGhMff8EdELXNq", - "C4cnE5kDRRnqfiLuWShvoGNDstq6yk91N2PWTxQ6Hmk2", + 'BRgwGasCSz1zA4yqdcvurAGV7ZroAJ9bvDNvdYj7az4X', + '5UqsR2PGzbP8pGPbXEeXx86Gjz2N2UFBAuFZUSVydAEe', + 'HLDgPtVv2Yyzzze462P89igFnyLxaCM3f9hVFmCuAX97', + 'C4cnE5kDRRnqfiLuWShvoGNDstq6yk91N2PWTxQ6Hmk2', + '8Vo5ScTZ1qNTYhMEibq2fekRe5DotmdqpcD2nprmRzJg', + 'F2uk8zsKMex8MztU7saFNq6tNbj4esWnKLJXyfo2egax', + '9PCRbk8Gvt2zqewLKbxaSyTxA2JMtdQGhMff8EdELXNq' ]; + + From 9a806de5a9b8b36b0d6618a6f54caae1e597ad20 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Wed, 7 May 2025 15:29:15 -0400 Subject: [PATCH 25/88] space --- solauto-sdk/src/constants/solautoConstants.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/solauto-sdk/src/constants/solautoConstants.ts b/solauto-sdk/src/constants/solautoConstants.ts index 89522450..338fd833 100644 --- a/solauto-sdk/src/constants/solautoConstants.ts +++ b/solauto-sdk/src/constants/solautoConstants.ts @@ -77,5 +77,3 @@ export const AUTHORITIES_REQUIRING_PATCH_LUT = [ 'F2uk8zsKMex8MztU7saFNq6tNbj4esWnKLJXyfo2egax', '9PCRbk8Gvt2zqewLKbxaSyTxA2JMtdQGhMff8EdELXNq' ]; - - From 0660387cea1f1456ed96121c8666b8d5ffbe10ed Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 9 May 2025 01:27:07 -0400 Subject: [PATCH 26/88] optimize stack memory usage in program --- .../solauto/src/instructions/rebalance.rs | 146 +++---- programs/solauto/src/processors/position.rs | 36 +- programs/solauto/src/rebalance/rebalancer.rs | 314 +++++++------- .../solauto/src/rebalance/rebalancer_tests.rs | 410 +++++++++--------- .../solauto/src/rebalance/solauto_fees.rs | 10 - programs/solauto/src/types/solauto.rs | 26 +- programs/solauto/src/types/solauto_manager.rs | 159 +++---- solauto-sdk/package.json | 2 +- .../src/services/rebalance/solautoFees.ts | 9 - .../manager/transactionsManager.ts | 5 +- 10 files changed, 532 insertions(+), 585 deletions(-) diff --git a/programs/solauto/src/instructions/rebalance.rs b/programs/solauto/src/instructions/rebalance.rs index 0ca6fe95..d097edf9 100644 --- a/programs/solauto/src/instructions/rebalance.rs +++ b/programs/solauto/src/instructions/rebalance.rs @@ -2,7 +2,10 @@ use std::ops::Sub; use marginfi_sdk::generated::accounts::Bank; use solana_program::{ - clock::Clock, entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey, + clock::Clock, + entrypoint::ProgramResult, + program_error::ProgramError, + pubkey::Pubkey, sysvar::Sysvar, }; @@ -14,12 +17,13 @@ use crate::{ types::{ errors::SolautoError, instruction::{ - accounts::{Context, MarginfiRebalanceAccounts}, - RebalanceSettings, SolautoStandardAccounts, + accounts::{ Context, MarginfiRebalanceAccounts }, + RebalanceSettings, + SolautoStandardAccounts, }, - lending_protocol::{LendingProtocolClient, LendingProtocolTokenAccounts}, - shared::{DeserializedAccount, RebalanceStep, SolautoRebalanceType, TokenType}, - solauto_manager::{SolautoManager, SolautoManagerAccounts}, + lending_protocol::{ LendingProtocolClient, LendingProtocolTokenAccounts }, + shared::{ DeserializedAccount, RebalanceStep, SolautoRebalanceType, TokenType }, + solauto_manager::{ SolautoManager, SolautoManagerAccounts }, }, utils::ix_utils, }; @@ -30,46 +34,48 @@ pub fn marginfi_rebalance<'a>( ctx: Context<'a, MarginfiRebalanceAccounts<'a>>, mut std_accounts: Box>, rebalance_step: RebalanceStep, - args: RebalanceSettings, + args: RebalanceSettings ) -> ProgramResult { let supply_tas = LendingProtocolTokenAccounts::from( None, Some(ctx.accounts.position_supply_ta), ctx.accounts.authority_supply_ta, - ctx.accounts.vault_supply_ta, + ctx.accounts.vault_supply_ta )?; let debt_tas = LendingProtocolTokenAccounts::from( None, Some(ctx.accounts.position_debt_ta), ctx.accounts.authority_debt_ta, - ctx.accounts.vault_debt_ta, + ctx.accounts.vault_debt_ta )?; - let marginfi_client = Box::new(MarginfiClient::from( - ctx.accounts.signer, - ctx.accounts.marginfi_program, - ctx.accounts.marginfi_group, - ctx.accounts.marginfi_account, - ctx.accounts.supply_bank, - ctx.accounts.supply_price_oracle, - supply_tas.clone(), - ctx.accounts.supply_vault_authority, - ctx.accounts.debt_bank, - ctx.accounts.debt_price_oracle, - debt_tas.clone(), - ctx.accounts.debt_vault_authority, - )?); - let solauto_manager_accounts = - SolautoManagerAccounts::from(supply_tas, debt_tas, ctx.accounts.intermediary_ta, None)?; - - let rebalance_type = std_accounts - .solauto_position - .data - .rebalance - .ixs - .rebalance_type; - if rebalance_step == RebalanceStep::PreSwap - || rebalance_type == SolautoRebalanceType::FLSwapThenRebalance + let marginfi_client = Box::new( + MarginfiClient::from( + ctx.accounts.signer, + ctx.accounts.marginfi_program, + ctx.accounts.marginfi_group, + ctx.accounts.marginfi_account, + ctx.accounts.supply_bank, + ctx.accounts.supply_price_oracle, + supply_tas.clone(), + ctx.accounts.supply_vault_authority, + ctx.accounts.debt_bank, + ctx.accounts.debt_price_oracle, + debt_tas.clone(), + ctx.accounts.debt_vault_authority + )? + ); + let solauto_manager_accounts = SolautoManagerAccounts::from( + supply_tas, + debt_tas, + ctx.accounts.intermediary_ta, + None + )?; + + let rebalance_type = std_accounts.solauto_position.data.rebalance.ixs.rebalance_type; + if + rebalance_step == RebalanceStep::PreSwap || + rebalance_type == SolautoRebalanceType::FLSwapThenRebalance { if needs_refresh(&std_accounts.solauto_position, &args)? { refresh::marginfi_refresh_accounts( @@ -81,57 +87,41 @@ pub fn marginfi_rebalance<'a>( ctx.accounts.debt_bank, ctx.accounts.debt_price_oracle.unwrap(), &mut std_accounts.solauto_position, - args.price_type.unwrap().clone(), + args.price_type.unwrap().clone() )?; } else { let supply_price = MarginfiClient::load_price( &DeserializedAccount::::zerocopy(Some(ctx.accounts.supply_bank))?.unwrap(), ctx.accounts.supply_price_oracle.unwrap(), args.price_type.unwrap().clone(), - TokenType::Supply, + TokenType::Supply )?; let debt_price = MarginfiClient::load_price( &DeserializedAccount::::zerocopy(Some(ctx.accounts.debt_bank))?.unwrap(), ctx.accounts.debt_price_oracle.unwrap(), args.price_type.unwrap().clone(), - TokenType::Debt, + TokenType::Debt )?; update_token_prices(&mut std_accounts, supply_price, debt_price); } } - rebalance( - marginfi_client, - solauto_manager_accounts, - std_accounts, - rebalance_step, - args, - ) + rebalance(marginfi_client, solauto_manager_accounts, std_accounts, rebalance_step, args) } fn update_token_prices<'a>( std_accounts: &mut Box>, supply_price: f64, - debt_price: f64, + debt_price: f64 ) { - std_accounts - .solauto_position - .data - .state - .supply - .update_market_price(supply_price); - std_accounts - .solauto_position - .data - .state - .debt - .update_market_price(debt_price); + std_accounts.solauto_position.data.state.supply.update_market_price(supply_price); + std_accounts.solauto_position.data.state.debt.update_market_price(debt_price); std_accounts.solauto_position.data.refresh_state(); } fn needs_refresh( solauto_position: &DeserializedAccount, - args: &RebalanceSettings, + args: &RebalanceSettings ) -> Result { if solauto_position.data.self_managed.val { return Ok(true); @@ -144,12 +134,6 @@ fn needs_refresh( return Ok(false); } - if args.target_liq_utilization_rate_bps.is_some() - && args.target_liq_utilization_rate_bps.unwrap() == 0 - { - return Ok(true); - } - Ok(false) } @@ -158,44 +142,28 @@ fn rebalance<'a>( solauto_manager_accounts: SolautoManagerAccounts<'a>, std_accounts: Box>, rebalance_step: RebalanceStep, - args: RebalanceSettings, + args: RebalanceSettings ) -> ProgramResult { check!( - args.target_liq_utilization_rate_bps.is_none() - || std_accounts.signer.key == &std_accounts.solauto_position.data.authority, + args.target_liq_utilization_rate_bps.is_none() || + std_accounts.signer.key == &std_accounts.solauto_position.data.authority, SolautoError::NonAuthorityProvidedTargetLTV ); - check!( - std_accounts.authority_referral_state.is_some(), - SolautoError::IncorrectAccounts - ); - check!( - args.flash_loan_fee_bps.unwrap_or(0) <= 150, - SolautoError::IncorrectInstructions - ); + check!(std_accounts.authority_referral_state.is_some(), SolautoError::IncorrectAccounts); + check!(args.flash_loan_fee_bps.unwrap_or(0) <= 150, SolautoError::IncorrectInstructions); let fees_bps = SolautoFeesBps::from( - std_accounts - .authority_referral_state - .as_ref() - .unwrap() - .data - .referred_by_state - != Pubkey::default(), + std_accounts.authority_referral_state.as_ref().unwrap().data.referred_by_state != + Pubkey::default(), args.target_liq_utilization_rate_bps, - std_accounts - .solauto_position - .data - .state - .net_worth - .usd_value(), + std_accounts.solauto_position.data.state.net_worth.usd_value() ); let mut solauto_manager = SolautoManager::from( client, solauto_manager_accounts, std_accounts, - Some(fees_bps), + Some(fees_bps) )?; solauto_manager.rebalance(args, rebalance_step)?; diff --git a/programs/solauto/src/processors/position.rs b/programs/solauto/src/processors/position.rs index ffc9cba8..c9d20fc9 100644 --- a/programs/solauto/src/processors/position.rs +++ b/programs/solauto/src/processors/position.rs @@ -1,29 +1,27 @@ -use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, msg}; +use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, msg }; use crate::{ - check, - instructions::{close_position, update_position}, + instructions::{ close_position, update_position }, state::solauto_position::SolautoPosition, types::{ - errors::SolautoError, instruction::{ - accounts::{CancelDCAAccounts, ClosePositionAccounts, UpdatePositionAccounts}, + accounts::{ ClosePositionAccounts, UpdatePositionAccounts }, UpdatePositionData, }, shared::DeserializedAccount, }, - utils::{ix_utils, solauto_utils, validation_utils}, + utils::validation_utils, }; pub fn process_update_position_instruction<'a>( accounts: &'a [AccountInfo<'a>], - args: UpdatePositionData, + args: UpdatePositionData ) -> ProgramResult { msg!("Instruction: Update position"); let ctx = UpdatePositionAccounts::context(accounts)?; - let solauto_position = - DeserializedAccount::::zerocopy(Some(ctx.accounts.solauto_position))? - .unwrap(); + let solauto_position = DeserializedAccount:: + ::zerocopy(Some(ctx.accounts.solauto_position))? + .unwrap(); validation_utils::validate_instruction(ctx.accounts.signer, &solauto_position, true, true)?; validation_utils::validate_standard_programs( @@ -31,7 +29,7 @@ pub fn process_update_position_instruction<'a>( Some(ctx.accounts.token_program), None, None, - None, + None )?; if args.dca.is_some() { @@ -39,7 +37,7 @@ pub fn process_update_position_instruction<'a>( &solauto_position, ctx.accounts.position_dca_ta, Some(args.dca.as_ref().unwrap().token_type), - None, + None )?; } @@ -49,9 +47,9 @@ pub fn process_update_position_instruction<'a>( pub fn process_close_position_instruction<'a>(accounts: &'a [AccountInfo<'a>]) -> ProgramResult { msg!("Instruction: Close position"); let ctx = ClosePositionAccounts::context(accounts)?; - let solauto_position = - DeserializedAccount::::zerocopy(Some(ctx.accounts.solauto_position))? - .unwrap(); + let solauto_position = DeserializedAccount:: + ::zerocopy(Some(ctx.accounts.solauto_position))? + .unwrap(); validation_utils::validate_instruction(ctx.accounts.signer, &solauto_position, true, true)?; validation_utils::validate_standard_programs( @@ -59,25 +57,25 @@ pub fn process_close_position_instruction<'a>(accounts: &'a [AccountInfo<'a>]) - Some(ctx.accounts.token_program), Some(ctx.accounts.ata_program), None, - None, + None )?; validation_utils::validate_token_accounts( &solauto_position, Some(ctx.accounts.position_supply_ta), - Some(ctx.accounts.position_debt_ta), + Some(ctx.accounts.position_debt_ta) )?; validation_utils::validate_token_accounts( &solauto_position, Some(ctx.accounts.signer_supply_ta), - Some(ctx.accounts.signer_debt_ta), + Some(ctx.accounts.signer_debt_ta) )?; if !cfg!(feature = "local") { validation_utils::validate_no_active_balances( ctx.accounts.lp_user_account, - solauto_position.data.position.lending_platform, + solauto_position.data.position.lending_platform )?; } diff --git a/programs/solauto/src/rebalance/rebalancer.rs b/programs/solauto/src/rebalance/rebalancer.rs index b6180542..da9e9f5e 100644 --- a/programs/solauto/src/rebalance/rebalancer.rs +++ b/programs/solauto/src/rebalance/rebalancer.rs @@ -1,46 +1,53 @@ -use std::{ - cmp::min, - ops::{Add, Mul}, -}; +use std::{ cmp::min, ops::{ Add, Mul } }; -use solana_program::{entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey}; +use solana_program::{ entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey }; use crate::{ check, constants::SOLAUTO_FEES_WALLET, state::solauto_position::{ - PositionTokenState, RebalanceData, SolautoPosition, TokenBalanceChangeType, + PositionTokenState, + RebalanceData, + SolautoPosition, + TokenBalanceChangeType, }, types::{ errors::SolautoError, instruction::RebalanceSettings, shared::{ - BareSplTokenTransferArgs, RebalanceDirection, RebalanceStep, SolautoRebalanceType, - SwapType, TokenBalanceAmount, + RebalanceDirection, + RebalanceStep, + SolautoRebalanceType, + SwapType, + TokenBalanceAmount, + }, + solauto::{ + FromLendingPlatformAction, + SolautoAccount, + SolautoCpiAction, + SolautoSplTokenTransferArgs, }, - solauto::{FromLendingPlatformAction, SolautoCpiAction}, }, utils::{ - math_utils::{calc_fee_amount, from_bps, from_rounded_usd_value, usd_value_to_base_unit}, + math_utils::{ calc_fee_amount, from_bps, from_rounded_usd_value, usd_value_to_base_unit }, validation_utils::correct_token_account, }, }; use super::{ solauto_fees::SolautoFeesBps, - utils::{eligible_for_rebalance, get_rebalance_values}, + utils::{ eligible_for_rebalance, get_rebalance_values }, }; pub struct TokenAccountData { - pub pk: Pubkey, pub balance: u64, } impl TokenAccountData { - pub fn from(pk: Pubkey, balance: u64) -> Self { - Self { pk, balance } + pub fn from(balance: u64) -> Self { + Self { balance } } - pub fn without_balance(pk: Pubkey) -> Self { - Self { pk, balance: 0 } + pub fn new() -> Self { + Self { balance: 0 } } } @@ -53,9 +60,6 @@ pub struct SolautoPositionData<'a> { pub struct RebalancerData<'a> { pub rebalance_args: RebalanceSettings, pub solauto_position: SolautoPositionData<'a>, - pub intermediary_ta: TokenAccountData, - pub authority_supply_ta: Option, - pub authority_debt_ta: Option, pub solauto_fees_bps: SolautoFeesBps, pub solauto_fees_ta: Option, pub referred_by_state: Option, @@ -113,18 +117,15 @@ impl<'a> Rebalancer<'a> { } check!( - self.data - .rebalance_args - .target_liq_utilization_rate_bps - .is_some() - || eligible_for_rebalance(self.position_data()), + self.data.rebalance_args.target_liq_utilization_rate_bps.is_some() || + eligible_for_rebalance(self.position_data()), SolautoError::InvalidRebalanceCondition ); self.data.solauto_position.data.rebalance.values = get_rebalance_values( self.position_data(), &self.data.rebalance_args, - &self.data.solauto_fees_bps, + &self.data.solauto_fees_bps )?; Ok(()) @@ -134,12 +135,12 @@ impl<'a> Rebalancer<'a> { &self, rounded_usd_value: u64, token_usage: PositionTokenState, - max: Option, + max: Option ) -> u64 { let base_unit_amount = usd_value_to_base_unit( from_rounded_usd_value(rounded_usd_value), token_usage.decimals, - token_usage.market_price(), + token_usage.market_price() ); if max.is_some() { @@ -149,50 +150,52 @@ impl<'a> Rebalancer<'a> { } } - fn get_dynamic_balance(&self) -> (u64, &TokenAccountData) { - let ta = if self.is_boost() { - self.position_supply_ta() + fn get_dynamic_balance(&self) -> (u64, SolautoAccount) { + let (ta, account) = if self.is_boost() { + (self.position_supply_ta(), SolautoAccount::SolautoPositionSupplyTa) } else { - self.position_debt_ta() + (self.position_debt_ta(), SolautoAccount::SolautoPositionDebtTa) }; let balance = ta.balance; // Subtract current balances that are attributed to DCA / limit order in - (balance, ta) + (balance, account) } fn transfer_to_authority_if_needed(&mut self, base_unit_amount: u64) { if self.position_data().self_managed.val { let (solauto_position_ta, authority_ta) = if self.is_boost() { - (self.position_supply_ta().pk, &self.data.authority_supply_ta) + (SolautoAccount::SolautoPositionSupplyTa, SolautoAccount::AuthoritySupplyTa) } else { - (self.position_debt_ta().pk, &self.data.authority_debt_ta) + (SolautoAccount::SolautoPositionDebtTa, SolautoAccount::AuthorityDebtTa) }; - self.actions.push(SolautoCpiAction::SplTokenTransfer( - BareSplTokenTransferArgs { - from_wallet: self.data.solauto_position.data.pubkey(), + self.actions.push( + SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { + from_wallet: SolautoAccount::SolautoPosition, from_wallet_ta: solauto_position_ta, - to_wallet_ta: authority_ta.as_ref().unwrap().pk, + to_wallet_ta: authority_ta, amount: base_unit_amount, - }, - )); + }) + ); } } - fn pull_liquidity_from_lp(&mut self, base_unit_amount: u64, destination_ta: Pubkey) { + fn pull_liquidity_from_lp(&mut self, base_unit_amount: u64, destination_ta: SolautoAccount) { if self.is_boost() { - self.actions - .push(SolautoCpiAction::Borrow(FromLendingPlatformAction { + self.actions.push( + SolautoCpiAction::Borrow(FromLendingPlatformAction { amount: base_unit_amount, to_wallet_ta: destination_ta, - })); + }) + ); } else { - self.actions - .push(SolautoCpiAction::Withdraw(FromLendingPlatformAction { + self.actions.push( + SolautoCpiAction::Withdraw(FromLendingPlatformAction { amount: TokenBalanceAmount::Some(base_unit_amount), to_wallet_ta: destination_ta, - })); + }) + ); } } @@ -200,40 +203,24 @@ impl<'a> Rebalancer<'a> { self.transfer_to_authority_if_needed(base_unit_amount); if self.is_boost() { - self.actions - .push(SolautoCpiAction::Deposit(base_unit_amount)); + self.actions.push(SolautoCpiAction::Deposit(base_unit_amount)); } else { - let token_balance_amount = if self - .data - .rebalance_args - .target_liq_utilization_rate_bps - .is_some() - && self - .data - .rebalance_args - .target_liq_utilization_rate_bps - .unwrap() - == 0 + let token_balance_amount = if + self.data.rebalance_args.target_liq_utilization_rate_bps.is_some() && + self.data.rebalance_args.target_liq_utilization_rate_bps.unwrap() == 0 { TokenBalanceAmount::All } else { - TokenBalanceAmount::Some(min( - self.position_data().state.debt.amount_used.base_unit, - base_unit_amount, - )) + TokenBalanceAmount::Some( + min(self.position_data().state.debt.amount_used.base_unit, base_unit_amount) + ) }; - self.actions - .push(SolautoCpiAction::Repay(token_balance_amount)); + self.actions.push(SolautoCpiAction::Repay(token_balance_amount)); } } fn get_additional_amount_before_swap(&mut self) -> u64 { - if !self - .rebalance_data() - .values - .token_balance_change - .requires_one() - { + if !self.rebalance_data().values.token_balance_change.requires_one() { return 0; } @@ -242,41 +229,45 @@ impl<'a> Rebalancer<'a> { let action = match token_balance_change.change_type { TokenBalanceChangeType::PreSwapDeposit => { - Some(SolautoCpiAction::Deposit(self.calc_additional_amount( - token_balance_change.amount_usd, - self.position_data().state.supply, - Some(self.data.solauto_position.supply_ta.balance), - ))) + Some( + SolautoCpiAction::Deposit( + self.calc_additional_amount( + token_balance_change.amount_usd, + self.position_data().state.supply, + Some(self.data.solauto_position.supply_ta.balance) + ) + ) + ) } TokenBalanceChangeType::PostSwapDeposit => { amount = self.calc_additional_amount( token_balance_change.amount_usd, self.position_data().state.debt, - Some(self.data.solauto_position.debt_ta.balance), + Some(self.data.solauto_position.debt_ta.balance) ); - Some(SolautoCpiAction::SplTokenTransfer( - BareSplTokenTransferArgs { + Some( + SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { amount, - from_wallet: self.data.solauto_position.data.pubkey(), - from_wallet_ta: self.position_debt_ta().pk, - to_wallet_ta: self.data.intermediary_ta.pk, - }, - )) + from_wallet: SolautoAccount::SolautoPosition, + from_wallet_ta: SolautoAccount::SolautoPositionDebtTa, + to_wallet_ta: SolautoAccount::IntermediaryTa, + }) + ) } TokenBalanceChangeType::PostRebalanceWithdrawDebtToken => { amount = self.calc_additional_amount( token_balance_change.amount_usd, self.position_data().state.supply, - Some(self.position_supply_ta().balance), + Some(self.position_supply_ta().balance) ); - Some(SolautoCpiAction::SplTokenTransfer( - BareSplTokenTransferArgs { + Some( + SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { amount, - from_wallet: self.data.solauto_position.data.pubkey(), - from_wallet_ta: self.position_supply_ta().pk, - to_wallet_ta: self.data.intermediary_ta.pk, - }, - )) + from_wallet: SolautoAccount::SolautoPosition, + from_wallet_ta: SolautoAccount::SolautoPositionSupplyTa, + to_wallet_ta: SolautoAccount::IntermediaryTa, + }) + ) } _ => None, }; @@ -289,12 +280,7 @@ impl<'a> Rebalancer<'a> { } fn get_additional_amount_after_swap(&mut self) -> u64 { - if !self - .rebalance_data() - .values - .token_balance_change - .requires_one() - { + if !self.rebalance_data().values.token_balance_change.requires_one() { return 0; } @@ -306,31 +292,31 @@ impl<'a> Rebalancer<'a> { amount = self.calc_additional_amount( token_balance_change.amount_usd, self.position_data().state.supply, - None, + None ); - Some(SolautoCpiAction::SplTokenTransfer( - BareSplTokenTransferArgs { + Some( + SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { amount, - from_wallet: self.data.solauto_position.data.pubkey(), - from_wallet_ta: self.position_supply_ta().pk, - to_wallet_ta: self.data.authority_supply_ta.as_ref().unwrap().pk, // TODO: what if this is native mint - }, - )) + from_wallet: SolautoAccount::SolautoPosition, + from_wallet_ta: SolautoAccount::SolautoPositionSupplyTa, + to_wallet_ta: SolautoAccount::AuthoritySupplyTa, // TODO: what if this is native mint + }) + ) } TokenBalanceChangeType::PostRebalanceWithdrawDebtToken => { amount = self.calc_additional_amount( token_balance_change.amount_usd, self.position_data().state.debt, - None, + None ); - Some(SolautoCpiAction::SplTokenTransfer( - BareSplTokenTransferArgs { + Some( + SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { amount, - from_wallet: self.data.solauto_position.data.pubkey(), - from_wallet_ta: self.position_debt_ta().pk, - to_wallet_ta: self.data.authority_debt_ta.as_ref().unwrap().pk, // TODO: what if this is native mint - }, - )) + from_wallet: SolautoAccount::SolautoPosition, + from_wallet_ta: SolautoAccount::SolautoPositionDebtTa, + to_wallet_ta: SolautoAccount::AuthorityDebtTa, // TODO: what if this is native mint + }) + ) } _ => None, }; @@ -346,25 +332,18 @@ impl<'a> Rebalancer<'a> { &mut self, available_balance: u64, fee_pct_bps: u16, - token_mint: Pubkey, - position_ta: Pubkey, - destination_wallet: Pubkey, - destination_ta: Pubkey, + position_ta: SolautoAccount, + destination_ta: SolautoAccount ) -> Result { - check!( - correct_token_account(&destination_ta, &destination_wallet, &token_mint), - SolautoError::IncorrectAccounts - ); - let fee_amount = calc_fee_amount(available_balance, fee_pct_bps); - self.actions.push(SolautoCpiAction::SplTokenTransfer( - BareSplTokenTransferArgs { - from_wallet: self.data.solauto_position.data.pubkey(), + self.actions.push( + SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { + from_wallet: SolautoAccount::SolautoPosition, from_wallet_ta: position_ta, to_wallet_ta: destination_ta, amount: fee_amount, - }, - )); + }) + ); Ok(fee_amount) } @@ -372,40 +351,47 @@ impl<'a> Rebalancer<'a> { fn payout_fees(&mut self, available_balance: u64) -> Result { let rebalance_direction = &self.rebalance_data().values.rebalance_direction; let (token_mint, position_ta) = if self.is_boost() { - ( - self.position_data().state.supply.mint, - self.position_supply_ta().pk, - ) + (self.position_data().state.supply.mint, SolautoAccount::SolautoPositionSupplyTa) } else { - ( - self.position_data().state.debt.mint, - self.position_debt_ta().pk, - ) + (self.position_data().state.debt.mint, SolautoAccount::SolautoPositionDebtTa) }; let fee_payout = self.data.solauto_fees_bps.fetch_fees(rebalance_direction); if fee_payout.total == 0 { return Ok(available_balance); } + check!( + correct_token_account( + self.data.solauto_fees_ta.as_ref().unwrap(), + &SOLAUTO_FEES_WALLET, + &token_mint + ), + SolautoError::IncorrectAccounts + ); let solauto_fees = self.payout_fee( available_balance, fee_payout.solauto, - token_mint, position_ta, - SOLAUTO_FEES_WALLET, - self.data.solauto_fees_ta.unwrap(), + SolautoAccount::SolautoFeesTa )?; - let referrer_fees = if self.data.referred_by_state.is_some() - && self.data.referred_by_state.unwrap() != Pubkey::default() + let referrer_fees = if + self.data.referred_by_state.is_some() && + self.data.referred_by_state.unwrap() != Pubkey::default() { + check!( + correct_token_account( + self.data.referred_by_ta.as_ref().unwrap(), + self.data.referred_by_state.as_ref().unwrap(), + &token_mint + ), + SolautoError::IncorrectAccounts + ); self.payout_fee( available_balance, fee_payout.referrer, - token_mint, position_ta, - self.data.referred_by_state.unwrap(), - self.data.referred_by_ta.unwrap(), + SolautoAccount::ReferredByTa )? } else { 0 @@ -415,12 +401,14 @@ impl<'a> Rebalancer<'a> { } fn repay_flash_loan_if_necessary(&mut self) -> ProgramResult { - if matches!( - self.rebalance_data().ixs.rebalance_type, - SolautoRebalanceType::DoubleRebalanceWithFL - | SolautoRebalanceType::FLRebalanceThenSwap - | SolautoRebalanceType::FLSwapThenRebalance - ) { + if + matches!( + self.rebalance_data().ixs.rebalance_type, + SolautoRebalanceType::DoubleRebalanceWithFL | + SolautoRebalanceType::FLRebalanceThenSwap | + SolautoRebalanceType::FLSwapThenRebalance + ) + { let flash_loan_amount = self.rebalance_data().ixs.flash_loan_amount; let fl_repay_amount = if self.rebalance_data().ixs.swap_type == SwapType::ExactOut { @@ -429,13 +417,11 @@ impl<'a> Rebalancer<'a> { check!(flash_loan_amount != 0, SolautoError::IncorrectInstructions); let flash_loan_fee_bps = self.data.rebalance_args.flash_loan_fee_bps.unwrap_or(0); flash_loan_amount.add( - (flash_loan_amount as f64) - .mul(from_bps(flash_loan_fee_bps)) - .ceil() as u64, + (flash_loan_amount as f64).mul(from_bps(flash_loan_fee_bps)).ceil() as u64 ) }; - self.pull_liquidity_from_lp(fl_repay_amount, self.data.intermediary_ta.pk); + self.pull_liquidity_from_lp(fl_repay_amount, SolautoAccount::IntermediaryTa); } Ok(()) @@ -460,7 +446,7 @@ impl<'a> Rebalancer<'a> { Ok(RebalanceResult { finished: true }) } else { let amount_to_pull_from_lp = amount_to_swap - additional_amount_to_swap; - self.pull_liquidity_from_lp(amount_to_pull_from_lp, self.data.intermediary_ta.pk); + self.pull_liquidity_from_lp(amount_to_pull_from_lp, SolautoAccount::IntermediaryTa); Ok(RebalanceResult { finished: false }) } } @@ -473,14 +459,14 @@ impl<'a> Rebalancer<'a> { let balance_leftover = dynamic_balance - additional_amount_after_swap; if self.rebalance_data().ixs.swap_type == SwapType::ExactOut { - self.actions.push(SolautoCpiAction::SplTokenTransfer( - BareSplTokenTransferArgs { - from_wallet: self.data.solauto_position.data.pubkey(), - from_wallet_ta: balance_ta.pk, - to_wallet_ta: self.data.intermediary_ta.pk, + self.actions.push( + SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { + from_wallet: SolautoAccount::SolautoPosition, + from_wallet_ta: balance_ta, + to_wallet_ta: SolautoAccount::IntermediaryTa, amount: balance_leftover, - }, - )); + }) + ); } else { self.finish_rebalance(balance_leftover)?; } @@ -490,7 +476,7 @@ impl<'a> Rebalancer<'a> { pub fn rebalance( &mut self, - rebalance_step: RebalanceStep, + rebalance_step: RebalanceStep ) -> Result { match rebalance_step { RebalanceStep::PreSwap => self.pre_swap_rebalance(), diff --git a/programs/solauto/src/rebalance/rebalancer_tests.rs b/programs/solauto/src/rebalance/rebalancer_tests.rs index 9c836585..e3446fbb 100644 --- a/programs/solauto/src/rebalance/rebalancer_tests.rs +++ b/programs/solauto/src/rebalance/rebalancer_tests.rs @@ -1,4 +1,4 @@ -use std::ops::{Div, Mul}; +use std::ops::{ Div, Mul }; use solana_program::pubkey::Pubkey; use spl_associated_token_account::get_associated_token_address; @@ -6,21 +6,33 @@ use spl_associated_token_account::get_associated_token_address; use crate::{ constants::SOLAUTO_FEES_WALLET, state::solauto_position::{ - PositionData, PositionState, RebalanceData, SolautoPosition, SolautoSettingsParameters, + PositionData, + PositionState, + RebalanceData, + SolautoPosition, + SolautoSettingsParameters, SolautoSettingsParametersInp, }, types::{ instruction::RebalanceSettings, shared::{ - PodBool, PositionType, RebalanceDirection, RefreshedTokenState, SwapType, + PodBool, + PositionType, + RebalanceDirection, + RefreshedTokenState, + SwapType, TokenBalanceAmount, }, - solauto::{PositionValues, SolautoCpiAction}, + solauto::{ PositionValues, SolautoAccount, SolautoCpiAction }, }, utils::{ math_utils::{ - from_base_unit, from_bps, from_rounded_usd_value, get_liq_utilization_rate_bps, - round_to_decimals, to_base_unit, + from_base_unit, + from_bps, + from_rounded_usd_value, + get_liq_utilization_rate_bps, + round_to_decimals, + to_base_unit, }, solauto_utils::update_token_state, validation_utils, @@ -28,7 +40,7 @@ use crate::{ }; use super::{ - rebalancer::{Rebalancer, RebalancerData, SolautoPositionData, TokenAccountData}, + rebalancer::{ Rebalancer, RebalancerData, SolautoPositionData, TokenAccountData }, solauto_fees::SolautoFeesBps, }; @@ -55,7 +67,7 @@ fn create_position<'a>(pos: &FakePosition<'a>) -> Box { state.liq_utilization_rate_bps = get_liq_utilization_rate_bps( pos.values.supply_usd, pos.values.debt_usd, - from_bps(state.liq_threshold_bps), + from_bps(state.liq_threshold_bps) ); let supply_mint = Pubkey::new_unique(); @@ -72,7 +84,7 @@ fn create_position<'a>(pos: &FakePosition<'a>) -> Box { decimals: TEST_TOKEN_DECIMALS, market_price: SUPPLY_PRICE, borrow_fee_bps: None, - }), + }) ); update_token_state( &mut state.debt, @@ -83,7 +95,7 @@ fn create_position<'a>(pos: &FakePosition<'a>) -> Box { decimals: TEST_TOKEN_DECIMALS, market_price: DEBT_PRICE, borrow_fee_bps: Some(BORROW_FEE_BPS), - }), + }) ); let mut position_data = PositionData::default(); @@ -94,7 +106,7 @@ fn create_position<'a>(pos: &FakePosition<'a>) -> Box { Pubkey::new_unique(), PositionType::Leverage, position_data, - state, + state ); Box::new(position) @@ -110,21 +122,29 @@ pub struct FakeRebalance<'a> { fn create_rebalancer<'a>( data: FakeRebalance<'a>, rebalance_args: RebalanceSettings, - flash_loan_amount: Option, + flash_loan_amount: Option ) -> Rebalancer<'a> { data.pos.rebalance.ixs.rebalance_type = rebalance_args.rebalance_type; data.pos.rebalance.ixs.flash_loan_amount = flash_loan_amount.unwrap_or(0); data.pos.rebalance.ixs.active = PodBool::new(true); data.pos.rebalance.ixs.swap_type = rebalance_args.swap_type.unwrap_or(SwapType::default()); - let position_supply_ta = - get_associated_token_address(&data.pos.pubkey(), &data.pos.state.supply.mint); - let position_debt_ta = - get_associated_token_address(&data.pos.pubkey(), &data.pos.state.debt.mint); - let position_authority_supply_ta = - get_associated_token_address(&data.pos.authority, &data.pos.state.supply.mint); - let position_authority_debt_ta = - get_associated_token_address(&data.pos.authority, &data.pos.state.debt.mint); + let position_supply_ta = get_associated_token_address( + &data.pos.pubkey(), + &data.pos.state.supply.mint + ); + let position_debt_ta = get_associated_token_address( + &data.pos.pubkey(), + &data.pos.state.debt.mint + ); + let position_authority_supply_ta = get_associated_token_address( + &data.pos.authority, + &data.pos.state.supply.mint + ); + let position_authority_debt_ta = get_associated_token_address( + &data.pos.authority, + &data.pos.state.debt.mint + ); let fees_mint = if data.rebalance_direction == RebalanceDirection::Boost { data.pos.state.supply.mint @@ -138,32 +158,24 @@ fn create_rebalancer<'a>( rebalance_args, solauto_position: SolautoPositionData { data: data.pos, - supply_ta: TokenAccountData::from( - position_supply_ta, - data.position_supply_ta_balance.unwrap_or(0), - ), - debt_ta: TokenAccountData::from( - position_debt_ta, - data.position_debt_ta_balance.unwrap_or(0), - ), + supply_ta: TokenAccountData::from(data.position_supply_ta_balance.unwrap_or(0)), + debt_ta: TokenAccountData::from(data.position_debt_ta_balance.unwrap_or(0)), }, - authority_supply_ta: Some(TokenAccountData::without_balance( - position_authority_supply_ta, - )), - authority_debt_ta: Some(TokenAccountData::without_balance( - position_authority_debt_ta, - )), solauto_fees_bps: solauto_fees, referred_by_state: None, referred_by_ta: None, - intermediary_ta: TokenAccountData::without_balance(Pubkey::new_unique()), solauto_fees_ta: Some(solauto_fees_ta), }); rebalancer } -fn credit_token_account<'a>(rebalancer: &mut Rebalancer<'a>, ta_pk: Pubkey, base_unit_amount: i64) { +fn credit_token_account<'a>( + rebalancer: &mut Rebalancer<'a>, + ta_creditor: &mut TaCreditor, + ta_pk: SolautoAccount, + base_unit_amount: i64 +) { let credit_ta = |ta: &mut TokenAccountData| { println!("Crediting token account with {}", base_unit_amount); if base_unit_amount > 0 { @@ -173,106 +185,94 @@ fn credit_token_account<'a>(rebalancer: &mut Rebalancer<'a>, ta_pk: Pubkey, base } }; - if ta_pk == rebalancer.data.solauto_position.supply_ta.pk { + if ta_pk == SolautoAccount::SolautoPositionSupplyTa { credit_ta(&mut rebalancer.data.solauto_position.supply_ta); - } else if ta_pk == rebalancer.data.solauto_position.debt_ta.pk { + } else if ta_pk == SolautoAccount::SolautoPositionDebtTa { credit_ta(&mut rebalancer.data.solauto_position.debt_ta); - } else if ta_pk == rebalancer.data.intermediary_ta.pk { - credit_ta(&mut rebalancer.data.intermediary_ta); - } else if ta_pk == rebalancer.data.authority_supply_ta.as_ref().unwrap().pk { - credit_ta(&mut rebalancer.data.authority_supply_ta.as_mut().unwrap()); - } else if ta_pk == rebalancer.data.authority_debt_ta.as_ref().unwrap().pk { - credit_ta(&mut rebalancer.data.authority_debt_ta.as_mut().unwrap()); + } else if ta_pk == SolautoAccount::IntermediaryTa { + credit_ta(&mut ta_creditor.intermediary_ta); + } else if ta_pk == SolautoAccount::AuthoritySupplyTa { + credit_ta(&mut ta_creditor.authority_supply_ta); + } else if ta_pk == SolautoAccount::AuthorityDebtTa { + credit_ta(&mut ta_creditor.authority_debt_ta); } else { println!("Couldn't find token account"); } } -fn apply_actions<'a>(rebalancer: &mut Rebalancer<'a>) { +fn apply_actions<'a>(rebalancer: &mut Rebalancer<'a>, ta_creditor: &mut TaCreditor) { println!("Actions: {}", rebalancer.actions().len()); for action in rebalancer.actions().clone() { match action { SolautoCpiAction::Deposit(amount) => { println!("Deposit {}", amount); - rebalancer - .data - .solauto_position - .data - .state - .supply - .update_usage(amount as i64); + rebalancer.data.solauto_position.data.state.supply.update_usage(amount as i64); credit_token_account( rebalancer, - rebalancer.data.solauto_position.supply_ta.pk, - (amount as i64) * -1, + ta_creditor, + SolautoAccount::SolautoPositionSupplyTa, + (amount as i64) * -1 ); } SolautoCpiAction::Withdraw(data) => { let base_unit_amount = if let TokenBalanceAmount::Some(amount) = data.amount { amount } else { - rebalancer - .data - .solauto_position - .data - .state - .supply - .amount_used - .base_unit + rebalancer.data.solauto_position.data.state.supply.amount_used.base_unit }; println!("Withdraw {}", base_unit_amount); - rebalancer - .data - .solauto_position - .data - .state - .supply - .update_usage((base_unit_amount as i64) * -1); - credit_token_account(rebalancer, data.to_wallet_ta, base_unit_amount as i64); + rebalancer.data.solauto_position.data.state.supply.update_usage( + (base_unit_amount as i64) * -1 + ); + credit_token_account( + rebalancer, + ta_creditor, + data.to_wallet_ta, + base_unit_amount as i64 + ); } SolautoCpiAction::Borrow(data) => { println!("Borrow {}", data.amount); - rebalancer - .data - .solauto_position - .data - .state - .debt - .update_usage(data.amount as i64); - credit_token_account(rebalancer, data.to_wallet_ta, data.amount as i64); + rebalancer.data.solauto_position.data.state.debt.update_usage(data.amount as i64); + credit_token_account( + rebalancer, + ta_creditor, + data.to_wallet_ta, + data.amount as i64 + ); } SolautoCpiAction::Repay(data) => { let base_unit_amount = if let TokenBalanceAmount::Some(amount) = data { amount } else { - rebalancer - .data - .solauto_position - .data - .state - .debt - .amount_used - .base_unit + rebalancer.data.solauto_position.data.state.debt.amount_used.base_unit }; println!("Repay {}", base_unit_amount); - rebalancer - .data - .solauto_position - .data - .state - .debt - .update_usage((base_unit_amount as i64) * -1); + rebalancer.data.solauto_position.data.state.debt.update_usage( + (base_unit_amount as i64) * -1 + ); credit_token_account( rebalancer, - rebalancer.data.solauto_position.debt_ta.pk, - (base_unit_amount as i64) * -1, + ta_creditor, + SolautoAccount::SolautoPositionDebtTa, + (base_unit_amount as i64) * -1 ); } SolautoCpiAction::SplTokenTransfer(args) => { println!("Transfer from {}", args.amount); - credit_token_account(rebalancer, args.from_wallet_ta, (args.amount as i64) * -1); - credit_token_account(rebalancer, args.to_wallet_ta, args.amount as i64); + credit_token_account( + rebalancer, + ta_creditor, + args.from_wallet_ta, + (args.amount as i64) * -1 + ); + credit_token_account( + rebalancer, + ta_creditor, + args.to_wallet_ta, + args.amount as i64 + ); } } } @@ -282,8 +282,9 @@ fn apply_actions<'a>(rebalancer: &mut Rebalancer<'a>) { fn perform_swap<'a>( rebalancer: &mut Rebalancer<'a>, + ta_creditor: &mut TaCreditor, rebalance_direction: &RebalanceDirection, - to_solauto_position_ta: bool, + to_solauto_position_ta: bool ) -> u64 { let (input_price, output_price) = if rebalance_direction == &RebalanceDirection::Boost { (DEBT_PRICE, SUPPLY_PRICE) @@ -292,30 +293,33 @@ fn perform_swap<'a>( }; let swap_usd_value = from_base_unit::( - rebalancer.data.intermediary_ta.balance, - TEST_TOKEN_DECIMALS, - ) - .mul(input_price); + ta_creditor.intermediary_ta.balance, + TEST_TOKEN_DECIMALS + ).mul(input_price); println!("Swapping ${}", swap_usd_value); - rebalancer.data.intermediary_ta.balance = 0; + ta_creditor.intermediary_ta.balance = 0; - let output_amount = - to_base_unit::(swap_usd_value.div(output_price), TEST_TOKEN_DECIMALS); + let output_amount = to_base_unit::( + swap_usd_value.div(output_price), + TEST_TOKEN_DECIMALS + ); if to_solauto_position_ta { if rebalance_direction == &RebalanceDirection::Boost { credit_token_account( rebalancer, - rebalancer.data.solauto_position.supply_ta.pk, - output_amount as i64, + ta_creditor, + SolautoAccount::SolautoPositionSupplyTa, + output_amount as i64 ); } else { credit_token_account( rebalancer, - rebalancer.data.solauto_position.debt_ta.pk, - output_amount as i64, + ta_creditor, + SolautoAccount::SolautoPositionDebtTa, + output_amount as i64 ); } } @@ -327,25 +331,12 @@ fn validate_rebalance<'a>(rebalancer: &mut Rebalancer<'a>) { assert_eq!( round_to_decimals( from_rounded_usd_value( - rebalancer - .data - .solauto_position - .data - .rebalance - .values - .target_debt_usd + rebalancer.data.solauto_position.data.rebalance.values.target_debt_usd ), 4 ), round_to_decimals( - rebalancer - .data - .solauto_position - .data - .state - .debt - .amount_used - .usd_value(), + rebalancer.data.solauto_position.data.state.debt.amount_used.usd_value(), 4 ), "Incorrect debt usd. Expected (left) vs. actual (right)" @@ -353,25 +344,12 @@ fn validate_rebalance<'a>(rebalancer: &mut Rebalancer<'a>) { assert_eq!( round_to_decimals( from_rounded_usd_value( - rebalancer - .data - .solauto_position - .data - .rebalance - .values - .target_supply_usd + rebalancer.data.solauto_position.data.rebalance.values.target_supply_usd ), 4 ), round_to_decimals( - rebalancer - .data - .solauto_position - .data - .state - .supply - .amount_used - .usd_value(), + rebalancer.data.solauto_position.data.state.supply.amount_used.usd_value(), 4 ), "Incorrect supply usd. Expected (left) vs. actual (right)" @@ -381,15 +359,30 @@ fn validate_rebalance<'a>(rebalancer: &mut Rebalancer<'a>) { rebalancer.data.solauto_position.data.rebalance = RebalanceData::default(); } +pub struct TaCreditor { + pub intermediary_ta: TokenAccountData, + pub authority_supply_ta: TokenAccountData, + pub authority_debt_ta: TokenAccountData, +} +impl TaCreditor { + pub fn new() -> Self { + Self { + intermediary_ta: TokenAccountData { balance: 0 }, + authority_supply_ta: TokenAccountData { balance: 0 }, + authority_debt_ta: TokenAccountData { balance: 0 }, + } + } +} + mod tests { - use std::ops::{Add, Div}; + use std::ops::{ Add, Div }; use crate::{ types::{ - shared::{RebalanceStep, SolautoRebalanceType, SwapType}, + shared::{ RebalanceStep, SolautoRebalanceType, SwapType }, solauto::RebalanceFeesBps, }, - utils::math_utils::{get_debt_adjustment, get_max_boost_to_bps, get_max_repay_to_bps}, + utils::math_utils::{ get_debt_adjustment, get_max_boost_to_bps, get_max_repay_to_bps }, }; use super::*; @@ -415,7 +408,7 @@ mod tests { settings, max_ltv_bps: Some(MAX_LTV_BPS), liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), - }), + }) ); let debt_adjustment = get_debt_adjustment( LIQ_THRESHOLD_BPS, @@ -425,15 +418,17 @@ mod tests { solauto: SOLAUTO_FEE_BPS, lp_borrow: BORROW_FEE_BPS, flash_loan: 0, - }), + }) ); let rebalance_args = RebalanceSettings { rebalance_type: SolautoRebalanceType::Regular, target_liq_utilization_rate_bps: None, - swap_in_amount_base_unit: Some(to_base_unit( - debt_adjustment.debt_adjustment_usd.div(DEBT_PRICE), - TEST_TOKEN_DECIMALS, - )), + swap_in_amount_base_unit: Some( + to_base_unit( + debt_adjustment.debt_adjustment_usd.div(DEBT_PRICE), + TEST_TOKEN_DECIMALS + ) + ), flash_loan_fee_bps: None, swap_type: Some(SwapType::ExactIn), price_type: None, @@ -446,18 +441,19 @@ mod tests { rebalance_direction: rebalance_direction.clone(), }, rebalance_args, - None, + None ); + let ta_creditor = &mut TaCreditor::new(); let res = rebalancer.rebalance(RebalanceStep::PreSwap); assert!(res.is_ok()); - apply_actions(rebalancer); + apply_actions(rebalancer, ta_creditor); - perform_swap(rebalancer, &rebalance_direction, true); + perform_swap(rebalancer, ta_creditor, &rebalance_direction, true); let res = rebalancer.rebalance(RebalanceStep::PostSwap); assert!(res.is_ok()); - apply_actions(rebalancer); + apply_actions(rebalancer, ta_creditor); validate_rebalance(rebalancer); } @@ -483,7 +479,7 @@ mod tests { settings, max_ltv_bps: Some(MAX_LTV_BPS), liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), - }), + }) ); let debt_adjustment = get_debt_adjustment( LIQ_THRESHOLD_BPS, @@ -493,15 +489,17 @@ mod tests { solauto: SOLAUTO_FEE_BPS, lp_borrow: BORROW_FEE_BPS, flash_loan: 0, - }), + }) ); let rebalance_args = RebalanceSettings { rebalance_type: SolautoRebalanceType::Regular, target_liq_utilization_rate_bps: None, - swap_in_amount_base_unit: Some(to_base_unit( - debt_adjustment.debt_adjustment_usd.abs().div(SUPPLY_PRICE), - TEST_TOKEN_DECIMALS, - )), + swap_in_amount_base_unit: Some( + to_base_unit( + debt_adjustment.debt_adjustment_usd.abs().div(SUPPLY_PRICE), + TEST_TOKEN_DECIMALS + ) + ), flash_loan_fee_bps: None, swap_type: Some(SwapType::ExactIn), price_type: None, @@ -514,18 +512,19 @@ mod tests { rebalance_direction: rebalance_direction.clone(), }, rebalance_args, - None, + None ); + let ta_creditor = &mut TaCreditor::new(); let res = rebalancer.rebalance(RebalanceStep::PreSwap); assert!(res.is_ok()); - apply_actions(rebalancer); + apply_actions(rebalancer, ta_creditor); - perform_swap(rebalancer, &rebalance_direction, true); + perform_swap(rebalancer, ta_creditor, &rebalance_direction, true); let res = rebalancer.rebalance(RebalanceStep::PostSwap); assert!(res.is_ok()); - apply_actions(rebalancer); + apply_actions(rebalancer, ta_creditor); validate_rebalance(rebalancer); } @@ -558,7 +557,7 @@ mod tests { settings, max_ltv_bps: Some(MAX_LTV_BPS), liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), - }), + }) ); let debt_adjustment = get_debt_adjustment( @@ -569,11 +568,11 @@ mod tests { solauto: SOLAUTO_FEE_BPS, lp_borrow: BORROW_FEE_BPS, flash_loan: FLASH_LOAN_FEE_BPS, - }), + }) ); let flash_borrow = to_base_unit( debt_adjustment.debt_adjustment_usd.abs().div(DEBT_PRICE), - TEST_TOKEN_DECIMALS, + TEST_TOKEN_DECIMALS ); let rebalance_args = RebalanceSettings { @@ -592,20 +591,22 @@ mod tests { rebalance_direction: rebalance_direction.clone(), }, rebalance_args, - Some(flash_borrow), + Some(flash_borrow) ); + let ta_creditor = &mut TaCreditor::new(); credit_token_account( rebalancer, - rebalancer.data.intermediary_ta.pk, - flash_borrow as i64, + ta_creditor, + SolautoAccount::IntermediaryTa, + flash_borrow as i64 ); - perform_swap(rebalancer, &rebalance_direction, true); + perform_swap(rebalancer, ta_creditor, &rebalance_direction, true); let res = rebalancer.rebalance(RebalanceStep::PostSwap); assert!(res.is_ok()); - apply_actions(rebalancer); + apply_actions(rebalancer, ta_creditor); validate_rebalance(rebalancer); } @@ -631,7 +632,7 @@ mod tests { settings, max_ltv_bps: Some(MAX_LTV_BPS), liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), - }), + }) ); let debt_adjustment = get_debt_adjustment( @@ -642,11 +643,11 @@ mod tests { solauto: SOLAUTO_FEE_BPS, lp_borrow: BORROW_FEE_BPS, flash_loan: FLASH_LOAN_FEE_BPS, - }), + }) ); let flash_borrow = to_base_unit( debt_adjustment.debt_adjustment_usd.abs().div(SUPPLY_PRICE), - TEST_TOKEN_DECIMALS, + TEST_TOKEN_DECIMALS ); let rebalance_args = RebalanceSettings { @@ -665,20 +666,22 @@ mod tests { rebalance_direction: rebalance_direction.clone(), }, rebalance_args, - Some(flash_borrow), + Some(flash_borrow) ); + let ta_creditor = &mut TaCreditor::new(); credit_token_account( rebalancer, - rebalancer.data.intermediary_ta.pk, - flash_borrow as i64, + ta_creditor, + SolautoAccount::IntermediaryTa, + flash_borrow as i64 ); - perform_swap(rebalancer, &rebalance_direction, true); + perform_swap(rebalancer, ta_creditor, &rebalance_direction, true); let res = rebalancer.rebalance(RebalanceStep::PostSwap); assert!(res.is_ok()); - apply_actions(rebalancer); + apply_actions(rebalancer, ta_creditor); validate_rebalance(rebalancer); } @@ -706,7 +709,7 @@ mod tests { settings, max_ltv_bps: Some(MAX_LTV_BPS), liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), - }), + }) ); let debt_adjustment = get_debt_adjustment( @@ -717,17 +720,19 @@ mod tests { solauto: SOLAUTO_FEE_BPS, lp_borrow: BORROW_FEE_BPS, flash_loan: 0, - }), + }) ); println!("{}", debt_adjustment.debt_adjustment_usd.abs()); let rebalance_args = RebalanceSettings { rebalance_type: SolautoRebalanceType::FLRebalanceThenSwap, target_liq_utilization_rate_bps: None, - swap_in_amount_base_unit: Some(to_base_unit( - debt_adjustment.debt_adjustment_usd.abs().div(SUPPLY_PRICE), - TEST_TOKEN_DECIMALS, - )), + swap_in_amount_base_unit: Some( + to_base_unit( + debt_adjustment.debt_adjustment_usd.abs().div(SUPPLY_PRICE), + TEST_TOKEN_DECIMALS + ) + ), flash_loan_fee_bps: None, swap_type: Some(SwapType::ExactOut), price_type: None, @@ -740,26 +745,28 @@ mod tests { rebalance_direction: rebalance_direction.clone(), }, rebalance_args, - None, + None ); + let ta_creditor = &mut TaCreditor::new(); let flash_borrow = to_base_unit( debt_adjustment.debt_adjustment_usd.abs().div(DEBT_PRICE), - TEST_TOKEN_DECIMALS, + TEST_TOKEN_DECIMALS ); credit_token_account( rebalancer, - rebalancer.data.solauto_position.debt_ta.pk, - flash_borrow, + ta_creditor, + SolautoAccount::SolautoPositionDebtTa, + flash_borrow ); let res = rebalancer.rebalance(RebalanceStep::PreSwap); assert!(res.is_ok()); - apply_actions(rebalancer); + apply_actions(rebalancer, ta_creditor); validate_rebalance(rebalancer); - let swap_output_amount = perform_swap(rebalancer, &rebalance_direction, false); + let swap_output_amount = perform_swap(rebalancer, ta_creditor, &rebalance_direction, false); assert_eq!( round_to_decimals(from_base_unit(swap_output_amount, TEST_TOKEN_DECIMALS), 4), @@ -789,7 +796,7 @@ mod tests { settings, max_ltv_bps: Some(MAX_LTV_BPS), liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), - }), + }) ); let debt_adjustment = get_debt_adjustment( LIQ_THRESHOLD_BPS, @@ -799,15 +806,17 @@ mod tests { solauto: SOLAUTO_FEE_BPS, lp_borrow: BORROW_FEE_BPS, flash_loan: 0, - }), + }) ); let rebalance_args = RebalanceSettings { rebalance_type: SolautoRebalanceType::Regular, target_liq_utilization_rate_bps: Some(rebalance_to), - swap_in_amount_base_unit: Some(to_base_unit( - debt_adjustment.debt_adjustment_usd.div(DEBT_PRICE), - TEST_TOKEN_DECIMALS, - )), + swap_in_amount_base_unit: Some( + to_base_unit( + debt_adjustment.debt_adjustment_usd.div(DEBT_PRICE), + TEST_TOKEN_DECIMALS + ) + ), flash_loan_fee_bps: None, swap_type: Some(SwapType::ExactIn), price_type: None, @@ -820,18 +829,19 @@ mod tests { rebalance_direction: rebalance_direction.clone(), }, rebalance_args, - None, + None ); + let ta_creditor = &mut TaCreditor::new(); let res = rebalancer.rebalance(RebalanceStep::PreSwap); assert!(res.is_ok()); - apply_actions(rebalancer); + apply_actions(rebalancer, ta_creditor); - perform_swap(rebalancer, &rebalance_direction, true); + perform_swap(rebalancer, ta_creditor, &rebalance_direction, true); let res = rebalancer.rebalance(RebalanceStep::PostSwap); assert!(res.is_ok()); - apply_actions(rebalancer); + apply_actions(rebalancer, ta_creditor); validate_rebalance(rebalancer); } diff --git a/programs/solauto/src/rebalance/solauto_fees.rs b/programs/solauto/src/rebalance/solauto_fees.rs index 3316d3dc..d0e7bb24 100644 --- a/programs/solauto/src/rebalance/solauto_fees.rs +++ b/programs/solauto/src/rebalance/solauto_fees.rs @@ -61,16 +61,6 @@ impl SolautoFeesBps { let k = 1.5; let mut fee_bps: f64; - if self.target_liq_utilization_rate_bps.is_some() - && self.target_liq_utilization_rate_bps.unwrap() == 0 - { - return FeePayout { - solauto: 0, - referrer: 0, - total: 0, - }; - } - if self.target_liq_utilization_rate_bps.is_some() { fee_bps = 15.0; } else if rebalance_direction == &RebalanceDirection::Repay { diff --git a/programs/solauto/src/types/solauto.rs b/programs/solauto/src/types/solauto.rs index fd2f70ad..aa05bd52 100644 --- a/programs/solauto/src/types/solauto.rs +++ b/programs/solauto/src/types/solauto.rs @@ -1,11 +1,29 @@ -use solana_program::pubkey::Pubkey; +use super::shared::TokenBalanceAmount; -use super::shared::{BareSplTokenTransferArgs, TokenBalanceAmount}; +#[derive(Clone, Copy, Eq, PartialEq, Hash)] +pub enum SolautoAccount { + SolautoPosition, + SolautoPositionSupplyTa, + SolautoPositionDebtTa, + AuthoritySupplyTa, + AuthorityDebtTa, + IntermediaryTa, + SolautoFeesTa, + ReferredByTa +} #[derive(Clone)] pub struct FromLendingPlatformAction { pub amount: T, - pub to_wallet_ta: Pubkey, + pub to_wallet_ta: SolautoAccount, +} + +#[derive(Clone)] +pub struct SolautoSplTokenTransferArgs { + pub from_wallet: SolautoAccount, + pub from_wallet_ta: SolautoAccount, + pub to_wallet_ta: SolautoAccount, + pub amount: u64, } #[derive(Clone)] @@ -14,7 +32,7 @@ pub enum SolautoCpiAction { Borrow(FromLendingPlatformAction), Repay(TokenBalanceAmount), Withdraw(FromLendingPlatformAction), - SplTokenTransfer(BareSplTokenTransferArgs), + SplTokenTransfer(SolautoSplTokenTransferArgs), } #[derive(Copy, Clone)] diff --git a/programs/solauto/src/types/solauto_manager.rs b/programs/solauto/src/types/solauto_manager.rs index d75389e6..e95858fc 100644 --- a/programs/solauto/src/types/solauto_manager.rs +++ b/programs/solauto/src/types/solauto_manager.rs @@ -1,23 +1,32 @@ +use std::collections::HashMap; + use math_utils::to_bps; use solana_program::{ - account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, - program_error::ProgramError, pubkey::Pubkey, + account_info::AccountInfo, + clock::Clock, + entrypoint::ProgramResult, + msg, + program_error::ProgramError, }; use super::{ - instruction::{RebalanceSettings, SolautoAction, SolautoStandardAccounts}, - lending_protocol::{LendingProtocolClient, LendingProtocolTokenAccounts}, + instruction::{ RebalanceSettings, SolautoAction, SolautoStandardAccounts }, + lending_protocol::{ LendingProtocolClient, LendingProtocolTokenAccounts }, shared::{ - RebalanceStep, RefreshStateProps, SplTokenTransferArgs, TokenBalanceAmount, TokenType, + RebalanceStep, + RefreshStateProps, + SplTokenTransferArgs, + TokenBalanceAmount, + TokenType, }, - solauto::SolautoCpiAction, + solauto::{ SolautoAccount, SolautoCpiAction }, }; use crate::{ rebalance::{ - rebalancer::{Rebalancer, RebalancerData, SolautoPositionData, TokenAccountData}, + rebalancer::{ Rebalancer, RebalancerData, SolautoPositionData, TokenAccountData }, solauto_fees::SolautoFeesBps, }, - state::solauto_position::{RebalanceData, SolautoPosition}, + state::solauto_position::{ RebalanceData, SolautoPosition }, utils::*, }; @@ -32,7 +41,7 @@ impl<'a> SolautoManagerAccounts<'a> { supply: LendingProtocolTokenAccounts<'a>, debt: LendingProtocolTokenAccounts<'a>, intermediary_ta: Option<&'a AccountInfo<'a>>, - solauto_fees: Option, + solauto_fees: Option ) -> Result { Ok(Self { supply, @@ -55,7 +64,7 @@ impl<'a> SolautoManager<'a> { client: Box + 'a>, accounts: SolautoManagerAccounts<'a>, std_accounts: Box>, - solauto_fees_bps: Option, + solauto_fees_bps: Option ) -> Result { client.validate(&std_accounts)?; Ok(Self { @@ -80,15 +89,14 @@ impl<'a> SolautoManager<'a> { fn borrow(&mut self, base_unit_amount: u64, destination: &'a AccountInfo<'a>) -> ProgramResult { msg!("Borrowing {}", base_unit_amount); self.update_usage(base_unit_amount as i64, TokenType::Debt); - self.client - .borrow(base_unit_amount, destination, &self.std_accounts)?; + self.client.borrow(base_unit_amount, destination, &self.std_accounts)?; Ok(()) } fn withdraw( &mut self, amount: TokenBalanceAmount, - destination: &'a AccountInfo<'a>, + destination: &'a AccountInfo<'a> ) -> ProgramResult { let base_unit_amount = match amount { TokenBalanceAmount::All => self.position_data().state.supply.amount_used.base_unit, @@ -97,8 +105,7 @@ impl<'a> SolautoManager<'a> { msg!("Withdrawing {}", base_unit_amount); self.update_usage((base_unit_amount as i64) * -1, TokenType::Supply); - self.client - .withdraw(amount, destination, &self.std_accounts)?; + self.client.withdraw(amount, destination, &self.std_accounts)?; Ok(()) } @@ -117,41 +124,32 @@ impl<'a> SolautoManager<'a> { fn update_usage(&mut self, base_unit_amount: i64, token_type: TokenType) { let position_data = self.position_data(); if !position_data.self_managed.val || position_data.rebalance.active() { - self.std_accounts - .solauto_position - .data - .update_usage(token_type, base_unit_amount); + self.std_accounts.solauto_position.data.update_usage(token_type, base_unit_amount); } } fn get_token_account_data(&self, account: Option<&'a AccountInfo<'a>>) -> TokenAccountData { TokenAccountData::from( - *account.unwrap().key, - solauto_utils::safe_unpack_token_account(account) - .unwrap() - .unwrap() - .data - .amount, + solauto_utils::safe_unpack_token_account(account).unwrap().unwrap().data.amount ) } - fn pk_to_account_info(&self, pk: Pubkey) -> &'a AccountInfo<'a> { - let accounts = [ - Some(self.std_accounts.solauto_position.account_info), - self.accounts.supply.position_ta, - self.accounts.supply.authority_ta, - self.accounts.debt.position_ta, - self.accounts.debt.authority_ta, - self.accounts.intermediary_ta, - self.std_accounts.solauto_fees_ta, - self.std_accounts.referred_by_ta, - ]; - - accounts - .iter() - .find(|acc| acc.is_some() && acc.unwrap().key == &pk) - .unwrap() - .unwrap() + fn to_account_info(&self, acc: &SolautoAccount) -> &'a AccountInfo<'a> { + let mut map: HashMap> = HashMap::new(); + + map.insert( + SolautoAccount::SolautoPosition, + Some(self.std_accounts.solauto_position.account_info) + ); + map.insert(SolautoAccount::SolautoPositionSupplyTa, self.accounts.supply.position_ta); + map.insert(SolautoAccount::SolautoPositionDebtTa, self.accounts.debt.position_ta); + map.insert(SolautoAccount::AuthoritySupplyTa, self.accounts.supply.authority_ta); + map.insert(SolautoAccount::AuthorityDebtTa, self.accounts.debt.authority_ta); + map.insert(SolautoAccount::IntermediaryTa, self.accounts.intermediary_ta); + map.insert(SolautoAccount::SolautoFeesTa, self.std_accounts.solauto_fees_ta); + map.insert(SolautoAccount::ReferredByTa, self.std_accounts.referred_by_ta); + + map.get(acc).unwrap().unwrap() } fn get_rebalancer(&mut self, rebalance_args: RebalanceSettings) -> Rebalancer { @@ -165,61 +163,51 @@ impl<'a> SolautoManager<'a> { supply_ta: position_supply_ta, debt_ta: position_debt_ta, }, - authority_supply_ta: self.accounts.supply.authority_ta.map_or(None, |acc| { - Some(TokenAccountData::without_balance(*acc.key)) - }), - authority_debt_ta: self.accounts.debt.authority_ta.map_or(None, |acc| { - Some(TokenAccountData::without_balance(*acc.key)) - }), - intermediary_ta: TokenAccountData::without_balance( - *self.accounts.intermediary_ta.unwrap().key, - ), solauto_fees_bps: self.solauto_fees_bps.unwrap().clone(), - solauto_fees_ta: self - .std_accounts - .solauto_fees_ta - .map_or(None, |acc| Some(*acc.key)), - referred_by_state: self - .std_accounts - .authority_referral_state + solauto_fees_ta: self.std_accounts.solauto_fees_ta.map_or(None, |acc| Some(*acc.key)), + referred_by_state: self.std_accounts.authority_referral_state .as_ref() .map_or(None, |acc| Some(acc.data.referred_by_state.clone())), - referred_by_ta: self - .std_accounts - .referred_by_ta - .map_or(None, |acc| Some(*acc.key)), + referred_by_ta: self.std_accounts.referred_by_ta.map_or(None, |acc| Some(*acc.key)), }) } fn execute_cpi_actions(&mut self, actions: Vec) -> ProgramResult { - let sm = self; + let owned_seeds: Vec> = self.std_accounts.solauto_position.data + .seeds_with_bump() + .iter() + .map(|s| s.to_vec()) + .collect(); + let seeds_vec: Vec<&[u8]> = owned_seeds + .iter() + .map(|v| v.as_slice()) + .collect(); for action in actions { match action { - SolautoCpiAction::Deposit(amount) => sm.deposit(amount)?, + SolautoCpiAction::Deposit(amount) => self.deposit(amount)?, SolautoCpiAction::Withdraw(data) => { - sm.withdraw(data.amount, sm.pk_to_account_info(data.to_wallet_ta))?; + self.withdraw(data.amount, self.to_account_info(&data.to_wallet_ta))?; } SolautoCpiAction::Borrow(data) => { - sm.borrow(data.amount, sm.pk_to_account_info(data.to_wallet_ta))?; + self.borrow(data.amount, self.to_account_info(&data.to_wallet_ta))?; } - SolautoCpiAction::Repay(amount) => sm.repay(amount)?, + SolautoCpiAction::Repay(amount) => self.repay(amount)?, SolautoCpiAction::SplTokenTransfer(data) => { - let seeds = - if &data.from_wallet == sm.std_accounts.solauto_position.account_info.key { - Some(sm.std_accounts.solauto_position.data.seeds_with_bump()) - } else { - None - }; + let authority_seeds = if &data.from_wallet == &SolautoAccount::SolautoPosition { + Some(&seeds_vec) + } else { + None + }; solana_utils::spl_token_transfer( - sm.std_accounts.token_program, + self.std_accounts.token_program, SplTokenTransferArgs { amount: data.amount, - source: sm.pk_to_account_info(data.from_wallet_ta), - authority: sm.pk_to_account_info(data.from_wallet), - recipient: sm.pk_to_account_info(data.to_wallet_ta), - authority_seeds: seeds.as_ref(), - }, + source: self.to_account_info(&data.from_wallet_ta), + authority: self.to_account_info(&data.from_wallet), + recipient: self.to_account_info(&data.to_wallet_ta), + authority_seeds, + } )?; } } @@ -230,7 +218,7 @@ impl<'a> SolautoManager<'a> { pub fn refresh_position( solauto_position: &mut SolautoPosition, updated_data: RefreshStateProps, - clock: Clock, + clock: Clock ) -> ProgramResult { // Update mint addresses if self-managed if solauto_position.self_managed.val { @@ -248,11 +236,11 @@ impl<'a> SolautoManager<'a> { solauto_position.state.supply.amount_used.usd_value(), solauto_position.state.debt.amount_used.usd_value(), solauto_position.state.supply.market_price(), - solauto_position.state.supply.decimals, + solauto_position.state.supply.decimals ); solauto_position.state.net_worth.update_usd_value( updated_data.supply.market_price, - solauto_position.state.supply.decimals, + solauto_position.state.supply.decimals ); solauto_position.refresh_state(); @@ -267,10 +255,7 @@ impl<'a> SolautoManager<'a> { self.deposit(base_unit_amount)?; } SolautoAction::Borrow(base_unit_amount) => { - self.borrow( - base_unit_amount, - self.accounts.debt.position_ta.as_ref().unwrap(), - )?; + self.borrow(base_unit_amount, self.accounts.debt.position_ta.as_ref().unwrap())?; } SolautoAction::Repay(amount) => { self.repay(amount)?; @@ -285,7 +270,7 @@ impl<'a> SolautoManager<'a> { pub fn rebalance( &mut self, rebalance_args: RebalanceSettings, - rebalance_step: RebalanceStep, + rebalance_step: RebalanceStep ) -> ProgramResult { let (actions, finished) = { let mut rebalancer = self.get_rebalancer(rebalance_args.clone()); diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index ef3bff57..ac09ace9 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.749", + "version": "1.0.751", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/rebalance/solautoFees.ts b/solauto-sdk/src/services/rebalance/solautoFees.ts index 9f58893c..9d70cd1e 100644 --- a/solauto-sdk/src/services/rebalance/solautoFees.ts +++ b/solauto-sdk/src/services/rebalance/solautoFees.ts @@ -27,16 +27,7 @@ export class SolautoFeesBps { const minFeeBps = 25; // Fee in basis points for maxSize (0.25%) const k = 1.5; - if (this.targetLiqUtilizationRateBps === 0) { - return { - solauto: 0, - referrer: 0, - total: 0, - }; - } - let feeBps: number = 0; - if (this.targetLiqUtilizationRateBps !== undefined) { feeBps = 15; } else if (rebalanceDirection === RebalanceDirection.Repay) { diff --git a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts index 40a385b8..ac6afc0e 100644 --- a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts @@ -125,8 +125,9 @@ export class TransactionsManager { item, ]); for (let j = i; j >= 0; j--) { - if (await newSet.fitsWith(txItems[j])) { - newSet.prepend(txItems[j]); + const tx = txItems[j]; + if ((await newSet.fitsWith(tx))) { + newSet.prepend(tx); i--; } else { break; From d8af1b0b8675a7576987b8d8e7243af4a9387b85 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 9 May 2025 02:39:43 -0400 Subject: [PATCH 27/88] more optimizations for stack mem --- .../src/instructions/close_position.rs | 41 ++-- .../solauto/src/instructions/referral_fees.rs | 78 +++--- programs/solauto/src/rebalance/rebalancer.rs | 42 +--- .../solauto/src/rebalance/rebalancer_tests.rs | 29 +-- programs/solauto/src/state/referral_state.rs | 3 + programs/solauto/src/types/shared.rs | 33 ++- programs/solauto/src/types/solauto.rs | 6 +- programs/solauto/src/types/solauto_manager.rs | 45 +++- programs/solauto/src/utils/solana_utils.rs | 48 ++-- .../solauto/src/utils/validation_utils.rs | 227 ++++++++---------- 10 files changed, 253 insertions(+), 299 deletions(-) diff --git a/programs/solauto/src/instructions/close_position.rs b/programs/solauto/src/instructions/close_position.rs index 106db22b..610346dd 100644 --- a/programs/solauto/src/instructions/close_position.rs +++ b/programs/solauto/src/instructions/close_position.rs @@ -1,37 +1,34 @@ -use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult}; +use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult }; use crate::{ constants::WSOL_MINT, state::solauto_position::SolautoPosition, types::{ - instruction::accounts::{ClosePositionAccounts, Context}, - shared::{DeserializedAccount, SplTokenTransferArgs}, + instruction::accounts::{ ClosePositionAccounts, Context }, + shared::{ DeserializedAccount, SplTokenTransferArgs }, }, - utils::{solana_utils, solauto_utils}, + utils::{ solana_utils, solauto_utils }, }; pub fn close_position_ta<'a>( ctx: &Context>, solauto_position: &DeserializedAccount<'a, SolautoPosition>, position_ta: &'a AccountInfo<'a>, - signer_ta: &'a AccountInfo<'a>, + signer_ta: &'a AccountInfo<'a> ) -> ProgramResult { let solauto_position_seeds = &solauto_position.data.seeds_with_bump(); - let position_ta_data = solauto_utils::safe_unpack_token_account(Some(position_ta))? - .unwrap() - .data; + let position_ta_data = solauto_utils + ::safe_unpack_token_account(Some(position_ta))? + .unwrap().data; if position_ta_data.amount > 0 && position_ta_data.mint != WSOL_MINT { - solana_utils::spl_token_transfer( - ctx.accounts.token_program, - SplTokenTransferArgs { - source: position_ta, - authority: solauto_position.account_info, - recipient: signer_ta, - amount: position_ta_data.amount, - authority_seeds: Some(solauto_position_seeds), - }, - )?; + solana_utils::spl_token_transfer(ctx.accounts.token_program, SplTokenTransferArgs { + source: position_ta, + authority: solauto_position.account_info, + recipient: signer_ta, + amount: position_ta_data.amount, + authority_seeds: Some(solauto_position_seeds), + })?; } solana_utils::close_token_account( @@ -39,25 +36,25 @@ pub fn close_position_ta<'a>( position_ta, ctx.accounts.signer, ctx.accounts.solauto_position, - Some(solauto_position_seeds), + Some(solauto_position_seeds) ) } pub fn close_position<'a>( ctx: &Context>, - solauto_position: &DeserializedAccount<'a, SolautoPosition>, + solauto_position: &DeserializedAccount<'a, SolautoPosition> ) -> ProgramResult { close_position_ta( ctx, solauto_position, ctx.accounts.position_supply_ta, - ctx.accounts.signer_supply_ta, + ctx.accounts.signer_supply_ta )?; close_position_ta( ctx, solauto_position, ctx.accounts.position_debt_ta, - ctx.accounts.signer_debt_ta, + ctx.accounts.signer_debt_ta )?; solana_utils::close_pda(ctx.accounts.solauto_position, ctx.accounts.signer) } diff --git a/programs/solauto/src/instructions/referral_fees.rs b/programs/solauto/src/instructions/referral_fees.rs index 3f3beb44..f80808ad 100644 --- a/programs/solauto/src/instructions/referral_fees.rs +++ b/programs/solauto/src/instructions/referral_fees.rs @@ -1,39 +1,36 @@ -use solana_program::{entrypoint::ProgramResult, program_pack::Pack, rent::Rent, sysvar::Sysvar}; +use solana_program::{ entrypoint::ProgramResult, program_pack::Pack, rent::Rent, sysvar::Sysvar }; use spl_token::state::Account as TokenAccount; use crate::{ constants::WSOL_MINT, state::referral_state::ReferralState, types::{ - instruction::accounts::{ClaimReferralFeesAccounts, Context, ConvertReferralFeesAccounts}, - shared::{DeserializedAccount, SplTokenTransferArgs}, + instruction::accounts::{ ClaimReferralFeesAccounts, Context, ConvertReferralFeesAccounts }, + shared::{ DeserializedAccount, SplTokenTransferArgs }, }, utils::solana_utils, }; pub fn convert_referral_fees( ctx: Context, - referral_state: DeserializedAccount, + referral_state: DeserializedAccount ) -> ProgramResult { let balance = TokenAccount::unpack(&ctx.accounts.referral_fees_ta.data.borrow())?.amount; - solana_utils::spl_token_transfer( - ctx.accounts.token_program, - SplTokenTransferArgs { - source: ctx.accounts.referral_fees_ta, - authority: ctx.accounts.referral_state, - recipient: ctx.accounts.intermediary_ta, - amount: balance, - authority_seeds: Some(&referral_state.data.seeds_with_bump()), - }, - )?; + solana_utils::spl_token_transfer(ctx.accounts.token_program, SplTokenTransferArgs { + source: ctx.accounts.referral_fees_ta, + authority: ctx.accounts.referral_state, + recipient: ctx.accounts.intermediary_ta, + amount: balance, + authority_seeds: Some(&referral_state.data.seeds_with_bump()), + })?; Ok(()) } pub fn claim_referral_fees( ctx: Context, - referral_state: DeserializedAccount, + referral_state: DeserializedAccount ) -> ProgramResult { let referral_state_seeds = &referral_state.data.seeds_with_bump(); @@ -45,28 +42,25 @@ pub fn claim_referral_fees( ctx.accounts.signer, ctx.accounts.signer, ctx.accounts.signer_wsol_ta.unwrap(), - ctx.accounts.referral_fees_dest_mint, + ctx.accounts.referral_fees_dest_mint )?; let rent = Rent::get()?; let account_rent = rent.minimum_balance(TokenAccount::LEN); - solana_utils::spl_token_transfer( - ctx.accounts.token_program, - SplTokenTransferArgs { - source: ctx.accounts.referral_fees_dest_ta, - authority: ctx.accounts.referral_state, - recipient: ctx.accounts.signer_wsol_ta.unwrap(), - amount: account_rent, - authority_seeds: Some(referral_state_seeds), - }, - )?; + solana_utils::spl_token_transfer(ctx.accounts.token_program, SplTokenTransferArgs { + source: ctx.accounts.referral_fees_dest_ta, + authority: ctx.accounts.referral_state, + recipient: ctx.accounts.signer_wsol_ta.unwrap(), + amount: account_rent, + authority_seeds: Some(referral_state_seeds), + })?; solana_utils::close_token_account( ctx.accounts.token_program, ctx.accounts.signer_wsol_ta.unwrap(), ctx.accounts.signer, ctx.accounts.signer, - None, + None )?; solana_utils::init_ata_if_needed( @@ -75,7 +69,7 @@ pub fn claim_referral_fees( ctx.accounts.signer, ctx.accounts.signer, ctx.accounts.signer_wsol_ta.unwrap(), - ctx.accounts.referral_fees_dest_mint, + ctx.accounts.referral_fees_dest_mint )?; } @@ -84,7 +78,7 @@ pub fn claim_referral_fees( ctx.accounts.referral_fees_dest_ta, ctx.accounts.referral_authority, ctx.accounts.referral_state, - Some(referral_state_seeds), + Some(referral_state_seeds) )?; solana_utils::init_ata_if_needed( @@ -93,7 +87,7 @@ pub fn claim_referral_fees( ctx.accounts.signer, ctx.accounts.referral_state, ctx.accounts.referral_fees_dest_ta, - ctx.accounts.referral_fees_dest_mint, + ctx.accounts.referral_fees_dest_mint )?; } else { solana_utils::init_ata_if_needed( @@ -102,22 +96,20 @@ pub fn claim_referral_fees( ctx.accounts.signer, ctx.accounts.referral_authority, ctx.accounts.fees_destination_ta.unwrap(), - ctx.accounts.referral_fees_dest_mint, + ctx.accounts.referral_fees_dest_mint )?; - let balance = - TokenAccount::unpack(&ctx.accounts.referral_fees_dest_ta.data.borrow())?.amount; + let balance = TokenAccount::unpack( + &ctx.accounts.referral_fees_dest_ta.data.borrow() + )?.amount; - solana_utils::spl_token_transfer( - ctx.accounts.token_program, - SplTokenTransferArgs { - source: ctx.accounts.referral_fees_dest_ta, - authority: ctx.accounts.referral_state, - recipient: ctx.accounts.fees_destination_ta.unwrap(), - amount: balance, - authority_seeds: Some(referral_state_seeds), - }, - )?; + solana_utils::spl_token_transfer(ctx.accounts.token_program, SplTokenTransferArgs { + source: ctx.accounts.referral_fees_dest_ta, + authority: ctx.accounts.referral_state, + recipient: ctx.accounts.fees_destination_ta.unwrap(), + amount: balance, + authority_seeds: Some(referral_state_seeds), + })?; } Ok(()) diff --git a/programs/solauto/src/rebalance/rebalancer.rs b/programs/solauto/src/rebalance/rebalancer.rs index da9e9f5e..4b7269af 100644 --- a/programs/solauto/src/rebalance/rebalancer.rs +++ b/programs/solauto/src/rebalance/rebalancer.rs @@ -1,10 +1,9 @@ use std::{ cmp::min, ops::{ Add, Mul } }; -use solana_program::{ entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey }; +use solana_program::{ entrypoint::ProgramResult, program_error::ProgramError }; use crate::{ check, - constants::SOLAUTO_FEES_WALLET, state::solauto_position::{ PositionTokenState, RebalanceData, @@ -28,9 +27,11 @@ use crate::{ SolautoSplTokenTransferArgs, }, }, - utils::{ - math_utils::{ calc_fee_amount, from_bps, from_rounded_usd_value, usd_value_to_base_unit }, - validation_utils::correct_token_account, + utils::math_utils::{ + calc_fee_amount, + from_bps, + from_rounded_usd_value, + usd_value_to_base_unit, }, }; @@ -61,9 +62,7 @@ pub struct RebalancerData<'a> { pub rebalance_args: RebalanceSettings, pub solauto_position: SolautoPositionData<'a>, pub solauto_fees_bps: SolautoFeesBps, - pub solauto_fees_ta: Option, - pub referred_by_state: Option, - pub referred_by_ta: Option, + pub referred_by: bool, } pub struct RebalanceResult { @@ -350,24 +349,16 @@ impl<'a> Rebalancer<'a> { fn payout_fees(&mut self, available_balance: u64) -> Result { let rebalance_direction = &self.rebalance_data().values.rebalance_direction; - let (token_mint, position_ta) = if self.is_boost() { - (self.position_data().state.supply.mint, SolautoAccount::SolautoPositionSupplyTa) + let position_ta = if self.is_boost() { + SolautoAccount::SolautoPositionSupplyTa } else { - (self.position_data().state.debt.mint, SolautoAccount::SolautoPositionDebtTa) + SolautoAccount::SolautoPositionDebtTa }; let fee_payout = self.data.solauto_fees_bps.fetch_fees(rebalance_direction); if fee_payout.total == 0 { return Ok(available_balance); } - check!( - correct_token_account( - self.data.solauto_fees_ta.as_ref().unwrap(), - &SOLAUTO_FEES_WALLET, - &token_mint - ), - SolautoError::IncorrectAccounts - ); let solauto_fees = self.payout_fee( available_balance, fee_payout.solauto, @@ -375,18 +366,7 @@ impl<'a> Rebalancer<'a> { SolautoAccount::SolautoFeesTa )?; - let referrer_fees = if - self.data.referred_by_state.is_some() && - self.data.referred_by_state.unwrap() != Pubkey::default() - { - check!( - correct_token_account( - self.data.referred_by_ta.as_ref().unwrap(), - self.data.referred_by_state.as_ref().unwrap(), - &token_mint - ), - SolautoError::IncorrectAccounts - ); + let referrer_fees = if self.data.referred_by { self.payout_fee( available_balance, fee_payout.referrer, diff --git a/programs/solauto/src/rebalance/rebalancer_tests.rs b/programs/solauto/src/rebalance/rebalancer_tests.rs index e3446fbb..34ce628b 100644 --- a/programs/solauto/src/rebalance/rebalancer_tests.rs +++ b/programs/solauto/src/rebalance/rebalancer_tests.rs @@ -1,10 +1,8 @@ use std::ops::{ Div, Mul }; use solana_program::pubkey::Pubkey; -use spl_associated_token_account::get_associated_token_address; use crate::{ - constants::SOLAUTO_FEES_WALLET, state::solauto_position::{ PositionData, PositionState, @@ -129,29 +127,6 @@ fn create_rebalancer<'a>( data.pos.rebalance.ixs.active = PodBool::new(true); data.pos.rebalance.ixs.swap_type = rebalance_args.swap_type.unwrap_or(SwapType::default()); - let position_supply_ta = get_associated_token_address( - &data.pos.pubkey(), - &data.pos.state.supply.mint - ); - let position_debt_ta = get_associated_token_address( - &data.pos.pubkey(), - &data.pos.state.debt.mint - ); - let position_authority_supply_ta = get_associated_token_address( - &data.pos.authority, - &data.pos.state.supply.mint - ); - let position_authority_debt_ta = get_associated_token_address( - &data.pos.authority, - &data.pos.state.debt.mint - ); - - let fees_mint = if data.rebalance_direction == RebalanceDirection::Boost { - data.pos.state.supply.mint - } else { - data.pos.state.debt.mint - }; - let solauto_fees_ta = get_associated_token_address(&SOLAUTO_FEES_WALLET, &fees_mint); let solauto_fees = SolautoFeesBps::from_mock(SOLAUTO_FEE_BPS, false); let rebalancer = Rebalancer::new(RebalancerData { @@ -162,9 +137,7 @@ fn create_rebalancer<'a>( debt_ta: TokenAccountData::from(data.position_debt_ta_balance.unwrap_or(0)), }, solauto_fees_bps: solauto_fees, - referred_by_state: None, - referred_by_ta: None, - solauto_fees_ta: Some(solauto_fees_ta), + referred_by: false, }); rebalancer diff --git a/programs/solauto/src/state/referral_state.rs b/programs/solauto/src/state/referral_state.rs index 7aa2e445..0b4da833 100644 --- a/programs/solauto/src/state/referral_state.rs +++ b/programs/solauto/src/state/referral_state.rs @@ -49,6 +49,9 @@ impl ReferralState { seeds.push(&self.bump); seeds } + pub fn is_referred(&self) -> bool { + self.referred_by_state != Pubkey::default() + } } mod tests { diff --git a/programs/solauto/src/types/shared.rs b/programs/solauto/src/types/shared.rs index e6945dc1..45557d3b 100644 --- a/programs/solauto/src/types/shared.rs +++ b/programs/solauto/src/types/shared.rs @@ -1,4 +1,4 @@ -use borsh::{BorshDeserialize, BorshSerialize}; +use borsh::{ BorshDeserialize, BorshSerialize }; use bytemuck::AnyBitPattern; use bytemuck::Pod; use bytemuck::Zeroable; @@ -8,7 +8,7 @@ use solana_program::pubkey::Pubkey; use solana_program::{ account_info::AccountInfo, program_error::ProgramError, - program_pack::{IsInitialized, Pack}, + program_pack::{ IsInitialized, Pack }, }; use std::fmt; @@ -122,14 +122,6 @@ pub struct SplTokenTransferArgs<'a, 'b> { pub authority_seeds: Option<&'b Vec<&'b [u8]>>, } -#[derive(Clone)] -pub struct BareSplTokenTransferArgs { - pub from_wallet: Pubkey, - pub from_wallet_ta: Pubkey, - pub to_wallet_ta: Pubkey, - pub amount: u64, -} - #[repr(C)] #[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankType, Default, PartialEq, Copy)] pub struct PodBool { @@ -161,10 +153,13 @@ pub struct DeserializedAccount<'a, T> { impl<'a, T: AnyBitPattern> DeserializedAccount<'a, T> { pub fn zerocopy(account: Option<&'a AccountInfo<'a>>) -> Result, ProgramError> { match account { - Some(account_info) => Ok(Some(Self { - account_info, - data: Box::new(*bytemuck::from_bytes::(&account_info.data.borrow())), - })), + Some(account_info) => + Ok( + Some(Self { + account_info, + data: Box::new(*bytemuck::from_bytes::(&account_info.data.borrow())), + }) + ), None => Ok(None), } } @@ -178,10 +173,12 @@ impl<'a, T: Pack + IsInitialized> DeserializedAccount<'a, T> { msg!("Failed to deserialize account data"); SolautoError::FailedAccountDeserialization })?; - Ok(Some(Self { - account_info, - data: Box::new(deserialized_data), - })) + Ok( + Some(Self { + account_info, + data: Box::new(deserialized_data), + }) + ) } None => Ok(None), } diff --git a/programs/solauto/src/types/solauto.rs b/programs/solauto/src/types/solauto.rs index aa05bd52..f7f76979 100644 --- a/programs/solauto/src/types/solauto.rs +++ b/programs/solauto/src/types/solauto.rs @@ -1,4 +1,4 @@ -use super::shared::TokenBalanceAmount; +use super::shared::{ TokenBalanceAmount, TokenType }; #[derive(Clone, Copy, Eq, PartialEq, Hash)] pub enum SolautoAccount { @@ -9,7 +9,9 @@ pub enum SolautoAccount { AuthorityDebtTa, IntermediaryTa, SolautoFeesTa, - ReferredByTa + ReferredByTa, + SupplyMint, + DebtMint, } #[derive(Clone)] diff --git a/programs/solauto/src/types/solauto_manager.rs b/programs/solauto/src/types/solauto_manager.rs index e95858fc..067c4aca 100644 --- a/programs/solauto/src/types/solauto_manager.rs +++ b/programs/solauto/src/types/solauto_manager.rs @@ -22,11 +22,14 @@ use super::{ solauto::{ SolautoAccount, SolautoCpiAction }, }; use crate::{ + check, + constants::SOLAUTO_FEES_WALLET, rebalance::{ rebalancer::{ Rebalancer, RebalancerData, SolautoPositionData, TokenAccountData }, solauto_fees::SolautoFeesBps, }, state::solauto_position::{ RebalanceData, SolautoPosition }, + types::errors::SolautoError, utils::*, }; @@ -164,11 +167,8 @@ impl<'a> SolautoManager<'a> { debt_ta: position_debt_ta, }, solauto_fees_bps: self.solauto_fees_bps.unwrap().clone(), - solauto_fees_ta: self.std_accounts.solauto_fees_ta.map_or(None, |acc| Some(*acc.key)), - referred_by_state: self.std_accounts.authority_referral_state - .as_ref() - .map_or(None, |acc| Some(acc.data.referred_by_state.clone())), - referred_by_ta: self.std_accounts.referred_by_ta.map_or(None, |acc| Some(*acc.key)), + referred_by: self.std_accounts.authority_referral_state.is_some() && + self.std_accounts.authority_referral_state.as_ref().unwrap().data.is_referred(), }) } @@ -267,11 +267,46 @@ impl<'a> SolautoManager<'a> { Ok(()) } + fn validate_fee_token_accounts(&self) -> ProgramResult { + let mints = vec![ + self.std_accounts.solauto_position.data.state.supply.mint, + self.std_accounts.solauto_position.data.state.debt.mint + ]; + + if self.std_accounts.solauto_fees_ta.is_some() { + check!( + validation_utils::valid_token_account_for_mints( + self.std_accounts.solauto_fees_ta.as_ref().unwrap().key, + &SOLAUTO_FEES_WALLET, + &mints + ), + SolautoError::IncorrectAccounts + ); + } + + if self.std_accounts.referred_by_ta.is_some() { + check!( + validation_utils::valid_token_account_for_mints( + self.std_accounts.referred_by_ta.as_ref().unwrap().key, + &self.std_accounts.authority_referral_state + .as_ref() + .unwrap().data.referred_by_state, + &mints + ), + SolautoError::IncorrectAccounts + ); + } + + Ok(()) + } + pub fn rebalance( &mut self, rebalance_args: RebalanceSettings, rebalance_step: RebalanceStep ) -> ProgramResult { + self.validate_fee_token_accounts()?; + let (actions, finished) = { let mut rebalancer = self.get_rebalancer(rebalance_args.clone()); let rebalance_result = rebalancer.rebalance(rebalance_step)?; diff --git a/programs/solauto/src/utils/solana_utils.rs b/programs/solauto/src/utils/solana_utils.rs index 3c4cc00c..96f08a90 100644 --- a/programs/solauto/src/utils/solana_utils.rs +++ b/programs/solauto/src/utils/solana_utils.rs @@ -2,7 +2,7 @@ use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, instruction::Instruction, - program::{invoke, invoke_signed}, + program::{ invoke, invoke_signed }, pubkey::Pubkey, rent::Rent, system_instruction, @@ -13,7 +13,7 @@ use spl_token::instruction as spl_instruction; use crate::{ check, - types::{errors::SolautoError, shared::SplTokenTransferArgs}, + types::{ errors::SolautoError, shared::SplTokenTransferArgs }, utils::validation_utils::correct_token_account, }; @@ -24,7 +24,7 @@ pub fn account_has_data(account: &AccountInfo) -> bool { pub fn invoke_instruction( instruction: &Instruction, account_infos: &[AccountInfo], - seeds: Option<&Vec<&[u8]>>, + seeds: Option<&Vec<&[u8]>> ) -> ProgramResult { if let Some(seeds) = seeds { invoke_signed(instruction, account_infos, &[seeds.as_slice()]) @@ -39,14 +39,12 @@ pub fn init_account<'a>( account: &'a AccountInfo<'a>, new_owner: &Pubkey, account_seed: Option>, - space: usize, + space: usize ) -> ProgramResult { check!(!account_has_data(account), SolautoError::IncorrectAccounts); let rent = &Rent::from_account_info(rent_sysvar)?; - let required_lamports = rent - .minimum_balance(space) - .saturating_sub(account.lamports()); + let required_lamports = rent.minimum_balance(space).saturating_sub(account.lamports()); if required_lamports > 0 { system_transfer(payer, account, required_lamports, None)?; } @@ -56,13 +54,13 @@ pub fn init_account<'a>( invoke_instruction( &system_instruction::allocate(account.key, space.try_into().unwrap()), accounts, - account_seed.as_ref(), + account_seed.as_ref() )?; invoke_instruction( &system_instruction::assign(account.key, &new_owner), accounts, - account_seed.as_ref(), + account_seed.as_ref() )?; Ok(()) @@ -74,7 +72,7 @@ pub fn init_ata_if_needed<'a, 'b>( payer: &'a AccountInfo<'a>, wallet: &'a AccountInfo<'a>, token_account: &'a AccountInfo<'a>, - token_mint: &'a AccountInfo<'a>, + token_mint: &'a AccountInfo<'a> ) -> ProgramResult { check!( correct_token_account(token_account.key, wallet.key, token_mint.key), @@ -94,7 +92,7 @@ pub fn init_ata_if_needed<'a, 'b>( token_mint.clone(), system_program.clone(), token_program.clone(), - ], + ] ) } @@ -102,18 +100,18 @@ pub fn system_transfer<'a>( source: &'a AccountInfo<'a>, destination: &'a AccountInfo<'a>, lamports: u64, - source_seeds: Option<&Vec<&[u8]>>, + source_seeds: Option<&Vec<&[u8]>> ) -> ProgramResult { invoke_instruction( &system_instruction::transfer(source.key, destination.key, lamports), &[source.clone(), destination.clone()], - source_seeds, + source_seeds ) } pub fn spl_token_transfer<'a, 'b>( token_program: &'a AccountInfo<'a>, - args: SplTokenTransferArgs<'a, 'b>, + args: SplTokenTransferArgs<'a, 'b> ) -> ProgramResult { invoke_instruction( &spl_instruction::transfer( @@ -122,14 +120,10 @@ pub fn spl_token_transfer<'a, 'b>( args.recipient.key, args.authority.key, &[], - args.amount, + args.amount )?, - &[ - args.source.clone(), - args.recipient.clone(), - args.authority.clone(), - ], - args.authority_seeds, + &[args.source.clone(), args.recipient.clone(), args.authority.clone()], + args.authority_seeds ) } @@ -138,7 +132,7 @@ pub fn close_token_account<'a, 'b>( account: &'a AccountInfo<'a>, sol_destination: &'a AccountInfo<'a>, account_owner: &'a AccountInfo<'a>, - owner_seeds: Option<&Vec<&[u8]>>, + owner_seeds: Option<&Vec<&[u8]>> ) -> ProgramResult { invoke_instruction( &spl_instruction::close_account( @@ -146,14 +140,10 @@ pub fn close_token_account<'a, 'b>( account.key, sol_destination.key, account_owner.key, - &[], + &[] )?, - &[ - account.clone(), - sol_destination.clone(), - account_owner.clone(), - ], - owner_seeds, + &[account.clone(), sol_destination.clone(), account_owner.clone()], + owner_seeds ) } diff --git a/programs/solauto/src/utils/validation_utils.rs b/programs/solauto/src/utils/validation_utils.rs index 131d9cf3..572e24ce 100644 --- a/programs/solauto/src/utils/validation_utils.rs +++ b/programs/solauto/src/utils/validation_utils.rs @@ -1,6 +1,6 @@ use std::ops::Div; -use marginfi_sdk::generated::accounts::{Bank, MarginfiAccount}; +use marginfi_sdk::generated::accounts::{ Bank, MarginfiAccount }; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, @@ -8,32 +8,36 @@ use solana_program::{ program_error::ProgramError, pubkey::Pubkey, system_program::ID as system_program_id, - sysvar::{instructions::ID as ixs_sysvar_id, rent::ID as rent_program_id}, + sysvar::{ instructions::ID as ixs_sysvar_id, rent::ID as rent_program_id }, }; -use spl_associated_token_account::{get_associated_token_address, ID as ata_program_id}; +use spl_associated_token_account::{ get_associated_token_address, ID as ata_program_id }; use spl_token::ID as token_program_id; use crate::{ check, constants::{ - MARGINFI_PROD_PROGRAM, MARGINFI_STAGING_PROGRAM, MIN_BOOST_GAP_BPS, MIN_REPAY_GAP_BPS, + MARGINFI_PROD_PROGRAM, + MARGINFI_STAGING_PROGRAM, + MIN_BOOST_GAP_BPS, + MIN_REPAY_GAP_BPS, SOLAUTO_MANAGER, }, error_if, state::{ - automation::AutomationSettings, referral_state::ReferralState, + automation::AutomationSettings, + referral_state::ReferralState, solauto_position::SolautoPosition, }, types::{ errors::SolautoError, instruction::SolautoStandardAccounts, - shared::{DeserializedAccount, LendingPlatform, TokenType}, + shared::{ DeserializedAccount, LendingPlatform, TokenType }, }, utils::math_utils::from_rounded_usd_value, }; use super::{ - math_utils::{get_max_boost_to_bps, get_max_repay_from_bps, get_max_repay_to_bps}, + math_utils::{ get_max_boost_to_bps, get_max_repay_from_bps, get_max_repay_to_bps }, solauto_utils::safe_unpack_token_account, }; @@ -41,13 +45,13 @@ pub fn generic_instruction_validation( accounts: &Box, lending_platform: LendingPlatform, authority_signer_only_ix: bool, - solauto_managed_only_ix: bool, + solauto_managed_only_ix: bool ) -> ProgramResult { validate_instruction( accounts.signer, &accounts.solauto_position, authority_signer_only_ix, - solauto_managed_only_ix, + solauto_managed_only_ix )?; validate_lending_program_account(accounts.lending_protocol, lending_platform)?; validate_standard_programs( @@ -55,7 +59,7 @@ pub fn generic_instruction_validation( Some(accounts.token_program), accounts.ata_program, accounts.rent, - accounts.ixs_sysvar, + accounts.ixs_sysvar )?; if accounts.authority_referral_state.is_some() { @@ -63,11 +67,11 @@ pub fn generic_instruction_validation( &accounts.solauto_position.data.authority, accounts.authority_referral_state.as_ref().unwrap(), accounts.referred_by_ta, - true, + true )?; } - // The solauto_fees_ta is validated at payout before transfer + // The solauto_fees_ta is validated during rebalance in solauto_manager.rs because it requires up-to-date state Ok(()) } @@ -75,7 +79,7 @@ pub fn validate_instruction( signer: &AccountInfo, solauto_position: &DeserializedAccount, authority_signer_only_ix: bool, - solauto_managed_only_ix: bool, + solauto_managed_only_ix: bool ) -> ProgramResult { check!(&signer.is_signer, ProgramError::MissingRequiredSignature); @@ -83,9 +87,8 @@ pub fn validate_instruction( let authority_signed = || { let expected_solauto_position_address = Pubkey::create_program_address( solauto_position.data.seeds_with_bump().as_slice(), - &crate::ID, - ) - .expect("Ok"); + &crate::ID + ).expect("Ok"); let expected_address_matches = solauto_position.account_info.key == &expected_solauto_position_address; return signer.key == &position_authority && expected_address_matches; @@ -117,15 +120,15 @@ pub fn validate_instruction( pub fn validate_position_settings(solauto_position: &SolautoPosition) -> ProgramResult { let max_boost_to_bps = get_max_boost_to_bps( solauto_position.state.max_ltv_bps, - solauto_position.state.liq_threshold_bps, + solauto_position.state.liq_threshold_bps ); let max_repay_to_bps = get_max_repay_to_bps( solauto_position.state.max_ltv_bps, - solauto_position.state.liq_threshold_bps, + solauto_position.state.liq_threshold_bps ); let max_repay_from_bps = get_max_repay_from_bps( solauto_position.state.max_ltv_bps, - solauto_position.state.liq_threshold_bps, + solauto_position.state.liq_threshold_bps ); let data = &solauto_position.position; @@ -133,22 +136,10 @@ pub fn validate_position_settings(solauto_position: &SolautoPosition) -> Program data.settings.repay_to_bps >= data.settings.boost_to_bps, SolautoError::InvalidRepayToSetting ); - check!( - data.settings.boost_to_bps <= max_boost_to_bps, - SolautoError::InvalidBoostToSetting - ); - check!( - data.settings.repay_gap >= MIN_REPAY_GAP_BPS, - SolautoError::InvalidRepayGapSetting - ); - check!( - data.settings.boost_gap >= MIN_BOOST_GAP_BPS, - SolautoError::InvalidBoostGapSetting - ); - check!( - data.settings.repay_to_bps <= max_repay_to_bps, - SolautoError::InvalidRepayToSetting - ); + check!(data.settings.boost_to_bps <= max_boost_to_bps, SolautoError::InvalidBoostToSetting); + check!(data.settings.repay_gap >= MIN_REPAY_GAP_BPS, SolautoError::InvalidRepayGapSetting); + check!(data.settings.boost_gap >= MIN_BOOST_GAP_BPS, SolautoError::InvalidBoostGapSetting); + check!(data.settings.repay_to_bps <= max_repay_to_bps, SolautoError::InvalidRepayToSetting); check!( data.settings.repay_to_bps + data.settings.repay_gap <= max_repay_from_bps, SolautoError::InvalidRepayFromSetting @@ -158,7 +149,7 @@ pub fn validate_position_settings(solauto_position: &SolautoPosition) -> Program pub fn validate_automation_settings( automation: &AutomationSettings, - current_unix_timestamp: u64, + current_unix_timestamp: u64 ) -> ProgramResult { let invalid_params = |error_msg| { msg!(error_msg); @@ -173,8 +164,9 @@ pub fn validate_automation_settings( return invalid_params("Interval period must be between 10 minutes and 1 month"); } - if current_unix_timestamp < automation.unix_start_date - || current_unix_timestamp > automation.unix_start_date + automation.interval_seconds + if + current_unix_timestamp < automation.unix_start_date || + current_unix_timestamp > automation.unix_start_date + automation.interval_seconds { return invalid_params("Provided an invalid unix start date"); } @@ -188,7 +180,7 @@ pub fn validate_automation_settings( pub fn validate_lending_program_account( program: &AccountInfo, - lending_platform: LendingPlatform, + lending_platform: LendingPlatform ) -> ProgramResult { match lending_platform { LendingPlatform::Marginfi => { @@ -207,7 +199,7 @@ pub fn validate_standard_programs( token_program: Option<&AccountInfo>, ata_program: Option<&AccountInfo>, rent: Option<&AccountInfo>, - ixs_sysvar: Option<&AccountInfo>, + ixs_sysvar: Option<&AccountInfo> ) -> ProgramResult { check!( system_program.is_none() || system_program.unwrap().key == &system_program_id, @@ -236,34 +228,34 @@ pub fn validate_referral_accounts<'a>( referral_state_authority: &Pubkey, authority_referral_state: &DeserializedAccount<'a, ReferralState>, referred_by_ta: Option<&'a AccountInfo<'a>>, - validate_ta: bool, + validate_ta: bool ) -> ProgramResult { let referral_state_pda = Pubkey::create_program_address( authority_referral_state.data.seeds_with_bump().as_slice(), - &crate::ID, + &crate::ID )?; error_if!( - &authority_referral_state.data.authority != referral_state_authority - || &referral_state_pda != authority_referral_state.account_info.key, + &authority_referral_state.data.authority != referral_state_authority || + &referral_state_pda != authority_referral_state.account_info.key, SolautoError::IncorrectAccounts ); let authority_referred_by_state = &authority_referral_state.data.referred_by_state; error_if!( - validate_ta - && authority_referred_by_state != &Pubkey::default() - && referred_by_ta.is_none(), + validate_ta && + authority_referred_by_state != &Pubkey::default() && + referred_by_ta.is_none(), SolautoError::IncorrectAccounts ); - // The referred_by_ta is further validated at payout before transfer + // The referred_by_ta is validated during rebalance in solauto_manager.rs because it requires up-to-date state Ok(()) } pub fn validate_marginfi_bank<'a>( marginfi_bank: &'a AccountInfo<'a>, - mint: &Pubkey, + mint: &Pubkey ) -> ProgramResult { if mint == &Pubkey::default() { return Ok(()); @@ -280,14 +272,14 @@ pub fn validate_lending_program_accounts_with_position<'a>( solauto_position: &DeserializedAccount, lp_user_account: &'a AccountInfo<'a>, lp_supply_account: &'a AccountInfo<'a>, - lp_debt_account: &'a AccountInfo<'a>, + lp_debt_account: &'a AccountInfo<'a> ) -> ProgramResult { let supply_mint = &solauto_position.data.state.supply.mint; let debt_mint = &solauto_position.data.state.debt.mint; error_if!( - !solauto_position.data.self_managed.val - && lp_user_account.key != &solauto_position.data.position.lp_user_account, + !solauto_position.data.self_managed.val && + lp_user_account.key != &solauto_position.data.position.lp_user_account, SolautoError::IncorrectAccounts ); @@ -304,20 +296,10 @@ pub fn validate_lending_program_accounts_with_position<'a>( pub fn validate_token_accounts<'a, 'b>( solauto_position: &'b DeserializedAccount<'a, SolautoPosition>, source_supply_ta: Option<&'a AccountInfo<'a>>, - source_debt_ta: Option<&'a AccountInfo<'a>>, + source_debt_ta: Option<&'a AccountInfo<'a>> ) -> ProgramResult { - validate_token_account( - solauto_position, - source_supply_ta, - Some(TokenType::Supply), - None, - )?; - validate_token_account( - solauto_position, - source_debt_ta, - Some(TokenType::Debt), - None, - )?; + validate_token_account(solauto_position, source_supply_ta, Some(TokenType::Supply), None)?; + validate_token_account(solauto_position, source_debt_ta, Some(TokenType::Debt), None)?; Ok(()) } @@ -325,7 +307,7 @@ pub fn validate_token_account<'a>( solauto_position: &DeserializedAccount<'a, SolautoPosition>, source_ta: Option<&'a AccountInfo<'a>>, token_type: Option, - token_mint: Option<&Pubkey>, + token_mint: Option<&Pubkey> ) -> ProgramResult { if solauto_position.data.self_managed.val && token_mint.is_none() { return Ok(()); @@ -342,15 +324,19 @@ pub fn validate_token_account<'a>( mint_key }; - let associated_position_ta = - get_associated_token_address(&solauto_position.account_info.key, mint_key); - let associated_authority_ta = - get_associated_token_address(&solauto_position.data.authority, mint_key); + let associated_position_ta = get_associated_token_address( + &solauto_position.account_info.key, + mint_key + ); + let associated_authority_ta = get_associated_token_address( + &solauto_position.data.authority, + mint_key + ); error_if!( - source_ta.is_some() - && source_ta.unwrap().key != &associated_position_ta - && source_ta.unwrap().key != &associated_authority_ta, + source_ta.is_some() && + source_ta.unwrap().key != &associated_position_ta && + source_ta.unwrap().key != &associated_authority_ta, SolautoError::IncorrectAccounts ); @@ -360,7 +346,7 @@ pub fn validate_token_account<'a>( pub fn token_account_owned_by<'a>( token_account: &'a AccountInfo<'a>, expected_owner: &Pubkey, - token_mint: Option<&Pubkey>, + token_mint: Option<&Pubkey> ) -> Result { if token_mint.is_some() { return Ok( @@ -368,29 +354,28 @@ pub fn token_account_owned_by<'a>( ); } else { let token_account_data = safe_unpack_token_account(Some(token_account))?.unwrap(); - return Ok(token_account_data.account_info.owner == &token_program_id - && &token_account_data.data.owner == expected_owner); + return Ok( + token_account_data.account_info.owner == &token_program_id && + &token_account_data.data.owner == expected_owner + ); } } pub fn validate_referral_signer( referral_state: &DeserializedAccount, signer: &AccountInfo, - allow_solauto_manager: bool, + allow_solauto_manager: bool ) -> ProgramResult { let referral_state_pda = Pubkey::create_program_address( referral_state.data.seeds_with_bump().as_slice(), - &crate::ID, + &crate::ID )?; check!(&signer.is_signer, ProgramError::MissingRequiredSignature); - check!( - &referral_state_pda == referral_state.account_info.key, - SolautoError::IncorrectAccounts - ); + check!(&referral_state_pda == referral_state.account_info.key, SolautoError::IncorrectAccounts); error_if!( - signer.key != &referral_state.data.authority - && (!allow_solauto_manager || signer.key != &SOLAUTO_MANAGER), + signer.key != &referral_state.data.authority && + (!allow_solauto_manager || signer.key != &SOLAUTO_MANAGER), SolautoError::IncorrectAccounts ); @@ -399,22 +384,19 @@ pub fn validate_referral_signer( pub fn validate_no_active_balances<'a>( lp_user_account: &'a AccountInfo<'a>, - lending_platform: LendingPlatform, + lending_platform: LendingPlatform ) -> ProgramResult { if lending_platform == LendingPlatform::Marginfi { - let marginfi_account = - DeserializedAccount::::zerocopy(Some(lp_user_account))?.unwrap(); + let marginfi_account = DeserializedAccount:: + ::zerocopy(Some(lp_user_account))? + .unwrap(); check!( - marginfi_account - .data - .lending_account - .balances + marginfi_account.data.lending_account.balances .iter() .filter(|balance| balance.active == 1) .collect::>() - .len() - == 0, + .len() == 0, SolautoError::IncorrectAccounts ); @@ -429,20 +411,13 @@ pub fn validate_rebalance(solauto_position: &SolautoPosition) -> ProgramResult { let curr_supply_usd = solauto_position.state.supply.amount_used.usd_value(); let curr_debt_usd = solauto_position.state.debt.amount_used.usd_value(); - let target_supply_usd = - from_rounded_usd_value(solauto_position.rebalance.values.target_supply_usd); + let target_supply_usd = from_rounded_usd_value( + solauto_position.rebalance.values.target_supply_usd + ); let target_debt_usd = from_rounded_usd_value(solauto_position.rebalance.values.target_debt_usd); - msg!( - "Supply expected vs. actual: {}, {}", - target_supply_usd, - curr_supply_usd - ); - msg!( - "Debt expected vs. actual: {}, {}", - target_debt_usd, - curr_debt_usd - ); + msg!("Supply expected vs. actual: {}, {}", target_supply_usd, curr_supply_usd); + msg!("Debt expected vs. actual: {}, {}", target_debt_usd, curr_debt_usd); check!( value_gte_with_threshold(curr_supply_usd, target_supply_usd, 0.2), SolautoError::InvalidRebalanceMade @@ -459,6 +434,14 @@ pub fn correct_token_account(token_account: &Pubkey, wallet: &Pubkey, mint: &Pub token_account == &get_associated_token_address(wallet, mint) } +pub fn valid_token_account_for_mints( + token_account: &Pubkey, + wallet: &Pubkey, + mints: &Vec +) -> bool { + mints.iter().any(|mint| correct_token_account(token_account, wallet, mint)) +} + pub fn value_lte_with_threshold(value: f64, target_value: f64, threshold: f64) -> bool { if target_value == 0.0 { return value == 0.0; @@ -484,9 +467,11 @@ pub fn value_match_with_threshold(value: f64, target_value: f64, threshold: f64) mod tests { use crate::{ state::{ - automation::{AutomationSettings, AutomationSettingsInp}, + automation::{ AutomationSettings, AutomationSettingsInp }, solauto_position::{ - PositionData, PositionState, SolautoSettingsParameters, + PositionData, + PositionState, + SolautoSettingsParameters, SolautoSettingsParametersInp, }, }, @@ -509,7 +494,7 @@ mod tests { Pubkey::default(), PositionType::default(), position_data, - position_state, + position_state ); let result = validate_position_settings(&solauto_position); assert!(result.is_err()); @@ -529,14 +514,14 @@ mod tests { boost_gap: MIN_BOOST_GAP_BPS - 10, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { repay_gap: MIN_REPAY_GAP_BPS - 10, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -544,7 +529,7 @@ mod tests { repay_gap: 600, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -552,7 +537,7 @@ mod tests { boost_gap: 1000, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -560,7 +545,7 @@ mod tests { repay_to_bps: 4000, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -568,14 +553,14 @@ mod tests { repay_gap: 500, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { repay_to_bps: 9900, ..default_settings_args }), - default_liq_threshold_bps, + default_liq_threshold_bps ); } @@ -597,25 +582,25 @@ mod tests { test_automation_settings( current_timestamp, AutomationSettings::from(AutomationSettingsInp { - unix_start_date: current_timestamp - + default_automation_settings_args.interval_seconds - + 100, + unix_start_date: current_timestamp + + default_automation_settings_args.interval_seconds + + 100, ..default_automation_settings_args - }), + }) ); test_automation_settings( current_timestamp, AutomationSettings::from(AutomationSettingsInp { interval_seconds: 60, ..default_automation_settings_args.clone() - }), + }) ); test_automation_settings( current_timestamp, AutomationSettings::from(AutomationSettingsInp { interval_seconds: 60 * 60 * 24 * 60, ..default_automation_settings_args.clone() - }), + }) ); } } From b139e38b8f199a743f72867844cad3a287b18bdb Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 9 May 2025 03:37:25 -0400 Subject: [PATCH 28/88] formatting & fixes --- .../src/instructions/close_position.rs | 41 +-- .../solauto/src/instructions/rebalance.rs | 140 ++++++---- .../solauto/src/instructions/referral_fees.rs | 78 +++--- programs/solauto/src/processors/position.rs | 32 +-- programs/solauto/src/rebalance/rebalancer.rs | 221 ++++++++------- .../solauto/src/rebalance/rebalancer_tests.rs | 251 ++++++++++-------- programs/solauto/src/types/shared.rs | 25 +- programs/solauto/src/types/solauto.rs | 2 +- programs/solauto/src/types/solauto_manager.rs | 126 +++++---- programs/solauto/src/utils/solana_utils.rs | 48 ++-- .../solauto/src/utils/validation_utils.rs | 221 ++++++++------- solauto-sdk/package.json | 2 +- .../rebalance/rebalanceSwapManager.ts | 22 +- 13 files changed, 685 insertions(+), 524 deletions(-) diff --git a/programs/solauto/src/instructions/close_position.rs b/programs/solauto/src/instructions/close_position.rs index 610346dd..106db22b 100644 --- a/programs/solauto/src/instructions/close_position.rs +++ b/programs/solauto/src/instructions/close_position.rs @@ -1,34 +1,37 @@ -use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult }; +use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult}; use crate::{ constants::WSOL_MINT, state::solauto_position::SolautoPosition, types::{ - instruction::accounts::{ ClosePositionAccounts, Context }, - shared::{ DeserializedAccount, SplTokenTransferArgs }, + instruction::accounts::{ClosePositionAccounts, Context}, + shared::{DeserializedAccount, SplTokenTransferArgs}, }, - utils::{ solana_utils, solauto_utils }, + utils::{solana_utils, solauto_utils}, }; pub fn close_position_ta<'a>( ctx: &Context>, solauto_position: &DeserializedAccount<'a, SolautoPosition>, position_ta: &'a AccountInfo<'a>, - signer_ta: &'a AccountInfo<'a> + signer_ta: &'a AccountInfo<'a>, ) -> ProgramResult { let solauto_position_seeds = &solauto_position.data.seeds_with_bump(); - let position_ta_data = solauto_utils - ::safe_unpack_token_account(Some(position_ta))? - .unwrap().data; + let position_ta_data = solauto_utils::safe_unpack_token_account(Some(position_ta))? + .unwrap() + .data; if position_ta_data.amount > 0 && position_ta_data.mint != WSOL_MINT { - solana_utils::spl_token_transfer(ctx.accounts.token_program, SplTokenTransferArgs { - source: position_ta, - authority: solauto_position.account_info, - recipient: signer_ta, - amount: position_ta_data.amount, - authority_seeds: Some(solauto_position_seeds), - })?; + solana_utils::spl_token_transfer( + ctx.accounts.token_program, + SplTokenTransferArgs { + source: position_ta, + authority: solauto_position.account_info, + recipient: signer_ta, + amount: position_ta_data.amount, + authority_seeds: Some(solauto_position_seeds), + }, + )?; } solana_utils::close_token_account( @@ -36,25 +39,25 @@ pub fn close_position_ta<'a>( position_ta, ctx.accounts.signer, ctx.accounts.solauto_position, - Some(solauto_position_seeds) + Some(solauto_position_seeds), ) } pub fn close_position<'a>( ctx: &Context>, - solauto_position: &DeserializedAccount<'a, SolautoPosition> + solauto_position: &DeserializedAccount<'a, SolautoPosition>, ) -> ProgramResult { close_position_ta( ctx, solauto_position, ctx.accounts.position_supply_ta, - ctx.accounts.signer_supply_ta + ctx.accounts.signer_supply_ta, )?; close_position_ta( ctx, solauto_position, ctx.accounts.position_debt_ta, - ctx.accounts.signer_debt_ta + ctx.accounts.signer_debt_ta, )?; solana_utils::close_pda(ctx.accounts.solauto_position, ctx.accounts.signer) } diff --git a/programs/solauto/src/instructions/rebalance.rs b/programs/solauto/src/instructions/rebalance.rs index d097edf9..e78bc336 100644 --- a/programs/solauto/src/instructions/rebalance.rs +++ b/programs/solauto/src/instructions/rebalance.rs @@ -2,10 +2,7 @@ use std::ops::Sub; use marginfi_sdk::generated::accounts::Bank; use solana_program::{ - clock::Clock, - entrypoint::ProgramResult, - program_error::ProgramError, - pubkey::Pubkey, + clock::Clock, entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey, sysvar::Sysvar, }; @@ -17,13 +14,12 @@ use crate::{ types::{ errors::SolautoError, instruction::{ - accounts::{ Context, MarginfiRebalanceAccounts }, - RebalanceSettings, - SolautoStandardAccounts, + accounts::{Context, MarginfiRebalanceAccounts}, + RebalanceSettings, SolautoStandardAccounts, }, - lending_protocol::{ LendingProtocolClient, LendingProtocolTokenAccounts }, - shared::{ DeserializedAccount, RebalanceStep, SolautoRebalanceType, TokenType }, - solauto_manager::{ SolautoManager, SolautoManagerAccounts }, + lending_protocol::{LendingProtocolClient, LendingProtocolTokenAccounts}, + shared::{DeserializedAccount, RebalanceStep, SolautoRebalanceType, TokenType}, + solauto_manager::{SolautoManager, SolautoManagerAccounts}, }, utils::ix_utils, }; @@ -34,48 +30,46 @@ pub fn marginfi_rebalance<'a>( ctx: Context<'a, MarginfiRebalanceAccounts<'a>>, mut std_accounts: Box>, rebalance_step: RebalanceStep, - args: RebalanceSettings + args: RebalanceSettings, ) -> ProgramResult { let supply_tas = LendingProtocolTokenAccounts::from( None, Some(ctx.accounts.position_supply_ta), ctx.accounts.authority_supply_ta, - ctx.accounts.vault_supply_ta + ctx.accounts.vault_supply_ta, )?; let debt_tas = LendingProtocolTokenAccounts::from( None, Some(ctx.accounts.position_debt_ta), ctx.accounts.authority_debt_ta, - ctx.accounts.vault_debt_ta + ctx.accounts.vault_debt_ta, )?; - let marginfi_client = Box::new( - MarginfiClient::from( - ctx.accounts.signer, - ctx.accounts.marginfi_program, - ctx.accounts.marginfi_group, - ctx.accounts.marginfi_account, - ctx.accounts.supply_bank, - ctx.accounts.supply_price_oracle, - supply_tas.clone(), - ctx.accounts.supply_vault_authority, - ctx.accounts.debt_bank, - ctx.accounts.debt_price_oracle, - debt_tas.clone(), - ctx.accounts.debt_vault_authority - )? - ); - let solauto_manager_accounts = SolautoManagerAccounts::from( - supply_tas, - debt_tas, - ctx.accounts.intermediary_ta, - None - )?; - - let rebalance_type = std_accounts.solauto_position.data.rebalance.ixs.rebalance_type; - if - rebalance_step == RebalanceStep::PreSwap || - rebalance_type == SolautoRebalanceType::FLSwapThenRebalance + let marginfi_client = Box::new(MarginfiClient::from( + ctx.accounts.signer, + ctx.accounts.marginfi_program, + ctx.accounts.marginfi_group, + ctx.accounts.marginfi_account, + ctx.accounts.supply_bank, + ctx.accounts.supply_price_oracle, + supply_tas.clone(), + ctx.accounts.supply_vault_authority, + ctx.accounts.debt_bank, + ctx.accounts.debt_price_oracle, + debt_tas.clone(), + ctx.accounts.debt_vault_authority, + )?); + let solauto_manager_accounts = + SolautoManagerAccounts::from(supply_tas, debt_tas, ctx.accounts.intermediary_ta, None)?; + + let rebalance_type = std_accounts + .solauto_position + .data + .rebalance + .ixs + .rebalance_type; + if rebalance_step == RebalanceStep::PreSwap + || rebalance_type == SolautoRebalanceType::FLSwapThenRebalance { if needs_refresh(&std_accounts.solauto_position, &args)? { refresh::marginfi_refresh_accounts( @@ -87,41 +81,57 @@ pub fn marginfi_rebalance<'a>( ctx.accounts.debt_bank, ctx.accounts.debt_price_oracle.unwrap(), &mut std_accounts.solauto_position, - args.price_type.unwrap().clone() + args.price_type.unwrap().clone(), )?; } else { let supply_price = MarginfiClient::load_price( &DeserializedAccount::::zerocopy(Some(ctx.accounts.supply_bank))?.unwrap(), ctx.accounts.supply_price_oracle.unwrap(), args.price_type.unwrap().clone(), - TokenType::Supply + TokenType::Supply, )?; let debt_price = MarginfiClient::load_price( &DeserializedAccount::::zerocopy(Some(ctx.accounts.debt_bank))?.unwrap(), ctx.accounts.debt_price_oracle.unwrap(), args.price_type.unwrap().clone(), - TokenType::Debt + TokenType::Debt, )?; update_token_prices(&mut std_accounts, supply_price, debt_price); } } - rebalance(marginfi_client, solauto_manager_accounts, std_accounts, rebalance_step, args) + rebalance( + marginfi_client, + solauto_manager_accounts, + std_accounts, + rebalance_step, + args, + ) } fn update_token_prices<'a>( std_accounts: &mut Box>, supply_price: f64, - debt_price: f64 + debt_price: f64, ) { - std_accounts.solauto_position.data.state.supply.update_market_price(supply_price); - std_accounts.solauto_position.data.state.debt.update_market_price(debt_price); + std_accounts + .solauto_position + .data + .state + .supply + .update_market_price(supply_price); + std_accounts + .solauto_position + .data + .state + .debt + .update_market_price(debt_price); std_accounts.solauto_position.data.refresh_state(); } fn needs_refresh( solauto_position: &DeserializedAccount, - args: &RebalanceSettings + args: &RebalanceSettings, ) -> Result { if solauto_position.data.self_managed.val { return Ok(true); @@ -142,28 +152,44 @@ fn rebalance<'a>( solauto_manager_accounts: SolautoManagerAccounts<'a>, std_accounts: Box>, rebalance_step: RebalanceStep, - args: RebalanceSettings + args: RebalanceSettings, ) -> ProgramResult { check!( - args.target_liq_utilization_rate_bps.is_none() || - std_accounts.signer.key == &std_accounts.solauto_position.data.authority, + args.target_liq_utilization_rate_bps.is_none() + || std_accounts.signer.key == &std_accounts.solauto_position.data.authority, SolautoError::NonAuthorityProvidedTargetLTV ); - check!(std_accounts.authority_referral_state.is_some(), SolautoError::IncorrectAccounts); - check!(args.flash_loan_fee_bps.unwrap_or(0) <= 150, SolautoError::IncorrectInstructions); + check!( + std_accounts.authority_referral_state.is_some(), + SolautoError::IncorrectAccounts + ); + check!( + args.flash_loan_fee_bps.unwrap_or(0) <= 150, + SolautoError::IncorrectInstructions + ); let fees_bps = SolautoFeesBps::from( - std_accounts.authority_referral_state.as_ref().unwrap().data.referred_by_state != - Pubkey::default(), + std_accounts + .authority_referral_state + .as_ref() + .unwrap() + .data + .referred_by_state + != Pubkey::default(), args.target_liq_utilization_rate_bps, - std_accounts.solauto_position.data.state.net_worth.usd_value() + std_accounts + .solauto_position + .data + .state + .net_worth + .usd_value(), ); let mut solauto_manager = SolautoManager::from( client, solauto_manager_accounts, std_accounts, - Some(fees_bps) + Some(fees_bps), )?; solauto_manager.rebalance(args, rebalance_step)?; diff --git a/programs/solauto/src/instructions/referral_fees.rs b/programs/solauto/src/instructions/referral_fees.rs index f80808ad..3f3beb44 100644 --- a/programs/solauto/src/instructions/referral_fees.rs +++ b/programs/solauto/src/instructions/referral_fees.rs @@ -1,36 +1,39 @@ -use solana_program::{ entrypoint::ProgramResult, program_pack::Pack, rent::Rent, sysvar::Sysvar }; +use solana_program::{entrypoint::ProgramResult, program_pack::Pack, rent::Rent, sysvar::Sysvar}; use spl_token::state::Account as TokenAccount; use crate::{ constants::WSOL_MINT, state::referral_state::ReferralState, types::{ - instruction::accounts::{ ClaimReferralFeesAccounts, Context, ConvertReferralFeesAccounts }, - shared::{ DeserializedAccount, SplTokenTransferArgs }, + instruction::accounts::{ClaimReferralFeesAccounts, Context, ConvertReferralFeesAccounts}, + shared::{DeserializedAccount, SplTokenTransferArgs}, }, utils::solana_utils, }; pub fn convert_referral_fees( ctx: Context, - referral_state: DeserializedAccount + referral_state: DeserializedAccount, ) -> ProgramResult { let balance = TokenAccount::unpack(&ctx.accounts.referral_fees_ta.data.borrow())?.amount; - solana_utils::spl_token_transfer(ctx.accounts.token_program, SplTokenTransferArgs { - source: ctx.accounts.referral_fees_ta, - authority: ctx.accounts.referral_state, - recipient: ctx.accounts.intermediary_ta, - amount: balance, - authority_seeds: Some(&referral_state.data.seeds_with_bump()), - })?; + solana_utils::spl_token_transfer( + ctx.accounts.token_program, + SplTokenTransferArgs { + source: ctx.accounts.referral_fees_ta, + authority: ctx.accounts.referral_state, + recipient: ctx.accounts.intermediary_ta, + amount: balance, + authority_seeds: Some(&referral_state.data.seeds_with_bump()), + }, + )?; Ok(()) } pub fn claim_referral_fees( ctx: Context, - referral_state: DeserializedAccount + referral_state: DeserializedAccount, ) -> ProgramResult { let referral_state_seeds = &referral_state.data.seeds_with_bump(); @@ -42,25 +45,28 @@ pub fn claim_referral_fees( ctx.accounts.signer, ctx.accounts.signer, ctx.accounts.signer_wsol_ta.unwrap(), - ctx.accounts.referral_fees_dest_mint + ctx.accounts.referral_fees_dest_mint, )?; let rent = Rent::get()?; let account_rent = rent.minimum_balance(TokenAccount::LEN); - solana_utils::spl_token_transfer(ctx.accounts.token_program, SplTokenTransferArgs { - source: ctx.accounts.referral_fees_dest_ta, - authority: ctx.accounts.referral_state, - recipient: ctx.accounts.signer_wsol_ta.unwrap(), - amount: account_rent, - authority_seeds: Some(referral_state_seeds), - })?; + solana_utils::spl_token_transfer( + ctx.accounts.token_program, + SplTokenTransferArgs { + source: ctx.accounts.referral_fees_dest_ta, + authority: ctx.accounts.referral_state, + recipient: ctx.accounts.signer_wsol_ta.unwrap(), + amount: account_rent, + authority_seeds: Some(referral_state_seeds), + }, + )?; solana_utils::close_token_account( ctx.accounts.token_program, ctx.accounts.signer_wsol_ta.unwrap(), ctx.accounts.signer, ctx.accounts.signer, - None + None, )?; solana_utils::init_ata_if_needed( @@ -69,7 +75,7 @@ pub fn claim_referral_fees( ctx.accounts.signer, ctx.accounts.signer, ctx.accounts.signer_wsol_ta.unwrap(), - ctx.accounts.referral_fees_dest_mint + ctx.accounts.referral_fees_dest_mint, )?; } @@ -78,7 +84,7 @@ pub fn claim_referral_fees( ctx.accounts.referral_fees_dest_ta, ctx.accounts.referral_authority, ctx.accounts.referral_state, - Some(referral_state_seeds) + Some(referral_state_seeds), )?; solana_utils::init_ata_if_needed( @@ -87,7 +93,7 @@ pub fn claim_referral_fees( ctx.accounts.signer, ctx.accounts.referral_state, ctx.accounts.referral_fees_dest_ta, - ctx.accounts.referral_fees_dest_mint + ctx.accounts.referral_fees_dest_mint, )?; } else { solana_utils::init_ata_if_needed( @@ -96,20 +102,22 @@ pub fn claim_referral_fees( ctx.accounts.signer, ctx.accounts.referral_authority, ctx.accounts.fees_destination_ta.unwrap(), - ctx.accounts.referral_fees_dest_mint + ctx.accounts.referral_fees_dest_mint, )?; - let balance = TokenAccount::unpack( - &ctx.accounts.referral_fees_dest_ta.data.borrow() - )?.amount; + let balance = + TokenAccount::unpack(&ctx.accounts.referral_fees_dest_ta.data.borrow())?.amount; - solana_utils::spl_token_transfer(ctx.accounts.token_program, SplTokenTransferArgs { - source: ctx.accounts.referral_fees_dest_ta, - authority: ctx.accounts.referral_state, - recipient: ctx.accounts.fees_destination_ta.unwrap(), - amount: balance, - authority_seeds: Some(referral_state_seeds), - })?; + solana_utils::spl_token_transfer( + ctx.accounts.token_program, + SplTokenTransferArgs { + source: ctx.accounts.referral_fees_dest_ta, + authority: ctx.accounts.referral_state, + recipient: ctx.accounts.fees_destination_ta.unwrap(), + amount: balance, + authority_seeds: Some(referral_state_seeds), + }, + )?; } Ok(()) diff --git a/programs/solauto/src/processors/position.rs b/programs/solauto/src/processors/position.rs index c9d20fc9..d7fa466a 100644 --- a/programs/solauto/src/processors/position.rs +++ b/programs/solauto/src/processors/position.rs @@ -1,11 +1,11 @@ -use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, msg }; +use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, msg}; use crate::{ - instructions::{ close_position, update_position }, + instructions::{close_position, update_position}, state::solauto_position::SolautoPosition, types::{ instruction::{ - accounts::{ ClosePositionAccounts, UpdatePositionAccounts }, + accounts::{ClosePositionAccounts, UpdatePositionAccounts}, UpdatePositionData, }, shared::DeserializedAccount, @@ -15,13 +15,13 @@ use crate::{ pub fn process_update_position_instruction<'a>( accounts: &'a [AccountInfo<'a>], - args: UpdatePositionData + args: UpdatePositionData, ) -> ProgramResult { msg!("Instruction: Update position"); let ctx = UpdatePositionAccounts::context(accounts)?; - let solauto_position = DeserializedAccount:: - ::zerocopy(Some(ctx.accounts.solauto_position))? - .unwrap(); + let solauto_position = + DeserializedAccount::::zerocopy(Some(ctx.accounts.solauto_position))? + .unwrap(); validation_utils::validate_instruction(ctx.accounts.signer, &solauto_position, true, true)?; validation_utils::validate_standard_programs( @@ -29,7 +29,7 @@ pub fn process_update_position_instruction<'a>( Some(ctx.accounts.token_program), None, None, - None + None, )?; if args.dca.is_some() { @@ -37,7 +37,7 @@ pub fn process_update_position_instruction<'a>( &solauto_position, ctx.accounts.position_dca_ta, Some(args.dca.as_ref().unwrap().token_type), - None + None, )?; } @@ -47,9 +47,9 @@ pub fn process_update_position_instruction<'a>( pub fn process_close_position_instruction<'a>(accounts: &'a [AccountInfo<'a>]) -> ProgramResult { msg!("Instruction: Close position"); let ctx = ClosePositionAccounts::context(accounts)?; - let solauto_position = DeserializedAccount:: - ::zerocopy(Some(ctx.accounts.solauto_position))? - .unwrap(); + let solauto_position = + DeserializedAccount::::zerocopy(Some(ctx.accounts.solauto_position))? + .unwrap(); validation_utils::validate_instruction(ctx.accounts.signer, &solauto_position, true, true)?; validation_utils::validate_standard_programs( @@ -57,25 +57,25 @@ pub fn process_close_position_instruction<'a>(accounts: &'a [AccountInfo<'a>]) - Some(ctx.accounts.token_program), Some(ctx.accounts.ata_program), None, - None + None, )?; validation_utils::validate_token_accounts( &solauto_position, Some(ctx.accounts.position_supply_ta), - Some(ctx.accounts.position_debt_ta) + Some(ctx.accounts.position_debt_ta), )?; validation_utils::validate_token_accounts( &solauto_position, Some(ctx.accounts.signer_supply_ta), - Some(ctx.accounts.signer_debt_ta) + Some(ctx.accounts.signer_debt_ta), )?; if !cfg!(feature = "local") { validation_utils::validate_no_active_balances( ctx.accounts.lp_user_account, - solauto_position.data.position.lending_platform + solauto_position.data.position.lending_platform, )?; } diff --git a/programs/solauto/src/rebalance/rebalancer.rs b/programs/solauto/src/rebalance/rebalancer.rs index 4b7269af..565390d5 100644 --- a/programs/solauto/src/rebalance/rebalancer.rs +++ b/programs/solauto/src/rebalance/rebalancer.rs @@ -1,43 +1,34 @@ -use std::{ cmp::min, ops::{ Add, Mul } }; +use std::{ + cmp::min, + ops::{Add, Mul}, +}; -use solana_program::{ entrypoint::ProgramResult, program_error::ProgramError }; +use solana_program::{entrypoint::ProgramResult, program_error::ProgramError}; use crate::{ check, state::solauto_position::{ - PositionTokenState, - RebalanceData, - SolautoPosition, - TokenBalanceChangeType, + PositionTokenState, RebalanceData, SolautoPosition, TokenBalanceChangeType, }, types::{ errors::SolautoError, instruction::RebalanceSettings, shared::{ - RebalanceDirection, - RebalanceStep, - SolautoRebalanceType, - SwapType, - TokenBalanceAmount, + RebalanceDirection, RebalanceStep, SolautoRebalanceType, SwapType, TokenBalanceAmount, }, solauto::{ - FromLendingPlatformAction, - SolautoAccount, - SolautoCpiAction, + FromLendingPlatformAction, SolautoAccount, SolautoCpiAction, SolautoSplTokenTransferArgs, }, }, utils::math_utils::{ - calc_fee_amount, - from_bps, - from_rounded_usd_value, - usd_value_to_base_unit, + calc_fee_amount, from_bps, from_rounded_usd_value, usd_value_to_base_unit, }, }; use super::{ solauto_fees::SolautoFeesBps, - utils::{ eligible_for_rebalance, get_rebalance_values }, + utils::{eligible_for_rebalance, get_rebalance_values}, }; pub struct TokenAccountData { @@ -116,15 +107,18 @@ impl<'a> Rebalancer<'a> { } check!( - self.data.rebalance_args.target_liq_utilization_rate_bps.is_some() || - eligible_for_rebalance(self.position_data()), + self.data + .rebalance_args + .target_liq_utilization_rate_bps + .is_some() + || eligible_for_rebalance(self.position_data()), SolautoError::InvalidRebalanceCondition ); self.data.solauto_position.data.rebalance.values = get_rebalance_values( self.position_data(), &self.data.rebalance_args, - &self.data.solauto_fees_bps + &self.data.solauto_fees_bps, )?; Ok(()) @@ -134,12 +128,12 @@ impl<'a> Rebalancer<'a> { &self, rounded_usd_value: u64, token_usage: PositionTokenState, - max: Option + max: Option, ) -> u64 { let base_unit_amount = usd_value_to_base_unit( from_rounded_usd_value(rounded_usd_value), token_usage.decimals, - token_usage.market_price() + token_usage.market_price(), ); if max.is_some() { @@ -151,9 +145,15 @@ impl<'a> Rebalancer<'a> { fn get_dynamic_balance(&self) -> (u64, SolautoAccount) { let (ta, account) = if self.is_boost() { - (self.position_supply_ta(), SolautoAccount::SolautoPositionSupplyTa) + ( + self.position_supply_ta(), + SolautoAccount::SolautoPositionSupplyTa, + ) } else { - (self.position_debt_ta(), SolautoAccount::SolautoPositionDebtTa) + ( + self.position_debt_ta(), + SolautoAccount::SolautoPositionDebtTa, + ) }; let balance = ta.balance; @@ -165,36 +165,40 @@ impl<'a> Rebalancer<'a> { fn transfer_to_authority_if_needed(&mut self, base_unit_amount: u64) { if self.position_data().self_managed.val { let (solauto_position_ta, authority_ta) = if self.is_boost() { - (SolautoAccount::SolautoPositionSupplyTa, SolautoAccount::AuthoritySupplyTa) + ( + SolautoAccount::SolautoPositionSupplyTa, + SolautoAccount::AuthoritySupplyTa, + ) } else { - (SolautoAccount::SolautoPositionDebtTa, SolautoAccount::AuthorityDebtTa) + ( + SolautoAccount::SolautoPositionDebtTa, + SolautoAccount::AuthorityDebtTa, + ) }; - self.actions.push( - SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { + self.actions.push(SolautoCpiAction::SplTokenTransfer( + SolautoSplTokenTransferArgs { from_wallet: SolautoAccount::SolautoPosition, from_wallet_ta: solauto_position_ta, to_wallet_ta: authority_ta, amount: base_unit_amount, - }) - ); + }, + )); } } fn pull_liquidity_from_lp(&mut self, base_unit_amount: u64, destination_ta: SolautoAccount) { if self.is_boost() { - self.actions.push( - SolautoCpiAction::Borrow(FromLendingPlatformAction { + self.actions + .push(SolautoCpiAction::Borrow(FromLendingPlatformAction { amount: base_unit_amount, to_wallet_ta: destination_ta, - }) - ); + })); } else { - self.actions.push( - SolautoCpiAction::Withdraw(FromLendingPlatformAction { + self.actions + .push(SolautoCpiAction::Withdraw(FromLendingPlatformAction { amount: TokenBalanceAmount::Some(base_unit_amount), to_wallet_ta: destination_ta, - }) - ); + })); } } @@ -202,24 +206,40 @@ impl<'a> Rebalancer<'a> { self.transfer_to_authority_if_needed(base_unit_amount); if self.is_boost() { - self.actions.push(SolautoCpiAction::Deposit(base_unit_amount)); + self.actions + .push(SolautoCpiAction::Deposit(base_unit_amount)); } else { - let token_balance_amount = if - self.data.rebalance_args.target_liq_utilization_rate_bps.is_some() && - self.data.rebalance_args.target_liq_utilization_rate_bps.unwrap() == 0 + let token_balance_amount = if self + .data + .rebalance_args + .target_liq_utilization_rate_bps + .is_some() + && self + .data + .rebalance_args + .target_liq_utilization_rate_bps + .unwrap() + == 0 { TokenBalanceAmount::All } else { - TokenBalanceAmount::Some( - min(self.position_data().state.debt.amount_used.base_unit, base_unit_amount) - ) + TokenBalanceAmount::Some(min( + self.position_data().state.debt.amount_used.base_unit, + base_unit_amount, + )) }; - self.actions.push(SolautoCpiAction::Repay(token_balance_amount)); + self.actions + .push(SolautoCpiAction::Repay(token_balance_amount)); } } fn get_additional_amount_before_swap(&mut self) -> u64 { - if !self.rebalance_data().values.token_balance_change.requires_one() { + if !self + .rebalance_data() + .values + .token_balance_change + .requires_one() + { return 0; } @@ -228,45 +248,41 @@ impl<'a> Rebalancer<'a> { let action = match token_balance_change.change_type { TokenBalanceChangeType::PreSwapDeposit => { - Some( - SolautoCpiAction::Deposit( - self.calc_additional_amount( - token_balance_change.amount_usd, - self.position_data().state.supply, - Some(self.data.solauto_position.supply_ta.balance) - ) - ) - ) + Some(SolautoCpiAction::Deposit(self.calc_additional_amount( + token_balance_change.amount_usd, + self.position_data().state.supply, + Some(self.data.solauto_position.supply_ta.balance), + ))) } TokenBalanceChangeType::PostSwapDeposit => { amount = self.calc_additional_amount( token_balance_change.amount_usd, self.position_data().state.debt, - Some(self.data.solauto_position.debt_ta.balance) + Some(self.data.solauto_position.debt_ta.balance), ); - Some( - SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { + Some(SolautoCpiAction::SplTokenTransfer( + SolautoSplTokenTransferArgs { amount, from_wallet: SolautoAccount::SolautoPosition, from_wallet_ta: SolautoAccount::SolautoPositionDebtTa, to_wallet_ta: SolautoAccount::IntermediaryTa, - }) - ) + }, + )) } TokenBalanceChangeType::PostRebalanceWithdrawDebtToken => { amount = self.calc_additional_amount( token_balance_change.amount_usd, self.position_data().state.supply, - Some(self.position_supply_ta().balance) + Some(self.position_supply_ta().balance), ); - Some( - SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { + Some(SolautoCpiAction::SplTokenTransfer( + SolautoSplTokenTransferArgs { amount, from_wallet: SolautoAccount::SolautoPosition, from_wallet_ta: SolautoAccount::SolautoPositionSupplyTa, to_wallet_ta: SolautoAccount::IntermediaryTa, - }) - ) + }, + )) } _ => None, }; @@ -279,7 +295,12 @@ impl<'a> Rebalancer<'a> { } fn get_additional_amount_after_swap(&mut self) -> u64 { - if !self.rebalance_data().values.token_balance_change.requires_one() { + if !self + .rebalance_data() + .values + .token_balance_change + .requires_one() + { return 0; } @@ -291,31 +312,31 @@ impl<'a> Rebalancer<'a> { amount = self.calc_additional_amount( token_balance_change.amount_usd, self.position_data().state.supply, - None + None, ); - Some( - SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { + Some(SolautoCpiAction::SplTokenTransfer( + SolautoSplTokenTransferArgs { amount, from_wallet: SolautoAccount::SolautoPosition, from_wallet_ta: SolautoAccount::SolautoPositionSupplyTa, to_wallet_ta: SolautoAccount::AuthoritySupplyTa, // TODO: what if this is native mint - }) - ) + }, + )) } TokenBalanceChangeType::PostRebalanceWithdrawDebtToken => { amount = self.calc_additional_amount( token_balance_change.amount_usd, self.position_data().state.debt, - None + None, ); - Some( - SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { + Some(SolautoCpiAction::SplTokenTransfer( + SolautoSplTokenTransferArgs { amount, from_wallet: SolautoAccount::SolautoPosition, from_wallet_ta: SolautoAccount::SolautoPositionDebtTa, to_wallet_ta: SolautoAccount::AuthorityDebtTa, // TODO: what if this is native mint - }) - ) + }, + )) } _ => None, }; @@ -332,17 +353,17 @@ impl<'a> Rebalancer<'a> { available_balance: u64, fee_pct_bps: u16, position_ta: SolautoAccount, - destination_ta: SolautoAccount + destination_ta: SolautoAccount, ) -> Result { let fee_amount = calc_fee_amount(available_balance, fee_pct_bps); - self.actions.push( - SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { + self.actions.push(SolautoCpiAction::SplTokenTransfer( + SolautoSplTokenTransferArgs { from_wallet: SolautoAccount::SolautoPosition, from_wallet_ta: position_ta, to_wallet_ta: destination_ta, amount: fee_amount, - }) - ); + }, + )); Ok(fee_amount) } @@ -363,7 +384,7 @@ impl<'a> Rebalancer<'a> { available_balance, fee_payout.solauto, position_ta, - SolautoAccount::SolautoFeesTa + SolautoAccount::SolautoFeesTa, )?; let referrer_fees = if self.data.referred_by { @@ -371,7 +392,7 @@ impl<'a> Rebalancer<'a> { available_balance, fee_payout.referrer, position_ta, - SolautoAccount::ReferredByTa + SolautoAccount::ReferredByTa, )? } else { 0 @@ -381,14 +402,12 @@ impl<'a> Rebalancer<'a> { } fn repay_flash_loan_if_necessary(&mut self) -> ProgramResult { - if - matches!( - self.rebalance_data().ixs.rebalance_type, - SolautoRebalanceType::DoubleRebalanceWithFL | - SolautoRebalanceType::FLRebalanceThenSwap | - SolautoRebalanceType::FLSwapThenRebalance - ) - { + if matches!( + self.rebalance_data().ixs.rebalance_type, + SolautoRebalanceType::DoubleRebalanceWithFL + | SolautoRebalanceType::FLRebalanceThenSwap + | SolautoRebalanceType::FLSwapThenRebalance + ) { let flash_loan_amount = self.rebalance_data().ixs.flash_loan_amount; let fl_repay_amount = if self.rebalance_data().ixs.swap_type == SwapType::ExactOut { @@ -397,7 +416,9 @@ impl<'a> Rebalancer<'a> { check!(flash_loan_amount != 0, SolautoError::IncorrectInstructions); let flash_loan_fee_bps = self.data.rebalance_args.flash_loan_fee_bps.unwrap_or(0); flash_loan_amount.add( - (flash_loan_amount as f64).mul(from_bps(flash_loan_fee_bps)).ceil() as u64 + (flash_loan_amount as f64) + .mul(from_bps(flash_loan_fee_bps)) + .ceil() as u64, ) }; @@ -439,14 +460,14 @@ impl<'a> Rebalancer<'a> { let balance_leftover = dynamic_balance - additional_amount_after_swap; if self.rebalance_data().ixs.swap_type == SwapType::ExactOut { - self.actions.push( - SolautoCpiAction::SplTokenTransfer(SolautoSplTokenTransferArgs { + self.actions.push(SolautoCpiAction::SplTokenTransfer( + SolautoSplTokenTransferArgs { from_wallet: SolautoAccount::SolautoPosition, from_wallet_ta: balance_ta, to_wallet_ta: SolautoAccount::IntermediaryTa, amount: balance_leftover, - }) - ); + }, + )); } else { self.finish_rebalance(balance_leftover)?; } @@ -456,7 +477,7 @@ impl<'a> Rebalancer<'a> { pub fn rebalance( &mut self, - rebalance_step: RebalanceStep + rebalance_step: RebalanceStep, ) -> Result { match rebalance_step { RebalanceStep::PreSwap => self.pre_swap_rebalance(), diff --git a/programs/solauto/src/rebalance/rebalancer_tests.rs b/programs/solauto/src/rebalance/rebalancer_tests.rs index 34ce628b..ed315258 100644 --- a/programs/solauto/src/rebalance/rebalancer_tests.rs +++ b/programs/solauto/src/rebalance/rebalancer_tests.rs @@ -1,36 +1,24 @@ -use std::ops::{ Div, Mul }; +use std::ops::{Div, Mul}; use solana_program::pubkey::Pubkey; use crate::{ state::solauto_position::{ - PositionData, - PositionState, - RebalanceData, - SolautoPosition, - SolautoSettingsParameters, + PositionData, PositionState, RebalanceData, SolautoPosition, SolautoSettingsParameters, SolautoSettingsParametersInp, }, types::{ instruction::RebalanceSettings, shared::{ - PodBool, - PositionType, - RebalanceDirection, - RefreshedTokenState, - SwapType, + PodBool, PositionType, RebalanceDirection, RefreshedTokenState, SwapType, TokenBalanceAmount, }, - solauto::{ PositionValues, SolautoAccount, SolautoCpiAction }, + solauto::{PositionValues, SolautoAccount, SolautoCpiAction}, }, utils::{ math_utils::{ - from_base_unit, - from_bps, - from_rounded_usd_value, - get_liq_utilization_rate_bps, - round_to_decimals, - to_base_unit, + from_base_unit, from_bps, from_rounded_usd_value, get_liq_utilization_rate_bps, + round_to_decimals, to_base_unit, }, solauto_utils::update_token_state, validation_utils, @@ -38,7 +26,7 @@ use crate::{ }; use super::{ - rebalancer::{ Rebalancer, RebalancerData, SolautoPositionData, TokenAccountData }, + rebalancer::{Rebalancer, RebalancerData, SolautoPositionData, TokenAccountData}, solauto_fees::SolautoFeesBps, }; @@ -65,7 +53,7 @@ fn create_position<'a>(pos: &FakePosition<'a>) -> Box { state.liq_utilization_rate_bps = get_liq_utilization_rate_bps( pos.values.supply_usd, pos.values.debt_usd, - from_bps(state.liq_threshold_bps) + from_bps(state.liq_threshold_bps), ); let supply_mint = Pubkey::new_unique(); @@ -82,7 +70,7 @@ fn create_position<'a>(pos: &FakePosition<'a>) -> Box { decimals: TEST_TOKEN_DECIMALS, market_price: SUPPLY_PRICE, borrow_fee_bps: None, - }) + }), ); update_token_state( &mut state.debt, @@ -93,7 +81,7 @@ fn create_position<'a>(pos: &FakePosition<'a>) -> Box { decimals: TEST_TOKEN_DECIMALS, market_price: DEBT_PRICE, borrow_fee_bps: Some(BORROW_FEE_BPS), - }) + }), ); let mut position_data = PositionData::default(); @@ -104,7 +92,7 @@ fn create_position<'a>(pos: &FakePosition<'a>) -> Box { Pubkey::new_unique(), PositionType::Leverage, position_data, - state + state, ); Box::new(position) @@ -120,7 +108,7 @@ pub struct FakeRebalance<'a> { fn create_rebalancer<'a>( data: FakeRebalance<'a>, rebalance_args: RebalanceSettings, - flash_loan_amount: Option + flash_loan_amount: Option, ) -> Rebalancer<'a> { data.pos.rebalance.ixs.rebalance_type = rebalance_args.rebalance_type; data.pos.rebalance.ixs.flash_loan_amount = flash_loan_amount.unwrap_or(0); @@ -147,7 +135,7 @@ fn credit_token_account<'a>( rebalancer: &mut Rebalancer<'a>, ta_creditor: &mut TaCreditor, ta_pk: SolautoAccount, - base_unit_amount: i64 + base_unit_amount: i64, ) { let credit_ta = |ta: &mut TokenAccountData| { println!("Crediting token account with {}", base_unit_amount); @@ -180,56 +168,90 @@ fn apply_actions<'a>(rebalancer: &mut Rebalancer<'a>, ta_creditor: &mut TaCredit match action { SolautoCpiAction::Deposit(amount) => { println!("Deposit {}", amount); - rebalancer.data.solauto_position.data.state.supply.update_usage(amount as i64); + rebalancer + .data + .solauto_position + .data + .state + .supply + .update_usage(amount as i64); credit_token_account( rebalancer, ta_creditor, SolautoAccount::SolautoPositionSupplyTa, - (amount as i64) * -1 + (amount as i64) * -1, ); } SolautoCpiAction::Withdraw(data) => { let base_unit_amount = if let TokenBalanceAmount::Some(amount) = data.amount { amount } else { - rebalancer.data.solauto_position.data.state.supply.amount_used.base_unit + rebalancer + .data + .solauto_position + .data + .state + .supply + .amount_used + .base_unit }; println!("Withdraw {}", base_unit_amount); - rebalancer.data.solauto_position.data.state.supply.update_usage( - (base_unit_amount as i64) * -1 - ); + rebalancer + .data + .solauto_position + .data + .state + .supply + .update_usage((base_unit_amount as i64) * -1); credit_token_account( rebalancer, ta_creditor, data.to_wallet_ta, - base_unit_amount as i64 + base_unit_amount as i64, ); } SolautoCpiAction::Borrow(data) => { println!("Borrow {}", data.amount); - rebalancer.data.solauto_position.data.state.debt.update_usage(data.amount as i64); + rebalancer + .data + .solauto_position + .data + .state + .debt + .update_usage(data.amount as i64); credit_token_account( rebalancer, ta_creditor, data.to_wallet_ta, - data.amount as i64 + data.amount as i64, ); } SolautoCpiAction::Repay(data) => { let base_unit_amount = if let TokenBalanceAmount::Some(amount) = data { amount } else { - rebalancer.data.solauto_position.data.state.debt.amount_used.base_unit + rebalancer + .data + .solauto_position + .data + .state + .debt + .amount_used + .base_unit }; println!("Repay {}", base_unit_amount); - rebalancer.data.solauto_position.data.state.debt.update_usage( - (base_unit_amount as i64) * -1 - ); + rebalancer + .data + .solauto_position + .data + .state + .debt + .update_usage((base_unit_amount as i64) * -1); credit_token_account( rebalancer, ta_creditor, SolautoAccount::SolautoPositionDebtTa, - (base_unit_amount as i64) * -1 + (base_unit_amount as i64) * -1, ); } SolautoCpiAction::SplTokenTransfer(args) => { @@ -238,13 +260,13 @@ fn apply_actions<'a>(rebalancer: &mut Rebalancer<'a>, ta_creditor: &mut TaCredit rebalancer, ta_creditor, args.from_wallet_ta, - (args.amount as i64) * -1 + (args.amount as i64) * -1, ); credit_token_account( rebalancer, ta_creditor, args.to_wallet_ta, - args.amount as i64 + args.amount as i64, ); } } @@ -257,7 +279,7 @@ fn perform_swap<'a>( rebalancer: &mut Rebalancer<'a>, ta_creditor: &mut TaCreditor, rebalance_direction: &RebalanceDirection, - to_solauto_position_ta: bool + to_solauto_position_ta: bool, ) -> u64 { let (input_price, output_price) = if rebalance_direction == &RebalanceDirection::Boost { (DEBT_PRICE, SUPPLY_PRICE) @@ -265,19 +287,16 @@ fn perform_swap<'a>( (SUPPLY_PRICE, DEBT_PRICE) }; - let swap_usd_value = from_base_unit::( - ta_creditor.intermediary_ta.balance, - TEST_TOKEN_DECIMALS - ).mul(input_price); + let swap_usd_value = + from_base_unit::(ta_creditor.intermediary_ta.balance, TEST_TOKEN_DECIMALS) + .mul(input_price); println!("Swapping ${}", swap_usd_value); ta_creditor.intermediary_ta.balance = 0; - let output_amount = to_base_unit::( - swap_usd_value.div(output_price), - TEST_TOKEN_DECIMALS - ); + let output_amount = + to_base_unit::(swap_usd_value.div(output_price), TEST_TOKEN_DECIMALS); if to_solauto_position_ta { if rebalance_direction == &RebalanceDirection::Boost { @@ -285,14 +304,14 @@ fn perform_swap<'a>( rebalancer, ta_creditor, SolautoAccount::SolautoPositionSupplyTa, - output_amount as i64 + output_amount as i64, ); } else { credit_token_account( rebalancer, ta_creditor, SolautoAccount::SolautoPositionDebtTa, - output_amount as i64 + output_amount as i64, ); } } @@ -304,12 +323,25 @@ fn validate_rebalance<'a>(rebalancer: &mut Rebalancer<'a>) { assert_eq!( round_to_decimals( from_rounded_usd_value( - rebalancer.data.solauto_position.data.rebalance.values.target_debt_usd + rebalancer + .data + .solauto_position + .data + .rebalance + .values + .target_debt_usd ), 4 ), round_to_decimals( - rebalancer.data.solauto_position.data.state.debt.amount_used.usd_value(), + rebalancer + .data + .solauto_position + .data + .state + .debt + .amount_used + .usd_value(), 4 ), "Incorrect debt usd. Expected (left) vs. actual (right)" @@ -317,12 +349,25 @@ fn validate_rebalance<'a>(rebalancer: &mut Rebalancer<'a>) { assert_eq!( round_to_decimals( from_rounded_usd_value( - rebalancer.data.solauto_position.data.rebalance.values.target_supply_usd + rebalancer + .data + .solauto_position + .data + .rebalance + .values + .target_supply_usd ), 4 ), round_to_decimals( - rebalancer.data.solauto_position.data.state.supply.amount_used.usd_value(), + rebalancer + .data + .solauto_position + .data + .state + .supply + .amount_used + .usd_value(), 4 ), "Incorrect supply usd. Expected (left) vs. actual (right)" @@ -348,14 +393,14 @@ impl TaCreditor { } mod tests { - use std::ops::{ Add, Div }; + use std::ops::{Add, Div}; use crate::{ types::{ - shared::{ RebalanceStep, SolautoRebalanceType, SwapType }, + shared::{RebalanceStep, SolautoRebalanceType, SwapType}, solauto::RebalanceFeesBps, }, - utils::math_utils::{ get_debt_adjustment, get_max_boost_to_bps, get_max_repay_to_bps }, + utils::math_utils::{get_debt_adjustment, get_max_boost_to_bps, get_max_repay_to_bps}, }; use super::*; @@ -381,7 +426,7 @@ mod tests { settings, max_ltv_bps: Some(MAX_LTV_BPS), liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), - }) + }), ); let debt_adjustment = get_debt_adjustment( LIQ_THRESHOLD_BPS, @@ -391,17 +436,15 @@ mod tests { solauto: SOLAUTO_FEE_BPS, lp_borrow: BORROW_FEE_BPS, flash_loan: 0, - }) + }), ); let rebalance_args = RebalanceSettings { rebalance_type: SolautoRebalanceType::Regular, target_liq_utilization_rate_bps: None, - swap_in_amount_base_unit: Some( - to_base_unit( - debt_adjustment.debt_adjustment_usd.div(DEBT_PRICE), - TEST_TOKEN_DECIMALS - ) - ), + swap_in_amount_base_unit: Some(to_base_unit( + debt_adjustment.debt_adjustment_usd.div(DEBT_PRICE), + TEST_TOKEN_DECIMALS, + )), flash_loan_fee_bps: None, swap_type: Some(SwapType::ExactIn), price_type: None, @@ -414,7 +457,7 @@ mod tests { rebalance_direction: rebalance_direction.clone(), }, rebalance_args, - None + None, ); let ta_creditor = &mut TaCreditor::new(); @@ -452,7 +495,7 @@ mod tests { settings, max_ltv_bps: Some(MAX_LTV_BPS), liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), - }) + }), ); let debt_adjustment = get_debt_adjustment( LIQ_THRESHOLD_BPS, @@ -462,17 +505,15 @@ mod tests { solauto: SOLAUTO_FEE_BPS, lp_borrow: BORROW_FEE_BPS, flash_loan: 0, - }) + }), ); let rebalance_args = RebalanceSettings { rebalance_type: SolautoRebalanceType::Regular, target_liq_utilization_rate_bps: None, - swap_in_amount_base_unit: Some( - to_base_unit( - debt_adjustment.debt_adjustment_usd.abs().div(SUPPLY_PRICE), - TEST_TOKEN_DECIMALS - ) - ), + swap_in_amount_base_unit: Some(to_base_unit( + debt_adjustment.debt_adjustment_usd.abs().div(SUPPLY_PRICE), + TEST_TOKEN_DECIMALS, + )), flash_loan_fee_bps: None, swap_type: Some(SwapType::ExactIn), price_type: None, @@ -485,7 +526,7 @@ mod tests { rebalance_direction: rebalance_direction.clone(), }, rebalance_args, - None + None, ); let ta_creditor = &mut TaCreditor::new(); @@ -530,7 +571,7 @@ mod tests { settings, max_ltv_bps: Some(MAX_LTV_BPS), liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), - }) + }), ); let debt_adjustment = get_debt_adjustment( @@ -541,11 +582,11 @@ mod tests { solauto: SOLAUTO_FEE_BPS, lp_borrow: BORROW_FEE_BPS, flash_loan: FLASH_LOAN_FEE_BPS, - }) + }), ); let flash_borrow = to_base_unit( debt_adjustment.debt_adjustment_usd.abs().div(DEBT_PRICE), - TEST_TOKEN_DECIMALS + TEST_TOKEN_DECIMALS, ); let rebalance_args = RebalanceSettings { @@ -564,7 +605,7 @@ mod tests { rebalance_direction: rebalance_direction.clone(), }, rebalance_args, - Some(flash_borrow) + Some(flash_borrow), ); let ta_creditor = &mut TaCreditor::new(); @@ -572,7 +613,7 @@ mod tests { rebalancer, ta_creditor, SolautoAccount::IntermediaryTa, - flash_borrow as i64 + flash_borrow as i64, ); perform_swap(rebalancer, ta_creditor, &rebalance_direction, true); @@ -605,7 +646,7 @@ mod tests { settings, max_ltv_bps: Some(MAX_LTV_BPS), liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), - }) + }), ); let debt_adjustment = get_debt_adjustment( @@ -616,11 +657,11 @@ mod tests { solauto: SOLAUTO_FEE_BPS, lp_borrow: BORROW_FEE_BPS, flash_loan: FLASH_LOAN_FEE_BPS, - }) + }), ); let flash_borrow = to_base_unit( debt_adjustment.debt_adjustment_usd.abs().div(SUPPLY_PRICE), - TEST_TOKEN_DECIMALS + TEST_TOKEN_DECIMALS, ); let rebalance_args = RebalanceSettings { @@ -639,7 +680,7 @@ mod tests { rebalance_direction: rebalance_direction.clone(), }, rebalance_args, - Some(flash_borrow) + Some(flash_borrow), ); let ta_creditor = &mut TaCreditor::new(); @@ -647,7 +688,7 @@ mod tests { rebalancer, ta_creditor, SolautoAccount::IntermediaryTa, - flash_borrow as i64 + flash_borrow as i64, ); perform_swap(rebalancer, ta_creditor, &rebalance_direction, true); @@ -682,7 +723,7 @@ mod tests { settings, max_ltv_bps: Some(MAX_LTV_BPS), liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), - }) + }), ); let debt_adjustment = get_debt_adjustment( @@ -693,19 +734,17 @@ mod tests { solauto: SOLAUTO_FEE_BPS, lp_borrow: BORROW_FEE_BPS, flash_loan: 0, - }) + }), ); println!("{}", debt_adjustment.debt_adjustment_usd.abs()); let rebalance_args = RebalanceSettings { rebalance_type: SolautoRebalanceType::FLRebalanceThenSwap, target_liq_utilization_rate_bps: None, - swap_in_amount_base_unit: Some( - to_base_unit( - debt_adjustment.debt_adjustment_usd.abs().div(SUPPLY_PRICE), - TEST_TOKEN_DECIMALS - ) - ), + swap_in_amount_base_unit: Some(to_base_unit( + debt_adjustment.debt_adjustment_usd.abs().div(SUPPLY_PRICE), + TEST_TOKEN_DECIMALS, + )), flash_loan_fee_bps: None, swap_type: Some(SwapType::ExactOut), price_type: None, @@ -718,19 +757,19 @@ mod tests { rebalance_direction: rebalance_direction.clone(), }, rebalance_args, - None + None, ); let ta_creditor = &mut TaCreditor::new(); let flash_borrow = to_base_unit( debt_adjustment.debt_adjustment_usd.abs().div(DEBT_PRICE), - TEST_TOKEN_DECIMALS + TEST_TOKEN_DECIMALS, ); credit_token_account( rebalancer, ta_creditor, SolautoAccount::SolautoPositionDebtTa, - flash_borrow + flash_borrow, ); let res = rebalancer.rebalance(RebalanceStep::PreSwap); @@ -769,7 +808,7 @@ mod tests { settings, max_ltv_bps: Some(MAX_LTV_BPS), liq_threshold_bps: Some(LIQ_THRESHOLD_BPS), - }) + }), ); let debt_adjustment = get_debt_adjustment( LIQ_THRESHOLD_BPS, @@ -779,17 +818,15 @@ mod tests { solauto: SOLAUTO_FEE_BPS, lp_borrow: BORROW_FEE_BPS, flash_loan: 0, - }) + }), ); let rebalance_args = RebalanceSettings { rebalance_type: SolautoRebalanceType::Regular, target_liq_utilization_rate_bps: Some(rebalance_to), - swap_in_amount_base_unit: Some( - to_base_unit( - debt_adjustment.debt_adjustment_usd.div(DEBT_PRICE), - TEST_TOKEN_DECIMALS - ) - ), + swap_in_amount_base_unit: Some(to_base_unit( + debt_adjustment.debt_adjustment_usd.div(DEBT_PRICE), + TEST_TOKEN_DECIMALS, + )), flash_loan_fee_bps: None, swap_type: Some(SwapType::ExactIn), price_type: None, @@ -802,7 +839,7 @@ mod tests { rebalance_direction: rebalance_direction.clone(), }, rebalance_args, - None + None, ); let ta_creditor = &mut TaCreditor::new(); diff --git a/programs/solauto/src/types/shared.rs b/programs/solauto/src/types/shared.rs index 45557d3b..1212defd 100644 --- a/programs/solauto/src/types/shared.rs +++ b/programs/solauto/src/types/shared.rs @@ -1,4 +1,4 @@ -use borsh::{ BorshDeserialize, BorshSerialize }; +use borsh::{BorshDeserialize, BorshSerialize}; use bytemuck::AnyBitPattern; use bytemuck::Pod; use bytemuck::Zeroable; @@ -8,7 +8,7 @@ use solana_program::pubkey::Pubkey; use solana_program::{ account_info::AccountInfo, program_error::ProgramError, - program_pack::{ IsInitialized, Pack }, + program_pack::{IsInitialized, Pack}, }; use std::fmt; @@ -153,13 +153,10 @@ pub struct DeserializedAccount<'a, T> { impl<'a, T: AnyBitPattern> DeserializedAccount<'a, T> { pub fn zerocopy(account: Option<&'a AccountInfo<'a>>) -> Result, ProgramError> { match account { - Some(account_info) => - Ok( - Some(Self { - account_info, - data: Box::new(*bytemuck::from_bytes::(&account_info.data.borrow())), - }) - ), + Some(account_info) => Ok(Some(Self { + account_info, + data: Box::new(*bytemuck::from_bytes::(&account_info.data.borrow())), + })), None => Ok(None), } } @@ -173,12 +170,10 @@ impl<'a, T: Pack + IsInitialized> DeserializedAccount<'a, T> { msg!("Failed to deserialize account data"); SolautoError::FailedAccountDeserialization })?; - Ok( - Some(Self { - account_info, - data: Box::new(deserialized_data), - }) - ) + Ok(Some(Self { + account_info, + data: Box::new(deserialized_data), + })) } None => Ok(None), } diff --git a/programs/solauto/src/types/solauto.rs b/programs/solauto/src/types/solauto.rs index f7f76979..f7aa5398 100644 --- a/programs/solauto/src/types/solauto.rs +++ b/programs/solauto/src/types/solauto.rs @@ -1,4 +1,4 @@ -use super::shared::{ TokenBalanceAmount, TokenType }; +use super::shared::{TokenBalanceAmount, TokenType}; #[derive(Clone, Copy, Eq, PartialEq, Hash)] pub enum SolautoAccount { diff --git a/programs/solauto/src/types/solauto_manager.rs b/programs/solauto/src/types/solauto_manager.rs index 067c4aca..19d7e9fb 100644 --- a/programs/solauto/src/types/solauto_manager.rs +++ b/programs/solauto/src/types/solauto_manager.rs @@ -2,33 +2,26 @@ use std::collections::HashMap; use math_utils::to_bps; use solana_program::{ - account_info::AccountInfo, - clock::Clock, - entrypoint::ProgramResult, - msg, + account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, program_error::ProgramError, }; use super::{ - instruction::{ RebalanceSettings, SolautoAction, SolautoStandardAccounts }, - lending_protocol::{ LendingProtocolClient, LendingProtocolTokenAccounts }, + instruction::{RebalanceSettings, SolautoAction, SolautoStandardAccounts}, + lending_protocol::{LendingProtocolClient, LendingProtocolTokenAccounts}, shared::{ - RebalanceStep, - RefreshStateProps, - SplTokenTransferArgs, - TokenBalanceAmount, - TokenType, + RebalanceStep, RefreshStateProps, SplTokenTransferArgs, TokenBalanceAmount, TokenType, }, - solauto::{ SolautoAccount, SolautoCpiAction }, + solauto::{SolautoAccount, SolautoCpiAction}, }; use crate::{ check, constants::SOLAUTO_FEES_WALLET, rebalance::{ - rebalancer::{ Rebalancer, RebalancerData, SolautoPositionData, TokenAccountData }, + rebalancer::{Rebalancer, RebalancerData, SolautoPositionData, TokenAccountData}, solauto_fees::SolautoFeesBps, }, - state::solauto_position::{ RebalanceData, SolautoPosition }, + state::solauto_position::{RebalanceData, SolautoPosition}, types::errors::SolautoError, utils::*, }; @@ -44,7 +37,7 @@ impl<'a> SolautoManagerAccounts<'a> { supply: LendingProtocolTokenAccounts<'a>, debt: LendingProtocolTokenAccounts<'a>, intermediary_ta: Option<&'a AccountInfo<'a>>, - solauto_fees: Option + solauto_fees: Option, ) -> Result { Ok(Self { supply, @@ -67,7 +60,7 @@ impl<'a> SolautoManager<'a> { client: Box + 'a>, accounts: SolautoManagerAccounts<'a>, std_accounts: Box>, - solauto_fees_bps: Option + solauto_fees_bps: Option, ) -> Result { client.validate(&std_accounts)?; Ok(Self { @@ -92,14 +85,15 @@ impl<'a> SolautoManager<'a> { fn borrow(&mut self, base_unit_amount: u64, destination: &'a AccountInfo<'a>) -> ProgramResult { msg!("Borrowing {}", base_unit_amount); self.update_usage(base_unit_amount as i64, TokenType::Debt); - self.client.borrow(base_unit_amount, destination, &self.std_accounts)?; + self.client + .borrow(base_unit_amount, destination, &self.std_accounts)?; Ok(()) } fn withdraw( &mut self, amount: TokenBalanceAmount, - destination: &'a AccountInfo<'a> + destination: &'a AccountInfo<'a>, ) -> ProgramResult { let base_unit_amount = match amount { TokenBalanceAmount::All => self.position_data().state.supply.amount_used.base_unit, @@ -108,7 +102,8 @@ impl<'a> SolautoManager<'a> { msg!("Withdrawing {}", base_unit_amount); self.update_usage((base_unit_amount as i64) * -1, TokenType::Supply); - self.client.withdraw(amount, destination, &self.std_accounts)?; + self.client + .withdraw(amount, destination, &self.std_accounts)?; Ok(()) } @@ -127,13 +122,20 @@ impl<'a> SolautoManager<'a> { fn update_usage(&mut self, base_unit_amount: i64, token_type: TokenType) { let position_data = self.position_data(); if !position_data.self_managed.val || position_data.rebalance.active() { - self.std_accounts.solauto_position.data.update_usage(token_type, base_unit_amount); + self.std_accounts + .solauto_position + .data + .update_usage(token_type, base_unit_amount); } } fn get_token_account_data(&self, account: Option<&'a AccountInfo<'a>>) -> TokenAccountData { TokenAccountData::from( - solauto_utils::safe_unpack_token_account(account).unwrap().unwrap().data.amount + solauto_utils::safe_unpack_token_account(account) + .unwrap() + .unwrap() + .data + .amount, ) } @@ -142,15 +144,36 @@ impl<'a> SolautoManager<'a> { map.insert( SolautoAccount::SolautoPosition, - Some(self.std_accounts.solauto_position.account_info) + Some(self.std_accounts.solauto_position.account_info), + ); + map.insert( + SolautoAccount::SolautoPositionSupplyTa, + self.accounts.supply.position_ta, + ); + map.insert( + SolautoAccount::SolautoPositionDebtTa, + self.accounts.debt.position_ta, + ); + map.insert( + SolautoAccount::AuthoritySupplyTa, + self.accounts.supply.authority_ta, + ); + map.insert( + SolautoAccount::AuthorityDebtTa, + self.accounts.debt.authority_ta, + ); + map.insert( + SolautoAccount::IntermediaryTa, + self.accounts.intermediary_ta, + ); + map.insert( + SolautoAccount::SolautoFeesTa, + self.std_accounts.solauto_fees_ta, + ); + map.insert( + SolautoAccount::ReferredByTa, + self.std_accounts.referred_by_ta, ); - map.insert(SolautoAccount::SolautoPositionSupplyTa, self.accounts.supply.position_ta); - map.insert(SolautoAccount::SolautoPositionDebtTa, self.accounts.debt.position_ta); - map.insert(SolautoAccount::AuthoritySupplyTa, self.accounts.supply.authority_ta); - map.insert(SolautoAccount::AuthorityDebtTa, self.accounts.debt.authority_ta); - map.insert(SolautoAccount::IntermediaryTa, self.accounts.intermediary_ta); - map.insert(SolautoAccount::SolautoFeesTa, self.std_accounts.solauto_fees_ta); - map.insert(SolautoAccount::ReferredByTa, self.std_accounts.referred_by_ta); map.get(acc).unwrap().unwrap() } @@ -167,21 +190,27 @@ impl<'a> SolautoManager<'a> { debt_ta: position_debt_ta, }, solauto_fees_bps: self.solauto_fees_bps.unwrap().clone(), - referred_by: self.std_accounts.authority_referral_state.is_some() && - self.std_accounts.authority_referral_state.as_ref().unwrap().data.is_referred(), + referred_by: self.std_accounts.authority_referral_state.is_some() + && self + .std_accounts + .authority_referral_state + .as_ref() + .unwrap() + .data + .is_referred(), }) } fn execute_cpi_actions(&mut self, actions: Vec) -> ProgramResult { - let owned_seeds: Vec> = self.std_accounts.solauto_position.data + let owned_seeds: Vec> = self + .std_accounts + .solauto_position + .data .seeds_with_bump() .iter() .map(|s| s.to_vec()) .collect(); - let seeds_vec: Vec<&[u8]> = owned_seeds - .iter() - .map(|v| v.as_slice()) - .collect(); + let seeds_vec: Vec<&[u8]> = owned_seeds.iter().map(|v| v.as_slice()).collect(); for action in actions { match action { @@ -207,7 +236,7 @@ impl<'a> SolautoManager<'a> { authority: self.to_account_info(&data.from_wallet), recipient: self.to_account_info(&data.to_wallet_ta), authority_seeds, - } + }, )?; } } @@ -218,7 +247,7 @@ impl<'a> SolautoManager<'a> { pub fn refresh_position( solauto_position: &mut SolautoPosition, updated_data: RefreshStateProps, - clock: Clock + clock: Clock, ) -> ProgramResult { // Update mint addresses if self-managed if solauto_position.self_managed.val { @@ -236,11 +265,11 @@ impl<'a> SolautoManager<'a> { solauto_position.state.supply.amount_used.usd_value(), solauto_position.state.debt.amount_used.usd_value(), solauto_position.state.supply.market_price(), - solauto_position.state.supply.decimals + solauto_position.state.supply.decimals, ); solauto_position.state.net_worth.update_usd_value( updated_data.supply.market_price, - solauto_position.state.supply.decimals + solauto_position.state.supply.decimals, ); solauto_position.refresh_state(); @@ -255,7 +284,10 @@ impl<'a> SolautoManager<'a> { self.deposit(base_unit_amount)?; } SolautoAction::Borrow(base_unit_amount) => { - self.borrow(base_unit_amount, self.accounts.debt.position_ta.as_ref().unwrap())?; + self.borrow( + base_unit_amount, + self.accounts.debt.position_ta.as_ref().unwrap(), + )?; } SolautoAction::Repay(amount) => { self.repay(amount)?; @@ -270,7 +302,7 @@ impl<'a> SolautoManager<'a> { fn validate_fee_token_accounts(&self) -> ProgramResult { let mints = vec![ self.std_accounts.solauto_position.data.state.supply.mint, - self.std_accounts.solauto_position.data.state.debt.mint + self.std_accounts.solauto_position.data.state.debt.mint, ]; if self.std_accounts.solauto_fees_ta.is_some() { @@ -288,9 +320,13 @@ impl<'a> SolautoManager<'a> { check!( validation_utils::valid_token_account_for_mints( self.std_accounts.referred_by_ta.as_ref().unwrap().key, - &self.std_accounts.authority_referral_state + &self + .std_accounts + .authority_referral_state .as_ref() - .unwrap().data.referred_by_state, + .unwrap() + .data + .referred_by_state, &mints ), SolautoError::IncorrectAccounts @@ -303,7 +339,7 @@ impl<'a> SolautoManager<'a> { pub fn rebalance( &mut self, rebalance_args: RebalanceSettings, - rebalance_step: RebalanceStep + rebalance_step: RebalanceStep, ) -> ProgramResult { self.validate_fee_token_accounts()?; diff --git a/programs/solauto/src/utils/solana_utils.rs b/programs/solauto/src/utils/solana_utils.rs index 96f08a90..3c4cc00c 100644 --- a/programs/solauto/src/utils/solana_utils.rs +++ b/programs/solauto/src/utils/solana_utils.rs @@ -2,7 +2,7 @@ use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, instruction::Instruction, - program::{ invoke, invoke_signed }, + program::{invoke, invoke_signed}, pubkey::Pubkey, rent::Rent, system_instruction, @@ -13,7 +13,7 @@ use spl_token::instruction as spl_instruction; use crate::{ check, - types::{ errors::SolautoError, shared::SplTokenTransferArgs }, + types::{errors::SolautoError, shared::SplTokenTransferArgs}, utils::validation_utils::correct_token_account, }; @@ -24,7 +24,7 @@ pub fn account_has_data(account: &AccountInfo) -> bool { pub fn invoke_instruction( instruction: &Instruction, account_infos: &[AccountInfo], - seeds: Option<&Vec<&[u8]>> + seeds: Option<&Vec<&[u8]>>, ) -> ProgramResult { if let Some(seeds) = seeds { invoke_signed(instruction, account_infos, &[seeds.as_slice()]) @@ -39,12 +39,14 @@ pub fn init_account<'a>( account: &'a AccountInfo<'a>, new_owner: &Pubkey, account_seed: Option>, - space: usize + space: usize, ) -> ProgramResult { check!(!account_has_data(account), SolautoError::IncorrectAccounts); let rent = &Rent::from_account_info(rent_sysvar)?; - let required_lamports = rent.minimum_balance(space).saturating_sub(account.lamports()); + let required_lamports = rent + .minimum_balance(space) + .saturating_sub(account.lamports()); if required_lamports > 0 { system_transfer(payer, account, required_lamports, None)?; } @@ -54,13 +56,13 @@ pub fn init_account<'a>( invoke_instruction( &system_instruction::allocate(account.key, space.try_into().unwrap()), accounts, - account_seed.as_ref() + account_seed.as_ref(), )?; invoke_instruction( &system_instruction::assign(account.key, &new_owner), accounts, - account_seed.as_ref() + account_seed.as_ref(), )?; Ok(()) @@ -72,7 +74,7 @@ pub fn init_ata_if_needed<'a, 'b>( payer: &'a AccountInfo<'a>, wallet: &'a AccountInfo<'a>, token_account: &'a AccountInfo<'a>, - token_mint: &'a AccountInfo<'a> + token_mint: &'a AccountInfo<'a>, ) -> ProgramResult { check!( correct_token_account(token_account.key, wallet.key, token_mint.key), @@ -92,7 +94,7 @@ pub fn init_ata_if_needed<'a, 'b>( token_mint.clone(), system_program.clone(), token_program.clone(), - ] + ], ) } @@ -100,18 +102,18 @@ pub fn system_transfer<'a>( source: &'a AccountInfo<'a>, destination: &'a AccountInfo<'a>, lamports: u64, - source_seeds: Option<&Vec<&[u8]>> + source_seeds: Option<&Vec<&[u8]>>, ) -> ProgramResult { invoke_instruction( &system_instruction::transfer(source.key, destination.key, lamports), &[source.clone(), destination.clone()], - source_seeds + source_seeds, ) } pub fn spl_token_transfer<'a, 'b>( token_program: &'a AccountInfo<'a>, - args: SplTokenTransferArgs<'a, 'b> + args: SplTokenTransferArgs<'a, 'b>, ) -> ProgramResult { invoke_instruction( &spl_instruction::transfer( @@ -120,10 +122,14 @@ pub fn spl_token_transfer<'a, 'b>( args.recipient.key, args.authority.key, &[], - args.amount + args.amount, )?, - &[args.source.clone(), args.recipient.clone(), args.authority.clone()], - args.authority_seeds + &[ + args.source.clone(), + args.recipient.clone(), + args.authority.clone(), + ], + args.authority_seeds, ) } @@ -132,7 +138,7 @@ pub fn close_token_account<'a, 'b>( account: &'a AccountInfo<'a>, sol_destination: &'a AccountInfo<'a>, account_owner: &'a AccountInfo<'a>, - owner_seeds: Option<&Vec<&[u8]>> + owner_seeds: Option<&Vec<&[u8]>>, ) -> ProgramResult { invoke_instruction( &spl_instruction::close_account( @@ -140,10 +146,14 @@ pub fn close_token_account<'a, 'b>( account.key, sol_destination.key, account_owner.key, - &[] + &[], )?, - &[account.clone(), sol_destination.clone(), account_owner.clone()], - owner_seeds + &[ + account.clone(), + sol_destination.clone(), + account_owner.clone(), + ], + owner_seeds, ) } diff --git a/programs/solauto/src/utils/validation_utils.rs b/programs/solauto/src/utils/validation_utils.rs index 572e24ce..fd101cca 100644 --- a/programs/solauto/src/utils/validation_utils.rs +++ b/programs/solauto/src/utils/validation_utils.rs @@ -1,6 +1,6 @@ use std::ops::Div; -use marginfi_sdk::generated::accounts::{ Bank, MarginfiAccount }; +use marginfi_sdk::generated::accounts::{Bank, MarginfiAccount}; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, @@ -8,36 +8,32 @@ use solana_program::{ program_error::ProgramError, pubkey::Pubkey, system_program::ID as system_program_id, - sysvar::{ instructions::ID as ixs_sysvar_id, rent::ID as rent_program_id }, + sysvar::{instructions::ID as ixs_sysvar_id, rent::ID as rent_program_id}, }; -use spl_associated_token_account::{ get_associated_token_address, ID as ata_program_id }; +use spl_associated_token_account::{get_associated_token_address, ID as ata_program_id}; use spl_token::ID as token_program_id; use crate::{ check, constants::{ - MARGINFI_PROD_PROGRAM, - MARGINFI_STAGING_PROGRAM, - MIN_BOOST_GAP_BPS, - MIN_REPAY_GAP_BPS, + MARGINFI_PROD_PROGRAM, MARGINFI_STAGING_PROGRAM, MIN_BOOST_GAP_BPS, MIN_REPAY_GAP_BPS, SOLAUTO_MANAGER, }, error_if, state::{ - automation::AutomationSettings, - referral_state::ReferralState, + automation::AutomationSettings, referral_state::ReferralState, solauto_position::SolautoPosition, }, types::{ errors::SolautoError, instruction::SolautoStandardAccounts, - shared::{ DeserializedAccount, LendingPlatform, TokenType }, + shared::{DeserializedAccount, LendingPlatform, TokenType}, }, utils::math_utils::from_rounded_usd_value, }; use super::{ - math_utils::{ get_max_boost_to_bps, get_max_repay_from_bps, get_max_repay_to_bps }, + math_utils::{get_max_boost_to_bps, get_max_repay_from_bps, get_max_repay_to_bps}, solauto_utils::safe_unpack_token_account, }; @@ -45,13 +41,13 @@ pub fn generic_instruction_validation( accounts: &Box, lending_platform: LendingPlatform, authority_signer_only_ix: bool, - solauto_managed_only_ix: bool + solauto_managed_only_ix: bool, ) -> ProgramResult { validate_instruction( accounts.signer, &accounts.solauto_position, authority_signer_only_ix, - solauto_managed_only_ix + solauto_managed_only_ix, )?; validate_lending_program_account(accounts.lending_protocol, lending_platform)?; validate_standard_programs( @@ -59,7 +55,7 @@ pub fn generic_instruction_validation( Some(accounts.token_program), accounts.ata_program, accounts.rent, - accounts.ixs_sysvar + accounts.ixs_sysvar, )?; if accounts.authority_referral_state.is_some() { @@ -67,7 +63,7 @@ pub fn generic_instruction_validation( &accounts.solauto_position.data.authority, accounts.authority_referral_state.as_ref().unwrap(), accounts.referred_by_ta, - true + true, )?; } @@ -79,7 +75,7 @@ pub fn validate_instruction( signer: &AccountInfo, solauto_position: &DeserializedAccount, authority_signer_only_ix: bool, - solauto_managed_only_ix: bool + solauto_managed_only_ix: bool, ) -> ProgramResult { check!(&signer.is_signer, ProgramError::MissingRequiredSignature); @@ -87,8 +83,9 @@ pub fn validate_instruction( let authority_signed = || { let expected_solauto_position_address = Pubkey::create_program_address( solauto_position.data.seeds_with_bump().as_slice(), - &crate::ID - ).expect("Ok"); + &crate::ID, + ) + .expect("Ok"); let expected_address_matches = solauto_position.account_info.key == &expected_solauto_position_address; return signer.key == &position_authority && expected_address_matches; @@ -120,15 +117,15 @@ pub fn validate_instruction( pub fn validate_position_settings(solauto_position: &SolautoPosition) -> ProgramResult { let max_boost_to_bps = get_max_boost_to_bps( solauto_position.state.max_ltv_bps, - solauto_position.state.liq_threshold_bps + solauto_position.state.liq_threshold_bps, ); let max_repay_to_bps = get_max_repay_to_bps( solauto_position.state.max_ltv_bps, - solauto_position.state.liq_threshold_bps + solauto_position.state.liq_threshold_bps, ); let max_repay_from_bps = get_max_repay_from_bps( solauto_position.state.max_ltv_bps, - solauto_position.state.liq_threshold_bps + solauto_position.state.liq_threshold_bps, ); let data = &solauto_position.position; @@ -136,10 +133,22 @@ pub fn validate_position_settings(solauto_position: &SolautoPosition) -> Program data.settings.repay_to_bps >= data.settings.boost_to_bps, SolautoError::InvalidRepayToSetting ); - check!(data.settings.boost_to_bps <= max_boost_to_bps, SolautoError::InvalidBoostToSetting); - check!(data.settings.repay_gap >= MIN_REPAY_GAP_BPS, SolautoError::InvalidRepayGapSetting); - check!(data.settings.boost_gap >= MIN_BOOST_GAP_BPS, SolautoError::InvalidBoostGapSetting); - check!(data.settings.repay_to_bps <= max_repay_to_bps, SolautoError::InvalidRepayToSetting); + check!( + data.settings.boost_to_bps <= max_boost_to_bps, + SolautoError::InvalidBoostToSetting + ); + check!( + data.settings.repay_gap >= MIN_REPAY_GAP_BPS, + SolautoError::InvalidRepayGapSetting + ); + check!( + data.settings.boost_gap >= MIN_BOOST_GAP_BPS, + SolautoError::InvalidBoostGapSetting + ); + check!( + data.settings.repay_to_bps <= max_repay_to_bps, + SolautoError::InvalidRepayToSetting + ); check!( data.settings.repay_to_bps + data.settings.repay_gap <= max_repay_from_bps, SolautoError::InvalidRepayFromSetting @@ -149,7 +158,7 @@ pub fn validate_position_settings(solauto_position: &SolautoPosition) -> Program pub fn validate_automation_settings( automation: &AutomationSettings, - current_unix_timestamp: u64 + current_unix_timestamp: u64, ) -> ProgramResult { let invalid_params = |error_msg| { msg!(error_msg); @@ -164,9 +173,8 @@ pub fn validate_automation_settings( return invalid_params("Interval period must be between 10 minutes and 1 month"); } - if - current_unix_timestamp < automation.unix_start_date || - current_unix_timestamp > automation.unix_start_date + automation.interval_seconds + if current_unix_timestamp < automation.unix_start_date + || current_unix_timestamp > automation.unix_start_date + automation.interval_seconds { return invalid_params("Provided an invalid unix start date"); } @@ -180,7 +188,7 @@ pub fn validate_automation_settings( pub fn validate_lending_program_account( program: &AccountInfo, - lending_platform: LendingPlatform + lending_platform: LendingPlatform, ) -> ProgramResult { match lending_platform { LendingPlatform::Marginfi => { @@ -199,7 +207,7 @@ pub fn validate_standard_programs( token_program: Option<&AccountInfo>, ata_program: Option<&AccountInfo>, rent: Option<&AccountInfo>, - ixs_sysvar: Option<&AccountInfo> + ixs_sysvar: Option<&AccountInfo>, ) -> ProgramResult { check!( system_program.is_none() || system_program.unwrap().key == &system_program_id, @@ -228,24 +236,24 @@ pub fn validate_referral_accounts<'a>( referral_state_authority: &Pubkey, authority_referral_state: &DeserializedAccount<'a, ReferralState>, referred_by_ta: Option<&'a AccountInfo<'a>>, - validate_ta: bool + validate_ta: bool, ) -> ProgramResult { let referral_state_pda = Pubkey::create_program_address( authority_referral_state.data.seeds_with_bump().as_slice(), - &crate::ID + &crate::ID, )?; error_if!( - &authority_referral_state.data.authority != referral_state_authority || - &referral_state_pda != authority_referral_state.account_info.key, + &authority_referral_state.data.authority != referral_state_authority + || &referral_state_pda != authority_referral_state.account_info.key, SolautoError::IncorrectAccounts ); let authority_referred_by_state = &authority_referral_state.data.referred_by_state; error_if!( - validate_ta && - authority_referred_by_state != &Pubkey::default() && - referred_by_ta.is_none(), + validate_ta + && authority_referred_by_state != &Pubkey::default() + && referred_by_ta.is_none(), SolautoError::IncorrectAccounts ); // The referred_by_ta is validated during rebalance in solauto_manager.rs because it requires up-to-date state @@ -255,7 +263,7 @@ pub fn validate_referral_accounts<'a>( pub fn validate_marginfi_bank<'a>( marginfi_bank: &'a AccountInfo<'a>, - mint: &Pubkey + mint: &Pubkey, ) -> ProgramResult { if mint == &Pubkey::default() { return Ok(()); @@ -272,14 +280,14 @@ pub fn validate_lending_program_accounts_with_position<'a>( solauto_position: &DeserializedAccount, lp_user_account: &'a AccountInfo<'a>, lp_supply_account: &'a AccountInfo<'a>, - lp_debt_account: &'a AccountInfo<'a> + lp_debt_account: &'a AccountInfo<'a>, ) -> ProgramResult { let supply_mint = &solauto_position.data.state.supply.mint; let debt_mint = &solauto_position.data.state.debt.mint; error_if!( - !solauto_position.data.self_managed.val && - lp_user_account.key != &solauto_position.data.position.lp_user_account, + !solauto_position.data.self_managed.val + && lp_user_account.key != &solauto_position.data.position.lp_user_account, SolautoError::IncorrectAccounts ); @@ -296,10 +304,20 @@ pub fn validate_lending_program_accounts_with_position<'a>( pub fn validate_token_accounts<'a, 'b>( solauto_position: &'b DeserializedAccount<'a, SolautoPosition>, source_supply_ta: Option<&'a AccountInfo<'a>>, - source_debt_ta: Option<&'a AccountInfo<'a>> + source_debt_ta: Option<&'a AccountInfo<'a>>, ) -> ProgramResult { - validate_token_account(solauto_position, source_supply_ta, Some(TokenType::Supply), None)?; - validate_token_account(solauto_position, source_debt_ta, Some(TokenType::Debt), None)?; + validate_token_account( + solauto_position, + source_supply_ta, + Some(TokenType::Supply), + None, + )?; + validate_token_account( + solauto_position, + source_debt_ta, + Some(TokenType::Debt), + None, + )?; Ok(()) } @@ -307,7 +325,7 @@ pub fn validate_token_account<'a>( solauto_position: &DeserializedAccount<'a, SolautoPosition>, source_ta: Option<&'a AccountInfo<'a>>, token_type: Option, - token_mint: Option<&Pubkey> + token_mint: Option<&Pubkey>, ) -> ProgramResult { if solauto_position.data.self_managed.val && token_mint.is_none() { return Ok(()); @@ -324,19 +342,15 @@ pub fn validate_token_account<'a>( mint_key }; - let associated_position_ta = get_associated_token_address( - &solauto_position.account_info.key, - mint_key - ); - let associated_authority_ta = get_associated_token_address( - &solauto_position.data.authority, - mint_key - ); + let associated_position_ta = + get_associated_token_address(&solauto_position.account_info.key, mint_key); + let associated_authority_ta = + get_associated_token_address(&solauto_position.data.authority, mint_key); error_if!( - source_ta.is_some() && - source_ta.unwrap().key != &associated_position_ta && - source_ta.unwrap().key != &associated_authority_ta, + source_ta.is_some() + && source_ta.unwrap().key != &associated_position_ta + && source_ta.unwrap().key != &associated_authority_ta, SolautoError::IncorrectAccounts ); @@ -346,7 +360,7 @@ pub fn validate_token_account<'a>( pub fn token_account_owned_by<'a>( token_account: &'a AccountInfo<'a>, expected_owner: &Pubkey, - token_mint: Option<&Pubkey> + token_mint: Option<&Pubkey>, ) -> Result { if token_mint.is_some() { return Ok( @@ -354,28 +368,29 @@ pub fn token_account_owned_by<'a>( ); } else { let token_account_data = safe_unpack_token_account(Some(token_account))?.unwrap(); - return Ok( - token_account_data.account_info.owner == &token_program_id && - &token_account_data.data.owner == expected_owner - ); + return Ok(token_account_data.account_info.owner == &token_program_id + && &token_account_data.data.owner == expected_owner); } } pub fn validate_referral_signer( referral_state: &DeserializedAccount, signer: &AccountInfo, - allow_solauto_manager: bool + allow_solauto_manager: bool, ) -> ProgramResult { let referral_state_pda = Pubkey::create_program_address( referral_state.data.seeds_with_bump().as_slice(), - &crate::ID + &crate::ID, )?; check!(&signer.is_signer, ProgramError::MissingRequiredSignature); - check!(&referral_state_pda == referral_state.account_info.key, SolautoError::IncorrectAccounts); + check!( + &referral_state_pda == referral_state.account_info.key, + SolautoError::IncorrectAccounts + ); error_if!( - signer.key != &referral_state.data.authority && - (!allow_solauto_manager || signer.key != &SOLAUTO_MANAGER), + signer.key != &referral_state.data.authority + && (!allow_solauto_manager || signer.key != &SOLAUTO_MANAGER), SolautoError::IncorrectAccounts ); @@ -384,19 +399,22 @@ pub fn validate_referral_signer( pub fn validate_no_active_balances<'a>( lp_user_account: &'a AccountInfo<'a>, - lending_platform: LendingPlatform + lending_platform: LendingPlatform, ) -> ProgramResult { if lending_platform == LendingPlatform::Marginfi { - let marginfi_account = DeserializedAccount:: - ::zerocopy(Some(lp_user_account))? - .unwrap(); + let marginfi_account = + DeserializedAccount::::zerocopy(Some(lp_user_account))?.unwrap(); check!( - marginfi_account.data.lending_account.balances + marginfi_account + .data + .lending_account + .balances .iter() .filter(|balance| balance.active == 1) .collect::>() - .len() == 0, + .len() + == 0, SolautoError::IncorrectAccounts ); @@ -411,13 +429,20 @@ pub fn validate_rebalance(solauto_position: &SolautoPosition) -> ProgramResult { let curr_supply_usd = solauto_position.state.supply.amount_used.usd_value(); let curr_debt_usd = solauto_position.state.debt.amount_used.usd_value(); - let target_supply_usd = from_rounded_usd_value( - solauto_position.rebalance.values.target_supply_usd - ); + let target_supply_usd = + from_rounded_usd_value(solauto_position.rebalance.values.target_supply_usd); let target_debt_usd = from_rounded_usd_value(solauto_position.rebalance.values.target_debt_usd); - msg!("Supply expected vs. actual: {}, {}", target_supply_usd, curr_supply_usd); - msg!("Debt expected vs. actual: {}, {}", target_debt_usd, curr_debt_usd); + msg!( + "Supply expected vs. actual: {}, {}", + target_supply_usd, + curr_supply_usd + ); + msg!( + "Debt expected vs. actual: {}, {}", + target_debt_usd, + curr_debt_usd + ); check!( value_gte_with_threshold(curr_supply_usd, target_supply_usd, 0.2), SolautoError::InvalidRebalanceMade @@ -437,9 +462,11 @@ pub fn correct_token_account(token_account: &Pubkey, wallet: &Pubkey, mint: &Pub pub fn valid_token_account_for_mints( token_account: &Pubkey, wallet: &Pubkey, - mints: &Vec + mints: &Vec, ) -> bool { - mints.iter().any(|mint| correct_token_account(token_account, wallet, mint)) + mints + .iter() + .any(|mint| correct_token_account(token_account, wallet, mint)) } pub fn value_lte_with_threshold(value: f64, target_value: f64, threshold: f64) -> bool { @@ -467,11 +494,9 @@ pub fn value_match_with_threshold(value: f64, target_value: f64, threshold: f64) mod tests { use crate::{ state::{ - automation::{ AutomationSettings, AutomationSettingsInp }, + automation::{AutomationSettings, AutomationSettingsInp}, solauto_position::{ - PositionData, - PositionState, - SolautoSettingsParameters, + PositionData, PositionState, SolautoSettingsParameters, SolautoSettingsParametersInp, }, }, @@ -494,7 +519,7 @@ mod tests { Pubkey::default(), PositionType::default(), position_data, - position_state + position_state, ); let result = validate_position_settings(&solauto_position); assert!(result.is_err()); @@ -514,14 +539,14 @@ mod tests { boost_gap: MIN_BOOST_GAP_BPS - 10, ..default_settings_args }), - default_liq_threshold_bps + default_liq_threshold_bps, ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { repay_gap: MIN_REPAY_GAP_BPS - 10, ..default_settings_args }), - default_liq_threshold_bps + default_liq_threshold_bps, ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -529,7 +554,7 @@ mod tests { repay_gap: 600, ..default_settings_args }), - default_liq_threshold_bps + default_liq_threshold_bps, ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -537,7 +562,7 @@ mod tests { boost_gap: 1000, ..default_settings_args }), - default_liq_threshold_bps + default_liq_threshold_bps, ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -545,7 +570,7 @@ mod tests { repay_to_bps: 4000, ..default_settings_args }), - default_liq_threshold_bps + default_liq_threshold_bps, ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { @@ -553,14 +578,14 @@ mod tests { repay_gap: 500, ..default_settings_args }), - default_liq_threshold_bps + default_liq_threshold_bps, ); test_position_settings( SolautoSettingsParameters::from(SolautoSettingsParametersInp { repay_to_bps: 9900, ..default_settings_args }), - default_liq_threshold_bps + default_liq_threshold_bps, ); } @@ -582,25 +607,25 @@ mod tests { test_automation_settings( current_timestamp, AutomationSettings::from(AutomationSettingsInp { - unix_start_date: current_timestamp + - default_automation_settings_args.interval_seconds + - 100, + unix_start_date: current_timestamp + + default_automation_settings_args.interval_seconds + + 100, ..default_automation_settings_args - }) + }), ); test_automation_settings( current_timestamp, AutomationSettings::from(AutomationSettingsInp { interval_seconds: 60, ..default_automation_settings_args.clone() - }) + }), ); test_automation_settings( current_timestamp, AutomationSettings::from(AutomationSettingsInp { interval_seconds: 60 * 60 * 24 * 60, ..default_automation_settings_args.clone() - }) + }), ); } } diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index ac09ace9..901917e9 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.751", + "version": "1.0.753", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts b/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts index 6579144c..ff782667 100644 --- a/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts +++ b/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts @@ -93,12 +93,8 @@ export class RebalanceSwapManager { let debtUsd = this.client.pos.debtUsd(this.priceType); // TODO: add token balance change - const { - input, - biasedInputPrice, - output, - biasedOutputPrice, - } = this.swapDetails(); + const { input, biasedInputPrice, output, biasedOutputPrice } = + this.swapDetails(); const swapInputAmount = swapInputAmountBaseUnit ? fromBaseUnit( @@ -125,7 +121,9 @@ export class RebalanceSwapManager { const res = applyDebtAdjustmentUsd( { debtAdjustmentUsd: this.isBoost() ? swapInputUsd : swapInputUsd * -1, - debtAdjustmentUsdOutput: this.isBoost() ? swapOutputUsd : swapOutputUsd * -1, + debtAdjustmentUsdOutput: this.isBoost() + ? swapOutputUsd + : swapOutputUsd * -1, }, { supplyUsd, debtUsd }, fromBps(this.client.pos.state.liqThresholdBps), @@ -177,8 +175,11 @@ export class RebalanceSwapManager { BigInt(parseInt(swapQuote.inAmount)) ); const exceedsMinOutput = criteria.minOutputAmount - ? outputAmount < Number(criteria.minOutputAmount) : false; - const exceedsMaxRate = criteria.maxLiqUtilizationRateBps ? postRebalanceRate > criteria.maxLiqUtilizationRateBps : false; + ? outputAmount < Number(criteria.minOutputAmount) + : false; + const exceedsMaxRate = criteria.maxLiqUtilizationRateBps + ? postRebalanceRate > criteria.maxLiqUtilizationRateBps + : false; insufficient = exceedsMinOutput || exceedsMaxRate; consoleLog(postRebalanceRate, criteria.maxLiqUtilizationRateBps); @@ -211,8 +212,7 @@ export class RebalanceSwapManager { BigInt( Math.round( Number(output.amountUsed.baseUnit) * - // Add this small percentage to account for the APR on the debt between now and the transaction - 0.0001 + (fromBps(this.solautoFeeBps) + 0.0001) ) ) : toBaseUnit(this.usdToSwap() / biasedOutputPrice, output.decimals); From c9a807a0a77846a6831746019f0b3cb6487e214b Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 9 May 2025 13:42:21 -0400 Subject: [PATCH 29/88] fixes --- solauto-sdk/package.json | 2 +- .../rebalance/rebalanceSwapManager.ts | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 901917e9..5189d3e2 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.753", + "version": "1.0.758", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts b/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts index ff782667..86f3a35d 100644 --- a/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts +++ b/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts @@ -207,16 +207,6 @@ export class RebalanceSwapManager { const rebalanceToZero = this.targetLiqUtilizationRateBps === 0; let { input, output, biasedOutputPrice, inputAmount } = this.swapDetails(); - let outputAmount = rebalanceToZero - ? output.amountUsed.baseUnit + - BigInt( - Math.round( - Number(output.amountUsed.baseUnit) * - (fromBps(this.solautoFeeBps) + 0.0001) - ) - ) - : toBaseUnit(this.usdToSwap() / biasedOutputPrice, output.decimals); - const flashLoanRepayFromDebt = !this.isBoost() && this.flRequirements && @@ -225,6 +215,15 @@ export class RebalanceSwapManager { const exactOut = flashLoanRepayFromDebt; const exactIn = !exactOut; + const outputPaddingPct = + (exactOut ? fromBps(this.solautoFeeBps) : 0) + 0.0001; + let outputAmount = rebalanceToZero + ? output.amountUsed.baseUnit + + BigInt( + Math.round(Number(output.amountUsed.baseUnit) * outputPaddingPct) + ) + : toBaseUnit(this.usdToSwap() / biasedOutputPrice, output.decimals); + if (exactIn && (rebalanceToZero || this.values.repayingCloseToMaxLtv)) { inputAmount = this.bigIntWithIncrement(inputAmount, 0.005); } From 7d7c5794256fdedb27ad5482d86a6cf53828652e Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 9 May 2025 14:20:50 -0400 Subject: [PATCH 30/88] adjust fee --- programs/solauto/src/rebalance/solauto_fees.rs | 2 +- solauto-sdk/src/services/rebalance/solautoFees.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/solauto/src/rebalance/solauto_fees.rs b/programs/solauto/src/rebalance/solauto_fees.rs index d0e7bb24..1b07823a 100644 --- a/programs/solauto/src/rebalance/solauto_fees.rs +++ b/programs/solauto/src/rebalance/solauto_fees.rs @@ -62,7 +62,7 @@ impl SolautoFeesBps { let mut fee_bps: f64; if self.target_liq_utilization_rate_bps.is_some() { - fee_bps = 15.0; + fee_bps = 10.0; } else if rebalance_direction == &RebalanceDirection::Repay { fee_bps = 25.0; } else if self.position_net_worth_usd <= min_size { diff --git a/solauto-sdk/src/services/rebalance/solautoFees.ts b/solauto-sdk/src/services/rebalance/solautoFees.ts index 9d70cd1e..a4e3bc98 100644 --- a/solauto-sdk/src/services/rebalance/solautoFees.ts +++ b/solauto-sdk/src/services/rebalance/solautoFees.ts @@ -29,7 +29,7 @@ export class SolautoFeesBps { let feeBps: number = 0; if (this.targetLiqUtilizationRateBps !== undefined) { - feeBps = 15; + feeBps = 10; } else if (rebalanceDirection === RebalanceDirection.Repay) { feeBps = 25; } else if (this.positionNetWorthUsd <= minSize) { From ed9e507d84bc1f828fce944c1b2f615877a6ae52 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 9 May 2025 15:06:38 -0400 Subject: [PATCH 31/88] bump --- solauto-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 5189d3e2..32e2928e 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.758", + "version": "1.0.759", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", From dfe09fbe6ed3d7a5cb82ef0d8a0d94976e57ffa5 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sat, 10 May 2025 15:24:04 -0400 Subject: [PATCH 32/88] fixes --- solauto-sdk/package.json | 2 +- solauto-sdk/src/services/solauto/txHandler.ts | 8 +++++--- .../services/transactions/manager/transactionsManager.ts | 2 +- solauto-sdk/src/utils/generalUtils.ts | 7 +++++-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 32e2928e..35022904 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.759", + "version": "1.0.761", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/solauto/txHandler.ts b/solauto-sdk/src/services/solauto/txHandler.ts index 5cdba227..35aafb1e 100644 --- a/solauto-sdk/src/services/solauto/txHandler.ts +++ b/solauto-sdk/src/services/solauto/txHandler.ts @@ -17,7 +17,7 @@ export interface TxHandlerProps { lpEnv?: ProgramEnv; } -export abstract class TxHandler { +export class TxHandler { public rpcUrl!: string; public showLogs = false; public programId!: PublicKey; @@ -64,7 +64,9 @@ export abstract class TxHandler { consoleLog(...args); } - abstract defaultLookupTables(): string[]; + defaultLookupTables(): string[] { + return []; + } - abstract resetLiveTxUpdates(success?: boolean): Promise; + resetLiveTxUpdates(success?: boolean) {} } diff --git a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts index ac6afc0e..c296cadb 100644 --- a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts @@ -585,7 +585,7 @@ export class TransactionsManager { consoleLog(errorString); if (!errorDetails.canBeIgnored) { - throw new Error(errorInfo); + throw error; } } } diff --git a/solauto-sdk/src/utils/generalUtils.ts b/solauto-sdk/src/utils/generalUtils.ts index 39b7bb1c..02b87fbc 100644 --- a/solauto-sdk/src/utils/generalUtils.ts +++ b/solauto-sdk/src/utils/generalUtils.ts @@ -127,7 +127,7 @@ export function retryWithExponentialBackoff( attemptNum++; if ( - errorsToThrow && + errorsToThrow?.length && errorsToThrow.some((errorType) => error instanceof errorType) ) { reject(error); @@ -206,7 +206,10 @@ export function validPubkey(pubkey?: PublicKey | UmiPublicKey | string) { return Boolean(pubkey) && pubkey!.toString() !== PublicKey.default.toString(); } -export function createRecord(keys: string[], values: T[]): Record { +export function createRecord( + keys: string[], + values: T[] +): Record { return Object.fromEntries( zip(keys, values).map(([k, v]) => [k.toString(), v]) ); From 4422a3c1801a5047292a9721c450886f745a6844 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sun, 11 May 2025 12:18:39 -0400 Subject: [PATCH 33/88] larger batch --- solauto-sdk/src/solautoPosition/positionUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solauto-sdk/src/solautoPosition/positionUtils.ts b/solauto-sdk/src/solautoPosition/positionUtils.ts index ef01da5d..3ce661a6 100644 --- a/solauto-sdk/src/solautoPosition/positionUtils.ts +++ b/solauto-sdk/src/solautoPosition/positionUtils.ts @@ -46,7 +46,7 @@ export async function getPositionExBulk( umi: Umi, publicKeys: PublicKey[] ): Promise { - const batches = getBatches(publicKeys, 50); + const batches = getBatches(publicKeys, 100); const data = ( await Promise.all( From 40c1f5da278d8c95f97566ea6192802ece4008cf Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 19 May 2025 15:18:59 -0400 Subject: [PATCH 34/88] some utils --- solauto-sdk/local/txSandbox.ts | 52 +++++++++++++++++++++++++--- solauto-sdk/package.json | 2 +- solauto-sdk/src/utils/numberUtils.ts | 31 +++++++++++++++++ 3 files changed, 79 insertions(+), 6 deletions(-) diff --git a/solauto-sdk/local/txSandbox.ts b/solauto-sdk/local/txSandbox.ts index add63425..f454f301 100644 --- a/solauto-sdk/local/txSandbox.ts +++ b/solauto-sdk/local/txSandbox.ts @@ -1,15 +1,19 @@ import { Keypair, PublicKey } from "@solana/web3.js"; -import { createSignerFromKeypair } from "@metaplex-foundation/umi"; +import { createSignerFromKeypair, publicKey } from "@metaplex-foundation/umi"; import { fromWeb3JsKeypair } from "@metaplex-foundation/umi-web3js-adapters"; import { + bytesToI80F48, ClientTransactionsManager, consoleLog, + fetchBank, + fetchMarginfiAccount, getBatches, getClient, getPositionExBulk, getSolanaRpcConnection, getSolautoManagedPositions, LendingPlatform, + lendingPoolAccrueBankInterest, LOCAL_IRONFORGE_API_URL, PriceType, PriorityFeeSetting, @@ -21,8 +25,9 @@ import { TransactionItem, } from "../src"; import { getSecretKey } from "./shared"; +import { fromBaseUnit } from "../dist"; -const payForTransaction = false; +const payForTransaction = true; const testProgram = false; const lpEnv: ProgramEnv = "Prod"; @@ -47,14 +52,23 @@ export async function main() { }); await client.initializeExistingSolautoPosition({ - positionId: 2, - authority: new PublicKey("EBhRj7jbF2EVE21i19JSuCX1BAbnZFYhoKW64HnaZ3kf"), + positionId: 1, + authority: new PublicKey("5UqsR2PGzbP8pGPbXEeXx86Gjz2N2UFBAuFZUSVydAEe"), // lpUserAccount: new PublicKey( // "GEokw9jqbh6d1xUNA3qaeYFFetbSR5Y1nt7C3chwwgSz" // ), }); - const transactionItems = [rebalance(client)]; + const transactionItems = [ + new TransactionItem(async () => ({ + tx: lendingPoolAccrueBankInterest(umi, { + marginfiGroup: publicKey( + "DQ2jqDJw9uzTwttf6h6r217BQ7kws3jZbJXDkfbCJa1q" + ), + bank: publicKey("EXrnNVfLagt3j4hCHSD9WqK75o6dkZBtjpnrSrSC78MA"), + }), + })), + ]; const txManager = new ClientTransactionsManager({ txHandler: client, @@ -64,6 +78,34 @@ export async function main() { }); const statuses = await txManager.send(transactionItems); consoleLog(statuses); + + await new Promise((resolve) => setTimeout(resolve, 5000)); + + const mfiAccount = await fetchMarginfiAccount( + umi, + publicKey("Fun9UD87tLCxqxoTvpGYAy6Uwk2eevFGDk1VvxpXbd5x") + ); + const bank = await fetchBank( + umi, + publicKey("EXrnNVfLagt3j4hCHSD9WqK75o6dkZBtjpnrSrSC78MA"), + { commitment: "confirmed" } + ); + + console.log( + fromBaseUnit( + BigInt( + Math.round( + bytesToI80F48( + mfiAccount.lendingAccount.balances[0].assetShares.value + ) * bytesToI80F48(bank.assetShareValue.value) + ) + ), + 6 + ) + ); + // 1:34pm - $4479.61 + // 2:51pm - $4513.30 + // 12:58pm - $4529.16 } async function refreshAll() { diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 35022904..79327ed6 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.761", + "version": "1.0.762", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/utils/numberUtils.ts b/solauto-sdk/src/utils/numberUtils.ts index 99b7e11a..b772da96 100644 --- a/solauto-sdk/src/utils/numberUtils.ts +++ b/solauto-sdk/src/utils/numberUtils.ts @@ -8,6 +8,8 @@ import { import { PositionState, PriceType } from "../generated"; import { RoundAction } from "../types"; import { safeGetPrice } from "./priceUtils"; +import { StrategyType, strategyType } from "./stringUtils"; +import { getDebtAdjustment } from "../services"; export function calcNetWorthUsd(state?: PositionState) { return fromRoundedUsdValue(state?.netWorth.baseAmountUsdValue ?? BigInt(0)); @@ -215,3 +217,32 @@ export function realtimeUsdToEmaUsd( safeGetPrice(mint, PriceType.Ema)! ); } + +export function boostSettingToLeverageFactor( + supplyMint: PublicKey, + debtMint: PublicKey, + boostToBps: number, + liqThresholdBps: number +) { + const strategy = strategyType(supplyMint, debtMint); + const supplyUsd = 100; + const debtUsd = getDebtAdjustment( + liqThresholdBps, + { supplyUsd: 100, debtUsd: 0 }, + boostToBps + ).debtAdjustmentUsd; + return getLeverageFactor(strategy, supplyUsd + debtUsd, debtUsd); +} + +export function getLeverageFactor( + strategyType: StrategyType, + supplyUsd: number, + debtUsd: number +): number { + return ( + (strategyType === "Long" || strategyType === "Ratio" + ? supplyUsd + : debtUsd) / + (supplyUsd - debtUsd) + ); +} From 3b76d0b25245470266c6c263bc679548af48d499 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 19 May 2025 15:21:47 -0400 Subject: [PATCH 35/88] fix sandbox --- solauto-sdk/local/txSandbox.ts | 46 ++-------------------------------- 1 file changed, 2 insertions(+), 44 deletions(-) diff --git a/solauto-sdk/local/txSandbox.ts b/solauto-sdk/local/txSandbox.ts index f454f301..688472ff 100644 --- a/solauto-sdk/local/txSandbox.ts +++ b/solauto-sdk/local/txSandbox.ts @@ -2,18 +2,14 @@ import { Keypair, PublicKey } from "@solana/web3.js"; import { createSignerFromKeypair, publicKey } from "@metaplex-foundation/umi"; import { fromWeb3JsKeypair } from "@metaplex-foundation/umi-web3js-adapters"; import { - bytesToI80F48, ClientTransactionsManager, consoleLog, - fetchBank, - fetchMarginfiAccount, getBatches, getClient, getPositionExBulk, getSolanaRpcConnection, getSolautoManagedPositions, LendingPlatform, - lendingPoolAccrueBankInterest, LOCAL_IRONFORGE_API_URL, PriceType, PriorityFeeSetting, @@ -25,9 +21,8 @@ import { TransactionItem, } from "../src"; import { getSecretKey } from "./shared"; -import { fromBaseUnit } from "../dist"; -const payForTransaction = true; +const payForTransaction = false; const testProgram = false; const lpEnv: ProgramEnv = "Prod"; @@ -59,16 +54,7 @@ export async function main() { // ), }); - const transactionItems = [ - new TransactionItem(async () => ({ - tx: lendingPoolAccrueBankInterest(umi, { - marginfiGroup: publicKey( - "DQ2jqDJw9uzTwttf6h6r217BQ7kws3jZbJXDkfbCJa1q" - ), - bank: publicKey("EXrnNVfLagt3j4hCHSD9WqK75o6dkZBtjpnrSrSC78MA"), - }), - })), - ]; + const transactionItems = [rebalance(client)]; const txManager = new ClientTransactionsManager({ txHandler: client, @@ -78,34 +64,6 @@ export async function main() { }); const statuses = await txManager.send(transactionItems); consoleLog(statuses); - - await new Promise((resolve) => setTimeout(resolve, 5000)); - - const mfiAccount = await fetchMarginfiAccount( - umi, - publicKey("Fun9UD87tLCxqxoTvpGYAy6Uwk2eevFGDk1VvxpXbd5x") - ); - const bank = await fetchBank( - umi, - publicKey("EXrnNVfLagt3j4hCHSD9WqK75o6dkZBtjpnrSrSC78MA"), - { commitment: "confirmed" } - ); - - console.log( - fromBaseUnit( - BigInt( - Math.round( - bytesToI80F48( - mfiAccount.lendingAccount.balances[0].assetShares.value - ) * bytesToI80F48(bank.assetShareValue.value) - ) - ), - 6 - ) - ); - // 1:34pm - $4479.61 - // 2:51pm - $4513.30 - // 12:58pm - $4529.16 } async function refreshAll() { From 9ed843754ed073d2c26983f902a83e73491e3901 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Tue, 20 May 2025 22:04:54 -0400 Subject: [PATCH 36/88] support marginfi changes --- .../src/services/solauto/solautoMarginfiClient.ts | 7 +++++-- solauto-sdk/src/utils/marginfi/general.ts | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts b/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts index 99bcd79a..602c52d2 100644 --- a/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts +++ b/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts @@ -37,6 +37,7 @@ import { hasFirstRebalance, getRemainingAccountsForMarginfiHealthCheck, getAccountMeta, + composeRemainingAccounts, } from "../../utils"; import { Bank, @@ -299,7 +300,7 @@ export class SolautoMarginfiClient extends SolautoClient { bankLiquidityVaultAuthority: publicKey( this.marginfiDebtAccounts.vaultAuthority ), - }).addRemainingAccounts(remainingAccounts); + }).addRemainingAccounts(composeRemainingAccounts(remainingAccounts)); } case "Repay": { return lendingAccountRepay(this.umi, { @@ -332,7 +333,9 @@ export class SolautoMarginfiClient extends SolautoClient { bankLiquidityVaultAuthority: publicKey( this.marginfiSupplyAccounts.vaultAuthority ), - }).addRemainingAccounts(this.healthCheckRemainingAccounts ?? []); + }).addRemainingAccounts( + composeRemainingAccounts(this.healthCheckRemainingAccounts ?? []) + ); } } } diff --git a/solauto-sdk/src/utils/marginfi/general.ts b/solauto-sdk/src/utils/marginfi/general.ts index 3d3a1a72..5a9ad505 100644 --- a/solauto-sdk/src/utils/marginfi/general.ts +++ b/solauto-sdk/src/utils/marginfi/general.ts @@ -224,3 +224,16 @@ export function marginfiAccountEmpty(marginfiAccount: MarginfiAccount) { ) === undefined ); } + +export function composeRemainingAccounts(accs: AccountMeta[]): AccountMeta[] { + const banksAndOracles: [AccountMeta, AccountMeta][] = accs.reduce( + (acc: [AccountMeta, AccountMeta][], _, i) => + i % 2 === 0 ? [...acc, [accs[i], accs[i + 1]]] : acc, + [] + ); + return banksAndOracles + .sort((a, b) => + b[0].pubkey.toString().localeCompare(a[0].pubkey.toString()) + ) + .flat(); +} From cee9086506c97ea8cdbfc4a1825cd4dcfa01282f Mon Sep 17 00:00:00 2001 From: Chelioso Date: Tue, 20 May 2025 22:06:06 -0400 Subject: [PATCH 37/88] formatting --- programs/solauto/src/clients/marginfi.rs | 35 ++++++++++++++++++++---- programs/solauto/src/types/shared.rs | 2 ++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/programs/solauto/src/clients/marginfi.rs b/programs/solauto/src/clients/marginfi.rs index a1c2c836..f96c89ee 100644 --- a/programs/solauto/src/clients/marginfi.rs +++ b/programs/solauto/src/clients/marginfi.rs @@ -28,8 +28,8 @@ use crate::{ }, lending_protocol::{LendingProtocolClient, LendingProtocolTokenAccounts}, shared::{ - DeserializedAccount, PriceType, RefreshStateProps, RefreshedTokenState, - TokenBalanceAmount, TokenType, + AccountMetaFlags, DeserializedAccount, PriceType, RefreshStateProps, + RefreshedTokenState, TokenBalanceAmount, TokenType, }, }, utils::{math_utils::*, solana_utils::*, solauto_utils::*, validation_utils::*}, @@ -416,6 +416,26 @@ impl<'a> MarginfiClient<'a> { ); cpi.invoke() } + + pub fn compose_remaining_accounts(accounts: Vec) -> Vec { + let mut banks_and_oracles: Vec<(AccountMetaFlags, AccountMetaFlags)> = accounts + .chunks(2) + .filter_map(|chunk| { + if chunk.len() == 2 { + Some((chunk[0], chunk[1])) + } else { + None + } + }) + .collect(); + + banks_and_oracles.sort_by(|a, b| b.0 .0.key.to_string().cmp(&a.0 .0.key.to_string())); + + banks_and_oracles + .into_iter() + .flat_map(|(a, b)| vec![a, b]) + .collect() + } } impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { @@ -552,7 +572,9 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { remaining_accounts.as_slice(), ) } else { - cpi.invoke_with_remaining_accounts(remaining_accounts.as_slice()) + cpi.invoke_with_remaining_accounts( + MarginfiClient::compose_remaining_accounts(remaining_accounts).as_slice(), + ) } } @@ -581,7 +603,8 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { }, ); - let mut remaining_accounts = Vec::with_capacity(4); + let mut remaining_accounts: Vec = + Vec::::with_capacity(4); remaining_accounts.push((self.supply.bank.account_info, false, false)); remaining_accounts.push((self.supply.price_oracle.unwrap(), false, false)); remaining_accounts.push((self.debt.bank.account_info, false, true)); @@ -597,7 +620,9 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { remaining_accounts.as_slice(), ) } else { - cpi.invoke_with_remaining_accounts(remaining_accounts.as_slice()) + cpi.invoke_with_remaining_accounts( + MarginfiClient::compose_remaining_accounts(remaining_accounts).as_slice(), + ) } } diff --git a/programs/solauto/src/types/shared.rs b/programs/solauto/src/types/shared.rs index 1212defd..c2e31943 100644 --- a/programs/solauto/src/types/shared.rs +++ b/programs/solauto/src/types/shared.rs @@ -179,3 +179,5 @@ impl<'a, T: Pack + IsInitialized> DeserializedAccount<'a, T> { } } } + +pub type AccountMetaFlags<'a> = (&'a AccountInfo<'a>, bool, bool); From 66c75e4df2151dca62c785ddc59b17eef5d906f6 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sat, 24 May 2025 17:07:25 -0400 Subject: [PATCH 38/88] fix missing piece --- solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts b/solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts index a9dec13f..f7fdb0a7 100644 --- a/solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts +++ b/solauto-sdk/src/services/flashLoans/marginfiFlProvider.ts @@ -23,6 +23,7 @@ import { import { FlProviderBase } from "./flProviderBase"; import { bytesToI80F48, + composeRemainingAccounts, consoleLog, fetchTokenPrices, findMarginfiAccounts, @@ -342,7 +343,7 @@ export class MarginfiFlProvider extends FlProviderBase { lendingAccountEndFlashloan(this.umi, { marginfiAccount: publicKey(iMfiAccount.accountPk), signer: this.signer, - }).addRemainingAccounts(remainingAccounts) + }).addRemainingAccounts(composeRemainingAccounts(remainingAccounts)) ); } From 7a67b2627a3c3adec620ca0927e58722dd153985 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sun, 25 May 2025 12:21:11 -0400 Subject: [PATCH 39/88] fixes --- .../marginfi-sdk/src/generated/programs.rs | 2 +- programs/solauto/src/clients/marginfi.rs | 4 ++-- .../solauto/src/instructions/rebalance.rs | 4 ++-- .../rebalance/rebalanceSwapManager.ts | 14 ------------- .../services/rebalance/rebalanceTxBuilder.ts | 2 +- .../services/solauto/solautoMarginfiClient.ts | 20 ++++++++++++++++--- .../marginfiSolautoPositionEx.ts | 2 +- solauto-sdk/tests/transactions/shared.ts | 7 +++++-- .../tests/transactions/solautoMarginfi.ts | 10 +++++++--- 9 files changed, 36 insertions(+), 29 deletions(-) diff --git a/programs/marginfi-sdk/src/generated/programs.rs b/programs/marginfi-sdk/src/generated/programs.rs index bd4b2e1e..4e88f74a 100644 --- a/programs/marginfi-sdk/src/generated/programs.rs +++ b/programs/marginfi-sdk/src/generated/programs.rs @@ -7,5 +7,5 @@ use solana_program::{pubkey, pubkey::Pubkey}; -/// `marginfi` program ID. pub const MARGINFI_ID: Pubkey = pubkey!("MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA"); +// pub const MARGINFI_ID: Pubkey = pubkey!("stag8sTKds2h4KzjUw3zKTsxbqvT4XKHdaR9X9E6Rct"); diff --git a/programs/solauto/src/clients/marginfi.rs b/programs/solauto/src/clients/marginfi.rs index f96c89ee..935fc3e7 100644 --- a/programs/solauto/src/clients/marginfi.rs +++ b/programs/solauto/src/clients/marginfi.rs @@ -569,7 +569,7 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { .data .seeds_with_bump() .as_slice()], - remaining_accounts.as_slice(), + MarginfiClient::compose_remaining_accounts(remaining_accounts).as_slice(), ) } else { cpi.invoke_with_remaining_accounts( @@ -617,7 +617,7 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { .data .seeds_with_bump() .as_slice()], - remaining_accounts.as_slice(), + MarginfiClient::compose_remaining_accounts(remaining_accounts).as_slice(), ) } else { cpi.invoke_with_remaining_accounts( diff --git a/programs/solauto/src/instructions/rebalance.rs b/programs/solauto/src/instructions/rebalance.rs index e78bc336..ee0534ae 100644 --- a/programs/solauto/src/instructions/rebalance.rs +++ b/programs/solauto/src/instructions/rebalance.rs @@ -71,7 +71,7 @@ pub fn marginfi_rebalance<'a>( if rebalance_step == RebalanceStep::PreSwap || rebalance_type == SolautoRebalanceType::FLSwapThenRebalance { - if needs_refresh(&std_accounts.solauto_position, &args)? { + if needs_refresh(&std_accounts.solauto_position)? { refresh::marginfi_refresh_accounts( ctx.accounts.marginfi_program, ctx.accounts.marginfi_group, @@ -131,7 +131,6 @@ fn update_token_prices<'a>( fn needs_refresh( solauto_position: &DeserializedAccount, - args: &RebalanceSettings, ) -> Result { if solauto_position.data.self_managed.val { return Ok(true); @@ -163,6 +162,7 @@ fn rebalance<'a>( std_accounts.authority_referral_state.is_some(), SolautoError::IncorrectAccounts ); + #[cfg(not(feature = "test"))] check!( args.flash_loan_fee_bps.unwrap_or(0) <= 150, SolautoError::IncorrectInstructions diff --git a/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts b/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts index 86f3a35d..a1e576d7 100644 --- a/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts +++ b/solauto-sdk/src/services/rebalance/rebalanceSwapManager.ts @@ -134,20 +134,6 @@ export class RebalanceSwapManager { } ); - // if (isMarginfiPosition(this.client.pos)) { - // console.log(res.newPos.supplyUsd, res.newPos.debtUsd); - // console.log( - // res.newPos.supplyUsd * - // bytesToI80F48( - // this.client.pos.supplyBank!.config.assetWeightInit.value - // ), - // res.newPos.debtUsd * - // bytesToI80F48( - // this.client.pos.debtBank!.config.liabilityWeightInit.value - // ) - // ); - // } - return getLiqUtilzationRateBps( res.newPos.supplyUsd, res.newPos.debtUsd, diff --git a/solauto-sdk/src/services/rebalance/rebalanceTxBuilder.ts b/solauto-sdk/src/services/rebalance/rebalanceTxBuilder.ts index a106b4d2..e3be74db 100644 --- a/solauto-sdk/src/services/rebalance/rebalanceTxBuilder.ts +++ b/solauto-sdk/src/services/rebalance/rebalanceTxBuilder.ts @@ -53,7 +53,7 @@ export class RebalanceTxBuilder { ) {} private shouldProceedWithRebalance() { - if (this.client.pos.selfManaged && !this.targetLiqUtilizationRateBps) { + if (this.client.pos.selfManaged && this.targetLiqUtilizationRateBps === undefined) { throw new Error( "A target rate must be provided for self managed position rebalances" ); diff --git a/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts b/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts index 602c52d2..e8960501 100644 --- a/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts +++ b/solauto-sdk/src/services/solauto/solautoMarginfiClient.ts @@ -62,7 +62,7 @@ export class SolautoMarginfiClient extends SolautoClient { public marginfiAccount!: PublicKey | Signer; public marginfiAccountPk!: PublicKey; - public healthCheckRemainingAccounts?: AccountMeta[]; + public healthCheckRemainingAccounts!: AccountMeta[]; public marginfiGroup!: PublicKey; public marginfiSupplyAccounts!: MarginfiAssetAccounts; @@ -77,6 +77,7 @@ export class SolautoMarginfiClient extends SolautoClient { this.mfiAccounts = getMarginfiAccounts(this.lpEnv); this.marginfiGroup = this.pos.lpPoolAccount; + this.healthCheckRemainingAccounts = []; if (this.pos.selfManaged) { this.marginfiAccount = @@ -259,6 +260,18 @@ export class SolautoMarginfiClient extends SolautoClient { private marginfiProtocolInteractionIx(args: SolautoActionArgs) { switch (args.__kind) { case "Deposit": { + if ( + !this.healthCheckRemainingAccounts + .map((x) => x.pubkey.toString()) + .includes(this.marginfiSupplyAccounts.bank) + ) { + this.healthCheckRemainingAccounts.push( + ...[ + getAccountMeta(new PublicKey(this.marginfiSupplyAccounts.bank)), + getAccountMeta(this.supplyPriceOracle), + ] + ); + } return lendingAccountDeposit(this.umi, { signer: this.signer, signerTokenAccount: publicKey(this.signerSupplyTa), @@ -273,7 +286,7 @@ export class SolautoMarginfiClient extends SolautoClient { }); } case "Borrow": { - const remainingAccounts = this.healthCheckRemainingAccounts ?? []; + const remainingAccounts = this.healthCheckRemainingAccounts; if ( !remainingAccounts.find( (x) => @@ -287,6 +300,7 @@ export class SolautoMarginfiClient extends SolautoClient { ] ); } + return lendingAccountBorrow(this.umi, { amount: args.fields[0], signer: this.signer, @@ -334,7 +348,7 @@ export class SolautoMarginfiClient extends SolautoClient { this.marginfiSupplyAccounts.vaultAuthority ), }).addRemainingAccounts( - composeRemainingAccounts(this.healthCheckRemainingAccounts ?? []) + composeRemainingAccounts(this.healthCheckRemainingAccounts) ); } } diff --git a/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts b/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts index e959157b..b7d9e6f9 100644 --- a/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts +++ b/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts @@ -138,7 +138,7 @@ export class MarginfiSolautoPositionEx extends SolautoPositionEx { getBankLiquidityUsedBaseUnit(this.supplyBank, false), this.supplyMintInfo.decimals ); - return Math.min((deposits - borrows), this.totalSupply) * this.supplyPrice()!; + return Math.min(deposits - borrows, this.totalSupply) * this.supplyPrice()!; } async refreshPositionState(priceType?: PriceType): Promise { diff --git a/solauto-sdk/tests/transactions/shared.ts b/solauto-sdk/tests/transactions/shared.ts index 4394e2ca..7310e18c 100644 --- a/solauto-sdk/tests/transactions/shared.ts +++ b/solauto-sdk/tests/transactions/shared.ts @@ -22,6 +22,7 @@ import { closeSolautoPosition, getMarginfiAccounts, ClientTransactionsManager, + ProgramEnv, } from "../../src"; export async function e2eTransactionTest( @@ -29,13 +30,15 @@ export async function e2eTransactionTest( testProgram: boolean, lendingPlatform: LendingPlatform, withFlashLoan: boolean, - showLogs?: boolean + showLogs?: boolean, + lpEnv?: ProgramEnv ) { const client = getClient(lendingPlatform, { signer, showLogs, rpcUrl: LOCAL_IRONFORGE_API_URL, programId: testProgram ? SOLAUTO_TEST_PROGRAM : SOLAUTO_PROD_PROGRAM, + lpEnv, }); const supplyMint = new PublicKey(NATIVE_MINT); @@ -43,7 +46,7 @@ export async function e2eTransactionTest( await client.initializeNewSolautoPosition({ positionId: 1, - lpPoolAccount: getMarginfiAccounts().defaultGroup, + lpPoolAccount: getMarginfiAccounts(lpEnv).defaultGroup, supplyMint, debtMint, }); diff --git a/solauto-sdk/tests/transactions/solautoMarginfi.ts b/solauto-sdk/tests/transactions/solautoMarginfi.ts index a04d44f4..b8b02e3a 100644 --- a/solauto-sdk/tests/transactions/solautoMarginfi.ts +++ b/solauto-sdk/tests/transactions/solautoMarginfi.ts @@ -1,11 +1,13 @@ import { describe, it } from "mocha"; -import { LendingPlatform } from "../../src"; +import { LendingPlatform, ProgramEnv } from "../../src"; import { setupTest } from "../shared"; import { e2eTransactionTest } from "./shared"; describe("Solauto Marginfi tests", async () => { const signer = setupTest(); const testProgram = false; + const showLogs = false; + const lpEnv: ProgramEnv = "Prod"; it("open - deposit - borrow - rebalance to 0 - withdraw - close", async () => { await e2eTransactionTest( @@ -13,7 +15,8 @@ describe("Solauto Marginfi tests", async () => { testProgram, LendingPlatform.Marginfi, false, - false + showLogs, + lpEnv ); }); @@ -23,7 +26,8 @@ describe("Solauto Marginfi tests", async () => { testProgram, LendingPlatform.Marginfi, true, - false + showLogs, + lpEnv ); }); }); From 729cffa4dd3ff8c8e1e3592bb946e87b284e11a8 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sun, 25 May 2025 13:15:13 -0400 Subject: [PATCH 40/88] slight change --- programs/solauto/src/rebalance/solauto_fees.rs | 2 +- solauto-sdk/src/services/rebalance/solautoFees.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/solauto/src/rebalance/solauto_fees.rs b/programs/solauto/src/rebalance/solauto_fees.rs index 1b07823a..d0e7bb24 100644 --- a/programs/solauto/src/rebalance/solauto_fees.rs +++ b/programs/solauto/src/rebalance/solauto_fees.rs @@ -62,7 +62,7 @@ impl SolautoFeesBps { let mut fee_bps: f64; if self.target_liq_utilization_rate_bps.is_some() { - fee_bps = 10.0; + fee_bps = 15.0; } else if rebalance_direction == &RebalanceDirection::Repay { fee_bps = 25.0; } else if self.position_net_worth_usd <= min_size { diff --git a/solauto-sdk/src/services/rebalance/solautoFees.ts b/solauto-sdk/src/services/rebalance/solautoFees.ts index a4e3bc98..9d70cd1e 100644 --- a/solauto-sdk/src/services/rebalance/solautoFees.ts +++ b/solauto-sdk/src/services/rebalance/solautoFees.ts @@ -29,7 +29,7 @@ export class SolautoFeesBps { let feeBps: number = 0; if (this.targetLiqUtilizationRateBps !== undefined) { - feeBps = 10; + feeBps = 15; } else if (rebalanceDirection === RebalanceDirection.Repay) { feeBps = 25; } else if (this.positionNetWorthUsd <= minSize) { From 1b818179cdf05afaa7176c9a6f690f46f1e4d04d Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sun, 25 May 2025 13:43:05 -0400 Subject: [PATCH 41/88] adjust threshold --- programs/solauto/src/utils/validation_utils.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/solauto/src/utils/validation_utils.rs b/programs/solauto/src/utils/validation_utils.rs index fd101cca..17303cd4 100644 --- a/programs/solauto/src/utils/validation_utils.rs +++ b/programs/solauto/src/utils/validation_utils.rs @@ -444,11 +444,11 @@ pub fn validate_rebalance(solauto_position: &SolautoPosition) -> ProgramResult { curr_debt_usd ); check!( - value_gte_with_threshold(curr_supply_usd, target_supply_usd, 0.2), + value_gte_with_threshold(curr_supply_usd, target_supply_usd, 0.15), SolautoError::InvalidRebalanceMade ); check!( - value_lte_with_threshold(curr_debt_usd, target_debt_usd, 0.2), + value_lte_with_threshold(curr_debt_usd, target_debt_usd, 0.15), SolautoError::InvalidRebalanceMade ); From 2b9fa871f4c095fc0329f8bce2550a04deb76f7d Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sun, 25 May 2025 22:10:49 -0400 Subject: [PATCH 42/88] adjustment --- programs/solauto/src/rebalance/solauto_fees.rs | 6 +++++- solauto-sdk/src/services/rebalance/solautoFees.ts | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/programs/solauto/src/rebalance/solauto_fees.rs b/programs/solauto/src/rebalance/solauto_fees.rs index d0e7bb24..d033de4b 100644 --- a/programs/solauto/src/rebalance/solauto_fees.rs +++ b/programs/solauto/src/rebalance/solauto_fees.rs @@ -62,7 +62,11 @@ impl SolautoFeesBps { let mut fee_bps: f64; if self.target_liq_utilization_rate_bps.is_some() { - fee_bps = 15.0; + if self.target_liq_utilization_rate_bps.unwrap() == 0 { + fee_bps = 15.0; + } else { + fee_bps = 10.0; + } } else if rebalance_direction == &RebalanceDirection::Repay { fee_bps = 25.0; } else if self.position_net_worth_usd <= min_size { diff --git a/solauto-sdk/src/services/rebalance/solautoFees.ts b/solauto-sdk/src/services/rebalance/solautoFees.ts index 9d70cd1e..b3a4d753 100644 --- a/solauto-sdk/src/services/rebalance/solautoFees.ts +++ b/solauto-sdk/src/services/rebalance/solautoFees.ts @@ -29,7 +29,11 @@ export class SolautoFeesBps { let feeBps: number = 0; if (this.targetLiqUtilizationRateBps !== undefined) { - feeBps = 15; + if (this.targetLiqUtilizationRateBps === 0) { + feeBps = 15; + } else { + feeBps = 10; + } } else if (rebalanceDirection === RebalanceDirection.Repay) { feeBps = 25; } else if (this.positionNetWorthUsd <= minSize) { From 724fe6ab106a0b1a9c83b8ff977351ff2241dfb5 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 26 May 2025 15:49:48 -0400 Subject: [PATCH 43/88] remove unused import --- programs/solauto/src/types/solauto.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/solauto/src/types/solauto.rs b/programs/solauto/src/types/solauto.rs index f7aa5398..83602ba1 100644 --- a/programs/solauto/src/types/solauto.rs +++ b/programs/solauto/src/types/solauto.rs @@ -1,4 +1,4 @@ -use super::shared::{TokenBalanceAmount, TokenType}; +use super::shared::TokenBalanceAmount; #[derive(Clone, Copy, Eq, PartialEq, Hash)] pub enum SolautoAccount { From f1f56bdf22d79285ea407da3cd95794810d3771e Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 26 May 2025 17:10:03 -0400 Subject: [PATCH 44/88] fixes --- package.json | 1 + programs/marginfi-sdk/Cargo.toml | 5 +++++ programs/marginfi-sdk/src/generated/programs.rs | 7 +++++-- programs/solauto/Cargo.toml | 4 ++-- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index c81239e0..c4fdafb6 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "push": "git add . && git commit -m 'wip' && git push", "format:rust": "find ./programs/* -name '*.rs' -exec rustfmt {} +", "build:rs:local": "cargo build-sbf -- --package solauto --features local", + "build:rs:staging": "cargo build-sbf -- --package solauto --features \"test staging\"", "build:rs:test": "cargo build-sbf -- --package solauto --features test", "build:rs:prod": "solana-verify build --library-name solauto --base-image solanafoundation/solana-verifiable-build@sha256:f3d3a4adaa8008644fc4535373c6818275c7e35a0b07660890b4a95ef434221e", "build:ts": "cd solauto-sdk && npm run build", diff --git a/programs/marginfi-sdk/Cargo.toml b/programs/marginfi-sdk/Cargo.toml index b4eb34c2..02b0bc4e 100644 --- a/programs/marginfi-sdk/Cargo.toml +++ b/programs/marginfi-sdk/Cargo.toml @@ -3,6 +3,11 @@ name = "marginfi-sdk" version = "0.1.0" edition = "2021" +[features] +default = [] +test = [] +staging = [] + [dependencies] solana-program = ">=1.16" borsh = "^0.10" diff --git a/programs/marginfi-sdk/src/generated/programs.rs b/programs/marginfi-sdk/src/generated/programs.rs index 4e88f74a..fa7763f8 100644 --- a/programs/marginfi-sdk/src/generated/programs.rs +++ b/programs/marginfi-sdk/src/generated/programs.rs @@ -5,7 +5,10 @@ //! [https://github.com/metaplex-foundation/kinobi] //! -use solana_program::{pubkey, pubkey::Pubkey}; +use solana_program::{ pubkey, pubkey::Pubkey }; +#[cfg(feature = "staging")] +pub const MARGINFI_ID: Pubkey = pubkey!("stag8sTKds2h4KzjUw3zKTsxbqvT4XKHdaR9X9E6Rct"); + +#[cfg(not(feature = "staging"))] pub const MARGINFI_ID: Pubkey = pubkey!("MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA"); -// pub const MARGINFI_ID: Pubkey = pubkey!("stag8sTKds2h4KzjUw3zKTsxbqvT4XKHdaR9X9E6Rct"); diff --git a/programs/solauto/Cargo.toml b/programs/solauto/Cargo.toml index bdb23caa..c2ea350e 100644 --- a/programs/solauto/Cargo.toml +++ b/programs/solauto/Cargo.toml @@ -14,8 +14,8 @@ no-idl = [] no-log-ix-name = [] cpi = ["no-entrypoint"] default = [] -test = [] -local = [] +test = ["marginfi-sdk/test"] +staging = ["marginfi-sdk/staging"] [net] git-fetch-with-cli = true From be831672a52b97e222e7b03b6f9c767d19e0c3ae Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 26 May 2025 20:58:25 -0400 Subject: [PATCH 45/88] bump --- solauto-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 79327ed6..77a7db04 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.762", + "version": "1.0.763", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", From a7386db681efb881a68d481bae209c902860ff04 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Thu, 29 May 2025 21:07:15 -0400 Subject: [PATCH 46/88] increase jito tip --- solauto-sdk/package.json | 2 +- solauto-sdk/src/utils/jitoUtils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 77a7db04..78a9d946 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.763", + "version": "1.0.764", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/utils/jitoUtils.ts b/solauto-sdk/src/utils/jitoUtils.ts index e65a623a..810a3a1e 100644 --- a/solauto-sdk/src/utils/jitoUtils.ts +++ b/solauto-sdk/src/utils/jitoUtils.ts @@ -301,7 +301,7 @@ export async function sendJitoBundledTransactions( txs.map((x) => x.getTransactionSize(umi)) ); - txs[0] = txs[0].prepend(getTipInstruction(userSigner, 150_000)); + txs[0] = txs[0].prepend(getTipInstruction(userSigner, 250_000)); const latestBlockhash = ( await umi.rpc.getLatestBlockhash({ commitment: "confirmed" }) From 21a740e8b598db71eb5abe9a05bb96c73bf316c3 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 30 May 2025 13:05:59 -0400 Subject: [PATCH 47/88] tweaks --- solauto-sdk/local/txSandbox.ts | 4 ++-- solauto-sdk/package.json | 2 +- solauto-sdk/src/utils/jitoUtils.ts | 8 ++++++-- solauto-sdk/src/utils/solanaUtils.ts | 10 +++++++--- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/solauto-sdk/local/txSandbox.ts b/solauto-sdk/local/txSandbox.ts index 688472ff..a4f7f4a0 100644 --- a/solauto-sdk/local/txSandbox.ts +++ b/solauto-sdk/local/txSandbox.ts @@ -22,7 +22,7 @@ import { } from "../src"; import { getSecretKey } from "./shared"; -const payForTransaction = false; +const payForTransaction = true; const testProgram = false; const lpEnv: ProgramEnv = "Prod"; @@ -48,7 +48,7 @@ export async function main() { await client.initializeExistingSolautoPosition({ positionId: 1, - authority: new PublicKey("5UqsR2PGzbP8pGPbXEeXx86Gjz2N2UFBAuFZUSVydAEe"), + authority: new PublicKey("61rtn5tzVkesapo6Cz83SPoShUfAePSxJsqniuF2wRKC"), // lpUserAccount: new PublicKey( // "GEokw9jqbh6d1xUNA3qaeYFFetbSR5Y1nt7C3chwwgSz" // ), diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 78a9d946..897b8865 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.764", + "version": "1.0.767", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/utils/jitoUtils.ts b/solauto-sdk/src/utils/jitoUtils.ts index 810a3a1e..d326bca9 100644 --- a/solauto-sdk/src/utils/jitoUtils.ts +++ b/solauto-sdk/src/utils/jitoUtils.ts @@ -304,7 +304,9 @@ export async function sendJitoBundledTransactions( txs[0] = txs[0].prepend(getTipInstruction(userSigner, 250_000)); const latestBlockhash = ( - await umi.rpc.getLatestBlockhash({ commitment: "confirmed" }) + await retryWithExponentialBackoff( + async () => await umi.rpc.getLatestBlockhash({ commitment: "confirmed" }) + ) ).blockhash; if (abortController?.signal.aborted) { @@ -322,7 +324,9 @@ export async function sendJitoBundledTransactions( txs, false, undefined, - Array(txs.length).fill(null).map((_) => 1_400_000) + Array(txs.length) + .fill(null) + .map((_) => 1_400_000) ); simulationResults = await simulateJitoBundle(umi, builtTxs); } diff --git a/solauto-sdk/src/utils/solanaUtils.ts b/solauto-sdk/src/utils/solanaUtils.ts index 360fde99..b2cec155 100644 --- a/solauto-sdk/src/utils/solanaUtils.ts +++ b/solauto-sdk/src/utils/solanaUtils.ts @@ -387,7 +387,7 @@ async function spamSendTransactionUntilConfirmed( blockhash: BlockhashWithExpiryBlockHeight, spamInterval: number = 1500 ): Promise { - let transactionSignature: string | null = null; + let transactionSignature: string | undefined; const sendTx = async () => { try { @@ -395,7 +395,9 @@ async function spamSendTransactionUntilConfirmed( Buffer.from(transaction.serialize()), { skipPreflight: true, maxRetries: 0 } ); - transactionSignature = txSignature; + if (!transactionSignature) { + transactionSignature = txSignature; + } consoleLog(`Transaction sent`); } catch (e) {} }; @@ -451,7 +453,9 @@ export async function sendSingleOptimizedTransaction( ]); consoleLog("Unique account locks: ", Array.from(new Set(accounts)).length); - const blockhash = await connection.getLatestBlockhash("confirmed"); + const blockhash = await retryWithExponentialBackoff( + async () => await connection.getLatestBlockhash("confirmed") + ); if (abortController?.signal.aborted) { return; From a946e9c7e1c6547dea1cf20d8913a8f67c886258 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 30 May 2025 21:49:00 -0400 Subject: [PATCH 48/88] updates --- solauto-sdk/package.json | 2 +- solauto-sdk/src/utils/solanaUtils.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 897b8865..51dd01ee 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.767", + "version": "1.0.769", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/utils/solanaUtils.ts b/solauto-sdk/src/utils/solanaUtils.ts index b2cec155..0e752a47 100644 --- a/solauto-sdk/src/utils/solanaUtils.ts +++ b/solauto-sdk/src/utils/solanaUtils.ts @@ -393,7 +393,7 @@ async function spamSendTransactionUntilConfirmed( try { const txSignature = await connection.sendRawTransaction( Buffer.from(transaction.serialize()), - { skipPreflight: true, maxRetries: 0 } + { skipPreflight: true, maxRetries: 3 } ); if (!transactionSignature) { transactionSignature = txSignature; @@ -409,7 +409,7 @@ async function spamSendTransactionUntilConfirmed( }, spamInterval); if (!transactionSignature) { - throw new Error("Failed to send"); + throw new Error("No transaction signature found"); } const resp = await connection From 8356c77abedecb28b817e9c3331f43221be4708a Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 2 Jun 2025 22:43:20 -0400 Subject: [PATCH 49/88] fixes --- solauto-sdk/package.json | 2 +- solauto-sdk/src/services/swap/jupSwapManager.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 51dd01ee..1d012e94 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.769", + "version": "1.0.770", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/swap/jupSwapManager.ts b/solauto-sdk/src/services/swap/jupSwapManager.ts index 6ca7e97d..f81ae776 100644 --- a/solauto-sdk/src/services/swap/jupSwapManager.ts +++ b/solauto-sdk/src/services/swap/jupSwapManager.ts @@ -80,6 +80,7 @@ export class JupSwapManager { !data.exactOut && this.limitSize ? (lowLiquidityMint ? 25 : 15) + attemptNum * 5 : undefined, + excludeDexes: ["obric"], }), 6, 250 @@ -159,6 +160,7 @@ export class JupSwapManager { this.adaptSlippageToPriceImpact(data.slippageIncFactor); } consoleLog("Quote:", this.jupQuote); + consoleLog("route plan", this.jupQuote.routePlan); const instructions = await this.getJupInstructions(data); From c6a1f7e9c583f4cdd3d08e27c424d1c359dc9800 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Thu, 5 Jun 2025 01:51:24 -0400 Subject: [PATCH 50/88] filter obric out --- solauto-sdk/package.json | 2 +- solauto-sdk/src/services/swap/jupSwapManager.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 1d012e94..66ffcb91 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.770", + "version": "1.0.771", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/swap/jupSwapManager.ts b/solauto-sdk/src/services/swap/jupSwapManager.ts index f81ae776..e2b4e659 100644 --- a/solauto-sdk/src/services/swap/jupSwapManager.ts +++ b/solauto-sdk/src/services/swap/jupSwapManager.ts @@ -80,7 +80,7 @@ export class JupSwapManager { !data.exactOut && this.limitSize ? (lowLiquidityMint ? 25 : 15) + attemptNum * 5 : undefined, - excludeDexes: ["obric"], + excludeDexes: ["Obric V2"], }), 6, 250 From 374e1f9825ec0cde17c126ec4b14413519cbf4bf Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 6 Jun 2025 17:34:38 -0400 Subject: [PATCH 51/88] get rid of patch lut --- solauto-sdk/local/patchLUT.ts | 3 +-- solauto-sdk/src/constants/solautoConstants.ts | 12 ------------ solauto-sdk/src/services/solauto/solautoClient.ts | 12 +----------- 3 files changed, 2 insertions(+), 25 deletions(-) diff --git a/solauto-sdk/local/patchLUT.ts b/solauto-sdk/local/patchLUT.ts index 14c8cc3d..63d73b08 100644 --- a/solauto-sdk/local/patchLUT.ts +++ b/solauto-sdk/local/patchLUT.ts @@ -10,7 +10,6 @@ import { getSolautoManagedPositions, getTokenAccount, LOCAL_IRONFORGE_API_URL, - PATCH_LUT, SOLAUTO_PROD_PROGRAM, } from "../src"; import { PublicKey } from "@solana/web3.js"; @@ -93,5 +92,5 @@ async function getMissingAccounts() { } getMissingAccounts().then(async (accs) => { - await updateLookupTable(accs, new PublicKey(PATCH_LUT)); + // await updateLookupTable(accs, new PublicKey(PATCH_LUT)); }); diff --git a/solauto-sdk/src/constants/solautoConstants.ts b/solauto-sdk/src/constants/solautoConstants.ts index 338fd833..9f6af971 100644 --- a/solauto-sdk/src/constants/solautoConstants.ts +++ b/solauto-sdk/src/constants/solautoConstants.ts @@ -65,15 +65,3 @@ export const STANDARD_LUT_ACCOUNTS = [ SYSVAR_INSTRUCTIONS_PUBKEY, JUPITER_PROGRAM_ID, ].map((x) => x.toString()); - -// TODO: remove me -export const PATCH_LUT = "CmPZfu3tkeoMutytxhVKT7Hemuwd5jM65VdLNGdBddxQ"; -export const AUTHORITIES_REQUIRING_PATCH_LUT = [ - 'BRgwGasCSz1zA4yqdcvurAGV7ZroAJ9bvDNvdYj7az4X', - '5UqsR2PGzbP8pGPbXEeXx86Gjz2N2UFBAuFZUSVydAEe', - 'HLDgPtVv2Yyzzze462P89igFnyLxaCM3f9hVFmCuAX97', - 'C4cnE5kDRRnqfiLuWShvoGNDstq6yk91N2PWTxQ6Hmk2', - '8Vo5ScTZ1qNTYhMEibq2fekRe5DotmdqpcD2nprmRzJg', - 'F2uk8zsKMex8MztU7saFNq6tNbj4esWnKLJXyfo2egax', - '9PCRbk8Gvt2zqewLKbxaSyTxA2JMtdQGhMff8EdELXNq' -]; diff --git a/solauto-sdk/src/services/solauto/solautoClient.ts b/solauto-sdk/src/services/solauto/solautoClient.ts index 364428db..074ec385 100644 --- a/solauto-sdk/src/services/solauto/solautoClient.ts +++ b/solauto-sdk/src/services/solauto/solautoClient.ts @@ -29,12 +29,7 @@ import { splTokenTransferUmiIx, ContextUpdates, } from "../../utils"; -import { - AUTHORITIES_REQUIRING_PATCH_LUT, - PATCH_LUT, - SOLAUTO_FEES_WALLET, - SOLAUTO_LUT, -} from "../../constants"; +import { SOLAUTO_FEES_WALLET, SOLAUTO_LUT } from "../../constants"; import { ProgramEnv, RebalanceDetails } from "../../types"; import { ReferralStateManager, @@ -226,11 +221,6 @@ export abstract class SolautoClient extends ReferralStateManager { ...(this.authorityLutAddress ? [this.authorityLutAddress.toString()] : []), - ...(AUTHORITIES_REQUIRING_PATCH_LUT.includes( - this.pos.authority.toString() - ) - ? [PATCH_LUT] - : []), ]; } From b9e81e93f730f52732a85da1dca2f30ec8c19069 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 6 Jun 2025 19:59:52 -0400 Subject: [PATCH 52/88] bump api version --- solauto-sdk/package.json | 2 +- solauto-sdk/src/utils/solanaUtils.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 66ffcb91..47988421 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.771", + "version": "1.0.772", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/utils/solanaUtils.ts b/solauto-sdk/src/utils/solanaUtils.ts index 0e752a47..6fe31bc5 100644 --- a/solauto-sdk/src/utils/solanaUtils.ts +++ b/solauto-sdk/src/utils/solanaUtils.ts @@ -331,6 +331,7 @@ export async function getQnComputeUnitPriceEstimate( return await customRpcCall(umi, "qn_estimatePriorityFees", { last_n_blocks: blockheight, account: programId.toString(), + api_version: 2 }); } From 7a6d9a5353cc81b4b5c81fb9d5a5ac99fbe87a60 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 9 Jun 2025 19:28:14 -0400 Subject: [PATCH 53/88] bump --- solauto-sdk/package.json | 2 +- solauto-sdk/src/utils/generalUtils.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 47988421..435b4b24 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.772", + "version": "1.0.773", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/utils/generalUtils.ts b/solauto-sdk/src/utils/generalUtils.ts index 02b87fbc..8623faca 100644 --- a/solauto-sdk/src/utils/generalUtils.ts +++ b/solauto-sdk/src/utils/generalUtils.ts @@ -186,6 +186,9 @@ export async function customRpcCall(umi: Umi, method: string, params?: any) { if ("result" in data) { return data.result; } else { + if ("error" in data) { + console.log(JSON.stringify(data.error)); + } return data; } } From 5edcdda03d7da5bf59ad82e0b5d06dd8bafbe181 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Wed, 11 Jun 2025 13:28:57 -0400 Subject: [PATCH 54/88] fix price bias --- .../src/services/rebalance/rebalanceValues.ts | 4 +-- .../marginfiSolautoPositionEx.ts | 20 ++++++++++++--- .../src/solautoPosition/solautoPositionEx.ts | 25 +++++++++++-------- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/solauto-sdk/src/services/rebalance/rebalanceValues.ts b/solauto-sdk/src/services/rebalance/rebalanceValues.ts index bd4de076..d188f20f 100644 --- a/solauto-sdk/src/services/rebalance/rebalanceValues.ts +++ b/solauto-sdk/src/services/rebalance/rebalanceValues.ts @@ -132,12 +132,12 @@ function getTargetLiqUtilizationRateBps( } if ( - solautoPosition.liqUtilizationRateBps(PriceType.Realtime) + (bpsDistanceFromRebalance ?? 0) >= + solautoPosition.liqUtilizationRateBps(PriceType.Realtime, true) + (bpsDistanceFromRebalance ?? 0) >= solautoPosition.repayFromBps ) { return solautoPosition.settings!.repayToBps; } else if ( - solautoPosition.liqUtilizationRateBps(priceType) - (bpsDistanceFromRebalance ?? 0) <= + solautoPosition.liqUtilizationRateBps(priceType, true) - (bpsDistanceFromRebalance ?? 0) <= solautoPosition.boostFromBps ) { return solautoPosition.settings!.boostToBps; diff --git a/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts b/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts index b7d9e6f9..417b0ed9 100644 --- a/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts +++ b/solauto-sdk/src/solautoPosition/marginfiSolautoPositionEx.ts @@ -25,16 +25,28 @@ export class MarginfiSolautoPositionEx extends SolautoPositionEx { public supplyBank: Bank | null = null; public debtBank: Bank | null = null; - supplyPrice(priceType?: PriceType): number | undefined { + supplyPrice( + priceType?: PriceType, + withoutBias?: boolean + ): number | undefined { return ( this._supplyPrice ?? - safeGetPrice(this.supplyMint, priceType, PriceBias.Low) + safeGetPrice( + this.supplyMint, + priceType, + !withoutBias ? PriceBias.Low : undefined + ) ); } - debtPrice(priceType?: PriceType): number | undefined { + debtPrice(priceType?: PriceType, withoutBias?: boolean): number | undefined { return ( - this._debtPrice ?? safeGetPrice(this.debtMint, priceType, PriceBias.High) + this._debtPrice ?? + safeGetPrice( + this.debtMint, + priceType, + !withoutBias ? PriceBias.High : undefined + ) ); } diff --git a/solauto-sdk/src/solautoPosition/solautoPositionEx.ts b/solauto-sdk/src/solautoPosition/solautoPositionEx.ts index 1d651ada..76c40009 100644 --- a/solauto-sdk/src/solautoPosition/solautoPositionEx.ts +++ b/solauto-sdk/src/solautoPosition/solautoPositionEx.ts @@ -146,10 +146,10 @@ export abstract class SolautoPositionEx { ); } - liqUtilizationRateBps(priceType?: PriceType): number { + liqUtilizationRateBps(priceType?: PriceType, withoutBias?: boolean): number { return getLiqUtilzationRateBps( - this.supplyUsd(priceType), - this.debtUsd(priceType), + this.supplyUsd(priceType, withoutBias), + this.debtUsd(priceType, withoutBias), this.state.liqThresholdBps ); } @@ -229,14 +229,14 @@ export abstract class SolautoPositionEx { return calcTotalSupply(this.state); } - supplyUsd(priceType?: PriceType) { - const supplyPrice = this.supplyPrice(priceType); + supplyUsd(priceType?: PriceType, withoutBias?: boolean) { + const supplyPrice = this.supplyPrice(priceType, withoutBias); return supplyPrice ? calcTotalSupply(this.state) * supplyPrice : calcSupplyUsd(this.state); } - supplyPrice(priceType?: PriceType) { + supplyPrice(priceType?: PriceType, withoutBias?: boolean) { return this._supplyPrice ?? safeGetPrice(this.supplyMint, priceType); } @@ -244,14 +244,14 @@ export abstract class SolautoPositionEx { return calcTotalDebt(this.state); } - debtUsd(priceType?: PriceType) { - const debtPrice = this.debtPrice(priceType); + debtUsd(priceType?: PriceType, withoutBias?: boolean) { + const debtPrice = this.debtPrice(priceType, withoutBias); return debtPrice ? calcTotalDebt(this.state) * debtPrice : calcDebtUsd(this.state); } - debtPrice(priceType?: PriceType) { + debtPrice(priceType?: PriceType, withoutBias?: boolean) { return this._debtPrice ?? safeGetPrice(this.debtMint, priceType); } @@ -495,7 +495,8 @@ class PositionRebalanceHelper { return ( this.validRealtimePricesBoost(debtAdjustmentUsd) || - this.pos.liqUtilizationRateBps(PriceType.Ema) - this.pos.boostFromBps <= + this.pos.liqUtilizationRateBps(PriceType.Ema, true) - + this.pos.boostFromBps <= bpsDistanceThreshold ); } @@ -509,9 +510,11 @@ class PositionRebalanceHelper { } const realtimeLiqUtilRateBps = this.pos.liqUtilizationRateBps( - PriceType.Realtime + PriceType.Realtime, + true ); + console.log(realtimeLiqUtilRateBps, this.pos.boostFromBps); if ( this.pos.repayFromBps - realtimeLiqUtilRateBps <= bpsDistanceThreshold From 7694328538e1ebd7471aa7794ba83b0810c24bf4 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Wed, 11 Jun 2025 13:29:30 -0400 Subject: [PATCH 55/88] bump --- solauto-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 435b4b24..48b507b6 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.773", + "version": "1.0.774", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", From 957dd0b8d860504342fd36959ba0a8802c72f526 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 30 Jun 2025 11:58:53 -0400 Subject: [PATCH 56/88] updates --- solauto-sdk/package.json | 2 +- .../transactions/manager/transactionsManager.ts | 4 ++-- .../src/solautoPosition/solautoPositionEx.ts | 1 - solauto-sdk/src/utils/priceUtils.ts | 2 +- solauto-sdk/src/utils/solanaUtils.ts | 13 +++++++++++-- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 48b507b6..29ae30ab 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.774", + "version": "1.0.777", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts index c296cadb..b10458b5 100644 --- a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts @@ -126,7 +126,7 @@ export class TransactionsManager { ]); for (let j = i; j >= 0; j--) { const tx = txItems[j]; - if ((await newSet.fitsWith(tx))) { + if (await newSet.fitsWith(tx)) { newSet.prepend(tx); i--; } else { @@ -585,7 +585,7 @@ export class TransactionsManager { consoleLog(errorString); if (!errorDetails.canBeIgnored) { - throw error; + throw errorDetails.errorName ? new Error(errorString) : error; } } } diff --git a/solauto-sdk/src/solautoPosition/solautoPositionEx.ts b/solauto-sdk/src/solautoPosition/solautoPositionEx.ts index 76c40009..cbc33a38 100644 --- a/solauto-sdk/src/solautoPosition/solautoPositionEx.ts +++ b/solauto-sdk/src/solautoPosition/solautoPositionEx.ts @@ -514,7 +514,6 @@ class PositionRebalanceHelper { true ); - console.log(realtimeLiqUtilRateBps, this.pos.boostFromBps); if ( this.pos.repayFromBps - realtimeLiqUtilRateBps <= bpsDistanceThreshold diff --git a/solauto-sdk/src/utils/priceUtils.ts b/solauto-sdk/src/utils/priceUtils.ts index 268b44f4..a967f751 100644 --- a/solauto-sdk/src/utils/priceUtils.ts +++ b/solauto-sdk/src/utils/priceUtils.ts @@ -123,7 +123,7 @@ export async function getPythPrices( return prices; }, 5, - 200 + 250 ); return createRecord( diff --git a/solauto-sdk/src/utils/solanaUtils.ts b/solauto-sdk/src/utils/solanaUtils.ts index 6fe31bc5..ae9111b8 100644 --- a/solauto-sdk/src/utils/solanaUtils.ts +++ b/solauto-sdk/src/utils/solanaUtils.ts @@ -331,7 +331,7 @@ export async function getQnComputeUnitPriceEstimate( return await customRpcCall(umi, "qn_estimatePriorityFees", { last_n_blocks: blockheight, account: programId.toString(), - api_version: 2 + api_version: 2, }); } @@ -403,7 +403,16 @@ async function spamSendTransactionUntilConfirmed( } catch (e) {} }; - await sendTx(); + let i = 0; + while (i < 5) { + await sendTx(); + i++; + if (!transactionSignature) { + await new Promise((resolve) => setTimeout(resolve, 1000)); + } else { + break; + } + } const sendIntervalId = setInterval(async () => { await sendTx(); From c7a0c63667b53c7d6736d8ff53a0d7884325308c Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 30 Jun 2025 12:01:04 -0400 Subject: [PATCH 57/88] updates --- solauto-sdk/package.json | 2 +- solauto-sdk/src/utils/solanaUtils.ts | 13 ++----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 29ae30ab..77facaf2 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.777", + "version": "1.0.778", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/utils/solanaUtils.ts b/solauto-sdk/src/utils/solanaUtils.ts index ae9111b8..8694642c 100644 --- a/solauto-sdk/src/utils/solanaUtils.ts +++ b/solauto-sdk/src/utils/solanaUtils.ts @@ -403,21 +403,12 @@ async function spamSendTransactionUntilConfirmed( } catch (e) {} }; - let i = 0; - while (i < 5) { - await sendTx(); - i++; - if (!transactionSignature) { - await new Promise((resolve) => setTimeout(resolve, 1000)); - } else { - break; - } - } - const sendIntervalId = setInterval(async () => { await sendTx(); }, spamInterval); + await new Promise((resolve) => setTimeout(resolve, spamInterval * 4)); + if (!transactionSignature) { throw new Error("No transaction signature found"); } From e31ead324cb50228cba1d8a391ad94a2c5b3cc08 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 30 Jun 2025 16:38:20 -0400 Subject: [PATCH 58/88] upgrade jup price api --- solauto-sdk/package.json | 2 +- solauto-sdk/src/utils/jupiterUtils.ts | 47 +++++++++++++-------------- solauto-sdk/src/utils/priceUtils.ts | 11 +++++-- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 77facaf2..07651502 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.778", + "version": "1.0.781", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/utils/jupiterUtils.ts b/solauto-sdk/src/utils/jupiterUtils.ts index 48d58115..a620a689 100644 --- a/solauto-sdk/src/utils/jupiterUtils.ts +++ b/solauto-sdk/src/utils/jupiterUtils.ts @@ -1,6 +1,6 @@ import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import { Instruction } from "@jup-ag/api"; -import { retryWithExponentialBackoff } from "./generalUtils"; +import { getBatches, retryWithExponentialBackoff } from "./generalUtils"; export function jupIxToSolanaIx( instruction: Instruction @@ -17,31 +17,28 @@ export function jupIxToSolanaIx( } export async function getJupPriceData(mints: PublicKey[]) { - const data = await retryWithExponentialBackoff(async () => { - const res = await ( - await fetch( - "https://api.jup.ag/price/v2?ids=" + - mints.map((x) => x.toString()).join(",") + - "&showExtraInfo=true" - ) - ).json(); - const result = res.data; - if (!result || result === null || typeof result !== "object") { - throw new Error("Failed to get token prices using Jupiter"); - } + const batches = getBatches(mints, 50); - const trueData: { [key: string]: any } = Object.entries( - result as { [key: string]: any } - ).reduce( - (acc, [key, val]) => - !val?.extraInfo?.quotedPrice?.sellAt - ? { ...acc, [key]: { ...val, price: "0" } } - : { ...acc, [key]: val }, - {} - ); + const results = await Promise.all( + batches.map((batch) => + retryWithExponentialBackoff(async () => { + const res = await ( + await fetch( + "https://lite-api.jup.ag/price/v3?ids=" + + batch.map((x) => x.toString()).join(",") + ) + ).json(); - return trueData; - }, 3); + if (!res || typeof res !== "object") { + throw new Error("Failed to get token prices using Jupiter"); + } - return data; + return res; + }, 4) + ) + ); + + const mergedResults = Object.assign({}, ...results); + + return mergedResults; } diff --git a/solauto-sdk/src/utils/priceUtils.ts b/solauto-sdk/src/utils/priceUtils.ts index a967f751..52058e8f 100644 --- a/solauto-sdk/src/utils/priceUtils.ts +++ b/solauto-sdk/src/utils/priceUtils.ts @@ -212,10 +212,15 @@ export async function getJupTokenPrices( const data = getSortedPriceData(await getJupPriceData(mints), mints); const prices: Record = Object.fromEntries( - Object.entries(data).map(([mint, x]) => [ + mints.map((mint) => [ mint, - x !== null && typeof x === "object" && "price" in x - ? { realtimePrice: parseFloat(x.price as string) } + data !== null && + typeof data === "object" && + typeof data[mint.toString()] === "object" && + "usdPrice" in data[mint.toString()] + ? { + realtimePrice: parseFloat(data[mint.toString()].usdPrice as string), + } : { realtimePrice: 0 }, ]) ); From e25a49a274e4ebd3ec25b6cb79dcdd4f5fdcdc0d Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 30 Jun 2025 20:05:12 -0400 Subject: [PATCH 59/88] fixes --- solauto-sdk/package.json | 2 +- solauto-sdk/src/utils/jupiterUtils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 07651502..7093eb24 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.781", + "version": "1.0.782", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/utils/jupiterUtils.ts b/solauto-sdk/src/utils/jupiterUtils.ts index a620a689..90327adc 100644 --- a/solauto-sdk/src/utils/jupiterUtils.ts +++ b/solauto-sdk/src/utils/jupiterUtils.ts @@ -34,7 +34,7 @@ export async function getJupPriceData(mints: PublicKey[]) { } return res; - }, 4) + }, 6, 250) ) ); From 66fce9514ce2f0535cce4c02c100e7499dd8024e Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 7 Jul 2025 15:01:52 -0400 Subject: [PATCH 60/88] bump versions --- pnpm-lock.yaml | 217 +-- solauto-sdk/package.json | 10 +- solauto-sdk/pnpm-lock.yaml | 480 ++--- solauto-sdk/src/idls/switchboard.json | 1949 --------------------- solauto-sdk/src/utils/switchboardUtils.ts | 32 +- 5 files changed, 288 insertions(+), 2400 deletions(-) delete mode 100644 solauto-sdk/src/idls/switchboard.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a9acb1a..312f22c7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,12 +34,6 @@ packages: dependencies: regenerator-runtime: 0.14.1 - /@brokerloop/ttlcache@3.2.3: - resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} - dependencies: - '@soncodi/signal': 2.0.7 - dev: true - /@common.js/quick-lru@7.0.0: resolution: {integrity: sha512-DO3vApnH1vLizdWRSqzhg+S956vptHhtO+vw6PP6StJGDtaAGyfKSSPPGYWguJZu/Jlti6l6m6jB8NrKEQexLg==} engines: {node: '>=18'} @@ -137,6 +131,11 @@ packages: yargs: 17.7.2 dev: false + /@isaacs/ttlcache@1.4.1: + resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} + engines: {node: '>=12'} + dev: true + /@js-sdsl/ordered-map@4.4.2: resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} dev: false @@ -526,6 +525,16 @@ packages: typescript: 4.9.5 dev: true + /@solana/codecs-core@2.1.1(typescript@4.9.5): + resolution: {integrity: sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + dependencies: + '@solana/errors': 2.1.1(typescript@4.9.5) + typescript: 4.9.5 + dev: true + /@solana/codecs-data-structures@2.0.0-preview.4(typescript@4.9.5): resolution: {integrity: sha512-nt2k2eTeyzlI/ccutPcG36M/J8NAYfxBPI9h/nQjgJ+M+IgOKi31JV8StDDlG/1XvY0zyqugV3I0r3KAbZRJpA==} peerDependencies: @@ -575,6 +584,17 @@ packages: typescript: 4.9.5 dev: true + /@solana/codecs-numbers@2.1.1(typescript@4.9.5): + resolution: {integrity: sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + dependencies: + '@solana/codecs-core': 2.1.1(typescript@4.9.5) + '@solana/errors': 2.1.1(typescript@4.9.5) + typescript: 4.9.5 + dev: true + /@solana/codecs-strings@2.0.0-preview.1(fastestsmallesttextencoderdecoder@1.0.22): resolution: {integrity: sha512-kBAxE9ZD5/c8j9CkPxqc55dbo7R50Re3k94SXR+k13DZCCs37Fyn0/mAkw/S95fofbi/zsi4jSfmsT5vCZD75A==} peerDependencies: @@ -672,6 +692,18 @@ packages: typescript: 4.9.5 dev: true + /@solana/errors@2.1.1(typescript@4.9.5): + resolution: {integrity: sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' + dependencies: + chalk: 5.4.1 + commander: 13.1.0 + typescript: 4.9.5 + dev: true + /@solana/options@2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-tv2O/Frxql/wSe3jbzi5nVicIWIus/BftH+5ZR+r9r3FO0/htEllZS5Q9XdbmSboHu+St87584JXeDx3xm4jaA==} peerDependencies: @@ -779,25 +811,6 @@ packages: - utf-8-validate dev: true - /@solana/spl-token@0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.88.0 - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8 - buffer: 6.0.3 - transitivePeerDependencies: - - bufferutil - - encoding - - fastestsmallesttextencoderdecoder - - typescript - - utf-8-validate - dev: true - /@solana/spl-token@0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-RO0JD9vPRi4LsAbMUdNbDJ5/cv2z11MGhtAvFeRzT4+hAGE/FUzRi0tkkWtuCfSIU3twC6CtmAihRp/+XXjWsA==} engines: {node: '>=16'} @@ -964,29 +977,31 @@ packages: - encoding - utf-8-validate - /@solworks/soltoolkit-sdk@0.0.23(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} + /@solana/web3.js@1.98.2(typescript@4.9.5): + resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} dependencies: + '@babel/runtime': 7.25.7 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 '@solana/buffer-layout': 4.0.1 - '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8 - '@types/bn.js': 5.1.6 - '@types/node': 18.19.67 - '@types/node-fetch': 2.6.12 + '@solana/codecs-numbers': 2.1.1(typescript@4.9.5) + agentkeepalive: 4.5.0 bn.js: 5.2.1 - decimal.js: 10.4.3 - typescript: 4.9.5 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.2 + node-fetch: 2.7.0 + rpc-websockets: 9.0.4 + superstruct: 2.0.2 transitivePeerDependencies: - bufferutil - encoding - - fastestsmallesttextencoderdecoder + - typescript - utf-8-validate dev: true - /@soncodi/signal@2.0.7: - resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} - dev: true - /@sqds/multisig@2.1.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-WOiL7La+RSiJsz7jVO85yhSiiSvNMUthiWuLPeWVOoD6IYa34BEAzanF1RdXRWGglSbRFYCTkyr+Ay1WmXmSRQ==} engines: {node: '>=14'} @@ -1015,28 +1030,6 @@ packages: dependencies: tslib: 2.7.0 - /@switchboard-xyz/common@2.5.5: - resolution: {integrity: sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w==} - engines: {node: '>=12'} - dependencies: - '@solana/web3.js': 1.95.8 - axios: 1.7.8 - big.js: 6.2.2 - bn.js: 5.2.1 - bs58: 5.0.0 - cron-validator: 1.3.1 - decimal.js: 10.4.3 - js-sha256: 0.11.0 - lodash: 4.17.21 - protobufjs: 7.4.0 - yaml: 2.6.1 - transitivePeerDependencies: - - bufferutil - - debug - - encoding - - utf-8-validate - dev: true - /@switchboard-xyz/common@3.0.12: resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} engines: {node: '>=20'} @@ -1079,25 +1072,26 @@ packages: - utf-8-validate dev: false - /@switchboard-xyz/on-demand@1.2.51(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} - engines: {node: '>= 18'} + /@switchboard-xyz/common@3.4.1(typescript@4.9.5): + resolution: {integrity: sha512-TropBlBYuDeBnmGHkPSmgC3clLqAxy51ZGbwk4ejAgadnszWOgYHcH7taRG4Ha17DYSCWw/LGMBKbunGo+Aoaw==} + engines: {node: '>=20'} dependencies: - '@brokerloop/ttlcache': 3.2.3 - '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 - '@solana/web3.js': 1.95.8 - '@solworks/soltoolkit-sdk': 0.0.23(fastestsmallesttextencoderdecoder@1.0.22) - '@switchboard-xyz/common': 2.5.5 - axios: 1.7.8 + '@solana/web3.js': 1.98.2(typescript@4.9.5) + axios: 1.10.0 big.js: 6.2.2 - bs58: 5.0.0 - js-yaml: 4.1.0 + bn.js: 5.2.1 + bs58: 6.0.0 + buffer: 6.0.3 + decimal.js: 10.4.3 + js-sha256: 0.11.0 protobufjs: 7.4.0 + yaml: 2.6.1 + zod: 4.0.0-beta.20250505T195954 transitivePeerDependencies: - bufferutil - debug - encoding - - fastestsmallesttextencoderdecoder + - typescript - utf-8-validate dev: true @@ -1120,6 +1114,25 @@ packages: - utf-8-validate dev: false + /@switchboard-xyz/on-demand@2.8.1(typescript@4.9.5): + resolution: {integrity: sha512-MqUXMuqmYfhjMdFIAyFOvCYr1BeacmA3ZY6Eu2RkHJLG1X3NAKdCHR2Bj13UU/H9P7HrKhse29Sn7QdbSeEp/w==} + engines: {node: '>= 18'} + dependencies: + '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 + '@isaacs/ttlcache': 1.4.1 + '@switchboard-xyz/common': 3.4.1(typescript@4.9.5) + axios: 1.10.0 + bs58: 6.0.0 + buffer: 6.0.3 + js-yaml: 4.1.0 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - typescript + - utf-8-validate + dev: true + /@types/bn.js@5.1.6: resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} dependencies: @@ -1131,22 +1144,9 @@ packages: dependencies: '@types/node': 20.16.11 - /@types/node-fetch@2.6.12: - resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} - dependencies: - '@types/node': 20.16.11 - form-data: 4.0.1 - dev: true - /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - /@types/node@18.19.67: - resolution: {integrity: sha512-wI8uHusga+0ZugNp0Ol/3BqQfEcCCNfojtO6Oou9iVNGPTL6QNSdnUdqq85fRgIorLhLMuPIKpsN98QE9Nh+KQ==} - dependencies: - undici-types: 5.26.5 - dev: true - /@types/node@20.16.11: resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} dependencies: @@ -1177,6 +1177,10 @@ packages: '@wallet-standard/base': 1.1.0 dev: false + /@zod/core@0.11.6: + resolution: {integrity: sha512-03Bv82fFSfjDAvMfdHHdGSS6SOJs0iCcJlWJv1kJHRtoTT02hZpyip/2Lk6oo4l4FtjuwTrsEQTwg/LD8I7dJA==} + dev: true + /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -1237,6 +1241,16 @@ packages: possible-typed-array-names: 1.0.0 dev: true + /axios@1.10.0: + resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: true + /axios@1.7.8: resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} dependencies: @@ -1359,6 +1373,11 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + /chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true + /cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -1389,6 +1408,11 @@ packages: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} + /commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + dev: true + /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -1397,10 +1421,6 @@ packages: engines: {node: '>= 6'} dev: false - /cron-validator@1.3.1: - resolution: {integrity: sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==} - dev: true - /cross-fetch@3.1.8: resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} dependencies: @@ -1748,10 +1768,6 @@ packages: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} dev: false - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true - /long@5.2.3: resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} @@ -1995,10 +2011,6 @@ packages: hasBin: true dev: true - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: true - /undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -2107,6 +2119,12 @@ packages: yargs-parser: 21.1.1 dev: false + /zod@4.0.0-beta.20250505T195954: + resolution: {integrity: sha512-iB8WvxkobVIXMARvQu20fKvbS7mUTiYRpcD8OQV1xjRhxO0EEpYIRJBk6yfBzHAHEdOSDh3SxDITr5Eajr2vtg==} + dependencies: + '@zod/core': 0.11.6 + dev: true + file:solauto-sdk(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {directory: solauto-sdk, type: directory} id: file:solauto-sdk @@ -2122,9 +2140,10 @@ packages: '@solana/web3.js': 1.95.8 '@sqds/multisig': 2.1.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) '@switchboard-xyz/common': 3.0.12 - '@switchboard-xyz/on-demand': 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) + '@switchboard-xyz/on-demand': 2.8.1(typescript@4.9.5) '@types/node': 20.16.11 axios: 1.7.8 + big.js: 6.2.2 bs58: 5.0.0 cross-fetch: 4.0.0 dotenv: 16.4.7 diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 7093eb24..75d71aa4 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.782", + "version": "1.0.784", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", @@ -12,16 +12,16 @@ "test:unit": "ts-mocha -p ./tsconfig.json -t 1000000 tests/unit/**/*.ts" }, "dependencies": { - "@coral-xyz/anchor": "^0.30.1", + "@coral-xyz/anchor": "=0.31.1", "@jup-ag/api": "=6.0.24", "@metaplex-foundation/umi": "^0.9.1", "@metaplex-foundation/umi-bundle-defaults": "^0.9.1", "@metaplex-foundation/umi-signer-wallet-adapters": "^0.9.1", "@metaplex-foundation/umi-web3js-adapters": "^0.9.1", "@solana/spl-token": "^0.4.0", - "@solana/web3.js": "=1.95.8", - "@switchboard-xyz/common": "=3.0.12", - "@switchboard-xyz/on-demand": "=1.2.51", + "@solana/web3.js": "=1.98.2", + "@switchboard-xyz/common": "=3.4.1", + "@switchboard-xyz/on-demand": "=2.11.0", "axios": "^1.7.8", "big.js": "^6.2.2", "bs58": "^5.0.0", diff --git a/solauto-sdk/pnpm-lock.yaml b/solauto-sdk/pnpm-lock.yaml index 5003c773..4d59ae42 100644 --- a/solauto-sdk/pnpm-lock.yaml +++ b/solauto-sdk/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: '@coral-xyz/anchor': - specifier: ^0.30.1 - version: 0.30.1 + specifier: '=0.31.1' + version: 0.31.1(typescript@5.6.3) '@jup-ag/api': specifier: '=6.0.24' version: 6.0.24 @@ -16,25 +16,25 @@ dependencies: version: 0.9.2 '@metaplex-foundation/umi-bundle-defaults': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) '@metaplex-foundation/umi-signer-wallet-adapters': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) '@metaplex-foundation/umi-web3js-adapters': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) '@solana/spl-token': specifier: ^0.4.0 - version: 0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + version: 0.4.8(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/web3.js': - specifier: '=1.95.8' - version: 1.95.8 + specifier: '=1.98.2' + version: 1.98.2(typescript@5.6.3) '@switchboard-xyz/common': - specifier: '=3.0.12' - version: 3.0.12 + specifier: '=3.4.1' + version: 3.4.1(typescript@5.6.3) '@switchboard-xyz/on-demand': - specifier: '=1.2.51' - version: 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) + specifier: '=2.11.0' + version: 2.11.0(typescript@5.6.3) axios: specifier: ^1.7.8 version: 1.7.8 @@ -89,58 +89,56 @@ packages: regenerator-runtime: 0.14.1 dev: false - /@brokerloop/ttlcache@3.2.3: - resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} - dependencies: - '@soncodi/signal': 2.0.7 - dev: false - - /@coral-xyz/anchor-errors@0.30.1: - resolution: {integrity: sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==} + /@coral-xyz/anchor-errors@0.31.1: + resolution: {integrity: sha512-NhNEku4F3zzUSBtrYz84FzYWm48+9OvmT1Hhnwr6GnPQry2dsEqH/ti/7ASjjpoFTWRnPXrjAIT1qM6Isop+LQ==} engines: {node: '>=10'} dev: false - /@coral-xyz/anchor@0.30.1: - resolution: {integrity: sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==} - engines: {node: '>=11'} + /@coral-xyz/anchor@0.31.1(typescript@5.6.3): + resolution: {integrity: sha512-QUqpoEK+gi2S6nlYc2atgT2r41TT3caWr/cPUEL8n8Md9437trZ68STknq897b82p5mW0XrTBNOzRbmIRJtfsA==} + engines: {node: '>=17'} dependencies: - '@coral-xyz/anchor-errors': 0.30.1 - '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.8) + '@coral-xyz/anchor-errors': 0.31.1 + '@coral-xyz/borsh': 0.31.1(@solana/web3.js@1.98.2) '@noble/hashes': 1.5.0 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) bn.js: 5.2.1 bs58: 4.0.1 buffer-layout: 1.2.2 camelcase: 6.3.0 cross-fetch: 3.1.8 - crypto-hash: 1.3.0 eventemitter3: 4.0.7 pako: 2.1.0 - snake-case: 3.0.4 superstruct: 0.15.5 toml: 3.0.0 transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate dev: false - /@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} + /@coral-xyz/borsh@0.31.1(@solana/web3.js@1.98.2): + resolution: {integrity: sha512-9N8AU9F0ubriKfNE3g1WF0/4dtlGXoBN/hd1PvbNBamBNwRgHxH4P+o3Zt7rSEloW1HUs6LfZEchlx9fW7POYw==} engines: {node: '>=10'} peerDependencies: - '@solana/web3.js': ^1.68.0 + '@solana/web3.js': ^1.69.0 dependencies: - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) bn.js: 5.2.1 buffer-layout: 1.2.2 dev: false + /@isaacs/ttlcache@1.4.1: + resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} + engines: {node: '>=12'} + dev: false + /@jup-ag/api@6.0.24: resolution: {integrity: sha512-zIX4WIPb0Kb2UnK2wNIOQBWqPJyMJq/D9dQTf/2qvPb0hfa8XdgbrQAzomHMHnAzw9StMQoybBk+JK/A76xP3w==} dev: false - /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): + /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): resolution: {integrity: sha512-kV3tfvgvRjVP1p9OFOtH+ibOtN9omVJSwKr0We4/9r45e5LTj+32su0V/rixZUkG1EZzzOYBsxhtIE0kIw/Hrw==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 @@ -148,14 +146,14 @@ packages: dependencies: '@metaplex-foundation/umi': 0.9.2 '@metaplex-foundation/umi-downloader-http': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) '@metaplex-foundation/umi-http-fetch': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-program-repository': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-rpc-chunk-get-accounts': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) '@metaplex-foundation/umi-serializer-data-view': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 + '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@solana/web3.js': 1.98.2(typescript@5.6.3) transitivePeerDependencies: - encoding dev: false @@ -168,16 +166,16 @@ packages: '@metaplex-foundation/umi': 0.9.2 dev: false - /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): + /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): resolution: {integrity: sha512-hhPCxXbYIp4BC4z9gK78sXpWLkNSrfv4ndhF5ruAkdIp7GcRVYKj0QnOUO6lGYGiIkNlw20yoTwOe1CT//OfTQ==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) '@noble/curves': 1.6.0 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) dev: false /@metaplex-foundation/umi-http-fetch@0.9.2(@metaplex-foundation/umi@0.9.2): @@ -217,15 +215,15 @@ packages: '@metaplex-foundation/umi': 0.9.2 dev: false - /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): + /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): resolution: {integrity: sha512-MqcsBz8B4wGl6jxsf2Jo/rAEpYReU9VCSR15QSjhvADHMmdFxCIZCCAgE+gDE2Vuanfl437VhOcP3g5Uw8C16Q==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@solana/web3.js': 1.98.2(typescript@5.6.3) dev: false /@metaplex-foundation/umi-serializer-data-view@0.9.2(@metaplex-foundation/umi@0.9.2): @@ -262,36 +260,36 @@ packages: '@metaplex-foundation/umi-serializers-numbers': 0.8.9 dev: false - /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): + /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): resolution: {integrity: sha512-DFG0ZFocKG8briypSkG9bGUTVsWpAgYugsl2BzTygkGExc4evWfF4Sb1F2C2w9FdrA9ESZM1gpLX9xtx5taOXg==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@solana/web3.js': 1.98.2(typescript@5.6.3) dev: false - /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): + /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): resolution: {integrity: sha512-fR1Kf21uylMFd1Smkltmj4jTNxhqSWf416owsJ+T+cvJi2VCOcOwq/3UFzOrpz78fA0RhsajKYKj0HYsRnQI1g==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@solana/web3.js': 1.98.2(typescript@5.6.3) dev: false - /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): + /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): resolution: {integrity: sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) buffer: 6.0.3 dev: false @@ -358,17 +356,18 @@ packages: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} dev: false - /@solana/buffer-layout-utils@0.2.0: + /@solana/buffer-layout-utils@0.2.0(typescript@5.6.3): resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} engines: {node: '>= 10'} dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) bigint-buffer: 1.1.5 bignumber.js: 9.1.2 transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate dev: false @@ -388,21 +387,22 @@ packages: typescript: 5.6.3 dev: false - /@solana/codecs-core@2.0.0-rc.1(typescript@4.9.5): + /@solana/codecs-core@2.0.0-rc.1(typescript@5.6.3): resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} peerDependencies: typescript: '>=5' dependencies: - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - typescript: 4.9.5 + '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) + typescript: 5.6.3 dev: false - /@solana/codecs-core@2.0.0-rc.1(typescript@5.6.3): - resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} + /@solana/codecs-core@2.1.1(typescript@5.6.3): + resolution: {integrity: sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg==} + engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5' + typescript: '>=5.3.3' dependencies: - '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) + '@solana/errors': 2.1.1(typescript@5.6.3) typescript: 5.6.3 dev: false @@ -417,17 +417,6 @@ packages: typescript: 5.6.3 dev: false - /@solana/codecs-data-structures@2.0.0-rc.1(typescript@4.9.5): - resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} - peerDependencies: - typescript: '>=5' - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - typescript: 4.9.5 - dev: false - /@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.6.3): resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} peerDependencies: @@ -449,23 +438,24 @@ packages: typescript: 5.6.3 dev: false - /@solana/codecs-numbers@2.0.0-rc.1(typescript@4.9.5): + /@solana/codecs-numbers@2.0.0-rc.1(typescript@5.6.3): resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} peerDependencies: typescript: '>=5' dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - typescript: 4.9.5 + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.6.3) + '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) + typescript: 5.6.3 dev: false - /@solana/codecs-numbers@2.0.0-rc.1(typescript@5.6.3): - resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} + /@solana/codecs-numbers@2.1.1(typescript@5.6.3): + resolution: {integrity: sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ==} + engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5' + typescript: '>=5.3.3' dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.6.3) - '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) + '@solana/codecs-core': 2.1.1(typescript@5.6.3) + '@solana/errors': 2.1.1(typescript@5.6.3) typescript: 5.6.3 dev: false @@ -482,19 +472,6 @@ packages: typescript: 5.6.3 dev: false - /@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} - peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - typescript: '>=5' - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - fastestsmallesttextencoderdecoder: 1.0.22 - typescript: 4.9.5 - dev: false - /@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} peerDependencies: @@ -523,21 +500,6 @@ packages: - fastestsmallesttextencoderdecoder dev: false - /@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} - peerDependencies: - typescript: '>=5' - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - dev: false - /@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} peerDependencies: @@ -564,7 +526,7 @@ packages: typescript: 5.6.3 dev: false - /@solana/errors@2.0.0-rc.1(typescript@4.9.5): + /@solana/errors@2.0.0-rc.1(typescript@5.6.3): resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} hasBin: true peerDependencies: @@ -572,17 +534,18 @@ packages: dependencies: chalk: 5.3.0 commander: 12.1.0 - typescript: 4.9.5 + typescript: 5.6.3 dev: false - /@solana/errors@2.0.0-rc.1(typescript@5.6.3): - resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} + /@solana/errors@2.1.1(typescript@5.6.3): + resolution: {integrity: sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw==} + engines: {node: '>=20.18.0'} hasBin: true peerDependencies: - typescript: '>=5' + typescript: '>=5.3.3' dependencies: - chalk: 5.3.0 - commander: 12.1.0 + chalk: 5.4.1 + commander: 13.1.0 typescript: 5.6.3 dev: false @@ -601,21 +564,6 @@ packages: - fastestsmallesttextencoderdecoder dev: false - /@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} - peerDependencies: - typescript: '>=5' - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - dev: false - /@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} peerDependencies: @@ -631,7 +579,7 @@ packages: - fastestsmallesttextencoderdecoder dev: false - /@solana/spl-token-group@0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token-group@0.0.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-CLJnWEcdoUBpQJfx9WEbX3h6nTdNiUzswfFdkABUik7HVwSNA98u5AYvBVK2H93d9PGMOHAak2lHW9xr+zAJGQ==} engines: {node: '>=16'} peerDependencies: @@ -639,13 +587,13 @@ packages: dependencies: '@solana/codecs': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript dev: false - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} engines: {node: '>=16'} peerDependencies: @@ -653,56 +601,23 @@ packages: dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript dev: false - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.95.3 - dependencies: - '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.98.0 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - typescript - dev: false - - /@solana/spl-token@0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.88.0 - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.98.0 - buffer: 6.0.3 - transitivePeerDependencies: - - bufferutil - - encoding - - fastestsmallesttextencoderdecoder - - typescript - - utf-8-validate - dev: false - - /@solana/spl-token@0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token@0.4.8(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-RO0JD9vPRi4LsAbMUdNbDJ5/cv2z11MGhtAvFeRzT4+hAGE/FUzRi0tkkWtuCfSIU3twC6CtmAihRp/+XXjWsA==} engines: {node: '>=16'} peerDependencies: '@solana/web3.js': ^1.94.0 dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/web3.js': 1.95.8 + '@solana/buffer-layout-utils': 0.2.0(typescript@5.6.3) + '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/web3.js': 1.98.2(typescript@5.6.3) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -719,39 +634,15 @@ packages: buffer: 6.0.3 dev: false - /@solana/web3.js@1.95.8: - resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} - dependencies: - '@babel/runtime': 7.25.7 - '@noble/curves': 1.6.0 - '@noble/hashes': 1.5.0 - '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.5.0 - bigint-buffer: 1.1.5 - bn.js: 5.2.1 - borsh: 0.7.0 - bs58: 4.0.1 - buffer: 6.0.3 - fast-stable-stringify: 1.0.0 - jayson: 4.1.2 - node-fetch: 2.7.0 - rpc-websockets: 9.0.4 - superstruct: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - - /@solana/web3.js@1.98.0: - resolution: {integrity: sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==} + /@solana/web3.js@1.98.2(typescript@5.6.3): + resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} dependencies: '@babel/runtime': 7.25.7 '@noble/curves': 1.6.0 '@noble/hashes': 1.5.0 '@solana/buffer-layout': 4.0.1 + '@solana/codecs-numbers': 2.1.1(typescript@5.6.3) agentkeepalive: 4.5.0 - bigint-buffer: 1.1.5 bn.js: 5.2.1 borsh: 0.7.0 bs58: 4.0.1 @@ -764,66 +655,22 @@ packages: transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate dev: false - /@solworks/soltoolkit-sdk@0.0.23(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/spl-token': 0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.98.0 - '@types/bn.js': 5.1.6 - '@types/node': 18.19.65 - '@types/node-fetch': 2.6.12 - bn.js: 5.2.1 - decimal.js: 10.4.3 - typescript: 4.9.5 - transitivePeerDependencies: - - bufferutil - - encoding - - fastestsmallesttextencoderdecoder - - utf-8-validate - dev: false - - /@soncodi/signal@2.0.7: - resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} - dev: false - /@swc/helpers@0.5.13: resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} dependencies: tslib: 2.7.0 dev: false - /@switchboard-xyz/common@2.5.5: - resolution: {integrity: sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w==} - engines: {node: '>=12'} - dependencies: - '@solana/web3.js': 1.98.0 - axios: 1.8.4 - big.js: 6.2.2 - bn.js: 5.2.1 - bs58: 5.0.0 - cron-validator: 1.3.1 - decimal.js: 10.4.3 - js-sha256: 0.11.0 - lodash: 4.17.21 - protobufjs: 7.4.0 - yaml: 2.6.1 - transitivePeerDependencies: - - bufferutil - - debug - - encoding - - utf-8-validate - dev: false - - /@switchboard-xyz/common@3.0.12: - resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} + /@switchboard-xyz/common@3.4.1(typescript@5.6.3): + resolution: {integrity: sha512-TropBlBYuDeBnmGHkPSmgC3clLqAxy51ZGbwk4ejAgadnszWOgYHcH7taRG4Ha17DYSCWw/LGMBKbunGo+Aoaw==} engines: {node: '>=20'} dependencies: - '@solana/web3.js': 1.98.0 - axios: 1.8.4 + '@solana/web3.js': 1.98.2(typescript@5.6.3) + axios: 1.10.0 big.js: 6.2.2 bn.js: 5.2.1 bs58: 6.0.0 @@ -832,33 +679,32 @@ packages: js-sha256: 0.11.0 protobufjs: 7.4.0 yaml: 2.6.1 + zod: 4.0.0-beta.20250505T195954 transitivePeerDependencies: - bufferutil - debug - encoding + - typescript - utf-8-validate dev: false - /@switchboard-xyz/on-demand@1.2.51(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} + /@switchboard-xyz/on-demand@2.11.0(typescript@5.6.3): + resolution: {integrity: sha512-w4iHyRpvIuv2CT2Bcap6zIdunLYcDBuMUliyJuxmxLD+ch2Lta1QWHAZCsjuBasE2OhSKoTz3MAtapYuCuR2gA==} engines: {node: '>= 18'} - deprecated: deprecated in favor of 2.x.x - dependencies: - '@brokerloop/ttlcache': 3.2.3 - '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 - '@solana/web3.js': 1.98.0 - '@solworks/soltoolkit-sdk': 0.0.23(fastestsmallesttextencoderdecoder@1.0.22) - '@switchboard-xyz/common': 2.5.5 - axios: 1.8.4 - big.js: 6.2.2 - bs58: 5.0.0 + dependencies: + '@coral-xyz/anchor-31': /@coral-xyz/anchor@0.31.1(typescript@5.6.3) + '@isaacs/ttlcache': 1.4.1 + '@switchboard-xyz/common': 3.4.1(typescript@5.6.3) + axios: 1.10.0 + bs58: 6.0.0 + buffer: 6.0.3 js-yaml: 4.1.0 - protobufjs: 7.4.0 + ws: 8.18.3 transitivePeerDependencies: - bufferutil - debug - encoding - - fastestsmallesttextencoderdecoder + - typescript - utf-8-validate dev: false @@ -866,12 +712,6 @@ packages: resolution: {integrity: sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==} dev: true - /@types/bn.js@5.1.6: - resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} - dependencies: - '@types/node': 20.16.11 - dev: false - /@types/chai@4.3.20: resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} dev: true @@ -892,23 +732,10 @@ packages: resolution: {integrity: sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==} dev: true - /@types/node-fetch@2.6.12: - resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} - dependencies: - '@types/node': 20.16.11 - form-data: 4.0.1 - dev: false - /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: false - /@types/node@18.19.65: - resolution: {integrity: sha512-Ay5BZuO1UkTmVHzZJNvZKw/E+iB3GQABb6kijEz89w2JrfhNA+M/ebp18pfz9Gqe9ywhMC8AA8yC01lZq48J+Q==} - dependencies: - undici-types: 5.26.5 - dev: false - /@types/node@20.16.11: resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} dependencies: @@ -934,6 +761,10 @@ packages: resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} dev: true + /@zod/core@0.11.6: + resolution: {integrity: sha512-03Bv82fFSfjDAvMfdHHdGSS6SOJs0iCcJlWJv1kJHRtoTT02hZpyip/2Lk6oo4l4FtjuwTrsEQTwg/LD8I7dJA==} + dev: false + /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -990,8 +821,8 @@ packages: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false - /axios@1.7.8: - resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} + /axios@1.10.0: + resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} dependencies: follow-redirects: 1.15.9 form-data: 4.0.1 @@ -1000,8 +831,8 @@ packages: - debug dev: false - /axios@1.8.4: - resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} + /axios@1.7.8: + resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} dependencies: follow-redirects: 1.15.9 form-data: 4.0.1 @@ -1161,6 +992,11 @@ packages: engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} dev: false + /chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: false + /check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} dependencies: @@ -1213,6 +1049,11 @@ packages: engines: {node: '>=18'} dev: false + /commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + dev: false + /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: false @@ -1221,10 +1062,6 @@ packages: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true - /cron-validator@1.3.1: - resolution: {integrity: sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==} - dev: false - /cross-fetch@3.1.8: resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} dependencies: @@ -1241,11 +1078,6 @@ packages: - encoding dev: false - /crypto-hash@1.3.0: - resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} - engines: {node: '>=8'} - dev: false - /debug@4.3.3(supports-color@8.1.1): resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} engines: {node: '>=6.0'} @@ -1295,13 +1127,6 @@ packages: engines: {node: '>=0.3.1'} dev: true - /dot-case@3.0.4: - resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} - dependencies: - no-case: 3.0.4 - tslib: 2.7.0 - dev: false - /dotenv@16.4.7: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} @@ -1580,10 +1405,6 @@ packages: p-locate: 5.0.0 dev: true - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: false - /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -1602,12 +1423,6 @@ packages: get-func-name: 2.0.2 dev: true - /lower-case@2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} - dependencies: - tslib: 2.7.0 - dev: false - /make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: true @@ -1692,13 +1507,6 @@ packages: hasBin: true dev: true - /no-case@3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - dependencies: - lower-case: 2.0.2 - tslib: 2.7.0 - dev: false - /node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -1846,13 +1654,6 @@ packages: randombytes: 2.1.0 dev: true - /snake-case@3.0.4: - resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} - dependencies: - dot-case: 3.0.4 - tslib: 2.7.0 - dev: false - /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: @@ -1987,21 +1788,11 @@ packages: engines: {node: '>=4'} dev: true - /typescript@4.9.5: - resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: false - /typescript@5.6.3: resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} hasBin: true - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: false - /undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -2083,6 +1874,19 @@ packages: utf-8-validate: 5.0.10 dev: false + /ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -2131,3 +1935,9 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true + + /zod@4.0.0-beta.20250505T195954: + resolution: {integrity: sha512-iB8WvxkobVIXMARvQu20fKvbS7mUTiYRpcD8OQV1xjRhxO0EEpYIRJBk6yfBzHAHEdOSDh3SxDITr5Eajr2vtg==} + dependencies: + '@zod/core': 0.11.6 + dev: false diff --git a/solauto-sdk/src/idls/switchboard.json b/solauto-sdk/src/idls/switchboard.json deleted file mode 100644 index 6996121a..00000000 --- a/solauto-sdk/src/idls/switchboard.json +++ /dev/null @@ -1,1949 +0,0 @@ -{ - "address": "SBondMDrcV3K4kxZR1HNVT7osZxAHVHgYXL5Ze1oMUv", - "metadata": { - "name": "sb_on_demand", - "version": "0.1.0", - "spec": "0.1.0", - "description": "Created with Anchor" - }, - "instructions": [ - { - "name": "guardian_quote_verify", - "discriminator": [168, 36, 93, 156, 157, 150, 148, 45], - "accounts": [ - { "name": "guardian", "writable": true }, - { "name": "oracle", "writable": true }, - { "name": "authority", "signer": true, "relations": ["oracle"] }, - { "name": "guardian_queue", "writable": true, "relations": ["state"] }, - { "name": "state" }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "GuardianQuoteVerifyParams" } } - } - ] - }, - { - "name": "guardian_register", - "discriminator": [159, 76, 53, 117, 219, 29, 116, 135], - "accounts": [ - { "name": "oracle", "writable": true }, - { "name": "state" }, - { "name": "guardian_queue", "relations": ["state"] }, - { "name": "authority", "signer": true, "relations": ["state"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "GuardianRegisterParams" } } - } - ] - }, - { - "name": "guardian_unregister", - "discriminator": [215, 19, 61, 120, 155, 224, 120, 60], - "accounts": [ - { "name": "oracle", "writable": true }, - { "name": "state" }, - { "name": "guardian_queue", "writable": true, "relations": ["state"] }, - { "name": "authority", "signer": true, "relations": ["state"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "GuardianUnregisterParams" } } - } - ] - }, - { - "name": "oracle_heartbeat", - "discriminator": [10, 175, 217, 130, 111, 35, 117, 54], - "accounts": [ - { "name": "oracle", "writable": true }, - { - "name": "oracle_stats", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] - }, - { "kind": "account", "path": "oracle" } - ] - } - }, - { "name": "oracle_signer", "signer": true }, - { - "name": "queue", - "writable": true, - "relations": ["oracle", "gc_node"] - }, - { "name": "gc_node", "writable": true }, - { "name": "program_state", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "native_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "queue_escrow", "writable": true }, - { - "name": "stake_program", - "address": "SBSTk6t52R89MmCdD739Rdd97HdbTQUFHe41vCX7pTt", - "relations": ["program_state"] - }, - { "name": "delegation_pool", "writable": true }, - { "name": "delegation_group", "writable": true } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "OracleHeartbeatParams" } } - } - ] - }, - { - "name": "oracle_init", - "discriminator": [21, 158, 66, 65, 60, 221, 148, 61], - "accounts": [ - { "name": "oracle", "writable": true, "signer": true }, - { - "name": "oracle_stats", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] - }, - { "kind": "account", "path": "oracle" } - ] - } - }, - { "name": "program_state", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - }, - { "name": "stake_program", "relations": ["program_state"] }, - { "name": "stake_pool", "relations": ["program_state"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "OracleInitParams" } } - } - ] - }, - { - "name": "oracle_set_configs", - "discriminator": [129, 111, 223, 4, 191, 188, 70, 180], - "accounts": [ - { "name": "oracle" }, - { "name": "authority", "signer": true, "relations": ["oracle"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "OracleSetConfigsParams" } } - } - ] - }, - { - "name": "oracle_update_delegation", - "discriminator": [46, 198, 113, 223, 160, 189, 118, 90], - "accounts": [ - { "name": "oracle", "writable": true }, - { - "name": "oracle_stats", - "pda": { - "seeds": [ - { - "kind": "const", - "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] - }, - { "kind": "account", "path": "oracle" } - ] - } - }, - { "name": "queue", "relations": ["oracle"] }, - { "name": "authority", "signer": true }, - { "name": "program_state", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { "name": "delegation_pool", "writable": true }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - }, - { "name": "switch_mint" }, - { - "name": "native_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "wsol_vault", "writable": true }, - { "name": "switch_vault", "writable": true }, - { "name": "stake_program", "relations": ["program_state"] }, - { "name": "stake_pool" }, - { "name": "delegation_group" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "OracleUpdateDelegationParams" } } - } - ] - }, - { - "name": "permission_set", - "discriminator": [211, 122, 185, 120, 129, 182, 55, 103], - "accounts": [ - { "name": "authority", "signer": true }, - { "name": "granter" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PermissionSetParams" } } - } - ] - }, - { - "name": "pull_feed_close", - "discriminator": [19, 134, 50, 142, 177, 215, 196, 83], - "accounts": [ - { "name": "pull_feed", "writable": true }, - { "name": "reward_escrow", "writable": true }, - { "name": "lut", "writable": true }, - { "name": "lut_signer" }, - { "name": "payer", "writable": true, "signer": true }, - { "name": "state" }, - { - "name": "authority", - "writable": true, - "signer": true, - "relations": ["pull_feed"] - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "associated_token_program", - "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedCloseParams" } } - } - ] - }, - { - "name": "pull_feed_init", - "discriminator": [198, 130, 53, 198, 235, 61, 143, 40], - "accounts": [ - { "name": "pull_feed", "writable": true, "signer": true }, - { "name": "queue" }, - { "name": "authority" }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "program_state" }, - { - "name": "reward_escrow", - "writable": true, - "pda": { - "seeds": [ - { "kind": "account", "path": "pull_feed" }, - { - "kind": "const", - "value": [ - 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, - 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, - 245, 133, 126, 255, 0, 169 - ] - }, - { "kind": "account", "path": "wrapped_sol_mint" } - ], - "program": { - "kind": "const", - "value": [ - 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, - 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, - 219, 233, 248, 89 - ] - } - } - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "associated_token_program", - "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" - }, - { - "name": "wrapped_sol_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedInitParams" } } - } - ] - }, - { - "name": "pull_feed_set_configs", - "discriminator": [217, 45, 11, 246, 64, 26, 82, 168], - "accounts": [ - { "name": "pull_feed", "writable": true }, - { "name": "authority", "signer": true, "relations": ["pull_feed"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedSetConfigsParams" } } - } - ] - }, - { - "name": "pull_feed_submit_response", - "discriminator": [150, 22, 215, 166, 143, 93, 48, 137], - "accounts": [ - { "name": "feed", "writable": true }, - { "name": "queue", "relations": ["feed"] }, - { "name": "program_state" }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "reward_vault", "writable": true }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "token_mint", - "address": "So11111111111111111111111111111111111111112" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedSubmitResponseParams" } } - } - ] - }, - { - "name": "pull_feed_submit_response_many", - "discriminator": [47, 156, 45, 25, 200, 71, 37, 215], - "accounts": [ - { "name": "queue" }, - { "name": "program_state" }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "reward_vault", "writable": true }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "token_mint", - "address": "So11111111111111111111111111111111111111112" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedSubmitResponseManyParams" } } - } - ] - }, - { - "name": "queue_add_mr_enclave", - "discriminator": [199, 255, 81, 50, 60, 133, 171, 138], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "authority", "signer": true }, - { "name": "program_authority" }, - { "name": "state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueAddMrEnclaveParams" } } - } - ] - }, - { - "name": "queue_allow_subsidies", - "discriminator": [94, 203, 82, 157, 188, 138, 202, 108], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "authority", "signer": true, "relations": ["state"] }, - { "name": "state", "writable": true } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueAllowSubsidiesParams" } } - } - ] - }, - { - "name": "queue_garbage_collect", - "discriminator": [187, 208, 104, 247, 16, 91, 96, 98], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "oracle", "writable": true }, - { "name": "authority", "signer": true }, - { "name": "state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueGarbageCollectParams" } } - } - ] - }, - { - "name": "queue_init", - "discriminator": [144, 18, 99, 145, 133, 27, 207, 13], - "accounts": [ - { "name": "queue", "writable": true, "signer": true }, - { - "name": "queue_escrow", - "writable": true, - "pda": { - "seeds": [ - { "kind": "account", "path": "queue" }, - { - "kind": "const", - "value": [ - 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, - 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, - 245, 133, 126, 255, 0, 169 - ] - }, - { "kind": "account", "path": "native_mint" } - ], - "program": { - "kind": "const", - "value": [ - 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, - 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, - 219, 233, 248, 89 - ] - } - } - }, - { "name": "authority" }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "native_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "program_state" }, - { "name": "lut_signer", "writable": true }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - }, - { - "name": "associated_token_program", - "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueInitParams" } } - } - ] - }, - { - "name": "queue_init_delegation_group", - "discriminator": [239, 146, 75, 158, 20, 166, 159, 14], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "program_state" }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - }, - { "name": "delegation_group", "writable": true }, - { "name": "stake_program", "relations": ["program_state"] }, - { "name": "stake_pool" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueInitDelegationGroupParams" } } - } - ] - }, - { - "name": "queue_remove_mr_enclave", - "discriminator": [3, 64, 135, 33, 190, 133, 68, 252], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "authority", "signer": true }, - { "name": "program_authority" }, - { "name": "state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueRemoveMrEnclaveParams" } } - } - ] - }, - { - "name": "queue_set_configs", - "discriminator": [54, 183, 243, 199, 49, 103, 142, 48], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "authority", "signer": true }, - { "name": "state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueSetConfigsParams" } } - } - ] - }, - { - "name": "randomness_commit", - "discriminator": [52, 170, 152, 201, 179, 133, 242, 141], - "accounts": [ - { "name": "randomness", "writable": true }, - { "name": "queue", "relations": ["randomness", "oracle"] }, - { "name": "oracle", "writable": true }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - }, - { "name": "authority", "signer": true, "relations": ["randomness"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "RandomnessCommitParams" } } - } - ] - }, - { - "name": "randomness_init", - "discriminator": [9, 9, 204, 33, 50, 116, 113, 15], - "accounts": [ - { "name": "randomness", "writable": true, "signer": true }, - { - "name": "reward_escrow", - "writable": true, - "pda": { - "seeds": [ - { "kind": "account", "path": "randomness" }, - { - "kind": "const", - "value": [ - 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, - 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, - 245, 133, 126, 255, 0, 169 - ] - }, - { "kind": "account", "path": "wrapped_sol_mint" } - ], - "program": { - "kind": "const", - "value": [ - 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, - 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, - 219, 233, 248, 89 - ] - } - } - }, - { "name": "authority", "signer": true }, - { "name": "queue", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "associated_token_program", - "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" - }, - { - "name": "wrapped_sol_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "program_state" }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "RandomnessInitParams" } } - } - ] - }, - { - "name": "randomness_reveal", - "discriminator": [197, 181, 187, 10, 30, 58, 20, 73], - "accounts": [ - { "name": "randomness", "writable": true }, - { "name": "oracle", "relations": ["randomness"] }, - { "name": "queue", "relations": ["oracle"] }, - { - "name": "stats", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 79, 114, 97, 99, 108, 101, 82, 97, 110, 100, 111, 109, 110, - 101, 115, 115, 83, 116, 97, 116, 115 - ] - }, - { "kind": "account", "path": "oracle" } - ] - } - }, - { "name": "authority", "signer": true, "relations": ["randomness"] }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "reward_escrow", "writable": true }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "wrapped_sol_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "program_state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "RandomnessRevealParams" } } - } - ] - }, - { - "name": "state_init", - "discriminator": [103, 241, 106, 190, 217, 153, 87, 105], - "accounts": [ - { - "name": "state", - "writable": true, - "pda": { - "seeds": [{ "kind": "const", "value": [83, 84, 65, 84, 69] }] - } - }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "StateInitParams" } } - } - ] - }, - { - "name": "state_set_configs", - "discriminator": [40, 98, 76, 37, 206, 9, 47, 144], - "accounts": [ - { "name": "state", "writable": true }, - { "name": "authority", "signer": true, "relations": ["state"] }, - { "name": "queue", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "StateSetConfigsParams" } } - } - ] - } - ], - "accounts": [ - { - "name": "OracleAccountData", - "discriminator": [128, 30, 16, 241, 170, 73, 55, 54] - }, - { - "name": "OracleStatsAccountData", - "discriminator": [180, 157, 178, 234, 240, 27, 152, 179] - }, - { - "name": "PullFeedAccountData", - "discriminator": [196, 27, 108, 196, 10, 215, 219, 40] - }, - { - "name": "QueueAccountData", - "discriminator": [217, 194, 55, 127, 184, 83, 138, 1] - }, - { - "name": "RandomnessAccountData", - "discriminator": [10, 66, 229, 135, 220, 239, 217, 114] - }, - { "name": "State", "discriminator": [216, 146, 107, 94, 104, 75, 182, 177] } - ], - "events": [ - { - "name": "CostWhitelistEvent", - "discriminator": [56, 107, 191, 127, 116, 6, 138, 149] - }, - { - "name": "GarbageCollectionEvent", - "discriminator": [232, 235, 2, 188, 8, 143, 145, 237] - }, - { - "name": "GuardianQuoteVerifyEvent", - "discriminator": [31, 37, 39, 6, 214, 186, 33, 115] - }, - { - "name": "OracleHeartbeatEvent", - "discriminator": [52, 29, 166, 2, 94, 7, 188, 13] - }, - { - "name": "OracleInitEvent", - "discriminator": [89, 193, 219, 200, 1, 83, 167, 24] - }, - { - "name": "OracleQuoteOverrideEvent", - "discriminator": [78, 204, 191, 210, 164, 196, 244, 65] - }, - { - "name": "OracleQuoteRotateEvent", - "discriminator": [26, 189, 196, 192, 225, 127, 26, 228] - }, - { - "name": "OracleQuoteVerifyRequestEvent", - "discriminator": [203, 209, 79, 0, 20, 71, 226, 202] - }, - { - "name": "PermissionSetEvent", - "discriminator": [148, 86, 123, 0, 102, 20, 119, 206] - }, - { - "name": "PullFeedErrorValueEvent", - "discriminator": [225, 80, 192, 95, 14, 12, 83, 192] - }, - { - "name": "PullFeedValueEvents", - "discriminator": [86, 7, 231, 28, 122, 161, 117, 69] - }, - { - "name": "QueueAddMrEnclaveEvent", - "discriminator": [170, 186, 175, 38, 216, 51, 69, 175] - }, - { - "name": "QueueInitEvent", - "discriminator": [44, 137, 99, 227, 107, 8, 30, 105] - }, - { - "name": "QueueRemoveMrEnclaveEvent", - "discriminator": [4, 105, 196, 60, 84, 122, 203, 196] - }, - { - "name": "RandomnessCommitEvent", - "discriminator": [88, 60, 172, 90, 112, 10, 206, 147] - } - ], - "errors": [ - { "code": 6000, "name": "GenericError" }, - { "code": 6001, "name": "InvalidQuote" }, - { "code": 6002, "name": "InsufficientQueue" }, - { "code": 6003, "name": "QueueFull" }, - { "code": 6004, "name": "InvalidEnclaveSigner" }, - { "code": 6005, "name": "InvalidSigner" }, - { "code": 6006, "name": "MrEnclaveAlreadyExists" }, - { "code": 6007, "name": "MrEnclaveAtCapacity" }, - { "code": 6008, "name": "MrEnclaveDoesntExist" }, - { "code": 6009, "name": "PermissionDenied" }, - { "code": 6010, "name": "InvalidQueue" }, - { "code": 6011, "name": "IncorrectMrEnclave" }, - { "code": 6012, "name": "InvalidAuthority" }, - { "code": 6013, "name": "InvalidMrEnclave" }, - { "code": 6014, "name": "InvalidTimestamp" }, - { "code": 6015, "name": "InvalidOracleIdx" }, - { "code": 6016, "name": "InvalidSecpSignature" }, - { "code": 6017, "name": "InvalidGuardianQueue" }, - { "code": 6018, "name": "InvalidIndex" }, - { "code": 6019, "name": "InvalidOracleQueue" }, - { "code": 6020, "name": "InvalidPermission" }, - { "code": 6021, "name": "InvalidePermissionedAccount" }, - { "code": 6022, "name": "InvalidEpochRotate" }, - { "code": 6023, "name": "InvalidEpochFinalize" }, - { "code": 6024, "name": "InvalidEscrow" }, - { "code": 6025, "name": "IllegalOracle" }, - { "code": 6026, "name": "IllegalExecuteAttempt" }, - { "code": 6027, "name": "IllegalFeedValue" }, - { "code": 6028, "name": "InvalidOracleFeedStats" }, - { "code": 6029, "name": "InvalidStateAuthority" }, - { "code": 6030, "name": "NotEnoughSamples" }, - { "code": 6031, "name": "OracleIsVerified" }, - { "code": 6032, "name": "QueueIsEmpty" }, - { "code": 6033, "name": "SecpRecoverFailure" }, - { "code": 6034, "name": "StaleSample" }, - { "code": 6035, "name": "SwitchboardRandomnessTooOld" }, - { "code": 6036, "name": "EpochIdMismatch" }, - { "code": 6037, "name": "GuardianAlreadyVoted" }, - { "code": 6038, "name": "RandomnessNotRequested" }, - { "code": 6039, "name": "InvalidSlotNumber" }, - { "code": 6040, "name": "RandomnessOracleKeyExpired" }, - { "code": 6041, "name": "InvalidAdvisory" }, - { "code": 6042, "name": "InvalidOracleStats" }, - { "code": 6043, "name": "InvalidStakeProgram" }, - { "code": 6044, "name": "InvalidStakePool" }, - { "code": 6045, "name": "InvalidDelegationPool" }, - { "code": 6046, "name": "UnparsableAccount" }, - { "code": 6047, "name": "InvalidInstruction" }, - { "code": 6048, "name": "OracleAlreadyVerified" }, - { "code": 6049, "name": "GuardianNotVerified" }, - { "code": 6050, "name": "InvalidConstraint" }, - { "code": 6051, "name": "InvalidDelegationGroup" }, - { "code": 6052, "name": "OracleKeyNotFound" }, - { "code": 6053, "name": "GuardianReregisterAttempt" } - ], - "types": [ - { - "name": "CompactResult", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "std_dev", - "docs": [ - "The standard deviation of the submissions needed for quorom size" - ], - "type": "f32" - }, - { - "name": "mean", - "docs": ["The mean of the submissions needed for quorom size"], - "type": "f32" - }, - { - "name": "slot", - "docs": ["The slot at which this value was signed."], - "type": "u64" - } - ] - } - }, - { - "name": "CostWhitelistEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "feeds", "type": { "vec": "pubkey" } }, - { "name": "reward", "type": "u32" } - ] - } - }, - { - "name": "CurrentResult", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "value", - "docs": [ - "The median value of the submissions needed for quorom size" - ], - "type": "i128" - }, - { - "name": "std_dev", - "docs": [ - "The standard deviation of the submissions needed for quorom size" - ], - "type": "i128" - }, - { - "name": "mean", - "docs": ["The mean of the submissions needed for quorom size"], - "type": "i128" - }, - { - "name": "range", - "docs": ["The range of the submissions needed for quorom size"], - "type": "i128" - }, - { - "name": "min_value", - "docs": [ - "The minimum value of the submissions needed for quorom size" - ], - "type": "i128" - }, - { - "name": "max_value", - "docs": [ - "The maximum value of the submissions needed for quorom size" - ], - "type": "i128" - }, - { - "name": "num_samples", - "docs": ["The number of samples used to calculate this result"], - "type": "u8" - }, - { "name": "padding1", "type": { "array": ["u8", 7] } }, - { - "name": "slot", - "docs": ["The slot at which this value was signed."], - "type": "u64" - }, - { - "name": "min_slot", - "docs": [ - "The slot at which the first considered submission was made" - ], - "type": "u64" - }, - { - "name": "max_slot", - "docs": [ - "The slot at which the last considered submission was made" - ], - "type": "u64" - } - ] - } - }, - { - "name": "GarbageCollectionEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "oracle", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" } - ] - } - }, - { - "name": "GuardianQuoteVerifyEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "quote", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" } - ] - } - }, - { - "name": "GuardianQuoteVerifyParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "timestamp", "type": "i64" }, - { "name": "mr_enclave", "type": { "array": ["u8", 32] } }, - { "name": "_reserved1", "type": "u32" }, - { "name": "ed25519_key", "type": "pubkey" }, - { "name": "secp256k1_key", "type": { "array": ["u8", 64] } }, - { "name": "slot", "type": "u64" }, - { "name": "signature", "type": { "array": ["u8", 64] } }, - { "name": "recovery_id", "type": "u8" }, - { "name": "advisories", "type": { "vec": "u32" } } - ] - } - }, - { - "name": "GuardianRegisterParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "GuardianUnregisterParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "MegaSlotInfo", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "reserved1", "type": "u64" }, - { "name": "slot_end", "type": "u64" }, - { "name": "perf_goal", "type": "i64" }, - { "name": "current_signature_count", "type": "i64" } - ] - } - }, - { - "name": "MultiSubmission", - "type": { - "kind": "struct", - "fields": [ - { "name": "values", "type": { "vec": "i128" } }, - { "name": "signature", "type": { "array": ["u8", 64] } }, - { "name": "recovery_id", "type": "u8" } - ] - } - }, - { - "name": "OracleAccountData", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "enclave", - "docs": ["Represents the state of the quote verifiers enclave."], - "type": { "defined": { "name": "Quote" } } - }, - { - "name": "authority", - "docs": [ - "The authority of the EnclaveAccount which is permitted to make account changes." - ], - "type": "pubkey" - }, - { - "name": "queue", - "docs": [ - "Queue used for attestation to verify a MRENCLAVE measurement." - ], - "type": "pubkey" - }, - { - "name": "created_at", - "docs": ["The unix timestamp when the quote was created."], - "type": "i64" - }, - { - "name": "last_heartbeat", - "docs": ["The last time the quote heartbeated on-chain."], - "type": "i64" - }, - { "name": "secp_authority", "type": { "array": ["u8", 64] } }, - { - "name": "gateway_uri", - "docs": ["URI location of the verifier's gateway."], - "type": { "array": ["u8", 64] } - }, - { "name": "permissions", "type": "u64" }, - { - "name": "is_on_queue", - "docs": [ - "Whether the quote is located on the AttestationQueues buffer." - ], - "type": "u8" - }, - { "name": "_padding1", "type": { "array": ["u8", 7] } }, - { "name": "lut_slot", "type": "u64" }, - { "name": "last_reward_epoch", "type": "u64" }, - { "name": "_ebuf4", "type": { "array": ["u8", 16] } }, - { "name": "_ebuf3", "type": { "array": ["u8", 32] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 64] } }, - { "name": "_ebuf1", "type": { "array": ["u8", 1024] } } - ] - } - }, - { - "name": "OracleEpochInfo", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "id", "type": "u64" }, - { "name": "reserved1", "type": "u64" }, - { "name": "slot_end", "type": "u64" }, - { "name": "slash_score", "type": "u64" }, - { "name": "reward_score", "type": "u64" }, - { "name": "stake_score", "type": "u64" } - ] - } - }, - { - "name": "OracleHeartbeatEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "oracle", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" } - ] - } - }, - { - "name": "OracleHeartbeatParams", - "type": { - "kind": "struct", - "fields": [ - { - "name": "gateway_uri", - "type": { "option": { "array": ["u8", 64] } } - } - ] - } - }, - { - "name": "OracleInitEvent", - "type": { - "kind": "struct", - "fields": [{ "name": "oracle", "type": "pubkey" }] - } - }, - { - "name": "OracleInitParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "recent_slot", "type": "u64" }, - { "name": "authority", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" }, - { - "name": "secp_authority", - "type": { "option": { "array": ["u8", 64] } } - } - ] - } - }, - { - "name": "OracleQuoteOverrideEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "oracle", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" } - ] - } - }, - { - "name": "OracleQuoteRotateEvent", - "type": { - "kind": "struct", - "fields": [{ "name": "oracle", "type": "pubkey" }] - } - }, - { - "name": "OracleQuoteVerifyRequestEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "quote", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" } - ] - } - }, - { - "name": "OracleSetConfigsParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "new_authority", "type": { "option": "pubkey" } }, - { - "name": "new_secp_authority", - "type": { "option": { "array": ["u8", 64] } } - } - ] - } - }, - { - "name": "OracleStatsAccountData", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "owner", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" }, - { - "name": "finalized_epoch", - "docs": [ - "The last epoch that has completed. cleared after registered with the", - "staking program." - ], - "type": { "defined": { "name": "OracleEpochInfo" } } - }, - { - "name": "current_epoch", - "docs": [ - "The current epoch info being used by the oracle. for stake. Will moved", - "to finalized_epoch as soon as the epoch is over." - ], - "type": { "defined": { "name": "OracleEpochInfo" } } - }, - { - "name": "mega_slot_info", - "type": { "defined": { "name": "MegaSlotInfo" } } - }, - { "name": "last_transfer_slot", "type": "u64" }, - { "name": "bump", "type": "u8" }, - { "name": "padding1", "type": { "array": ["u8", 7] } }, - { - "name": "_ebuf", - "docs": ["Reserved."], - "type": { "array": ["u8", 1024] } - } - ] - } - }, - { - "name": "OracleSubmission", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "oracle", - "docs": ["The public key of the oracle that submitted this value."], - "type": "pubkey" - }, - { - "name": "slot", - "docs": ["The slot at which this value was signed."], - "type": "u64" - }, - { "name": "padding1", "type": { "array": ["u8", 8] } }, - { - "name": "value", - "docs": ["The value that was submitted."], - "type": "i128" - } - ] - } - }, - { - "name": "OracleUpdateDelegationParams", - "type": { - "kind": "struct", - "fields": [{ "name": "_reserved1", "type": "u64" }] - } - }, - { - "name": "PermissionSetEvent", - "type": { - "kind": "struct", - "fields": [{ "name": "permission", "type": "pubkey" }] - } - }, - { - "name": "PermissionSetParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "permission", "type": "u8" }, - { "name": "enable", "type": "bool" } - ] - } - }, - { - "name": "PullFeedAccountData", - "docs": ["A representation of the data in a pull feed account."], - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "submissions", - "docs": ["The oracle submissions for this feed."], - "type": { - "array": [{ "defined": { "name": "OracleSubmission" } }, 32] - } - }, - { - "name": "authority", - "docs": [ - "The public key of the authority that can update the feed hash that", - "this account will use for registering updates." - ], - "type": "pubkey" - }, - { - "name": "queue", - "docs": [ - "The public key of the queue which oracles must be bound to in order to", - "submit data to this feed." - ], - "type": "pubkey" - }, - { - "name": "feed_hash", - "docs": [ - "SHA-256 hash of the job schema oracles will execute to produce data", - "for this feed." - ], - "type": { "array": ["u8", 32] } - }, - { - "name": "initialized_at", - "docs": ["The slot at which this account was initialized."], - "type": "i64" - }, - { "name": "permissions", "type": "u64" }, - { "name": "max_variance", "type": "u64" }, - { "name": "min_responses", "type": "u32" }, - { "name": "name", "type": { "array": ["u8", 32] } }, - { "name": "padding1", "type": { "array": ["u8", 2] } }, - { "name": "historical_result_idx", "type": "u8" }, - { "name": "min_sample_size", "type": "u8" }, - { "name": "last_update_timestamp", "type": "i64" }, - { "name": "lut_slot", "type": "u64" }, - { "name": "_reserved1", "type": { "array": ["u8", 32] } }, - { - "name": "result", - "type": { "defined": { "name": "CurrentResult" } } - }, - { "name": "max_staleness", "type": "u32" }, - { "name": "padding2", "type": { "array": ["u8", 12] } }, - { - "name": "historical_results", - "type": { - "array": [{ "defined": { "name": "CompactResult" } }, 32] - } - }, - { "name": "_ebuf4", "type": { "array": ["u8", 8] } }, - { "name": "_ebuf3", "type": { "array": ["u8", 24] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 256] } } - ] - } - }, - { - "name": "PullFeedCloseParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "PullFeedErrorValueEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "feed", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" } - ] - } - }, - { - "name": "PullFeedInitParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "feed_hash", "type": { "array": ["u8", 32] } }, - { "name": "max_variance", "type": "u64" }, - { "name": "min_responses", "type": "u32" }, - { "name": "name", "type": { "array": ["u8", 32] } }, - { "name": "recent_slot", "type": "u64" }, - { "name": "ipfs_hash", "type": { "array": ["u8", 32] } }, - { "name": "min_sample_size", "type": "u8" }, - { "name": "max_staleness", "type": "u32" } - ] - } - }, - { - "name": "PullFeedSetConfigsParams", - "type": { - "kind": "struct", - "fields": [ - { - "name": "feed_hash", - "type": { "option": { "array": ["u8", 32] } } - }, - { "name": "authority", "type": { "option": "pubkey" } }, - { "name": "max_variance", "type": { "option": "u64" } }, - { "name": "min_responses", "type": { "option": "u32" } }, - { "name": "name", "type": { "option": { "array": ["u8", 32] } } }, - { - "name": "ipfs_hash", - "type": { "option": { "array": ["u8", 32] } } - }, - { "name": "min_sample_size", "type": { "option": "u8" } }, - { "name": "max_staleness", "type": { "option": "u32" } } - ] - } - }, - { - "name": "PullFeedSubmitResponseManyParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "slot", "type": "u64" }, - { - "name": "submissions", - "type": { "vec": { "defined": { "name": "MultiSubmission" } } } - } - ] - } - }, - { - "name": "PullFeedSubmitResponseParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "slot", "type": "u64" }, - { - "name": "submissions", - "type": { "vec": { "defined": { "name": "Submission" } } } - } - ] - } - }, - { - "name": "PullFeedValueEvents", - "type": { - "kind": "struct", - "fields": [ - { "name": "feeds", "type": { "vec": "pubkey" } }, - { "name": "oracles", "type": { "vec": "pubkey" } }, - { "name": "values", "type": { "vec": { "vec": "i128" } } }, - { "name": "reward", "type": "u32" } - ] - } - }, - { - "name": "QueueAccountData", - "docs": [ - "An Queue represents a round-robin queue of oracle oracles who attest on-chain", - "whether a Switchboard Function was executed within an enclave against an expected set of", - "enclave measurements.", - "", - "For an oracle to join the queue, the oracle must first submit their enclave quote on-chain and", - "wait for an existing oracle to attest their quote. If the oracle's quote matches an expected", - "measurement within the queues mr_enclaves config, it is granted permissions and will start", - "being assigned update requests." - ], - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "authority", - "docs": [ - "The address of the authority which is permitted to add/remove allowed enclave measurements." - ], - "type": "pubkey" - }, - { - "name": "mr_enclaves", - "docs": ["Allowed enclave measurements."], - "type": { "array": [{ "array": ["u8", 32] }, 32] } - }, - { - "name": "oracle_keys", - "docs": [ - "The addresses of the quote oracles who have a valid", - "verification status and have heartbeated on-chain recently." - ], - "type": { "array": ["pubkey", 128] } - }, - { - "name": "max_quote_verification_age", - "docs": [ - "The maximum allowable time until a EnclaveAccount needs to be re-verified on-chain." - ], - "type": "i64" - }, - { - "name": "last_heartbeat", - "docs": [ - "The unix timestamp when the last quote oracle heartbeated on-chain." - ], - "type": "i64" - }, - { "name": "node_timeout", "type": "i64" }, - { - "name": "oracle_min_stake", - "docs": [ - "The minimum number of lamports a quote oracle needs to lock-up in order to heartbeat and verify other quotes." - ], - "type": "u64" - }, - { "name": "allow_authority_override_after", "type": "i64" }, - { - "name": "mr_enclaves_len", - "docs": ["The number of allowed enclave measurements."], - "type": "u32" - }, - { - "name": "oracle_keys_len", - "docs": [ - "The length of valid quote oracles for the given attestation queue." - ], - "type": "u32" - }, - { - "name": "reward", - "docs": [ - "The reward paid to quote oracles for attesting on-chain." - ], - "type": "u32" - }, - { - "name": "curr_idx", - "docs": [ - "Incrementer used to track the current quote oracle permitted to run any available functions." - ], - "type": "u32" - }, - { - "name": "gc_idx", - "docs": [ - "Incrementer used to garbage collect and remove stale quote oracles." - ], - "type": "u32" - }, - { "name": "require_authority_heartbeat_permission", "type": "u8" }, - { "name": "require_authority_verify_permission", "type": "u8" }, - { "name": "require_usage_permissions", "type": "u8" }, - { "name": "signer_bump", "type": "u8" }, - { "name": "mint", "type": "pubkey" }, - { "name": "lut_slot", "type": "u64" }, - { "name": "allow_subsidies", "type": "u8" }, - { - "name": "_ebuf6", - "docs": ["Reserved."], - "type": { "array": ["u8", 23] } - }, - { "name": "_ebuf5", "type": { "array": ["u8", 32] } }, - { "name": "_ebuf4", "type": { "array": ["u8", 64] } }, - { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 256] } }, - { "name": "_ebuf1", "type": { "array": ["u8", 512] } } - ] - } - }, - { - "name": "QueueAddMrEnclaveEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "queue", "type": "pubkey" }, - { "name": "mr_enclave", "type": { "array": ["u8", 32] } } - ] - } - }, - { - "name": "QueueAddMrEnclaveParams", - "type": { - "kind": "struct", - "fields": [{ "name": "mr_enclave", "type": { "array": ["u8", 32] } }] - } - }, - { - "name": "QueueAllowSubsidiesParams", - "type": { - "kind": "struct", - "fields": [{ "name": "allow_subsidies", "type": "u8" }] - } - }, - { - "name": "QueueGarbageCollectParams", - "type": { "kind": "struct", "fields": [{ "name": "idx", "type": "u32" }] } - }, - { - "name": "QueueInitDelegationGroupParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "QueueInitEvent", - "type": { - "kind": "struct", - "fields": [{ "name": "queue", "type": "pubkey" }] - } - }, - { - "name": "QueueInitParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "allow_authority_override_after", "type": "u32" }, - { "name": "require_authority_heartbeat_permission", "type": "bool" }, - { "name": "require_usage_permissions", "type": "bool" }, - { "name": "max_quote_verification_age", "type": "u32" }, - { "name": "reward", "type": "u32" }, - { "name": "node_timeout", "type": "u32" }, - { "name": "recent_slot", "type": "u64" } - ] - } - }, - { - "name": "QueueRemoveMrEnclaveEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "queue", "type": "pubkey" }, - { "name": "mr_enclave", "type": { "array": ["u8", 32] } } - ] - } - }, - { - "name": "QueueRemoveMrEnclaveParams", - "type": { - "kind": "struct", - "fields": [{ "name": "mr_enclave", "type": { "array": ["u8", 32] } }] - } - }, - { - "name": "QueueSetConfigsParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "authority", "type": { "option": "pubkey" } }, - { "name": "reward", "type": { "option": "u32" } }, - { "name": "node_timeout", "type": { "option": "i64" } } - ] - } - }, - { - "name": "Quote", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "enclave_signer", - "docs": ["The address of the signer generated within an enclave."], - "type": "pubkey" - }, - { - "name": "mr_enclave", - "docs": [ - "The quotes MRENCLAVE measurement dictating the contents of the secure enclave." - ], - "type": { "array": ["u8", 32] } - }, - { - "name": "verification_status", - "docs": ["The VerificationStatus of the quote."], - "type": "u8" - }, - { "name": "padding1", "type": { "array": ["u8", 7] } }, - { - "name": "verification_timestamp", - "docs": ["The unix timestamp when the quote was last verified."], - "type": "i64" - }, - { - "name": "valid_until", - "docs": [ - "The unix timestamp when the quotes verification status expires." - ], - "type": "i64" - }, - { - "name": "quote_registry", - "docs": [ - "The off-chain registry where the verifiers quote can be located." - ], - "type": { "array": ["u8", 32] } - }, - { - "name": "registry_key", - "docs": [ - "Key to lookup the buffer data on IPFS or an alternative decentralized storage solution." - ], - "type": { "array": ["u8", 64] } - }, - { - "name": "secp256k1_signer", - "docs": [ - "The secp256k1 public key of the enclave signer. Derived from the enclave_signer." - ], - "type": { "array": ["u8", 64] } - }, - { "name": "last_ed25519_signer", "type": "pubkey" }, - { "name": "last_secp256k1_signer", "type": { "array": ["u8", 64] } }, - { "name": "last_rotate_slot", "type": "u64" }, - { "name": "guardian_approvers", "type": { "array": ["pubkey", 64] } }, - { "name": "guardian_approvers_len", "type": "u8" }, - { "name": "padding2", "type": { "array": ["u8", 7] } }, - { "name": "staging_ed25519_signer", "type": "pubkey" }, - { - "name": "staging_secp256k1_signer", - "type": { "array": ["u8", 64] } - }, - { - "name": "_ebuf4", - "docs": ["Reserved."], - "type": { "array": ["u8", 32] } - }, - { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 256] } }, - { "name": "_ebuf1", "type": { "array": ["u8", 512] } } - ] - } - }, - { - "name": "RandomnessAccountData", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "authority", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" }, - { "name": "seed_slothash", "type": { "array": ["u8", 32] } }, - { "name": "seed_slot", "type": "u64" }, - { "name": "oracle", "type": "pubkey" }, - { "name": "reveal_slot", "type": "u64" }, - { "name": "value", "type": { "array": ["u8", 32] } }, - { "name": "lut_slot", "type": "u64" }, - { "name": "_ebuf3", "type": { "array": ["u8", 24] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 64] } }, - { "name": "_ebuf1", "type": { "array": ["u8", 128] } }, - { - "name": "active_secp256k1_signer", - "type": { "array": ["u8", 64] } - }, - { "name": "active_secp256k1_expiration", "type": "i64" } - ] - } - }, - { - "name": "RandomnessCommitEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "randomness_account", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" }, - { "name": "slot", "type": "u64" }, - { "name": "slothash", "type": { "array": ["u8", 32] } } - ] - } - }, - { - "name": "RandomnessCommitParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "RandomnessInitParams", - "type": { - "kind": "struct", - "fields": [{ "name": "recent_slot", "type": "u64" }] - } - }, - { - "name": "RandomnessRevealParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "signature", "type": { "array": ["u8", 64] } }, - { "name": "recovery_id", "type": "u8" }, - { "name": "value", "type": { "array": ["u8", 32] } } - ] - } - }, - { - "name": "State", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "bump", "type": "u8" }, - { "name": "test_only_disable_mr_enclave_check", "type": "u8" }, - { "name": "enable_staking", "type": "u8" }, - { "name": "padding1", "type": { "array": ["u8", 5] } }, - { "name": "authority", "type": "pubkey" }, - { "name": "guardian_queue", "type": "pubkey" }, - { "name": "reserved1", "type": "u64" }, - { "name": "epoch_length", "type": "u64" }, - { - "name": "current_epoch", - "type": { "defined": { "name": "StateEpochInfo" } } - }, - { - "name": "next_epoch", - "type": { "defined": { "name": "StateEpochInfo" } } - }, - { - "name": "finalized_epoch", - "type": { "defined": { "name": "StateEpochInfo" } } - }, - { "name": "stake_pool", "type": "pubkey" }, - { "name": "stake_program", "type": "pubkey" }, - { "name": "switch_mint", "type": "pubkey" }, - { "name": "sgx_advisories", "type": { "array": ["u16", 32] } }, - { "name": "advisories_len", "type": "u8" }, - { "name": "padding2", "type": "u8" }, - { "name": "flat_reward_cut_percentage", "type": "u8" }, - { "name": "enable_slashing", "type": "u8" }, - { "name": "subsidy_amount", "type": "u32" }, - { "name": "lut_slot", "type": "u64" }, - { "name": "base_reward", "type": "u32" }, - { "name": "_ebuf6", "type": { "array": ["u8", 28] } }, - { "name": "_ebuf5", "type": { "array": ["u8", 32] } }, - { "name": "_ebuf4", "type": { "array": ["u8", 64] } }, - { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 512] } }, - { - "name": "cost_whitelist", - "docs": ["Cost whitelist by authority"], - "type": { "array": ["pubkey", 32] } - } - ] - } - }, - { - "name": "StateEpochInfo", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "id", "type": "u64" }, - { "name": "_reserved1", "type": "u64" }, - { "name": "slot_end", "type": "u64" } - ] - } - }, - { "name": "StateInitParams", "type": { "kind": "struct", "fields": [] } }, - { - "name": "StateSetConfigsParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "new_authority", "type": "pubkey" }, - { "name": "test_only_disable_mr_enclave_check", "type": "u8" }, - { "name": "stake_pool", "type": "pubkey" }, - { "name": "stake_program", "type": "pubkey" }, - { "name": "add_advisory", "type": "u16" }, - { "name": "rm_advisory", "type": "u16" }, - { "name": "epoch_length", "type": "u32" }, - { "name": "reset_epochs", "type": "bool" }, - { "name": "switch_mint", "type": "pubkey" }, - { "name": "enable_staking", "type": "u8" }, - { "name": "subsidy_amount", "type": "u32" }, - { "name": "base_reward", "type": "u32" }, - { "name": "add_cost_wl", "type": "pubkey" }, - { "name": "rm_cost_wl", "type": "pubkey" } - ] - } - }, - { - "name": "Submission", - "type": { - "kind": "struct", - "fields": [ - { "name": "value", "type": "i128" }, - { "name": "signature", "type": { "array": ["u8", 64] } }, - { "name": "recovery_id", "type": "u8" }, - { "name": "offset", "type": "u8" } - ] - } - } - ] -} diff --git a/solauto-sdk/src/utils/switchboardUtils.ts b/solauto-sdk/src/utils/switchboardUtils.ts index 7f635d6f..a29ed0a5 100644 --- a/solauto-sdk/src/utils/switchboardUtils.ts +++ b/solauto-sdk/src/utils/switchboardUtils.ts @@ -6,10 +6,9 @@ import { } from "@solana/web3.js"; import { Signer, transactionBuilder } from "@metaplex-foundation/umi"; import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; -import { AnchorProvider, Idl, Program } from "@coral-xyz/anchor"; +import { AnchorProvider, Program } from "@coral-xyz/anchor"; import * as OnDemand from "@switchboard-xyz/on-demand"; import Big from "big.js"; -import switchboardIdl from "../idls/switchboard.json"; import { PRICES, SWITCHBOARD_PRICE_FEED_IDS } from "../constants"; import { TransactionItemInputs } from "../types"; import { @@ -18,7 +17,7 @@ import { } from "./generalUtils"; import { getWrappedInstruction } from "./solanaUtils"; -export function getPullFeed( +export async function getPullFeed( conn: Connection, mint: PublicKey, wallet?: PublicKey @@ -37,11 +36,12 @@ export function getPullFeed( dummyWallet, AnchorProvider.defaultOptions() ); - const program = new Program(switchboardIdl as Idl, provider); + const { PullFeed, ON_DEMAND_MAINNET_PID } = OnDemand; + const sbProgram = await Program.at(ON_DEMAND_MAINNET_PID, provider); - const { PullFeed } = OnDemand; + console.log(new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId).toString()) return new PullFeed( - program, + sbProgram, new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId) ); } @@ -51,12 +51,18 @@ export async function buildSwbSubmitResponseTx( signer: Signer, mint: PublicKey ): Promise { - const feed = getPullFeed(conn, mint, toWeb3JsPublicKey(signer.publicKey)); - const [pullIx, responses] = await retryWithExponentialBackoff( + const feed = await getPullFeed( + conn, + mint, + toWeb3JsPublicKey(signer.publicKey) + ); + const gateway = await feed.fetchGatewayUrl(); + const [pullIxs, responses] = await retryWithExponentialBackoff( async () => { const res = await feed.fetchUpdateIx({ + gateway: gateway, chain: "solana", - network: "mainnet-beta", + network: "mainnet", }); if (!res[1] || !res[1][0].value) { throw new Error("Unable to fetch Switchboard pull IX"); @@ -67,7 +73,7 @@ export async function buildSwbSubmitResponseTx( 200 ); - if (!pullIx) { + if (!pullIxs || !pullIxs.length) { throw new Error("Unable to fetch SWB crank IX"); } @@ -81,7 +87,9 @@ export async function buildSwbSubmitResponseTx( }; return { - tx: transactionBuilder([getWrappedInstruction(signer, pullIx!)]), + tx: transactionBuilder( + pullIxs.map((x) => getWrappedInstruction(signer, x)) + ), lookupTableAddresses: responses .filter((x) => Boolean(x.oracle.lut?.key)) .map((x) => x.oracle.lut!.key.toString()), @@ -103,7 +111,7 @@ export async function getSwitchboardFeedData( const results = await Promise.all( mints.map(async (mint) => { - const feed = getPullFeed(conn, mint); + const feed = await getPullFeed(conn, mint); const result = await feed.loadData(); const price = Number(result.result.value) / Math.pow(10, 18); const stale = From 66bd27790d5653fd45df6a8bcfdfef8008de4d9b Mon Sep 17 00:00:00 2001 From: Chelioso Date: Wed, 9 Jul 2025 10:21:08 -0400 Subject: [PATCH 61/88] Revert "bump versions" This reverts commit 66fce9514ce2f0535cce4c02c100e7499dd8024e. --- pnpm-lock.yaml | 217 ++- solauto-sdk/package.json | 10 +- solauto-sdk/pnpm-lock.yaml | 480 +++-- solauto-sdk/src/idls/switchboard.json | 1949 +++++++++++++++++++++ solauto-sdk/src/utils/switchboardUtils.ts | 32 +- 5 files changed, 2400 insertions(+), 288 deletions(-) create mode 100644 solauto-sdk/src/idls/switchboard.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 312f22c7..4a9acb1a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,6 +34,12 @@ packages: dependencies: regenerator-runtime: 0.14.1 + /@brokerloop/ttlcache@3.2.3: + resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} + dependencies: + '@soncodi/signal': 2.0.7 + dev: true + /@common.js/quick-lru@7.0.0: resolution: {integrity: sha512-DO3vApnH1vLizdWRSqzhg+S956vptHhtO+vw6PP6StJGDtaAGyfKSSPPGYWguJZu/Jlti6l6m6jB8NrKEQexLg==} engines: {node: '>=18'} @@ -131,11 +137,6 @@ packages: yargs: 17.7.2 dev: false - /@isaacs/ttlcache@1.4.1: - resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} - engines: {node: '>=12'} - dev: true - /@js-sdsl/ordered-map@4.4.2: resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} dev: false @@ -525,16 +526,6 @@ packages: typescript: 4.9.5 dev: true - /@solana/codecs-core@2.1.1(typescript@4.9.5): - resolution: {integrity: sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' - dependencies: - '@solana/errors': 2.1.1(typescript@4.9.5) - typescript: 4.9.5 - dev: true - /@solana/codecs-data-structures@2.0.0-preview.4(typescript@4.9.5): resolution: {integrity: sha512-nt2k2eTeyzlI/ccutPcG36M/J8NAYfxBPI9h/nQjgJ+M+IgOKi31JV8StDDlG/1XvY0zyqugV3I0r3KAbZRJpA==} peerDependencies: @@ -584,17 +575,6 @@ packages: typescript: 4.9.5 dev: true - /@solana/codecs-numbers@2.1.1(typescript@4.9.5): - resolution: {integrity: sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' - dependencies: - '@solana/codecs-core': 2.1.1(typescript@4.9.5) - '@solana/errors': 2.1.1(typescript@4.9.5) - typescript: 4.9.5 - dev: true - /@solana/codecs-strings@2.0.0-preview.1(fastestsmallesttextencoderdecoder@1.0.22): resolution: {integrity: sha512-kBAxE9ZD5/c8j9CkPxqc55dbo7R50Re3k94SXR+k13DZCCs37Fyn0/mAkw/S95fofbi/zsi4jSfmsT5vCZD75A==} peerDependencies: @@ -692,18 +672,6 @@ packages: typescript: 4.9.5 dev: true - /@solana/errors@2.1.1(typescript@4.9.5): - resolution: {integrity: sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw==} - engines: {node: '>=20.18.0'} - hasBin: true - peerDependencies: - typescript: '>=5.3.3' - dependencies: - chalk: 5.4.1 - commander: 13.1.0 - typescript: 4.9.5 - dev: true - /@solana/options@2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-tv2O/Frxql/wSe3jbzi5nVicIWIus/BftH+5ZR+r9r3FO0/htEllZS5Q9XdbmSboHu+St87584JXeDx3xm4jaA==} peerDependencies: @@ -811,6 +779,25 @@ packages: - utf-8-validate dev: true + /@solana/spl-token@0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.88.0 + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/buffer-layout-utils': 0.2.0 + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8 + buffer: 6.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + dev: true + /@solana/spl-token@0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-RO0JD9vPRi4LsAbMUdNbDJ5/cv2z11MGhtAvFeRzT4+hAGE/FUzRi0tkkWtuCfSIU3twC6CtmAihRp/+XXjWsA==} engines: {node: '>=16'} @@ -977,31 +964,29 @@ packages: - encoding - utf-8-validate - /@solana/web3.js@1.98.2(typescript@4.9.5): - resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} + /@solworks/soltoolkit-sdk@0.0.23(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} dependencies: - '@babel/runtime': 7.25.7 - '@noble/curves': 1.6.0 - '@noble/hashes': 1.5.0 '@solana/buffer-layout': 4.0.1 - '@solana/codecs-numbers': 2.1.1(typescript@4.9.5) - agentkeepalive: 4.5.0 + '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8 + '@types/bn.js': 5.1.6 + '@types/node': 18.19.67 + '@types/node-fetch': 2.6.12 bn.js: 5.2.1 - borsh: 0.7.0 - bs58: 4.0.1 - buffer: 6.0.3 - fast-stable-stringify: 1.0.0 - jayson: 4.1.2 - node-fetch: 2.7.0 - rpc-websockets: 9.0.4 - superstruct: 2.0.2 + decimal.js: 10.4.3 + typescript: 4.9.5 transitivePeerDependencies: - bufferutil - encoding - - typescript + - fastestsmallesttextencoderdecoder - utf-8-validate dev: true + /@soncodi/signal@2.0.7: + resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} + dev: true + /@sqds/multisig@2.1.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-WOiL7La+RSiJsz7jVO85yhSiiSvNMUthiWuLPeWVOoD6IYa34BEAzanF1RdXRWGglSbRFYCTkyr+Ay1WmXmSRQ==} engines: {node: '>=14'} @@ -1030,6 +1015,28 @@ packages: dependencies: tslib: 2.7.0 + /@switchboard-xyz/common@2.5.5: + resolution: {integrity: sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w==} + engines: {node: '>=12'} + dependencies: + '@solana/web3.js': 1.95.8 + axios: 1.7.8 + big.js: 6.2.2 + bn.js: 5.2.1 + bs58: 5.0.0 + cron-validator: 1.3.1 + decimal.js: 10.4.3 + js-sha256: 0.11.0 + lodash: 4.17.21 + protobufjs: 7.4.0 + yaml: 2.6.1 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - utf-8-validate + dev: true + /@switchboard-xyz/common@3.0.12: resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} engines: {node: '>=20'} @@ -1072,26 +1079,25 @@ packages: - utf-8-validate dev: false - /@switchboard-xyz/common@3.4.1(typescript@4.9.5): - resolution: {integrity: sha512-TropBlBYuDeBnmGHkPSmgC3clLqAxy51ZGbwk4ejAgadnszWOgYHcH7taRG4Ha17DYSCWw/LGMBKbunGo+Aoaw==} - engines: {node: '>=20'} + /@switchboard-xyz/on-demand@1.2.51(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} + engines: {node: '>= 18'} dependencies: - '@solana/web3.js': 1.98.2(typescript@4.9.5) - axios: 1.10.0 + '@brokerloop/ttlcache': 3.2.3 + '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 + '@solana/web3.js': 1.95.8 + '@solworks/soltoolkit-sdk': 0.0.23(fastestsmallesttextencoderdecoder@1.0.22) + '@switchboard-xyz/common': 2.5.5 + axios: 1.7.8 big.js: 6.2.2 - bn.js: 5.2.1 - bs58: 6.0.0 - buffer: 6.0.3 - decimal.js: 10.4.3 - js-sha256: 0.11.0 + bs58: 5.0.0 + js-yaml: 4.1.0 protobufjs: 7.4.0 - yaml: 2.6.1 - zod: 4.0.0-beta.20250505T195954 transitivePeerDependencies: - bufferutil - debug - encoding - - typescript + - fastestsmallesttextencoderdecoder - utf-8-validate dev: true @@ -1114,25 +1120,6 @@ packages: - utf-8-validate dev: false - /@switchboard-xyz/on-demand@2.8.1(typescript@4.9.5): - resolution: {integrity: sha512-MqUXMuqmYfhjMdFIAyFOvCYr1BeacmA3ZY6Eu2RkHJLG1X3NAKdCHR2Bj13UU/H9P7HrKhse29Sn7QdbSeEp/w==} - engines: {node: '>= 18'} - dependencies: - '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 - '@isaacs/ttlcache': 1.4.1 - '@switchboard-xyz/common': 3.4.1(typescript@4.9.5) - axios: 1.10.0 - bs58: 6.0.0 - buffer: 6.0.3 - js-yaml: 4.1.0 - transitivePeerDependencies: - - bufferutil - - debug - - encoding - - typescript - - utf-8-validate - dev: true - /@types/bn.js@5.1.6: resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} dependencies: @@ -1144,9 +1131,22 @@ packages: dependencies: '@types/node': 20.16.11 + /@types/node-fetch@2.6.12: + resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + dependencies: + '@types/node': 20.16.11 + form-data: 4.0.1 + dev: true + /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + /@types/node@18.19.67: + resolution: {integrity: sha512-wI8uHusga+0ZugNp0Ol/3BqQfEcCCNfojtO6Oou9iVNGPTL6QNSdnUdqq85fRgIorLhLMuPIKpsN98QE9Nh+KQ==} + dependencies: + undici-types: 5.26.5 + dev: true + /@types/node@20.16.11: resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} dependencies: @@ -1177,10 +1177,6 @@ packages: '@wallet-standard/base': 1.1.0 dev: false - /@zod/core@0.11.6: - resolution: {integrity: sha512-03Bv82fFSfjDAvMfdHHdGSS6SOJs0iCcJlWJv1kJHRtoTT02hZpyip/2Lk6oo4l4FtjuwTrsEQTwg/LD8I7dJA==} - dev: true - /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -1241,16 +1237,6 @@ packages: possible-typed-array-names: 1.0.0 dev: true - /axios@1.10.0: - resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} - dependencies: - follow-redirects: 1.15.9 - form-data: 4.0.1 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - dev: true - /axios@1.7.8: resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} dependencies: @@ -1373,11 +1359,6 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - /chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: true - /cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -1408,11 +1389,6 @@ packages: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} - /commander@13.1.0: - resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} - engines: {node: '>=18'} - dev: true - /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -1421,6 +1397,10 @@ packages: engines: {node: '>= 6'} dev: false + /cron-validator@1.3.1: + resolution: {integrity: sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==} + dev: true + /cross-fetch@3.1.8: resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} dependencies: @@ -1768,6 +1748,10 @@ packages: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} dev: false + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + /long@5.2.3: resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} @@ -2011,6 +1995,10 @@ packages: hasBin: true dev: true + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + /undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -2119,12 +2107,6 @@ packages: yargs-parser: 21.1.1 dev: false - /zod@4.0.0-beta.20250505T195954: - resolution: {integrity: sha512-iB8WvxkobVIXMARvQu20fKvbS7mUTiYRpcD8OQV1xjRhxO0EEpYIRJBk6yfBzHAHEdOSDh3SxDITr5Eajr2vtg==} - dependencies: - '@zod/core': 0.11.6 - dev: true - file:solauto-sdk(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {directory: solauto-sdk, type: directory} id: file:solauto-sdk @@ -2140,10 +2122,9 @@ packages: '@solana/web3.js': 1.95.8 '@sqds/multisig': 2.1.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) '@switchboard-xyz/common': 3.0.12 - '@switchboard-xyz/on-demand': 2.8.1(typescript@4.9.5) + '@switchboard-xyz/on-demand': 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) '@types/node': 20.16.11 axios: 1.7.8 - big.js: 6.2.2 bs58: 5.0.0 cross-fetch: 4.0.0 dotenv: 16.4.7 diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 75d71aa4..7093eb24 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.784", + "version": "1.0.782", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", @@ -12,16 +12,16 @@ "test:unit": "ts-mocha -p ./tsconfig.json -t 1000000 tests/unit/**/*.ts" }, "dependencies": { - "@coral-xyz/anchor": "=0.31.1", + "@coral-xyz/anchor": "^0.30.1", "@jup-ag/api": "=6.0.24", "@metaplex-foundation/umi": "^0.9.1", "@metaplex-foundation/umi-bundle-defaults": "^0.9.1", "@metaplex-foundation/umi-signer-wallet-adapters": "^0.9.1", "@metaplex-foundation/umi-web3js-adapters": "^0.9.1", "@solana/spl-token": "^0.4.0", - "@solana/web3.js": "=1.98.2", - "@switchboard-xyz/common": "=3.4.1", - "@switchboard-xyz/on-demand": "=2.11.0", + "@solana/web3.js": "=1.95.8", + "@switchboard-xyz/common": "=3.0.12", + "@switchboard-xyz/on-demand": "=1.2.51", "axios": "^1.7.8", "big.js": "^6.2.2", "bs58": "^5.0.0", diff --git a/solauto-sdk/pnpm-lock.yaml b/solauto-sdk/pnpm-lock.yaml index 4d59ae42..5003c773 100644 --- a/solauto-sdk/pnpm-lock.yaml +++ b/solauto-sdk/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: '@coral-xyz/anchor': - specifier: '=0.31.1' - version: 0.31.1(typescript@5.6.3) + specifier: ^0.30.1 + version: 0.30.1 '@jup-ag/api': specifier: '=6.0.24' version: 6.0.24 @@ -16,25 +16,25 @@ dependencies: version: 0.9.2 '@metaplex-foundation/umi-bundle-defaults': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-signer-wallet-adapters': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-web3js-adapters': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@solana/spl-token': specifier: ^0.4.0 - version: 0.4.8(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + version: 0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/web3.js': - specifier: '=1.98.2' - version: 1.98.2(typescript@5.6.3) + specifier: '=1.95.8' + version: 1.95.8 '@switchboard-xyz/common': - specifier: '=3.4.1' - version: 3.4.1(typescript@5.6.3) + specifier: '=3.0.12' + version: 3.0.12 '@switchboard-xyz/on-demand': - specifier: '=2.11.0' - version: 2.11.0(typescript@5.6.3) + specifier: '=1.2.51' + version: 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) axios: specifier: ^1.7.8 version: 1.7.8 @@ -89,56 +89,58 @@ packages: regenerator-runtime: 0.14.1 dev: false - /@coral-xyz/anchor-errors@0.31.1: - resolution: {integrity: sha512-NhNEku4F3zzUSBtrYz84FzYWm48+9OvmT1Hhnwr6GnPQry2dsEqH/ti/7ASjjpoFTWRnPXrjAIT1qM6Isop+LQ==} + /@brokerloop/ttlcache@3.2.3: + resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} + dependencies: + '@soncodi/signal': 2.0.7 + dev: false + + /@coral-xyz/anchor-errors@0.30.1: + resolution: {integrity: sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==} engines: {node: '>=10'} dev: false - /@coral-xyz/anchor@0.31.1(typescript@5.6.3): - resolution: {integrity: sha512-QUqpoEK+gi2S6nlYc2atgT2r41TT3caWr/cPUEL8n8Md9437trZ68STknq897b82p5mW0XrTBNOzRbmIRJtfsA==} - engines: {node: '>=17'} + /@coral-xyz/anchor@0.30.1: + resolution: {integrity: sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==} + engines: {node: '>=11'} dependencies: - '@coral-xyz/anchor-errors': 0.31.1 - '@coral-xyz/borsh': 0.31.1(@solana/web3.js@1.98.2) + '@coral-xyz/anchor-errors': 0.30.1 + '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.8) '@noble/hashes': 1.5.0 - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 bn.js: 5.2.1 bs58: 4.0.1 buffer-layout: 1.2.2 camelcase: 6.3.0 cross-fetch: 3.1.8 + crypto-hash: 1.3.0 eventemitter3: 4.0.7 pako: 2.1.0 + snake-case: 3.0.4 superstruct: 0.15.5 toml: 3.0.0 transitivePeerDependencies: - bufferutil - encoding - - typescript - utf-8-validate dev: false - /@coral-xyz/borsh@0.31.1(@solana/web3.js@1.98.2): - resolution: {integrity: sha512-9N8AU9F0ubriKfNE3g1WF0/4dtlGXoBN/hd1PvbNBamBNwRgHxH4P+o3Zt7rSEloW1HUs6LfZEchlx9fW7POYw==} + /@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} engines: {node: '>=10'} peerDependencies: - '@solana/web3.js': ^1.69.0 + '@solana/web3.js': ^1.68.0 dependencies: - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 bn.js: 5.2.1 buffer-layout: 1.2.2 dev: false - /@isaacs/ttlcache@1.4.1: - resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} - engines: {node: '>=12'} - dev: false - /@jup-ag/api@6.0.24: resolution: {integrity: sha512-zIX4WIPb0Kb2UnK2wNIOQBWqPJyMJq/D9dQTf/2qvPb0hfa8XdgbrQAzomHMHnAzw9StMQoybBk+JK/A76xP3w==} dev: false - /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): + /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-kV3tfvgvRjVP1p9OFOtH+ibOtN9omVJSwKr0We4/9r45e5LTj+32su0V/rixZUkG1EZzzOYBsxhtIE0kIw/Hrw==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 @@ -146,14 +148,14 @@ packages: dependencies: '@metaplex-foundation/umi': 0.9.2 '@metaplex-foundation/umi-downloader-http': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-http-fetch': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-program-repository': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-rpc-chunk-get-accounts': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-serializer-data-view': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 transitivePeerDependencies: - encoding dev: false @@ -166,16 +168,16 @@ packages: '@metaplex-foundation/umi': 0.9.2 dev: false - /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): + /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-hhPCxXbYIp4BC4z9gK78sXpWLkNSrfv4ndhF5ruAkdIp7GcRVYKj0QnOUO6lGYGiIkNlw20yoTwOe1CT//OfTQ==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@noble/curves': 1.6.0 - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 dev: false /@metaplex-foundation/umi-http-fetch@0.9.2(@metaplex-foundation/umi@0.9.2): @@ -215,15 +217,15 @@ packages: '@metaplex-foundation/umi': 0.9.2 dev: false - /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): + /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-MqcsBz8B4wGl6jxsf2Jo/rAEpYReU9VCSR15QSjhvADHMmdFxCIZCCAgE+gDE2Vuanfl437VhOcP3g5Uw8C16Q==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 dev: false /@metaplex-foundation/umi-serializer-data-view@0.9.2(@metaplex-foundation/umi@0.9.2): @@ -260,36 +262,36 @@ packages: '@metaplex-foundation/umi-serializers-numbers': 0.8.9 dev: false - /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): + /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-DFG0ZFocKG8briypSkG9bGUTVsWpAgYugsl2BzTygkGExc4evWfF4Sb1F2C2w9FdrA9ESZM1gpLX9xtx5taOXg==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 dev: false - /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): + /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-fR1Kf21uylMFd1Smkltmj4jTNxhqSWf416owsJ+T+cvJi2VCOcOwq/3UFzOrpz78fA0RhsajKYKj0HYsRnQI1g==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 dev: false - /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): + /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 buffer: 6.0.3 dev: false @@ -356,18 +358,17 @@ packages: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} dev: false - /@solana/buffer-layout-utils@0.2.0(typescript@5.6.3): + /@solana/buffer-layout-utils@0.2.0: resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} engines: {node: '>= 10'} dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 bigint-buffer: 1.1.5 bignumber.js: 9.1.2 transitivePeerDependencies: - bufferutil - encoding - - typescript - utf-8-validate dev: false @@ -387,22 +388,21 @@ packages: typescript: 5.6.3 dev: false - /@solana/codecs-core@2.0.0-rc.1(typescript@5.6.3): + /@solana/codecs-core@2.0.0-rc.1(typescript@4.9.5): resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} peerDependencies: typescript: '>=5' dependencies: - '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) - typescript: 5.6.3 + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 dev: false - /@solana/codecs-core@2.1.1(typescript@5.6.3): - resolution: {integrity: sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg==} - engines: {node: '>=20.18.0'} + /@solana/codecs-core@2.0.0-rc.1(typescript@5.6.3): + resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} peerDependencies: - typescript: '>=5.3.3' + typescript: '>=5' dependencies: - '@solana/errors': 2.1.1(typescript@5.6.3) + '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) typescript: 5.6.3 dev: false @@ -417,6 +417,17 @@ packages: typescript: 5.6.3 dev: false + /@solana/codecs-data-structures@2.0.0-rc.1(typescript@4.9.5): + resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} + peerDependencies: + typescript: '>=5' + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 + dev: false + /@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.6.3): resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} peerDependencies: @@ -438,24 +449,23 @@ packages: typescript: 5.6.3 dev: false - /@solana/codecs-numbers@2.0.0-rc.1(typescript@5.6.3): + /@solana/codecs-numbers@2.0.0-rc.1(typescript@4.9.5): resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} peerDependencies: typescript: '>=5' dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.6.3) - '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) - typescript: 5.6.3 + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 dev: false - /@solana/codecs-numbers@2.1.1(typescript@5.6.3): - resolution: {integrity: sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ==} - engines: {node: '>=20.18.0'} + /@solana/codecs-numbers@2.0.0-rc.1(typescript@5.6.3): + resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} peerDependencies: - typescript: '>=5.3.3' + typescript: '>=5' dependencies: - '@solana/codecs-core': 2.1.1(typescript@5.6.3) - '@solana/errors': 2.1.1(typescript@5.6.3) + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.6.3) + '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) typescript: 5.6.3 dev: false @@ -472,6 +482,19 @@ packages: typescript: 5.6.3 dev: false + /@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5' + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + fastestsmallesttextencoderdecoder: 1.0.22 + typescript: 4.9.5 + dev: false + /@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} peerDependencies: @@ -500,6 +523,21 @@ packages: - fastestsmallesttextencoderdecoder dev: false + /@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} + peerDependencies: + typescript: '>=5' + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + dev: false + /@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} peerDependencies: @@ -526,7 +564,7 @@ packages: typescript: 5.6.3 dev: false - /@solana/errors@2.0.0-rc.1(typescript@5.6.3): + /@solana/errors@2.0.0-rc.1(typescript@4.9.5): resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} hasBin: true peerDependencies: @@ -534,18 +572,17 @@ packages: dependencies: chalk: 5.3.0 commander: 12.1.0 - typescript: 5.6.3 + typescript: 4.9.5 dev: false - /@solana/errors@2.1.1(typescript@5.6.3): - resolution: {integrity: sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw==} - engines: {node: '>=20.18.0'} + /@solana/errors@2.0.0-rc.1(typescript@5.6.3): + resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} hasBin: true peerDependencies: - typescript: '>=5.3.3' + typescript: '>=5' dependencies: - chalk: 5.4.1 - commander: 13.1.0 + chalk: 5.3.0 + commander: 12.1.0 typescript: 5.6.3 dev: false @@ -564,6 +601,21 @@ packages: - fastestsmallesttextencoderdecoder dev: false + /@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} + peerDependencies: + typescript: '>=5' + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + dev: false + /@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} peerDependencies: @@ -579,7 +631,7 @@ packages: - fastestsmallesttextencoderdecoder dev: false - /@solana/spl-token-group@0.0.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token-group@0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-CLJnWEcdoUBpQJfx9WEbX3h6nTdNiUzswfFdkABUik7HVwSNA98u5AYvBVK2H93d9PGMOHAak2lHW9xr+zAJGQ==} engines: {node: '>=16'} peerDependencies: @@ -587,13 +639,13 @@ packages: dependencies: '@solana/codecs': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript dev: false - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} engines: {node: '>=16'} peerDependencies: @@ -601,23 +653,56 @@ packages: dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript dev: false - /@solana/spl-token@0.4.8(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.3 + dependencies: + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/spl-type-length-value': 0.1.0 + '@solana/web3.js': 1.98.0 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - typescript + dev: false + + /@solana/spl-token@0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.88.0 + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/buffer-layout-utils': 0.2.0 + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.98.0 + buffer: 6.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + dev: false + + /@solana/spl-token@0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-RO0JD9vPRi4LsAbMUdNbDJ5/cv2z11MGhtAvFeRzT4+hAGE/FUzRi0tkkWtuCfSIU3twC6CtmAihRp/+XXjWsA==} engines: {node: '>=16'} peerDependencies: '@solana/web3.js': ^1.94.0 dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0(typescript@5.6.3) - '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/buffer-layout-utils': 0.2.0 + '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/web3.js': 1.95.8 buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -634,15 +719,15 @@ packages: buffer: 6.0.3 dev: false - /@solana/web3.js@1.98.2(typescript@5.6.3): - resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} + /@solana/web3.js@1.95.8: + resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} dependencies: '@babel/runtime': 7.25.7 '@noble/curves': 1.6.0 '@noble/hashes': 1.5.0 '@solana/buffer-layout': 4.0.1 - '@solana/codecs-numbers': 2.1.1(typescript@5.6.3) agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 bn.js: 5.2.1 borsh: 0.7.0 bs58: 4.0.1 @@ -655,22 +740,90 @@ packages: transitivePeerDependencies: - bufferutil - encoding - - typescript - utf-8-validate dev: false + /@solana/web3.js@1.98.0: + resolution: {integrity: sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==} + dependencies: + '@babel/runtime': 7.25.7 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.2 + node-fetch: 2.7.0 + rpc-websockets: 9.0.4 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@solworks/soltoolkit-sdk@0.0.23(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/spl-token': 0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.98.0 + '@types/bn.js': 5.1.6 + '@types/node': 18.19.65 + '@types/node-fetch': 2.6.12 + bn.js: 5.2.1 + decimal.js: 10.4.3 + typescript: 4.9.5 + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - utf-8-validate + dev: false + + /@soncodi/signal@2.0.7: + resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} + dev: false + /@swc/helpers@0.5.13: resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} dependencies: tslib: 2.7.0 dev: false - /@switchboard-xyz/common@3.4.1(typescript@5.6.3): - resolution: {integrity: sha512-TropBlBYuDeBnmGHkPSmgC3clLqAxy51ZGbwk4ejAgadnszWOgYHcH7taRG4Ha17DYSCWw/LGMBKbunGo+Aoaw==} + /@switchboard-xyz/common@2.5.5: + resolution: {integrity: sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w==} + engines: {node: '>=12'} + dependencies: + '@solana/web3.js': 1.98.0 + axios: 1.8.4 + big.js: 6.2.2 + bn.js: 5.2.1 + bs58: 5.0.0 + cron-validator: 1.3.1 + decimal.js: 10.4.3 + js-sha256: 0.11.0 + lodash: 4.17.21 + protobufjs: 7.4.0 + yaml: 2.6.1 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - utf-8-validate + dev: false + + /@switchboard-xyz/common@3.0.12: + resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} engines: {node: '>=20'} dependencies: - '@solana/web3.js': 1.98.2(typescript@5.6.3) - axios: 1.10.0 + '@solana/web3.js': 1.98.0 + axios: 1.8.4 big.js: 6.2.2 bn.js: 5.2.1 bs58: 6.0.0 @@ -679,32 +832,33 @@ packages: js-sha256: 0.11.0 protobufjs: 7.4.0 yaml: 2.6.1 - zod: 4.0.0-beta.20250505T195954 transitivePeerDependencies: - bufferutil - debug - encoding - - typescript - utf-8-validate dev: false - /@switchboard-xyz/on-demand@2.11.0(typescript@5.6.3): - resolution: {integrity: sha512-w4iHyRpvIuv2CT2Bcap6zIdunLYcDBuMUliyJuxmxLD+ch2Lta1QWHAZCsjuBasE2OhSKoTz3MAtapYuCuR2gA==} + /@switchboard-xyz/on-demand@1.2.51(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} engines: {node: '>= 18'} - dependencies: - '@coral-xyz/anchor-31': /@coral-xyz/anchor@0.31.1(typescript@5.6.3) - '@isaacs/ttlcache': 1.4.1 - '@switchboard-xyz/common': 3.4.1(typescript@5.6.3) - axios: 1.10.0 - bs58: 6.0.0 - buffer: 6.0.3 + deprecated: deprecated in favor of 2.x.x + dependencies: + '@brokerloop/ttlcache': 3.2.3 + '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 + '@solana/web3.js': 1.98.0 + '@solworks/soltoolkit-sdk': 0.0.23(fastestsmallesttextencoderdecoder@1.0.22) + '@switchboard-xyz/common': 2.5.5 + axios: 1.8.4 + big.js: 6.2.2 + bs58: 5.0.0 js-yaml: 4.1.0 - ws: 8.18.3 + protobufjs: 7.4.0 transitivePeerDependencies: - bufferutil - debug - encoding - - typescript + - fastestsmallesttextencoderdecoder - utf-8-validate dev: false @@ -712,6 +866,12 @@ packages: resolution: {integrity: sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==} dev: true + /@types/bn.js@5.1.6: + resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} + dependencies: + '@types/node': 20.16.11 + dev: false + /@types/chai@4.3.20: resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} dev: true @@ -732,10 +892,23 @@ packages: resolution: {integrity: sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==} dev: true + /@types/node-fetch@2.6.12: + resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + dependencies: + '@types/node': 20.16.11 + form-data: 4.0.1 + dev: false + /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: false + /@types/node@18.19.65: + resolution: {integrity: sha512-Ay5BZuO1UkTmVHzZJNvZKw/E+iB3GQABb6kijEz89w2JrfhNA+M/ebp18pfz9Gqe9ywhMC8AA8yC01lZq48J+Q==} + dependencies: + undici-types: 5.26.5 + dev: false + /@types/node@20.16.11: resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} dependencies: @@ -761,10 +934,6 @@ packages: resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} dev: true - /@zod/core@0.11.6: - resolution: {integrity: sha512-03Bv82fFSfjDAvMfdHHdGSS6SOJs0iCcJlWJv1kJHRtoTT02hZpyip/2Lk6oo4l4FtjuwTrsEQTwg/LD8I7dJA==} - dev: false - /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -821,8 +990,8 @@ packages: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false - /axios@1.10.0: - resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + /axios@1.7.8: + resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} dependencies: follow-redirects: 1.15.9 form-data: 4.0.1 @@ -831,8 +1000,8 @@ packages: - debug dev: false - /axios@1.7.8: - resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} + /axios@1.8.4: + resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} dependencies: follow-redirects: 1.15.9 form-data: 4.0.1 @@ -992,11 +1161,6 @@ packages: engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} dev: false - /chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: false - /check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} dependencies: @@ -1049,11 +1213,6 @@ packages: engines: {node: '>=18'} dev: false - /commander@13.1.0: - resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} - engines: {node: '>=18'} - dev: false - /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: false @@ -1062,6 +1221,10 @@ packages: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true + /cron-validator@1.3.1: + resolution: {integrity: sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==} + dev: false + /cross-fetch@3.1.8: resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} dependencies: @@ -1078,6 +1241,11 @@ packages: - encoding dev: false + /crypto-hash@1.3.0: + resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} + engines: {node: '>=8'} + dev: false + /debug@4.3.3(supports-color@8.1.1): resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} engines: {node: '>=6.0'} @@ -1127,6 +1295,13 @@ packages: engines: {node: '>=0.3.1'} dev: true + /dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dependencies: + no-case: 3.0.4 + tslib: 2.7.0 + dev: false + /dotenv@16.4.7: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} @@ -1405,6 +1580,10 @@ packages: p-locate: 5.0.0 dev: true + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: false + /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -1423,6 +1602,12 @@ packages: get-func-name: 2.0.2 dev: true + /lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.7.0 + dev: false + /make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: true @@ -1507,6 +1692,13 @@ packages: hasBin: true dev: true + /no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.7.0 + dev: false + /node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -1654,6 +1846,13 @@ packages: randombytes: 2.1.0 dev: true + /snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + dependencies: + dot-case: 3.0.4 + tslib: 2.7.0 + dev: false + /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: @@ -1788,11 +1987,21 @@ packages: engines: {node: '>=4'} dev: true + /typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: false + /typescript@5.6.3: resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} hasBin: true + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: false + /undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -1874,19 +2083,6 @@ packages: utf-8-validate: 5.0.10 dev: false - /ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: false - /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -1935,9 +2131,3 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true - - /zod@4.0.0-beta.20250505T195954: - resolution: {integrity: sha512-iB8WvxkobVIXMARvQu20fKvbS7mUTiYRpcD8OQV1xjRhxO0EEpYIRJBk6yfBzHAHEdOSDh3SxDITr5Eajr2vtg==} - dependencies: - '@zod/core': 0.11.6 - dev: false diff --git a/solauto-sdk/src/idls/switchboard.json b/solauto-sdk/src/idls/switchboard.json new file mode 100644 index 00000000..6996121a --- /dev/null +++ b/solauto-sdk/src/idls/switchboard.json @@ -0,0 +1,1949 @@ +{ + "address": "SBondMDrcV3K4kxZR1HNVT7osZxAHVHgYXL5Ze1oMUv", + "metadata": { + "name": "sb_on_demand", + "version": "0.1.0", + "spec": "0.1.0", + "description": "Created with Anchor" + }, + "instructions": [ + { + "name": "guardian_quote_verify", + "discriminator": [168, 36, 93, 156, 157, 150, 148, 45], + "accounts": [ + { "name": "guardian", "writable": true }, + { "name": "oracle", "writable": true }, + { "name": "authority", "signer": true, "relations": ["oracle"] }, + { "name": "guardian_queue", "writable": true, "relations": ["state"] }, + { "name": "state" }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "GuardianQuoteVerifyParams" } } + } + ] + }, + { + "name": "guardian_register", + "discriminator": [159, 76, 53, 117, 219, 29, 116, 135], + "accounts": [ + { "name": "oracle", "writable": true }, + { "name": "state" }, + { "name": "guardian_queue", "relations": ["state"] }, + { "name": "authority", "signer": true, "relations": ["state"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "GuardianRegisterParams" } } + } + ] + }, + { + "name": "guardian_unregister", + "discriminator": [215, 19, 61, 120, 155, 224, 120, 60], + "accounts": [ + { "name": "oracle", "writable": true }, + { "name": "state" }, + { "name": "guardian_queue", "writable": true, "relations": ["state"] }, + { "name": "authority", "signer": true, "relations": ["state"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "GuardianUnregisterParams" } } + } + ] + }, + { + "name": "oracle_heartbeat", + "discriminator": [10, 175, 217, 130, 111, 35, 117, 54], + "accounts": [ + { "name": "oracle", "writable": true }, + { + "name": "oracle_stats", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] + }, + { "kind": "account", "path": "oracle" } + ] + } + }, + { "name": "oracle_signer", "signer": true }, + { + "name": "queue", + "writable": true, + "relations": ["oracle", "gc_node"] + }, + { "name": "gc_node", "writable": true }, + { "name": "program_state", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "native_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "queue_escrow", "writable": true }, + { + "name": "stake_program", + "address": "SBSTk6t52R89MmCdD739Rdd97HdbTQUFHe41vCX7pTt", + "relations": ["program_state"] + }, + { "name": "delegation_pool", "writable": true }, + { "name": "delegation_group", "writable": true } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "OracleHeartbeatParams" } } + } + ] + }, + { + "name": "oracle_init", + "discriminator": [21, 158, 66, 65, 60, 221, 148, 61], + "accounts": [ + { "name": "oracle", "writable": true, "signer": true }, + { + "name": "oracle_stats", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] + }, + { "kind": "account", "path": "oracle" } + ] + } + }, + { "name": "program_state", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + }, + { "name": "stake_program", "relations": ["program_state"] }, + { "name": "stake_pool", "relations": ["program_state"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "OracleInitParams" } } + } + ] + }, + { + "name": "oracle_set_configs", + "discriminator": [129, 111, 223, 4, 191, 188, 70, 180], + "accounts": [ + { "name": "oracle" }, + { "name": "authority", "signer": true, "relations": ["oracle"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "OracleSetConfigsParams" } } + } + ] + }, + { + "name": "oracle_update_delegation", + "discriminator": [46, 198, 113, 223, 160, 189, 118, 90], + "accounts": [ + { "name": "oracle", "writable": true }, + { + "name": "oracle_stats", + "pda": { + "seeds": [ + { + "kind": "const", + "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] + }, + { "kind": "account", "path": "oracle" } + ] + } + }, + { "name": "queue", "relations": ["oracle"] }, + { "name": "authority", "signer": true }, + { "name": "program_state", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { "name": "delegation_pool", "writable": true }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + }, + { "name": "switch_mint" }, + { + "name": "native_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "wsol_vault", "writable": true }, + { "name": "switch_vault", "writable": true }, + { "name": "stake_program", "relations": ["program_state"] }, + { "name": "stake_pool" }, + { "name": "delegation_group" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "OracleUpdateDelegationParams" } } + } + ] + }, + { + "name": "permission_set", + "discriminator": [211, 122, 185, 120, 129, 182, 55, 103], + "accounts": [ + { "name": "authority", "signer": true }, + { "name": "granter" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PermissionSetParams" } } + } + ] + }, + { + "name": "pull_feed_close", + "discriminator": [19, 134, 50, 142, 177, 215, 196, 83], + "accounts": [ + { "name": "pull_feed", "writable": true }, + { "name": "reward_escrow", "writable": true }, + { "name": "lut", "writable": true }, + { "name": "lut_signer" }, + { "name": "payer", "writable": true, "signer": true }, + { "name": "state" }, + { + "name": "authority", + "writable": true, + "signer": true, + "relations": ["pull_feed"] + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedCloseParams" } } + } + ] + }, + { + "name": "pull_feed_init", + "discriminator": [198, 130, 53, 198, 235, 61, 143, 40], + "accounts": [ + { "name": "pull_feed", "writable": true, "signer": true }, + { "name": "queue" }, + { "name": "authority" }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "program_state" }, + { + "name": "reward_escrow", + "writable": true, + "pda": { + "seeds": [ + { "kind": "account", "path": "pull_feed" }, + { + "kind": "const", + "value": [ + 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, + 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, + 245, 133, 126, 255, 0, 169 + ] + }, + { "kind": "account", "path": "wrapped_sol_mint" } + ], + "program": { + "kind": "const", + "value": [ + 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, + 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, + 219, 233, 248, 89 + ] + } + } + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + }, + { + "name": "wrapped_sol_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedInitParams" } } + } + ] + }, + { + "name": "pull_feed_set_configs", + "discriminator": [217, 45, 11, 246, 64, 26, 82, 168], + "accounts": [ + { "name": "pull_feed", "writable": true }, + { "name": "authority", "signer": true, "relations": ["pull_feed"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedSetConfigsParams" } } + } + ] + }, + { + "name": "pull_feed_submit_response", + "discriminator": [150, 22, 215, 166, 143, 93, 48, 137], + "accounts": [ + { "name": "feed", "writable": true }, + { "name": "queue", "relations": ["feed"] }, + { "name": "program_state" }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "reward_vault", "writable": true }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "token_mint", + "address": "So11111111111111111111111111111111111111112" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedSubmitResponseParams" } } + } + ] + }, + { + "name": "pull_feed_submit_response_many", + "discriminator": [47, 156, 45, 25, 200, 71, 37, 215], + "accounts": [ + { "name": "queue" }, + { "name": "program_state" }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "reward_vault", "writable": true }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "token_mint", + "address": "So11111111111111111111111111111111111111112" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedSubmitResponseManyParams" } } + } + ] + }, + { + "name": "queue_add_mr_enclave", + "discriminator": [199, 255, 81, 50, 60, 133, 171, 138], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "authority", "signer": true }, + { "name": "program_authority" }, + { "name": "state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueAddMrEnclaveParams" } } + } + ] + }, + { + "name": "queue_allow_subsidies", + "discriminator": [94, 203, 82, 157, 188, 138, 202, 108], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "authority", "signer": true, "relations": ["state"] }, + { "name": "state", "writable": true } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueAllowSubsidiesParams" } } + } + ] + }, + { + "name": "queue_garbage_collect", + "discriminator": [187, 208, 104, 247, 16, 91, 96, 98], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "oracle", "writable": true }, + { "name": "authority", "signer": true }, + { "name": "state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueGarbageCollectParams" } } + } + ] + }, + { + "name": "queue_init", + "discriminator": [144, 18, 99, 145, 133, 27, 207, 13], + "accounts": [ + { "name": "queue", "writable": true, "signer": true }, + { + "name": "queue_escrow", + "writable": true, + "pda": { + "seeds": [ + { "kind": "account", "path": "queue" }, + { + "kind": "const", + "value": [ + 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, + 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, + 245, 133, 126, 255, 0, 169 + ] + }, + { "kind": "account", "path": "native_mint" } + ], + "program": { + "kind": "const", + "value": [ + 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, + 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, + 219, 233, 248, 89 + ] + } + } + }, + { "name": "authority" }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "native_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "program_state" }, + { "name": "lut_signer", "writable": true }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueInitParams" } } + } + ] + }, + { + "name": "queue_init_delegation_group", + "discriminator": [239, 146, 75, 158, 20, 166, 159, 14], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "program_state" }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + }, + { "name": "delegation_group", "writable": true }, + { "name": "stake_program", "relations": ["program_state"] }, + { "name": "stake_pool" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueInitDelegationGroupParams" } } + } + ] + }, + { + "name": "queue_remove_mr_enclave", + "discriminator": [3, 64, 135, 33, 190, 133, 68, 252], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "authority", "signer": true }, + { "name": "program_authority" }, + { "name": "state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueRemoveMrEnclaveParams" } } + } + ] + }, + { + "name": "queue_set_configs", + "discriminator": [54, 183, 243, 199, 49, 103, 142, 48], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "authority", "signer": true }, + { "name": "state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueSetConfigsParams" } } + } + ] + }, + { + "name": "randomness_commit", + "discriminator": [52, 170, 152, 201, 179, 133, 242, 141], + "accounts": [ + { "name": "randomness", "writable": true }, + { "name": "queue", "relations": ["randomness", "oracle"] }, + { "name": "oracle", "writable": true }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + }, + { "name": "authority", "signer": true, "relations": ["randomness"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "RandomnessCommitParams" } } + } + ] + }, + { + "name": "randomness_init", + "discriminator": [9, 9, 204, 33, 50, 116, 113, 15], + "accounts": [ + { "name": "randomness", "writable": true, "signer": true }, + { + "name": "reward_escrow", + "writable": true, + "pda": { + "seeds": [ + { "kind": "account", "path": "randomness" }, + { + "kind": "const", + "value": [ + 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, + 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, + 245, 133, 126, 255, 0, 169 + ] + }, + { "kind": "account", "path": "wrapped_sol_mint" } + ], + "program": { + "kind": "const", + "value": [ + 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, + 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, + 219, 233, 248, 89 + ] + } + } + }, + { "name": "authority", "signer": true }, + { "name": "queue", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + }, + { + "name": "wrapped_sol_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "program_state" }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "RandomnessInitParams" } } + } + ] + }, + { + "name": "randomness_reveal", + "discriminator": [197, 181, 187, 10, 30, 58, 20, 73], + "accounts": [ + { "name": "randomness", "writable": true }, + { "name": "oracle", "relations": ["randomness"] }, + { "name": "queue", "relations": ["oracle"] }, + { + "name": "stats", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 79, 114, 97, 99, 108, 101, 82, 97, 110, 100, 111, 109, 110, + 101, 115, 115, 83, 116, 97, 116, 115 + ] + }, + { "kind": "account", "path": "oracle" } + ] + } + }, + { "name": "authority", "signer": true, "relations": ["randomness"] }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "reward_escrow", "writable": true }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "wrapped_sol_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "program_state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "RandomnessRevealParams" } } + } + ] + }, + { + "name": "state_init", + "discriminator": [103, 241, 106, 190, 217, 153, 87, 105], + "accounts": [ + { + "name": "state", + "writable": true, + "pda": { + "seeds": [{ "kind": "const", "value": [83, 84, 65, 84, 69] }] + } + }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "StateInitParams" } } + } + ] + }, + { + "name": "state_set_configs", + "discriminator": [40, 98, 76, 37, 206, 9, 47, 144], + "accounts": [ + { "name": "state", "writable": true }, + { "name": "authority", "signer": true, "relations": ["state"] }, + { "name": "queue", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "StateSetConfigsParams" } } + } + ] + } + ], + "accounts": [ + { + "name": "OracleAccountData", + "discriminator": [128, 30, 16, 241, 170, 73, 55, 54] + }, + { + "name": "OracleStatsAccountData", + "discriminator": [180, 157, 178, 234, 240, 27, 152, 179] + }, + { + "name": "PullFeedAccountData", + "discriminator": [196, 27, 108, 196, 10, 215, 219, 40] + }, + { + "name": "QueueAccountData", + "discriminator": [217, 194, 55, 127, 184, 83, 138, 1] + }, + { + "name": "RandomnessAccountData", + "discriminator": [10, 66, 229, 135, 220, 239, 217, 114] + }, + { "name": "State", "discriminator": [216, 146, 107, 94, 104, 75, 182, 177] } + ], + "events": [ + { + "name": "CostWhitelistEvent", + "discriminator": [56, 107, 191, 127, 116, 6, 138, 149] + }, + { + "name": "GarbageCollectionEvent", + "discriminator": [232, 235, 2, 188, 8, 143, 145, 237] + }, + { + "name": "GuardianQuoteVerifyEvent", + "discriminator": [31, 37, 39, 6, 214, 186, 33, 115] + }, + { + "name": "OracleHeartbeatEvent", + "discriminator": [52, 29, 166, 2, 94, 7, 188, 13] + }, + { + "name": "OracleInitEvent", + "discriminator": [89, 193, 219, 200, 1, 83, 167, 24] + }, + { + "name": "OracleQuoteOverrideEvent", + "discriminator": [78, 204, 191, 210, 164, 196, 244, 65] + }, + { + "name": "OracleQuoteRotateEvent", + "discriminator": [26, 189, 196, 192, 225, 127, 26, 228] + }, + { + "name": "OracleQuoteVerifyRequestEvent", + "discriminator": [203, 209, 79, 0, 20, 71, 226, 202] + }, + { + "name": "PermissionSetEvent", + "discriminator": [148, 86, 123, 0, 102, 20, 119, 206] + }, + { + "name": "PullFeedErrorValueEvent", + "discriminator": [225, 80, 192, 95, 14, 12, 83, 192] + }, + { + "name": "PullFeedValueEvents", + "discriminator": [86, 7, 231, 28, 122, 161, 117, 69] + }, + { + "name": "QueueAddMrEnclaveEvent", + "discriminator": [170, 186, 175, 38, 216, 51, 69, 175] + }, + { + "name": "QueueInitEvent", + "discriminator": [44, 137, 99, 227, 107, 8, 30, 105] + }, + { + "name": "QueueRemoveMrEnclaveEvent", + "discriminator": [4, 105, 196, 60, 84, 122, 203, 196] + }, + { + "name": "RandomnessCommitEvent", + "discriminator": [88, 60, 172, 90, 112, 10, 206, 147] + } + ], + "errors": [ + { "code": 6000, "name": "GenericError" }, + { "code": 6001, "name": "InvalidQuote" }, + { "code": 6002, "name": "InsufficientQueue" }, + { "code": 6003, "name": "QueueFull" }, + { "code": 6004, "name": "InvalidEnclaveSigner" }, + { "code": 6005, "name": "InvalidSigner" }, + { "code": 6006, "name": "MrEnclaveAlreadyExists" }, + { "code": 6007, "name": "MrEnclaveAtCapacity" }, + { "code": 6008, "name": "MrEnclaveDoesntExist" }, + { "code": 6009, "name": "PermissionDenied" }, + { "code": 6010, "name": "InvalidQueue" }, + { "code": 6011, "name": "IncorrectMrEnclave" }, + { "code": 6012, "name": "InvalidAuthority" }, + { "code": 6013, "name": "InvalidMrEnclave" }, + { "code": 6014, "name": "InvalidTimestamp" }, + { "code": 6015, "name": "InvalidOracleIdx" }, + { "code": 6016, "name": "InvalidSecpSignature" }, + { "code": 6017, "name": "InvalidGuardianQueue" }, + { "code": 6018, "name": "InvalidIndex" }, + { "code": 6019, "name": "InvalidOracleQueue" }, + { "code": 6020, "name": "InvalidPermission" }, + { "code": 6021, "name": "InvalidePermissionedAccount" }, + { "code": 6022, "name": "InvalidEpochRotate" }, + { "code": 6023, "name": "InvalidEpochFinalize" }, + { "code": 6024, "name": "InvalidEscrow" }, + { "code": 6025, "name": "IllegalOracle" }, + { "code": 6026, "name": "IllegalExecuteAttempt" }, + { "code": 6027, "name": "IllegalFeedValue" }, + { "code": 6028, "name": "InvalidOracleFeedStats" }, + { "code": 6029, "name": "InvalidStateAuthority" }, + { "code": 6030, "name": "NotEnoughSamples" }, + { "code": 6031, "name": "OracleIsVerified" }, + { "code": 6032, "name": "QueueIsEmpty" }, + { "code": 6033, "name": "SecpRecoverFailure" }, + { "code": 6034, "name": "StaleSample" }, + { "code": 6035, "name": "SwitchboardRandomnessTooOld" }, + { "code": 6036, "name": "EpochIdMismatch" }, + { "code": 6037, "name": "GuardianAlreadyVoted" }, + { "code": 6038, "name": "RandomnessNotRequested" }, + { "code": 6039, "name": "InvalidSlotNumber" }, + { "code": 6040, "name": "RandomnessOracleKeyExpired" }, + { "code": 6041, "name": "InvalidAdvisory" }, + { "code": 6042, "name": "InvalidOracleStats" }, + { "code": 6043, "name": "InvalidStakeProgram" }, + { "code": 6044, "name": "InvalidStakePool" }, + { "code": 6045, "name": "InvalidDelegationPool" }, + { "code": 6046, "name": "UnparsableAccount" }, + { "code": 6047, "name": "InvalidInstruction" }, + { "code": 6048, "name": "OracleAlreadyVerified" }, + { "code": 6049, "name": "GuardianNotVerified" }, + { "code": 6050, "name": "InvalidConstraint" }, + { "code": 6051, "name": "InvalidDelegationGroup" }, + { "code": 6052, "name": "OracleKeyNotFound" }, + { "code": 6053, "name": "GuardianReregisterAttempt" } + ], + "types": [ + { + "name": "CompactResult", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "std_dev", + "docs": [ + "The standard deviation of the submissions needed for quorom size" + ], + "type": "f32" + }, + { + "name": "mean", + "docs": ["The mean of the submissions needed for quorom size"], + "type": "f32" + }, + { + "name": "slot", + "docs": ["The slot at which this value was signed."], + "type": "u64" + } + ] + } + }, + { + "name": "CostWhitelistEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "feeds", "type": { "vec": "pubkey" } }, + { "name": "reward", "type": "u32" } + ] + } + }, + { + "name": "CurrentResult", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "value", + "docs": [ + "The median value of the submissions needed for quorom size" + ], + "type": "i128" + }, + { + "name": "std_dev", + "docs": [ + "The standard deviation of the submissions needed for quorom size" + ], + "type": "i128" + }, + { + "name": "mean", + "docs": ["The mean of the submissions needed for quorom size"], + "type": "i128" + }, + { + "name": "range", + "docs": ["The range of the submissions needed for quorom size"], + "type": "i128" + }, + { + "name": "min_value", + "docs": [ + "The minimum value of the submissions needed for quorom size" + ], + "type": "i128" + }, + { + "name": "max_value", + "docs": [ + "The maximum value of the submissions needed for quorom size" + ], + "type": "i128" + }, + { + "name": "num_samples", + "docs": ["The number of samples used to calculate this result"], + "type": "u8" + }, + { "name": "padding1", "type": { "array": ["u8", 7] } }, + { + "name": "slot", + "docs": ["The slot at which this value was signed."], + "type": "u64" + }, + { + "name": "min_slot", + "docs": [ + "The slot at which the first considered submission was made" + ], + "type": "u64" + }, + { + "name": "max_slot", + "docs": [ + "The slot at which the last considered submission was made" + ], + "type": "u64" + } + ] + } + }, + { + "name": "GarbageCollectionEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "oracle", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" } + ] + } + }, + { + "name": "GuardianQuoteVerifyEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "quote", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" } + ] + } + }, + { + "name": "GuardianQuoteVerifyParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "timestamp", "type": "i64" }, + { "name": "mr_enclave", "type": { "array": ["u8", 32] } }, + { "name": "_reserved1", "type": "u32" }, + { "name": "ed25519_key", "type": "pubkey" }, + { "name": "secp256k1_key", "type": { "array": ["u8", 64] } }, + { "name": "slot", "type": "u64" }, + { "name": "signature", "type": { "array": ["u8", 64] } }, + { "name": "recovery_id", "type": "u8" }, + { "name": "advisories", "type": { "vec": "u32" } } + ] + } + }, + { + "name": "GuardianRegisterParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "GuardianUnregisterParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "MegaSlotInfo", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "reserved1", "type": "u64" }, + { "name": "slot_end", "type": "u64" }, + { "name": "perf_goal", "type": "i64" }, + { "name": "current_signature_count", "type": "i64" } + ] + } + }, + { + "name": "MultiSubmission", + "type": { + "kind": "struct", + "fields": [ + { "name": "values", "type": { "vec": "i128" } }, + { "name": "signature", "type": { "array": ["u8", 64] } }, + { "name": "recovery_id", "type": "u8" } + ] + } + }, + { + "name": "OracleAccountData", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "enclave", + "docs": ["Represents the state of the quote verifiers enclave."], + "type": { "defined": { "name": "Quote" } } + }, + { + "name": "authority", + "docs": [ + "The authority of the EnclaveAccount which is permitted to make account changes." + ], + "type": "pubkey" + }, + { + "name": "queue", + "docs": [ + "Queue used for attestation to verify a MRENCLAVE measurement." + ], + "type": "pubkey" + }, + { + "name": "created_at", + "docs": ["The unix timestamp when the quote was created."], + "type": "i64" + }, + { + "name": "last_heartbeat", + "docs": ["The last time the quote heartbeated on-chain."], + "type": "i64" + }, + { "name": "secp_authority", "type": { "array": ["u8", 64] } }, + { + "name": "gateway_uri", + "docs": ["URI location of the verifier's gateway."], + "type": { "array": ["u8", 64] } + }, + { "name": "permissions", "type": "u64" }, + { + "name": "is_on_queue", + "docs": [ + "Whether the quote is located on the AttestationQueues buffer." + ], + "type": "u8" + }, + { "name": "_padding1", "type": { "array": ["u8", 7] } }, + { "name": "lut_slot", "type": "u64" }, + { "name": "last_reward_epoch", "type": "u64" }, + { "name": "_ebuf4", "type": { "array": ["u8", 16] } }, + { "name": "_ebuf3", "type": { "array": ["u8", 32] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 64] } }, + { "name": "_ebuf1", "type": { "array": ["u8", 1024] } } + ] + } + }, + { + "name": "OracleEpochInfo", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "id", "type": "u64" }, + { "name": "reserved1", "type": "u64" }, + { "name": "slot_end", "type": "u64" }, + { "name": "slash_score", "type": "u64" }, + { "name": "reward_score", "type": "u64" }, + { "name": "stake_score", "type": "u64" } + ] + } + }, + { + "name": "OracleHeartbeatEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "oracle", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" } + ] + } + }, + { + "name": "OracleHeartbeatParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "gateway_uri", + "type": { "option": { "array": ["u8", 64] } } + } + ] + } + }, + { + "name": "OracleInitEvent", + "type": { + "kind": "struct", + "fields": [{ "name": "oracle", "type": "pubkey" }] + } + }, + { + "name": "OracleInitParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "recent_slot", "type": "u64" }, + { "name": "authority", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" }, + { + "name": "secp_authority", + "type": { "option": { "array": ["u8", 64] } } + } + ] + } + }, + { + "name": "OracleQuoteOverrideEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "oracle", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" } + ] + } + }, + { + "name": "OracleQuoteRotateEvent", + "type": { + "kind": "struct", + "fields": [{ "name": "oracle", "type": "pubkey" }] + } + }, + { + "name": "OracleQuoteVerifyRequestEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "quote", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" } + ] + } + }, + { + "name": "OracleSetConfigsParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "new_authority", "type": { "option": "pubkey" } }, + { + "name": "new_secp_authority", + "type": { "option": { "array": ["u8", 64] } } + } + ] + } + }, + { + "name": "OracleStatsAccountData", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "owner", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" }, + { + "name": "finalized_epoch", + "docs": [ + "The last epoch that has completed. cleared after registered with the", + "staking program." + ], + "type": { "defined": { "name": "OracleEpochInfo" } } + }, + { + "name": "current_epoch", + "docs": [ + "The current epoch info being used by the oracle. for stake. Will moved", + "to finalized_epoch as soon as the epoch is over." + ], + "type": { "defined": { "name": "OracleEpochInfo" } } + }, + { + "name": "mega_slot_info", + "type": { "defined": { "name": "MegaSlotInfo" } } + }, + { "name": "last_transfer_slot", "type": "u64" }, + { "name": "bump", "type": "u8" }, + { "name": "padding1", "type": { "array": ["u8", 7] } }, + { + "name": "_ebuf", + "docs": ["Reserved."], + "type": { "array": ["u8", 1024] } + } + ] + } + }, + { + "name": "OracleSubmission", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "oracle", + "docs": ["The public key of the oracle that submitted this value."], + "type": "pubkey" + }, + { + "name": "slot", + "docs": ["The slot at which this value was signed."], + "type": "u64" + }, + { "name": "padding1", "type": { "array": ["u8", 8] } }, + { + "name": "value", + "docs": ["The value that was submitted."], + "type": "i128" + } + ] + } + }, + { + "name": "OracleUpdateDelegationParams", + "type": { + "kind": "struct", + "fields": [{ "name": "_reserved1", "type": "u64" }] + } + }, + { + "name": "PermissionSetEvent", + "type": { + "kind": "struct", + "fields": [{ "name": "permission", "type": "pubkey" }] + } + }, + { + "name": "PermissionSetParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "permission", "type": "u8" }, + { "name": "enable", "type": "bool" } + ] + } + }, + { + "name": "PullFeedAccountData", + "docs": ["A representation of the data in a pull feed account."], + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "submissions", + "docs": ["The oracle submissions for this feed."], + "type": { + "array": [{ "defined": { "name": "OracleSubmission" } }, 32] + } + }, + { + "name": "authority", + "docs": [ + "The public key of the authority that can update the feed hash that", + "this account will use for registering updates." + ], + "type": "pubkey" + }, + { + "name": "queue", + "docs": [ + "The public key of the queue which oracles must be bound to in order to", + "submit data to this feed." + ], + "type": "pubkey" + }, + { + "name": "feed_hash", + "docs": [ + "SHA-256 hash of the job schema oracles will execute to produce data", + "for this feed." + ], + "type": { "array": ["u8", 32] } + }, + { + "name": "initialized_at", + "docs": ["The slot at which this account was initialized."], + "type": "i64" + }, + { "name": "permissions", "type": "u64" }, + { "name": "max_variance", "type": "u64" }, + { "name": "min_responses", "type": "u32" }, + { "name": "name", "type": { "array": ["u8", 32] } }, + { "name": "padding1", "type": { "array": ["u8", 2] } }, + { "name": "historical_result_idx", "type": "u8" }, + { "name": "min_sample_size", "type": "u8" }, + { "name": "last_update_timestamp", "type": "i64" }, + { "name": "lut_slot", "type": "u64" }, + { "name": "_reserved1", "type": { "array": ["u8", 32] } }, + { + "name": "result", + "type": { "defined": { "name": "CurrentResult" } } + }, + { "name": "max_staleness", "type": "u32" }, + { "name": "padding2", "type": { "array": ["u8", 12] } }, + { + "name": "historical_results", + "type": { + "array": [{ "defined": { "name": "CompactResult" } }, 32] + } + }, + { "name": "_ebuf4", "type": { "array": ["u8", 8] } }, + { "name": "_ebuf3", "type": { "array": ["u8", 24] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 256] } } + ] + } + }, + { + "name": "PullFeedCloseParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "PullFeedErrorValueEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "feed", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" } + ] + } + }, + { + "name": "PullFeedInitParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "feed_hash", "type": { "array": ["u8", 32] } }, + { "name": "max_variance", "type": "u64" }, + { "name": "min_responses", "type": "u32" }, + { "name": "name", "type": { "array": ["u8", 32] } }, + { "name": "recent_slot", "type": "u64" }, + { "name": "ipfs_hash", "type": { "array": ["u8", 32] } }, + { "name": "min_sample_size", "type": "u8" }, + { "name": "max_staleness", "type": "u32" } + ] + } + }, + { + "name": "PullFeedSetConfigsParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "feed_hash", + "type": { "option": { "array": ["u8", 32] } } + }, + { "name": "authority", "type": { "option": "pubkey" } }, + { "name": "max_variance", "type": { "option": "u64" } }, + { "name": "min_responses", "type": { "option": "u32" } }, + { "name": "name", "type": { "option": { "array": ["u8", 32] } } }, + { + "name": "ipfs_hash", + "type": { "option": { "array": ["u8", 32] } } + }, + { "name": "min_sample_size", "type": { "option": "u8" } }, + { "name": "max_staleness", "type": { "option": "u32" } } + ] + } + }, + { + "name": "PullFeedSubmitResponseManyParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "slot", "type": "u64" }, + { + "name": "submissions", + "type": { "vec": { "defined": { "name": "MultiSubmission" } } } + } + ] + } + }, + { + "name": "PullFeedSubmitResponseParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "slot", "type": "u64" }, + { + "name": "submissions", + "type": { "vec": { "defined": { "name": "Submission" } } } + } + ] + } + }, + { + "name": "PullFeedValueEvents", + "type": { + "kind": "struct", + "fields": [ + { "name": "feeds", "type": { "vec": "pubkey" } }, + { "name": "oracles", "type": { "vec": "pubkey" } }, + { "name": "values", "type": { "vec": { "vec": "i128" } } }, + { "name": "reward", "type": "u32" } + ] + } + }, + { + "name": "QueueAccountData", + "docs": [ + "An Queue represents a round-robin queue of oracle oracles who attest on-chain", + "whether a Switchboard Function was executed within an enclave against an expected set of", + "enclave measurements.", + "", + "For an oracle to join the queue, the oracle must first submit their enclave quote on-chain and", + "wait for an existing oracle to attest their quote. If the oracle's quote matches an expected", + "measurement within the queues mr_enclaves config, it is granted permissions and will start", + "being assigned update requests." + ], + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "authority", + "docs": [ + "The address of the authority which is permitted to add/remove allowed enclave measurements." + ], + "type": "pubkey" + }, + { + "name": "mr_enclaves", + "docs": ["Allowed enclave measurements."], + "type": { "array": [{ "array": ["u8", 32] }, 32] } + }, + { + "name": "oracle_keys", + "docs": [ + "The addresses of the quote oracles who have a valid", + "verification status and have heartbeated on-chain recently." + ], + "type": { "array": ["pubkey", 128] } + }, + { + "name": "max_quote_verification_age", + "docs": [ + "The maximum allowable time until a EnclaveAccount needs to be re-verified on-chain." + ], + "type": "i64" + }, + { + "name": "last_heartbeat", + "docs": [ + "The unix timestamp when the last quote oracle heartbeated on-chain." + ], + "type": "i64" + }, + { "name": "node_timeout", "type": "i64" }, + { + "name": "oracle_min_stake", + "docs": [ + "The minimum number of lamports a quote oracle needs to lock-up in order to heartbeat and verify other quotes." + ], + "type": "u64" + }, + { "name": "allow_authority_override_after", "type": "i64" }, + { + "name": "mr_enclaves_len", + "docs": ["The number of allowed enclave measurements."], + "type": "u32" + }, + { + "name": "oracle_keys_len", + "docs": [ + "The length of valid quote oracles for the given attestation queue." + ], + "type": "u32" + }, + { + "name": "reward", + "docs": [ + "The reward paid to quote oracles for attesting on-chain." + ], + "type": "u32" + }, + { + "name": "curr_idx", + "docs": [ + "Incrementer used to track the current quote oracle permitted to run any available functions." + ], + "type": "u32" + }, + { + "name": "gc_idx", + "docs": [ + "Incrementer used to garbage collect and remove stale quote oracles." + ], + "type": "u32" + }, + { "name": "require_authority_heartbeat_permission", "type": "u8" }, + { "name": "require_authority_verify_permission", "type": "u8" }, + { "name": "require_usage_permissions", "type": "u8" }, + { "name": "signer_bump", "type": "u8" }, + { "name": "mint", "type": "pubkey" }, + { "name": "lut_slot", "type": "u64" }, + { "name": "allow_subsidies", "type": "u8" }, + { + "name": "_ebuf6", + "docs": ["Reserved."], + "type": { "array": ["u8", 23] } + }, + { "name": "_ebuf5", "type": { "array": ["u8", 32] } }, + { "name": "_ebuf4", "type": { "array": ["u8", 64] } }, + { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 256] } }, + { "name": "_ebuf1", "type": { "array": ["u8", 512] } } + ] + } + }, + { + "name": "QueueAddMrEnclaveEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "queue", "type": "pubkey" }, + { "name": "mr_enclave", "type": { "array": ["u8", 32] } } + ] + } + }, + { + "name": "QueueAddMrEnclaveParams", + "type": { + "kind": "struct", + "fields": [{ "name": "mr_enclave", "type": { "array": ["u8", 32] } }] + } + }, + { + "name": "QueueAllowSubsidiesParams", + "type": { + "kind": "struct", + "fields": [{ "name": "allow_subsidies", "type": "u8" }] + } + }, + { + "name": "QueueGarbageCollectParams", + "type": { "kind": "struct", "fields": [{ "name": "idx", "type": "u32" }] } + }, + { + "name": "QueueInitDelegationGroupParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "QueueInitEvent", + "type": { + "kind": "struct", + "fields": [{ "name": "queue", "type": "pubkey" }] + } + }, + { + "name": "QueueInitParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "allow_authority_override_after", "type": "u32" }, + { "name": "require_authority_heartbeat_permission", "type": "bool" }, + { "name": "require_usage_permissions", "type": "bool" }, + { "name": "max_quote_verification_age", "type": "u32" }, + { "name": "reward", "type": "u32" }, + { "name": "node_timeout", "type": "u32" }, + { "name": "recent_slot", "type": "u64" } + ] + } + }, + { + "name": "QueueRemoveMrEnclaveEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "queue", "type": "pubkey" }, + { "name": "mr_enclave", "type": { "array": ["u8", 32] } } + ] + } + }, + { + "name": "QueueRemoveMrEnclaveParams", + "type": { + "kind": "struct", + "fields": [{ "name": "mr_enclave", "type": { "array": ["u8", 32] } }] + } + }, + { + "name": "QueueSetConfigsParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "authority", "type": { "option": "pubkey" } }, + { "name": "reward", "type": { "option": "u32" } }, + { "name": "node_timeout", "type": { "option": "i64" } } + ] + } + }, + { + "name": "Quote", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "enclave_signer", + "docs": ["The address of the signer generated within an enclave."], + "type": "pubkey" + }, + { + "name": "mr_enclave", + "docs": [ + "The quotes MRENCLAVE measurement dictating the contents of the secure enclave." + ], + "type": { "array": ["u8", 32] } + }, + { + "name": "verification_status", + "docs": ["The VerificationStatus of the quote."], + "type": "u8" + }, + { "name": "padding1", "type": { "array": ["u8", 7] } }, + { + "name": "verification_timestamp", + "docs": ["The unix timestamp when the quote was last verified."], + "type": "i64" + }, + { + "name": "valid_until", + "docs": [ + "The unix timestamp when the quotes verification status expires." + ], + "type": "i64" + }, + { + "name": "quote_registry", + "docs": [ + "The off-chain registry where the verifiers quote can be located." + ], + "type": { "array": ["u8", 32] } + }, + { + "name": "registry_key", + "docs": [ + "Key to lookup the buffer data on IPFS or an alternative decentralized storage solution." + ], + "type": { "array": ["u8", 64] } + }, + { + "name": "secp256k1_signer", + "docs": [ + "The secp256k1 public key of the enclave signer. Derived from the enclave_signer." + ], + "type": { "array": ["u8", 64] } + }, + { "name": "last_ed25519_signer", "type": "pubkey" }, + { "name": "last_secp256k1_signer", "type": { "array": ["u8", 64] } }, + { "name": "last_rotate_slot", "type": "u64" }, + { "name": "guardian_approvers", "type": { "array": ["pubkey", 64] } }, + { "name": "guardian_approvers_len", "type": "u8" }, + { "name": "padding2", "type": { "array": ["u8", 7] } }, + { "name": "staging_ed25519_signer", "type": "pubkey" }, + { + "name": "staging_secp256k1_signer", + "type": { "array": ["u8", 64] } + }, + { + "name": "_ebuf4", + "docs": ["Reserved."], + "type": { "array": ["u8", 32] } + }, + { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 256] } }, + { "name": "_ebuf1", "type": { "array": ["u8", 512] } } + ] + } + }, + { + "name": "RandomnessAccountData", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "authority", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" }, + { "name": "seed_slothash", "type": { "array": ["u8", 32] } }, + { "name": "seed_slot", "type": "u64" }, + { "name": "oracle", "type": "pubkey" }, + { "name": "reveal_slot", "type": "u64" }, + { "name": "value", "type": { "array": ["u8", 32] } }, + { "name": "lut_slot", "type": "u64" }, + { "name": "_ebuf3", "type": { "array": ["u8", 24] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 64] } }, + { "name": "_ebuf1", "type": { "array": ["u8", 128] } }, + { + "name": "active_secp256k1_signer", + "type": { "array": ["u8", 64] } + }, + { "name": "active_secp256k1_expiration", "type": "i64" } + ] + } + }, + { + "name": "RandomnessCommitEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "randomness_account", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" }, + { "name": "slot", "type": "u64" }, + { "name": "slothash", "type": { "array": ["u8", 32] } } + ] + } + }, + { + "name": "RandomnessCommitParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "RandomnessInitParams", + "type": { + "kind": "struct", + "fields": [{ "name": "recent_slot", "type": "u64" }] + } + }, + { + "name": "RandomnessRevealParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "signature", "type": { "array": ["u8", 64] } }, + { "name": "recovery_id", "type": "u8" }, + { "name": "value", "type": { "array": ["u8", 32] } } + ] + } + }, + { + "name": "State", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "bump", "type": "u8" }, + { "name": "test_only_disable_mr_enclave_check", "type": "u8" }, + { "name": "enable_staking", "type": "u8" }, + { "name": "padding1", "type": { "array": ["u8", 5] } }, + { "name": "authority", "type": "pubkey" }, + { "name": "guardian_queue", "type": "pubkey" }, + { "name": "reserved1", "type": "u64" }, + { "name": "epoch_length", "type": "u64" }, + { + "name": "current_epoch", + "type": { "defined": { "name": "StateEpochInfo" } } + }, + { + "name": "next_epoch", + "type": { "defined": { "name": "StateEpochInfo" } } + }, + { + "name": "finalized_epoch", + "type": { "defined": { "name": "StateEpochInfo" } } + }, + { "name": "stake_pool", "type": "pubkey" }, + { "name": "stake_program", "type": "pubkey" }, + { "name": "switch_mint", "type": "pubkey" }, + { "name": "sgx_advisories", "type": { "array": ["u16", 32] } }, + { "name": "advisories_len", "type": "u8" }, + { "name": "padding2", "type": "u8" }, + { "name": "flat_reward_cut_percentage", "type": "u8" }, + { "name": "enable_slashing", "type": "u8" }, + { "name": "subsidy_amount", "type": "u32" }, + { "name": "lut_slot", "type": "u64" }, + { "name": "base_reward", "type": "u32" }, + { "name": "_ebuf6", "type": { "array": ["u8", 28] } }, + { "name": "_ebuf5", "type": { "array": ["u8", 32] } }, + { "name": "_ebuf4", "type": { "array": ["u8", 64] } }, + { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 512] } }, + { + "name": "cost_whitelist", + "docs": ["Cost whitelist by authority"], + "type": { "array": ["pubkey", 32] } + } + ] + } + }, + { + "name": "StateEpochInfo", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "id", "type": "u64" }, + { "name": "_reserved1", "type": "u64" }, + { "name": "slot_end", "type": "u64" } + ] + } + }, + { "name": "StateInitParams", "type": { "kind": "struct", "fields": [] } }, + { + "name": "StateSetConfigsParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "new_authority", "type": "pubkey" }, + { "name": "test_only_disable_mr_enclave_check", "type": "u8" }, + { "name": "stake_pool", "type": "pubkey" }, + { "name": "stake_program", "type": "pubkey" }, + { "name": "add_advisory", "type": "u16" }, + { "name": "rm_advisory", "type": "u16" }, + { "name": "epoch_length", "type": "u32" }, + { "name": "reset_epochs", "type": "bool" }, + { "name": "switch_mint", "type": "pubkey" }, + { "name": "enable_staking", "type": "u8" }, + { "name": "subsidy_amount", "type": "u32" }, + { "name": "base_reward", "type": "u32" }, + { "name": "add_cost_wl", "type": "pubkey" }, + { "name": "rm_cost_wl", "type": "pubkey" } + ] + } + }, + { + "name": "Submission", + "type": { + "kind": "struct", + "fields": [ + { "name": "value", "type": "i128" }, + { "name": "signature", "type": { "array": ["u8", 64] } }, + { "name": "recovery_id", "type": "u8" }, + { "name": "offset", "type": "u8" } + ] + } + } + ] +} diff --git a/solauto-sdk/src/utils/switchboardUtils.ts b/solauto-sdk/src/utils/switchboardUtils.ts index a29ed0a5..7f635d6f 100644 --- a/solauto-sdk/src/utils/switchboardUtils.ts +++ b/solauto-sdk/src/utils/switchboardUtils.ts @@ -6,9 +6,10 @@ import { } from "@solana/web3.js"; import { Signer, transactionBuilder } from "@metaplex-foundation/umi"; import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; -import { AnchorProvider, Program } from "@coral-xyz/anchor"; +import { AnchorProvider, Idl, Program } from "@coral-xyz/anchor"; import * as OnDemand from "@switchboard-xyz/on-demand"; import Big from "big.js"; +import switchboardIdl from "../idls/switchboard.json"; import { PRICES, SWITCHBOARD_PRICE_FEED_IDS } from "../constants"; import { TransactionItemInputs } from "../types"; import { @@ -17,7 +18,7 @@ import { } from "./generalUtils"; import { getWrappedInstruction } from "./solanaUtils"; -export async function getPullFeed( +export function getPullFeed( conn: Connection, mint: PublicKey, wallet?: PublicKey @@ -36,12 +37,11 @@ export async function getPullFeed( dummyWallet, AnchorProvider.defaultOptions() ); - const { PullFeed, ON_DEMAND_MAINNET_PID } = OnDemand; - const sbProgram = await Program.at(ON_DEMAND_MAINNET_PID, provider); + const program = new Program(switchboardIdl as Idl, provider); - console.log(new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId).toString()) + const { PullFeed } = OnDemand; return new PullFeed( - sbProgram, + program, new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId) ); } @@ -51,18 +51,12 @@ export async function buildSwbSubmitResponseTx( signer: Signer, mint: PublicKey ): Promise { - const feed = await getPullFeed( - conn, - mint, - toWeb3JsPublicKey(signer.publicKey) - ); - const gateway = await feed.fetchGatewayUrl(); - const [pullIxs, responses] = await retryWithExponentialBackoff( + const feed = getPullFeed(conn, mint, toWeb3JsPublicKey(signer.publicKey)); + const [pullIx, responses] = await retryWithExponentialBackoff( async () => { const res = await feed.fetchUpdateIx({ - gateway: gateway, chain: "solana", - network: "mainnet", + network: "mainnet-beta", }); if (!res[1] || !res[1][0].value) { throw new Error("Unable to fetch Switchboard pull IX"); @@ -73,7 +67,7 @@ export async function buildSwbSubmitResponseTx( 200 ); - if (!pullIxs || !pullIxs.length) { + if (!pullIx) { throw new Error("Unable to fetch SWB crank IX"); } @@ -87,9 +81,7 @@ export async function buildSwbSubmitResponseTx( }; return { - tx: transactionBuilder( - pullIxs.map((x) => getWrappedInstruction(signer, x)) - ), + tx: transactionBuilder([getWrappedInstruction(signer, pullIx!)]), lookupTableAddresses: responses .filter((x) => Boolean(x.oracle.lut?.key)) .map((x) => x.oracle.lut!.key.toString()), @@ -111,7 +103,7 @@ export async function getSwitchboardFeedData( const results = await Promise.all( mints.map(async (mint) => { - const feed = await getPullFeed(conn, mint); + const feed = getPullFeed(conn, mint); const result = await feed.loadData(); const price = Number(result.result.value) / Math.pow(10, 18); const stale = From 46dfe2432ed64642431ae47f44086d2ba03f958e Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 11 Jul 2025 12:54:45 -0400 Subject: [PATCH 62/88] Revert "Revert "bump versions"" This reverts commit 66bd27790d5653fd45df6a8bcfdfef8008de4d9b. --- pnpm-lock.yaml | 217 +-- solauto-sdk/package.json | 10 +- solauto-sdk/pnpm-lock.yaml | 480 ++--- solauto-sdk/src/idls/switchboard.json | 1949 --------------------- solauto-sdk/src/utils/switchboardUtils.ts | 32 +- 5 files changed, 288 insertions(+), 2400 deletions(-) delete mode 100644 solauto-sdk/src/idls/switchboard.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a9acb1a..312f22c7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,12 +34,6 @@ packages: dependencies: regenerator-runtime: 0.14.1 - /@brokerloop/ttlcache@3.2.3: - resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} - dependencies: - '@soncodi/signal': 2.0.7 - dev: true - /@common.js/quick-lru@7.0.0: resolution: {integrity: sha512-DO3vApnH1vLizdWRSqzhg+S956vptHhtO+vw6PP6StJGDtaAGyfKSSPPGYWguJZu/Jlti6l6m6jB8NrKEQexLg==} engines: {node: '>=18'} @@ -137,6 +131,11 @@ packages: yargs: 17.7.2 dev: false + /@isaacs/ttlcache@1.4.1: + resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} + engines: {node: '>=12'} + dev: true + /@js-sdsl/ordered-map@4.4.2: resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} dev: false @@ -526,6 +525,16 @@ packages: typescript: 4.9.5 dev: true + /@solana/codecs-core@2.1.1(typescript@4.9.5): + resolution: {integrity: sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + dependencies: + '@solana/errors': 2.1.1(typescript@4.9.5) + typescript: 4.9.5 + dev: true + /@solana/codecs-data-structures@2.0.0-preview.4(typescript@4.9.5): resolution: {integrity: sha512-nt2k2eTeyzlI/ccutPcG36M/J8NAYfxBPI9h/nQjgJ+M+IgOKi31JV8StDDlG/1XvY0zyqugV3I0r3KAbZRJpA==} peerDependencies: @@ -575,6 +584,17 @@ packages: typescript: 4.9.5 dev: true + /@solana/codecs-numbers@2.1.1(typescript@4.9.5): + resolution: {integrity: sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + dependencies: + '@solana/codecs-core': 2.1.1(typescript@4.9.5) + '@solana/errors': 2.1.1(typescript@4.9.5) + typescript: 4.9.5 + dev: true + /@solana/codecs-strings@2.0.0-preview.1(fastestsmallesttextencoderdecoder@1.0.22): resolution: {integrity: sha512-kBAxE9ZD5/c8j9CkPxqc55dbo7R50Re3k94SXR+k13DZCCs37Fyn0/mAkw/S95fofbi/zsi4jSfmsT5vCZD75A==} peerDependencies: @@ -672,6 +692,18 @@ packages: typescript: 4.9.5 dev: true + /@solana/errors@2.1.1(typescript@4.9.5): + resolution: {integrity: sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' + dependencies: + chalk: 5.4.1 + commander: 13.1.0 + typescript: 4.9.5 + dev: true + /@solana/options@2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-tv2O/Frxql/wSe3jbzi5nVicIWIus/BftH+5ZR+r9r3FO0/htEllZS5Q9XdbmSboHu+St87584JXeDx3xm4jaA==} peerDependencies: @@ -779,25 +811,6 @@ packages: - utf-8-validate dev: true - /@solana/spl-token@0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.88.0 - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8 - buffer: 6.0.3 - transitivePeerDependencies: - - bufferutil - - encoding - - fastestsmallesttextencoderdecoder - - typescript - - utf-8-validate - dev: true - /@solana/spl-token@0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-RO0JD9vPRi4LsAbMUdNbDJ5/cv2z11MGhtAvFeRzT4+hAGE/FUzRi0tkkWtuCfSIU3twC6CtmAihRp/+XXjWsA==} engines: {node: '>=16'} @@ -964,29 +977,31 @@ packages: - encoding - utf-8-validate - /@solworks/soltoolkit-sdk@0.0.23(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} + /@solana/web3.js@1.98.2(typescript@4.9.5): + resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} dependencies: + '@babel/runtime': 7.25.7 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 '@solana/buffer-layout': 4.0.1 - '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8 - '@types/bn.js': 5.1.6 - '@types/node': 18.19.67 - '@types/node-fetch': 2.6.12 + '@solana/codecs-numbers': 2.1.1(typescript@4.9.5) + agentkeepalive: 4.5.0 bn.js: 5.2.1 - decimal.js: 10.4.3 - typescript: 4.9.5 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.2 + node-fetch: 2.7.0 + rpc-websockets: 9.0.4 + superstruct: 2.0.2 transitivePeerDependencies: - bufferutil - encoding - - fastestsmallesttextencoderdecoder + - typescript - utf-8-validate dev: true - /@soncodi/signal@2.0.7: - resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} - dev: true - /@sqds/multisig@2.1.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-WOiL7La+RSiJsz7jVO85yhSiiSvNMUthiWuLPeWVOoD6IYa34BEAzanF1RdXRWGglSbRFYCTkyr+Ay1WmXmSRQ==} engines: {node: '>=14'} @@ -1015,28 +1030,6 @@ packages: dependencies: tslib: 2.7.0 - /@switchboard-xyz/common@2.5.5: - resolution: {integrity: sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w==} - engines: {node: '>=12'} - dependencies: - '@solana/web3.js': 1.95.8 - axios: 1.7.8 - big.js: 6.2.2 - bn.js: 5.2.1 - bs58: 5.0.0 - cron-validator: 1.3.1 - decimal.js: 10.4.3 - js-sha256: 0.11.0 - lodash: 4.17.21 - protobufjs: 7.4.0 - yaml: 2.6.1 - transitivePeerDependencies: - - bufferutil - - debug - - encoding - - utf-8-validate - dev: true - /@switchboard-xyz/common@3.0.12: resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} engines: {node: '>=20'} @@ -1079,25 +1072,26 @@ packages: - utf-8-validate dev: false - /@switchboard-xyz/on-demand@1.2.51(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} - engines: {node: '>= 18'} + /@switchboard-xyz/common@3.4.1(typescript@4.9.5): + resolution: {integrity: sha512-TropBlBYuDeBnmGHkPSmgC3clLqAxy51ZGbwk4ejAgadnszWOgYHcH7taRG4Ha17DYSCWw/LGMBKbunGo+Aoaw==} + engines: {node: '>=20'} dependencies: - '@brokerloop/ttlcache': 3.2.3 - '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 - '@solana/web3.js': 1.95.8 - '@solworks/soltoolkit-sdk': 0.0.23(fastestsmallesttextencoderdecoder@1.0.22) - '@switchboard-xyz/common': 2.5.5 - axios: 1.7.8 + '@solana/web3.js': 1.98.2(typescript@4.9.5) + axios: 1.10.0 big.js: 6.2.2 - bs58: 5.0.0 - js-yaml: 4.1.0 + bn.js: 5.2.1 + bs58: 6.0.0 + buffer: 6.0.3 + decimal.js: 10.4.3 + js-sha256: 0.11.0 protobufjs: 7.4.0 + yaml: 2.6.1 + zod: 4.0.0-beta.20250505T195954 transitivePeerDependencies: - bufferutil - debug - encoding - - fastestsmallesttextencoderdecoder + - typescript - utf-8-validate dev: true @@ -1120,6 +1114,25 @@ packages: - utf-8-validate dev: false + /@switchboard-xyz/on-demand@2.8.1(typescript@4.9.5): + resolution: {integrity: sha512-MqUXMuqmYfhjMdFIAyFOvCYr1BeacmA3ZY6Eu2RkHJLG1X3NAKdCHR2Bj13UU/H9P7HrKhse29Sn7QdbSeEp/w==} + engines: {node: '>= 18'} + dependencies: + '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 + '@isaacs/ttlcache': 1.4.1 + '@switchboard-xyz/common': 3.4.1(typescript@4.9.5) + axios: 1.10.0 + bs58: 6.0.0 + buffer: 6.0.3 + js-yaml: 4.1.0 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - typescript + - utf-8-validate + dev: true + /@types/bn.js@5.1.6: resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} dependencies: @@ -1131,22 +1144,9 @@ packages: dependencies: '@types/node': 20.16.11 - /@types/node-fetch@2.6.12: - resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} - dependencies: - '@types/node': 20.16.11 - form-data: 4.0.1 - dev: true - /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - /@types/node@18.19.67: - resolution: {integrity: sha512-wI8uHusga+0ZugNp0Ol/3BqQfEcCCNfojtO6Oou9iVNGPTL6QNSdnUdqq85fRgIorLhLMuPIKpsN98QE9Nh+KQ==} - dependencies: - undici-types: 5.26.5 - dev: true - /@types/node@20.16.11: resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} dependencies: @@ -1177,6 +1177,10 @@ packages: '@wallet-standard/base': 1.1.0 dev: false + /@zod/core@0.11.6: + resolution: {integrity: sha512-03Bv82fFSfjDAvMfdHHdGSS6SOJs0iCcJlWJv1kJHRtoTT02hZpyip/2Lk6oo4l4FtjuwTrsEQTwg/LD8I7dJA==} + dev: true + /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -1237,6 +1241,16 @@ packages: possible-typed-array-names: 1.0.0 dev: true + /axios@1.10.0: + resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: true + /axios@1.7.8: resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} dependencies: @@ -1359,6 +1373,11 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + /chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true + /cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -1389,6 +1408,11 @@ packages: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} + /commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + dev: true + /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -1397,10 +1421,6 @@ packages: engines: {node: '>= 6'} dev: false - /cron-validator@1.3.1: - resolution: {integrity: sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==} - dev: true - /cross-fetch@3.1.8: resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} dependencies: @@ -1748,10 +1768,6 @@ packages: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} dev: false - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true - /long@5.2.3: resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} @@ -1995,10 +2011,6 @@ packages: hasBin: true dev: true - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: true - /undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -2107,6 +2119,12 @@ packages: yargs-parser: 21.1.1 dev: false + /zod@4.0.0-beta.20250505T195954: + resolution: {integrity: sha512-iB8WvxkobVIXMARvQu20fKvbS7mUTiYRpcD8OQV1xjRhxO0EEpYIRJBk6yfBzHAHEdOSDh3SxDITr5Eajr2vtg==} + dependencies: + '@zod/core': 0.11.6 + dev: true + file:solauto-sdk(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {directory: solauto-sdk, type: directory} id: file:solauto-sdk @@ -2122,9 +2140,10 @@ packages: '@solana/web3.js': 1.95.8 '@sqds/multisig': 2.1.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) '@switchboard-xyz/common': 3.0.12 - '@switchboard-xyz/on-demand': 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) + '@switchboard-xyz/on-demand': 2.8.1(typescript@4.9.5) '@types/node': 20.16.11 axios: 1.7.8 + big.js: 6.2.2 bs58: 5.0.0 cross-fetch: 4.0.0 dotenv: 16.4.7 diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 7093eb24..75d71aa4 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.782", + "version": "1.0.784", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", @@ -12,16 +12,16 @@ "test:unit": "ts-mocha -p ./tsconfig.json -t 1000000 tests/unit/**/*.ts" }, "dependencies": { - "@coral-xyz/anchor": "^0.30.1", + "@coral-xyz/anchor": "=0.31.1", "@jup-ag/api": "=6.0.24", "@metaplex-foundation/umi": "^0.9.1", "@metaplex-foundation/umi-bundle-defaults": "^0.9.1", "@metaplex-foundation/umi-signer-wallet-adapters": "^0.9.1", "@metaplex-foundation/umi-web3js-adapters": "^0.9.1", "@solana/spl-token": "^0.4.0", - "@solana/web3.js": "=1.95.8", - "@switchboard-xyz/common": "=3.0.12", - "@switchboard-xyz/on-demand": "=1.2.51", + "@solana/web3.js": "=1.98.2", + "@switchboard-xyz/common": "=3.4.1", + "@switchboard-xyz/on-demand": "=2.11.0", "axios": "^1.7.8", "big.js": "^6.2.2", "bs58": "^5.0.0", diff --git a/solauto-sdk/pnpm-lock.yaml b/solauto-sdk/pnpm-lock.yaml index 5003c773..4d59ae42 100644 --- a/solauto-sdk/pnpm-lock.yaml +++ b/solauto-sdk/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: '@coral-xyz/anchor': - specifier: ^0.30.1 - version: 0.30.1 + specifier: '=0.31.1' + version: 0.31.1(typescript@5.6.3) '@jup-ag/api': specifier: '=6.0.24' version: 6.0.24 @@ -16,25 +16,25 @@ dependencies: version: 0.9.2 '@metaplex-foundation/umi-bundle-defaults': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) '@metaplex-foundation/umi-signer-wallet-adapters': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) '@metaplex-foundation/umi-web3js-adapters': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) '@solana/spl-token': specifier: ^0.4.0 - version: 0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + version: 0.4.8(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/web3.js': - specifier: '=1.95.8' - version: 1.95.8 + specifier: '=1.98.2' + version: 1.98.2(typescript@5.6.3) '@switchboard-xyz/common': - specifier: '=3.0.12' - version: 3.0.12 + specifier: '=3.4.1' + version: 3.4.1(typescript@5.6.3) '@switchboard-xyz/on-demand': - specifier: '=1.2.51' - version: 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) + specifier: '=2.11.0' + version: 2.11.0(typescript@5.6.3) axios: specifier: ^1.7.8 version: 1.7.8 @@ -89,58 +89,56 @@ packages: regenerator-runtime: 0.14.1 dev: false - /@brokerloop/ttlcache@3.2.3: - resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} - dependencies: - '@soncodi/signal': 2.0.7 - dev: false - - /@coral-xyz/anchor-errors@0.30.1: - resolution: {integrity: sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==} + /@coral-xyz/anchor-errors@0.31.1: + resolution: {integrity: sha512-NhNEku4F3zzUSBtrYz84FzYWm48+9OvmT1Hhnwr6GnPQry2dsEqH/ti/7ASjjpoFTWRnPXrjAIT1qM6Isop+LQ==} engines: {node: '>=10'} dev: false - /@coral-xyz/anchor@0.30.1: - resolution: {integrity: sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==} - engines: {node: '>=11'} + /@coral-xyz/anchor@0.31.1(typescript@5.6.3): + resolution: {integrity: sha512-QUqpoEK+gi2S6nlYc2atgT2r41TT3caWr/cPUEL8n8Md9437trZ68STknq897b82p5mW0XrTBNOzRbmIRJtfsA==} + engines: {node: '>=17'} dependencies: - '@coral-xyz/anchor-errors': 0.30.1 - '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.8) + '@coral-xyz/anchor-errors': 0.31.1 + '@coral-xyz/borsh': 0.31.1(@solana/web3.js@1.98.2) '@noble/hashes': 1.5.0 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) bn.js: 5.2.1 bs58: 4.0.1 buffer-layout: 1.2.2 camelcase: 6.3.0 cross-fetch: 3.1.8 - crypto-hash: 1.3.0 eventemitter3: 4.0.7 pako: 2.1.0 - snake-case: 3.0.4 superstruct: 0.15.5 toml: 3.0.0 transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate dev: false - /@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} + /@coral-xyz/borsh@0.31.1(@solana/web3.js@1.98.2): + resolution: {integrity: sha512-9N8AU9F0ubriKfNE3g1WF0/4dtlGXoBN/hd1PvbNBamBNwRgHxH4P+o3Zt7rSEloW1HUs6LfZEchlx9fW7POYw==} engines: {node: '>=10'} peerDependencies: - '@solana/web3.js': ^1.68.0 + '@solana/web3.js': ^1.69.0 dependencies: - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) bn.js: 5.2.1 buffer-layout: 1.2.2 dev: false + /@isaacs/ttlcache@1.4.1: + resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} + engines: {node: '>=12'} + dev: false + /@jup-ag/api@6.0.24: resolution: {integrity: sha512-zIX4WIPb0Kb2UnK2wNIOQBWqPJyMJq/D9dQTf/2qvPb0hfa8XdgbrQAzomHMHnAzw9StMQoybBk+JK/A76xP3w==} dev: false - /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): + /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): resolution: {integrity: sha512-kV3tfvgvRjVP1p9OFOtH+ibOtN9omVJSwKr0We4/9r45e5LTj+32su0V/rixZUkG1EZzzOYBsxhtIE0kIw/Hrw==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 @@ -148,14 +146,14 @@ packages: dependencies: '@metaplex-foundation/umi': 0.9.2 '@metaplex-foundation/umi-downloader-http': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) '@metaplex-foundation/umi-http-fetch': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-program-repository': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-rpc-chunk-get-accounts': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) '@metaplex-foundation/umi-serializer-data-view': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 + '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@solana/web3.js': 1.98.2(typescript@5.6.3) transitivePeerDependencies: - encoding dev: false @@ -168,16 +166,16 @@ packages: '@metaplex-foundation/umi': 0.9.2 dev: false - /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): + /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): resolution: {integrity: sha512-hhPCxXbYIp4BC4z9gK78sXpWLkNSrfv4ndhF5ruAkdIp7GcRVYKj0QnOUO6lGYGiIkNlw20yoTwOe1CT//OfTQ==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) '@noble/curves': 1.6.0 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) dev: false /@metaplex-foundation/umi-http-fetch@0.9.2(@metaplex-foundation/umi@0.9.2): @@ -217,15 +215,15 @@ packages: '@metaplex-foundation/umi': 0.9.2 dev: false - /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): + /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): resolution: {integrity: sha512-MqcsBz8B4wGl6jxsf2Jo/rAEpYReU9VCSR15QSjhvADHMmdFxCIZCCAgE+gDE2Vuanfl437VhOcP3g5Uw8C16Q==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@solana/web3.js': 1.98.2(typescript@5.6.3) dev: false /@metaplex-foundation/umi-serializer-data-view@0.9.2(@metaplex-foundation/umi@0.9.2): @@ -262,36 +260,36 @@ packages: '@metaplex-foundation/umi-serializers-numbers': 0.8.9 dev: false - /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): + /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): resolution: {integrity: sha512-DFG0ZFocKG8briypSkG9bGUTVsWpAgYugsl2BzTygkGExc4evWfF4Sb1F2C2w9FdrA9ESZM1gpLX9xtx5taOXg==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@solana/web3.js': 1.98.2(typescript@5.6.3) dev: false - /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): + /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): resolution: {integrity: sha512-fR1Kf21uylMFd1Smkltmj4jTNxhqSWf416owsJ+T+cvJi2VCOcOwq/3UFzOrpz78fA0RhsajKYKj0HYsRnQI1g==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@solana/web3.js': 1.98.2(typescript@5.6.3) dev: false - /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): + /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): resolution: {integrity: sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) buffer: 6.0.3 dev: false @@ -358,17 +356,18 @@ packages: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} dev: false - /@solana/buffer-layout-utils@0.2.0: + /@solana/buffer-layout-utils@0.2.0(typescript@5.6.3): resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} engines: {node: '>= 10'} dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) bigint-buffer: 1.1.5 bignumber.js: 9.1.2 transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate dev: false @@ -388,21 +387,22 @@ packages: typescript: 5.6.3 dev: false - /@solana/codecs-core@2.0.0-rc.1(typescript@4.9.5): + /@solana/codecs-core@2.0.0-rc.1(typescript@5.6.3): resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} peerDependencies: typescript: '>=5' dependencies: - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - typescript: 4.9.5 + '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) + typescript: 5.6.3 dev: false - /@solana/codecs-core@2.0.0-rc.1(typescript@5.6.3): - resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} + /@solana/codecs-core@2.1.1(typescript@5.6.3): + resolution: {integrity: sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg==} + engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5' + typescript: '>=5.3.3' dependencies: - '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) + '@solana/errors': 2.1.1(typescript@5.6.3) typescript: 5.6.3 dev: false @@ -417,17 +417,6 @@ packages: typescript: 5.6.3 dev: false - /@solana/codecs-data-structures@2.0.0-rc.1(typescript@4.9.5): - resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} - peerDependencies: - typescript: '>=5' - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - typescript: 4.9.5 - dev: false - /@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.6.3): resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} peerDependencies: @@ -449,23 +438,24 @@ packages: typescript: 5.6.3 dev: false - /@solana/codecs-numbers@2.0.0-rc.1(typescript@4.9.5): + /@solana/codecs-numbers@2.0.0-rc.1(typescript@5.6.3): resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} peerDependencies: typescript: '>=5' dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - typescript: 4.9.5 + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.6.3) + '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) + typescript: 5.6.3 dev: false - /@solana/codecs-numbers@2.0.0-rc.1(typescript@5.6.3): - resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} + /@solana/codecs-numbers@2.1.1(typescript@5.6.3): + resolution: {integrity: sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ==} + engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5' + typescript: '>=5.3.3' dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.6.3) - '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) + '@solana/codecs-core': 2.1.1(typescript@5.6.3) + '@solana/errors': 2.1.1(typescript@5.6.3) typescript: 5.6.3 dev: false @@ -482,19 +472,6 @@ packages: typescript: 5.6.3 dev: false - /@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} - peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - typescript: '>=5' - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - fastestsmallesttextencoderdecoder: 1.0.22 - typescript: 4.9.5 - dev: false - /@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} peerDependencies: @@ -523,21 +500,6 @@ packages: - fastestsmallesttextencoderdecoder dev: false - /@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} - peerDependencies: - typescript: '>=5' - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - dev: false - /@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} peerDependencies: @@ -564,7 +526,7 @@ packages: typescript: 5.6.3 dev: false - /@solana/errors@2.0.0-rc.1(typescript@4.9.5): + /@solana/errors@2.0.0-rc.1(typescript@5.6.3): resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} hasBin: true peerDependencies: @@ -572,17 +534,18 @@ packages: dependencies: chalk: 5.3.0 commander: 12.1.0 - typescript: 4.9.5 + typescript: 5.6.3 dev: false - /@solana/errors@2.0.0-rc.1(typescript@5.6.3): - resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} + /@solana/errors@2.1.1(typescript@5.6.3): + resolution: {integrity: sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw==} + engines: {node: '>=20.18.0'} hasBin: true peerDependencies: - typescript: '>=5' + typescript: '>=5.3.3' dependencies: - chalk: 5.3.0 - commander: 12.1.0 + chalk: 5.4.1 + commander: 13.1.0 typescript: 5.6.3 dev: false @@ -601,21 +564,6 @@ packages: - fastestsmallesttextencoderdecoder dev: false - /@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} - peerDependencies: - typescript: '>=5' - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - dev: false - /@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} peerDependencies: @@ -631,7 +579,7 @@ packages: - fastestsmallesttextencoderdecoder dev: false - /@solana/spl-token-group@0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token-group@0.0.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-CLJnWEcdoUBpQJfx9WEbX3h6nTdNiUzswfFdkABUik7HVwSNA98u5AYvBVK2H93d9PGMOHAak2lHW9xr+zAJGQ==} engines: {node: '>=16'} peerDependencies: @@ -639,13 +587,13 @@ packages: dependencies: '@solana/codecs': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript dev: false - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} engines: {node: '>=16'} peerDependencies: @@ -653,56 +601,23 @@ packages: dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.98.2(typescript@5.6.3) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript dev: false - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.95.3 - dependencies: - '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.98.0 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - typescript - dev: false - - /@solana/spl-token@0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.88.0 - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.98.0 - buffer: 6.0.3 - transitivePeerDependencies: - - bufferutil - - encoding - - fastestsmallesttextencoderdecoder - - typescript - - utf-8-validate - dev: false - - /@solana/spl-token@0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token@0.4.8(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-RO0JD9vPRi4LsAbMUdNbDJ5/cv2z11MGhtAvFeRzT4+hAGE/FUzRi0tkkWtuCfSIU3twC6CtmAihRp/+XXjWsA==} engines: {node: '>=16'} peerDependencies: '@solana/web3.js': ^1.94.0 dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/web3.js': 1.95.8 + '@solana/buffer-layout-utils': 0.2.0(typescript@5.6.3) + '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/web3.js': 1.98.2(typescript@5.6.3) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -719,39 +634,15 @@ packages: buffer: 6.0.3 dev: false - /@solana/web3.js@1.95.8: - resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} - dependencies: - '@babel/runtime': 7.25.7 - '@noble/curves': 1.6.0 - '@noble/hashes': 1.5.0 - '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.5.0 - bigint-buffer: 1.1.5 - bn.js: 5.2.1 - borsh: 0.7.0 - bs58: 4.0.1 - buffer: 6.0.3 - fast-stable-stringify: 1.0.0 - jayson: 4.1.2 - node-fetch: 2.7.0 - rpc-websockets: 9.0.4 - superstruct: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - - /@solana/web3.js@1.98.0: - resolution: {integrity: sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==} + /@solana/web3.js@1.98.2(typescript@5.6.3): + resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} dependencies: '@babel/runtime': 7.25.7 '@noble/curves': 1.6.0 '@noble/hashes': 1.5.0 '@solana/buffer-layout': 4.0.1 + '@solana/codecs-numbers': 2.1.1(typescript@5.6.3) agentkeepalive: 4.5.0 - bigint-buffer: 1.1.5 bn.js: 5.2.1 borsh: 0.7.0 bs58: 4.0.1 @@ -764,66 +655,22 @@ packages: transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate dev: false - /@solworks/soltoolkit-sdk@0.0.23(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/spl-token': 0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.98.0 - '@types/bn.js': 5.1.6 - '@types/node': 18.19.65 - '@types/node-fetch': 2.6.12 - bn.js: 5.2.1 - decimal.js: 10.4.3 - typescript: 4.9.5 - transitivePeerDependencies: - - bufferutil - - encoding - - fastestsmallesttextencoderdecoder - - utf-8-validate - dev: false - - /@soncodi/signal@2.0.7: - resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} - dev: false - /@swc/helpers@0.5.13: resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} dependencies: tslib: 2.7.0 dev: false - /@switchboard-xyz/common@2.5.5: - resolution: {integrity: sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w==} - engines: {node: '>=12'} - dependencies: - '@solana/web3.js': 1.98.0 - axios: 1.8.4 - big.js: 6.2.2 - bn.js: 5.2.1 - bs58: 5.0.0 - cron-validator: 1.3.1 - decimal.js: 10.4.3 - js-sha256: 0.11.0 - lodash: 4.17.21 - protobufjs: 7.4.0 - yaml: 2.6.1 - transitivePeerDependencies: - - bufferutil - - debug - - encoding - - utf-8-validate - dev: false - - /@switchboard-xyz/common@3.0.12: - resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} + /@switchboard-xyz/common@3.4.1(typescript@5.6.3): + resolution: {integrity: sha512-TropBlBYuDeBnmGHkPSmgC3clLqAxy51ZGbwk4ejAgadnszWOgYHcH7taRG4Ha17DYSCWw/LGMBKbunGo+Aoaw==} engines: {node: '>=20'} dependencies: - '@solana/web3.js': 1.98.0 - axios: 1.8.4 + '@solana/web3.js': 1.98.2(typescript@5.6.3) + axios: 1.10.0 big.js: 6.2.2 bn.js: 5.2.1 bs58: 6.0.0 @@ -832,33 +679,32 @@ packages: js-sha256: 0.11.0 protobufjs: 7.4.0 yaml: 2.6.1 + zod: 4.0.0-beta.20250505T195954 transitivePeerDependencies: - bufferutil - debug - encoding + - typescript - utf-8-validate dev: false - /@switchboard-xyz/on-demand@1.2.51(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} + /@switchboard-xyz/on-demand@2.11.0(typescript@5.6.3): + resolution: {integrity: sha512-w4iHyRpvIuv2CT2Bcap6zIdunLYcDBuMUliyJuxmxLD+ch2Lta1QWHAZCsjuBasE2OhSKoTz3MAtapYuCuR2gA==} engines: {node: '>= 18'} - deprecated: deprecated in favor of 2.x.x - dependencies: - '@brokerloop/ttlcache': 3.2.3 - '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 - '@solana/web3.js': 1.98.0 - '@solworks/soltoolkit-sdk': 0.0.23(fastestsmallesttextencoderdecoder@1.0.22) - '@switchboard-xyz/common': 2.5.5 - axios: 1.8.4 - big.js: 6.2.2 - bs58: 5.0.0 + dependencies: + '@coral-xyz/anchor-31': /@coral-xyz/anchor@0.31.1(typescript@5.6.3) + '@isaacs/ttlcache': 1.4.1 + '@switchboard-xyz/common': 3.4.1(typescript@5.6.3) + axios: 1.10.0 + bs58: 6.0.0 + buffer: 6.0.3 js-yaml: 4.1.0 - protobufjs: 7.4.0 + ws: 8.18.3 transitivePeerDependencies: - bufferutil - debug - encoding - - fastestsmallesttextencoderdecoder + - typescript - utf-8-validate dev: false @@ -866,12 +712,6 @@ packages: resolution: {integrity: sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==} dev: true - /@types/bn.js@5.1.6: - resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} - dependencies: - '@types/node': 20.16.11 - dev: false - /@types/chai@4.3.20: resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} dev: true @@ -892,23 +732,10 @@ packages: resolution: {integrity: sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==} dev: true - /@types/node-fetch@2.6.12: - resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} - dependencies: - '@types/node': 20.16.11 - form-data: 4.0.1 - dev: false - /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: false - /@types/node@18.19.65: - resolution: {integrity: sha512-Ay5BZuO1UkTmVHzZJNvZKw/E+iB3GQABb6kijEz89w2JrfhNA+M/ebp18pfz9Gqe9ywhMC8AA8yC01lZq48J+Q==} - dependencies: - undici-types: 5.26.5 - dev: false - /@types/node@20.16.11: resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} dependencies: @@ -934,6 +761,10 @@ packages: resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} dev: true + /@zod/core@0.11.6: + resolution: {integrity: sha512-03Bv82fFSfjDAvMfdHHdGSS6SOJs0iCcJlWJv1kJHRtoTT02hZpyip/2Lk6oo4l4FtjuwTrsEQTwg/LD8I7dJA==} + dev: false + /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -990,8 +821,8 @@ packages: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false - /axios@1.7.8: - resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} + /axios@1.10.0: + resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} dependencies: follow-redirects: 1.15.9 form-data: 4.0.1 @@ -1000,8 +831,8 @@ packages: - debug dev: false - /axios@1.8.4: - resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} + /axios@1.7.8: + resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} dependencies: follow-redirects: 1.15.9 form-data: 4.0.1 @@ -1161,6 +992,11 @@ packages: engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} dev: false + /chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: false + /check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} dependencies: @@ -1213,6 +1049,11 @@ packages: engines: {node: '>=18'} dev: false + /commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + dev: false + /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: false @@ -1221,10 +1062,6 @@ packages: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true - /cron-validator@1.3.1: - resolution: {integrity: sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==} - dev: false - /cross-fetch@3.1.8: resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} dependencies: @@ -1241,11 +1078,6 @@ packages: - encoding dev: false - /crypto-hash@1.3.0: - resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} - engines: {node: '>=8'} - dev: false - /debug@4.3.3(supports-color@8.1.1): resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} engines: {node: '>=6.0'} @@ -1295,13 +1127,6 @@ packages: engines: {node: '>=0.3.1'} dev: true - /dot-case@3.0.4: - resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} - dependencies: - no-case: 3.0.4 - tslib: 2.7.0 - dev: false - /dotenv@16.4.7: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} @@ -1580,10 +1405,6 @@ packages: p-locate: 5.0.0 dev: true - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: false - /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -1602,12 +1423,6 @@ packages: get-func-name: 2.0.2 dev: true - /lower-case@2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} - dependencies: - tslib: 2.7.0 - dev: false - /make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: true @@ -1692,13 +1507,6 @@ packages: hasBin: true dev: true - /no-case@3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - dependencies: - lower-case: 2.0.2 - tslib: 2.7.0 - dev: false - /node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -1846,13 +1654,6 @@ packages: randombytes: 2.1.0 dev: true - /snake-case@3.0.4: - resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} - dependencies: - dot-case: 3.0.4 - tslib: 2.7.0 - dev: false - /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: @@ -1987,21 +1788,11 @@ packages: engines: {node: '>=4'} dev: true - /typescript@4.9.5: - resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: false - /typescript@5.6.3: resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} hasBin: true - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: false - /undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -2083,6 +1874,19 @@ packages: utf-8-validate: 5.0.10 dev: false + /ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -2131,3 +1935,9 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true + + /zod@4.0.0-beta.20250505T195954: + resolution: {integrity: sha512-iB8WvxkobVIXMARvQu20fKvbS7mUTiYRpcD8OQV1xjRhxO0EEpYIRJBk6yfBzHAHEdOSDh3SxDITr5Eajr2vtg==} + dependencies: + '@zod/core': 0.11.6 + dev: false diff --git a/solauto-sdk/src/idls/switchboard.json b/solauto-sdk/src/idls/switchboard.json deleted file mode 100644 index 6996121a..00000000 --- a/solauto-sdk/src/idls/switchboard.json +++ /dev/null @@ -1,1949 +0,0 @@ -{ - "address": "SBondMDrcV3K4kxZR1HNVT7osZxAHVHgYXL5Ze1oMUv", - "metadata": { - "name": "sb_on_demand", - "version": "0.1.0", - "spec": "0.1.0", - "description": "Created with Anchor" - }, - "instructions": [ - { - "name": "guardian_quote_verify", - "discriminator": [168, 36, 93, 156, 157, 150, 148, 45], - "accounts": [ - { "name": "guardian", "writable": true }, - { "name": "oracle", "writable": true }, - { "name": "authority", "signer": true, "relations": ["oracle"] }, - { "name": "guardian_queue", "writable": true, "relations": ["state"] }, - { "name": "state" }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "GuardianQuoteVerifyParams" } } - } - ] - }, - { - "name": "guardian_register", - "discriminator": [159, 76, 53, 117, 219, 29, 116, 135], - "accounts": [ - { "name": "oracle", "writable": true }, - { "name": "state" }, - { "name": "guardian_queue", "relations": ["state"] }, - { "name": "authority", "signer": true, "relations": ["state"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "GuardianRegisterParams" } } - } - ] - }, - { - "name": "guardian_unregister", - "discriminator": [215, 19, 61, 120, 155, 224, 120, 60], - "accounts": [ - { "name": "oracle", "writable": true }, - { "name": "state" }, - { "name": "guardian_queue", "writable": true, "relations": ["state"] }, - { "name": "authority", "signer": true, "relations": ["state"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "GuardianUnregisterParams" } } - } - ] - }, - { - "name": "oracle_heartbeat", - "discriminator": [10, 175, 217, 130, 111, 35, 117, 54], - "accounts": [ - { "name": "oracle", "writable": true }, - { - "name": "oracle_stats", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] - }, - { "kind": "account", "path": "oracle" } - ] - } - }, - { "name": "oracle_signer", "signer": true }, - { - "name": "queue", - "writable": true, - "relations": ["oracle", "gc_node"] - }, - { "name": "gc_node", "writable": true }, - { "name": "program_state", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "native_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "queue_escrow", "writable": true }, - { - "name": "stake_program", - "address": "SBSTk6t52R89MmCdD739Rdd97HdbTQUFHe41vCX7pTt", - "relations": ["program_state"] - }, - { "name": "delegation_pool", "writable": true }, - { "name": "delegation_group", "writable": true } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "OracleHeartbeatParams" } } - } - ] - }, - { - "name": "oracle_init", - "discriminator": [21, 158, 66, 65, 60, 221, 148, 61], - "accounts": [ - { "name": "oracle", "writable": true, "signer": true }, - { - "name": "oracle_stats", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] - }, - { "kind": "account", "path": "oracle" } - ] - } - }, - { "name": "program_state", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - }, - { "name": "stake_program", "relations": ["program_state"] }, - { "name": "stake_pool", "relations": ["program_state"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "OracleInitParams" } } - } - ] - }, - { - "name": "oracle_set_configs", - "discriminator": [129, 111, 223, 4, 191, 188, 70, 180], - "accounts": [ - { "name": "oracle" }, - { "name": "authority", "signer": true, "relations": ["oracle"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "OracleSetConfigsParams" } } - } - ] - }, - { - "name": "oracle_update_delegation", - "discriminator": [46, 198, 113, 223, 160, 189, 118, 90], - "accounts": [ - { "name": "oracle", "writable": true }, - { - "name": "oracle_stats", - "pda": { - "seeds": [ - { - "kind": "const", - "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] - }, - { "kind": "account", "path": "oracle" } - ] - } - }, - { "name": "queue", "relations": ["oracle"] }, - { "name": "authority", "signer": true }, - { "name": "program_state", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { "name": "delegation_pool", "writable": true }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - }, - { "name": "switch_mint" }, - { - "name": "native_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "wsol_vault", "writable": true }, - { "name": "switch_vault", "writable": true }, - { "name": "stake_program", "relations": ["program_state"] }, - { "name": "stake_pool" }, - { "name": "delegation_group" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "OracleUpdateDelegationParams" } } - } - ] - }, - { - "name": "permission_set", - "discriminator": [211, 122, 185, 120, 129, 182, 55, 103], - "accounts": [ - { "name": "authority", "signer": true }, - { "name": "granter" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PermissionSetParams" } } - } - ] - }, - { - "name": "pull_feed_close", - "discriminator": [19, 134, 50, 142, 177, 215, 196, 83], - "accounts": [ - { "name": "pull_feed", "writable": true }, - { "name": "reward_escrow", "writable": true }, - { "name": "lut", "writable": true }, - { "name": "lut_signer" }, - { "name": "payer", "writable": true, "signer": true }, - { "name": "state" }, - { - "name": "authority", - "writable": true, - "signer": true, - "relations": ["pull_feed"] - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "associated_token_program", - "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedCloseParams" } } - } - ] - }, - { - "name": "pull_feed_init", - "discriminator": [198, 130, 53, 198, 235, 61, 143, 40], - "accounts": [ - { "name": "pull_feed", "writable": true, "signer": true }, - { "name": "queue" }, - { "name": "authority" }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "program_state" }, - { - "name": "reward_escrow", - "writable": true, - "pda": { - "seeds": [ - { "kind": "account", "path": "pull_feed" }, - { - "kind": "const", - "value": [ - 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, - 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, - 245, 133, 126, 255, 0, 169 - ] - }, - { "kind": "account", "path": "wrapped_sol_mint" } - ], - "program": { - "kind": "const", - "value": [ - 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, - 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, - 219, 233, 248, 89 - ] - } - } - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "associated_token_program", - "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" - }, - { - "name": "wrapped_sol_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedInitParams" } } - } - ] - }, - { - "name": "pull_feed_set_configs", - "discriminator": [217, 45, 11, 246, 64, 26, 82, 168], - "accounts": [ - { "name": "pull_feed", "writable": true }, - { "name": "authority", "signer": true, "relations": ["pull_feed"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedSetConfigsParams" } } - } - ] - }, - { - "name": "pull_feed_submit_response", - "discriminator": [150, 22, 215, 166, 143, 93, 48, 137], - "accounts": [ - { "name": "feed", "writable": true }, - { "name": "queue", "relations": ["feed"] }, - { "name": "program_state" }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "reward_vault", "writable": true }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "token_mint", - "address": "So11111111111111111111111111111111111111112" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedSubmitResponseParams" } } - } - ] - }, - { - "name": "pull_feed_submit_response_many", - "discriminator": [47, 156, 45, 25, 200, 71, 37, 215], - "accounts": [ - { "name": "queue" }, - { "name": "program_state" }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "reward_vault", "writable": true }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "token_mint", - "address": "So11111111111111111111111111111111111111112" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedSubmitResponseManyParams" } } - } - ] - }, - { - "name": "queue_add_mr_enclave", - "discriminator": [199, 255, 81, 50, 60, 133, 171, 138], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "authority", "signer": true }, - { "name": "program_authority" }, - { "name": "state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueAddMrEnclaveParams" } } - } - ] - }, - { - "name": "queue_allow_subsidies", - "discriminator": [94, 203, 82, 157, 188, 138, 202, 108], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "authority", "signer": true, "relations": ["state"] }, - { "name": "state", "writable": true } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueAllowSubsidiesParams" } } - } - ] - }, - { - "name": "queue_garbage_collect", - "discriminator": [187, 208, 104, 247, 16, 91, 96, 98], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "oracle", "writable": true }, - { "name": "authority", "signer": true }, - { "name": "state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueGarbageCollectParams" } } - } - ] - }, - { - "name": "queue_init", - "discriminator": [144, 18, 99, 145, 133, 27, 207, 13], - "accounts": [ - { "name": "queue", "writable": true, "signer": true }, - { - "name": "queue_escrow", - "writable": true, - "pda": { - "seeds": [ - { "kind": "account", "path": "queue" }, - { - "kind": "const", - "value": [ - 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, - 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, - 245, 133, 126, 255, 0, 169 - ] - }, - { "kind": "account", "path": "native_mint" } - ], - "program": { - "kind": "const", - "value": [ - 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, - 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, - 219, 233, 248, 89 - ] - } - } - }, - { "name": "authority" }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "native_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "program_state" }, - { "name": "lut_signer", "writable": true }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - }, - { - "name": "associated_token_program", - "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueInitParams" } } - } - ] - }, - { - "name": "queue_init_delegation_group", - "discriminator": [239, 146, 75, 158, 20, 166, 159, 14], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "program_state" }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - }, - { "name": "delegation_group", "writable": true }, - { "name": "stake_program", "relations": ["program_state"] }, - { "name": "stake_pool" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueInitDelegationGroupParams" } } - } - ] - }, - { - "name": "queue_remove_mr_enclave", - "discriminator": [3, 64, 135, 33, 190, 133, 68, 252], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "authority", "signer": true }, - { "name": "program_authority" }, - { "name": "state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueRemoveMrEnclaveParams" } } - } - ] - }, - { - "name": "queue_set_configs", - "discriminator": [54, 183, 243, 199, 49, 103, 142, 48], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "authority", "signer": true }, - { "name": "state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueSetConfigsParams" } } - } - ] - }, - { - "name": "randomness_commit", - "discriminator": [52, 170, 152, 201, 179, 133, 242, 141], - "accounts": [ - { "name": "randomness", "writable": true }, - { "name": "queue", "relations": ["randomness", "oracle"] }, - { "name": "oracle", "writable": true }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - }, - { "name": "authority", "signer": true, "relations": ["randomness"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "RandomnessCommitParams" } } - } - ] - }, - { - "name": "randomness_init", - "discriminator": [9, 9, 204, 33, 50, 116, 113, 15], - "accounts": [ - { "name": "randomness", "writable": true, "signer": true }, - { - "name": "reward_escrow", - "writable": true, - "pda": { - "seeds": [ - { "kind": "account", "path": "randomness" }, - { - "kind": "const", - "value": [ - 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, - 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, - 245, 133, 126, 255, 0, 169 - ] - }, - { "kind": "account", "path": "wrapped_sol_mint" } - ], - "program": { - "kind": "const", - "value": [ - 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, - 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, - 219, 233, 248, 89 - ] - } - } - }, - { "name": "authority", "signer": true }, - { "name": "queue", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "associated_token_program", - "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" - }, - { - "name": "wrapped_sol_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "program_state" }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "RandomnessInitParams" } } - } - ] - }, - { - "name": "randomness_reveal", - "discriminator": [197, 181, 187, 10, 30, 58, 20, 73], - "accounts": [ - { "name": "randomness", "writable": true }, - { "name": "oracle", "relations": ["randomness"] }, - { "name": "queue", "relations": ["oracle"] }, - { - "name": "stats", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 79, 114, 97, 99, 108, 101, 82, 97, 110, 100, 111, 109, 110, - 101, 115, 115, 83, 116, 97, 116, 115 - ] - }, - { "kind": "account", "path": "oracle" } - ] - } - }, - { "name": "authority", "signer": true, "relations": ["randomness"] }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "reward_escrow", "writable": true }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "wrapped_sol_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "program_state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "RandomnessRevealParams" } } - } - ] - }, - { - "name": "state_init", - "discriminator": [103, 241, 106, 190, 217, 153, 87, 105], - "accounts": [ - { - "name": "state", - "writable": true, - "pda": { - "seeds": [{ "kind": "const", "value": [83, 84, 65, 84, 69] }] - } - }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "StateInitParams" } } - } - ] - }, - { - "name": "state_set_configs", - "discriminator": [40, 98, 76, 37, 206, 9, 47, 144], - "accounts": [ - { "name": "state", "writable": true }, - { "name": "authority", "signer": true, "relations": ["state"] }, - { "name": "queue", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "StateSetConfigsParams" } } - } - ] - } - ], - "accounts": [ - { - "name": "OracleAccountData", - "discriminator": [128, 30, 16, 241, 170, 73, 55, 54] - }, - { - "name": "OracleStatsAccountData", - "discriminator": [180, 157, 178, 234, 240, 27, 152, 179] - }, - { - "name": "PullFeedAccountData", - "discriminator": [196, 27, 108, 196, 10, 215, 219, 40] - }, - { - "name": "QueueAccountData", - "discriminator": [217, 194, 55, 127, 184, 83, 138, 1] - }, - { - "name": "RandomnessAccountData", - "discriminator": [10, 66, 229, 135, 220, 239, 217, 114] - }, - { "name": "State", "discriminator": [216, 146, 107, 94, 104, 75, 182, 177] } - ], - "events": [ - { - "name": "CostWhitelistEvent", - "discriminator": [56, 107, 191, 127, 116, 6, 138, 149] - }, - { - "name": "GarbageCollectionEvent", - "discriminator": [232, 235, 2, 188, 8, 143, 145, 237] - }, - { - "name": "GuardianQuoteVerifyEvent", - "discriminator": [31, 37, 39, 6, 214, 186, 33, 115] - }, - { - "name": "OracleHeartbeatEvent", - "discriminator": [52, 29, 166, 2, 94, 7, 188, 13] - }, - { - "name": "OracleInitEvent", - "discriminator": [89, 193, 219, 200, 1, 83, 167, 24] - }, - { - "name": "OracleQuoteOverrideEvent", - "discriminator": [78, 204, 191, 210, 164, 196, 244, 65] - }, - { - "name": "OracleQuoteRotateEvent", - "discriminator": [26, 189, 196, 192, 225, 127, 26, 228] - }, - { - "name": "OracleQuoteVerifyRequestEvent", - "discriminator": [203, 209, 79, 0, 20, 71, 226, 202] - }, - { - "name": "PermissionSetEvent", - "discriminator": [148, 86, 123, 0, 102, 20, 119, 206] - }, - { - "name": "PullFeedErrorValueEvent", - "discriminator": [225, 80, 192, 95, 14, 12, 83, 192] - }, - { - "name": "PullFeedValueEvents", - "discriminator": [86, 7, 231, 28, 122, 161, 117, 69] - }, - { - "name": "QueueAddMrEnclaveEvent", - "discriminator": [170, 186, 175, 38, 216, 51, 69, 175] - }, - { - "name": "QueueInitEvent", - "discriminator": [44, 137, 99, 227, 107, 8, 30, 105] - }, - { - "name": "QueueRemoveMrEnclaveEvent", - "discriminator": [4, 105, 196, 60, 84, 122, 203, 196] - }, - { - "name": "RandomnessCommitEvent", - "discriminator": [88, 60, 172, 90, 112, 10, 206, 147] - } - ], - "errors": [ - { "code": 6000, "name": "GenericError" }, - { "code": 6001, "name": "InvalidQuote" }, - { "code": 6002, "name": "InsufficientQueue" }, - { "code": 6003, "name": "QueueFull" }, - { "code": 6004, "name": "InvalidEnclaveSigner" }, - { "code": 6005, "name": "InvalidSigner" }, - { "code": 6006, "name": "MrEnclaveAlreadyExists" }, - { "code": 6007, "name": "MrEnclaveAtCapacity" }, - { "code": 6008, "name": "MrEnclaveDoesntExist" }, - { "code": 6009, "name": "PermissionDenied" }, - { "code": 6010, "name": "InvalidQueue" }, - { "code": 6011, "name": "IncorrectMrEnclave" }, - { "code": 6012, "name": "InvalidAuthority" }, - { "code": 6013, "name": "InvalidMrEnclave" }, - { "code": 6014, "name": "InvalidTimestamp" }, - { "code": 6015, "name": "InvalidOracleIdx" }, - { "code": 6016, "name": "InvalidSecpSignature" }, - { "code": 6017, "name": "InvalidGuardianQueue" }, - { "code": 6018, "name": "InvalidIndex" }, - { "code": 6019, "name": "InvalidOracleQueue" }, - { "code": 6020, "name": "InvalidPermission" }, - { "code": 6021, "name": "InvalidePermissionedAccount" }, - { "code": 6022, "name": "InvalidEpochRotate" }, - { "code": 6023, "name": "InvalidEpochFinalize" }, - { "code": 6024, "name": "InvalidEscrow" }, - { "code": 6025, "name": "IllegalOracle" }, - { "code": 6026, "name": "IllegalExecuteAttempt" }, - { "code": 6027, "name": "IllegalFeedValue" }, - { "code": 6028, "name": "InvalidOracleFeedStats" }, - { "code": 6029, "name": "InvalidStateAuthority" }, - { "code": 6030, "name": "NotEnoughSamples" }, - { "code": 6031, "name": "OracleIsVerified" }, - { "code": 6032, "name": "QueueIsEmpty" }, - { "code": 6033, "name": "SecpRecoverFailure" }, - { "code": 6034, "name": "StaleSample" }, - { "code": 6035, "name": "SwitchboardRandomnessTooOld" }, - { "code": 6036, "name": "EpochIdMismatch" }, - { "code": 6037, "name": "GuardianAlreadyVoted" }, - { "code": 6038, "name": "RandomnessNotRequested" }, - { "code": 6039, "name": "InvalidSlotNumber" }, - { "code": 6040, "name": "RandomnessOracleKeyExpired" }, - { "code": 6041, "name": "InvalidAdvisory" }, - { "code": 6042, "name": "InvalidOracleStats" }, - { "code": 6043, "name": "InvalidStakeProgram" }, - { "code": 6044, "name": "InvalidStakePool" }, - { "code": 6045, "name": "InvalidDelegationPool" }, - { "code": 6046, "name": "UnparsableAccount" }, - { "code": 6047, "name": "InvalidInstruction" }, - { "code": 6048, "name": "OracleAlreadyVerified" }, - { "code": 6049, "name": "GuardianNotVerified" }, - { "code": 6050, "name": "InvalidConstraint" }, - { "code": 6051, "name": "InvalidDelegationGroup" }, - { "code": 6052, "name": "OracleKeyNotFound" }, - { "code": 6053, "name": "GuardianReregisterAttempt" } - ], - "types": [ - { - "name": "CompactResult", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "std_dev", - "docs": [ - "The standard deviation of the submissions needed for quorom size" - ], - "type": "f32" - }, - { - "name": "mean", - "docs": ["The mean of the submissions needed for quorom size"], - "type": "f32" - }, - { - "name": "slot", - "docs": ["The slot at which this value was signed."], - "type": "u64" - } - ] - } - }, - { - "name": "CostWhitelistEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "feeds", "type": { "vec": "pubkey" } }, - { "name": "reward", "type": "u32" } - ] - } - }, - { - "name": "CurrentResult", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "value", - "docs": [ - "The median value of the submissions needed for quorom size" - ], - "type": "i128" - }, - { - "name": "std_dev", - "docs": [ - "The standard deviation of the submissions needed for quorom size" - ], - "type": "i128" - }, - { - "name": "mean", - "docs": ["The mean of the submissions needed for quorom size"], - "type": "i128" - }, - { - "name": "range", - "docs": ["The range of the submissions needed for quorom size"], - "type": "i128" - }, - { - "name": "min_value", - "docs": [ - "The minimum value of the submissions needed for quorom size" - ], - "type": "i128" - }, - { - "name": "max_value", - "docs": [ - "The maximum value of the submissions needed for quorom size" - ], - "type": "i128" - }, - { - "name": "num_samples", - "docs": ["The number of samples used to calculate this result"], - "type": "u8" - }, - { "name": "padding1", "type": { "array": ["u8", 7] } }, - { - "name": "slot", - "docs": ["The slot at which this value was signed."], - "type": "u64" - }, - { - "name": "min_slot", - "docs": [ - "The slot at which the first considered submission was made" - ], - "type": "u64" - }, - { - "name": "max_slot", - "docs": [ - "The slot at which the last considered submission was made" - ], - "type": "u64" - } - ] - } - }, - { - "name": "GarbageCollectionEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "oracle", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" } - ] - } - }, - { - "name": "GuardianQuoteVerifyEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "quote", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" } - ] - } - }, - { - "name": "GuardianQuoteVerifyParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "timestamp", "type": "i64" }, - { "name": "mr_enclave", "type": { "array": ["u8", 32] } }, - { "name": "_reserved1", "type": "u32" }, - { "name": "ed25519_key", "type": "pubkey" }, - { "name": "secp256k1_key", "type": { "array": ["u8", 64] } }, - { "name": "slot", "type": "u64" }, - { "name": "signature", "type": { "array": ["u8", 64] } }, - { "name": "recovery_id", "type": "u8" }, - { "name": "advisories", "type": { "vec": "u32" } } - ] - } - }, - { - "name": "GuardianRegisterParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "GuardianUnregisterParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "MegaSlotInfo", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "reserved1", "type": "u64" }, - { "name": "slot_end", "type": "u64" }, - { "name": "perf_goal", "type": "i64" }, - { "name": "current_signature_count", "type": "i64" } - ] - } - }, - { - "name": "MultiSubmission", - "type": { - "kind": "struct", - "fields": [ - { "name": "values", "type": { "vec": "i128" } }, - { "name": "signature", "type": { "array": ["u8", 64] } }, - { "name": "recovery_id", "type": "u8" } - ] - } - }, - { - "name": "OracleAccountData", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "enclave", - "docs": ["Represents the state of the quote verifiers enclave."], - "type": { "defined": { "name": "Quote" } } - }, - { - "name": "authority", - "docs": [ - "The authority of the EnclaveAccount which is permitted to make account changes." - ], - "type": "pubkey" - }, - { - "name": "queue", - "docs": [ - "Queue used for attestation to verify a MRENCLAVE measurement." - ], - "type": "pubkey" - }, - { - "name": "created_at", - "docs": ["The unix timestamp when the quote was created."], - "type": "i64" - }, - { - "name": "last_heartbeat", - "docs": ["The last time the quote heartbeated on-chain."], - "type": "i64" - }, - { "name": "secp_authority", "type": { "array": ["u8", 64] } }, - { - "name": "gateway_uri", - "docs": ["URI location of the verifier's gateway."], - "type": { "array": ["u8", 64] } - }, - { "name": "permissions", "type": "u64" }, - { - "name": "is_on_queue", - "docs": [ - "Whether the quote is located on the AttestationQueues buffer." - ], - "type": "u8" - }, - { "name": "_padding1", "type": { "array": ["u8", 7] } }, - { "name": "lut_slot", "type": "u64" }, - { "name": "last_reward_epoch", "type": "u64" }, - { "name": "_ebuf4", "type": { "array": ["u8", 16] } }, - { "name": "_ebuf3", "type": { "array": ["u8", 32] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 64] } }, - { "name": "_ebuf1", "type": { "array": ["u8", 1024] } } - ] - } - }, - { - "name": "OracleEpochInfo", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "id", "type": "u64" }, - { "name": "reserved1", "type": "u64" }, - { "name": "slot_end", "type": "u64" }, - { "name": "slash_score", "type": "u64" }, - { "name": "reward_score", "type": "u64" }, - { "name": "stake_score", "type": "u64" } - ] - } - }, - { - "name": "OracleHeartbeatEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "oracle", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" } - ] - } - }, - { - "name": "OracleHeartbeatParams", - "type": { - "kind": "struct", - "fields": [ - { - "name": "gateway_uri", - "type": { "option": { "array": ["u8", 64] } } - } - ] - } - }, - { - "name": "OracleInitEvent", - "type": { - "kind": "struct", - "fields": [{ "name": "oracle", "type": "pubkey" }] - } - }, - { - "name": "OracleInitParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "recent_slot", "type": "u64" }, - { "name": "authority", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" }, - { - "name": "secp_authority", - "type": { "option": { "array": ["u8", 64] } } - } - ] - } - }, - { - "name": "OracleQuoteOverrideEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "oracle", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" } - ] - } - }, - { - "name": "OracleQuoteRotateEvent", - "type": { - "kind": "struct", - "fields": [{ "name": "oracle", "type": "pubkey" }] - } - }, - { - "name": "OracleQuoteVerifyRequestEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "quote", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" } - ] - } - }, - { - "name": "OracleSetConfigsParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "new_authority", "type": { "option": "pubkey" } }, - { - "name": "new_secp_authority", - "type": { "option": { "array": ["u8", 64] } } - } - ] - } - }, - { - "name": "OracleStatsAccountData", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "owner", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" }, - { - "name": "finalized_epoch", - "docs": [ - "The last epoch that has completed. cleared after registered with the", - "staking program." - ], - "type": { "defined": { "name": "OracleEpochInfo" } } - }, - { - "name": "current_epoch", - "docs": [ - "The current epoch info being used by the oracle. for stake. Will moved", - "to finalized_epoch as soon as the epoch is over." - ], - "type": { "defined": { "name": "OracleEpochInfo" } } - }, - { - "name": "mega_slot_info", - "type": { "defined": { "name": "MegaSlotInfo" } } - }, - { "name": "last_transfer_slot", "type": "u64" }, - { "name": "bump", "type": "u8" }, - { "name": "padding1", "type": { "array": ["u8", 7] } }, - { - "name": "_ebuf", - "docs": ["Reserved."], - "type": { "array": ["u8", 1024] } - } - ] - } - }, - { - "name": "OracleSubmission", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "oracle", - "docs": ["The public key of the oracle that submitted this value."], - "type": "pubkey" - }, - { - "name": "slot", - "docs": ["The slot at which this value was signed."], - "type": "u64" - }, - { "name": "padding1", "type": { "array": ["u8", 8] } }, - { - "name": "value", - "docs": ["The value that was submitted."], - "type": "i128" - } - ] - } - }, - { - "name": "OracleUpdateDelegationParams", - "type": { - "kind": "struct", - "fields": [{ "name": "_reserved1", "type": "u64" }] - } - }, - { - "name": "PermissionSetEvent", - "type": { - "kind": "struct", - "fields": [{ "name": "permission", "type": "pubkey" }] - } - }, - { - "name": "PermissionSetParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "permission", "type": "u8" }, - { "name": "enable", "type": "bool" } - ] - } - }, - { - "name": "PullFeedAccountData", - "docs": ["A representation of the data in a pull feed account."], - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "submissions", - "docs": ["The oracle submissions for this feed."], - "type": { - "array": [{ "defined": { "name": "OracleSubmission" } }, 32] - } - }, - { - "name": "authority", - "docs": [ - "The public key of the authority that can update the feed hash that", - "this account will use for registering updates." - ], - "type": "pubkey" - }, - { - "name": "queue", - "docs": [ - "The public key of the queue which oracles must be bound to in order to", - "submit data to this feed." - ], - "type": "pubkey" - }, - { - "name": "feed_hash", - "docs": [ - "SHA-256 hash of the job schema oracles will execute to produce data", - "for this feed." - ], - "type": { "array": ["u8", 32] } - }, - { - "name": "initialized_at", - "docs": ["The slot at which this account was initialized."], - "type": "i64" - }, - { "name": "permissions", "type": "u64" }, - { "name": "max_variance", "type": "u64" }, - { "name": "min_responses", "type": "u32" }, - { "name": "name", "type": { "array": ["u8", 32] } }, - { "name": "padding1", "type": { "array": ["u8", 2] } }, - { "name": "historical_result_idx", "type": "u8" }, - { "name": "min_sample_size", "type": "u8" }, - { "name": "last_update_timestamp", "type": "i64" }, - { "name": "lut_slot", "type": "u64" }, - { "name": "_reserved1", "type": { "array": ["u8", 32] } }, - { - "name": "result", - "type": { "defined": { "name": "CurrentResult" } } - }, - { "name": "max_staleness", "type": "u32" }, - { "name": "padding2", "type": { "array": ["u8", 12] } }, - { - "name": "historical_results", - "type": { - "array": [{ "defined": { "name": "CompactResult" } }, 32] - } - }, - { "name": "_ebuf4", "type": { "array": ["u8", 8] } }, - { "name": "_ebuf3", "type": { "array": ["u8", 24] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 256] } } - ] - } - }, - { - "name": "PullFeedCloseParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "PullFeedErrorValueEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "feed", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" } - ] - } - }, - { - "name": "PullFeedInitParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "feed_hash", "type": { "array": ["u8", 32] } }, - { "name": "max_variance", "type": "u64" }, - { "name": "min_responses", "type": "u32" }, - { "name": "name", "type": { "array": ["u8", 32] } }, - { "name": "recent_slot", "type": "u64" }, - { "name": "ipfs_hash", "type": { "array": ["u8", 32] } }, - { "name": "min_sample_size", "type": "u8" }, - { "name": "max_staleness", "type": "u32" } - ] - } - }, - { - "name": "PullFeedSetConfigsParams", - "type": { - "kind": "struct", - "fields": [ - { - "name": "feed_hash", - "type": { "option": { "array": ["u8", 32] } } - }, - { "name": "authority", "type": { "option": "pubkey" } }, - { "name": "max_variance", "type": { "option": "u64" } }, - { "name": "min_responses", "type": { "option": "u32" } }, - { "name": "name", "type": { "option": { "array": ["u8", 32] } } }, - { - "name": "ipfs_hash", - "type": { "option": { "array": ["u8", 32] } } - }, - { "name": "min_sample_size", "type": { "option": "u8" } }, - { "name": "max_staleness", "type": { "option": "u32" } } - ] - } - }, - { - "name": "PullFeedSubmitResponseManyParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "slot", "type": "u64" }, - { - "name": "submissions", - "type": { "vec": { "defined": { "name": "MultiSubmission" } } } - } - ] - } - }, - { - "name": "PullFeedSubmitResponseParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "slot", "type": "u64" }, - { - "name": "submissions", - "type": { "vec": { "defined": { "name": "Submission" } } } - } - ] - } - }, - { - "name": "PullFeedValueEvents", - "type": { - "kind": "struct", - "fields": [ - { "name": "feeds", "type": { "vec": "pubkey" } }, - { "name": "oracles", "type": { "vec": "pubkey" } }, - { "name": "values", "type": { "vec": { "vec": "i128" } } }, - { "name": "reward", "type": "u32" } - ] - } - }, - { - "name": "QueueAccountData", - "docs": [ - "An Queue represents a round-robin queue of oracle oracles who attest on-chain", - "whether a Switchboard Function was executed within an enclave against an expected set of", - "enclave measurements.", - "", - "For an oracle to join the queue, the oracle must first submit their enclave quote on-chain and", - "wait for an existing oracle to attest their quote. If the oracle's quote matches an expected", - "measurement within the queues mr_enclaves config, it is granted permissions and will start", - "being assigned update requests." - ], - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "authority", - "docs": [ - "The address of the authority which is permitted to add/remove allowed enclave measurements." - ], - "type": "pubkey" - }, - { - "name": "mr_enclaves", - "docs": ["Allowed enclave measurements."], - "type": { "array": [{ "array": ["u8", 32] }, 32] } - }, - { - "name": "oracle_keys", - "docs": [ - "The addresses of the quote oracles who have a valid", - "verification status and have heartbeated on-chain recently." - ], - "type": { "array": ["pubkey", 128] } - }, - { - "name": "max_quote_verification_age", - "docs": [ - "The maximum allowable time until a EnclaveAccount needs to be re-verified on-chain." - ], - "type": "i64" - }, - { - "name": "last_heartbeat", - "docs": [ - "The unix timestamp when the last quote oracle heartbeated on-chain." - ], - "type": "i64" - }, - { "name": "node_timeout", "type": "i64" }, - { - "name": "oracle_min_stake", - "docs": [ - "The minimum number of lamports a quote oracle needs to lock-up in order to heartbeat and verify other quotes." - ], - "type": "u64" - }, - { "name": "allow_authority_override_after", "type": "i64" }, - { - "name": "mr_enclaves_len", - "docs": ["The number of allowed enclave measurements."], - "type": "u32" - }, - { - "name": "oracle_keys_len", - "docs": [ - "The length of valid quote oracles for the given attestation queue." - ], - "type": "u32" - }, - { - "name": "reward", - "docs": [ - "The reward paid to quote oracles for attesting on-chain." - ], - "type": "u32" - }, - { - "name": "curr_idx", - "docs": [ - "Incrementer used to track the current quote oracle permitted to run any available functions." - ], - "type": "u32" - }, - { - "name": "gc_idx", - "docs": [ - "Incrementer used to garbage collect and remove stale quote oracles." - ], - "type": "u32" - }, - { "name": "require_authority_heartbeat_permission", "type": "u8" }, - { "name": "require_authority_verify_permission", "type": "u8" }, - { "name": "require_usage_permissions", "type": "u8" }, - { "name": "signer_bump", "type": "u8" }, - { "name": "mint", "type": "pubkey" }, - { "name": "lut_slot", "type": "u64" }, - { "name": "allow_subsidies", "type": "u8" }, - { - "name": "_ebuf6", - "docs": ["Reserved."], - "type": { "array": ["u8", 23] } - }, - { "name": "_ebuf5", "type": { "array": ["u8", 32] } }, - { "name": "_ebuf4", "type": { "array": ["u8", 64] } }, - { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 256] } }, - { "name": "_ebuf1", "type": { "array": ["u8", 512] } } - ] - } - }, - { - "name": "QueueAddMrEnclaveEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "queue", "type": "pubkey" }, - { "name": "mr_enclave", "type": { "array": ["u8", 32] } } - ] - } - }, - { - "name": "QueueAddMrEnclaveParams", - "type": { - "kind": "struct", - "fields": [{ "name": "mr_enclave", "type": { "array": ["u8", 32] } }] - } - }, - { - "name": "QueueAllowSubsidiesParams", - "type": { - "kind": "struct", - "fields": [{ "name": "allow_subsidies", "type": "u8" }] - } - }, - { - "name": "QueueGarbageCollectParams", - "type": { "kind": "struct", "fields": [{ "name": "idx", "type": "u32" }] } - }, - { - "name": "QueueInitDelegationGroupParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "QueueInitEvent", - "type": { - "kind": "struct", - "fields": [{ "name": "queue", "type": "pubkey" }] - } - }, - { - "name": "QueueInitParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "allow_authority_override_after", "type": "u32" }, - { "name": "require_authority_heartbeat_permission", "type": "bool" }, - { "name": "require_usage_permissions", "type": "bool" }, - { "name": "max_quote_verification_age", "type": "u32" }, - { "name": "reward", "type": "u32" }, - { "name": "node_timeout", "type": "u32" }, - { "name": "recent_slot", "type": "u64" } - ] - } - }, - { - "name": "QueueRemoveMrEnclaveEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "queue", "type": "pubkey" }, - { "name": "mr_enclave", "type": { "array": ["u8", 32] } } - ] - } - }, - { - "name": "QueueRemoveMrEnclaveParams", - "type": { - "kind": "struct", - "fields": [{ "name": "mr_enclave", "type": { "array": ["u8", 32] } }] - } - }, - { - "name": "QueueSetConfigsParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "authority", "type": { "option": "pubkey" } }, - { "name": "reward", "type": { "option": "u32" } }, - { "name": "node_timeout", "type": { "option": "i64" } } - ] - } - }, - { - "name": "Quote", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "enclave_signer", - "docs": ["The address of the signer generated within an enclave."], - "type": "pubkey" - }, - { - "name": "mr_enclave", - "docs": [ - "The quotes MRENCLAVE measurement dictating the contents of the secure enclave." - ], - "type": { "array": ["u8", 32] } - }, - { - "name": "verification_status", - "docs": ["The VerificationStatus of the quote."], - "type": "u8" - }, - { "name": "padding1", "type": { "array": ["u8", 7] } }, - { - "name": "verification_timestamp", - "docs": ["The unix timestamp when the quote was last verified."], - "type": "i64" - }, - { - "name": "valid_until", - "docs": [ - "The unix timestamp when the quotes verification status expires." - ], - "type": "i64" - }, - { - "name": "quote_registry", - "docs": [ - "The off-chain registry where the verifiers quote can be located." - ], - "type": { "array": ["u8", 32] } - }, - { - "name": "registry_key", - "docs": [ - "Key to lookup the buffer data on IPFS or an alternative decentralized storage solution." - ], - "type": { "array": ["u8", 64] } - }, - { - "name": "secp256k1_signer", - "docs": [ - "The secp256k1 public key of the enclave signer. Derived from the enclave_signer." - ], - "type": { "array": ["u8", 64] } - }, - { "name": "last_ed25519_signer", "type": "pubkey" }, - { "name": "last_secp256k1_signer", "type": { "array": ["u8", 64] } }, - { "name": "last_rotate_slot", "type": "u64" }, - { "name": "guardian_approvers", "type": { "array": ["pubkey", 64] } }, - { "name": "guardian_approvers_len", "type": "u8" }, - { "name": "padding2", "type": { "array": ["u8", 7] } }, - { "name": "staging_ed25519_signer", "type": "pubkey" }, - { - "name": "staging_secp256k1_signer", - "type": { "array": ["u8", 64] } - }, - { - "name": "_ebuf4", - "docs": ["Reserved."], - "type": { "array": ["u8", 32] } - }, - { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 256] } }, - { "name": "_ebuf1", "type": { "array": ["u8", 512] } } - ] - } - }, - { - "name": "RandomnessAccountData", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "authority", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" }, - { "name": "seed_slothash", "type": { "array": ["u8", 32] } }, - { "name": "seed_slot", "type": "u64" }, - { "name": "oracle", "type": "pubkey" }, - { "name": "reveal_slot", "type": "u64" }, - { "name": "value", "type": { "array": ["u8", 32] } }, - { "name": "lut_slot", "type": "u64" }, - { "name": "_ebuf3", "type": { "array": ["u8", 24] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 64] } }, - { "name": "_ebuf1", "type": { "array": ["u8", 128] } }, - { - "name": "active_secp256k1_signer", - "type": { "array": ["u8", 64] } - }, - { "name": "active_secp256k1_expiration", "type": "i64" } - ] - } - }, - { - "name": "RandomnessCommitEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "randomness_account", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" }, - { "name": "slot", "type": "u64" }, - { "name": "slothash", "type": { "array": ["u8", 32] } } - ] - } - }, - { - "name": "RandomnessCommitParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "RandomnessInitParams", - "type": { - "kind": "struct", - "fields": [{ "name": "recent_slot", "type": "u64" }] - } - }, - { - "name": "RandomnessRevealParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "signature", "type": { "array": ["u8", 64] } }, - { "name": "recovery_id", "type": "u8" }, - { "name": "value", "type": { "array": ["u8", 32] } } - ] - } - }, - { - "name": "State", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "bump", "type": "u8" }, - { "name": "test_only_disable_mr_enclave_check", "type": "u8" }, - { "name": "enable_staking", "type": "u8" }, - { "name": "padding1", "type": { "array": ["u8", 5] } }, - { "name": "authority", "type": "pubkey" }, - { "name": "guardian_queue", "type": "pubkey" }, - { "name": "reserved1", "type": "u64" }, - { "name": "epoch_length", "type": "u64" }, - { - "name": "current_epoch", - "type": { "defined": { "name": "StateEpochInfo" } } - }, - { - "name": "next_epoch", - "type": { "defined": { "name": "StateEpochInfo" } } - }, - { - "name": "finalized_epoch", - "type": { "defined": { "name": "StateEpochInfo" } } - }, - { "name": "stake_pool", "type": "pubkey" }, - { "name": "stake_program", "type": "pubkey" }, - { "name": "switch_mint", "type": "pubkey" }, - { "name": "sgx_advisories", "type": { "array": ["u16", 32] } }, - { "name": "advisories_len", "type": "u8" }, - { "name": "padding2", "type": "u8" }, - { "name": "flat_reward_cut_percentage", "type": "u8" }, - { "name": "enable_slashing", "type": "u8" }, - { "name": "subsidy_amount", "type": "u32" }, - { "name": "lut_slot", "type": "u64" }, - { "name": "base_reward", "type": "u32" }, - { "name": "_ebuf6", "type": { "array": ["u8", 28] } }, - { "name": "_ebuf5", "type": { "array": ["u8", 32] } }, - { "name": "_ebuf4", "type": { "array": ["u8", 64] } }, - { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 512] } }, - { - "name": "cost_whitelist", - "docs": ["Cost whitelist by authority"], - "type": { "array": ["pubkey", 32] } - } - ] - } - }, - { - "name": "StateEpochInfo", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "id", "type": "u64" }, - { "name": "_reserved1", "type": "u64" }, - { "name": "slot_end", "type": "u64" } - ] - } - }, - { "name": "StateInitParams", "type": { "kind": "struct", "fields": [] } }, - { - "name": "StateSetConfigsParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "new_authority", "type": "pubkey" }, - { "name": "test_only_disable_mr_enclave_check", "type": "u8" }, - { "name": "stake_pool", "type": "pubkey" }, - { "name": "stake_program", "type": "pubkey" }, - { "name": "add_advisory", "type": "u16" }, - { "name": "rm_advisory", "type": "u16" }, - { "name": "epoch_length", "type": "u32" }, - { "name": "reset_epochs", "type": "bool" }, - { "name": "switch_mint", "type": "pubkey" }, - { "name": "enable_staking", "type": "u8" }, - { "name": "subsidy_amount", "type": "u32" }, - { "name": "base_reward", "type": "u32" }, - { "name": "add_cost_wl", "type": "pubkey" }, - { "name": "rm_cost_wl", "type": "pubkey" } - ] - } - }, - { - "name": "Submission", - "type": { - "kind": "struct", - "fields": [ - { "name": "value", "type": "i128" }, - { "name": "signature", "type": { "array": ["u8", 64] } }, - { "name": "recovery_id", "type": "u8" }, - { "name": "offset", "type": "u8" } - ] - } - } - ] -} diff --git a/solauto-sdk/src/utils/switchboardUtils.ts b/solauto-sdk/src/utils/switchboardUtils.ts index 7f635d6f..a29ed0a5 100644 --- a/solauto-sdk/src/utils/switchboardUtils.ts +++ b/solauto-sdk/src/utils/switchboardUtils.ts @@ -6,10 +6,9 @@ import { } from "@solana/web3.js"; import { Signer, transactionBuilder } from "@metaplex-foundation/umi"; import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; -import { AnchorProvider, Idl, Program } from "@coral-xyz/anchor"; +import { AnchorProvider, Program } from "@coral-xyz/anchor"; import * as OnDemand from "@switchboard-xyz/on-demand"; import Big from "big.js"; -import switchboardIdl from "../idls/switchboard.json"; import { PRICES, SWITCHBOARD_PRICE_FEED_IDS } from "../constants"; import { TransactionItemInputs } from "../types"; import { @@ -18,7 +17,7 @@ import { } from "./generalUtils"; import { getWrappedInstruction } from "./solanaUtils"; -export function getPullFeed( +export async function getPullFeed( conn: Connection, mint: PublicKey, wallet?: PublicKey @@ -37,11 +36,12 @@ export function getPullFeed( dummyWallet, AnchorProvider.defaultOptions() ); - const program = new Program(switchboardIdl as Idl, provider); + const { PullFeed, ON_DEMAND_MAINNET_PID } = OnDemand; + const sbProgram = await Program.at(ON_DEMAND_MAINNET_PID, provider); - const { PullFeed } = OnDemand; + console.log(new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId).toString()) return new PullFeed( - program, + sbProgram, new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId) ); } @@ -51,12 +51,18 @@ export async function buildSwbSubmitResponseTx( signer: Signer, mint: PublicKey ): Promise { - const feed = getPullFeed(conn, mint, toWeb3JsPublicKey(signer.publicKey)); - const [pullIx, responses] = await retryWithExponentialBackoff( + const feed = await getPullFeed( + conn, + mint, + toWeb3JsPublicKey(signer.publicKey) + ); + const gateway = await feed.fetchGatewayUrl(); + const [pullIxs, responses] = await retryWithExponentialBackoff( async () => { const res = await feed.fetchUpdateIx({ + gateway: gateway, chain: "solana", - network: "mainnet-beta", + network: "mainnet", }); if (!res[1] || !res[1][0].value) { throw new Error("Unable to fetch Switchboard pull IX"); @@ -67,7 +73,7 @@ export async function buildSwbSubmitResponseTx( 200 ); - if (!pullIx) { + if (!pullIxs || !pullIxs.length) { throw new Error("Unable to fetch SWB crank IX"); } @@ -81,7 +87,9 @@ export async function buildSwbSubmitResponseTx( }; return { - tx: transactionBuilder([getWrappedInstruction(signer, pullIx!)]), + tx: transactionBuilder( + pullIxs.map((x) => getWrappedInstruction(signer, x)) + ), lookupTableAddresses: responses .filter((x) => Boolean(x.oracle.lut?.key)) .map((x) => x.oracle.lut!.key.toString()), @@ -103,7 +111,7 @@ export async function getSwitchboardFeedData( const results = await Promise.all( mints.map(async (mint) => { - const feed = getPullFeed(conn, mint); + const feed = await getPullFeed(conn, mint); const result = await feed.loadData(); const price = Number(result.result.value) / Math.pow(10, 18); const stale = From 65f71d98f9b7690a1e4f292711da72fdf34c0cd6 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Fri, 11 Jul 2025 12:55:26 -0400 Subject: [PATCH 63/88] Revert "Revert "Revert "bump versions""" This reverts commit 46dfe2432ed64642431ae47f44086d2ba03f958e. --- pnpm-lock.yaml | 217 ++- solauto-sdk/package.json | 10 +- solauto-sdk/pnpm-lock.yaml | 480 +++-- solauto-sdk/src/idls/switchboard.json | 1949 +++++++++++++++++++++ solauto-sdk/src/utils/switchboardUtils.ts | 32 +- 5 files changed, 2400 insertions(+), 288 deletions(-) create mode 100644 solauto-sdk/src/idls/switchboard.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 312f22c7..4a9acb1a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,6 +34,12 @@ packages: dependencies: regenerator-runtime: 0.14.1 + /@brokerloop/ttlcache@3.2.3: + resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} + dependencies: + '@soncodi/signal': 2.0.7 + dev: true + /@common.js/quick-lru@7.0.0: resolution: {integrity: sha512-DO3vApnH1vLizdWRSqzhg+S956vptHhtO+vw6PP6StJGDtaAGyfKSSPPGYWguJZu/Jlti6l6m6jB8NrKEQexLg==} engines: {node: '>=18'} @@ -131,11 +137,6 @@ packages: yargs: 17.7.2 dev: false - /@isaacs/ttlcache@1.4.1: - resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} - engines: {node: '>=12'} - dev: true - /@js-sdsl/ordered-map@4.4.2: resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} dev: false @@ -525,16 +526,6 @@ packages: typescript: 4.9.5 dev: true - /@solana/codecs-core@2.1.1(typescript@4.9.5): - resolution: {integrity: sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' - dependencies: - '@solana/errors': 2.1.1(typescript@4.9.5) - typescript: 4.9.5 - dev: true - /@solana/codecs-data-structures@2.0.0-preview.4(typescript@4.9.5): resolution: {integrity: sha512-nt2k2eTeyzlI/ccutPcG36M/J8NAYfxBPI9h/nQjgJ+M+IgOKi31JV8StDDlG/1XvY0zyqugV3I0r3KAbZRJpA==} peerDependencies: @@ -584,17 +575,6 @@ packages: typescript: 4.9.5 dev: true - /@solana/codecs-numbers@2.1.1(typescript@4.9.5): - resolution: {integrity: sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ==} - engines: {node: '>=20.18.0'} - peerDependencies: - typescript: '>=5.3.3' - dependencies: - '@solana/codecs-core': 2.1.1(typescript@4.9.5) - '@solana/errors': 2.1.1(typescript@4.9.5) - typescript: 4.9.5 - dev: true - /@solana/codecs-strings@2.0.0-preview.1(fastestsmallesttextencoderdecoder@1.0.22): resolution: {integrity: sha512-kBAxE9ZD5/c8j9CkPxqc55dbo7R50Re3k94SXR+k13DZCCs37Fyn0/mAkw/S95fofbi/zsi4jSfmsT5vCZD75A==} peerDependencies: @@ -692,18 +672,6 @@ packages: typescript: 4.9.5 dev: true - /@solana/errors@2.1.1(typescript@4.9.5): - resolution: {integrity: sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw==} - engines: {node: '>=20.18.0'} - hasBin: true - peerDependencies: - typescript: '>=5.3.3' - dependencies: - chalk: 5.4.1 - commander: 13.1.0 - typescript: 4.9.5 - dev: true - /@solana/options@2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-tv2O/Frxql/wSe3jbzi5nVicIWIus/BftH+5ZR+r9r3FO0/htEllZS5Q9XdbmSboHu+St87584JXeDx3xm4jaA==} peerDependencies: @@ -811,6 +779,25 @@ packages: - utf-8-validate dev: true + /@solana/spl-token@0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.88.0 + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/buffer-layout-utils': 0.2.0 + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8 + buffer: 6.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + dev: true + /@solana/spl-token@0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-RO0JD9vPRi4LsAbMUdNbDJ5/cv2z11MGhtAvFeRzT4+hAGE/FUzRi0tkkWtuCfSIU3twC6CtmAihRp/+XXjWsA==} engines: {node: '>=16'} @@ -977,31 +964,29 @@ packages: - encoding - utf-8-validate - /@solana/web3.js@1.98.2(typescript@4.9.5): - resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} + /@solworks/soltoolkit-sdk@0.0.23(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} dependencies: - '@babel/runtime': 7.25.7 - '@noble/curves': 1.6.0 - '@noble/hashes': 1.5.0 '@solana/buffer-layout': 4.0.1 - '@solana/codecs-numbers': 2.1.1(typescript@4.9.5) - agentkeepalive: 4.5.0 + '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8 + '@types/bn.js': 5.1.6 + '@types/node': 18.19.67 + '@types/node-fetch': 2.6.12 bn.js: 5.2.1 - borsh: 0.7.0 - bs58: 4.0.1 - buffer: 6.0.3 - fast-stable-stringify: 1.0.0 - jayson: 4.1.2 - node-fetch: 2.7.0 - rpc-websockets: 9.0.4 - superstruct: 2.0.2 + decimal.js: 10.4.3 + typescript: 4.9.5 transitivePeerDependencies: - bufferutil - encoding - - typescript + - fastestsmallesttextencoderdecoder - utf-8-validate dev: true + /@soncodi/signal@2.0.7: + resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} + dev: true + /@sqds/multisig@2.1.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {integrity: sha512-WOiL7La+RSiJsz7jVO85yhSiiSvNMUthiWuLPeWVOoD6IYa34BEAzanF1RdXRWGglSbRFYCTkyr+Ay1WmXmSRQ==} engines: {node: '>=14'} @@ -1030,6 +1015,28 @@ packages: dependencies: tslib: 2.7.0 + /@switchboard-xyz/common@2.5.5: + resolution: {integrity: sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w==} + engines: {node: '>=12'} + dependencies: + '@solana/web3.js': 1.95.8 + axios: 1.7.8 + big.js: 6.2.2 + bn.js: 5.2.1 + bs58: 5.0.0 + cron-validator: 1.3.1 + decimal.js: 10.4.3 + js-sha256: 0.11.0 + lodash: 4.17.21 + protobufjs: 7.4.0 + yaml: 2.6.1 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - utf-8-validate + dev: true + /@switchboard-xyz/common@3.0.12: resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} engines: {node: '>=20'} @@ -1072,26 +1079,25 @@ packages: - utf-8-validate dev: false - /@switchboard-xyz/common@3.4.1(typescript@4.9.5): - resolution: {integrity: sha512-TropBlBYuDeBnmGHkPSmgC3clLqAxy51ZGbwk4ejAgadnszWOgYHcH7taRG4Ha17DYSCWw/LGMBKbunGo+Aoaw==} - engines: {node: '>=20'} + /@switchboard-xyz/on-demand@1.2.51(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} + engines: {node: '>= 18'} dependencies: - '@solana/web3.js': 1.98.2(typescript@4.9.5) - axios: 1.10.0 + '@brokerloop/ttlcache': 3.2.3 + '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 + '@solana/web3.js': 1.95.8 + '@solworks/soltoolkit-sdk': 0.0.23(fastestsmallesttextencoderdecoder@1.0.22) + '@switchboard-xyz/common': 2.5.5 + axios: 1.7.8 big.js: 6.2.2 - bn.js: 5.2.1 - bs58: 6.0.0 - buffer: 6.0.3 - decimal.js: 10.4.3 - js-sha256: 0.11.0 + bs58: 5.0.0 + js-yaml: 4.1.0 protobufjs: 7.4.0 - yaml: 2.6.1 - zod: 4.0.0-beta.20250505T195954 transitivePeerDependencies: - bufferutil - debug - encoding - - typescript + - fastestsmallesttextencoderdecoder - utf-8-validate dev: true @@ -1114,25 +1120,6 @@ packages: - utf-8-validate dev: false - /@switchboard-xyz/on-demand@2.8.1(typescript@4.9.5): - resolution: {integrity: sha512-MqUXMuqmYfhjMdFIAyFOvCYr1BeacmA3ZY6Eu2RkHJLG1X3NAKdCHR2Bj13UU/H9P7HrKhse29Sn7QdbSeEp/w==} - engines: {node: '>= 18'} - dependencies: - '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 - '@isaacs/ttlcache': 1.4.1 - '@switchboard-xyz/common': 3.4.1(typescript@4.9.5) - axios: 1.10.0 - bs58: 6.0.0 - buffer: 6.0.3 - js-yaml: 4.1.0 - transitivePeerDependencies: - - bufferutil - - debug - - encoding - - typescript - - utf-8-validate - dev: true - /@types/bn.js@5.1.6: resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} dependencies: @@ -1144,9 +1131,22 @@ packages: dependencies: '@types/node': 20.16.11 + /@types/node-fetch@2.6.12: + resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + dependencies: + '@types/node': 20.16.11 + form-data: 4.0.1 + dev: true + /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + /@types/node@18.19.67: + resolution: {integrity: sha512-wI8uHusga+0ZugNp0Ol/3BqQfEcCCNfojtO6Oou9iVNGPTL6QNSdnUdqq85fRgIorLhLMuPIKpsN98QE9Nh+KQ==} + dependencies: + undici-types: 5.26.5 + dev: true + /@types/node@20.16.11: resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} dependencies: @@ -1177,10 +1177,6 @@ packages: '@wallet-standard/base': 1.1.0 dev: false - /@zod/core@0.11.6: - resolution: {integrity: sha512-03Bv82fFSfjDAvMfdHHdGSS6SOJs0iCcJlWJv1kJHRtoTT02hZpyip/2Lk6oo4l4FtjuwTrsEQTwg/LD8I7dJA==} - dev: true - /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -1241,16 +1237,6 @@ packages: possible-typed-array-names: 1.0.0 dev: true - /axios@1.10.0: - resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} - dependencies: - follow-redirects: 1.15.9 - form-data: 4.0.1 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - dev: true - /axios@1.7.8: resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} dependencies: @@ -1373,11 +1359,6 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - /chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: true - /cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -1408,11 +1389,6 @@ packages: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} - /commander@13.1.0: - resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} - engines: {node: '>=18'} - dev: true - /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -1421,6 +1397,10 @@ packages: engines: {node: '>= 6'} dev: false + /cron-validator@1.3.1: + resolution: {integrity: sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==} + dev: true + /cross-fetch@3.1.8: resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} dependencies: @@ -1768,6 +1748,10 @@ packages: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} dev: false + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + /long@5.2.3: resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} @@ -2011,6 +1995,10 @@ packages: hasBin: true dev: true + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + /undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -2119,12 +2107,6 @@ packages: yargs-parser: 21.1.1 dev: false - /zod@4.0.0-beta.20250505T195954: - resolution: {integrity: sha512-iB8WvxkobVIXMARvQu20fKvbS7mUTiYRpcD8OQV1xjRhxO0EEpYIRJBk6yfBzHAHEdOSDh3SxDITr5Eajr2vtg==} - dependencies: - '@zod/core': 0.11.6 - dev: true - file:solauto-sdk(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): resolution: {directory: solauto-sdk, type: directory} id: file:solauto-sdk @@ -2140,10 +2122,9 @@ packages: '@solana/web3.js': 1.95.8 '@sqds/multisig': 2.1.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) '@switchboard-xyz/common': 3.0.12 - '@switchboard-xyz/on-demand': 2.8.1(typescript@4.9.5) + '@switchboard-xyz/on-demand': 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) '@types/node': 20.16.11 axios: 1.7.8 - big.js: 6.2.2 bs58: 5.0.0 cross-fetch: 4.0.0 dotenv: 16.4.7 diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 75d71aa4..7093eb24 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.784", + "version": "1.0.782", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", @@ -12,16 +12,16 @@ "test:unit": "ts-mocha -p ./tsconfig.json -t 1000000 tests/unit/**/*.ts" }, "dependencies": { - "@coral-xyz/anchor": "=0.31.1", + "@coral-xyz/anchor": "^0.30.1", "@jup-ag/api": "=6.0.24", "@metaplex-foundation/umi": "^0.9.1", "@metaplex-foundation/umi-bundle-defaults": "^0.9.1", "@metaplex-foundation/umi-signer-wallet-adapters": "^0.9.1", "@metaplex-foundation/umi-web3js-adapters": "^0.9.1", "@solana/spl-token": "^0.4.0", - "@solana/web3.js": "=1.98.2", - "@switchboard-xyz/common": "=3.4.1", - "@switchboard-xyz/on-demand": "=2.11.0", + "@solana/web3.js": "=1.95.8", + "@switchboard-xyz/common": "=3.0.12", + "@switchboard-xyz/on-demand": "=1.2.51", "axios": "^1.7.8", "big.js": "^6.2.2", "bs58": "^5.0.0", diff --git a/solauto-sdk/pnpm-lock.yaml b/solauto-sdk/pnpm-lock.yaml index 4d59ae42..5003c773 100644 --- a/solauto-sdk/pnpm-lock.yaml +++ b/solauto-sdk/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: '@coral-xyz/anchor': - specifier: '=0.31.1' - version: 0.31.1(typescript@5.6.3) + specifier: ^0.30.1 + version: 0.30.1 '@jup-ag/api': specifier: '=6.0.24' version: 6.0.24 @@ -16,25 +16,25 @@ dependencies: version: 0.9.2 '@metaplex-foundation/umi-bundle-defaults': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-signer-wallet-adapters': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-web3js-adapters': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@solana/spl-token': specifier: ^0.4.0 - version: 0.4.8(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + version: 0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/web3.js': - specifier: '=1.98.2' - version: 1.98.2(typescript@5.6.3) + specifier: '=1.95.8' + version: 1.95.8 '@switchboard-xyz/common': - specifier: '=3.4.1' - version: 3.4.1(typescript@5.6.3) + specifier: '=3.0.12' + version: 3.0.12 '@switchboard-xyz/on-demand': - specifier: '=2.11.0' - version: 2.11.0(typescript@5.6.3) + specifier: '=1.2.51' + version: 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) axios: specifier: ^1.7.8 version: 1.7.8 @@ -89,56 +89,58 @@ packages: regenerator-runtime: 0.14.1 dev: false - /@coral-xyz/anchor-errors@0.31.1: - resolution: {integrity: sha512-NhNEku4F3zzUSBtrYz84FzYWm48+9OvmT1Hhnwr6GnPQry2dsEqH/ti/7ASjjpoFTWRnPXrjAIT1qM6Isop+LQ==} + /@brokerloop/ttlcache@3.2.3: + resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} + dependencies: + '@soncodi/signal': 2.0.7 + dev: false + + /@coral-xyz/anchor-errors@0.30.1: + resolution: {integrity: sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==} engines: {node: '>=10'} dev: false - /@coral-xyz/anchor@0.31.1(typescript@5.6.3): - resolution: {integrity: sha512-QUqpoEK+gi2S6nlYc2atgT2r41TT3caWr/cPUEL8n8Md9437trZ68STknq897b82p5mW0XrTBNOzRbmIRJtfsA==} - engines: {node: '>=17'} + /@coral-xyz/anchor@0.30.1: + resolution: {integrity: sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==} + engines: {node: '>=11'} dependencies: - '@coral-xyz/anchor-errors': 0.31.1 - '@coral-xyz/borsh': 0.31.1(@solana/web3.js@1.98.2) + '@coral-xyz/anchor-errors': 0.30.1 + '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.8) '@noble/hashes': 1.5.0 - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 bn.js: 5.2.1 bs58: 4.0.1 buffer-layout: 1.2.2 camelcase: 6.3.0 cross-fetch: 3.1.8 + crypto-hash: 1.3.0 eventemitter3: 4.0.7 pako: 2.1.0 + snake-case: 3.0.4 superstruct: 0.15.5 toml: 3.0.0 transitivePeerDependencies: - bufferutil - encoding - - typescript - utf-8-validate dev: false - /@coral-xyz/borsh@0.31.1(@solana/web3.js@1.98.2): - resolution: {integrity: sha512-9N8AU9F0ubriKfNE3g1WF0/4dtlGXoBN/hd1PvbNBamBNwRgHxH4P+o3Zt7rSEloW1HUs6LfZEchlx9fW7POYw==} + /@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} engines: {node: '>=10'} peerDependencies: - '@solana/web3.js': ^1.69.0 + '@solana/web3.js': ^1.68.0 dependencies: - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 bn.js: 5.2.1 buffer-layout: 1.2.2 dev: false - /@isaacs/ttlcache@1.4.1: - resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} - engines: {node: '>=12'} - dev: false - /@jup-ag/api@6.0.24: resolution: {integrity: sha512-zIX4WIPb0Kb2UnK2wNIOQBWqPJyMJq/D9dQTf/2qvPb0hfa8XdgbrQAzomHMHnAzw9StMQoybBk+JK/A76xP3w==} dev: false - /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): + /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-kV3tfvgvRjVP1p9OFOtH+ibOtN9omVJSwKr0We4/9r45e5LTj+32su0V/rixZUkG1EZzzOYBsxhtIE0kIw/Hrw==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 @@ -146,14 +148,14 @@ packages: dependencies: '@metaplex-foundation/umi': 0.9.2 '@metaplex-foundation/umi-downloader-http': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-http-fetch': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-program-repository': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-rpc-chunk-get-accounts': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@metaplex-foundation/umi-serializer-data-view': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 transitivePeerDependencies: - encoding dev: false @@ -166,16 +168,16 @@ packages: '@metaplex-foundation/umi': 0.9.2 dev: false - /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): + /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-hhPCxXbYIp4BC4z9gK78sXpWLkNSrfv4ndhF5ruAkdIp7GcRVYKj0QnOUO6lGYGiIkNlw20yoTwOe1CT//OfTQ==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) '@noble/curves': 1.6.0 - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 dev: false /@metaplex-foundation/umi-http-fetch@0.9.2(@metaplex-foundation/umi@0.9.2): @@ -215,15 +217,15 @@ packages: '@metaplex-foundation/umi': 0.9.2 dev: false - /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): + /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-MqcsBz8B4wGl6jxsf2Jo/rAEpYReU9VCSR15QSjhvADHMmdFxCIZCCAgE+gDE2Vuanfl437VhOcP3g5Uw8C16Q==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 dev: false /@metaplex-foundation/umi-serializer-data-view@0.9.2(@metaplex-foundation/umi@0.9.2): @@ -260,36 +262,36 @@ packages: '@metaplex-foundation/umi-serializers-numbers': 0.8.9 dev: false - /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): + /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-DFG0ZFocKG8briypSkG9bGUTVsWpAgYugsl2BzTygkGExc4evWfF4Sb1F2C2w9FdrA9ESZM1gpLX9xtx5taOXg==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 dev: false - /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): + /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-fR1Kf21uylMFd1Smkltmj4jTNxhqSWf416owsJ+T+cvJi2VCOcOwq/3UFzOrpz78fA0RhsajKYKj0HYsRnQI1g==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2) - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8 dev: false - /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2): + /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): resolution: {integrity: sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 dependencies: '@metaplex-foundation/umi': 0.9.2 - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 buffer: 6.0.3 dev: false @@ -356,18 +358,17 @@ packages: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} dev: false - /@solana/buffer-layout-utils@0.2.0(typescript@5.6.3): + /@solana/buffer-layout-utils@0.2.0: resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} engines: {node: '>= 10'} dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 bigint-buffer: 1.1.5 bignumber.js: 9.1.2 transitivePeerDependencies: - bufferutil - encoding - - typescript - utf-8-validate dev: false @@ -387,22 +388,21 @@ packages: typescript: 5.6.3 dev: false - /@solana/codecs-core@2.0.0-rc.1(typescript@5.6.3): + /@solana/codecs-core@2.0.0-rc.1(typescript@4.9.5): resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} peerDependencies: typescript: '>=5' dependencies: - '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) - typescript: 5.6.3 + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 dev: false - /@solana/codecs-core@2.1.1(typescript@5.6.3): - resolution: {integrity: sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg==} - engines: {node: '>=20.18.0'} + /@solana/codecs-core@2.0.0-rc.1(typescript@5.6.3): + resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} peerDependencies: - typescript: '>=5.3.3' + typescript: '>=5' dependencies: - '@solana/errors': 2.1.1(typescript@5.6.3) + '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) typescript: 5.6.3 dev: false @@ -417,6 +417,17 @@ packages: typescript: 5.6.3 dev: false + /@solana/codecs-data-structures@2.0.0-rc.1(typescript@4.9.5): + resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} + peerDependencies: + typescript: '>=5' + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 + dev: false + /@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.6.3): resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} peerDependencies: @@ -438,24 +449,23 @@ packages: typescript: 5.6.3 dev: false - /@solana/codecs-numbers@2.0.0-rc.1(typescript@5.6.3): + /@solana/codecs-numbers@2.0.0-rc.1(typescript@4.9.5): resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} peerDependencies: typescript: '>=5' dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.6.3) - '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) - typescript: 5.6.3 + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 dev: false - /@solana/codecs-numbers@2.1.1(typescript@5.6.3): - resolution: {integrity: sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ==} - engines: {node: '>=20.18.0'} + /@solana/codecs-numbers@2.0.0-rc.1(typescript@5.6.3): + resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} peerDependencies: - typescript: '>=5.3.3' + typescript: '>=5' dependencies: - '@solana/codecs-core': 2.1.1(typescript@5.6.3) - '@solana/errors': 2.1.1(typescript@5.6.3) + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.6.3) + '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) typescript: 5.6.3 dev: false @@ -472,6 +482,19 @@ packages: typescript: 5.6.3 dev: false + /@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5' + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + fastestsmallesttextencoderdecoder: 1.0.22 + typescript: 4.9.5 + dev: false + /@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} peerDependencies: @@ -500,6 +523,21 @@ packages: - fastestsmallesttextencoderdecoder dev: false + /@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} + peerDependencies: + typescript: '>=5' + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + dev: false + /@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} peerDependencies: @@ -526,7 +564,7 @@ packages: typescript: 5.6.3 dev: false - /@solana/errors@2.0.0-rc.1(typescript@5.6.3): + /@solana/errors@2.0.0-rc.1(typescript@4.9.5): resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} hasBin: true peerDependencies: @@ -534,18 +572,17 @@ packages: dependencies: chalk: 5.3.0 commander: 12.1.0 - typescript: 5.6.3 + typescript: 4.9.5 dev: false - /@solana/errors@2.1.1(typescript@5.6.3): - resolution: {integrity: sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw==} - engines: {node: '>=20.18.0'} + /@solana/errors@2.0.0-rc.1(typescript@5.6.3): + resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} hasBin: true peerDependencies: - typescript: '>=5.3.3' + typescript: '>=5' dependencies: - chalk: 5.4.1 - commander: 13.1.0 + chalk: 5.3.0 + commander: 12.1.0 typescript: 5.6.3 dev: false @@ -564,6 +601,21 @@ packages: - fastestsmallesttextencoderdecoder dev: false + /@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} + peerDependencies: + typescript: '>=5' + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + dev: false + /@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} peerDependencies: @@ -579,7 +631,7 @@ packages: - fastestsmallesttextencoderdecoder dev: false - /@solana/spl-token-group@0.0.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token-group@0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-CLJnWEcdoUBpQJfx9WEbX3h6nTdNiUzswfFdkABUik7HVwSNA98u5AYvBVK2H93d9PGMOHAak2lHW9xr+zAJGQ==} engines: {node: '>=16'} peerDependencies: @@ -587,13 +639,13 @@ packages: dependencies: '@solana/codecs': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript dev: false - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} engines: {node: '>=16'} peerDependencies: @@ -601,23 +653,56 @@ packages: dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/web3.js': 1.95.8 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript dev: false - /@solana/spl-token@0.4.8(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): + /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.3 + dependencies: + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/spl-type-length-value': 0.1.0 + '@solana/web3.js': 1.98.0 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - typescript + dev: false + + /@solana/spl-token@0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): + resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.88.0 + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/buffer-layout-utils': 0.2.0 + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.98.0 + buffer: 6.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + dev: false + + /@solana/spl-token@0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): resolution: {integrity: sha512-RO0JD9vPRi4LsAbMUdNbDJ5/cv2z11MGhtAvFeRzT4+hAGE/FUzRi0tkkWtuCfSIU3twC6CtmAihRp/+XXjWsA==} engines: {node: '>=16'} peerDependencies: '@solana/web3.js': ^1.94.0 dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0(typescript@5.6.3) - '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.98.2)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/web3.js': 1.98.2(typescript@5.6.3) + '@solana/buffer-layout-utils': 0.2.0 + '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) + '@solana/web3.js': 1.95.8 buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -634,15 +719,15 @@ packages: buffer: 6.0.3 dev: false - /@solana/web3.js@1.98.2(typescript@5.6.3): - resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} + /@solana/web3.js@1.95.8: + resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} dependencies: '@babel/runtime': 7.25.7 '@noble/curves': 1.6.0 '@noble/hashes': 1.5.0 '@solana/buffer-layout': 4.0.1 - '@solana/codecs-numbers': 2.1.1(typescript@5.6.3) agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 bn.js: 5.2.1 borsh: 0.7.0 bs58: 4.0.1 @@ -655,22 +740,90 @@ packages: transitivePeerDependencies: - bufferutil - encoding - - typescript - utf-8-validate dev: false + /@solana/web3.js@1.98.0: + resolution: {integrity: sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==} + dependencies: + '@babel/runtime': 7.25.7 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.2 + node-fetch: 2.7.0 + rpc-websockets: 9.0.4 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@solworks/soltoolkit-sdk@0.0.23(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/spl-token': 0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.98.0 + '@types/bn.js': 5.1.6 + '@types/node': 18.19.65 + '@types/node-fetch': 2.6.12 + bn.js: 5.2.1 + decimal.js: 10.4.3 + typescript: 4.9.5 + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - utf-8-validate + dev: false + + /@soncodi/signal@2.0.7: + resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} + dev: false + /@swc/helpers@0.5.13: resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} dependencies: tslib: 2.7.0 dev: false - /@switchboard-xyz/common@3.4.1(typescript@5.6.3): - resolution: {integrity: sha512-TropBlBYuDeBnmGHkPSmgC3clLqAxy51ZGbwk4ejAgadnszWOgYHcH7taRG4Ha17DYSCWw/LGMBKbunGo+Aoaw==} + /@switchboard-xyz/common@2.5.5: + resolution: {integrity: sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w==} + engines: {node: '>=12'} + dependencies: + '@solana/web3.js': 1.98.0 + axios: 1.8.4 + big.js: 6.2.2 + bn.js: 5.2.1 + bs58: 5.0.0 + cron-validator: 1.3.1 + decimal.js: 10.4.3 + js-sha256: 0.11.0 + lodash: 4.17.21 + protobufjs: 7.4.0 + yaml: 2.6.1 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - utf-8-validate + dev: false + + /@switchboard-xyz/common@3.0.12: + resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} engines: {node: '>=20'} dependencies: - '@solana/web3.js': 1.98.2(typescript@5.6.3) - axios: 1.10.0 + '@solana/web3.js': 1.98.0 + axios: 1.8.4 big.js: 6.2.2 bn.js: 5.2.1 bs58: 6.0.0 @@ -679,32 +832,33 @@ packages: js-sha256: 0.11.0 protobufjs: 7.4.0 yaml: 2.6.1 - zod: 4.0.0-beta.20250505T195954 transitivePeerDependencies: - bufferutil - debug - encoding - - typescript - utf-8-validate dev: false - /@switchboard-xyz/on-demand@2.11.0(typescript@5.6.3): - resolution: {integrity: sha512-w4iHyRpvIuv2CT2Bcap6zIdunLYcDBuMUliyJuxmxLD+ch2Lta1QWHAZCsjuBasE2OhSKoTz3MAtapYuCuR2gA==} + /@switchboard-xyz/on-demand@1.2.51(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} engines: {node: '>= 18'} - dependencies: - '@coral-xyz/anchor-31': /@coral-xyz/anchor@0.31.1(typescript@5.6.3) - '@isaacs/ttlcache': 1.4.1 - '@switchboard-xyz/common': 3.4.1(typescript@5.6.3) - axios: 1.10.0 - bs58: 6.0.0 - buffer: 6.0.3 + deprecated: deprecated in favor of 2.x.x + dependencies: + '@brokerloop/ttlcache': 3.2.3 + '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 + '@solana/web3.js': 1.98.0 + '@solworks/soltoolkit-sdk': 0.0.23(fastestsmallesttextencoderdecoder@1.0.22) + '@switchboard-xyz/common': 2.5.5 + axios: 1.8.4 + big.js: 6.2.2 + bs58: 5.0.0 js-yaml: 4.1.0 - ws: 8.18.3 + protobufjs: 7.4.0 transitivePeerDependencies: - bufferutil - debug - encoding - - typescript + - fastestsmallesttextencoderdecoder - utf-8-validate dev: false @@ -712,6 +866,12 @@ packages: resolution: {integrity: sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==} dev: true + /@types/bn.js@5.1.6: + resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} + dependencies: + '@types/node': 20.16.11 + dev: false + /@types/chai@4.3.20: resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} dev: true @@ -732,10 +892,23 @@ packages: resolution: {integrity: sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==} dev: true + /@types/node-fetch@2.6.12: + resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + dependencies: + '@types/node': 20.16.11 + form-data: 4.0.1 + dev: false + /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: false + /@types/node@18.19.65: + resolution: {integrity: sha512-Ay5BZuO1UkTmVHzZJNvZKw/E+iB3GQABb6kijEz89w2JrfhNA+M/ebp18pfz9Gqe9ywhMC8AA8yC01lZq48J+Q==} + dependencies: + undici-types: 5.26.5 + dev: false + /@types/node@20.16.11: resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} dependencies: @@ -761,10 +934,6 @@ packages: resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} dev: true - /@zod/core@0.11.6: - resolution: {integrity: sha512-03Bv82fFSfjDAvMfdHHdGSS6SOJs0iCcJlWJv1kJHRtoTT02hZpyip/2Lk6oo4l4FtjuwTrsEQTwg/LD8I7dJA==} - dev: false - /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -821,8 +990,8 @@ packages: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false - /axios@1.10.0: - resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + /axios@1.7.8: + resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} dependencies: follow-redirects: 1.15.9 form-data: 4.0.1 @@ -831,8 +1000,8 @@ packages: - debug dev: false - /axios@1.7.8: - resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} + /axios@1.8.4: + resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} dependencies: follow-redirects: 1.15.9 form-data: 4.0.1 @@ -992,11 +1161,6 @@ packages: engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} dev: false - /chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: false - /check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} dependencies: @@ -1049,11 +1213,6 @@ packages: engines: {node: '>=18'} dev: false - /commander@13.1.0: - resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} - engines: {node: '>=18'} - dev: false - /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: false @@ -1062,6 +1221,10 @@ packages: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true + /cron-validator@1.3.1: + resolution: {integrity: sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==} + dev: false + /cross-fetch@3.1.8: resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} dependencies: @@ -1078,6 +1241,11 @@ packages: - encoding dev: false + /crypto-hash@1.3.0: + resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} + engines: {node: '>=8'} + dev: false + /debug@4.3.3(supports-color@8.1.1): resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} engines: {node: '>=6.0'} @@ -1127,6 +1295,13 @@ packages: engines: {node: '>=0.3.1'} dev: true + /dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dependencies: + no-case: 3.0.4 + tslib: 2.7.0 + dev: false + /dotenv@16.4.7: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} @@ -1405,6 +1580,10 @@ packages: p-locate: 5.0.0 dev: true + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: false + /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -1423,6 +1602,12 @@ packages: get-func-name: 2.0.2 dev: true + /lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.7.0 + dev: false + /make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: true @@ -1507,6 +1692,13 @@ packages: hasBin: true dev: true + /no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.7.0 + dev: false + /node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -1654,6 +1846,13 @@ packages: randombytes: 2.1.0 dev: true + /snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + dependencies: + dot-case: 3.0.4 + tslib: 2.7.0 + dev: false + /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: @@ -1788,11 +1987,21 @@ packages: engines: {node: '>=4'} dev: true + /typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: false + /typescript@5.6.3: resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} hasBin: true + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: false + /undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -1874,19 +2083,6 @@ packages: utf-8-validate: 5.0.10 dev: false - /ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: false - /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -1935,9 +2131,3 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true - - /zod@4.0.0-beta.20250505T195954: - resolution: {integrity: sha512-iB8WvxkobVIXMARvQu20fKvbS7mUTiYRpcD8OQV1xjRhxO0EEpYIRJBk6yfBzHAHEdOSDh3SxDITr5Eajr2vtg==} - dependencies: - '@zod/core': 0.11.6 - dev: false diff --git a/solauto-sdk/src/idls/switchboard.json b/solauto-sdk/src/idls/switchboard.json new file mode 100644 index 00000000..6996121a --- /dev/null +++ b/solauto-sdk/src/idls/switchboard.json @@ -0,0 +1,1949 @@ +{ + "address": "SBondMDrcV3K4kxZR1HNVT7osZxAHVHgYXL5Ze1oMUv", + "metadata": { + "name": "sb_on_demand", + "version": "0.1.0", + "spec": "0.1.0", + "description": "Created with Anchor" + }, + "instructions": [ + { + "name": "guardian_quote_verify", + "discriminator": [168, 36, 93, 156, 157, 150, 148, 45], + "accounts": [ + { "name": "guardian", "writable": true }, + { "name": "oracle", "writable": true }, + { "name": "authority", "signer": true, "relations": ["oracle"] }, + { "name": "guardian_queue", "writable": true, "relations": ["state"] }, + { "name": "state" }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "GuardianQuoteVerifyParams" } } + } + ] + }, + { + "name": "guardian_register", + "discriminator": [159, 76, 53, 117, 219, 29, 116, 135], + "accounts": [ + { "name": "oracle", "writable": true }, + { "name": "state" }, + { "name": "guardian_queue", "relations": ["state"] }, + { "name": "authority", "signer": true, "relations": ["state"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "GuardianRegisterParams" } } + } + ] + }, + { + "name": "guardian_unregister", + "discriminator": [215, 19, 61, 120, 155, 224, 120, 60], + "accounts": [ + { "name": "oracle", "writable": true }, + { "name": "state" }, + { "name": "guardian_queue", "writable": true, "relations": ["state"] }, + { "name": "authority", "signer": true, "relations": ["state"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "GuardianUnregisterParams" } } + } + ] + }, + { + "name": "oracle_heartbeat", + "discriminator": [10, 175, 217, 130, 111, 35, 117, 54], + "accounts": [ + { "name": "oracle", "writable": true }, + { + "name": "oracle_stats", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] + }, + { "kind": "account", "path": "oracle" } + ] + } + }, + { "name": "oracle_signer", "signer": true }, + { + "name": "queue", + "writable": true, + "relations": ["oracle", "gc_node"] + }, + { "name": "gc_node", "writable": true }, + { "name": "program_state", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "native_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "queue_escrow", "writable": true }, + { + "name": "stake_program", + "address": "SBSTk6t52R89MmCdD739Rdd97HdbTQUFHe41vCX7pTt", + "relations": ["program_state"] + }, + { "name": "delegation_pool", "writable": true }, + { "name": "delegation_group", "writable": true } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "OracleHeartbeatParams" } } + } + ] + }, + { + "name": "oracle_init", + "discriminator": [21, 158, 66, 65, 60, 221, 148, 61], + "accounts": [ + { "name": "oracle", "writable": true, "signer": true }, + { + "name": "oracle_stats", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] + }, + { "kind": "account", "path": "oracle" } + ] + } + }, + { "name": "program_state", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + }, + { "name": "stake_program", "relations": ["program_state"] }, + { "name": "stake_pool", "relations": ["program_state"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "OracleInitParams" } } + } + ] + }, + { + "name": "oracle_set_configs", + "discriminator": [129, 111, 223, 4, 191, 188, 70, 180], + "accounts": [ + { "name": "oracle" }, + { "name": "authority", "signer": true, "relations": ["oracle"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "OracleSetConfigsParams" } } + } + ] + }, + { + "name": "oracle_update_delegation", + "discriminator": [46, 198, 113, 223, 160, 189, 118, 90], + "accounts": [ + { "name": "oracle", "writable": true }, + { + "name": "oracle_stats", + "pda": { + "seeds": [ + { + "kind": "const", + "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] + }, + { "kind": "account", "path": "oracle" } + ] + } + }, + { "name": "queue", "relations": ["oracle"] }, + { "name": "authority", "signer": true }, + { "name": "program_state", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { "name": "delegation_pool", "writable": true }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + }, + { "name": "switch_mint" }, + { + "name": "native_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "wsol_vault", "writable": true }, + { "name": "switch_vault", "writable": true }, + { "name": "stake_program", "relations": ["program_state"] }, + { "name": "stake_pool" }, + { "name": "delegation_group" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "OracleUpdateDelegationParams" } } + } + ] + }, + { + "name": "permission_set", + "discriminator": [211, 122, 185, 120, 129, 182, 55, 103], + "accounts": [ + { "name": "authority", "signer": true }, + { "name": "granter" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PermissionSetParams" } } + } + ] + }, + { + "name": "pull_feed_close", + "discriminator": [19, 134, 50, 142, 177, 215, 196, 83], + "accounts": [ + { "name": "pull_feed", "writable": true }, + { "name": "reward_escrow", "writable": true }, + { "name": "lut", "writable": true }, + { "name": "lut_signer" }, + { "name": "payer", "writable": true, "signer": true }, + { "name": "state" }, + { + "name": "authority", + "writable": true, + "signer": true, + "relations": ["pull_feed"] + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedCloseParams" } } + } + ] + }, + { + "name": "pull_feed_init", + "discriminator": [198, 130, 53, 198, 235, 61, 143, 40], + "accounts": [ + { "name": "pull_feed", "writable": true, "signer": true }, + { "name": "queue" }, + { "name": "authority" }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "program_state" }, + { + "name": "reward_escrow", + "writable": true, + "pda": { + "seeds": [ + { "kind": "account", "path": "pull_feed" }, + { + "kind": "const", + "value": [ + 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, + 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, + 245, 133, 126, 255, 0, 169 + ] + }, + { "kind": "account", "path": "wrapped_sol_mint" } + ], + "program": { + "kind": "const", + "value": [ + 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, + 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, + 219, 233, 248, 89 + ] + } + } + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + }, + { + "name": "wrapped_sol_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedInitParams" } } + } + ] + }, + { + "name": "pull_feed_set_configs", + "discriminator": [217, 45, 11, 246, 64, 26, 82, 168], + "accounts": [ + { "name": "pull_feed", "writable": true }, + { "name": "authority", "signer": true, "relations": ["pull_feed"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedSetConfigsParams" } } + } + ] + }, + { + "name": "pull_feed_submit_response", + "discriminator": [150, 22, 215, 166, 143, 93, 48, 137], + "accounts": [ + { "name": "feed", "writable": true }, + { "name": "queue", "relations": ["feed"] }, + { "name": "program_state" }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "reward_vault", "writable": true }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "token_mint", + "address": "So11111111111111111111111111111111111111112" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedSubmitResponseParams" } } + } + ] + }, + { + "name": "pull_feed_submit_response_many", + "discriminator": [47, 156, 45, 25, 200, 71, 37, 215], + "accounts": [ + { "name": "queue" }, + { "name": "program_state" }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "reward_vault", "writable": true }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "token_mint", + "address": "So11111111111111111111111111111111111111112" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "PullFeedSubmitResponseManyParams" } } + } + ] + }, + { + "name": "queue_add_mr_enclave", + "discriminator": [199, 255, 81, 50, 60, 133, 171, 138], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "authority", "signer": true }, + { "name": "program_authority" }, + { "name": "state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueAddMrEnclaveParams" } } + } + ] + }, + { + "name": "queue_allow_subsidies", + "discriminator": [94, 203, 82, 157, 188, 138, 202, 108], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "authority", "signer": true, "relations": ["state"] }, + { "name": "state", "writable": true } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueAllowSubsidiesParams" } } + } + ] + }, + { + "name": "queue_garbage_collect", + "discriminator": [187, 208, 104, 247, 16, 91, 96, 98], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "oracle", "writable": true }, + { "name": "authority", "signer": true }, + { "name": "state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueGarbageCollectParams" } } + } + ] + }, + { + "name": "queue_init", + "discriminator": [144, 18, 99, 145, 133, 27, 207, 13], + "accounts": [ + { "name": "queue", "writable": true, "signer": true }, + { + "name": "queue_escrow", + "writable": true, + "pda": { + "seeds": [ + { "kind": "account", "path": "queue" }, + { + "kind": "const", + "value": [ + 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, + 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, + 245, 133, 126, 255, 0, 169 + ] + }, + { "kind": "account", "path": "native_mint" } + ], + "program": { + "kind": "const", + "value": [ + 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, + 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, + 219, 233, 248, 89 + ] + } + } + }, + { "name": "authority" }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "native_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "program_state" }, + { "name": "lut_signer", "writable": true }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueInitParams" } } + } + ] + }, + { + "name": "queue_init_delegation_group", + "discriminator": [239, 146, 75, 158, 20, 166, 159, 14], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "program_state" }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + }, + { "name": "delegation_group", "writable": true }, + { "name": "stake_program", "relations": ["program_state"] }, + { "name": "stake_pool" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueInitDelegationGroupParams" } } + } + ] + }, + { + "name": "queue_remove_mr_enclave", + "discriminator": [3, 64, 135, 33, 190, 133, 68, 252], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "authority", "signer": true }, + { "name": "program_authority" }, + { "name": "state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueRemoveMrEnclaveParams" } } + } + ] + }, + { + "name": "queue_set_configs", + "discriminator": [54, 183, 243, 199, 49, 103, 142, 48], + "accounts": [ + { "name": "queue", "writable": true }, + { "name": "authority", "signer": true }, + { "name": "state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "QueueSetConfigsParams" } } + } + ] + }, + { + "name": "randomness_commit", + "discriminator": [52, 170, 152, 201, 179, 133, 242, 141], + "accounts": [ + { "name": "randomness", "writable": true }, + { "name": "queue", "relations": ["randomness", "oracle"] }, + { "name": "oracle", "writable": true }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + }, + { "name": "authority", "signer": true, "relations": ["randomness"] } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "RandomnessCommitParams" } } + } + ] + }, + { + "name": "randomness_init", + "discriminator": [9, 9, 204, 33, 50, 116, 113, 15], + "accounts": [ + { "name": "randomness", "writable": true, "signer": true }, + { + "name": "reward_escrow", + "writable": true, + "pda": { + "seeds": [ + { "kind": "account", "path": "randomness" }, + { + "kind": "const", + "value": [ + 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, + 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, + 245, 133, 126, 255, 0, 169 + ] + }, + { "kind": "account", "path": "wrapped_sol_mint" } + ], + "program": { + "kind": "const", + "value": [ + 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, + 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, + 219, 233, 248, 89 + ] + } + } + }, + { "name": "authority", "signer": true }, + { "name": "queue", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + }, + { + "name": "wrapped_sol_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "program_state" }, + { "name": "lut_signer" }, + { "name": "lut", "writable": true }, + { + "name": "address_lookup_table_program", + "address": "AddressLookupTab1e1111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "RandomnessInitParams" } } + } + ] + }, + { + "name": "randomness_reveal", + "discriminator": [197, 181, 187, 10, 30, 58, 20, 73], + "accounts": [ + { "name": "randomness", "writable": true }, + { "name": "oracle", "relations": ["randomness"] }, + { "name": "queue", "relations": ["oracle"] }, + { + "name": "stats", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 79, 114, 97, 99, 108, 101, 82, 97, 110, 100, 111, 109, 110, + 101, 115, 115, 83, 116, 97, 116, 115 + ] + }, + { "kind": "account", "path": "oracle" } + ] + } + }, + { "name": "authority", "signer": true, "relations": ["randomness"] }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "recent_slothashes", + "address": "SysvarS1otHashes111111111111111111111111111" + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + }, + { "name": "reward_escrow", "writable": true }, + { + "name": "token_program", + "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + }, + { + "name": "wrapped_sol_mint", + "address": "So11111111111111111111111111111111111111112" + }, + { "name": "program_state" } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "RandomnessRevealParams" } } + } + ] + }, + { + "name": "state_init", + "discriminator": [103, 241, 106, 190, 217, 153, 87, 105], + "accounts": [ + { + "name": "state", + "writable": true, + "pda": { + "seeds": [{ "kind": "const", "value": [83, 84, 65, 84, 69] }] + } + }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "StateInitParams" } } + } + ] + }, + { + "name": "state_set_configs", + "discriminator": [40, 98, 76, 37, 206, 9, 47, 144], + "accounts": [ + { "name": "state", "writable": true }, + { "name": "authority", "signer": true, "relations": ["state"] }, + { "name": "queue", "writable": true }, + { "name": "payer", "writable": true, "signer": true }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "params", + "type": { "defined": { "name": "StateSetConfigsParams" } } + } + ] + } + ], + "accounts": [ + { + "name": "OracleAccountData", + "discriminator": [128, 30, 16, 241, 170, 73, 55, 54] + }, + { + "name": "OracleStatsAccountData", + "discriminator": [180, 157, 178, 234, 240, 27, 152, 179] + }, + { + "name": "PullFeedAccountData", + "discriminator": [196, 27, 108, 196, 10, 215, 219, 40] + }, + { + "name": "QueueAccountData", + "discriminator": [217, 194, 55, 127, 184, 83, 138, 1] + }, + { + "name": "RandomnessAccountData", + "discriminator": [10, 66, 229, 135, 220, 239, 217, 114] + }, + { "name": "State", "discriminator": [216, 146, 107, 94, 104, 75, 182, 177] } + ], + "events": [ + { + "name": "CostWhitelistEvent", + "discriminator": [56, 107, 191, 127, 116, 6, 138, 149] + }, + { + "name": "GarbageCollectionEvent", + "discriminator": [232, 235, 2, 188, 8, 143, 145, 237] + }, + { + "name": "GuardianQuoteVerifyEvent", + "discriminator": [31, 37, 39, 6, 214, 186, 33, 115] + }, + { + "name": "OracleHeartbeatEvent", + "discriminator": [52, 29, 166, 2, 94, 7, 188, 13] + }, + { + "name": "OracleInitEvent", + "discriminator": [89, 193, 219, 200, 1, 83, 167, 24] + }, + { + "name": "OracleQuoteOverrideEvent", + "discriminator": [78, 204, 191, 210, 164, 196, 244, 65] + }, + { + "name": "OracleQuoteRotateEvent", + "discriminator": [26, 189, 196, 192, 225, 127, 26, 228] + }, + { + "name": "OracleQuoteVerifyRequestEvent", + "discriminator": [203, 209, 79, 0, 20, 71, 226, 202] + }, + { + "name": "PermissionSetEvent", + "discriminator": [148, 86, 123, 0, 102, 20, 119, 206] + }, + { + "name": "PullFeedErrorValueEvent", + "discriminator": [225, 80, 192, 95, 14, 12, 83, 192] + }, + { + "name": "PullFeedValueEvents", + "discriminator": [86, 7, 231, 28, 122, 161, 117, 69] + }, + { + "name": "QueueAddMrEnclaveEvent", + "discriminator": [170, 186, 175, 38, 216, 51, 69, 175] + }, + { + "name": "QueueInitEvent", + "discriminator": [44, 137, 99, 227, 107, 8, 30, 105] + }, + { + "name": "QueueRemoveMrEnclaveEvent", + "discriminator": [4, 105, 196, 60, 84, 122, 203, 196] + }, + { + "name": "RandomnessCommitEvent", + "discriminator": [88, 60, 172, 90, 112, 10, 206, 147] + } + ], + "errors": [ + { "code": 6000, "name": "GenericError" }, + { "code": 6001, "name": "InvalidQuote" }, + { "code": 6002, "name": "InsufficientQueue" }, + { "code": 6003, "name": "QueueFull" }, + { "code": 6004, "name": "InvalidEnclaveSigner" }, + { "code": 6005, "name": "InvalidSigner" }, + { "code": 6006, "name": "MrEnclaveAlreadyExists" }, + { "code": 6007, "name": "MrEnclaveAtCapacity" }, + { "code": 6008, "name": "MrEnclaveDoesntExist" }, + { "code": 6009, "name": "PermissionDenied" }, + { "code": 6010, "name": "InvalidQueue" }, + { "code": 6011, "name": "IncorrectMrEnclave" }, + { "code": 6012, "name": "InvalidAuthority" }, + { "code": 6013, "name": "InvalidMrEnclave" }, + { "code": 6014, "name": "InvalidTimestamp" }, + { "code": 6015, "name": "InvalidOracleIdx" }, + { "code": 6016, "name": "InvalidSecpSignature" }, + { "code": 6017, "name": "InvalidGuardianQueue" }, + { "code": 6018, "name": "InvalidIndex" }, + { "code": 6019, "name": "InvalidOracleQueue" }, + { "code": 6020, "name": "InvalidPermission" }, + { "code": 6021, "name": "InvalidePermissionedAccount" }, + { "code": 6022, "name": "InvalidEpochRotate" }, + { "code": 6023, "name": "InvalidEpochFinalize" }, + { "code": 6024, "name": "InvalidEscrow" }, + { "code": 6025, "name": "IllegalOracle" }, + { "code": 6026, "name": "IllegalExecuteAttempt" }, + { "code": 6027, "name": "IllegalFeedValue" }, + { "code": 6028, "name": "InvalidOracleFeedStats" }, + { "code": 6029, "name": "InvalidStateAuthority" }, + { "code": 6030, "name": "NotEnoughSamples" }, + { "code": 6031, "name": "OracleIsVerified" }, + { "code": 6032, "name": "QueueIsEmpty" }, + { "code": 6033, "name": "SecpRecoverFailure" }, + { "code": 6034, "name": "StaleSample" }, + { "code": 6035, "name": "SwitchboardRandomnessTooOld" }, + { "code": 6036, "name": "EpochIdMismatch" }, + { "code": 6037, "name": "GuardianAlreadyVoted" }, + { "code": 6038, "name": "RandomnessNotRequested" }, + { "code": 6039, "name": "InvalidSlotNumber" }, + { "code": 6040, "name": "RandomnessOracleKeyExpired" }, + { "code": 6041, "name": "InvalidAdvisory" }, + { "code": 6042, "name": "InvalidOracleStats" }, + { "code": 6043, "name": "InvalidStakeProgram" }, + { "code": 6044, "name": "InvalidStakePool" }, + { "code": 6045, "name": "InvalidDelegationPool" }, + { "code": 6046, "name": "UnparsableAccount" }, + { "code": 6047, "name": "InvalidInstruction" }, + { "code": 6048, "name": "OracleAlreadyVerified" }, + { "code": 6049, "name": "GuardianNotVerified" }, + { "code": 6050, "name": "InvalidConstraint" }, + { "code": 6051, "name": "InvalidDelegationGroup" }, + { "code": 6052, "name": "OracleKeyNotFound" }, + { "code": 6053, "name": "GuardianReregisterAttempt" } + ], + "types": [ + { + "name": "CompactResult", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "std_dev", + "docs": [ + "The standard deviation of the submissions needed for quorom size" + ], + "type": "f32" + }, + { + "name": "mean", + "docs": ["The mean of the submissions needed for quorom size"], + "type": "f32" + }, + { + "name": "slot", + "docs": ["The slot at which this value was signed."], + "type": "u64" + } + ] + } + }, + { + "name": "CostWhitelistEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "feeds", "type": { "vec": "pubkey" } }, + { "name": "reward", "type": "u32" } + ] + } + }, + { + "name": "CurrentResult", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "value", + "docs": [ + "The median value of the submissions needed for quorom size" + ], + "type": "i128" + }, + { + "name": "std_dev", + "docs": [ + "The standard deviation of the submissions needed for quorom size" + ], + "type": "i128" + }, + { + "name": "mean", + "docs": ["The mean of the submissions needed for quorom size"], + "type": "i128" + }, + { + "name": "range", + "docs": ["The range of the submissions needed for quorom size"], + "type": "i128" + }, + { + "name": "min_value", + "docs": [ + "The minimum value of the submissions needed for quorom size" + ], + "type": "i128" + }, + { + "name": "max_value", + "docs": [ + "The maximum value of the submissions needed for quorom size" + ], + "type": "i128" + }, + { + "name": "num_samples", + "docs": ["The number of samples used to calculate this result"], + "type": "u8" + }, + { "name": "padding1", "type": { "array": ["u8", 7] } }, + { + "name": "slot", + "docs": ["The slot at which this value was signed."], + "type": "u64" + }, + { + "name": "min_slot", + "docs": [ + "The slot at which the first considered submission was made" + ], + "type": "u64" + }, + { + "name": "max_slot", + "docs": [ + "The slot at which the last considered submission was made" + ], + "type": "u64" + } + ] + } + }, + { + "name": "GarbageCollectionEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "oracle", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" } + ] + } + }, + { + "name": "GuardianQuoteVerifyEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "quote", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" } + ] + } + }, + { + "name": "GuardianQuoteVerifyParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "timestamp", "type": "i64" }, + { "name": "mr_enclave", "type": { "array": ["u8", 32] } }, + { "name": "_reserved1", "type": "u32" }, + { "name": "ed25519_key", "type": "pubkey" }, + { "name": "secp256k1_key", "type": { "array": ["u8", 64] } }, + { "name": "slot", "type": "u64" }, + { "name": "signature", "type": { "array": ["u8", 64] } }, + { "name": "recovery_id", "type": "u8" }, + { "name": "advisories", "type": { "vec": "u32" } } + ] + } + }, + { + "name": "GuardianRegisterParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "GuardianUnregisterParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "MegaSlotInfo", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "reserved1", "type": "u64" }, + { "name": "slot_end", "type": "u64" }, + { "name": "perf_goal", "type": "i64" }, + { "name": "current_signature_count", "type": "i64" } + ] + } + }, + { + "name": "MultiSubmission", + "type": { + "kind": "struct", + "fields": [ + { "name": "values", "type": { "vec": "i128" } }, + { "name": "signature", "type": { "array": ["u8", 64] } }, + { "name": "recovery_id", "type": "u8" } + ] + } + }, + { + "name": "OracleAccountData", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "enclave", + "docs": ["Represents the state of the quote verifiers enclave."], + "type": { "defined": { "name": "Quote" } } + }, + { + "name": "authority", + "docs": [ + "The authority of the EnclaveAccount which is permitted to make account changes." + ], + "type": "pubkey" + }, + { + "name": "queue", + "docs": [ + "Queue used for attestation to verify a MRENCLAVE measurement." + ], + "type": "pubkey" + }, + { + "name": "created_at", + "docs": ["The unix timestamp when the quote was created."], + "type": "i64" + }, + { + "name": "last_heartbeat", + "docs": ["The last time the quote heartbeated on-chain."], + "type": "i64" + }, + { "name": "secp_authority", "type": { "array": ["u8", 64] } }, + { + "name": "gateway_uri", + "docs": ["URI location of the verifier's gateway."], + "type": { "array": ["u8", 64] } + }, + { "name": "permissions", "type": "u64" }, + { + "name": "is_on_queue", + "docs": [ + "Whether the quote is located on the AttestationQueues buffer." + ], + "type": "u8" + }, + { "name": "_padding1", "type": { "array": ["u8", 7] } }, + { "name": "lut_slot", "type": "u64" }, + { "name": "last_reward_epoch", "type": "u64" }, + { "name": "_ebuf4", "type": { "array": ["u8", 16] } }, + { "name": "_ebuf3", "type": { "array": ["u8", 32] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 64] } }, + { "name": "_ebuf1", "type": { "array": ["u8", 1024] } } + ] + } + }, + { + "name": "OracleEpochInfo", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "id", "type": "u64" }, + { "name": "reserved1", "type": "u64" }, + { "name": "slot_end", "type": "u64" }, + { "name": "slash_score", "type": "u64" }, + { "name": "reward_score", "type": "u64" }, + { "name": "stake_score", "type": "u64" } + ] + } + }, + { + "name": "OracleHeartbeatEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "oracle", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" } + ] + } + }, + { + "name": "OracleHeartbeatParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "gateway_uri", + "type": { "option": { "array": ["u8", 64] } } + } + ] + } + }, + { + "name": "OracleInitEvent", + "type": { + "kind": "struct", + "fields": [{ "name": "oracle", "type": "pubkey" }] + } + }, + { + "name": "OracleInitParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "recent_slot", "type": "u64" }, + { "name": "authority", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" }, + { + "name": "secp_authority", + "type": { "option": { "array": ["u8", 64] } } + } + ] + } + }, + { + "name": "OracleQuoteOverrideEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "oracle", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" } + ] + } + }, + { + "name": "OracleQuoteRotateEvent", + "type": { + "kind": "struct", + "fields": [{ "name": "oracle", "type": "pubkey" }] + } + }, + { + "name": "OracleQuoteVerifyRequestEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "quote", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" } + ] + } + }, + { + "name": "OracleSetConfigsParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "new_authority", "type": { "option": "pubkey" } }, + { + "name": "new_secp_authority", + "type": { "option": { "array": ["u8", 64] } } + } + ] + } + }, + { + "name": "OracleStatsAccountData", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "owner", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" }, + { + "name": "finalized_epoch", + "docs": [ + "The last epoch that has completed. cleared after registered with the", + "staking program." + ], + "type": { "defined": { "name": "OracleEpochInfo" } } + }, + { + "name": "current_epoch", + "docs": [ + "The current epoch info being used by the oracle. for stake. Will moved", + "to finalized_epoch as soon as the epoch is over." + ], + "type": { "defined": { "name": "OracleEpochInfo" } } + }, + { + "name": "mega_slot_info", + "type": { "defined": { "name": "MegaSlotInfo" } } + }, + { "name": "last_transfer_slot", "type": "u64" }, + { "name": "bump", "type": "u8" }, + { "name": "padding1", "type": { "array": ["u8", 7] } }, + { + "name": "_ebuf", + "docs": ["Reserved."], + "type": { "array": ["u8", 1024] } + } + ] + } + }, + { + "name": "OracleSubmission", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "oracle", + "docs": ["The public key of the oracle that submitted this value."], + "type": "pubkey" + }, + { + "name": "slot", + "docs": ["The slot at which this value was signed."], + "type": "u64" + }, + { "name": "padding1", "type": { "array": ["u8", 8] } }, + { + "name": "value", + "docs": ["The value that was submitted."], + "type": "i128" + } + ] + } + }, + { + "name": "OracleUpdateDelegationParams", + "type": { + "kind": "struct", + "fields": [{ "name": "_reserved1", "type": "u64" }] + } + }, + { + "name": "PermissionSetEvent", + "type": { + "kind": "struct", + "fields": [{ "name": "permission", "type": "pubkey" }] + } + }, + { + "name": "PermissionSetParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "permission", "type": "u8" }, + { "name": "enable", "type": "bool" } + ] + } + }, + { + "name": "PullFeedAccountData", + "docs": ["A representation of the data in a pull feed account."], + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "submissions", + "docs": ["The oracle submissions for this feed."], + "type": { + "array": [{ "defined": { "name": "OracleSubmission" } }, 32] + } + }, + { + "name": "authority", + "docs": [ + "The public key of the authority that can update the feed hash that", + "this account will use for registering updates." + ], + "type": "pubkey" + }, + { + "name": "queue", + "docs": [ + "The public key of the queue which oracles must be bound to in order to", + "submit data to this feed." + ], + "type": "pubkey" + }, + { + "name": "feed_hash", + "docs": [ + "SHA-256 hash of the job schema oracles will execute to produce data", + "for this feed." + ], + "type": { "array": ["u8", 32] } + }, + { + "name": "initialized_at", + "docs": ["The slot at which this account was initialized."], + "type": "i64" + }, + { "name": "permissions", "type": "u64" }, + { "name": "max_variance", "type": "u64" }, + { "name": "min_responses", "type": "u32" }, + { "name": "name", "type": { "array": ["u8", 32] } }, + { "name": "padding1", "type": { "array": ["u8", 2] } }, + { "name": "historical_result_idx", "type": "u8" }, + { "name": "min_sample_size", "type": "u8" }, + { "name": "last_update_timestamp", "type": "i64" }, + { "name": "lut_slot", "type": "u64" }, + { "name": "_reserved1", "type": { "array": ["u8", 32] } }, + { + "name": "result", + "type": { "defined": { "name": "CurrentResult" } } + }, + { "name": "max_staleness", "type": "u32" }, + { "name": "padding2", "type": { "array": ["u8", 12] } }, + { + "name": "historical_results", + "type": { + "array": [{ "defined": { "name": "CompactResult" } }, 32] + } + }, + { "name": "_ebuf4", "type": { "array": ["u8", 8] } }, + { "name": "_ebuf3", "type": { "array": ["u8", 24] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 256] } } + ] + } + }, + { + "name": "PullFeedCloseParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "PullFeedErrorValueEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "feed", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" } + ] + } + }, + { + "name": "PullFeedInitParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "feed_hash", "type": { "array": ["u8", 32] } }, + { "name": "max_variance", "type": "u64" }, + { "name": "min_responses", "type": "u32" }, + { "name": "name", "type": { "array": ["u8", 32] } }, + { "name": "recent_slot", "type": "u64" }, + { "name": "ipfs_hash", "type": { "array": ["u8", 32] } }, + { "name": "min_sample_size", "type": "u8" }, + { "name": "max_staleness", "type": "u32" } + ] + } + }, + { + "name": "PullFeedSetConfigsParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "feed_hash", + "type": { "option": { "array": ["u8", 32] } } + }, + { "name": "authority", "type": { "option": "pubkey" } }, + { "name": "max_variance", "type": { "option": "u64" } }, + { "name": "min_responses", "type": { "option": "u32" } }, + { "name": "name", "type": { "option": { "array": ["u8", 32] } } }, + { + "name": "ipfs_hash", + "type": { "option": { "array": ["u8", 32] } } + }, + { "name": "min_sample_size", "type": { "option": "u8" } }, + { "name": "max_staleness", "type": { "option": "u32" } } + ] + } + }, + { + "name": "PullFeedSubmitResponseManyParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "slot", "type": "u64" }, + { + "name": "submissions", + "type": { "vec": { "defined": { "name": "MultiSubmission" } } } + } + ] + } + }, + { + "name": "PullFeedSubmitResponseParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "slot", "type": "u64" }, + { + "name": "submissions", + "type": { "vec": { "defined": { "name": "Submission" } } } + } + ] + } + }, + { + "name": "PullFeedValueEvents", + "type": { + "kind": "struct", + "fields": [ + { "name": "feeds", "type": { "vec": "pubkey" } }, + { "name": "oracles", "type": { "vec": "pubkey" } }, + { "name": "values", "type": { "vec": { "vec": "i128" } } }, + { "name": "reward", "type": "u32" } + ] + } + }, + { + "name": "QueueAccountData", + "docs": [ + "An Queue represents a round-robin queue of oracle oracles who attest on-chain", + "whether a Switchboard Function was executed within an enclave against an expected set of", + "enclave measurements.", + "", + "For an oracle to join the queue, the oracle must first submit their enclave quote on-chain and", + "wait for an existing oracle to attest their quote. If the oracle's quote matches an expected", + "measurement within the queues mr_enclaves config, it is granted permissions and will start", + "being assigned update requests." + ], + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "authority", + "docs": [ + "The address of the authority which is permitted to add/remove allowed enclave measurements." + ], + "type": "pubkey" + }, + { + "name": "mr_enclaves", + "docs": ["Allowed enclave measurements."], + "type": { "array": [{ "array": ["u8", 32] }, 32] } + }, + { + "name": "oracle_keys", + "docs": [ + "The addresses of the quote oracles who have a valid", + "verification status and have heartbeated on-chain recently." + ], + "type": { "array": ["pubkey", 128] } + }, + { + "name": "max_quote_verification_age", + "docs": [ + "The maximum allowable time until a EnclaveAccount needs to be re-verified on-chain." + ], + "type": "i64" + }, + { + "name": "last_heartbeat", + "docs": [ + "The unix timestamp when the last quote oracle heartbeated on-chain." + ], + "type": "i64" + }, + { "name": "node_timeout", "type": "i64" }, + { + "name": "oracle_min_stake", + "docs": [ + "The minimum number of lamports a quote oracle needs to lock-up in order to heartbeat and verify other quotes." + ], + "type": "u64" + }, + { "name": "allow_authority_override_after", "type": "i64" }, + { + "name": "mr_enclaves_len", + "docs": ["The number of allowed enclave measurements."], + "type": "u32" + }, + { + "name": "oracle_keys_len", + "docs": [ + "The length of valid quote oracles for the given attestation queue." + ], + "type": "u32" + }, + { + "name": "reward", + "docs": [ + "The reward paid to quote oracles for attesting on-chain." + ], + "type": "u32" + }, + { + "name": "curr_idx", + "docs": [ + "Incrementer used to track the current quote oracle permitted to run any available functions." + ], + "type": "u32" + }, + { + "name": "gc_idx", + "docs": [ + "Incrementer used to garbage collect and remove stale quote oracles." + ], + "type": "u32" + }, + { "name": "require_authority_heartbeat_permission", "type": "u8" }, + { "name": "require_authority_verify_permission", "type": "u8" }, + { "name": "require_usage_permissions", "type": "u8" }, + { "name": "signer_bump", "type": "u8" }, + { "name": "mint", "type": "pubkey" }, + { "name": "lut_slot", "type": "u64" }, + { "name": "allow_subsidies", "type": "u8" }, + { + "name": "_ebuf6", + "docs": ["Reserved."], + "type": { "array": ["u8", 23] } + }, + { "name": "_ebuf5", "type": { "array": ["u8", 32] } }, + { "name": "_ebuf4", "type": { "array": ["u8", 64] } }, + { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 256] } }, + { "name": "_ebuf1", "type": { "array": ["u8", 512] } } + ] + } + }, + { + "name": "QueueAddMrEnclaveEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "queue", "type": "pubkey" }, + { "name": "mr_enclave", "type": { "array": ["u8", 32] } } + ] + } + }, + { + "name": "QueueAddMrEnclaveParams", + "type": { + "kind": "struct", + "fields": [{ "name": "mr_enclave", "type": { "array": ["u8", 32] } }] + } + }, + { + "name": "QueueAllowSubsidiesParams", + "type": { + "kind": "struct", + "fields": [{ "name": "allow_subsidies", "type": "u8" }] + } + }, + { + "name": "QueueGarbageCollectParams", + "type": { "kind": "struct", "fields": [{ "name": "idx", "type": "u32" }] } + }, + { + "name": "QueueInitDelegationGroupParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "QueueInitEvent", + "type": { + "kind": "struct", + "fields": [{ "name": "queue", "type": "pubkey" }] + } + }, + { + "name": "QueueInitParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "allow_authority_override_after", "type": "u32" }, + { "name": "require_authority_heartbeat_permission", "type": "bool" }, + { "name": "require_usage_permissions", "type": "bool" }, + { "name": "max_quote_verification_age", "type": "u32" }, + { "name": "reward", "type": "u32" }, + { "name": "node_timeout", "type": "u32" }, + { "name": "recent_slot", "type": "u64" } + ] + } + }, + { + "name": "QueueRemoveMrEnclaveEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "queue", "type": "pubkey" }, + { "name": "mr_enclave", "type": { "array": ["u8", 32] } } + ] + } + }, + { + "name": "QueueRemoveMrEnclaveParams", + "type": { + "kind": "struct", + "fields": [{ "name": "mr_enclave", "type": { "array": ["u8", 32] } }] + } + }, + { + "name": "QueueSetConfigsParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "authority", "type": { "option": "pubkey" } }, + { "name": "reward", "type": { "option": "u32" } }, + { "name": "node_timeout", "type": { "option": "i64" } } + ] + } + }, + { + "name": "Quote", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { + "name": "enclave_signer", + "docs": ["The address of the signer generated within an enclave."], + "type": "pubkey" + }, + { + "name": "mr_enclave", + "docs": [ + "The quotes MRENCLAVE measurement dictating the contents of the secure enclave." + ], + "type": { "array": ["u8", 32] } + }, + { + "name": "verification_status", + "docs": ["The VerificationStatus of the quote."], + "type": "u8" + }, + { "name": "padding1", "type": { "array": ["u8", 7] } }, + { + "name": "verification_timestamp", + "docs": ["The unix timestamp when the quote was last verified."], + "type": "i64" + }, + { + "name": "valid_until", + "docs": [ + "The unix timestamp when the quotes verification status expires." + ], + "type": "i64" + }, + { + "name": "quote_registry", + "docs": [ + "The off-chain registry where the verifiers quote can be located." + ], + "type": { "array": ["u8", 32] } + }, + { + "name": "registry_key", + "docs": [ + "Key to lookup the buffer data on IPFS or an alternative decentralized storage solution." + ], + "type": { "array": ["u8", 64] } + }, + { + "name": "secp256k1_signer", + "docs": [ + "The secp256k1 public key of the enclave signer. Derived from the enclave_signer." + ], + "type": { "array": ["u8", 64] } + }, + { "name": "last_ed25519_signer", "type": "pubkey" }, + { "name": "last_secp256k1_signer", "type": { "array": ["u8", 64] } }, + { "name": "last_rotate_slot", "type": "u64" }, + { "name": "guardian_approvers", "type": { "array": ["pubkey", 64] } }, + { "name": "guardian_approvers_len", "type": "u8" }, + { "name": "padding2", "type": { "array": ["u8", 7] } }, + { "name": "staging_ed25519_signer", "type": "pubkey" }, + { + "name": "staging_secp256k1_signer", + "type": { "array": ["u8", 64] } + }, + { + "name": "_ebuf4", + "docs": ["Reserved."], + "type": { "array": ["u8", 32] } + }, + { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 256] } }, + { "name": "_ebuf1", "type": { "array": ["u8", 512] } } + ] + } + }, + { + "name": "RandomnessAccountData", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "authority", "type": "pubkey" }, + { "name": "queue", "type": "pubkey" }, + { "name": "seed_slothash", "type": { "array": ["u8", 32] } }, + { "name": "seed_slot", "type": "u64" }, + { "name": "oracle", "type": "pubkey" }, + { "name": "reveal_slot", "type": "u64" }, + { "name": "value", "type": { "array": ["u8", 32] } }, + { "name": "lut_slot", "type": "u64" }, + { "name": "_ebuf3", "type": { "array": ["u8", 24] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 64] } }, + { "name": "_ebuf1", "type": { "array": ["u8", 128] } }, + { + "name": "active_secp256k1_signer", + "type": { "array": ["u8", 64] } + }, + { "name": "active_secp256k1_expiration", "type": "i64" } + ] + } + }, + { + "name": "RandomnessCommitEvent", + "type": { + "kind": "struct", + "fields": [ + { "name": "randomness_account", "type": "pubkey" }, + { "name": "oracle", "type": "pubkey" }, + { "name": "slot", "type": "u64" }, + { "name": "slothash", "type": { "array": ["u8", 32] } } + ] + } + }, + { + "name": "RandomnessCommitParams", + "type": { "kind": "struct", "fields": [] } + }, + { + "name": "RandomnessInitParams", + "type": { + "kind": "struct", + "fields": [{ "name": "recent_slot", "type": "u64" }] + } + }, + { + "name": "RandomnessRevealParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "signature", "type": { "array": ["u8", 64] } }, + { "name": "recovery_id", "type": "u8" }, + { "name": "value", "type": { "array": ["u8", 32] } } + ] + } + }, + { + "name": "State", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "bump", "type": "u8" }, + { "name": "test_only_disable_mr_enclave_check", "type": "u8" }, + { "name": "enable_staking", "type": "u8" }, + { "name": "padding1", "type": { "array": ["u8", 5] } }, + { "name": "authority", "type": "pubkey" }, + { "name": "guardian_queue", "type": "pubkey" }, + { "name": "reserved1", "type": "u64" }, + { "name": "epoch_length", "type": "u64" }, + { + "name": "current_epoch", + "type": { "defined": { "name": "StateEpochInfo" } } + }, + { + "name": "next_epoch", + "type": { "defined": { "name": "StateEpochInfo" } } + }, + { + "name": "finalized_epoch", + "type": { "defined": { "name": "StateEpochInfo" } } + }, + { "name": "stake_pool", "type": "pubkey" }, + { "name": "stake_program", "type": "pubkey" }, + { "name": "switch_mint", "type": "pubkey" }, + { "name": "sgx_advisories", "type": { "array": ["u16", 32] } }, + { "name": "advisories_len", "type": "u8" }, + { "name": "padding2", "type": "u8" }, + { "name": "flat_reward_cut_percentage", "type": "u8" }, + { "name": "enable_slashing", "type": "u8" }, + { "name": "subsidy_amount", "type": "u32" }, + { "name": "lut_slot", "type": "u64" }, + { "name": "base_reward", "type": "u32" }, + { "name": "_ebuf6", "type": { "array": ["u8", 28] } }, + { "name": "_ebuf5", "type": { "array": ["u8", 32] } }, + { "name": "_ebuf4", "type": { "array": ["u8", 64] } }, + { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, + { "name": "_ebuf2", "type": { "array": ["u8", 512] } }, + { + "name": "cost_whitelist", + "docs": ["Cost whitelist by authority"], + "type": { "array": ["pubkey", 32] } + } + ] + } + }, + { + "name": "StateEpochInfo", + "serialization": "bytemuck", + "repr": { "kind": "c" }, + "type": { + "kind": "struct", + "fields": [ + { "name": "id", "type": "u64" }, + { "name": "_reserved1", "type": "u64" }, + { "name": "slot_end", "type": "u64" } + ] + } + }, + { "name": "StateInitParams", "type": { "kind": "struct", "fields": [] } }, + { + "name": "StateSetConfigsParams", + "type": { + "kind": "struct", + "fields": [ + { "name": "new_authority", "type": "pubkey" }, + { "name": "test_only_disable_mr_enclave_check", "type": "u8" }, + { "name": "stake_pool", "type": "pubkey" }, + { "name": "stake_program", "type": "pubkey" }, + { "name": "add_advisory", "type": "u16" }, + { "name": "rm_advisory", "type": "u16" }, + { "name": "epoch_length", "type": "u32" }, + { "name": "reset_epochs", "type": "bool" }, + { "name": "switch_mint", "type": "pubkey" }, + { "name": "enable_staking", "type": "u8" }, + { "name": "subsidy_amount", "type": "u32" }, + { "name": "base_reward", "type": "u32" }, + { "name": "add_cost_wl", "type": "pubkey" }, + { "name": "rm_cost_wl", "type": "pubkey" } + ] + } + }, + { + "name": "Submission", + "type": { + "kind": "struct", + "fields": [ + { "name": "value", "type": "i128" }, + { "name": "signature", "type": { "array": ["u8", 64] } }, + { "name": "recovery_id", "type": "u8" }, + { "name": "offset", "type": "u8" } + ] + } + } + ] +} diff --git a/solauto-sdk/src/utils/switchboardUtils.ts b/solauto-sdk/src/utils/switchboardUtils.ts index a29ed0a5..7f635d6f 100644 --- a/solauto-sdk/src/utils/switchboardUtils.ts +++ b/solauto-sdk/src/utils/switchboardUtils.ts @@ -6,9 +6,10 @@ import { } from "@solana/web3.js"; import { Signer, transactionBuilder } from "@metaplex-foundation/umi"; import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; -import { AnchorProvider, Program } from "@coral-xyz/anchor"; +import { AnchorProvider, Idl, Program } from "@coral-xyz/anchor"; import * as OnDemand from "@switchboard-xyz/on-demand"; import Big from "big.js"; +import switchboardIdl from "../idls/switchboard.json"; import { PRICES, SWITCHBOARD_PRICE_FEED_IDS } from "../constants"; import { TransactionItemInputs } from "../types"; import { @@ -17,7 +18,7 @@ import { } from "./generalUtils"; import { getWrappedInstruction } from "./solanaUtils"; -export async function getPullFeed( +export function getPullFeed( conn: Connection, mint: PublicKey, wallet?: PublicKey @@ -36,12 +37,11 @@ export async function getPullFeed( dummyWallet, AnchorProvider.defaultOptions() ); - const { PullFeed, ON_DEMAND_MAINNET_PID } = OnDemand; - const sbProgram = await Program.at(ON_DEMAND_MAINNET_PID, provider); + const program = new Program(switchboardIdl as Idl, provider); - console.log(new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId).toString()) + const { PullFeed } = OnDemand; return new PullFeed( - sbProgram, + program, new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId) ); } @@ -51,18 +51,12 @@ export async function buildSwbSubmitResponseTx( signer: Signer, mint: PublicKey ): Promise { - const feed = await getPullFeed( - conn, - mint, - toWeb3JsPublicKey(signer.publicKey) - ); - const gateway = await feed.fetchGatewayUrl(); - const [pullIxs, responses] = await retryWithExponentialBackoff( + const feed = getPullFeed(conn, mint, toWeb3JsPublicKey(signer.publicKey)); + const [pullIx, responses] = await retryWithExponentialBackoff( async () => { const res = await feed.fetchUpdateIx({ - gateway: gateway, chain: "solana", - network: "mainnet", + network: "mainnet-beta", }); if (!res[1] || !res[1][0].value) { throw new Error("Unable to fetch Switchboard pull IX"); @@ -73,7 +67,7 @@ export async function buildSwbSubmitResponseTx( 200 ); - if (!pullIxs || !pullIxs.length) { + if (!pullIx) { throw new Error("Unable to fetch SWB crank IX"); } @@ -87,9 +81,7 @@ export async function buildSwbSubmitResponseTx( }; return { - tx: transactionBuilder( - pullIxs.map((x) => getWrappedInstruction(signer, x)) - ), + tx: transactionBuilder([getWrappedInstruction(signer, pullIx!)]), lookupTableAddresses: responses .filter((x) => Boolean(x.oracle.lut?.key)) .map((x) => x.oracle.lut!.key.toString()), @@ -111,7 +103,7 @@ export async function getSwitchboardFeedData( const results = await Promise.all( mints.map(async (mint) => { - const feed = await getPullFeed(conn, mint); + const feed = getPullFeed(conn, mint); const result = await feed.loadData(); const price = Number(result.result.value) / Math.pow(10, 18); const stale = From d9498636adaaed58eeed3af2832ebaaa27c82e3f Mon Sep 17 00:00:00 2001 From: Chelioso Date: Thu, 17 Jul 2025 14:41:08 -0400 Subject: [PATCH 64/88] fixes --- generateClients.cjs | 59 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/generateClients.cjs b/generateClients.cjs index c65890e3..28fad739 100644 --- a/generateClients.cjs +++ b/generateClients.cjs @@ -28,6 +28,45 @@ function fixAnchorIDL(idlFilename, programId) { origin: "anchor", address: programId, }; + + function flattenDefined(data) { + if (typeof data === "object" && data !== null) { + if (Array.isArray(data)) { + return data.map(flattenDefined); + } else if (data.defined && typeof data.defined === "object") { + return { ...data, defined: data.defined.name }; + } else { + return Object.keys(data).reduce((acc, key) => { + acc[key] = flattenDefined(data[key]); + return acc; + }, {}); + } + } + return data; + } + + data = flattenDefined(data); + + function replacePubkeyWithPublicKey(data) { + if (typeof data === "object" && data !== null) { + if (Array.isArray(data)) { + return data.map(replacePubkeyWithPublicKey); + } else { + return Object.keys(data).reduce((acc, key) => { + if (key === "pubkey") { + acc["publicKey"] = data[key]; + } else { + acc[key] = replacePubkeyWithPublicKey(data[key]); + } + return acc; + }, {}); + } + } + return data; + } + + data = replacePubkeyWithPublicKey(data); + fs.writeFileSync(idlFilePath, JSON.stringify(data, null, 2), "utf8"); } @@ -92,16 +131,16 @@ async function cleanJupiterTsSDK(exclusions = []) { generateSolautoSDK(); -// generateRustSDKForAnchorIDL( -// "marginfi-sdk", -// "marginfi.json", -// "MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA" -// ); -// generateTypescriptSDKForAnchorIDL( -// "marginfiSdk", -// "marginfi.json", -// "MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA" -// ); +generateRustSDKForAnchorIDL( + "marginfi-sdk", + "marginfi.json", + "MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA" +); +generateTypescriptSDKForAnchorIDL( + "marginfiSdk", + "marginfi.json", + "MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA" +); // generateRustSDKForAnchorIDL( // "jupiter-sdk", From fa13e29d6c4e4874b595c4f6ec39066a2722148c Mon Sep 17 00:00:00 2001 From: Chelioso Date: Thu, 17 Jul 2025 15:20:00 -0400 Subject: [PATCH 65/88] small fix --- generateClients.cjs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/generateClients.cjs b/generateClients.cjs index 28fad739..65eda860 100644 --- a/generateClients.cjs +++ b/generateClients.cjs @@ -89,7 +89,9 @@ function generateTypescriptSDKForAnchorIDL(sdkDirName, idlFilename, programId) { const kinobi = k.createFromIdls([idlFilePath]); kinobi.accept( - new k.renderJavaScriptVisitor(path.join(typescriptSdkDir, sdkDirName)) + new k.renderJavaScriptVisitor( + path.join(typescriptSdkDir, "externalSdks", sdkDirName) + ) ); } @@ -137,7 +139,7 @@ generateRustSDKForAnchorIDL( "MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA" ); generateTypescriptSDKForAnchorIDL( - "marginfiSdk", + "marginfi", "marginfi.json", "MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA" ); @@ -148,12 +150,12 @@ generateTypescriptSDKForAnchorIDL( // "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4" // ); // generateTypescriptSDKForAnchorIDL( -// "jupiterSdk", +// "jupiter", // "jupiter.json", // "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4" // ); // generateTypescriptSDKForAnchorIDL( -// "pythSdk", +// "pyth", // "pyth.json", // "pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT" // ); From 7c035afc791eb1266489b9876c1f606349868b8b Mon Sep 17 00:00:00 2001 From: Chelioso Date: Thu, 17 Jul 2025 15:45:39 -0400 Subject: [PATCH 66/88] fixes --- generateClients.cjs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/generateClients.cjs b/generateClients.cjs index 65eda860..73edb58c 100644 --- a/generateClients.cjs +++ b/generateClients.cjs @@ -55,12 +55,16 @@ function fixAnchorIDL(idlFilename, programId) { return Object.keys(data).reduce((acc, key) => { if (key === "pubkey") { acc["publicKey"] = data[key]; + } else if (typeof data[key] === "string" && data[key] === "pubkey") { + acc[key] = "publicKey"; } else { acc[key] = replacePubkeyWithPublicKey(data[key]); } return acc; }, {}); } + } else if (data === "pubkey") { + return "publicKey"; } return data; } From ea157c0ea726f6e9cf23cbbb03d7214ffc3dce18 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sat, 19 Jul 2025 11:04:23 -0400 Subject: [PATCH 67/88] adding some more accounts --- solauto-sdk/local/createTokenAccounts.ts | 2 +- solauto-sdk/local/updateSolautoLUT.ts | 2 ++ solauto-sdk/src/constants/marginfiAccounts.ts | 5 +++++ solauto-sdk/src/constants/pythConstants.ts | 6 ++++++ solauto-sdk/src/constants/tokenConstants.ts | 7 +++++++ solauto-sdk/src/generated/types/solautoAction.ts | 2 +- solauto-sdk/src/generated/types/tokenBalanceAmount.ts | 2 +- 7 files changed, 23 insertions(+), 3 deletions(-) diff --git a/solauto-sdk/local/createTokenAccounts.ts b/solauto-sdk/local/createTokenAccounts.ts index 5f38efe3..2d317d20 100644 --- a/solauto-sdk/local/createTokenAccounts.ts +++ b/solauto-sdk/local/createTokenAccounts.ts @@ -50,4 +50,4 @@ async function createTokenAccounts(wallet: PublicKey) { } } -createTokenAccounts(SOLAUTO_FEES_WALLET); +createTokenAccounts(SOLAUTO_FEES_WALLET).catch((e) => console.log(e)); diff --git a/solauto-sdk/local/updateSolautoLUT.ts b/solauto-sdk/local/updateSolautoLUT.ts index 6a764d47..c5d3e3f1 100644 --- a/solauto-sdk/local/updateSolautoLUT.ts +++ b/solauto-sdk/local/updateSolautoLUT.ts @@ -7,6 +7,7 @@ import { SWITCHBOARD_PRICE_FEED_IDS, ALL_SUPPORTED_TOKENS, getTokenAccounts, + PYTH_ORACLE_ACCOUNTS, } from "../src"; import { updateLookupTable } from "./shared"; @@ -30,6 +31,7 @@ export async function updateSolautoLut(additionalAccounts?: string[]) { ...solautoManagerTokenAccounts.map((x) => x.toString()), ...solautoFeeWalletTokenAccounts.map((x) => x.toString()), ...Object.values(SWITCHBOARD_PRICE_FEED_IDS).map((x) => x.feedId), + ...Object.values(PYTH_ORACLE_ACCOUNTS), ...(additionalAccounts ?? []), ], LOOKUP_TABLE_ADDRESS diff --git a/solauto-sdk/src/constants/marginfiAccounts.ts b/solauto-sdk/src/constants/marginfiAccounts.ts index f9246a75..06717825 100644 --- a/solauto-sdk/src/constants/marginfiAccounts.ts +++ b/solauto-sdk/src/constants/marginfiAccounts.ts @@ -138,6 +138,11 @@ const MARGINFI_PROD_ACCOUNTS: MarginfiBankAccountsMap = { liquidityVault: "4kT3EXc5dDVndUU9mV6EH3Jh3CSEvpcCZjuMkwqrtxUy", vaultAuthority: "9gNrvvZ9RuTyRWooiEEypwcXU6kyXW8yWuhXU8tWUH5L", }, + [tokens.PUMP]: { + bank: "61Qx9kgWo9RVtPHf8Rku6gbaUtcnzgkpAuifQBUcMRVK", + liquidityVault: "6FxnrCaJNHLyrFy6EPtqFjoUK5iRxDQbaVo1bA69nDhH", + vaultAuthority: "6VL2QW6sy8cjxL24xHL7eFbnUSi35DMJd8AzRwssSs9y" + } }, ["DQ2jqDJw9uzTwttf6h6r217BQ7kws3jZbJXDkfbCJa1q"]: { [tokens.POPCAT]: { diff --git a/solauto-sdk/src/constants/pythConstants.ts b/solauto-sdk/src/constants/pythConstants.ts index 6db1af73..21d0c4b0 100644 --- a/solauto-sdk/src/constants/pythConstants.ts +++ b/solauto-sdk/src/constants/pythConstants.ts @@ -45,4 +45,10 @@ export const PYTH_PRICE_FEED_IDS = { "0x72b021217ca3fe68922a19aaf990109cb9d84e9ad004b4d2025ad6f529314419", [tokens.WIF]: "0x4ca4beeca86f0d164160323817a4e42b10010a724c2217c6ee41b54cd4cc61fc", + [tokens.PUMP]: + "0x7a01fca212788bba7c5bf8c9efd576a8a722f070d2c17596ff7bb609b8d5c3b9", +}; + +export const PYTH_ORACLE_ACCOUNTS = { + [tokens.PUMP]: "HMm3GPbdnqGwbkTnUUqCFsH8AMHDdEC3Lg8gcPD3HJSH", }; diff --git a/solauto-sdk/src/constants/tokenConstants.ts b/solauto-sdk/src/constants/tokenConstants.ts index 7e98f955..855c10d6 100644 --- a/solauto-sdk/src/constants/tokenConstants.ts +++ b/solauto-sdk/src/constants/tokenConstants.ts @@ -24,6 +24,7 @@ export const POPCAT = "7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr"; export const RETARDIO = "6ogzHhzdrQr9Pgv6hZ2MNze7UrzBMAFyBBWUYp1Fhitx"; export const BILLY = "3B5wuUrMEi5yATD7on46hKfej3pfmd7t1RKgrsN3pump"; export const HMTR = "7JhmUcZrrfhyt5nTSu3AfsrUq2L9992a7AhwdSDxdoL2"; +export const PUMP = "pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn"; export const ALL_SUPPORTED_TOKENS = [ NATIVE_MINT.toString(), @@ -49,6 +50,7 @@ export const ALL_SUPPORTED_TOKENS = [ RETARDIO, BILLY, HMTR, + PUMP, ]; export interface TokenInfo { @@ -193,6 +195,11 @@ export const TOKEN_INFO: { [key: string]: TokenInfo } = { decimals: 0, isMeme: true, }, + [PUMP]: { + ticker: "PUMP", + name: "Pump.fun", + decimals: 6, + } }; export const MAJORS_PRIO = { diff --git a/solauto-sdk/src/generated/types/solautoAction.ts b/solauto-sdk/src/generated/types/solautoAction.ts index 15473529..9e766e89 100644 --- a/solauto-sdk/src/generated/types/solautoAction.ts +++ b/solauto-sdk/src/generated/types/solautoAction.ts @@ -90,7 +90,7 @@ export function solautoAction( data?: any ): Extract { return Array.isArray(data) - ? { __kind: kind, fields: data } + ? { __kind: kind, fields: data } as Extract : { __kind: kind, ...(data ?? {}) }; } export function isSolautoAction( diff --git a/solauto-sdk/src/generated/types/tokenBalanceAmount.ts b/solauto-sdk/src/generated/types/tokenBalanceAmount.ts index d5c8d96b..8606e01a 100644 --- a/solauto-sdk/src/generated/types/tokenBalanceAmount.ts +++ b/solauto-sdk/src/generated/types/tokenBalanceAmount.ts @@ -56,7 +56,7 @@ export function tokenBalanceAmount( data?: any ): Extract { return Array.isArray(data) - ? { __kind: kind, fields: data } + ? { __kind: kind, fields: data } as Extract : { __kind: kind, ...(data ?? {}) }; } export function isTokenBalanceAmount( From 033f82c6a32727a798b13dc675359177eb87421e Mon Sep 17 00:00:00 2001 From: Chelioso Date: Tue, 22 Jul 2025 11:18:06 -0400 Subject: [PATCH 68/88] remove dependency on oracle key --- programs/solauto/src/clients/marginfi.rs | 311 +++++++++++------------ 1 file changed, 152 insertions(+), 159 deletions(-) diff --git a/programs/solauto/src/clients/marginfi.rs b/programs/solauto/src/clients/marginfi.rs index 935fc3e7..e676253a 100644 --- a/programs/solauto/src/clients/marginfi.rs +++ b/programs/solauto/src/clients/marginfi.rs @@ -1,20 +1,22 @@ use borsh::BorshDeserialize; use fixed::types::I80F48; use marginfi_sdk::generated::{ - accounts::{Bank, MarginfiAccount}, + accounts::{ Bank, MarginfiAccount }, instructions::*, - types::{Balance, OracleSetup}, + types::{ Balance, OracleSetup }, }; use pyth_sdk_solana::state::SolanaPriceAccount; use pyth_solana_receiver_sdk::price_update::PriceUpdateV2; use solana_program::{ - account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, msg, - program_error::ProgramError, pubkey::Pubkey, sysvar::Sysvar, -}; -use std::{ - cmp::min, - ops::{Div, Mul, Sub}, + account_info::AccountInfo, + clock::Clock, + entrypoint::ProgramResult, + msg, + program_error::ProgramError, + pubkey::Pubkey, + sysvar::Sysvar, }; +use std::{ cmp::min, ops::{ Div, Mul, Sub } }; use switchboard_on_demand::PullFeedAccountData; use switchboard_v2::AggregatorAccountData; @@ -23,16 +25,21 @@ use crate::{ types::{ errors::SolautoError, instruction::{ - accounts::{Context, MarginfiOpenPositionAccounts}, + accounts::{ Context, MarginfiOpenPositionAccounts }, SolautoStandardAccounts, }, - lending_protocol::{LendingProtocolClient, LendingProtocolTokenAccounts}, + lending_protocol::{ LendingProtocolClient, LendingProtocolTokenAccounts }, shared::{ - AccountMetaFlags, DeserializedAccount, PriceType, RefreshStateProps, - RefreshedTokenState, TokenBalanceAmount, TokenType, + AccountMetaFlags, + DeserializedAccount, + PriceType, + RefreshStateProps, + RefreshedTokenState, + TokenBalanceAmount, + TokenType, }, }, - utils::{math_utils::*, solana_utils::*, solauto_utils::*, validation_utils::*}, + utils::{ math_utils::*, solana_utils::*, solauto_utils::*, validation_utils::* }, }; const CONF_INTERVAL_MULTIPLE: f64 = 2.12; @@ -57,7 +64,7 @@ pub struct MarginfiClient<'a> { impl<'a> MarginfiClient<'a> { pub fn initialize<'c>( ctx: &'c Context<'a, MarginfiOpenPositionAccounts<'a>>, - solauto_position: &'c DeserializedAccount<'a, SolautoPosition>, + solauto_position: &'c DeserializedAccount<'a, SolautoPosition> ) -> ProgramResult { if account_has_data(ctx.accounts.marginfi_account) { return Ok(()); @@ -72,22 +79,26 @@ impl<'a> MarginfiClient<'a> { authority: marginfi_account_owner, fee_payer: ctx.accounts.signer, system_program: ctx.accounts.system_program, - }, + } ); if marginfi_account_owner.key == solauto_position.account_info.key { let mut marginfi_account_seeds = vec![ solauto_position.account_info.key.as_ref(), - ctx.accounts.marginfi_group.key.as_ref(), + ctx.accounts.marginfi_group.key.as_ref() ]; - let (_, bump) = - Pubkey::find_program_address(marginfi_account_seeds.as_slice(), &crate::ID); + let (_, bump) = Pubkey::find_program_address( + marginfi_account_seeds.as_slice(), + &crate::ID + ); let binding = [bump]; marginfi_account_seeds.push(&binding); - cpi.invoke_signed(&[ - solauto_position.data.seeds_with_bump().as_slice(), - marginfi_account_seeds.as_slice(), - ]) + cpi.invoke_signed( + &[ + solauto_position.data.seeds_with_bump().as_slice(), + marginfi_account_seeds.as_slice(), + ] + ) } else { cpi.invoke() } @@ -105,7 +116,7 @@ impl<'a> MarginfiClient<'a> { debt_bank: &'a AccountInfo<'a>, debt_price_oracle: Option<&'a AccountInfo<'a>>, debt_tas: LendingProtocolTokenAccounts<'a>, - debt_vault_authority: Option<&'a AccountInfo<'a>>, + debt_vault_authority: Option<&'a AccountInfo<'a>> ) -> Result { let supply = MarginfiBankAccounts { bank: DeserializedAccount::::zerocopy(Some(supply_bank))?.unwrap(), @@ -134,7 +145,7 @@ impl<'a> MarginfiClient<'a> { fn get_account_balance( account_balances: &[Balance], bank: &DeserializedAccount, - is_supply: bool, + is_supply: bool ) -> Option { account_balances.iter().find_map(|balance| { if &balance.bank_pk == bank.account_info.key { @@ -152,24 +163,22 @@ impl<'a> MarginfiClient<'a> { pub fn get_max_ltv_and_liq_threshold( supply_bank: &'a AccountInfo<'a>, - debt_bank: &'a AccountInfo<'a>, + debt_bank: &'a AccountInfo<'a> ) -> Result<(f64, f64), ProgramError> { let supply_bank = DeserializedAccount::::zerocopy(Some(supply_bank))?.unwrap(); let debt_bank = DeserializedAccount::::zerocopy(Some(debt_bank))?.unwrap(); - let max_ltv = i80f48_to_f64(I80F48::from_le_bytes( - supply_bank.data.config.asset_weight_init.value, - )) - .div(i80f48_to_f64(I80F48::from_le_bytes( - debt_bank.data.config.liability_weight_init.value, - ))); + let max_ltv = i80f48_to_f64( + I80F48::from_le_bytes(supply_bank.data.config.asset_weight_init.value) + ).div( + i80f48_to_f64(I80F48::from_le_bytes(debt_bank.data.config.liability_weight_init.value)) + ); - let liq_threshold = i80f48_to_f64(I80F48::from_le_bytes( - supply_bank.data.config.asset_weight_maint.value, - )) - .div(i80f48_to_f64(I80F48::from_le_bytes( - debt_bank.data.config.liability_weight_maint.value, - ))); + let liq_threshold = i80f48_to_f64( + I80F48::from_le_bytes(supply_bank.data.config.asset_weight_maint.value) + ).div( + i80f48_to_f64(I80F48::from_le_bytes(debt_bank.data.config.liability_weight_maint.value)) + ); Ok((max_ltv, liq_threshold)) } @@ -179,14 +188,18 @@ impl<'a> MarginfiClient<'a> { supply_bank: &'a AccountInfo<'a>, price_oracle: &'a AccountInfo<'a>, price_type: PriceType, - mut max_ltv: f64, + mut max_ltv: f64 ) -> Result<(RefreshedTokenState, f64), ProgramError> { let bank = DeserializedAccount::::zerocopy(Some(supply_bank))?.unwrap(); let asset_share_value = I80F48::from_le_bytes(bank.data.asset_share_value.value); - let market_price = - MarginfiClient::load_price(&bank, price_oracle, price_type, TokenType::Supply)?; + let market_price = MarginfiClient::load_price( + &bank, + price_oracle, + price_type, + TokenType::Supply + )?; let supply_shares = MarginfiClient::get_account_balance(account_balances, &bank, true); let base_unit_account_deposits = if supply_shares.is_some() { @@ -195,19 +208,24 @@ impl<'a> MarginfiClient<'a> { 0 }; - let total_deposited = - I80F48::from_le_bytes(bank.data.total_asset_shares.value).mul(asset_share_value); - let base_unit_deposit_room_available = - I80F48::from(bank.data.config.deposit_limit).sub(total_deposited); + let total_deposited = I80F48::from_le_bytes(bank.data.total_asset_shares.value).mul( + asset_share_value + ); + let base_unit_deposit_room_available = I80F48::from(bank.data.config.deposit_limit).sub( + total_deposited + ); - let bank_deposits_usd_value = - from_base_unit::(i80f48_to_f64(total_deposited), bank.data.mint_decimals) - .mul(market_price); - if bank.data.config.total_asset_value_init_limit != 0 - && bank_deposits_usd_value > (bank.data.config.total_asset_value_init_limit as f64) + let bank_deposits_usd_value = from_base_unit::( + i80f48_to_f64(total_deposited), + bank.data.mint_decimals + ).mul(market_price); + if + bank.data.config.total_asset_value_init_limit != 0 && + bank_deposits_usd_value > (bank.data.config.total_asset_value_init_limit as f64) { - let discount_factor = - (bank.data.config.total_asset_value_init_limit as f64).div(bank_deposits_usd_value); + let discount_factor = (bank.data.config.total_asset_value_init_limit as f64).div( + bank_deposits_usd_value + ); max_ltv = max_ltv * discount_factor; } @@ -228,14 +246,18 @@ impl<'a> MarginfiClient<'a> { account_balances: &[Balance], debt_bank: &'a AccountInfo<'a>, price_oracle: &'a AccountInfo<'a>, - price_type: PriceType, + price_type: PriceType ) -> Result { let bank = DeserializedAccount::::zerocopy(Some(debt_bank))?.unwrap(); let liability_share_value = I80F48::from_le_bytes(bank.data.liability_share_value.value); - let market_price = - MarginfiClient::load_price(&bank, price_oracle, price_type, TokenType::Debt)?; + let market_price = MarginfiClient::load_price( + &bank, + price_oracle, + price_type, + TokenType::Debt + )?; let debt_shares = MarginfiClient::get_account_balance(account_balances, &bank, false); let base_unit_account_debt = if debt_shares.is_some() { @@ -244,29 +266,26 @@ impl<'a> MarginfiClient<'a> { 0 }; - let total_deposited = I80F48::from_le_bytes(bank.data.total_asset_shares.value) - .mul(I80F48::from_le_bytes(bank.data.asset_share_value.value)); - let total_borrows = I80F48::from_le_bytes(bank.data.total_liability_shares.value) - .mul(liability_share_value); + let total_deposited = I80F48::from_le_bytes(bank.data.total_asset_shares.value).mul( + I80F48::from_le_bytes(bank.data.asset_share_value.value) + ); + let total_borrows = I80F48::from_le_bytes(bank.data.total_liability_shares.value).mul( + liability_share_value + ); let base_unit_supply_available = total_deposited.sub(total_borrows); let amount_can_be_used = min( - bank.data - .config - .borrow_limit - .saturating_sub(i80f48_to_u64(total_borrows)), - i80f48_to_u64(base_unit_supply_available), + bank.data.config.borrow_limit.saturating_sub(i80f48_to_u64(total_borrows)), + i80f48_to_u64(base_unit_supply_available) ); - let borrow_fee_bps = i80f48_to_f64(I80F48::from_le_bytes( - bank.data - .config - .interest_rate_config - .protocol_origination_fee - .value, - )) - .mul(10_000.0) - .round() as u16; + let borrow_fee_bps = i80f48_to_f64( + I80F48::from_le_bytes( + bank.data.config.interest_rate_config.protocol_origination_fee.value + ) + ) + .mul(10_000.0) + .round() as u16; Ok(RefreshedTokenState { mint: bank.data.mint, @@ -284,17 +303,19 @@ impl<'a> MarginfiClient<'a> { supply_price_oracle: &'a AccountInfo<'a>, debt_bank: &'a AccountInfo<'a>, debt_price_oracle: &'a AccountInfo<'a>, - price_type: PriceType, + price_type: PriceType ) -> Result { - let (max_ltv, liq_threshold) = - MarginfiClient::get_max_ltv_and_liq_threshold(supply_bank, debt_bank)?; + let (max_ltv, liq_threshold) = MarginfiClient::get_max_ltv_and_liq_threshold( + supply_bank, + debt_bank + )?; let account_balances = &marginfi_account.data.lending_account.balances[..2]; let debt = MarginfiClient::get_debt_token_usage( account_balances, debt_bank, debt_price_oracle, - price_type, + price_type )?; let (supply, max_ltv) = MarginfiClient::get_supply_token_usage( @@ -302,7 +323,7 @@ impl<'a> MarginfiClient<'a> { supply_bank, supply_price_oracle, price_type, - max_ltv, + max_ltv )?; Ok(RefreshStateProps { @@ -317,7 +338,7 @@ impl<'a> MarginfiClient<'a> { bank: &DeserializedAccount, price_oracle: &AccountInfo, price_type: PriceType, - token_type: TokenType, + token_type: TokenType ) -> Result { let clock = Clock::get()?; let max_price_age = 120; // Default used by Marginfi is 60 @@ -347,28 +368,27 @@ impl<'a> MarginfiClient<'a> { let price_feed_data = price_oracle.try_borrow_data()?; let price_feed = PriceUpdateV2::deserialize(&mut &price_feed_data.as_ref()[8..])?; - let (price, conf_interval) = if price_type == PriceType::Ema { - let ema_price = price_feed.price_message.ema_price; - let conf = price_feed.price_message.ema_conf; - let exponent = price_feed.price_message.exponent; + let (price, conf, exponent) = if price_type == PriceType::Ema { ( - derive_value(ema_price, exponent), - derive_value(conf as i64, exponent), + price_feed.price_message.ema_price, + price_feed.price_message.ema_conf, + price_feed.price_message.exponent, ) } else { - let feed_id = &bank.data.config.oracle_keys[0].to_bytes(); - let price_result = price_feed.get_price_unchecked(feed_id).unwrap(); ( - derive_value(price_result.price, price_result.exponent), - derive_value(price_result.conf as i64, price_result.exponent), + price_feed.price_message.price, + price_feed.price_message.conf, + price_feed.price_message.exponent, ) }; - Ok(with_conf_interval( - price, - conf_interval.mul(CONF_INTERVAL_MULTIPLE), - token_type, - )) + Ok( + with_conf_interval( + derive_value(price, exponent), + derive_value(conf as i64, exponent).mul(CONF_INTERVAL_MULTIPLE), + token_type + ) + ) } OracleSetup::SwitchboardLegacy => { let data = price_oracle.data.borrow(); @@ -386,8 +406,9 @@ impl<'a> MarginfiClient<'a> { } OracleSetup::SwitchboardPull => { let data = price_oracle.data.borrow(); - let feed = PullFeedAccountData::parse(data) - .map_err(|_| SolautoError::IncorrectAccounts)?; + let feed = PullFeedAccountData::parse(data).map_err( + |_| SolautoError::IncorrectAccounts + )?; let price = (feed.result.value as f64) // 10^18 @@ -405,14 +426,14 @@ impl<'a> MarginfiClient<'a> { pub fn refresh_bank( program: &'a AccountInfo<'a>, marginfi_group: &'a AccountInfo<'a>, - bank: &'a AccountInfo<'a>, + bank: &'a AccountInfo<'a> ) -> ProgramResult { let cpi = LendingPoolAccrueBankInterestCpi::new( program, LendingPoolAccrueBankInterestCpiAccounts { marginfi_group, bank, - }, + } ); cpi.invoke() } @@ -421,15 +442,11 @@ impl<'a> MarginfiClient<'a> { let mut banks_and_oracles: Vec<(AccountMetaFlags, AccountMetaFlags)> = accounts .chunks(2) .filter_map(|chunk| { - if chunk.len() == 2 { - Some((chunk[0], chunk[1])) - } else { - None - } + if chunk.len() == 2 { Some((chunk[0], chunk[1])) } else { None } }) .collect(); - banks_and_oracles.sort_by(|a, b| b.0 .0.key.to_string().cmp(&a.0 .0.key.to_string())); + banks_and_oracles.sort_by(|a, b| b.0.0.key.to_string().cmp(&a.0.0.key.to_string())); banks_and_oracles .into_iter() @@ -443,12 +460,12 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { validate_token_accounts( &std_accounts.solauto_position, self.supply.token_accounts.position_ta, - self.debt.token_accounts.position_ta, + self.debt.token_accounts.position_ta )?; validate_token_accounts( &std_accounts.solauto_position, self.supply.token_accounts.authority_ta, - self.debt.token_accounts.authority_ta, + self.debt.token_accounts.authority_ta )?; Ok(()) } @@ -456,7 +473,7 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { fn deposit<'c>( &self, base_unit_amount: u64, - std_accounts: &'c Box>, + std_accounts: &'c Box> ) -> ProgramResult { let authority = get_owner(&std_accounts.solauto_position, self.signer); @@ -480,15 +497,11 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { LendingAccountDepositInstructionArgs { amount: base_unit_amount, deposit_up_to_limit: Some(true), - }, + } ); if !std_accounts.solauto_position.data.self_managed.val { - cpi.invoke_signed(&[std_accounts - .solauto_position - .data - .seeds_with_bump() - .as_slice()]) + cpi.invoke_signed(&[std_accounts.solauto_position.data.seeds_with_bump().as_slice()]) } else { cpi.invoke() } @@ -498,15 +511,11 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { &self, amount: TokenBalanceAmount, destination: &'a AccountInfo<'a>, - std_accounts: &'c Box>, + std_accounts: &'c Box> ) -> ProgramResult { let authority = get_owner(&std_accounts.solauto_position, self.signer); - let base_unit_amount = if let TokenBalanceAmount::Some(num) = amount { - num - } else { - 0 - }; + let base_unit_amount = if let TokenBalanceAmount::Some(num) = amount { num } else { 0 }; let cpi = LendingAccountWithdrawCpi::new( self.program, @@ -523,17 +532,14 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { LendingAccountWithdrawInstructionArgs { amount: base_unit_amount, withdraw_all: Some(amount == TokenBalanceAmount::All), - }, + } ); - let marginfi_account_data = - DeserializedAccount::::zerocopy(Some(self.marginfi_account))? - .unwrap() - .data; + let marginfi_account_data = DeserializedAccount:: + ::zerocopy(Some(self.marginfi_account))? + .unwrap().data; - let active_balances = marginfi_account_data - .lending_account - .balances + let active_balances = marginfi_account_data.lending_account.balances .iter() .filter(|balance| balance.active == 1) .collect::>(); @@ -543,9 +549,11 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { let mut withdrawing_all = amount == TokenBalanceAmount::All; if !withdrawing_all && active_balances.len() == 1 { let asset_shares = I80F48::from_le_bytes(active_balances[0].asset_shares.value); - let supply_balance = i80f48_to_u64(asset_shares.mul(I80F48::from_le_bytes( - self.supply.bank.data.asset_share_value.value, - ))); + let supply_balance = i80f48_to_u64( + asset_shares.mul( + I80F48::from_le_bytes(self.supply.bank.data.asset_share_value.value) + ) + ); let TokenBalanceAmount::Some(withdraw_amount) = amount else { panic!("Unexpected amount type"); }; @@ -564,16 +572,12 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { if !std_accounts.solauto_position.data.self_managed.val { cpi.invoke_signed_with_remaining_accounts( - &[std_accounts - .solauto_position - .data - .seeds_with_bump() - .as_slice()], - MarginfiClient::compose_remaining_accounts(remaining_accounts).as_slice(), + &[std_accounts.solauto_position.data.seeds_with_bump().as_slice()], + MarginfiClient::compose_remaining_accounts(remaining_accounts).as_slice() ) } else { cpi.invoke_with_remaining_accounts( - MarginfiClient::compose_remaining_accounts(remaining_accounts).as_slice(), + MarginfiClient::compose_remaining_accounts(remaining_accounts).as_slice() ) } } @@ -582,7 +586,7 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { &self, base_unit_amount: u64, destination: &'a AccountInfo<'a>, - std_accounts: &'c Box>, + std_accounts: &'c Box> ) -> ProgramResult { let authority = get_owner(&std_accounts.solauto_position, self.signer); @@ -600,11 +604,12 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { }, LendingAccountBorrowInstructionArgs { amount: base_unit_amount, - }, + } ); - let mut remaining_accounts: Vec = - Vec::::with_capacity(4); + let mut remaining_accounts: Vec = Vec::::with_capacity( + 4 + ); remaining_accounts.push((self.supply.bank.account_info, false, false)); remaining_accounts.push((self.supply.price_oracle.unwrap(), false, false)); remaining_accounts.push((self.debt.bank.account_info, false, true)); @@ -612,16 +617,12 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { if !std_accounts.solauto_position.data.self_managed.val { cpi.invoke_signed_with_remaining_accounts( - &[std_accounts - .solauto_position - .data - .seeds_with_bump() - .as_slice()], - MarginfiClient::compose_remaining_accounts(remaining_accounts).as_slice(), + &[std_accounts.solauto_position.data.seeds_with_bump().as_slice()], + MarginfiClient::compose_remaining_accounts(remaining_accounts).as_slice() ) } else { cpi.invoke_with_remaining_accounts( - MarginfiClient::compose_remaining_accounts(remaining_accounts).as_slice(), + MarginfiClient::compose_remaining_accounts(remaining_accounts).as_slice() ) } } @@ -629,15 +630,11 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { fn repay<'c>( &self, amount: TokenBalanceAmount, - std_accounts: &'c Box>, + std_accounts: &'c Box> ) -> ProgramResult { let authority = get_owner(&std_accounts.solauto_position, self.signer); - let base_unit_amount = if let TokenBalanceAmount::Some(num) = amount { - num - } else { - 0 - }; + let base_unit_amount = if let TokenBalanceAmount::Some(num) = amount { num } else { 0 }; let signer_token_account = if !std_accounts.solauto_position.data.self_managed.val { self.debt.token_accounts.position_ta.as_ref().unwrap() @@ -659,15 +656,11 @@ impl<'a> LendingProtocolClient<'a> for MarginfiClient<'a> { LendingAccountRepayInstructionArgs { amount: base_unit_amount, repay_all: Some(amount == TokenBalanceAmount::All), - }, + } ); if !std_accounts.solauto_position.data.self_managed.val { - cpi.invoke_signed(&[std_accounts - .solauto_position - .data - .seeds_with_bump() - .as_slice()]) + cpi.invoke_signed(&[std_accounts.solauto_position.data.seeds_with_bump().as_slice()]) } else { cpi.invoke() } From 6755a360c4a3d234fd90b70d33153ee7aadf7a31 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Thu, 31 Jul 2025 01:09:22 -0400 Subject: [PATCH 69/88] fixes --- solauto-sdk/package.json | 2 +- solauto-sdk/src/utils/marginfi/general.ts | 28 +++++++++++------------ 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 7093eb24..312f8f19 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.782", + "version": "1.0.789", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/utils/marginfi/general.ts b/solauto-sdk/src/utils/marginfi/general.ts index 5a9ad505..81c950eb 100644 --- a/solauto-sdk/src/utils/marginfi/general.ts +++ b/solauto-sdk/src/utils/marginfi/general.ts @@ -28,6 +28,7 @@ import { getPythPushOracleAddress, } from "../pythUtils"; import { getAccountMeta } from "../solanaUtils"; +import { validPubkey } from "../generalUtils"; export function createDynamicMarginfiProgram(env?: ProgramEnv): Program { return { @@ -69,15 +70,11 @@ export async function getAllBankRelatedAccounts( ); const oracles = banksData - .map((bank) => { - const oracleKey = toWeb3JsPublicKey(bank.config.oracleKeys[0]); - return bank.config.oracleSetup === OracleSetup.PythPushOracle - ? [ - getPythPushOracleAddress(oracleKey, PYTH_SPONSORED_SHARD_ID), - getPythPushOracleAddress(oracleKey, MARGINFI_SPONSORED_SHARD_ID), - ] - : [oracleKey]; - }) + .map((bank) => + bank.config.oracleKeys + .map((x) => toWeb3JsPublicKey(x)) + .filter((x) => validPubkey(x)) + ) .flat() .map((x) => x.toString()); @@ -118,14 +115,15 @@ export async function getMarginfiPriceOracle( bank.data = await fetchBank(umi, fromWeb3JsPublicKey(bank.pk!)); } - const oracleKey = toWeb3JsPublicKey(bank.data.config.oracleKeys[0]); const priceOracle = bank.data.config.oracleSetup === OracleSetup.PythPushOracle - ? await getMostUpToDatePythOracle(umi, [ - getPythPushOracleAddress(oracleKey, PYTH_SPONSORED_SHARD_ID), - getPythPushOracleAddress(oracleKey, MARGINFI_SPONSORED_SHARD_ID), - ]) - : oracleKey; + ? await getMostUpToDatePythOracle( + umi, + bank.data.config.oracleKeys + .map((x) => toWeb3JsPublicKey(x)) + .filter((x) => validPubkey(x)) + ) + : toWeb3JsPublicKey(bank.data.config.oracleKeys[0]); return priceOracle; } From e0596bb25408883d1ed815f3aed60c3d9f11c185 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Wed, 6 Aug 2025 18:03:59 -0400 Subject: [PATCH 70/88] remove unused variables --- solauto-sdk/src/constants/pythConstants.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/solauto-sdk/src/constants/pythConstants.ts b/solauto-sdk/src/constants/pythConstants.ts index 21d0c4b0..41fb1c4c 100644 --- a/solauto-sdk/src/constants/pythConstants.ts +++ b/solauto-sdk/src/constants/pythConstants.ts @@ -6,9 +6,6 @@ export const PYTH_PUSH_PROGRAM = new PublicKey( "pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT" ); -export const PYTH_SPONSORED_SHARD_ID = 0; -export const MARGINFI_SPONSORED_SHARD_ID = 3301; - // https://pyth.network/developers/price-feed-ids#solana-stable export const PYTH_PRICE_FEED_IDS = { [NATIVE_MINT.toString()]: From eb0462a4ea917c62d4d0349b0f9c1de54468f0f7 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Thu, 7 Aug 2025 23:17:24 -0400 Subject: [PATCH 71/88] test commit --- solauto-sdk/src/constants/pythConstants.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/solauto-sdk/src/constants/pythConstants.ts b/solauto-sdk/src/constants/pythConstants.ts index 41fb1c4c..7319dbf7 100644 --- a/solauto-sdk/src/constants/pythConstants.ts +++ b/solauto-sdk/src/constants/pythConstants.ts @@ -6,6 +6,7 @@ export const PYTH_PUSH_PROGRAM = new PublicKey( "pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT" ); + // https://pyth.network/developers/price-feed-ids#solana-stable export const PYTH_PRICE_FEED_IDS = { [NATIVE_MINT.toString()]: From 6e041af7b449e7ab73c60ea9d75833cc158bcbac Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sun, 10 Aug 2025 19:53:34 -0400 Subject: [PATCH 72/88] remove unused imports --- solauto-sdk/src/constants/pythConstants.ts | 1 - solauto-sdk/src/utils/marginfi/general.ts | 3 --- solauto-sdk/src/utils/pythUtils.ts | 12 ------------ 3 files changed, 16 deletions(-) diff --git a/solauto-sdk/src/constants/pythConstants.ts b/solauto-sdk/src/constants/pythConstants.ts index 7319dbf7..41fb1c4c 100644 --- a/solauto-sdk/src/constants/pythConstants.ts +++ b/solauto-sdk/src/constants/pythConstants.ts @@ -6,7 +6,6 @@ export const PYTH_PUSH_PROGRAM = new PublicKey( "pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT" ); - // https://pyth.network/developers/price-feed-ids#solana-stable export const PYTH_PRICE_FEED_IDS = { [NATIVE_MINT.toString()]: diff --git a/solauto-sdk/src/utils/marginfi/general.ts b/solauto-sdk/src/utils/marginfi/general.ts index 81c950eb..1d6866b2 100644 --- a/solauto-sdk/src/utils/marginfi/general.ts +++ b/solauto-sdk/src/utils/marginfi/general.ts @@ -7,9 +7,7 @@ import { import { ProgramEnv, MarginfiAssetAccounts } from "../../types"; import { getMarginfiAccounts, - MARGINFI_SPONSORED_SHARD_ID, MarginfiBankAccountsMap, - PYTH_SPONSORED_SHARD_ID, } from "../../constants"; import { Balance, @@ -25,7 +23,6 @@ import { bytesToI80F48, fromBaseUnit, toBps } from "../numberUtils"; import { getTokenAccountData } from "../accountUtils"; import { getMostUpToDatePythOracle, - getPythPushOracleAddress, } from "../pythUtils"; import { getAccountMeta } from "../solanaUtils"; import { validPubkey } from "../generalUtils"; diff --git a/solauto-sdk/src/utils/pythUtils.ts b/solauto-sdk/src/utils/pythUtils.ts index 68595692..8ca99a49 100644 --- a/solauto-sdk/src/utils/pythUtils.ts +++ b/solauto-sdk/src/utils/pythUtils.ts @@ -23,15 +23,3 @@ export async function getMostUpToDatePythOracle( return oracles[0][0]; } - -export function getPythPushOracleAddress( - feedId: PublicKey, - shardId: number, - programId: PublicKey = PYTH_PUSH_PROGRAM -): PublicKey { - const shardBytes = u16ToArrayBufferLE(shardId); - return PublicKey.findProgramAddressSync( - [shardBytes, feedId.toBuffer()], - programId - )[0]; -} From 17818b79262ba527b6788ee3bc6657e067d31366 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sun, 10 Aug 2025 19:59:21 -0400 Subject: [PATCH 73/88] small fixes --- README.md | 2 +- pnpm-lock.yaml | 2870 +++++++++++++++++----------------- solauto-sdk/pnpm-lock.yaml | 2986 ++++++++++++++++++++---------------- 3 files changed, 3116 insertions(+), 2742 deletions(-) diff --git a/README.md b/README.md index 6852fb18..0346f7ce 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ See the [Program documentation](/programs/solauto/README.md) for more info on th - PNPM ``` -crate install shank-idl +cargo install shank-cli rustup component add rustfmt pnpm install -g ts-node ``` diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a9acb1a..95d1b0a1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,66 +1,994 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -dependencies: - '@metaplex-foundation/kinobi': - specifier: ^0.18.5 - version: 0.18.5(fastestsmallesttextencoderdecoder@1.0.22) - '@mrgnlabs/marginfi-client-v2': - specifier: ^6.0.1 - version: 6.0.1 - '@mrgnlabs/mrgn-common': - specifier: ^2.0.2 - version: 2.0.2 - borsh: - specifier: ^2.0.0 - version: 2.0.0 - -devDependencies: - solauto-sdk: - specifier: file:solauto-sdk - version: file:solauto-sdk(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - typescript: - specifier: ^4.9.5 - version: 4.9.5 +importers: + + .: + dependencies: + '@metaplex-foundation/kinobi': + specifier: ^0.18.5 + version: 0.18.5(fastestsmallesttextencoderdecoder@1.0.22) + '@mrgnlabs/marginfi-client-v2': + specifier: ^6.0.1 + version: 6.1.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@mrgnlabs/mrgn-common': + specifier: ^2.0.2 + version: 2.0.3(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + borsh: + specifier: ^2.0.0 + version: 2.0.0 + devDependencies: + solauto-sdk: + specifier: file:solauto-sdk + version: '@haven-fi/solauto-sdk@file:solauto-sdk(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)' + typescript: + specifier: ^4.9.5 + version: 4.9.5 packages: - /@babel/runtime@7.25.7: - resolution: {integrity: sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==} + '@babel/runtime@7.27.6': + resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.14.1 - /@brokerloop/ttlcache@3.2.3: - resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} + '@brokerloop/ttlcache@3.2.3': + resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} + + '@common.js/quick-lru@7.0.0': + resolution: {integrity: sha512-DO3vApnH1vLizdWRSqzhg+S956vptHhtO+vw6PP6StJGDtaAGyfKSSPPGYWguJZu/Jlti6l6m6jB8NrKEQexLg==} + engines: {node: '>=18'} + + '@coral-xyz/anchor-errors@0.30.1': + resolution: {integrity: sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==} + engines: {node: '>=10'} + + '@coral-xyz/anchor@0.29.0': + resolution: {integrity: sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==} + engines: {node: '>=11'} + + '@coral-xyz/anchor@0.30.1': + resolution: {integrity: sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==} + engines: {node: '>=11'} + + '@coral-xyz/borsh@0.29.0': + resolution: {integrity: sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + + '@coral-xyz/borsh@0.30.1': + resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + + '@grpc/grpc-js@1.13.4': + resolution: {integrity: sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==} + engines: {node: '>=12.10.0'} + + '@grpc/proto-loader@0.7.15': + resolution: {integrity: sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==} + engines: {node: '>=6'} + hasBin: true + + '@haven-fi/solauto-sdk@file:solauto-sdk': + resolution: {directory: solauto-sdk, type: directory} + + '@js-sdsl/ordered-map@4.4.2': + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + + '@jup-ag/api@6.0.24': + resolution: {integrity: sha512-zIX4WIPb0Kb2UnK2wNIOQBWqPJyMJq/D9dQTf/2qvPb0hfa8XdgbrQAzomHMHnAzw9StMQoybBk+JK/A76xP3w==} + + '@metaplex-foundation/kinobi@0.18.5': + resolution: {integrity: sha512-qh4h4xGB+PHR5o4rcZki+wsIeZYi6R9SRV5UMqGi/rfDJXk0ckAZ+fxdam+mCc4N8HWLLWmEJbF5gx8E5K0fOA==} + + '@metaplex-foundation/umi-bundle-defaults@0.9.2': + resolution: {integrity: sha512-kV3tfvgvRjVP1p9OFOtH+ibOtN9omVJSwKr0We4/9r45e5LTj+32su0V/rixZUkG1EZzzOYBsxhtIE0kIw/Hrw==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + '@solana/web3.js': ^1.72.0 + + '@metaplex-foundation/umi-downloader-http@0.9.2': + resolution: {integrity: sha512-tzPT9hBwenzTzAQg07rmsrqZfgguAXELbcJrsYMoASp5VqWFXYIP00g94KET6XLjWUXH4P1J2zoa6hGennPXHA==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + + '@metaplex-foundation/umi-eddsa-web3js@0.9.2': + resolution: {integrity: sha512-hhPCxXbYIp4BC4z9gK78sXpWLkNSrfv4ndhF5ruAkdIp7GcRVYKj0QnOUO6lGYGiIkNlw20yoTwOe1CT//OfTQ==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + '@solana/web3.js': ^1.72.0 + + '@metaplex-foundation/umi-http-fetch@0.9.2': + resolution: {integrity: sha512-YCZuBu24T9ZzEDe4+w12LEZm/fO9pkyViZufGgASC5NX93814Lvf6Ssjn/hZzjfA7CvZbvLFbmujc6CV3Q/m9Q==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + + '@metaplex-foundation/umi-options@0.8.9': + resolution: {integrity: sha512-jSQ61sZMPSAk/TXn8v8fPqtz3x8d0/blVZXLLbpVbo2/T5XobiI6/MfmlUosAjAUaQl6bHRF8aIIqZEFkJiy4A==} + + '@metaplex-foundation/umi-program-repository@0.9.2': + resolution: {integrity: sha512-g3+FPqXEmYsBa8eETtUE2gb2Oe3mqac0z3/Ur1TvAg5TtIy3mzRzOy/nza+sgzejnfcxcVg835rmpBaxpBnjDA==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + + '@metaplex-foundation/umi-public-keys@0.8.9': + resolution: {integrity: sha512-CxMzN7dgVGOq9OcNCJe2casKUpJ3RmTVoOvDFyeoTQuK+vkZ1YSSahbqC1iGuHEtKTLSjtWjKvUU6O7zWFTw3Q==} + + '@metaplex-foundation/umi-rpc-chunk-get-accounts@0.9.2': + resolution: {integrity: sha512-YRwVf6xH0jPBAUgMhEPi+UbjioAeqTXmjsN2TnmQCPAmHbrHrMRj0rlWYwFLWAgkmoxazYrXP9lqOFRrfOGAEA==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + + '@metaplex-foundation/umi-rpc-web3js@0.9.2': + resolution: {integrity: sha512-MqcsBz8B4wGl6jxsf2Jo/rAEpYReU9VCSR15QSjhvADHMmdFxCIZCCAgE+gDE2Vuanfl437VhOcP3g5Uw8C16Q==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + '@solana/web3.js': ^1.72.0 + + '@metaplex-foundation/umi-serializer-data-view@0.9.2': + resolution: {integrity: sha512-5vGptadJxUxvUcyrwFZxXlEc6Q7AYySBesizCtrBFUY8w8PnF2vzmS45CP1MLySEATNH6T9mD4Rs0tLb87iQyA==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + + '@metaplex-foundation/umi-serializers-core@0.8.9': + resolution: {integrity: sha512-WT82tkiYJ0Qmscp7uTj1Hz6aWQPETwaKLAENAUN5DeWghkuBKtuxyBKVvEOuoXerJSdhiAk0e8DWA4cxcTTQ/w==} + + '@metaplex-foundation/umi-serializers-encodings@0.8.9': + resolution: {integrity: sha512-N3VWLDTJ0bzzMKcJDL08U3FaqRmwlN79FyE4BHj6bbAaJ9LEHjDQ9RJijZyWqTm0jE7I750fU7Ow5EZL38Xi6Q==} + + '@metaplex-foundation/umi-serializers-numbers@0.8.9': + resolution: {integrity: sha512-NtBf1fnVNQJHFQjLFzRu2i9GGnigb9hOm/Gfrk628d0q0tRJB7BOM3bs5C61VAs7kJs4yd+pDNVAERJkknQ7Lg==} + + '@metaplex-foundation/umi-serializers@0.9.0': + resolution: {integrity: sha512-hAOW9Djl4w4ioKeR4erDZl5IG4iJdP0xA19ZomdaCbMhYAAmG/FEs5khh0uT2mq53/MnzWcXSUPoO8WBN4Q+Vg==} + + '@metaplex-foundation/umi-signer-wallet-adapters@0.9.2': + resolution: {integrity: sha512-DFG0ZFocKG8briypSkG9bGUTVsWpAgYugsl2BzTygkGExc4evWfF4Sb1F2C2w9FdrA9ESZM1gpLX9xtx5taOXg==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + '@solana/web3.js': ^1.72.0 + + '@metaplex-foundation/umi-transaction-factory-web3js@0.9.2': + resolution: {integrity: sha512-fR1Kf21uylMFd1Smkltmj4jTNxhqSWf416owsJ+T+cvJi2VCOcOwq/3UFzOrpz78fA0RhsajKYKj0HYsRnQI1g==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + '@solana/web3.js': ^1.72.0 + + '@metaplex-foundation/umi-web3js-adapters@0.9.2': + resolution: {integrity: sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + '@solana/web3.js': ^1.72.0 + + '@metaplex-foundation/umi@0.9.2': + resolution: {integrity: sha512-9i4Acm4pruQfJcpRrc2EauPBwkfDN0I9QTvJyZocIlKgoZwD6A6wH0PViH1AjOVG5CQCd1YI3tJd5XjYE1ElBw==} + + '@mrgnlabs/marginfi-client-v2@6.1.0': + resolution: {integrity: sha512-8T93tWsp6BbFyKocQBTxaJ1RhslnseNtMO+TWPySpr8iNaUmFax15fuA6Ml/q/wgjZHu2sqNPy501UeDnCb/kw==} + + '@mrgnlabs/mrgn-common@2.0.3': + resolution: {integrity: sha512-OrCvFJv2mCHVqTDhVRRacLO8e1yHSXP1+PrQEAuxGHTnP8qQE51yFwRR+Ne8Gz6VMaD50BxWqsgBlT8/6hOStw==} + + '@noble/curves@1.9.4': + resolution: {integrity: sha512-2bKONnuM53lINoDrSmK8qP8W271ms7pygDhZt4SiLOoLwBtoHqeCFi6RG42V8zd3mLHuJFhU/Bmaqo4nX0/kBw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/ed25519@1.7.5': + resolution: {integrity: sha512-xuS0nwRMQBvSxDa7UxMb61xTiH3MxTgUfhyPUALVIe0FlOAz4sjELwyDRyUvqeEYfRSG9qNjFIycqLZppg4RSA==} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@prettier/sync@0.5.5': + resolution: {integrity: sha512-6BMtNr7aQhyNcGzmumkL0tgr1YQGfm9d7ZdmRpWqWuqpc9vZBind4xMe5NMiRECOhjuSiWHfBWLBnXkpeE90bw==} + peerDependencies: + prettier: '*' + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + + '@pythnetwork/price-service-sdk@1.8.0': + resolution: {integrity: sha512-tFZ1thj3Zja06DzPIX2dEWSi7kIfIyqreoywvw5NQ3Z1pl5OJHQGMEhxt6Li3UCGSp2ooYZS9wl8/8XfrfrNSA==} + + '@pythnetwork/pyth-solana-receiver@0.8.2': + resolution: {integrity: sha512-WrrdwwhSYvvB5vJEL+SfPnfuxgkRKMeKdZvGFFwe6ENrMhrQCM05oDkvNNYfXATLcpQGRAyBu9l1xIxUxixpqw==} + + '@pythnetwork/solana-utils@0.4.2': + resolution: {integrity: sha512-hKo7Bcs/kDWA5Fnqhg9zJSB94NMoUDIDjHjSi/uvZOzwizISUQI6oY3LWd2CXzNh4f8djjY2BS5iNHaM4cm8Bw==} + + '@solana/buffer-layout-utils@0.2.0': + resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} + engines: {node: '>= 10'} + + '@solana/buffer-layout@4.0.1': + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + + '@solana/codecs-core@2.0.0-preview.1': + resolution: {integrity: sha512-0y3kgFSJAOApNGefEOgLRMiXOHVmcF29Xw3zmR4LDUABvytG3ecKMXGz5oLt3vdaU2CyN3tuUVeGmQjrd0U1kw==} + + '@solana/codecs-core@2.0.0-rc.1': + resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-core@2.3.0': + resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-data-structures@2.0.0-rc.1': + resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-numbers@2.0.0-preview.1': + resolution: {integrity: sha512-NFA8itgcYUY3hkWMBpVRozd2poy1zfOvkIWZKx/D69oIMUtQTBpKrodRVBuhlBkAv12vDNkFljqVySpcMZMl7A==} + + '@solana/codecs-numbers@2.0.0-rc.1': + resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-numbers@2.3.0': + resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-strings@2.0.0-preview.1': + resolution: {integrity: sha512-kBAxE9ZD5/c8j9CkPxqc55dbo7R50Re3k94SXR+k13DZCCs37Fyn0/mAkw/S95fofbi/zsi4jSfmsT5vCZD75A==} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + + '@solana/codecs-strings@2.0.0-rc.1': + resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5' + + '@solana/codecs@2.0.0-rc.1': + resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} + peerDependencies: + typescript: '>=5' + + '@solana/errors@2.0.0-preview.1': + resolution: {integrity: sha512-mnBWfLVwMH4hxwb4sWZ7G7djQCMsyymjysvUPDiF89LueTBm1hfdxUv8Cy1uUCGsJ3jO3scdPwB4noOgr0rG/g==} + hasBin: true + + '@solana/errors@2.0.0-rc.1': + resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} + hasBin: true + peerDependencies: + typescript: '>=5' + + '@solana/errors@2.3.0': + resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' + + '@solana/options@2.0.0-rc.1': + resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} + peerDependencies: + typescript: '>=5' + + '@solana/spl-token-group@0.0.7': + resolution: {integrity: sha512-V1N/iX7Cr7H0uazWUT2uk27TMqlqedpXHRqqAbVO2gvmJyT0E0ummMEAVQeXZ05ZhQ/xF39DLSdBp90XebWEug==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.3 + + '@solana/spl-token-metadata@0.1.6': + resolution: {integrity: sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.3 + + '@solana/spl-token@0.1.8': + resolution: {integrity: sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==} + engines: {node: '>= 10'} + + '@solana/spl-token@0.3.11': + resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.88.0 + + '@solana/spl-token@0.4.13': + resolution: {integrity: sha512-cite/pYWQZZVvLbg5lsodSovbetK/eA24gaR0eeUeMuBAMNrT8XFCwaygKy0N2WSg3gSyjjNpIeAGBAKZaY/1w==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.5 + + '@solana/wallet-adapter-base@0.9.27': + resolution: {integrity: sha512-kXjeNfNFVs/NE9GPmysBRKQ/nf+foSaq3kfVSeMcO/iVgigyRmB551OjU3WyAolLG/1jeEfKLqF9fKwMCRkUqg==} + engines: {node: '>=20'} + peerDependencies: + '@solana/web3.js': ^1.98.0 + + '@solana/wallet-standard-features@1.3.0': + resolution: {integrity: sha512-ZhpZtD+4VArf6RPitsVExvgkF+nGghd1rzPjd97GmBximpnt1rsUxMOEyoIEuH3XBxPyNB6Us7ha7RHWQR+abg==} + engines: {node: '>=16'} + + '@solana/web3.js@1.77.4': + resolution: {integrity: sha512-XdN0Lh4jdY7J8FYMyucxCwzn6Ga2Sr1DHDWRbqVzk7ZPmmpSPOVWHzO67X1cVT+jNi1D6gZi2tgjHgDPuj6e9Q==} + + '@solana/web3.js@1.95.8': + resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} + + '@solana/web3.js@1.98.2': + resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} + + '@solworks/soltoolkit-sdk@0.0.23': + resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} + + '@soncodi/signal@2.0.7': + resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} + + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + + '@switchboard-xyz/common@2.5.19': + resolution: {integrity: sha512-Bzj1bu2U69YRh2OoNjkrafdREeB1KH+wmeFkBsASDjlhy/xXjey2Ry2HUTAIzdg2DMtfP6DoCW2Nn9ZQD5IO+Q==} + engines: {node: '>=12'} + + '@switchboard-xyz/common@3.0.12': + resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} + engines: {node: '>=20'} + + '@switchboard-xyz/common@3.4.1': + resolution: {integrity: sha512-TropBlBYuDeBnmGHkPSmgC3clLqAxy51ZGbwk4ejAgadnszWOgYHcH7taRG4Ha17DYSCWw/LGMBKbunGo+Aoaw==} + engines: {node: '>=20'} + + '@switchboard-xyz/on-demand@1.2.51': + resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} + engines: {node: '>= 18'} + deprecated: deprecated in favor of 2.x.x + + '@switchboard-xyz/on-demand@1.2.67': + resolution: {integrity: sha512-rtGA+9tQHb/xQnUFgVzyaOs2uKgnwP7OqYQLEOjTDdNTEEgU8OTR72ujluOEYB9LMByb7h9SRuOR353vxYQhYA==} + engines: {node: '>= 18'} + deprecated: deprecated in favor of 2.x.x + + '@types/bn.js@5.2.0': + resolution: {integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/node-fetch@2.6.12': + resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@18.19.119': + resolution: {integrity: sha512-d0F6m9itIPaKnrvEMlzE48UjwZaAnFW7Jwibacw9MNdqadjKNpUm9tfJYDwmShJmgqcoqYUX3EMKO1+RWiuuNg==} + + '@types/node@24.0.14': + resolution: {integrity: sha512-4zXMWD91vBLGRtHK3YbIoFMia+1nqEz72coM42C5ETjnNCa/heoj7NT1G67iAfOqMmcfhuCZ4uNpyz8EjlAejw==} + + '@types/uuid@8.3.4': + resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} + + '@types/ws@7.4.7': + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@wallet-standard/base@1.1.0': + resolution: {integrity: sha512-DJDQhjKmSNVLKWItoKThJS+CsJQjR9AOBOirBVT1F9YpRyC9oYHE+ZnSf8y8bxUphtKqdQMPVQ2mHohYdRvDVQ==} + engines: {node: '>=16'} + + '@wallet-standard/features@1.1.0': + resolution: {integrity: sha512-hiEivWNztx73s+7iLxsuD1sOJ28xtRix58W7Xnz4XzzA/pF0+aicnWgjOdA10doVDEDZdUuZCIIqG96SFNlDUg==} + engines: {node: '>=16'} + + '@zod/core@0.11.6': + resolution: {integrity: sha512-03Bv82fFSfjDAvMfdHHdGSS6SOJs0iCcJlWJv1kJHRtoTT02hZpyip/2Lk6oo4l4FtjuwTrsEQTwg/LD8I7dJA==} + + a-sync-waterfall@1.0.1: + resolution: {integrity: sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==} + + agentkeepalive@4.6.0: + resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} + engines: {node: '>= 8.0.0'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.10.0: + resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + + base-x@3.0.11: + resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} + + base-x@4.0.1: + resolution: {integrity: sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==} + + base-x@5.0.1: + resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + big.js@6.2.2: + resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + + bigint-buffer@1.1.5: + resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} + engines: {node: '>= 10.0.0'} + + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bn.js@5.2.2: + resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} + + borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + + borsh@2.0.0: + resolution: {integrity: sha512-kc9+BgR3zz9+cjbwM8ODoUB4fs3X3I5A/HtX7LZKxCLaMrEeDFoBpnhZY//DTS1VZBSs6S5v46RZRbZjRFspEg==} + + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + bs58@5.0.0: + resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} + + bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + + buffer-layout@1.2.2: + resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==} + engines: {node: '>=4.5'} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bufferutil@4.0.9: + resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} + engines: {node: '>=6.14.2'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@14.0.0: + resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} + engines: {node: '>=20'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + + cron-validator@1.4.0: + resolution: {integrity: sha512-wGcJ9FCy65iaU6egSH8b5dZYJF7GU/3Jh06wzaT9lsa5dbqExjljmu+0cJ8cpKn+vUyZa/EM4WAxeLR6SypJXw==} + + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + + crypto-hash@1.3.0: + resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} + engines: {node: '>=8'} + + crypto-hash@3.1.0: + resolution: {integrity: sha512-HR8JlZ+Dn54Lc5gGWZJxJitWbOCUzWb9/AlyONGecBnYZ+n/ONvt0gQnEzDNpJMYeRrYO7KogQ4qwyTPKnWKEw==} + engines: {node: '>=18'} + + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + + dotenv@10.0.0: + resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==} + engines: {node: '>=10'} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + + es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + + fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + + fastestsmallesttextencoderdecoder@1.0.22: + resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + engines: {node: '>= 6'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + + jayson@4.2.0: + resolution: {integrity: sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg==} + engines: {node: '>=8'} + hasBin: true + + jito-ts@3.0.1: + resolution: {integrity: sha512-TSofF7KqcwyaWGjPaSYC8RDoNBY1TPRNBHdrw24bdIi7mQ5bFEDdYK3D//llw/ml8YDvcZlgd644WxhjLTS9yg==} + + js-sha256@0.11.1: + resolution: {integrity: sha512-o6WSo/LUvY2uC4j7mO50a2ms7E/EAdbP0swigLV+nzHKTTaYnaLIWJ02VdXrsJX0vGedDESQnLsOekr94ryfjg==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-stable-stringify@1.3.0: + resolution: {integrity: sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==} + engines: {node: '>= 0.4'} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + jsonify@0.0.1: + resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + + make-synchronized@0.4.2: + resolution: {integrity: sha512-EwEJSg8gSGLicKXp/VzNi1tvzhdmNBxOzslkkJSoNUCQFZKH/NIUIp7xlfN+noaHrz4BJDN73gne8IHnjl/F/A==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + numeral@2.0.6: + resolution: {integrity: sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==} + + nunjucks@3.2.4: + resolution: {integrity: sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==} + engines: {node: '>= 6.9.0'} + hasBin: true + peerDependencies: + chokidar: ^3.3.0 + peerDependenciesMeta: + chokidar: + optional: true + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} + hasBin: true + + protobufjs@7.5.3: + resolution: {integrity: sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==} + engines: {node: '>=12.0.0'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + rpc-websockets@7.11.0: + resolution: {integrity: sha512-IkLYjayPv6Io8C/TdCL5gwgzd1hFz2vmBZrjMw/SPEXo51ETOhnzgS4Qy5GWi2JQN7HKHa66J3+2mv0fgNh/7w==} + deprecated: deprecate 7.11.0 + + rpc-websockets@7.11.2: + resolution: {integrity: sha512-pL9r5N6AVHlMN/vT98+fcO+5+/UcPLf/4tq+WUaid/PPUGS/ttJ3y8e9IqmaWKtShNAysMSjkczuEA49NuV7UQ==} + + rpc-websockets@9.1.1: + resolution: {integrity: sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + + stream-chain@2.2.5: + resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==} + + stream-json@1.9.1: + resolution: {integrity: sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + superstruct@0.14.2: + resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} + + superstruct@0.15.5: + resolution: {integrity: sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==} + + superstruct@1.0.4: + resolution: {integrity: sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==} + engines: {node: '>=14.0.0'} + + superstruct@2.0.2: + resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} + engines: {node: '>=14.0.0'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + + toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici-types@7.8.0: + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} + + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaml@2.8.0: + resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + zod@4.0.0-beta.20250505T195954: + resolution: {integrity: sha512-iB8WvxkobVIXMARvQu20fKvbS7mUTiYRpcD8OQV1xjRhxO0EEpYIRJBk6yfBzHAHEdOSDh3SxDITr5Eajr2vtg==} + +snapshots: + + '@babel/runtime@7.27.6': {} + + '@brokerloop/ttlcache@3.2.3': dependencies: '@soncodi/signal': 2.0.7 - dev: true - /@common.js/quick-lru@7.0.0: - resolution: {integrity: sha512-DO3vApnH1vLizdWRSqzhg+S956vptHhtO+vw6PP6StJGDtaAGyfKSSPPGYWguJZu/Jlti6l6m6jB8NrKEQexLg==} - engines: {node: '>=18'} - dev: false + '@common.js/quick-lru@7.0.0': {} - /@coral-xyz/anchor-errors@0.30.1: - resolution: {integrity: sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==} - engines: {node: '>=10'} + '@coral-xyz/anchor-errors@0.30.1': {} - /@coral-xyz/anchor@0.29.0: - resolution: {integrity: sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==} - engines: {node: '>=11'} + '@coral-xyz/anchor@0.29.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.95.4) - '@noble/hashes': 1.5.0 - '@solana/web3.js': 1.95.4 - bn.js: 5.2.1 + '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) + '@noble/hashes': 1.8.0 + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + bn.js: 5.2.2 bs58: 4.0.1 buffer-layout: 1.2.2 camelcase: 6.3.0 - cross-fetch: 3.1.8 + cross-fetch: 3.2.0 crypto-hash: 1.3.0 eventemitter3: 4.0.7 pako: 2.1.0 @@ -70,22 +998,20 @@ packages: transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate - dev: false - /@coral-xyz/anchor@0.30.1: - resolution: {integrity: sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==} - engines: {node: '>=11'} + '@coral-xyz/anchor@0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@coral-xyz/anchor-errors': 0.30.1 - '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.4) - '@noble/hashes': 1.5.0 - '@solana/web3.js': 1.95.4 - bn.js: 5.2.1 + '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@noble/hashes': 1.8.0 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + bn.js: 5.2.2 bs58: 4.0.1 buffer-layout: 1.2.2 camelcase: 6.3.0 - cross-fetch: 3.1.8 + cross-fetch: 3.2.0 crypto-hash: 1.3.0 eventemitter3: 4.0.7 pako: 2.1.0 @@ -97,540 +1023,354 @@ packages: - encoding - utf-8-validate - /@coral-xyz/borsh@0.29.0(@solana/web3.js@1.95.4): - resolution: {integrity: sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==} - engines: {node: '>=10'} - peerDependencies: - '@solana/web3.js': ^1.68.0 + '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.95.4 - bn.js: 5.2.1 + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + bn.js: 5.2.2 buffer-layout: 1.2.2 - dev: false - /@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.4): - resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} - engines: {node: '>=10'} - peerDependencies: - '@solana/web3.js': ^1.68.0 + '@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.95.4 - bn.js: 5.2.1 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + bn.js: 5.2.2 buffer-layout: 1.2.2 - /@grpc/grpc-js@1.13.2: - resolution: {integrity: sha512-nnR5nmL6lxF8YBqb6gWvEgLdLh/Fn+kvAdX5hUOnt48sNSb0riz/93ASd2E5gvanPA41X6Yp25bIfGRp1SMb2g==} - engines: {node: '>=12.10.0'} + '@coral-xyz/borsh@0.30.1(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))': + dependencies: + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + bn.js: 5.2.2 + buffer-layout: 1.2.2 + + '@grpc/grpc-js@1.13.4': dependencies: - '@grpc/proto-loader': 0.7.13 + '@grpc/proto-loader': 0.7.15 '@js-sdsl/ordered-map': 4.4.2 - dev: false - /@grpc/proto-loader@0.7.13: - resolution: {integrity: sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==} - engines: {node: '>=6'} - hasBin: true + '@grpc/proto-loader@0.7.15': dependencies: lodash.camelcase: 4.3.0 - long: 5.2.3 - protobufjs: 7.4.0 + long: 5.3.2 + protobufjs: 7.5.3 yargs: 17.7.2 - dev: false - - /@js-sdsl/ordered-map@4.4.2: - resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} - dev: false - - /@jup-ag/api@6.0.24: - resolution: {integrity: sha512-zIX4WIPb0Kb2UnK2wNIOQBWqPJyMJq/D9dQTf/2qvPb0hfa8XdgbrQAzomHMHnAzw9StMQoybBk+JK/A76xP3w==} - dev: true - /@metaplex-foundation/beet-solana@0.4.0: - resolution: {integrity: sha512-B1L94N3ZGMo53b0uOSoznbuM5GBNJ8LwSeznxBxJ+OThvfHQ4B5oMUqb+0zdLRfkKGS7Q6tpHK9P+QK0j3w2cQ==} + '@haven-fi/solauto-sdk@file:solauto-sdk(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@metaplex-foundation/beet': 0.7.1 - '@solana/web3.js': 1.95.3 + '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@jup-ag/api': 6.0.24 + '@metaplex-foundation/umi': 0.9.2 + '@metaplex-foundation/umi-bundle-defaults': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metaplex-foundation/umi-signer-wallet-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/spl-token': 0.4.13(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@switchboard-xyz/common': 3.0.12(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@switchboard-xyz/on-demand': 1.2.51(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10) + axios: 1.10.0 + big.js: 6.2.2 bs58: 5.0.0 - debug: 4.3.7 + cross-fetch: 4.1.0 + dotenv: 16.6.1 + rpc-websockets: 7.11.0 transitivePeerDependencies: - bufferutil + - debug - encoding - - supports-color + - fastestsmallesttextencoderdecoder + - typescript - utf-8-validate - dev: true - /@metaplex-foundation/beet@0.7.1: - resolution: {integrity: sha512-hNCEnS2WyCiYyko82rwuISsBY3KYpe828ubsd2ckeqZr7tl0WVLivGkoyA/qdiaaHEBGdGl71OpfWa2rqL3DiA==} - dependencies: - ansicolors: 0.3.2 - bn.js: 5.2.1 - debug: 4.3.7 - transitivePeerDependencies: - - supports-color - dev: true + '@js-sdsl/ordered-map@4.4.2': {} - /@metaplex-foundation/cusper@0.0.2: - resolution: {integrity: sha512-S9RulC2fFCFOQraz61bij+5YCHhSO9llJegK8c8Y6731fSi6snUSQJdCUqYS8AIgR0TKbQvdvgSyIIdbDFZbBA==} - dev: true + '@jup-ag/api@6.0.24': {} - /@metaplex-foundation/kinobi@0.18.5(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-qh4h4xGB+PHR5o4rcZki+wsIeZYi6R9SRV5UMqGi/rfDJXk0ckAZ+fxdam+mCc4N8HWLLWmEJbF5gx8E5K0fOA==} + '@metaplex-foundation/kinobi@0.18.5(fastestsmallesttextencoderdecoder@1.0.22)': dependencies: - '@noble/hashes': 1.5.0 - '@prettier/sync': 0.5.2(prettier@3.3.3) + '@noble/hashes': 1.8.0 + '@prettier/sync': 0.5.5(prettier@3.6.2) '@solana/codecs-strings': 2.0.0-preview.1(fastestsmallesttextencoderdecoder@1.0.22) chalk: 4.1.2 - json-stable-stringify: 1.1.1 + json-stable-stringify: 1.3.0 nunjucks: 3.2.4 - prettier: 3.3.3 + prettier: 3.6.2 transitivePeerDependencies: - chokidar - fastestsmallesttextencoderdecoder - dev: false - /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-kV3tfvgvRjVP1p9OFOtH+ibOtN9omVJSwKr0We4/9r45e5LTj+32su0V/rixZUkG1EZzzOYBsxhtIE0kIw/Hrw==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 - '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 '@metaplex-foundation/umi-downloader-http': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@metaplex-foundation/umi-http-fetch': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-program-repository': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-rpc-chunk-get-accounts': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@metaplex-foundation/umi-serializer-data-view': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 + '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - encoding - dev: true - /@metaplex-foundation/umi-downloader-http@0.9.2(@metaplex-foundation/umi@0.9.2): - resolution: {integrity: sha512-tzPT9hBwenzTzAQg07rmsrqZfgguAXELbcJrsYMoASp5VqWFXYIP00g94KET6XLjWUXH4P1J2zoa6hGennPXHA==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 + '@metaplex-foundation/umi-downloader-http@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: '@metaplex-foundation/umi': 0.9.2 - dev: true - /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-hhPCxXbYIp4BC4z9gK78sXpWLkNSrfv4ndhF5ruAkdIp7GcRVYKj0QnOUO6lGYGiIkNlw20yoTwOe1CT//OfTQ==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 - '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@noble/curves': 1.6.0 - '@solana/web3.js': 1.95.8 - dev: true + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@noble/curves': 1.9.4 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - /@metaplex-foundation/umi-http-fetch@0.9.2(@metaplex-foundation/umi@0.9.2): - resolution: {integrity: sha512-YCZuBu24T9ZzEDe4+w12LEZm/fO9pkyViZufGgASC5NX93814Lvf6Ssjn/hZzjfA7CvZbvLFbmujc6CV3Q/m9Q==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 + '@metaplex-foundation/umi-http-fetch@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: '@metaplex-foundation/umi': 0.9.2 node-fetch: 2.7.0 transitivePeerDependencies: - encoding - dev: true - /@metaplex-foundation/umi-options@0.8.9: - resolution: {integrity: sha512-jSQ61sZMPSAk/TXn8v8fPqtz3x8d0/blVZXLLbpVbo2/T5XobiI6/MfmlUosAjAUaQl6bHRF8aIIqZEFkJiy4A==} - dev: true + '@metaplex-foundation/umi-options@0.8.9': {} - /@metaplex-foundation/umi-program-repository@0.9.2(@metaplex-foundation/umi@0.9.2): - resolution: {integrity: sha512-g3+FPqXEmYsBa8eETtUE2gb2Oe3mqac0z3/Ur1TvAg5TtIy3mzRzOy/nza+sgzejnfcxcVg835rmpBaxpBnjDA==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 + '@metaplex-foundation/umi-program-repository@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: '@metaplex-foundation/umi': 0.9.2 - dev: true - /@metaplex-foundation/umi-public-keys@0.8.9: - resolution: {integrity: sha512-CxMzN7dgVGOq9OcNCJe2casKUpJ3RmTVoOvDFyeoTQuK+vkZ1YSSahbqC1iGuHEtKTLSjtWjKvUU6O7zWFTw3Q==} + '@metaplex-foundation/umi-public-keys@0.8.9': dependencies: '@metaplex-foundation/umi-serializers-encodings': 0.8.9 - dev: true - /@metaplex-foundation/umi-rpc-chunk-get-accounts@0.9.2(@metaplex-foundation/umi@0.9.2): - resolution: {integrity: sha512-YRwVf6xH0jPBAUgMhEPi+UbjioAeqTXmjsN2TnmQCPAmHbrHrMRj0rlWYwFLWAgkmoxazYrXP9lqOFRrfOGAEA==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 + '@metaplex-foundation/umi-rpc-chunk-get-accounts@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: '@metaplex-foundation/umi': 0.9.2 - dev: true - /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-MqcsBz8B4wGl6jxsf2Jo/rAEpYReU9VCSR15QSjhvADHMmdFxCIZCCAgE+gDE2Vuanfl437VhOcP3g5Uw8C16Q==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 - '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 - dev: true + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - /@metaplex-foundation/umi-serializer-data-view@0.9.2(@metaplex-foundation/umi@0.9.2): - resolution: {integrity: sha512-5vGptadJxUxvUcyrwFZxXlEc6Q7AYySBesizCtrBFUY8w8PnF2vzmS45CP1MLySEATNH6T9mD4Rs0tLb87iQyA==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 + '@metaplex-foundation/umi-serializer-data-view@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: '@metaplex-foundation/umi': 0.9.2 - dev: true - /@metaplex-foundation/umi-serializers-core@0.8.9: - resolution: {integrity: sha512-WT82tkiYJ0Qmscp7uTj1Hz6aWQPETwaKLAENAUN5DeWghkuBKtuxyBKVvEOuoXerJSdhiAk0e8DWA4cxcTTQ/w==} - dev: true + '@metaplex-foundation/umi-serializers-core@0.8.9': {} - /@metaplex-foundation/umi-serializers-encodings@0.8.9: - resolution: {integrity: sha512-N3VWLDTJ0bzzMKcJDL08U3FaqRmwlN79FyE4BHj6bbAaJ9LEHjDQ9RJijZyWqTm0jE7I750fU7Ow5EZL38Xi6Q==} + '@metaplex-foundation/umi-serializers-encodings@0.8.9': dependencies: '@metaplex-foundation/umi-serializers-core': 0.8.9 - dev: true - /@metaplex-foundation/umi-serializers-numbers@0.8.9: - resolution: {integrity: sha512-NtBf1fnVNQJHFQjLFzRu2i9GGnigb9hOm/Gfrk628d0q0tRJB7BOM3bs5C61VAs7kJs4yd+pDNVAERJkknQ7Lg==} + '@metaplex-foundation/umi-serializers-numbers@0.8.9': dependencies: '@metaplex-foundation/umi-serializers-core': 0.8.9 - dev: true - /@metaplex-foundation/umi-serializers@0.9.0: - resolution: {integrity: sha512-hAOW9Djl4w4ioKeR4erDZl5IG4iJdP0xA19ZomdaCbMhYAAmG/FEs5khh0uT2mq53/MnzWcXSUPoO8WBN4Q+Vg==} + '@metaplex-foundation/umi-serializers@0.9.0': dependencies: '@metaplex-foundation/umi-options': 0.8.9 '@metaplex-foundation/umi-public-keys': 0.8.9 '@metaplex-foundation/umi-serializers-core': 0.8.9 '@metaplex-foundation/umi-serializers-encodings': 0.8.9 '@metaplex-foundation/umi-serializers-numbers': 0.8.9 - dev: true - /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-DFG0ZFocKG8briypSkG9bGUTVsWpAgYugsl2BzTygkGExc4evWfF4Sb1F2C2w9FdrA9ESZM1gpLX9xtx5taOXg==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 - '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 - dev: true + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-fR1Kf21uylMFd1Smkltmj4jTNxhqSWf416owsJ+T+cvJi2VCOcOwq/3UFzOrpz78fA0RhsajKYKj0HYsRnQI1g==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 - '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 - dev: true + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 - '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) buffer: 6.0.3 - dev: true - /@metaplex-foundation/umi@0.9.2: - resolution: {integrity: sha512-9i4Acm4pruQfJcpRrc2EauPBwkfDN0I9QTvJyZocIlKgoZwD6A6wH0PViH1AjOVG5CQCd1YI3tJd5XjYE1ElBw==} + '@metaplex-foundation/umi@0.9.2': dependencies: '@metaplex-foundation/umi-options': 0.8.9 '@metaplex-foundation/umi-public-keys': 0.8.9 '@metaplex-foundation/umi-serializers': 0.9.0 - dev: true - - /@mrgnlabs/marginfi-client-v2@6.0.1: - resolution: {integrity: sha512-I4IdrS+fAIhkcgqXmRfwsuZDRgzSipy1Ok8L8Wm3NGgw6JFvTje6qYJ2rNKdZOpZaTDl2q+kZc/GD5EhJkQrLA==} - dependencies: - '@coral-xyz/anchor': 0.30.1 - '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.4) - '@mrgnlabs/mrgn-common': 2.0.2 - '@pythnetwork/pyth-solana-receiver': 0.8.2 - '@solana/spl-token': 0.1.8 - '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.95.4) - '@solana/web3.js': 1.95.4 - '@switchboard-xyz/on-demand': 1.2.67 - bignumber.js: 9.1.2 + + '@mrgnlabs/marginfi-client-v2@6.1.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': + dependencies: + '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) + '@mrgnlabs/mrgn-common': 2.0.3(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@pythnetwork/pyth-solana-receiver': 0.8.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/spl-token': 0.1.8(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/wallet-adapter-base': 0.9.27(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@switchboard-xyz/on-demand': 1.2.67(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + bignumber.js: 9.3.1 borsh: 2.0.0 bs58: 6.0.0 crypto-hash: 3.1.0 - decimal.js: 10.4.3 + decimal.js: 10.6.0 superstruct: 1.0.4 transitivePeerDependencies: - bufferutil - debug - encoding + - typescript - utf-8-validate - dev: false - /@mrgnlabs/mrgn-common@2.0.2: - resolution: {integrity: sha512-PypRjfnLPN4HPLz6VOyq7FpcbZPvG1CsZzBX7YMTBBiIZElt8NVk9cMZvTjZS7FzjgBdli0l8L60gt1ZdV2jvg==} + '@mrgnlabs/mrgn-common@2.0.3(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/anchor': 0.30.1 + '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.95.4) - '@solana/web3.js': 1.95.4 - bignumber.js: 9.1.2 + '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/wallet-adapter-base': 0.9.27(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + bignumber.js: 9.3.1 bs58: 6.0.0 - decimal.js: 10.4.3 + decimal.js: 10.6.0 numeral: 2.0.6 superstruct: 1.0.4 transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate - dev: false - /@noble/curves@1.6.0: - resolution: {integrity: sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==} - engines: {node: ^14.21.3 || >=16} + '@noble/curves@1.9.4': dependencies: - '@noble/hashes': 1.5.0 + '@noble/hashes': 1.8.0 - /@noble/ed25519@1.7.3: - resolution: {integrity: sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==} - dev: false + '@noble/ed25519@1.7.5': {} - /@noble/hashes@1.5.0: - resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} - engines: {node: ^14.21.3 || >=16} - - /@prettier/sync@0.5.2(prettier@3.3.3): - resolution: {integrity: sha512-Yb569su456XNx5BsH/Vyem7xD6g/y9iLmLUzRKM1a/dhU/D7HqqvkAG72znulXlMXztbV0iiu9O5AL8K98TzZQ==} - peerDependencies: - prettier: '*' + '@noble/hashes@1.8.0': {} + + '@prettier/sync@0.5.5(prettier@3.6.2)': dependencies: - make-synchronized: 0.2.9 - prettier: 3.3.3 - dev: false + make-synchronized: 0.4.2 + prettier: 3.6.2 - /@protobufjs/aspromise@1.1.2: - resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + '@protobufjs/aspromise@1.1.2': {} - /@protobufjs/base64@1.1.2: - resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + '@protobufjs/base64@1.1.2': {} - /@protobufjs/codegen@2.0.4: - resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + '@protobufjs/codegen@2.0.4': {} - /@protobufjs/eventemitter@1.1.0: - resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + '@protobufjs/eventemitter@1.1.0': {} - /@protobufjs/fetch@1.1.0: - resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + '@protobufjs/fetch@1.1.0': dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/inquire': 1.1.0 - /@protobufjs/float@1.0.2: - resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + '@protobufjs/float@1.0.2': {} - /@protobufjs/inquire@1.1.0: - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + '@protobufjs/inquire@1.1.0': {} - /@protobufjs/path@1.1.2: - resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + '@protobufjs/path@1.1.2': {} - /@protobufjs/pool@1.1.0: - resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + '@protobufjs/pool@1.1.0': {} - /@protobufjs/utf8@1.1.0: - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + '@protobufjs/utf8@1.1.0': {} - /@pythnetwork/price-service-sdk@1.8.0: - resolution: {integrity: sha512-tFZ1thj3Zja06DzPIX2dEWSi7kIfIyqreoywvw5NQ3Z1pl5OJHQGMEhxt6Li3UCGSp2ooYZS9wl8/8XfrfrNSA==} + '@pythnetwork/price-service-sdk@1.8.0': dependencies: - bn.js: 5.2.1 - dev: false + bn.js: 5.2.2 - /@pythnetwork/pyth-solana-receiver@0.8.2: - resolution: {integrity: sha512-WrrdwwhSYvvB5vJEL+SfPnfuxgkRKMeKdZvGFFwe6ENrMhrQCM05oDkvNNYfXATLcpQGRAyBu9l1xIxUxixpqw==} + '@pythnetwork/pyth-solana-receiver@0.8.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/anchor': 0.29.0 - '@noble/hashes': 1.5.0 + '@coral-xyz/anchor': 0.29.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@noble/hashes': 1.8.0 '@pythnetwork/price-service-sdk': 1.8.0 - '@pythnetwork/solana-utils': 0.4.2 - '@solana/web3.js': 1.95.4 + '@pythnetwork/solana-utils': 0.4.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate - dev: false - /@pythnetwork/solana-utils@0.4.2: - resolution: {integrity: sha512-hKo7Bcs/kDWA5Fnqhg9zJSB94NMoUDIDjHjSi/uvZOzwizISUQI6oY3LWd2CXzNh4f8djjY2BS5iNHaM4cm8Bw==} + '@pythnetwork/solana-utils@0.4.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/anchor': 0.29.0 - '@solana/web3.js': 1.95.4 + '@coral-xyz/anchor': 0.29.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) bs58: 5.0.0 - jito-ts: 3.0.1 + jito-ts: 3.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate - dev: false - /@solana/buffer-layout-utils@0.2.0: - resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} - engines: {node: '>= 10'} + '@solana/buffer-layout-utils@0.2.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.95.4 + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) bigint-buffer: 1.1.5 - bignumber.js: 9.1.2 + bignumber.js: 9.3.1 transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate - /@solana/buffer-layout@4.0.1: - resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} - engines: {node: '>=5.10'} + '@solana/buffer-layout@4.0.1': dependencies: buffer: 6.0.3 - /@solana/codecs-core@2.0.0-preview.1: - resolution: {integrity: sha512-0y3kgFSJAOApNGefEOgLRMiXOHVmcF29Xw3zmR4LDUABvytG3ecKMXGz5oLt3vdaU2CyN3tuUVeGmQjrd0U1kw==} + '@solana/codecs-core@2.0.0-preview.1': dependencies: '@solana/errors': 2.0.0-preview.1 - dev: false - - /@solana/codecs-core@2.0.0-preview.4(typescript@4.9.5): - resolution: {integrity: sha512-A0VVuDDA5kNKZUinOqHxJQK32aKTucaVbvn31YenGzHX1gPqq+SOnFwgaEY6pq4XEopSmaK16w938ZQS8IvCnw==} - peerDependencies: - typescript: '>=5' - dependencies: - '@solana/errors': 2.0.0-preview.4(typescript@4.9.5) - typescript: 4.9.5 - dev: true - /@solana/codecs-core@2.0.0-rc.1(typescript@4.9.5): - resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} - peerDependencies: - typescript: '>=5' + '@solana/codecs-core@2.0.0-rc.1(typescript@4.9.5)': dependencies: '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) typescript: 4.9.5 - dev: true - /@solana/codecs-data-structures@2.0.0-preview.4(typescript@4.9.5): - resolution: {integrity: sha512-nt2k2eTeyzlI/ccutPcG36M/J8NAYfxBPI9h/nQjgJ+M+IgOKi31JV8StDDlG/1XvY0zyqugV3I0r3KAbZRJpA==} - peerDependencies: - typescript: '>=5' + '@solana/codecs-core@2.3.0(typescript@4.9.5)': dependencies: - '@solana/codecs-core': 2.0.0-preview.4(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-preview.4(typescript@4.9.5) - '@solana/errors': 2.0.0-preview.4(typescript@4.9.5) + '@solana/errors': 2.3.0(typescript@4.9.5) typescript: 4.9.5 - dev: true - /@solana/codecs-data-structures@2.0.0-rc.1(typescript@4.9.5): - resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} - peerDependencies: - typescript: '>=5' + '@solana/codecs-data-structures@2.0.0-rc.1(typescript@4.9.5)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) typescript: 4.9.5 - dev: true - /@solana/codecs-numbers@2.0.0-preview.1: - resolution: {integrity: sha512-NFA8itgcYUY3hkWMBpVRozd2poy1zfOvkIWZKx/D69oIMUtQTBpKrodRVBuhlBkAv12vDNkFljqVySpcMZMl7A==} + '@solana/codecs-numbers@2.0.0-preview.1': dependencies: '@solana/codecs-core': 2.0.0-preview.1 '@solana/errors': 2.0.0-preview.1 - dev: false - /@solana/codecs-numbers@2.0.0-preview.4(typescript@4.9.5): - resolution: {integrity: sha512-Q061rLtMadsO7uxpguT+Z7G4UHnjQ6moVIxAQxR58nLxDPCC7MB1Pk106/Z7NDhDLHTcd18uO6DZ7ajHZEn2XQ==} - peerDependencies: - typescript: '>=5' + '@solana/codecs-numbers@2.0.0-rc.1(typescript@4.9.5)': dependencies: - '@solana/codecs-core': 2.0.0-preview.4(typescript@4.9.5) - '@solana/errors': 2.0.0-preview.4(typescript@4.9.5) + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) typescript: 4.9.5 - dev: true - /@solana/codecs-numbers@2.0.0-rc.1(typescript@4.9.5): - resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} - peerDependencies: - typescript: '>=5' + '@solana/codecs-numbers@2.3.0(typescript@4.9.5)': dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-core': 2.3.0(typescript@4.9.5) + '@solana/errors': 2.3.0(typescript@4.9.5) typescript: 4.9.5 - dev: true - /@solana/codecs-strings@2.0.0-preview.1(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-kBAxE9ZD5/c8j9CkPxqc55dbo7R50Re3k94SXR+k13DZCCs37Fyn0/mAkw/S95fofbi/zsi4jSfmsT5vCZD75A==} - peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 + '@solana/codecs-strings@2.0.0-preview.1(fastestsmallesttextencoderdecoder@1.0.22)': dependencies: '@solana/codecs-core': 2.0.0-preview.1 '@solana/codecs-numbers': 2.0.0-preview.1 '@solana/errors': 2.0.0-preview.1 fastestsmallesttextencoderdecoder: 1.0.22 - dev: false - /@solana/codecs-strings@2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-YDbsQePRWm+xnrfS64losSGRg8Wb76cjK1K6qfR8LPmdwIC3787x9uW5/E4icl/k+9nwgbIRXZ65lpF+ucZUnw==} - peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - typescript: '>=5' - dependencies: - '@solana/codecs-core': 2.0.0-preview.4(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-preview.4(typescript@4.9.5) - '@solana/errors': 2.0.0-preview.4(typescript@4.9.5) - fastestsmallesttextencoderdecoder: 1.0.22 - typescript: 4.9.5 - dev: true - - /@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} - peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - typescript: '>=5' + '@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) fastestsmallesttextencoderdecoder: 1.0.22 typescript: 4.9.5 - dev: true - - /@solana/codecs@2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-gLMupqI4i+G4uPi2SGF/Tc1aXcviZF2ybC81x7Q/fARamNSgNOCUUoSCg9nWu1Gid6+UhA7LH80sWI8XjKaRog==} - peerDependencies: - typescript: '>=5' - dependencies: - '@solana/codecs-core': 2.0.0-preview.4(typescript@4.9.5) - '@solana/codecs-data-structures': 2.0.0-preview.4(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-preview.4(typescript@4.9.5) - '@solana/codecs-strings': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/options': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - dev: true - /@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} - peerDependencies: - typescript: '>=5' + '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) @@ -640,57 +1380,25 @@ packages: typescript: 4.9.5 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - dev: true - - /@solana/errors@2.0.0-preview.1: - resolution: {integrity: sha512-mnBWfLVwMH4hxwb4sWZ7G7djQCMsyymjysvUPDiF89LueTBm1hfdxUv8Cy1uUCGsJ3jO3scdPwB4noOgr0rG/g==} - hasBin: true - dependencies: - chalk: 5.3.0 - commander: 12.1.0 - dev: false - /@solana/errors@2.0.0-preview.4(typescript@4.9.5): - resolution: {integrity: sha512-kadtlbRv2LCWr8A9V22On15Us7Nn8BvqNaOB4hXsTB3O0fU40D1ru2l+cReqLcRPij4znqlRzW9Xi0m6J5DIhA==} - hasBin: true - peerDependencies: - typescript: '>=5' + '@solana/errors@2.0.0-preview.1': dependencies: - chalk: 5.3.0 + chalk: 5.4.1 commander: 12.1.0 - typescript: 4.9.5 - dev: true - /@solana/errors@2.0.0-rc.1(typescript@4.9.5): - resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} - hasBin: true - peerDependencies: - typescript: '>=5' + '@solana/errors@2.0.0-rc.1(typescript@4.9.5)': dependencies: - chalk: 5.3.0 + chalk: 5.4.1 commander: 12.1.0 typescript: 4.9.5 - dev: true - /@solana/options@2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-tv2O/Frxql/wSe3jbzi5nVicIWIus/BftH+5ZR+r9r3FO0/htEllZS5Q9XdbmSboHu+St87584JXeDx3xm4jaA==} - peerDependencies: - typescript: '>=5' + '@solana/errors@2.3.0(typescript@4.9.5)': dependencies: - '@solana/codecs-core': 2.0.0-preview.4(typescript@4.9.5) - '@solana/codecs-data-structures': 2.0.0-preview.4(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-preview.4(typescript@4.9.5) - '@solana/codecs-strings': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/errors': 2.0.0-preview.4(typescript@4.9.5) + chalk: 5.4.1 + commander: 14.0.0 typescript: 4.9.5 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - dev: true - /@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} - peerDependencies: - typescript: '>=5' + '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) @@ -700,95 +1408,43 @@ packages: typescript: 4.9.5 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - dev: true - - /@solana/spl-token-group@0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-CLJnWEcdoUBpQJfx9WEbX3h6nTdNiUzswfFdkABUik7HVwSNA98u5AYvBVK2H93d9PGMOHAak2lHW9xr+zAJGQ==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.94.0 - dependencies: - '@solana/codecs': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.8 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - typescript - dev: true - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.3)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.95.3 + '@solana/spl-token-group@0.0.7(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.3 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript - dev: true - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.95.3 + '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript - dev: true - /@solana/spl-token@0.1.8: - resolution: {integrity: sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==} - engines: {node: '>= 10'} + '@solana/spl-token@0.1.8(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.25.7 - '@solana/web3.js': 1.95.4 - bn.js: 5.2.1 + '@babel/runtime': 7.27.6 + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + bn.js: 5.2.2 buffer: 6.0.3 buffer-layout: 1.2.2 dotenv: 10.0.0 transitivePeerDependencies: - bufferutil - encoding - - utf-8-validate - dev: false - - /@solana/spl-token@0.3.11(@solana/web3.js@1.95.3)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.88.0 - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.3)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.3 - buffer: 6.0.3 - transitivePeerDependencies: - - bufferutil - - encoding - - fastestsmallesttextencoderdecoder - typescript - utf-8-validate - dev: true - /@solana/spl-token@0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.88.0 + '@solana/spl-token@0.3.11(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8 + '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -796,19 +1452,14 @@ packages: - fastestsmallesttextencoderdecoder - typescript - utf-8-validate - dev: true - /@solana/spl-token@0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-RO0JD9vPRi4LsAbMUdNbDJ5/cv2z11MGhtAvFeRzT4+hAGE/FUzRi0tkkWtuCfSIU3twC6CtmAihRp/+XXjWsA==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.94.0 + '@solana/spl-token@0.4.13(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8 + '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/spl-token-group': 0.0.7(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -816,300 +1467,193 @@ packages: - fastestsmallesttextencoderdecoder - typescript - utf-8-validate - dev: true - - /@solana/spl-type-length-value@0.1.0: - resolution: {integrity: sha512-JBMGB0oR4lPttOZ5XiUGyvylwLQjt1CPJa6qQ5oM+MBCndfjz2TKKkw0eATlLLcYmq1jBVsNlJ2cD6ns2GR7lA==} - engines: {node: '>=16'} - dependencies: - buffer: 6.0.3 - dev: true - /@solana/wallet-adapter-base@0.9.24(@solana/web3.js@1.95.4): - resolution: {integrity: sha512-f3kwHF/2Lx3YgcO37B45MM46YLFy4QkdLemZ+N/0SwLAnSfhq3+Vb9bC5vuoupMJ/onos09TIDeIxRdg/+51kw==} - engines: {node: '>=20'} - peerDependencies: - '@solana/web3.js': ^1.77.3 + '@solana/wallet-adapter-base@0.9.27(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))': dependencies: '@solana/wallet-standard-features': 1.3.0 - '@solana/web3.js': 1.95.4 + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) '@wallet-standard/base': 1.1.0 '@wallet-standard/features': 1.1.0 - eventemitter3: 4.0.7 - dev: false + eventemitter3: 5.0.1 - /@solana/wallet-standard-features@1.3.0: - resolution: {integrity: sha512-ZhpZtD+4VArf6RPitsVExvgkF+nGghd1rzPjd97GmBximpnt1rsUxMOEyoIEuH3XBxPyNB6Us7ha7RHWQR+abg==} - engines: {node: '>=16'} + '@solana/wallet-standard-features@1.3.0': dependencies: '@wallet-standard/base': 1.1.0 '@wallet-standard/features': 1.1.0 - dev: false - /@solana/web3.js@1.77.4: - resolution: {integrity: sha512-XdN0Lh4jdY7J8FYMyucxCwzn6Ga2Sr1DHDWRbqVzk7ZPmmpSPOVWHzO67X1cVT+jNi1D6gZi2tgjHgDPuj6e9Q==} + '@solana/web3.js@1.77.4(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.25.7 - '@noble/curves': 1.6.0 - '@noble/hashes': 1.5.0 + '@babel/runtime': 7.27.6 + '@noble/curves': 1.9.4 + '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.5.0 + agentkeepalive: 4.6.0 bigint-buffer: 1.1.5 - bn.js: 5.2.1 + bn.js: 5.2.2 borsh: 0.7.0 bs58: 4.0.1 buffer: 6.0.3 fast-stable-stringify: 1.0.0 - jayson: 4.1.2 + jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) node-fetch: 2.7.0 - rpc-websockets: 7.11.0 + rpc-websockets: 7.11.2 superstruct: 0.14.2 transitivePeerDependencies: - bufferutil - encoding - utf-8-validate - dev: false - - /@solana/web3.js@1.95.3: - resolution: {integrity: sha512-O6rPUN0w2fkNqx/Z3QJMB9L225Ex10PRDH8bTaIUPZXMPV0QP8ZpPvjQnXK+upUczlRgzHzd6SjKIha1p+I6og==} - dependencies: - '@babel/runtime': 7.25.7 - '@noble/curves': 1.6.0 - '@noble/hashes': 1.5.0 - '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.5.0 - bigint-buffer: 1.1.5 - bn.js: 5.2.1 - borsh: 0.7.0 - bs58: 4.0.1 - buffer: 6.0.3 - fast-stable-stringify: 1.0.0 - jayson: 4.1.2 - node-fetch: 2.7.0 - rpc-websockets: 9.0.4 - superstruct: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: true - - /@solana/web3.js@1.95.4: - resolution: {integrity: sha512-sdewnNEA42ZSMxqkzdwEWi6fDgzwtJHaQa5ndUGEJYtoOnM6X5cvPmjoTUp7/k7bRrVAxfBgDnvQQHD6yhlLYw==} - dependencies: - '@babel/runtime': 7.25.7 - '@noble/curves': 1.6.0 - '@noble/hashes': 1.5.0 - '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.5.0 - bigint-buffer: 1.1.5 - bn.js: 5.2.1 - borsh: 0.7.0 - bs58: 4.0.1 - buffer: 6.0.3 - fast-stable-stringify: 1.0.0 - jayson: 4.1.2 - node-fetch: 2.7.0 - rpc-websockets: 9.0.4 - superstruct: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - /@solana/web3.js@1.95.8: - resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} + '@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.25.7 - '@noble/curves': 1.6.0 - '@noble/hashes': 1.5.0 + '@babel/runtime': 7.27.6 + '@noble/curves': 1.9.4 + '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.5.0 + agentkeepalive: 4.6.0 bigint-buffer: 1.1.5 - bn.js: 5.2.1 + bn.js: 5.2.2 borsh: 0.7.0 bs58: 4.0.1 buffer: 6.0.3 fast-stable-stringify: 1.0.0 - jayson: 4.1.2 + jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) node-fetch: 2.7.0 - rpc-websockets: 9.0.4 + rpc-websockets: 9.1.1 superstruct: 2.0.2 transitivePeerDependencies: - bufferutil - encoding - utf-8-validate - dev: true - /@solana/web3.js@1.98.0: - resolution: {integrity: sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==} + '@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.25.7 - '@noble/curves': 1.6.0 - '@noble/hashes': 1.5.0 + '@babel/runtime': 7.27.6 + '@noble/curves': 1.9.4 + '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.5.0 - bigint-buffer: 1.1.5 - bn.js: 5.2.1 + '@solana/codecs-numbers': 2.3.0(typescript@4.9.5) + agentkeepalive: 4.6.0 + bn.js: 5.2.2 borsh: 0.7.0 bs58: 4.0.1 buffer: 6.0.3 fast-stable-stringify: 1.0.0 - jayson: 4.1.2 + jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) node-fetch: 2.7.0 - rpc-websockets: 9.0.4 + rpc-websockets: 9.1.1 superstruct: 2.0.2 transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate - /@solworks/soltoolkit-sdk@0.0.23(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} + '@solworks/soltoolkit-sdk@0.0.23(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8 - '@types/bn.js': 5.1.6 - '@types/node': 18.19.67 + '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@types/bn.js': 5.2.0 + '@types/node': 18.19.119 '@types/node-fetch': 2.6.12 - bn.js: 5.2.1 - decimal.js: 10.4.3 + bn.js: 5.2.2 + decimal.js: 10.6.0 typescript: 4.9.5 transitivePeerDependencies: - bufferutil - encoding - fastestsmallesttextencoderdecoder - utf-8-validate - dev: true - - /@soncodi/signal@2.0.7: - resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} - dev: true - /@sqds/multisig@2.1.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-WOiL7La+RSiJsz7jVO85yhSiiSvNMUthiWuLPeWVOoD6IYa34BEAzanF1RdXRWGglSbRFYCTkyr+Ay1WmXmSRQ==} - engines: {node: '>=14'} - dependencies: - '@metaplex-foundation/beet': 0.7.1 - '@metaplex-foundation/beet-solana': 0.4.0 - '@metaplex-foundation/cusper': 0.0.2 - '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.3)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.3 - '@types/bn.js': 5.1.6 - assert: 2.1.0 - bn.js: 5.2.1 - buffer: 6.0.3 - invariant: 2.2.4 - transitivePeerDependencies: - - bufferutil - - encoding - - fastestsmallesttextencoderdecoder - - supports-color - - typescript - - utf-8-validate - dev: true + '@soncodi/signal@2.0.7': {} - /@swc/helpers@0.5.13: - resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} + '@swc/helpers@0.5.17': dependencies: - tslib: 2.7.0 + tslib: 2.8.1 - /@switchboard-xyz/common@2.5.5: - resolution: {integrity: sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w==} - engines: {node: '>=12'} + '@switchboard-xyz/common@2.5.19(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: - '@solana/web3.js': 1.95.8 - axios: 1.7.8 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + axios: 1.10.0 big.js: 6.2.2 - bn.js: 5.2.1 - bs58: 5.0.0 - cron-validator: 1.3.1 - decimal.js: 10.4.3 - js-sha256: 0.11.0 + bn.js: 5.2.2 + bs58: 6.0.0 + cron-validator: 1.4.0 + decimal.js: 10.6.0 + js-sha256: 0.11.1 lodash: 4.17.21 - protobufjs: 7.4.0 - yaml: 2.6.1 + protobufjs: 7.5.3 + yaml: 2.8.0 transitivePeerDependencies: - bufferutil - debug - encoding - utf-8-validate - dev: true - /@switchboard-xyz/common@3.0.12: - resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} - engines: {node: '>=20'} + '@switchboard-xyz/common@3.0.12(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@solana/web3.js': 1.98.0 - axios: 1.8.4 + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + axios: 1.10.0 big.js: 6.2.2 - bn.js: 5.2.1 + bn.js: 5.2.2 bs58: 6.0.0 buffer: 6.0.3 - decimal.js: 10.4.3 - js-sha256: 0.11.0 - protobufjs: 7.4.0 - yaml: 2.6.1 + decimal.js: 10.6.0 + js-sha256: 0.11.1 + protobufjs: 7.5.3 + yaml: 2.8.0 transitivePeerDependencies: - bufferutil - debug - encoding + - typescript - utf-8-validate - dev: true - /@switchboard-xyz/common@3.0.13: - resolution: {integrity: sha512-I+18pvqh6Oajz9bYvAJ/swz+XUqRbz7i3dgz/BzasDyxpI4pzIsG4qsnVfIpAnTGsgzhq61Q6W721SnnyFdKuw==} - engines: {node: '>=20'} + '@switchboard-xyz/common@3.4.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@solana/web3.js': 1.98.0 - axios: 1.8.4 + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + axios: 1.10.0 big.js: 6.2.2 - bn.js: 5.2.1 + bn.js: 5.2.2 bs58: 6.0.0 buffer: 6.0.3 - decimal.js: 10.4.3 - js-sha256: 0.11.0 - protobufjs: 7.4.0 - yaml: 2.6.1 + decimal.js: 10.6.0 + js-sha256: 0.11.1 + protobufjs: 7.5.3 + yaml: 2.8.0 + zod: 4.0.0-beta.20250505T195954 transitivePeerDependencies: - bufferutil - debug - encoding + - typescript - utf-8-validate - dev: false - /@switchboard-xyz/on-demand@1.2.51(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} - engines: {node: '>= 18'} + '@switchboard-xyz/on-demand@1.2.51(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10)': dependencies: '@brokerloop/ttlcache': 3.2.3 - '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 - '@solana/web3.js': 1.95.8 - '@solworks/soltoolkit-sdk': 0.0.23(fastestsmallesttextencoderdecoder@1.0.22) - '@switchboard-xyz/common': 2.5.5 - axios: 1.7.8 + '@coral-xyz/anchor-30': '@coral-xyz/anchor@0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)' + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solworks/soltoolkit-sdk': 0.0.23(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10) + '@switchboard-xyz/common': 2.5.19(bufferutil@4.0.9)(utf-8-validate@5.0.10) + axios: 1.10.0 big.js: 6.2.2 bs58: 5.0.0 js-yaml: 4.1.0 - protobufjs: 7.4.0 + protobufjs: 7.5.3 transitivePeerDependencies: - bufferutil - debug - encoding - fastestsmallesttextencoderdecoder - utf-8-validate - dev: true - /@switchboard-xyz/on-demand@1.2.67: - resolution: {integrity: sha512-rtGA+9tQHb/xQnUFgVzyaOs2uKgnwP7OqYQLEOjTDdNTEEgU8OTR72ujluOEYB9LMByb7h9SRuOR353vxYQhYA==} - engines: {node: '>= 18'} - deprecated: deprecated in favor of 2.x.x + '@switchboard-xyz/on-demand@1.2.67(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: '@common.js/quick-lru': 7.0.0 - '@coral-xyz/anchor': 0.30.1 - '@switchboard-xyz/common': 3.0.13 - axios: 1.7.8 + '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@switchboard-xyz/common': 3.4.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + axios: 1.10.0 bs58: 6.0.0 buffer: 6.0.3 js-yaml: 4.1.0 @@ -1117,754 +1661,428 @@ packages: - bufferutil - debug - encoding + - typescript - utf-8-validate - dev: false - /@types/bn.js@5.1.6: - resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} + '@types/bn.js@5.2.0': dependencies: - '@types/node': 20.16.11 - dev: true + '@types/node': 18.19.119 - /@types/connect@3.4.38: - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@types/connect@3.4.38': dependencies: - '@types/node': 20.16.11 + '@types/node': 12.20.55 - /@types/node-fetch@2.6.12: - resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + '@types/node-fetch@2.6.12': dependencies: - '@types/node': 20.16.11 - form-data: 4.0.1 - dev: true + '@types/node': 18.19.119 + form-data: 4.0.4 - /@types/node@12.20.55: - resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@12.20.55': {} - /@types/node@18.19.67: - resolution: {integrity: sha512-wI8uHusga+0ZugNp0Ol/3BqQfEcCCNfojtO6Oou9iVNGPTL6QNSdnUdqq85fRgIorLhLMuPIKpsN98QE9Nh+KQ==} + '@types/node@18.19.119': dependencies: undici-types: 5.26.5 - dev: true - /@types/node@20.16.11: - resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} + '@types/node@24.0.14': dependencies: - undici-types: 6.19.8 + undici-types: 7.8.0 - /@types/uuid@8.3.4: - resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} + '@types/uuid@8.3.4': {} - /@types/ws@7.4.7: - resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + '@types/ws@7.4.7': dependencies: - '@types/node': 20.16.11 + '@types/node': 12.20.55 - /@types/ws@8.5.12: - resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} + '@types/ws@8.18.1': dependencies: - '@types/node': 20.16.11 + '@types/node': 24.0.14 - /@wallet-standard/base@1.1.0: - resolution: {integrity: sha512-DJDQhjKmSNVLKWItoKThJS+CsJQjR9AOBOirBVT1F9YpRyC9oYHE+ZnSf8y8bxUphtKqdQMPVQ2mHohYdRvDVQ==} - engines: {node: '>=16'} - dev: false + '@wallet-standard/base@1.1.0': {} - /@wallet-standard/features@1.1.0: - resolution: {integrity: sha512-hiEivWNztx73s+7iLxsuD1sOJ28xtRix58W7Xnz4XzzA/pF0+aicnWgjOdA10doVDEDZdUuZCIIqG96SFNlDUg==} - engines: {node: '>=16'} + '@wallet-standard/features@1.1.0': dependencies: '@wallet-standard/base': 1.1.0 - dev: false - /JSONStream@1.3.5: - resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} - hasBin: true - dependencies: - jsonparse: 1.3.1 - through: 2.3.8 + '@zod/core@0.11.6': {} - /a-sync-waterfall@1.0.1: - resolution: {integrity: sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==} - dev: false + a-sync-waterfall@1.0.1: {} - /agentkeepalive@4.5.0: - resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} - engines: {node: '>= 8.0.0'} + agentkeepalive@4.6.0: dependencies: humanize-ms: 1.2.1 - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - dev: false + ansi-regex@5.0.1: {} - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 - dev: false - - /ansicolors@0.3.2: - resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} - dev: true - - /argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - /asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - dev: false - /assert@2.1.0: - resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} - dependencies: - call-bind: 1.0.7 - is-nan: 1.3.2 - object-is: 1.1.6 - object.assign: 4.1.5 - util: 0.12.5 - dev: true - - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + argparse@2.0.1: {} - /available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} - dependencies: - possible-typed-array-names: 1.0.0 - dev: true + asap@2.0.6: {} - /axios@1.7.8: - resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} - dependencies: - follow-redirects: 1.15.9 - form-data: 4.0.1 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug + asynckit@0.4.0: {} - /axios@1.8.4: - resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} + axios@1.10.0: dependencies: follow-redirects: 1.15.9 - form-data: 4.0.1 + form-data: 4.0.4 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - /base-x@3.0.10: - resolution: {integrity: sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==} + base-x@3.0.11: dependencies: safe-buffer: 5.2.1 - /base-x@4.0.0: - resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} + base-x@4.0.1: {} - /base-x@5.0.1: - resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} + base-x@5.0.1: {} - /base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + base64-js@1.5.1: {} - /big.js@6.2.2: - resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + big.js@6.2.2: {} - /bigint-buffer@1.1.5: - resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} - engines: {node: '>= 10.0.0'} - requiresBuild: true + bigint-buffer@1.1.5: dependencies: bindings: 1.5.0 - /bignumber.js@9.1.2: - resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + bignumber.js@9.3.1: {} - /bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + bindings@1.5.0: dependencies: file-uri-to-path: 1.0.0 - /bn.js@5.2.1: - resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + bn.js@5.2.2: {} - /borsh@0.7.0: - resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + borsh@0.7.0: dependencies: - bn.js: 5.2.1 + bn.js: 5.2.2 bs58: 4.0.1 text-encoding-utf-8: 1.0.2 - /borsh@2.0.0: - resolution: {integrity: sha512-kc9+BgR3zz9+cjbwM8ODoUB4fs3X3I5A/HtX7LZKxCLaMrEeDFoBpnhZY//DTS1VZBSs6S5v46RZRbZjRFspEg==} - dev: false + borsh@2.0.0: {} - /bs58@4.0.1: - resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + bs58@4.0.1: dependencies: - base-x: 3.0.10 + base-x: 3.0.11 - /bs58@5.0.0: - resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} + bs58@5.0.0: dependencies: - base-x: 4.0.0 + base-x: 4.0.1 - /bs58@6.0.0: - resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + bs58@6.0.0: dependencies: base-x: 5.0.1 - /buffer-layout@1.2.2: - resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==} - engines: {node: '>=4.5'} + buffer-layout@1.2.2: {} - /buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + buffer@6.0.3: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - /bufferutil@4.0.8: - resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} - engines: {node: '>=6.14.2'} - requiresBuild: true + bufferutil@4.0.9: dependencies: - node-gyp-build: 4.8.2 + node-gyp-build: 4.8.4 + optional: true - /call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} - engines: {node: '>= 0.4'} + call-bind-apply-helpers@1.0.2: dependencies: - es-define-property: 1.0.0 es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.4 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 set-function-length: 1.2.2 - /camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 - /chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + camelcase@6.3.0: {} + + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - dev: false - /chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chalk@5.4.1: {} - /cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + cliui@8.0.1: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - dev: false - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + color-convert@2.0.1: dependencies: color-name: 1.1.4 - dev: false - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: false + color-name@1.1.4: {} - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 - /commander@12.1.0: - resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} - engines: {node: '>=18'} + commander@12.1.0: {} - /commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@14.0.0: {} - /commander@5.1.0: - resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} - engines: {node: '>= 6'} - dev: false + commander@2.20.3: {} + + commander@5.1.0: {} - /cron-validator@1.3.1: - resolution: {integrity: sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==} - dev: true + cron-validator@1.4.0: {} - /cross-fetch@3.1.8: - resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + cross-fetch@3.2.0: dependencies: node-fetch: 2.7.0 transitivePeerDependencies: - encoding - /cross-fetch@4.0.0: - resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + cross-fetch@4.1.0: dependencies: node-fetch: 2.7.0 transitivePeerDependencies: - encoding - dev: true - /crypto-hash@1.3.0: - resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} - engines: {node: '>=8'} - - /crypto-hash@3.1.0: - resolution: {integrity: sha512-HR8JlZ+Dn54Lc5gGWZJxJitWbOCUzWb9/AlyONGecBnYZ+n/ONvt0gQnEzDNpJMYeRrYO7KogQ4qwyTPKnWKEw==} - engines: {node: '>=18'} - dev: false + crypto-hash@1.3.0: {} - /debug@4.3.7: - resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: true + crypto-hash@3.1.0: {} - /decimal.js@10.4.3: - resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + decimal.js@10.6.0: {} - /define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} + define-data-property@1.1.4: dependencies: - es-define-property: 1.0.0 + es-define-property: 1.0.1 es-errors: 1.3.0 - gopd: 1.0.1 + gopd: 1.2.0 - /define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} + delay@5.0.0: {} + + delayed-stream@1.0.0: {} + + dot-case@3.0.4: dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - dev: true + no-case: 3.0.4 + tslib: 2.8.1 - /delay@5.0.0: - resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} - engines: {node: '>=10'} + dotenv@10.0.0: {} - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} + dotenv@16.6.1: {} - /dot-case@3.0.4: - resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dunder-proto@1.0.1: dependencies: - no-case: 3.0.4 - tslib: 2.7.0 + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 - /dotenv@10.0.0: - resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==} - engines: {node: '>=10'} - dev: false + emoji-regex@8.0.0: {} - /dotenv@16.4.7: - resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} - engines: {node: '>=12'} + es-define-property@1.0.1: {} - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: false + es-errors@1.3.0: {} - /es-define-property@1.0.0: - resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} - engines: {node: '>= 0.4'} + es-object-atoms@1.1.1: dependencies: - get-intrinsic: 1.2.4 + es-errors: 1.3.0 - /es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 - /es6-promise@4.2.8: - resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + es6-promise@4.2.8: {} - /es6-promisify@5.0.0: - resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + es6-promisify@5.0.0: dependencies: es6-promise: 4.2.8 - /escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - dev: false - - /eventemitter3@4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + escalade@3.2.0: {} - /eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + eventemitter3@4.0.7: {} - /eyes@0.1.8: - resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} - engines: {node: '> 0.1.90'} + eventemitter3@5.0.1: {} - /fast-stable-stringify@1.0.0: - resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + eyes@0.1.8: {} - /fastestsmallesttextencoderdecoder@1.0.22: - resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} + fast-stable-stringify@1.0.0: {} - /file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + fastestsmallesttextencoderdecoder@1.0.22: {} - /follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true + file-uri-to-path@1.0.0: {} - /for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - dependencies: - is-callable: 1.2.7 - dev: true + follow-redirects@1.15.9: {} - /form-data@4.0.1: - resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} - engines: {node: '>= 6'} + form-data@4.0.4: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 mime-types: 2.1.35 - /function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + function-bind@1.1.2: {} - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: false + get-caller-file@2.0.5: {} - /get-intrinsic@1.2.4: - resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} - engines: {node: '>= 0.4'} + get-intrinsic@1.3.0: dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 es-errors: 1.3.0 + es-object-atoms: 1.1.1 function-bind: 1.1.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 hasown: 2.0.2 + math-intrinsics: 1.1.0 - /gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + get-proto@1.0.1: dependencies: - get-intrinsic: 1.2.4 + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: false + gopd@1.2.0: {} - /has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - dependencies: - es-define-property: 1.0.0 + has-flag@4.0.0: {} - /has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} - engines: {node: '>= 0.4'} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 - /has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} + has-symbols@1.1.0: {} - /has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} + has-tostringtag@1.0.2: dependencies: - has-symbols: 1.0.3 - dev: true + has-symbols: 1.1.0 - /hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} + hasown@2.0.2: dependencies: function-bind: 1.1.2 - /humanize-ms@1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + humanize-ms@1.2.1: dependencies: ms: 2.1.3 - /ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true - - /invariant@2.2.4: - resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} - dependencies: - loose-envify: 1.4.0 - dev: true - - /is-arguments@1.1.1: - resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - dev: true - - /is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - dev: true - - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - dev: false - - /is-generator-function@1.0.10: - resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.2 - dev: true - - /is-nan@1.3.2: - resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - dev: true + ieee754@1.2.1: {} - /is-typed-array@1.1.13: - resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} - engines: {node: '>= 0.4'} - dependencies: - which-typed-array: 1.1.15 - dev: true + is-fullwidth-code-point@3.0.0: {} - /isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - dev: false + isarray@2.0.5: {} - /isomorphic-ws@4.0.1(ws@7.5.10): - resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} - peerDependencies: - ws: '*' + isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: - ws: 7.5.10 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) - /jayson@4.1.2: - resolution: {integrity: sha512-5nzMWDHy6f+koZOuYsArh2AXs73NfWYVlFyJJuCedr93GpY+Ku8qq10ropSXVfHK+H0T6paA88ww+/dV+1fBNA==} - engines: {node: '>=8'} - hasBin: true + jayson@4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@types/connect': 3.4.38 '@types/node': 12.20.55 '@types/ws': 7.4.7 - JSONStream: 1.3.5 commander: 2.20.3 delay: 5.0.0 es6-promisify: 5.0.0 eyes: 0.1.8 - isomorphic-ws: 4.0.1(ws@7.5.10) + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) json-stringify-safe: 5.0.1 + stream-json: 1.9.1 uuid: 8.3.2 - ws: 7.5.10 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - utf-8-validate - /jito-ts@3.0.1: - resolution: {integrity: sha512-TSofF7KqcwyaWGjPaSYC8RDoNBY1TPRNBHdrw24bdIi7mQ5bFEDdYK3D//llw/ml8YDvcZlgd644WxhjLTS9yg==} + jito-ts@3.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: - '@grpc/grpc-js': 1.13.2 - '@noble/ed25519': 1.7.3 - '@solana/web3.js': 1.77.4 - agentkeepalive: 4.5.0 - dotenv: 16.4.7 - jayson: 4.1.2 + '@grpc/grpc-js': 1.13.4 + '@noble/ed25519': 1.7.5 + '@solana/web3.js': 1.77.4(bufferutil@4.0.9)(utf-8-validate@5.0.10) + agentkeepalive: 4.6.0 + dotenv: 16.6.1 + jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) node-fetch: 2.7.0 superstruct: 1.0.4 transitivePeerDependencies: - bufferutil - encoding - utf-8-validate - dev: false - - /js-sha256@0.11.0: - resolution: {integrity: sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==} - /js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true + js-sha256@0.11.1: {} - /js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true + js-yaml@4.1.0: dependencies: argparse: 2.0.1 - /json-stable-stringify@1.1.1: - resolution: {integrity: sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==} - engines: {node: '>= 0.4'} + json-stable-stringify@1.3.0: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 isarray: 2.0.5 jsonify: 0.0.1 object-keys: 1.1.1 - dev: false - - /json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - /jsonify@0.0.1: - resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} - dev: false + json-stringify-safe@5.0.1: {} - /jsonparse@1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} + jsonify@0.0.1: {} - /lodash.camelcase@4.3.0: - resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - dev: false + lodash.camelcase@4.3.0: {} - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true + lodash@4.17.21: {} - /long@5.2.3: - resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} + long@5.3.2: {} - /loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true + lower-case@2.0.2: dependencies: - js-tokens: 4.0.0 - dev: true + tslib: 2.8.1 - /lower-case@2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} - dependencies: - tslib: 2.7.0 + make-synchronized@0.4.2: {} - /make-synchronized@0.2.9: - resolution: {integrity: sha512-4wczOs8SLuEdpEvp3vGo83wh8rjJ78UsIk7DIX5fxdfmfMJGog4bQzxfvOwq7Q3yCHLC4jp1urPHIxRS/A93gA==} - dev: false + math-intrinsics@1.1.0: {} - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} + mime-db@1.52.0: {} - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + mime-types@2.1.35: dependencies: mime-db: 1.52.0 - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + ms@2.1.3: {} - /no-case@3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + no-case@3.0.4: dependencies: lower-case: 2.0.2 - tslib: 2.7.0 + tslib: 2.8.1 - /node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true + node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 - /node-gyp-build@4.8.2: - resolution: {integrity: sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==} - hasBin: true - requiresBuild: true + node-gyp-build@4.8.4: + optional: true - /numeral@2.0.6: - resolution: {integrity: sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==} - dev: false + numeral@2.0.6: {} - /nunjucks@3.2.4: - resolution: {integrity: sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==} - engines: {node: '>= 6.9.0'} - hasBin: true - peerDependencies: - chokidar: ^3.3.0 - peerDependenciesMeta: - chokidar: - optional: true + nunjucks@3.2.4: dependencies: a-sync-waterfall: 1.0.1 asap: 2.0.6 commander: 5.1.0 - dev: false - - /object-is@1.1.6: - resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - dev: true - - /object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - /object.assign@4.1.5: - resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - has-symbols: 1.0.3 - object-keys: 1.1.1 - dev: true - /pako@2.1.0: - resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + object-keys@1.1.1: {} - /possible-typed-array-names@1.0.0: - resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} - engines: {node: '>= 0.4'} - dev: true + pako@2.1.0: {} - /prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} - engines: {node: '>=14'} - hasBin: true - dev: false + prettier@3.6.2: {} - /protobufjs@7.4.0: - resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==} - engines: {node: '>=12.0.0'} - requiresBuild: true + protobufjs@7.5.3: dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/base64': 1.1.2 @@ -1876,227 +2094,139 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 20.16.11 - long: 5.2.3 + '@types/node': 24.0.14 + long: 5.3.2 - /proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + proxy-from-env@1.1.0: {} - /regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + require-directory@2.1.1: {} - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: false + rpc-websockets@7.11.0: + dependencies: + eventemitter3: 4.0.7 + uuid: 8.3.2 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 - /rpc-websockets@7.11.0: - resolution: {integrity: sha512-IkLYjayPv6Io8C/TdCL5gwgzd1hFz2vmBZrjMw/SPEXo51ETOhnzgS4Qy5GWi2JQN7HKHa66J3+2mv0fgNh/7w==} - deprecated: deprecate 7.11.0 + rpc-websockets@7.11.2: dependencies: eventemitter3: 4.0.7 uuid: 8.3.2 - ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - bufferutil: 4.0.8 + bufferutil: 4.0.9 utf-8-validate: 5.0.10 - /rpc-websockets@9.0.4: - resolution: {integrity: sha512-yWZWN0M+bivtoNLnaDbtny4XchdAIF5Q4g/ZsC5UC61Ckbp0QczwO8fg44rV3uYmY4WHd+EZQbn90W1d8ojzqQ==} + rpc-websockets@9.1.1: dependencies: - '@swc/helpers': 0.5.13 + '@swc/helpers': 0.5.17 '@types/uuid': 8.3.4 - '@types/ws': 8.5.12 + '@types/ws': 8.18.1 buffer: 6.0.3 eventemitter3: 5.0.1 uuid: 8.3.2 - ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - bufferutil: 4.0.8 + bufferutil: 4.0.9 utf-8-validate: 5.0.10 - /safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-buffer@5.2.1: {} - /set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.4 - gopd: 1.0.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 has-property-descriptors: 1.0.2 - /snake-case@3.0.4: - resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + snake-case@3.0.4: dependencies: dot-case: 3.0.4 - tslib: 2.7.0 + tslib: 2.8.1 - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + stream-chain@2.2.5: {} + + stream-json@1.9.1: + dependencies: + stream-chain: 2.2.5 + + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - dev: false - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - dev: false - /superstruct@0.14.2: - resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} - dev: false + superstruct@0.14.2: {} - /superstruct@0.15.5: - resolution: {integrity: sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==} + superstruct@0.15.5: {} - /superstruct@1.0.4: - resolution: {integrity: sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==} - engines: {node: '>=14.0.0'} - dev: false + superstruct@1.0.4: {} - /superstruct@2.0.2: - resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} - engines: {node: '>=14.0.0'} + superstruct@2.0.2: {} - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 - dev: false - /text-encoding-utf-8@1.0.2: - resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} - - /through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - - /toml@3.0.0: - resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + text-encoding-utf-8@1.0.2: {} - /tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + toml@3.0.0: {} - /tslib@2.7.0: - resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tr46@0.0.3: {} - /typescript@4.9.5: - resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: true + tslib@2.8.1: {} - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: true + typescript@4.9.5: {} - /undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + undici-types@5.26.5: {} - /utf-8-validate@5.0.10: - resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} - engines: {node: '>=6.14.2'} - requiresBuild: true - dependencies: - node-gyp-build: 4.8.2 + undici-types@7.8.0: {} - /util@0.12.5: - resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + utf-8-validate@5.0.10: dependencies: - inherits: 2.0.4 - is-arguments: 1.1.1 - is-generator-function: 1.0.10 - is-typed-array: 1.1.13 - which-typed-array: 1.1.15 - dev: true + node-gyp-build: 4.8.4 + optional: true - /uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true + uuid@8.3.2: {} - /webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webidl-conversions@3.0.1: {} - /whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 - /which-typed-array@1.1.15: - resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} - engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.7 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.2 - dev: true - - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - dev: false - /ws@7.5.10: - resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} - engines: {node: '>=8.3.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true + ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 - /ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): - resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dependencies: - bufferutil: 4.0.8 + ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 utf-8-validate: 5.0.10 - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: false + y18n@5.0.8: {} - /yaml@2.6.1: - resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==} - engines: {node: '>= 14'} - hasBin: true + yaml@2.8.0: {} - /yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - dev: false + yargs-parser@21.1.1: {} - /yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + yargs@17.7.2: dependencies: cliui: 8.0.1 escalade: 3.2.0 @@ -2105,35 +2235,7 @@ packages: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 - dev: false - file:solauto-sdk(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {directory: solauto-sdk, type: directory} - id: file:solauto-sdk - name: '@haven-fi/solauto-sdk' + zod@4.0.0-beta.20250505T195954: dependencies: - '@coral-xyz/anchor': 0.30.1 - '@jup-ag/api': 6.0.24 - '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-bundle-defaults': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@metaplex-foundation/umi-signer-wallet-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/spl-token': 0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8 - '@sqds/multisig': 2.1.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@switchboard-xyz/common': 3.0.12 - '@switchboard-xyz/on-demand': 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) - '@types/node': 20.16.11 - axios: 1.7.8 - bs58: 5.0.0 - cross-fetch: 4.0.0 - dotenv: 16.4.7 - rpc-websockets: 7.11.0 - transitivePeerDependencies: - - bufferutil - - debug - - encoding - - fastestsmallesttextencoderdecoder - - typescript - - utf-8-validate - dev: true + '@zod/core': 0.11.6 diff --git a/solauto-sdk/pnpm-lock.yaml b/solauto-sdk/pnpm-lock.yaml index 5003c773..ee47e07a 100644 --- a/solauto-sdk/pnpm-lock.yaml +++ b/solauto-sdk/pnpm-lock.yaml @@ -1,118 +1,1166 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -dependencies: - '@coral-xyz/anchor': - specifier: ^0.30.1 - version: 0.30.1 - '@jup-ag/api': - specifier: '=6.0.24' - version: 6.0.24 - '@metaplex-foundation/umi': - specifier: ^0.9.1 - version: 0.9.2 - '@metaplex-foundation/umi-bundle-defaults': - specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@metaplex-foundation/umi-signer-wallet-adapters': - specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@metaplex-foundation/umi-web3js-adapters': - specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/spl-token': - specifier: ^0.4.0 - version: 0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/web3.js': - specifier: '=1.95.8' - version: 1.95.8 - '@switchboard-xyz/common': - specifier: '=3.0.12' - version: 3.0.12 - '@switchboard-xyz/on-demand': - specifier: '=1.2.51' - version: 1.2.51(fastestsmallesttextencoderdecoder@1.0.22) - axios: - specifier: ^1.7.8 - version: 1.7.8 - big.js: - specifier: ^6.2.2 - version: 6.2.2 - bs58: - specifier: ^5.0.0 - version: 5.0.0 - cross-fetch: - specifier: ^4.0.0 - version: 4.0.0 - dotenv: - specifier: ^16.4.7 - version: 16.4.7 - rpc-websockets: - specifier: 7.11.0 - version: 7.11.0 - -devDependencies: - '@types/big.js': - specifier: ^6.2.2 - version: 6.2.2 - '@types/chai': - specifier: ^4.3.0 - version: 4.3.20 - '@types/mocha': - specifier: ^9.1.1 - version: 9.1.1 - '@types/node': - specifier: ^20.16.11 - version: 20.16.11 - chai: - specifier: ^4.3.4 - version: 4.5.0 - mocha: - specifier: ^9.2.2 - version: 9.2.2 - ts-mocha: - specifier: ^10.0.0 - version: 10.0.0(mocha@9.2.2) - typescript: - specifier: ^5.5.4 - version: 5.6.3 +importers: + + .: + dependencies: + '@coral-xyz/anchor': + specifier: ^0.30.1 + version: 0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@jup-ag/api': + specifier: '=6.0.24' + version: 6.0.24 + '@metaplex-foundation/umi': + specifier: ^0.9.1 + version: 0.9.2 + '@metaplex-foundation/umi-bundle-defaults': + specifier: ^0.9.1 + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metaplex-foundation/umi-signer-wallet-adapters': + specifier: ^0.9.1 + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metaplex-foundation/umi-web3js-adapters': + specifier: ^0.9.1 + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/spl-token': + specifier: ^0.4.0 + version: 0.4.13(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@solana/web3.js': + specifier: '=1.95.8' + version: 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@switchboard-xyz/common': + specifier: '=3.0.12' + version: 3.0.12(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@switchboard-xyz/on-demand': + specifier: '=1.2.51' + version: 1.2.51(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10) + axios: + specifier: ^1.7.8 + version: 1.10.0 + big.js: + specifier: ^6.2.2 + version: 6.2.2 + bs58: + specifier: ^5.0.0 + version: 5.0.0 + cross-fetch: + specifier: ^4.0.0 + version: 4.1.0 + dotenv: + specifier: ^16.4.7 + version: 16.6.1 + rpc-websockets: + specifier: 7.11.0 + version: 7.11.0 + devDependencies: + '@types/big.js': + specifier: ^6.2.2 + version: 6.2.2 + '@types/chai': + specifier: ^4.3.0 + version: 4.3.20 + '@types/mocha': + specifier: ^9.1.1 + version: 9.1.1 + '@types/node': + specifier: ^20.16.11 + version: 20.19.8 + chai: + specifier: ^4.3.4 + version: 4.5.0 + mocha: + specifier: ^9.2.2 + version: 9.2.2 + ts-mocha: + specifier: ^10.0.0 + version: 10.1.0(mocha@9.2.2) + typescript: + specifier: ^5.5.4 + version: 5.8.3 packages: - /@babel/runtime@7.25.7: - resolution: {integrity: sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==} + '@babel/runtime@7.27.6': + resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.14.1 - dev: false - /@brokerloop/ttlcache@3.2.3: - resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} + '@brokerloop/ttlcache@3.2.3': + resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} + + '@coral-xyz/anchor-errors@0.30.1': + resolution: {integrity: sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==} + engines: {node: '>=10'} + + '@coral-xyz/anchor@0.30.1': + resolution: {integrity: sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==} + engines: {node: '>=11'} + + '@coral-xyz/borsh@0.30.1': + resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.68.0 + + '@jup-ag/api@6.0.24': + resolution: {integrity: sha512-zIX4WIPb0Kb2UnK2wNIOQBWqPJyMJq/D9dQTf/2qvPb0hfa8XdgbrQAzomHMHnAzw9StMQoybBk+JK/A76xP3w==} + + '@metaplex-foundation/umi-bundle-defaults@0.9.2': + resolution: {integrity: sha512-kV3tfvgvRjVP1p9OFOtH+ibOtN9omVJSwKr0We4/9r45e5LTj+32su0V/rixZUkG1EZzzOYBsxhtIE0kIw/Hrw==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + '@solana/web3.js': ^1.72.0 + + '@metaplex-foundation/umi-downloader-http@0.9.2': + resolution: {integrity: sha512-tzPT9hBwenzTzAQg07rmsrqZfgguAXELbcJrsYMoASp5VqWFXYIP00g94KET6XLjWUXH4P1J2zoa6hGennPXHA==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + + '@metaplex-foundation/umi-eddsa-web3js@0.9.2': + resolution: {integrity: sha512-hhPCxXbYIp4BC4z9gK78sXpWLkNSrfv4ndhF5ruAkdIp7GcRVYKj0QnOUO6lGYGiIkNlw20yoTwOe1CT//OfTQ==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + '@solana/web3.js': ^1.72.0 + + '@metaplex-foundation/umi-http-fetch@0.9.2': + resolution: {integrity: sha512-YCZuBu24T9ZzEDe4+w12LEZm/fO9pkyViZufGgASC5NX93814Lvf6Ssjn/hZzjfA7CvZbvLFbmujc6CV3Q/m9Q==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + + '@metaplex-foundation/umi-options@0.8.9': + resolution: {integrity: sha512-jSQ61sZMPSAk/TXn8v8fPqtz3x8d0/blVZXLLbpVbo2/T5XobiI6/MfmlUosAjAUaQl6bHRF8aIIqZEFkJiy4A==} + + '@metaplex-foundation/umi-program-repository@0.9.2': + resolution: {integrity: sha512-g3+FPqXEmYsBa8eETtUE2gb2Oe3mqac0z3/Ur1TvAg5TtIy3mzRzOy/nza+sgzejnfcxcVg835rmpBaxpBnjDA==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + + '@metaplex-foundation/umi-public-keys@0.8.9': + resolution: {integrity: sha512-CxMzN7dgVGOq9OcNCJe2casKUpJ3RmTVoOvDFyeoTQuK+vkZ1YSSahbqC1iGuHEtKTLSjtWjKvUU6O7zWFTw3Q==} + + '@metaplex-foundation/umi-rpc-chunk-get-accounts@0.9.2': + resolution: {integrity: sha512-YRwVf6xH0jPBAUgMhEPi+UbjioAeqTXmjsN2TnmQCPAmHbrHrMRj0rlWYwFLWAgkmoxazYrXP9lqOFRrfOGAEA==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + + '@metaplex-foundation/umi-rpc-web3js@0.9.2': + resolution: {integrity: sha512-MqcsBz8B4wGl6jxsf2Jo/rAEpYReU9VCSR15QSjhvADHMmdFxCIZCCAgE+gDE2Vuanfl437VhOcP3g5Uw8C16Q==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + '@solana/web3.js': ^1.72.0 + + '@metaplex-foundation/umi-serializer-data-view@0.9.2': + resolution: {integrity: sha512-5vGptadJxUxvUcyrwFZxXlEc6Q7AYySBesizCtrBFUY8w8PnF2vzmS45CP1MLySEATNH6T9mD4Rs0tLb87iQyA==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + + '@metaplex-foundation/umi-serializers-core@0.8.9': + resolution: {integrity: sha512-WT82tkiYJ0Qmscp7uTj1Hz6aWQPETwaKLAENAUN5DeWghkuBKtuxyBKVvEOuoXerJSdhiAk0e8DWA4cxcTTQ/w==} + + '@metaplex-foundation/umi-serializers-encodings@0.8.9': + resolution: {integrity: sha512-N3VWLDTJ0bzzMKcJDL08U3FaqRmwlN79FyE4BHj6bbAaJ9LEHjDQ9RJijZyWqTm0jE7I750fU7Ow5EZL38Xi6Q==} + + '@metaplex-foundation/umi-serializers-numbers@0.8.9': + resolution: {integrity: sha512-NtBf1fnVNQJHFQjLFzRu2i9GGnigb9hOm/Gfrk628d0q0tRJB7BOM3bs5C61VAs7kJs4yd+pDNVAERJkknQ7Lg==} + + '@metaplex-foundation/umi-serializers@0.9.0': + resolution: {integrity: sha512-hAOW9Djl4w4ioKeR4erDZl5IG4iJdP0xA19ZomdaCbMhYAAmG/FEs5khh0uT2mq53/MnzWcXSUPoO8WBN4Q+Vg==} + + '@metaplex-foundation/umi-signer-wallet-adapters@0.9.2': + resolution: {integrity: sha512-DFG0ZFocKG8briypSkG9bGUTVsWpAgYugsl2BzTygkGExc4evWfF4Sb1F2C2w9FdrA9ESZM1gpLX9xtx5taOXg==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + '@solana/web3.js': ^1.72.0 + + '@metaplex-foundation/umi-transaction-factory-web3js@0.9.2': + resolution: {integrity: sha512-fR1Kf21uylMFd1Smkltmj4jTNxhqSWf416owsJ+T+cvJi2VCOcOwq/3UFzOrpz78fA0RhsajKYKj0HYsRnQI1g==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + '@solana/web3.js': ^1.72.0 + + '@metaplex-foundation/umi-web3js-adapters@0.9.2': + resolution: {integrity: sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==} + peerDependencies: + '@metaplex-foundation/umi': ^0.9.2 + '@solana/web3.js': ^1.72.0 + + '@metaplex-foundation/umi@0.9.2': + resolution: {integrity: sha512-9i4Acm4pruQfJcpRrc2EauPBwkfDN0I9QTvJyZocIlKgoZwD6A6wH0PViH1AjOVG5CQCd1YI3tJd5XjYE1ElBw==} + + '@noble/curves@1.9.4': + resolution: {integrity: sha512-2bKONnuM53lINoDrSmK8qP8W271ms7pygDhZt4SiLOoLwBtoHqeCFi6RG42V8zd3mLHuJFhU/Bmaqo4nX0/kBw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + + '@solana/buffer-layout-utils@0.2.0': + resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} + engines: {node: '>= 10'} + + '@solana/buffer-layout@4.0.1': + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + + '@solana/codecs-core@2.0.0-rc.1': + resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-core@2.3.0': + resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-data-structures@2.0.0-rc.1': + resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-numbers@2.0.0-rc.1': + resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-numbers@2.3.0': + resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-strings@2.0.0-rc.1': + resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5' + + '@solana/codecs@2.0.0-rc.1': + resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} + peerDependencies: + typescript: '>=5' + + '@solana/errors@2.0.0-rc.1': + resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} + hasBin: true + peerDependencies: + typescript: '>=5' + + '@solana/errors@2.3.0': + resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' + + '@solana/options@2.0.0-rc.1': + resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} + peerDependencies: + typescript: '>=5' + + '@solana/spl-token-group@0.0.7': + resolution: {integrity: sha512-V1N/iX7Cr7H0uazWUT2uk27TMqlqedpXHRqqAbVO2gvmJyT0E0ummMEAVQeXZ05ZhQ/xF39DLSdBp90XebWEug==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.3 + + '@solana/spl-token-metadata@0.1.6': + resolution: {integrity: sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.3 + + '@solana/spl-token@0.3.11': + resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.88.0 + + '@solana/spl-token@0.4.13': + resolution: {integrity: sha512-cite/pYWQZZVvLbg5lsodSovbetK/eA24gaR0eeUeMuBAMNrT8XFCwaygKy0N2WSg3gSyjjNpIeAGBAKZaY/1w==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.5 + + '@solana/web3.js@1.95.8': + resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} + + '@solana/web3.js@1.98.2': + resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} + + '@solworks/soltoolkit-sdk@0.0.23': + resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} + + '@soncodi/signal@2.0.7': + resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} + + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + + '@switchboard-xyz/common@2.5.19': + resolution: {integrity: sha512-Bzj1bu2U69YRh2OoNjkrafdREeB1KH+wmeFkBsASDjlhy/xXjey2Ry2HUTAIzdg2DMtfP6DoCW2Nn9ZQD5IO+Q==} + engines: {node: '>=12'} + + '@switchboard-xyz/common@3.0.12': + resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} + engines: {node: '>=20'} + + '@switchboard-xyz/on-demand@1.2.51': + resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} + engines: {node: '>= 18'} + deprecated: deprecated in favor of 2.x.x + + '@types/big.js@6.2.2': + resolution: {integrity: sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==} + + '@types/bn.js@5.2.0': + resolution: {integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==} + + '@types/chai@4.3.20': + resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/mocha@9.1.1': + resolution: {integrity: sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==} + + '@types/node-fetch@2.6.12': + resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@18.19.119': + resolution: {integrity: sha512-d0F6m9itIPaKnrvEMlzE48UjwZaAnFW7Jwibacw9MNdqadjKNpUm9tfJYDwmShJmgqcoqYUX3EMKO1+RWiuuNg==} + + '@types/node@20.19.8': + resolution: {integrity: sha512-HzbgCY53T6bfu4tT7Aq3TvViJyHjLjPNaAS3HOuMc9pw97KHsUtXNX4L+wu59g1WnjsZSko35MbEqnO58rihhw==} + + '@types/uuid@8.3.4': + resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} + + '@types/ws@7.4.7': + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@ungap/promise-all-settled@1.1.2': + resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} + + agentkeepalive@4.6.0: + resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} + engines: {node: '>= 8.0.0'} + + ansi-colors@4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.10.0: + resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base-x@3.0.11: + resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} + + base-x@4.0.1: + resolution: {integrity: sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==} + + base-x@5.0.1: + resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + big.js@6.2.2: + resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + + bigint-buffer@1.1.5: + resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} + engines: {node: '>= 10.0.0'} + + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bn.js@5.2.2: + resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} + + borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + bs58@5.0.0: + resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} + + bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-layout@1.2.2: + resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==} + engines: {node: '>=4.5'} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bufferutil@4.0.9: + resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} + engines: {node: '>=6.14.2'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + chai@4.5.0: + resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + + chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@14.0.0: + resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} + engines: {node: '>=20'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cron-validator@1.4.0: + resolution: {integrity: sha512-wGcJ9FCy65iaU6egSH8b5dZYJF7GU/3Jh06wzaT9lsa5dbqExjljmu+0cJ8cpKn+vUyZa/EM4WAxeLR6SypJXw==} + + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + + crypto-hash@1.3.0: + resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} + engines: {node: '>=8'} + + debug@4.3.3: + resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} + + delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + diff@3.5.0: + resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==} + engines: {node: '>=0.3.1'} + + diff@5.0.0: + resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} + engines: {node: '>=0.3.1'} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + + es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + + fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + + fastestsmallesttextencoderdecoder@1.0.22: + resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + engines: {node: '>= 6'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + deprecated: Glob versions prior to v9 are no longer supported + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + growl@1.10.5: + resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} + engines: {node: '>=4.x'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + + jayson@4.2.0: + resolution: {integrity: sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg==} + engines: {node: '>=8'} + hasBin: true + + js-sha256@0.11.1: + resolution: {integrity: sha512-o6WSo/LUvY2uC4j7mO50a2ms7E/EAdbP0swigLV+nzHKTTaYnaLIWJ02VdXrsJX0vGedDESQnLsOekr94ryfjg==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@4.2.1: + resolution: {integrity: sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==} + engines: {node: '>=10'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mocha@9.2.2: + resolution: {integrity: sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==} + engines: {node: '>= 12.0.0'} + hasBin: true + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.1: + resolution: {integrity: sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + protobufjs@7.5.3: + resolution: {integrity: sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==} + engines: {node: '>=12.0.0'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + rpc-websockets@7.11.0: + resolution: {integrity: sha512-IkLYjayPv6Io8C/TdCL5gwgzd1hFz2vmBZrjMw/SPEXo51ETOhnzgS4Qy5GWi2JQN7HKHa66J3+2mv0fgNh/7w==} + deprecated: deprecate 7.11.0 + + rpc-websockets@9.1.1: + resolution: {integrity: sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + serialize-javascript@6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + + snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + stream-chain@2.2.5: + resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==} + + stream-json@1.9.1: + resolution: {integrity: sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + superstruct@0.15.5: + resolution: {integrity: sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==} + + superstruct@2.0.2: + resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} + engines: {node: '>=14.0.0'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + ts-mocha@10.1.0: + resolution: {integrity: sha512-T0C0Xm3/WqCuF2tpa0GNGESTBoKZaiqdUP8guNv4ZY316AFXlyidnrzQ1LUrCT0Wb1i3J0zFTgOh/55Un44WdA==} + engines: {node: '>= 6.X.X'} + hasBin: true + peerDependencies: + mocha: ^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X || ^11.X.X + + ts-node@7.0.1: + resolution: {integrity: sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==} + engines: {node: '>=4.2.0'} + hasBin: true + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + + typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + workerpool@6.2.0: + resolution: {integrity: sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaml@2.8.0: + resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@20.2.4: + resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + engines: {node: '>=10'} + + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yn@2.0.0: + resolution: {integrity: sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==} + engines: {node: '>=4'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@babel/runtime@7.27.6': {} + + '@brokerloop/ttlcache@3.2.3': dependencies: '@soncodi/signal': 2.0.7 - dev: false - /@coral-xyz/anchor-errors@0.30.1: - resolution: {integrity: sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==} - engines: {node: '>=10'} - dev: false + '@coral-xyz/anchor-errors@0.30.1': {} - /@coral-xyz/anchor@0.30.1: - resolution: {integrity: sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==} - engines: {node: '>=11'} + '@coral-xyz/anchor@0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@coral-xyz/anchor-errors': 0.30.1 - '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.8) - '@noble/hashes': 1.5.0 - '@solana/web3.js': 1.95.8 - bn.js: 5.2.1 + '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@noble/hashes': 1.8.0 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + bn.js: 5.2.2 bs58: 4.0.1 buffer-layout: 1.2.2 camelcase: 6.3.0 - cross-fetch: 3.1.8 + cross-fetch: 3.2.0 crypto-hash: 1.3.0 eventemitter3: 4.0.7 pako: 2.1.0 @@ -123,410 +1171,222 @@ packages: - bufferutil - encoding - utf-8-validate - dev: false - /@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} - engines: {node: '>=10'} - peerDependencies: - '@solana/web3.js': ^1.68.0 + '@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.95.8 - bn.js: 5.2.1 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + bn.js: 5.2.2 buffer-layout: 1.2.2 - dev: false - /@jup-ag/api@6.0.24: - resolution: {integrity: sha512-zIX4WIPb0Kb2UnK2wNIOQBWqPJyMJq/D9dQTf/2qvPb0hfa8XdgbrQAzomHMHnAzw9StMQoybBk+JK/A76xP3w==} - dev: false + '@jup-ag/api@6.0.24': {} - /@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-kV3tfvgvRjVP1p9OFOtH+ibOtN9omVJSwKr0We4/9r45e5LTj+32su0V/rixZUkG1EZzzOYBsxhtIE0kIw/Hrw==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 - '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 '@metaplex-foundation/umi-downloader-http': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@metaplex-foundation/umi-http-fetch': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-program-repository': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-rpc-chunk-get-accounts': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) + '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@metaplex-foundation/umi-serializer-data-view': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 + '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - encoding - dev: false - /@metaplex-foundation/umi-downloader-http@0.9.2(@metaplex-foundation/umi@0.9.2): - resolution: {integrity: sha512-tzPT9hBwenzTzAQg07rmsrqZfgguAXELbcJrsYMoASp5VqWFXYIP00g94KET6XLjWUXH4P1J2zoa6hGennPXHA==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 + '@metaplex-foundation/umi-downloader-http@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: '@metaplex-foundation/umi': 0.9.2 - dev: false - /@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-hhPCxXbYIp4BC4z9gK78sXpWLkNSrfv4ndhF5ruAkdIp7GcRVYKj0QnOUO6lGYGiIkNlw20yoTwOe1CT//OfTQ==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 - '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@noble/curves': 1.6.0 - '@solana/web3.js': 1.95.8 - dev: false - - /@metaplex-foundation/umi-http-fetch@0.9.2(@metaplex-foundation/umi@0.9.2): - resolution: {integrity: sha512-YCZuBu24T9ZzEDe4+w12LEZm/fO9pkyViZufGgASC5NX93814Lvf6Ssjn/hZzjfA7CvZbvLFbmujc6CV3Q/m9Q==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@noble/curves': 1.9.4 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + '@metaplex-foundation/umi-http-fetch@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: '@metaplex-foundation/umi': 0.9.2 node-fetch: 2.7.0 transitivePeerDependencies: - encoding - dev: false - /@metaplex-foundation/umi-options@0.8.9: - resolution: {integrity: sha512-jSQ61sZMPSAk/TXn8v8fPqtz3x8d0/blVZXLLbpVbo2/T5XobiI6/MfmlUosAjAUaQl6bHRF8aIIqZEFkJiy4A==} - dev: false + '@metaplex-foundation/umi-options@0.8.9': {} - /@metaplex-foundation/umi-program-repository@0.9.2(@metaplex-foundation/umi@0.9.2): - resolution: {integrity: sha512-g3+FPqXEmYsBa8eETtUE2gb2Oe3mqac0z3/Ur1TvAg5TtIy3mzRzOy/nza+sgzejnfcxcVg835rmpBaxpBnjDA==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 + '@metaplex-foundation/umi-program-repository@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: '@metaplex-foundation/umi': 0.9.2 - dev: false - /@metaplex-foundation/umi-public-keys@0.8.9: - resolution: {integrity: sha512-CxMzN7dgVGOq9OcNCJe2casKUpJ3RmTVoOvDFyeoTQuK+vkZ1YSSahbqC1iGuHEtKTLSjtWjKvUU6O7zWFTw3Q==} + '@metaplex-foundation/umi-public-keys@0.8.9': dependencies: '@metaplex-foundation/umi-serializers-encodings': 0.8.9 - dev: false - /@metaplex-foundation/umi-rpc-chunk-get-accounts@0.9.2(@metaplex-foundation/umi@0.9.2): - resolution: {integrity: sha512-YRwVf6xH0jPBAUgMhEPi+UbjioAeqTXmjsN2TnmQCPAmHbrHrMRj0rlWYwFLWAgkmoxazYrXP9lqOFRrfOGAEA==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 + '@metaplex-foundation/umi-rpc-chunk-get-accounts@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: '@metaplex-foundation/umi': 0.9.2 - dev: false - /@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-MqcsBz8B4wGl6jxsf2Jo/rAEpYReU9VCSR15QSjhvADHMmdFxCIZCCAgE+gDE2Vuanfl437VhOcP3g5Uw8C16Q==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 - '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 - dev: false + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - /@metaplex-foundation/umi-serializer-data-view@0.9.2(@metaplex-foundation/umi@0.9.2): - resolution: {integrity: sha512-5vGptadJxUxvUcyrwFZxXlEc6Q7AYySBesizCtrBFUY8w8PnF2vzmS45CP1MLySEATNH6T9mD4Rs0tLb87iQyA==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 + '@metaplex-foundation/umi-serializer-data-view@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: '@metaplex-foundation/umi': 0.9.2 - dev: false - /@metaplex-foundation/umi-serializers-core@0.8.9: - resolution: {integrity: sha512-WT82tkiYJ0Qmscp7uTj1Hz6aWQPETwaKLAENAUN5DeWghkuBKtuxyBKVvEOuoXerJSdhiAk0e8DWA4cxcTTQ/w==} - dev: false + '@metaplex-foundation/umi-serializers-core@0.8.9': {} - /@metaplex-foundation/umi-serializers-encodings@0.8.9: - resolution: {integrity: sha512-N3VWLDTJ0bzzMKcJDL08U3FaqRmwlN79FyE4BHj6bbAaJ9LEHjDQ9RJijZyWqTm0jE7I750fU7Ow5EZL38Xi6Q==} + '@metaplex-foundation/umi-serializers-encodings@0.8.9': dependencies: '@metaplex-foundation/umi-serializers-core': 0.8.9 - dev: false - /@metaplex-foundation/umi-serializers-numbers@0.8.9: - resolution: {integrity: sha512-NtBf1fnVNQJHFQjLFzRu2i9GGnigb9hOm/Gfrk628d0q0tRJB7BOM3bs5C61VAs7kJs4yd+pDNVAERJkknQ7Lg==} + '@metaplex-foundation/umi-serializers-numbers@0.8.9': dependencies: '@metaplex-foundation/umi-serializers-core': 0.8.9 - dev: false - /@metaplex-foundation/umi-serializers@0.9.0: - resolution: {integrity: sha512-hAOW9Djl4w4ioKeR4erDZl5IG4iJdP0xA19ZomdaCbMhYAAmG/FEs5khh0uT2mq53/MnzWcXSUPoO8WBN4Q+Vg==} + '@metaplex-foundation/umi-serializers@0.9.0': dependencies: '@metaplex-foundation/umi-options': 0.8.9 '@metaplex-foundation/umi-public-keys': 0.8.9 '@metaplex-foundation/umi-serializers-core': 0.8.9 '@metaplex-foundation/umi-serializers-encodings': 0.8.9 '@metaplex-foundation/umi-serializers-numbers': 0.8.9 - dev: false - /@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-DFG0ZFocKG8briypSkG9bGUTVsWpAgYugsl2BzTygkGExc4evWfF4Sb1F2C2w9FdrA9ESZM1gpLX9xtx5taOXg==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 - '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 - dev: false + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - /@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-fR1Kf21uylMFd1Smkltmj4jTNxhqSWf416owsJ+T+cvJi2VCOcOwq/3UFzOrpz78fA0RhsajKYKj0HYsRnQI1g==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 - '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8) - '@solana/web3.js': 1.95.8 - dev: false + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - /@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8): - resolution: {integrity: sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==} - peerDependencies: - '@metaplex-foundation/umi': ^0.9.2 - '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) buffer: 6.0.3 - dev: false - /@metaplex-foundation/umi@0.9.2: - resolution: {integrity: sha512-9i4Acm4pruQfJcpRrc2EauPBwkfDN0I9QTvJyZocIlKgoZwD6A6wH0PViH1AjOVG5CQCd1YI3tJd5XjYE1ElBw==} + '@metaplex-foundation/umi@0.9.2': dependencies: '@metaplex-foundation/umi-options': 0.8.9 '@metaplex-foundation/umi-public-keys': 0.8.9 '@metaplex-foundation/umi-serializers': 0.9.0 - dev: false - /@noble/curves@1.6.0: - resolution: {integrity: sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==} - engines: {node: ^14.21.3 || >=16} + '@noble/curves@1.9.4': dependencies: - '@noble/hashes': 1.5.0 - dev: false + '@noble/hashes': 1.8.0 - /@noble/hashes@1.5.0: - resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} - engines: {node: ^14.21.3 || >=16} - dev: false + '@noble/hashes@1.8.0': {} - /@protobufjs/aspromise@1.1.2: - resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} - dev: false + '@protobufjs/aspromise@1.1.2': {} - /@protobufjs/base64@1.1.2: - resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - dev: false + '@protobufjs/base64@1.1.2': {} - /@protobufjs/codegen@2.0.4: - resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} - dev: false + '@protobufjs/codegen@2.0.4': {} - /@protobufjs/eventemitter@1.1.0: - resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} - dev: false + '@protobufjs/eventemitter@1.1.0': {} - /@protobufjs/fetch@1.1.0: - resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + '@protobufjs/fetch@1.1.0': dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/inquire': 1.1.0 - dev: false - /@protobufjs/float@1.0.2: - resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - dev: false + '@protobufjs/float@1.0.2': {} - /@protobufjs/inquire@1.1.0: - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} - dev: false + '@protobufjs/inquire@1.1.0': {} - /@protobufjs/path@1.1.2: - resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} - dev: false + '@protobufjs/path@1.1.2': {} - /@protobufjs/pool@1.1.0: - resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - dev: false + '@protobufjs/pool@1.1.0': {} - /@protobufjs/utf8@1.1.0: - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - dev: false + '@protobufjs/utf8@1.1.0': {} - /@solana/buffer-layout-utils@0.2.0: - resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} - engines: {node: '>= 10'} + '@solana/buffer-layout-utils@0.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.95.8 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) bigint-buffer: 1.1.5 - bignumber.js: 9.1.2 + bignumber.js: 9.3.1 transitivePeerDependencies: - bufferutil - encoding - utf-8-validate - dev: false - /@solana/buffer-layout@4.0.1: - resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} - engines: {node: '>=5.10'} + '@solana/buffer-layout@4.0.1': dependencies: buffer: 6.0.3 - dev: false - - /@solana/codecs-core@2.0.0-preview.4(typescript@5.6.3): - resolution: {integrity: sha512-A0VVuDDA5kNKZUinOqHxJQK32aKTucaVbvn31YenGzHX1gPqq+SOnFwgaEY6pq4XEopSmaK16w938ZQS8IvCnw==} - peerDependencies: - typescript: '>=5' - dependencies: - '@solana/errors': 2.0.0-preview.4(typescript@5.6.3) - typescript: 5.6.3 - dev: false - /@solana/codecs-core@2.0.0-rc.1(typescript@4.9.5): - resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} - peerDependencies: - typescript: '>=5' + '@solana/codecs-core@2.0.0-rc.1(typescript@4.9.5)': dependencies: '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) typescript: 4.9.5 - dev: false - /@solana/codecs-core@2.0.0-rc.1(typescript@5.6.3): - resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} - peerDependencies: - typescript: '>=5' + '@solana/codecs-core@2.0.0-rc.1(typescript@5.8.3)': dependencies: - '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) - typescript: 5.6.3 - dev: false + '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) + typescript: 5.8.3 - /@solana/codecs-data-structures@2.0.0-preview.4(typescript@5.6.3): - resolution: {integrity: sha512-nt2k2eTeyzlI/ccutPcG36M/J8NAYfxBPI9h/nQjgJ+M+IgOKi31JV8StDDlG/1XvY0zyqugV3I0r3KAbZRJpA==} - peerDependencies: - typescript: '>=5' + '@solana/codecs-core@2.3.0(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.0.0-preview.4(typescript@5.6.3) - '@solana/codecs-numbers': 2.0.0-preview.4(typescript@5.6.3) - '@solana/errors': 2.0.0-preview.4(typescript@5.6.3) - typescript: 5.6.3 - dev: false + '@solana/errors': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 - /@solana/codecs-data-structures@2.0.0-rc.1(typescript@4.9.5): - resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} - peerDependencies: - typescript: '>=5' + '@solana/codecs-data-structures@2.0.0-rc.1(typescript@4.9.5)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) typescript: 4.9.5 - dev: false - /@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.6.3): - resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} - peerDependencies: - typescript: '>=5' - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.6.3) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.6.3) - '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) - typescript: 5.6.3 - dev: false - - /@solana/codecs-numbers@2.0.0-preview.4(typescript@5.6.3): - resolution: {integrity: sha512-Q061rLtMadsO7uxpguT+Z7G4UHnjQ6moVIxAQxR58nLxDPCC7MB1Pk106/Z7NDhDLHTcd18uO6DZ7ajHZEn2XQ==} - peerDependencies: - typescript: '>=5' + '@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.0.0-preview.4(typescript@5.6.3) - '@solana/errors': 2.0.0-preview.4(typescript@5.6.3) - typescript: 5.6.3 - dev: false + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.8.3) + '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) + typescript: 5.8.3 - /@solana/codecs-numbers@2.0.0-rc.1(typescript@4.9.5): - resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} - peerDependencies: - typescript: '>=5' + '@solana/codecs-numbers@2.0.0-rc.1(typescript@4.9.5)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) typescript: 4.9.5 - dev: false - /@solana/codecs-numbers@2.0.0-rc.1(typescript@5.6.3): - resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} - peerDependencies: - typescript: '>=5' + '@solana/codecs-numbers@2.0.0-rc.1(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.6.3) - '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) - typescript: 5.6.3 - dev: false + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) + '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) + typescript: 5.8.3 - /@solana/codecs-strings@2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): - resolution: {integrity: sha512-YDbsQePRWm+xnrfS64losSGRg8Wb76cjK1K6qfR8LPmdwIC3787x9uW5/E4icl/k+9nwgbIRXZ65lpF+ucZUnw==} - peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - typescript: '>=5' + '@solana/codecs-numbers@2.3.0(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.0.0-preview.4(typescript@5.6.3) - '@solana/codecs-numbers': 2.0.0-preview.4(typescript@5.6.3) - '@solana/errors': 2.0.0-preview.4(typescript@5.6.3) - fastestsmallesttextencoderdecoder: 1.0.22 - typescript: 5.6.3 - dev: false + '@solana/codecs-core': 2.3.0(typescript@5.8.3) + '@solana/errors': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 - /@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} - peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - typescript: '>=5' + '@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) fastestsmallesttextencoderdecoder: 1.0.22 typescript: 4.9.5 - dev: false - /@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): - resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} - peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - typescript: '>=5' + '@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.6.3) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.6.3) - '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.8.3) + '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) fastestsmallesttextencoderdecoder: 1.0.22 - typescript: 5.6.3 - dev: false - - /@solana/codecs@2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): - resolution: {integrity: sha512-gLMupqI4i+G4uPi2SGF/Tc1aXcviZF2ybC81x7Q/fARamNSgNOCUUoSCg9nWu1Gid6+UhA7LH80sWI8XjKaRog==} - peerDependencies: - typescript: '>=5' - dependencies: - '@solana/codecs-core': 2.0.0-preview.4(typescript@5.6.3) - '@solana/codecs-data-structures': 2.0.0-preview.4(typescript@5.6.3) - '@solana/codecs-numbers': 2.0.0-preview.4(typescript@5.6.3) - '@solana/codecs-strings': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/options': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - typescript: 5.6.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - dev: false + typescript: 5.8.3 - /@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} - peerDependencies: - typescript: '>=5' + '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) @@ -536,75 +1396,37 @@ packages: typescript: 4.9.5 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - dev: false - /@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): - resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} - peerDependencies: - typescript: '>=5' + '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.6.3) - '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.6.3) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.6.3) - '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - typescript: 5.6.3 + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - dev: false - - /@solana/errors@2.0.0-preview.4(typescript@5.6.3): - resolution: {integrity: sha512-kadtlbRv2LCWr8A9V22On15Us7Nn8BvqNaOB4hXsTB3O0fU40D1ru2l+cReqLcRPij4znqlRzW9Xi0m6J5DIhA==} - hasBin: true - peerDependencies: - typescript: '>=5' - dependencies: - chalk: 5.3.0 - commander: 12.1.0 - typescript: 5.6.3 - dev: false - /@solana/errors@2.0.0-rc.1(typescript@4.9.5): - resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} - hasBin: true - peerDependencies: - typescript: '>=5' + '@solana/errors@2.0.0-rc.1(typescript@4.9.5)': dependencies: - chalk: 5.3.0 + chalk: 5.4.1 commander: 12.1.0 typescript: 4.9.5 - dev: false - /@solana/errors@2.0.0-rc.1(typescript@5.6.3): - resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} - hasBin: true - peerDependencies: - typescript: '>=5' + '@solana/errors@2.0.0-rc.1(typescript@5.8.3)': dependencies: - chalk: 5.3.0 + chalk: 5.4.1 commander: 12.1.0 - typescript: 5.6.3 - dev: false + typescript: 5.8.3 - /@solana/options@2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): - resolution: {integrity: sha512-tv2O/Frxql/wSe3jbzi5nVicIWIus/BftH+5ZR+r9r3FO0/htEllZS5Q9XdbmSboHu+St87584JXeDx3xm4jaA==} - peerDependencies: - typescript: '>=5' + '@solana/errors@2.3.0(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.0.0-preview.4(typescript@5.6.3) - '@solana/codecs-data-structures': 2.0.0-preview.4(typescript@5.6.3) - '@solana/codecs-numbers': 2.0.0-preview.4(typescript@5.6.3) - '@solana/codecs-strings': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/errors': 2.0.0-preview.4(typescript@5.6.3) - typescript: 5.6.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - dev: false + chalk: 5.4.1 + commander: 14.0.0 + typescript: 5.8.3 - /@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} - peerDependencies: - typescript: '>=5' + '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) @@ -614,75 +1436,48 @@ packages: typescript: 4.9.5 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - dev: false - /@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): - resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} - peerDependencies: - typescript: '>=5' + '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@5.6.3) - '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.6.3) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.6.3) - '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/errors': 2.0.0-rc.1(typescript@5.6.3) - typescript: 5.6.3 + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.8.3) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - dev: false - /@solana/spl-token-group@0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): - resolution: {integrity: sha512-CLJnWEcdoUBpQJfx9WEbX3h6nTdNiUzswfFdkABUik7HVwSNA98u5AYvBVK2H93d9PGMOHAak2lHW9xr+zAJGQ==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.94.0 + '@solana/spl-token-group@0.0.7(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/codecs': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.8 + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript - dev: false - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): - resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.95.3 + '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': dependencies: - '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.8 + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript - dev: false - /@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-DSBlo7vjuLe/xvNn75OKKndDBkFxlqjLdWlq6rf40StnrhRn7TDntHGLZpry1cf3uzQFShqeLROGNPAJwvkPnA==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.95.3 + '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.98.0 + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript - dev: false - /@solana/spl-token@0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5): - resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.88.0 + '@solana/spl-token@0.3.11(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.98.0 + '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -690,19 +1485,14 @@ packages: - fastestsmallesttextencoderdecoder - typescript - utf-8-validate - dev: false - /@solana/spl-token@0.4.8(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3): - resolution: {integrity: sha512-RO0JD9vPRi4LsAbMUdNbDJ5/cv2z11MGhtAvFeRzT4+hAGE/FUzRi0tkkWtuCfSIU3twC6CtmAihRp/+XXjWsA==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.94.0 + '@solana/spl-token@0.4.13(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3) - '@solana/web3.js': 1.95.8 + '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/spl-token-group': 0.0.7(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -710,434 +1500,288 @@ packages: - fastestsmallesttextencoderdecoder - typescript - utf-8-validate - dev: false - - /@solana/spl-type-length-value@0.1.0: - resolution: {integrity: sha512-JBMGB0oR4lPttOZ5XiUGyvylwLQjt1CPJa6qQ5oM+MBCndfjz2TKKkw0eATlLLcYmq1jBVsNlJ2cD6ns2GR7lA==} - engines: {node: '>=16'} - dependencies: - buffer: 6.0.3 - dev: false - /@solana/web3.js@1.95.8: - resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} + '@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.25.7 - '@noble/curves': 1.6.0 - '@noble/hashes': 1.5.0 + '@babel/runtime': 7.27.6 + '@noble/curves': 1.9.4 + '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.5.0 + agentkeepalive: 4.6.0 bigint-buffer: 1.1.5 - bn.js: 5.2.1 + bn.js: 5.2.2 borsh: 0.7.0 bs58: 4.0.1 buffer: 6.0.3 fast-stable-stringify: 1.0.0 - jayson: 4.1.2 + jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) node-fetch: 2.7.0 - rpc-websockets: 9.0.4 + rpc-websockets: 9.1.1 superstruct: 2.0.2 transitivePeerDependencies: - bufferutil - encoding - utf-8-validate - dev: false - /@solana/web3.js@1.98.0: - resolution: {integrity: sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==} + '@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.25.7 - '@noble/curves': 1.6.0 - '@noble/hashes': 1.5.0 + '@babel/runtime': 7.27.6 + '@noble/curves': 1.9.4 + '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.5.0 - bigint-buffer: 1.1.5 - bn.js: 5.2.1 + '@solana/codecs-numbers': 2.3.0(typescript@5.8.3) + agentkeepalive: 4.6.0 + bn.js: 5.2.2 borsh: 0.7.0 bs58: 4.0.1 buffer: 6.0.3 fast-stable-stringify: 1.0.0 - jayson: 4.1.2 + jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) node-fetch: 2.7.0 - rpc-websockets: 9.0.4 + rpc-websockets: 9.1.1 superstruct: 2.0.2 transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate - dev: false - /@solworks/soltoolkit-sdk@0.0.23(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} + '@solworks/soltoolkit-sdk@0.0.23(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/spl-token': 0.3.11(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.98.0 - '@types/bn.js': 5.1.6 - '@types/node': 18.19.65 + '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@types/bn.js': 5.2.0 + '@types/node': 18.19.119 '@types/node-fetch': 2.6.12 - bn.js: 5.2.1 - decimal.js: 10.4.3 + bn.js: 5.2.2 + decimal.js: 10.6.0 typescript: 4.9.5 transitivePeerDependencies: - bufferutil - encoding - fastestsmallesttextencoderdecoder - utf-8-validate - dev: false - /@soncodi/signal@2.0.7: - resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} - dev: false + '@soncodi/signal@2.0.7': {} - /@swc/helpers@0.5.13: - resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} + '@swc/helpers@0.5.17': dependencies: - tslib: 2.7.0 - dev: false + tslib: 2.8.1 - /@switchboard-xyz/common@2.5.5: - resolution: {integrity: sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w==} - engines: {node: '>=12'} + '@switchboard-xyz/common@2.5.19(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: - '@solana/web3.js': 1.98.0 - axios: 1.8.4 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + axios: 1.10.0 big.js: 6.2.2 - bn.js: 5.2.1 - bs58: 5.0.0 - cron-validator: 1.3.1 - decimal.js: 10.4.3 - js-sha256: 0.11.0 + bn.js: 5.2.2 + bs58: 6.0.0 + cron-validator: 1.4.0 + decimal.js: 10.6.0 + js-sha256: 0.11.1 lodash: 4.17.21 - protobufjs: 7.4.0 - yaml: 2.6.1 + protobufjs: 7.5.3 + yaml: 2.8.0 transitivePeerDependencies: - bufferutil - debug - encoding - utf-8-validate - dev: false - /@switchboard-xyz/common@3.0.12: - resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} - engines: {node: '>=20'} + '@switchboard-xyz/common@3.0.12(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: - '@solana/web3.js': 1.98.0 - axios: 1.8.4 + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + axios: 1.10.0 big.js: 6.2.2 - bn.js: 5.2.1 + bn.js: 5.2.2 bs58: 6.0.0 buffer: 6.0.3 - decimal.js: 10.4.3 - js-sha256: 0.11.0 - protobufjs: 7.4.0 - yaml: 2.6.1 + decimal.js: 10.6.0 + js-sha256: 0.11.1 + protobufjs: 7.5.3 + yaml: 2.8.0 transitivePeerDependencies: - bufferutil - debug - encoding + - typescript - utf-8-validate - dev: false - /@switchboard-xyz/on-demand@1.2.51(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} - engines: {node: '>= 18'} - deprecated: deprecated in favor of 2.x.x + '@switchboard-xyz/on-demand@1.2.51(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10)': dependencies: '@brokerloop/ttlcache': 3.2.3 - '@coral-xyz/anchor-30': /@coral-xyz/anchor@0.30.1 - '@solana/web3.js': 1.98.0 - '@solworks/soltoolkit-sdk': 0.0.23(fastestsmallesttextencoderdecoder@1.0.22) - '@switchboard-xyz/common': 2.5.5 - axios: 1.8.4 + '@coral-xyz/anchor-30': '@coral-xyz/anchor@0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)' + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solworks/soltoolkit-sdk': 0.0.23(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10) + '@switchboard-xyz/common': 2.5.19(bufferutil@4.0.9)(utf-8-validate@5.0.10) + axios: 1.10.0 big.js: 6.2.2 bs58: 5.0.0 js-yaml: 4.1.0 - protobufjs: 7.4.0 + protobufjs: 7.5.3 transitivePeerDependencies: - bufferutil - debug - encoding - fastestsmallesttextencoderdecoder - utf-8-validate - dev: false - /@types/big.js@6.2.2: - resolution: {integrity: sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==} - dev: true + '@types/big.js@6.2.2': {} - /@types/bn.js@5.1.6: - resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} + '@types/bn.js@5.2.0': dependencies: - '@types/node': 20.16.11 - dev: false + '@types/node': 20.19.8 - /@types/chai@4.3.20: - resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} - dev: true + '@types/chai@4.3.20': {} - /@types/connect@3.4.38: - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@types/connect@3.4.38': dependencies: - '@types/node': 20.16.11 - dev: false + '@types/node': 20.19.8 - /@types/json5@0.0.29: - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - requiresBuild: true - dev: true + '@types/json5@0.0.29': optional: true - /@types/mocha@9.1.1: - resolution: {integrity: sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==} - dev: true + '@types/mocha@9.1.1': {} - /@types/node-fetch@2.6.12: - resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + '@types/node-fetch@2.6.12': dependencies: - '@types/node': 20.16.11 - form-data: 4.0.1 - dev: false + '@types/node': 20.19.8 + form-data: 4.0.4 - /@types/node@12.20.55: - resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - dev: false + '@types/node@12.20.55': {} - /@types/node@18.19.65: - resolution: {integrity: sha512-Ay5BZuO1UkTmVHzZJNvZKw/E+iB3GQABb6kijEz89w2JrfhNA+M/ebp18pfz9Gqe9ywhMC8AA8yC01lZq48J+Q==} + '@types/node@18.19.119': dependencies: undici-types: 5.26.5 - dev: false - /@types/node@20.16.11: - resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} + '@types/node@20.19.8': dependencies: - undici-types: 6.19.8 + undici-types: 6.21.0 - /@types/uuid@8.3.4: - resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} - dev: false + '@types/uuid@8.3.4': {} - /@types/ws@7.4.7: - resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + '@types/ws@7.4.7': dependencies: - '@types/node': 20.16.11 - dev: false + '@types/node': 20.19.8 - /@types/ws@8.5.12: - resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} + '@types/ws@8.18.1': dependencies: - '@types/node': 20.16.11 - dev: false + '@types/node': 20.19.8 - /@ungap/promise-all-settled@1.1.2: - resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} - dev: true - - /JSONStream@1.3.5: - resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} - hasBin: true - dependencies: - jsonparse: 1.3.1 - through: 2.3.8 - dev: false + '@ungap/promise-all-settled@1.1.2': {} - /agentkeepalive@4.5.0: - resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} - engines: {node: '>= 8.0.0'} + agentkeepalive@4.6.0: dependencies: humanize-ms: 1.2.1 - dev: false - /ansi-colors@4.1.1: - resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} - engines: {node: '>=6'} - dev: true + ansi-colors@4.1.1: {} - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - dev: true + ansi-regex@5.0.1: {} - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 - dev: true - /anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 - dev: true - - /argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - /arrify@1.0.1: - resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} - engines: {node: '>=0.10.0'} - dev: true + argparse@2.0.1: {} - /assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - dev: true + arrify@1.0.1: {} - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false + assertion-error@1.1.0: {} - /axios@1.7.8: - resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} - dependencies: - follow-redirects: 1.15.9 - form-data: 4.0.1 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - dev: false + asynckit@0.4.0: {} - /axios@1.8.4: - resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} + axios@1.10.0: dependencies: follow-redirects: 1.15.9 - form-data: 4.0.1 + form-data: 4.0.4 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - dev: false - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true + balanced-match@1.0.2: {} - /base-x@3.0.10: - resolution: {integrity: sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==} + base-x@3.0.11: dependencies: safe-buffer: 5.2.1 - dev: false - /base-x@4.0.0: - resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} - dev: false + base-x@4.0.1: {} - /base-x@5.0.0: - resolution: {integrity: sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==} - dev: false + base-x@5.0.1: {} - /base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: false + base64-js@1.5.1: {} - /big.js@6.2.2: - resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} - dev: false + big.js@6.2.2: {} - /bigint-buffer@1.1.5: - resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} - engines: {node: '>= 10.0.0'} - requiresBuild: true + bigint-buffer@1.1.5: dependencies: bindings: 1.5.0 - dev: false - /bignumber.js@9.1.2: - resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} - dev: false + bignumber.js@9.3.1: {} - /binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - dev: true + binary-extensions@2.3.0: {} - /bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + bindings@1.5.0: dependencies: file-uri-to-path: 1.0.0 - dev: false - /bn.js@5.2.1: - resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} - dev: false + bn.js@5.2.2: {} - /borsh@0.7.0: - resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + borsh@0.7.0: dependencies: - bn.js: 5.2.1 + bn.js: 5.2.2 bs58: 4.0.1 text-encoding-utf-8: 1.0.2 - dev: false - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - dev: true - /braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} + braces@3.0.3: dependencies: fill-range: 7.1.1 - dev: true - /browser-stdout@1.3.1: - resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} - dev: true + browser-stdout@1.3.1: {} - /bs58@4.0.1: - resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + bs58@4.0.1: dependencies: - base-x: 3.0.10 - dev: false + base-x: 3.0.11 - /bs58@5.0.0: - resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} + bs58@5.0.0: dependencies: - base-x: 4.0.0 - dev: false + base-x: 4.0.1 - /bs58@6.0.0: - resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + bs58@6.0.0: dependencies: - base-x: 5.0.0 - dev: false + base-x: 5.0.1 - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true + buffer-from@1.1.2: {} - /buffer-layout@1.2.2: - resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==} - engines: {node: '>=4.5'} - dev: false + buffer-layout@1.2.2: {} - /buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + buffer@6.0.3: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - dev: false - /bufferutil@4.0.8: - resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} - engines: {node: '>=6.14.2'} - requiresBuild: true + bufferutil@4.0.9: dependencies: - node-gyp-build: 4.8.2 - dev: false + node-gyp-build: 4.8.4 + optional: true - /camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 - /chai@4.5.0: - resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} - engines: {node: '>=4'} + camelcase@6.3.0: {} + + chai@4.5.0: dependencies: assertion-error: 1.1.0 check-error: 1.0.3 @@ -1146,30 +1790,19 @@ packages: loupe: 2.3.7 pathval: 1.1.1 type-detect: 4.1.0 - dev: true - /chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - dev: true - /chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: false + chalk@5.4.1: {} - /check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + check-error@1.0.3: dependencies: get-func-name: 2.0.2 - dev: true - /chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} + chokidar@3.5.3: dependencies: anymatch: 3.1.3 braces: 3.0.3 @@ -1180,252 +1813,176 @@ packages: readdirp: 3.6.0 optionalDependencies: fsevents: 2.3.3 - dev: true - /cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + cliui@7.0.4: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - dev: true - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + color-convert@2.0.1: dependencies: color-name: 1.1.4 - dev: true - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true + color-name@1.1.4: {} - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 - dev: false - /commander@12.1.0: - resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} - engines: {node: '>=18'} - dev: false + commander@12.1.0: {} - /commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: false + commander@14.0.0: {} - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true + commander@2.20.3: {} + + concat-map@0.0.1: {} - /cron-validator@1.3.1: - resolution: {integrity: sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==} - dev: false + cron-validator@1.4.0: {} - /cross-fetch@3.1.8: - resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + cross-fetch@3.2.0: dependencies: node-fetch: 2.7.0 transitivePeerDependencies: - encoding - dev: false - /cross-fetch@4.0.0: - resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + cross-fetch@4.1.0: dependencies: node-fetch: 2.7.0 transitivePeerDependencies: - encoding - dev: false - /crypto-hash@1.3.0: - resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} - engines: {node: '>=8'} - dev: false + crypto-hash@1.3.0: {} - /debug@4.3.3(supports-color@8.1.1): - resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + debug@4.3.3(supports-color@8.1.1): dependencies: ms: 2.1.2 + optionalDependencies: supports-color: 8.1.1 - dev: true - /decamelize@4.0.0: - resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} - engines: {node: '>=10'} - dev: true + decamelize@4.0.0: {} - /decimal.js@10.4.3: - resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} - dev: false + decimal.js@10.6.0: {} - /deep-eql@4.1.4: - resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} - engines: {node: '>=6'} + deep-eql@4.1.4: dependencies: type-detect: 4.1.0 - dev: true - /delay@5.0.0: - resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} - engines: {node: '>=10'} - dev: false + delay@5.0.0: {} - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: false + delayed-stream@1.0.0: {} - /diff@3.5.0: - resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==} - engines: {node: '>=0.3.1'} - dev: true + diff@3.5.0: {} - /diff@5.0.0: - resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} - engines: {node: '>=0.3.1'} - dev: true + diff@5.0.0: {} - /dot-case@3.0.4: - resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dot-case@3.0.4: dependencies: no-case: 3.0.4 - tslib: 2.7.0 - dev: false + tslib: 2.8.1 - /dotenv@16.4.7: - resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} - engines: {node: '>=12'} - dev: false + dotenv@16.6.1: {} - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 - /es6-promise@4.2.8: - resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} - dev: false + emoji-regex@8.0.0: {} - /es6-promisify@5.0.0: - resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es6-promise@4.2.8: {} + + es6-promisify@5.0.0: dependencies: es6-promise: 4.2.8 - dev: false - /escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - dev: true + escalade@3.2.0: {} - /escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - dev: true + escape-string-regexp@4.0.0: {} - /eventemitter3@4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - dev: false + eventemitter3@4.0.7: {} - /eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} - dev: false + eventemitter3@5.0.1: {} - /eyes@0.1.8: - resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} - engines: {node: '> 0.1.90'} - dev: false + eyes@0.1.8: {} - /fast-stable-stringify@1.0.0: - resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} - dev: false + fast-stable-stringify@1.0.0: {} - /fastestsmallesttextencoderdecoder@1.0.22: - resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} - dev: false + fastestsmallesttextencoderdecoder@1.0.22: {} - /file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - dev: false + file-uri-to-path@1.0.0: {} - /fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 - dev: true - /find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} + find-up@5.0.0: dependencies: locate-path: 6.0.0 path-exists: 4.0.0 - dev: true - /flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true - dev: true + flat@5.0.2: {} - /follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false + follow-redirects@1.15.9: {} - /form-data@4.0.1: - resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} - engines: {node: '>= 6'} + form-data@4.0.4: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 mime-types: 2.1.35 - dev: false - /fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true + fs.realpath@1.0.0: {} - /fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: true + fsevents@2.3.3: optional: true - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true + function-bind@1.1.2: {} - /get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - dev: true + get-caller-file@2.0.5: {} - /glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + get-func-name@2.0.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 - dev: true - /glob@7.2.0: - resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} - deprecated: Glob versions prior to v9 are no longer supported + glob@7.2.0: dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -1433,225 +1990,139 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 - dev: true - /growl@1.10.5: - resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} - engines: {node: '>=4.x'} - dev: true + gopd@1.2.0: {} - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true + growl@1.10.5: {} - /he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - dev: true + has-flag@4.0.0: {} - /humanize-ms@1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + humanize-ms@1.2.1: dependencies: ms: 2.1.3 - dev: false - /ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: false + ieee754@1.2.1: {} - /inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + inflight@1.0.6: dependencies: once: 1.4.0 wrappy: 1.0.2 - dev: true - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true + inherits@2.0.4: {} - /is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 - dev: true - /is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - dev: true + is-extglob@2.1.1: {} - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - dev: true + is-fullwidth-code-point@3.0.0: {} - /is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 - dev: true - /is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true + is-number@7.0.0: {} - /is-plain-obj@2.1.0: - resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} - engines: {node: '>=8'} - dev: true + is-plain-obj@2.1.0: {} - /is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - dev: true + is-unicode-supported@0.1.0: {} - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true + isexe@2.0.0: {} - /isomorphic-ws@4.0.1(ws@7.5.10): - resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} - peerDependencies: - ws: '*' + isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: - ws: 7.5.10 - dev: false + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) - /jayson@4.1.2: - resolution: {integrity: sha512-5nzMWDHy6f+koZOuYsArh2AXs73NfWYVlFyJJuCedr93GpY+Ku8qq10ropSXVfHK+H0T6paA88ww+/dV+1fBNA==} - engines: {node: '>=8'} - hasBin: true + jayson@4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@types/connect': 3.4.38 '@types/node': 12.20.55 '@types/ws': 7.4.7 - JSONStream: 1.3.5 commander: 2.20.3 delay: 5.0.0 es6-promisify: 5.0.0 eyes: 0.1.8 - isomorphic-ws: 4.0.1(ws@7.5.10) + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) json-stringify-safe: 5.0.1 + stream-json: 1.9.1 uuid: 8.3.2 - ws: 7.5.10 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - utf-8-validate - dev: false - /js-sha256@0.11.0: - resolution: {integrity: sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==} - dev: false + js-sha256@0.11.1: {} - /js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true + js-yaml@4.1.0: dependencies: argparse: 2.0.1 - /json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - dev: false + json-stringify-safe@5.0.1: {} - /json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - requiresBuild: true + json5@1.0.2: dependencies: minimist: 1.2.8 - dev: true optional: true - /jsonparse@1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} - dev: false - - /locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 - dev: true - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: false + lodash@4.17.21: {} - /log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} + log-symbols@4.1.0: dependencies: chalk: 4.1.2 is-unicode-supported: 0.1.0 - dev: true - /long@5.2.3: - resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} - dev: false + long@5.3.2: {} - /loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + loupe@2.3.7: dependencies: get-func-name: 2.0.2 - dev: true - /lower-case@2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lower-case@2.0.2: dependencies: - tslib: 2.7.0 - dev: false + tslib: 2.8.1 - /make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true + make-error@1.3.6: {} - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: false + math-intrinsics@1.1.0: {} - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + mime-db@1.52.0: {} + + mime-types@2.1.35: dependencies: mime-db: 1.52.0 - dev: false - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@3.1.2: dependencies: - brace-expansion: 1.1.11 - dev: true + brace-expansion: 1.1.12 - /minimatch@4.2.1: - resolution: {integrity: sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==} - engines: {node: '>=10'} + minimatch@4.2.1: dependencies: - brace-expansion: 1.1.11 - dev: true + brace-expansion: 1.1.12 - /minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: true + minimist@1.2.8: {} - /mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true + mkdirp@0.5.6: dependencies: minimist: 1.2.8 - dev: true - /mocha@9.2.2: - resolution: {integrity: sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==} - engines: {node: '>= 12.0.0'} - hasBin: true + mocha@9.2.2: dependencies: '@ungap/promise-all-settled': 1.1.2 ansi-colors: 4.1.1 @@ -1677,98 +2148,50 @@ packages: yargs: 16.2.0 yargs-parser: 20.2.4 yargs-unparser: 2.0.0 - dev: true - /ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true + ms@2.1.2: {} - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + ms@2.1.3: {} - /nanoid@3.3.1: - resolution: {integrity: sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - dev: true + nanoid@3.3.1: {} - /no-case@3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + no-case@3.0.4: dependencies: lower-case: 2.0.2 - tslib: 2.7.0 - dev: false + tslib: 2.8.1 - /node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true + node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 - dev: false - /node-gyp-build@4.8.2: - resolution: {integrity: sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==} - hasBin: true - requiresBuild: true - dev: false + node-gyp-build@4.8.4: + optional: true - /normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - dev: true + normalize-path@3.0.0: {} - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + once@1.4.0: dependencies: wrappy: 1.0.2 - dev: true - /p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 - dev: true - /p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + p-locate@5.0.0: dependencies: p-limit: 3.1.0 - dev: true - /pako@2.1.0: - resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} - dev: false + pako@2.1.0: {} - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true + path-exists@4.0.0: {} - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: true + path-is-absolute@1.0.1: {} - /pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} - dev: true + pathval@1.1.1: {} - /picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true + picomatch@2.3.1: {} - /protobufjs@7.4.0: - resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==} - engines: {node: '>=12.0.0'} - requiresBuild: true + protobufjs@7.5.3: dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/base64': 1.1.2 @@ -1780,182 +2203,112 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 20.16.11 - long: 5.2.3 - dev: false + '@types/node': 20.19.8 + long: 5.3.2 - /proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: false + proxy-from-env@1.1.0: {} - /randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 - dev: true - /readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} + readdirp@3.6.0: dependencies: picomatch: 2.3.1 - dev: true - /regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - dev: false + require-directory@2.1.1: {} - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true - - /rpc-websockets@7.11.0: - resolution: {integrity: sha512-IkLYjayPv6Io8C/TdCL5gwgzd1hFz2vmBZrjMw/SPEXo51ETOhnzgS4Qy5GWi2JQN7HKHa66J3+2mv0fgNh/7w==} - deprecated: deprecate 7.11.0 + rpc-websockets@7.11.0: dependencies: eventemitter3: 4.0.7 uuid: 8.3.2 - ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - bufferutil: 4.0.8 + bufferutil: 4.0.9 utf-8-validate: 5.0.10 - dev: false - /rpc-websockets@9.0.4: - resolution: {integrity: sha512-yWZWN0M+bivtoNLnaDbtny4XchdAIF5Q4g/ZsC5UC61Ckbp0QczwO8fg44rV3uYmY4WHd+EZQbn90W1d8ojzqQ==} + rpc-websockets@9.1.1: dependencies: - '@swc/helpers': 0.5.13 + '@swc/helpers': 0.5.17 '@types/uuid': 8.3.4 - '@types/ws': 8.5.12 + '@types/ws': 8.18.1 buffer: 6.0.3 eventemitter3: 5.0.1 uuid: 8.3.2 - ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - bufferutil: 4.0.8 + bufferutil: 4.0.9 utf-8-validate: 5.0.10 - dev: false - /safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-buffer@5.2.1: {} - /serialize-javascript@6.0.0: - resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + serialize-javascript@6.0.0: dependencies: randombytes: 2.1.0 - dev: true - /snake-case@3.0.4: - resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + snake-case@3.0.4: dependencies: dot-case: 3.0.4 - tslib: 2.7.0 - dev: false + tslib: 2.8.1 - /source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 - dev: true - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true + source-map@0.6.1: {} - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + stream-chain@2.2.5: {} + + stream-json@1.9.1: + dependencies: + stream-chain: 2.2.5 + + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - dev: true - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - dev: true - /strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - requiresBuild: true - dev: true + strip-bom@3.0.0: optional: true - /strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true + strip-json-comments@3.1.1: {} - /superstruct@0.15.5: - resolution: {integrity: sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==} - dev: false + superstruct@0.15.5: {} - /superstruct@2.0.2: - resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} - engines: {node: '>=14.0.0'} - dev: false + superstruct@2.0.2: {} - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 - dev: true - /supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} + supports-color@8.1.1: dependencies: has-flag: 4.0.0 - dev: true - - /text-encoding-utf-8@1.0.2: - resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} - dev: false - /through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: false + text-encoding-utf-8@1.0.2: {} - /to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - dev: true - /toml@3.0.0: - resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} - dev: false + toml@3.0.0: {} - /tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: false + tr46@0.0.3: {} - /ts-mocha@10.0.0(mocha@9.2.2): - resolution: {integrity: sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw==} - engines: {node: '>= 6.X.X'} - hasBin: true - peerDependencies: - mocha: ^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X + ts-mocha@10.1.0(mocha@9.2.2): dependencies: mocha: 9.2.2 ts-node: 7.0.1 optionalDependencies: tsconfig-paths: 3.15.0 - dev: true - /ts-node@7.0.1: - resolution: {integrity: sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==} - engines: {node: '>=4.2.0'} - hasBin: true + ts-node@7.0.1: dependencies: arrify: 1.0.1 buffer-from: 1.1.2 @@ -1965,153 +2318,79 @@ packages: mkdirp: 0.5.6 source-map-support: 0.5.21 yn: 2.0.0 - dev: true - /tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - requiresBuild: true + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 json5: 1.0.2 minimist: 1.2.8 strip-bom: 3.0.0 - dev: true optional: true - /tslib@2.7.0: - resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} - dev: false + tslib@2.8.1: {} - /type-detect@4.1.0: - resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} - engines: {node: '>=4'} - dev: true + type-detect@4.1.0: {} - /typescript@4.9.5: - resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: false + typescript@4.9.5: {} - /typescript@5.6.3: - resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} - engines: {node: '>=14.17'} - hasBin: true + typescript@5.8.3: {} - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: false + undici-types@5.26.5: {} - /undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + undici-types@6.21.0: {} - /utf-8-validate@5.0.10: - resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} - engines: {node: '>=6.14.2'} - requiresBuild: true + utf-8-validate@5.0.10: dependencies: - node-gyp-build: 4.8.2 - dev: false + node-gyp-build: 4.8.4 + optional: true - /uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - dev: false + uuid@8.3.2: {} - /webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: false + webidl-conversions@3.0.1: {} - /whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 - dev: false - /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true + which@2.0.2: dependencies: isexe: 2.0.0 - dev: true - /workerpool@6.2.0: - resolution: {integrity: sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==} - dev: true + workerpool@6.2.0: {} - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - dev: true - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true + wrappy@1.0.2: {} - /ws@7.5.10: - resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} - engines: {node: '>=8.3.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: false + ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 - /ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): - resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dependencies: - bufferutil: 4.0.8 + ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 utf-8-validate: 5.0.10 - dev: false - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: true + y18n@5.0.8: {} - /yaml@2.6.1: - resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==} - engines: {node: '>= 14'} - hasBin: true - dev: false + yaml@2.8.0: {} - /yargs-parser@20.2.4: - resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} - engines: {node: '>=10'} - dev: true + yargs-parser@20.2.4: {} - /yargs-unparser@2.0.0: - resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} - engines: {node: '>=10'} + yargs-unparser@2.0.0: dependencies: camelcase: 6.3.0 decamelize: 4.0.0 flat: 5.0.2 is-plain-obj: 2.1.0 - dev: true - /yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} + yargs@16.2.0: dependencies: cliui: 7.0.4 escalade: 3.2.0 @@ -2120,14 +2399,7 @@ packages: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 20.2.4 - dev: true - /yn@2.0.0: - resolution: {integrity: sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==} - engines: {node: '>=4'} - dev: true + yn@2.0.0: {} - /yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - dev: true + yocto-queue@0.1.0: {} From a3dec7b9d3903dc41516725029b7fb895a20438c Mon Sep 17 00:00:00 2001 From: Chelioso Date: Thu, 4 Sep 2025 00:52:10 +0900 Subject: [PATCH 74/88] oracle changes from marginfi --- solauto-sdk/package.json | 2 +- .../src/constants/switchboardConstants.ts | 17 ++++++++ .../manager/clientTransactionsManager.ts | 41 ++++++++++++------- solauto-sdk/src/utils/priceUtils.ts | 10 +++-- 4 files changed, 52 insertions(+), 18 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 312f8f19..a891bfe0 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.789", + "version": "1.0.792", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/constants/switchboardConstants.ts b/solauto-sdk/src/constants/switchboardConstants.ts index bd2110eb..dafd62fd 100644 --- a/solauto-sdk/src/constants/switchboardConstants.ts +++ b/solauto-sdk/src/constants/switchboardConstants.ts @@ -1,3 +1,4 @@ +import { NATIVE_MINT } from "@solana/spl-token"; import * as tokens from "./tokenConstants"; interface SwitchboardFeed { @@ -7,11 +8,27 @@ interface SwitchboardFeed { // https://beta.ondemand.switchboard.xyz/solana/mainnet export const SWITCHBOARD_PRICE_FEED_IDS: { [key: string]: SwitchboardFeed } = { + [NATIVE_MINT.toString()]: { + feedId: "4Hmd6PdjVA9auCoScE12iaBogfwS4ZXQ6VZoBeqanwWW", + feedHash: "0x1f42dfb21efb24828b99fbe70e6d139cd665aafcbb1706bccd8f2a9b12562db6", + }, [tokens.JUP_SOL]: { feedId: "HX5WM3qzogAfRCjBUWwnniLByMfFrjm1b5yo4KoWGR27", feedHash: "0xc02f22d47b20b43bafde474328ac027283dbd7bb443660f5ec414c93faec56dc", }, + [tokens.JITO_SOL]: { + feedId: "5htZ4vPKPjAEg8EJv6JHcaCetMM4XehZo8znQvrp6Ur3", + feedHash: "0x44f5a7676baf4c6e5eb26fdde2695e7e3e0971071b76ddc622fa71528092ca25" + }, + [tokens.LST]: { + feedId: "BWK8Wnybb7rPteNMqJs9uWoqdfYApNym6WgE59BwLe1v", + feedHash: "0x74e140c452fe29cced80898a51961ed1410c1fe0efbdc970fe5aac986427419e" + }, + [tokens.JTO]: { + feedId: "A9RnpLxxtAS2TR3HtSMNJfsKpRPvkLbBkGZ6gKziSPLr", + feedHash: "0xa5bc3b659791facc5edfd8e74942c79d7e8d59f0f913dcdd9bcfb33a2fceb575" + }, [tokens.H_SOL]: { feedId: "1snBjCaHejZqQsAqkELAKNaqUrDNNCr7zmNX6qaQCzg", feedHash: diff --git a/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts b/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts index bc8a9dfb..9a1b2a4c 100644 --- a/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts @@ -6,6 +6,7 @@ import { SolautoClient } from "../../solauto"; import { TransactionsManager } from "./transactionsManager"; import { buildSwbSubmitResponseTx, + getSwitchboardFeedData, isSwitchboardMint, retryWithExponentialBackoff, } from "../../../utils"; @@ -44,20 +45,31 @@ export class ClientTransactionsManager extends TransactionsManager x.oracleInteractor) && switchboardMints.length) { - this.txHandler.log("Requires oracle update(s)..."); - const oracleTxs = switchboardMints.map( - (x) => - new TransactionItem( - async () => - await buildSwbSubmitResponseTx( - this.txHandler.connection, - this.txHandler.signer, - x - ), - this.updateOracleTxName + this.txHandler.log("Checking if oracle update(s) needed..."); + const staleOracles = + ( + await getSwitchboardFeedData( + this.txHandler.connection, + switchboardMints ) - ); - txs.unshift(...oracleTxs); + ).filter((x) => x.stale).length > 0; + + if (staleOracles) { + this.txHandler.log("Requires oracle update(s)..."); + const oracleTxs = switchboardMints.map( + (x) => + new TransactionItem( + async () => + await buildSwbSubmitResponseTx( + this.txHandler.connection, + this.txHandler.signer, + x + ), + this.updateOracleTxName + ) + ); + txs.unshift(...oracleTxs); + } } } @@ -111,7 +123,8 @@ export class ClientTransactionsManager extends TransactionsManager 4; + const updateLutInSepTx = + updateLut?.new || (updateLut?.accountsToAdd ?? []).length > 4; if (updateLut && updateLutInSepTx) { await this.updateLut(updateLut.tx, updateLut.new); } diff --git a/solauto-sdk/src/utils/priceUtils.ts b/solauto-sdk/src/utils/priceUtils.ts index 52058e8f..0d1ae90e 100644 --- a/solauto-sdk/src/utils/priceUtils.ts +++ b/solauto-sdk/src/utils/priceUtils.ts @@ -45,8 +45,10 @@ export async function fetchTokenPrices( const pythMints = newMints.filter((x) => Object.keys(PYTH_PRICE_FEED_IDS).includes(x.toString()) ); - const switchboardMints = newMints.filter((x) => - Object.keys(SWITCHBOARD_PRICE_FEED_IDS).includes(x.toString()) + const switchboardMints = newMints.filter( + (x) => + Object.keys(SWITCHBOARD_PRICE_FEED_IDS).includes(x.toString()) && + !pythMints.map((y) => y.toString()).includes(x.toString()) ); const otherMints = newMints.filter( (x) => !pythMints.includes(x) && !switchboardMints.includes(x) @@ -88,7 +90,9 @@ export async function getPythPrices( const getReq = async () => await fetch( - `https://hermes.pyth.network/v2/updates/price/latest?${priceFeedIds.map((x) => `ids%5B%5D=${x}`).join("&")}` + `https://hermes.pyth.network/v2/updates/price/latest?${priceFeedIds + .map((x) => `ids%5B%5D=${x}`) + .join("&")}` ); const deriveValue = (price: number, exponent: number) => { From 05ebbcb7879813cf0dc2194d790cdc4840275990 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 8 Sep 2025 16:28:01 +0900 Subject: [PATCH 75/88] script change --- package.json | 5 ++-- pnpm-lock.yaml | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c4fdafb6..d5c25753 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "build:ts": "cd solauto-sdk && npm run build", "deploy:buffer": "solana program write-buffer target/deploy/solauto.so --use-rpc --max-sign-attempts 50 --with-compute-unit-price 0.00001", "deploy:rs:test": "solana program deploy target/deploy/solauto.so --program-id TesTjfQ6TbXv96Tv6fqr95XTZ1LYPxtkafmShN9PjBp --use-rpc --buffer ~/.config/solana/buffer.json --max-sign-attempts 50", - "deploy:ts": "cd solauto-sdk && npm publish", + "deploy:ts": "cd solauto-sdk && cross-env NPM_TOKEN=$CHELISO_NPM_TOKEN npm publish", "generate": "pnpm generate:idl && pnpm generate:clients", "generate:idl": "shank idl --crate-root programs/solauto --out-dir idls --out-filename solauto.json -p AutoyKBRaHSBHy9RsmXCZMy6nNFAg5FYijrvZyQcNLV", "generate:clients": "node ./generateClients.cjs && pnpm format:rust", @@ -36,7 +36,8 @@ "@metaplex-foundation/kinobi": "^0.18.5", "@mrgnlabs/marginfi-client-v2": "^6.0.1", "@mrgnlabs/mrgn-common": "^2.0.2", - "borsh": "^2.0.0" + "borsh": "^2.0.0", + "cross-env": "^10.0.0" }, "devDependencies": { "solauto-sdk": "file:solauto-sdk", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 95d1b0a1..b2f2475b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: borsh: specifier: ^2.0.0 version: 2.0.0 + cross-env: + specifier: ^10.0.0 + version: 10.0.0 devDependencies: solauto-sdk: specifier: file:solauto-sdk @@ -65,6 +68,9 @@ packages: peerDependencies: '@solana/web3.js': ^1.68.0 + '@epic-web/invariant@1.0.0': + resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} + '@grpc/grpc-js@1.13.4': resolution: {integrity: sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==} engines: {node: '>=12.10.0'} @@ -562,12 +568,21 @@ packages: cron-validator@1.4.0: resolution: {integrity: sha512-wGcJ9FCy65iaU6egSH8b5dZYJF7GU/3Jh06wzaT9lsa5dbqExjljmu+0cJ8cpKn+vUyZa/EM4WAxeLR6SypJXw==} + cross-env@10.0.0: + resolution: {integrity: sha512-aU8qlEK/nHYtVuN4p7UQgAwVljzMg8hB4YK5ThRqD2l/ziSnryncPNn7bMLt5cFYsKVKBh8HqLqyCoTupEUu7Q==} + engines: {node: '>=20'} + hasBin: true + cross-fetch@3.2.0: resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} cross-fetch@4.1.0: resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + crypto-hash@1.3.0: resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} engines: {node: '>=8'} @@ -718,6 +733,9 @@ packages: isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isomorphic-ws@4.0.1: resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} peerDependencies: @@ -814,6 +832,10 @@ packages: pako@2.1.0: resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + prettier@3.6.2: resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} engines: {node: '>=14'} @@ -847,6 +869,14 @@ packages: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} @@ -919,6 +949,11 @@ packages: whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -1041,6 +1076,8 @@ snapshots: bn.js: 5.2.2 buffer-layout: 1.2.2 + '@epic-web/invariant@1.0.0': {} + '@grpc/grpc-js@1.13.4': dependencies: '@grpc/proto-loader': 0.7.15 @@ -1839,6 +1876,11 @@ snapshots: cron-validator@1.4.0: {} + cross-env@10.0.0: + dependencies: + '@epic-web/invariant': 1.0.0 + cross-spawn: 7.0.6 + cross-fetch@3.2.0: dependencies: node-fetch: 2.7.0 @@ -1851,6 +1893,12 @@ snapshots: transitivePeerDependencies: - encoding + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + crypto-hash@1.3.0: {} crypto-hash@3.1.0: {} @@ -1979,6 +2027,8 @@ snapshots: isarray@2.0.5: {} + isexe@2.0.0: {} + isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -2080,6 +2130,8 @@ snapshots: pako@2.1.0: {} + path-key@3.1.1: {} + prettier@3.6.2: {} protobufjs@7.5.3: @@ -2143,6 +2195,12 @@ snapshots: gopd: 1.2.0 has-property-descriptors: 1.0.2 + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + snake-case@3.0.4: dependencies: dot-case: 3.0.4 @@ -2204,6 +2262,10 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 + which@2.0.2: + dependencies: + isexe: 2.0.0 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 From 728b9738390273770a8c6a7ff15c9ee9ba9be5c5 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Mon, 8 Sep 2025 16:33:49 +0900 Subject: [PATCH 76/88] revert --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d5c25753..4c03ec4e 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "build:ts": "cd solauto-sdk && npm run build", "deploy:buffer": "solana program write-buffer target/deploy/solauto.so --use-rpc --max-sign-attempts 50 --with-compute-unit-price 0.00001", "deploy:rs:test": "solana program deploy target/deploy/solauto.so --program-id TesTjfQ6TbXv96Tv6fqr95XTZ1LYPxtkafmShN9PjBp --use-rpc --buffer ~/.config/solana/buffer.json --max-sign-attempts 50", - "deploy:ts": "cd solauto-sdk && cross-env NPM_TOKEN=$CHELISO_NPM_TOKEN npm publish", + "deploy:ts": "cd solauto-sdk && npm publish", "generate": "pnpm generate:idl && pnpm generate:clients", "generate:idl": "shank idl --crate-root programs/solauto --out-dir idls --out-filename solauto.json -p AutoyKBRaHSBHy9RsmXCZMy6nNFAg5FYijrvZyQcNLV", "generate:clients": "node ./generateClients.cjs && pnpm format:rust", From b5a32aef07dd123a517f10c7e737eecf0320fbaf Mon Sep 17 00:00:00 2001 From: Chelioso Date: Tue, 9 Sep 2025 00:18:51 +0900 Subject: [PATCH 77/88] marginfi crossbar instance --- solauto-sdk/src/utils/priceUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solauto-sdk/src/utils/priceUtils.ts b/solauto-sdk/src/utils/priceUtils.ts index 0d1ae90e..cc3f4eb3 100644 --- a/solauto-sdk/src/utils/priceUtils.ts +++ b/solauto-sdk/src/utils/priceUtils.ts @@ -160,7 +160,7 @@ export async function getSwitchboardPrices( } const { CrossbarClient } = SwbCommon; - const crossbar = CrossbarClient.default(); + const crossbar = new CrossbarClient("https://integrator-crossbar.mrgn.app/"); let prices: Record = {}; try { From e765fff547d416c47af2de68e081ad2f8ce6bb3d Mon Sep 17 00:00:00 2001 From: Chelioso Date: Thu, 2 Oct 2025 00:07:01 +0800 Subject: [PATCH 78/88] fix jup api --- solauto-sdk/src/services/swap/jupSwapManager.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/solauto-sdk/src/services/swap/jupSwapManager.ts b/solauto-sdk/src/services/swap/jupSwapManager.ts index e2b4e659..1df49106 100644 --- a/solauto-sdk/src/services/swap/jupSwapManager.ts +++ b/solauto-sdk/src/services/swap/jupSwapManager.ts @@ -47,7 +47,9 @@ export interface JupSwapTransactionData { } export class JupSwapManager { - jupApi = createJupiterApiClient(); + jupApi = createJupiterApiClient({ + basePath: "https://lite-api.jup.ag" + }); public jupQuote: QuoteResponse | undefined = undefined; @@ -103,7 +105,6 @@ export class JupSwapManager { userPublicKey: this.signer.publicKey.toString(), quoteResponse: this.jupQuote!, wrapAndUnwrapSol: data.wrapAndUnwrapSol ?? false, - useTokenLedger: !data.exactOut && !data.exactIn, destinationTokenAccount: getTokenAccount( data.destinationWallet ?? toWeb3JsPublicKey(this.signer.publicKey), From cc047cd46b382003ec744df207b208eb2e7949f9 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Thu, 2 Oct 2025 14:45:59 +0800 Subject: [PATCH 79/88] wip fixing swb --- solauto-sdk/package.json | 12 +- solauto-sdk/pnpm-lock.yaml | 421 +++++------------- .../manager/clientTransactionsManager.ts | 1 + solauto-sdk/src/utils/jitoUtils.ts | 3 +- solauto-sdk/src/utils/solanaUtils.ts | 31 +- solauto-sdk/src/utils/switchboardUtils.ts | 33 +- 6 files changed, 175 insertions(+), 326 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index a891bfe0..484905a4 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.792", + "version": "1.0.804", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", @@ -12,16 +12,16 @@ "test:unit": "ts-mocha -p ./tsconfig.json -t 1000000 tests/unit/**/*.ts" }, "dependencies": { - "@coral-xyz/anchor": "^0.30.1", - "@jup-ag/api": "=6.0.24", + "@coral-xyz/anchor": "=0.31.1", + "@jup-ag/api": "=6.0.44", "@metaplex-foundation/umi": "^0.9.1", "@metaplex-foundation/umi-bundle-defaults": "^0.9.1", "@metaplex-foundation/umi-signer-wallet-adapters": "^0.9.1", "@metaplex-foundation/umi-web3js-adapters": "^0.9.1", "@solana/spl-token": "^0.4.0", - "@solana/web3.js": "=1.95.8", - "@switchboard-xyz/common": "=3.0.12", - "@switchboard-xyz/on-demand": "=1.2.51", + "@solana/web3.js": "=1.98.2", + "@switchboard-xyz/common": "=3.4.1", + "@switchboard-xyz/on-demand": "=2.16.3", "axios": "^1.7.8", "big.js": "^6.2.2", "bs58": "^5.0.0", diff --git a/solauto-sdk/pnpm-lock.yaml b/solauto-sdk/pnpm-lock.yaml index ee47e07a..4525f1dc 100644 --- a/solauto-sdk/pnpm-lock.yaml +++ b/solauto-sdk/pnpm-lock.yaml @@ -9,35 +9,35 @@ importers: .: dependencies: '@coral-xyz/anchor': - specifier: ^0.30.1 - version: 0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + specifier: '=0.31.1' + version: 0.31.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) '@jup-ag/api': - specifier: '=6.0.24' - version: 6.0.24 + specifier: '=6.0.44' + version: 6.0.44 '@metaplex-foundation/umi': specifier: ^0.9.1 version: 0.9.2 '@metaplex-foundation/umi-bundle-defaults': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)) '@metaplex-foundation/umi-signer-wallet-adapters': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)) '@metaplex-foundation/umi-web3js-adapters': specifier: ^0.9.1 - version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)) '@solana/spl-token': specifier: ^0.4.0 - version: 0.4.13(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) + version: 0.4.13(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) '@solana/web3.js': - specifier: '=1.95.8' - version: 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + specifier: '=1.98.2' + version: 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) '@switchboard-xyz/common': - specifier: '=3.0.12' - version: 3.0.12(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + specifier: '=3.4.1' + version: 3.4.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) '@switchboard-xyz/on-demand': - specifier: '=1.2.51' - version: 1.2.51(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10) + specifier: '=2.16.3' + version: 2.16.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) axios: specifier: ^1.7.8 version: 1.10.0 @@ -88,25 +88,26 @@ packages: resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} engines: {node: '>=6.9.0'} - '@brokerloop/ttlcache@3.2.3': - resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} - - '@coral-xyz/anchor-errors@0.30.1': - resolution: {integrity: sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==} + '@coral-xyz/anchor-errors@0.31.1': + resolution: {integrity: sha512-NhNEku4F3zzUSBtrYz84FzYWm48+9OvmT1Hhnwr6GnPQry2dsEqH/ti/7ASjjpoFTWRnPXrjAIT1qM6Isop+LQ==} engines: {node: '>=10'} - '@coral-xyz/anchor@0.30.1': - resolution: {integrity: sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==} - engines: {node: '>=11'} + '@coral-xyz/anchor@0.31.1': + resolution: {integrity: sha512-QUqpoEK+gi2S6nlYc2atgT2r41TT3caWr/cPUEL8n8Md9437trZ68STknq897b82p5mW0XrTBNOzRbmIRJtfsA==} + engines: {node: '>=17'} - '@coral-xyz/borsh@0.30.1': - resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} + '@coral-xyz/borsh@0.31.1': + resolution: {integrity: sha512-9N8AU9F0ubriKfNE3g1WF0/4dtlGXoBN/hd1PvbNBamBNwRgHxH4P+o3Zt7rSEloW1HUs6LfZEchlx9fW7POYw==} engines: {node: '>=10'} peerDependencies: - '@solana/web3.js': ^1.68.0 + '@solana/web3.js': ^1.69.0 + + '@isaacs/ttlcache@1.4.1': + resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} + engines: {node: '>=12'} - '@jup-ag/api@6.0.24': - resolution: {integrity: sha512-zIX4WIPb0Kb2UnK2wNIOQBWqPJyMJq/D9dQTf/2qvPb0hfa8XdgbrQAzomHMHnAzw9StMQoybBk+JK/A76xP3w==} + '@jup-ag/api@6.0.44': + resolution: {integrity: sha512-C6oYi+wvNi07VlmWhT8+ZDMqTJuF+MiHuNBE65cYuBH6C4l0JfwpXaj6mKazAdVqVFWgngr3s2+0tdF5nDH4tA==} '@metaplex-foundation/umi-bundle-defaults@0.9.2': resolution: {integrity: sha512-kV3tfvgvRjVP1p9OFOtH+ibOtN9omVJSwKr0We4/9r45e5LTj+32su0V/rixZUkG1EZzzOYBsxhtIE0kIw/Hrw==} @@ -304,52 +305,33 @@ packages: peerDependencies: '@solana/web3.js': ^1.95.3 - '@solana/spl-token@0.3.11': - resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.88.0 - '@solana/spl-token@0.4.13': resolution: {integrity: sha512-cite/pYWQZZVvLbg5lsodSovbetK/eA24gaR0eeUeMuBAMNrT8XFCwaygKy0N2WSg3gSyjjNpIeAGBAKZaY/1w==} engines: {node: '>=16'} peerDependencies: '@solana/web3.js': ^1.95.5 - '@solana/web3.js@1.95.8': - resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} - '@solana/web3.js@1.98.2': resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} - '@solworks/soltoolkit-sdk@0.0.23': - resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} - - '@soncodi/signal@2.0.7': - resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} - '@swc/helpers@0.5.17': resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - '@switchboard-xyz/common@2.5.19': - resolution: {integrity: sha512-Bzj1bu2U69YRh2OoNjkrafdREeB1KH+wmeFkBsASDjlhy/xXjey2Ry2HUTAIzdg2DMtfP6DoCW2Nn9ZQD5IO+Q==} - engines: {node: '>=12'} + '@switchboard-xyz/common@3.4.1': + resolution: {integrity: sha512-TropBlBYuDeBnmGHkPSmgC3clLqAxy51ZGbwk4ejAgadnszWOgYHcH7taRG4Ha17DYSCWw/LGMBKbunGo+Aoaw==} + engines: {node: '>=20'} - '@switchboard-xyz/common@3.0.12': - resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} + '@switchboard-xyz/common@4.1.1': + resolution: {integrity: sha512-H5esycuUKAzS1SGqV6DZuBME7ZaGLHJc1jP7tgLGjZ2rZSoCRPthPLvHnQAAV3A18uomTyM8aSARyYYEAZnsFA==} engines: {node: '>=20'} - '@switchboard-xyz/on-demand@1.2.51': - resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} + '@switchboard-xyz/on-demand@2.16.3': + resolution: {integrity: sha512-y9NRl+cupDgqpCI/XB8BJRcMLlJJJdPqw6OuFUX43DCuZ225IHXpCM+lm1X1rCbNClTZMmHbb9hdjwkfTDsEUg==} engines: {node: '>= 18'} - deprecated: deprecated in favor of 2.x.x '@types/big.js@6.2.2': resolution: {integrity: sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==} - '@types/bn.js@5.2.0': - resolution: {integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==} - '@types/chai@4.3.20': resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} @@ -362,15 +344,9 @@ packages: '@types/mocha@9.1.1': resolution: {integrity: sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==} - '@types/node-fetch@2.6.12': - resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} - '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@18.19.119': - resolution: {integrity: sha512-d0F6m9itIPaKnrvEMlzE48UjwZaAnFW7Jwibacw9MNdqadjKNpUm9tfJYDwmShJmgqcoqYUX3EMKO1+RWiuuNg==} - '@types/node@20.19.8': resolution: {integrity: sha512-HzbgCY53T6bfu4tT7Aq3TvViJyHjLjPNaAS3HOuMc9pw97KHsUtXNX4L+wu59g1WnjsZSko35MbEqnO58rihhw==} @@ -386,6 +362,9 @@ packages: '@ungap/promise-all-settled@1.1.2': resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} + '@zod/core@0.11.6': + resolution: {integrity: sha512-03Bv82fFSfjDAvMfdHHdGSS6SOJs0iCcJlWJv1kJHRtoTT02hZpyip/2Lk6oo4l4FtjuwTrsEQTwg/LD8I7dJA==} + agentkeepalive@4.6.0: resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} engines: {node: '>= 8.0.0'} @@ -548,19 +527,12 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - cron-validator@1.4.0: - resolution: {integrity: sha512-wGcJ9FCy65iaU6egSH8b5dZYJF7GU/3Jh06wzaT9lsa5dbqExjljmu+0cJ8cpKn+vUyZa/EM4WAxeLR6SypJXw==} - cross-fetch@3.2.0: resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} cross-fetch@4.1.0: resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} - crypto-hash@1.3.0: - resolution: {integrity: sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==} - engines: {node: '>=8'} - debug@4.3.3: resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} engines: {node: '>=6.0'} @@ -597,9 +569,6 @@ packages: resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} engines: {node: '>=0.3.1'} - dot-case@3.0.4: - resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} - dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} @@ -796,6 +765,11 @@ packages: peerDependencies: ws: '*' + isomorphic-ws@5.0.0: + resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} + peerDependencies: + ws: '*' + jayson@4.2.0: resolution: {integrity: sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg==} engines: {node: '>=8'} @@ -819,9 +793,6 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -832,9 +803,6 @@ packages: loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} - lower-case@2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} - make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} @@ -880,9 +848,6 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - no-case@3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -960,9 +925,6 @@ packages: serialize-javascript@6.0.0: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} - snake-case@3.0.4: - resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} - source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -1042,19 +1004,11 @@ packages: resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} engines: {node: '>=4'} - typescript@4.9.5: - resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} - engines: {node: '>=4.2.0'} - hasBin: true - typescript@5.8.3: resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -1140,58 +1094,58 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + zod@4.0.0-beta.20250505T195954: + resolution: {integrity: sha512-iB8WvxkobVIXMARvQu20fKvbS7mUTiYRpcD8OQV1xjRhxO0EEpYIRJBk6yfBzHAHEdOSDh3SxDITr5Eajr2vtg==} + snapshots: '@babel/runtime@7.27.6': {} - '@brokerloop/ttlcache@3.2.3': - dependencies: - '@soncodi/signal': 2.0.7 - - '@coral-xyz/anchor-errors@0.30.1': {} + '@coral-xyz/anchor-errors@0.31.1': {} - '@coral-xyz/anchor@0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@coral-xyz/anchor@0.31.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/anchor-errors': 0.30.1 - '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@coral-xyz/anchor-errors': 0.31.1 + '@coral-xyz/borsh': 0.31.1(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)) '@noble/hashes': 1.8.0 - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) bn.js: 5.2.2 bs58: 4.0.1 buffer-layout: 1.2.2 camelcase: 6.3.0 cross-fetch: 3.2.0 - crypto-hash: 1.3.0 eventemitter3: 4.0.7 pako: 2.1.0 - snake-case: 3.0.4 superstruct: 0.15.5 toml: 3.0.0 transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate - '@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.31.1(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) bn.js: 5.2.2 buffer-layout: 1.2.2 - '@jup-ag/api@6.0.24': {} + '@isaacs/ttlcache@1.4.1': {} + + '@jup-ag/api@6.0.44': {} - '@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 '@metaplex-foundation/umi-downloader-http': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)) '@metaplex-foundation/umi-http-fetch': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-program-repository': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-rpc-chunk-get-accounts': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)) '@metaplex-foundation/umi-serializer-data-view': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) transitivePeerDependencies: - encoding @@ -1199,12 +1153,12 @@ snapshots: dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)) '@noble/curves': 1.9.4 - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) '@metaplex-foundation/umi-http-fetch@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: @@ -1227,11 +1181,11 @@ snapshots: dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) '@metaplex-foundation/umi-serializer-data-view@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: @@ -1255,22 +1209,22 @@ snapshots: '@metaplex-foundation/umi-serializers-encodings': 0.8.9 '@metaplex-foundation/umi-serializers-numbers': 0.8.9 - '@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) - '@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) - '@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) buffer: 6.0.3 '@metaplex-foundation/umi@0.9.2': @@ -1308,26 +1262,22 @@ snapshots: '@protobufjs/utf8@1.1.0': {} - '@solana/buffer-layout-utils@0.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@solana/buffer-layout-utils@0.2.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) bigint-buffer: 1.1.5 bignumber.js: 9.3.1 transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate '@solana/buffer-layout@4.0.1': dependencies: buffer: 6.0.3 - '@solana/codecs-core@2.0.0-rc.1(typescript@4.9.5)': - dependencies: - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - typescript: 4.9.5 - '@solana/codecs-core@2.0.0-rc.1(typescript@5.8.3)': dependencies: '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) @@ -1338,13 +1288,6 @@ snapshots: '@solana/errors': 2.3.0(typescript@5.8.3) typescript: 5.8.3 - '@solana/codecs-data-structures@2.0.0-rc.1(typescript@4.9.5)': - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - typescript: 4.9.5 - '@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.8.3)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) @@ -1352,12 +1295,6 @@ snapshots: '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) typescript: 5.8.3 - '@solana/codecs-numbers@2.0.0-rc.1(typescript@4.9.5)': - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - typescript: 4.9.5 - '@solana/codecs-numbers@2.0.0-rc.1(typescript@5.8.3)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) @@ -1370,14 +1307,6 @@ snapshots: '@solana/errors': 2.3.0(typescript@5.8.3) typescript: 5.8.3 - '@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - fastestsmallesttextencoderdecoder: 1.0.22 - typescript: 4.9.5 - '@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) @@ -1386,17 +1315,6 @@ snapshots: fastestsmallesttextencoderdecoder: 1.0.22 typescript: 5.8.3 - '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) @@ -1408,12 +1326,6 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/errors@2.0.0-rc.1(typescript@4.9.5)': - dependencies: - chalk: 5.4.1 - commander: 12.1.0 - typescript: 4.9.5 - '@solana/errors@2.0.0-rc.1(typescript@5.8.3)': dependencies: chalk: 5.4.1 @@ -1426,17 +1338,6 @@ snapshots: commander: 14.0.0 typescript: 5.8.3 - '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': - dependencies: - '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) - '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) @@ -1448,51 +1349,29 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/spl-token-group@0.0.7(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + '@solana/spl-token-group@0.0.7(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - typescript - - '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': - dependencies: - '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript - '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - typescript - - '@solana/spl-token@0.3.11(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)': - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - buffer: 6.0.3 + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) transitivePeerDependencies: - - bufferutil - - encoding - fastestsmallesttextencoderdecoder - typescript - - utf-8-validate - '@solana/spl-token@0.4.13(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)': + '@solana/spl-token@0.4.13(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@solana/spl-token-group': 0.0.7(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@solana/spl-token-group': 0.0.7(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -1501,28 +1380,6 @@ snapshots: - typescript - utf-8-validate - '@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)': - dependencies: - '@babel/runtime': 7.27.6 - '@noble/curves': 1.9.4 - '@noble/hashes': 1.8.0 - '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.6.0 - bigint-buffer: 1.1.5 - bn.js: 5.2.2 - borsh: 0.7.0 - bs58: 4.0.1 - buffer: 6.0.3 - fast-stable-stringify: 1.0.0 - jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - node-fetch: 2.7.0 - rpc-websockets: 9.1.1 - superstruct: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - '@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: '@babel/runtime': 7.27.6 @@ -1546,49 +1403,31 @@ snapshots: - typescript - utf-8-validate - '@solworks/soltoolkit-sdk@0.0.23(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10)': - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@types/bn.js': 5.2.0 - '@types/node': 18.19.119 - '@types/node-fetch': 2.6.12 - bn.js: 5.2.2 - decimal.js: 10.6.0 - typescript: 4.9.5 - transitivePeerDependencies: - - bufferutil - - encoding - - fastestsmallesttextencoderdecoder - - utf-8-validate - - '@soncodi/signal@2.0.7': {} - '@swc/helpers@0.5.17': dependencies: tslib: 2.8.1 - '@switchboard-xyz/common@2.5.19(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@switchboard-xyz/common@3.4.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) axios: 1.10.0 big.js: 6.2.2 bn.js: 5.2.2 bs58: 6.0.0 - cron-validator: 1.4.0 + buffer: 6.0.3 decimal.js: 10.6.0 js-sha256: 0.11.1 - lodash: 4.17.21 protobufjs: 7.5.3 yaml: 2.8.0 + zod: 4.0.0-beta.20250505T195954 transitivePeerDependencies: - bufferutil - debug - encoding + - typescript - utf-8-validate - '@switchboard-xyz/common@3.0.12(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': + '@switchboard-xyz/common@4.1.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) axios: 1.10.0 @@ -1600,6 +1439,7 @@ snapshots: js-sha256: 0.11.1 protobufjs: 7.5.3 yaml: 2.8.0 + zod: 4.0.0-beta.20250505T195954 transitivePeerDependencies: - bufferutil - debug @@ -1607,31 +1447,26 @@ snapshots: - typescript - utf-8-validate - '@switchboard-xyz/on-demand@1.2.51(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10)': + '@switchboard-xyz/on-demand@2.16.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: - '@brokerloop/ttlcache': 3.2.3 - '@coral-xyz/anchor-30': '@coral-xyz/anchor@0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)' - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@solworks/soltoolkit-sdk': 0.0.23(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10) - '@switchboard-xyz/common': 2.5.19(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@coral-xyz/anchor-31': '@coral-xyz/anchor@0.31.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)' + '@isaacs/ttlcache': 1.4.1 + '@switchboard-xyz/common': 4.1.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) axios: 1.10.0 - big.js: 6.2.2 - bs58: 5.0.0 + bs58: 6.0.0 + buffer: 6.0.3 + isomorphic-ws: 5.0.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) js-yaml: 4.1.0 - protobufjs: 7.5.3 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - debug - encoding - - fastestsmallesttextencoderdecoder + - typescript - utf-8-validate '@types/big.js@6.2.2': {} - '@types/bn.js@5.2.0': - dependencies: - '@types/node': 20.19.8 - '@types/chai@4.3.20': {} '@types/connect@3.4.38': @@ -1643,17 +1478,8 @@ snapshots: '@types/mocha@9.1.1': {} - '@types/node-fetch@2.6.12': - dependencies: - '@types/node': 20.19.8 - form-data: 4.0.4 - '@types/node@12.20.55': {} - '@types/node@18.19.119': - dependencies: - undici-types: 5.26.5 - '@types/node@20.19.8': dependencies: undici-types: 6.21.0 @@ -1670,6 +1496,8 @@ snapshots: '@ungap/promise-all-settled@1.1.2': {} + '@zod/core@0.11.6': {} + agentkeepalive@4.6.0: dependencies: humanize-ms: 1.2.1 @@ -1838,8 +1666,6 @@ snapshots: concat-map@0.0.1: {} - cron-validator@1.4.0: {} - cross-fetch@3.2.0: dependencies: node-fetch: 2.7.0 @@ -1852,8 +1678,6 @@ snapshots: transitivePeerDependencies: - encoding - crypto-hash@1.3.0: {} - debug@4.3.3(supports-color@8.1.1): dependencies: ms: 2.1.2 @@ -1876,11 +1700,6 @@ snapshots: diff@5.0.0: {} - dot-case@3.0.4: - dependencies: - no-case: 3.0.4 - tslib: 2.8.1 - dotenv@16.6.1: {} dunder-proto@1.0.1: @@ -2046,6 +1865,10 @@ snapshots: dependencies: ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + isomorphic-ws@5.0.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + jayson@4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@types/connect': 3.4.38 @@ -2081,8 +1904,6 @@ snapshots: dependencies: p-locate: 5.0.0 - lodash@4.17.21: {} - log-symbols@4.1.0: dependencies: chalk: 4.1.2 @@ -2094,10 +1915,6 @@ snapshots: dependencies: get-func-name: 2.0.2 - lower-case@2.0.2: - dependencies: - tslib: 2.8.1 - make-error@1.3.6: {} math-intrinsics@1.1.0: {} @@ -2155,11 +1972,6 @@ snapshots: nanoid@3.3.1: {} - no-case@3.0.4: - dependencies: - lower-case: 2.0.2 - tslib: 2.8.1 - node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 @@ -2246,11 +2058,6 @@ snapshots: dependencies: randombytes: 2.1.0 - snake-case@3.0.4: - dependencies: - dot-case: 3.0.4 - tslib: 2.8.1 - source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 @@ -2331,12 +2138,8 @@ snapshots: type-detect@4.1.0: {} - typescript@4.9.5: {} - typescript@5.8.3: {} - undici-types@5.26.5: {} - undici-types@6.21.0: {} utf-8-validate@5.0.10: @@ -2403,3 +2206,7 @@ snapshots: yn@2.0.0: {} yocto-queue@0.1.0: {} + + zod@4.0.0-beta.20250505T195954: + dependencies: + '@zod/core': 0.11.6 diff --git a/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts b/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts index 9a1b2a4c..fecebf5b 100644 --- a/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts @@ -68,6 +68,7 @@ export class ClientTransactionsManager extends TransactionsManager x.getTransactionSize(umi)) ); - txs[0] = txs[0].prepend(getTipInstruction(userSigner, 250_000)); + txs[0] = prependTx(txs[0], [getTipInstruction(userSigner, 250_000)]); const latestBlockhash = ( await retryWithExponentialBackoff( diff --git a/solauto-sdk/src/utils/solanaUtils.ts b/solauto-sdk/src/utils/solanaUtils.ts index 8694642c..f6899578 100644 --- a/solauto-sdk/src/utils/solanaUtils.ts +++ b/solauto-sdk/src/utils/solanaUtils.ts @@ -209,6 +209,31 @@ export async function getAddressLookupInputs( }, new Array()); } +export function prependTx( + tx: TransactionBuilder, + txsToAdd: (TransactionBuilder | WrappedInstruction)[] +) { + const instructions = tx.getInstructions(); + const keccakIdx = instructions.findIndex( + (x) => + x.programId.toString() === "KeccakSecp256k11111111111111111111111111111" + ); + if (keccakIdx !== -1) { + const [beforeKeccak, afterKeccak] = tx.splitByIndex(keccakIdx + 1); + let finalTx = transactionBuilder().add(beforeKeccak); + for (const txToAdd of txsToAdd) { + finalTx = finalTx.append(txToAdd); + } + return finalTx.add(afterKeccak); + } else { + let finalTx = tx; + for (const txToAdd of txsToAdd) { + finalTx = finalTx.prepend(txToAdd); + } + return finalTx; + } +} + export function addTxOptimizations( umi: Umi, tx: TransactionBuilder, @@ -227,11 +252,11 @@ export function addTxOptimizations( const withCuPrice = tx.prepend(computePriceIx); const withCuLimit = tx.prepend(computeLimitIx); if (allOptimizations.fitsInOneTransaction(umi)) { - return allOptimizations; + return prependTx(tx, [computePriceIx, computeLimitIx]); } else if (withCuPrice.fitsInOneTransaction(umi)) { - return withCuPrice; + return prependTx(tx, [computePriceIx]); } else if (withCuLimit.fitsInOneTransaction(umi)) { - return withCuLimit; + return prependTx(tx, [computeLimitIx]); } else { return tx; } diff --git a/solauto-sdk/src/utils/switchboardUtils.ts b/solauto-sdk/src/utils/switchboardUtils.ts index 7f635d6f..7f76dd79 100644 --- a/solauto-sdk/src/utils/switchboardUtils.ts +++ b/solauto-sdk/src/utils/switchboardUtils.ts @@ -13,12 +13,13 @@ import switchboardIdl from "../idls/switchboard.json"; import { PRICES, SWITCHBOARD_PRICE_FEED_IDS } from "../constants"; import { TransactionItemInputs } from "../types"; import { + consoleLog, currentUnixSeconds, retryWithExponentialBackoff, } from "./generalUtils"; import { getWrappedInstruction } from "./solanaUtils"; -export function getPullFeed( +export async function getPullFeed( conn: Connection, mint: PublicKey, wallet?: PublicKey @@ -37,11 +38,15 @@ export function getPullFeed( dummyWallet, AnchorProvider.defaultOptions() ); - const program = new Program(switchboardIdl as Idl, provider); - const { PullFeed } = OnDemand; + consoleLog("Pulling SWB program..."); + const { PullFeed, ON_DEMAND_MAINNET_PID } = OnDemand; + const sbProgram = await Program.at(ON_DEMAND_MAINNET_PID, provider); + + consoleLog("Pulled SWB program!"); + consoleLog("Feed id:", SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId); return new PullFeed( - program, + sbProgram, new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId) ); } @@ -51,10 +56,14 @@ export async function buildSwbSubmitResponseTx( signer: Signer, mint: PublicKey ): Promise { - const feed = getPullFeed(conn, mint, toWeb3JsPublicKey(signer.publicKey)); - const [pullIx, responses] = await retryWithExponentialBackoff( + const feed = await getPullFeed(conn, mint, toWeb3JsPublicKey(signer.publicKey)); + + const gateway = await feed.fetchGatewayUrl(); + consoleLog("Fetching crank IX..."); + const [pullIxs, responses] = await retryWithExponentialBackoff( async () => { const res = await feed.fetchUpdateIx({ + gateway, chain: "solana", network: "mainnet-beta", }); @@ -67,11 +76,13 @@ export async function buildSwbSubmitResponseTx( 200 ); - if (!pullIx) { + if (!pullIxs || !pullIxs.length) { throw new Error("Unable to fetch SWB crank IX"); } + consoleLog("Setting price locally..."); const price = (responses[0].value as Big).toNumber(); + consoleLog(price); PRICES[mint.toString()] = { realtimePrice: price, confInterval: 0, @@ -80,11 +91,15 @@ export async function buildSwbSubmitResponseTx( time: currentUnixSeconds(), }; + consoleLog("Returning SWB transaction data..."); return { - tx: transactionBuilder([getWrappedInstruction(signer, pullIx!)]), + tx: transactionBuilder( + pullIxs.map((x) => getWrappedInstruction(signer, x)) + ), lookupTableAddresses: responses .filter((x) => Boolean(x.oracle.lut?.key)) .map((x) => x.oracle.lut!.key.toString()), + orderPrio: -1, }; } @@ -103,7 +118,7 @@ export async function getSwitchboardFeedData( const results = await Promise.all( mints.map(async (mint) => { - const feed = getPullFeed(conn, mint); + const feed = await getPullFeed(conn, mint); const result = await feed.loadData(); const price = Number(result.result.value) / Math.pow(10, 18); const stale = From f294abb15695859f8641db7f7394d5f94fa4de58 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Sat, 4 Oct 2025 16:44:21 +0700 Subject: [PATCH 80/88] small fixes --- solauto-sdk/package.json | 4 +- solauto-sdk/pnpm-lock.yaml | 17 +- solauto-sdk/src/idls/switchboard.json | 1949 --------------------- solauto-sdk/src/utils/switchboardUtils.ts | 34 +- 4 files changed, 37 insertions(+), 1967 deletions(-) delete mode 100644 solauto-sdk/src/idls/switchboard.json diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 484905a4..0cbd7549 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.804", + "version": "1.0.806", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", @@ -21,7 +21,7 @@ "@solana/spl-token": "^0.4.0", "@solana/web3.js": "=1.98.2", "@switchboard-xyz/common": "=3.4.1", - "@switchboard-xyz/on-demand": "=2.16.3", + "@switchboard-xyz/on-demand": "=2.17.4", "axios": "^1.7.8", "big.js": "^6.2.2", "bs58": "^5.0.0", diff --git a/solauto-sdk/pnpm-lock.yaml b/solauto-sdk/pnpm-lock.yaml index 4525f1dc..55b8462e 100644 --- a/solauto-sdk/pnpm-lock.yaml +++ b/solauto-sdk/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: '=3.4.1' version: 3.4.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) '@switchboard-xyz/on-demand': - specifier: '=2.16.3' - version: 2.16.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + specifier: '=2.17.4' + version: 2.17.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) axios: specifier: ^1.7.8 version: 1.10.0 @@ -325,8 +325,8 @@ packages: resolution: {integrity: sha512-H5esycuUKAzS1SGqV6DZuBME7ZaGLHJc1jP7tgLGjZ2rZSoCRPthPLvHnQAAV3A18uomTyM8aSARyYYEAZnsFA==} engines: {node: '>=20'} - '@switchboard-xyz/on-demand@2.16.3': - resolution: {integrity: sha512-y9NRl+cupDgqpCI/XB8BJRcMLlJJJdPqw6OuFUX43DCuZ225IHXpCM+lm1X1rCbNClTZMmHbb9hdjwkfTDsEUg==} + '@switchboard-xyz/on-demand@2.17.4': + resolution: {integrity: sha512-jZtnjcI58Leet2GCABoK0+snfi3Sg4Kn997MnsE0aMQFWCQ/zsy2oI81x7Nk+kvM+3Q5OEAG7JpAsN00BMlgQw==} engines: {node: '>= 18'} '@types/big.js@6.2.2': @@ -616,6 +616,10 @@ packages: eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + eyes@0.1.8: resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} engines: {node: '> 0.1.90'} @@ -1447,7 +1451,7 @@ snapshots: - typescript - utf-8-validate - '@switchboard-xyz/on-demand@2.16.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': + '@switchboard-xyz/on-demand@2.17.4(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: '@coral-xyz/anchor-31': '@coral-xyz/anchor@0.31.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)' '@isaacs/ttlcache': 1.4.1 @@ -1455,6 +1459,7 @@ snapshots: axios: 1.10.0 bs58: 6.0.0 buffer: 6.0.3 + events: 3.3.0 isomorphic-ws: 5.0.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) js-yaml: 4.1.0 ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -1739,6 +1744,8 @@ snapshots: eventemitter3@5.0.1: {} + events@3.3.0: {} + eyes@0.1.8: {} fast-stable-stringify@1.0.0: {} diff --git a/solauto-sdk/src/idls/switchboard.json b/solauto-sdk/src/idls/switchboard.json deleted file mode 100644 index 6996121a..00000000 --- a/solauto-sdk/src/idls/switchboard.json +++ /dev/null @@ -1,1949 +0,0 @@ -{ - "address": "SBondMDrcV3K4kxZR1HNVT7osZxAHVHgYXL5Ze1oMUv", - "metadata": { - "name": "sb_on_demand", - "version": "0.1.0", - "spec": "0.1.0", - "description": "Created with Anchor" - }, - "instructions": [ - { - "name": "guardian_quote_verify", - "discriminator": [168, 36, 93, 156, 157, 150, 148, 45], - "accounts": [ - { "name": "guardian", "writable": true }, - { "name": "oracle", "writable": true }, - { "name": "authority", "signer": true, "relations": ["oracle"] }, - { "name": "guardian_queue", "writable": true, "relations": ["state"] }, - { "name": "state" }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "GuardianQuoteVerifyParams" } } - } - ] - }, - { - "name": "guardian_register", - "discriminator": [159, 76, 53, 117, 219, 29, 116, 135], - "accounts": [ - { "name": "oracle", "writable": true }, - { "name": "state" }, - { "name": "guardian_queue", "relations": ["state"] }, - { "name": "authority", "signer": true, "relations": ["state"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "GuardianRegisterParams" } } - } - ] - }, - { - "name": "guardian_unregister", - "discriminator": [215, 19, 61, 120, 155, 224, 120, 60], - "accounts": [ - { "name": "oracle", "writable": true }, - { "name": "state" }, - { "name": "guardian_queue", "writable": true, "relations": ["state"] }, - { "name": "authority", "signer": true, "relations": ["state"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "GuardianUnregisterParams" } } - } - ] - }, - { - "name": "oracle_heartbeat", - "discriminator": [10, 175, 217, 130, 111, 35, 117, 54], - "accounts": [ - { "name": "oracle", "writable": true }, - { - "name": "oracle_stats", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] - }, - { "kind": "account", "path": "oracle" } - ] - } - }, - { "name": "oracle_signer", "signer": true }, - { - "name": "queue", - "writable": true, - "relations": ["oracle", "gc_node"] - }, - { "name": "gc_node", "writable": true }, - { "name": "program_state", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "native_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "queue_escrow", "writable": true }, - { - "name": "stake_program", - "address": "SBSTk6t52R89MmCdD739Rdd97HdbTQUFHe41vCX7pTt", - "relations": ["program_state"] - }, - { "name": "delegation_pool", "writable": true }, - { "name": "delegation_group", "writable": true } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "OracleHeartbeatParams" } } - } - ] - }, - { - "name": "oracle_init", - "discriminator": [21, 158, 66, 65, 60, 221, 148, 61], - "accounts": [ - { "name": "oracle", "writable": true, "signer": true }, - { - "name": "oracle_stats", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] - }, - { "kind": "account", "path": "oracle" } - ] - } - }, - { "name": "program_state", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - }, - { "name": "stake_program", "relations": ["program_state"] }, - { "name": "stake_pool", "relations": ["program_state"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "OracleInitParams" } } - } - ] - }, - { - "name": "oracle_set_configs", - "discriminator": [129, 111, 223, 4, 191, 188, 70, 180], - "accounts": [ - { "name": "oracle" }, - { "name": "authority", "signer": true, "relations": ["oracle"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "OracleSetConfigsParams" } } - } - ] - }, - { - "name": "oracle_update_delegation", - "discriminator": [46, 198, 113, 223, 160, 189, 118, 90], - "accounts": [ - { "name": "oracle", "writable": true }, - { - "name": "oracle_stats", - "pda": { - "seeds": [ - { - "kind": "const", - "value": [79, 114, 97, 99, 108, 101, 83, 116, 97, 116, 115] - }, - { "kind": "account", "path": "oracle" } - ] - } - }, - { "name": "queue", "relations": ["oracle"] }, - { "name": "authority", "signer": true }, - { "name": "program_state", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { "name": "delegation_pool", "writable": true }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - }, - { "name": "switch_mint" }, - { - "name": "native_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "wsol_vault", "writable": true }, - { "name": "switch_vault", "writable": true }, - { "name": "stake_program", "relations": ["program_state"] }, - { "name": "stake_pool" }, - { "name": "delegation_group" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "OracleUpdateDelegationParams" } } - } - ] - }, - { - "name": "permission_set", - "discriminator": [211, 122, 185, 120, 129, 182, 55, 103], - "accounts": [ - { "name": "authority", "signer": true }, - { "name": "granter" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PermissionSetParams" } } - } - ] - }, - { - "name": "pull_feed_close", - "discriminator": [19, 134, 50, 142, 177, 215, 196, 83], - "accounts": [ - { "name": "pull_feed", "writable": true }, - { "name": "reward_escrow", "writable": true }, - { "name": "lut", "writable": true }, - { "name": "lut_signer" }, - { "name": "payer", "writable": true, "signer": true }, - { "name": "state" }, - { - "name": "authority", - "writable": true, - "signer": true, - "relations": ["pull_feed"] - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "associated_token_program", - "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedCloseParams" } } - } - ] - }, - { - "name": "pull_feed_init", - "discriminator": [198, 130, 53, 198, 235, 61, 143, 40], - "accounts": [ - { "name": "pull_feed", "writable": true, "signer": true }, - { "name": "queue" }, - { "name": "authority" }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "program_state" }, - { - "name": "reward_escrow", - "writable": true, - "pda": { - "seeds": [ - { "kind": "account", "path": "pull_feed" }, - { - "kind": "const", - "value": [ - 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, - 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, - 245, 133, 126, 255, 0, 169 - ] - }, - { "kind": "account", "path": "wrapped_sol_mint" } - ], - "program": { - "kind": "const", - "value": [ - 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, - 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, - 219, 233, 248, 89 - ] - } - } - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "associated_token_program", - "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" - }, - { - "name": "wrapped_sol_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedInitParams" } } - } - ] - }, - { - "name": "pull_feed_set_configs", - "discriminator": [217, 45, 11, 246, 64, 26, 82, 168], - "accounts": [ - { "name": "pull_feed", "writable": true }, - { "name": "authority", "signer": true, "relations": ["pull_feed"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedSetConfigsParams" } } - } - ] - }, - { - "name": "pull_feed_submit_response", - "discriminator": [150, 22, 215, 166, 143, 93, 48, 137], - "accounts": [ - { "name": "feed", "writable": true }, - { "name": "queue", "relations": ["feed"] }, - { "name": "program_state" }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "reward_vault", "writable": true }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "token_mint", - "address": "So11111111111111111111111111111111111111112" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedSubmitResponseParams" } } - } - ] - }, - { - "name": "pull_feed_submit_response_many", - "discriminator": [47, 156, 45, 25, 200, 71, 37, 215], - "accounts": [ - { "name": "queue" }, - { "name": "program_state" }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "reward_vault", "writable": true }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "token_mint", - "address": "So11111111111111111111111111111111111111112" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "PullFeedSubmitResponseManyParams" } } - } - ] - }, - { - "name": "queue_add_mr_enclave", - "discriminator": [199, 255, 81, 50, 60, 133, 171, 138], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "authority", "signer": true }, - { "name": "program_authority" }, - { "name": "state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueAddMrEnclaveParams" } } - } - ] - }, - { - "name": "queue_allow_subsidies", - "discriminator": [94, 203, 82, 157, 188, 138, 202, 108], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "authority", "signer": true, "relations": ["state"] }, - { "name": "state", "writable": true } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueAllowSubsidiesParams" } } - } - ] - }, - { - "name": "queue_garbage_collect", - "discriminator": [187, 208, 104, 247, 16, 91, 96, 98], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "oracle", "writable": true }, - { "name": "authority", "signer": true }, - { "name": "state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueGarbageCollectParams" } } - } - ] - }, - { - "name": "queue_init", - "discriminator": [144, 18, 99, 145, 133, 27, 207, 13], - "accounts": [ - { "name": "queue", "writable": true, "signer": true }, - { - "name": "queue_escrow", - "writable": true, - "pda": { - "seeds": [ - { "kind": "account", "path": "queue" }, - { - "kind": "const", - "value": [ - 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, - 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, - 245, 133, 126, 255, 0, 169 - ] - }, - { "kind": "account", "path": "native_mint" } - ], - "program": { - "kind": "const", - "value": [ - 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, - 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, - 219, 233, 248, 89 - ] - } - } - }, - { "name": "authority" }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "native_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "program_state" }, - { "name": "lut_signer", "writable": true }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - }, - { - "name": "associated_token_program", - "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueInitParams" } } - } - ] - }, - { - "name": "queue_init_delegation_group", - "discriminator": [239, 146, 75, 158, 20, 166, 159, 14], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "program_state" }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - }, - { "name": "delegation_group", "writable": true }, - { "name": "stake_program", "relations": ["program_state"] }, - { "name": "stake_pool" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueInitDelegationGroupParams" } } - } - ] - }, - { - "name": "queue_remove_mr_enclave", - "discriminator": [3, 64, 135, 33, 190, 133, 68, 252], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "authority", "signer": true }, - { "name": "program_authority" }, - { "name": "state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueRemoveMrEnclaveParams" } } - } - ] - }, - { - "name": "queue_set_configs", - "discriminator": [54, 183, 243, 199, 49, 103, 142, 48], - "accounts": [ - { "name": "queue", "writable": true }, - { "name": "authority", "signer": true }, - { "name": "state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "QueueSetConfigsParams" } } - } - ] - }, - { - "name": "randomness_commit", - "discriminator": [52, 170, 152, 201, 179, 133, 242, 141], - "accounts": [ - { "name": "randomness", "writable": true }, - { "name": "queue", "relations": ["randomness", "oracle"] }, - { "name": "oracle", "writable": true }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - }, - { "name": "authority", "signer": true, "relations": ["randomness"] } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "RandomnessCommitParams" } } - } - ] - }, - { - "name": "randomness_init", - "discriminator": [9, 9, 204, 33, 50, 116, 113, 15], - "accounts": [ - { "name": "randomness", "writable": true, "signer": true }, - { - "name": "reward_escrow", - "writable": true, - "pda": { - "seeds": [ - { "kind": "account", "path": "randomness" }, - { - "kind": "const", - "value": [ - 6, 221, 246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206, - 235, 121, 172, 28, 180, 133, 237, 95, 91, 55, 145, 58, 140, - 245, 133, 126, 255, 0, 169 - ] - }, - { "kind": "account", "path": "wrapped_sol_mint" } - ], - "program": { - "kind": "const", - "value": [ - 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, - 13, 131, 11, 90, 19, 153, 218, 255, 16, 132, 4, 142, 123, 216, - 219, 233, 248, 89 - ] - } - } - }, - { "name": "authority", "signer": true }, - { "name": "queue", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "associated_token_program", - "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" - }, - { - "name": "wrapped_sol_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "program_state" }, - { "name": "lut_signer" }, - { "name": "lut", "writable": true }, - { - "name": "address_lookup_table_program", - "address": "AddressLookupTab1e1111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "RandomnessInitParams" } } - } - ] - }, - { - "name": "randomness_reveal", - "discriminator": [197, 181, 187, 10, 30, 58, 20, 73], - "accounts": [ - { "name": "randomness", "writable": true }, - { "name": "oracle", "relations": ["randomness"] }, - { "name": "queue", "relations": ["oracle"] }, - { - "name": "stats", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 79, 114, 97, 99, 108, 101, 82, 97, 110, 100, 111, 109, 110, - 101, 115, 115, 83, 116, 97, 116, 115 - ] - }, - { "kind": "account", "path": "oracle" } - ] - } - }, - { "name": "authority", "signer": true, "relations": ["randomness"] }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "recent_slothashes", - "address": "SysvarS1otHashes111111111111111111111111111" - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { "name": "reward_escrow", "writable": true }, - { - "name": "token_program", - "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" - }, - { - "name": "wrapped_sol_mint", - "address": "So11111111111111111111111111111111111111112" - }, - { "name": "program_state" } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "RandomnessRevealParams" } } - } - ] - }, - { - "name": "state_init", - "discriminator": [103, 241, 106, 190, 217, 153, 87, 105], - "accounts": [ - { - "name": "state", - "writable": true, - "pda": { - "seeds": [{ "kind": "const", "value": [83, 84, 65, 84, 69] }] - } - }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "StateInitParams" } } - } - ] - }, - { - "name": "state_set_configs", - "discriminator": [40, 98, 76, 37, 206, 9, 47, 144], - "accounts": [ - { "name": "state", "writable": true }, - { "name": "authority", "signer": true, "relations": ["state"] }, - { "name": "queue", "writable": true }, - { "name": "payer", "writable": true, "signer": true }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [ - { - "name": "params", - "type": { "defined": { "name": "StateSetConfigsParams" } } - } - ] - } - ], - "accounts": [ - { - "name": "OracleAccountData", - "discriminator": [128, 30, 16, 241, 170, 73, 55, 54] - }, - { - "name": "OracleStatsAccountData", - "discriminator": [180, 157, 178, 234, 240, 27, 152, 179] - }, - { - "name": "PullFeedAccountData", - "discriminator": [196, 27, 108, 196, 10, 215, 219, 40] - }, - { - "name": "QueueAccountData", - "discriminator": [217, 194, 55, 127, 184, 83, 138, 1] - }, - { - "name": "RandomnessAccountData", - "discriminator": [10, 66, 229, 135, 220, 239, 217, 114] - }, - { "name": "State", "discriminator": [216, 146, 107, 94, 104, 75, 182, 177] } - ], - "events": [ - { - "name": "CostWhitelistEvent", - "discriminator": [56, 107, 191, 127, 116, 6, 138, 149] - }, - { - "name": "GarbageCollectionEvent", - "discriminator": [232, 235, 2, 188, 8, 143, 145, 237] - }, - { - "name": "GuardianQuoteVerifyEvent", - "discriminator": [31, 37, 39, 6, 214, 186, 33, 115] - }, - { - "name": "OracleHeartbeatEvent", - "discriminator": [52, 29, 166, 2, 94, 7, 188, 13] - }, - { - "name": "OracleInitEvent", - "discriminator": [89, 193, 219, 200, 1, 83, 167, 24] - }, - { - "name": "OracleQuoteOverrideEvent", - "discriminator": [78, 204, 191, 210, 164, 196, 244, 65] - }, - { - "name": "OracleQuoteRotateEvent", - "discriminator": [26, 189, 196, 192, 225, 127, 26, 228] - }, - { - "name": "OracleQuoteVerifyRequestEvent", - "discriminator": [203, 209, 79, 0, 20, 71, 226, 202] - }, - { - "name": "PermissionSetEvent", - "discriminator": [148, 86, 123, 0, 102, 20, 119, 206] - }, - { - "name": "PullFeedErrorValueEvent", - "discriminator": [225, 80, 192, 95, 14, 12, 83, 192] - }, - { - "name": "PullFeedValueEvents", - "discriminator": [86, 7, 231, 28, 122, 161, 117, 69] - }, - { - "name": "QueueAddMrEnclaveEvent", - "discriminator": [170, 186, 175, 38, 216, 51, 69, 175] - }, - { - "name": "QueueInitEvent", - "discriminator": [44, 137, 99, 227, 107, 8, 30, 105] - }, - { - "name": "QueueRemoveMrEnclaveEvent", - "discriminator": [4, 105, 196, 60, 84, 122, 203, 196] - }, - { - "name": "RandomnessCommitEvent", - "discriminator": [88, 60, 172, 90, 112, 10, 206, 147] - } - ], - "errors": [ - { "code": 6000, "name": "GenericError" }, - { "code": 6001, "name": "InvalidQuote" }, - { "code": 6002, "name": "InsufficientQueue" }, - { "code": 6003, "name": "QueueFull" }, - { "code": 6004, "name": "InvalidEnclaveSigner" }, - { "code": 6005, "name": "InvalidSigner" }, - { "code": 6006, "name": "MrEnclaveAlreadyExists" }, - { "code": 6007, "name": "MrEnclaveAtCapacity" }, - { "code": 6008, "name": "MrEnclaveDoesntExist" }, - { "code": 6009, "name": "PermissionDenied" }, - { "code": 6010, "name": "InvalidQueue" }, - { "code": 6011, "name": "IncorrectMrEnclave" }, - { "code": 6012, "name": "InvalidAuthority" }, - { "code": 6013, "name": "InvalidMrEnclave" }, - { "code": 6014, "name": "InvalidTimestamp" }, - { "code": 6015, "name": "InvalidOracleIdx" }, - { "code": 6016, "name": "InvalidSecpSignature" }, - { "code": 6017, "name": "InvalidGuardianQueue" }, - { "code": 6018, "name": "InvalidIndex" }, - { "code": 6019, "name": "InvalidOracleQueue" }, - { "code": 6020, "name": "InvalidPermission" }, - { "code": 6021, "name": "InvalidePermissionedAccount" }, - { "code": 6022, "name": "InvalidEpochRotate" }, - { "code": 6023, "name": "InvalidEpochFinalize" }, - { "code": 6024, "name": "InvalidEscrow" }, - { "code": 6025, "name": "IllegalOracle" }, - { "code": 6026, "name": "IllegalExecuteAttempt" }, - { "code": 6027, "name": "IllegalFeedValue" }, - { "code": 6028, "name": "InvalidOracleFeedStats" }, - { "code": 6029, "name": "InvalidStateAuthority" }, - { "code": 6030, "name": "NotEnoughSamples" }, - { "code": 6031, "name": "OracleIsVerified" }, - { "code": 6032, "name": "QueueIsEmpty" }, - { "code": 6033, "name": "SecpRecoverFailure" }, - { "code": 6034, "name": "StaleSample" }, - { "code": 6035, "name": "SwitchboardRandomnessTooOld" }, - { "code": 6036, "name": "EpochIdMismatch" }, - { "code": 6037, "name": "GuardianAlreadyVoted" }, - { "code": 6038, "name": "RandomnessNotRequested" }, - { "code": 6039, "name": "InvalidSlotNumber" }, - { "code": 6040, "name": "RandomnessOracleKeyExpired" }, - { "code": 6041, "name": "InvalidAdvisory" }, - { "code": 6042, "name": "InvalidOracleStats" }, - { "code": 6043, "name": "InvalidStakeProgram" }, - { "code": 6044, "name": "InvalidStakePool" }, - { "code": 6045, "name": "InvalidDelegationPool" }, - { "code": 6046, "name": "UnparsableAccount" }, - { "code": 6047, "name": "InvalidInstruction" }, - { "code": 6048, "name": "OracleAlreadyVerified" }, - { "code": 6049, "name": "GuardianNotVerified" }, - { "code": 6050, "name": "InvalidConstraint" }, - { "code": 6051, "name": "InvalidDelegationGroup" }, - { "code": 6052, "name": "OracleKeyNotFound" }, - { "code": 6053, "name": "GuardianReregisterAttempt" } - ], - "types": [ - { - "name": "CompactResult", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "std_dev", - "docs": [ - "The standard deviation of the submissions needed for quorom size" - ], - "type": "f32" - }, - { - "name": "mean", - "docs": ["The mean of the submissions needed for quorom size"], - "type": "f32" - }, - { - "name": "slot", - "docs": ["The slot at which this value was signed."], - "type": "u64" - } - ] - } - }, - { - "name": "CostWhitelistEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "feeds", "type": { "vec": "pubkey" } }, - { "name": "reward", "type": "u32" } - ] - } - }, - { - "name": "CurrentResult", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "value", - "docs": [ - "The median value of the submissions needed for quorom size" - ], - "type": "i128" - }, - { - "name": "std_dev", - "docs": [ - "The standard deviation of the submissions needed for quorom size" - ], - "type": "i128" - }, - { - "name": "mean", - "docs": ["The mean of the submissions needed for quorom size"], - "type": "i128" - }, - { - "name": "range", - "docs": ["The range of the submissions needed for quorom size"], - "type": "i128" - }, - { - "name": "min_value", - "docs": [ - "The minimum value of the submissions needed for quorom size" - ], - "type": "i128" - }, - { - "name": "max_value", - "docs": [ - "The maximum value of the submissions needed for quorom size" - ], - "type": "i128" - }, - { - "name": "num_samples", - "docs": ["The number of samples used to calculate this result"], - "type": "u8" - }, - { "name": "padding1", "type": { "array": ["u8", 7] } }, - { - "name": "slot", - "docs": ["The slot at which this value was signed."], - "type": "u64" - }, - { - "name": "min_slot", - "docs": [ - "The slot at which the first considered submission was made" - ], - "type": "u64" - }, - { - "name": "max_slot", - "docs": [ - "The slot at which the last considered submission was made" - ], - "type": "u64" - } - ] - } - }, - { - "name": "GarbageCollectionEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "oracle", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" } - ] - } - }, - { - "name": "GuardianQuoteVerifyEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "quote", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" } - ] - } - }, - { - "name": "GuardianQuoteVerifyParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "timestamp", "type": "i64" }, - { "name": "mr_enclave", "type": { "array": ["u8", 32] } }, - { "name": "_reserved1", "type": "u32" }, - { "name": "ed25519_key", "type": "pubkey" }, - { "name": "secp256k1_key", "type": { "array": ["u8", 64] } }, - { "name": "slot", "type": "u64" }, - { "name": "signature", "type": { "array": ["u8", 64] } }, - { "name": "recovery_id", "type": "u8" }, - { "name": "advisories", "type": { "vec": "u32" } } - ] - } - }, - { - "name": "GuardianRegisterParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "GuardianUnregisterParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "MegaSlotInfo", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "reserved1", "type": "u64" }, - { "name": "slot_end", "type": "u64" }, - { "name": "perf_goal", "type": "i64" }, - { "name": "current_signature_count", "type": "i64" } - ] - } - }, - { - "name": "MultiSubmission", - "type": { - "kind": "struct", - "fields": [ - { "name": "values", "type": { "vec": "i128" } }, - { "name": "signature", "type": { "array": ["u8", 64] } }, - { "name": "recovery_id", "type": "u8" } - ] - } - }, - { - "name": "OracleAccountData", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "enclave", - "docs": ["Represents the state of the quote verifiers enclave."], - "type": { "defined": { "name": "Quote" } } - }, - { - "name": "authority", - "docs": [ - "The authority of the EnclaveAccount which is permitted to make account changes." - ], - "type": "pubkey" - }, - { - "name": "queue", - "docs": [ - "Queue used for attestation to verify a MRENCLAVE measurement." - ], - "type": "pubkey" - }, - { - "name": "created_at", - "docs": ["The unix timestamp when the quote was created."], - "type": "i64" - }, - { - "name": "last_heartbeat", - "docs": ["The last time the quote heartbeated on-chain."], - "type": "i64" - }, - { "name": "secp_authority", "type": { "array": ["u8", 64] } }, - { - "name": "gateway_uri", - "docs": ["URI location of the verifier's gateway."], - "type": { "array": ["u8", 64] } - }, - { "name": "permissions", "type": "u64" }, - { - "name": "is_on_queue", - "docs": [ - "Whether the quote is located on the AttestationQueues buffer." - ], - "type": "u8" - }, - { "name": "_padding1", "type": { "array": ["u8", 7] } }, - { "name": "lut_slot", "type": "u64" }, - { "name": "last_reward_epoch", "type": "u64" }, - { "name": "_ebuf4", "type": { "array": ["u8", 16] } }, - { "name": "_ebuf3", "type": { "array": ["u8", 32] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 64] } }, - { "name": "_ebuf1", "type": { "array": ["u8", 1024] } } - ] - } - }, - { - "name": "OracleEpochInfo", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "id", "type": "u64" }, - { "name": "reserved1", "type": "u64" }, - { "name": "slot_end", "type": "u64" }, - { "name": "slash_score", "type": "u64" }, - { "name": "reward_score", "type": "u64" }, - { "name": "stake_score", "type": "u64" } - ] - } - }, - { - "name": "OracleHeartbeatEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "oracle", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" } - ] - } - }, - { - "name": "OracleHeartbeatParams", - "type": { - "kind": "struct", - "fields": [ - { - "name": "gateway_uri", - "type": { "option": { "array": ["u8", 64] } } - } - ] - } - }, - { - "name": "OracleInitEvent", - "type": { - "kind": "struct", - "fields": [{ "name": "oracle", "type": "pubkey" }] - } - }, - { - "name": "OracleInitParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "recent_slot", "type": "u64" }, - { "name": "authority", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" }, - { - "name": "secp_authority", - "type": { "option": { "array": ["u8", 64] } } - } - ] - } - }, - { - "name": "OracleQuoteOverrideEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "oracle", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" } - ] - } - }, - { - "name": "OracleQuoteRotateEvent", - "type": { - "kind": "struct", - "fields": [{ "name": "oracle", "type": "pubkey" }] - } - }, - { - "name": "OracleQuoteVerifyRequestEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "quote", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" } - ] - } - }, - { - "name": "OracleSetConfigsParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "new_authority", "type": { "option": "pubkey" } }, - { - "name": "new_secp_authority", - "type": { "option": { "array": ["u8", 64] } } - } - ] - } - }, - { - "name": "OracleStatsAccountData", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "owner", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" }, - { - "name": "finalized_epoch", - "docs": [ - "The last epoch that has completed. cleared after registered with the", - "staking program." - ], - "type": { "defined": { "name": "OracleEpochInfo" } } - }, - { - "name": "current_epoch", - "docs": [ - "The current epoch info being used by the oracle. for stake. Will moved", - "to finalized_epoch as soon as the epoch is over." - ], - "type": { "defined": { "name": "OracleEpochInfo" } } - }, - { - "name": "mega_slot_info", - "type": { "defined": { "name": "MegaSlotInfo" } } - }, - { "name": "last_transfer_slot", "type": "u64" }, - { "name": "bump", "type": "u8" }, - { "name": "padding1", "type": { "array": ["u8", 7] } }, - { - "name": "_ebuf", - "docs": ["Reserved."], - "type": { "array": ["u8", 1024] } - } - ] - } - }, - { - "name": "OracleSubmission", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "oracle", - "docs": ["The public key of the oracle that submitted this value."], - "type": "pubkey" - }, - { - "name": "slot", - "docs": ["The slot at which this value was signed."], - "type": "u64" - }, - { "name": "padding1", "type": { "array": ["u8", 8] } }, - { - "name": "value", - "docs": ["The value that was submitted."], - "type": "i128" - } - ] - } - }, - { - "name": "OracleUpdateDelegationParams", - "type": { - "kind": "struct", - "fields": [{ "name": "_reserved1", "type": "u64" }] - } - }, - { - "name": "PermissionSetEvent", - "type": { - "kind": "struct", - "fields": [{ "name": "permission", "type": "pubkey" }] - } - }, - { - "name": "PermissionSetParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "permission", "type": "u8" }, - { "name": "enable", "type": "bool" } - ] - } - }, - { - "name": "PullFeedAccountData", - "docs": ["A representation of the data in a pull feed account."], - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "submissions", - "docs": ["The oracle submissions for this feed."], - "type": { - "array": [{ "defined": { "name": "OracleSubmission" } }, 32] - } - }, - { - "name": "authority", - "docs": [ - "The public key of the authority that can update the feed hash that", - "this account will use for registering updates." - ], - "type": "pubkey" - }, - { - "name": "queue", - "docs": [ - "The public key of the queue which oracles must be bound to in order to", - "submit data to this feed." - ], - "type": "pubkey" - }, - { - "name": "feed_hash", - "docs": [ - "SHA-256 hash of the job schema oracles will execute to produce data", - "for this feed." - ], - "type": { "array": ["u8", 32] } - }, - { - "name": "initialized_at", - "docs": ["The slot at which this account was initialized."], - "type": "i64" - }, - { "name": "permissions", "type": "u64" }, - { "name": "max_variance", "type": "u64" }, - { "name": "min_responses", "type": "u32" }, - { "name": "name", "type": { "array": ["u8", 32] } }, - { "name": "padding1", "type": { "array": ["u8", 2] } }, - { "name": "historical_result_idx", "type": "u8" }, - { "name": "min_sample_size", "type": "u8" }, - { "name": "last_update_timestamp", "type": "i64" }, - { "name": "lut_slot", "type": "u64" }, - { "name": "_reserved1", "type": { "array": ["u8", 32] } }, - { - "name": "result", - "type": { "defined": { "name": "CurrentResult" } } - }, - { "name": "max_staleness", "type": "u32" }, - { "name": "padding2", "type": { "array": ["u8", 12] } }, - { - "name": "historical_results", - "type": { - "array": [{ "defined": { "name": "CompactResult" } }, 32] - } - }, - { "name": "_ebuf4", "type": { "array": ["u8", 8] } }, - { "name": "_ebuf3", "type": { "array": ["u8", 24] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 256] } } - ] - } - }, - { - "name": "PullFeedCloseParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "PullFeedErrorValueEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "feed", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" } - ] - } - }, - { - "name": "PullFeedInitParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "feed_hash", "type": { "array": ["u8", 32] } }, - { "name": "max_variance", "type": "u64" }, - { "name": "min_responses", "type": "u32" }, - { "name": "name", "type": { "array": ["u8", 32] } }, - { "name": "recent_slot", "type": "u64" }, - { "name": "ipfs_hash", "type": { "array": ["u8", 32] } }, - { "name": "min_sample_size", "type": "u8" }, - { "name": "max_staleness", "type": "u32" } - ] - } - }, - { - "name": "PullFeedSetConfigsParams", - "type": { - "kind": "struct", - "fields": [ - { - "name": "feed_hash", - "type": { "option": { "array": ["u8", 32] } } - }, - { "name": "authority", "type": { "option": "pubkey" } }, - { "name": "max_variance", "type": { "option": "u64" } }, - { "name": "min_responses", "type": { "option": "u32" } }, - { "name": "name", "type": { "option": { "array": ["u8", 32] } } }, - { - "name": "ipfs_hash", - "type": { "option": { "array": ["u8", 32] } } - }, - { "name": "min_sample_size", "type": { "option": "u8" } }, - { "name": "max_staleness", "type": { "option": "u32" } } - ] - } - }, - { - "name": "PullFeedSubmitResponseManyParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "slot", "type": "u64" }, - { - "name": "submissions", - "type": { "vec": { "defined": { "name": "MultiSubmission" } } } - } - ] - } - }, - { - "name": "PullFeedSubmitResponseParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "slot", "type": "u64" }, - { - "name": "submissions", - "type": { "vec": { "defined": { "name": "Submission" } } } - } - ] - } - }, - { - "name": "PullFeedValueEvents", - "type": { - "kind": "struct", - "fields": [ - { "name": "feeds", "type": { "vec": "pubkey" } }, - { "name": "oracles", "type": { "vec": "pubkey" } }, - { "name": "values", "type": { "vec": { "vec": "i128" } } }, - { "name": "reward", "type": "u32" } - ] - } - }, - { - "name": "QueueAccountData", - "docs": [ - "An Queue represents a round-robin queue of oracle oracles who attest on-chain", - "whether a Switchboard Function was executed within an enclave against an expected set of", - "enclave measurements.", - "", - "For an oracle to join the queue, the oracle must first submit their enclave quote on-chain and", - "wait for an existing oracle to attest their quote. If the oracle's quote matches an expected", - "measurement within the queues mr_enclaves config, it is granted permissions and will start", - "being assigned update requests." - ], - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "authority", - "docs": [ - "The address of the authority which is permitted to add/remove allowed enclave measurements." - ], - "type": "pubkey" - }, - { - "name": "mr_enclaves", - "docs": ["Allowed enclave measurements."], - "type": { "array": [{ "array": ["u8", 32] }, 32] } - }, - { - "name": "oracle_keys", - "docs": [ - "The addresses of the quote oracles who have a valid", - "verification status and have heartbeated on-chain recently." - ], - "type": { "array": ["pubkey", 128] } - }, - { - "name": "max_quote_verification_age", - "docs": [ - "The maximum allowable time until a EnclaveAccount needs to be re-verified on-chain." - ], - "type": "i64" - }, - { - "name": "last_heartbeat", - "docs": [ - "The unix timestamp when the last quote oracle heartbeated on-chain." - ], - "type": "i64" - }, - { "name": "node_timeout", "type": "i64" }, - { - "name": "oracle_min_stake", - "docs": [ - "The minimum number of lamports a quote oracle needs to lock-up in order to heartbeat and verify other quotes." - ], - "type": "u64" - }, - { "name": "allow_authority_override_after", "type": "i64" }, - { - "name": "mr_enclaves_len", - "docs": ["The number of allowed enclave measurements."], - "type": "u32" - }, - { - "name": "oracle_keys_len", - "docs": [ - "The length of valid quote oracles for the given attestation queue." - ], - "type": "u32" - }, - { - "name": "reward", - "docs": [ - "The reward paid to quote oracles for attesting on-chain." - ], - "type": "u32" - }, - { - "name": "curr_idx", - "docs": [ - "Incrementer used to track the current quote oracle permitted to run any available functions." - ], - "type": "u32" - }, - { - "name": "gc_idx", - "docs": [ - "Incrementer used to garbage collect and remove stale quote oracles." - ], - "type": "u32" - }, - { "name": "require_authority_heartbeat_permission", "type": "u8" }, - { "name": "require_authority_verify_permission", "type": "u8" }, - { "name": "require_usage_permissions", "type": "u8" }, - { "name": "signer_bump", "type": "u8" }, - { "name": "mint", "type": "pubkey" }, - { "name": "lut_slot", "type": "u64" }, - { "name": "allow_subsidies", "type": "u8" }, - { - "name": "_ebuf6", - "docs": ["Reserved."], - "type": { "array": ["u8", 23] } - }, - { "name": "_ebuf5", "type": { "array": ["u8", 32] } }, - { "name": "_ebuf4", "type": { "array": ["u8", 64] } }, - { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 256] } }, - { "name": "_ebuf1", "type": { "array": ["u8", 512] } } - ] - } - }, - { - "name": "QueueAddMrEnclaveEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "queue", "type": "pubkey" }, - { "name": "mr_enclave", "type": { "array": ["u8", 32] } } - ] - } - }, - { - "name": "QueueAddMrEnclaveParams", - "type": { - "kind": "struct", - "fields": [{ "name": "mr_enclave", "type": { "array": ["u8", 32] } }] - } - }, - { - "name": "QueueAllowSubsidiesParams", - "type": { - "kind": "struct", - "fields": [{ "name": "allow_subsidies", "type": "u8" }] - } - }, - { - "name": "QueueGarbageCollectParams", - "type": { "kind": "struct", "fields": [{ "name": "idx", "type": "u32" }] } - }, - { - "name": "QueueInitDelegationGroupParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "QueueInitEvent", - "type": { - "kind": "struct", - "fields": [{ "name": "queue", "type": "pubkey" }] - } - }, - { - "name": "QueueInitParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "allow_authority_override_after", "type": "u32" }, - { "name": "require_authority_heartbeat_permission", "type": "bool" }, - { "name": "require_usage_permissions", "type": "bool" }, - { "name": "max_quote_verification_age", "type": "u32" }, - { "name": "reward", "type": "u32" }, - { "name": "node_timeout", "type": "u32" }, - { "name": "recent_slot", "type": "u64" } - ] - } - }, - { - "name": "QueueRemoveMrEnclaveEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "queue", "type": "pubkey" }, - { "name": "mr_enclave", "type": { "array": ["u8", 32] } } - ] - } - }, - { - "name": "QueueRemoveMrEnclaveParams", - "type": { - "kind": "struct", - "fields": [{ "name": "mr_enclave", "type": { "array": ["u8", 32] } }] - } - }, - { - "name": "QueueSetConfigsParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "authority", "type": { "option": "pubkey" } }, - { "name": "reward", "type": { "option": "u32" } }, - { "name": "node_timeout", "type": { "option": "i64" } } - ] - } - }, - { - "name": "Quote", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { - "name": "enclave_signer", - "docs": ["The address of the signer generated within an enclave."], - "type": "pubkey" - }, - { - "name": "mr_enclave", - "docs": [ - "The quotes MRENCLAVE measurement dictating the contents of the secure enclave." - ], - "type": { "array": ["u8", 32] } - }, - { - "name": "verification_status", - "docs": ["The VerificationStatus of the quote."], - "type": "u8" - }, - { "name": "padding1", "type": { "array": ["u8", 7] } }, - { - "name": "verification_timestamp", - "docs": ["The unix timestamp when the quote was last verified."], - "type": "i64" - }, - { - "name": "valid_until", - "docs": [ - "The unix timestamp when the quotes verification status expires." - ], - "type": "i64" - }, - { - "name": "quote_registry", - "docs": [ - "The off-chain registry where the verifiers quote can be located." - ], - "type": { "array": ["u8", 32] } - }, - { - "name": "registry_key", - "docs": [ - "Key to lookup the buffer data on IPFS or an alternative decentralized storage solution." - ], - "type": { "array": ["u8", 64] } - }, - { - "name": "secp256k1_signer", - "docs": [ - "The secp256k1 public key of the enclave signer. Derived from the enclave_signer." - ], - "type": { "array": ["u8", 64] } - }, - { "name": "last_ed25519_signer", "type": "pubkey" }, - { "name": "last_secp256k1_signer", "type": { "array": ["u8", 64] } }, - { "name": "last_rotate_slot", "type": "u64" }, - { "name": "guardian_approvers", "type": { "array": ["pubkey", 64] } }, - { "name": "guardian_approvers_len", "type": "u8" }, - { "name": "padding2", "type": { "array": ["u8", 7] } }, - { "name": "staging_ed25519_signer", "type": "pubkey" }, - { - "name": "staging_secp256k1_signer", - "type": { "array": ["u8", 64] } - }, - { - "name": "_ebuf4", - "docs": ["Reserved."], - "type": { "array": ["u8", 32] } - }, - { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 256] } }, - { "name": "_ebuf1", "type": { "array": ["u8", 512] } } - ] - } - }, - { - "name": "RandomnessAccountData", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "authority", "type": "pubkey" }, - { "name": "queue", "type": "pubkey" }, - { "name": "seed_slothash", "type": { "array": ["u8", 32] } }, - { "name": "seed_slot", "type": "u64" }, - { "name": "oracle", "type": "pubkey" }, - { "name": "reveal_slot", "type": "u64" }, - { "name": "value", "type": { "array": ["u8", 32] } }, - { "name": "lut_slot", "type": "u64" }, - { "name": "_ebuf3", "type": { "array": ["u8", 24] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 64] } }, - { "name": "_ebuf1", "type": { "array": ["u8", 128] } }, - { - "name": "active_secp256k1_signer", - "type": { "array": ["u8", 64] } - }, - { "name": "active_secp256k1_expiration", "type": "i64" } - ] - } - }, - { - "name": "RandomnessCommitEvent", - "type": { - "kind": "struct", - "fields": [ - { "name": "randomness_account", "type": "pubkey" }, - { "name": "oracle", "type": "pubkey" }, - { "name": "slot", "type": "u64" }, - { "name": "slothash", "type": { "array": ["u8", 32] } } - ] - } - }, - { - "name": "RandomnessCommitParams", - "type": { "kind": "struct", "fields": [] } - }, - { - "name": "RandomnessInitParams", - "type": { - "kind": "struct", - "fields": [{ "name": "recent_slot", "type": "u64" }] - } - }, - { - "name": "RandomnessRevealParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "signature", "type": { "array": ["u8", 64] } }, - { "name": "recovery_id", "type": "u8" }, - { "name": "value", "type": { "array": ["u8", 32] } } - ] - } - }, - { - "name": "State", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "bump", "type": "u8" }, - { "name": "test_only_disable_mr_enclave_check", "type": "u8" }, - { "name": "enable_staking", "type": "u8" }, - { "name": "padding1", "type": { "array": ["u8", 5] } }, - { "name": "authority", "type": "pubkey" }, - { "name": "guardian_queue", "type": "pubkey" }, - { "name": "reserved1", "type": "u64" }, - { "name": "epoch_length", "type": "u64" }, - { - "name": "current_epoch", - "type": { "defined": { "name": "StateEpochInfo" } } - }, - { - "name": "next_epoch", - "type": { "defined": { "name": "StateEpochInfo" } } - }, - { - "name": "finalized_epoch", - "type": { "defined": { "name": "StateEpochInfo" } } - }, - { "name": "stake_pool", "type": "pubkey" }, - { "name": "stake_program", "type": "pubkey" }, - { "name": "switch_mint", "type": "pubkey" }, - { "name": "sgx_advisories", "type": { "array": ["u16", 32] } }, - { "name": "advisories_len", "type": "u8" }, - { "name": "padding2", "type": "u8" }, - { "name": "flat_reward_cut_percentage", "type": "u8" }, - { "name": "enable_slashing", "type": "u8" }, - { "name": "subsidy_amount", "type": "u32" }, - { "name": "lut_slot", "type": "u64" }, - { "name": "base_reward", "type": "u32" }, - { "name": "_ebuf6", "type": { "array": ["u8", 28] } }, - { "name": "_ebuf5", "type": { "array": ["u8", 32] } }, - { "name": "_ebuf4", "type": { "array": ["u8", 64] } }, - { "name": "_ebuf3", "type": { "array": ["u8", 128] } }, - { "name": "_ebuf2", "type": { "array": ["u8", 512] } }, - { - "name": "cost_whitelist", - "docs": ["Cost whitelist by authority"], - "type": { "array": ["pubkey", 32] } - } - ] - } - }, - { - "name": "StateEpochInfo", - "serialization": "bytemuck", - "repr": { "kind": "c" }, - "type": { - "kind": "struct", - "fields": [ - { "name": "id", "type": "u64" }, - { "name": "_reserved1", "type": "u64" }, - { "name": "slot_end", "type": "u64" } - ] - } - }, - { "name": "StateInitParams", "type": { "kind": "struct", "fields": [] } }, - { - "name": "StateSetConfigsParams", - "type": { - "kind": "struct", - "fields": [ - { "name": "new_authority", "type": "pubkey" }, - { "name": "test_only_disable_mr_enclave_check", "type": "u8" }, - { "name": "stake_pool", "type": "pubkey" }, - { "name": "stake_program", "type": "pubkey" }, - { "name": "add_advisory", "type": "u16" }, - { "name": "rm_advisory", "type": "u16" }, - { "name": "epoch_length", "type": "u32" }, - { "name": "reset_epochs", "type": "bool" }, - { "name": "switch_mint", "type": "pubkey" }, - { "name": "enable_staking", "type": "u8" }, - { "name": "subsidy_amount", "type": "u32" }, - { "name": "base_reward", "type": "u32" }, - { "name": "add_cost_wl", "type": "pubkey" }, - { "name": "rm_cost_wl", "type": "pubkey" } - ] - } - }, - { - "name": "Submission", - "type": { - "kind": "struct", - "fields": [ - { "name": "value", "type": "i128" }, - { "name": "signature", "type": { "array": ["u8", 64] } }, - { "name": "recovery_id", "type": "u8" }, - { "name": "offset", "type": "u8" } - ] - } - } - ] -} diff --git a/solauto-sdk/src/utils/switchboardUtils.ts b/solauto-sdk/src/utils/switchboardUtils.ts index 7f76dd79..1c5b04e9 100644 --- a/solauto-sdk/src/utils/switchboardUtils.ts +++ b/solauto-sdk/src/utils/switchboardUtils.ts @@ -9,7 +9,6 @@ import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; import { AnchorProvider, Idl, Program } from "@coral-xyz/anchor"; import * as OnDemand from "@switchboard-xyz/on-demand"; import Big from "big.js"; -import switchboardIdl from "../idls/switchboard.json"; import { PRICES, SWITCHBOARD_PRICE_FEED_IDS } from "../constants"; import { TransactionItemInputs } from "../types"; import { @@ -18,6 +17,7 @@ import { retryWithExponentialBackoff, } from "./generalUtils"; import { getWrappedInstruction } from "./solanaUtils"; +import { CrossbarClient } from "@switchboard-xyz/common"; export async function getPullFeed( conn: Connection, @@ -40,15 +40,22 @@ export async function getPullFeed( ); consoleLog("Pulling SWB program..."); - const { PullFeed, ON_DEMAND_MAINNET_PID } = OnDemand; + const { PullFeed, Queue, ON_DEMAND_MAINNET_PID } = OnDemand; const sbProgram = await Program.at(ON_DEMAND_MAINNET_PID, provider); + const crossbar = new CrossbarClient("https://integrator-crossbar.mrgn.app/"); + const queue = await Queue.loadDefault(sbProgram); + const gateway = await queue.fetchGatewayFromCrossbar(crossbar as any); + consoleLog("Pulled SWB program!"); consoleLog("Feed id:", SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId); - return new PullFeed( - sbProgram, - new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId) - ); + return { + gateway, + feed: new PullFeed( + sbProgram, + new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId) + ), + }; } export async function buildSwbSubmitResponseTx( @@ -56,14 +63,19 @@ export async function buildSwbSubmitResponseTx( signer: Signer, mint: PublicKey ): Promise { - const feed = await getPullFeed(conn, mint, toWeb3JsPublicKey(signer.publicKey)); + const { feed, gateway } = await getPullFeed( + conn, + mint, + toWeb3JsPublicKey(signer.publicKey) + ); + + // Try to replicate locally in the lambda docker container - const gateway = await feed.fetchGatewayUrl(); consoleLog("Fetching crank IX..."); const [pullIxs, responses] = await retryWithExponentialBackoff( async () => { const res = await feed.fetchUpdateIx({ - gateway, + gateway: gateway.endpoint(), chain: "solana", network: "mainnet-beta", }); @@ -99,7 +111,7 @@ export async function buildSwbSubmitResponseTx( lookupTableAddresses: responses .filter((x) => Boolean(x.oracle.lut?.key)) .map((x) => x.oracle.lut!.key.toString()), - orderPrio: -1, + orderPrio: -2, }; } @@ -118,7 +130,7 @@ export async function getSwitchboardFeedData( const results = await Promise.all( mints.map(async (mint) => { - const feed = await getPullFeed(conn, mint); + const { feed } = await getPullFeed(conn, mint); const result = await feed.loadData(); const price = Number(result.result.value) / Math.pow(10, 18); const stale = From c59aae619b50bb87b0ee531653363f6b8779d7c9 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Tue, 28 Oct 2025 22:52:03 -0400 Subject: [PATCH 81/88] add cbbtc and reorganize swb code --- programs/solauto/src/constants.rs | 2 +- solauto-sdk/local/txSandbox.ts | 41 +++++++++------- solauto-sdk/package.json | 2 +- solauto-sdk/src/constants/marginfiAccounts.ts | 5 ++ solauto-sdk/src/constants/pythConstants.ts | 2 + solauto-sdk/src/constants/solautoConstants.ts | 2 + solauto-sdk/src/constants/tokenConstants.ts | 13 ++++- .../manager/clientTransactionsManager.ts | 43 +---------------- .../manager/transactionsManager.ts | 23 ++++++--- solauto-sdk/src/utils/stringUtils.ts | 2 +- solauto-sdk/src/utils/switchboardUtils.ts | 47 +++++++++++++++++-- 11 files changed, 110 insertions(+), 72 deletions(-) diff --git a/programs/solauto/src/constants.rs b/programs/solauto/src/constants.rs index 2e36b314..d8681b25 100644 --- a/programs/solauto/src/constants.rs +++ b/programs/solauto/src/constants.rs @@ -17,4 +17,4 @@ pub const MAX_BASIS_POINTS: u16 = 10000; pub const REFERRER_PERCENTAGE: f64 = 0.15; -pub const OFFSET_FROM_MAX_LTV: f64 = 0.005; +pub const OFFSET_FROM_MAX_LTV: f64 = 0.005; \ No newline at end of file diff --git a/solauto-sdk/local/txSandbox.ts b/solauto-sdk/local/txSandbox.ts index a4f7f4a0..dc50db7b 100644 --- a/solauto-sdk/local/txSandbox.ts +++ b/solauto-sdk/local/txSandbox.ts @@ -4,6 +4,7 @@ import { fromWeb3JsKeypair } from "@metaplex-foundation/umi-web3js-adapters"; import { ClientTransactionsManager, consoleLog, + fetchBank, getBatches, getClient, getPositionExBulk, @@ -15,6 +16,8 @@ import { PriorityFeeSetting, ProgramEnv, rebalance, + safeFetchBank, + safeFetchMarginfiAccount, SOLAUTO_PROD_PROGRAM, SOLAUTO_TEST_PROGRAM, SolautoClient, @@ -46,24 +49,30 @@ export async function main() { lpEnv, }); - await client.initializeExistingSolautoPosition({ - positionId: 1, - authority: new PublicKey("61rtn5tzVkesapo6Cz83SPoShUfAePSxJsqniuF2wRKC"), - // lpUserAccount: new PublicKey( - // "GEokw9jqbh6d1xUNA3qaeYFFetbSR5Y1nt7C3chwwgSz" - // ), - }); + // await client.initializeExistingSolautoPosition({ + // positionId: 1, + // authority: new PublicKey("61rtn5tzVkesapo6Cz83SPoShUfAePSxJsqniuF2wRKC"), + // // lpUserAccount: new PublicKey( + // // "GEokw9jqbh6d1xUNA3qaeYFFetbSR5Y1nt7C3chwwgSz" + // // ), + // }); - const transactionItems = [rebalance(client)]; + // const transactionItems = [rebalance(client)]; - const txManager = new ClientTransactionsManager({ - txHandler: client, - txRunType: payForTransaction ? "normal" : "only-simulate", - priorityFeeSetting: PriorityFeeSetting.Default, - retryConfig: { totalRetries: 2 }, - }); - const statuses = await txManager.send(transactionItems); - consoleLog(statuses); + const account = await fetchBank(umi, publicKey("Ac4KV5K5isDqtABtg6h5DiwzZMe3Sp9bc3pBiCUvUpaQ")); + console.log(account.config.oracleKeys[0]); + console.log(account.config.oracleKeys[1]); + console.log(account.config.oracleKeys[2]); + console.log(account.config.oracleKeys[3]); + + // const txManager = new ClientTransactionsManager({ + // txHandler: client, + // txRunType: payForTransaction ? "normal" : "only-simulate", + // priorityFeeSetting: PriorityFeeSetting.Default, + // retryConfig: { totalRetries: 2 }, + // }); + // const statuses = await txManager.send(transactionItems); + // consoleLog(statuses); } async function refreshAll() { diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 0cbd7549..adf56441 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.806", + "version": "1.0.814", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/constants/marginfiAccounts.ts b/solauto-sdk/src/constants/marginfiAccounts.ts index 06717825..62e68d65 100644 --- a/solauto-sdk/src/constants/marginfiAccounts.ts +++ b/solauto-sdk/src/constants/marginfiAccounts.ts @@ -142,6 +142,11 @@ const MARGINFI_PROD_ACCOUNTS: MarginfiBankAccountsMap = { bank: "61Qx9kgWo9RVtPHf8Rku6gbaUtcnzgkpAuifQBUcMRVK", liquidityVault: "6FxnrCaJNHLyrFy6EPtqFjoUK5iRxDQbaVo1bA69nDhH", vaultAuthority: "6VL2QW6sy8cjxL24xHL7eFbnUSi35DMJd8AzRwssSs9y" + }, + [tokens.CBBTC]: { + bank: "Ac4KV5K5isDqtABtg6h5DiwzZMe3Sp9bc3pBiCUvUpaQ", + liquidityVault: "FvrJsHu7X9jkT9rTuR6Kfs6wSjPvjV6zhH4gVSiJ8LFT", + vaultAuthority: "jfBsYE2sAkNj1pwE6U1gQ515JU5vn9huZMDYVvZagb4", } }, ["DQ2jqDJw9uzTwttf6h6r217BQ7kws3jZbJXDkfbCJa1q"]: { diff --git a/solauto-sdk/src/constants/pythConstants.ts b/solauto-sdk/src/constants/pythConstants.ts index 41fb1c4c..a015b261 100644 --- a/solauto-sdk/src/constants/pythConstants.ts +++ b/solauto-sdk/src/constants/pythConstants.ts @@ -44,6 +44,8 @@ export const PYTH_PRICE_FEED_IDS = { "0x4ca4beeca86f0d164160323817a4e42b10010a724c2217c6ee41b54cd4cc61fc", [tokens.PUMP]: "0x7a01fca212788bba7c5bf8c9efd576a8a722f070d2c17596ff7bb609b8d5c3b9", + [tokens.CBBTC]: + "0x2817d7bfe5c64b8ea956e9a26f573ef64e72e4d7891f2d6af9bcc93f7aff9a97", }; export const PYTH_ORACLE_ACCOUNTS = { diff --git a/solauto-sdk/src/constants/solautoConstants.ts b/solauto-sdk/src/constants/solautoConstants.ts index 9f6af971..e6995179 100644 --- a/solauto-sdk/src/constants/solautoConstants.ts +++ b/solauto-sdk/src/constants/solautoConstants.ts @@ -65,3 +65,5 @@ export const STANDARD_LUT_ACCOUNTS = [ SYSVAR_INSTRUCTIONS_PUBKEY, JUPITER_PROGRAM_ID, ].map((x) => x.toString()); + +export const UPDATE_ORACLE_TX_NAME = "update oracle"; diff --git a/solauto-sdk/src/constants/tokenConstants.ts b/solauto-sdk/src/constants/tokenConstants.ts index 855c10d6..4258da82 100644 --- a/solauto-sdk/src/constants/tokenConstants.ts +++ b/solauto-sdk/src/constants/tokenConstants.ts @@ -25,6 +25,7 @@ export const RETARDIO = "6ogzHhzdrQr9Pgv6hZ2MNze7UrzBMAFyBBWUYp1Fhitx"; export const BILLY = "3B5wuUrMEi5yATD7on46hKfej3pfmd7t1RKgrsN3pump"; export const HMTR = "7JhmUcZrrfhyt5nTSu3AfsrUq2L9992a7AhwdSDxdoL2"; export const PUMP = "pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn"; +export const CBBTC = "cbbtcf3aa214zXHbiAZQwf4122FBYbraNdFqgw4iMij"; export const ALL_SUPPORTED_TOKENS = [ NATIVE_MINT.toString(), @@ -51,6 +52,7 @@ export const ALL_SUPPORTED_TOKENS = [ BILLY, HMTR, PUMP, + CBBTC, ]; export interface TokenInfo { @@ -199,11 +201,18 @@ export const TOKEN_INFO: { [key: string]: TokenInfo } = { ticker: "PUMP", name: "Pump.fun", decimals: 6, - } + }, + [CBBTC]: { + ticker: "CBBTC", + name: "Coinbase BTC", + decimals: 8, + isMajor: true, + }, }; export const MAJORS_PRIO = { [WBTC]: 0, + [CBBTC]: 0, [WETH]: 1, [NATIVE_MINT.toString()]: 2, -}; \ No newline at end of file +}; diff --git a/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts b/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts index fecebf5b..11877860 100644 --- a/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts @@ -5,6 +5,7 @@ import { import { SolautoClient } from "../../solauto"; import { TransactionsManager } from "./transactionsManager"; import { + addSwbOraclePullTxs, buildSwbSubmitResponseTx, getSwitchboardFeedData, isSwitchboardMint, @@ -34,46 +35,6 @@ export class ClientTransactionsManager extends TransactionsManager x.oracleInteractor) && switchboardMints.length) { - this.txHandler.log("Checking if oracle update(s) needed..."); - const staleOracles = - ( - await getSwitchboardFeedData( - this.txHandler.connection, - switchboardMints - ) - ).filter((x) => x.stale).length > 0; - - if (staleOracles) { - this.txHandler.log("Requires oracle update(s)..."); - const oracleTxs = switchboardMints.map( - (x) => - new TransactionItem( - async () => - await buildSwbSubmitResponseTx( - this.txHandler.connection, - this.txHandler.signer, - x - ), - this.updateOracleTxName - ) - ); - this.txHandler.log("Set crank IXs in TX"); - txs.unshift(...oracleTxs); - } - } - } - private async addChoreTxs( txs: TransactionItem[], updateLutTx?: TransactionBuilder @@ -131,7 +92,7 @@ export class ClientTransactionsManager extends TransactionsManager { protected retryDelay: number; protected abortController?: AbortController; - updateOracleTxName = "update oracle"; - constructor(args: TransactionsManagerArgs) { this.txHandler = args.txHandler; this.statusCallback = args.statusCallback; @@ -118,7 +117,9 @@ export class TransactionsManager { ); if (!transaction.fitsInOneTransaction(this.txHandler.umi)) { throw new TransactionTooLargeError( - `Exceeds max transaction size (${transaction.getTransactionSize(this.txHandler.umi)})` + `Exceeds max transaction size (${transaction.getTransactionSize( + this.txHandler.umi + )})` ); } else { let newSet = new TransactionSet(this.txHandler, this.lookupTables, [ @@ -166,7 +167,9 @@ export class TransactionsManager { } } consoleLog( - `${args.name} ${args.attemptNum} is ${args.status.toString().toLowerCase()}` + `${args.name} ${args.attemptNum} is ${args.status + .toString() + .toLowerCase()}` ); this.statusCallback?.([...this.statuses]); } @@ -180,7 +183,11 @@ export class TransactionsManager { (x) => !lutAccounts.includes(x) ); consoleLog( - `Program ${ix.programId}, data len: ${ix.data.length}, LUT accounts data: ${ix.keys.filter((x) => lutAccounts.includes(x.pubkey)).length * 3}` + `Program ${ix.programId}, data len: ${ + ix.data.length + }, LUT accounts data: ${ + ix.keys.filter((x) => lutAccounts.includes(x.pubkey)).length * 3 + }` ); if (accountsNotInLut.length > 0) { consoleLog(`${accountsNotInLut.length} accounts not in LUT:`); @@ -273,7 +280,7 @@ export class TransactionsManager { ); if ( newItemSetNames.length === 1 && - newItemSetNames[0] === this.updateOracleTxName + newItemSetNames[0] === UPDATE_ORACLE_TX_NAME ) { consoleLog("Skipping unnecessary oracle update"); this.updateStatusForSets( @@ -570,7 +577,9 @@ export class TransactionsManager { this.priorityFeeSetting ); - const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`; + const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${ + errorDetails.errorInfo?.split("\n")[0] ?? "unknown" + }`; const errorInfo = errorDetails.errorName || errorDetails.errorInfo ? errorString diff --git a/solauto-sdk/src/utils/stringUtils.ts b/solauto-sdk/src/utils/stringUtils.ts index 73e59753..baf85233 100644 --- a/solauto-sdk/src/utils/stringUtils.ts +++ b/solauto-sdk/src/utils/stringUtils.ts @@ -9,7 +9,7 @@ export type StrategyType = (typeof StrategyTypes)[number]; export function adjustedTicker(mint?: PublicKey) { const info = tokenInfo(mint); - if (info.ticker.toLowerCase() === "wbtc") { + if (info.ticker.toLowerCase().includes("btc")) { return "BTC"; } else if (info.ticker.toLowerCase() === "weth") { return "ETH"; diff --git a/solauto-sdk/src/utils/switchboardUtils.ts b/solauto-sdk/src/utils/switchboardUtils.ts index 1c5b04e9..d55be1b7 100644 --- a/solauto-sdk/src/utils/switchboardUtils.ts +++ b/solauto-sdk/src/utils/switchboardUtils.ts @@ -9,7 +9,11 @@ import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; import { AnchorProvider, Idl, Program } from "@coral-xyz/anchor"; import * as OnDemand from "@switchboard-xyz/on-demand"; import Big from "big.js"; -import { PRICES, SWITCHBOARD_PRICE_FEED_IDS } from "../constants"; +import { + PRICES, + SWITCHBOARD_PRICE_FEED_IDS, + UPDATE_ORACLE_TX_NAME, +} from "../constants"; import { TransactionItemInputs } from "../types"; import { consoleLog, @@ -18,6 +22,7 @@ import { } from "./generalUtils"; import { getWrappedInstruction } from "./solanaUtils"; import { CrossbarClient } from "@switchboard-xyz/common"; +import { SolautoClient, TransactionItem } from "../services"; export async function getPullFeed( conn: Connection, @@ -69,8 +74,6 @@ export async function buildSwbSubmitResponseTx( toWeb3JsPublicKey(signer.publicKey) ); - // Try to replicate locally in the lambda docker container - consoleLog("Fetching crank IX..."); const [pullIxs, responses] = await retryWithExponentialBackoff( async () => { @@ -146,3 +149,41 @@ export async function getSwitchboardFeedData( export function isSwitchboardMint(mint: PublicKey | string) { return Object.keys(SWITCHBOARD_PRICE_FEED_IDS).includes(mint.toString()); } + +export async function addSwbOraclePullTxs( + client: SolautoClient, + txs: TransactionItem[] +) { + const switchboardMints = [ + ...(isSwitchboardMint(client.pos.supplyMint) + ? [client.pos.supplyMint] + : []), + ...(isSwitchboardMint(client.pos.debtMint) ? [client.pos.debtMint] : []), + ]; + + if (txs.find((x) => x.oracleInteractor) && switchboardMints.length) { + consoleLog("Checking if oracle update(s) needed..."); + const staleOracles = + ( + await getSwitchboardFeedData(client.connection, switchboardMints) + ).filter((x) => x.stale).length > 0; + + if (staleOracles) { + consoleLog("Requires oracle update(s)..."); + const oracleTxs = switchboardMints.map( + (x) => + new TransactionItem( + async () => + await buildSwbSubmitResponseTx( + client.connection, + client.signer, + x + ), + UPDATE_ORACLE_TX_NAME + ) + ); + consoleLog("Set crank IXs in TX"); + txs.unshift(...oracleTxs); + } + } +} From 5591d0558730006064de9ccc5e86b6bc1b1d45fd Mon Sep 17 00:00:00 2001 From: Chelioso Date: Tue, 28 Oct 2025 23:21:25 -0400 Subject: [PATCH 82/88] sandbox script tweak --- solauto-sdk/local/txSandbox.ts | 38 ++++++++++++++-------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/solauto-sdk/local/txSandbox.ts b/solauto-sdk/local/txSandbox.ts index dc50db7b..97f43664 100644 --- a/solauto-sdk/local/txSandbox.ts +++ b/solauto-sdk/local/txSandbox.ts @@ -49,30 +49,24 @@ export async function main() { lpEnv, }); - // await client.initializeExistingSolautoPosition({ - // positionId: 1, - // authority: new PublicKey("61rtn5tzVkesapo6Cz83SPoShUfAePSxJsqniuF2wRKC"), - // // lpUserAccount: new PublicKey( - // // "GEokw9jqbh6d1xUNA3qaeYFFetbSR5Y1nt7C3chwwgSz" - // // ), - // }); - - // const transactionItems = [rebalance(client)]; + await client.initializeExistingSolautoPosition({ + positionId: 1, + authority: new PublicKey("61rtn5tzVkesapo6Cz83SPoShUfAePSxJsqniuF2wRKC"), + // lpUserAccount: new PublicKey( + // "GEokw9jqbh6d1xUNA3qaeYFFetbSR5Y1nt7C3chwwgSz" + // ), + }); - const account = await fetchBank(umi, publicKey("Ac4KV5K5isDqtABtg6h5DiwzZMe3Sp9bc3pBiCUvUpaQ")); - console.log(account.config.oracleKeys[0]); - console.log(account.config.oracleKeys[1]); - console.log(account.config.oracleKeys[2]); - console.log(account.config.oracleKeys[3]); + const transactionItems = [rebalance(client)]; - // const txManager = new ClientTransactionsManager({ - // txHandler: client, - // txRunType: payForTransaction ? "normal" : "only-simulate", - // priorityFeeSetting: PriorityFeeSetting.Default, - // retryConfig: { totalRetries: 2 }, - // }); - // const statuses = await txManager.send(transactionItems); - // consoleLog(statuses); + const txManager = new ClientTransactionsManager({ + txHandler: client, + txRunType: payForTransaction ? "normal" : "only-simulate", + priorityFeeSetting: PriorityFeeSetting.Default, + retryConfig: { totalRetries: 2 }, + }); + const statuses = await txManager.send(transactionItems); + consoleLog(statuses); } async function refreshAll() { From 2af3803070d50054c700ec2f53363a75dbe94f2e Mon Sep 17 00:00:00 2001 From: jgur-psyops Date: Thu, 18 Dec 2025 15:10:32 -0500 Subject: [PATCH 83/88] mut on top of the fixes branch --- idls/marginfi.json | 2 +- idls/solauto.json | 4 ++-- .../generated/instructions/lending_account_withdraw.rs | 8 ++++---- programs/solauto/src/types/instruction.rs | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/idls/marginfi.json b/idls/marginfi.json index ce043b18..b0775aa3 100644 --- a/idls/marginfi.json +++ b/idls/marginfi.json @@ -883,7 +883,7 @@ "accounts": [ { "name": "marginfiGroup", - "isMut": false, + "isMut": true, "isSigner": false }, { diff --git a/idls/solauto.json b/idls/solauto.json index eff84e1c..2a0c6270 100644 --- a/idls/solauto.json +++ b/idls/solauto.json @@ -559,7 +559,7 @@ }, { "name": "marginfiGroup", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -697,7 +697,7 @@ }, { "name": "marginfiGroup", - "isMut": false, + "isMut": true, "isSigner": false }, { diff --git a/programs/marginfi-sdk/src/generated/instructions/lending_account_withdraw.rs b/programs/marginfi-sdk/src/generated/instructions/lending_account_withdraw.rs index 5ee5c446..040c74ea 100644 --- a/programs/marginfi-sdk/src/generated/instructions/lending_account_withdraw.rs +++ b/programs/marginfi-sdk/src/generated/instructions/lending_account_withdraw.rs @@ -41,7 +41,7 @@ impl LendingAccountWithdraw { remaining_accounts: &[solana_program::instruction::AccountMeta], ) -> solana_program::instruction::Instruction { let mut accounts = Vec::with_capacity(8 + remaining_accounts.len()); - accounts.push(solana_program::instruction::AccountMeta::new_readonly( + accounts.push(solana_program::instruction::AccountMeta::new( self.marginfi_group, false, )); @@ -111,7 +111,7 @@ pub struct LendingAccountWithdrawInstructionArgs { /// /// ### Accounts: /// -/// 0. `[]` marginfi_group +/// 0. `[writable]` marginfi_group /// 1. `[writable]` marginfi_account /// 2. `[signer]` signer /// 3. `[writable]` bank @@ -345,7 +345,7 @@ impl<'a, 'b> LendingAccountWithdrawCpi<'a, 'b> { )], ) -> solana_program::entrypoint::ProgramResult { let mut accounts = Vec::with_capacity(8 + remaining_accounts.len()); - accounts.push(solana_program::instruction::AccountMeta::new_readonly( + accounts.push(solana_program::instruction::AccountMeta::new( *self.marginfi_group.key, false, )); @@ -421,7 +421,7 @@ impl<'a, 'b> LendingAccountWithdrawCpi<'a, 'b> { /// /// ### Accounts: /// -/// 0. `[]` marginfi_group +/// 0. `[writable]` marginfi_group /// 1. `[writable]` marginfi_account /// 2. `[signer]` signer /// 3. `[writable]` bank diff --git a/programs/solauto/src/types/instruction.rs b/programs/solauto/src/types/instruction.rs index f626208f..aee070b2 100644 --- a/programs/solauto/src/types/instruction.rs +++ b/programs/solauto/src/types/instruction.rs @@ -127,7 +127,7 @@ pub enum Instruction { #[account(name = "ata_program")] #[account(name = "rent")] #[account(mut, name = "solauto_position")] - #[account(name = "marginfi_group")] + #[account(mut, name = "marginfi_group")] #[account(mut, name = "marginfi_account")] #[account(mut, name = "supply_bank")] #[account(optional, name = "supply_price_oracle")] @@ -152,7 +152,7 @@ pub enum Instruction { #[account(mut, optional, name = "referred_by_ta")] #[account(mut, optional, name = "position_authority")] #[account(mut, name = "solauto_position")] - #[account(name = "marginfi_group")] + #[account(mut, name = "marginfi_group")] #[account(mut, name = "marginfi_account")] #[account(optional, mut, name = "intermediary_ta")] #[account(mut, name = "supply_bank")] From d916fc7753e246e1cb98c7d6ed7d2a842a2e3ef2 Mon Sep 17 00:00:00 2001 From: Matthew <19557547+mtleliever@users.noreply.github.com> Date: Thu, 18 Dec 2025 18:07:35 -0500 Subject: [PATCH 84/88] set marginfiGroup account to isWritable: true --- solauto-sdk/src/generated/instructions/marginfiRebalance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solauto-sdk/src/generated/instructions/marginfiRebalance.ts b/solauto-sdk/src/generated/instructions/marginfiRebalance.ts index d7330fd4..d7e87e58 100644 --- a/solauto-sdk/src/generated/instructions/marginfiRebalance.ts +++ b/solauto-sdk/src/generated/instructions/marginfiRebalance.ts @@ -188,7 +188,7 @@ export function marginfiRebalance( }, marginfiGroup: { index: 10, - isWritable: false as boolean, + isWritable: true as boolean, value: input.marginfiGroup ?? null, }, marginfiAccount: { From 8ece90a5b3d4b296b3f431aefe515cc9f0063265 Mon Sep 17 00:00:00 2001 From: Matthew <19557547+mtleliever@users.noreply.github.com> Date: Fri, 19 Dec 2025 03:22:25 -0500 Subject: [PATCH 85/88] fix marginfiProtocolInteraction isWritable --- .../src/generated/instructions/marginfiProtocolInteraction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solauto-sdk/src/generated/instructions/marginfiProtocolInteraction.ts b/solauto-sdk/src/generated/instructions/marginfiProtocolInteraction.ts index 5bc2a629..459dbf6a 100644 --- a/solauto-sdk/src/generated/instructions/marginfiProtocolInteraction.ts +++ b/solauto-sdk/src/generated/instructions/marginfiProtocolInteraction.ts @@ -139,7 +139,7 @@ export function marginfiProtocolInteraction( }, marginfiGroup: { index: 7, - isWritable: false as boolean, + isWritable: true as boolean, value: input.marginfiGroup ?? null, }, marginfiAccount: { From 3874f8a1ed5248493f8358bb650afd57bcd7cb22 Mon Sep 17 00:00:00 2001 From: Chelioso Date: Wed, 4 Feb 2026 15:26:32 -0700 Subject: [PATCH 86/88] fix transaction sizes --- solauto-sdk/package.json | 2 +- .../manager/clientTransactionsManager.ts | 4 -- .../manager/transactionsManager.ts | 31 ++++++++-- .../transactions/types/transactionSet.ts | 14 ++++- .../src/solautoPosition/positionUtils.ts | 20 +++---- solauto-sdk/src/utils/jitoUtils.ts | 22 +++---- solauto-sdk/src/utils/marginfi/data.ts | 12 ++-- solauto-sdk/src/utils/solanaUtils.ts | 58 +++++++++++++++++-- solauto-sdk/src/utils/solautoUtils.ts | 6 +- 9 files changed, 122 insertions(+), 47 deletions(-) diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index adf56441..14f59d84 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.814", + "version": "1.0.819", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts b/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts index 11877860..08d64af2 100644 --- a/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/clientTransactionsManager.ts @@ -5,10 +5,6 @@ import { import { SolautoClient } from "../../solauto"; import { TransactionsManager } from "./transactionsManager"; import { - addSwbOraclePullTxs, - buildSwbSubmitResponseTx, - getSwitchboardFeedData, - isSwitchboardMint, retryWithExponentialBackoff, } from "../../../utils"; import { TransactionItem } from "../types"; diff --git a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts index 745e7d5e..c7d9b809 100644 --- a/solauto-sdk/src/services/transactions/manager/transactionsManager.ts +++ b/solauto-sdk/src/services/transactions/manager/transactionsManager.ts @@ -7,15 +7,23 @@ import { TransactionRunType, } from "../../../types"; import { + addTxOptimizations, + canSerializeTransaction, consoleLog, ErrorsToThrow, + getActualTxSize, retryWithExponentialBackoff, sendSingleOptimizedTransaction, sendJitoBundledTransactions, } from "../../../utils"; import { TxHandler } from "../../solauto"; import { getErrorInfo } from "../transactionUtils"; -import { LookupTables, TransactionItem, TransactionSet } from "../types"; +import { + JITO_TIP_BUFFER_BYTES, + LookupTables, + TransactionItem, + TransactionSet, +} from "../types"; import { UPDATE_ORACLE_TX_NAME } from "../../../constants"; export class TransactionTooLargeError extends Error { @@ -112,14 +120,25 @@ export class TransactionsManager { continue; } - const transaction = item.tx.setAddressLookupTables( + const transaction = addTxOptimizations( + this.txHandler.umi, + item.tx, + 1, + 1 + ).setAddressLookupTables( await this.lookupTables.getLutInputs(item.lookupTableAddresses) ); - if (!transaction.fitsInOneTransaction(this.txHandler.umi)) { + // Check if transaction can be serialized with buffer for Jito tip instruction + if ( + !canSerializeTransaction( + this.txHandler.umi, + transaction, + JITO_TIP_BUFFER_BYTES + ) + ) { + const actualSize = getActualTxSize(this.txHandler.umi, transaction); throw new TransactionTooLargeError( - `Exceeds max transaction size (${transaction.getTransactionSize( - this.txHandler.umi - )})` + `Exceeds max transaction size (actual: ${actualSize ?? "failed to serialize"} + ~${JITO_TIP_BUFFER_BYTES} bytes for Jito tip)` ); } else { let newSet = new TransactionSet(this.txHandler, this.lookupTables, [ diff --git a/solauto-sdk/src/services/transactions/types/transactionSet.ts b/solauto-sdk/src/services/transactions/types/transactionSet.ts index ba1ec0ce..d11c83b0 100644 --- a/solauto-sdk/src/services/transactions/types/transactionSet.ts +++ b/solauto-sdk/src/services/transactions/types/transactionSet.ts @@ -2,15 +2,20 @@ import { AddressLookupTableInput, transactionBuilder, TransactionBuilder, + Umi, } from "@metaplex-foundation/umi"; import { TxHandler } from "../../solauto"; import { LookupTables } from "./lookupTables"; import { TransactionItem } from "./transactionItem"; -import { addTxOptimizations } from "../../../utils"; +import { addTxOptimizations, canSerializeTransaction } from "../../../utils"; import { CHORES_TX_NAME } from "../../../constants"; const MAX_SUPPORTED_ACCOUNT_LOCKS = 64; +// Buffer for Jito tip instruction (~44 bytes) + potential new accounts in message +// This accounts for: System Transfer instruction data, Jito tip account (if new), etc. +export const JITO_TIP_BUFFER_BYTES = 75; + export class TransactionSet { constructor( private txHandler: TxHandler, @@ -55,7 +60,12 @@ export class TransactionSet { ]) ); - return tx.fitsInOneTransaction(this.txHandler.umi); + // Use actual serialization check with buffer for Jito tip instruction + return canSerializeTransaction( + this.txHandler.umi, + tx, + JITO_TIP_BUFFER_BYTES + ); } add(...items: TransactionItem[]) { diff --git a/solauto-sdk/src/solautoPosition/positionUtils.ts b/solauto-sdk/src/solautoPosition/positionUtils.ts index 3ce661a6..9fcaeca5 100644 --- a/solauto-sdk/src/solautoPosition/positionUtils.ts +++ b/solauto-sdk/src/solautoPosition/positionUtils.ts @@ -38,7 +38,7 @@ export function createSolautoSettings( boostToBps: settings.boostToBps, repayGap: settings.repayGap, repayToBps: settings.repayToBps, - padding: [], + padding: new Array(24).fill(0), }; } @@ -167,9 +167,9 @@ export function createFakePositionState( borrowFeeBps: 0, decimals: supplyDecimals, mint: fromWeb3JsPublicKey(supply.mint), - padding1: [], - padding2: [], - padding: new Uint8Array([]), + padding1: new Array(5).fill(0), + padding2: new Array(8).fill(0), + padding: new Uint8Array(32), }, debt: { amountUsed: { @@ -186,9 +186,9 @@ export function createFakePositionState( borrowFeeBps: 0, decimals: debtDecimals, mint: fromWeb3JsPublicKey(debt.mint), - padding1: [], - padding2: [], - padding: new Uint8Array([]), + padding1: new Array(5).fill(0), + padding2: new Array(8).fill(0), + padding: new Uint8Array(32), }, netWorth: { baseUnit: supply.price @@ -199,8 +199,8 @@ export function createFakePositionState( maxLtvBps, liqThresholdBps, lastRefreshed: BigInt(currentUnixSeconds()), - padding1: [], - padding2: [], - padding: [], + padding1: new Array(6).fill(0), + padding2: new Array(4).fill(0), + padding: new Array(2).fill(0), }; } diff --git a/solauto-sdk/src/utils/jitoUtils.ts b/solauto-sdk/src/utils/jitoUtils.ts index 122a4459..d1031f7b 100644 --- a/solauto-sdk/src/utils/jitoUtils.ts +++ b/solauto-sdk/src/utils/jitoUtils.ts @@ -82,8 +82,8 @@ async function simulateJitoBundle(umi: Umi, txs: VersionedTransaction[]) { { encoding: "base64", commitment: "confirmed", - preExecutionAccountsConfigs: txs.map((_) => {}), - postExecutionAccountsConfigs: txs.map((_) => {}), + preExecutionAccountsConfigs: txs.map((_) => { }), + postExecutionAccountsConfigs: txs.map((_) => { }), skipSigVerify: true, }, ]); @@ -334,16 +334,16 @@ export async function sendJitoBundledTransactions( const feeEstimates = usePriorityFee(priorityFeeSetting) ? await Promise.all( - txs.map( - async (x) => - (await getComputeUnitPriceEstimate( - umi, - x, - priorityFeeSetting, - true - )) ?? 1000000 - ) + txs.map( + async (x) => + (await getComputeUnitPriceEstimate( + umi, + x, + priorityFeeSetting, + true + )) ?? 1000000 ) + ) : undefined; if (abortController?.signal.aborted) { diff --git a/solauto-sdk/src/utils/marginfi/data.ts b/solauto-sdk/src/utils/marginfi/data.ts index 019f6aa9..c4b41327 100644 --- a/solauto-sdk/src/utils/marginfi/data.ts +++ b/solauto-sdk/src/utils/marginfi/data.ts @@ -288,9 +288,9 @@ async function getTokenUsage( }, baseAmountMarketPriceUsd: toBaseUnit(marketPrice, USD_DECIMALS), borrowFeeBps: isAsset ? 0 : toBps(originationFee), - padding1: [], - padding2: [], - padding: new Uint8Array([]), + padding1: new Array(5).fill(0), + padding2: new Array(8).fill(0), + padding: new Uint8Array(32), }; } @@ -513,9 +513,9 @@ export async function getMarginfiAccountPositionState( maxLtvBps, liqThresholdBps, lastRefreshed: BigInt(currentUnixSeconds()), - padding1: [], - padding2: [], - padding: [], + padding1: new Array(6).fill(0), + padding2: new Array(4).fill(0), + padding: new Array(2).fill(0), }, }; } diff --git a/solauto-sdk/src/utils/solanaUtils.ts b/solauto-sdk/src/utils/solanaUtils.ts index f6899578..067f7c51 100644 --- a/solauto-sdk/src/utils/solanaUtils.ts +++ b/solauto-sdk/src/utils/solanaUtils.ts @@ -220,7 +220,11 @@ export function prependTx( ); if (keccakIdx !== -1) { const [beforeKeccak, afterKeccak] = tx.splitByIndex(keccakIdx + 1); - let finalTx = transactionBuilder().add(beforeKeccak); + // IMPORTANT: Preserve lookup tables from original transaction + const lookupTables = tx.options.addressLookupTables ?? []; + let finalTx = transactionBuilder() + .setAddressLookupTables(lookupTables) + .add(beforeKeccak); for (const txToAdd of txsToAdd) { finalTx = finalTx.append(txToAdd); } @@ -234,6 +238,50 @@ export function prependTx( } } +const MAX_TX_SIZE = 1232; + +// Dummy blockhash for size checking (all zeros, 32 bytes base58 encoded) +const DUMMY_BLOCKHASH = "11111111111111111111111111111111"; + +/** + * Safely checks if a transaction can be serialized and returns its actual size. + * Returns undefined if serialization fails. + */ +export function getActualTxSize( + umi: Umi, + tx: TransactionBuilder +): number | undefined { + try { + // Set a dummy blockhash if not already set, just for size checking + const txWithBlockhash = tx.setBlockhash(DUMMY_BLOCKHASH); + // Build the transaction and convert to web3.js format + const builtTx = txWithBlockhash.build(umi); + const web3Tx = toWeb3JsTransaction(builtTx); + // Actually serialize to get the real size + const serialized = web3Tx.serialize(); + return serialized.length; + } catch (e) { + // Serialization failed - transaction is too large or malformed + return undefined; + } +} + +/** + * Checks if a transaction can fit in a single transaction by actually serializing it. + * More accurate than getTransactionSize() estimation. + */ +export function canSerializeTransaction( + umi: Umi, + tx: TransactionBuilder, + buffer: number = 0 +): boolean { + const size = getActualTxSize(umi, tx); + if (size === undefined) { + return false; + } + return size + buffer <= MAX_TX_SIZE; +} + export function addTxOptimizations( umi: Umi, tx: TransactionBuilder, @@ -251,11 +299,13 @@ export function addTxOptimizations( const allOptimizations = tx.prepend(computePriceIx).prepend(computeLimitIx); const withCuPrice = tx.prepend(computePriceIx); const withCuLimit = tx.prepend(computeLimitIx); - if (allOptimizations.fitsInOneTransaction(umi)) { + + // Use actual serialization check instead of estimate + if (canSerializeTransaction(umi, allOptimizations)) { return prependTx(tx, [computePriceIx, computeLimitIx]); - } else if (withCuPrice.fitsInOneTransaction(umi)) { + } else if (canSerializeTransaction(umi, withCuPrice)) { return prependTx(tx, [computePriceIx]); - } else if (withCuLimit.fitsInOneTransaction(umi)) { + } else if (canSerializeTransaction(umi, withCuLimit)) { return prependTx(tx, [computeLimitIx]); } else { return tx; diff --git a/solauto-sdk/src/utils/solautoUtils.ts b/solauto-sdk/src/utils/solautoUtils.ts index 6703aeaf..651c5201 100644 --- a/solauto-sdk/src/utils/solautoUtils.ts +++ b/solauto-sdk/src/utils/solautoUtils.ts @@ -403,12 +403,12 @@ export class ContextUpdates { ...dca.automation, intervalSeconds: BigInt(dca.automation.intervalSeconds), unixStartDate: BigInt(dca.automation.unixStartDate), - padding: new Uint8Array([]), - padding1: [], + padding: new Uint8Array(32), + padding1: new Array(4).fill(0), }, dcaInBaseUnit: BigInt(dca.dcaInBaseUnit), tokenType: dca.tokenType, - padding: [], + padding: new Array(31).fill(0), }; } else if (update.type === "cancellingDca") { this.cancellingDca = update.value; From 058d42a6ce3f18387f138046e52a723e0813b196 Mon Sep 17 00:00:00 2001 From: cheliosooo Date: Fri, 1 May 2026 18:36:35 -0400 Subject: [PATCH 87/88] bump --- .gitignore | 1 + package.json | 1 + pnpm-lock.yaml | 463 ++++++++++-------- solauto-sdk/local/txSandbox.ts | 47 +- solauto-sdk/package.json | 2 +- .../services/transactions/transactionUtils.ts | 17 + solauto-sdk/src/utils/switchboardUtils.ts | 21 + 7 files changed, 343 insertions(+), 209 deletions(-) diff --git a/.gitignore b/.gitignore index 4e897b95..4ff41ab8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .DS_Store target **/node_modules/ +.pnpm-store .yarn .vscode dist diff --git a/package.json b/package.json index 4c03ec4e..0f73de93 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ }, "devDependencies": { "solauto-sdk": "file:solauto-sdk", + "ts-node": "^10.9.2", "typescript": "^4.9.5" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b2f2475b..8a845db2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,6 +27,9 @@ importers: solauto-sdk: specifier: file:solauto-sdk version: '@haven-fi/solauto-sdk@file:solauto-sdk(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)' + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@24.0.14)(typescript@4.9.5) typescript: specifier: ^4.9.5 version: 4.9.5 @@ -37,9 +40,6 @@ packages: resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} engines: {node: '>=6.9.0'} - '@brokerloop/ttlcache@3.2.3': - resolution: {integrity: sha512-kZWoyJGBYTv1cL5oHBYEixlJysJBf2RVnub3gbclD+dwaW9aKubbHzbZ9q1q6bONosxaOqMsoBorOrZKzBDiqg==} - '@common.js/quick-lru@7.0.0': resolution: {integrity: sha512-DO3vApnH1vLizdWRSqzhg+S956vptHhtO+vw6PP6StJGDtaAGyfKSSPPGYWguJZu/Jlti6l6m6jB8NrKEQexLg==} engines: {node: '>=18'} @@ -48,6 +48,10 @@ packages: resolution: {integrity: sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==} engines: {node: '>=10'} + '@coral-xyz/anchor-errors@0.31.1': + resolution: {integrity: sha512-NhNEku4F3zzUSBtrYz84FzYWm48+9OvmT1Hhnwr6GnPQry2dsEqH/ti/7ASjjpoFTWRnPXrjAIT1qM6Isop+LQ==} + engines: {node: '>=10'} + '@coral-xyz/anchor@0.29.0': resolution: {integrity: sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==} engines: {node: '>=11'} @@ -56,6 +60,10 @@ packages: resolution: {integrity: sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ==} engines: {node: '>=11'} + '@coral-xyz/anchor@0.31.1': + resolution: {integrity: sha512-QUqpoEK+gi2S6nlYc2atgT2r41TT3caWr/cPUEL8n8Md9437trZ68STknq897b82p5mW0XrTBNOzRbmIRJtfsA==} + engines: {node: '>=17'} + '@coral-xyz/borsh@0.29.0': resolution: {integrity: sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==} engines: {node: '>=10'} @@ -68,6 +76,16 @@ packages: peerDependencies: '@solana/web3.js': ^1.68.0 + '@coral-xyz/borsh@0.31.1': + resolution: {integrity: sha512-9N8AU9F0ubriKfNE3g1WF0/4dtlGXoBN/hd1PvbNBamBNwRgHxH4P+o3Zt7rSEloW1HUs6LfZEchlx9fW7POYw==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.69.0 + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + '@epic-web/invariant@1.0.0': resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} @@ -83,11 +101,25 @@ packages: '@haven-fi/solauto-sdk@file:solauto-sdk': resolution: {directory: solauto-sdk, type: directory} + '@isaacs/ttlcache@1.4.1': + resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} + engines: {node: '>=12'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} - '@jup-ag/api@6.0.24': - resolution: {integrity: sha512-zIX4WIPb0Kb2UnK2wNIOQBWqPJyMJq/D9dQTf/2qvPb0hfa8XdgbrQAzomHMHnAzw9StMQoybBk+JK/A76xP3w==} + '@jup-ag/api@6.0.44': + resolution: {integrity: sha512-C6oYi+wvNi07VlmWhT8+ZDMqTJuF+MiHuNBE65cYuBH6C4l0JfwpXaj6mKazAdVqVFWgngr3s2+0tdF5nDH4tA==} '@metaplex-foundation/kinobi@0.18.5': resolution: {integrity: sha512-qh4h4xGB+PHR5o4rcZki+wsIeZYi6R9SRV5UMqGi/rfDJXk0ckAZ+fxdam+mCc4N8HWLLWmEJbF5gx8E5K0fOA==} @@ -330,12 +362,6 @@ packages: resolution: {integrity: sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==} engines: {node: '>= 10'} - '@solana/spl-token@0.3.11': - resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.88.0 - '@solana/spl-token@0.4.13': resolution: {integrity: sha512-cite/pYWQZZVvLbg5lsodSovbetK/eA24gaR0eeUeMuBAMNrT8XFCwaygKy0N2WSg3gSyjjNpIeAGBAKZaY/1w==} engines: {node: '>=16'} @@ -355,58 +381,47 @@ packages: '@solana/web3.js@1.77.4': resolution: {integrity: sha512-XdN0Lh4jdY7J8FYMyucxCwzn6Ga2Sr1DHDWRbqVzk7ZPmmpSPOVWHzO67X1cVT+jNi1D6gZi2tgjHgDPuj6e9Q==} - '@solana/web3.js@1.95.8': - resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} - '@solana/web3.js@1.98.2': resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} - '@solworks/soltoolkit-sdk@0.0.23': - resolution: {integrity: sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w==} - - '@soncodi/signal@2.0.7': - resolution: {integrity: sha512-zA2oZluZmVvgZEDjF243KWD1S2J+1SH1MVynI0O1KRgDt1lU8nqk7AK3oQfW/WpwT51L5waGSU0xKF/9BTP5Cw==} - '@swc/helpers@0.5.17': resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - '@switchboard-xyz/common@2.5.19': - resolution: {integrity: sha512-Bzj1bu2U69YRh2OoNjkrafdREeB1KH+wmeFkBsASDjlhy/xXjey2Ry2HUTAIzdg2DMtfP6DoCW2Nn9ZQD5IO+Q==} - engines: {node: '>=12'} - - '@switchboard-xyz/common@3.0.12': - resolution: {integrity: sha512-SA+KEqM25rk+jYWVyiPrK3VaTajr38dPB1Hni+4AOCw7YUDNoM3JrTx8frZcj10ILzdHP3odAiUgxmulhZionQ==} - engines: {node: '>=20'} - '@switchboard-xyz/common@3.4.1': resolution: {integrity: sha512-TropBlBYuDeBnmGHkPSmgC3clLqAxy51ZGbwk4ejAgadnszWOgYHcH7taRG4Ha17DYSCWw/LGMBKbunGo+Aoaw==} engines: {node: '>=20'} - '@switchboard-xyz/on-demand@1.2.51': - resolution: {integrity: sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g==} - engines: {node: '>= 18'} - deprecated: deprecated in favor of 2.x.x + '@switchboard-xyz/common@4.1.11': + resolution: {integrity: sha512-zNclN+7Be28qL5dFlScL4qGCPAe/kLUQ7umNsT9+V9WC3jB3uUdYVlzsQzJc3WVYAGn0xc6gKJ0S/XW7NAxhzQ==} + engines: {node: '>=20'} '@switchboard-xyz/on-demand@1.2.67': resolution: {integrity: sha512-rtGA+9tQHb/xQnUFgVzyaOs2uKgnwP7OqYQLEOjTDdNTEEgU8OTR72ujluOEYB9LMByb7h9SRuOR353vxYQhYA==} engines: {node: '>= 18'} deprecated: deprecated in favor of 2.x.x - '@types/bn.js@5.2.0': - resolution: {integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==} + '@switchboard-xyz/on-demand@2.17.4': + resolution: {integrity: sha512-jZtnjcI58Leet2GCABoK0+snfi3Sg4Kn997MnsE0aMQFWCQ/zsy2oI81x7Nk+kvM+3Q5OEAG7JpAsN00BMlgQw==} + engines: {node: '>= 18'} + + '@tsconfig/node10@1.0.12': + resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - '@types/node-fetch@2.6.12': - resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} - '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@18.19.119': - resolution: {integrity: sha512-d0F6m9itIPaKnrvEMlzE48UjwZaAnFW7Jwibacw9MNdqadjKNpUm9tfJYDwmShJmgqcoqYUX3EMKO1+RWiuuNg==} - '@types/node@24.0.14': resolution: {integrity: sha512-4zXMWD91vBLGRtHK3YbIoFMia+1nqEz72coM42C5ETjnNCa/heoj7NT1G67iAfOqMmcfhuCZ4uNpyz8EjlAejw==} @@ -433,6 +448,15 @@ packages: a-sync-waterfall@1.0.1: resolution: {integrity: sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==} + acorn-walk@8.3.5: + resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} + engines: {node: '>=0.4.0'} + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + agentkeepalive@4.6.0: resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} engines: {node: '>= 8.0.0'} @@ -445,6 +469,9 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -565,8 +592,8 @@ packages: resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} engines: {node: '>= 6'} - cron-validator@1.4.0: - resolution: {integrity: sha512-wGcJ9FCy65iaU6egSH8b5dZYJF7GU/3Jh06wzaT9lsa5dbqExjljmu+0cJ8cpKn+vUyZa/EM4WAxeLR6SypJXw==} + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} cross-env@10.0.0: resolution: {integrity: sha512-aU8qlEK/nHYtVuN4p7UQgAwVljzMg8hB4YK5ThRqD2l/ziSnryncPNn7bMLt5cFYsKVKBh8HqLqyCoTupEUu7Q==} @@ -606,6 +633,10 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + diff@4.0.4: + resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} + engines: {node: '>=0.3.1'} + dot-case@3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} @@ -656,6 +687,10 @@ packages: eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + eyes@0.1.8: resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} engines: {node: '> 0.1.90'} @@ -741,6 +776,11 @@ packages: peerDependencies: ws: '*' + isomorphic-ws@5.0.0: + resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} + peerDependencies: + ws: '*' + jayson@4.2.0: resolution: {integrity: sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg==} engines: {node: '>=8'} @@ -769,15 +809,15 @@ packages: lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - long@5.3.2: resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + make-synchronized@0.4.2: resolution: {integrity: sha512-EwEJSg8gSGLicKXp/VzNi1tvzhdmNBxOzslkkJSoNUCQFZKH/NIUIp7xlfN+noaHrz4BJDN73gne8IHnjl/F/A==} @@ -921,6 +961,20 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -929,9 +983,6 @@ packages: engines: {node: '>=4.2.0'} hasBin: true - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - undici-types@7.8.0: resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} @@ -943,6 +994,9 @@ packages: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -999,6 +1053,10 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + zod@4.0.0-beta.20250505T195954: resolution: {integrity: sha512-iB8WvxkobVIXMARvQu20fKvbS7mUTiYRpcD8OQV1xjRhxO0EEpYIRJBk6yfBzHAHEdOSDh3SxDITr5Eajr2vtg==} @@ -1006,14 +1064,12 @@ snapshots: '@babel/runtime@7.27.6': {} - '@brokerloop/ttlcache@3.2.3': - dependencies: - '@soncodi/signal': 2.0.7 - '@common.js/quick-lru@7.0.0': {} '@coral-xyz/anchor-errors@0.30.1': {} + '@coral-xyz/anchor-errors@0.31.1': {} + '@coral-xyz/anchor@0.29.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) @@ -1036,12 +1092,12 @@ snapshots: - typescript - utf-8-validate - '@coral-xyz/anchor@0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@coral-xyz/anchor@0.30.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: '@coral-xyz/anchor-errors': 0.30.1 - '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) '@noble/hashes': 1.8.0 - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) bn.js: 5.2.2 bs58: 4.0.1 buffer-layout: 1.2.2 @@ -1056,17 +1112,33 @@ snapshots: transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate - '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))': + '@coral-xyz/anchor@0.31.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: + '@coral-xyz/anchor-errors': 0.31.1 + '@coral-xyz/borsh': 0.31.1(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) + '@noble/hashes': 1.8.0 '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) bn.js: 5.2.2 + bs58: 4.0.1 buffer-layout: 1.2.2 + camelcase: 6.3.0 + cross-fetch: 3.2.0 + eventemitter3: 4.0.7 + pako: 2.1.0 + superstruct: 0.15.5 + toml: 3.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate - '@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) bn.js: 5.2.2 buffer-layout: 1.2.2 @@ -1076,6 +1148,16 @@ snapshots: bn.js: 5.2.2 buffer-layout: 1.2.2 + '@coral-xyz/borsh@0.31.1(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))': + dependencies: + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + bn.js: 5.2.2 + buffer-layout: 1.2.2 + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + '@epic-web/invariant@1.0.0': {} '@grpc/grpc-js@1.13.4': @@ -1092,16 +1174,16 @@ snapshots: '@haven-fi/solauto-sdk@file:solauto-sdk(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@jup-ag/api': 6.0.24 + '@coral-xyz/anchor': 0.31.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@jup-ag/api': 6.0.44 '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-bundle-defaults': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@metaplex-foundation/umi-signer-wallet-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/spl-token': 0.4.13(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@switchboard-xyz/common': 3.0.12(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) - '@switchboard-xyz/on-demand': 1.2.51(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10) + '@metaplex-foundation/umi-bundle-defaults': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) + '@metaplex-foundation/umi-signer-wallet-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) + '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@switchboard-xyz/common': 3.4.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@switchboard-xyz/on-demand': 2.17.4(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) axios: 1.10.0 big.js: 6.2.2 bs58: 5.0.0 @@ -1116,9 +1198,20 @@ snapshots: - typescript - utf-8-validate + '@isaacs/ttlcache@1.4.1': {} + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + '@js-sdsl/ordered-map@4.4.2': {} - '@jup-ag/api@6.0.24': {} + '@jup-ag/api@6.0.44': {} '@metaplex-foundation/kinobi@0.18.5(fastestsmallesttextencoderdecoder@1.0.22)': dependencies: @@ -1133,18 +1226,18 @@ snapshots: - chokidar - fastestsmallesttextencoderdecoder - '@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metaplex-foundation/umi-bundle-defaults@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 '@metaplex-foundation/umi-downloader-http': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metaplex-foundation/umi-eddsa-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) '@metaplex-foundation/umi-http-fetch': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-program-repository': 0.9.2(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/umi-rpc-chunk-get-accounts': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metaplex-foundation/umi-rpc-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) '@metaplex-foundation/umi-serializer-data-view': 0.9.2(@metaplex-foundation/umi@0.9.2) - '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@metaplex-foundation/umi-transaction-factory-web3js': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) transitivePeerDependencies: - encoding @@ -1152,12 +1245,12 @@ snapshots: dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metaplex-foundation/umi-eddsa-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) '@noble/curves': 1.9.4 - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) '@metaplex-foundation/umi-http-fetch@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: @@ -1180,11 +1273,11 @@ snapshots: dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metaplex-foundation/umi-rpc-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) '@metaplex-foundation/umi-serializer-data-view@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: @@ -1208,22 +1301,22 @@ snapshots: '@metaplex-foundation/umi-serializers-encodings': 0.8.9 '@metaplex-foundation/umi-serializers-numbers': 0.8.9 - '@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metaplex-foundation/umi-signer-wallet-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) - '@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metaplex-foundation/umi-transaction-factory-web3js@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) - '@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) buffer: 6.0.3 '@metaplex-foundation/umi@0.9.2': @@ -1234,7 +1327,7 @@ snapshots: '@mrgnlabs/marginfi-client-v2@6.1.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) '@mrgnlabs/mrgn-common': 2.0.3(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) '@pythnetwork/pyth-solana-receiver': 0.8.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) @@ -1257,7 +1350,7 @@ snapshots: '@mrgnlabs/mrgn-common@2.0.3(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) '@solana/wallet-adapter-base': 0.9.27(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)) @@ -1446,18 +1539,18 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/spl-token-group@0.0.7(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': + '@solana/spl-token-group@0.0.7(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript - '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': + '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript @@ -1476,27 +1569,13 @@ snapshots: - typescript - utf-8-validate - '@solana/spl-token@0.3.11(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)': + '@solana/spl-token@0.4.13(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) - '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - buffer: 6.0.3 - transitivePeerDependencies: - - bufferutil - - encoding - - fastestsmallesttextencoderdecoder - - typescript - - utf-8-validate - - '@solana/spl-token@0.4.13(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)': - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) - '@solana/spl-token-group': 0.0.7(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/spl-token-group': 0.0.7(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -1540,28 +1619,6 @@ snapshots: - encoding - utf-8-validate - '@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)': - dependencies: - '@babel/runtime': 7.27.6 - '@noble/curves': 1.9.4 - '@noble/hashes': 1.8.0 - '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.6.0 - bigint-buffer: 1.1.5 - bn.js: 5.2.2 - borsh: 0.7.0 - bs58: 4.0.1 - buffer: 6.0.3 - fast-stable-stringify: 1.0.0 - jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - node-fetch: 2.7.0 - rpc-websockets: 9.1.1 - superstruct: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - '@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: '@babel/runtime': 7.27.6 @@ -1585,49 +1642,11 @@ snapshots: - typescript - utf-8-validate - '@solworks/soltoolkit-sdk@0.0.23(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10)': - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@types/bn.js': 5.2.0 - '@types/node': 18.19.119 - '@types/node-fetch': 2.6.12 - bn.js: 5.2.2 - decimal.js: 10.6.0 - typescript: 4.9.5 - transitivePeerDependencies: - - bufferutil - - encoding - - fastestsmallesttextencoderdecoder - - utf-8-validate - - '@soncodi/signal@2.0.7': {} - '@swc/helpers@0.5.17': dependencies: tslib: 2.8.1 - '@switchboard-xyz/common@2.5.19(bufferutil@4.0.9)(utf-8-validate@5.0.10)': - dependencies: - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - axios: 1.10.0 - big.js: 6.2.2 - bn.js: 5.2.2 - bs58: 6.0.0 - cron-validator: 1.4.0 - decimal.js: 10.6.0 - js-sha256: 0.11.1 - lodash: 4.17.21 - protobufjs: 7.5.3 - yaml: 2.8.0 - transitivePeerDependencies: - - bufferutil - - debug - - encoding - - utf-8-validate - - '@switchboard-xyz/common@3.0.12(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': + '@switchboard-xyz/common@3.4.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) axios: 1.10.0 @@ -1639,6 +1658,7 @@ snapshots: js-sha256: 0.11.1 protobufjs: 7.5.3 yaml: 2.8.0 + zod: 4.0.0-beta.20250505T195954 transitivePeerDependencies: - bufferutil - debug @@ -1646,7 +1666,7 @@ snapshots: - typescript - utf-8-validate - '@switchboard-xyz/common@3.4.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': + '@switchboard-xyz/common@4.1.11(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) axios: 1.10.0 @@ -1666,34 +1686,34 @@ snapshots: - typescript - utf-8-validate - '@switchboard-xyz/on-demand@1.2.51(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10)': + '@switchboard-xyz/on-demand@1.2.67(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@brokerloop/ttlcache': 3.2.3 - '@coral-xyz/anchor-30': '@coral-xyz/anchor@0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)' - '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@solworks/soltoolkit-sdk': 0.0.23(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10) - '@switchboard-xyz/common': 2.5.19(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@common.js/quick-lru': 7.0.0 + '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@switchboard-xyz/common': 3.4.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) axios: 1.10.0 - big.js: 6.2.2 - bs58: 5.0.0 + bs58: 6.0.0 + buffer: 6.0.3 js-yaml: 4.1.0 - protobufjs: 7.5.3 transitivePeerDependencies: - bufferutil - debug - encoding - - fastestsmallesttextencoderdecoder + - typescript - utf-8-validate - '@switchboard-xyz/on-demand@1.2.67(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': + '@switchboard-xyz/on-demand@2.17.4(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@common.js/quick-lru': 7.0.0 - '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@switchboard-xyz/common': 3.4.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@coral-xyz/anchor-31': '@coral-xyz/anchor@0.31.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)' + '@isaacs/ttlcache': 1.4.1 + '@switchboard-xyz/common': 4.1.11(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) axios: 1.10.0 bs58: 6.0.0 buffer: 6.0.3 + events: 3.3.0 + isomorphic-ws: 5.0.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) js-yaml: 4.1.0 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - debug @@ -1701,24 +1721,19 @@ snapshots: - typescript - utf-8-validate - '@types/bn.js@5.2.0': - dependencies: - '@types/node': 18.19.119 + '@tsconfig/node10@1.0.12': {} - '@types/connect@3.4.38': - dependencies: - '@types/node': 12.20.55 + '@tsconfig/node12@1.0.11': {} - '@types/node-fetch@2.6.12': - dependencies: - '@types/node': 18.19.119 - form-data: 4.0.4 + '@tsconfig/node14@1.0.3': {} - '@types/node@12.20.55': {} + '@tsconfig/node16@1.0.4': {} - '@types/node@18.19.119': + '@types/connect@3.4.38': dependencies: - undici-types: 5.26.5 + '@types/node': 24.0.14 + + '@types/node@12.20.55': {} '@types/node@24.0.14': dependencies: @@ -1728,7 +1743,7 @@ snapshots: '@types/ws@7.4.7': dependencies: - '@types/node': 12.20.55 + '@types/node': 24.0.14 '@types/ws@8.18.1': dependencies: @@ -1744,6 +1759,12 @@ snapshots: a-sync-waterfall@1.0.1: {} + acorn-walk@8.3.5: + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + agentkeepalive@4.6.0: dependencies: humanize-ms: 1.2.1 @@ -1754,6 +1775,8 @@ snapshots: dependencies: color-convert: 2.0.1 + arg@4.1.3: {} + argparse@2.0.1: {} asap@2.0.6: {} @@ -1874,7 +1897,7 @@ snapshots: commander@5.1.0: {} - cron-validator@1.4.0: {} + create-require@1.1.1: {} cross-env@10.0.0: dependencies: @@ -1915,6 +1938,8 @@ snapshots: delayed-stream@1.0.0: {} + diff@4.0.4: {} + dot-case@3.0.4: dependencies: no-case: 3.0.4 @@ -1959,6 +1984,8 @@ snapshots: eventemitter3@5.0.1: {} + events@3.3.0: {} + eyes@0.1.8: {} fast-stable-stringify@1.0.0: {} @@ -2033,6 +2060,10 @@ snapshots: dependencies: ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + isomorphic-ws@5.0.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + jayson@4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@types/connect': 3.4.38 @@ -2086,14 +2117,14 @@ snapshots: lodash.camelcase@4.3.0: {} - lodash@4.17.21: {} - long@5.3.2: {} lower-case@2.0.2: dependencies: tslib: 2.8.1 + make-error@1.3.6: {} + make-synchronized@0.4.2: {} math-intrinsics@1.1.0: {} @@ -2240,12 +2271,28 @@ snapshots: tr46@0.0.3: {} + ts-node@10.9.2(@types/node@24.0.14)(typescript@4.9.5): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.12 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 24.0.14 + acorn: 8.16.0 + acorn-walk: 8.3.5 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.4 + make-error: 1.3.6 + typescript: 4.9.5 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + tslib@2.8.1: {} typescript@4.9.5: {} - undici-types@5.26.5: {} - undici-types@7.8.0: {} utf-8-validate@5.0.10: @@ -2255,6 +2302,8 @@ snapshots: uuid@8.3.2: {} + v8-compile-cache-lib@3.0.1: {} + webidl-conversions@3.0.1: {} whatwg-url@5.0.0: @@ -2298,6 +2347,8 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yn@3.1.1: {} + zod@4.0.0-beta.20250505T195954: dependencies: '@zod/core': 0.11.6 diff --git a/solauto-sdk/local/txSandbox.ts b/solauto-sdk/local/txSandbox.ts index 97f43664..6d335371 100644 --- a/solauto-sdk/local/txSandbox.ts +++ b/solauto-sdk/local/txSandbox.ts @@ -1,7 +1,8 @@ import { Keypair, PublicKey } from "@solana/web3.js"; -import { createSignerFromKeypair, publicKey } from "@metaplex-foundation/umi"; +import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; import { fromWeb3JsKeypair } from "@metaplex-foundation/umi-web3js-adapters"; import { + buildSwbSubmitResponseTx, ClientTransactionsManager, consoleLog, fetchBank, @@ -10,6 +11,7 @@ import { getPositionExBulk, getSolanaRpcConnection, getSolautoManagedPositions, + JITO_SOL, LendingPlatform, LOCAL_IRONFORGE_API_URL, PriceType, @@ -18,6 +20,7 @@ import { rebalance, safeFetchBank, safeFetchMarginfiAccount, + sendSingleOptimizedTransaction, SOLAUTO_PROD_PROGRAM, SOLAUTO_TEST_PROGRAM, SolautoClient, @@ -115,5 +118,45 @@ async function refreshAll() { } } -main(); +async function testSwbOracleUpdate() { + (globalThis as any).SHOW_LOGS = true; + + let [conn, umiLocal] = getSolanaRpcConnection( + LOCAL_IRONFORGE_API_URL, + testProgram ? SOLAUTO_TEST_PROGRAM : SOLAUTO_PROD_PROGRAM, + lpEnv + ); + umiLocal = umiLocal.use(signerIdentity(signer)); + + const mint = new PublicKey(JITO_SOL); + console.log("Building SWB oracle update tx for JitoSOL..."); + + const result = await buildSwbSubmitResponseTx(conn, signer, mint); + if (!result) { + console.log("No oracle update needed"); + return; + } + + console.log("Instructions count:", result.tx.getInstructions().length); + console.log("Lookup tables:", result.lookupTableAddresses); + + console.log("Sending transaction..."); + const sig = await sendSingleOptimizedTransaction( + umiLocal, + conn, + result.tx, + payForTransaction ? "normal" : "only-simulate", + PriorityFeeSetting.Default + ); + + if (sig) { + const bs58 = await import("bs58"); + console.log("Transaction signature:", bs58.default.encode(sig)); + } else { + console.log("Transaction simulation complete (no sig returned)"); + } +} + +// main(); // refreshAll(); +testSwbOracleUpdate(); diff --git a/solauto-sdk/package.json b/solauto-sdk/package.json index 14f59d84..563e3e9b 100644 --- a/solauto-sdk/package.json +++ b/solauto-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@haven-fi/solauto-sdk", - "version": "1.0.819", + "version": "1.0.820", "main": "dist/index.js", "types": "dist/index.d.ts", "description": "Typescript SDK for the Solauto program on the Solana blockchain", diff --git a/solauto-sdk/src/services/transactions/transactionUtils.ts b/solauto-sdk/src/services/transactions/transactionUtils.ts index f0a6c484..c34be856 100644 --- a/solauto-sdk/src/services/transactions/transactionUtils.ts +++ b/solauto-sdk/src/services/transactions/transactionUtils.ts @@ -674,6 +674,23 @@ export function getErrorInfo( consoleLog("Error instruction index:", errIxIdx); consoleLog("Error code:", errCode); consoleLog("Error instruction program:", errIx?.programId.toString()); + if (errIx) { + consoleLog("Error ix data length:", errIx.data.length); + consoleLog("Error ix num keys:", errIx.keys.length); + consoleLog( + "Error ix data (first 64 bytes hex):", + Buffer.from(errIx.data.slice(0, 64)).toString("hex") + ); + } + consoleLog( + "All ixs in failing tx:", + txs[errTxIdx] + ?.getInstructions() + .map( + (ix, i) => + `[${i}] ${ix.programId.toString()} (data: ${ix.data.length}B, keys: ${ix.keys.length})` + ) + ); const solautoError = getSolautoErrorFromCode( errCode ?? -1, diff --git a/solauto-sdk/src/utils/switchboardUtils.ts b/solauto-sdk/src/utils/switchboardUtils.ts index d55be1b7..270f74ae 100644 --- a/solauto-sdk/src/utils/switchboardUtils.ts +++ b/solauto-sdk/src/utils/switchboardUtils.ts @@ -95,6 +95,27 @@ export async function buildSwbSubmitResponseTx( throw new Error("Unable to fetch SWB crank IX"); } + consoleLog("SWB pullIxs count:", pullIxs.length); + pullIxs.forEach((ix, i) => { + consoleLog(`SWB pullIx[${i}] programId: ${ix.programId.toString()}`); + consoleLog(`SWB pullIx[${i}] data length: ${ix.data.length}`); + consoleLog(`SWB pullIx[${i}] keys count: ${ix.keys.length}`); + if (ix.data.length > 0) { + consoleLog( + `SWB pullIx[${i}] data (first 128 bytes hex): ${Buffer.from(ix.data.slice(0, 128)).toString("hex")}` + ); + } + }); + consoleLog("SWB oracle responses:", responses.length); + consoleLog( + "SWB oracle response details:", + responses.map((r) => ({ + value: r.value?.toString(), + error: r.error, + oracle: r.oracle.pubkey.toString(), + })) + ); + consoleLog("Setting price locally..."); const price = (responses[0].value as Big).toNumber(); consoleLog(price); From 8e87c81d1cd584b6a5a72fef008f46b2680cd00c Mon Sep 17 00:00:00 2001 From: Rchie121 Date: Wed, 3 Jun 2026 14:08:18 -0400 Subject: [PATCH 88/88] Add copyright notice to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0346f7ce..1e35bb51 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Solauto - +All rights reserved @RichardPatterson ## Overview Solauto is a program on the Solana blockchain that lets you manage leveraged longs & shorts on auto-pilot to maximize your gains and eliminate the risk of liquidation.