@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.
- package/.env.example +2 -0
- package/README.md +58 -0
- package/cli/cli.ts +105 -0
- package/cli/commands/applyProfitShare.ts +48 -0
- package/cli/commands/deposit.ts +35 -0
- package/cli/commands/index.ts +13 -0
- package/cli/commands/initVault.ts +61 -0
- package/cli/commands/initVaultDepositor.ts +43 -0
- package/cli/commands/listDepositorsForVault.ts +33 -0
- package/cli/commands/managerCancelWithdraw.ts +25 -0
- package/cli/commands/managerDeposit.ts +34 -0
- package/cli/commands/managerRequestWithdraw.ts +27 -0
- package/cli/commands/managerUpdateVault.ts +36 -0
- package/cli/commands/managerWithdraw.ts +25 -0
- package/cli/commands/requestWithdraw.ts +29 -0
- package/cli/commands/vaultDeposit.ts +43 -0
- package/cli/commands/vaultWithdraw.ts +43 -0
- package/cli/commands/viewVault.ts +30 -0
- package/cli/commands/viewVaultDepositor.ts +37 -0
- package/cli/commands/withdraw.ts +25 -0
- package/cli/utils.ts +119 -0
- package/lib/accountSubscribers/index.d.ts +2 -0
- package/lib/accountSubscribers/index.js +14 -0
- package/lib/accountSubscribers/pollingVaultDepositorSubscriber.d.ts +7 -0
- package/lib/accountSubscribers/pollingVaultDepositorSubscriber.js +44 -0
- package/lib/accountSubscribers/pollingVaultSubscriber.d.ts +7 -0
- package/lib/accountSubscribers/pollingVaultSubscriber.js +44 -0
- package/lib/accountSubscribers/pollingVaultsProgramAccountSubscriber.d.ts +28 -0
- package/lib/accountSubscribers/pollingVaultsProgramAccountSubscriber.js +68 -0
- package/lib/accounts/index.d.ts +2 -0
- package/lib/accounts/index.js +14 -0
- package/lib/accounts/vaultAccount.d.ts +15 -0
- package/lib/accounts/vaultAccount.js +53 -0
- package/lib/accounts/vaultDepositorAccount.d.ts +18 -0
- package/lib/accounts/vaultDepositorAccount.js +45 -0
- package/lib/accounts/vaultsProgramAccount.d.ts +13 -0
- package/lib/accounts/vaultsProgramAccount.js +25 -0
- package/lib/addresses.d.ts +4 -0
- package/lib/addresses.js +46 -0
- package/lib/constants/index.d.ts +3 -0
- package/lib/constants/index.js +5 -0
- package/lib/index.d.ts +9 -0
- package/lib/index.js +21 -0
- package/lib/name.d.ts +3 -0
- package/lib/name.js +19 -0
- package/lib/parsers/index.d.ts +1 -0
- package/lib/parsers/index.js +13 -0
- package/lib/parsers/logParser.d.ts +14 -0
- package/lib/parsers/logParser.js +21 -0
- package/lib/types/drift_vaults.d.ts +1475 -0
- package/lib/types/drift_vaults.js +1477 -0
- package/lib/types/types.d.ts +137 -0
- package/lib/types/types.js +20 -0
- package/lib/utils.d.ts +7 -0
- package/lib/utils.js +43 -0
- package/lib/vaultClient.d.ts +100 -0
- package/lib/vaultClient.js +596 -0
- package/package.json +29 -0
- package/src/accountSubscribers/index.ts +2 -0
- package/src/accountSubscribers/pollingVaultDepositorSubscriber.ts +68 -0
- package/src/accountSubscribers/pollingVaultSubscriber.ts +62 -0
- package/src/accountSubscribers/pollingVaultsProgramAccountSubscriber.ts +111 -0
- package/src/accounts/index.ts +2 -0
- package/src/accounts/vaultAccount.ts +86 -0
- package/src/accounts/vaultDepositorAccount.ts +67 -0
- package/src/accounts/vaultsProgramAccount.ts +37 -0
- package/src/addresses.ts +43 -0
- package/src/constants/index.ts +3 -0
- package/src/idl/drift_vaults.json +1547 -0
- package/src/index.ts +9 -0
- package/src/name.ts +18 -0
- package/src/parsers/index.ts +1 -0
- package/src/parsers/logParser.ts +28 -0
- package/src/types/drift_vaults.ts +2949 -0
- package/src/types/types.ts +158 -0
- package/src/utils.ts +33 -0
- package/src/vaultClient.ts +904 -0
- 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,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
|
+
}
|