@drift-labs/vaults-sdk 0.1.0

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 (78) hide show
  1. package/.env.example +2 -0
  2. package/README.md +58 -0
  3. package/cli/cli.ts +105 -0
  4. package/cli/commands/applyProfitShare.ts +48 -0
  5. package/cli/commands/deposit.ts +35 -0
  6. package/cli/commands/index.ts +13 -0
  7. package/cli/commands/initVault.ts +61 -0
  8. package/cli/commands/initVaultDepositor.ts +43 -0
  9. package/cli/commands/listDepositorsForVault.ts +33 -0
  10. package/cli/commands/managerCancelWithdraw.ts +25 -0
  11. package/cli/commands/managerDeposit.ts +34 -0
  12. package/cli/commands/managerRequestWithdraw.ts +27 -0
  13. package/cli/commands/managerUpdateVault.ts +36 -0
  14. package/cli/commands/managerWithdraw.ts +25 -0
  15. package/cli/commands/requestWithdraw.ts +29 -0
  16. package/cli/commands/vaultDeposit.ts +43 -0
  17. package/cli/commands/vaultWithdraw.ts +43 -0
  18. package/cli/commands/viewVault.ts +30 -0
  19. package/cli/commands/viewVaultDepositor.ts +37 -0
  20. package/cli/commands/withdraw.ts +25 -0
  21. package/cli/utils.ts +119 -0
  22. package/lib/accountSubscribers/index.d.ts +2 -0
  23. package/lib/accountSubscribers/index.js +14 -0
  24. package/lib/accountSubscribers/pollingVaultDepositorSubscriber.d.ts +7 -0
  25. package/lib/accountSubscribers/pollingVaultDepositorSubscriber.js +44 -0
  26. package/lib/accountSubscribers/pollingVaultSubscriber.d.ts +7 -0
  27. package/lib/accountSubscribers/pollingVaultSubscriber.js +44 -0
  28. package/lib/accountSubscribers/pollingVaultsProgramAccountSubscriber.d.ts +28 -0
  29. package/lib/accountSubscribers/pollingVaultsProgramAccountSubscriber.js +68 -0
  30. package/lib/accounts/index.d.ts +2 -0
  31. package/lib/accounts/index.js +14 -0
  32. package/lib/accounts/vaultAccount.d.ts +15 -0
  33. package/lib/accounts/vaultAccount.js +53 -0
  34. package/lib/accounts/vaultDepositorAccount.d.ts +18 -0
  35. package/lib/accounts/vaultDepositorAccount.js +45 -0
  36. package/lib/accounts/vaultsProgramAccount.d.ts +13 -0
  37. package/lib/accounts/vaultsProgramAccount.js +25 -0
  38. package/lib/addresses.d.ts +4 -0
  39. package/lib/addresses.js +46 -0
  40. package/lib/constants/index.d.ts +3 -0
  41. package/lib/constants/index.js +5 -0
  42. package/lib/index.d.ts +9 -0
  43. package/lib/index.js +21 -0
  44. package/lib/name.d.ts +3 -0
  45. package/lib/name.js +19 -0
  46. package/lib/parsers/index.d.ts +1 -0
  47. package/lib/parsers/index.js +13 -0
  48. package/lib/parsers/logParser.d.ts +14 -0
  49. package/lib/parsers/logParser.js +21 -0
  50. package/lib/types/drift_vaults.d.ts +1475 -0
  51. package/lib/types/drift_vaults.js +1477 -0
  52. package/lib/types/types.d.ts +137 -0
  53. package/lib/types/types.js +20 -0
  54. package/lib/utils.d.ts +7 -0
  55. package/lib/utils.js +43 -0
  56. package/lib/vaultClient.d.ts +100 -0
  57. package/lib/vaultClient.js +596 -0
  58. package/package.json +29 -0
  59. package/src/accountSubscribers/index.ts +2 -0
  60. package/src/accountSubscribers/pollingVaultDepositorSubscriber.ts +68 -0
  61. package/src/accountSubscribers/pollingVaultSubscriber.ts +62 -0
  62. package/src/accountSubscribers/pollingVaultsProgramAccountSubscriber.ts +111 -0
  63. package/src/accounts/index.ts +2 -0
  64. package/src/accounts/vaultAccount.ts +86 -0
  65. package/src/accounts/vaultDepositorAccount.ts +67 -0
  66. package/src/accounts/vaultsProgramAccount.ts +37 -0
  67. package/src/addresses.ts +43 -0
  68. package/src/constants/index.ts +3 -0
  69. package/src/idl/drift_vaults.json +1547 -0
  70. package/src/index.ts +9 -0
  71. package/src/name.ts +18 -0
  72. package/src/parsers/index.ts +1 -0
  73. package/src/parsers/logParser.ts +28 -0
  74. package/src/types/drift_vaults.ts +2949 -0
  75. package/src/types/types.ts +158 -0
  76. package/src/utils.ts +33 -0
  77. package/src/vaultClient.ts +904 -0
  78. package/tsconfig.json +13 -0
