@glamsystems/glam-sdk 0.1.28 → 0.1.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs.js CHANGED
@@ -34,7 +34,7 @@ var borsh__namespace = /*#__PURE__*/_interopNamespaceDefault(borsh);
34
34
  var address = "GLAMbTqav9N9witRjswJ8enwp9vv5G8bsSJ2kPJ4rcyc";
35
35
  var metadata = {
36
36
  name: "glam_protocol",
37
- version: "0.4.32",
37
+ version: "0.4.33",
38
38
  spec: "0.1.0",
39
39
  description: "Glam Protocol"
40
40
  };
@@ -7166,6 +7166,11 @@ var instructions = [
7166
7166
  },
7167
7167
  {
7168
7168
  name: "price_kamino_vault_shares",
7169
+ docs: [
7170
+ "Extra accounts for pricing N kamino vault shares:",
7171
+ "- (kvault_share_ata, kvault_share_mint, kvault_state, kvault_deposit_token_oracle) x N",
7172
+ "- (lending_market, reserve) x M, M = number of unique markets used by all kvaults involved"
7173
+ ],
7169
7174
  discriminator: [
7170
7175
  112,
7171
7176
  92,
@@ -7301,6 +7306,10 @@ var instructions = [
7301
7306
  name: "PriceDenom"
7302
7307
  }
7303
7308
  }
7309
+ },
7310
+ {
7311
+ name: "num_vaults",
7312
+ type: "u8"
7304
7313
  }
7305
7314
  ]
7306
7315
  },
@@ -7545,16 +7554,22 @@ var instructions = [
7545
7554
  ]
7546
7555
  },
7547
7556
  {
7548
- name: "price_vault",
7557
+ name: "price_vault_tokens",
7558
+ docs: [
7559
+ "Price vault SOL balance and tokens it holds.",
7560
+ "",
7561
+ "Extra accounts for pricing N tokens:",
7562
+ "- (ata, mint, oracle) x N"
7563
+ ],
7549
7564
  discriminator: [
7550
- 47,
7551
- 213,
7552
- 36,
7553
- 17,
7565
+ 54,
7566
+ 42,
7567
+ 16,
7568
+ 199,
7569
+ 20,
7554
7570
  183,
7555
- 5,
7556
- 141,
7557
- 45
7571
+ 50,
7572
+ 137
7558
7573
  ],
7559
7574
  accounts: [
7560
7575
  {
@@ -14561,6 +14576,7 @@ const KAMINO_LENDING_PROGRAM = new web3_js.PublicKey("KLend2g3cP87fffoy8q1mQqGKj
14561
14576
  const KAMINO_VAULTS_PROGRAM = new web3_js.PublicKey("KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd");
14562
14577
  const KAMINO_FARM_PROGRAM = new web3_js.PublicKey("FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr");
14563
14578
  const MEMO_PROGRAM = new web3_js.PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");
14579
+ const ALT_PROGRAM_ID = new web3_js.PublicKey("AddressLookupTab1e1111111111111111111111111");
14564
14580
  /**
14565
14581
  * Stake pools
14566
14582
  */ const JITO_STAKE_POOL = new web3_js.PublicKey("Jito4APyf642JPZPx3hGc6WWJ8zPKtRbRs4P815Awbb");
@@ -14969,12 +14985,6 @@ var ClusterNetwork = /*#__PURE__*/ function(ClusterNetwork) {
14969
14985
  return ClusterNetwork;
14970
14986
  }({});
14971
14987
 
14972
- const LOOKUP_TABLES_MAP = new Map([
14973
- [
14974
- "3tfbxaHBDjczQo3eyNJGGG64ChZ9nG4V3Gywa4k59d5a",
14975
- new web3_js.PublicKey("8HUXT9abWS2z3z92QyDzg51nMcc18LyWFvaEQZJMPixu")
14976
- ]
14977
- ]);
14978
14988
  const findStakeAccounts = async (connection, withdrawAuthority)=>{
14979
14989
  // stake authority offset: 12
14980
14990
  // withdraw authority offset: 44
@@ -15079,45 +15089,6 @@ const parseMeteoraPosition = async (connection, position)=>{
15079
15089
  binArrayUpper
15080
15090
  };
15081
15091
  };
15082
- async function fetchLookupTables(connection, authority, firstEntry) {
15083
- const ALT_PROGRAM_ID = new web3_js.PublicKey("AddressLookupTab1e1111111111111111111111111");
15084
- const tablePubkey = LOOKUP_TABLES_MAP.get(firstEntry.toBase58());
15085
- if (tablePubkey) {
15086
- const accountInfo = await connection.getAccountInfo(tablePubkey);
15087
- if (accountInfo) {
15088
- return [
15089
- new web3_js.AddressLookupTableAccount({
15090
- key: tablePubkey,
15091
- state: web3_js.AddressLookupTableAccount.deserialize(accountInfo.data)
15092
- })
15093
- ];
15094
- }
15095
- } else {
15096
- // Fetch all accounts owned by the ALT program
15097
- // This is currently disabled due to RPC error "Request deprioritized due to number of accounts requested. Slow down requests or add filters to narrow down results"
15098
- const accounts = await connection.getProgramAccounts(ALT_PROGRAM_ID, {
15099
- filters: [
15100
- {
15101
- memcmp: {
15102
- offset: 22,
15103
- bytes: authority.toBase58()
15104
- }
15105
- },
15106
- {
15107
- memcmp: {
15108
- offset: 56,
15109
- bytes: firstEntry.toBase58()
15110
- }
15111
- }
15112
- ]
15113
- });
15114
- return accounts.map(({ pubkey, account })=>new web3_js.AddressLookupTableAccount({
15115
- key: pubkey,
15116
- state: web3_js.AddressLookupTableAccount.deserialize(account.data)
15117
- }));
15118
- }
15119
- return [];
15120
- }
15121
15092
  /**
15122
15093
  * Parses program logs to extract error message
15123
15094
  */ function parseProgramLogs(logs) {
@@ -15227,6 +15198,15 @@ const STAKE_POOLS = sanctumLstList.LstList.filter((lst)=>!lst.name.includes("San
15227
15198
  poolState: new web3_js.PublicKey(poolState)
15228
15199
  };
15229
15200
  });
15201
+ STAKE_POOLS.push({
15202
+ name: "Phantom Staked SOL",
15203
+ symbol: "PSOL",
15204
+ mint: "pSo1f9nQXWgXibFtKf7NWYxb5enAM4qfP6UJSiXRQfL",
15205
+ decimals: 9,
15206
+ logoURI: "https://assets.phantom.app/assets/metadata/PSOL-512.png",
15207
+ tokenProgram: splToken.TOKEN_PROGRAM_ID,
15208
+ poolState: new web3_js.PublicKey("pSPcvR8GmG9aKDUbn9nbKYjkxt9hxMS7kF1qqKJaPqJ")
15209
+ });
15230
15210
  const STAKE_POOLS_MAP = new Map(STAKE_POOLS.map((p)=>[
15231
15211
  p.mint,
15232
15212
  p
@@ -15527,6 +15507,12 @@ const LOOKUP_TABLES = [
15527
15507
  new web3_js.PublicKey("D9cnvzswDikQDf53k4HpQ3KJ9y1Fv3HGGDFYMXnK5T6c"),
15528
15508
  new web3_js.PublicKey("EiWSskK5HXnBTptiS5DH6gpAJRVNQ3cAhTKBGaiaysAb")
15529
15509
  ];
15510
+ const STATES_LOOKUP_TABLES_MAP = new Map([
15511
+ [
15512
+ "3tfbxaHBDjczQo3eyNJGGG64ChZ9nG4V3Gywa4k59d5a",
15513
+ new web3_js.PublicKey("8HUXT9abWS2z3z92QyDzg51nMcc18LyWFvaEQZJMPixu")
15514
+ ]
15515
+ ]);
15530
15516
  const isBrowser = process.env.ANCHOR_BROWSER || typeof window !== "undefined" && !window.process?.hasOwnProperty("type");
15531
15517
  class BaseClient {
15532
15518
  get detectedCluster() {
@@ -15608,6 +15594,59 @@ class BaseClient {
15608
15594
  })
15609
15595
  ];
15610
15596
  }
15597
+ /**
15598
+ * Fetches lookup tables for the current GLAM instance
15599
+ */ async findLookupTables() {
15600
+ const glamApi = process.env.NEXT_PUBLIC_GLAM_API || process.env.GLAM_API;
15601
+ if (glamApi) {
15602
+ const response = await fetch(`${glamApi}/v0/lut/glam/?state=${this.statePda}`);
15603
+ const data = await response.json();
15604
+ const { t: lookupTables } = data;
15605
+ const pubkeys = Object.keys(lookupTables);
15606
+ if (pubkeys.length > 0) {
15607
+ return await this.fetchAdressLookupTableAccounts(pubkeys);
15608
+ }
15609
+ }
15610
+ const tablePubkey = STATES_LOOKUP_TABLES_MAP.get(this.statePda.toBase58());
15611
+ if (tablePubkey) {
15612
+ return await this.fetchAdressLookupTableAccounts([
15613
+ tablePubkey
15614
+ ]);
15615
+ }
15616
+ // Fetch all accounts owned by the ALT program
15617
+ // This is very likely to hit the RPC error "Request deprioritized due to number of accounts requested. Slow down requests or add filters to narrow down results"
15618
+ const accounts = await this.provider.connection.getProgramAccounts(ALT_PROGRAM_ID, {
15619
+ filters: [
15620
+ {
15621
+ memcmp: {
15622
+ offset: 0,
15623
+ bytes: bytes.bs58.encode([
15624
+ 1,
15625
+ 0,
15626
+ 0,
15627
+ 0
15628
+ ])
15629
+ }
15630
+ },
15631
+ {
15632
+ memcmp: {
15633
+ offset: 56,
15634
+ bytes: this.statePda.toBase58()
15635
+ }
15636
+ },
15637
+ {
15638
+ memcmp: {
15639
+ offset: 88,
15640
+ bytes: this.vaultPda.toBase58()
15641
+ }
15642
+ }
15643
+ ]
15644
+ });
15645
+ return accounts.map(({ pubkey, account })=>new web3_js.AddressLookupTableAccount({
15646
+ key: pubkey,
15647
+ state: web3_js.AddressLookupTableAccount.deserialize(account.data)
15648
+ }));
15649
+ }
15611
15650
  async intoVersionedTransaction(tx, { lookupTables = [], signer, computeUnitLimit, getPriorityFeeMicroLamports, maxFeeLamports, useMaxFee = false, jitoTipLamports, simulate = false }) {
15612
15651
  signer = signer || this.getSigner();
15613
15652
  const instructions = tx.instructions;
@@ -15619,15 +15658,26 @@ class BaseClient {
15619
15658
  lamports: jitoTipLamports
15620
15659
  }));
15621
15660
  }
15622
- lookupTables.push(...await this.getAdressLookupTableAccounts(LOOKUP_TABLES));
15661
+ const lookupTableAccounts = [];
15662
+ if (lookupTables.every((t)=>t instanceof web3_js.AddressLookupTableAccount)) {
15663
+ const accounts = await this.fetchAdressLookupTableAccounts([
15664
+ ...LOOKUP_TABLES
15665
+ ]);
15666
+ lookupTableAccounts.push(...lookupTables, ...accounts);
15667
+ } else {
15668
+ const accounts = await this.fetchAdressLookupTableAccounts([
15669
+ ...lookupTables,
15670
+ ...LOOKUP_TABLES
15671
+ ]);
15672
+ lookupTableAccounts.push(...accounts);
15673
+ }
15623
15674
  const recentBlockhash = (await this.blockhashWithCache.get()).blockhash;
15624
- const { unitsConsumed, error, serializedTx } = await getSimulationResult(this.provider.connection, instructions, signer, lookupTables);
15675
+ const { unitsConsumed, error, serializedTx } = await getSimulationResult(this.provider.connection, instructions, signer, lookupTableAccounts);
15625
15676
  computeUnitLimit = unitsConsumed;
15626
15677
  // by default, a simulation error doesn't prevent the tx from being sent
15627
15678
  // - gui: wallet apps usually do the simulation themselves, we should ignore the simulation error here by default
15628
15679
  // - cli: we should set simulate=true
15629
15680
  if (error && simulate) {
15630
- console.log("Lookup tables:", lookupTables.map((lt)=>lt.key.toString()));
15631
15681
  console.log("Tx (base64):", serializedTx);
15632
15682
  console.error("Simulation failed:", error.message);
15633
15683
  console.error("If error message is too obscure, inspect and simulate the tx in explorer: https://explorer.solana.com/tx/inspector");
@@ -15638,7 +15688,7 @@ class BaseClient {
15638
15688
  payerKey: signer,
15639
15689
  recentBlockhash,
15640
15690
  instructions
15641
- }).compileToV0Message(lookupTables));
15691
+ }).compileToV0Message(lookupTableAccounts));
15642
15692
  const cuIxs = await this.getComputeBudgetIxs(vTx, computeUnitLimit, getPriorityFeeMicroLamports, maxFeeLamports, useMaxFee);
