@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
@@ -61,11 +61,12 @@ import {
61
61
  isNotNullPubkey,
62
62
  PublicKeySet,
63
63
  getAssociatedTokenAddress,
64
- ScopeRefresh,
64
+ ScopePriceRefreshConfig,
65
65
  createAtasIdempotent,
66
+ SOL_PADDING_FOR_INTEREST,
66
67
  obligationFarmStatePda,
67
68
  } from '../utils';
68
- import { KaminoMarket } from './market';
69
+ import { getTokenIdsForScopeRefresh, KaminoMarket } from './market';
69
70
  import { KaminoObligation } from './obligation';
70
71
  import { KaminoReserve } from './reserve';
71
72
  import { ReserveFarmKind } from '../idl_codegen/types';
@@ -73,9 +74,7 @@ import { farmsId } from '@kamino-finance/farms-sdk';
73
74
  import { Reserve } from '../idl_codegen/accounts';
74
75
  import { VanillaObligation } from '../utils/ObligationType';
75
76
  import { PROGRAM_ID } from '../lib';
76
- import { U16_MAX } from '@kamino-finance/scope-sdk';
77
-
78
- const SOL_PADDING_FOR_INTEREST = new BN('1000000');
77
+ import { Scope } from '@kamino-finance/scope-sdk';
79
78
 
80
79
  export type ActionType =
81
80
  | 'deposit'
