@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,596 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VaultClient = void 0;
4
+ const sdk_1 = require("@drift-labs/sdk");
5
+ const anchor_1 = require("@coral-xyz/anchor");
6
+ const addresses_1 = require("./addresses");
7
+ const web3_js_1 = require("@solana/web3.js");
8
+ const spl_token_1 = require("@solana/spl-token");
9
+ const bytes_1 = require("@coral-xyz/anchor/dist/cjs/utils/bytes");
10
+ class VaultClient {
11
+ constructor({ driftClient, program, cliMode, }) {
12
+ this.driftClient = driftClient;
13
+ this.program = program;
14
+ this.cliMode = !!cliMode;
15
+ }
16
+ async getVault(vault) {
17
+ return await this.program.account.vault.fetch(vault);
18
+ }
19
+ async getVaultDepositor(vaultDepositor) {
20
+ return await this.program.account.vaultDepositor.fetch(vaultDepositor);
21
+ }
22
+ async getAllVaultDepositors(vault) {
23
+ const filters = [
24
+ {
25
+ // discriminator = VaultDepositor
26
+ memcmp: {
27
+ offset: 0,
28
+ bytes: bytes_1.bs58.encode(anchor_1.BorshAccountsCoder.accountDiscriminator('VaultDepositor')),
29
+ },
30
+ },
31
+ {
32
+ // vault = vault
33
+ memcmp: {
34
+ offset: 8,
35
+ bytes: vault.toBase58(),
36
+ },
37
+ },
38
+ {
39
+ // last_withdraw_request_ts = 0
40
+ memcmp: {
41
+ offset: 144,
42
+ bytes: bytes_1.bs58.encode(Uint8Array.from([0])),
43
+ },
44
+ },
45
+ ];
46
+ // @ts-ignore
47
+ return (await this.program.account.vaultDepositor.all(filters));
48
+ }
49
+ /**
50
+ *
51
+ * @param vault pubkey
52
+ * @returns vault equity, in QUOTE_PRECISION
53
+ */
54
+ async calculateVaultEquity(params) {
55
+ let vaultAccount;
56
+ if (params.address !== undefined) {
57
+ vaultAccount = await this.program.account.vault.fetch(params.address);
58
+ }
59
+ else if (params.vault !== undefined) {
60
+ vaultAccount = params.vault;
61
+ }
62
+ else {
63
+ throw new Error('Must supply address or vault');
64
+ }
65
+ const user = new sdk_1.User({
66
+ driftClient: this.driftClient,
67
+ userAccountPublicKey: vaultAccount.user,
68
+ });
69
+ await user.subscribe();
70
+ const netSpotValue = user.getNetSpotMarketValue();
71
+ const unrealizedPnl = user.getUnrealizedPNL(true, undefined, undefined);
72
+ return netSpotValue.add(unrealizedPnl);
73
+ }
74
+ async initializeVault(params) {
75
+ const vault = addresses_1.getVaultAddressSync(this.program.programId, params.name);
76
+ const tokenAccount = addresses_1.getTokenVaultAddressSync(this.program.programId, vault);
77
+ const driftState = await this.driftClient.getStatePublicKey();
78
+ const spotMarket = this.driftClient.getSpotMarketAccount(params.spotMarketIndex);
79
+ const userStatsKey = sdk_1.getUserStatsAccountPublicKey(this.driftClient.program.programId, vault);
80
+ const userKey = sdk_1.getUserAccountPublicKeySync(this.driftClient.program.programId, vault);
81
+ const accounts = {
82
+ driftSpotMarket: spotMarket.pubkey,
83
+ driftSpotMarketMint: spotMarket.mint,
84
+ driftUserStats: userStatsKey,
85
+ driftUser: userKey,
86
+ driftState,
87
+ vault,
88
+ tokenAccount,
89
+ driftProgram: this.driftClient.program.programId,
90
+ };
91
+ return await this.program.methods
92
+ .initializeVault(params)
93
+ .accounts(accounts)
94
+ .rpc();
95
+ }
96
+ /**
97
+ * Updates the delegate address for a vault. The delegate address will be allowed to trade
98
+ * on behalf of the vault.
99
+ * @param vault vault address to update
100
+ * @param delegate delegate address to update to
101
+ * @returns
102
+ */
103
+ async updateDelegate(vault, delegate) {
104
+ const vaultAccount = await this.program.account.vault.fetch(vault);
105
+ return await this.program.methods
106
+ .updateDelegate(delegate)
107
+ .accounts({
108
+ vault: vault,
109
+ driftUser: vaultAccount.user,
110
+ driftProgram: this.driftClient.program.programId,
111
+ })
112
+ .rpc();
113
+ }
114
+ /**
115
+ *
116
+ * @param vault vault address to deposit to
117
+ * @param amount amount to deposit
118
+ * @returns
119
+ */
120
+ async managerDeposit(vault, amount) {
121
+ const vaultAccount = await this.program.account.vault.fetch(vault);
122
+ const driftSpotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
123
+ const user = new sdk_1.User({
124
+ driftClient: this.driftClient,
125
+ userAccountPublicKey: vaultAccount.user,
126
+ });
127
+ await user.subscribe();
128
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
129
+ userAccounts: [user.getUserAccount()],
130
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
131
+ });
132
+ return await this.program.methods
133
+ .managerDeposit(amount)
134
+ .accounts({
135
+ vault,
136
+ vaultTokenAccount: vaultAccount.tokenAccount,
137
+ driftUser: await sdk_1.getUserAccountPublicKey(this.driftClient.program.programId, vault),
138
+ driftProgram: this.driftClient.program.programId,
139
+ driftUserStats: sdk_1.getUserStatsAccountPublicKey(this.driftClient.program.programId, vault),
140
+ driftState: await this.driftClient.getStatePublicKey(),
141
+ driftSpotMarketVault: driftSpotMarket.vault,
142
+ userTokenAccount: spl_token_1.getAssociatedTokenAddressSync(driftSpotMarket.mint, this.driftClient.wallet.publicKey),
143
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
144
+ })
145
+ .remainingAccounts(remainingAccounts)
146
+ .rpc();
147
+ }
148
+ async managerRequestWithdraw(vault, amount, withdrawUnit) {
149
+ const vaultAccount = (await this.program.account.vault.fetch(vault));
150
+ if (!this.driftClient.wallet.publicKey.equals(vaultAccount.manager)) {
151
+ throw new Error(`Only the manager of the vault can request a withdraw.`);
152
+ }
153
+ const user = new sdk_1.User({
154
+ driftClient: this.driftClient,
155
+ userAccountPublicKey: vaultAccount.user,
156
+ });
157
+ await user.subscribe();
158
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
159
+ userAccounts: [user.getUserAccount()],
160
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
161
+ });
162
+ const userStatsKey = sdk_1.getUserStatsAccountPublicKey(this.driftClient.program.programId, vault);
163
+ const driftStateKey = await this.driftClient.getStatePublicKey();
164
+ const accounts = {
165
+ vault,
166
+ driftUserStats: userStatsKey,
167
+ driftUser: vaultAccount.user,
168
+ driftState: driftStateKey,
169
+ };
170
+ if (this.cliMode) {
171
+ return await this.program.methods
172
+ .managerRequestWithdraw(amount, withdrawUnit)
173
+ .accounts(accounts)
174
+ .remainingAccounts(remainingAccounts)
175
+ .rpc();
176
+ }
177
+ else {
178
+ const requestWithdrawIx = this.program.instruction.managerRequestWithdraw(amount, withdrawUnit, {
179
+ accounts: {
180
+ manager: this.driftClient.wallet.publicKey,
181
+ ...accounts,
182
+ },
183
+ remainingAccounts,
184
+ });
185
+ return await this.createAndSendTxn([requestWithdrawIx]);
186
+ }
187
+ }
188
+ async managerCancelWithdrawRequest(vault) {
189
+ const vaultAccount = await this.program.account.vault.fetch(vault);
190
+ const userStatsKey = sdk_1.getUserStatsAccountPublicKey(this.driftClient.program.programId, vault);
191
+ const driftStateKey = await this.driftClient.getStatePublicKey();
192
+ const accounts = {
193
+ manager: this.driftClient.wallet.publicKey,
194
+ vault,
195
+ driftUserStats: userStatsKey,
196
+ driftUser: vaultAccount.user,
197
+ driftState: driftStateKey,
198
+ };
199
+ const user = new sdk_1.User({
200
+ driftClient: this.driftClient,
201
+ userAccountPublicKey: vaultAccount.user,
202
+ });
203
+ await user.subscribe();
204
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
205
+ userAccounts: [user.getUserAccount()],
206
+ });
207
+ if (this.cliMode) {
208
+ return await this.program.methods
209
+ .mangerCancelWithdrawRequest()
210
+ .accounts(accounts)
211
+ .remainingAccounts(remainingAccounts)
212
+ .rpc();
213
+ }
214
+ else {
215
+ const cancelRequestWithdrawIx = this.program.instruction.mangerCancelWithdrawRequest({
216
+ accounts: {
217
+ manager: this.driftClient.wallet.publicKey,
218
+ ...accounts,
219
+ },
220
+ remainingAccounts,
221
+ });
222
+ return await this.createAndSendTxn([cancelRequestWithdrawIx]);
223
+ }
224
+ }
225
+ async managerWithdraw(vault) {
226
+ const vaultAccount = await this.program.account.vault.fetch(vault);
227
+ if (!this.driftClient.wallet.publicKey.equals(vaultAccount.manager)) {
228
+ throw new Error(`Only the manager of the vault can request a withdraw.`);
229
+ }
230
+ const user = new sdk_1.User({
231
+ driftClient: this.driftClient,
232
+ userAccountPublicKey: vaultAccount.user,
233
+ });
234
+ await user.subscribe();
235
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
236
+ userAccounts: [user.getUserAccount()],
237
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
238
+ });
239
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
240
+ if (!spotMarket) {
241
+ throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
242
+ }
243
+ const ix = this.program.instruction.managerWithdraw({
244
+ accounts: {
245
+ vault,
246
+ manager: this.driftClient.wallet.publicKey,
247
+ vaultTokenAccount: vaultAccount.tokenAccount,
248
+ driftUser: await sdk_1.getUserAccountPublicKey(this.driftClient.program.programId, vault),
249
+ driftProgram: this.driftClient.program.programId,
250
+ driftUserStats: sdk_1.getUserStatsAccountPublicKey(this.driftClient.program.programId, vault),
251
+ driftState: await this.driftClient.getStatePublicKey(),
252
+ driftSpotMarketVault: spotMarket.vault,
253
+ userTokenAccount: spl_token_1.getAssociatedTokenAddressSync(spotMarket.mint, this.driftClient.wallet.publicKey),
254
+ driftSigner: this.driftClient.getStateAccount().signer,
255
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
256
+ },
257
+ remainingAccounts,
258
+ });
259
+ return this.createAndSendTxn([ix], {
260
+ units: 1000000,
261
+ });
262
+ }
263
+ async managerUpdateVault(vault, params) {
264
+ return await this.program.methods
265
+ .updateVault(params)
266
+ .accounts({
267
+ vault,
268
+ manager: this.driftClient.wallet.publicKey,
269
+ })
270
+ .rpc();
271
+ }
272
+ async getApplyProfitShareIx(vault, vaultDepositor) {
273
+ const vaultAccount = await this.program.account.vault.fetch(vault);
274
+ const user = new sdk_1.User({
275
+ driftClient: this.driftClient,
276
+ userAccountPublicKey: vaultAccount.user,
277
+ });
278
+ await user.subscribe();
279
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
280
+ if (!spotMarket) {
281
+ throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
282
+ }
283
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
284
+ userAccounts: [user.getUserAccount()],
285
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
286
+ });
287
+ const accounts = {
288
+ vault,
289
+ vaultDepositor,
290
+ manager: this.driftClient.wallet.publicKey,
291
+ driftUserStats: sdk_1.getUserStatsAccountPublicKey(this.driftClient.program.programId, vault),
292
+ driftUser: await sdk_1.getUserAccountPublicKey(this.driftClient.program.programId, vault),
293
+ driftState: await this.driftClient.getStatePublicKey(),
294
+ driftSigner: this.driftClient.getStateAccount().signer,
295
+ driftProgram: this.driftClient.program.programId,
296
+ };
297
+ return this.program.instruction.applyProfitShare({
298
+ accounts: {
299
+ ...accounts,
300
+ },
301
+ remainingAccounts,
302
+ });
303
+ }
304
+ createInitVaultDepositorIx(vault, authority) {
305
+ const vaultDepositor = addresses_1.getVaultDepositorAddressSync(this.program.programId, vault, authority);
306
+ const accounts = {
307
+ vaultDepositor,
308
+ vault,
309
+ authority: authority || this.driftClient.wallet.publicKey,
310
+ };
311
+ const initIx = this.program.instruction.initializeVaultDepositor({
312
+ accounts: {
313
+ ...accounts,
314
+ payer: authority || this.driftClient.wallet.publicKey,
315
+ rent: web3_js_1.SYSVAR_RENT_PUBKEY,
316
+ systemProgram: web3_js_1.SystemProgram.programId,
317
+ },
318
+ });
319
+ return initIx;
320
+ }
321
+ /**
322
+ * Initializes the vault depositor account. This account is used to deposit funds into a vault.
323
+ * @param vault the vault address to deposit into
324
+ * @param authority the authority allowed to make deposits into the vault
325
+ * @returns
326
+ */
327
+ async initializeVaultDepositor(vault, authority) {
328
+ const vaultDepositor = addresses_1.getVaultDepositorAddressSync(this.program.programId, vault, authority);
329
+ const accounts = {
330
+ vaultDepositor,
331
+ vault,
332
+ authority: authority || this.driftClient.wallet.publicKey,
333
+ };
334
+ if (this.cliMode) {
335
+ return await this.program.methods
336
+ .initializeVaultDepositor()
337
+ .accounts(accounts)
338
+ .rpc();
339
+ }
340
+ else {
341
+ const initIx = this.createInitVaultDepositorIx(vault, authority);
342
+ return await this.createAndSendTxn([initIx]);
343
+ }
344
+ }
345
+ /**
346
+ * Depositor funds into the specified vault.
347
+ * @param vaultDepositor
348
+ * @param amount
349
+ * @param initVaultDepositor If true, will initialize the vault depositor account
350
+ * @returns
351
+ */
352
+ async deposit(vaultDepositor, amount, initVaultDepositor) {
353
+ let vaultPubKey;
354
+ if (initVaultDepositor) {
355
+ vaultPubKey = initVaultDepositor.vault;
356
+ }
357
+ else {
358
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
359
+ vaultPubKey = vaultDepositorAccount.vault;
360
+ }
361
+ const vaultAccount = await this.program.account.vault.fetch(vaultPubKey);
362
+ const user = new sdk_1.User({
363
+ driftClient: this.driftClient,
364
+ userAccountPublicKey: vaultAccount.user,
365
+ });
366
+ await user.subscribe();
367
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
368
+ userAccounts: [user.getUserAccount()],
369
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
370
+ });
371
+ const userStatsKey = sdk_1.getUserStatsAccountPublicKey(this.driftClient.program.programId, vaultPubKey);
372
+ const driftStateKey = await this.driftClient.getStatePublicKey();
373
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
374
+ const accounts = {
375
+ vault: vaultPubKey,
376
+ vaultDepositor,
377
+ vaultTokenAccount: vaultAccount.tokenAccount,
378
+ driftUserStats: userStatsKey,
379
+ driftUser: vaultAccount.user,
380
+ driftState: driftStateKey,
381
+ driftSpotMarketVault: spotMarket.vault,
382
+ userTokenAccount: spl_token_1.getAssociatedTokenAddressSync(spotMarket.mint, this.driftClient.wallet.publicKey, true),
383
+ driftProgram: this.driftClient.program.programId,
384
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
385
+ };
386
+ if (this.cliMode) {
387
+ if (initVaultDepositor) {
388
+ await this.initializeVaultDepositor(vaultAccount.pubkey, initVaultDepositor.authority);
389
+ }
390
+ return await this.program.methods
391
+ .deposit(amount)
392
+ .accounts(accounts)
393
+ .remainingAccounts(remainingAccounts)
394
+ .rpc();
395
+ }
396
+ else {
397
+ const depositIx = this.program.instruction.deposit(amount, {
398
+ accounts: {
399
+ authority: this.driftClient.wallet.publicKey,
400
+ ...accounts,
401
+ },
402
+ remainingAccounts,
403
+ });
404
+ if (initVaultDepositor) {
405
+ const initIx = this.createInitVaultDepositorIx(vaultAccount.pubkey, initVaultDepositor.authority);
406
+ return await this.createAndSendTxn([initIx, depositIx]);
407
+ }
408
+ else {
409
+ return await this.createAndSendTxn([depositIx]);
410
+ }
411
+ }
412
+ }
413
+ async requestWithdraw(vaultDepositor, amount, withdrawUnit) {
414
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
415
+ const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
416
+ const user = new sdk_1.User({
417
+ driftClient: this.driftClient,
418
+ userAccountPublicKey: vaultAccount.user,
419
+ });
420
+ await user.subscribe();
421
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
422
+ userAccounts: [user.getUserAccount()],
423
+ });
424
+ const userStatsKey = sdk_1.getUserStatsAccountPublicKey(this.driftClient.program.programId, vaultDepositorAccount.vault);
425
+ const driftStateKey = await this.driftClient.getStatePublicKey();
426
+ const accounts = {
427
+ vault: vaultDepositorAccount.vault,
428
+ vaultDepositor,
429
+ driftUserStats: userStatsKey,
430
+ driftUser: vaultAccount.user,
431
+ driftState: driftStateKey,
432
+ };
433
+ if (this.cliMode) {
434
+ return await this.program.methods
435
+ .requestWithdraw(amount, withdrawUnit)
436
+ .accounts(accounts)
437
+ .remainingAccounts(remainingAccounts)
438
+ .rpc();
439
+ }
440
+ else {
441
+ const requestWithdrawIx = this.program.instruction.requestWithdraw(amount, withdrawUnit, {
442
+ accounts: {
443
+ authority: this.driftClient.wallet.publicKey,
444
+ ...accounts,
445
+ },
446
+ remainingAccounts,
447
+ });
448
+ return await this.createAndSendTxn([requestWithdrawIx]);
449
+ }
450
+ }
451
+ async withdraw(vaultDepositor) {
452
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
453
+ const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
454
+ const user = new sdk_1.User({
455
+ driftClient: this.driftClient,
456
+ userAccountPublicKey: vaultAccount.user,
457
+ });
458
+ await user.subscribe();
459
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
460
+ userAccounts: [user.getUserAccount()],
461
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
462
+ });
463
+ const userStatsKey = sdk_1.getUserStatsAccountPublicKey(this.driftClient.program.programId, vaultDepositorAccount.vault);
464
+ const driftStateKey = await this.driftClient.getStatePublicKey();
465
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
466
+ const accounts = {
467
+ vault: vaultDepositorAccount.vault,
468
+ vaultDepositor,
469
+ vaultTokenAccount: vaultAccount.tokenAccount,
470
+ driftUserStats: userStatsKey,
471
+ driftUser: vaultAccount.user,
472
+ driftState: driftStateKey,
473
+ driftSpotMarketVault: spotMarket.vault,
474
+ driftSigner: this.driftClient.getStateAccount().signer,
475
+ userTokenAccount: spl_token_1.getAssociatedTokenAddressSync(spotMarket.mint, this.driftClient.wallet.publicKey, true),
476
+ driftProgram: this.driftClient.program.programId,
477
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
478
+ };
479
+ if (this.cliMode) {
480
+ return await this.program.methods
481
+ .withdraw()
482
+ .accounts(accounts)
483
+ .remainingAccounts(remainingAccounts)
484
+ .rpc();
485
+ }
486
+ else {
487
+ const withdrawIx = this.program.instruction.withdraw({
488
+ accounts: {
489
+ authority: this.driftClient.wallet.publicKey,
490
+ ...accounts,
491
+ },
492
+ remainingAccounts,
493
+ });
494
+ return await this.createAndSendTxn([withdrawIx]);
495
+ }
496
+ }
497
+ async cancelRequestWithdraw(vaultDepositor) {
498
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
499
+ const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
500
+ const userStatsKey = sdk_1.getUserStatsAccountPublicKey(this.driftClient.program.programId, vaultDepositorAccount.vault);
501
+ const driftStateKey = await this.driftClient.getStatePublicKey();
502
+ const accounts = {
503
+ vault: vaultDepositorAccount.vault,
504
+ vaultDepositor,
505
+ driftUserStats: userStatsKey,
506
+ driftUser: vaultAccount.user,
507
+ driftState: driftStateKey,
508
+ };
509
+ const user = new sdk_1.User({
510
+ driftClient: this.driftClient,
511
+ userAccountPublicKey: vaultAccount.user,
512
+ });
513
+ await user.subscribe();
514
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
515
+ userAccounts: [user.getUserAccount()],
516
+ });
517
+ if (this.cliMode) {
518
+ return await this.program.methods
519
+ .cancelRequestWithdraw()
520
+ .accounts(accounts)
521
+ .remainingAccounts(remainingAccounts)
522
+ .rpc();
523
+ }
524
+ else {
525
+ const cancelRequestWithdrawIx = this.program.instruction.cancelRequestWithdraw({
526
+ accounts: {
527
+ authority: this.driftClient.wallet.publicKey,
528
+ ...accounts,
529
+ },
530
+ remainingAccounts,
531
+ });
532
+ return await this.createAndSendTxn([cancelRequestWithdrawIx]);
533
+ }
534
+ }
535
+ /**
536
+ * Liquidates (become delegate for) a vault.
537
+ * @param
538
+ * @param
539
+ * @returns
540
+ */
541
+ async liquidate(vaultDepositor) {
542
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
543
+ const vaultPubKey = vaultDepositorAccount.vault;
544
+ const vaultAccount = await this.program.account.vault.fetch(vaultPubKey);
545
+ const user = new sdk_1.User({
546
+ driftClient: this.driftClient,
547
+ userAccountPublicKey: vaultAccount.user,
548
+ });
549
+ await user.subscribe();
550
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
551
+ userAccounts: [user.getUserAccount()],
552
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
553
+ });
554
+ const userStatsKey = sdk_1.getUserStatsAccountPublicKey(this.driftClient.program.programId, vaultPubKey);
555
+ const driftStateKey = await this.driftClient.getStatePublicKey();
556
+ const accounts = {
557
+ vault: vaultPubKey,
558
+ vaultDepositor,
559
+ vaultTokenAccount: vaultAccount.tokenAccount,
560
+ driftUserStats: userStatsKey,
561
+ driftUser: vaultAccount.user,
562
+ driftState: driftStateKey,
563
+ driftProgram: this.driftClient.program.programId,
564
+ };
565
+ if (this.cliMode) {
566
+ return await this.program.methods
567
+ .liquidate()
568
+ .accounts(accounts)
569
+ .remainingAccounts(remainingAccounts)
570
+ .rpc();
571
+ }
572
+ else {
573
+ const liquidateIx = this.program.instruction.liquidate({
574
+ accounts: {
575
+ authority: this.driftClient.wallet.publicKey,
576
+ ...accounts,
577
+ },
578
+ remainingAccounts,
579
+ });
580
+ return await this.createAndSendTxn([liquidateIx]);
581
+ }
582
+ }
583
+ /**
584
+ * Used for UI wallet adapters compatibility
585
+ */
586
+ async createAndSendTxn(ixs, computeUnitParams) {
587
+ const tx = new web3_js_1.Transaction();
588
+ tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit(computeUnitParams || {
589
+ units: 400000,
590
+ }));
591
+ tx.add(...ixs);
592
+ const { txSig } = await this.driftClient.sendTransaction(tx, [], this.driftClient.opts);
593
+ return txSig;
594
+ }
595
+ }
596
+ exports.VaultClient = VaultClient;
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@drift-labs/vaults-sdk",
3
+ "version": "0.1.0",
4
+ "main": "lib/index.js",
5
+ "types": "lib/index.d.ts",
6
+ "directories": {
7
+ "lib": "lib"
8
+ },
9
+ "peerDependencies": {
10
+ "@drift-labs/sdk": "2.40.0-beta.1"
11
+ },
12
+ "dependencies": {
13
+ "@coral-xyz/anchor": "^0.26.0",
14
+ "@solana/web3.js": "1.73.2",
15
+ "commander": "^11.0.0",
16
+ "dotenv": "^16.3.1",
17
+ "strict-event-emitter-types": "^2.0.0",
18
+ "ts-node": "^10.9.1",
19
+ "typescript": "^5.1.6"
20
+ },
21
+ "engines": {
22
+ "node": ">=16"
23
+ },
24
+ "scripts": {
25
+ "cli": "ts-node cli/cli.ts",
26
+ "clean": "rm -rf lib",
27
+ "build": "yarn clean && tsc"
28
+ }
29
+ }
@@ -0,0 +1,2 @@
1
+ export * from './pollingVaultDepositorSubscriber';
2
+ export * from './pollingVaultSubscriber';
@@ -0,0 +1,68 @@
1
+ import {
2
+ VaultDepositor,
3
+ VaultDepositorAccountEvents,
4
+ VaultDepositorAccountSubscriber,
5
+ } from '../types/types';
6
+ import { PollingVaultsProgramAccountSubscriber } from './pollingVaultsProgramAccountSubscriber';
7
+
8
+ export class PollingVaultDepositorSubscriber
9
+ extends PollingVaultsProgramAccountSubscriber<
10
+ VaultDepositor,
11
+ VaultDepositorAccountEvents
12
+ >
13
+ implements VaultDepositorAccountSubscriber
14
+ {
15
+ async addToAccountLoader(): Promise<void> {
16
+ if (this.callbackId) {
17
+ console.log(
18
+ 'Account for vault depositor already added to account loader'
19
+ );
20
+ return;
21
+ }
22
+
23
+ this.callbackId = await this.accountLoader.addAccount(
24
+ this.pubkey,
25
+ (buffer, slot) => {
26
+ if (!buffer) return;
27
+
28
+ if (this.account && this.account.slot > slot) {
29
+ return;
30
+ }
31
+
32
+ const account =
33
+ this.program.account.vaultDepositor.coder.accounts.decode(
34
+ 'vaultDepositor',
35
+ buffer
36
+ );
37
+ this.account = { data: account, slot };
38
+ this._eventEmitter.emit('vaultDepositorUpdate', account);
39
+ this._eventEmitter.emit('update');
40
+ }
41
+ );
42
+
43
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
44
+ this._eventEmitter.emit('error', error);
45
+ });
46
+ }
47
+
48
+ async fetch(): Promise<void> {
49
+ await this.accountLoader.load();
50
+ const { buffer, slot } = this.accountLoader.getBufferAndSlot(this.pubkey);
51
+ const currentSlot = this.account?.slot ?? 0;
52
+ if (buffer && slot > currentSlot) {
53
+ const account = this.program.account.vaultDepositor.coder.accounts.decode(
54
+ 'vaultDepositor',
55
+ buffer
56
+ );
57
+ this.account = { data: account, slot };
58
+ }
59
+ }
60
+
61
+ updateData(vaultDepositorAcc: VaultDepositor, slot: number): void {
62
+ if (!this.account || this.account.slot < slot) {
63
+ this.account = { data: vaultDepositorAcc, slot };
64
+ this._eventEmitter.emit('vaultDepositorUpdate', vaultDepositorAcc);
65
+ this._eventEmitter.emit('update');
66
+ }
67
+ }
68
+ }