@kamino-finance/klend-sdk 2.13.2 → 2.13.4

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.
@@ -1,6 +1,6 @@
1
1
  import { Connection, PublicKey, RpcResponseAndContext, SimulatedTransactionResponse, Transaction, TransactionInstruction, TransactionSignature } from '@solana/web3.js';
2
2
  import BN from 'bn.js';
3
- import { ObligationType } from '../utils';
3
+ import { ObligationType, ScopeRefresh } from '../utils';
4
4
  import { KaminoMarket } from './market';
5
5
  import { KaminoObligation } from './obligation';
6
6
  import { KaminoReserve } from './reserve';
@@ -28,7 +28,6 @@ export declare class KaminoAction {
28
28
  positions?: number;
29
29
  amount: BN;
30
30
  outflowAmount?: BN;
31
- hostAta?: PublicKey;
32
31
  setupIxs: Array<TransactionInstruction>;
33
32
  setupIxsLabels: Array<string>;
34
33
  inBetweenIxs: Array<TransactionInstruction>;
@@ -49,7 +48,7 @@ export declare class KaminoAction {
49
48
  preLoadedBorrowReservesSameTx: Array<PublicKey>;
50
49
  currentSlot: number;
51
50
  private constructor();
52
- static initialize(action: ActionType, amount: string | BN, mint: PublicKey, owner: PublicKey, kaminoMarket: KaminoMarket, obligation: KaminoObligation | ObligationType, referrer?: PublicKey, currentSlot?: number, hostAta?: PublicKey, payer?: PublicKey): Promise<KaminoAction>;
51
+ static initialize(action: ActionType, amount: string | BN, mint: PublicKey, owner: PublicKey, kaminoMarket: KaminoMarket, obligation: KaminoObligation | ObligationType, referrer?: PublicKey, currentSlot?: number, payer?: PublicKey): Promise<KaminoAction>;
53
52
  private static getUserAccountAddresses;
54
53
  private static loadObligation;
55
54
  static buildRefreshObligationTxns(kaminoMarket: KaminoMarket, payer: PublicKey, obligation: KaminoObligation, extraComputeBudget?: number, // if > 0 then adds the ixn
@@ -59,35 +58,37 @@ export declare class KaminoAction {
59
58
  static buildDepositTxns(kaminoMarket: KaminoMarket, amount: string | BN, mint: PublicKey, owner: PublicKey, obligation: KaminoObligation | ObligationType, extraComputeBudget?: number, // if > 0 then adds the ixn
60
59
  includeAtaIxns?: boolean, // if true it includes create and close wsol and token atas,
61
60
  requestElevationGroup?: boolean, includeUserMetadata?: boolean, // if true it includes user metadata
62
- referrer?: PublicKey, currentSlot?: number): Promise<KaminoAction>;
61
+ referrer?: PublicKey, currentSlot?: number, scopeRefresh?: ScopeRefresh): Promise<KaminoAction>;
62
+ getTokenIdsForScopeRefresh(kaminoMarket: KaminoMarket, reserves: PublicKey[]): number[];
63
+ addScopeRefreshIxs(tokens: number[], feed?: string): Promise<void>;
63
64
  static buildBorrowTxns(kaminoMarket: KaminoMarket, amount: string | BN, mint: PublicKey, owner: PublicKey, obligation: KaminoObligation | ObligationType, extraComputeBudget?: number, // if > 0 then adds the ixn
64
65
  includeAtaIxns?: boolean, // if true it includes create and close wsol and token atas,
65
66
  requestElevationGroup?: boolean, includeUserMetadata?: boolean, // if true it includes user metadata
66
- referrer?: PublicKey, currentSlot?: number, hostAta?: PublicKey): Promise<KaminoAction>;
67
+ referrer?: PublicKey, currentSlot?: number, scopeRefresh?: ScopeRefresh): Promise<KaminoAction>;
67
68
  static buildDepositReserveLiquidityTxns(kaminoMarket: KaminoMarket, amount: string | BN, mint: PublicKey, owner: PublicKey, obligation: KaminoObligation | ObligationType, extraComputeBudget?: number, // if > 0 then adds the ixn
68
69
  includeAtaIxns?: boolean, // if true it includes create and close wsol and token atas
69
70
  requestElevationGroup?: boolean, includeUserMetadata?: boolean, // if true it includes user metadata
70
- referrer?: PublicKey, currentSlot?: number): Promise<KaminoAction>;
71
+ referrer?: PublicKey, currentSlot?: number, scopeRefresh?: ScopeRefresh): Promise<KaminoAction>;
71
72
  static buildRedeemReserveCollateralTxns(kaminoMarket: KaminoMarket, amount: string | BN, mint: PublicKey, owner: PublicKey, obligation: KaminoObligation | ObligationType, extraComputeBudget?: number, // if > 0 then adds the ixn
72
73
  includeAtaIxns?: boolean, // if true it includes create and close wsol and token atas
73
74
  requestElevationGroup?: boolean, includeUserMetadata?: boolean, // if true it includes user metadata,
74
- referrer?: PublicKey, currentSlot?: number): Promise<KaminoAction>;
75
+ referrer?: PublicKey, currentSlot?: number, scopeRefresh?: ScopeRefresh): Promise<KaminoAction>;
75
76
  static buildDepositObligationCollateralTxns(kaminoMarket: KaminoMarket, amount: string | BN, mint: PublicKey, owner: PublicKey, obligation: KaminoObligation | ObligationType, extraComputeBudget?: number, // if > 0 then adds the ixn
76
77
  includeAtaIxns?: boolean, // if true it includes create and close wsol and token atas
77
78
  requestElevationGroup?: boolean, includeUserMetadata?: boolean, // if true it includes user metadata
78
- referrer?: PublicKey, currentSlot?: number): Promise<KaminoAction>;
79
+ referrer?: PublicKey, currentSlot?: number, scopeRefresh?: ScopeRefresh): Promise<KaminoAction>;
79
80
  static buildDepositAndBorrowTxns(kaminoMarket: KaminoMarket, depositAmount: string | BN, depositMint: PublicKey, borrowAmount: string | BN, borrowMint: PublicKey, payer: PublicKey, obligation: KaminoObligation | ObligationType, extraComputeBudget?: number, // if > 0 then adds the ixn
80
81
  includeAtaIxns?: boolean, // if true it includes create and close wsol and token atas,
81
82
  requestElevationGroup?: boolean, includeUserMetadata?: boolean, // if true it includes user metadata,
82
- referrer?: PublicKey, currentSlot?: number): Promise<KaminoAction>;
83
+ referrer?: PublicKey, currentSlot?: number, scopeRefresh?: ScopeRefresh): Promise<KaminoAction>;
83
84
  static buildRepayAndWithdrawTxns(kaminoMarket: KaminoMarket, repayAmount: string | BN, repayMint: PublicKey, withdrawAmount: string | BN, withdrawMint: PublicKey, payer: PublicKey, currentSlot: number, obligation: KaminoObligation | ObligationType, extraComputeBudget?: number, // if > 0 then adds the ixn
84
85
  includeAtaIxns?: boolean, // if true it includes create and close wsol and token atas,
85
86
  requestElevationGroup?: boolean, includeUserMetadata?: boolean, // if true it includes user metadata,
86
- isClosingPosition?: boolean, referrer?: PublicKey): Promise<KaminoAction>;
87
+ isClosingPosition?: boolean, referrer?: PublicKey, scopeRefresh?: ScopeRefresh): Promise<KaminoAction>;
87
88
  static buildWithdrawTxns(kaminoMarket: KaminoMarket, amount: string | BN, mint: PublicKey, owner: PublicKey, obligation: KaminoObligation | ObligationType, extraComputeBudget?: number, // if > 0 then adds the ixn
88
89
  includeAtaIxns?: boolean, // if true it includes create and close wsol and token atas,
89
90
  requestElevationGroup?: boolean, includeUserMetadata?: boolean, // if true it includes user metadata
90
- referrer?: PublicKey, currentSlot?: number): Promise<KaminoAction>;
91
+ referrer?: PublicKey, currentSlot?: number, scopeRefresh?: ScopeRefresh): Promise<KaminoAction>;
91
92
  /**
92
93
  *
93
94
  * @param kaminoMarket
@@ -103,11 +104,11 @@ export declare class KaminoAction {
103
104
  * @param includeUserMetadata - if true it includes user metadata
104
105
  * @param referrer
105
106
  */
