Skip to content

Instantly share code, notes, and snippets.

@mgild
Created March 28, 2025 14:20
Show Gist options
  • Save mgild/53da1038b275d9d809c641af4ca3bfed to your computer and use it in GitHub Desktop.
Save mgild/53da1038b275d9d809c641af4ca3bfed to your computer and use it in GitHub Desktop.
pub async fn calc_from_calculator(
client: &RpcClient,
mut calc: KnownLstSolValCalc,
) -> Result<Decimal> {
let accounts = calc.get_accounts_to_update();
let account_datas: Vec<Account> = client
.get_multiple_accounts(&accounts.clone())
.await
.map_err(|_| anyhow!("Failed to get accounts"))?
.into_iter()
.flatten()
.collect::<Vec<_>>();
if accounts.len() != account_datas.len() {
return Err(anyhow!(
"Account data mismatch, failed to fetch all needed calc accounts"
));
}
let mut data_map = HashMap::new();
for i in 0..accounts.len() {
let key = &accounts[i];
data_map.insert(*key, to_account_info(key, &account_datas[i]));
}
calc.update(&data_map)
.map_err(|_| anyhow!("Failed to update calc"))?;
let range = calc
.lst_to_sol(LAMPORTS_PER_SOL)
.map_err(|_| anyhow!("Failed to calculate lst_to_sol"))?;
// Allow up to 1 for rounding
if range.get_max() - range.get_min() > 1 {
return Err(anyhow!("SanctumCalcError: Unexpected range"));
}
Ok(Decimal::from(range.get_max()) / Decimal::from(LAMPORTS_PER_SOL))
}
pub async fn calc_from_lst(client: &RpcClient, lst: Option<&SanctumLst>) -> Result<Decimal> {
let lst = lst.ok_or(anyhow!("SanctumLstNotFound"))?;
let calc;
if let SanctumSplMulti(SplPoolAccounts { pool, .. }) = lst.pool {
let epoch = get_epoch(client).await?;
calc = KnownLstSolValCalc::SanctumSplMulti(SanctumSplMultiLstSolValCalc::from_keys(
SplLstSolValCalcInitKeys {
lst_mint: lst.mint,
stake_pool_addr: pool,
},
epoch,
));
} else if let SanctumSpl(SplPoolAccounts { pool, .. }) = lst.pool {
let epoch = get_epoch(client).await?;
calc = KnownLstSolValCalc::SanctumSpl(SanctumSplLstSolValCalc::from_keys(
SplLstSolValCalcInitKeys {
lst_mint: lst.mint,
stake_pool_addr: pool,
},
epoch,
));
} else if let Spl(SplPoolAccounts { pool, .. }) = lst.pool {
let epoch = get_epoch(client).await?;
calc = KnownLstSolValCalc::Spl(SplLstSolValCalc::from_keys(
SplLstSolValCalcInitKeys {
lst_mint: lst.mint,
stake_pool_addr: pool,
},
epoch,
));
} else if let sanctum_lst_list::PoolInfo::Marinade = lst.pool {
calc = MarinadeLstSolValCalc::default().into();
} else if let sanctum_lst_list::PoolInfo::Lido = lst.pool {
calc = LidoLstSolValCalc {
shared_current_epoch: get_epoch(client).await?,
calc: None,
}
.into();
} else if let sanctum_lst_list::PoolInfo::ReservePool = lst.pool {
calc = WsolLstSolValCalc {}.into();
} else if let SPool(_) = lst.pool {
if lst.mint != *INF_MINT {
return Err(anyhow!("InvalidSpool"));
}
return spool_quote(client).await;
} else {
return Err(anyhow!("SanctumLstNotSpl"));
}
calc_from_calculator(client, calc).await
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment