@kamino-finance/klend-sdk 5.11.6-beta.0 → 5.11.6

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.
Files changed (124) hide show
  1. package/dist/classes/action.d.ts +27 -35
  2. package/dist/classes/action.d.ts.map +1 -1
  3. package/dist/classes/action.js +198 -344
  4. package/dist/classes/action.js.map +1 -1
  5. package/dist/classes/index.d.ts +1 -0
  6. package/dist/classes/index.d.ts.map +1 -1
  7. package/dist/classes/index.js +1 -0
  8. package/dist/classes/index.js.map +1 -1
  9. package/dist/classes/manager.d.ts +6 -1
  10. package/dist/classes/manager.d.ts.map +1 -1
  11. package/dist/classes/manager.js +16 -1
  12. package/dist/classes/manager.js.map +1 -1
  13. package/dist/classes/market.d.ts +3 -3
  14. package/dist/classes/market.d.ts.map +1 -1
  15. package/dist/classes/market.js +30 -16
  16. package/dist/classes/market.js.map +1 -1
  17. package/dist/classes/obligation.d.ts +2 -0
  18. package/dist/classes/obligation.d.ts.map +1 -1
  19. package/dist/classes/obligation.js +5 -0
  20. package/dist/classes/obligation.js.map +1 -1
  21. package/dist/classes/types.d.ts.map +1 -1
  22. package/dist/classes/vault.d.ts +1 -0
  23. package/dist/classes/vault.d.ts.map +1 -1
  24. package/dist/classes/vault.js +21 -18
  25. package/dist/classes/vault.js.map +1 -1
  26. package/dist/idl_codegen_kamino_vault/accounts/VaultState.d.ts +6 -3
  27. package/dist/idl_codegen_kamino_vault/accounts/VaultState.d.ts.map +1 -1
  28. package/dist/idl_codegen_kamino_vault/accounts/VaultState.js +13 -7
  29. package/dist/idl_codegen_kamino_vault/accounts/VaultState.js.map +1 -1
  30. package/dist/idl_codegen_kamino_vault/errors/custom.d.ts +25 -1
  31. package/dist/idl_codegen_kamino_vault/errors/custom.d.ts.map +1 -1
  32. package/dist/idl_codegen_kamino_vault/errors/custom.js +43 -1
  33. package/dist/idl_codegen_kamino_vault/errors/custom.js.map +1 -1
  34. package/dist/idl_codegen_kamino_vault/instructions/giveUpPendingFees.d.ts +1 -1
  35. package/dist/idl_codegen_kamino_vault/instructions/giveUpPendingFees.d.ts.map +1 -1
  36. package/dist/idl_codegen_kamino_vault/instructions/giveUpPendingFees.js +1 -1
  37. package/dist/idl_codegen_kamino_vault/instructions/giveUpPendingFees.js.map +1 -1
  38. package/dist/idl_codegen_kamino_vault/instructions/initVault.d.ts +1 -0
  39. package/dist/idl_codegen_kamino_vault/instructions/initVault.d.ts.map +1 -1
  40. package/dist/idl_codegen_kamino_vault/instructions/initVault.js +1 -0
  41. package/dist/idl_codegen_kamino_vault/instructions/initVault.js.map +1 -1
  42. package/dist/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.d.ts +1 -1
  43. package/dist/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.d.ts.map +1 -1
  44. package/dist/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.js +1 -1
  45. package/dist/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.js.map +1 -1
  46. package/dist/idl_codegen_kamino_vault/instructions/updateReserveAllocation.d.ts +1 -1
  47. package/dist/idl_codegen_kamino_vault/instructions/updateReserveAllocation.d.ts.map +1 -1
  48. package/dist/idl_codegen_kamino_vault/instructions/updateReserveAllocation.js +1 -1
  49. package/dist/idl_codegen_kamino_vault/instructions/updateReserveAllocation.js.map +1 -1
  50. package/dist/idl_codegen_kamino_vault/instructions/updateSharesMetadata.d.ts +1 -1
  51. package/dist/idl_codegen_kamino_vault/instructions/updateSharesMetadata.d.ts.map +1 -1
  52. package/dist/idl_codegen_kamino_vault/instructions/updateSharesMetadata.js +1 -1
  53. package/dist/idl_codegen_kamino_vault/instructions/updateSharesMetadata.js.map +1 -1
  54. package/dist/idl_codegen_kamino_vault/instructions/updateVaultConfig.d.ts +1 -1
  55. package/dist/idl_codegen_kamino_vault/instructions/updateVaultConfig.d.ts.map +1 -1
  56. package/dist/idl_codegen_kamino_vault/instructions/updateVaultConfig.js +1 -1
  57. package/dist/idl_codegen_kamino_vault/instructions/updateVaultConfig.js.map +1 -1
  58. package/dist/idl_codegen_kamino_vault/instructions/withdrawPendingFees.d.ts +1 -1
  59. package/dist/idl_codegen_kamino_vault/instructions/withdrawPendingFees.d.ts.map +1 -1
  60. package/dist/idl_codegen_kamino_vault/instructions/withdrawPendingFees.js +1 -1
  61. package/dist/idl_codegen_kamino_vault/instructions/withdrawPendingFees.js.map +1 -1
  62. package/dist/idl_codegen_kamino_vault/types/VaultConfigField.d.ts +13 -0
  63. package/dist/idl_codegen_kamino_vault/types/VaultConfigField.d.ts.map +1 -1
  64. package/dist/idl_codegen_kamino_vault/types/VaultConfigField.js +25 -1
  65. package/dist/idl_codegen_kamino_vault/types/VaultConfigField.js.map +1 -1
  66. package/dist/idl_codegen_kamino_vault/types/index.d.ts +2 -2
  67. package/dist/idl_codegen_kamino_vault/types/index.d.ts.map +1 -1
  68. package/dist/idl_codegen_kamino_vault/types/index.js.map +1 -1
  69. package/dist/lending_operations/repay_with_collateral_operations.d.ts +4 -4
  70. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  71. package/dist/lending_operations/repay_with_collateral_operations.js +10 -8
  72. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  73. package/dist/lending_operations/swap_collateral_operations.d.ts +2 -2
  74. package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
  75. package/dist/lending_operations/swap_collateral_operations.js +11 -6
  76. package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
  77. package/dist/leverage/operations.d.ts +9 -7
  78. package/dist/leverage/operations.d.ts.map +1 -1
  79. package/dist/leverage/operations.js +78 -66
  80. package/dist/leverage/operations.js.map +1 -1
  81. package/dist/leverage/types.d.ts +4 -4
  82. package/dist/leverage/types.d.ts.map +1 -1
  83. package/dist/utils/ObligationType.d.ts +1 -1
  84. package/dist/utils/ObligationType.d.ts.map +1 -1
  85. package/dist/utils/constants.d.ts +6 -0
  86. package/dist/utils/constants.d.ts.map +1 -1
  87. package/dist/utils/constants.js +7 -1
  88. package/dist/utils/constants.js.map +1 -1
  89. package/dist/utils/managerTypes.d.ts.map +1 -1
  90. package/dist/utils/managerTypes.js +7 -52
  91. package/dist/utils/managerTypes.js.map +1 -1
  92. package/dist/utils/oracle.d.ts +3 -3
  93. package/dist/utils/oracle.d.ts.map +1 -1
  94. package/dist/utils/oracle.js +4 -3
  95. package/dist/utils/oracle.js.map +1 -1
  96. package/package.json +2 -2
  97. package/src/classes/action.ts +225 -400
  98. package/src/classes/index.ts +1 -0
  99. package/src/classes/manager.ts +27 -1
  100. package/src/classes/market.ts +34 -25
  101. package/src/classes/obligation.ts +6 -0
  102. package/src/classes/types.ts +1 -1
  103. package/src/classes/vault.ts +23 -22
  104. package/src/client.ts +8 -3
  105. package/src/idl_codegen_kamino_vault/accounts/VaultState.ts +17 -9
  106. package/src/idl_codegen_kamino_vault/errors/custom.ts +42 -0
  107. package/src/idl_codegen_kamino_vault/instructions/giveUpPendingFees.ts +2 -2
  108. package/src/idl_codegen_kamino_vault/instructions/initVault.ts +2 -0
  109. package/src/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.ts +2 -2
  110. package/src/idl_codegen_kamino_vault/instructions/updateReserveAllocation.ts +2 -2
  111. package/src/idl_codegen_kamino_vault/instructions/updateSharesMetadata.ts +2 -2
  112. package/src/idl_codegen_kamino_vault/instructions/updateVaultConfig.ts +2 -2
  113. package/src/idl_codegen_kamino_vault/instructions/withdrawPendingFees.ts +2 -2
  114. package/src/idl_codegen_kamino_vault/types/VaultConfigField.ts +30 -0
  115. package/src/idl_codegen_kamino_vault/types/index.ts +2 -0
  116. package/src/idl_kamino_vault.json +35 -8
  117. package/src/lending_operations/repay_with_collateral_operations.ts +15 -11
  118. package/src/lending_operations/swap_collateral_operations.ts +19 -7
  119. package/src/leverage/operations.ts +114 -66
  120. package/src/leverage/types.ts +4 -4
  121. package/src/utils/ObligationType.ts +1 -1
  122. package/src/utils/constants.ts +7 -0
  123. package/src/utils/managerTypes.ts +10 -52
  124. package/src/utils/oracle.ts +7 -6
