@velocity-exchange/vaults-sdk 0.0.1 → 0.0.2

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 (66) hide show
  1. package/lib/accountSubscribers/index.d.ts +3 -0
  2. package/lib/accountSubscribers/index.d.ts.map +1 -0
  3. package/lib/accountSubscribers/index.js +18 -0
  4. package/lib/accountSubscribers/pollingVaultDepositorSubscriber.d.ts +8 -0
  5. package/lib/accountSubscribers/pollingVaultDepositorSubscriber.d.ts.map +1 -0
  6. package/lib/accountSubscribers/pollingVaultDepositorSubscriber.js +46 -0
  7. package/lib/accountSubscribers/pollingVaultSubscriber.d.ts +8 -0
  8. package/lib/accountSubscribers/pollingVaultSubscriber.d.ts.map +1 -0
  9. package/lib/accountSubscribers/pollingVaultSubscriber.js +46 -0
  10. package/lib/accountSubscribers/pollingVaultsProgramAccountSubscriber.d.ts +28 -0
  11. package/lib/accountSubscribers/pollingVaultsProgramAccountSubscriber.d.ts.map +1 -0
  12. package/lib/accountSubscribers/pollingVaultsProgramAccountSubscriber.js +71 -0
  13. package/lib/accounts/index.d.ts +3 -0
  14. package/lib/accounts/index.d.ts.map +1 -0
  15. package/lib/accounts/index.js +18 -0
  16. package/lib/accounts/vaultAccount.d.ts +27 -0
  17. package/lib/accounts/vaultAccount.d.ts.map +1 -0
  18. package/lib/accounts/vaultAccount.js +174 -0
  19. package/lib/accounts/vaultDepositorAccount.d.ts +18 -0
  20. package/lib/accounts/vaultDepositorAccount.d.ts.map +1 -0
  21. package/lib/accounts/vaultDepositorAccount.js +47 -0
  22. package/lib/accounts/vaultsProgramAccount.d.ts +13 -0
  23. package/lib/accounts/vaultsProgramAccount.d.ts.map +1 -0
  24. package/lib/accounts/vaultsProgramAccount.js +25 -0
  25. package/lib/addresses.d.ts +10 -0
  26. package/lib/addresses.d.ts.map +1 -0
  27. package/lib/addresses.js +87 -0
  28. package/lib/constants/index.d.ts +8 -0
  29. package/lib/constants/index.d.ts.map +1 -0
  30. package/lib/constants/index.js +12 -0
  31. package/lib/idl/drift_vaults.json +5698 -0
  32. package/lib/index.d.ts +12 -0
  33. package/lib/index.d.ts.map +1 -0
  34. package/lib/index.js +27 -0
  35. package/lib/math/index.d.ts +3 -0
  36. package/lib/math/index.d.ts.map +1 -0
  37. package/lib/math/index.js +18 -0
  38. package/lib/math/vault.d.ts +17 -0
  39. package/lib/math/vault.d.ts.map +1 -0
  40. package/lib/math/vault.js +56 -0
  41. package/lib/math/vaultDepositor.d.ts +24 -0
  42. package/lib/math/vaultDepositor.d.ts.map +1 -0
  43. package/lib/math/vaultDepositor.js +49 -0
  44. package/lib/name.d.ts +4 -0
  45. package/lib/name.d.ts.map +1 -0
  46. package/lib/name.js +19 -0
  47. package/lib/parsers/index.d.ts +2 -0
  48. package/lib/parsers/index.d.ts.map +1 -0
  49. package/lib/parsers/index.js +17 -0
  50. package/lib/parsers/logParser.d.ts +15 -0
  51. package/lib/parsers/logParser.d.ts.map +1 -0
  52. package/lib/parsers/logParser.js +21 -0
  53. package/lib/types/drift_vaults.d.ts +6212 -0
  54. package/lib/types/drift_vaults.d.ts.map +1 -0
  55. package/lib/types/drift_vaults.js +2 -0
  56. package/lib/types/types.d.ts +283 -0
  57. package/lib/types/types.d.ts.map +1 -0
  58. package/lib/types/types.js +48 -0
  59. package/lib/utils.d.ts +10 -0
  60. package/lib/utils.d.ts.map +1 -0
  61. package/lib/utils.js +69 -0
  62. package/lib/vaultClient.d.ts +446 -0
  63. package/lib/vaultClient.d.ts.map +1 -0
  64. package/lib/vaultClient.js +1914 -0
  65. package/package.json +1 -1
  66. package/velocity-exchange-vaults-sdk-0.0.1.tgz +0 -0