106
- static buildRepayTxns(kaminoMarket: KaminoMarket, amount: string | BN, mint: PublicKey, owner: PublicKey, obligation: KaminoObligation | ObligationType, currentSlot: number, payer?: PublicKey | undefined, extraComputeBudget?: number, includeAtaIxns?: boolean, requestElevationGroup?: boolean, includeUserMetadata?: boolean, referrer?: PublicKey): Promise<KaminoAction>;
107
+ static buildRepayTxns(kaminoMarket: KaminoMarket, amount: string | BN, mint: PublicKey, owner: PublicKey, obligation: KaminoObligation | ObligationType, currentSlot: number, payer?: PublicKey | undefined, extraComputeBudget?: number, includeAtaIxns?: boolean, requestElevationGroup?: boolean, includeUserMetadata?: boolean, referrer?: PublicKey, scopeRefresh?: ScopeRefresh): Promise<KaminoAction>;
107
108
  static buildLiquidateTxns(kaminoMarket: KaminoMarket, amount: string | BN, minCollateralReceiveAmount: string | BN, repayTokenMint: PublicKey, withdrawTokenMint: PublicKey, liquidator: PublicKey, obligationOwner: PublicKey, obligation: KaminoObligation | ObligationType, extraComputeBudget?: number, // if > 0 then adds the ixn
108
109
  includeAtaIxns?: boolean, // if true it includes create and close wsol and token atas, and creates all other token atas if they don't exist
109
110
  requestElevationGroup?: boolean, includeUserMetadata?: boolean, // if true it includes user metadata
110
- referrer?: PublicKey, maxAllowedLtvOverridePercent?: number, currentSlot?: number): Promise<KaminoAction>;
111
+ referrer?: PublicKey, maxAllowedLtvOverridePercent?: number, currentSlot?: number, scopeRefresh?: ScopeRefresh): Promise<KaminoAction>;
111
112
  static buildWithdrawReferrerFeeTxns(owner: PublicKey, tokenMint: PublicKey, kaminoMarket: KaminoMarket, currentSlot?: number): Promise<KaminoAction>;