@@ -9,3 +9,4 @@ export * from './jupiterPerps';
9
9
  export * from './manager';
10
10
  export * from './vault';
11
11
  export * from './fraction';
12
+ export * from './types';
@@ -575,6 +575,32 @@ export class KaminoManager {
575
575
  return this._vaultClient.getAllVaults();
576
576
  }
577
577
 
578
+ /**
579
+ * Get all lending markets
580
+ * @returns an array of all lending markets
581
+ */
582
+ async getAllMarkets(): Promise<KaminoMarket[]> {
583
+ const lendingMarketsAccounts = await getProgramAccounts(
584
+ this.getConnection(),
585
+ this._kaminoLendProgramId,
586
+ LendingMarket.layout.span + 8,
587
+ {
588
+ commitment: this.getConnection().commitment ?? 'processed',
589
+ filters: [
590
+ { dataSize: LendingMarket.layout.span + 8 },
591
+ { memcmp: { offset: 0, bytes: bs58.encode(LendingMarket.discriminator) } },
592
+ ],
593
+ }
594
+ );
595
+
596
+ const markets = await Promise.all(
597
+ lendingMarketsAccounts.map((account) =>
598
+ KaminoMarket.load(this._connection, account.pubkey, this.recentSlotDurationMs, this._kaminoLendProgramId)
599
+ )
600
+ );
601
+ return markets.filter((market): market is KaminoMarket => market !== null);
602
+ }
603
+
578
604
  /**
579
605
  * Get all vaults for owner
580
606
  * @param owner the pubkey of the vaults owner
@@ -949,7 +975,7 @@ export class KaminoManager {
949
975
  }
950
976
 
951
977
  /**
952
- * This retruns an array of scope oracle configs to be used to set the scope price and twap oracles for a reserve
978
+ * This returns an array of scope oracle configs to be used to set the scope price and twap oracles for a reserve
953
979
  * @param feed - scope feed to fetch prices from
954
980
  * @param cluster - cluster to fetch from, this should be left unchanged unless working on devnet or locally
955
981
  * @returns - an array of scope oracle configs
@@ -29,7 +29,7 @@ import Decimal from 'decimal.js';
29
29
  import { FarmState } from '@kamino-finance/farms-sdk';
30
30
  import { PROGRAM_ID } from '../idl_codegen/programId';
31
31
  import bs58 from 'bs58';
32
- import { OraclePrices, Scope } from '@kamino-finance/scope-sdk';
32
+ import { OraclePrices, Scope, U16_MAX } from '@kamino-finance/scope-sdk';
33
33
  import { Fraction } from './fraction';
34
34
  import { chunks, KaminoPrices, MintToPriceMap } from '@kamino-finance/kliquidity-sdk';
35
35
  import { parseTokenSymbol, parseZeroPaddedUtf8 } from './utils';
@@ -59,8 +59,6 @@ export class KaminoMarket {
59
59
 
60
60
  readonly programId: PublicKey;
61
61
 
62
- scope: Scope;
63
-
64
62
  private readonly recentSlotDurationMs: number;
65
63
 
66
64
  private constructor(
@@ -68,7 +66,6 @@ export class KaminoMarket {
68
66
  state: LendingMarket,
69
67
  marketAddress: string,
70
68
  reserves: Map<PublicKey, KaminoReserve>,
71
- scope: Scope,
72
69
  recentSlotDurationMs: number,
73
70
  programId: PublicKey = PROGRAM_ID
74
71
  ) {
@@ -78,7 +75,6 @@ export class KaminoMarket {
78
75
  this.reserves = reserves;
79
76
  this.reservesActive = getReservesActive(this.reserves);
80
77
  this.programId = programId;
81
- this.scope = scope;
82
78
  this.recentSlotDurationMs = recentSlotDurationMs;
83
79
  }
84
80
 
@@ -97,7 +93,6 @@ export class KaminoMarket {
97
93
  marketAddress: PublicKey,
98
94
  recentSlotDurationMs: number,
99
95
  programId: PublicKey = PROGRAM_ID,
100
- setupLocalTest: boolean = false,
101
96
  withReserves: boolean = true
102
97
  ) {
103
98
  const market = await LendingMarket.fetch(connection, marketAddress, programId);
@@ -105,26 +100,12 @@ export class KaminoMarket {
105
100
  if (market === null) {
106
101
  return null;
107
102
  }
108
- let scope: Scope;
109
- if (!setupLocalTest) {
110
- scope = new Scope('mainnet-beta', connection);
111
- } else {
112
- scope = new Scope('localnet', connection);
113
- }
114
103
 
115
104
  const reserves = withReserves
116
105
  ? await getReservesForMarket(marketAddress, connection, programId, recentSlotDurationMs)
117
106
  : new Map<PublicKey, KaminoReserve>();
118
107
 
119
- return new KaminoMarket(
120
- connection,
121
- market,
122
- marketAddress.toString(),
123
- reserves,
124
- scope,
125
- recentSlotDurationMs,
126
- programId
127
- );
108
+ return new KaminoMarket(connection, market, marketAddress.toString(), reserves, recentSlotDurationMs, programId);
128
109
  }
129
110
 
130
111
  async reload(): Promise<void> {
@@ -1186,9 +1167,9 @@ export class KaminoMarket {
1186
1167
  /**
1187
1168
  * Get all Scope prices used by all the market reserves
1188
1169
  */