@@ -0,0 +1,904 @@
1
+ import {
2
+ BN,
3
+ DriftClient,
4
+ getUserAccountPublicKey,
5
+ getUserAccountPublicKeySync,
6
+ getUserStatsAccountPublicKey,
7
+ User,
8
+ } from '@drift-labs/sdk';
9
+ import { BorshAccountsCoder, Program, ProgramAccount } from '@coral-xyz/anchor';
10
+ import { DriftVaults } from './types/drift_vaults';
11
+ import {
12
+ getTokenVaultAddressSync,
13
+ getVaultAddressSync,
14
+ getVaultDepositorAddressSync,
15
+ } from './addresses';
16
+ import {
17
+ ComputeBudgetProgram,
18
+ PublicKey,
19
+ SetComputeUnitLimitParams,
20
+ SystemProgram,
21
+ SYSVAR_RENT_PUBKEY,
22
+ Transaction,
23
+ TransactionInstruction,
24
+ TransactionSignature,
25
+ } from '@solana/web3.js';
26
+ import {
27
+ getAssociatedTokenAddressSync,
28
+ TOKEN_PROGRAM_ID,
29
+ } from '@solana/spl-token';
30
+ import { Vault, VaultDepositor, WithdrawUnit } from './types/types';
31
+ import { bs58 } from '@coral-xyz/anchor/dist/cjs/utils/bytes';
32
+
33
+ export class VaultClient {
34
+ driftClient: DriftClient;
35
+ program: Program<DriftVaults>;
36
+ cliMode: boolean;
37
+
38
+ constructor({
39
+ driftClient,
40
+ program,
41
+ cliMode,
42
+ }: {
43
+ driftClient: DriftClient;
44
+ program: Program<DriftVaults>;
45
+ cliMode?: boolean;
46
+ }) {
47
+ this.driftClient = driftClient;
48
+ this.program = program;
49
+ this.cliMode = !!cliMode;
50
+ }
51
+
52
+ public async getVault(vault: PublicKey): Promise<Vault> {
53
+ return await this.program.account.vault.fetch(vault);
54
+ }
55
+
56
+ public async getVaultDepositor(vaultDepositor: PublicKey): Promise<any> {
57
+ return await this.program.account.vaultDepositor.fetch(vaultDepositor);
58
+ }
59
+
60
+ public async getAllVaultDepositors(
61
+ vault: PublicKey
62
+ ): Promise<ProgramAccount<VaultDepositor>[]> {
63
+ const filters = [
64
+ {
65
+ // discriminator = VaultDepositor
66
+ memcmp: {
67
+ offset: 0,
68
+ bytes: bs58.encode(
69
+ BorshAccountsCoder.accountDiscriminator('VaultDepositor')
70
+ ),
71
+ },
72
+ },
73
+ {
74
+ // vault = vault
75
+ memcmp: {
76
+ offset: 8,
77
+ bytes: vault.toBase58(),
78
+ },
79
+ },
80
+ {
81
+ // last_withdraw_request_ts = 0
82
+ memcmp: {
83
+ offset: 144,
84
+ bytes: bs58.encode(Uint8Array.from([0])),
85
+ },
86
+ },
87
+ ];
88
+ // @ts-ignore
89
+ return (await this.program.account.vaultDepositor.all(
90
+ filters
91
+ )) as ProgramAccount<VaultDepositor>[];
92
+ }
93
+
94
+ /**
95
+ *
96
+ * @param vault pubkey
97
+ * @returns vault equity, in QUOTE_PRECISION
98
+ */
99
+ public async calculateVaultEquity(params: {
100
+ address?: PublicKey;
101
+ vault?: Vault;
102
+ }): Promise<BN> {
103
+ let vaultAccount: Vault;
104
+ if (params.address !== undefined) {
105
+ vaultAccount = await this.program.account.vault.fetch(params.address);
106
+ } else if (params.vault !== undefined) {
107
+ vaultAccount = params.vault;
108
+ } else {
109
+ throw new Error('Must supply address or vault');
110
+ }
111
+
112
+ const user = new User({
113
+ driftClient: this.driftClient,
114
+ userAccountPublicKey: vaultAccount.user,
115
+ });
116
+ await user.subscribe();
117
+
118
+ const netSpotValue = user.getNetSpotMarketValue();
119
+ const unrealizedPnl = user.getUnrealizedPNL(true, undefined, undefined);
120
+
121
+ return netSpotValue.add(unrealizedPnl);
122
+ }
123
+
124
+ public async initializeVault(params: {
125
+ name: number[];
126
+ spotMarketIndex: number;
127
+ redeemPeriod: BN;
128
+ maxTokens: BN;
129
+ minDepositAmount: BN;
130
+ managementFee: BN;
131
+ profitShare: number;
132
+ hurdleRate: number;
133
+ permissioned: boolean;
134
+ }): Promise<TransactionSignature> {
135
+ const vault = getVaultAddressSync(this.program.programId, params.name);
136
+ const tokenAccount = getTokenVaultAddressSync(
137
+ this.program.programId,
138
+ vault
139
+ );
140
+
141
+ const driftState = await this.driftClient.getStatePublicKey();
142
+ const spotMarket = this.driftClient.getSpotMarketAccount(
143
+ params.spotMarketIndex
144
+ );
145
+
146
+ const userStatsKey = getUserStatsAccountPublicKey(
147
+ this.driftClient.program.programId,
148
+ vault
149
+ );
150
+ const userKey = getUserAccountPublicKeySync(
151
+ this.driftClient.program.programId,
152
+ vault
153
+ );
154
+
155
+ const accounts = {
156
+ driftSpotMarket: spotMarket.pubkey,
157
+ driftSpotMarketMint: spotMarket.mint,
158
+ driftUserStats: userStatsKey,
159
+ driftUser: userKey,
160
+ driftState,
161
+ vault,
162
+ tokenAccount,
163
+ driftProgram: this.driftClient.program.programId,
164
+ };
165
+
166
+ return await this.program.methods
167
+ .initializeVault(params)
168
+ .accounts(accounts)
169
+ .rpc();
170
+ }
171
+
172
+ /**
173
+ * Updates the delegate address for a vault. The delegate address will be allowed to trade
174
+ * on behalf of the vault.
175
+ * @param vault vault address to update
176
+ * @param delegate delegate address to update to
177
+ * @returns
178
+ */
179
+ public async updateDelegate(
180
+ vault: PublicKey,
181
+ delegate: PublicKey
182
+ ): Promise<TransactionSignature> {
183
+ const vaultAccount = await this.program.account.vault.fetch(vault);
184
+ return await this.program.methods
185
+ .updateDelegate(delegate)
186
+ .accounts({
187
+ vault: vault,
188
+ driftUser: vaultAccount.user,
189
+ driftProgram: this.driftClient.program.programId,
190
+ })
191
+ .rpc();
192
+ }
193
+
194
+ /**
195
+ *
196
+ * @param vault vault address to deposit to
197
+ * @param amount amount to deposit
198
+ * @returns
199
+ */
200
+ public async managerDeposit(
201
+ vault: PublicKey,
202
+ amount: BN
203
+ ): Promise<TransactionSignature> {
204
+ const vaultAccount = await this.program.account.vault.fetch(vault);
205
+ const driftSpotMarket = this.driftClient.getSpotMarketAccount(
206
+ vaultAccount.spotMarketIndex
207
+ );
208
+
209
+ const user = new User({
210
+ driftClient: this.driftClient,
211
+ userAccountPublicKey: vaultAccount.user,
212
+ });
213
+ await user.subscribe();
214
+
215
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
216
+ userAccounts: [user.getUserAccount()],
217
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
218
+ });
219
+
220
+ return await this.program.methods
221
+ .managerDeposit(amount)
222
+ .accounts({
223
+ vault,
224
+ vaultTokenAccount: vaultAccount.tokenAccount,
225
+ driftUser: await getUserAccountPublicKey(
226
+ this.driftClient.program.programId,
227
+ vault
228
+ ),
229
+ driftProgram: this.driftClient.program.programId,
230
+ driftUserStats: getUserStatsAccountPublicKey(
231
+ this.driftClient.program.programId,
232
+ vault
233
+ ),
234
+ driftState: await this.driftClient.getStatePublicKey(),
235
+ driftSpotMarketVault: driftSpotMarket.vault,
236
+ userTokenAccount: getAssociatedTokenAddressSync(
237
+ driftSpotMarket.mint,
238
+ this.driftClient.wallet.publicKey
239
+ ),
240
+ tokenProgram: TOKEN_PROGRAM_ID,
241
+ })
242
+ .remainingAccounts(remainingAccounts)
243
+ .rpc();
244
+ }
245
+
246
+ public async managerRequestWithdraw(
247
+ vault: PublicKey,
248
+ amount: BN,
249
+ withdrawUnit: WithdrawUnit
250
+ ): Promise<TransactionSignature> {
251
+ const vaultAccount = (await this.program.account.vault.fetch(
252
+ vault
253
+ )) as Vault;
254
+
255
+ if (!this.driftClient.wallet.publicKey.equals(vaultAccount.manager)) {
256
+ throw new Error(`Only the manager of the vault can request a withdraw.`);
257
+ }
258
+
259
+ const user = new User({
260
+ driftClient: this.driftClient,
261
+ userAccountPublicKey: vaultAccount.user,
262
+ });
263
+ await user.subscribe();
264
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
265
+ userAccounts: [user.getUserAccount()],
266
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
267
+ });
268
+
269
+ const userStatsKey = getUserStatsAccountPublicKey(
270
+ this.driftClient.program.programId,
271
+ vault
272
+ );
273
+
274
+ const driftStateKey = await this.driftClient.getStatePublicKey();
275
+
276
+ const accounts = {
277
+ vault,
278
+ driftUserStats: userStatsKey,
279
+ driftUser: vaultAccount.user,
280
+ driftState: driftStateKey,
281
+ };
282
+
283
+ if (this.cliMode) {
284
+ return await this.program.methods
285
+ .managerRequestWithdraw(amount, withdrawUnit)
286
+ .accounts(accounts)
287
+ .remainingAccounts(remainingAccounts)
288
+ .rpc();
289
+ } else {
290
+ const requestWithdrawIx = this.program.instruction.managerRequestWithdraw(
291
+ amount,
292
+ withdrawUnit,
293
+ {
294
+ accounts: {
295
+ manager: this.driftClient.wallet.publicKey,
296
+ ...accounts,
297
+ },
298
+ remainingAccounts,
299
+ }
300
+ );
301
+
302
+ return await this.createAndSendTxn([requestWithdrawIx]);
303
+ }
304
+ }
305
+
306
+ public async managerCancelWithdrawRequest(
307
+ vault: PublicKey
308
+ ): Promise<TransactionSignature> {
309
+ const vaultAccount = await this.program.account.vault.fetch(vault);
310
+
311
+ const userStatsKey = getUserStatsAccountPublicKey(
312
+ this.driftClient.program.programId,
313
+ vault
314
+ );
315
+
316
+ const driftStateKey = await this.driftClient.getStatePublicKey();
317
+
318
+ const accounts = {
319
+ manager: this.driftClient.wallet.publicKey,
320
+ vault,
321
+ driftUserStats: userStatsKey,
322
+ driftUser: vaultAccount.user,
323
+ driftState: driftStateKey,
324
+ };
325
+
326
+ const user = new User({
327
+ driftClient: this.driftClient,
328
+ userAccountPublicKey: vaultAccount.user,
329
+ });
330
+ await user.subscribe();
331
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
332
+ userAccounts: [user.getUserAccount()],
333
+ });
334
+
335
+ if (this.cliMode) {
336
+ return await this.program.methods
337
+ .mangerCancelWithdrawRequest()
338
+ .accounts(accounts)
339
+ .remainingAccounts(remainingAccounts)
340
+ .rpc();
341
+ } else {
342
+ const cancelRequestWithdrawIx =
343
+ this.program.instruction.mangerCancelWithdrawRequest({
344
+ accounts: {
345
+ manager: this.driftClient.wallet.publicKey,
346
+ ...accounts,
347
+ },
348
+ remainingAccounts,
349
+ });
350
+
351
+ return await this.createAndSendTxn([cancelRequestWithdrawIx]);
352
+ }
353
+ }
354
+
355
+ public async managerWithdraw(
356
+ vault: PublicKey
357
+ ): Promise<TransactionSignature> {
358
+ const vaultAccount = await this.program.account.vault.fetch(vault);
359
+
360
+ if (!this.driftClient.wallet.publicKey.equals(vaultAccount.manager)) {
361
+ throw new Error(`Only the manager of the vault can request a withdraw.`);
362
+ }
363
+
364
+ const user = new User({
365
+ driftClient: this.driftClient,
366
+ userAccountPublicKey: vaultAccount.user,
367
+ });
368
+ await user.subscribe();
369
+
370
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
371
+ userAccounts: [user.getUserAccount()],
372
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
373
+ });
374
+
375
+ const spotMarket = this.driftClient.getSpotMarketAccount(
376
+ vaultAccount.spotMarketIndex
377
+ );
378
+ if (!spotMarket) {
379
+ throw new Error(
380
+ `Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`
381
+ );
382
+ }
383
+
384
+ const ix = this.program.instruction.managerWithdraw({
385
+ accounts: {
386
+ vault,
387
+ manager: this.driftClient.wallet.publicKey,
388
+ vaultTokenAccount: vaultAccount.tokenAccount,
389
+ driftUser: await getUserAccountPublicKey(
390
+ this.driftClient.program.programId,
391
+ vault
392
+ ),
393
+ driftProgram: this.driftClient.program.programId,
394
+ driftUserStats: getUserStatsAccountPublicKey(
395
+ this.driftClient.program.programId,
396
+ vault
397
+ ),
398
+ driftState: await this.driftClient.getStatePublicKey(),
399
+ driftSpotMarketVault: spotMarket.vault,
400
+ userTokenAccount: getAssociatedTokenAddressSync(
401
+ spotMarket.mint,
402
+ this.driftClient.wallet.publicKey
403
+ ),
404
+ driftSigner: this.driftClient.getStateAccount().signer,
405
+ tokenProgram: TOKEN_PROGRAM_ID,
406
+ },
407
+ remainingAccounts,
408
+ });
409
+ return this.createAndSendTxn([ix], {
410
+ units: 1_000_000,
411
+ });
412
+ }
413
+
414
+ public async managerUpdateVault(
415
+ vault: PublicKey,
416
+ params: {
417
+ redeemPeriod: BN | null;
418
+ maxTokens: BN | null;
419
+ managementFee: BN | null;
420
+ minDepositAmount: BN | null;
421
+ profitShare: number | null;
422
+ hurdleRate: number | null;
423
+ permissioned: boolean | null;
424
+ }
425
+ ): Promise<TransactionSignature> {
426
+ return await this.program.methods
427
+ .updateVault(params)
428
+ .accounts({
429
+ vault,
430
+ manager: this.driftClient.wallet.publicKey,
431
+ })
432
+ .rpc();
433
+ }
434
+
435
+ public async getApplyProfitShareIx(
436
+ vault: PublicKey,
437
+ vaultDepositor: PublicKey
438
+ ): Promise<TransactionInstruction> {
439
+ const vaultAccount = await this.program.account.vault.fetch(vault);
440
+
441
+ const user = new User({
442
+ driftClient: this.driftClient,
443
+ userAccountPublicKey: vaultAccount.user,
444
+ });
445
+ await user.subscribe();
446
+
447
+ const spotMarket = this.driftClient.getSpotMarketAccount(
448
+ vaultAccount.spotMarketIndex
449
+ );
450
+ if (!spotMarket) {
451
+ throw new Error(
452
+ `Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`
453
+ );
454
+ }
455
+
456
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
457
+ userAccounts: [user.getUserAccount()],
458
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
459
+ });
460
+
461
+ const accounts = {
462
+ vault,
463
+ vaultDepositor,
464
+ manager: this.driftClient.wallet.publicKey,
465
+ driftUserStats: getUserStatsAccountPublicKey(
466
+ this.driftClient.program.programId,
467
+ vault
468
+ ),
469
+ driftUser: await getUserAccountPublicKey(
470
+ this.driftClient.program.programId,
471
+ vault
472
+ ),
473
+ driftState: await this.driftClient.getStatePublicKey(),
474
+ driftSigner: this.driftClient.getStateAccount().signer,
475
+ driftProgram: this.driftClient.program.programId,
476
+ };
477
+
478
+ return this.program.instruction.applyProfitShare({
479
+ accounts: {
480
+ ...accounts,
481
+ },
482
+ remainingAccounts,
483
+ });
484
+ }
485
+
486
+ private createInitVaultDepositorIx(vault: PublicKey, authority?: PublicKey) {
487
+ const vaultDepositor = getVaultDepositorAddressSync(
488
+ this.program.programId,
489
+ vault,
490
+ authority
491
+ );
492
+
493
+ const accounts = {
494
+ vaultDepositor,
495
+ vault,
496
+ authority: authority || this.driftClient.wallet.publicKey,
497
+ };
498
+
499
+ const initIx = this.program.instruction.initializeVaultDepositor({
500
+ accounts: {
501
+ ...accounts,
502
+ payer: authority || this.driftClient.wallet.publicKey,
503
+ rent: SYSVAR_RENT_PUBKEY,
504
+ systemProgram: SystemProgram.programId,
505
+ },
506
+ });
507
+
508
+ return initIx;
509
+ }
510
+
511
+ /**
512
+ * Initializes the vault depositor account. This account is used to deposit funds into a vault.
513
+ * @param vault the vault address to deposit into
514
+ * @param authority the authority allowed to make deposits into the vault
515
+ * @returns
516
+ */
517
+ public async initializeVaultDepositor(
518
+ vault: PublicKey,
519
+ authority?: PublicKey
520
+ ): Promise<TransactionSignature> {
521
+ const vaultDepositor = getVaultDepositorAddressSync(
522
+ this.program.programId,
523
+ vault,
524
+ authority
525
+ );
526
+
527
+ const accounts = {
528
+ vaultDepositor,
529
+ vault,
530
+ authority: authority || this.driftClient.wallet.publicKey,
531
+ };
532
+
533
+ if (this.cliMode) {
534
+ return await this.program.methods
535
+ .initializeVaultDepositor()
536
+ .accounts(accounts)
537
+ .rpc();
538
+ } else {
539
+ const initIx = this.createInitVaultDepositorIx(vault, authority);
540
+ return await this.createAndSendTxn([initIx]);
541
+ }
542
+ }
543
+
544
+ /**
545
+ * Depositor funds into the specified vault.
546
+ * @param vaultDepositor
547
+ * @param amount
548
+ * @param initVaultDepositor If true, will initialize the vault depositor account
549
+ * @returns
550
+ */
551
+ public async deposit(
552
+ vaultDepositor: PublicKey,
553
+ amount: BN,
554
+ initVaultDepositor?: {
555
+ authority: PublicKey;
556
+ vault: PublicKey;
557
+ }
558
+ ): Promise<TransactionSignature> {
559
+ let vaultPubKey: PublicKey;
560
+ if (initVaultDepositor) {
561
+ vaultPubKey = initVaultDepositor.vault;
562
+ } else {
563
+ const vaultDepositorAccount =
564
+ await this.program.account.vaultDepositor.fetch(vaultDepositor);
565
+ vaultPubKey = vaultDepositorAccount.vault;
566
+ }
567
+
568
+ const vaultAccount = await this.program.account.vault.fetch(vaultPubKey);
569
+
570
+ const user = new User({
571
+ driftClient: this.driftClient,
572
+ userAccountPublicKey: vaultAccount.user,
573
+ });
574
+ await user.subscribe();
575
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
576
+ userAccounts: [user.getUserAccount()],
577
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
578
+ });
579
+
580
+ const userStatsKey = getUserStatsAccountPublicKey(
581
+ this.driftClient.program.programId,
582
+ vaultPubKey
583
+ );
584
+
585
+ const driftStateKey = await this.driftClient.getStatePublicKey();
586
+
587
+ const spotMarket = this.driftClient.getSpotMarketAccount(
588
+ vaultAccount.spotMarketIndex
589
+ );
590
+
591
+ const accounts = {
592
+ vault: vaultPubKey,
593
+ vaultDepositor,
594
+ vaultTokenAccount: vaultAccount.tokenAccount,
595
+ driftUserStats: userStatsKey,
596
+ driftUser: vaultAccount.user,
597
+ driftState: driftStateKey,
598
+ driftSpotMarketVault: spotMarket.vault,
599
+ userTokenAccount: getAssociatedTokenAddressSync(
600
+ spotMarket.mint,
601
+ this.driftClient.wallet.publicKey,
602
+ true
603
+ ),
604
+ driftProgram: this.driftClient.program.programId,
605
+ tokenProgram: TOKEN_PROGRAM_ID,
606
+ };
607
+
608
+ if (this.cliMode) {
609
+ if (initVaultDepositor) {
610
+ await this.initializeVaultDepositor(
611
+ vaultAccount.pubkey,
612
+ initVaultDepositor.authority
613
+ );
614
+ }
615
+ return await this.program.methods
616
+ .deposit(amount)
617
+ .accounts(accounts)
618
+ .remainingAccounts(remainingAccounts)
619
+ .rpc();
620
+ } else {
621
+ const depositIx = this.program.instruction.deposit(amount, {
622
+ accounts: {
623
+ authority: this.driftClient.wallet.publicKey,
624
+ ...accounts,
625
+ },
626
+ remainingAccounts,
627
+ });
628
+
629
+ if (initVaultDepositor) {
630
+ const initIx = this.createInitVaultDepositorIx(
631
+ vaultAccount.pubkey,
632
+ initVaultDepositor.authority
633
+ );
634
+ return await this.createAndSendTxn([initIx, depositIx]);
635
+ } else {
636
+ return await this.createAndSendTxn([depositIx]);
637
+ }
638
+ }
639
+ }
640
+
641
+ public async requestWithdraw(
642
+ vaultDepositor: PublicKey,
643
+ amount: BN,
644
+ withdrawUnit: WithdrawUnit
645
+ ): Promise<TransactionSignature> {
646
+ const vaultDepositorAccount =
647
+ await this.program.account.vaultDepositor.fetch(vaultDepositor);
648
+ const vaultAccount = await this.program.account.vault.fetch(
649
+ vaultDepositorAccount.vault
650
+ );
651
+
652
+ const user = new User({
653
+ driftClient: this.driftClient,
654
+ userAccountPublicKey: vaultAccount.user,
655
+ });
656
+ await user.subscribe();
657
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
658
+ userAccounts: [user.getUserAccount()],
659
+ });
660
+
661
+ const userStatsKey = getUserStatsAccountPublicKey(
662
+ this.driftClient.program.programId,
663
+ vaultDepositorAccount.vault
664
+ );
665
+
666
+ const driftStateKey = await this.driftClient.getStatePublicKey();
667
+
668
+ const accounts = {
669
+ vault: vaultDepositorAccount.vault,
670
+ vaultDepositor,
671
+ driftUserStats: userStatsKey,
672
+ driftUser: vaultAccount.user,
673
+ driftState: driftStateKey,
674
+ };
675
+
676
+ if (this.cliMode) {
677
+ return await this.program.methods
678
+ .requestWithdraw(amount, withdrawUnit)
679
+ .accounts(accounts)
680
+ .remainingAccounts(remainingAccounts)
681
+ .rpc();
682
+ } else {
683
+ const requestWithdrawIx = this.program.instruction.requestWithdraw(
684
+ amount,
685
+ withdrawUnit,
686
+ {
687
+ accounts: {
688
+ authority: this.driftClient.wallet.publicKey,
689
+ ...accounts,
690
+ },
691
+ remainingAccounts,
692
+ }
693
+ );
694
+
695
+ return await this.createAndSendTxn([requestWithdrawIx]);
696
+ }
697
+ }
698
+
699
+ public async withdraw(
700
+ vaultDepositor: PublicKey
701
+ ): Promise<TransactionSignature> {
702
+ const vaultDepositorAccount =
703
+ await this.program.account.vaultDepositor.fetch(vaultDepositor);
704
+ const vaultAccount = await this.program.account.vault.fetch(
705
+ vaultDepositorAccount.vault
706
+ );
707
+
708
+ const user = new User({
709
+ driftClient: this.driftClient,
710
+ userAccountPublicKey: vaultAccount.user,
711
+ });
712
+ await user.subscribe();
713
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
714
+ userAccounts: [user.getUserAccount()],
715
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
716
+ });
717
+
718
+ const userStatsKey = getUserStatsAccountPublicKey(
719
+ this.driftClient.program.programId,
720
+ vaultDepositorAccount.vault
721
+ );
722
+
723
+ const driftStateKey = await this.driftClient.getStatePublicKey();
724
+
725
+ const spotMarket = this.driftClient.getSpotMarketAccount(
726
+ vaultAccount.spotMarketIndex
727
+ );
728
+
729
+ const accounts = {
730
+ vault: vaultDepositorAccount.vault,
731
+ vaultDepositor,
732
+ vaultTokenAccount: vaultAccount.tokenAccount,
733
+ driftUserStats: userStatsKey,
734
+ driftUser: vaultAccount.user,
735
+ driftState: driftStateKey,
736
+ driftSpotMarketVault: spotMarket.vault,
737
+ driftSigner: this.driftClient.getStateAccount().signer,
738
+ userTokenAccount: getAssociatedTokenAddressSync(
739
+ spotMarket.mint,
740
+ this.driftClient.wallet.publicKey,
741
+ true
742
+ ),
743
+ driftProgram: this.driftClient.program.programId,
744
+ tokenProgram: TOKEN_PROGRAM_ID,
745
+ };
746
+
747
+ if (this.cliMode) {
748
+ return await this.program.methods
749
+ .withdraw()
750
+ .accounts(accounts)
751
+ .remainingAccounts(remainingAccounts)
752
+ .rpc();
753
+ } else {
754
+ const withdrawIx = this.program.instruction.withdraw({
755
+ accounts: {
756
+ authority: this.driftClient.wallet.publicKey,
757
+ ...accounts,
758
+ },
759
+ remainingAccounts,
760
+ });
761
+
762
+ return await this.createAndSendTxn([withdrawIx]);
763
+ }
764
+ }
765
+
766
+ public async cancelRequestWithdraw(
767
+ vaultDepositor: PublicKey
768
+ ): Promise<TransactionSignature> {
769
+ const vaultDepositorAccount =
770
+ await this.program.account.vaultDepositor.fetch(vaultDepositor);
771
+ const vaultAccount = await this.program.account.vault.fetch(
772
+ vaultDepositorAccount.vault
773
+ );
774
+
775
+ const userStatsKey = getUserStatsAccountPublicKey(
776
+ this.driftClient.program.programId,
777
+ vaultDepositorAccount.vault
778
+ );
779
+
780
+ const driftStateKey = await this.driftClient.getStatePublicKey();
781
+
782
+ const accounts = {
783
+ vault: vaultDepositorAccount.vault,
784
+ vaultDepositor,
785
+ driftUserStats: userStatsKey,
786
+ driftUser: vaultAccount.user,
787
+ driftState: driftStateKey,
788
+ };
789
+
790
+ const user = new User({
791
+ driftClient: this.driftClient,
792
+ userAccountPublicKey: vaultAccount.user,
793
+ });
794
+ await user.subscribe();
795
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
796
+ userAccounts: [user.getUserAccount()],
797
+ });
798
+
799
+ if (this.cliMode) {
800
+ return await this.program.methods
801
+ .cancelRequestWithdraw()
802
+ .accounts(accounts)
803
+ .remainingAccounts(remainingAccounts)
804
+ .rpc();
805
+ } else {
806
+ const cancelRequestWithdrawIx =
807
+ this.program.instruction.cancelRequestWithdraw({
808
+ accounts: {
809
+ authority: this.driftClient.wallet.publicKey,
810
+ ...accounts,
811
+ },
812
+ remainingAccounts,
813
+ });
814
+
815
+ return await this.createAndSendTxn([cancelRequestWithdrawIx]);
816
+ }
817
+ }
818
+
819
+ /**
820
+ * Liquidates (become delegate for) a vault.
821
+ * @param
822
+ * @param
823
+ * @returns
824
+ */
825
+ public async liquidate(
826
+ vaultDepositor: PublicKey
827
+ ): Promise<TransactionSignature> {
828
+ const vaultDepositorAccount =
829
+ await this.program.account.vaultDepositor.fetch(vaultDepositor);
830
+ const vaultPubKey = vaultDepositorAccount.vault;
831
+
832
+ const vaultAccount = await this.program.account.vault.fetch(vaultPubKey);
833
+
834
+ const user = new User({
835
+ driftClient: this.driftClient,
836
+ userAccountPublicKey: vaultAccount.user,
837
+ });
838
+ await user.subscribe();
839
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
840
+ userAccounts: [user.getUserAccount()],
841
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
842
+ });
843
+
844
+ const userStatsKey = getUserStatsAccountPublicKey(
845
+ this.driftClient.program.programId,
846
+ vaultPubKey
847
+ );
848
+
849
+ const driftStateKey = await this.driftClient.getStatePublicKey();
850
+
851
+ const accounts = {
852
+ vault: vaultPubKey,
853
+ vaultDepositor,
854
+ vaultTokenAccount: vaultAccount.tokenAccount,
855
+ driftUserStats: userStatsKey,
856
+ driftUser: vaultAccount.user,
857
+ driftState: driftStateKey,
858
+ driftProgram: this.driftClient.program.programId,
859
+ };
860
+
861
+ if (this.cliMode) {
862
+ return await this.program.methods
863
+ .liquidate()
864
+ .accounts(accounts)
865
+ .remainingAccounts(remainingAccounts)
866
+ .rpc();
867
+ } else {
868
+ const liquidateIx = this.program.instruction.liquidate({
869
+ accounts: {
870
+ authority: this.driftClient.wallet.publicKey,
871
+ ...accounts,
872
+ },
873
+ remainingAccounts,
874
+ });
875
+
876
+ return await this.createAndSendTxn([liquidateIx]);
877
+ }
878
+ }
879
+
880
+ /**
881
+ * Used for UI wallet adapters compatibility
882
+ */
883
+ public async createAndSendTxn(
884
+ ixs: TransactionInstruction[],
885
+ computeUnitParams?: SetComputeUnitLimitParams
886
+ ): Promise<TransactionSignature> {
887
+ const tx = new Transaction();
888
+ tx.add(
889
+ ComputeBudgetProgram.setComputeUnitLimit(
890
+ computeUnitParams || {
891
+ units: 400_000,
892
+ }
893
+ )
894
+ );
895
+ tx.add(...ixs);
896
+ const { txSig } = await this.driftClient.sendTransaction(
897
+ tx,
898
+ [],
899
+ this.driftClient.opts
900
+ );
901
+
902
+ return txSig;
903
+ }
904
+ }