15643
15693
  instructions.unshift(...cuIxs);
15644
15694
  }
@@ -15646,7 +15696,7 @@ class BaseClient {
15646
15696
  payerKey: signer,
15647
15697
  recentBlockhash,
15648
15698
  instructions
15649
- }).compileToV0Message(lookupTables));
15699
+ }).compileToV0Message(lookupTableAccounts));
15650
15700
  }
15651
15701
  async sendAndConfirm(tx, additionalSigners = []) {
15652
15702
  const connection = this.provider.connection;
@@ -15694,13 +15744,21 @@ class BaseClient {
15694
15744
  }
15695
15745
  return txSig;
15696
15746
  }
15697
- async getAdressLookupTableAccounts(keys) {
15698
- if (!keys) {
15747
+ /**
15748
+ * Fetches multiple address lookup table accounts.
15749
+ *
15750
+ * @param pubkeys Array of lookup table public keys.
15751
+ * @returns
15752
+ */ async fetchAdressLookupTableAccounts(pubkeys) {
15753
+ if (!pubkeys) {
15699
15754
  throw new Error("addressLookupTableAddresses is undefined");
15700
15755
  }
15701
- const addressLookupTableAccountInfos = await this.provider.connection.getMultipleAccountsInfo(keys.map((key)=>new web3_js.PublicKey(key)));
15756
+ if (pubkeys.length === 0) {
15757
+ return [];
15758
+ }
15759
+ const addressLookupTableAccountInfos = await this.provider.connection.getMultipleAccountsInfo(pubkeys.map((key)=>new web3_js.PublicKey(key)));
15702
15760
  return addressLookupTableAccountInfos.reduce((acc, accountInfo, index)=>{
15703
- const tableAddress = keys[index];
15761
+ const tableAddress = pubkeys[index];
15704
15762
  if (accountInfo) {
15705
15763
  const tableAccount = new web3_js.AddressLookupTableAccount({
15706
15764
  key: new web3_js.PublicKey(tableAddress),
@@ -17997,7 +18055,7 @@ class JupiterSwapClient {
17997
18055
  swapInstruction = swapInstructions.swapInstruction;
17998
18056
  addressLookupTableAddresses = swapInstructions.addressLookupTableAddresses;
17999
18057
  }
18000
- const lookupTables = await this.base.getAdressLookupTableAccounts(addressLookupTableAddresses);
18058
+ const lookupTables = addressLookupTableAddresses.map((pubkey)=>new web3_js.PublicKey(pubkey));
18001
18059
  const swapIx = this.toTransactionInstruction(swapInstruction, glamVault.toBase58());
18002
18060
  const [inputTokenProgram, outputTokenProgram] = (await this.base.fetchMintsAndTokenPrograms([
18003
18061
  inputMint,
@@ -19699,7 +19757,6 @@ const KVaultStateLayout = borsh.struct([
19699
19757
  borsh.array(borsh.u128(), 242, "padding3")
19700
19758
  ]);
19701
19759
 
19702
- const LOOKUP_TABLE = new web3_js.PublicKey("284iwGtA9X9aLy3KsyV8uT2pXLARhYbiSi5SiM2g47M2");
19703
19760
  const DEFAULT_OBLIGATION_ARGS = {
19704
19761
  tag: 0,
19705
19762
  id: 0
@@ -20344,13 +20401,7 @@ class KaminoLendingClient {
20344
20401
  reserveFarmState: depositReserve.farmCollateral,
20345
20402
  farmsProgram: KAMINO_FARM_PROGRAM
20346
20403
  }).preInstructions(preInstructions).postInstructions(postInstructions).transaction();
20347
- const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
20348
- LOOKUP_TABLE
20349
- ]);
20350
- const vTx = await this.base.intoVersionedTransaction(tx, {
20351
- ...txOptions,
20352
- lookupTables
20353
- });
20404
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20354
20405
  return vTx;
20355
20406
  }
20356
20407
  async withdrawTx(market, asset, amount, txOptions) {
@@ -20435,13 +20486,7 @@ class KaminoLendingClient {
20435
20486
  // - refreshObligationFarmsForReserve (if farm exists)
20436
20487
  const tx = new web3_js.Transaction();
20437
20488
  tx.add(...preInstructions, withdrawIx, ...postInstructions);
20438
- const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
20439
- LOOKUP_TABLE
20440
- ]);
20441
- const vTx = await this.base.intoVersionedTransaction(tx, {
20442
- ...txOptions,
20443
- lookupTables
20444
- });
20489
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20445
20490
  return vTx;
20446
20491
  }
20447
20492
  async borrowTx(market, asset, amount, txOptions) {
@@ -20523,13 +20568,7 @@ class KaminoLendingClient {
20523
20568
  // - borrowObligationLiquidityV2
20524
20569
  const tx = new web3_js.Transaction();
20525
20570
  tx.add(...preInstructions, borrowIx);
20526
- const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
20527
- LOOKUP_TABLE
20528
- ]);
20529
- const vTx = await this.base.intoVersionedTransaction(tx, {
20530
- ...txOptions,
20531
- lookupTables
20532
- });
20571
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20533
20572
  return vTx;
20534
20573
  }
20535
20574
  async repayTx(market, asset, amount, txOptions = {}) {
@@ -20596,13 +20635,7 @@ class KaminoLendingClient {
20596
20635
  // - repayObligationLiquidityV2
20597
20636
  const tx = new web3_js.Transaction();
20598
20637
  tx.add(...preInstructions, repayIx);
20599
- const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
20600
- LOOKUP_TABLE
20601
- ]);
20602
- const vTx = await this.base.intoVersionedTransaction(tx, {
20603
- ...txOptions,
20604
- lookupTables
20605
- });
20638
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20606
20639
  return vTx;
20607
20640
  }
20608
20641
  constructor(base){
@@ -20724,13 +20757,7 @@ class KaminoFarmClient {
20724
20757
  tx.add(createAtaIx, harvestIx);
20725
20758
  }
20726
20759
  }
20727
- const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
20728
- LOOKUP_TABLE
20729
- ]);
20730
- const vTx = await this.base.intoVersionedTransaction(tx, {
20731
- ...txOptions,
20732
- lookupTables
20733
- });
20760
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20734
20761
  return vTx;
20735
20762
  }
20736
20763
  constructor(base){
@@ -20796,9 +20823,10 @@ class KaminoVaultsClient {
20796
20823
  this.shareMintToVaultPdaMap.set(vaultState.sharesMint.toBase58(), vault);
20797
20824
  return vaultState;
20798
20825
  }
20799
- async composeRemainingAccounts(allocationStrategies) {
20800
- // For each allocation get reserve and market pubkeys
20801
- const reserves = allocationStrategies.map((strategy)=>strategy.reserve);
20826
+ async composeRemainingAccounts(allocationStrategies, pricingMode = false) {
20827
+ // Iterate over allocation strategies and get reserve pubkeys, using a Set to avoid dupes
20828
+ const reservesSet = new Set(allocationStrategies.map((strategy)=>strategy.reserve.toBase58()));
20829
+ const reserves = Array.from(reservesSet).map((p)=>new web3_js.PublicKey(p));
20802
20830
  const parsedReserves = await this.kaminoLending.fetchAndParseReserves(reserves);
20803
20831
  const reserveMetas = reserves.map((pubkey)=>({
20804
20832
  pubkey,
@@ -20810,15 +20838,21 @@ class KaminoVaultsClient {
20810
20838
  isSigner: false,
20811
20839
  isWritable: false
20812
20840
  }));
20841
+ if (pricingMode) {
20842
+ // (market, reserve) must be paired
20843
+ return marketMetas.reduce((acc, marketMeta, i)=>{
20844
+ acc.push(marketMeta, reserveMetas[i]);
20845
+ return acc;
20846
+ }, []);
20847
+ }
20813
20848
  return [
20814
20849
  ...reserveMetas,
20815
20850
  ...marketMetas
20816
- ];
20851
+ ]; // Non pricing mode
20817
20852
  }
20818
20853
  async depositTx(vault, amount, txOptions = {}) {
20819
20854
  const glamSigner = txOptions.signer || this.base.getSigner();
20820
20855
  const vaultState = await this.fetchAndParseVaultState(vault);
20821
- const amountBN = amount.mul(new anchor.BN(10).pow(vaultState.tokenMintDecimals));
20822
20856
  const { tokenProgram: sharesTokenProgram } = await this.base.fetchMintAndTokenProgram(vaultState.sharesMint);
20823
20857
  const userTokenAta = this.base.getVaultAta(vaultState.tokenMint, vaultState.tokenProgram);
20824
20858
  const userSharesAta = this.base.getVaultAta(vaultState.sharesMint, sharesTokenProgram);
@@ -20828,7 +20862,7 @@ class KaminoVaultsClient {
20828
20862
  ];
20829
20863
  // Remaining accounts, skip empty allocation strategies
20830
20864
  const remainingAccounts = await this.composeRemainingAccounts(vaultState.vaultAllocationStrategy.filter(({ reserve })=>!reserve.equals(web3_js.PublicKey.default)));
20831
- const tx = await this.base.program.methods.kaminoVaultsDeposit(amountBN).accounts({
20865
+ const tx = await this.base.program.methods.kaminoVaultsDeposit(amount).accounts({
20832
20866
  glamState: this.base.statePda,
20833
20867
  glamSigner,
20834
20868
  vaultState: vault,
@@ -20853,7 +20887,6 @@ class KaminoVaultsClient {
20853
20887
  const userTokenAta = this.base.getVaultAta(vaultState.tokenMint, vaultState.tokenProgram);
20854
20888
  const { tokenProgram: sharesTokenProgram } = await this.base.fetchMintAndTokenProgram(vaultState.sharesMint);
20855
20889
  const userSharesAta = this.base.getVaultAta(vaultState.sharesMint, sharesTokenProgram);
20856
- const amountBN = amount.mul(new anchor.BN(10).pow(vaultState.sharesMintDecimals));
20857
20890
  const reserves = vaultState.vaultAllocationStrategy.filter(({ reserve })=>!reserve.equals(web3_js.PublicKey.default));
20858
20891
  // Withdraw from the first reserve when kvault does not have enough liquidity
20859
20892
  const idx = 0;
@@ -20863,7 +20896,7 @@ class KaminoVaultsClient {
20863
20896
  const preInstructions = [
20864
20897
  splToken.createAssociatedTokenAccountIdempotentInstruction(glamSigner, userTokenAta, this.base.vaultPda, vaultState.tokenMint, vaultState.tokenProgram)
20865
20898
  ];
20866
- const tx = await this.base.program.methods.kaminoVaultsWithdraw(amountBN).accounts({
20899
+ const tx = await this.base.program.methods.kaminoVaultsWithdraw(amount).accounts({
20867
20900
  glamState: this.base.statePda,
20868
20901
  glamSigner,
20869
20902
  withdrawFromAvailableVaultState: vault,
@@ -21384,28 +21417,40 @@ class PriceClient {
21384
21417
  const shareAtas = [];
21385
21418
  const shareMints = [];
21386
21419
  const kvaultStates = [];
21420
+ const oracles = []; // oracle of kvault deposit token
21387
21421
  possibleShareAtaAccountsInfo.forEach((info, i)=>{
21388
21422
  if (info !== null) {
21389
21423
  shareAtas.push(possibleShareAtas[i]);
21390
21424
  shareMints.push(allKvaultMints[i]);
21391
21425
  kvaultStates.push(allKvaultStates[i]);
21426
+ const { tokenMint } = allKvaultStates[i];
21427
+ const assetMeta = ASSETS_MAINNET.get(tokenMint.toBase58());
21428
+ oracles.push(assetMeta?.oracle);
21392
21429
  }
21393
21430
  });
21394
21431
  const kvaultPdas = await this.kvaults.getVaultPdasByShareMints(shareMints);
21395
- const remainingAccounts = (await Promise.all(kvaultStates.map((kvault)=>{
21396
- return this.kvaults.composeRemainingAccounts(kvault.vaultAllocationStrategy.filter((alloc)=>!alloc.reserve.equals(web3_js.PublicKey.default)));
21397
- }))).flat();
21398
- [
21399
- ...kvaultPdas,
21400
- ...shareAtas
21401
- ].map((pubkey)=>{
21402
- remainingAccounts.unshift({
21403
- pubkey: pubkey,
21404
- isSigner: false,
21405
- isWritable: false
21432
+ const remainingAccounts = [];
21433
+ // first 3N remaining accounts are N tuples of (kvault_shares_ata, kvault_shares_mint, kvault_state)
21434
+ for(let i = 0; i < shareAtas.length; i++){
21435
+ [
21436
+ shareAtas[i],
21437
+ shareMints[i],
21438
+ kvaultPdas[i],
21439
+ oracles[i]
21440
+ ].map((pubkey)=>{
21441
+ remainingAccounts.push({
21442
+ pubkey,
21443
+ isSigner: false,
21444
+ isWritable: false
21445
+ });
21406
21446
  });
21407
- });
21408
- const priceIx = await this.base.program.methods.priceKaminoVaultShares(priceDenom).accounts({
21447
+ }
21448
+ // markets and reserves
21449
+ const marketsAndReserves = (await Promise.all(kvaultStates.map((kvault)=>{
21450
+ return this.kvaults.composeRemainingAccounts(kvault.vaultAllocationStrategy.filter((alloc)=>!alloc.reserve.equals(web3_js.PublicKey.default)), true);
21451
+ }))).flat();
21452
+ remainingAccounts.push(...marketsAndReserves);
21453
+ const priceIx = await this.base.program.methods.priceKaminoVaultShares(priceDenom, shareAtas.length).accounts({
21409
21454
  glamState: this.base.statePda,
21410
21455
  solOracle: SOL_ORACLE,
21411
21456
  pythOracle: null,
@@ -21527,7 +21572,7 @@ class PriceClient {
21527
21572
  * Returns an instruction that prices vault balance and tokens the vault holds
21528
21573
  */ async priceVaultIx(priceDenom) {
21529
21574
  const remainingAccounts = await this.remainingAccountsForPricingVaultAssets(priceDenom == PriceDenom.ASSET);
21530
- const priceVaultIx = await this.base.program.methods.priceVault(priceDenom).accounts({
21575
+ const priceVaultIx = await this.base.program.methods.priceVaultTokens(priceDenom).accounts({
21531
21576
  glamState: this.base.statePda,
21532
21577
  solOracle: SOL_ORACLE
21533
21578
  }).remainingAccounts(remainingAccounts).instruction();
@@ -21592,7 +21637,9 @@ class PriceClient {
21592
21637
  kaminoVaults: this.priceKaminoVaultSharesIx.bind(this)
21593
21638
  };
21594
21639
  const pricingFns = integrations.map((integration)=>integrationsToPricingFns[integration]).filter(Boolean);
21595
- const pricingIxs = [];
21640
+ const pricingIxs = [
21641
+ priceVaultIx
21642
+ ];
21596
21643
  for (const fn of pricingFns){
21597
21644
  const ix = await fn(priceDenom);
21598
21645
  pricingIxs.push(ix);
@@ -21957,6 +22004,7 @@ function getMarketOrderParams(params) {
21957
22004
  return Object.assign({}, DefaultOrderParams, optionalOrderParams, overridingParams);
21958
22005
  }
21959
22006
 
22007
+ exports.ALT_PROGRAM_ID = ALT_PROGRAM_ID;
21960
22008
  exports.ASSETS_MAINNET = ASSETS_MAINNET;
21961
22009
  exports.ASSETS_TESTS = ASSETS_TESTS;
21962
22010
  exports.AssetTier = AssetTier;
@@ -22064,7 +22112,6 @@ exports.VoteAuthorize = VoteAuthorize;
22064
22112
  exports.WSOL = WSOL;
22065
22113
  exports.ZERO = ZERO;
22066
22114
  exports.decodeUser = decodeUser;
22067
- exports.fetchLookupTables = fetchLookupTables;
22068
22115
  exports.fetchMeteoraPositions = fetchMeteoraPositions;
22069
22116
  exports.fetchProgramLabels = fetchProgramLabels;
22070
22117
  exports.fetchTokenPrices = fetchTokenPrices;
package/index.esm.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as anchor from '@coral-xyz/anchor';
2
2
  import { Program, BN } from '@coral-xyz/anchor';
3
- import { PublicKey, StakeProgram, AddressLookupTableAccount, ComputeBudgetProgram, VersionedTransaction, TransactionMessage, SystemProgram, Connection, Transaction, sendAndConfirmTransaction, LAMPORTS_PER_SOL, TransactionInstruction, SYSVAR_CLOCK_PUBKEY, Keypair, STAKE_CONFIG_ID, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_RENT_PUBKEY } from '@solana/web3.js';
4
- import { getExtensionData, ExtensionType, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID, getAssociatedTokenAddressSync, getAccount, TokenAccountNotFoundError, unpackMint, createAssociatedTokenAccountIdempotentInstruction, createSyncNativeInstruction, createTransferCheckedInstruction, unpackAccount, createCloseAccountInstruction } from '@solana/spl-token';
3
+ import { PublicKey, StakeProgram, ComputeBudgetProgram, VersionedTransaction, TransactionMessage, AddressLookupTableAccount, SystemProgram, Connection, Transaction, sendAndConfirmTransaction, LAMPORTS_PER_SOL, TransactionInstruction, SYSVAR_CLOCK_PUBKEY, Keypair, STAKE_CONFIG_ID, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_RENT_PUBKEY } from '@solana/web3.js';
4
+ import { getExtensionData, ExtensionType, TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, getAssociatedTokenAddressSync, getAccount, TokenAccountNotFoundError, unpackMint, createAssociatedTokenAccountIdempotentInstruction, createSyncNativeInstruction, createTransferCheckedInstruction, unpackAccount, createCloseAccountInstruction } from '@solana/spl-token';
5
5
  import { unpack } from '@solana/spl-token-metadata';
6
6
  import DLMM, { binIdToBinArrayIndex, deriveBinArray, Strategy } from '@meteora-ag/dlmm';
7
7
  import { LstList } from 'sanctum-lst-list';
@@ -14,7 +14,7 @@ import { getStakePoolAccount } from '@solana/spl-stake-pool';
14
14
  var address = "GLAMbTqav9N9witRjswJ8enwp9vv5G8bsSJ2kPJ4rcyc";
15
15
  var metadata = {
16
16
  name: "glam_protocol",
17
- version: "0.4.32",
17
+ version: "0.4.33",
18
18
  spec: "0.1.0",
19
19
  description: "Glam Protocol"
20
20
  };
@@ -7146,6 +7146,11 @@ var instructions = [
7146
7146
  },
7147
7147
  {
7148
7148
  name: "price_kamino_vault_shares",
7149
+ docs: [
7150
+ "Extra accounts for pricing N kamino vault shares:",
7151
+ "- (kvault_share_ata, kvault_share_mint, kvault_state, kvault_deposit_token_oracle) x N",
7152
+ "- (lending_market, reserve) x M, M = number of unique markets used by all kvaults involved"
7153
+ ],
7149
7154
  discriminator: [
7150
7155
  112,
7151
7156
  92,
@@ -7281,6 +7286,10 @@ var instructions = [
7281
7286
  name: "PriceDenom"
7282
7287
  }
7283
7288
  }
7289
+ },
7290
+ {
7291
+ name: "num_vaults",
7292
+ type: "u8"
7284
7293
  }
7285
7294
  ]
7286
7295
  },
@@ -7525,16 +7534,22 @@ var instructions = [
7525
7534
  ]
7526
7535
  },
7527
7536
  {
7528
- name: "price_vault",
7537
+ name: "price_vault_tokens",
7538
+ docs: [
7539
+ "Price vault SOL balance and tokens it holds.",
7540
+ "",
7541
+ "Extra accounts for pricing N tokens:",
7542
+ "- (ata, mint, oracle) x N"
7543
+ ],
7529
7544
  discriminator: [
7530
- 47,
7531
- 213,
7532
- 36,
7533
- 17,
7545
+ 54,
7546
+ 42,
7547
+ 16,
7548
+ 199,
7549
+ 20,
7534
7550
  183,
7535
- 5,
7536
- 141,
7537
- 45
7551
+ 50,
7552
+ 137
7538
7553
  ],
7539
7554
  accounts: [
7540
7555
  {
@@ -14541,6 +14556,7 @@ const KAMINO_LENDING_PROGRAM = new PublicKey("KLend2g3cP87fffoy8q1mQqGKjrxjC8boS
14541
14556
  const KAMINO_VAULTS_PROGRAM = new PublicKey("KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd");
14542
14557
  const KAMINO_FARM_PROGRAM = new PublicKey("FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr");
14543
14558
  const MEMO_PROGRAM = new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");
14559
+ const ALT_PROGRAM_ID = new PublicKey("AddressLookupTab1e1111111111111111111111111");
14544
14560
  /**
14545
14561
  * Stake pools
14546
14562
  */ const JITO_STAKE_POOL = new PublicKey("Jito4APyf642JPZPx3hGc6WWJ8zPKtRbRs4P815Awbb");
@@ -14949,12 +14965,6 @@ var ClusterNetwork = /*#__PURE__*/ function(ClusterNetwork) {
14949
14965
  return ClusterNetwork;
14950
14966
  }({});
14951
14967
 
14952
- const LOOKUP_TABLES_MAP = new Map([
14953
- [
14954
- "3tfbxaHBDjczQo3eyNJGGG64ChZ9nG4V3Gywa4k59d5a",
14955
- new PublicKey("8HUXT9abWS2z3z92QyDzg51nMcc18LyWFvaEQZJMPixu")
14956
- ]
14957
- ]);
14958
14968
  const findStakeAccounts = async (connection, withdrawAuthority)=>{
14959
14969
  // stake authority offset: 12
14960
14970
  // withdraw authority offset: 44
@@ -15059,45 +15069,6 @@ const parseMeteoraPosition = async (connection, position)=>{
15059
15069
  binArrayUpper
15060
15070
  };
15061
15071
  };
15062
- async function fetchLookupTables(connection, authority, firstEntry) {
15063
- const ALT_PROGRAM_ID = new PublicKey("AddressLookupTab1e1111111111111111111111111");
15064
- const tablePubkey = LOOKUP_TABLES_MAP.get(firstEntry.toBase58());
15065
- if (tablePubkey) {
15066
- const accountInfo = await connection.getAccountInfo(tablePubkey);
15067
- if (accountInfo) {
15068
- return [
15069
- new AddressLookupTableAccount({
15070
- key: tablePubkey,
15071
- state: AddressLookupTableAccount.deserialize(accountInfo.data)
15072
- })
15073
- ];
15074
- }
15075
- } else {
15076
- // Fetch all accounts owned by the ALT program
15077
- // This is currently disabled due to RPC error "Request deprioritized due to number of accounts requested. Slow down requests or add filters to narrow down results"
15078
- const accounts = await connection.getProgramAccounts(ALT_PROGRAM_ID, {
15079
- filters: [
15080
- {
15081
- memcmp: {
15082
- offset: 22,
15083
- bytes: authority.toBase58()
15084
- }
15085
- },
15086
- {
15087
- memcmp: {
15088
- offset: 56,
15089
- bytes: firstEntry.toBase58()
15090
- }
15091
- }
15092
- ]
15093
- });
15094
- return accounts.map(({ pubkey, account })=>new AddressLookupTableAccount({
15095
- key: pubkey,
15096
- state: AddressLookupTableAccount.deserialize(account.data)
15097
- }));
15098
- }
15099
- return [];
15100
- }
15101
15072
  /**
15102
15073
  * Parses program logs to extract error message
15103
15074
  */ function parseProgramLogs(logs) {
@@ -15207,6 +15178,15 @@ const STAKE_POOLS = LstList.filter((lst)=>!lst.name.includes("Sanctum Automated"
15207
15178
  poolState: new PublicKey(poolState)
15208
15179
  };
15209
15180
  });
15181
+ STAKE_POOLS.push({
15182
+ name: "Phantom Staked SOL",
15183
+ symbol: "PSOL",
15184
+ mint: "pSo1f9nQXWgXibFtKf7NWYxb5enAM4qfP6UJSiXRQfL",
15185
+ decimals: 9,
15186
+ logoURI: "https://assets.phantom.app/assets/metadata/PSOL-512.png",
15187
+ tokenProgram: TOKEN_PROGRAM_ID,
15188
+ poolState: new PublicKey("pSPcvR8GmG9aKDUbn9nbKYjkxt9hxMS7kF1qqKJaPqJ")
15189
+ });
15210
15190
  const STAKE_POOLS_MAP = new Map(STAKE_POOLS.map((p)=>[
15211
15191
  p.mint,
15212
15192
  p
@@ -15507,6 +15487,12 @@ const LOOKUP_TABLES = [
15507
15487
  new PublicKey("D9cnvzswDikQDf53k4HpQ3KJ9y1Fv3HGGDFYMXnK5T6c"),
15508
15488
  new PublicKey("EiWSskK5HXnBTptiS5DH6gpAJRVNQ3cAhTKBGaiaysAb")
15509
15489
  ];
15490
+ const STATES_LOOKUP_TABLES_MAP = new Map([
15491
+ [
15492
+ "3tfbxaHBDjczQo3eyNJGGG64ChZ9nG4V3Gywa4k59d5a",
15493
+ new PublicKey("8HUXT9abWS2z3z92QyDzg51nMcc18LyWFvaEQZJMPixu")
15494
+ ]
15495
+ ]);
15510
15496
  const isBrowser = process.env.ANCHOR_BROWSER || typeof window !== "undefined" && !window.process?.hasOwnProperty("type");
15511
15497
  class BaseClient {
15512
15498
  get detectedCluster() {
@@ -15588,6 +15574,59 @@ class BaseClient {
15588
15574
  })
15589
15575
  ];
15590
15576
  }
15577
+ /**
15578
+ * Fetches lookup tables for the current GLAM instance
15579
+ */ async findLookupTables() {
15580
+ const glamApi = process.env.NEXT_PUBLIC_GLAM_API || process.env.GLAM_API;
15581
+ if (glamApi) {
15582
+ const response = await fetch(`${glamApi}/v0/lut/glam/?state=${this.statePda}`);
15583
+ const data = await response.json();
15584
+ const { t: lookupTables } = data;
15585
+ const pubkeys = Object.keys(lookupTables);
15586
+ if (pubkeys.length > 0) {
15587
+ return await this.fetchAdressLookupTableAccounts(pubkeys);
15588
+ }
15589
+ }
15590
+ const tablePubkey = STATES_LOOKUP_TABLES_MAP.get(this.statePda.toBase58());
15591
+ if (tablePubkey) {
15592
+ return await this.fetchAdressLookupTableAccounts([
15593
+ tablePubkey
15594
+ ]);
15595
+ }
15596
+ // Fetch all accounts owned by the ALT program
15597
+ // This is very likely to hit the RPC error "Request deprioritized due to number of accounts requested. Slow down requests or add filters to narrow down results"
15598
+ const accounts = await this.provider.connection.getProgramAccounts(ALT_PROGRAM_ID, {
15599
+ filters: [
15600
+ {
15601
+ memcmp: {
15602
+ offset: 0,
15603
+ bytes: bs58.encode([
15604
+ 1,
15605
+ 0,
15606
+ 0,
15607
+ 0
15608
+ ])
15609
+ }
15610
+ },
15611
+ {
15612
+ memcmp: {
15613
+ offset: 56,
15614
+ bytes: this.statePda.toBase58()
15615
+ }
15616
+ },
15617
+ {
15618
+ memcmp: {
15619
+ offset: 88,
15620
+ bytes: this.vaultPda.toBase58()
15621
+ }
15622
+ }
15623
+ ]
15624
+ });
15625
+ return accounts.map(({ pubkey, account })=>new AddressLookupTableAccount({
15626
+ key: pubkey,
15627
+ state: AddressLookupTableAccount.deserialize(account.data)
15628
+ }));
15629
+ }
15591
15630
  async intoVersionedTransaction(tx, { lookupTables = [], signer, computeUnitLimit, getPriorityFeeMicroLamports, maxFeeLamports, useMaxFee = false, jitoTipLamports, simulate = false }) {
15592
15631
  signer = signer || this.getSigner();
15593
15632
  const instructions = tx.instructions;
@@ -15599,15 +15638,26 @@ class BaseClient {
15599
15638
  lamports: jitoTipLamports
15600
15639
  }));
15601
15640
  }
15602
- lookupTables.push(...await this.getAdressLookupTableAccounts(LOOKUP_TABLES));
15641
+ const lookupTableAccounts = [];
15642
+ if (lookupTables.every((t)=>t instanceof AddressLookupTableAccount)) {
15643
+ const accounts = await this.fetchAdressLookupTableAccounts([
15644
+ ...LOOKUP_TABLES
15645
+ ]);
15646
+ lookupTableAccounts.push(...lookupTables, ...accounts);
15647
+ } else {
15648
+ const accounts = await this.fetchAdressLookupTableAccounts([
15649
+ ...lookupTables,
15650
+ ...LOOKUP_TABLES
15651
+ ]);
15652
+ lookupTableAccounts.push(...accounts);
15653
+ }
15603
15654
  const recentBlockhash = (await this.blockhashWithCache.get()).blockhash;
15604
- const { unitsConsumed, error, serializedTx } = await getSimulationResult(this.provider.connection, instructions, signer, lookupTables);
15655
+ const { unitsConsumed, error, serializedTx } = await getSimulationResult(this.provider.connection, instructions, signer, lookupTableAccounts);
15605
15656
  computeUnitLimit = unitsConsumed;
15606
15657
  // by default, a simulation error doesn't prevent the tx from being sent
15607
15658
  // - gui: wallet apps usually do the simulation themselves, we should ignore the simulation error here by default
15608
15659
  // - cli: we should set simulate=true
15609
15660
  if (error && simulate) {
15610
- console.log("Lookup tables:", lookupTables.map((lt)=>lt.key.toString()));
15611
15661
  console.log("Tx (base64):", serializedTx);
15612
15662
  console.error("Simulation failed:", error.message);
15613
15663
  console.error("If error message is too obscure, inspect and simulate the tx in explorer: https://explorer.solana.com/tx/inspector");
@@ -15618,7 +15668,7 @@ class BaseClient {
15618
15668
  payerKey: signer,
15619
15669
  recentBlockhash,
15620
15670
  instructions
15621
- }).compileToV0Message(lookupTables));
15671
+ }).compileToV0Message(lookupTableAccounts));
15622
15672
  const cuIxs = await this.getComputeBudgetIxs(vTx, computeUnitLimit, getPriorityFeeMicroLamports, maxFeeLamports, useMaxFee);
15623
15673
  instructions.unshift(...cuIxs);
15624
15674
  }
@@ -15626,7 +15676,7 @@ class BaseClient {
15626
15676
  payerKey: signer,
15627
15677
  recentBlockhash,
15628
15678
  instructions
15629
- }).compileToV0Message(lookupTables));
15679
+ }).compileToV0Message(lookupTableAccounts));
15630
15680
  }
15631
15681
  async sendAndConfirm(tx, additionalSigners = []) {
15632
15682
  const connection = this.provider.connection;
@@ -15674,13 +15724,21 @@ class BaseClient {
15674
15724
  }
15675
15725
  return txSig;
15676
15726
  }
15677
- async getAdressLookupTableAccounts(keys) {
15678
- if (!keys) {
15727
+ /**
15728
+ * Fetches multiple address lookup table accounts.
15729
+ *
15730
+ * @param pubkeys Array of lookup table public keys.
15731
+ * @returns
15732
+ */ async fetchAdressLookupTableAccounts(pubkeys) {
15733
+ if (!pubkeys) {
15679
15734
  throw new Error("addressLookupTableAddresses is undefined");
15680
15735
  }
15681
- const addressLookupTableAccountInfos = await this.provider.connection.getMultipleAccountsInfo(keys.map((key)=>new PublicKey(key)));
15736
+ if (pubkeys.length === 0) {
15737
+ return [];
15738
+ }
15739
+ const addressLookupTableAccountInfos = await this.provider.connection.getMultipleAccountsInfo(pubkeys.map((key)=>new PublicKey(key)));
15682
15740
  return addressLookupTableAccountInfos.reduce((acc, accountInfo, index)=>{
15683
- const tableAddress = keys[index];
15741
+ const tableAddress = pubkeys[index];
15684
15742
  if (accountInfo) {
15685
15743
  const tableAccount = new AddressLookupTableAccount({
15686
15744
  key: new PublicKey(tableAddress),
@@ -17977,7 +18035,7 @@ class JupiterSwapClient {
17977
18035
  swapInstruction = swapInstructions.swapInstruction;
17978
18036
  addressLookupTableAddresses = swapInstructions.addressLookupTableAddresses;
17979
18037
  }
17980
- const lookupTables = await this.base.getAdressLookupTableAccounts(addressLookupTableAddresses);
18038
+ const lookupTables = addressLookupTableAddresses.map((pubkey)=>new PublicKey(pubkey));
17981
18039
  const swapIx = this.toTransactionInstruction(swapInstruction, glamVault.toBase58());
17982
18040
  const [inputTokenProgram, outputTokenProgram] = (await this.base.fetchMintsAndTokenPrograms([
17983
18041
  inputMint,
@@ -19679,7 +19737,6 @@ const KVaultStateLayout = struct([
19679
19737
  array(u128(), 242, "padding3")
19680
19738
  ]);
19681
19739
 
19682
- const LOOKUP_TABLE = new PublicKey("284iwGtA9X9aLy3KsyV8uT2pXLARhYbiSi5SiM2g47M2");
19683
19740
  const DEFAULT_OBLIGATION_ARGS = {
19684
19741
  tag: 0,
19685
19742
  id: 0
@@ -20324,13 +20381,7 @@ class KaminoLendingClient {
20324
20381
  reserveFarmState: depositReserve.farmCollateral,
20325
20382
  farmsProgram: KAMINO_FARM_PROGRAM
20326
20383
  }).preInstructions(preInstructions).postInstructions(postInstructions).transaction();
20327
- const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
20328
- LOOKUP_TABLE
20329
- ]);
20330
- const vTx = await this.base.intoVersionedTransaction(tx, {
20331
- ...txOptions,
20332
- lookupTables
20333
- });
20384
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20334
20385
  return vTx;
20335
20386
  }
20336
20387
  async withdrawTx(market, asset, amount, txOptions) {
@@ -20415,13 +20466,7 @@ class KaminoLendingClient {
20415
20466
  // - refreshObligationFarmsForReserve (if farm exists)
20416
20467
  const tx = new Transaction();
20417
20468
  tx.add(...preInstructions, withdrawIx, ...postInstructions);
20418
- const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
20419
- LOOKUP_TABLE
20420
- ]);
20421
- const vTx = await this.base.intoVersionedTransaction(tx, {
20422
- ...txOptions,
20423
- lookupTables
20424
- });
20469
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20425
20470
  return vTx;
20426
20471
  }
20427
20472
  async borrowTx(market, asset, amount, txOptions) {
@@ -20503,13 +20548,7 @@ class KaminoLendingClient {
20503
20548
  // - borrowObligationLiquidityV2
20504
20549
  const tx = new Transaction();
20505
20550
  tx.add(...preInstructions, borrowIx);
20506
- const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
20507
- LOOKUP_TABLE
20508
- ]);
20509
- const vTx = await this.base.intoVersionedTransaction(tx, {
20510
- ...txOptions,
20511
- lookupTables
20512
- });
20551
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20513
20552
  return vTx;
20514
20553
  }
20515
20554
  async repayTx(market, asset, amount, txOptions = {}) {
@@ -20576,13 +20615,7 @@ class KaminoLendingClient {
20576
20615
  // - repayObligationLiquidityV2
20577
20616
  const tx = new Transaction();
20578
20617
  tx.add(...preInstructions, repayIx);
20579
- const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
20580
- LOOKUP_TABLE
20581
- ]);
20582
- const vTx = await this.base.intoVersionedTransaction(tx, {
20583
- ...txOptions,
20584
- lookupTables
20585
- });
20618
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20586
20619
  return vTx;
20587
20620
  }
20588
20621
  constructor(base){
@@ -20704,13 +20737,7 @@ class KaminoFarmClient {
20704
20737
  tx.add(createAtaIx, harvestIx);
20705
20738
  }
20706
20739
  }
20707
- const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
20708
- LOOKUP_TABLE
20709
- ]);
20710
- const vTx = await this.base.intoVersionedTransaction(tx, {
20711
- ...txOptions,
20712
- lookupTables
20713
- });
20740
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20714
20741
  return vTx;
20715
20742
  }
20716
20743
  constructor(base){
@@ -20776,9 +20803,10 @@ class KaminoVaultsClient {
20776
20803
  this.shareMintToVaultPdaMap.set(vaultState.sharesMint.toBase58(), vault);
20777
20804
  return vaultState;
20778
20805
  }
20779
- async composeRemainingAccounts(allocationStrategies) {
20780
- // For each allocation get reserve and market pubkeys
20781
- const reserves = allocationStrategies.map((strategy)=>strategy.reserve);
20806
+ async composeRemainingAccounts(allocationStrategies, pricingMode = false) {
20807
+ // Iterate over allocation strategies and get reserve pubkeys, using a Set to avoid dupes
20808
+ const reservesSet = new Set(allocationStrategies.map((strategy)=>strategy.reserve.toBase58()));
20809
+ const reserves = Array.from(reservesSet).map((p)=>new PublicKey(p));
20782
20810
  const parsedReserves = await this.kaminoLending.fetchAndParseReserves(reserves);
20783
20811
  const reserveMetas = reserves.map((pubkey)=>({
20784
20812
  pubkey,
@@ -20790,15 +20818,21 @@ class KaminoVaultsClient {
20790
20818
  isSigner: false,
20791
20819
  isWritable: false
20792
20820
  }));
20821
+ if (pricingMode) {
20822
+ // (market, reserve) must be paired
20823
+ return marketMetas.reduce((acc, marketMeta, i)=>{
20824
+ acc.push(marketMeta, reserveMetas[i]);
20825
+ return acc;
20826
+ }, []);
20827
+ }
20793
20828
  return [
20794
20829
  ...reserveMetas,
20795
20830
  ...marketMetas
20796
- ];
20831
+ ]; // Non pricing mode
20797
20832
  }
20798
20833
  async depositTx(vault, amount, txOptions = {}) {
20799
20834
  const glamSigner = txOptions.signer || this.base.getSigner();
20800
20835
  const vaultState = await this.fetchAndParseVaultState(vault);
20801
- const amountBN = amount.mul(new BN(10).pow(vaultState.tokenMintDecimals));
20802
20836
  const { tokenProgram: sharesTokenProgram } = await this.base.fetchMintAndTokenProgram(vaultState.sharesMint);
20803
20837
  const userTokenAta = this.base.getVaultAta(vaultState.tokenMint, vaultState.tokenProgram);
20804
20838
  const userSharesAta = this.base.getVaultAta(vaultState.sharesMint, sharesTokenProgram);
@@ -20808,7 +20842,7 @@ class KaminoVaultsClient {
20808
20842
  ];
20809
20843
  // Remaining accounts, skip empty allocation strategies
20810
20844
  const remainingAccounts = await this.composeRemainingAccounts(vaultState.vaultAllocationStrategy.filter(({ reserve })=>!reserve.equals(PublicKey.default)));
20811
- const tx = await this.base.program.methods.kaminoVaultsDeposit(amountBN).accounts({
20845
+ const tx = await this.base.program.methods.kaminoVaultsDeposit(amount).accounts({
20812
20846
  glamState: this.base.statePda,
20813
20847
  glamSigner,
20814
20848
  vaultState: vault,
@@ -20833,7 +20867,6 @@ class KaminoVaultsClient {
20833
20867
  const userTokenAta = this.base.getVaultAta(vaultState.tokenMint, vaultState.tokenProgram);
20834
20868
  const { tokenProgram: sharesTokenProgram } = await this.base.fetchMintAndTokenProgram(vaultState.sharesMint);
20835
20869
  const userSharesAta = this.base.getVaultAta(vaultState.sharesMint, sharesTokenProgram);
20836
- const amountBN = amount.mul(new BN(10).pow(vaultState.sharesMintDecimals));
20837
20870
  const reserves = vaultState.vaultAllocationStrategy.filter(({ reserve })=>!reserve.equals(PublicKey.default));
20838
20871
  // Withdraw from the first reserve when kvault does not have enough liquidity
20839
20872
  const idx = 0;
@@ -20843,7 +20876,7 @@ class KaminoVaultsClient {
20843
20876
  const preInstructions = [
20844
20877
  createAssociatedTokenAccountIdempotentInstruction(glamSigner, userTokenAta, this.base.vaultPda, vaultState.tokenMint, vaultState.tokenProgram)
20845
20878
  ];
20846
- const tx = await this.base.program.methods.kaminoVaultsWithdraw(amountBN).accounts({
20879
+ const tx = await this.base.program.methods.kaminoVaultsWithdraw(amount).accounts({
20847
20880
  glamState: this.base.statePda,
20848
20881
  glamSigner,
20849
20882
  withdrawFromAvailableVaultState: vault,
@@ -21364,28 +21397,40 @@ class PriceClient {
21364
21397
  const shareAtas = [];
21365
21398
  const shareMints = [];
21366
21399
  const kvaultStates = [];
21400
+ const oracles = []; // oracle of kvault deposit token
21367
21401
  possibleShareAtaAccountsInfo.forEach((info, i)=>{
21368
21402
  if (info !== null) {
21369
21403
  shareAtas.push(possibleShareAtas[i]);
21370
21404
  shareMints.push(allKvaultMints[i]);
21371
21405
  kvaultStates.push(allKvaultStates[i]);
21406
+ const { tokenMint } = allKvaultStates[i];
21407
+ const assetMeta = ASSETS_MAINNET.get(tokenMint.toBase58());
21408
+ oracles.push(assetMeta?.oracle);
21372
21409
  }
21373
21410
  });
21374
21411
  const kvaultPdas = await this.kvaults.getVaultPdasByShareMints(shareMints);
21375
- const remainingAccounts = (await Promise.all(kvaultStates.map((kvault)=>{
21376
- return this.kvaults.composeRemainingAccounts(kvault.vaultAllocationStrategy.filter((alloc)=>!alloc.reserve.equals(PublicKey.default)));
21377
- }))).flat();
21378
- [
21379
- ...kvaultPdas,
21380
- ...shareAtas
21381
- ].map((pubkey)=>{
21382
- remainingAccounts.unshift({
21383
- pubkey: pubkey,
21384
- isSigner: false,
21385
- isWritable: false
21412
+ const remainingAccounts = [];
21413
+ // first 3N remaining accounts are N tuples of (kvault_shares_ata, kvault_shares_mint, kvault_state)
21414
+ for(let i = 0; i < shareAtas.length; i++){
21415
+ [
21416
+ shareAtas[i],
21417
+ shareMints[i],
21418
+ kvaultPdas[i],
21419
+ oracles[i]
21420
+ ].map((pubkey)=>{
21421
+ remainingAccounts.push({
21422
+ pubkey,
21423
+ isSigner: false,
21424
+ isWritable: false
21425
+ });
21386
21426
  });
21387
- });
21388
- const priceIx = await this.base.program.methods.priceKaminoVaultShares(priceDenom).accounts({
21427
+ }
21428
+ // markets and reserves
21429
+ const marketsAndReserves = (await Promise.all(kvaultStates.map((kvault)=>{
21430
+ return this.kvaults.composeRemainingAccounts(kvault.vaultAllocationStrategy.filter((alloc)=>!alloc.reserve.equals(PublicKey.default)), true);
21431
+ }))).flat();
21432
+ remainingAccounts.push(...marketsAndReserves);
21433
+ const priceIx = await this.base.program.methods.priceKaminoVaultShares(priceDenom, shareAtas.length).accounts({
21389
21434
  glamState: this.base.statePda,
21390
21435
  solOracle: SOL_ORACLE,
21391
21436
  pythOracle: null,
@@ -21507,7 +21552,7 @@ class PriceClient {
21507
21552
  * Returns an instruction that prices vault balance and tokens the vault holds
21508
21553
  */ async priceVaultIx(priceDenom) {
21509
21554
  const remainingAccounts = await this.remainingAccountsForPricingVaultAssets(priceDenom == PriceDenom.ASSET);
21510
- const priceVaultIx = await this.base.program.methods.priceVault(priceDenom).accounts({
21555
+ const priceVaultIx = await this.base.program.methods.priceVaultTokens(priceDenom).accounts({
21511
21556
  glamState: this.base.statePda,
21512
21557
  solOracle: SOL_ORACLE
21513
21558
  }).remainingAccounts(remainingAccounts).instruction();
@@ -21572,7 +21617,9 @@ class PriceClient {
21572
21617
  kaminoVaults: this.priceKaminoVaultSharesIx.bind(this)
21573
21618
  };
21574
21619
  const pricingFns = integrations.map((integration)=>integrationsToPricingFns[integration]).filter(Boolean);
21575
- const pricingIxs = [];
21620
+ const pricingIxs = [
21621
+ priceVaultIx
21622
+ ];
21576
21623
  for (const fn of pricingFns){
21577
21624
  const ix = await fn(priceDenom);
21578
21625
  pricingIxs.push(ix);
@@ -21937,4 +21984,4 @@ function getMarketOrderParams(params) {
21937
21984
  return Object.assign({}, DefaultOrderParams, optionalOrderParams, overridingParams);
21938
21985
  }
21939
21986
 
21940
- export { ASSETS_MAINNET, ASSETS_TESTS, AssetTier, BaseClient, ClusterNetwork, CompanyModel, ContractTier, ContractType, CreatedModel, DRIFT_PROGRAM_ID, DRIFT_VAULTS_PROGRAM_ID, DRIFT_VAULT_DEPOSITOR_SIZE, DefaultOrderParams, DelegateAcl, DepositDirection, DepositExplanation, DriftClient, DriftVaultsClient, ExchangeStatus, FuelOverflowStatus, FundOpenfundsModel, GLAM_REFERRER, GOVERNANCE_PROGRAM_ID, GlamClient, GlamError, GlamIdl, GlamIntegrations, GlamPermissions, GlamProtocolIdlJson, InsuranceFundOperation, JITO_STAKE_POOL, JITO_TIP_DEFAULT, JUP, JUPITER_API_DEFAULT, JUPITER_PROGRAM_ID, JUPSOL_STAKE_POOL, JUP_VOTE_PROGRAM, JupiterSwapClient, JupiterVoteClient, KAMINO_FARM_PROGRAM, KAMINO_LENDING_PROGRAM, KAMINO_OBTRIGATION_SIZE, KAMINO_SCOPE_PRICES, KAMINO_VAULTS_PROGRAM, LPAction, LiquidationType, MARINADE_NATIVE_STAKE_AUTHORITY, MARINADE_PROGRAM_ID, MEMO_PROGRAM, MERKLE_DISTRIBUTOR_PROGRAM, METEORA_DLMM_PROGRAM, METEORA_POSITION_SIZE, MSOL, ManagerModel, MarginMode, MarketStatus, MarketType, Metadata, MintIdlModel, MintModel, MintOpenfundsModel, ModifyOrderPolicy, OracleSource, OracleSourceNum, OrderAction, OrderActionExplanation, OrderStatus, OrderTriggerCondition, OrderType, PerpOperation, PlaceAndTakeOrderSuccessCondition, PositionDirection, PostOnlyParams, PriceDenom, ReferrerStatus, SANCTUM_STAKE_POOL_PROGRAM_ID, SEED_ESCROW, SEED_METADATA, SEED_MINT, SEED_STATE, SEED_VAULT, SOL_ORACLE, STAKE_ACCOUNT_SIZE, STAKE_POOLS, STAKE_POOLS_MAP, SettlePnlExplanation, SettlePnlMode, SpotBalanceType, SpotFulfillmentConfigStatus, SpotFulfillmentStatus, SpotFulfillmentType, SpotOperation, StakeAction, StateIdlModel, StateModel, SwapDirection, SwapReduceOnly, TRANSFER_HOOK_PROGRAM, TimeUnit, TradeSide, USDC, USDC_ORACLE, UserStatus, VoteAuthorize, WSOL, ZERO, decodeUser, fetchLookupTables, fetchMeteoraPositions, fetchProgramLabels, fetchTokenPrices, fetchTokensList, findStakeAccounts, getAccountPolicyPda, getEscrowPda, getExtraMetasPda, getGlamProgram, getGlamProgramId, getLimitOrderParams, getMarketOrderParams, getMintPda, getOpenfundsPda, getOrderParams, getPriorityFeeEstimate, getSimulationResult, getStakeAccountsWithStates, getStatePda, getTriggerLimitOrderParams, getTriggerMarketOrderParams, getVariant, getVaultPda, isBrowser, isOneOfVariant, isVariant, parseMeteoraPosition, parseProgramLogs, setsAreEqual };
21987
+ export { ALT_PROGRAM_ID, ASSETS_MAINNET, ASSETS_TESTS, AssetTier, BaseClient, ClusterNetwork, CompanyModel, ContractTier, ContractType, CreatedModel, DRIFT_PROGRAM_ID, DRIFT_VAULTS_PROGRAM_ID, DRIFT_VAULT_DEPOSITOR_SIZE, DefaultOrderParams, DelegateAcl, DepositDirection, DepositExplanation, DriftClient, DriftVaultsClient, ExchangeStatus, FuelOverflowStatus, FundOpenfundsModel, GLAM_REFERRER, GOVERNANCE_PROGRAM_ID, GlamClient, GlamError, GlamIdl, GlamIntegrations, GlamPermissions, GlamProtocolIdlJson, InsuranceFundOperation, JITO_STAKE_POOL, JITO_TIP_DEFAULT, JUP, JUPITER_API_DEFAULT, JUPITER_PROGRAM_ID, JUPSOL_STAKE_POOL, JUP_VOTE_PROGRAM, JupiterSwapClient, JupiterVoteClient, KAMINO_FARM_PROGRAM, KAMINO_LENDING_PROGRAM, KAMINO_OBTRIGATION_SIZE, KAMINO_SCOPE_PRICES, KAMINO_VAULTS_PROGRAM, LPAction, LiquidationType, MARINADE_NATIVE_STAKE_AUTHORITY, MARINADE_PROGRAM_ID, MEMO_PROGRAM, MERKLE_DISTRIBUTOR_PROGRAM, METEORA_DLMM_PROGRAM, METEORA_POSITION_SIZE, MSOL, ManagerModel, MarginMode, MarketStatus, MarketType, Metadata, MintIdlModel, MintModel, MintOpenfundsModel, ModifyOrderPolicy, OracleSource, OracleSourceNum, OrderAction, OrderActionExplanation, OrderStatus, OrderTriggerCondition, OrderType, PerpOperation, PlaceAndTakeOrderSuccessCondition, PositionDirection, PostOnlyParams, PriceDenom, ReferrerStatus, SANCTUM_STAKE_POOL_PROGRAM_ID, SEED_ESCROW, SEED_METADATA, SEED_MINT, SEED_STATE, SEED_VAULT, SOL_ORACLE, STAKE_ACCOUNT_SIZE, STAKE_POOLS, STAKE_POOLS_MAP, SettlePnlExplanation, SettlePnlMode, SpotBalanceType, SpotFulfillmentConfigStatus, SpotFulfillmentStatus, SpotFulfillmentType, SpotOperation, StakeAction, StateIdlModel, StateModel, SwapDirection, SwapReduceOnly, TRANSFER_HOOK_PROGRAM, TimeUnit, TradeSide, USDC, USDC_ORACLE, UserStatus, VoteAuthorize, WSOL, ZERO, decodeUser, fetchMeteoraPositions, fetchProgramLabels, fetchTokenPrices, fetchTokensList, findStakeAccounts, getAccountPolicyPda, getEscrowPda, getExtraMetasPda, getGlamProgram, getGlamProgramId, getLimitOrderParams, getMarketOrderParams, getMintPda, getOpenfundsPda, getOrderParams, getPriorityFeeEstimate, getSimulationResult, getStakeAccountsWithStates, getStatePda, getTriggerLimitOrderParams, getTriggerMarketOrderParams, getVariant, getVaultPda, isBrowser, isOneOfVariant, isVariant, parseMeteoraPosition, parseProgramLogs, setsAreEqual };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glamsystems/glam-sdk",
3
- "version": "0.1.28",
3
+ "version": "0.1.29",
4
4
  "description": "TypeScript SDK for the GLAM Protocol",
5
5
  "main": "./index.cjs.js",
6
6
  "module": "./index.esm.js",
@@ -17,7 +17,7 @@ export type TxOptions = {
17
17
  useMaxFee?: boolean;
18
18
  jitoTipLamports?: number;
19
19
  preInstructions?: TransactionInstruction[];
20
- lookupTables?: AddressLookupTableAccount[];
20
+ lookupTables?: PublicKey[] | AddressLookupTableAccount[];
21
21
  simulate?: boolean;
22
22
  };
23
23
  export type TokenAccount = {
@@ -50,9 +50,19 @@ export declare class BaseClient {
50
50
  */
51
51
  getAssetMeta(assetMint: string): AssetMeta;
52
52
  private getComputeBudgetIxs;
53
+ /**
54
+ * Fetches lookup tables for the current GLAM instance
55
+ */
56
+ findLookupTables(): Promise<AddressLookupTableAccount[]>;
53
57
  intoVersionedTransaction(tx: Transaction, { lookupTables, signer, computeUnitLimit, getPriorityFeeMicroLamports, maxFeeLamports, useMaxFee, jitoTipLamports, simulate, }: TxOptions): Promise<VersionedTransaction>;
54
58
  sendAndConfirm(tx: VersionedTransaction | Transaction, additionalSigners?: Keypair[]): Promise<TransactionSignature>;
55
- getAdressLookupTableAccounts(keys?: string[] | PublicKey[]): Promise<AddressLookupTableAccount[]>;
59
+ /**
60
+ * Fetches multiple address lookup table accounts.
61
+ *
62
+ * @param pubkeys Array of lookup table public keys.
63
+ * @returns
64
+ */
65
+ fetchAdressLookupTableAccounts(pubkeys?: string[] | PublicKey[]): Promise<AddressLookupTableAccount[]>;
56
66
  getWallet(): Wallet;
57
67
  getSigner(): PublicKey;
58
68
  get signer(): PublicKey;
@@ -146,7 +146,7 @@ export declare class KaminoVaultsClient {
146
146
  findAndParseKaminoVaults(): Promise<KVaultState[]>;
147
147
  getVaultPdasByShareMints(mints: PublicKey[]): Promise<PublicKey[]>;
148
148
  fetchAndParseVaultState(vault: PublicKey): Promise<KVaultState>;
149
- composeRemainingAccounts(allocationStrategies: KVaultAllocation[]): Promise<AccountMeta[]>;
149
+ composeRemainingAccounts(allocationStrategies: KVaultAllocation[], pricingMode?: boolean): Promise<AccountMeta[]>;
150
150
  depositTx(vault: PublicKey, amount: BN, txOptions?: TxOptions): Promise<VersionedTransaction>;
151
151
  withdrawTx(vault: PublicKey, amount: BN, txOptions?: TxOptions): Promise<VersionedTransaction>;
152
152
  }
@@ -38,6 +38,7 @@ export declare const KAMINO_LENDING_PROGRAM: PublicKey;
38
38
  export declare const KAMINO_VAULTS_PROGRAM: PublicKey;
39
39
  export declare const KAMINO_FARM_PROGRAM: PublicKey;
40
40
  export declare const MEMO_PROGRAM: PublicKey;
41
+ export declare const ALT_PROGRAM_ID: PublicKey;
41
42
  /**
42
43
  * Stake pools
43
44
  */
@@ -22,7 +22,6 @@ interface GlamProviderContext {
22
22
  prices: TokenPrice[];
23
23
  jupTokenList?: TokenListItem[];
24
24
  driftMarketConfigs: DriftMarketConfigs;
25
- driftUser: DriftUser;
26
25
  setActiveGlamState: (f: GlamStateCache) => void;
27
26
  refresh: () => Promise<void>;
28
27
  refetchGlamStates: () => Promise<void>;
@@ -15,7 +15,6 @@ export declare const parseMeteoraPosition: (connection: Connection, position: Pu
15
15
  binArrayLower: PublicKey;
16
16
  binArrayUpper: PublicKey;
17
17
  }>;
18
- export declare function fetchLookupTables(connection: Connection, authority: PublicKey, firstEntry: PublicKey): Promise<AddressLookupTableAccount[]>;
19
18
  /**
20
19
  * Parses program logs to extract error message
21
20
  */
@@ -2,7 +2,7 @@
2
2
  "address": "GLAMbTqav9N9witRjswJ8enwp9vv5G8bsSJ2kPJ4rcyc",
3
3
  "metadata": {
4
4
  "name": "glam_protocol",
5
- "version": "0.4.32",
5
+ "version": "0.4.33",
6
6
  "spec": "0.1.0",
7
7
  "description": "Glam Protocol"
8
8
  },
@@ -7134,6 +7134,11 @@
7134
7134
  },
7135
7135
  {
7136
7136
  "name": "price_kamino_vault_shares",
7137
+ "docs": [
7138
+ "Extra accounts for pricing N kamino vault shares:",
7139
+ "- (kvault_share_ata, kvault_share_mint, kvault_state, kvault_deposit_token_oracle) x N",
7140
+ "- (lending_market, reserve) x M, M = number of unique markets used by all kvaults involved"
7141
+ ],
7137
7142
  "discriminator": [
7138
7143
  112,
7139
7144
  92,
@@ -7269,6 +7274,10 @@
7269
7274
  "name": "PriceDenom"
7270
7275
  }
7271
7276
  }
7277
+ },
7278
+ {
7279
+ "name": "num_vaults",
7280
+ "type": "u8"
7272
7281
  }
7273
7282
  ]
7274
7283
  },
@@ -7513,16 +7522,22 @@
7513
7522
  ]
7514
7523
  },
7515
7524
  {
7516
- "name": "price_vault",
7525
+ "name": "price_vault_tokens",
7526
+ "docs": [
7527
+ "Price vault SOL balance and tokens it holds.",
7528
+ "",
7529
+ "Extra accounts for pricing N tokens:",
7530
+ "- (ata, mint, oracle) x N"
7531
+ ],
7517
7532
  "discriminator": [
7518
- 47,
7519
- 213,
7520
- 36,
7521
- 17,
7533
+ 54,
7534
+ 42,
7535
+ 16,
7536
+ 199,
7537
+ 20,
7522
7538
  183,
7523
- 5,
7524
- 141,
7525
- 45
7539
+ 50,
7540
+ 137
7526
7541
  ],
7527
7542
  "accounts": [
7528
7543
  {
@@ -8,7 +8,7 @@ export type GlamProtocol = {
8
8
  "address": "GLAMbTqav9N9witRjswJ8enwp9vv5G8bsSJ2kPJ4rcyc";
9
9
  "metadata": {
10
10
  "name": "glamProtocol";
11
- "version": "0.4.32";
11
+ "version": "0.4.33";
12
12
  "spec": "0.1.0";
13
13
  "description": "Glam Protocol";
14
14
  };
@@ -7140,6 +7140,11 @@ export type GlamProtocol = {
7140
7140
  },
7141
7141
  {
7142
7142
  "name": "priceKaminoVaultShares";
7143
+ "docs": [
7144
+ "Extra accounts for pricing N kamino vault shares:",
7145
+ "- (kvault_share_ata, kvault_share_mint, kvault_state, kvault_deposit_token_oracle) x N",
7146
+ "- (lending_market, reserve) x M, M = number of unique markets used by all kvaults involved"
7147
+ ];
7143
7148
  "discriminator": [
7144
7149
  112,
7145
7150
  92,
@@ -7275,6 +7280,10 @@ export type GlamProtocol = {
7275
7280
  "name": "priceDenom";
7276
7281
  };
7277
7282
  };
7283
+ },
7284
+ {
7285
+ "name": "numVaults";
7286
+ "type": "u8";
7278
7287
  }
7279
7288
  ];
7280
7289
  },
@@ -7519,16 +7528,22 @@ export type GlamProtocol = {
7519
7528
  ];
7520
7529
  },
7521
7530
  {
7522
- "name": "priceVault";
7531
+ "name": "priceVaultTokens";
7532
+ "docs": [
7533
+ "Price vault SOL balance and tokens it holds.",
7534
+ "",
7535
+ "Extra accounts for pricing N tokens:",
7536
+ "- (ata, mint, oracle) x N"
7537
+ ];
7523
7538
  "discriminator": [
7524
- 47,
7525
- 213,
7526
- 36,
7527
- 17,
7539
+ 54,
7540
+ 42,
7541
+ 16,
7542
+ 199,
7543
+ 20,
7528
7544
  183,
7529
- 5,
7530
- 141,
7531
- 45
7545
+ 50,
7546
+ 137
7532
7547
  ];
7533
7548
  "accounts": [
7534
7549
  {
@@ -8,7 +8,7 @@ export type GlamProtocol = {
8
8
  "address": "GLAMbTqav9N9witRjswJ8enwp9vv5G8bsSJ2kPJ4rcyc",
9
9
  "metadata": {
10
10
  "name": "glamProtocol",
11
- "version": "0.4.32",
11
+ "version": "0.4.33",
12
12
  "spec": "0.1.0",
13
13
  "description": "Glam Protocol"
14
14
  },
@@ -7140,6 +7140,11 @@ export type GlamProtocol = {
7140
7140
  },
7141
7141
  {
7142
7142
  "name": "priceKaminoVaultShares",
7143
+ "docs": [
7144
+ "Extra accounts for pricing N kamino vault shares:",
7145
+ "- (kvault_share_ata, kvault_share_mint, kvault_state, kvault_deposit_token_oracle) x N",
7146
+ "- (lending_market, reserve) x M, M = number of unique markets used by all kvaults involved"
7147
+ ],
7143
7148
  "discriminator": [
7144
7149
  112,
7145
7150
  92,
@@ -7275,6 +7280,10 @@ export type GlamProtocol = {
7275
7280
  "name": "priceDenom"
7276
7281
  }
7277
7282
  }
7283
+ },
7284
+ {
7285
+ "name": "numVaults",
7286
+ "type": "u8"
7278
7287
  }
7279
7288
  ]
7280
7289
  },
@@ -7519,16 +7528,22 @@ export type GlamProtocol = {
7519
7528
  ]
7520
7529
  },
7521
7530
  {
7522
- "name": "priceVault",
7531
+ "name": "priceVaultTokens",
7532
+ "docs": [
7533
+ "Price vault SOL balance and tokens it holds.",
7534
+ "",
7535
+ "Extra accounts for pricing N tokens:",
7536
+ "- (ata, mint, oracle) x N"
7537
+ ],
7523
7538
  "discriminator": [
7524
- 47,
7525
- 213,
7526
- 36,
7527
- 17,
7539
+ 54,
7540
+ 42,
7541
+ 16,
7542
+ 199,
7543
+ 20,
7528
7544
  183,
7529
- 5,
7530
- 141,
7531
- 45
7545
+ 50,
7546
+ 137
7532
7547
  ],
7533
7548
  "accounts": [
7534
7549
  {