@@ -108,12 +107,6 @@ export class KaminoAction {
108
107
 
109
108
  referrer: PublicKey;
110
109
 
111
- userTokenAccountAddress: PublicKey;
112
-
113
- userCollateralAccountAddress: PublicKey;
114
-
115
- additionalTokenAccountAddress?: PublicKey;
116
-
117
110
  /**
118
111
  * Null unless the obligation is not passed
119
112
  */
@@ -143,12 +136,6 @@ export class KaminoAction {
143
136
  cleanupIxs: Array<TransactionInstruction>;
144
137
  cleanupIxsLabels: Array<string>;
145
138
 
146
- preTxnIxs: Array<TransactionInstruction>;
147
- preTxnIxsLabels: Array<string>;
148
-
149
- postTxnIxs: Array<TransactionInstruction>;
150
- postTxnIxsLabels: Array<string>;
151
-
152
139
  refreshFarmsCleanupTxnIxs: Array<TransactionInstruction>;
153
140
  refreshFarmsCleanupTxnIxsLabels: Array<string>;
154
141
 
@@ -163,8 +150,6 @@ export class KaminoAction {
163
150
  kaminoMarket: KaminoMarket,
164
151
  owner: PublicKey,
165
152
  obligation: KaminoObligation | ObligationType | null,
166
- userTokenAccountAddress: PublicKey,
167
- userCollateralAccountAddress: PublicKey,
168
153
  mint: PublicKey,
169
154
  positions: number,
170
155
  amount: string | BN,
@@ -173,7 +158,6 @@ export class KaminoAction {
173
158
  reserveState: KaminoReserve,
174
159
  currentSlot: number,
175
160
  secondaryMint?: PublicKey,
176
- additionalTokenAccountAddress?: PublicKey,
177
161
  outflowReserveState?: KaminoReserve,
178
162
  outflowAmount?: string | BN,
179
163
  referrer?: PublicKey,
@@ -191,8 +175,6 @@ export class KaminoAction {
191
175
  this.amount = new BN(amount);
192
176
  this.mint = mint;
193
177
  this.positions = positions;
194
- this.userTokenAccountAddress = userTokenAccountAddress;
195
- this.userCollateralAccountAddress = userCollateralAccountAddress;
196
178
  this.computeBudgetIxs = [];
197
179
  this.computeBudgetIxsLabels = [];
198
180
  this.setupIxs = [];
@@ -203,15 +185,10 @@ export class KaminoAction {
203
185
  this.lendingIxsLabels = [];
204
186
  this.cleanupIxs = [];
205
187
  this.cleanupIxsLabels = [];
206
- this.preTxnIxs = [];
207
- this.preTxnIxsLabels = [];
208
- this.postTxnIxs = [];
209
- this.postTxnIxsLabels = [];
210
188
  this.refreshFarmsCleanupTxnIxs = [];
211
189
  this.refreshFarmsCleanupTxnIxsLabels = [];
212
190
  this.depositReserves = depositReserves;
213
191
  this.borrowReserves = borrowReserves;
214
- this.additionalTokenAccountAddress = additionalTokenAccountAddress;
215
192
  this.secondaryMint = secondaryMint;
216
193
  this.reserve = reserveState;
217
194
  this.outflowReserve = outflowReserveState;
@@ -237,11 +214,6 @@ export class KaminoAction {
237
214
  throw new Error(`Reserve ${mint} not found in market ${kaminoMarket.getAddress().toBase58()}`);
238
215
  }
239
216
 
240
- const { userTokenAccountAddress, userCollateralAccountAddress } = KaminoAction.getUserAccountAddresses(
241
- payer ?? owner,
242
- reserve.state
243
- );
244
-
245
217
  const { kaminoObligation, depositReserves, borrowReserves, distinctReserveCount } =
246
218
  await KaminoAction.loadObligation(action, kaminoMarket, owner, reserve.address, obligation);
247
219
 
@@ -251,8 +223,6 @@ export class KaminoAction {
251
223
  kaminoMarket,
252
224
  owner,
253
225
  kaminoObligation || obligation,
254
- userTokenAccountAddress,
255
- userCollateralAccountAddress,
256
226
  mint,
257
227
  distinctReserveCount,
258
228
  amount,
@@ -263,7 +233,6 @@ export class KaminoAction {
263
233
  undefined,
264
234
  undefined,
265
235
  undefined,
266
- undefined,
267
236
  referrerKey,
268
237
  payer
269
238
  );
@@ -411,6 +380,7 @@ export class KaminoAction {
411
380
  owner: PublicKey,
412
381
  obligation: KaminoObligation | ObligationType,
413
382
  useV2Ixs: boolean,
383
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
414
384
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
415
385
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas,
416
386
  requestElevationGroup: boolean = false, // to be requested *before* the deposit
@@ -418,7 +388,6 @@ export class KaminoAction {
418
388
  createLookupTable: boolean = true,
419
389
  referrer: PublicKey = PublicKey.default,
420
390
  currentSlot: number = 0,
421
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' },
422
391
  overrideElevationGroupRequest: number | undefined = undefined // if set, when an elevationgroup request is made, it will use this value
423
392
  ) {
424
393
  const axn = await KaminoAction.initialize(
@@ -437,16 +406,6 @@ export class KaminoAction {
437
406
  axn.addComputeBudgetIxn(extraComputeBudget);
438
407
  }
439
408
 
440
- const allReserves = new PublicKeySet<PublicKey>([
441
- ...axn.depositReserves,
442
- ...axn.borrowReserves,
443
- axn.reserve.address,
444
- ]).toArray();
445
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
446
-
447
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
448
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
449
- }
450
409
  await axn.addSupportIxs(
451
410
  'deposit',
452
411
  includeAtaIxns,
@@ -454,6 +413,7 @@ export class KaminoAction {
454
413
  includeUserMetadata,
455
414
  addInitObligationForFarm,
456
415
  useV2Ixs,
416
+ scopeRefreshConfig,
457
417
  createLookupTable,
458
418
  undefined,
459
419
  overrideElevationGroupRequest
@@ -468,36 +428,10 @@ export class KaminoAction {
468
428
  return axn;
469
429
  }
470
430
 
471
- getTokenIdsForScopeRefresh(kaminoMarket: KaminoMarket, reserves: PublicKey[]): number[] {
472
- const tokenIds: number[] = [];
473
-
474
- for (const reserveAddress of reserves) {
475
- const reserve = kaminoMarket.getReserveByAddress(reserveAddress);
476
- if (!reserve) {
477
- throw new Error(`Reserve not found for reserve ${reserveAddress.toBase58()}`);
478
- }
479
-
480
- if (!reserve.state.config.tokenInfo.scopeConfiguration.priceFeed.equals(PublicKey.default)) {
481
- reserve.state.config.tokenInfo.scopeConfiguration.priceChain.map((x) => {
482
- if (x !== U16_MAX) {
483
- tokenIds.push(x);
484
- }
485
- });
486
- reserve.state.config.tokenInfo.scopeConfiguration.twapChain.map((x) => {
487
- if (x !== U16_MAX) {
488
- tokenIds.push(x);
489
- }
490
- });
491
- }
492
- }
493
-
494
- return tokenIds;
495
- }
496
-
497
- async addScopeRefreshIxs(tokens: number[], feed: string = 'hubble') {
498
- this.preTxnIxsLabels.unshift(`refreshScopePrices`);
499
- this.preTxnIxs.unshift(
500
- await this.kaminoMarket.scope.refreshPriceListIx(
431
+ async addScopeRefreshIxs(scope: Scope, tokens: number[], feed: string = 'hubble') {
432
+ this.setupIxsLabels.unshift(`refreshScopePrices`);
433
+ this.setupIxs.unshift(
434
+ await scope.refreshPriceListIx(
501
435
  {
502
436
  feed: feed,
503
437
  },
@@ -513,6 +447,7 @@ export class KaminoAction {
513
447
  owner: PublicKey,
514
448
  obligation: KaminoObligation | ObligationType,
515
449
  useV2Ixs: boolean,
450
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
516
451
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
517
452
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas,
518
453
  requestElevationGroup: boolean = false,
@@ -520,7 +455,6 @@ export class KaminoAction {
520
455
  createLookupTable: boolean = true,
521
456
  referrer: PublicKey = PublicKey.default,
522
457
  currentSlot: number = 0,
523
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' },
524
458
  overrideElevationGroupRequest: number | undefined = undefined // if set, when an elevationgroup request is made, it will use this value
525
459
  ) {
526
460
  const axn = await KaminoAction.initialize(
@@ -538,15 +472,16 @@ export class KaminoAction {
538
472
  axn.addComputeBudgetIxn(extraComputeBudget);
539
473
  }
540
474
 
541
- const allReserves = new PublicKeySet<PublicKey>([
542
- ...axn.depositReserves,
543
- ...axn.borrowReserves,
544
- axn.reserve.address,
545
- ]).toArray();
546
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
547
-
548
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
549
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
475
+ if (!axn.referrer.equals(PublicKey.default)) {
476
+ const referrerTokenState = referrerTokenStatePda(
477
+ axn.referrer,
478
+ axn.reserve.address,
479
+ axn.kaminoMarket.programId
480
+ )[0];
481
+ const account = await axn.kaminoMarket.getConnection().getAccountInfo(referrerTokenState);
482
+ if (!account) {
483
+ axn.addInitReferrerTokenStateIx(axn.reserve, referrerTokenState);
484
+ }
550
485
  }
551
486
 
552
487
  await axn.addSupportIxs(
@@ -556,6 +491,7 @@ export class KaminoAction {
556
491
  includeUserMetadata,
557
492
  addInitObligationForFarm,
558
493
  useV2Ixs,
494
+ scopeRefreshConfig,
559
495
  createLookupTable,
560
496
  undefined,
561
497
  overrideElevationGroupRequest
@@ -576,12 +512,12 @@ export class KaminoAction {
576
512
  mint: PublicKey,
577
513
  owner: PublicKey,
578
514
  obligation: KaminoObligation | ObligationType,
515
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
579
516
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
580
517
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas
581
518
  requestElevationGroup: boolean = false,
582
519
  referrer: PublicKey = PublicKey.default,
583
- currentSlot: number = 0,
584
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
520
+ currentSlot: number = 0
585
521
  ) {
586
522
  const axn = await KaminoAction.initialize(
587
523
  'mint',
@@ -599,17 +535,6 @@ export class KaminoAction {
599
535
  axn.addComputeBudgetIxn(extraComputeBudget);
600
536
  }
601
537
 
602
- const allReserves = new PublicKeySet<PublicKey>([
603
- ...axn.depositReserves,
604
- ...axn.borrowReserves,
605
- axn.reserve.address,
606
- ]).toArray();
607
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
608
-
609
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
610
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
611
- }
612
-
613
538
  await axn.addSupportIxs(
614
539
  'mint',
615
540
  includeAtaIxns,
@@ -617,6 +542,7 @@ export class KaminoAction {
617
542
  false,
618
543
  addInitObligationForFarm,
619
544
  false,
545
+ scopeRefreshConfig,
620
546
  false
621
547
  );
622
548
  axn.addDepositReserveLiquidityIx();
@@ -630,12 +556,12 @@ export class KaminoAction {
630
556
  mint: PublicKey,
631
557
  owner: PublicKey,
632
558
  obligation: KaminoObligation | ObligationType,
559
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
633
560
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
634
561
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas
635
562
  requestElevationGroup: boolean = false,
636
563
  referrer: PublicKey = PublicKey.default,
637
- currentSlot: number = 0,
638
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
564
+ currentSlot: number = 0
639
565
  ) {
640
566
  const axn = await KaminoAction.initialize(
641
567
  'redeem',
@@ -653,17 +579,6 @@ export class KaminoAction {
653
579
  axn.addComputeBudgetIxn(extraComputeBudget);
654
580
  }
655
581
 
656
- const allReserves = new PublicKeySet<PublicKey>([
657
- ...axn.depositReserves,
658
- ...axn.borrowReserves,
659
- axn.reserve.address,
660
- ]).toArray();
661
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
662
-
663
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
664
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
665
- }
666
-
667
582
  await axn.addSupportIxs(
668
583
  'redeem',
669
584
  includeAtaIxns,
@@ -671,6 +586,7 @@ export class KaminoAction {
671
586
  false,
672
587
  addInitObligationForFarm,
673
588
  false,
589
+ scopeRefreshConfig,
674
590
  false
675
591
  );
676
592
  axn.addRedeemReserveCollateralIx();
@@ -685,14 +601,14 @@ export class KaminoAction {
685
601
  owner: PublicKey,
686
602
  obligation: KaminoObligation | ObligationType,
687
603
  useV2Ixs: boolean,
604
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
688
605
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
689
606
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas
690
607
  requestElevationGroup: boolean = false,
691
608
  includeUserMetadata: boolean = true, // if true it includes user metadata
692
609
  createLookupTable: boolean = true,
693
610
  referrer: PublicKey = PublicKey.default,
694
- currentSlot: number = 0,
695
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
611
+ currentSlot: number = 0
696
612
  ) {
697
613
  const axn = await KaminoAction.initialize(
698
614
  'depositCollateral',
@@ -710,17 +626,6 @@ export class KaminoAction {
710
626
  axn.addComputeBudgetIxn(extraComputeBudget);
711
627
  }
712
628
 
713
- const allReserves = new PublicKeySet<PublicKey>([
714
- ...axn.depositReserves,
715
- ...axn.borrowReserves,
716
- axn.reserve.address,
717
- ]).toArray();
718
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
719
-
720
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
721
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
722
- }
723
-
724
629
  await axn.addSupportIxs(
725
630
  'depositCollateral',
726
631
  includeAtaIxns,
@@ -728,6 +633,7 @@ export class KaminoAction {
728
633
  includeUserMetadata,
729
634
  addInitObligationForFarm,
730
635
  useV2Ixs,
636
+ scopeRefreshConfig,
731
637
  createLookupTable
732
638
  );
733
639
  if (useV2Ixs) {
@@ -748,14 +654,14 @@ export class KaminoAction {
748
654
  payer: PublicKey,
749
655
  obligation: KaminoObligation | ObligationType,
750
656
  useV2Ixs: boolean,
657
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
751
658
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
752
659
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas,
753
660
  requestElevationGroup: boolean = false,
754
661
  includeUserMetadata: boolean = true, // if true it includes user metadata,
755
662
  createLookupTable: boolean = true,
756
663
  referrer: PublicKey = PublicKey.default,
757
- currentSlot: number = 0,
758
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
664
+ currentSlot: number = 0
759
665
  ) {
760
666
  const axn = await KaminoAction.initializeMultiTokenAction(
761
667
  kaminoMarket,
@@ -778,18 +684,17 @@ export class KaminoAction {
778
684
  axn.addComputeBudgetIxn(extraComputeBudget);
779
685
  }
780
686
 
781
- const allReserves = new PublicKeySet<PublicKey>([
782
- ...axn.depositReserves,
783
- ...axn.borrowReserves,
784
- axn.reserve.address,
785
- axn.outflowReserve!.address,
786
- ]).toArray();
787
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
788
-
789
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
790
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
687
+ if (!axn.referrer.equals(PublicKey.default)) {
688
+ const referrerTokenState = referrerTokenStatePda(
689
+ axn.referrer,
690
+ axn.outflowReserve!.address,
691
+ axn.kaminoMarket.programId
692
+ )[0];
693
+ const account = await axn.kaminoMarket.getConnection().getAccountInfo(referrerTokenState);
694
+ if (!account) {
695
+ axn.addInitReferrerTokenStateIx(axn.outflowReserve!, referrerTokenState);
696
+ }
791
697
  }
792
-
793
698
  await axn.addSupportIxs(
794
699
  'deposit',
795
700
  includeAtaIxns,
@@ -797,6 +702,7 @@ export class KaminoAction {
797
702
  includeUserMetadata,
798
703
  addInitObligationForFarmForDeposit,
799
704
  useV2Ixs,
705
+ undefined,
800
706
  createLookupTable,
801
707
  twoTokenAction
802
708
  );
@@ -814,6 +720,20 @@ export class KaminoAction {
814
720
  useV2Ixs
815
721
  );
816
722
  axn.addRefreshFarmsCleanupTxnIxsToCleanupIxs();
723
+
724
+ // Create the scope refresh ixn in here to ensure it's the first ixn in the txn
725
+ const allReserves = new PublicKeySet<PublicKey>([
726
+ ...axn.depositReserves,
727
+ ...axn.borrowReserves,
728
+ axn.reserve.address,
729
+ ...(axn.outflowReserve ? [axn.outflowReserve.address] : []),
730
+ ...(axn.preLoadedDepositReservesSameTx ? axn.preLoadedDepositReservesSameTx : []),
731
+ ]).toArray();
732
+ const tokenIds = getTokenIdsForScopeRefresh(axn.kaminoMarket, allReserves);
733
+
734
+ if (tokenIds.length > 0 && scopeRefreshConfig) {
735
+ await axn.addScopeRefreshIxs(scopeRefreshConfig.scope, tokenIds, scopeRefreshConfig.scopeFeed);
736
+ }
817
737
  return axn;
818
738
  }
819
739
 
@@ -827,13 +747,13 @@ export class KaminoAction {
827
747
  currentSlot: number,
828
748
  obligation: KaminoObligation | ObligationType,
829
749
  useV2Ixs: boolean,
750
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
830
751
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
831
752
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas,
832
753
  requestElevationGroup: boolean = false,
833
754
  includeUserMetadata: boolean = true, // if true it includes user metadata,
834
755
  createLookupTable: boolean = true,
835
- referrer: PublicKey = PublicKey.default,
836
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
756
+ referrer: PublicKey = PublicKey.default
837
757
  ) {
838
758
  const axn = await KaminoAction.initializeMultiTokenAction(
839
759
  kaminoMarket,
@@ -855,18 +775,6 @@ export class KaminoAction {
855
775
  axn.addComputeBudgetIxn(extraComputeBudget);
856
776
  }
857
777
 
858
- const allReserves = new PublicKeySet<PublicKey>([
859
- ...axn.depositReserves,
860
- ...axn.borrowReserves,
861
- axn.reserve.address,
862
- axn.outflowReserve!.address,
863
- ]).toArray();
864
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
865
-
866
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
867
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
868
- }
869
-
870
778
  await axn.addSupportIxs(
871
779
  'repay',
872
780
  includeAtaIxns,
@@ -874,6 +782,7 @@ export class KaminoAction {
874
782
  includeUserMetadata,
875
783
  addInitObligationForFarmForRepay,
876
784
  useV2Ixs,
785
+ undefined,
877
786
  createLookupTable,
878
787
  twoTokenAction
879
788
  );
@@ -893,6 +802,19 @@ export class KaminoAction {
893
802
  useV2Ixs
894
803
  );
895
804
  axn.addRefreshFarmsCleanupTxnIxsToCleanupIxs();
805
+ // Create the scope refresh ixn in here to ensure it's the first ixn in the txn
806
+ const allReserves = new PublicKeySet<PublicKey>([
807
+ ...axn.depositReserves,
808
+ ...axn.borrowReserves,
809
+ axn.reserve.address,
810
+ ...(axn.outflowReserve ? [axn.outflowReserve.address] : []),
811
+ ...(axn.preLoadedDepositReservesSameTx ? axn.preLoadedDepositReservesSameTx : []),
812
+ ]).toArray();
813
+ const tokenIds = getTokenIdsForScopeRefresh(axn.kaminoMarket, allReserves);
814
+
815
+ if (tokenIds.length > 0 && scopeRefreshConfig) {
816
+ await axn.addScopeRefreshIxs(scopeRefreshConfig.scope, tokenIds, scopeRefreshConfig.scopeFeed);
817
+ }
896
818
  return axn;
897
819
  }
898
820
 
@@ -903,6 +825,7 @@ export class KaminoAction {
903
825
  owner: PublicKey,
904
826
  obligation: KaminoObligation | ObligationType,
905
827
  useV2Ixs: boolean,
828
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
906
829
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
907
830
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas,
908
831
  requestElevationGroup: boolean = false, // to be requested *after* the withdraw
@@ -910,7 +833,6 @@ export class KaminoAction {
910
833
  createLookupTable: boolean = true,
911
834
  referrer: PublicKey = PublicKey.default,
912
835
  currentSlot: number = 0,
913
- scopeRefresh: ScopeRefresh | undefined = undefined,
914
836
  overrideElevationGroupRequest?: number,
915
837
  // Optional customizations which may be needed if the obligation was mutated by some previous ixn.
916
838
  obligationCustomizations?: {
@@ -936,17 +858,6 @@ export class KaminoAction {
936
858
 
937
859
  axn.depositReserves.push(...(obligationCustomizations?.addedDepositReserves || []));
938
860
 
939
- const allReserves = new PublicKeySet<PublicKey>([
940
- ...axn.depositReserves,
941
- ...axn.borrowReserves,
942
- axn.reserve.address,
943
- ]).toArray();
944
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
945
-
946
- if (tokenIds.length > 0 && scopeRefresh && scopeRefresh.includeScopeRefresh) {
947
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
948
- }
949
-
950
861
  await axn.addSupportIxs(
951
862
  'withdraw',
952
863
  includeAtaIxns,
@@ -954,6 +865,7 @@ export class KaminoAction {
954
865
  includeUserMetadata,
955
866
  addInitObligationForFarm,
956
867
  useV2Ixs,
868
+ scopeRefreshConfig,
957
869
  createLookupTable,
958
870
  false,
959
871
  overrideElevationGroupRequest
@@ -993,6 +905,7 @@ export class KaminoAction {
993
905
  owner: PublicKey,
994
906
  obligation: KaminoObligation | ObligationType,
995
907
  useV2Ixs: boolean,
908
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
996
909
  currentSlot: number,
997
910
  payer: PublicKey | undefined = undefined,
998
911
  extraComputeBudget: number = 1_000_000,
@@ -1000,8 +913,7 @@ export class KaminoAction {
1000
913
  requestElevationGroup: boolean = false,
1001
914
  includeUserMetadata: boolean = true,
1002
915
  createLookupTable: boolean = true,
1003
- referrer: PublicKey = PublicKey.default,
1004
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
916
+ referrer: PublicKey = PublicKey.default
1005
917
  ) {
1006
918
  const axn = await KaminoAction.initialize(
1007
919
  'repay',
@@ -1020,17 +932,6 @@ export class KaminoAction {
1020
932
  axn.addComputeBudgetIxn(extraComputeBudget);
1021
933
  }
1022
934
 
1023
- const allReserves = new PublicKeySet<PublicKey>([
1024
- ...axn.depositReserves,
1025
- ...axn.borrowReserves,
1026
- axn.reserve.address,
1027
- ]).toArray();
1028
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
1029
-
1030
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
1031
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
1032
- }
1033
-
1034
935
  await axn.addSupportIxs(
1035
936
  'repay',
1036
937
  includeAtaIxns,
@@ -1038,6 +939,7 @@ export class KaminoAction {
1038
939
  includeUserMetadata,
1039
940
  addInitObligationForFarm,
1040
941
  useV2Ixs,
942
+ scopeRefreshConfig,
1041
943
  createLookupTable
1042
944
  );
1043
945
  if (useV2Ixs) {
@@ -1060,6 +962,7 @@ export class KaminoAction {
1060
962
  obligationOwner: PublicKey,
1061
963
  obligation: KaminoObligation | ObligationType,
1062
964
  useV2Ixs: boolean,
965
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
1063
966
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
1064
967
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas, and creates all other token atas if they don't exist
1065
968
  requestElevationGroup: boolean = false,
@@ -1067,8 +970,7 @@ export class KaminoAction {
1067
970
  createLookupTable: boolean = true,
1068
971
  referrer: PublicKey = PublicKey.default,
1069
972
  maxAllowedLtvOverridePercent: number = 0,
1070
- currentSlot: number = 0,
1071
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
973
+ currentSlot: number = 0
1072
974
  ) {
1073
975
  const axn = await KaminoAction.initializeMultiTokenAction(
1074
976
  kaminoMarket,
@@ -1089,18 +991,6 @@ export class KaminoAction {
1089
991
  axn.addComputeBudgetIxn(extraComputeBudget);
1090
992
  }
1091
993
 
1092
- const allReserves = new PublicKeySet<PublicKey>([
1093
- ...axn.depositReserves,
1094
- ...axn.borrowReserves,
1095
- axn.reserve.address,
1096
- axn.outflowReserve!.address,
1097
- ]).toArray();
1098
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
1099
-
1100
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
1101
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
1102
- }
1103
-
1104
994
  await axn.addSupportIxs(
1105
995
  'liquidate',
1106
996
  includeAtaIxns,
@@ -1108,6 +998,7 @@ export class KaminoAction {
1108
998
  includeUserMetadata,
1109
999
  addInitObligationForFarm,
1110
1000
  useV2Ixs,
1001
+ scopeRefreshConfig,
1111
1002
  createLookupTable
1112
1003
  );
1113
1004
  if (useV2Ixs) {
@@ -1133,9 +1024,20 @@ export class KaminoAction {
1133
1024
  currentSlot
1134
1025
  );
1135
1026
 
1136
- axn.preTxnIxs.push(...createAtaIxs);
1137
- axn.preTxnIxsLabels.push(`createAtasIxs[${axn.userTokenAccountAddress.toString()}]`);
1027
+ axn.setupIxs.push(...createAtaIxs);
1028
+ axn.setupIxsLabels.push(`createAtasIxs[${axn.owner.toString()}]`);
1138
1029
 
1030
+ if (!axn.referrer.equals(PublicKey.default)) {
1031
+ const referrerTokenState = referrerTokenStatePda(
1032
+ axn.referrer,
1033
+ axn.reserve.address,
1034
+ axn.kaminoMarket.programId
1035
+ )[0];
1036
+ const account = await axn.kaminoMarket.getConnection().getAccountInfo(referrerTokenState);
1037
+ if (!account) {
1038
+ axn.addInitReferrerTokenStateIx(axn.reserve, referrerTokenState);
1039
+ }
1040
+ }
1139
1041
  axn.addRefreshReserveIxs([axn.reserve.address]);
1140
1042
  axn.addWithdrawReferrerFeesIxs();
1141
1043
 
@@ -1143,25 +1045,10 @@ export class KaminoAction {
1143
1045
  }
1144
1046
 
1145
1047
  async getTransactions() {
1146
- const txns: {
1147
- preLendingTxn: Transaction | null;
1148
- lendingTxn: Transaction | null;
1149
- postLendingTxn: Transaction | null;
1150
- } = {
1151
- preLendingTxn: null,
1152
- lendingTxn: null,
1153
- postLendingTxn: null,
1154
- };
1155
-
1156
- if (this.preTxnIxs.length) {
1157
- txns.preLendingTxn = new Transaction({
1158
- feePayer: this.owner,
1159
- recentBlockhash: (await this.kaminoMarket.getConnection().getLatestBlockhash()).blockhash,
1160
- }).add(...this.preTxnIxs);
1161
- }
1048
+ let txns: Transaction;
1162
1049
 
1163
1050
  if (this.lendingIxs.length === 2) {
1164
- txns.lendingTxn = new Transaction({
1051
+ txns = new Transaction({
1165
1052
  feePayer: this.owner,
1166
1053
  recentBlockhash: (await this.kaminoMarket.getConnection().getLatestBlockhash()).blockhash,
1167
1054
  }).add(
@@ -1172,30 +1059,19 @@ export class KaminoAction {
1172
1059
  ...this.cleanupIxs
1173
1060
  );
1174
1061
  } else {
1175
- txns.lendingTxn = new Transaction({
1062
+ txns = new Transaction({
1176
1063
  feePayer: this.owner,
1177
1064
  recentBlockhash: (await this.kaminoMarket.getConnection().getLatestBlockhash()).blockhash,
1178
1065
  }).add(...this.setupIxs, ...this.lendingIxs, ...this.cleanupIxs);
1179
1066
  }
1180
1067
 
1181
- if (this.postTxnIxs.length) {
1182
- txns.postLendingTxn = new Transaction({
1183
- feePayer: this.owner,
1184
- recentBlockhash: (await this.kaminoMarket.getConnection().getLatestBlockhash()).blockhash,
1185
- }).add(...this.postTxnIxs);
1186
- }
1187
-
1188
1068
  return txns;
1189
1069
  }
1190
1070
 
1191
1071
  async sendTransactions(sendTransaction: (txn: Transaction, connection: Connection) => Promise<TransactionSignature>) {
1192
1072
  const txns = await this.getTransactions();
1193
1073
 
1194
- await this.sendSingleTransaction(txns.preLendingTxn, sendTransaction);
1195
-
1196
- const signature = await this.sendSingleTransaction(txns.lendingTxn, sendTransaction);
1197
-
1198
- await this.sendSingleTransaction(txns.postLendingTxn, sendTransaction);
1074
+ const signature = await this.sendSingleTransaction(txns, sendTransaction);
1199
1075
 
1200
1076
  return signature;
1201
1077
  }
@@ -1220,11 +1096,7 @@ export class KaminoAction {
1220
1096
  ) {
1221
1097
  const txns = await this.getTransactions();
1222
1098
 
1223
- await this.simulateSingleTransaction(txns.preLendingTxn, sendTransaction);
1224
-
1225
- const signature = await this.simulateSingleTransaction(txns.lendingTxn, sendTransaction);
1226
-
1227
- await this.simulateSingleTransaction(txns.postLendingTxn, sendTransaction);
1099
+ const signature = await this.simulateSingleTransaction(txns, sendTransaction);
1228
1100
 
1229
1101
  return signature;
1230
1102
  }
@@ -1255,8 +1127,8 @@ export class KaminoAction {
1255
1127
  reserveLiquidityMint: this.reserve.getLiquidityMint(),
1256
1128
  reserveLiquiditySupply: this.reserve.state.liquidity.supplyVault,
1257
1129
  reserveCollateralMint: this.reserve.getCTokenMint(),
1258
- userSourceLiquidity: this.userTokenAccountAddress,
1259
- userDestinationCollateral: this.userCollateralAccountAddress,
1130
+ userSourceLiquidity: this.getUserTokenAccountAddress(this.reserve),
1131
+ userDestinationCollateral: this.getUserCollateralAccountAddress(this.reserve),
1260
1132
  collateralTokenProgram: TOKEN_PROGRAM_ID,
1261
1133
  liquidityTokenProgram: this.reserve.getLiquidityTokenProgram(),
1262
1134
  instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
@@ -1281,8 +1153,8 @@ export class KaminoAction {
1281
1153
  reserveLiquidityMint: this.reserve.getLiquidityMint(),
1282
1154
  reserveLiquiditySupply: this.reserve.state.liquidity.supplyVault,
1283
1155
  reserveCollateralMint: this.reserve.getCTokenMint(),
1284
- userSourceCollateral: this.userCollateralAccountAddress,
1285
- userDestinationLiquidity: this.userTokenAccountAddress,
1156
+ userSourceCollateral: this.getUserCollateralAccountAddress(this.reserve),
1157
+ userDestinationLiquidity: this.getUserTokenAccountAddress(this.reserve),
1286
1158
  collateralTokenProgram: TOKEN_PROGRAM_ID,
1287
1159
  liquidityTokenProgram: this.reserve.getLiquidityTokenProgram(),
1288
1160
  instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
@@ -1310,7 +1182,7 @@ export class KaminoAction {
1310
1182
  reserveLiquiditySupply: this.reserve.state.liquidity.supplyVault,
1311
1183
  reserveCollateralMint: this.reserve.getCTokenMint(),
1312
1184
  reserveDestinationDepositCollateral: this.reserve.state.collateral.supplyVault, // destinationCollateral
1313
- userSourceLiquidity: this.userTokenAccountAddress,
1185
+ userSourceLiquidity: this.getUserTokenAccountAddress(this.reserve),
1314
1186
  placeholderUserDestinationCollateral: this.kaminoMarket.programId,
1315
1187
  collateralTokenProgram: TOKEN_PROGRAM_ID,
1316
1188
  liquidityTokenProgram: this.reserve.getLiquidityTokenProgram(),
@@ -1324,8 +1196,8 @@ export class KaminoAction {
1324
1196
  addDepositIxV2() {
1325
1197
  const farmsAccounts = this.reserve.state.farmCollateral.equals(PublicKey.default)
1326
1198
  ? {
1327
- obligationFarmUserState: PROGRAM_ID,
1328
- reserveFarmState: PROGRAM_ID,
1199
+ obligationFarmUserState: this.kaminoMarket.programId,
1200
+ reserveFarmState: this.kaminoMarket.programId,
1329
1201
  }
1330
1202
  : {
1331
1203
  obligationFarmUserState: obligationFarmStatePda(
@@ -1352,7 +1224,7 @@ export class KaminoAction {
1352
1224
  reserveLiquiditySupply: this.reserve.state.liquidity.supplyVault,
1353
1225
  reserveCollateralMint: this.reserve.getCTokenMint(),
1354
1226
  reserveDestinationDepositCollateral: this.reserve.state.collateral.supplyVault, // destinationCollateral
1355
- userSourceLiquidity: this.userTokenAccountAddress,
1227
+ userSourceLiquidity: this.getUserTokenAccountAddress(this.reserve),
1356
1228
  placeholderUserDestinationCollateral: this.kaminoMarket.programId,
1357
1229
  collateralTokenProgram: TOKEN_PROGRAM_ID,
1358
1230
  liquidityTokenProgram: this.reserve.getLiquidityTokenProgram(),
@@ -1380,7 +1252,7 @@ export class KaminoAction {
1380
1252
  lendingMarket: this.kaminoMarket.getAddress(),
1381
1253
  depositReserve: this.reserve.address,
1382
1254
  reserveDestinationCollateral: this.reserve.state.collateral.supplyVault,
1383
- userSourceCollateral: this.userCollateralAccountAddress,
1255
+ userSourceCollateral: this.getUserCollateralAccountAddress(this.reserve),
1384
1256
  tokenProgram: TOKEN_PROGRAM_ID,
1385
1257
  instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
1386
1258
  },
@@ -1392,8 +1264,8 @@ export class KaminoAction {
1392
1264
  addDepositObligationCollateralIxV2() {
1393
1265
  const farmsAccounts = this.reserve.state.farmCollateral.equals(PublicKey.default)
1394
1266
  ? {
1395
- obligationFarmUserState: PROGRAM_ID,
1396
- reserveFarmState: PROGRAM_ID,
1267
+ obligationFarmUserState: this.kaminoMarket.programId,
1268
+ reserveFarmState: this.kaminoMarket.programId,
1397
1269
  }
1398
1270
  : {
1399
1271
  obligationFarmUserState: obligationFarmStatePda(
@@ -1416,7 +1288,7 @@ export class KaminoAction {
1416
1288
  lendingMarket: this.kaminoMarket.getAddress(),
1417
1289
  depositReserve: this.reserve.address,
1418
1290
  reserveDestinationCollateral: this.reserve.state.collateral.supplyVault,
1419
- userSourceCollateral: this.userCollateralAccountAddress,
1291
+ userSourceCollateral: this.getUserCollateralAccountAddress(this.reserve),
1420
1292
  tokenProgram: TOKEN_PROGRAM_ID,
1421
1293
  instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
1422
1294
  },
@@ -1451,7 +1323,7 @@ export class KaminoAction {
1451
1323
  borrowReserve: this.reserve.address,
1452
1324
  borrowReserveLiquidityMint: this.reserve.getLiquidityMint(),
1453
1325
  reserveSourceLiquidity: this.reserve.state.liquidity.supplyVault,
1454
- userDestinationLiquidity: this.userTokenAccountAddress,
1326
+ userDestinationLiquidity: this.getUserTokenAccountAddress(this.reserve),
1455
1327
  borrowReserveLiquidityFeeReceiver: this.reserve.state.liquidity.feeVault,
1456
1328
  referrerTokenState: referrerTokenStatePda(this.referrer, this.reserve.address, this.kaminoMarket.programId)[0],
1457
1329
  tokenProgram: this.reserve.getLiquidityTokenProgram(),
@@ -1477,8 +1349,8 @@ export class KaminoAction {
1477
1349
 
1478
1350
  const farmsAccounts = this.reserve.state.farmDebt.equals(PublicKey.default)
1479
1351
  ? {
1480
- obligationFarmUserState: PROGRAM_ID,
1481
- reserveFarmState: PROGRAM_ID,
1352
+ obligationFarmUserState: this.kaminoMarket.programId,
1353
+ reserveFarmState: this.kaminoMarket.programId,
1482
1354
  }
1483
1355
  : {
1484
1356
  obligationFarmUserState: obligationFarmStatePda(this.getObligationPda(), this.reserve.state.farmDebt)[0],
@@ -1498,7 +1370,7 @@ export class KaminoAction {
1498
1370
  borrowReserve: this.reserve.address,
1499
1371
  borrowReserveLiquidityMint: this.reserve.getLiquidityMint(),
1500
1372
  reserveSourceLiquidity: this.reserve.state.liquidity.supplyVault,
1501
- userDestinationLiquidity: this.userTokenAccountAddress,
1373
+ userDestinationLiquidity: this.getUserTokenAccountAddress(this.reserve),
1502
1374
  borrowReserveLiquidityFeeReceiver: this.reserve.state.liquidity.feeVault,
1503
1375
  referrerTokenState: referrerTokenStatePda(
1504
1376
  this.referrer,
@@ -1538,7 +1410,7 @@ export class KaminoAction {
1538
1410
  reserveCollateralMint: this.reserve.getCTokenMint(),
1539
1411
  reserveLiquiditySupply: this.reserve.state.liquidity.supplyVault,
1540
1412
  reserveSourceCollateral: this.reserve.state.collateral.supplyVault,
1541
- userDestinationLiquidity: this.userTokenAccountAddress,
1413
+ userDestinationLiquidity: this.getUserTokenAccountAddress(this.reserve),
1542
1414
  placeholderUserDestinationCollateral: this.kaminoMarket.programId,
1543
1415
  collateralTokenProgram: TOKEN_PROGRAM_ID,
1544
1416
  liquidityTokenProgram: this.reserve.getLiquidityTokenProgram(),
@@ -1552,8 +1424,8 @@ export class KaminoAction {
1552
1424
  async addWithdrawIxV2(collateralAmount: BN) {
1553
1425
  const farmsAccounts = this.reserve.state.farmCollateral.equals(PublicKey.default)
1554
1426
  ? {
1555
- obligationFarmUserState: PROGRAM_ID,
1556
- reserveFarmState: PROGRAM_ID,
1427
+ obligationFarmUserState: this.kaminoMarket.programId,
1428
+ reserveFarmState: this.kaminoMarket.programId,
1557
1429
  }
1558
1430
  : {
1559
1431
  obligationFarmUserState: obligationFarmStatePda(
@@ -1580,7 +1452,7 @@ export class KaminoAction {
1580
1452
  reserveCollateralMint: this.reserve.getCTokenMint(),
1581
1453
  reserveLiquiditySupply: this.reserve.state.liquidity.supplyVault,
1582
1454
  reserveSourceCollateral: this.reserve.state.collateral.supplyVault,
1583
- userDestinationLiquidity: this.userTokenAccountAddress,
1455
+ userDestinationLiquidity: this.getUserTokenAccountAddress(this.reserve),
1584
1456
  placeholderUserDestinationCollateral: this.kaminoMarket.programId,
1585
1457
  collateralTokenProgram: TOKEN_PROGRAM_ID,
1586
1458
  liquidityTokenProgram: this.reserve.getLiquidityTokenProgram(),
@@ -1616,7 +1488,7 @@ export class KaminoAction {
1616
1488
  lendingMarket: this.kaminoMarket.getAddress(),
1617
1489
  repayReserve: this.reserve.address,
1618
1490
  reserveLiquidityMint: this.reserve.getLiquidityMint(),
1619
- userSourceLiquidity: this.userTokenAccountAddress,
1491
+ userSourceLiquidity: this.getTokenAccountAddressByUser(this.reserve, this.payer),
1620
1492
  reserveDestinationLiquidity: this.reserve.state.liquidity.supplyVault,
1621
1493
  tokenProgram: this.reserve.getLiquidityTokenProgram(),
1622
1494
  instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
@@ -1639,8 +1511,8 @@ export class KaminoAction {
1639
1511
 
1640
1512
  const farmsAccounts = this.reserve.state.farmDebt.equals(PublicKey.default)
1641
1513
  ? {
1642
- obligationFarmUserState: PROGRAM_ID,
1643
- reserveFarmState: PROGRAM_ID,
1514
+ obligationFarmUserState: this.kaminoMarket.programId,
1515
+ reserveFarmState: this.kaminoMarket.programId,
1644
1516
  }
1645
1517
  : {
1646
1518
  obligationFarmUserState: obligationFarmStatePda(this.getObligationPda(), this.reserve.state.farmDebt)[0],
@@ -1661,7 +1533,7 @@ export class KaminoAction {
1661
1533
  lendingMarket: this.kaminoMarket.getAddress(),
1662
1534
  repayReserve: this.reserve.address,
1663
1535
  reserveLiquidityMint: this.reserve.getLiquidityMint(),
1664
- userSourceLiquidity: this.userTokenAccountAddress,
1536
+ userSourceLiquidity: this.getTokenAccountAddressByUser(this.reserve, this.payer),
1665
1537
  reserveDestinationLiquidity: this.reserve.state.liquidity.supplyVault,
1666
1538
  tokenProgram: this.reserve.getLiquidityTokenProgram(),
1667
1539
  instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
@@ -1697,7 +1569,7 @@ export class KaminoAction {
1697
1569
  reserveLiquiditySupply: this.reserve.state.liquidity.supplyVault,
1698
1570
  reserveCollateralMint: this.reserve.getCTokenMint(),
1699
1571
  reserveDestinationDepositCollateral: this.reserve.state.collateral.supplyVault, // destinationCollateral
1700
- userSourceLiquidity: this.userTokenAccountAddress,
1572
+ userSourceLiquidity: this.getUserTokenAccountAddress(this.reserve),
1701
1573
  placeholderUserDestinationCollateral: this.kaminoMarket.programId,
1702
1574
  collateralTokenProgram: TOKEN_PROGRAM_ID,
1703
1575
  liquidityTokenProgram: this.reserve.getLiquidityTokenProgram(),
@@ -1711,10 +1583,6 @@ export class KaminoAction {
1711
1583
  throw new Error(`outflowReserve not set`);
1712
1584
  }
1713
1585
 
1714
- if (!this.additionalTokenAccountAddress) {
1715
- throw new Error(`additionalTokenAccountAddress not set`);
1716
- }
1717
-
1718
1586
  if (!this.outflowAmount) {
1719
1587
  throw new Error(`outflowAmount not set`);
1720
1588
  }
@@ -1739,7 +1607,7 @@ export class KaminoAction {
1739
1607
  borrowReserve: this.outflowReserve.address,
1740
1608
  borrowReserveLiquidityMint: this.outflowReserve.getLiquidityMint(),
1741
1609
  reserveSourceLiquidity: this.outflowReserve.state.liquidity.supplyVault,
1742
- userDestinationLiquidity: this.additionalTokenAccountAddress,
1610
+ userDestinationLiquidity: this.getUserTokenAccountAddress(this.outflowReserve),
1743
1611
  borrowReserveLiquidityFeeReceiver: this.outflowReserve.state.liquidity.feeVault,
1744
1612
  referrerTokenState: referrerTokenStatePda(
1745
1613
  this.referrer,
@@ -1760,8 +1628,8 @@ export class KaminoAction {
1760
1628
  async addDepositAndBorrowIxV2() {
1761
1629
  const collateralFarmsAccounts = this.reserve.state.farmCollateral.equals(PublicKey.default)
1762
1630
  ? {
1763
- obligationFarmUserState: PROGRAM_ID,
1764
- reserveFarmState: PROGRAM_ID,
1631
+ obligationFarmUserState: this.kaminoMarket.programId,
1632
+ reserveFarmState: this.kaminoMarket.programId,
1765
1633
  }
1766
1634
  : {
1767
1635
  obligationFarmUserState: obligationFarmStatePda(
@@ -1789,7 +1657,7 @@ export class KaminoAction {
1789
1657
  reserveLiquiditySupply: this.reserve.state.liquidity.supplyVault,
1790
1658
  reserveCollateralMint: this.reserve.getCTokenMint(),
1791
1659
  reserveDestinationDepositCollateral: this.reserve.state.collateral.supplyVault, // destinationCollateral
1792
- userSourceLiquidity: this.userTokenAccountAddress,
1660
+ userSourceLiquidity: this.getUserTokenAccountAddress(this.reserve),
1793
1661
  placeholderUserDestinationCollateral: this.kaminoMarket.programId,
1794
1662
  collateralTokenProgram: TOKEN_PROGRAM_ID,
1795
1663
  liquidityTokenProgram: this.reserve.getLiquidityTokenProgram(),
@@ -1806,10 +1674,6 @@ export class KaminoAction {
1806
1674
  throw new Error(`outflowReserve not set`);
1807
1675
  }
1808
1676
 
1809
- if (!this.additionalTokenAccountAddress) {
1810
- throw new Error(`additionalTokenAccountAddress not set`);
1811
- }
1812
-
1813
1677
  if (!this.outflowAmount) {
1814
1678
  throw new Error(`outflowAmount not set`);
1815
1679
  }
@@ -1824,8 +1688,8 @@ export class KaminoAction {
1824
1688
 
1825
1689
  const debtFarmsAccounts = this.outflowReserve.state.farmDebt.equals(PublicKey.default)
1826
1690
  ? {
1827
- obligationFarmUserState: PROGRAM_ID,
1828
- reserveFarmState: PROGRAM_ID,
1691
+ obligationFarmUserState: this.kaminoMarket.programId,
1692
+ reserveFarmState: this.kaminoMarket.programId,
1829
1693
  }
1830
1694
  : {
1831
1695
  obligationFarmUserState: obligationFarmStatePda(
@@ -1848,7 +1712,7 @@ export class KaminoAction {
1848
1712
  borrowReserve: this.outflowReserve.address,
1849
1713
  borrowReserveLiquidityMint: this.outflowReserve.getLiquidityMint(),
1850
1714
  reserveSourceLiquidity: this.outflowReserve.state.liquidity.supplyVault,
1851
- userDestinationLiquidity: this.additionalTokenAccountAddress,
1715
+ userDestinationLiquidity: this.getUserTokenAccountAddress(this.outflowReserve),
1852
1716
  borrowReserveLiquidityFeeReceiver: this.outflowReserve.state.liquidity.feeVault,
1853
1717
  referrerTokenState: referrerTokenStatePda(
1854
1718
  this.referrer,
@@ -1890,7 +1754,7 @@ export class KaminoAction {
1890
1754
  lendingMarket: this.kaminoMarket.getAddress(),
1891
1755
  repayReserve: this.reserve!.address,
1892
1756
  reserveLiquidityMint: this.reserve.getLiquidityMint(),
1893
- userSourceLiquidity: this.userTokenAccountAddress,
1757
+ userSourceLiquidity: this.getUserTokenAccountAddress(this.reserve),
1894
1758
  reserveDestinationLiquidity: this.reserve.state.liquidity.supplyVault,
1895
1759
  tokenProgram: this.reserve.getLiquidityTokenProgram(),
1896
1760
  instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
@@ -1905,10 +1769,6 @@ export class KaminoAction {
1905
1769
  throw new Error(`outflowReserve not set`);
1906
1770
  }
1907
1771
 
1908
- if (!this.additionalTokenAccountAddress) {
1909
- throw new Error(`additionalTokenAccountAddress not set`);
1910
- }
1911
-
1912
1772
  if (!this.outflowAmount) {
1913
1773
  throw new Error(`outflowAmount not set`);
1914
1774
  }
@@ -1928,7 +1788,7 @@ export class KaminoAction {
1928
1788
  reserveCollateralMint: this.outflowReserve.getCTokenMint(),
1929
1789
  reserveLiquiditySupply: this.outflowReserve.state.liquidity.supplyVault,
1930
1790
  reserveSourceCollateral: this.outflowReserve.state.collateral.supplyVault,
1931
- userDestinationLiquidity: this.additionalTokenAccountAddress,
1791
+ userDestinationLiquidity: this.getUserTokenAccountAddress(this.outflowReserve),
1932
1792
  placeholderUserDestinationCollateral: this.kaminoMarket.programId,
1933
1793
  collateralTokenProgram: TOKEN_PROGRAM_ID,
1934
1794
  liquidityTokenProgram: this.outflowReserve.getLiquidityTokenProgram(),
@@ -1953,8 +1813,8 @@ export class KaminoAction {
1953
1813
 
1954
1814
  const debtFarmsAccounts = this.reserve.state.farmDebt.equals(PublicKey.default)
1955
1815
  ? {
1956
- obligationFarmUserState: PROGRAM_ID,
1957
- reserveFarmState: PROGRAM_ID,
1816
+ obligationFarmUserState: this.kaminoMarket.programId,
1817
+ reserveFarmState: this.kaminoMarket.programId,
1958
1818
  }
1959
1819
  : {
1960
1820
  obligationFarmUserState: obligationFarmStatePda(this.getObligationPda(), this.reserve.state.farmDebt)[0],
@@ -1972,7 +1832,7 @@ export class KaminoAction {
1972
1832
  lendingMarket: this.kaminoMarket.getAddress(),
1973
1833
  repayReserve: this.reserve!.address,
1974
1834
  reserveLiquidityMint: this.reserve.getLiquidityMint(),
1975
- userSourceLiquidity: this.userTokenAccountAddress,
1835
+ userSourceLiquidity: this.getUserTokenAccountAddress(this.reserve),
1976
1836
  reserveDestinationLiquidity: this.reserve.state.liquidity.supplyVault,
1977
1837
  tokenProgram: this.reserve.getLiquidityTokenProgram(),
1978
1838
  instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
@@ -1991,18 +1851,14 @@ export class KaminoAction {
1991
1851
  throw new Error(`outflowReserve not set`);
1992
1852
  }
1993
1853
 
1994
- if (!this.additionalTokenAccountAddress) {
1995
- throw new Error(`additionalTokenAccountAddress not set`);
1996
- }
1997
-
1998
1854
  if (!this.outflowAmount) {
1999
1855
  throw new Error(`outflowAmount not set`);
2000
1856
  }
2001
1857
 
2002
1858
  const collateralFarmsAccounts = this.outflowReserve.state.farmCollateral.equals(PublicKey.default)
2003
1859
  ? {
2004
- obligationFarmUserState: PROGRAM_ID,
2005
- reserveFarmState: PROGRAM_ID,
1860
+ obligationFarmUserState: this.kaminoMarket.programId,
1861
+ reserveFarmState: this.kaminoMarket.programId,
2006
1862
  }
2007
1863
  : {
2008
1864
  obligationFarmUserState: obligationFarmStatePda(
@@ -2028,7 +1884,7 @@ export class KaminoAction {
2028
1884
  reserveCollateralMint: this.outflowReserve.getCTokenMint(),
2029
1885
  reserveLiquiditySupply: this.outflowReserve.state.liquidity.supplyVault,
2030
1886
  reserveSourceCollateral: this.outflowReserve.state.collateral.supplyVault,
2031
- userDestinationLiquidity: this.additionalTokenAccountAddress,
1887
+ userDestinationLiquidity: this.getUserTokenAccountAddress(this.outflowReserve),
2032
1888
  placeholderUserDestinationCollateral: this.kaminoMarket.programId,
2033
1889
  collateralTokenProgram: TOKEN_PROGRAM_ID,
2034
1890
  liquidityTokenProgram: this.outflowReserve.getLiquidityTokenProgram(),
@@ -2047,9 +1903,6 @@ export class KaminoAction {
2047
1903
  if (!this.outflowReserve) {
2048
1904
  throw Error(`Withdraw reserve during liquidation is not defined`);
2049
1905
  }
2050
- if (!this.additionalTokenAccountAddress) {
2051
- throw Error(`Liquidating token account address is not defined`);
2052
- }
2053
1906
 
2054
1907
  const depositReservesList = this.getAdditionalDepositReservesList();
2055
1908
  const depositReserveAccountMetas = depositReservesList.map((reserve) => {
@@ -2076,9 +1929,9 @@ export class KaminoAction {
2076
1929
  withdrawReserveCollateralMint: this.outflowReserve.getCTokenMint(),
2077
1930
  withdrawReserveCollateralSupply: this.outflowReserve.state.collateral.supplyVault,
2078
1931
  withdrawReserveLiquiditySupply: this.outflowReserve.state.liquidity.supplyVault,
2079
- userSourceLiquidity: this.additionalTokenAccountAddress,
2080
- userDestinationCollateral: this.userCollateralAccountAddress,
2081
- userDestinationLiquidity: this.userTokenAccountAddress,
1932
+ userSourceLiquidity: this.getUserTokenAccountAddress(this.reserve),
1933
+ userDestinationCollateral: this.getUserCollateralAccountAddress(this.outflowReserve),
1934
+ userDestinationLiquidity: this.getUserTokenAccountAddress(this.outflowReserve),
2082
1935
  withdrawReserveLiquidityFeeReceiver: this.outflowReserve.state.liquidity.feeVault,
2083
1936
  collateralTokenProgram: TOKEN_PROGRAM_ID,
2084
1937
  repayLiquidityTokenProgram: this.reserve.getLiquidityTokenProgram(),
@@ -2099,9 +1952,6 @@ export class KaminoAction {
2099
1952
  if (!this.outflowReserve) {
2100
1953
  throw Error(`Withdraw reserve during liquidation is not defined`);
2101
1954
  }
2102
- if (!this.additionalTokenAccountAddress) {
2103
- throw Error(`Liquidating token account address is not defined`);
2104
- }
2105
1955
 
2106
1956
  const depositReservesList = this.getAdditionalDepositReservesList();
2107
1957
  const depositReserveAccountMetas = depositReservesList.map((reserve) => {
@@ -2110,8 +1960,8 @@ export class KaminoAction {
2110
1960
 
2111
1961
  const collateralFarmsAccounts = this.outflowReserve.state.farmCollateral.equals(PublicKey.default)
2112
1962
  ? {
2113
- obligationFarmUserState: PROGRAM_ID,
2114
- reserveFarmState: PROGRAM_ID,
1963
+ obligationFarmUserState: this.kaminoMarket.programId,
1964
+ reserveFarmState: this.kaminoMarket.programId,
2115
1965
  }
2116
1966
  : {
2117
1967
  obligationFarmUserState: obligationFarmStatePda(
@@ -2123,8 +1973,8 @@ export class KaminoAction {
2123
1973
 
2124
1974
  const debtFarmsAccounts = this.reserve.state.farmDebt.equals(PublicKey.default)
2125
1975
  ? {
2126
- obligationFarmUserState: PROGRAM_ID,
2127
- reserveFarmState: PROGRAM_ID,
1976
+ obligationFarmUserState: this.kaminoMarket.programId,
1977
+ reserveFarmState: this.kaminoMarket.programId,
2128
1978
  }
2129
1979
  : {
2130
1980
  obligationFarmUserState: obligationFarmStatePda(this.getObligationPda(), this.reserve.state.farmDebt)[0],
@@ -2152,9 +2002,9 @@ export class KaminoAction {
2152
2002
  withdrawReserveCollateralMint: this.outflowReserve.getCTokenMint(),
2153
2003
  withdrawReserveCollateralSupply: this.outflowReserve.state.collateral.supplyVault,
2154
2004
  withdrawReserveLiquiditySupply: this.outflowReserve.state.liquidity.supplyVault,
2155
- userSourceLiquidity: this.additionalTokenAccountAddress,
2156
- userDestinationCollateral: this.userCollateralAccountAddress,
2157
- userDestinationLiquidity: this.userTokenAccountAddress,
2005
+ userSourceLiquidity: this.getUserTokenAccountAddress(this.reserve),
2006
+ userDestinationCollateral: this.getUserCollateralAccountAddress(this.outflowReserve),
2007
+ userDestinationLiquidity: this.getUserTokenAccountAddress(this.outflowReserve),
2158
2008
  withdrawReserveLiquidityFeeReceiver: this.outflowReserve.state.liquidity.feeVault,
2159
2009
  collateralTokenProgram: TOKEN_PROGRAM_ID,
2160
2010
  repayLiquidityTokenProgram: this.reserve.getLiquidityTokenProgram(),
@@ -2500,6 +2350,7 @@ export class KaminoAction {
2500
2350
  includeUserMetadata: boolean,
2501
2351
  addInitObligationForFarm: boolean,
2502
2352
  useV2Ixs: boolean,
2353
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
2503
2354
  createLookupTable: boolean,
2504
2355
  twoTokenAction: boolean = false,
2505
2356
  overrideElevationGroupRequest?: number
@@ -2520,13 +2371,6 @@ export class KaminoAction {
2520
2371
  this.addInitUserMetadataIxs(lookupTable);
2521
2372
  }
2522
2373
 
2523
- if (['borrow', 'withdrawReferrerFees'].includes(action)) {
2524
- await this.addInitReferrerTokenStateIx(this.reserve);
2525
- }
2526
- // depositAndBorrow
2527
- if (action === 'deposit' && this.outflowReserve) {
2528
- await this.addInitReferrerTokenStateIx(this.outflowReserve);
2529
- }
2530
2374
  await this.addInitObligationIxs();
2531
2375
  }
2532
2376
 
@@ -2540,6 +2384,19 @@ export class KaminoAction {
2540
2384
  twoTokenAction,
2541
2385
  overrideElevationGroupRequest
2542
2386
  );
2387
+
2388
+ const allReserves = new PublicKeySet<PublicKey>([
2389
+ ...this.depositReserves,
2390
+ ...this.borrowReserves,
2391
+ this.reserve.address,
2392
+ ...(this.outflowReserve ? [this.outflowReserve.address] : []),
2393
+ ...(this.preLoadedDepositReservesSameTx ? this.preLoadedDepositReservesSameTx : []),
2394
+ ]).toArray();
2395
+ const tokenIds = getTokenIdsForScopeRefresh(this.kaminoMarket, allReserves);
2396
+
2397
+ if (tokenIds.length > 0 && scopeRefreshConfig) {
2398
+ await this.addScopeRefreshIxs(scopeRefreshConfig.scope, tokenIds, scopeRefreshConfig.scopeFeed);
2399
+ }
2543
2400
  }
2544
2401
 
2545
2402
  private static optionalAccount(pubkey: PublicKey, programId: PublicKey = PROGRAM_ID): PublicKey {
@@ -2948,29 +2805,21 @@ export class KaminoAction {
2948
2805
  this.setupIxsLabels.push(`initUserMetadata[${userMetadataAddress.toString()}]`);
2949
2806
  }
2950
2807
 
2951
- private async addInitReferrerTokenStateIx(reserve: KaminoReserve) {
2952
- if (this.referrer.equals(PublicKey.default)) {
2953
- return;
2954
- }
2955
-
2956
- const referrerTokenState = referrerTokenStatePda(this.referrer, reserve.address, this.kaminoMarket.programId)[0];
2957
- const account = await this.kaminoMarket.getConnection().getAccountInfo(referrerTokenState);
2958
- if (!account) {
2959
- const initReferrerTokenStateIx = initReferrerTokenState(
2960
- {
2961
- lendingMarket: this.kaminoMarket.getAddress(),
2962
- payer: this.owner,
2963
- reserve: reserve.address,
2964
- referrer: this.referrer,
2965
- referrerTokenState,
2966
- rent: SYSVAR_RENT_PUBKEY,
2967
- systemProgram: SystemProgram.programId,
2968
- },
2969
- this.kaminoMarket.programId
2970
- );
2971
- this.setupIxs.unshift(initReferrerTokenStateIx);
2972
- this.setupIxsLabels.unshift(`InitReferrerTokenState[${referrerTokenState.toString()} res=${reserve.address}]`);
2973
- }
2808
+ private addInitReferrerTokenStateIx(reserve: KaminoReserve, referrerTokenState: PublicKey) {
2809
+ const initReferrerTokenStateIx = initReferrerTokenState(
2810
+ {
2811
+ lendingMarket: this.kaminoMarket.getAddress(),
2812
+ payer: this.owner,
2813
+ reserve: reserve.address,
2814
+ referrer: this.referrer,
2815
+ referrerTokenState,
2816
+ rent: SYSVAR_RENT_PUBKEY,
2817
+ systemProgram: SystemProgram.programId,
2818
+ },
2819
+ this.kaminoMarket.programId
2820
+ );
2821
+ this.setupIxs.unshift(initReferrerTokenStateIx);
2822
+ this.setupIxsLabels.unshift(`InitReferrerTokenState[${referrerTokenState.toString()} res=${reserve.address}]`);
2974
2823
  }
2975
2824
 
2976
2825
  private addWithdrawReferrerFeesIxs() {
@@ -2988,7 +2837,7 @@ export class KaminoAction {
2988
2837
  reserveLiquidityMint: this.reserve.getLiquidityMint(),
2989
2838
  referrerTokenState: referrerTokenStateAddress,
2990
2839
  reserveSupplyLiquidity: this.reserve.state.liquidity.supplyVault,
2991
- referrerTokenAccount: this.userTokenAccountAddress,
2840
+ referrerTokenAccount: this.getUserTokenAccountAddress(this.reserve),
2992
2841
  lendingMarketAuthority: this.kaminoMarket.getLendingMarketAuthority(),
2993
2842
  tokenProgram: this.reserve.getLiquidityTokenProgram(),
2994
2843
  },
@@ -3015,7 +2864,7 @@ export class KaminoAction {
3015
2864
  this.reserve.getLiquidityMint(),
3016
2865
  this.owner,
3017
2866
  this.reserve.getLiquidityTokenProgram(),
3018
- this.userTokenAccountAddress
2867
+ this.getUserTokenAccountAddress(this.reserve)
3019
2868
  );
3020
2869
 
3021
2870
  this.setupIxs.unshift(createUserTokenAccountIx);
@@ -3024,7 +2873,7 @@ export class KaminoAction {
3024
2873
 
3025
2874
  if (action === 'liquidate') {
3026
2875
  if (!this.outflowReserve) {
3027
- throw new Error(`Outflow reserve state not found ${this.mint}`);
2876
+ throw new Error(`Outflow reserve state not found ${this.secondaryMint}`);
3028
2877
  }
3029
2878
 
3030
2879
  const [, createUserTokenAccountIx] = createAssociatedTokenAccountIdempotentInstruction(
@@ -3032,40 +2881,36 @@ export class KaminoAction {
3032
2881
  this.outflowReserve.getLiquidityMint(),
3033
2882
  this.owner,
3034
2883
  this.outflowReserve.getLiquidityTokenProgram(),
3035
- this.userTokenAccountAddress
2884
+ this.getUserTokenAccountAddress(this.outflowReserve)
3036
2885
  );
3037
2886
 
3038
2887
  this.setupIxs.unshift(createUserTokenAccountIx);
3039
- this.setupIxsLabels.unshift(`CreateUserAta[${this.userTokenAccountAddress.toBase58()}]`);
2888
+ this.setupIxsLabels.unshift(`CreateUserAta[${this.getUserTokenAccountAddress(this.outflowReserve).toBase58()}]`);
3040
2889
 
3041
2890
  const [, createUserCollateralAccountIx] = createAssociatedTokenAccountIdempotentInstruction(
3042
2891
  this.owner,
3043
2892
  this.outflowReserve.getCTokenMint(),
3044
2893
  this.owner,
3045
2894
  TOKEN_PROGRAM_ID,
3046
- this.userCollateralAccountAddress
2895
+ this.getUserCollateralAccountAddress(this.outflowReserve)
3047
2896
  );
3048
2897
 
3049
2898
  this.setupIxs.unshift(createUserCollateralAccountIx);
3050
- this.setupIxsLabels.unshift(`CreateCollateralUserAta[${this.userCollateralAccountAddress.toString()}]`);
3051
-
3052
- if (!this.additionalTokenAccountAddress) {
3053
- throw new Error(`Additional token account address not found ${this.mint}`);
3054
- }
2899
+ this.setupIxsLabels.unshift(
2900
+ `CreateCollateralUserAta[${this.getUserCollateralAccountAddress(this.outflowReserve).toString()}]`
2901
+ );
3055
2902
  }
3056
2903
 
3057
2904
  if (action === 'depositAndBorrow' || (action === 'repayAndWithdraw' && !this.secondaryMint?.equals(NATIVE_MINT))) {
3058
- if (!this.additionalTokenAccountAddress) {
3059
- throw new Error(`Additional token account address not found ${this.secondaryMint}`);
3060
- }
3061
-
3062
2905
  if (!this.outflowReserve) {
3063
2906
  throw new Error(`Outflow reserve state not found ${this.mint}`);
3064
2907
  }
3065
2908
 
2909
+ const additionalUserTokenAccountAddress = this.getUserTokenAccountAddress(this.outflowReserve);
2910
+
3066
2911
  const additionalUserTokenAccountInfo = await this.kaminoMarket
3067
2912
  .getConnection()
3068
- .getAccountInfo(this.additionalTokenAccountAddress);
2913
+ .getAccountInfo(additionalUserTokenAccountAddress);
3069
2914
 
3070
2915
  if (!additionalUserTokenAccountInfo) {
3071
2916
  const [, createUserTokenAccountIx] = createAssociatedTokenAccountIdempotentInstruction(
@@ -3073,7 +2918,7 @@ export class KaminoAction {
3073
2918
  this.outflowReserve.getLiquidityMint(),
3074
2919
  this.owner,
3075
2920
  this.outflowReserve.getLiquidityTokenProgram(),
3076
- this.additionalTokenAccountAddress
2921
+ additionalUserTokenAccountAddress
3077
2922
  );
3078
2923
 
3079
2924
  this.setupIxs.unshift(createUserTokenAccountIx);
@@ -3087,23 +2932,24 @@ export class KaminoAction {
3087
2932
  this.reserve.getLiquidityMint(),
3088
2933
  this.owner,
3089
2934
  this.reserve.getLiquidityTokenProgram(),
3090
- this.userTokenAccountAddress
2935
+ this.getUserTokenAccountAddress(this.reserve)
3091
2936
  );
3092
- this.preTxnIxs.push(createUserTokenAccountIx);
3093
- this.preTxnIxsLabels.push(`CreateUserAta[${this.userTokenAccountAddress.toBase58()}]`);
2937
+ this.setupIxs.unshift(createUserTokenAccountIx);
2938
+ this.setupIxsLabels.unshift(`CreateUserAta[${this.getUserTokenAccountAddress(this.reserve).toBase58()}]`);
3094
2939
  }
3095
2940
  if (action === 'mint') {
3096
- const collateralMintPubkey = this.reserve.getCTokenMint();
3097
2941
  const [, createUserCollateralAccountIx] = createAssociatedTokenAccountIdempotentInstruction(
3098
2942
  this.owner,
3099
- collateralMintPubkey,
2943
+ this.reserve.getCTokenMint(),
3100
2944
  this.owner,
3101
2945
  TOKEN_PROGRAM_ID,
3102
- this.userCollateralAccountAddress
2946
+ this.getUserCollateralAccountAddress(this.reserve)
3103
2947
  );
3104
2948
 
3105
2949
  this.setupIxs.unshift(createUserCollateralAccountIx);
3106
- this.setupIxsLabels.unshift(`CreateCollateralUserAta[${this.userCollateralAccountAddress.toString()}]`);
2950
+ this.setupIxsLabels.unshift(
2951
+ `CreateCollateralUserAta[${this.getUserCollateralAccountAddress(this.reserve).toString()}]`
2952
+ );
3107
2953
  }
3108
2954
  }
3109
2955
 
@@ -3145,12 +2991,14 @@ export class KaminoAction {
3145
2991
  );
3146
2992
  }
3147
2993
 
3148
- let userTokenAccountAddress = this.userTokenAccountAddress;
2994
+ let userTokenAccountAddress = this.getUserTokenAccountAddress(this.reserve);
3149
2995
  if (this.secondaryMint?.equals(NATIVE_MINT)) {
3150
- if (!this.additionalTokenAccountAddress) {
3151
- throw new Error(`Additional token account address not found ${this.secondaryMint}`);
2996
+ if (!this.outflowReserve) {
2997
+ throw new Error(`Outflow reserve state not found ${this.secondaryMint}`);
3152
2998
  }
3153
- userTokenAccountAddress = this.additionalTokenAccountAddress;
2999
+
3000
+ const additionalUserTokenAccountAddress = this.getUserTokenAccountAddress(this.outflowReserve);
3001
+ userTokenAccountAddress = additionalUserTokenAccountAddress;
3154
3002
  }
3155
3003
 
3156
3004
  const userWSOLAccountInfo = await this.kaminoMarket.getConnection().getAccountInfo(userTokenAccountAddress);
@@ -3162,7 +3010,7 @@ export class KaminoAction {
3162
3010
  action === 'deposit' ||
3163
3011
  action === 'repay' ||
3164
3012
  action === 'mint' ||
3165
- (action === 'liquidate' && this.secondaryMint?.equals(NATIVE_MINT)); // only sync WSOL amount if liquidator repays SOL which is secondaryMint
3013
+ (action === 'liquidate' && this.mint?.equals(NATIVE_MINT)); // only sync WSOL amount if liquidator repays SOL which is secondaryMint
3166
3014
 
3167
3015
  const transferLamportsIx = SystemProgram.transfer({
3168
3016
  fromPubkey: this.owner,
@@ -3231,16 +3079,6 @@ export class KaminoAction {
3231
3079
  throw new Error('reserve states are not fetched');
3232
3080
  }
3233
3081
 
3234
- const {
3235
- userTokenAccountAddress: userOutflowTokenAccountAddress,
3236
- userCollateralAccountAddress: userOutflowCollateralAccountAddress,
3237
- } = KaminoAction.getUserAccountAddresses(payer, outflowReserve.state);
3238
-
3239
- const {
3240
- userTokenAccountAddress: userInflowTokenAccountAddress,
3241
- userCollateralAccountAddress: userInflowCollateralAccountAddress,
3242
- } = KaminoAction.getUserAccountAddresses(payer, inflowReserve.state);
3243
-
3244
3082
  const { kaminoObligation, depositReserves, borrowReserves, distinctReserveCount } =
3245
3083
  await KaminoAction.loadObligation(
3246
3084
  action,
@@ -3252,30 +3090,12 @@ export class KaminoAction {
3252
3090
  );
3253
3091
  const referrerKey = await this.getReferrerKey(kaminoMarket, payer, kaminoObligation, referrer);
3254
3092
 
3255
- let userTokenAccountAddress: PublicKey;
3256
- let userCollateralAccountAddress: PublicKey;
3257
- let additionalUserTokenAccountAddress: PublicKey;
3258
3093
  let secondaryMint: PublicKey;
3259
3094
  let primaryMint: PublicKey;
3260
3095
 
3261
- if (action === 'liquidate') {
3262
- userTokenAccountAddress = userOutflowTokenAccountAddress;
3263
- userCollateralAccountAddress = userOutflowCollateralAccountAddress;
3264
- additionalUserTokenAccountAddress = userInflowTokenAccountAddress;
3265
- primaryMint = outflowTokenMint;
3266
- secondaryMint = inflowTokenMint;
3267
- } else if (action === 'depositAndBorrow') {
3268
- userTokenAccountAddress = userInflowTokenAccountAddress;
3269
- userCollateralAccountAddress = userInflowCollateralAccountAddress;
3270
- additionalUserTokenAccountAddress = userOutflowTokenAccountAddress;
3271
- primaryMint = inflowTokenMint;
3272
- secondaryMint = outflowTokenMint;
3273
- } else if (action === 'repayAndWithdraw') {
3096
+ if (action === 'liquidate' || action === 'depositAndBorrow' || action === 'repayAndWithdraw') {
3274
3097
  primaryMint = inflowTokenMint;
3275
3098
  secondaryMint = outflowTokenMint;
3276
- userTokenAccountAddress = userInflowTokenAccountAddress;
3277
- userCollateralAccountAddress = userOutflowCollateralAccountAddress;
3278
- additionalUserTokenAccountAddress = userOutflowTokenAccountAddress;
3279
3099
  } else {
3280
3100
  throw new Error('Invalid action');
3281
3101
  }
@@ -3284,8 +3104,6 @@ export class KaminoAction {
3284
3104
  kaminoMarket,
3285
3105
  payer,
3286
3106
  kaminoObligation || obligation,
3287
- userTokenAccountAddress,
3288
- userCollateralAccountAddress,
3289
3107
  primaryMint,
3290
3108
  distinctReserveCount,
3291
3109
  inflowAmount,
@@ -3294,7 +3112,6 @@ export class KaminoAction {
3294
3112
  inflowReserve,
3295
3113
  currentSlot,
3296
3114
  secondaryMint,
3297
- additionalUserTokenAccountAddress,
3298
3115
  outflowReserve,
3299
3116
  outflowAmount,
3300
3117
  referrerKey
@@ -3312,22 +3129,18 @@ export class KaminoAction {
3312
3129
  throw new Error(`Reserve ${mint} not found in market ${kaminoMarket.getAddress().toBase58()}`);
3313
3130
  }
3314
3131
 
3315
- const [{ ata, createAtaIx }] = createAtasIdempotent(owner, [
3132
+ const [{ createAtaIx }] = createAtasIdempotent(owner, [
3316
3133
  {
3317
3134
  mint: reserve.getLiquidityMint(),
3318
3135
  tokenProgram: reserve.getLiquidityTokenProgram(),
3319
3136
  },
3320
3137
  ]);
3321
3138
 
3322
- const userTokenAccountAddress = ata;
3323
-
3324
3139
  return {
3325
3140
  axn: new KaminoAction(
3326
3141
  kaminoMarket,
3327
3142
  owner,
3328
3143
  new VanillaObligation(kaminoMarket.programId),
3329
- userTokenAccountAddress,
3330
- PublicKey.default,
3331
3144
  mint,
3332
3145
  0,
3333
3146
  new BN(0),
@@ -3404,6 +3217,18 @@ export class KaminoAction {
3404
3217
  return referrerKey;
3405
3218
  }
3406
3219
 
3220
+ getUserTokenAccountAddress(reserve: KaminoReserve): PublicKey {
3221
+ return getAssociatedTokenAddress(reserve.getLiquidityMint(), this.owner, true, reserve.getLiquidityTokenProgram());
3222
+ }
3223
+
3224
+ getTokenAccountAddressByUser(reserve: KaminoReserve, user: PublicKey): PublicKey {
3225
+ return getAssociatedTokenAddress(reserve.getLiquidityMint(), user, true, reserve.getLiquidityTokenProgram());
3226
+ }
3227
+
3228
+ getUserCollateralAccountAddress(reserve: KaminoReserve): PublicKey {
3229
+ return getAssociatedTokenAddress(reserve.getCTokenMint(), this.owner, true);
3230
+ }
3231
+
3407
3232
  public static actionToIxs(action: KaminoAction): Array<TransactionInstruction> {
3408
3233
  const ixs: TransactionInstruction[] = [...action.computeBudgetIxs, ...action.setupIxs];
3409
3234
  ixs.push(...KaminoAction.actionToLendingIxs(action));
@@ -3430,13 +3255,13 @@ export class KaminoAction {
3430
3255
  }
3431
3256
 
3432
3257
  public static actionToLendingIxLabels(action: KaminoAction): Array<string> {
3433
- const lables: string[] = [];
3258
+ const labels: string[] = [];
3434
3259
  for (let i = 0; i < action.lendingIxsLabels.length; i++) {
3435
- lables.push(action.lendingIxsLabels[i]);
3260
+ labels.push(action.lendingIxsLabels[i]);
3436
3261
  if (i !== action.lendingIxsLabels.length - 1) {
3437
- lables.push(...action.inBetweenIxsLabels);
3262
+ labels.push(...action.inBetweenIxsLabels);
3438
3263
  }
3439
3264
  }
3440
- return lables;
3265
+ return labels;
3441
3266
  }
3442
3267
  }