@glamsystems/glam-sdk 0.1.26 → 0.1.27

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.28",
37
+ version: "0.4.29",
38
38
  spec: "0.1.0",
39
39
  description: "Glam Protocol"
40
40
  };
@@ -4284,10 +4284,12 @@ var instructions = [
4284
4284
  ],
4285
4285
  accounts: [
4286
4286
  {
4287
- name: "glam_state"
4287
+ name: "glam_state",
4288
+ writable: true
4288
4289
  },
4289
4290
  {
4290
4291
  name: "glam_vault",
4292
+ writable: true,
4291
4293
  pda: {
4292
4294
  seeds: [
4293
4295
  {
@@ -4379,10 +4381,12 @@ var instructions = [
4379
4381
  ],
4380
4382
  accounts: [
4381
4383
  {
4382
- name: "glam_state"
4384
+ name: "glam_state",
4385
+ writable: true
4383
4386
  },
4384
4387
  {
4385
4388
  name: "glam_vault",
4389
+ writable: true,
4386
4390
  pda: {
4387
4391
  seeds: [
4388
4392
  {
@@ -6662,6 +6666,146 @@ var instructions = [
6662
6666
  }
6663
6667
  ]
6664
6668
  },
6669
+ {
6670
+ name: "price_kamino_vault_shares",
6671
+ discriminator: [
6672
+ 112,
6673
+ 92,
6674
+ 238,
6675
+ 224,
6676
+ 145,
6677
+ 105,
6678
+ 38,
6679
+ 249
6680
+ ],
6681
+ accounts: [
6682
+ {
6683
+ name: "glam_state",
6684
+ writable: true
6685
+ },
6686
+ {
6687
+ name: "glam_vault",
6688
+ pda: {
6689
+ seeds: [
6690
+ {
6691
+ kind: "const",
6692
+ value: [
6693
+ 118,
6694
+ 97,
6695
+ 117,
6696
+ 108,
6697
+ 116
6698
+ ]
6699
+ },
6700
+ {
6701
+ kind: "account",
6702
+ path: "glam_state"
6703
+ }
6704
+ ]
6705
+ }
6706
+ },
6707
+ {
6708
+ name: "signer",
6709
+ writable: true,
6710
+ signer: true
6711
+ },
6712
+ {
6713
+ name: "kamino_lending_program",
6714
+ address: "KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD"
6715
+ },
6716
+ {
6717
+ name: "sol_oracle"
6718
+ },
6719
+ {
6720
+ name: "glam_config",
6721
+ pda: {
6722
+ seeds: [
6723
+ {
6724
+ kind: "const",
6725
+ value: [
6726
+ 103,
6727
+ 108,
6728
+ 111,
6729
+ 98,
6730
+ 97,
6731
+ 108,
6732
+ 95,
6733
+ 99,
6734
+ 111,
6735
+ 110,
6736
+ 102,
6737
+ 105,
6738
+ 103
6739
+ ]
6740
+ }
6741
+ ],
6742
+ program: {
6743
+ kind: "const",
6744
+ value: [
6745
+ 10,
6746
+ 11,
6747
+ 0,
6748
+ 83,
6749
+ 72,
6750
+ 16,
6751
+ 46,
6752
+ 144,
6753
+ 46,
6754
+ 42,
6755
+ 79,
6756
+ 22,
6757
+ 157,
6758
+ 123,
6759
+ 21,
6760
+ 242,
6761
+ 192,
6762
+ 146,
6763
+ 1,
6764
+ 78,
6765
+ 88,
6766
+ 59,
6767
+ 102,
6768
+ 9,
6769
+ 190,
6770
+ 226,
6771
+ 92,
6772
+ 189,
6773
+ 187,
6774
+ 232,
6775
+ 83,
6776
+ 220
6777
+ ]
6778
+ }
6779
+ }
6780
+ },
6781
+ {
6782
+ name: "pyth_oracle",
6783
+ optional: true
6784
+ },
6785
+ {
6786
+ name: "switchboard_price_oracle",
6787
+ optional: true
6788
+ },
6789
+ {
6790
+ name: "switchboard_twap_oracle",
6791
+ optional: true
6792
+ },
6793
+ {
6794
+ name: "scope_prices",
6795
+ optional: true
6796
+ }
6797
+ ],
6798
+ args: [
6799
+ {
6800
+ name: "denom",
6801
+ type: {
6802
+ defined: {
6803
+ name: "PriceDenom"
6804
+ }
6805
+ }
6806
+ }
6807
+ ]
6808
+ },
6665
6809
  {
6666
6810
  name: "price_meteora_positions",
6667
6811
  discriminator: [
@@ -13738,6 +13882,7 @@ const MERKLE_DISTRIBUTOR_PROGRAM = new web3_js.PublicKey("DiS3nNjFVMieMgmiQFm6wg
13738
13882
  const TRANSFER_HOOK_PROGRAM = new web3_js.PublicKey("po1iCYakK3gHCLbuju4wGzFowTMpAJxkqK1iwUqMonY");
13739
13883
  const METEORA_DLMM_PROGRAM = new web3_js.PublicKey("LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo");
13740
13884
  const KAMINO_LENDING_PROGRAM = new web3_js.PublicKey("KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD");
13885
+ const KAMINO_VAULTS_PROGRAM = new web3_js.PublicKey("KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd");
13741
13886
  const KAMINO_FARM_PROGRAM = new web3_js.PublicKey("FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr");
13742
13887
  const MEMO_PROGRAM = new web3_js.PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");
13743
13888
  /**
@@ -14681,7 +14826,7 @@ class BaseClient {
14681
14826
  set statePda(statePda) {
14682
14827
  this._statePda = statePda;
14683
14828
  }
14684
- isMainnet() {
14829
+ get isMainnet() {
14685
14830
  return this.cluster === ClusterNetwork.Mainnet;
14686
14831
  }
14687
14832
  isPhantom() {
@@ -14696,7 +14841,7 @@ class BaseClient {
14696
14841
  * @returns Metadata of the asset
14697
14842
  */ getAssetMeta(assetMint) {
14698
14843
  let assetMeta = ASSETS_MAINNET.get(assetMint);
14699
- if (!assetMeta && !this.isMainnet()) {
14844
+ if (!assetMeta && !this.isMainnet) {
14700
14845
  assetMeta = ASSETS_TESTS.get(assetMint);
14701
14846
  }
14702
14847
  if (!assetMeta) {
@@ -15086,9 +15231,9 @@ class BaseClient {
15086
15231
  if (stateAccount.mints.length > 0) {
15087
15232
  const mintPubkey = glamStatePda.equals(this.statePda) ? this.mintPda : getMintPda(glamStatePda, 0, this.program.programId);
15088
15233
  const { mint } = await this.fetchMintAndTokenProgram(mintPubkey);
15089
- return StateModel.fromOnchainAccounts(statePda, stateAccount, openfundsMetadataAccount, mint, this.program.programId);
15234
+ return StateModel.fromOnchainAccounts(glamStatePda, stateAccount, openfundsMetadataAccount, mint, this.program.programId);
15090
15235
  }
15091
- return StateModel.fromOnchainAccounts(statePda, stateAccount, openfundsMetadataAccount, undefined, this.program.programId);
15236
+ return StateModel.fromOnchainAccounts(glamStatePda, stateAccount, openfundsMetadataAccount, undefined, this.program.programId);
15092
15237
  }
15093
15238
  /**
15094
15239
  * Fetch all glam state models if no filter options provided
@@ -15308,6 +15453,12 @@ DepositDirection.WITHDRAW = {
15308
15453
  withdraw: {}
15309
15454
  };
15310
15455
  class OracleSource {
15456
+ static fromString(name) {
15457
+ const k = name.slice(0, 1).toLowerCase() + name.slice(1);
15458
+ return {
15459
+ [k]: {}
15460
+ };
15461
+ }
15311
15462
  static get(n) {
15312
15463
  const name = Object.entries(OracleSourceNum).find(([, v])=>v === n)?.[0];
15313
15464
  const source = Object.entries(OracleSource).find(([key, _])=>key.toLocaleLowerCase() === name?.toLocaleLowerCase())?.[1];
@@ -15763,6 +15914,24 @@ const DriftVaultLayout = borsh.struct([
15763
15914
  // Final padding
15764
15915
  borsh.array(borsh.u64(), 3, "padding")
15765
15916
  ]);
15917
+ borsh.struct([
15918
+ borsh.array(borsh.u8(), 8, "discriminator"),
15919
+ borsh.publicKey("marketPda"),
15920
+ borsh.publicKey("oracle"),
15921
+ borsh.publicKey("mint"),
15922
+ borsh.publicKey("vault"),
15923
+ borsh.array(borsh.u8(), 32, "name"),
15924
+ // Padding for bytes between name and cumulativeDepositInterest
15925
+ borsh.array(borsh.u8(), 464 - 168, "padding1"),
15926
+ borsh.u128("cumulativeDepositInterest"),
15927
+ borsh.u128("cumulativeBorrowInterest"),
15928
+ // Padding for bytes between cumulativeBorrowInterest and decimals
15929
+ borsh.array(borsh.u8(), 680 - 496, "padding2"),
15930
+ borsh.u32("decimals"),
15931
+ borsh.u16("marketIndex"),
15932
+ borsh.u8("padding3"),
15933
+ borsh.u8("oracleSource")
15934
+ ]);
15766
15935
 
15767
15936
  function readUnsignedBigInt64LE(buffer, offset) {
15768
15937
  return new anchor.BN(buffer.subarray(offset, offset + 8), 10, "le");
@@ -16223,17 +16392,17 @@ class DriftClient {
16223
16392
  Buffer.from("drift_state")
16224
16393
  ], DRIFT_PROGRAM_ID)[0];
16225
16394
  }
16226
- async fetchAndParseSpotMarket(marketIndex) {
16395
+ async fetchAndParseSpotMarket(marketIndex, skipCache = false) {
16227
16396
  const markets = await this.fetchAndParseSpotMarkets([
16228
16397
  marketIndex
16229
- ]);
16398
+ ], skipCache);
16230
16399
  if (!markets || markets.length === 0) {
16231
16400
  throw new Error(`Spot market not found at index ${marketIndex}`);
16232
16401
  }
16233
16402
  return markets[0];
16234
16403
  }
16235
- async fetchAndParseSpotMarkets(marketIndexes) {
16236
- const indexesToFetch = marketIndexes.filter((marketIndex)=>!this.spotMarkets.has(marketIndex));
16404
+ async fetchAndParseSpotMarkets(marketIndexes, skipCache = false) {
16405
+ const indexesToFetch = marketIndexes.filter((marketIndex)=>skipCache || !this.spotMarkets.has(marketIndex));
16237
16406
  if (indexesToFetch.length > 0) {
16238
16407
  if (process.env.NODE_ENV === "development") {
16239
16408
  console.log("Fetching spot markets:", indexesToFetch);
@@ -16256,17 +16425,17 @@ class DriftClient {
16256
16425
  }
16257
16426
  return spotMarkets;
16258
16427
  }
16259
- async fetchAndParsePerpMarket(marketIndex) {
16428
+ async fetchAndParsePerpMarket(marketIndex, skipCache = false) {
16260
16429
  const markets = await this.fetchAndParsePerpMarkets([
16261
16430
  marketIndex
16262
- ]);
16431
+ ], skipCache);
16263
16432
  if (!markets || markets.length === 0) {
16264
16433
  throw new Error(`Perp market not found at index ${marketIndex}`);
16265
16434
  }
16266
16435
  return markets[0];
16267
16436
  }
16268
- async fetchAndParsePerpMarkets(marketIndexes) {
16269
- const indexesToFetch = marketIndexes.filter((marketIndex)=>!this.perpMarkets.has(marketIndex));
16437
+ async fetchAndParsePerpMarkets(marketIndexes, skipCache = false) {
16438
+ const indexesToFetch = marketIndexes.filter((marketIndex)=>skipCache || !this.perpMarkets.has(marketIndex));
16270
16439
  if (indexesToFetch.length > 0) {
16271
16440
  if (process.env.NODE_ENV === "development") {
16272
16441
  console.log("Fetching perp markets:", indexesToFetch);
@@ -16291,33 +16460,56 @@ class DriftClient {
16291
16460
  }
16292
16461
  return perpMarkets;
16293
16462
  }
16294
- async fetchMarketConfigs() {
16295
- // const response = await fetch(
16296
- // "https://api.glam.systems/v0/drift/market_configs/",
16297
- // );
16298
- // if (!response.ok) {
16299
- // throw new Error(`Failed to fetch market configs: ${response.status}`);
16300
- // }
16301
- // const data = await response.json();
16302
- // const { orderConstants, perp, spot } = data;
16303
- // // Transform perp market from API to `PerpMarket` type
16304
- // const perpMarkets = perp.map((m: any) => ({
16305
- // marketIndex: m.marketIndex,
16306
- // marketPda: m.marketPDA,
16307
- // oracle: new PublicKey(m.oracle),
16308
- // }));
16309
- // // Transform spot market from API to `SpotMarket` type
16310
- // const spotMarkets = spot.map((m: any) => ({
16311
- // marketIndex: m.marketIndex,
16312
- // marketPda: m.marketPDA,
16313
- // oracle: new PublicKey(m.oracle),
16314
- // mint: new PublicKey(m.mint),
16315
- // vault: new PublicKey(m.vaultPDA),
16316
- // decimals: m.decimals,
16317
- // }));
16463
+ async fetchMarketConfigs(skipCache = false) {
16464
+ // Attempt to fetch market configs from glam API first
16465
+ const glamApi = process.env.NEXT_PUBLIC_GLAM_API || process.env.GLAM_API;
16466
+ if (glamApi) {
16467
+ const response = await fetch(`${glamApi}/v0/drift/market_configs/`);
16468
+ if (!response.ok) {
16469
+ throw new Error(`Failed to fetch market configs from ${glamApi}: ${response.status}`);
16470
+ }
16471
+ const data = await response.json();
16472
+ const { orderConstants, perp, spot } = data;
16473
+ // Transform perp market from API to `PerpMarket` type
16474
+ const perpMarkets = perp.map((m)=>({
16475
+ name: m.symbol,
16476
+ marketIndex: m.marketIndex,
16477
+ marketPda: new web3_js.PublicKey(m.marketPDA),
16478
+ oracle: new web3_js.PublicKey(m.oracle),
16479
+ oracleSource: OracleSource.fromString(m.oracleSource)
16480
+ }));
16481
+ perpMarkets.forEach((m)=>{
16482
+ this.perpMarkets.set(m.marketIndex, m);
16483
+ });
16484
+ // Transform spot market from API to `SpotMarket` type
16485
+ const spotMarkets = spot.map((m)=>({
16486
+ name: m.symbol,
16487
+ marketIndex: m.marketIndex,
16488
+ marketPda: new web3_js.PublicKey(m.marketPDA),
16489
+ vault: new web3_js.PublicKey(m.vaultPDA),
16490
+ oracle: new web3_js.PublicKey(m.oracle),
16491
+ oracleSource: OracleSource.fromString(m.oracleSource),
16492
+ mint: new web3_js.PublicKey(m.mint),
16493
+ decimals: m.decimals,
16494
+ tokenProgram: new web3_js.PublicKey(m.tokenProgram),
16495
+ cumulativeDepositInterest: new anchor.BN(m.cumulativeDepositInterest),
16496
+ cumulativeBorrowInterest: new anchor.BN(m.cumulativeBorrowInterest)
16497
+ }));
16498
+ spotMarkets.forEach((m)=>{
16499
+ this.spotMarkets.set(m.marketIndex, m);
16500
+ });
16501
+ const marketConfigs = {
16502
+ orderConstants,
16503
+ perpMarkets,
16504
+ spotMarkets
16505
+ };
16506
+ this.marketConfigs = marketConfigs;
16507
+ return marketConfigs;
16508
+ }
16509
+ // If glam API is not available, fetch market configs from RPC
16318
16510
  if (!this.marketConfigs) {
16319
- const perpMarkets = await this.fetchAndParsePerpMarkets(Array.from(Array(100).keys()));
16320
- const spotMarkets = await this.fetchAndParseSpotMarkets(Array.from(Array(100).keys()));
16511
+ const perpMarkets = await this.fetchAndParsePerpMarkets(Array.from(Array(100).keys()), skipCache);
16512
+ const spotMarkets = await this.fetchAndParseSpotMarkets(Array.from(Array(100).keys()), skipCache);
16321
16513
  this.marketConfigs = {
16322
16514
  orderConstants: {
16323
16515
  perpBaseScale: 9,
@@ -16329,24 +16521,10 @@ class DriftClient {
16329
16521
  }
16330
16522
  return this.marketConfigs;
16331
16523
  }
16332
- // public async fetchGlamDriftUser(
16333
- // glamState: PublicKey | string,
16334
- // subAccountId: number = 0,
16335
- // ): Promise<GlamDriftUser> {
16336
- // const vault = this.base.getVaultPda(new PublicKey(glamState));
16337
- // const response = await fetch(
16338
- // `https://api.glam.systems/v0/drift/user?authority=${vault.toBase58()}&accountId=${subAccountId}`,
16339
- // );
16340
- // const data = await response.json();
16341
- // if (!data) {
16342
- // throw new Error("Failed to fetch drift user.");
16343
- // }
16344
- // return data as GlamDriftUser;
16345
- // }
16346
16524
  charsToName(chars) {
16347
16525
  return String.fromCharCode(...chars).replace(/\0/g, "").trim();
16348
16526
  }
16349
- async fetchDriftUser(subAccountId = 0) {
16527
+ async fetchDriftUser(subAccountId = 0, skipCache = false) {
16350
16528
  const { user } = this.getDriftUserPdas(subAccountId);
16351
16529
  const accountInfo = await this.base.provider.connection.getAccountInfo(user);
16352
16530
  if (!accountInfo) {
@@ -16354,7 +16532,7 @@ class DriftClient {
16354
16532
  }
16355
16533
  const { delegate, name, spotPositions, marginMode, perpPositions, isMarginTradingEnabled, maxMarginRatio, orders } = decodeUser(accountInfo.data);
16356
16534
  // Prefetch market configs
16357
- const marketConfigs = await this.fetchMarketConfigs();
16535
+ const marketConfigs = await this.fetchMarketConfigs(skipCache);
16358
16536
  const spotPositionsExt = await Promise.all(spotPositions.map(async (p)=>{
16359
16537
  const { amount, uiAmount } = await this.calcSpotBalance(p.marketIndex, p.scaledBalance, p.balanceType);
16360
16538
  const spotMarket = marketConfigs.spotMarkets.find((m)=>m.marketIndex === p.marketIndex);
@@ -16379,22 +16557,10 @@ class DriftClient {
16379
16557
  maxMarginRatio
16380
16558
  };
16381
16559
  }
16382
- // async getPositions(statePda: PublicKey | string, subAccountId: number = 0) {
16383
- // const driftUser = await this.fetchDriftUser(
16384
- // new PublicKey(statePda),
16385
- // subAccountId,
16386
- // );
16387
- // if (!driftUser) {
16388
- // return { spotPositions: [], perpPositions: [] };
16389
- // }
16390
- // const marketConfigs = await this.fetchMarketConfigs();
16391
- // const { spotPositions, perpPositions } = driftUser;
16392
- // return { spotPositions, perpPositions };
16393
- // }
16394
16560
  /**
16395
16561
  * @deprecated
16396
- */ async fetchPolicyConfig(glamState) {
16397
- const driftUserAccount = glamState && glamState.id && await this.fetchDriftUser();
16562
+ */ async fetchPolicyConfig(stateModel) {
16563
+ const driftUserAccount = await this.fetchDriftUser();
16398
16564
  let delegate = driftUserAccount?.delegate;
16399
16565
  if (delegate && delegate.equals(web3_js.PublicKey.default)) {
16400
16566
  delegate = undefined;
@@ -16402,11 +16568,11 @@ class DriftClient {
16402
16568
  return {
16403
16569
  driftAccessControl: delegate ? 0 : 1,
16404
16570
  driftDelegatedAccount: delegate || null,
16405
- driftMarketIndexesPerp: glamState?.driftMarketIndexesPerp || [],
16406
- driftOrderTypes: glamState?.driftOrderTypes || [],
16571
+ driftMarketIndexesPerp: stateModel?.driftMarketIndexesPerp || [],
16572
+ driftOrderTypes: stateModel?.driftOrderTypes || [],
16407
16573
  driftMaxLeverage: driftUserAccount?.maxMarginRatio ? DRIFT_MARGIN_PRECISION / driftUserAccount?.maxMarginRatio : null,
16408
16574
  driftEnableSpot: driftUserAccount?.isMarginTradingEnabled || false,
16409
- driftMarketIndexesSpot: glamState?.driftMarketIndexesSpot || []
16575
+ driftMarketIndexesSpot: stateModel?.driftMarketIndexesSpot || []
16410
16576
  };
16411
16577
  }
16412
16578
  async composeRemainingAccounts(subAccountId, marketType, marketIndex) {
@@ -16501,7 +16667,8 @@ class DriftClient {
16501
16667
  const glamSigner = txOptions.signer || this.base.getSigner();
16502
16668
  const { user } = this.getDriftUserPdas(subAccountId);
16503
16669
  // https://github.com/drift-labs/protocol-v2/blob/babed162b08b1fe34e49a81c5aa3e4ec0a88ecdf/programs/drift/src/math/constants.rs#L183-L184
16504
- const marginRatio = DRIFT_MARGIN_PRECISION / maxLeverage;
16670
+ // 0 means No Limit
16671
+ const marginRatio = maxLeverage === 0 ? 0 : DRIFT_MARGIN_PRECISION / maxLeverage;
16505
16672
  return await this.base.program.methods.driftUpdateUserCustomMarginRatio(subAccountId, marginRatio).accounts({
16506
16673
  glamState: this.base.statePda,
16507
16674
  glamSigner,
@@ -17525,7 +17692,8 @@ class MarinadeClient {
17525
17692
  // Fetch stake accounts by withdraw authority
17526
17693
  // Filter by state "active" does not work in localnet tests
17527
17694
  const stakeAccounts = await getStakeAccountsWithStates(this.base.provider.connection, stakeWithdrawAuthority);
17528
- const { stakeIndex, validatorIndex } = await this.getIndexes(stakeAccounts[0], stakeList, validatorList);
17695
+ const idx = this.base.cluster === ClusterNetwork.Mainnet ? stakeAccounts.findIndex((s)=>s.state === "active") : 0;
17696
+ const { stakeIndex, validatorIndex } = await this.getIndexes(stakeAccounts[idx], stakeList, validatorList);
17529
17697
  const burnMsolFrom = this.base.getVaultAta(MSOL);
17530
17698
  const newStake = web3_js.Keypair.generate();
17531
17699
  const postInstructions = deactivate ? [
@@ -17541,7 +17709,7 @@ class MarinadeClient {
17541
17709
  state: marinadeState.marinadeStateAddress,
17542
17710
  validatorList: validatorList.account,
17543
17711
  stakeList: stakeList.account,
17544
- stakeAccount: stakeAccounts[0].address,
17712
+ stakeAccount: stakeAccounts[idx].address,
17545
17713
  stakeWithdrawAuthority,
17546
17714
  stakeDepositAuthority,
17547
17715
  treasuryMsolAccount: marinadeState.treasuryMsolAccount,
@@ -17712,7 +17880,7 @@ class VaultClient {
17712
17880
  const tx = new web3_js.Transaction().add(splToken.createAssociatedTokenAccountIdempotentInstruction(signer, vaultAta, this.base.vaultPda, asset, tokenProgram), splToken.createTransferCheckedInstruction(signerAta, asset, vaultAta, signer, new anchor.BN(amount).toNumber(), mint.decimals, [], tokenProgram));
17713
17881
  return await this.base.intoVersionedTransaction(tx, txOptions);
17714
17882
  }
17715
- async withdrawIxs(asset, amount, txOptions) {
17883
+ async withdrawIxs(asset, amount, txOptions = {}) {
17716
17884
  const glamSigner = txOptions.signer || this.base.getSigner();
17717
17885
  const { tokenProgram } = await this.base.fetchMintAndTokenProgram(asset);
17718
17886
  const signerAta = this.base.getAta(asset, glamSigner, tokenProgram);
@@ -18641,11 +18809,69 @@ class MintClient {
18641
18809
  }
18642
18810
  }
18643
18811
 
18812
+ const MAX_RESERVES = 25;
18813
+ const VaultAllocationLayout = borsh.struct([
18814
+ borsh.publicKey("reserve"),
18815
+ borsh.publicKey("ctokenVault"),
18816
+ borsh.u64("targetAllocationWeight"),
18817
+ borsh.u64("tokenAllocationCap"),
18818
+ borsh.u64("ctokenVaultBump"),
18819
+ borsh.array(borsh.u64(), 127, "configPadding"),
18820
+ borsh.u64("ctokenAllocation"),
18821
+ borsh.u64("lastInvestSlot"),
18822
+ borsh.u128("tokenTargetAllocationSf"),
18823
+ borsh.array(borsh.u64(), 128, "statePadding")
18824
+ ]);
18825
+ const KVaultStateLayout = borsh.struct([
18826
+ borsh.array(borsh.u8(), 8, "discriminator"),
18827
+ // Admin
18828
+ borsh.publicKey("vaultAdminAuthority"),
18829
+ borsh.publicKey("baseVaultAuthority"),
18830
+ borsh.u64("baseVaultAuthorityBump"),
18831
+ borsh.publicKey("tokenMint"),
18832
+ borsh.u64("tokenMintDecimals"),
18833
+ borsh.publicKey("tokenVault"),
18834
+ borsh.publicKey("tokenProgram"),
18835
+ // shares
18836
+ borsh.publicKey("sharesMint"),
18837
+ borsh.u64("sharesMintDecimals"),
18838
+ // accounting
18839
+ borsh.u64("tokenAvailable"),
18840
+ borsh.u64("sharesIssued"),
18841
+ borsh.u64("availableCrankFunds"),
18842
+ borsh.u64("padding0"),
18843
+ borsh.u64("performanceFeeBps"),
18844
+ borsh.u64("managementFeeBps"),
18845
+ borsh.u64("lastFeeChargeTimestamp"),
18846
+ borsh.u128("prevAumSf"),
18847
+ borsh.u128("pendingFeesSf"),
18848
+ borsh.array(VaultAllocationLayout, MAX_RESERVES, "vaultAllocationStrategy"),
18849
+ borsh.array(borsh.u128(), 256, "padding1"),
18850
+ // General config
18851
+ borsh.u64("minDepositAmount"),
18852
+ borsh.u64("minWithdrawAmount"),
18853
+ borsh.u64("minInvestAmount"),
18854
+ borsh.u64("minInvestDelaySlots"),
18855
+ borsh.u64("crankFundFeePerReserve"),
18856
+ borsh.publicKey("pendingAdmin"),
18857
+ borsh.u128("cumulativeEarnedInterestSf"),
18858
+ borsh.u128("cumulativeMgmtFeesSf"),
18859
+ borsh.u128("cumulativePerfFeesSf"),
18860
+ borsh.array(borsh.u8(), 40, "name"),
18861
+ borsh.publicKey("vaultLookupTable"),
18862
+ borsh.publicKey("vaultFarm"),
18863
+ borsh.u64("creationTimestamp"),
18864
+ borsh.u64("padding2"),
18865
+ borsh.publicKey("allocationAdmin"),
18866
+ borsh.array(borsh.u128(), 242, "padding3")
18867
+ ]);
18868
+
18644
18869
  const LOOKUP_TABLE = new web3_js.PublicKey("284iwGtA9X9aLy3KsyV8uT2pXLARhYbiSi5SiM2g47M2");
18645
18870
  const DEFAULT_OBLIGATION_ARGS = {
18646
18871
  tag: 0,
18647
18872
  id: 0
18648
18873
  };
18874
+ const EVENT_AUTHORITY$1 = new web3_js.PublicKey("24tHwQyJJ9akVXxnvkekGfAoeUJXXS7mE6kQNioNySsK");
18649
18875
  function refreshObligation(accounts, programId = KAMINO_LENDING_PROGRAM) {
18650
18876
  const keys = [
18651
18877
  {
@@ -19044,7 +19270,7 @@ class KaminoLendingClient {
19044
19270
  /**
19045
19271
  * Fetches and parses an obligation account
19046
19272
  */ async fetchAndParseObligation(obligation) {
19047
- const cached = this.obligations.get(obligation);
19273
+ const cached = this.obligations.get(obligation.toBase58());
19048
19274
  if (cached) {
19049
19275
  return cached;
19050
19276
  }
@@ -19058,7 +19284,7 @@ class KaminoLendingClient {
19058
19284
  };
19059
19285
  }
19060
19286
  const parsedObligation = this.parseObligation(obligation, obligationAccount.data);
19061
- this.obligations.set(obligation, parsedObligation);
19287
+ this.obligations.set(obligation.toBase58(), parsedObligation);
19062
19288
  return parsedObligation;
19063
19289
  }
19064
19290
  parseReserveAccount(reserve, data) {
@@ -19068,6 +19294,7 @@ class KaminoLendingClient {
19068
19294
  const liquidityMint = new web3_js.PublicKey(data.subarray(128, 160));
19069
19295
  return {
19070
19296
  address: reserve,
19297
+ market,
19071
19298
  farmCollateral: farmCollateral.equals(web3_js.PublicKey.default) ? null : farmCollateral,
19072
19299
  farmDebt: farmDebt.equals(web3_js.PublicKey.default) ? null : farmDebt,
19073
19300
  liquidityMint,
@@ -19075,16 +19302,28 @@ class KaminoLendingClient {
19075
19302
  };
19076
19303
  }
19077
19304
  async fetchAndParseReserves(reserves) {
19078
- if (this.pubkeyArraysEqual(reserves, Array.from(this.reserves.keys()))) {
19079
- return Array.from(this.reserves.values());
19080
- }
19081
- const reserveAccounts = await this.base.provider.connection.getMultipleAccountsInfo(reserves);
19082
- if (reserveAccounts.find((a)=>!a)) {
19305
+ const requestReservesSet = new Set(reserves.map((r)=>r.toBase58()));
19306
+ const cachedReservesSet = new Set(this.reserves.keys());
19307
+ // If all requested reserves are cached, return data from cache
19308
+ if ([
19309
+ ...requestReservesSet
19310
+ ].every((r)=>cachedReservesSet.has(r))) {
19311
+ return Array.from(this.reserves.values()).filter((r)=>requestReservesSet.has(r.address.toBase58()));
19312
+ }
19313
+ // Only fetch reserves that are not cached
19314
+ const reservesToFetch = [
19315
+ ...requestReservesSet
19316
+ ].filter((r)=>!cachedReservesSet.has(r)).map((r)=>new web3_js.PublicKey(r));
19317
+ if (process.env.NODE_ENV !== "production") {
19318
+ console.log("Fetching reserves:", reservesToFetch.map((r)=>r.toBase58()));
19319
+ }
19320
+ const reserveAccounts = await this.base.provider.connection.getMultipleAccountsInfo(reservesToFetch);
19321
+ if (reserveAccounts.some((a)=>!a)) {
19083
19322
  throw new Error("Not all reserves can be found");
19084
19323
  }
19085
- return reserveAccounts.filter((a)=>!!a).map((account, i)=>{
19324
+ return reserveAccounts.map((account, i)=>{
19086
19325
  const parsedReserve = this.parseReserveAccount(reserves[i], account.data);
19087
- this.reserves.set(reserves[i], parsedReserve);
19326
+ this.reserves.set(reserves[i].toBase58(), parsedReserve);
19088
19327
  return parsedReserve;
19089
19328
  });
19090
19329
  }
@@ -19112,7 +19351,7 @@ class KaminoLendingClient {
19112
19351
  throw new Error("Reserve not found");
19113
19352
  }
19114
19353
  const parsedReserve = this.parseReserveAccount(accounts[0].pubkey, accounts[0].account.data);
19115
- this.reserves.set(accounts[0].pubkey, parsedReserve);
19354
+ this.reserves.set(accounts[0].pubkey.toBase58(), parsedReserve);
19116
19355
  return parsedReserve;
19117
19356
  }
19118
19357
  /**
@@ -19142,7 +19381,7 @@ class KaminoLendingClient {
19142
19381
  // Parse obligations and cache them
19143
19382
  return accounts.map((a)=>{
19144
19383
  const parsedObligation = this.parseObligation(a.pubkey, a.account.data);
19145
- this.obligations.set(a.pubkey, parsedObligation);
19384
+ this.obligations.set(a.pubkey.toBase58(), parsedObligation);
19146
19385
  return parsedObligation;
19147
19386
  });
19148
19387
  }
@@ -19673,6 +19912,160 @@ class KaminoFarmClient {
19673
19912
  ], KAMINO_FARM_PROGRAM)[0];
19674
19913
  }
19675
19914
  }
19915
+ class KaminoVaultsClient {
19916
+ async deposit(vault, amount, txOptions = {}) {
19917
+ const tx = await this.depositTx(vault, amount, txOptions);
19918
+ return await this.base.sendAndConfirm(tx);
19919
+ }
19920
+ async withdraw(vault, amount, txOptions = {}) {
19921
+ const tx = await this.withdrawTx(vault, amount, txOptions);
19922
+ return await this.base.sendAndConfirm(tx);
19923
+ }
19924
+ async findAndParseKaminoVaults() {
19925
+ const accounts = await this.base.provider.connection.getProgramAccounts(KAMINO_VAULTS_PROGRAM, {
19926
+ filters: [
19927
+ {
19928
+ dataSize: 62552
19929
+ },
19930
+ {
19931
+ memcmp: {
19932
+ offset: 0,
19933
+ bytes: "5MRSpWLS65g=",
19934
+ encoding: "base64"
19935
+ }
19936
+ }
19937
+ ]
19938
+ });
19939
+ if (accounts.length === 0) {
19940
+ throw new Error("Kamino vaults not found");
19941
+ }
19942
+ return accounts.map((a)=>{
19943
+ const vaultState = KVaultStateLayout.decode(a.account.data);
19944
+ this.vaultStates.set(a.pubkey.toBase58(), vaultState);
19945
+ this.shareMintToVaultPdaMap.set(vaultState.sharesMint.toBase58(), a.pubkey);
19946
+ return vaultState;
19947
+ });
19948
+ }
19949
+ async getVaultPdasByShareMints(mints) {
19950
+ if (this.vaultStates.size === 0) {
19951
+ await this.findAndParseKaminoVaults();
19952
+ }
19953
+ return mints.map((mint)=>this.shareMintToVaultPdaMap.get(mint.toBase58()));
19954
+ }
19955
+ async fetchAndParseVaultState(vault) {
19956
+ const vaultAccount = await this.base.provider.connection.getAccountInfo(vault);
19957
+ if (!vaultAccount) {
19958
+ throw new Error(`Kamino vault account not found:, ${vault}`);
19959
+ }
19960
+ const vaultState = KVaultStateLayout.decode(vaultAccount.data);
19961
+ this.vaultStates.set(vault.toBase58(), vaultState);
19962
+ this.shareMintToVaultPdaMap.set(vaultState.sharesMint.toBase58(), vault);
19963
+ return vaultState;
19964
+ }
19965
+ async composeRemainingAccounts(allocationStrategies) {
19966
+ // For each allocation get reserve and market pubkeys
19967
+ const reserves = allocationStrategies.map((strategy)=>strategy.reserve);
19968
+ const parsedReserves = await this.kaminoLending.fetchAndParseReserves(reserves);
19969
+ const reserveMetas = reserves.map((pubkey)=>({
19970
+ pubkey,
19971
+ isSigner: false,
19972
+ isWritable: true
19973
+ }));
19974
+ const marketMetas = parsedReserves.map(({ market })=>({
19975
+ pubkey: market,
19976
+ isSigner: false,
19977
+ isWritable: false
19978
+ }));
19979
+ return [
19980
+ ...reserveMetas,
19981
+ ...marketMetas
19982
+ ];
19983
+ }
19984
+ async depositTx(vault, amount, txOptions = {}) {
19985
+ const glamSigner = txOptions.signer || this.base.getSigner();
19986
+ const vaultState = await this.fetchAndParseVaultState(vault);
19987
+ const amountBN = new anchor.BN(amount * 10 ** vaultState.tokenMintDecimals.toNumber());
19988
+ const { tokenProgram: sharesTokenProgram } = await this.base.fetchMintAndTokenProgram(vaultState.sharesMint);
19989
+ const userTokenAta = this.base.getVaultAta(vaultState.tokenMint, vaultState.tokenProgram);
19990
+ const userSharesAta = this.base.getVaultAta(vaultState.sharesMint, sharesTokenProgram);
19991
+ // Create user shares ata
19992
+ const preInstructions = [
19993
+ splToken.createAssociatedTokenAccountIdempotentInstruction(glamSigner, userSharesAta, this.base.vaultPda, vaultState.sharesMint, sharesTokenProgram)
19994
+ ];
19995
+ // Remaining accounts, skip empty allocation strategies
19996
+ const remainingAccounts = await this.composeRemainingAccounts(vaultState.vaultAllocationStrategy.filter(({ reserve })=>!reserve.equals(web3_js.PublicKey.default)));
19997
+ const tx = await this.base.program.methods.kaminoVaultsDeposit(amountBN).accounts({
19998
+ glamState: this.base.statePda,
19999
+ glamSigner,
20000
+ vaultState: vault,
20001
+ tokenVault: vaultState.tokenVault,
20002
+ tokenMint: vaultState.tokenMint,
20003
+ baseVaultAuthority: vaultState.baseVaultAuthority,
20004
+ sharesMint: vaultState.sharesMint,
20005
+ userTokenAta,
20006
+ userSharesAta,
20007
+ klendProgram: KAMINO_LENDING_PROGRAM,
20008
+ tokenProgram: vaultState.tokenProgram,
20009
+ sharesTokenProgram,
20010
+ eventAuthority: EVENT_AUTHORITY$1,
20011
+ program: KAMINO_VAULTS_PROGRAM
20012
+ }).remainingAccounts(remainingAccounts).preInstructions(preInstructions).transaction();
20013
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20014
+ return vTx;
20015
+ }
20016
+ async withdrawTx(vault, amount, txOptions = {}) {
20017
+ const glamSigner = txOptions.signer || this.base.getSigner();
20018
+ const vaultState = await this.fetchAndParseVaultState(vault);
20019
+ const userTokenAta = this.base.getVaultAta(vaultState.tokenMint, vaultState.tokenProgram);
20020
+ const { tokenProgram: sharesTokenProgram } = await this.base.fetchMintAndTokenProgram(vaultState.sharesMint);
20021
+ const userSharesAta = this.base.getVaultAta(vaultState.sharesMint, sharesTokenProgram);
20022
+ const amountBN = new anchor.BN(amount * 10 ** vaultState.sharesMintDecimals.toNumber());
20023
+ const reserves = vaultState.vaultAllocationStrategy.filter(({ reserve })=>!reserve.equals(web3_js.PublicKey.default));
20024
+ // Withdraw from the first reserve when kvault does not have enough liquidity
20025
+ const idx = 0;
20026
+ const withdrawReserve = (await this.kaminoLending.fetchAndParseReserves(reserves.map((r)=>r.reserve)))[idx];
20027
+ const vaultCollateralTokenVault = vaultState.vaultAllocationStrategy[idx].ctokenVault;
20028
+ const remainingAccounts = await this.composeRemainingAccounts(reserves);
20029
+ const preInstructions = [
20030
+ splToken.createAssociatedTokenAccountIdempotentInstruction(glamSigner, userTokenAta, this.base.vaultPda, vaultState.tokenMint, vaultState.tokenProgram)
20031
+ ];
20032
+ const tx = await this.base.program.methods.kaminoVaultsWithdraw(amountBN).accounts({
20033
+ glamState: this.base.statePda,
20034
+ glamSigner,
20035
+ withdrawFromAvailableVaultState: vault,
20036
+ withdrawFromAvailableTokenVault: vaultState.tokenVault,
20037
+ withdrawFromAvailableBaseVaultAuthority: vaultState.baseVaultAuthority,
20038
+ withdrawFromAvailableUserTokenAta: userTokenAta,
20039
+ withdrawFromAvailableTokenMint: vaultState.tokenMint,
20040
+ withdrawFromAvailableUserSharesAta: userSharesAta,
20041
+ withdrawFromAvailableSharesMint: vaultState.sharesMint,
20042
+ withdrawFromAvailableTokenProgram: vaultState.tokenProgram,
20043
+ withdrawFromAvailableSharesTokenProgram: sharesTokenProgram,
20044
+ withdrawFromAvailableKlendProgram: KAMINO_LENDING_PROGRAM,
20045
+ withdrawFromAvailableEventAuthority: EVENT_AUTHORITY$1,
20046
+ withdrawFromAvailableProgram: KAMINO_VAULTS_PROGRAM,
20047
+ withdrawFromReserveVaultState: vault,
20048
+ withdrawFromReserveReserve: withdrawReserve.address,
20049
+ withdrawFromReserveCtokenVault: vaultCollateralTokenVault,
20050
+ withdrawFromReserveLendingMarket: withdrawReserve.market,
20051
+ withdrawFromReserveLendingMarketAuthority: this.kaminoLending.getMarketAuthority(withdrawReserve.market),
20052
+ withdrawFromReserveReserveLiquiditySupply: withdrawReserve.liquiditySupplyVault,
20053
+ withdrawFromReserveReserveCollateralMint: withdrawReserve.collateralMint,
20054
+ withdrawFromReserveReserveCollateralTokenProgram: splToken.TOKEN_PROGRAM_ID,
20055
+ withdrawFromReserveInstructionSysvarAccount: web3_js.SYSVAR_INSTRUCTIONS_PUBKEY,
20056
+ eventAuthority: EVENT_AUTHORITY$1,
20057
+ program: KAMINO_VAULTS_PROGRAM
20058
+ }).remainingAccounts(remainingAccounts).preInstructions(preInstructions).transaction();
20059
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20060
+ return vTx;
20061
+ }
20062
+ constructor(base, kaminoLending){
20063
+ this.base = base;
20064
+ this.kaminoLending = kaminoLending;
20065
+ this.vaultStates = new Map();
20066
+ this.shareMintToVaultPdaMap = new Map();
20067
+ }
20068
+ }
19676
20069
 
19677
20070
  // Pubkey::find_program_address(&[b"__event_authority"], &dlmm_interface::ID)
19678
20071
  const EVENT_AUTHORITY = new web3_js.PublicKey("D1ZN9Wj1fRSUQfCjhvnu1hqDMT7hzjzBBpi12nVniYD6");
@@ -20171,6 +20564,46 @@ class PriceClient {
20171
20564
  }).remainingAccounts(remainingAccounts).instruction();
20172
20565
  return priceIx;
20173
20566
  }
20567
+ async priceKaminoVaultSharesIx(priceDenom) {
20568
+ const allKvaultStates = await this.kvaults.findAndParseKaminoVaults();
20569
+ const allKvaultMints = allKvaultStates.map((kvault)=>kvault.sharesMint);
20570
+ // All share token accounts GLAM vault could possibly hold
20571
+ const possibleShareAtas = allKvaultMints.map((mint)=>this.base.getVaultAta(mint));
20572
+ const possibleShareAtaAccountsInfo = await this.base.provider.connection.getMultipleAccountsInfo(possibleShareAtas);
20573
+ const shareAtas = [];
20574
+ const shareMints = [];
20575
+ const kvaultStates = [];
20576
+ possibleShareAtaAccountsInfo.forEach((info, i)=>{
20577
+ if (info !== null) {
20578
+ shareAtas.push(possibleShareAtas[i]);
20579
+ shareMints.push(allKvaultMints[i]);
20580
+ kvaultStates.push(allKvaultStates[i]);
20581
+ }
20582
+ });
20583
+ const kvaultPdas = await this.kvaults.getVaultPdasByShareMints(shareMints);
20584
+ const remainingAccounts = (await Promise.all(kvaultStates.map((kvault)=>{
20585
+ return this.kvaults.composeRemainingAccounts(kvault.vaultAllocationStrategy.filter((alloc)=>!alloc.reserve.equals(web3_js.PublicKey.default)));
20586
+ }))).flat();
20587
+ [
20588
+ ...kvaultPdas,
20589
+ ...shareAtas
20590
+ ].map((pubkey)=>{
20591
+ remainingAccounts.unshift({
20592
+ pubkey: pubkey,
20593
+ isSigner: false,
20594
+ isWritable: false
20595
+ });
20596
+ });
20597
+ const priceIx = await this.base.program.methods.priceKaminoVaultShares(priceDenom).accounts({
20598
+ glamState: this.base.statePda,
20599
+ solOracle: SOL_ORACLE,
20600
+ pythOracle: null,
20601
+ switchboardPriceOracle: null,
20602
+ switchboardTwapOracle: null,
20603
+ scopePrices: KAMINO_SCOPE_PRICES
20604
+ }).remainingAccounts(remainingAccounts).instruction();
20605
+ return priceIx;
20606
+ }
20174
20607
  /**
20175
20608
  * Returns an instruction that prices the all Drift users (aka sub-accounts) controlled by the GLAM vault.
20176
20609
  * These Drift users must share the same user_stats that's also controlled by the GLAM vault.
@@ -20204,7 +20637,7 @@ class PriceClient {
20204
20637
  * Returns an instruction that prices a drift vault depositor.
20205
20638
  * If there are no vault depositor accounts, returns null.
20206
20639
  */ async priceDriftVaultDepositorsIx(priceDenom) {
20207
- const parsedVaultDepositors = await this.driftVaults.findAndParseVaultDepositors();
20640
+ const parsedVaultDepositors = await this.dvaults.findAndParseVaultDepositors();
20208
20641
  if (parsedVaultDepositors.length === 0) {
20209
20642
  return null;
20210
20643
  }
@@ -20219,9 +20652,9 @@ class PriceClient {
20219
20652
  for (const depositor of parsedVaultDepositors){
20220
20653
  remainingAccountsKeys.add(depositor.address.toBase58());
20221
20654
  remainingAccountsKeys.add(depositor.driftVault.toBase58());
20222
- const { user: driftUser } = await this.driftVaults.parseDriftVault(depositor.driftVault);
20655
+ const { user: driftUser } = await this.dvaults.parseDriftVault(depositor.driftVault);
20223
20656
  remainingAccountsKeys.add(driftUser.toBase58());
20224
- const markets_and_oracles = (await this.driftVaults.composeRemainingAccounts(driftUser)).map((a)=>a.pubkey.toBase58());
20657
+ const markets_and_oracles = (await this.dvaults.composeRemainingAccounts(driftUser)).map((a)=>a.pubkey.toBase58());
20225
20658
  for (const k of markets_and_oracles){
20226
20659
  remainingAccountsKeys.add(k);
20227
20660
  }
@@ -20310,11 +20743,12 @@ class PriceClient {
20310
20743
  priceDriftVaultDepositorsIx
20311
20744
  ].filter((ix)=>ix !== null);
20312
20745
  }
20313
- constructor(base, klend, drift, driftVaults){
20746
+ constructor(base, klend, kvaults, drift, dvaults){
20314
20747
  this.base = base;
20315
20748
  this.klend = klend;
20749
+ this.kvaults = kvaults;
20316
20750
  this.drift = drift;
20317
- this.driftVaults = driftVaults;
20751
+ this.dvaults = dvaults;
20318
20752
  this.remainingAccountsForPricingMeteora = async ()=>{
20319
20753
  const positions = await fetchMeteoraPositions(this.base.provider.connection, this.base.vaultPda);
20320
20754
  let chunks = await Promise.all(positions.map(async (pubkey)=>{
@@ -20429,7 +20863,7 @@ class PriceClient {
20429
20863
  }
20430
20864
  get price() {
20431
20865
  if (!this._price) {
20432
- this._price = new PriceClient(this, this.kaminoLending, this.drift, this.driftVaults);
20866
+ this._price = new PriceClient(this, this.kaminoLending, this.kaminoVaults, this.drift, this.driftVaults);
20433
20867
  }
20434
20868
  return this._price;
20435
20869
  }
@@ -20457,6 +20891,12 @@ class PriceClient {
20457
20891
  }
20458
20892
  return this._kaminoFarm;
20459
20893
  }
20894
+ get kaminoVaults() {
20895
+ if (!this._kaminoVaults) {
20896
+ this._kaminoVaults = new KaminoVaultsClient(this, this.kaminoLending);
20897
+ }
20898
+ return this._kaminoVaults;
20899
+ }
20460
20900
  get meteoraDlmm() {
20461
20901
  if (!this._meteoraDlmm) {
20462
20902
  this._meteoraDlmm = new MeteoraDlmmClient(this);
@@ -20582,6 +21022,7 @@ exports.KAMINO_FARM_PROGRAM = KAMINO_FARM_PROGRAM;
20582
21022
  exports.KAMINO_LENDING_PROGRAM = KAMINO_LENDING_PROGRAM;
20583
21023
  exports.KAMINO_OBTRIGATION_SIZE = KAMINO_OBTRIGATION_SIZE;
20584
21024
  exports.KAMINO_SCOPE_PRICES = KAMINO_SCOPE_PRICES;
21025
+ exports.KAMINO_VAULTS_PROGRAM = KAMINO_VAULTS_PROGRAM;
20585
21026
  exports.LPAction = LPAction;
20586
21027
  exports.LiquidationType = LiquidationType;
20587
21028
  exports.MARINADE_NATIVE_STAKE_AUTHORITY = MARINADE_NATIVE_STAKE_AUTHORITY;