112
113
  getTransactions(): Promise<{
113
114
  preLendingTxn: Transaction | null;
@@ -148,10 +149,11 @@ export declare class KaminoAction {
148
149
  private addAtaIxs;
149
150
  private updateWSOLAccount;
150
151
  static initializeMultiTokenAction(kaminoMarket: KaminoMarket, action: ActionType, inflowAmount: string | BN, inflowTokenMint: PublicKey, outflowTokenMint: PublicKey, payer: PublicKey, obligationOwner: PublicKey, obligation: KaminoObligation | ObligationType, outflowAmount?: string | BN, referrer?: PublicKey, currentSlot?: number): Promise<KaminoAction>;
151
- static initializeWithdrawReferrerFees(mint: PublicKey, owner: PublicKey, kaminoMarket: KaminoMarket, currentSlot?: number, hostAta?: PublicKey): Promise<{
152
+ static initializeWithdrawReferrerFees(mint: PublicKey, owner: PublicKey, kaminoMarket: KaminoMarket, currentSlot?: number): Promise<{
152
153
  axn: KaminoAction;
153
154
  createAtasIxns: TransactionInstruction[];
154
155
  }>;
155
156
  getObligationPda(): PublicKey;
156
157
  getAdditionalDepositReservesList(): PublicKey[];
158
+ private static getReferrerKey;
157
159
  }
@@ -24,12 +24,13 @@ const types_1 = require("../idl_codegen/types");
24
24
  const farms_sdk_1 = require("@hubbleprotocol/farms-sdk");
25
25
  const ObligationType_1 = require("../utils/ObligationType");
26
26
  const lib_1 = require("../lib");
27
+ const scope_sdk_1 = require("@hubbleprotocol/scope-sdk");
27
28
  exports.POSITION_LIMIT = 10;
28
29
  exports.BORROWS_LIMIT = 5;
29
30
  exports.DEPOSITS_LIMIT = 8;
30
31
  const SOL_PADDING_FOR_INTEREST = new bn_js_1.default('1000000');
31
32
  class KaminoAction {
32
- constructor(kaminoMarket, owner, obligation, userTokenAccountAddress, userCollateralAccountAddress, mint, positions, amount, depositReserves, borrowReserves, reserveState, currentSlot, hostAta, secondaryMint, additionalTokenAccountAddress, outflowReserveState, outflowAmount, referrer, payer) {
33
+ constructor(kaminoMarket, owner, obligation, userTokenAccountAddress, userCollateralAccountAddress, mint, positions, amount, depositReserves, borrowReserves, reserveState, currentSlot, secondaryMint, additionalTokenAccountAddress, outflowReserveState, outflowAmount, referrer, payer) {
33
34
  this.obligation = null;
34
35
  /**
35
36
  * Null unless the obligation is not passed
@@ -47,7 +48,6 @@ class KaminoAction {
47
48
  this.amount = new bn_js_1.default(amount);
48
49
  this.mint = mint;
49
50
  this.positions = positions;
50
- this.hostAta = hostAta;
51
51
  this.userTokenAccountAddress = userTokenAccountAddress;
52
52
  this.userCollateralAccountAddress = userCollateralAccountAddress;
53
53
  this.setupIxs = [];
@@ -77,19 +77,15 @@ class KaminoAction {
77
77
  this.currentSlot = currentSlot;
78
78
  }
79
79
  static initialize(action_1, amount_1, mint_1, owner_1, kaminoMarket_1, obligation_2) {
80
- return __awaiter(this, arguments, void 0, function* (action, amount, mint, owner, kaminoMarket, obligation, referrer = web3_js_1.PublicKey.default, currentSlot = 0, hostAta, payer) {
80
+ return __awaiter(this, arguments, void 0, function* (action, amount, mint, owner, kaminoMarket, obligation, referrer = web3_js_1.PublicKey.default, currentSlot = 0, payer) {
81
81
  const reserve = kaminoMarket.getReserveByMint(mint);
82
82
  if (reserve === undefined) {
83
83
  throw new Error(`Reserve ${mint} not found in market ${kaminoMarket.getAddress().toBase58()}`);
84
84
  }
85
85
  const { userTokenAccountAddress, userCollateralAccountAddress } = KaminoAction.getUserAccountAddresses(payer !== null && payer !== void 0 ? payer : owner, reserve.state);
86
86
  const { kaminoObligation, depositReserves, borrowReserves, distinctReserveCount } = yield KaminoAction.loadObligation(action, kaminoMarket, owner, reserve.address, obligation);
87
- const [_, userMetadata] = yield kaminoMarket.getUserMetadata(owner);
88
- if (userMetadata) {
89
- referrer = userMetadata.referrer;
90
- }
91
- const referrerKey = kaminoObligation ? kaminoObligation.state.referrer : referrer;
92
- return new KaminoAction(kaminoMarket, owner, kaminoObligation || obligation, userTokenAccountAddress, userCollateralAccountAddress, mint, distinctReserveCount, amount, depositReserves, borrowReserves, reserve, currentSlot, hostAta, undefined, undefined, undefined, undefined, referrerKey, payer);
87
+ const referrerKey = yield this.getReferrerKey(kaminoMarket, owner, kaminoObligation, referrer);
88
+ return new KaminoAction(kaminoMarket, owner, kaminoObligation || obligation, userTokenAccountAddress, userCollateralAccountAddress, mint, distinctReserveCount, amount, depositReserves, borrowReserves, reserve, currentSlot, undefined, undefined, undefined, undefined, referrerKey, payer);
93
89
  });
94
90
  }
95
91
  static getUserAccountAddresses(owner, reserve) {
@@ -117,20 +113,16 @@ class KaminoAction {
117
113
  throw new Error(`Outflow reserve has not been set for depositAndBorrow`);
118
114
  }
119
115
  // Union of addresses
120
- const distinctReserveCount = [
121
- ...new Set([
122
- ...borrowReserves.map((e) => e.toBase58()),
123
- ...(action === 'borrow' ? [reserve.toBase58()] : []),
124
- ...(action === 'depositAndBorrow' ? [reserve.toBase58()] : []),
125
- ]),
126
- ].length +
127
- [
128
- ...new Set([
129
- ...depositReserves.map((e) => e.toBase58()),
130
- ...(action === 'deposit' ? [reserve.toBase58()] : []),
131
- ...(action === 'depositAndBorrow' ? [outflowReserve.toBase58()] : []),
132
- ]),
133
- ].length;
116
+ const distinctReserveCount = new utils_1.PublicKeySet([
117
+ ...borrowReserves.map((e) => e),
118
+ ...(action === 'borrow' ? [reserve] : []),
119
+ ...(action === 'depositAndBorrow' ? [reserve] : []),
120
+ ]).toArray().length +
121
+ new utils_1.PublicKeySet([
122
+ ...depositReserves.map((e) => e),
123
+ ...(action === 'deposit' ? [reserve] : []),
124
+ ...(action === 'depositAndBorrow' ? [outflowReserve] : []),
125
+ ]).toArray().length;
134
126
  if (distinctReserveCount > exports.POSITION_LIMIT) {
135
127
  throw Error(`Obligation already has max number of positions: ${exports.POSITION_LIMIT}`);
136
128
  }
@@ -151,7 +143,7 @@ class KaminoAction {
151
143
  if (!firstKaminoReserve) {
152
144
  throw new Error(`Reserve ${firstReserve.toBase58()} not found`);
153
145
  }
154
- const axn = yield KaminoAction.initialize('refreshObligation', '0', firstKaminoReserve === null || firstKaminoReserve === void 0 ? void 0 : firstKaminoReserve.getLiquidityMint(), obligation.state.owner, kaminoMarket, obligation, kaminoMarket.programId, currentSlot);
146
+ const axn = yield KaminoAction.initialize('refreshObligation', '0', firstKaminoReserve === null || firstKaminoReserve === void 0 ? void 0 : firstKaminoReserve.getLiquidityMint(), obligation.state.owner, kaminoMarket, obligation, undefined, currentSlot);
155
147
  if (extraComputeBudget > 0) {
156
148
  axn.addComputeBudgetIxn(extraComputeBudget);
157
149
  }
@@ -167,7 +159,7 @@ class KaminoAction {
167
159
  if (!firstKaminoReserve) {
168
160
  throw new Error(`Reserve ${firstReserve.toBase58()} not found`);
169
161
  }
170
- const axn = yield KaminoAction.initialize('requestElevationGroup', '0', firstKaminoReserve === null || firstKaminoReserve === void 0 ? void 0 : firstKaminoReserve.getLiquidityMint(), obligation.state.owner, kaminoMarket, obligation, kaminoMarket.programId, currentSlot);
162
+ const axn = yield KaminoAction.initialize('requestElevationGroup', '0', firstKaminoReserve === null || firstKaminoReserve === void 0 ? void 0 : firstKaminoReserve.getLiquidityMint(), obligation.state.owner, kaminoMarket, obligation, undefined, currentSlot);
171
163
  if (extraComputeBudget > 0) {
172
164
  axn.addComputeBudgetIxn(extraComputeBudget);
173
165
  }
@@ -180,28 +172,76 @@ class KaminoAction {
180
172
  return __awaiter(this, arguments, void 0, function* (kaminoMarket, amount, mint, owner, obligation, extraComputeBudget = 1000000, // if > 0 then adds the ixn
181
173
  includeAtaIxns = true, // if true it includes create and close wsol and token atas,
182
174
  requestElevationGroup = false, includeUserMetadata = true, // if true it includes user metadata
183
- referrer = web3_js_1.PublicKey.default, currentSlot = 0) {
175
+ referrer = web3_js_1.PublicKey.default, currentSlot = 0, scopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }) {
184
176
  const axn = yield KaminoAction.initialize('deposit', amount, mint, owner, kaminoMarket, obligation, referrer, currentSlot);
185
177
  const addInitObligationForFarm = true;
186
178
  if (extraComputeBudget > 0) {
187
179
  axn.addComputeBudgetIxn(extraComputeBudget);
188
180
  }
181
+ const allReserves = new utils_1.PublicKeySet([
182
+ ...axn.depositReserves,
183
+ ...axn.borrowReserves,
184
+ axn.reserve.address,
185
+ ]).toArray();
186
+ const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
187
+ if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
188
+ yield axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
189
+ }
189
190
  yield axn.addSupportIxs('deposit', includeAtaIxns, requestElevationGroup, includeUserMetadata, addInitObligationForFarm);
190
191
  axn.addDepositIx();
191
192
  axn.addRefreshFarmsCleanupTxnIxsToCleanupIxs();
192
193
  return axn;
193
194
  });
194
195
  }
196
+ getTokenIdsForScopeRefresh(kaminoMarket, reserves) {
197
+ const tokenIds = [];
198
+ for (const reserveAddress of reserves) {
199
+ const reserve = kaminoMarket.getReserveByAddress(reserveAddress);
200
+ if (!reserve) {
201
+ throw new Error(`Reserve not found for reserve ${reserveAddress.toBase58()}`);
202
+ }
203
+ if (!reserve.state.config.tokenInfo.scopeConfiguration.priceFeed.equals(web3_js_1.PublicKey.default)) {
204
+ reserve.state.config.tokenInfo.scopeConfiguration.priceChain.map((x) => {
205
+ if (x !== scope_sdk_1.U16_MAX) {
206
+ tokenIds.push(x);
207
+ }
208
+ });
209
+ reserve.state.config.tokenInfo.scopeConfiguration.twapChain.map((x) => {
210
+ if (x !== scope_sdk_1.U16_MAX) {
211
+ tokenIds.push(x);
212
+ }
213
+ });
214
+ }
215
+ }
216
+ return tokenIds;
217
+ }
218
+ addScopeRefreshIxs(tokens_1) {
219
+ return __awaiter(this, arguments, void 0, function* (tokens, feed = 'hubble') {
220
+ this.preTxnIxsLabels.unshift(`refreshScopePrices`);
221
+ this.preTxnIxs.unshift(yield this.kaminoMarket.scope.refreshPriceListIx({
222
+ feed: feed,
223
+ }, tokens));
224
+ });
225
+ }
195
226
  static buildBorrowTxns(kaminoMarket_1, amount_1, mint_1, owner_1, obligation_2) {
196
227
  return __awaiter(this, arguments, void 0, function* (kaminoMarket, amount, mint, owner, obligation, extraComputeBudget = 1000000, // if > 0 then adds the ixn
197
228
  includeAtaIxns = true, // if true it includes create and close wsol and token atas,
198
229
  requestElevationGroup = false, includeUserMetadata = true, // if true it includes user metadata
199
- referrer = web3_js_1.PublicKey.default, currentSlot = 0, hostAta) {
200
- const axn = yield KaminoAction.initialize('borrow', amount, mint, owner, kaminoMarket, obligation, referrer, currentSlot, hostAta);
230
+ referrer = web3_js_1.PublicKey.default, currentSlot = 0, scopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }) {
231
+ const axn = yield KaminoAction.initialize('borrow', amount, mint, owner, kaminoMarket, obligation, referrer, currentSlot);
201
232
  const addInitObligationForFarm = true;
202
233
  if (extraComputeBudget > 0) {
203
234
  axn.addComputeBudgetIxn(extraComputeBudget);
204
235
  }
236
+ const allReserves = new utils_1.PublicKeySet([
237
+ ...axn.depositReserves,
238
+ ...axn.borrowReserves,
239
+ axn.reserve.address,
240
+ ]).toArray();
241
+ const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
242
+ if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
243
+ yield axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
244
+ }
205
245
  yield axn.addSupportIxs('borrow', includeAtaIxns, requestElevationGroup, includeUserMetadata, addInitObligationForFarm);
206
246
  axn.addBorrowIx();
207
247
  axn.addRefreshFarmsCleanupTxnIxsToCleanupIxs();
@@ -212,12 +252,21 @@ class KaminoAction {
212
252
  return __awaiter(this, arguments, void 0, function* (kaminoMarket, amount, mint, owner, obligation, extraComputeBudget = 1000000, // if > 0 then adds the ixn
213
253
  includeAtaIxns = true, // if true it includes create and close wsol and token atas
214
254
  requestElevationGroup = false, includeUserMetadata = true, // if true it includes user metadata
215
- referrer = web3_js_1.PublicKey.default, currentSlot = 0) {
255
+ referrer = web3_js_1.PublicKey.default, currentSlot = 0, scopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }) {
216
256
  const axn = yield KaminoAction.initialize('mint', amount, mint, owner, kaminoMarket, obligation, referrer, currentSlot);
217
257
  const addInitObligationForFarm = true;
218
258
  if (extraComputeBudget > 0) {
219
259
  axn.addComputeBudgetIxn(extraComputeBudget);
220
260
  }
261
+ const allReserves = new utils_1.PublicKeySet([
262
+ ...axn.depositReserves,
263
+ ...axn.borrowReserves,
264
+ axn.reserve.address,
265
+ ]).toArray();
266
+ const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
267
+ if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
268
+ yield axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
269
+ }
221
270
  yield axn.addSupportIxs('mint', includeAtaIxns, requestElevationGroup, includeUserMetadata, addInitObligationForFarm);
222
271
  axn.addDepositReserveLiquidityIx();
223
272
  axn.addRefreshFarmsCleanupTxnIxsToCleanupIxs();
@@ -228,12 +277,21 @@ class KaminoAction {
228
277
  return __awaiter(this, arguments, void 0, function* (kaminoMarket, amount, mint, owner, obligation, extraComputeBudget = 1000000, // if > 0 then adds the ixn
229
278
  includeAtaIxns = true, // if true it includes create and close wsol and token atas
230
279
  requestElevationGroup = false, includeUserMetadata = true, // if true it includes user metadata,
231
- referrer = web3_js_1.PublicKey.default, currentSlot = 0) {
280
+ referrer = web3_js_1.PublicKey.default, currentSlot = 0, scopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }) {
232
281
  const axn = yield KaminoAction.initialize('redeem', amount, mint, owner, kaminoMarket, obligation, referrer, currentSlot);
233
282
  const addInitObligationForFarm = true;
234
283
  if (extraComputeBudget > 0) {
235
284
  axn.addComputeBudgetIxn(extraComputeBudget);
236
285
  }
286
+ const allReserves = new utils_1.PublicKeySet([
287
+ ...axn.depositReserves,
288
+ ...axn.borrowReserves,
289
+ axn.reserve.address,
290
+ ]).toArray();
291
+ const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
292
+ if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
293
+ yield axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
294
+ }
237
295
  yield axn.addSupportIxs('redeem', includeAtaIxns, requestElevationGroup, includeUserMetadata, addInitObligationForFarm);
238
296
  axn.addRedeemReserveCollateralIx();
239
297
  axn.addRefreshFarmsCleanupTxnIxsToCleanupIxs();
@@ -244,12 +302,21 @@ class KaminoAction {
244
302
  return __awaiter(this, arguments, void 0, function* (kaminoMarket, amount, mint, owner, obligation, extraComputeBudget = 1000000, // if > 0 then adds the ixn
245
303
  includeAtaIxns = true, // if true it includes create and close wsol and token atas
246
304
  requestElevationGroup = false, includeUserMetadata = true, // if true it includes user metadata
247
- referrer = web3_js_1.PublicKey.default, currentSlot = 0) {
305
+ referrer = web3_js_1.PublicKey.default, currentSlot = 0, scopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }) {
248
306
  const axn = yield KaminoAction.initialize('depositCollateral', amount, mint, owner, kaminoMarket, obligation, referrer, currentSlot);
249
307
  const addInitObligationForFarm = true;
250
308
  if (extraComputeBudget > 0) {
251
309
  axn.addComputeBudgetIxn(extraComputeBudget);
252
310
  }
311
+ const allReserves = new utils_1.PublicKeySet([
312
+ ...axn.depositReserves,
313
+ ...axn.borrowReserves,
314
+ axn.reserve.address,
315
+ ]).toArray();
316
+ const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
317
+ if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
318
+ yield axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
319
+ }
253
320
  yield axn.addSupportIxs('depositCollateral', includeAtaIxns, requestElevationGroup, includeUserMetadata, addInitObligationForFarm);
254
321
  axn.addDepositObligationCollateralIx();
255
322
  axn.addRefreshFarmsCleanupTxnIxsToCleanupIxs();
@@ -260,7 +327,7 @@ class KaminoAction {
260
327
  return __awaiter(this, arguments, void 0, function* (kaminoMarket, depositAmount, depositMint, borrowAmount, borrowMint, payer, obligation, extraComputeBudget = 1000000, // if > 0 then adds the ixn
261
328
  includeAtaIxns = true, // if true it includes create and close wsol and token atas,
262
329
  requestElevationGroup = false, includeUserMetadata = true, // if true it includes user metadata,
263
- referrer = web3_js_1.PublicKey.default, currentSlot = 0) {
330
+ referrer = web3_js_1.PublicKey.default, currentSlot = 0, scopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }) {
264
331
  const axn = yield KaminoAction.initializeMultiTokenAction(kaminoMarket, 'depositAndBorrow', depositAmount, depositMint, borrowMint, payer, payer, obligation, borrowAmount, referrer, currentSlot);
265
332
  const addInitObligationForFarmForDeposit = true;
266
333
  const addInitObligationForFarmForBorrow = false;
@@ -268,6 +335,16 @@ class KaminoAction {
268
335
  if (extraComputeBudget > 0) {
269
336
  axn.addComputeBudgetIxn(extraComputeBudget);
270
337
  }
338
+ const allReserves = new utils_1.PublicKeySet([
339
+ ...axn.depositReserves,
340
+ ...axn.borrowReserves,
341
+ axn.reserve.address,
342
+ axn.outflowReserve.address,
343
+ ]).toArray();
344
+ const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
345
+ if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
346
+ yield axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
347
+ }
271
348
  yield axn.addSupportIxs('deposit', includeAtaIxns, requestElevationGroup, includeUserMetadata, addInitObligationForFarmForDeposit, twoTokenAction);
272
349
  yield axn.addDepositAndBorrowIx();
273
350
  yield axn.addInBetweenIxs('depositAndBorrow', includeAtaIxns, requestElevationGroup, addInitObligationForFarmForBorrow);
@@ -279,7 +356,7 @@ class KaminoAction {
279
356
  return __awaiter(this, arguments, void 0, function* (kaminoMarket, repayAmount, repayMint, withdrawAmount, withdrawMint, payer, currentSlot, obligation, extraComputeBudget = 1000000, // if > 0 then adds the ixn
280
357
  includeAtaIxns = true, // if true it includes create and close wsol and token atas,
281
358
  requestElevationGroup = false, includeUserMetadata = true, // if true it includes user metadata,
282
- isClosingPosition = false, referrer = web3_js_1.PublicKey.default) {
359
+ isClosingPosition = false, referrer = web3_js_1.PublicKey.default, scopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }) {
283
360
  const axn = yield KaminoAction.initializeMultiTokenAction(kaminoMarket, 'repayAndWithdraw', repayAmount, repayMint, withdrawMint, payer, payer, obligation, withdrawAmount, referrer, currentSlot);
284
361
  const addInitObligationForFarmForRepay = true;
285
362
  const addInitObligationForFarmForWithdraw = false;
@@ -287,6 +364,16 @@ class KaminoAction {
287
364
  if (extraComputeBudget > 0) {
288
365
  axn.addComputeBudgetIxn(extraComputeBudget);
289
366
  }
367
+ const allReserves = new utils_1.PublicKeySet([
368
+ ...axn.depositReserves,
369
+ ...axn.borrowReserves,
370
+ axn.reserve.address,
371
+ axn.outflowReserve.address,
372
+ ]).toArray();
373
+ const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
374
+ if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
375
+ yield axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
376
+ }
290
377
  yield axn.addSupportIxs('repay', includeAtaIxns, requestElevationGroup, includeUserMetadata, addInitObligationForFarmForRepay, twoTokenAction);
291
378
  yield axn.addRepayAndWithdrawIxs();
292
379
  yield axn.addInBetweenIxs('repayAndWithdraw', includeAtaIxns, requestElevationGroup, addInitObligationForFarmForWithdraw, isClosingPosition);
@@ -298,12 +385,21 @@ class KaminoAction {
298
385
  return __awaiter(this, arguments, void 0, function* (kaminoMarket, amount, mint, owner, obligation, extraComputeBudget = 1000000, // if > 0 then adds the ixn
299
386
  includeAtaIxns = true, // if true it includes create and close wsol and token atas,
300
387
  requestElevationGroup = false, includeUserMetadata = true, // if true it includes user metadata
301
- referrer = web3_js_1.PublicKey.default, currentSlot = 0) {
388
+ referrer = web3_js_1.PublicKey.default, currentSlot = 0, scopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }) {
302
389
  const axn = yield KaminoAction.initialize('withdraw', amount, mint, owner, kaminoMarket, obligation, referrer, currentSlot);
303
390
  const addInitObligationForFarm = true;
304
391
  if (extraComputeBudget > 0) {
305
392
  axn.addComputeBudgetIxn(extraComputeBudget);
306
393
  }
394
+ const allReserves = new utils_1.PublicKeySet([
395
+ ...axn.depositReserves,
396
+ ...axn.borrowReserves,
397
+ axn.reserve.address,
398
+ ]).toArray();
399
+ const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
400
+ if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
401
+ yield axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
402
+ }
307
403
  yield axn.addSupportIxs('withdraw', includeAtaIxns, requestElevationGroup, includeUserMetadata, addInitObligationForFarm);
308
404
  yield axn.addWithdrawIx();
309
405
  axn.addRefreshFarmsCleanupTxnIxsToCleanupIxs();
@@ -326,12 +422,21 @@ class KaminoAction {
326
422
  * @param referrer
327
423
  */
328
424
  static buildRepayTxns(kaminoMarket_1, amount_1, mint_1, owner_1, obligation_2, currentSlot_1) {
329
- return __awaiter(this, arguments, void 0, function* (kaminoMarket, amount, mint, owner, obligation, currentSlot, payer = undefined, extraComputeBudget = 1000000, includeAtaIxns = true, requestElevationGroup = false, includeUserMetadata = true, referrer = web3_js_1.PublicKey.default) {
330
- const axn = yield KaminoAction.initialize('repay', amount, mint, owner, kaminoMarket, obligation, referrer, currentSlot, undefined, payer);
425
+ return __awaiter(this, arguments, void 0, function* (kaminoMarket, amount, mint, owner, obligation, currentSlot, payer = undefined, extraComputeBudget = 1000000, includeAtaIxns = true, requestElevationGroup = false, includeUserMetadata = true, referrer = web3_js_1.PublicKey.default, scopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }) {
426
+ const axn = yield KaminoAction.initialize('repay', amount, mint, owner, kaminoMarket, obligation, referrer, currentSlot, payer);
331
427
  const addInitObligationForFarm = true;
332
428
  if (extraComputeBudget > 0) {
333
429
  axn.addComputeBudgetIxn(extraComputeBudget);
334
430
  }
431
+ const allReserves = new utils_1.PublicKeySet([
432
+ ...axn.depositReserves,
433
+ ...axn.borrowReserves,
434
+ axn.reserve.address,
435
+ ]).toArray();
436
+ const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
437
+ if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
438
+ yield axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
439
+ }
335
440
  yield axn.addSupportIxs('repay', includeAtaIxns, requestElevationGroup, includeUserMetadata, addInitObligationForFarm);
336
441
  yield axn.addRepayIx();
337
442
  axn.addRefreshFarmsCleanupTxnIxsToCleanupIxs();
@@ -342,12 +447,22 @@ class KaminoAction {
342
447
  return __awaiter(this, arguments, void 0, function* (kaminoMarket, amount, minCollateralReceiveAmount, repayTokenMint, withdrawTokenMint, liquidator, obligationOwner, obligation, extraComputeBudget = 1000000, // if > 0 then adds the ixn
343
448
  includeAtaIxns = true, // if true it includes create and close wsol and token atas, and creates all other token atas if they don't exist
344
449
  requestElevationGroup = false, includeUserMetadata = true, // if true it includes user metadata
345
- referrer = web3_js_1.PublicKey.default, maxAllowedLtvOverridePercent = 0, currentSlot = 0) {
450
+ referrer = web3_js_1.PublicKey.default, maxAllowedLtvOverridePercent = 0, currentSlot = 0, scopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }) {
346
451
  const axn = yield KaminoAction.initializeMultiTokenAction(kaminoMarket, 'liquidate', amount, repayTokenMint, withdrawTokenMint, liquidator, obligationOwner, obligation, minCollateralReceiveAmount, referrer, currentSlot);
347
452
  const addInitObligationForFarm = true;
348
453
  if (extraComputeBudget > 0) {
349
454
  axn.addComputeBudgetIxn(extraComputeBudget);
350
455
  }
456
+ const allReserves = new utils_1.PublicKeySet([
457
+ ...axn.depositReserves,
458
+ ...axn.borrowReserves,
459
+ axn.reserve.address,
460
+ axn.outflowReserve.address,
461
+ ]).toArray();
462
+ const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
463
+ if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
464
+ yield axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
465
+ }
351
466
  yield axn.addSupportIxs('liquidate', includeAtaIxns, requestElevationGroup, includeUserMetadata, addInitObligationForFarm);
352
467
  yield axn.addLiquidateIx(maxAllowedLtvOverridePercent);
353
468
  axn.addRefreshFarmsCleanupTxnIxsToCleanupIxs();
@@ -1250,18 +1365,22 @@ class KaminoAction {
1250
1365
  }
1251
1366
  addInitReferrerTokenStateIxs() {
1252
1367
  return __awaiter(this, arguments, void 0, function* (reservesArr = []) {
1368
+ var _a;
1253
1369
  if (this.referrer.equals(web3_js_1.PublicKey.default)) {
1254
1370
  return;
1255
1371
  }
1256
- const reserves = reservesArr.length !== 0 ? reservesArr : [...new Set([this.reserve, this.outflowReserve])];
1372
+ const outflowReserve = ((_a = this.outflowReserve) === null || _a === void 0 ? void 0 : _a.address) ? [this.outflowReserve.address] : [];
1373
+ const reserves = reservesArr.length !== 0
1374
+ ? reservesArr.map((reserve) => reserve.address)
1375
+ : new utils_1.PublicKeySet([this.reserve.address, ...outflowReserve]).toArray();
1257
1376
  const tokenStatesToCreate = [];
1258
1377
  for (const reserve of reserves) {
1259
1378
  if (!reserve) {
1260
1379
  continue;
1261
1380
  }
1262
- const referrerTokenStateAddress = (0, utils_1.referrerTokenStatePda)(this.referrer, reserve.address, this.kaminoMarket.programId)[0];
1381
+ const referrerTokenStateAddress = (0, utils_1.referrerTokenStatePda)(this.referrer, reserve, this.kaminoMarket.programId)[0];
1263
1382
  if (!(yield (0, utils_1.checkIfAccountExists)(this.kaminoMarket.getConnection(), referrerTokenStateAddress))) {
1264
- tokenStatesToCreate.push([referrerTokenStateAddress, reserve === null || reserve === void 0 ? void 0 : reserve.address]);
1383
+ tokenStatesToCreate.push([referrerTokenStateAddress, reserve]);
1265
1384
  }
1266
1385
  }
1267
1386
  tokenStatesToCreate.forEach(([referrerTokenStateAddress, reserveAddress]) => {
@@ -1310,7 +1429,7 @@ class KaminoAction {
1310
1429
  const userTokenAccountInfo = yield this.kaminoMarket.getConnection().getAccountInfo(this.userTokenAccountAddress);
1311
1430
  if (!userTokenAccountInfo) {
1312
1431
  const [, createUserTokenAccountIx] = (0, utils_1.createAssociatedTokenAccountIdempotentInstruction)(this.owner, this.reserve.getLiquidityMint(), this.owner, this.reserve.getLiquidityTokenProgram(), this.userTokenAccountAddress);
1313
- if (this.positions === exports.POSITION_LIMIT && this.hostAta) {
1432
+ if (this.positions === exports.POSITION_LIMIT) {
1314
1433
  this.preTxnIxs.push(createUserTokenAccountIx);
1315
1434
  this.preTxnIxsLabels.push(`CreateLiquidityUserAta[${this.owner}]`);
1316
1435
  }
@@ -1490,11 +1609,7 @@ class KaminoAction {
1490
1609
  const { userTokenAccountAddress: userOutflowTokenAccountAddress, userCollateralAccountAddress: userOutflowCollateralAccountAddress, } = KaminoAction.getUserAccountAddresses(payer, outflowReserve.state);
1491
1610
  const { userTokenAccountAddress: userInflowTokenAccountAddress, userCollateralAccountAddress: userInflowCollateralAccountAddress, } = KaminoAction.getUserAccountAddresses(payer, inflowReserve.state);
1492
1611
  const { kaminoObligation, depositReserves, borrowReserves, distinctReserveCount } = yield KaminoAction.loadObligation(action, kaminoMarket, obligationOwner, inflowReserve.address, obligation, outflowReserve.address);
1493
- const [_, userMetadata] = yield kaminoMarket.getUserMetadata(payer);
1494
- if (userMetadata) {
1495
- referrer = userMetadata.referrer;
1496
- }
1497
- const referrerKey = kaminoObligation ? kaminoObligation.state.referrer : referrer;
1612
+ const referrerKey = yield this.getReferrerKey(kaminoMarket, payer, kaminoObligation, referrer);
1498
1613
  let userTokenAccountAddress;
1499
1614
  let userCollateralAccountAddress;
1500
1615
  let additionalUserTokenAccountAddress;
@@ -1524,21 +1639,19 @@ class KaminoAction {
1524
1639
  else {
1525
1640
  throw new Error('Invalid action');
1526
1641
  }
1527
- return new KaminoAction(kaminoMarket, payer, kaminoObligation || obligation, userTokenAccountAddress, userCollateralAccountAddress, primaryMint, distinctReserveCount, inflowAmount, depositReserves, borrowReserves, inflowReserve, currentSlot, undefined, secondaryMint, additionalUserTokenAccountAddress, outflowReserve, outflowAmount, referrerKey);
1642
+ return new KaminoAction(kaminoMarket, payer, kaminoObligation || obligation, userTokenAccountAddress, userCollateralAccountAddress, primaryMint, distinctReserveCount, inflowAmount, depositReserves, borrowReserves, inflowReserve, currentSlot, secondaryMint, additionalUserTokenAccountAddress, outflowReserve, outflowAmount, referrerKey);
1528
1643
  });
1529
1644
  }
1530
1645
  static initializeWithdrawReferrerFees(mint_1, owner_1, kaminoMarket_1) {
1531
- return __awaiter(this, arguments, void 0, function* (mint, owner, kaminoMarket, currentSlot = 0, hostAta) {
1646
+ return __awaiter(this, arguments, void 0, function* (mint, owner, kaminoMarket, currentSlot = 0) {
1532
1647
  const reserve = kaminoMarket.getReserveByMint(mint);
1533
1648
  if (reserve === undefined) {
1534
1649
  throw new Error(`Reserve ${mint} not found in market ${kaminoMarket.getAddress().toBase58()}`);
1535
1650
  }
1536
- const { atas, createAtasIxns } = yield (0, utils_1.getAtasWithCreateIxnsIfMissing)(kaminoMarket.getConnection(), owner, [
1537
- reserve.getLiquidityMint(),
1538
- ]);
1651
+ const { atas, createAtasIxns } = yield (0, utils_1.getAtasWithCreateIxnsIfMissing)(kaminoMarket.getConnection(), owner, [reserve.getLiquidityMint()], [reserve.getLiquidityTokenProgram()]);
1539
1652
  const userTokenAccountAddress = atas[0];
1540
1653
  return {
1541
- axn: new KaminoAction(kaminoMarket, owner, new ObligationType_1.VanillaObligation(kaminoMarket.programId), userTokenAccountAddress, web3_js_1.PublicKey.default, mint, 0, new bn_js_1.default(0), [], [], reserve, currentSlot, hostAta, undefined, undefined, undefined, undefined, undefined),
1654
+ axn: new KaminoAction(kaminoMarket, owner, new ObligationType_1.VanillaObligation(kaminoMarket.programId), userTokenAccountAddress, web3_js_1.PublicKey.default, mint, 0, new bn_js_1.default(0), [], [], reserve, currentSlot, undefined, undefined, undefined, undefined, undefined),
1542
1655
  createAtasIxns,
1543
1656
  };
1544
1657
  });
@@ -1565,6 +1678,23 @@ class KaminoAction {
1565
1678
  }
1566
1679
  return depositReservesList;
1567
1680
  }
1681
+ static getReferrerKey(kaminoMarket, owner, kaminoObligation, referrer) {
1682
+ return __awaiter(this, void 0, void 0, function* () {
1683
+ let referrerKey = referrer;
1684
+ if (!referrer || referrer.equals(web3_js_1.PublicKey.default)) {
1685
+ if (kaminoObligation === null) {
1686
+ const [_, userMetadata] = yield kaminoMarket.getUserMetadata(owner);
1687
+ if (userMetadata) {
1688
+ referrerKey = userMetadata.referrer;
1689
+ }
1690
+ }
1691
+ else {
1692
+ referrerKey = kaminoObligation.state.referrer;
1693
+ }
1694
+ }
1695
+ return referrerKey;
1696
+ });
1697
+ }
1568
1698
  }
1569
1699
  exports.KaminoAction = KaminoAction;
1570
1700
  //# sourceMappingURL=action.js.map