@@ -0,0 +1,1914 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VaultClient = void 0;
4
+ const sdk_1 = require("@velocity-exchange/sdk");
5
+ const addresses_1 = require("./addresses");
6
+ const web3_js_1 = require("@solana/web3.js");
7
+ const spl_token_1 = require("@solana/spl-token");
8
+ const types_1 = require("./types/types");
9
+ const bytes_1 = require("@coral-xyz/anchor/dist/cjs/utils/bytes");
10
+ const math_1 = require("./math");
11
+ const utils_1 = require("./utils");
12
+ const constants_1 = require("./constants");
13
+ class VaultClient {
14
+ constructor({ driftClient, program, metaplex,
15
+ // @deprecated, no longer used
16
+ cliMode, userMapConfig, }) {
17
+ this.driftClient = driftClient;
18
+ this.metaplex = metaplex;
19
+ this.program = program;
20
+ this.cliMode = !!cliMode;
21
+ if (!userMapConfig) {
22
+ this.vaultUsers = new sdk_1.UserMap({
23
+ driftClient: driftClient,
24
+ subscriptionConfig: {
25
+ type: 'polling',
26
+ frequency: 1000,
27
+ commitment: 'processed',
28
+ },
29
+ });
30
+ }
31
+ else {
32
+ this.vaultUsers = new sdk_1.UserMap(userMapConfig);
33
+ }
34
+ }
35
+ getRemainingAccountsForUser(userAccounts, writableSpotMarketIndexes, vaultAccount, _userStats, skipVaultProtocol = false, _skipFuelOverflow = false, skipFeeUpdate = false) {
36
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
37
+ userAccounts,
38
+ writableSpotMarketIndexes,
39
+ });
40
+ const hasVaultProtocol = vaultAccount.vaultProtocol === true;
41
+ const hasFeeUpdate = (0, types_1.hasPendingFeeUpdate)(vaultAccount.feeUpdateStatus);
42
+ if (hasFeeUpdate && !skipFeeUpdate) {
43
+ const feeUpdate = (0, addresses_1.getFeeUpdateAddressSync)(this.program.programId, vaultAccount.pubkey);
44
+ remainingAccounts.push({
45
+ pubkey: feeUpdate,
46
+ isSigner: false,
47
+ isWritable: true,
48
+ });
49
+ }
50
+ if (hasVaultProtocol && !skipVaultProtocol) {
51
+ const vaultProtocol = this.getVaultProtocolAddress(vaultAccount.pubkey);
52
+ remainingAccounts.push({
53
+ pubkey: vaultProtocol,
54
+ isSigner: false,
55
+ isWritable: true,
56
+ });
57
+ }
58
+ return remainingAccounts;
59
+ }
60
+ async checkIfAccountExists(account) {
61
+ try {
62
+ const accountInfo = await this.driftClient.connection.getAccountInfo(account);
63
+ return accountInfo != null;
64
+ }
65
+ catch (e) {
66
+ // Doesn't already exist
67
+ return false;
68
+ }
69
+ }
70
+ /**
71
+ * Unsubscribes from the vault users map. Call this to clean up any dangling promises.
72
+ */
73
+ async unsubscribe() {
74
+ if (this.vaultUsers) {
75
+ await this.vaultUsers.unsubscribe();
76
+ }
77
+ }
78
+ async getVault(vault) {
79
+ return await this.program.account.vault.fetch(vault);
80
+ }
81
+ async getFeeUpdate(feeUpdate) {
82
+ return await this.program.account.feeUpdate.fetch(feeUpdate);
83
+ }
84
+ async getVaultAndSlot(vault) {
85
+ const vaultAndSlot = await this.program.account.vault.fetchAndContext(vault);
86
+ return {
87
+ vault: vaultAndSlot.data,
88
+ slot: vaultAndSlot.context.slot,
89
+ };
90
+ }
91
+ async getVaultDepositor(vaultDepositor) {
92
+ return await this.program.account.vaultDepositor.fetch(vaultDepositor);
93
+ }
94
+ async getVaultDepositorAndSlot(vaultDepositor) {
95
+ const vaultDepositorAndSlot = await this.program.account.vaultDepositor.fetchAndContext(vaultDepositor);
96
+ return {
97
+ vaultDepositor: vaultDepositorAndSlot.data,
98
+ slot: vaultDepositorAndSlot.context.slot,
99
+ };
100
+ }
101
+ getVaultProtocolAddress(vault) {
102
+ return (0, addresses_1.getVaultProtocolAddressSync)(this.program.programId, vault);
103
+ }
104
+ async getVaultProtocol(vaultProtocol) {
105
+ return await this.program.account.vaultProtocol.fetch(vaultProtocol);
106
+ }
107
+ async getVaultProtocolAndSlot(vaultProtocol) {
108
+ const vaultProtocolAndSlot = await this.program.account.vaultProtocol.fetchAndContext(vaultProtocol);
109
+ return {
110
+ vaultProtocol: vaultProtocolAndSlot.data,
111
+ slot: vaultProtocolAndSlot.context.slot,
112
+ };
113
+ }
114
+ async getAllVaultDepositorsWithNoWithdrawRequest(vault) {
115
+ const filters = [
116
+ {
117
+ // discriminator = VaultDepositor
118
+ memcmp: {
119
+ offset: 0,
120
+ bytes: bytes_1.bs58.encode(this.program.coder.accounts.accountDiscriminator('vaultDepositor')),
121
+ },
122
+ },
123
+ {
124
+ // vault = vault
125
+ memcmp: {
126
+ offset: 8,
127
+ bytes: vault.toBase58(),
128
+ },
129
+ },
130
+ {
131
+ // last_withdraw_request.shares (u128) = 0
132
+ memcmp: {
133
+ offset: 112,
134
+ bytes: bytes_1.bs58.encode(new Uint8Array(16).fill(0)),
135
+ },
136
+ },
137
+ ];
138
+ // @ts-ignore
139
+ return (await this.program.account.vaultDepositor.all(filters));
140
+ }
141
+ async getAllVaultDepositors(vault) {
142
+ const filters = [
143
+ {
144
+ // discriminator = VaultDepositor
145
+ memcmp: {
146
+ offset: 0,
147
+ bytes: bytes_1.bs58.encode(this.program.coder.accounts.accountDiscriminator('vaultDepositor')),
148
+ },
149
+ },
150
+ ];
151
+ if (vault) {
152
+ filters.push({
153
+ // vault = vault
154
+ memcmp: {
155
+ offset: 8,
156
+ bytes: vault.toBase58(),
157
+ },
158
+ });
159
+ }
160
+ // @ts-ignore
161
+ return (await this.program.account.vaultDepositor.all(filters));
162
+ }
163
+ async getAllVaultDepositorsForAuthority(authority) {
164
+ const filters = [
165
+ {
166
+ // discriminator = VaultDepositor
167
+ memcmp: {
168
+ offset: 0,
169
+ bytes: bytes_1.bs58.encode(this.program.coder.accounts.accountDiscriminator('vaultDepositor')),
170
+ },
171
+ },
172
+ ];
173
+ filters.push({
174
+ // authority = authority
175
+ memcmp: {
176
+ offset: 8 + 32 + 32,
177
+ bytes: authority.toBase58(),
178
+ },
179
+ });
180
+ // @ts-ignore
181
+ return (await this.program.account.vaultDepositor.all(filters));
182
+ }
183
+ async getSubscribedVaultUser(vaultDriftUserAccountPubKey) {
184
+ return this.vaultUsers.mustGet(vaultDriftUserAccountPubKey.toBase58(), {
185
+ type: 'websocket',
186
+ });
187
+ }
188
+ /// useful for syncing state during tests.
189
+ async syncVaultUsers() {
190
+ for (const user of this.vaultUsers.values()) {
191
+ await user.fetchAccounts();
192
+ }
193
+ }
194
+ /**
195
+ *
196
+ * @param vault pubkey
197
+ * @param factorUnrealizedPNL add unrealized pnl to net balance
198
+ * @returns vault equity, in USDC
199
+ */
200
+ async calculateVaultEquity(params) {
201
+ try {
202
+ // defaults to true if undefined
203
+ let factorUnrealizedPNL = true;
204
+ if (params.factorUnrealizedPNL !== undefined) {
205
+ factorUnrealizedPNL = params.factorUnrealizedPNL;
206
+ }
207
+ let includeManagerBorrowedValue = true;
208
+ if (params.includeManagerBorrowedValue !== undefined) {
209
+ includeManagerBorrowedValue = params.includeManagerBorrowedValue;
210
+ }
211
+ let vaultAccount;
212
+ if (params.address !== undefined) {
213
+ // @ts-ignore
214
+ vaultAccount = await this.program.account.vault.fetch(params.address);
215
+ }
216
+ else if (params.vault !== undefined) {
217
+ vaultAccount = params.vault;
218
+ }
219
+ else {
220
+ throw new Error('Must supply address or vault');
221
+ }
222
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
223
+ let netSpotValue = user.getNetSpotMarketValue();
224
+ if (factorUnrealizedPNL) {
225
+ const unrealizedPnl = user.getUnrealizedPNL(true, undefined, undefined);
226
+ netSpotValue = netSpotValue.add(unrealizedPnl);
227
+ }
228
+ if (includeManagerBorrowedValue) {
229
+ netSpotValue = netSpotValue.add(vaultAccount.managerBorrowedValue);
230
+ }
231
+ return netSpotValue;
232
+ }
233
+ catch (err) {
234
+ console.error('VaultClient ~ err:', err);
235
+ return sdk_1.ZERO;
236
+ }
237
+ }
238
+ async calculateVaultAllTimeNotionalPnl(params) {
239
+ try {
240
+ let vaultAccount;
241
+ if (params.address !== undefined) {
242
+ // @ts-ignore
243
+ vaultAccount = await this.program.account.vault.fetch(params.address);
244
+ }
245
+ else if (params.vault !== undefined) {
246
+ vaultAccount = params.vault;
247
+ }
248
+ else {
249
+ throw new Error('Must supply address or vault');
250
+ }
251
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
252
+ const allTimeTotalPnl = user.getTotalAllTimePnl();
253
+ return allTimeTotalPnl;
254
+ }
255
+ catch (err) {
256
+ console.error('VaultClient ~ err:', err);
257
+ return sdk_1.ZERO;
258
+ }
259
+ }
260
+ /**
261
+ *
262
+ * @param vault pubkey
263
+ * @param factorUnrealizedPNL add unrealized pnl to existing equity
264
+ * @returns total vault equity, in spot deposit asset
265
+ */
266
+ async calculateVaultEquityInDepositAsset(params) {
267
+ let vaultAccount;
268
+ if (params.address !== undefined) {
269
+ vaultAccount = await this.program.account.vault.fetch(params.address);
270
+ }
271
+ else if (params.vault !== undefined) {
272
+ vaultAccount = params.vault;
273
+ }
274
+ else {
275
+ throw new Error('Must supply address or vault');
276
+ }
277
+ const vaultEquity = await this.calculateVaultEquity({
278
+ vault: vaultAccount,
279
+ factorUnrealizedPNL: params.factorUnrealizedPNL,
280
+ });
281
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
282
+ const spotOracle = this.driftClient.getOracleDataForSpotMarket(vaultAccount.spotMarketIndex);
283
+ const spotPrecision = sdk_1.TEN.pow(new sdk_1.BN(spotMarket.decimals));
284
+ return vaultEquity.mul(spotPrecision).div(spotOracle.price);
285
+ }
286
+ /**
287
+ * @param params
288
+ * @returns vault depositor equity, in spot market value (which is usually USDC)
289
+ */
290
+ async calculateWithdrawableVaultDepositorEquity(params) {
291
+ let vaultAccount;
292
+ if (params.vaultAddress !== undefined) {
293
+ vaultAccount = await this.program.account.vault.fetch(params.vaultAddress);
294
+ }
295
+ else if (params.vault !== undefined) {
296
+ vaultAccount = params.vault;
297
+ }
298
+ else {
299
+ throw new Error('Must supply vaultAddress or vault');
300
+ }
301
+ let vaultDepositorAccount;
302
+ if (params.vaultDepositorAddress !== undefined) {
303
+ vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(params.vaultDepositorAddress);
304
+ }
305
+ else if (params.vaultDepositor !== undefined) {
306
+ vaultDepositorAccount = params.vaultDepositor;
307
+ }
308
+ else {
309
+ throw new Error('Must supply vaultDepositorAddress or vaultDepositor');
310
+ }
311
+ const vaultEquity = await this.calculateVaultEquity({
312
+ vault: vaultAccount,
313
+ factorUnrealizedPNL: false,
314
+ });
315
+ return (0, math_1.calculateRealizedVaultDepositorEquity)(vaultDepositorAccount, vaultEquity, vaultAccount);
316
+ }
317
+ async calculateWithdrawableVaultDepositorEquityInDepositAsset(params) {
318
+ let vaultAccount;
319
+ if (params.vaultAddress !== undefined) {
320
+ vaultAccount = await this.program.account.vault.fetch(params.vaultAddress);
321
+ }
322
+ else if (params.vault !== undefined) {
323
+ vaultAccount = params.vault;
324
+ }
325
+ else {
326
+ throw new Error('Must supply vaultAddress or vault');
327
+ }
328
+ let vaultDepositorAccount;
329
+ if (params.vaultDepositorAddress !== undefined) {
330
+ vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(params.vaultDepositorAddress);
331
+ }
332
+ else if (params.vaultDepositor !== undefined) {
333
+ vaultDepositorAccount = params.vaultDepositor;
334
+ }
335
+ else {
336
+ throw new Error('Must supply vaultDepositorAddress or vaultDepositor');
337
+ }
338
+ let vaultProtocol = undefined;
339
+ if (vaultAccount.vaultProtocol) {
340
+ vaultProtocol = await this.program.account.vaultProtocol.fetch(this.getVaultProtocolAddress(vaultAccount.pubkey));
341
+ }
342
+ const vaultEquity = await this.calculateVaultEquity({
343
+ vault: vaultAccount,
344
+ factorUnrealizedPNL: false,
345
+ });
346
+ const vdEquity = (0, math_1.calculateRealizedVaultDepositorEquity)(vaultDepositorAccount, vaultEquity, vaultAccount, vaultProtocol);
347
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
348
+ const spotOracle = this.driftClient.getOracleDataForSpotMarket(vaultAccount.spotMarketIndex);
349
+ const spotPrecision = sdk_1.TEN.pow(new sdk_1.BN(spotMarket.decimals));
350
+ return vdEquity.mul(spotPrecision).div(spotOracle.price);
351
+ }
352
+ async calculateVaultProtocolEquity(params) {
353
+ const vaultAccount = await this.program.account.vault.fetch(params.vault);
354
+ const vaultTotalEquity = await this.calculateVaultEquity({
355
+ vault: vaultAccount,
356
+ });
357
+ const vaultProtocol = this.getVaultProtocolAddress(params.vault);
358
+ const vpAccount = await this.program.account.vaultProtocol.fetch(vaultProtocol);
359
+ return (0, sdk_1.unstakeSharesToAmount)(vpAccount.protocolProfitAndFeeShares, vaultAccount.totalShares, vaultTotalEquity);
360
+ }
361
+ async initializeVault(params, uiTxParams) {
362
+ const ix = await this.getInitializeVaultIx(params);
363
+ return await this.createAndSendTxn([ix], uiTxParams);
364
+ }
365
+ async getInitializeVaultIx(params) {
366
+ var _a, _b, _c, _d;
367
+ const { vaultProtocol: vaultProtocolParams, ...vaultParams } = params;
368
+ const vault = (0, addresses_1.getVaultAddressSync)(this.program.programId, params.name);
369
+ const tokenAccount = (0, addresses_1.getTokenVaultAddressSync)(this.program.programId, vault);
370
+ const driftState = await this.driftClient.getStatePublicKey();
371
+ const spotMarket = this.driftClient.getSpotMarketAccount(params.spotMarketIndex);
372
+ if (!spotMarket) {
373
+ throw new Error(`Spot market ${params.spotMarketIndex} not found on driftClient`);
374
+ }
375
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
376
+ const userKey = (0, sdk_1.getUserAccountPublicKeySync)(this.driftClient.program.programId, vault);
377
+ const accounts = {
378
+ driftSpotMarket: spotMarket.pubkey,
379
+ driftSpotMarketMint: spotMarket.mint,
380
+ driftUserStats: userStatsKey,
381
+ driftUser: userKey,
382
+ driftState,
383
+ vault,
384
+ tokenAccount,
385
+ driftProgram: this.driftClient.program.programId,
386
+ };
387
+ if (vaultProtocolParams) {
388
+ const _params = {
389
+ ...vaultParams,
390
+ vaultProtocol: vaultProtocolParams,
391
+ };
392
+ const uiAuthority = this.driftClient.wallet.publicKey;
393
+ const initializeVaultWithProtocolIx = await this.program.methods
394
+ .initializeVaultWithProtocol(_params)
395
+ .accounts({
396
+ ...accounts,
397
+ payer: (_a = params.manager) !== null && _a !== void 0 ? _a : uiAuthority,
398
+ manager: (_b = params.manager) !== null && _b !== void 0 ? _b : uiAuthority,
399
+ })
400
+ .instruction();
401
+ return initializeVaultWithProtocolIx;
402
+ }
403
+ else {
404
+ const _params = vaultParams;
405
+ const uiAuthority = this.driftClient.wallet.publicKey;
406
+ const initializeVaultIx = await this.program.methods
407
+ .initializeVault(_params)
408
+ .accounts({
409
+ ...accounts,
410
+ payer: (_c = params.manager) !== null && _c !== void 0 ? _c : uiAuthority,
411
+ manager: (_d = params.manager) !== null && _d !== void 0 ? _d : uiAuthority,
412
+ })
413
+ .instruction();
414
+ return initializeVaultIx;
415
+ }
416
+ }
417
+ /**
418
+ * Updates the delegate address for a vault. The delegate address will be allowed to trade
419
+ * on behalf of the vault.
420
+ * @param vault vault address to update
421
+ * @param delegate delegate address to update to
422
+ * @returns
423
+ */
424
+ async updateDelegate(vault, delegate, uiTxParams) {
425
+ const vaultAccount = await this.program.account.vault.fetch(vault);
426
+ const updateDelegateIx = await this.getUpdateDelegateIx(vault, delegate, vaultAccount.user, vaultAccount.manager);
427
+ return await this.createAndSendTxn([updateDelegateIx], uiTxParams);
428
+ }
429
+ async getUpdateDelegateIx(vault, delegate, vaultDriftUser, vaultManager) {
430
+ const accounts = {
431
+ vault: vault,
432
+ driftUser: vaultDriftUser,
433
+ driftProgram: this.driftClient.program.programId,
434
+ };
435
+ return await this.program.methods
436
+ .updateDelegate(delegate)
437
+ .accounts({ ...accounts, manager: vaultManager })
438
+ .instruction();
439
+ }
440
+ /**
441
+ * Updates the vault margin trading status.
442
+ * @param vault vault address to update
443
+ * @param enabled whether to enable margin trading
444
+ * @returns
445
+ */
446
+ async updateMarginTradingEnabled(vault, enabled, uiTxParams) {
447
+ const updateMarginTradingEnabledIx = await this.getUpdateMarginTradingEnabledIx(vault, enabled);
448
+ return await this.createAndSendTxn([updateMarginTradingEnabledIx], uiTxParams);
449
+ }
450
+ async getUpdateMarginTradingEnabledIx(vault, enabled) {
451
+ const vaultAccount = await this.program.account.vault.fetch(vault);
452
+ const accounts = {
453
+ vault: vault,
454
+ driftUser: vaultAccount.user,
455
+ driftProgram: this.driftClient.program.programId,
456
+ };
457
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
458
+ const remainingAccounts = [];
459
+ try {
460
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
461
+ const driftProgram = this.driftClient.program;
462
+ const userStats = (await driftProgram.account.userStats.fetch(userStatsKey));
463
+ remainingAccounts.push(...this.getRemainingAccountsForUser([user.getUserAccount()], [], vaultAccount, userStats));
464
+ }
465
+ catch (err) {
466
+ console.error('failed to get remaining accounts', err);
467
+ // do nothing
468
+ }
469
+ return await this.program.methods
470
+ .updateMarginTradingEnabled(enabled)
471
+ .accounts({ ...accounts, manager: vaultAccount.manager })
472
+ .remainingAccounts(remainingAccounts)
473
+ .instruction();
474
+ }
475
+ /**
476
+ * Updates the vault's pool id (for isolated pools).
477
+ * @param vault vault address to update
478
+ * @param poolId pool id to update to
479
+ * @returns
480
+ */
481
+ async updateUserPoolId(vault, poolId, uiTxParams) {
482
+ const vaultAccount = await this.program.account.vault.fetch(vault);
483
+ const updatePoolIdIx = await this.getUpdatePoolIdIx(vault, poolId, vaultAccount);
484
+ return await this.createAndSendTxn([updatePoolIdIx], uiTxParams);
485
+ }
486
+ /**
487
+ * Gets the instruction to update the pool id for a vault.
488
+ * @param vault vault address to update
489
+ * @param vaultAccount vault account data (optional, will be fetched if not provided)
490
+ * @param poolId pool id to update to
491
+ * @returns instruction to update pool id
492
+ */
493
+ async getUpdatePoolIdIx(vault, poolId, vaultAccount) {
494
+ if (!vaultAccount) {
495
+ vaultAccount = await this.program.account.vault.fetch(vault);
496
+ }
497
+ const accounts = {
498
+ vault: vault,
499
+ driftUser: vaultAccount.user,
500
+ driftProgram: this.driftClient.program.programId,
501
+ };
502
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
503
+ const remainingAccounts = [];
504
+ try {
505
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
506
+ const driftProgram = this.driftClient.program;
507
+ const userStats = (await driftProgram.account.userStats.fetch(userStatsKey));
508
+ remainingAccounts.push(...this.getRemainingAccountsForUser([user.getUserAccount()], [], vaultAccount, userStats));
509
+ }
510
+ catch (err) {
511
+ console.error('failed to get remaining accounts', err);
512
+ // do nothing
513
+ }
514
+ return await this.program.methods
515
+ .updateUserPoolId(poolId)
516
+ .accounts({ ...accounts, manager: vaultAccount.manager })
517
+ .remainingAccounts(remainingAccounts)
518
+ .instruction();
519
+ }
520
+ async handleWSolMovement(amount, driftSpotMarket, userTokenAccount) {
521
+ const isSolDeposit = driftSpotMarket.mint.equals(sdk_1.WRAPPED_SOL_MINT);
522
+ const preIxs = [];
523
+ const postIxs = [];
524
+ if (isSolDeposit) {
525
+ const { ixs: createWSolAccountIxs, pubkey } = await this.driftClient.getWrappedSolAccountCreationIxs(amount, true);
526
+ userTokenAccount = pubkey;
527
+ preIxs.push(...createWSolAccountIxs);
528
+ postIxs.push((0, spl_token_1.createCloseAccountInstruction)(userTokenAccount, this.driftClient.wallet.publicKey, this.driftClient.wallet.publicKey, []));
529
+ }
530
+ return { userTokenAccount, preIxs, postIxs };
531
+ }
532
+ /**
533
+ *
534
+ * @param vault vault address to deposit to
535
+ * @param amount amount to deposit
536
+ * @returns
537
+ */
538
+ async managerDeposit(vault, amount, uiTxParams, managerTokenAccount) {
539
+ const managerDepositIxs = await this.getManagerDepositIx(vault, amount, managerTokenAccount);
540
+ return await this.createAndSendTxn(managerDepositIxs, uiTxParams);
541
+ }
542
+ /**
543
+ *
544
+ * @param vault vault address to deposit to
545
+ * @param amount amount to deposit
546
+ * @returns
547
+ */
548
+ async getManagerDepositIx(vault, amount, managerTokenAccount) {
549
+ const vaultAccount = await this.program.account.vault.fetch(vault);
550
+ const driftSpotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
551
+ if (!driftSpotMarket) {
552
+ throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
553
+ }
554
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
555
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
556
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
557
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, true, true);
558
+ const accounts = {
559
+ vault,
560
+ vaultTokenAccount: vaultAccount.tokenAccount,
561
+ driftUser: await (0, sdk_1.getUserAccountPublicKey)(this.driftClient.program.programId, vault),
562
+ driftUserStats: (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault),
563
+ driftProgram: this.driftClient.program.programId,
564
+ driftState: await this.driftClient.getStatePublicKey(),
565
+ driftSpotMarketVault: driftSpotMarket.vault,
566
+ userTokenAccount: managerTokenAccount !== null && managerTokenAccount !== void 0 ? managerTokenAccount : (0, spl_token_1.getAssociatedTokenAddressSync)(driftSpotMarket.mint, vaultAccount.manager, true),
567
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
568
+ };
569
+ const { userTokenAccount, preIxs, postIxs } = await this.handleWSolMovement(amount, driftSpotMarket, accounts.userTokenAccount);
570
+ const managerDepositIx = await this.program.methods
571
+ .managerDeposit(amount)
572
+ .accounts({
573
+ ...accounts,
574
+ userTokenAccount,
575
+ manager: vaultAccount.manager,
576
+ })
577
+ .remainingAccounts(remainingAccounts)
578
+ .instruction();
579
+ return [...preIxs, managerDepositIx, ...postIxs];
580
+ }
581
+ async managerRequestWithdraw(vault, amount, withdrawUnit, uiTxParams) {
582
+ const requestWithdrawIx = await this.getManagerRequestWithdrawIx(vault, amount, withdrawUnit);
583
+ return await this.createAndSendTxn([requestWithdrawIx], uiTxParams);
584
+ }
585
+ async getManagerRequestWithdrawIx(vault, amount, withdrawUnit) {
586
+ this.program.idl.types;
587
+ // @ts-ignore
588
+ const vaultAccount = (await this.program.account.vault.fetch(vault));
589
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
590
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
591
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
592
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, true, true);
593
+ const accounts = {
594
+ vault,
595
+ driftUser: vaultAccount.user,
596
+ driftUserStats: userStatsKey,
597
+ };
598
+ return this.program.instruction.managerRequestWithdraw(
599
+ // @ts-ignore
600
+ amount, withdrawUnit, {
601
+ accounts: {
602
+ manager: vaultAccount.manager,
603
+ ...accounts,
604
+ },
605
+ remainingAccounts,
606
+ });
607
+ }
608
+ async managerCancelWithdrawRequest(vault, uiTxParams) {
609
+ const ix = await this.getManagerCancelWithdrawRequestIx(vault);
610
+ return await this.createAndSendTxn([ix], uiTxParams);
611
+ }
612
+ async getManagerCancelWithdrawRequestIx(vault) {
613
+ const vaultAccount = await this.program.account.vault.fetch(vault);
614
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
615
+ const accounts = {
616
+ manager: vaultAccount.manager,
617
+ vault,
618
+ driftUser: vaultAccount.user,
619
+ driftUserStats: userStatsKey,
620
+ };
621
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
622
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
623
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [], vaultAccount, userStats, false, true, true);
624
+ return this.program.instruction.mangerCancelWithdrawRequest({
625
+ accounts,
626
+ remainingAccounts,
627
+ });
628
+ }
629
+ async managerWithdraw(vault, uiTxParams) {
630
+ const ixs = await this.getManagerWithdrawIx(vault);
631
+ return this.createAndSendTxn(ixs, uiTxParams);
632
+ }
633
+ async getManagerWithdrawIx(vault) {
634
+ const vaultAccount = await this.program.account.vault.fetch(vault);
635
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
636
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
637
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
638
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, false, false);
639
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
640
+ if (!spotMarket) {
641
+ throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
642
+ }
643
+ const isSolMarket = spotMarket.mint.equals(sdk_1.WRAPPED_SOL_MINT);
644
+ let userAta = (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, vaultAccount.manager, true);
645
+ const preIxs = [];
646
+ const postIxs = [];
647
+ if (isSolMarket) {
648
+ const { ixs, pubkey } = await this.driftClient.getWrappedSolAccountCreationIxs(sdk_1.ZERO, false);
649
+ userAta = pubkey;
650
+ preIxs.push(...ixs);
651
+ postIxs.push((0, spl_token_1.createSyncNativeInstruction)(userAta));
652
+ postIxs.push((0, spl_token_1.createCloseAccountInstruction)(userAta, vaultAccount.manager, vaultAccount.manager, []));
653
+ }
654
+ else {
655
+ const userAtaExists = await this.driftClient.connection.getAccountInfo(userAta);
656
+ if (userAtaExists === null) {
657
+ preIxs.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(vaultAccount.manager, userAta, vaultAccount.manager, spotMarket.mint));
658
+ }
659
+ }
660
+ const withdrawIx = await this.program.instruction.managerWithdraw({
661
+ accounts: {
662
+ vault,
663
+ manager: vaultAccount.manager,
664
+ vaultTokenAccount: vaultAccount.tokenAccount,
665
+ driftUser: await (0, sdk_1.getUserAccountPublicKey)(this.driftClient.program.programId, vault),
666
+ driftProgram: this.driftClient.program.programId,
667
+ driftUserStats: (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault),
668
+ driftState: await this.driftClient.getStatePublicKey(),
669
+ driftSpotMarketVault: spotMarket.vault,
670
+ userTokenAccount: userAta,
671
+ driftSigner: this.driftClient.getStateAccount().signer,
672
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
673
+ },
674
+ remainingAccounts,
675
+ });
676
+ return [...preIxs, withdrawIx, ...postIxs];
677
+ }
678
+ async managerBorrow(vault, borrowSpotMarketIndex, borrowAmount, managerTokenAccount, txParams) {
679
+ const ixs = await this.getManagerBorrowIx(vault, borrowSpotMarketIndex, borrowAmount, managerTokenAccount);
680
+ return await this.createAndSendTxn(ixs, txParams);
681
+ }
682
+ async getManagerBorrowIx(vault, borrowSpotMarketIndex, borrowAmount, managerTokenAccount) {
683
+ const vaultAccount = await this.program.account.vault.fetch(vault);
684
+ const spotMarket = this.driftClient.getSpotMarketAccount(borrowSpotMarketIndex);
685
+ if (!spotMarket) {
686
+ throw new Error(`Spot market ${borrowSpotMarketIndex} not found on driftClient`);
687
+ }
688
+ if (!managerTokenAccount) {
689
+ managerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, this.driftClient.wallet.publicKey, true);
690
+ }
691
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
692
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
693
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
694
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [borrowSpotMarketIndex, vaultAccount.spotMarketIndex], vaultAccount, userStats, false, false, false);
695
+ const preIxs = [];
696
+ const postIxs = [];
697
+ const managerTokenAccountExists = await this.driftClient.connection.getAccountInfo(managerTokenAccount);
698
+ if (managerTokenAccountExists === null) {
699
+ preIxs.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(vaultAccount.manager, managerTokenAccount, vaultAccount.manager, spotMarket.mint));
700
+ }
701
+ const vaultBorrowTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, vault, true);
702
+ const vaultBorrowTokenAccountExists = await this.driftClient.connection.getAccountInfo(vaultBorrowTokenAccount);
703
+ if (vaultBorrowTokenAccountExists === null) {
704
+ preIxs.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(this.driftClient.wallet.publicKey, vaultBorrowTokenAccount, vault, spotMarket.mint));
705
+ }
706
+ if (spotMarket.mint.equals(sdk_1.WRAPPED_SOL_MINT)) {
707
+ postIxs.push((0, spl_token_1.createCloseAccountInstruction)(managerTokenAccount, vaultAccount.manager, vaultAccount.manager, []));
708
+ }
709
+ return [
710
+ ...preIxs,
711
+ await this.program.methods
712
+ .managerBorrow(borrowSpotMarketIndex, borrowAmount)
713
+ .accounts({
714
+ vault,
715
+ vaultTokenAccount: vaultBorrowTokenAccount,
716
+ manager: vaultAccount.manager,
717
+ driftUserStats: userStatsKey,
718
+ driftUser: vaultAccount.user,
719
+ driftState: await this.driftClient.getStatePublicKey(),
720
+ driftSpotMarketVault: spotMarket.vault,
721
+ driftSigner: this.driftClient.getStateAccount().signer,
722
+ userTokenAccount: managerTokenAccount,
723
+ })
724
+ .remainingAccounts(remainingAccounts)
725
+ .instruction(),
726
+ ...postIxs,
727
+ ];
728
+ }
729
+ async managerRepay(vault, repaySpotMarketIndex, repayAmount, repayValue, managerTokenAccount, uiTxParams) {
730
+ const ixs = await this.getManagerRepayIxs(vault, repaySpotMarketIndex, repayAmount, repayValue, managerTokenAccount);
731
+ return this.createAndSendTxn(ixs, uiTxParams);
732
+ }
733
+ /**
734
+ * Get the instructions for the manager repay transaction
735
+ * @param vault - The vault to repay
736
+ * @param repaySpotMarketIndex - The spot market index to repay
737
+ * @param repayAmount - The amount to repay
738
+ * @param repayValue - The value of the repay
739
+ * @param managerTokenAccount - The manager token account to use, if depositing SOL, leave undefined to automatically wrap the SOL
740
+ * @returns The instructions for the manager repay transaction
741
+ */
742
+ async getManagerRepayIxs(vault, repaySpotMarketIndex, repayAmount, repayValue, managerTokenAccount) {
743
+ const vaultAccount = await this.program.account.vault.fetch(vault);
744
+ const spotMarket = this.driftClient.getSpotMarketAccount(repaySpotMarketIndex);
745
+ if (!spotMarket) {
746
+ throw new Error(`Spot market ${repaySpotMarketIndex} not found on driftClient`);
747
+ }
748
+ const isSolMarket = spotMarket.mint.equals(sdk_1.WRAPPED_SOL_MINT);
749
+ const preIxs = [];
750
+ const postIxs = [];
751
+ let createdWsolAccount = false;
752
+ if (!managerTokenAccount) {
753
+ if (isSolMarket) {
754
+ // create wSOL
755
+ const { ixs, pubkey } = await this.driftClient.getWrappedSolAccountCreationIxs(repayAmount, true);
756
+ preIxs.push(...ixs);
757
+ managerTokenAccount = pubkey;
758
+ createdWsolAccount = true;
759
+ }
760
+ else {
761
+ managerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, vaultAccount.manager, true);
762
+ }
763
+ }
764
+ const vaultRepayTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, vault, true);
765
+ const vaultRepayTokenAccountExists = await this.driftClient.connection.getAccountInfo(vaultRepayTokenAccount);
766
+ if (vaultRepayTokenAccountExists === null) {
767
+ preIxs.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(this.driftClient.wallet.publicKey, vaultRepayTokenAccount, vault, spotMarket.mint));
768
+ }
769
+ if (createdWsolAccount) {
770
+ postIxs.push((0, spl_token_1.createCloseAccountInstruction)(managerTokenAccount, vaultAccount.manager, vaultAccount.manager, []));
771
+ }
772
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
773
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
774
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
775
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [repaySpotMarketIndex, vaultAccount.spotMarketIndex], vaultAccount, userStats, false, false, false);
776
+ return [
777
+ ...preIxs,
778
+ await this.program.methods
779
+ .managerRepay(repaySpotMarketIndex, repayAmount, repayValue)
780
+ .accounts({
781
+ vault,
782
+ vaultTokenAccount: vaultRepayTokenAccount,
783
+ manager: vaultAccount.manager,
784
+ driftUserStats: userStatsKey,
785
+ driftUser: vaultAccount.user,
786
+ driftState: await this.driftClient.getStatePublicKey(),
787
+ driftSpotMarketVault: spotMarket.vault,
788
+ driftSigner: this.driftClient.getStateAccount().signer,
789
+ userTokenAccount: managerTokenAccount,
790
+ })
791
+ .remainingAccounts(remainingAccounts)
792
+ .instruction(),
793
+ ...postIxs,
794
+ ];
795
+ }
796
+ async managerUpdateBorrow(vault, newBorrowValue, txParams) {
797
+ const ix = await this.getManagerUpdateBorrowIx(vault, newBorrowValue);
798
+ return await this.createAndSendTxn([ix], txParams);
799
+ }
800
+ async getManagerUpdateBorrowIx(vault, newBorrowValue) {
801
+ const vaultAccount = await this.program.account.vault.fetch(vault);
802
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
803
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
804
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
805
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [], vaultAccount, userStats, false, false, false);
806
+ return this.program.instruction.managerUpdateBorrow(newBorrowValue, {
807
+ accounts: {
808
+ vault,
809
+ manager: vaultAccount.manager,
810
+ driftUserStats: userStatsKey,
811
+ driftUser: vaultAccount.user,
812
+ },
813
+ remainingAccounts,
814
+ });
815
+ }
816
+ async managerUpdateVault(vault, params, uiTxParams) {
817
+ const ix = await this.getManagerUpdateVaultIx(vault, params);
818
+ return this.createAndSendTxn([ix], uiTxParams);
819
+ }
820
+ async getManagerUpdateVaultIx(vault, params) {
821
+ const vaultAccount = await this.program.account.vault.fetch(vault);
822
+ return this.program.instruction.updateVault(params, {
823
+ accounts: {
824
+ vault,
825
+ manager: vaultAccount.manager,
826
+ },
827
+ });
828
+ }
829
+ async managerUpdateVaultManager(vault, manager, uiTxParams) {
830
+ const ix = await this.getManagerUpdateVaultManagerIx(vault, manager);
831
+ return this.createAndSendTxn([ix], uiTxParams);
832
+ }
833
+ async getManagerUpdateVaultManagerIx(vault, manager) {
834
+ const vaultAccount = await this.program.account.vault.fetch(vault);
835
+ return this.program.instruction.updateVaultManager(manager, {
836
+ accounts: {
837
+ vault,
838
+ manager: vaultAccount.manager,
839
+ },
840
+ });
841
+ }
842
+ async applyProfitShare(vault, vaultDepositor, uiTxParams) {
843
+ const ix = await this.getApplyProfitShareIx(vault, vaultDepositor);
844
+ return this.createAndSendTxn([ix], uiTxParams);
845
+ }
846
+ async getApplyProfitShareIx(vault, vaultDepositor) {
847
+ const vaultAccount = await this.program.account.vault.fetch(vault);
848
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
849
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
850
+ if (!spotMarket) {
851
+ throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
852
+ }
853
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
854
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
855
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, false, false);
856
+ const accounts = {
857
+ vault,
858
+ vaultDepositor,
859
+ manager: vaultAccount.manager,
860
+ driftUserStats: (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault),
861
+ driftUser: await (0, sdk_1.getUserAccountPublicKey)(this.driftClient.program.programId, vault),
862
+ driftState: await this.driftClient.getStatePublicKey(),
863
+ driftSigner: this.driftClient.getStateAccount().signer,
864
+ driftProgram: this.driftClient.program.programId,
865
+ };
866
+ return this.program.instruction.applyProfitShare({
867
+ accounts: {
868
+ ...accounts,
869
+ },
870
+ remainingAccounts,
871
+ });
872
+ }
873
+ async getApplyRebaseTokenizedDepositorIx(vault, tokenizedVaultDepositor) {
874
+ const vaultAccount = await this.program.account.vault.fetch(vault);
875
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
876
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
877
+ if (!spotMarket) {
878
+ throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
879
+ }
880
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
881
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
882
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, true, true);
883
+ const accounts = {
884
+ vault,
885
+ tokenizedVaultDepositor,
886
+ driftUser: await (0, sdk_1.getUserAccountPublicKey)(this.driftClient.program.programId, vault),
887
+ driftState: await this.driftClient.getStatePublicKey(),
888
+ driftSigner: this.driftClient.getStateAccount().signer,
889
+ driftProgram: this.driftClient.program.programId,
890
+ };
891
+ return this.program.instruction.applyRebaseTokenizedDepositor({
892
+ accounts: {
893
+ ...accounts,
894
+ },
895
+ remainingAccounts,
896
+ });
897
+ }
898
+ async applyRebase(vault, vaultDepositor) {
899
+ return await this.createAndSendTxn([
900
+ await this.getApplyRebaseIx(vault, vaultDepositor),
901
+ ]);
902
+ }
903
+ async getApplyRebaseIx(vault, vaultDepositor) {
904
+ const vaultAccount = await this.program.account.vault.fetch(vault);
905
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
906
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
907
+ if (!spotMarket) {
908
+ throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
909
+ }
910
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
911
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
912
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, true, true);
913
+ const accounts = {
914
+ vault,
915
+ vaultDepositor,
916
+ driftUser: await (0, sdk_1.getUserAccountPublicKey)(this.driftClient.program.programId, vault),
917
+ driftState: await this.driftClient.getStatePublicKey(),
918
+ driftSigner: this.driftClient.getStateAccount().signer,
919
+ driftProgram: this.driftClient.program.programId,
920
+ };
921
+ return this.program.instruction.applyRebase({
922
+ accounts: {
923
+ ...accounts,
924
+ },
925
+ remainingAccounts,
926
+ });
927
+ }
928
+ async applyRebaseTokenizedDepositor(vault, tokenizedVaultDepositor) {
929
+ return await this.createAndSendTxn([
930
+ await this.getApplyRebaseTokenizedDepositorIx(vault, tokenizedVaultDepositor),
931
+ ]);
932
+ }
933
+ createInitVaultDepositorIx(vault, authority, payer) {
934
+ const vaultDepositor = (0, addresses_1.getVaultDepositorAddressSync)(this.program.programId, vault, authority || this.driftClient.wallet.publicKey);
935
+ const accounts = {
936
+ vaultDepositor,
937
+ vault,
938
+ authority: authority || this.driftClient.wallet.publicKey,
939
+ };
940
+ const initIx = this.program.instruction.initializeVaultDepositor({
941
+ accounts: {
942
+ ...accounts,
943
+ payer: payer || authority || this.driftClient.wallet.publicKey,
944
+ rent: web3_js_1.SYSVAR_RENT_PUBKEY,
945
+ systemProgram: web3_js_1.SystemProgram.programId,
946
+ },
947
+ });
948
+ return initIx;
949
+ }
950
+ /**
951
+ * Initializes the vault depositor account. This account is used to deposit funds into a vault.
952
+ * @param vault the vault address to deposit into
953
+ * @param authority the authority allowed to make deposits into the vault
954
+ * @returns
955
+ */
956
+ async initializeVaultDepositor(vault, authority, payer, uiTxParams) {
957
+ const initIx = this.createInitVaultDepositorIx(vault, authority, payer);
958
+ return await this.createAndSendTxn([initIx], uiTxParams);
959
+ }
960
+ async initializeTokenizedVaultDepositor(params, uiTxParams) {
961
+ var _a;
962
+ if (!this.metaplex) {
963
+ throw new Error('Metaplex instance is required when constructing VaultClient to initialize a tokenized vault depositor');
964
+ }
965
+ let spotMarketDecimals = 6;
966
+ let sharesBase = 0;
967
+ if (params.decimals === undefined || params.sharesBase === undefined) {
968
+ const vault = await this.program.account.vault.fetch(params.vault);
969
+ const spotMarketAccount = this.driftClient.getSpotMarketAccount(vault.spotMarketIndex);
970
+ if (!spotMarketAccount) {
971
+ throw new Error(`DriftClient failed to load vault's spot market (marketIndex: ${vault.spotMarketIndex})`);
972
+ }
973
+ spotMarketDecimals = spotMarketAccount.decimals;
974
+ sharesBase = vault.sharesBase;
975
+ }
976
+ const mintAddress = (0, addresses_1.getTokenizedVaultMintAddressSync)(this.program.programId, params.vault, sharesBase);
977
+ const vaultAccount = await this.program.account.vault.fetch(params.vault);
978
+ const accounts = {
979
+ vault: params.vault,
980
+ vaultDepositor: (0, addresses_1.getTokenizedVaultAddressSync)(this.program.programId, params.vault, sharesBase),
981
+ mintAccount: mintAddress,
982
+ metadataAccount: this.metaplex.nfts().pdas().metadata({
983
+ mint: mintAddress,
984
+ }),
985
+ tokenMetadataProgram: this.metaplex.programs().getTokenMetadata().address,
986
+ payer: vaultAccount.manager,
987
+ };
988
+ const vaultTokenAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mintAddress, params.vault, true);
989
+ const createAtaIx = (0, spl_token_1.createAssociatedTokenAccountInstruction)(vaultAccount.manager, vaultTokenAta, params.vault, mintAddress);
990
+ return await this.createAndSendTxn([
991
+ await this.program.methods
992
+ .initializeTokenizedVaultDepositor({
993
+ ...params,
994
+ decimals: (_a = params.decimals) !== null && _a !== void 0 ? _a : spotMarketDecimals,
995
+ })
996
+ .accounts(accounts)
997
+ .instruction(),
998
+ createAtaIx,
999
+ ], uiTxParams);
1000
+ }
1001
+ async createTokenizeSharesIx(vaultDepositor, amount, unit, mint) {
1002
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
1003
+ const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
1004
+ mint =
1005
+ mint !== null && mint !== void 0 ? mint : (0, addresses_1.getTokenizedVaultMintAddressSync)(this.program.programId, vaultDepositorAccount.vault, vaultAccount.sharesBase);
1006
+ const userAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mint, this.driftClient.wallet.publicKey, true);
1007
+ const ixs = [];
1008
+ const userAtaExists = await this.driftClient.connection.getAccountInfo(userAta);
1009
+ if (userAtaExists === null) {
1010
+ ixs.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(this.driftClient.wallet.publicKey, userAta, this.driftClient.wallet.publicKey, mint));
1011
+ }
1012
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1013
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vaultDepositorAccount.vault);
1014
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
1015
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, true, true);
1016
+ ixs.push(await this.program.methods
1017
+ // anchor idl bug: https://github.com/coral-xyz/anchor/issues/2914
1018
+ // @ts-ignore args tuple vs anchor 0.32 IDL recursion limit
1019
+ .tokenizeShares(amount, unit)
1020
+ // `mint` is auto-resolved from IDL seeds, but anchor 1.0's IDL
1021
+ // generator can't encode `vault.shares_base.to_string().as_bytes()`
1022
+ // and emits broken seeds. Pass it explicitly to override.
1023
+ .accountsPartial({
1024
+ authority: this.driftClient.wallet.publicKey,
1025
+ vault: vaultDepositorAccount.vault,
1026
+ tokenizedVaultDepositor: (0, addresses_1.getTokenizedVaultAddressSync)(this.program.programId, vaultDepositorAccount.vault, vaultAccount.sharesBase),
1027
+ mint,
1028
+ userTokenAccount: userAta,
1029
+ driftUser: vaultAccount.user,
1030
+ })
1031
+ .remainingAccounts(remainingAccounts)
1032
+ .instruction());
1033
+ return ixs;
1034
+ }
1035
+ async tokenizeShares(vaultDepositor, amount, unit, mint, txParams) {
1036
+ const ixs = await this.createTokenizeSharesIx(vaultDepositor, amount, unit, mint);
1037
+ return await this.createAndSendTxn(ixs, txParams);
1038
+ }
1039
+ async createTransferVaultDepositorSharesIx(fromVaultDepositor, toVaultDepositor, amount, withdrawUnit) {
1040
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(fromVaultDepositor);
1041
+ const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
1042
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1043
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vaultDepositorAccount.vault);
1044
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
1045
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, true, true);
1046
+ const ixs = [];
1047
+ ixs.push(await this.program.methods
1048
+ // @ts-ignore args tuple vs anchor 0.32 IDL recursion limit
1049
+ .transferVaultDepositorShares(amount, withdrawUnit)
1050
+ .accounts({
1051
+ vault: vaultDepositorAccount.vault,
1052
+ authority: this.driftClient.wallet.publicKey,
1053
+ toVaultDepositor,
1054
+ driftUser: vaultAccount.user,
1055
+ })
1056
+ .remainingAccounts(remainingAccounts)
1057
+ .instruction());
1058
+ return ixs;
1059
+ }
1060
+ async transferVaultDepositorShares(fromVaultDepositor, toVaultDepositor, amount, withdrawUnit, txParams) {
1061
+ const ixs = await this.createTransferVaultDepositorSharesIx(fromVaultDepositor, toVaultDepositor, amount, withdrawUnit);
1062
+ return await this.createAndSendTxn(ixs, txParams);
1063
+ }
1064
+ async createRedeemTokensIx(vaultDepositor, tokensToBurn, sharesBase) {
1065
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
1066
+ const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
1067
+ const mint = (0, addresses_1.getTokenizedVaultMintAddressSync)(this.program.programId, vaultDepositorAccount.vault, sharesBase !== null && sharesBase !== void 0 ? sharesBase : vaultAccount.sharesBase);
1068
+ const userAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mint, this.driftClient.wallet.publicKey, true);
1069
+ const vaultTokenAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mint, vaultDepositorAccount.vault, true);
1070
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1071
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vaultDepositorAccount.vault);
1072
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
1073
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, true, true);
1074
+ return await this.program.methods
1075
+ .redeemTokens(tokensToBurn)
1076
+ .accounts({
1077
+ authority: this.driftClient.wallet.publicKey,
1078
+ vault: vaultDepositorAccount.vault,
1079
+ tokenizedVaultDepositor: (0, addresses_1.getTokenizedVaultAddressSync)(this.program.programId, vaultDepositorAccount.vault, sharesBase !== null && sharesBase !== void 0 ? sharesBase : vaultAccount.sharesBase),
1080
+ mint,
1081
+ userTokenAccount: userAta,
1082
+ vaultTokenAccount: vaultTokenAta,
1083
+ driftUser: vaultAccount.user,
1084
+ })
1085
+ .remainingAccounts(remainingAccounts)
1086
+ .instruction();
1087
+ }
1088
+ /**
1089
+ * Redeems tokens from the vault.
1090
+ * @param vaultDepositor
1091
+ * @param tokensToBurn
1092
+ * @param mint optionally provide a mint, or infer the mint from the current vault share base
1093
+ * @param txParams
1094
+ * @returns
1095
+ */
1096
+ async redeemTokens(vaultDepositor, tokensToBurn, sharesBase, txParams) {
1097
+ const ix = await this.createRedeemTokensIx(vaultDepositor, tokensToBurn, sharesBase);
1098
+ return await this.createAndSendTxn([ix], txParams);
1099
+ }
1100
+ async prepDepositTx(vaultDepositor, amount, initVaultDepositor, depositTokenAccount) {
1101
+ let vaultPubKey;
1102
+ if (initVaultDepositor) {
1103
+ vaultPubKey = initVaultDepositor.vault;
1104
+ }
1105
+ else {
1106
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
1107
+ vaultPubKey = vaultDepositorAccount.vault;
1108
+ }
1109
+ const vaultAccount = await this.program.account.vault.fetch(vaultPubKey);
1110
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1111
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vaultPubKey);
1112
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
1113
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, false, false);
1114
+ const driftStateKey = await this.driftClient.getStatePublicKey();
1115
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
1116
+ if (!spotMarket) {
1117
+ throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
1118
+ }
1119
+ const nonWSolUserTokenAccount = depositTokenAccount !== null && depositTokenAccount !== void 0 ? depositTokenAccount : (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, this.driftClient.wallet.publicKey, true);
1120
+ const { userTokenAccount, preIxs, postIxs } = await this.handleWSolMovement(amount, spotMarket, nonWSolUserTokenAccount);
1121
+ const accounts = {
1122
+ vault: vaultPubKey,
1123
+ vaultDepositor,
1124
+ vaultTokenAccount: vaultAccount.tokenAccount,
1125
+ driftUserStats: userStatsKey,
1126
+ driftUser: vaultAccount.user,
1127
+ driftState: driftStateKey,
1128
+ driftSpotMarketVault: spotMarket.vault,
1129
+ userTokenAccount: userTokenAccount,
1130
+ driftProgram: this.driftClient.program.programId,
1131
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
1132
+ };
1133
+ return {
1134
+ vaultAccount,
1135
+ accounts,
1136
+ remainingAccounts,
1137
+ preIxs,
1138
+ postIxs,
1139
+ };
1140
+ }
1141
+ /**
1142
+ * Creates a transaction to deposit funds into the specified vault.
1143
+ * Uses the associated token account of the vault depositor authority and spot market mint,
1144
+ * and assumes it exists before calling this function.
1145
+ * @param vaultDepositor
1146
+ * @param amount
1147
+ * @param initVaultDepositor If true, will initialize the vault depositor account
1148
+ * @returns transaction
1149
+ */
1150
+ async createDepositTx(vaultDepositor, amount, initVaultDepositor, txParams, userTokenAccount) {
1151
+ const { vaultAccount, accounts, remainingAccounts, preIxs, postIxs } = await this.prepDepositTx(vaultDepositor, amount, initVaultDepositor, userTokenAccount);
1152
+ const ixs = [];
1153
+ if (initVaultDepositor) {
1154
+ ixs.push(this.createInitVaultDepositorIx(vaultAccount.pubkey, initVaultDepositor.authority));
1155
+ }
1156
+ const depositIx = await this.program.methods
1157
+ .deposit(amount)
1158
+ .accounts({
1159
+ authority: this.driftClient.wallet.publicKey,
1160
+ ...accounts,
1161
+ })
1162
+ .remainingAccounts(remainingAccounts)
1163
+ .instruction();
1164
+ ixs.push(...preIxs);
1165
+ ixs.push(depositIx);
1166
+ ixs.push(...postIxs);
1167
+ if ((txParams === null || txParams === void 0 ? void 0 : txParams.noLut) ? txParams.noLut : false) {
1168
+ return await this.createTxnNoLut(ixs, txParams);
1169
+ }
1170
+ else {
1171
+ return await this.createTxn(ixs, txParams);
1172
+ }
1173
+ }
1174
+ /**
1175
+ * Depositor funds into the specified vault.
1176
+ * @param vaultDepositor
1177
+ * @param amount
1178
+ * @param initVaultDepositor If true, will initialize the vault depositor account
1179
+ * @param txParams
1180
+ * @returns
1181
+ */
1182
+ async deposit(vaultDepositor, amount, initVaultDepositor, txParams, userTokenAccount) {
1183
+ const depositTxn = await this.createDepositTx(vaultDepositor, amount, initVaultDepositor, txParams, userTokenAccount);
1184
+ return this.sendTxn(depositTxn, txParams === null || txParams === void 0 ? void 0 : txParams.simulateTransaction);
1185
+ }
1186
+ async requestWithdraw(vaultDepositor, amount, withdrawUnit, txParams) {
1187
+ const ixs = await this.getRequestWithdrawIx(vaultDepositor, amount, withdrawUnit, txParams === null || txParams === void 0 ? void 0 : txParams.oracleFeedsToCrank);
1188
+ return await this.createAndSendTxn(ixs, txParams);
1189
+ }
1190
+ async getRequestWithdrawIx(vaultDepositor, amount, withdrawUnit, oracleFeedsToCrank) {
1191
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
1192
+ const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
1193
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1194
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vaultDepositorAccount.vault);
1195
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
1196
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, false, false);
1197
+ const accounts = {
1198
+ vault: vaultDepositorAccount.vault,
1199
+ vaultDepositor,
1200
+ driftUser: vaultAccount.user,
1201
+ driftUserStats: userStatsKey,
1202
+ };
1203
+ const oracleFeedsToCrankIxs = await this.getOracleFeedsToCrankIxs(oracleFeedsToCrank);
1204
+ const requestWithdrawIx = this.program.instruction.requestWithdraw(
1205
+ // @ts-ignore
1206
+ amount, withdrawUnit, {
1207
+ accounts: {
1208
+ authority: this.driftClient.wallet.publicKey,
1209
+ ...accounts,
1210
+ },
1211
+ remainingAccounts,
1212
+ });
1213
+ return [...oracleFeedsToCrankIxs, requestWithdrawIx];
1214
+ }
1215
+ async withdraw(vaultDepositor, txParams) {
1216
+ const ixs = await this.getWithdrawIx(vaultDepositor, txParams === null || txParams === void 0 ? void 0 : txParams.oracleFeedsToCrank);
1217
+ return await this.createAndSendTxn(ixs, {
1218
+ cuLimit: 850000, // overestimating to be safe
1219
+ ...txParams,
1220
+ });
1221
+ }
1222
+ async getWithdrawIx(vaultDepositor, oracleFeedsToCrank) {
1223
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
1224
+ const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
1225
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1226
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vaultDepositorAccount.vault);
1227
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
1228
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, false, false);
1229
+ const driftStateKey = await this.driftClient.getStatePublicKey();
1230
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
1231
+ if (!spotMarket) {
1232
+ throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
1233
+ }
1234
+ const isSolMarket = spotMarket.mint.equals(sdk_1.WRAPPED_SOL_MINT);
1235
+ // let createAtaIx: TransactionInstruction | undefined = undefined;
1236
+ let userAta = (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, this.driftClient.wallet.publicKey, true);
1237
+ const preIxs = [];
1238
+ const postIxs = [];
1239
+ if (isSolMarket) {
1240
+ const { ixs, pubkey } = await this.driftClient.getWrappedSolAccountCreationIxs(sdk_1.ZERO, false);
1241
+ userAta = pubkey;
1242
+ preIxs.push(...ixs);
1243
+ postIxs.push((0, spl_token_1.createSyncNativeInstruction)(userAta));
1244
+ postIxs.push((0, spl_token_1.createCloseAccountInstruction)(userAta, this.driftClient.wallet.publicKey, this.driftClient.wallet.publicKey, []));
1245
+ }
1246
+ else {
1247
+ const userAtaExists = await this.driftClient.connection.getAccountInfo(userAta);
1248
+ if (userAtaExists === null) {
1249
+ preIxs.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(this.driftClient.wallet.publicKey, userAta, this.driftClient.wallet.publicKey, spotMarket.mint));
1250
+ }
1251
+ }
1252
+ const accounts = {
1253
+ vault: vaultDepositorAccount.vault,
1254
+ vaultDepositor,
1255
+ vaultTokenAccount: vaultAccount.tokenAccount,
1256
+ driftUserStats: userStatsKey,
1257
+ driftUser: vaultAccount.user,
1258
+ driftState: driftStateKey,
1259
+ driftSpotMarketVault: spotMarket.vault,
1260
+ driftSigner: this.driftClient.getStateAccount().signer,
1261
+ userTokenAccount: userAta,
1262
+ driftProgram: this.driftClient.program.programId,
1263
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
1264
+ };
1265
+ const oracleFeedsToCrankIxs = await this.getOracleFeedsToCrankIxs(oracleFeedsToCrank);
1266
+ const ixs = [
1267
+ ...oracleFeedsToCrankIxs,
1268
+ ...preIxs,
1269
+ await this.program.methods
1270
+ .withdraw()
1271
+ .accounts({
1272
+ authority: this.driftClient.wallet.publicKey,
1273
+ ...accounts,
1274
+ })
1275
+ .remainingAccounts(remainingAccounts)
1276
+ .instruction(),
1277
+ ...postIxs,
1278
+ ];
1279
+ return ixs;
1280
+ }
1281
+ async forceWithdraw(vaultDepositor, txParams) {
1282
+ const ix = await this.getForceWithdrawIx(vaultDepositor);
1283
+ return await this.createAndSendTxn(ix, txParams);
1284
+ }
1285
+ async getForceWithdrawIx(vaultDepositor) {
1286
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
1287
+ const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
1288
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1289
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vaultDepositorAccount.vault);
1290
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
1291
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, false, false);
1292
+ if (vaultAccount.vaultProtocol) {
1293
+ const vaultProtocol = this.getVaultProtocolAddress(vaultDepositorAccount.vault);
1294
+ remainingAccounts.push({
1295
+ pubkey: vaultProtocol,
1296
+ isSigner: false,
1297
+ isWritable: true,
1298
+ });
1299
+ }
1300
+ const driftStateKey = await this.driftClient.getStatePublicKey();
1301
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
1302
+ if (!spotMarket) {
1303
+ throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
1304
+ }
1305
+ const [userTokenAccount, createAtaIx] = await (0, utils_1.getOrCreateATAInstruction)(spotMarket.mint, vaultDepositorAccount.authority, this.driftClient.connection, true, this.driftClient.wallet.publicKey);
1306
+ if (createAtaIx) {
1307
+ console.log(`Creating ATA for ${vaultDepositorAccount.authority.toBase58()} to ${userTokenAccount.toBase58()}`);
1308
+ }
1309
+ const accounts = {
1310
+ manager: vaultAccount.manager,
1311
+ vault: vaultDepositorAccount.vault,
1312
+ vaultDepositor,
1313
+ vaultTokenAccount: vaultAccount.tokenAccount,
1314
+ driftUserStats: userStatsKey,
1315
+ driftUser: vaultAccount.user,
1316
+ driftState: driftStateKey,
1317
+ driftSpotMarketVault: spotMarket.vault,
1318
+ driftSigner: this.driftClient.getStateAccount().signer,
1319
+ userTokenAccount,
1320
+ driftProgram: this.driftClient.program.programId,
1321
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
1322
+ };
1323
+ const ixs = [];
1324
+ if (createAtaIx) {
1325
+ ixs.push(createAtaIx);
1326
+ }
1327
+ ixs.push(await this.program.methods
1328
+ .forceWithdraw()
1329
+ .accounts(accounts)
1330
+ .remainingAccounts(remainingAccounts)
1331
+ .instruction());
1332
+ return ixs;
1333
+ }
1334
+ async cancelRequestWithdraw(vaultDepositor, txParams) {
1335
+ const ixs = await this.getCancelRequestWithdrawIx(vaultDepositor, txParams === null || txParams === void 0 ? void 0 : txParams.oracleFeedsToCrank);
1336
+ return await this.createAndSendTxn(ixs, txParams);
1337
+ }
1338
+ async getCancelRequestWithdrawIx(vaultDepositor, oracleFeedsToCrank) {
1339
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
1340
+ const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
1341
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vaultDepositorAccount.vault);
1342
+ const accounts = {
1343
+ vault: vaultDepositorAccount.vault,
1344
+ vaultDepositor,
1345
+ driftUserStats: userStatsKey,
1346
+ driftUser: vaultAccount.user,
1347
+ };
1348
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1349
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
1350
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, false, false);
1351
+ if (this.cliMode) {
1352
+ return [
1353
+ await this.program.methods
1354
+ .cancelRequestWithdraw()
1355
+ .accounts(accounts)
1356
+ .remainingAccounts(remainingAccounts)
1357
+ .instruction(),
1358
+ ];
1359
+ }
1360
+ else {
1361
+ const oracleFeedsToCrankIxs = await this.getOracleFeedsToCrankIxs(oracleFeedsToCrank);
1362
+ const cancelRequestWithdrawIx = this.program.instruction.cancelRequestWithdraw({
1363
+ accounts: {
1364
+ authority: this.driftClient.wallet.publicKey,
1365
+ ...accounts,
1366
+ },
1367
+ remainingAccounts,
1368
+ });
1369
+ return [...oracleFeedsToCrankIxs, cancelRequestWithdrawIx];
1370
+ }
1371
+ }
1372
+ /**
1373
+ * Liquidates (become delegate for) a vault.
1374
+ * @param
1375
+ * @param
1376
+ * @returns
1377
+ */
1378
+ async liquidate(vaultDepositor, txParams) {
1379
+ const ix = await this.getLiquidateIx(vaultDepositor);
1380
+ return await this.createAndSendTxn([ix], txParams);
1381
+ }
1382
+ async getLiquidateIx(vaultDepositor) {
1383
+ if (!this.driftClient.wallet.publicKey.equals(constants_1.VAULT_ADMIN_KEY)) {
1384
+ throw new Error('Only vault admin can liquidate');
1385
+ }
1386
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
1387
+ const vault = vaultDepositorAccount.vault;
1388
+ const vaultAccount = await this.program.account.vault.fetch(vault);
1389
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1390
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
1391
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
1392
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [vaultAccount.spotMarketIndex], vaultAccount, userStats, false, true, true);
1393
+ const driftStateKey = await this.driftClient.getStatePublicKey();
1394
+ const accounts = {
1395
+ vault,
1396
+ vaultDepositor,
1397
+ vaultTokenAccount: vaultAccount.tokenAccount,
1398
+ driftUserStats: userStatsKey,
1399
+ driftUser: vaultAccount.user,
1400
+ driftState: driftStateKey,
1401
+ driftProgram: this.driftClient.program.programId,
1402
+ authority: vaultDepositorAccount.authority,
1403
+ };
1404
+ if (this.cliMode) {
1405
+ return await this.program.methods
1406
+ .liquidate()
1407
+ .accounts(accounts)
1408
+ .remainingAccounts(remainingAccounts)
1409
+ .instruction();
1410
+ }
1411
+ else {
1412
+ return this.program.instruction.liquidate({
1413
+ accounts: {
1414
+ ...accounts,
1415
+ admin: this.driftClient.wallet.publicKey,
1416
+ },
1417
+ remainingAccounts,
1418
+ });
1419
+ }
1420
+ }
1421
+ async createTxn(vaultIxs, txParams) {
1422
+ var _a, _b;
1423
+ const ixs = [
1424
+ web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
1425
+ units: (_a = txParams === null || txParams === void 0 ? void 0 : txParams.cuLimit) !== null && _a !== void 0 ? _a : 400000,
1426
+ }),
1427
+ web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
1428
+ microLamports: (txParams === null || txParams === void 0 ? void 0 : txParams.cuPriceMicroLamports) === undefined
1429
+ ? 50000
1430
+ : txParams.cuPriceMicroLamports,
1431
+ }),
1432
+ ...vaultIxs,
1433
+ ];
1434
+ return (await this.driftClient.txHandler.buildTransaction({
1435
+ connection: this.driftClient.connection,
1436
+ instructions: ixs,
1437
+ lookupTables: (_b = txParams === null || txParams === void 0 ? void 0 : txParams.lookupTables) !== null && _b !== void 0 ? _b : [],
1438
+ preFlightCommitment: 'confirmed',
1439
+ forceVersionedTransaction: true,
1440
+ txVersion: 0,
1441
+ fetchAllMarketLookupTableAccounts: this.driftClient.fetchAllLookupTableAccounts.bind(this.driftClient),
1442
+ }));
1443
+ }
1444
+ async createTxnNoLut(vaultIxs, txParams) {
1445
+ var _a;
1446
+ const ixs = [
1447
+ web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
1448
+ units: (_a = txParams === null || txParams === void 0 ? void 0 : txParams.cuLimit) !== null && _a !== void 0 ? _a : 400000,
1449
+ }),
1450
+ web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
1451
+ microLamports: (txParams === null || txParams === void 0 ? void 0 : txParams.cuPriceMicroLamports) === undefined
1452
+ ? 50000
1453
+ : txParams.cuPriceMicroLamports,
1454
+ }),
1455
+ ...vaultIxs,
1456
+ ];
1457
+ const recentBlockhash = await this.driftClient.connection.getLatestBlockhash();
1458
+ return this.driftClient.txHandler.generateVersionedTransaction(recentBlockhash, ixs, [], this.driftClient.wallet);
1459
+ }
1460
+ async sendTxn(transaction, simulateTransaction) {
1461
+ var _a;
1462
+ let txSig = bytes_1.bs58.encode(transaction.signatures[0]);
1463
+ if (simulateTransaction) {
1464
+ try {
1465
+ const resp = await this.driftClient.connection.simulateTransaction(transaction, {
1466
+ sigVerify: false,
1467
+ commitment: this.driftClient.connection.commitment,
1468
+ });
1469
+ console.log(`Simulated transaction:\n${JSON.stringify(resp, null, 2)}`);
1470
+ }
1471
+ catch (e) {
1472
+ const err = e;
1473
+ console.error(`Error simulating transaction: ${err.message}\n:${(_a = err.stack) !== null && _a !== void 0 ? _a : ''}`);
1474
+ }
1475
+ }
1476
+ else {
1477
+ const resp = await this.driftClient.sendTransaction(transaction, [], this.driftClient.opts);
1478
+ if (resp.txSig !== txSig) {
1479
+ txSig = resp.txSig;
1480
+ }
1481
+ }
1482
+ return txSig;
1483
+ }
1484
+ /**
1485
+ * Used for UI wallet adapters compatibility
1486
+ */
1487
+ async createAndSendTxn(vaultIxs, txParams) {
1488
+ let tx;
1489
+ if ((txParams === null || txParams === void 0 ? void 0 : txParams.noLut) ? txParams.noLut : false) {
1490
+ tx = await this.createTxnNoLut(vaultIxs, txParams);
1491
+ // @ts-ignore
1492
+ tx.sign([this.driftClient.wallet.payer]);
1493
+ }
1494
+ else {
1495
+ tx = await this.createTxn(vaultIxs, txParams);
1496
+ }
1497
+ const txSig = await this.sendTxn(tx, txParams === null || txParams === void 0 ? void 0 : txParams.simulateTransaction);
1498
+ return txSig;
1499
+ }
1500
+ /**
1501
+ * Initializes an insurance fund stake for the vault.
1502
+ * @param vault vault address to update
1503
+ * @param spotMarketIndex spot market index of the insurance fund stake
1504
+ * @returns
1505
+ */
1506
+ async initializeInsuranceFundStake(vault, spotMarketIndex, txParams) {
1507
+ const ixs = await this.getInitializeInsuranceFundStakeIx(vault, spotMarketIndex);
1508
+ return await this.createAndSendTxn([ixs], txParams);
1509
+ }
1510
+ async getInitializeInsuranceFundStakeIx(vault, spotMarketIndex) {
1511
+ const vaultAccount = await this.program.account.vault.fetch(vault);
1512
+ const _ifStakeAccountPublicKey = (0, sdk_1.getInsuranceFundStakeAccountPublicKey)(this.driftClient.program.programId, vault, spotMarketIndex);
1513
+ const spotMarket = this.driftClient.getSpotMarketAccount(spotMarketIndex);
1514
+ if (!spotMarket) {
1515
+ throw new Error(`Spot market ${spotMarketIndex} not found on driftClient`);
1516
+ }
1517
+ const _ifVaultTokenAccount = (0, addresses_1.getInsuranceFundTokenVaultAddressSync)(this.program.programId, vault, spotMarketIndex);
1518
+ return await this.program.methods
1519
+ .initializeInsuranceFundStake(spotMarketIndex)
1520
+ .accounts({
1521
+ vault: vault,
1522
+ driftSpotMarketMint: spotMarket.mint,
1523
+ driftUserStats: vaultAccount.userStats,
1524
+ driftState: await this.driftClient.getStatePublicKey(),
1525
+ })
1526
+ .instruction();
1527
+ }
1528
+ /**
1529
+ * Adds an amount to an insurance fund stake for the vault.
1530
+ * @param vault vault address to update
1531
+ * @param spotMarketIndex spot market index of the insurance fund stake
1532
+ * @param amount amount to add to the insurance fund stake, in spotMarketIndex precision
1533
+ * @returns
1534
+ */
1535
+ async addToInsuranceFundStake(vault, spotMarketIndex, amount, managerTokenAccount, txParams) {
1536
+ const ixs = await this.getAddToInsuranceFundStakeIx(vault, spotMarketIndex, amount, managerTokenAccount);
1537
+ return await this.createAndSendTxn([ixs], txParams);
1538
+ }
1539
+ async getAddToInsuranceFundStakeIx(vault, spotMarketIndex, amount, managerTokenAccount) {
1540
+ const vaultAccount = await this.program.account.vault.fetch(vault);
1541
+ if (!vaultAccount.manager.equals(this.driftClient.wallet.publicKey)) {
1542
+ throw new Error(`Only the manager of the vault can add to the insurance fund stake.`);
1543
+ }
1544
+ const _ifStakeAccountPublicKey = (0, sdk_1.getInsuranceFundStakeAccountPublicKey)(this.driftClient.program.programId, vault, spotMarketIndex);
1545
+ const _ifVaultPublicKey = await (0, sdk_1.getInsuranceFundVaultPublicKey)(this.driftClient.program.programId, spotMarketIndex);
1546
+ const spotMarket = this.driftClient.getSpotMarketAccount(spotMarketIndex);
1547
+ if (!spotMarket) {
1548
+ throw new Error(`Spot market ${spotMarketIndex} not found on driftClient`);
1549
+ }
1550
+ if (!managerTokenAccount) {
1551
+ managerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, vaultAccount.manager, true);
1552
+ }
1553
+ const _ifVaultTokenAccount = (0, addresses_1.getInsuranceFundTokenVaultAddressSync)(this.program.programId, vault, spotMarketIndex);
1554
+ return await this.program.methods
1555
+ .addInsuranceFundStake(spotMarketIndex, amount)
1556
+ .accounts({
1557
+ vault: vault,
1558
+ managerTokenAccount,
1559
+ driftUserStats: vaultAccount.userStats,
1560
+ driftState: await this.driftClient.getStatePublicKey(),
1561
+ driftSigner: this.driftClient.getStateAccount().signer,
1562
+ })
1563
+ .instruction();
1564
+ }
1565
+ async requestRemoveInsuranceFundStake(vault, spotMarketIndex, amount, txParams) {
1566
+ const ix = await this.getRequestRemoveInsuranceFundStakeIx(vault, spotMarketIndex, amount);
1567
+ return await this.createAndSendTxn([ix], txParams);
1568
+ }
1569
+ async getRequestRemoveInsuranceFundStakeIx(vault, spotMarketIndex, amount) {
1570
+ const vaultAccount = await this.program.account.vault.fetch(vault);
1571
+ const _ifStakeAccountPublicKey = (0, sdk_1.getInsuranceFundStakeAccountPublicKey)(this.driftClient.program.programId, vault, spotMarketIndex);
1572
+ const _ifVaultPublicKey = await (0, sdk_1.getInsuranceFundVaultPublicKey)(this.driftClient.program.programId, spotMarketIndex);
1573
+ const spotMarket = this.driftClient.getSpotMarketAccount(spotMarketIndex);
1574
+ if (!spotMarket) {
1575
+ throw new Error(`Spot market ${spotMarketIndex} not found on driftClient`);
1576
+ }
1577
+ return await this.program.methods
1578
+ .requestRemoveInsuranceFundStake(spotMarketIndex, amount)
1579
+ .accounts({
1580
+ vault,
1581
+ manager: vaultAccount.manager,
1582
+ driftUserStats: vaultAccount.userStats,
1583
+ })
1584
+ .instruction();
1585
+ }
1586
+ async cancelRequestRemoveInsuranceFundStake(vault, spotMarketIndex, txParams) {
1587
+ const ix = await this.getCancelRequestRemoveInsuranceFundStakeIx(vault, spotMarketIndex);
1588
+ return await this.createAndSendTxn([ix], txParams);
1589
+ }
1590
+ async getCancelRequestRemoveInsuranceFundStakeIx(vault, spotMarketIndex) {
1591
+ const vaultAccount = await this.program.account.vault.fetch(vault);
1592
+ const _ifStakeAccountPublicKey = (0, sdk_1.getInsuranceFundStakeAccountPublicKey)(this.driftClient.program.programId, vault, spotMarketIndex);
1593
+ const _ifVaultPublicKey = await (0, sdk_1.getInsuranceFundVaultPublicKey)(this.driftClient.program.programId, spotMarketIndex);
1594
+ const spotMarket = this.driftClient.getSpotMarketAccount(spotMarketIndex);
1595
+ if (!spotMarket) {
1596
+ throw new Error(`Spot market ${spotMarketIndex} not found on driftClient`);
1597
+ }
1598
+ return await this.program.methods
1599
+ .cancelRequestRemoveInsuranceFundStake(spotMarketIndex)
1600
+ .accounts({
1601
+ vault: vault,
1602
+ manager: vaultAccount.manager,
1603
+ driftUserStats: vaultAccount.userStats,
1604
+ })
1605
+ .instruction();
1606
+ }
1607
+ async removeInsuranceFundStake(vault, spotMarketIndex, managerTokenAccount, txParams) {
1608
+ const ixs = await this.getRemoveInsuranceFundStakeIx(vault, spotMarketIndex, managerTokenAccount);
1609
+ return await this.createAndSendTxn([ixs], txParams);
1610
+ }
1611
+ async getRemoveInsuranceFundStakeIx(vault, spotMarketIndex, managerTokenAccount) {
1612
+ const vaultAccount = await this.program.account.vault.fetch(vault);
1613
+ const _ifStakeAccountPublicKey = (0, sdk_1.getInsuranceFundStakeAccountPublicKey)(this.driftClient.program.programId, vault, spotMarketIndex);
1614
+ const _ifVaultPublicKey = await (0, sdk_1.getInsuranceFundVaultPublicKey)(this.driftClient.program.programId, spotMarketIndex);
1615
+ const spotMarket = this.driftClient.getSpotMarketAccount(spotMarketIndex);
1616
+ if (!spotMarket) {
1617
+ throw new Error(`Spot market ${spotMarketIndex} not found on driftClient`);
1618
+ }
1619
+ if (!managerTokenAccount) {
1620
+ managerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, vaultAccount.manager, true);
1621
+ }
1622
+ const _ifVaultTokenAccount = (0, addresses_1.getInsuranceFundTokenVaultAddressSync)(this.program.programId, vault, spotMarketIndex);
1623
+ return await this.program.methods
1624
+ .removeInsuranceFundStake(spotMarketIndex)
1625
+ .accounts({
1626
+ vault: vault,
1627
+ managerTokenAccount,
1628
+ driftState: await this.driftClient.getStatePublicKey(),
1629
+ driftUserStats: vaultAccount.userStats,
1630
+ driftSigner: this.driftClient.getStateAccount().signer,
1631
+ })
1632
+ .instruction();
1633
+ }
1634
+ async protocolRequestWithdraw(vault, amount, withdrawUnit, txParams) {
1635
+ const ix = await this.getProtocolRequestWithdrawIx(vault, amount, withdrawUnit);
1636
+ return await this.createAndSendTxn([ix], txParams);
1637
+ }
1638
+ async getProtocolRequestWithdrawIx(vault, amount, withdrawUnit) {
1639
+ // @ts-ignore
1640
+ const vaultAccount = (await this.program.account.vault.fetch(vault));
1641
+ const vp = this.getVaultProtocolAddress(vault);
1642
+ const vpAccount = (await this.program.account.vaultProtocol.fetch(vp));
1643
+ if (!this.driftClient.wallet.publicKey.equals(vpAccount.protocol)) {
1644
+ throw new Error(`Only the protocol of the vault can request a withdraw.`);
1645
+ }
1646
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1647
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
1648
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
1649
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [], vaultAccount, userStats, false, true, true);
1650
+ const accounts = {
1651
+ vault,
1652
+ driftUserStats: userStatsKey,
1653
+ driftUser: vaultAccount.user,
1654
+ };
1655
+ if (this.cliMode) {
1656
+ return await this.program.methods
1657
+ // @ts-ignore, 0.29.0 anchor issues..
1658
+ .managerRequestWithdraw(amount, withdrawUnit)
1659
+ .accounts(accounts)
1660
+ .remainingAccounts(remainingAccounts)
1661
+ .instruction();
1662
+ }
1663
+ else {
1664
+ const requestWithdrawIx = this.program.instruction.managerRequestWithdraw(
1665
+ // @ts-ignore
1666
+ amount, withdrawUnit, {
1667
+ accounts: {
1668
+ manager: vaultAccount.manager,
1669
+ ...accounts,
1670
+ },
1671
+ remainingAccounts,
1672
+ });
1673
+ return requestWithdrawIx;
1674
+ }
1675
+ }
1676
+ async protocolCancelWithdrawRequest(vault, txParams) {
1677
+ const ixs = await this.getProtocolCancelWithdrawRequestIx(vault);
1678
+ return await this.createAndSendTxn(ixs, txParams);
1679
+ }
1680
+ async getProtocolCancelWithdrawRequestIx(vault) {
1681
+ const vaultAccount = await this.program.account.vault.fetch(vault);
1682
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
1683
+ const accounts = {
1684
+ manager: vaultAccount.manager,
1685
+ vault,
1686
+ driftUserStats: userStatsKey,
1687
+ driftUser: vaultAccount.user,
1688
+ };
1689
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1690
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
1691
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [], vaultAccount, userStats, false, true, true);
1692
+ if (this.cliMode) {
1693
+ return [
1694
+ await this.program.methods
1695
+ .mangerCancelWithdrawRequest()
1696
+ .accounts(accounts)
1697
+ .remainingAccounts(remainingAccounts)
1698
+ .instruction(),
1699
+ ];
1700
+ }
1701
+ else {
1702
+ const cancelRequestWithdrawIx = this.program.instruction.mangerCancelWithdrawRequest({
1703
+ accounts: {
1704
+ ...accounts,
1705
+ manager: vaultAccount.manager,
1706
+ },
1707
+ remainingAccounts,
1708
+ });
1709
+ return [cancelRequestWithdrawIx];
1710
+ }
1711
+ }
1712
+ async protocolWithdraw(vault, txParams) {
1713
+ const ixs = await this.getProtocolWithdrawIx(vault);
1714
+ return await this.createAndSendTxn(ixs, txParams);
1715
+ }
1716
+ async getProtocolWithdrawIx(vault) {
1717
+ const vaultAccount = await this.program.account.vault.fetch(vault);
1718
+ if (!this.driftClient.wallet.publicKey.equals(vaultAccount.manager)) {
1719
+ throw new Error(`Only the manager of the vault can request a withdraw.`);
1720
+ }
1721
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1722
+ const userStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, vault);
1723
+ const userStats = (await this.driftClient.program.account.userStats.fetch(userStatsKey));
1724
+ const remainingAccounts = this.getRemainingAccountsForUser([user.getUserAccount()], [], vaultAccount, userStats, false, true, true);
1725
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
1726
+ if (!spotMarket) {
1727
+ throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
1728
+ }
1729
+ const ix = this.program.instruction.managerWithdraw({
1730
+ accounts: {
1731
+ vault,
1732
+ manager: vaultAccount.manager,
1733
+ vaultTokenAccount: vaultAccount.tokenAccount,
1734
+ driftUser: await (0, sdk_1.getUserAccountPublicKey)(this.driftClient.program.programId, vault),
1735
+ driftProgram: this.driftClient.program.programId,
1736
+ driftUserStats: userStatsKey,
1737
+ driftState: await this.driftClient.getStatePublicKey(),
1738
+ driftSpotMarketVault: spotMarket.vault,
1739
+ userTokenAccount: (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, this.driftClient.wallet.publicKey),
1740
+ driftSigner: this.driftClient.getStateAccount().signer,
1741
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
1742
+ },
1743
+ remainingAccounts,
1744
+ });
1745
+ return [ix];
1746
+ }
1747
+ async getPythLazerOracleCrankIxs(oracleFeedsToCrank = [], pythLazerMsgHexGetter) {
1748
+ try {
1749
+ const isPythLazerOracle = (oracleSource) => {
1750
+ const pythLazerStr = JSON.stringify(sdk_1.OracleSource.PYTH_LAZER);
1751
+ const pythLazer1kStr = JSON.stringify(sdk_1.OracleSource.PYTH_LAZER_1K);
1752
+ const pythLazer1mStr = JSON.stringify(sdk_1.OracleSource.PYTH_LAZER_1M);
1753
+ const pythLazerStableCoinStr = JSON.stringify(sdk_1.OracleSource.PYTH_LAZER_STABLE_COIN);
1754
+ const targetOracleSourceStr = JSON.stringify(oracleSource);
1755
+ return (targetOracleSourceStr === pythLazerStr ||
1756
+ targetOracleSourceStr === pythLazer1kStr ||
1757
+ targetOracleSourceStr === pythLazer1mStr ||
1758
+ targetOracleSourceStr === pythLazerStableCoinStr);
1759
+ };
1760
+ const pythLazerOracles = oracleFeedsToCrank.filter((config) => isPythLazerOracle(config.oracleSource));
1761
+ if (pythLazerOracles.length === 0) {
1762
+ return [];
1763
+ }
1764
+ if (!pythLazerMsgHexGetter) {
1765
+ console.error('pythLazerMsgHexGetter is required to crank pyth lazer oracles');
1766
+ return [];
1767
+ }
1768
+ const pythLazerFeedIds = pythLazerOracles
1769
+ .map((config) => config.pythLazerId)
1770
+ .filter(Boolean);
1771
+ const pythLazerMsgHex = await pythLazerMsgHexGetter(pythLazerFeedIds);
1772
+ const oracleUpdateIxs = await this.driftClient.getPostPythLazerOracleUpdateIxs(pythLazerFeedIds, pythLazerMsgHex, undefined, 3);
1773
+ return oracleUpdateIxs;
1774
+ }
1775
+ catch (err) {
1776
+ console.error('Error cranking pyth lazer oracles', err);
1777
+ return [];
1778
+ }
1779
+ }
1780
+ async getOracleFeedsToCrankIxs(oracleFeedsToCrank) {
1781
+ if (!(oracleFeedsToCrank === null || oracleFeedsToCrank === void 0 ? void 0 : oracleFeedsToCrank.feedsToCrank)) {
1782
+ return [];
1783
+ }
1784
+ return await this.getPythLazerOracleCrankIxs(oracleFeedsToCrank.feedsToCrank, oracleFeedsToCrank.pythLazerMsgHexGetter);
1785
+ }
1786
+ async updateVaultProtocol(vault, params, txParams) {
1787
+ const ix = await this.getUpdateVaultProtocolIx(vault, params);
1788
+ return await this.createAndSendTxn([ix], txParams);
1789
+ }
1790
+ async getUpdateVaultProtocolIx(vault, params) {
1791
+ return this.program.methods
1792
+ .updateVaultProtocol(params)
1793
+ .accounts({
1794
+ vault,
1795
+ vaultProtocol: this.getVaultProtocolAddress(vault),
1796
+ })
1797
+ .instruction();
1798
+ }
1799
+ async adminInitFeeUpdate(vault, uiTxParams) {
1800
+ const ix = await this.getAdminInitFeeUpdateIx(vault);
1801
+ return await this.createAndSendTxn([ix], uiTxParams);
1802
+ }
1803
+ async getAdminInitFeeUpdateIx(vault) {
1804
+ const feeUpdate = (0, addresses_1.getFeeUpdateAddressSync)(this.program.programId, vault);
1805
+ return this.program.instruction.adminInitFeeUpdate({
1806
+ accounts: {
1807
+ vault,
1808
+ admin: this.driftClient.wallet.publicKey,
1809
+ feeUpdate,
1810
+ systemProgram: web3_js_1.SystemProgram.programId,
1811
+ },
1812
+ });
1813
+ }
1814
+ async adminDeleteFeeUpdate(vault, uiTxParams) {
1815
+ const ix = await this.getAdminDeleteFeeUpdateIx(vault);
1816
+ return await this.createAndSendTxn([ix], uiTxParams);
1817
+ }
1818
+ async getAdminDeleteFeeUpdateIx(vault) {
1819
+ const feeUpdate = (0, addresses_1.getFeeUpdateAddressSync)(this.program.programId, vault);
1820
+ return this.program.instruction.adminDeleteFeeUpdate({
1821
+ accounts: {
1822
+ vault,
1823
+ admin: this.driftClient.wallet.publicKey,
1824
+ feeUpdate,
1825
+ },
1826
+ });
1827
+ }
1828
+ async adminUpdateVaultClass(vault, newVaultClass, uiTxParams) {
1829
+ const ix = await this.getAdminUpdateVaultClassIx(vault, newVaultClass);
1830
+ return await this.createAndSendTxn([ix], uiTxParams);
1831
+ }
1832
+ async getAdminUpdateVaultClassIx(vault, newVaultClass) {
1833
+ return this.program.methods
1834
+ .adminUpdateVaultClass(newVaultClass)
1835
+ .accounts({
1836
+ vault,
1837
+ admin: this.driftClient.wallet.publicKey,
1838
+ })
1839
+ .instruction();
1840
+ }
1841
+ async managerUpdateFees(vault, params, uiTxParams) {
1842
+ const feeUpdate = (0, addresses_1.getFeeUpdateAddressSync)(this.program.programId, vault);
1843
+ const ixs = [];
1844
+ if (!(await this.checkIfAccountExists(feeUpdate))) {
1845
+ throw new Error('Fee update account does not exist, it must be created by an admin first');
1846
+ }
1847
+ ixs.push(await this.getManagerUpdateFeesIx(vault, params));
1848
+ return await this.createAndSendTxn(ixs, uiTxParams);
1849
+ }
1850
+ async getManagerUpdateFeesIx(vault, params) {
1851
+ const vaultAccount = await this.program.account.vault.fetch(vault);
1852
+ const feeUpdate = (0, addresses_1.getFeeUpdateAddressSync)(this.program.programId, vault);
1853
+ return this.program.instruction.managerUpdateFees(params, {
1854
+ accounts: {
1855
+ vault,
1856
+ manager: vaultAccount.manager,
1857
+ feeUpdate,
1858
+ },
1859
+ });
1860
+ }
1861
+ async managerCancelFeeUpdate(vault, uiTxParams) {
1862
+ const ix = await this.getManagerCancelFeeUpdateIx(vault);
1863
+ return await this.createAndSendTxn([ix], uiTxParams);
1864
+ }
1865
+ async getManagerCancelFeeUpdateIx(vault) {
1866
+ const vaultAccount = await this.program.account.vault.fetch(vault);
1867
+ const feeUpdate = (0, addresses_1.getFeeUpdateAddressSync)(this.program.programId, vault);
1868
+ return this.program.instruction.managerCancelFeeUpdate({
1869
+ accounts: {
1870
+ vault,
1871
+ manager: vaultAccount.manager,
1872
+ feeUpdate,
1873
+ },
1874
+ });
1875
+ }
1876
+ /**
1877
+ * Calculate the vault share price (base value per share)
1878
+ * @param params vault address or vault account, and precision exponent
1879
+ * @returns BigNum representing the base value per share
1880
+ */
1881
+ async calcVaultSharePrice(params) {
1882
+ let spotPrecisionExp = sdk_1.QUOTE_PRECISION_EXP;
1883
+ try {
1884
+ let vaultAccount;
1885
+ if (params.address !== undefined) {
1886
+ vaultAccount = await this.program.account.vault.fetch(params.address);
1887
+ }
1888
+ else if (params.vault !== undefined) {
1889
+ vaultAccount = params.vault;
1890
+ }
1891
+ else {
1892
+ throw new Error('Must supply address or vault');
1893
+ }
1894
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
1895
+ spotPrecisionExp = new sdk_1.BN(spotMarket.decimals);
1896
+ const totalAccountValue = await this.calculateVaultEquityInDepositAsset({
1897
+ vault: vaultAccount,
1898
+ factorUnrealizedPNL: true,
1899
+ });
1900
+ const vaultTotalShares = vaultAccount.totalShares.toString();
1901
+ const totalAccountValueStr = totalAccountValue.toString();
1902
+ return vaultTotalShares === '0'
1903
+ ? sdk_1.BigNum.from(0, spotPrecisionExp)
1904
+ : new sdk_1.BigNum(totalAccountValueStr, spotPrecisionExp)
1905
+ .shift(constants_1.VAULT_SHARES_PRECISION_EXP)
1906
+ .div(new sdk_1.BigNum(vaultTotalShares, constants_1.VAULT_SHARES_PRECISION_EXP));
1907
+ }
1908
+ catch (err) {
1909
+ console.error('VaultClient calcVaultSharePrice error:', err);
1910
+ return sdk_1.BigNum.from(0, spotPrecisionExp);
1911
+ }
1912
+ }
1913
+ }
1914
+ exports.VaultClient = VaultClient;