1189
- async getAllScopePrices(oraclePrices?: OraclePrices): Promise<KaminoPrices> {
1170
+ async getAllScopePrices(scope: Scope, oraclePrices?: OraclePrices): Promise<KaminoPrices> {
1190
1171
  if (!oraclePrices) {
1191
- oraclePrices = await this.scope.getOraclePrices();
1172
+ oraclePrices = await scope.getOraclePrices();
1192
1173
  }
1193
1174
  const spot: MintToPriceMap = {};
1194
1175
  const twaps: MintToPriceMap = {};
@@ -1199,11 +1180,11 @@ export class KaminoMarket {
1199
1180
  const chain = reserve.state.config.tokenInfo.scopeConfiguration.priceChain;
1200
1181
  const twapChain = reserve.state.config.tokenInfo.scopeConfiguration.twapChain.filter((x) => x > 0);
1201
1182
  if (oracle && isNotNullPubkey(oracle) && chain && Scope.isScopeChainValid(chain)) {
1202
- const spotPrice = await this.scope.getPriceFromChain(chain, oraclePrices);
1183
+ const spotPrice = await scope.getPriceFromChain(chain, oraclePrices);
1203
1184
  spot[tokenMint] = { price: spotPrice.price, name: tokenName };
1204
1185
  }
1205
1186
  if (oracle && isNotNullPubkey(oracle) && twapChain && Scope.isScopeChainValid(twapChain)) {
1206
- const twap = await this.scope.getPriceFromChain(twapChain, oraclePrices);
1187
+ const twap = await scope.getPriceFromChain(twapChain, oraclePrices);
1207
1188
  twaps[tokenMint] = { price: twap.price, name: tokenName };
1208
1189
  }
1209
1190
  }
@@ -1527,6 +1508,34 @@ export function getReservesActive(reserves: Map<PublicKey, KaminoReserve>): Map<
1527
1508
  return reservesActive;
1528
1509
  }
1529
1510
 
1511
+ export function getTokenIdsForScopeRefresh(kaminoMarket: KaminoMarket, reserves: PublicKey[]): number[] {
1512
+ const tokenIds: number[] = [];
1513
+
1514
+ for (const reserveAddress of reserves) {
1515
+ const reserve = kaminoMarket.getReserveByAddress(reserveAddress);
1516
+ if (!reserve) {
1517
+ throw new Error(`Reserve not found for reserve ${reserveAddress.toBase58()}`);
1518
+ }
1519
+
1520
+ if (!reserve.state.config.tokenInfo.scopeConfiguration.priceFeed.equals(PublicKey.default)) {
1521
+ let x = 0;
1522
+
1523
+ while (reserve.state.config.tokenInfo.scopeConfiguration.priceChain[x] !== U16_MAX) {
1524
+ tokenIds.push(reserve.state.config.tokenInfo.scopeConfiguration.priceChain[x]);
1525
+ x++;
1526
+ }
1527
+
1528
+ x = 0;
1529
+ while (reserve.state.config.tokenInfo.scopeConfiguration.twapChain[x] !== U16_MAX) {
1530
+ tokenIds.push(reserve.state.config.tokenInfo.scopeConfiguration.twapChain[x]);
1531
+ x++;
1532
+ }
1533
+ }
1534
+ }
1535
+
1536
+ return tokenIds;
1537
+ }
1538
+
1530
1539
  export async function getReserveFromMintAndMarket(
1531
1540
  connection: Connection,
1532
1541
  market: KaminoMarket,
@@ -17,6 +17,7 @@ import {
17
17
  getObligationPdaWithArgs,
18
18
  getObligationType,
19
19
  isNotNullPubkey,
20
+ ObligationType,
20
21
  PubkeyHashMap,
21
22
  TOTAL_NUMBER_OF_IDS_TO_CHECK,
22
23
  U64_MAX,
@@ -1593,3 +1594,8 @@ export class KaminoObligation {
1593
1594
  }
1594
1595
  }
1595
1596
  }
1597
+
1598
+ // Create a function that checks if an obligation is of type obligation or obligationType
1599
+ export function isKaminoObligation(obligation: KaminoObligation | ObligationType): obligation is KaminoObligation {
1600
+ return 'obligationAddress' in obligation;
1601
+ }
@@ -58,4 +58,4 @@ export type ReserveAllocationOverview = {
58
58
  export type APYs = {
59
59
  grossAPY: Decimal;
60
60
  netAPY: Decimal;
61
- }
61
+ };
@@ -11,7 +11,7 @@ import {
11
11
  SYSVAR_RENT_PUBKEY,
12
12
  TransactionInstruction,
13
13
  } from '@solana/web3.js';
14
- import { NATIVE_MINT, TOKEN_PROGRAM_ID, unpackAccount } from '@solana/spl-token';
14
+ import { getAssociatedTokenAddressSync, NATIVE_MINT, TOKEN_PROGRAM_ID, unpackAccount } from '@solana/spl-token';
15
15
  import {
16
16
  getAssociatedTokenAddress,
17
17
  getTransferWsolIxns,
@@ -100,6 +100,8 @@ const CTOKEN_VAULT_SEED = 'ctoken_vault';
100
100
  const BASE_VAULT_AUTHORITY_SEED = 'authority';
101
101
  const SHARES_SEED = 'shares';
102
102
 
103
+ export const INITIAL_DEPOSIT_LAMPORTS = 1000;
104
+
103
105
  /**
104
106
  * KaminoVaultClient is a class that provides a high-level interface to interact with the Kamino Vault program.
105
107
  */
@@ -195,6 +197,8 @@ export class KaminoVaultClient {
195
197
  this._kaminoVaultProgramId
196
198
  )[0];
197
199
 
200
+ const adminTokenAccount = getAssociatedTokenAddressSync(vaultConfig.tokenMint, vaultConfig.admin, false);
201
+
198
202
  const initVaultAccounts: InitVaultAccounts = {
199
203
  adminAuthority: vaultConfig.admin,
200
204
  vaultState: vaultState.publicKey,
@@ -206,6 +210,7 @@ export class KaminoVaultClient {
206
210
  rent: SYSVAR_RENT_PUBKEY,
207
211
  tokenProgram: vaultConfig.tokenMintProgramId,
208
212
  sharesTokenProgram: TOKEN_PROGRAM_ID,
213
+ adminTokenAccount,
209
214
  };
210
215
  const initVaultIx = initVault(initVaultAccounts, this._kaminoVaultProgramId);
211
216
 
@@ -288,7 +293,7 @@ export class KaminoVaultClient {
288
293
  );
289
294
 
290
295
  const updateReserveAllocationAccounts: UpdateReserveAllocationAccounts = {
291
- adminAuthority: vaultState.adminAuthority,
296
+ signer: vaultState.vaultAdminAuthority,
292
297
  vaultState: vault.address,
293
298
  baseVaultAuthority: vaultState.baseVaultAuthority,
294
299
  reserveCollateralMint: reserveState.collateral.mintPubkey,
@@ -296,7 +301,7 @@ export class KaminoVaultClient {
296
301
  ctokenVault: cTokenVault,
297
302
  systemProgram: SystemProgram.programId,
298
303
  rent: SYSVAR_RENT_PUBKEY,
299
- reserveCollateralTokenProgram: vaultState.tokenProgram,
304
+ reserveCollateralTokenProgram: TOKEN_PROGRAM_ID,
300
305
  };
301
306
 
302
307
  const updateReserveAllocationArgs: UpdateReserveAllocationArgs = {
@@ -320,7 +325,7 @@ export class KaminoVaultClient {
320
325
  accountsToAddToLUT.push(lendingMarketAuth);
321
326
 
322
327
  const insertIntoLUTIxs = await this.insertIntoLookupTableIxs(
323
- vaultState.adminAuthority,
328
+ vaultState.vaultAdminAuthority,
324
329
  vaultState.vaultLookupTable,
325
330
  accountsToAddToLUT
326
331
  );
@@ -350,12 +355,12 @@ export class KaminoVaultClient {
350
355
  const vaultState: VaultState = await vault.getState(this.getConnection());
351
356
 
352
357
  const updateVaultConfigAccs: UpdateVaultConfigAccounts = {
353
- adminAuthority: vaultState.adminAuthority,
358
+ vaultAdminAuthority: vaultState.vaultAdminAuthority,
354
359
  vaultState: vault.address,
355
360
  klendProgram: this._kaminoLendProgramId,
356
361
  };
357
362
  if (signer) {
358
- updateVaultConfigAccs.adminAuthority = signer;
363
+ updateVaultConfigAccs.vaultAdminAuthority = signer;
359
364
  }
360
365
 
361
366
  const updateVaultConfigArgs: UpdateVaultConfigArgs = {
@@ -409,7 +414,7 @@ export class KaminoVaultClient {
409
414
  if (mode.kind === new VaultConfigField.PendingVaultAdmin().kind) {
410
415
  const newPubkey = new PublicKey(value);
411
416
  const insertIntoLutIxs = await this.insertIntoLookupTableIxs(
412
- vaultState.adminAuthority,
417
+ vaultState.vaultAdminAuthority,
413
418
  vaultState.vaultLookupTable,
414
419
  [newPubkey]
415
420
  );
@@ -427,7 +432,7 @@ export class KaminoVaultClient {
427
432
  farmState!.globalConfig
428
433
  );
429
434
  const insertIntoLutIxs = await this.insertIntoLookupTableIxs(
430
- vaultState.adminAuthority,
435
+ vaultState.vaultAdminAuthority,
431
436
  vaultState.vaultLookupTable,
432
437
  keysToAddToLUT
433
438
  );
@@ -476,7 +481,7 @@ export class KaminoVaultClient {
476
481
  value: string
477
482
  ): TransactionInstruction {
478
483
  const updateVaultConfigAccs: UpdateVaultConfigAccounts = {
479
- adminAuthority: admin,
484
+ vaultAdminAuthority: admin,
480
485
  vaultState: vault,
481
486
  klendProgram: this._kaminoLendProgramId,
482
487
  };
@@ -526,7 +531,7 @@ export class KaminoVaultClient {
526
531
 
527
532
  // read the current LUT and create a new one for the new admin and backfill it
528
533
  const accountsInExistentLUT = (await getAccountsInLUT(this.getConnection(), vaultState.vaultLookupTable)).filter(
529
- (account) => !account.equals(vaultState.adminAuthority)
534
+ (account) => !account.equals(vaultState.vaultAdminAuthority)
530
535
  );
531
536
 
532
537
  const LUTIxs: TransactionInstruction[] = [];
@@ -569,7 +574,7 @@ export class KaminoVaultClient {
569
574
  const vaultState: VaultState = await vault.getState(this.getConnection());
570
575
 
571
576
  const giveUpPendingFeesAccounts: GiveUpPendingFeesAccounts = {
572
- adminAuthority: vaultState.adminAuthority,
577
+ vaultAdminAuthority: vaultState.vaultAdminAuthority,
573
578
  vaultState: vault.address,
574
579
  klendProgram: this._kaminoLendProgramId,
575
580
  };
@@ -599,7 +604,7 @@ export class KaminoVaultClient {
599
604
  ): Promise<TransactionInstruction[]> {
600
605
  const vaultState: VaultState = await vault.getState(this.getConnection());
601
606
  const vaultReservesState = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vaultState);
602
- const [{ ata: adminTokenAta, createAtaIx }] = createAtasIdempotent(vaultState.adminAuthority, [
607
+ const [{ ata: adminTokenAta, createAtaIx }] = createAtasIdempotent(vaultState.vaultAdminAuthority, [
603
608
  {
604
609
  mint: vaultState.tokenMint,
605
610
  tokenProgram: TOKEN_PROGRAM_ID,
@@ -1010,20 +1015,16 @@ export class KaminoVaultClient {
1010
1015
  if (allReserves.length === 0) {
1011
1016
  throw new Error('No reserves found for the vault, please select at least one reserve for the vault');
1012
1017
  }
1013
-
1014
1018
  const [allReservesStateMap, computedReservesAllocation] = await Promise.all([
1015
1019
  this.loadVaultReserves(vaultState),
1016
1020
  this.getVaultComputedReservesAllocation(vaultState),
1017
1021
  ]);
1018
-
1019
1022
  const tokenProgram = await getAccountOwner(this.getConnection(), vaultState.tokenMint);
1020
1023
  const [{ ata: _payerTokenAta, createAtaIx }] = createAtasIdempotent(payer, [
1021
1024
  { mint: vaultState.tokenMint, tokenProgram },
1022
1025
  ]);
1023
-
1024
1026
  // compute total vault holdings and expected distribution based on weights
1025
1027
  const curentVaultAllocations = this.getVaultAllocations(vaultState);
1026
-
1027
1028
  const reservesToDisinvestFrom: PublicKey[] = [];
1028
1029
  const reservesToInvestInto: PublicKey[] = [];
1029
1030
 
@@ -1294,7 +1295,7 @@ export class KaminoVaultClient {
1294
1295
  const lendingMarketAuth = lendingMarketAuthPda(marketAddress, this._kaminoLendProgramId)[0];
1295
1296
 
1296
1297
  const withdrawPendingFeesAccounts: WithdrawPendingFeesAccounts = {
1297
- adminAuthority: vaultState.adminAuthority,
1298
+ vaultAdminAuthority: vaultState.vaultAdminAuthority,
1298
1299
  vaultState: vault.address,
1299
1300
  reserve: reserve.address,
1300
1301
  tokenVault: vaultState.tokenVault,
@@ -1354,7 +1355,7 @@ export class KaminoVaultClient {
1354
1355
  const vaultState = await vault.getState(this.getConnection());
1355
1356
  const allAccountsToBeInserted = [
1356
1357
  vault.address,
1357
- vaultState.adminAuthority,
1358
+ vaultState.vaultAdminAuthority,
1358
1359
  vaultState.baseVaultAuthority,
1359
1360
  vaultState.tokenMint,
1360
1361
  vaultState.tokenVault,
@@ -1399,7 +1400,7 @@ export class KaminoVaultClient {
1399
1400
  let lut = vaultState.vaultLookupTable;
1400
1401
  if (lut.equals(PublicKey.default)) {
1401
1402
  const recentSlot = await this.getConnection().getSlot();
1402
- const [ixn, address] = initLookupTableIx(vaultState.adminAuthority, recentSlot);
1403
+ const [ixn, address] = initLookupTableIx(vaultState.vaultAdminAuthority, recentSlot);
1403
1404
  setupLUTIfNeededIxs.push(ixn);
1404
1405
  lut = address;
1405
1406
 
@@ -1419,7 +1420,7 @@ export class KaminoVaultClient {
1419
1420
  }
1420
1421
  ixns.push(
1421
1422
  ...(await this.insertIntoLookupTableIxs(
1422
- vaultState.adminAuthority,
1423
+ vaultState.vaultAdminAuthority,
1423
1424
  lut,
1424
1425
  allAccountsToBeInserted,
1425
1426
  overridenExistentAccounts
@@ -1528,8 +1529,8 @@ export class KaminoVaultClient {
1528
1529
 
1529
1530
  let totalLeftToInvest = holdings.totalAUMIncludingFees.sub(holdings.pendingFees);
1530
1531
  let currentAllocationSum = totalAllocation;
1531
- const ZERO = new Decimal(0);
1532
- while (totalLeftToInvest.gt(ZERO)) {
1532
+ const ONE = new Decimal(1);
1533
+ while (totalLeftToInvest.gt(ONE)) {
1533
1534
  const totalLeftover = totalLeftToInvest;
1534
1535
  for (const reserve of allReserves) {
1535
1536
  const reserveWithWeight = initialVaultAllocations.get(reserve);
package/src/client.ts CHANGED
@@ -22,6 +22,7 @@ import { VanillaObligation } from './utils/ObligationType';
22
22
  import { parseTokenSymbol } from './classes/utils';
23
23
  import { Env, initEnv } from '../tests/runner/setup_utils';
24
24
  import { initializeFarmsForReserve } from '../tests/runner/farms/farms_operations';
25
+ import { Scope } from '@kamino-finance/scope-sdk';
25
26
 
26
27
  const STAGING_LENDING_MARKET = new PublicKey('6WVSwDQXrBZeQVnu6hpnsRZhodaJTZBUaC334SiiBKdb');
27
28
  const MAINNET_LENDING_MARKET = new PublicKey('7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF');
@@ -309,7 +310,8 @@ async function deposit(connection: Connection, wallet: Keypair, token: string, d
309
310
  kaminoMarket.getReserveBySymbol(token)!.getLiquidityMint(),
310
311
  wallet.publicKey,
311
312
  new VanillaObligation(STAGING_LENDING_MARKET),
312
- true
313
+ true,
314
+ { scope: new Scope('mainnet-beta', connection), scopeFeed: 'hubble' }
313
315
  );
314
316
  console.log('User obligation', kaminoAction.obligation!.obligationAddress.toString());
315
317
 
@@ -330,7 +332,8 @@ async function withdraw(connection: Connection, wallet: Keypair, token: string,
330
332
  kaminoMarket.getReserveBySymbol(token)!.getLiquidityMint(),
331
333
  wallet.publicKey,
332
334
  new VanillaObligation(new PublicKey(STAGING_LENDING_MARKET)),
333
- true
335
+ true,
336
+ { scope: new Scope('mainnet-beta', connection), scopeFeed: 'hubble' }
334
337
  );
335
338
  console.log('User obligation', kaminoAction.obligation!.obligationAddress.toString());
336
339
 
@@ -351,7 +354,8 @@ async function borrow(connection: Connection, wallet: Keypair, token: string, bo
351
354
  kaminoMarket.getReserveBySymbol(token)!.getLiquidityMint(),
352
355
  wallet.publicKey,
353
356
  new VanillaObligation(new PublicKey(STAGING_LENDING_MARKET)),
354
- true
357
+ true,
358
+ { scope: new Scope('mainnet-beta', connection), scopeFeed: 'hubble' }
355
359
  );
356
360
  console.log('User obligation', kaminoAction.obligation!.obligationAddress.toString());
357
361
 
@@ -373,6 +377,7 @@ async function repay(connection: Connection, wallet: Keypair, token: string, bor
373
377
  wallet.publicKey,
374
378
  new VanillaObligation(new PublicKey(STAGING_LENDING_MARKET)),
375
379
  true,
380
+ { scope: new Scope('mainnet-beta', connection), scopeFeed: 'hubble' },
376
381
  await connection.getSlot()
377
382
  );
378
383
  console.log('User obligation', kaminoAction.obligation!.obligationAddress.toString());
@@ -5,7 +5,7 @@ import * as types from "../types" // eslint-disable-line @typescript-eslint/no-u
5
5
  import { PROGRAM_ID } from "../programId"
6
6
 
7
7
  export interface VaultStateFields {
8
- adminAuthority: PublicKey
8
+ vaultAdminAuthority: PublicKey
9
9
  baseVaultAuthority: PublicKey
10
10
  baseVaultAuthorityBump: BN
11
11
  tokenMint: PublicKey
@@ -38,11 +38,12 @@ export interface VaultStateFields {
38
38
  vaultFarm: PublicKey
39
39
  creationTimestamp: BN
40
40
  padding1: BN
41
+ allocationAdmin: PublicKey
41
42
  padding2: Array<BN>
42
43
  }
43
44
 
44
45
  export interface VaultStateJSON {
45
- adminAuthority: string
46
+ vaultAdminAuthority: string
46
47
  baseVaultAuthority: string
47
48
  baseVaultAuthorityBump: string
48
49
  tokenMint: string
@@ -75,11 +76,12 @@ export interface VaultStateJSON {
75
76
  vaultFarm: string
76
77
  creationTimestamp: string
77
78
  padding1: string
79
+ allocationAdmin: string
78
80
  padding2: Array<string>
79
81
  }
80
82
 
81
83
  export class VaultState {
82
- readonly adminAuthority: PublicKey
84
+ readonly vaultAdminAuthority: PublicKey
83
85
  readonly baseVaultAuthority: PublicKey
84
86
  readonly baseVaultAuthorityBump: BN
85
87
  readonly tokenMint: PublicKey
@@ -112,6 +114,7 @@ export class VaultState {
112
114
  readonly vaultFarm: PublicKey
113
115
  readonly creationTimestamp: BN
114
116
  readonly padding1: BN
117
+ readonly allocationAdmin: PublicKey
115
118
  readonly padding2: Array<BN>
116
119
 
117
120
  static readonly discriminator = Buffer.from([
@@ -119,7 +122,7 @@ export class VaultState {
119
122
  ])
120
123
 
121
124
  static readonly layout = borsh.struct([
122
- borsh.publicKey("adminAuthority"),
125
+ borsh.publicKey("vaultAdminAuthority"),
123
126
  borsh.publicKey("baseVaultAuthority"),
124
127
  borsh.u64("baseVaultAuthorityBump"),
125
128
  borsh.publicKey("tokenMint"),
@@ -152,11 +155,12 @@ export class VaultState {
152
155
  borsh.publicKey("vaultFarm"),
153
156
  borsh.u64("creationTimestamp"),
154
157
  borsh.u64("padding1"),
155
- borsh.array(borsh.u128(), 244, "padding2"),
158
+ borsh.publicKey("allocationAdmin"),
159
+ borsh.array(borsh.u128(), 242, "padding2"),
156
160
  ])
157
161
 
158
162
  constructor(fields: VaultStateFields) {
159
- this.adminAuthority = fields.adminAuthority
163
+ this.vaultAdminAuthority = fields.vaultAdminAuthority
160
164
  this.baseVaultAuthority = fields.baseVaultAuthority
161
165
  this.baseVaultAuthorityBump = fields.baseVaultAuthorityBump
162
166
  this.tokenMint = fields.tokenMint
@@ -191,6 +195,7 @@ export class VaultState {
191
195
  this.vaultFarm = fields.vaultFarm
192
196
  this.creationTimestamp = fields.creationTimestamp
193
197
  this.padding1 = fields.padding1
198
+ this.allocationAdmin = fields.allocationAdmin
194
199
  this.padding2 = fields.padding2
195
200
  }
196
201
 
@@ -238,7 +243,7 @@ export class VaultState {
238
243
  const dec = VaultState.layout.decode(data.slice(8))
239
244
 
240
245
  return new VaultState({
241
- adminAuthority: dec.adminAuthority,
246
+ vaultAdminAuthority: dec.vaultAdminAuthority,
242
247
  baseVaultAuthority: dec.baseVaultAuthority,
243
248
  baseVaultAuthorityBump: dec.baseVaultAuthorityBump,
244
249
  tokenMint: dec.tokenMint,
@@ -275,13 +280,14 @@ export class VaultState {
275
280
  vaultFarm: dec.vaultFarm,
276
281
  creationTimestamp: dec.creationTimestamp,
277
282
  padding1: dec.padding1,
283
+ allocationAdmin: dec.allocationAdmin,
278
284
  padding2: dec.padding2,
279
285
  })
280
286
  }
281
287
 
282
288
  toJSON(): VaultStateJSON {
283
289
  return {
284
- adminAuthority: this.adminAuthority.toString(),
290
+ vaultAdminAuthority: this.vaultAdminAuthority.toString(),
285
291
  baseVaultAuthority: this.baseVaultAuthority.toString(),
286
292
  baseVaultAuthorityBump: this.baseVaultAuthorityBump.toString(),
287
293
  tokenMint: this.tokenMint.toString(),
@@ -316,13 +322,14 @@ export class VaultState {
316
322
  vaultFarm: this.vaultFarm.toString(),
317
323
  creationTimestamp: this.creationTimestamp.toString(),
318
324
  padding1: this.padding1.toString(),
325
+ allocationAdmin: this.allocationAdmin.toString(),
319
326
  padding2: this.padding2.map((item) => item.toString()),
320
327
  }
321
328
  }
322
329
 
323
330
  static fromJSON(obj: VaultStateJSON): VaultState {
324
331
  return new VaultState({
325
- adminAuthority: new PublicKey(obj.adminAuthority),
332
+ vaultAdminAuthority: new PublicKey(obj.vaultAdminAuthority),
326
333
  baseVaultAuthority: new PublicKey(obj.baseVaultAuthority),
327
334
  baseVaultAuthorityBump: new BN(obj.baseVaultAuthorityBump),
328
335
  tokenMint: new PublicKey(obj.tokenMint),
@@ -357,6 +364,7 @@ export class VaultState {
357
364
  vaultFarm: new PublicKey(obj.vaultFarm),
358
365
  creationTimestamp: new BN(obj.creationTimestamp),
359
366
  padding1: new BN(obj.padding1),
367
+ allocationAdmin: new PublicKey(obj.allocationAdmin),
360
368
  padding2: obj.padding2.map((item) => new BN(item)),
361
369
  })
362
370
  }
@@ -43,6 +43,9 @@ export type CustomError =
43
43
  | ManagementFeeGreaterThanMaxAllowed
44
44
  | VaultAUMZero
45
45
  | MissingReserveForBatchRefresh
46
+ | MinWithdrawAmountTooBig
47
+ | InvestTooSoon
48
+ | WrongAdminOrAllocationAdmin
46
49
 
47
50
  export class DepositAmountsZero extends Error {
48
51
  static readonly code = 7000
@@ -528,6 +531,39 @@ export class MissingReserveForBatchRefresh extends Error {
528
531
  }
529
532
  }
530
533
 
534
+ export class MinWithdrawAmountTooBig extends Error {
535
+ static readonly code = 7044
536
+ readonly code = 7044
537
+ readonly name = "MinWithdrawAmountTooBig"
538
+ readonly msg = "Min withdraw amount is too big"
539
+
540
+ constructor(readonly logs?: string[]) {
541
+ super("7044: Min withdraw amount is too big")
542
+ }
543
+ }
544
+
545
+ export class InvestTooSoon extends Error {
546
+ static readonly code = 7045
547
+ readonly code = 7045
548
+ readonly name = "InvestTooSoon"
549
+ readonly msg = "Invest is called too soon after last invest"
550
+
551
+ constructor(readonly logs?: string[]) {
552
+ super("7045: Invest is called too soon after last invest")
553
+ }
554
+ }
555
+
556
+ export class WrongAdminOrAllocationAdmin extends Error {
557
+ static readonly code = 7046
558
+ readonly code = 7046
559
+ readonly name = "WrongAdminOrAllocationAdmin"
560
+ readonly msg = "Wrong admin or allocation admin"
561
+
562
+ constructor(readonly logs?: string[]) {
563
+ super("7046: Wrong admin or allocation admin")
564
+ }
565
+ }
566
+
531
567
  export function fromCode(code: number, logs?: string[]): CustomError | null {
532
568
  switch (code) {
533
569
  case 7000:
@@ -618,6 +654,12 @@ export function fromCode(code: number, logs?: string[]): CustomError | null {
618
654
  return new VaultAUMZero(logs)
619
655
  case 7043:
620
656
  return new MissingReserveForBatchRefresh(logs)
657
+ case 7044:
658
+ return new MinWithdrawAmountTooBig(logs)
659
+ case 7045:
660
+ return new InvestTooSoon(logs)
661
+ case 7046:
662
+ return new WrongAdminOrAllocationAdmin(logs)
621
663
  }
622
664
 
623
665
  return null
@@ -9,7 +9,7 @@ export interface GiveUpPendingFeesArgs {
9
9
  }
10
10
 
11
11
  export interface GiveUpPendingFeesAccounts {
12
- adminAuthority: PublicKey
12
+ vaultAdminAuthority: PublicKey
13
13
  vaultState: PublicKey
14
14
  klendProgram: PublicKey
15
15
  }
@@ -22,7 +22,7 @@ export function giveUpPendingFees(
22
22
  programId: PublicKey = PROGRAM_ID
23
23
  ) {
24
24
  const keys: Array<AccountMeta> = [
25
- { pubkey: accounts.adminAuthority, isSigner: true, isWritable: true },
25
+ { pubkey: accounts.vaultAdminAuthority, isSigner: true, isWritable: true },
26
26
  { pubkey: accounts.vaultState, isSigner: false, isWritable: true },
27
27
  { pubkey: accounts.klendProgram, isSigner: false, isWritable: false },
28
28
  ]
@@ -11,6 +11,7 @@ export interface InitVaultAccounts {
11
11
  tokenVault: PublicKey
12
12
  baseTokenMint: PublicKey
13
13
  sharesMint: PublicKey
14
+ adminTokenAccount: PublicKey
14
15
  systemProgram: PublicKey
15
16
  rent: PublicKey
16
17
  tokenProgram: PublicKey
@@ -28,6 +29,7 @@ export function initVault(
28
29
  { pubkey: accounts.tokenVault, isSigner: false, isWritable: true },
29
30
  { pubkey: accounts.baseTokenMint, isSigner: false, isWritable: false },
30
31
  { pubkey: accounts.sharesMint, isSigner: false, isWritable: true },
32
+ { pubkey: accounts.adminTokenAccount, isSigner: false, isWritable: true },
31
33
  { pubkey: accounts.systemProgram, isSigner: false, isWritable: false },
32
34
  { pubkey: accounts.rent, isSigner: false, isWritable: false },
33
35
  { pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
@@ -11,7 +11,7 @@ export interface InitializeSharesMetadataArgs {
11
11
  }
12
12
 
13
13
  export interface InitializeSharesMetadataAccounts {
14
- adminAuthority: PublicKey
14
+ vaultAdminAuthority: PublicKey
15
15
  vaultState: PublicKey
16
16
  sharesMint: PublicKey
17
17
  baseVaultAuthority: PublicKey
@@ -33,7 +33,7 @@ export function initializeSharesMetadata(
33
33
  programId: PublicKey = PROGRAM_ID
34
34
  ) {
35
35
  const keys: Array<AccountMeta> = [
36
- { pubkey: accounts.adminAuthority, isSigner: true, isWritable: true },
36
+ { pubkey: accounts.vaultAdminAuthority, isSigner: true, isWritable: true },
37
37
  { pubkey: accounts.vaultState, isSigner: false, isWritable: false },
38
38
  { pubkey: accounts.sharesMint, isSigner: false, isWritable: false },
39
39
  { pubkey: accounts.baseVaultAuthority, isSigner: false, isWritable: false },