@drift-labs/vaults-sdk 0.1.531 → 0.1.533
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/cli/cli.ts +6 -0
- package/cli/commands/applyProfitShare.ts +14 -16
- package/cli/commands/forceWithdrawAll.ts +101 -0
- package/cli/commands/index.ts +1 -0
- package/cli/utils.ts +2 -0
- package/lib/addresses.d.ts +3 -0
- package/lib/addresses.js +24 -0
- package/lib/types/drift_vaults.d.ts +673 -60
- package/lib/types/drift_vaults.js +668 -55
- package/lib/utils.d.ts +2 -1
- package/lib/utils.js +20 -1
- package/lib/vaultClient.d.ts +39 -8
- package/lib/vaultClient.js +347 -44
- package/package.json +2 -2
- package/src/addresses.ts +45 -0
- package/src/idl/drift_vaults.json +1527 -207
- package/src/types/drift_vaults.ts +1322 -96
- package/src/utils.ts +37 -1
- package/src/vaultClient.ts +642 -60
package/lib/utils.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { DriftClient, IWallet } from '@drift-labs/sdk';
|
|
2
|
-
import { Connection } from '@solana/web3.js';
|
|
2
|
+
import { Connection, PublicKey, TransactionInstruction } from '@solana/web3.js';
|
|
3
3
|
import { DriftVaults } from './types/drift_vaults';
|
|
4
4
|
import { VaultClient } from './vaultClient';
|
|
5
5
|
import * as anchor from '@coral-xyz/anchor';
|
|
6
6
|
export declare const getDriftVaultProgram: (connection: Connection, wallet: IWallet) => anchor.Program<DriftVaults>;
|
|
7
7
|
export declare const getVaultClient: (connection: Connection, wallet: IWallet, driftClient: DriftClient) => VaultClient;
|
|
8
|
+
export declare const getOrCreateATAInstruction: (tokenMint: PublicKey, owner: PublicKey, connection: Connection, allowOwnerOffCurve?: boolean, payer?: PublicKey) => Promise<[PublicKey, TransactionInstruction?]>;
|
package/lib/utils.js
CHANGED
|
@@ -23,12 +23,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.getVaultClient = exports.getDriftVaultProgram = void 0;
|
|
26
|
+
exports.getOrCreateATAInstruction = exports.getVaultClient = exports.getDriftVaultProgram = void 0;
|
|
27
27
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
28
28
|
const drift_vaults_1 = require("./types/drift_vaults");
|
|
29
29
|
const vaultClient_1 = require("./vaultClient");
|
|
30
30
|
const anchor = __importStar(require("@coral-xyz/anchor"));
|
|
31
31
|
const types_1 = require("./types/types");
|
|
32
|
+
const spl_token_1 = require("@solana/spl-token");
|
|
32
33
|
const getDriftVaultProgram = (connection, wallet) => {
|
|
33
34
|
const provider = new anchor_1.AnchorProvider(connection, wallet, {});
|
|
34
35
|
anchor.setProvider(provider);
|
|
@@ -45,3 +46,21 @@ const getVaultClient = (connection, wallet, driftClient) => {
|
|
|
45
46
|
return vaultClient;
|
|
46
47
|
};
|
|
47
48
|
exports.getVaultClient = getVaultClient;
|
|
49
|
+
const getOrCreateATAInstruction = async (tokenMint, owner, connection, allowOwnerOffCurve = true, payer = owner) => {
|
|
50
|
+
let toAccount;
|
|
51
|
+
try {
|
|
52
|
+
toAccount = await (0, spl_token_1.getAssociatedTokenAddress)(tokenMint, owner, allowOwnerOffCurve);
|
|
53
|
+
const account = await connection.getAccountInfo(toAccount);
|
|
54
|
+
if (!account) {
|
|
55
|
+
const ix = (0, spl_token_1.createAssociatedTokenAccountInstruction)(payer, toAccount, owner, tokenMint);
|
|
56
|
+
return [toAccount, ix];
|
|
57
|
+
}
|
|
58
|
+
return [toAccount, undefined];
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
/* handle error */
|
|
62
|
+
console.error('Error::getOrCreateATAInstruction', e);
|
|
63
|
+
throw e;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
exports.getOrCreateATAInstruction = getOrCreateATAInstruction;
|
package/lib/vaultClient.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { BN, DriftClient, UserMap } from '@drift-labs/sdk';
|
|
2
2
|
import { Program, ProgramAccount } from '@coral-xyz/anchor';
|
|
3
3
|
import { DriftVaults } from './types/drift_vaults';
|
|
4
|
-
import { CompetitionsClient } from '@drift-labs/competitions-sdk';
|
|
5
4
|
import { AddressLookupTableAccount, PublicKey, TransactionInstruction, TransactionSignature, VersionedTransaction } from '@solana/web3.js';
|
|
6
5
|
import { Vault, VaultDepositor, VaultProtocol, VaultProtocolParams, WithdrawUnit } from './types/types';
|
|
7
6
|
import { UserMapConfig } from '@drift-labs/sdk';
|
|
7
|
+
import { Metaplex } from '@metaplex-foundation/js';
|
|
8
8
|
export type TxParams = {
|
|
9
9
|
cuLimit?: number;
|
|
10
10
|
cuPriceMicroLamports?: number;
|
|
@@ -13,15 +13,17 @@ export type TxParams = {
|
|
|
13
13
|
};
|
|
14
14
|
export declare class VaultClient {
|
|
15
15
|
driftClient: DriftClient;
|
|
16
|
+
metaplex?: Metaplex;
|
|
16
17
|
program: Program<DriftVaults>;
|
|
17
18
|
cliMode: boolean;
|
|
18
19
|
/**
|
|
19
20
|
* Cache map of drift user accounts of vaults.
|
|
20
21
|
*/
|
|
21
22
|
readonly vaultUsers: UserMap;
|
|
22
|
-
constructor({ driftClient, program, cliMode, userMapConfig, }: {
|
|
23
|
+
constructor({ driftClient, program, metaplex, cliMode, userMapConfig, }: {
|
|
23
24
|
driftClient: DriftClient;
|
|
24
25
|
program: Program<DriftVaults>;
|
|
26
|
+
metaplex?: Metaplex;
|
|
25
27
|
cliMode?: boolean;
|
|
26
28
|
userMapConfig?: UserMapConfig;
|
|
27
29
|
});
|
|
@@ -136,6 +138,10 @@ export declare class VaultClient {
|
|
|
136
138
|
permissioned: boolean | null;
|
|
137
139
|
}): Promise<TransactionSignature>;
|
|
138
140
|
getApplyProfitShareIx(vault: PublicKey, vaultDepositor: PublicKey): Promise<TransactionInstruction>;
|
|
141
|
+
getApplyRebaseTokenizedDepositorIx(vault: PublicKey, tokenizedVaultDepositor: PublicKey): Promise<TransactionInstruction>;
|
|
142
|
+
applyRebase(vault: PublicKey, vaultDepositor: PublicKey): Promise<TransactionSignature>;
|
|
143
|
+
getApplyRebaseIx(vault: PublicKey, vaultDepositor: PublicKey): Promise<TransactionInstruction>;
|
|
144
|
+
applyRebaseTokenizedDepositor(vault: PublicKey, tokenizedVaultDepositor: PublicKey): Promise<TransactionSignature>;
|
|
139
145
|
private createInitVaultDepositorIx;
|
|
140
146
|
/**
|
|
141
147
|
* Initializes the vault depositor account. This account is used to deposit funds into a vault.
|
|
@@ -144,10 +150,30 @@ export declare class VaultClient {
|
|
|
144
150
|
* @returns
|
|
145
151
|
*/
|
|
146
152
|
initializeVaultDepositor(vault: PublicKey, authority?: PublicKey): Promise<TransactionSignature>;
|
|
153
|
+
initializeTokenizedVaultDepositor(params: {
|
|
154
|
+
vault: PublicKey;
|
|
155
|
+
tokenName: string;
|
|
156
|
+
tokenSymbol: string;
|
|
157
|
+
tokenUri: string;
|
|
158
|
+
decimals?: number;
|
|
159
|
+
sharesBase?: number;
|
|
160
|
+
}): Promise<TransactionSignature>;
|
|
161
|
+
createTokenizeSharesIx(vaultDepositor: PublicKey, amount: BN, unit: WithdrawUnit, mint?: PublicKey): Promise<TransactionInstruction[]>;
|
|
162
|
+
tokenizeShares(vaultDepositor: PublicKey, amount: BN, unit: WithdrawUnit, mint?: PublicKey, txParams?: TxParams): Promise<TransactionSignature>;
|
|
163
|
+
createRedeemTokensIx(vaultDepositor: PublicKey, tokensToBurn: BN, sharesBase?: number): Promise<TransactionInstruction>;
|
|
164
|
+
/**
|
|
165
|
+
* Redeems tokens from the vault.
|
|
166
|
+
* @param vaultDepositor
|
|
167
|
+
* @param tokensToBurn
|
|
168
|
+
* @param mint optionally provide a mint, or infer the mint from the current vault share base
|
|
169
|
+
* @param txParams
|
|
170
|
+
* @returns
|
|
171
|
+
*/
|
|
172
|
+
redeemTokens(vaultDepositor: PublicKey, tokensToBurn: BN, sharesBase?: number, txParams?: TxParams): Promise<TransactionSignature>;
|
|
147
173
|
prepDepositTx(vaultDepositor: PublicKey, amount: BN, initVaultDepositor?: {
|
|
148
174
|
authority: PublicKey;
|
|
149
175
|
vault: PublicKey;
|
|
150
|
-
}): Promise<{
|
|
176
|
+
}, userTokenAccount?: PublicKey): Promise<{
|
|
151
177
|
vaultAccount: {
|
|
152
178
|
name: number[];
|
|
153
179
|
pubkey: PublicKey;
|
|
@@ -228,10 +254,11 @@ export declare class VaultClient {
|
|
|
228
254
|
deposit(vaultDepositor: PublicKey, amount: BN, initVaultDepositor?: {
|
|
229
255
|
authority: PublicKey;
|
|
230
256
|
vault: PublicKey;
|
|
231
|
-
}, txParams?: TxParams): Promise<TransactionSignature>;
|
|
257
|
+
}, txParams?: TxParams, userTokenAccount?: PublicKey): Promise<TransactionSignature>;
|
|
232
258
|
requestWithdraw(vaultDepositor: PublicKey, amount: BN, withdrawUnit: WithdrawUnit, txParams?: TxParams): Promise<TransactionSignature>;
|
|
233
259
|
withdraw(vaultDepositor: PublicKey, txParams?: TxParams): Promise<TransactionSignature>;
|
|
234
260
|
forceWithdraw(vaultDepositor: PublicKey): Promise<TransactionSignature>;
|
|
261
|
+
getForceWithdrawIx(vaultDepositor: PublicKey): Promise<TransactionInstruction[]>;
|
|
235
262
|
cancelRequestWithdraw(vaultDepositor: PublicKey, txParams?: TxParams): Promise<TransactionSignature>;
|
|
236
263
|
/**
|
|
237
264
|
* Liquidates (become delegate for) a vault.
|
|
@@ -254,12 +281,16 @@ export declare class VaultClient {
|
|
|
254
281
|
*/
|
|
255
282
|
initializeInsuranceFundStake(vault: PublicKey, spotMarketIndex: number): Promise<TransactionSignature>;
|
|
256
283
|
/**
|
|
257
|
-
*
|
|
258
|
-
* @param vault vault address to
|
|
259
|
-
* @param
|
|
284
|
+
* Adds an amount to an insurance fund stake for the vault.
|
|
285
|
+
* @param vault vault address to update
|
|
286
|
+
* @param spotMarketIndex spot market index of the insurance fund stake
|
|
287
|
+
* @param amount amount to add to the insurance fund stake, in spotMarketIndex precision
|
|
260
288
|
* @returns
|
|
261
289
|
*/
|
|
262
|
-
|
|
290
|
+
addToInsuranceFundStake(vault: PublicKey, spotMarketIndex: number, amount: BN, managerTokenAccount?: PublicKey): Promise<TransactionSignature>;
|
|
291
|
+
requestRemoveInsuranceFundStake(vault: PublicKey, spotMarketIndex: number, amount: BN): Promise<TransactionSignature>;
|
|
292
|
+
cancelRequestRemoveInsuranceFundStake(vault: PublicKey, spotMarketIndex: number): Promise<TransactionSignature>;
|
|
293
|
+
removeInsuranceFundStake(vault: PublicKey, spotMarketIndex: number, managerTokenAccount?: PublicKey): Promise<TransactionSignature>;
|
|
263
294
|
protocolRequestWithdraw(vault: PublicKey, amount: BN, withdrawUnit: WithdrawUnit): Promise<TransactionSignature>;
|
|
264
295
|
protocolCancelWithdrawRequest(vault: PublicKey): Promise<TransactionSignature>;
|
|
265
296
|
protocolWithdraw(vault: PublicKey): Promise<TransactionSignature>;
|
package/lib/vaultClient.js
CHANGED
|
@@ -3,15 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.VaultClient = void 0;
|
|
4
4
|
const sdk_1 = require("@drift-labs/sdk");
|
|
5
5
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
6
|
-
const competitions_sdk_1 = require("@drift-labs/competitions-sdk");
|
|
7
6
|
const addresses_1 = require("./addresses");
|
|
8
7
|
const web3_js_1 = require("@solana/web3.js");
|
|
9
8
|
const spl_token_1 = require("@solana/spl-token");
|
|
10
9
|
const bytes_1 = require("@coral-xyz/anchor/dist/cjs/utils/bytes");
|
|
11
10
|
const math_1 = require("./math");
|
|
11
|
+
const utils_1 = require("./utils");
|
|
12
12
|
class VaultClient {
|
|
13
|
-
constructor({ driftClient, program, cliMode, userMapConfig, }) {
|
|
13
|
+
constructor({ driftClient, program, metaplex, cliMode, userMapConfig, }) {
|
|
14
14
|
this.driftClient = driftClient;
|
|
15
|
+
this.metaplex = metaplex;
|
|
15
16
|
this.program = program;
|
|
16
17
|
this.cliMode = !!cliMode;
|
|
17
18
|
if (!userMapConfig) {
|
|
@@ -574,6 +575,68 @@ class VaultClient {
|
|
|
574
575
|
remainingAccounts,
|
|
575
576
|
});
|
|
576
577
|
}
|
|
578
|
+
async getApplyRebaseTokenizedDepositorIx(vault, tokenizedVaultDepositor) {
|
|
579
|
+
const vaultAccount = await this.program.account.vault.fetch(vault);
|
|
580
|
+
const user = await this.getSubscribedVaultUser(vaultAccount.user);
|
|
581
|
+
const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
|
|
582
|
+
if (!spotMarket) {
|
|
583
|
+
throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
|
|
584
|
+
}
|
|
585
|
+
const remainingAccounts = this.driftClient.getRemainingAccounts({
|
|
586
|
+
userAccounts: [user.getUserAccount()],
|
|
587
|
+
writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
|
|
588
|
+
});
|
|
589
|
+
const accounts = {
|
|
590
|
+
vault,
|
|
591
|
+
tokenizedVaultDepositor,
|
|
592
|
+
driftUser: await (0, sdk_1.getUserAccountPublicKey)(this.driftClient.program.programId, vault),
|
|
593
|
+
driftState: await this.driftClient.getStatePublicKey(),
|
|
594
|
+
driftSigner: this.driftClient.getStateAccount().signer,
|
|
595
|
+
driftProgram: this.driftClient.program.programId,
|
|
596
|
+
};
|
|
597
|
+
return this.program.instruction.applyRebaseTokenizedDepositor({
|
|
598
|
+
accounts: {
|
|
599
|
+
...accounts,
|
|
600
|
+
},
|
|
601
|
+
remainingAccounts,
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
async applyRebase(vault, vaultDepositor) {
|
|
605
|
+
return await this.createAndSendTxn([
|
|
606
|
+
await this.getApplyRebaseIx(vault, vaultDepositor),
|
|
607
|
+
]);
|
|
608
|
+
}
|
|
609
|
+
async getApplyRebaseIx(vault, vaultDepositor) {
|
|
610
|
+
const vaultAccount = await this.program.account.vault.fetch(vault);
|
|
611
|
+
const user = await this.getSubscribedVaultUser(vaultAccount.user);
|
|
612
|
+
const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
|
|
613
|
+
if (!spotMarket) {
|
|
614
|
+
throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
|
|
615
|
+
}
|
|
616
|
+
const remainingAccounts = this.driftClient.getRemainingAccounts({
|
|
617
|
+
userAccounts: [user.getUserAccount()],
|
|
618
|
+
writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
|
|
619
|
+
});
|
|
620
|
+
const accounts = {
|
|
621
|
+
vault,
|
|
622
|
+
vaultDepositor,
|
|
623
|
+
driftUser: await (0, sdk_1.getUserAccountPublicKey)(this.driftClient.program.programId, vault),
|
|
624
|
+
driftState: await this.driftClient.getStatePublicKey(),
|
|
625
|
+
driftSigner: this.driftClient.getStateAccount().signer,
|
|
626
|
+
driftProgram: this.driftClient.program.programId,
|
|
627
|
+
};
|
|
628
|
+
return this.program.instruction.applyRebase({
|
|
629
|
+
accounts: {
|
|
630
|
+
...accounts,
|
|
631
|
+
},
|
|
632
|
+
remainingAccounts,
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
async applyRebaseTokenizedDepositor(vault, tokenizedVaultDepositor) {
|
|
636
|
+
return await this.createAndSendTxn([
|
|
637
|
+
await this.getApplyRebaseTokenizedDepositorIx(vault, tokenizedVaultDepositor),
|
|
638
|
+
]);
|
|
639
|
+
}
|
|
577
640
|
createInitVaultDepositorIx(vault, authority) {
|
|
578
641
|
const vaultDepositor = (0, addresses_1.getVaultDepositorAddressSync)(this.program.programId, vault, authority || this.driftClient.wallet.publicKey);
|
|
579
642
|
const accounts = {
|
|
@@ -605,9 +668,14 @@ class VaultClient {
|
|
|
605
668
|
authority: authority || this.driftClient.wallet.publicKey,
|
|
606
669
|
};
|
|
607
670
|
if (this.cliMode) {
|
|
608
|
-
return
|
|
671
|
+
return this.program.methods
|
|
609
672
|
.initializeVaultDepositor()
|
|
610
|
-
.accounts(
|
|
673
|
+
.accounts({
|
|
674
|
+
...accounts,
|
|
675
|
+
payer: authority || this.driftClient.wallet.publicKey,
|
|
676
|
+
rent: web3_js_1.SYSVAR_RENT_PUBKEY,
|
|
677
|
+
systemProgram: web3_js_1.SystemProgram.programId,
|
|
678
|
+
})
|
|
611
679
|
.rpc();
|
|
612
680
|
}
|
|
613
681
|
else {
|
|
@@ -615,7 +683,156 @@ class VaultClient {
|
|
|
615
683
|
return await this.createAndSendTxn([initIx]);
|
|
616
684
|
}
|
|
617
685
|
}
|
|
618
|
-
async
|
|
686
|
+
async initializeTokenizedVaultDepositor(params) {
|
|
687
|
+
var _a;
|
|
688
|
+
if (!this.metaplex) {
|
|
689
|
+
throw new Error('Metaplex instance is required when constructing VaultClient to initialize a tokenized vault depositor');
|
|
690
|
+
}
|
|
691
|
+
let spotMarketDecimals = 6;
|
|
692
|
+
let sharesBase = 0;
|
|
693
|
+
if (params.decimals === undefined || params.sharesBase === undefined) {
|
|
694
|
+
const vault = await this.program.account.vault.fetch(params.vault);
|
|
695
|
+
const spotMarketAccount = this.driftClient.getSpotMarketAccount(vault.spotMarketIndex);
|
|
696
|
+
if (!spotMarketAccount) {
|
|
697
|
+
throw new Error(`DriftClient failed to load vault's spot market (marketIndex: ${vault.spotMarketIndex})`);
|
|
698
|
+
}
|
|
699
|
+
spotMarketDecimals = spotMarketAccount.decimals;
|
|
700
|
+
sharesBase = vault.sharesBase;
|
|
701
|
+
}
|
|
702
|
+
const mintAddress = (0, addresses_1.getTokenizedVaultMintAddressSync)(this.program.programId, params.vault, sharesBase);
|
|
703
|
+
const accounts = {
|
|
704
|
+
vault: params.vault,
|
|
705
|
+
vaultDepositor: (0, addresses_1.getTokenizedVaultAddressSync)(this.program.programId, params.vault, sharesBase),
|
|
706
|
+
mintAccount: mintAddress,
|
|
707
|
+
metadataAccount: this.metaplex.nfts().pdas().metadata({
|
|
708
|
+
mint: mintAddress,
|
|
709
|
+
}),
|
|
710
|
+
tokenMetadataProgram: this.metaplex.programs().getTokenMetadata().address,
|
|
711
|
+
payer: this.driftClient.wallet.publicKey,
|
|
712
|
+
};
|
|
713
|
+
const vaultTokenAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mintAddress, params.vault, true);
|
|
714
|
+
const createAtaIx = (0, spl_token_1.createAssociatedTokenAccountInstruction)(this.driftClient.wallet.publicKey, vaultTokenAta, params.vault, mintAddress);
|
|
715
|
+
if (!this.cliMode) {
|
|
716
|
+
throw new Error('CLI mode is not supported for initializeTokenizedVaultDepositor');
|
|
717
|
+
}
|
|
718
|
+
return await this.program.methods
|
|
719
|
+
.initializeTokenizedVaultDepositor({
|
|
720
|
+
...params,
|
|
721
|
+
decimals: (_a = params.decimals) !== null && _a !== void 0 ? _a : spotMarketDecimals,
|
|
722
|
+
})
|
|
723
|
+
.preInstructions([
|
|
724
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
|
|
725
|
+
microLamports: 50000,
|
|
726
|
+
}),
|
|
727
|
+
])
|
|
728
|
+
.postInstructions([createAtaIx])
|
|
729
|
+
.accounts(accounts)
|
|
730
|
+
.rpc();
|
|
731
|
+
}
|
|
732
|
+
async createTokenizeSharesIx(vaultDepositor, amount, unit, mint) {
|
|
733
|
+
const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
|
|
734
|
+
const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
|
|
735
|
+
mint =
|
|
736
|
+
mint !== null && mint !== void 0 ? mint : (0, addresses_1.getTokenizedVaultMintAddressSync)(this.program.programId, vaultDepositorAccount.vault, vaultAccount.sharesBase);
|
|
737
|
+
const userAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mint, this.driftClient.wallet.publicKey, true);
|
|
738
|
+
const ixs = [];
|
|
739
|
+
const userAtaExists = await this.driftClient.connection.getAccountInfo(userAta);
|
|
740
|
+
if (userAtaExists === null) {
|
|
741
|
+
ixs.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(this.driftClient.wallet.publicKey, userAta, this.driftClient.wallet.publicKey, mint));
|
|
742
|
+
}
|
|
743
|
+
const user = await this.getSubscribedVaultUser(vaultAccount.user);
|
|
744
|
+
const remainingAccounts = this.driftClient.getRemainingAccounts({
|
|
745
|
+
userAccounts: [user.getUserAccount()],
|
|
746
|
+
writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
|
|
747
|
+
});
|
|
748
|
+
ixs.push(await this.program.methods
|
|
749
|
+
// anchor idl bug: https://github.com/coral-xyz/anchor/issues/2914
|
|
750
|
+
// @ts-ignore
|
|
751
|
+
.tokenizeShares(amount, unit)
|
|
752
|
+
.accounts({
|
|
753
|
+
authority: this.driftClient.wallet.publicKey,
|
|
754
|
+
vault: vaultDepositorAccount.vault,
|
|
755
|
+
vaultDepositor,
|
|
756
|
+
tokenizedVaultDepositor: (0, addresses_1.getTokenizedVaultAddressSync)(this.program.programId, vaultDepositorAccount.vault, vaultAccount.sharesBase),
|
|
757
|
+
mint,
|
|
758
|
+
userTokenAccount: userAta,
|
|
759
|
+
driftUser: vaultAccount.user,
|
|
760
|
+
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
761
|
+
})
|
|
762
|
+
.remainingAccounts(remainingAccounts)
|
|
763
|
+
.instruction());
|
|
764
|
+
return ixs;
|
|
765
|
+
}
|
|
766
|
+
async tokenizeShares(vaultDepositor, amount, unit, mint, txParams) {
|
|
767
|
+
const ixs = await this.createTokenizeSharesIx(vaultDepositor, amount, unit, mint);
|
|
768
|
+
if (this.cliMode) {
|
|
769
|
+
try {
|
|
770
|
+
const tx = new web3_js_1.Transaction().add(...ixs);
|
|
771
|
+
const txSig = await this.driftClient.txSender.send(tx, undefined, undefined, false);
|
|
772
|
+
return txSig.txSig;
|
|
773
|
+
}
|
|
774
|
+
catch (e) {
|
|
775
|
+
console.error(e);
|
|
776
|
+
throw e;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
else {
|
|
780
|
+
return await this.createAndSendTxn(ixs, txParams);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
async createRedeemTokensIx(vaultDepositor, tokensToBurn, sharesBase) {
|
|
784
|
+
const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
|
|
785
|
+
const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
|
|
786
|
+
const mint = (0, addresses_1.getTokenizedVaultMintAddressSync)(this.program.programId, vaultDepositorAccount.vault, sharesBase !== null && sharesBase !== void 0 ? sharesBase : vaultAccount.sharesBase);
|
|
787
|
+
const userAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mint, this.driftClient.wallet.publicKey, true);
|
|
788
|
+
const vaultTokenAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mint, vaultDepositorAccount.vault, true);
|
|
789
|
+
const user = await this.getSubscribedVaultUser(vaultAccount.user);
|
|
790
|
+
const remainingAccounts = this.driftClient.getRemainingAccounts({
|
|
791
|
+
userAccounts: [user.getUserAccount()],
|
|
792
|
+
writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
|
|
793
|
+
});
|
|
794
|
+
return await this.program.methods
|
|
795
|
+
.redeemTokens(tokensToBurn)
|
|
796
|
+
.accounts({
|
|
797
|
+
authority: this.driftClient.wallet.publicKey,
|
|
798
|
+
vault: vaultDepositorAccount.vault,
|
|
799
|
+
vaultDepositor,
|
|
800
|
+
tokenizedVaultDepositor: (0, addresses_1.getTokenizedVaultAddressSync)(this.program.programId, vaultDepositorAccount.vault, sharesBase !== null && sharesBase !== void 0 ? sharesBase : vaultAccount.sharesBase),
|
|
801
|
+
mint,
|
|
802
|
+
userTokenAccount: userAta,
|
|
803
|
+
vaultTokenAccount: vaultTokenAta,
|
|
804
|
+
driftUser: vaultAccount.user,
|
|
805
|
+
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
806
|
+
})
|
|
807
|
+
.remainingAccounts(remainingAccounts)
|
|
808
|
+
.instruction();
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* Redeems tokens from the vault.
|
|
812
|
+
* @param vaultDepositor
|
|
813
|
+
* @param tokensToBurn
|
|
814
|
+
* @param mint optionally provide a mint, or infer the mint from the current vault share base
|
|
815
|
+
* @param txParams
|
|
816
|
+
* @returns
|
|
817
|
+
*/
|
|
818
|
+
async redeemTokens(vaultDepositor, tokensToBurn, sharesBase, txParams) {
|
|
819
|
+
const ix = await this.createRedeemTokensIx(vaultDepositor, tokensToBurn, sharesBase);
|
|
820
|
+
if (this.cliMode) {
|
|
821
|
+
try {
|
|
822
|
+
const tx = new web3_js_1.Transaction().add(ix);
|
|
823
|
+
const txSig = await this.driftClient.txSender.send(tx, undefined, undefined, false);
|
|
824
|
+
return txSig.txSig;
|
|
825
|
+
}
|
|
826
|
+
catch (e) {
|
|
827
|
+
console.error(e);
|
|
828
|
+
throw e;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
else {
|
|
832
|
+
return await this.createAndSendTxn([ix], txParams);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
async prepDepositTx(vaultDepositor, amount, initVaultDepositor, userTokenAccount) {
|
|
619
836
|
let vaultPubKey;
|
|
620
837
|
if (initVaultDepositor) {
|
|
621
838
|
vaultPubKey = initVaultDepositor.vault;
|
|
@@ -652,7 +869,7 @@ class VaultClient {
|
|
|
652
869
|
driftUser: vaultAccount.user,
|
|
653
870
|
driftState: driftStateKey,
|
|
654
871
|
driftSpotMarketVault: spotMarket.vault,
|
|
655
|
-
userTokenAccount: (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, this.driftClient.wallet.publicKey, true),
|
|
872
|
+
userTokenAccount: userTokenAccount !== null && userTokenAccount !== void 0 ? userTokenAccount : (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, this.driftClient.wallet.publicKey, true),
|
|
656
873
|
driftProgram: this.driftClient.program.programId,
|
|
657
874
|
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
658
875
|
};
|
|
@@ -696,13 +913,13 @@ class VaultClient {
|
|
|
696
913
|
* @param txParams
|
|
697
914
|
* @returns
|
|
698
915
|
*/
|
|
699
|
-
async deposit(vaultDepositor, amount, initVaultDepositor, txParams) {
|
|
916
|
+
async deposit(vaultDepositor, amount, initVaultDepositor, txParams, userTokenAccount) {
|
|
700
917
|
if (this.cliMode) {
|
|
701
|
-
const { vaultAccount, accounts, remainingAccounts } = await this.prepDepositTx(vaultDepositor, amount, initVaultDepositor);
|
|
918
|
+
const { vaultAccount, accounts, remainingAccounts } = await this.prepDepositTx(vaultDepositor, amount, initVaultDepositor, userTokenAccount);
|
|
702
919
|
if (initVaultDepositor) {
|
|
703
920
|
await this.initializeVaultDepositor(vaultAccount.pubkey, initVaultDepositor.authority);
|
|
704
921
|
}
|
|
705
|
-
return
|
|
922
|
+
return this.program.methods
|
|
706
923
|
.deposit(amount)
|
|
707
924
|
.accounts(accounts)
|
|
708
925
|
.remainingAccounts(remainingAccounts)
|
|
@@ -838,6 +1055,10 @@ class VaultClient {
|
|
|
838
1055
|
}
|
|
839
1056
|
}
|
|
840
1057
|
async forceWithdraw(vaultDepositor) {
|
|
1058
|
+
const ix = await this.getForceWithdrawIx(vaultDepositor);
|
|
1059
|
+
return await this.createAndSendTxn(ix);
|
|
1060
|
+
}
|
|
1061
|
+
async getForceWithdrawIx(vaultDepositor) {
|
|
841
1062
|
const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
|
|
842
1063
|
const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
|
|
843
1064
|
const user = await this.getSubscribedVaultUser(vaultAccount.user);
|
|
@@ -859,6 +1080,10 @@ class VaultClient {
|
|
|
859
1080
|
if (!spotMarket) {
|
|
860
1081
|
throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
|
|
861
1082
|
}
|
|
1083
|
+
const [userTokenAccount, createAtaIx] = await (0, utils_1.getOrCreateATAInstruction)(spotMarket.mint, vaultDepositorAccount.authority, this.driftClient.connection, true, this.driftClient.wallet.publicKey);
|
|
1084
|
+
if (createAtaIx) {
|
|
1085
|
+
console.log(`Creating ATA for ${vaultDepositorAccount.authority.toBase58()} to ${userTokenAccount.toBase58()}`);
|
|
1086
|
+
}
|
|
862
1087
|
const accounts = {
|
|
863
1088
|
manager: this.driftClient.wallet.publicKey,
|
|
864
1089
|
vault: vaultDepositorAccount.vault,
|
|
@@ -869,34 +1094,20 @@ class VaultClient {
|
|
|
869
1094
|
driftState: driftStateKey,
|
|
870
1095
|
driftSpotMarketVault: spotMarket.vault,
|
|
871
1096
|
driftSigner: this.driftClient.getStateAccount().signer,
|
|
872
|
-
userTokenAccount
|
|
1097
|
+
userTokenAccount,
|
|
873
1098
|
driftProgram: this.driftClient.program.programId,
|
|
874
1099
|
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
875
1100
|
};
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
.preInstructions([
|
|
880
|
-
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
881
|
-
units: 500000,
|
|
882
|
-
}),
|
|
883
|
-
web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
|
|
884
|
-
microLamports: 50000,
|
|
885
|
-
}),
|
|
886
|
-
])
|
|
887
|
-
.accounts(accounts)
|
|
888
|
-
.remainingAccounts(remainingAccounts)
|
|
889
|
-
.rpc();
|
|
890
|
-
}
|
|
891
|
-
else {
|
|
892
|
-
const forceWithdrawIx = this.program.instruction.forceWithdraw({
|
|
893
|
-
accounts: {
|
|
894
|
-
...accounts,
|
|
895
|
-
},
|
|
896
|
-
remainingAccounts,
|
|
897
|
-
});
|
|
898
|
-
return await this.createAndSendTxn([forceWithdrawIx]);
|
|
1101
|
+
const ixs = [];
|
|
1102
|
+
if (createAtaIx) {
|
|
1103
|
+
ixs.push(createAtaIx);
|
|
899
1104
|
}
|
|
1105
|
+
ixs.push(await this.program.methods
|
|
1106
|
+
.forceWithdraw()
|
|
1107
|
+
.accounts(accounts)
|
|
1108
|
+
.remainingAccounts(remainingAccounts)
|
|
1109
|
+
.instruction());
|
|
1110
|
+
return ixs;
|
|
900
1111
|
}
|
|
901
1112
|
async cancelRequestWithdraw(vaultDepositor, txParams) {
|
|
902
1113
|
const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
|
|
@@ -1051,11 +1262,14 @@ class VaultClient {
|
|
|
1051
1262
|
if (!spotMarket) {
|
|
1052
1263
|
throw new Error(`Spot market ${spotMarketIndex} not found on driftClient`);
|
|
1053
1264
|
}
|
|
1265
|
+
const ifVaultTokenAccount = (0, addresses_1.getInsuranceFundTokenVaultAddressSync)(this.program.programId, vault, spotMarketIndex);
|
|
1054
1266
|
return await this.program.methods
|
|
1055
1267
|
.initializeInsuranceFundStake(spotMarketIndex)
|
|
1056
1268
|
.accounts({
|
|
1057
1269
|
vault: vault,
|
|
1058
1270
|
driftSpotMarket: spotMarket.pubkey,
|
|
1271
|
+
driftSpotMarketMint: spotMarket.mint,
|
|
1272
|
+
vaultTokenAccount: ifVaultTokenAccount,
|
|
1059
1273
|
insuranceFundStake: ifStakeAccountPublicKey,
|
|
1060
1274
|
driftUserStats: vaultAccount.userStats,
|
|
1061
1275
|
driftState: await this.driftClient.getStatePublicKey(),
|
|
@@ -1064,24 +1278,113 @@ class VaultClient {
|
|
|
1064
1278
|
.rpc();
|
|
1065
1279
|
}
|
|
1066
1280
|
/**
|
|
1067
|
-
*
|
|
1068
|
-
* @param vault vault address to
|
|
1069
|
-
* @param
|
|
1281
|
+
* Adds an amount to an insurance fund stake for the vault.
|
|
1282
|
+
* @param vault vault address to update
|
|
1283
|
+
* @param spotMarketIndex spot market index of the insurance fund stake
|
|
1284
|
+
* @param amount amount to add to the insurance fund stake, in spotMarketIndex precision
|
|
1070
1285
|
* @returns
|
|
1071
1286
|
*/
|
|
1072
|
-
async
|
|
1287
|
+
async addToInsuranceFundStake(vault, spotMarketIndex, amount, managerTokenAccount) {
|
|
1073
1288
|
const vaultAccount = await this.program.account.vault.fetch(vault);
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1289
|
+
if (!vaultAccount.manager.equals(this.driftClient.wallet.publicKey)) {
|
|
1290
|
+
throw new Error(`Only the manager of the vault can add to the insurance fund stake.`);
|
|
1291
|
+
}
|
|
1292
|
+
const ifStakeAccountPublicKey = (0, sdk_1.getInsuranceFundStakeAccountPublicKey)(this.driftClient.program.programId, vault, spotMarketIndex);
|
|
1293
|
+
const ifVaultPublicKey = await (0, sdk_1.getInsuranceFundVaultPublicKey)(this.driftClient.program.programId, spotMarketIndex);
|
|
1294
|
+
const spotMarket = this.driftClient.getSpotMarketAccount(spotMarketIndex);
|
|
1295
|
+
if (!spotMarket) {
|
|
1296
|
+
throw new Error(`Spot market ${spotMarketIndex} not found on driftClient`);
|
|
1297
|
+
}
|
|
1298
|
+
if (!managerTokenAccount) {
|
|
1299
|
+
managerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, this.driftClient.wallet.publicKey);
|
|
1300
|
+
}
|
|
1301
|
+
const ifVaultTokenAccount = (0, addresses_1.getInsuranceFundTokenVaultAddressSync)(this.program.programId, vault, spotMarketIndex);
|
|
1077
1302
|
return await this.program.methods
|
|
1078
|
-
.
|
|
1303
|
+
.addInsuranceFundStake(spotMarketIndex, amount)
|
|
1079
1304
|
.accounts({
|
|
1080
1305
|
vault: vault,
|
|
1081
|
-
|
|
1082
|
-
|
|
1306
|
+
driftSpotMarket: spotMarket.pubkey,
|
|
1307
|
+
driftSpotMarketVault: spotMarket.vault,
|
|
1308
|
+
insuranceFundStake: ifStakeAccountPublicKey,
|
|
1309
|
+
insuranceFundVault: ifVaultPublicKey,
|
|
1310
|
+
managerTokenAccount,
|
|
1311
|
+
vaultIfTokenAccount: ifVaultTokenAccount,
|
|
1083
1312
|
driftUserStats: vaultAccount.userStats,
|
|
1084
|
-
|
|
1313
|
+
driftState: await this.driftClient.getStatePublicKey(),
|
|
1314
|
+
driftProgram: this.driftClient.program.programId,
|
|
1315
|
+
driftSigner: this.driftClient.getStateAccount().signer,
|
|
1316
|
+
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
1317
|
+
})
|
|
1318
|
+
.rpc();
|
|
1319
|
+
}
|
|
1320
|
+
async requestRemoveInsuranceFundStake(vault, spotMarketIndex, amount) {
|
|
1321
|
+
const vaultAccount = await this.program.account.vault.fetch(vault);
|
|
1322
|
+
const ifStakeAccountPublicKey = (0, sdk_1.getInsuranceFundStakeAccountPublicKey)(this.driftClient.program.programId, vault, spotMarketIndex);
|
|
1323
|
+
const ifVaultPublicKey = await (0, sdk_1.getInsuranceFundVaultPublicKey)(this.driftClient.program.programId, spotMarketIndex);
|
|
1324
|
+
const spotMarket = this.driftClient.getSpotMarketAccount(spotMarketIndex);
|
|
1325
|
+
if (!spotMarket) {
|
|
1326
|
+
throw new Error(`Spot market ${spotMarketIndex} not found on driftClient`);
|
|
1327
|
+
}
|
|
1328
|
+
return await this.program.methods
|
|
1329
|
+
.requestRemoveInsuranceFundStake(spotMarketIndex, amount)
|
|
1330
|
+
.accounts({
|
|
1331
|
+
vault,
|
|
1332
|
+
manager: this.driftClient.wallet.publicKey,
|
|
1333
|
+
driftSpotMarket: spotMarket.pubkey,
|
|
1334
|
+
insuranceFundStake: ifStakeAccountPublicKey,
|
|
1335
|
+
insuranceFundVault: ifVaultPublicKey,
|
|
1336
|
+
driftUserStats: vaultAccount.userStats,
|
|
1337
|
+
driftProgram: this.driftClient.program.programId,
|
|
1338
|
+
})
|
|
1339
|
+
.rpc();
|
|
1340
|
+
}
|
|
1341
|
+
async cancelRequestRemoveInsuranceFundStake(vault, spotMarketIndex) {
|
|
1342
|
+
const vaultAccount = await this.program.account.vault.fetch(vault);
|
|
1343
|
+
const ifStakeAccountPublicKey = (0, sdk_1.getInsuranceFundStakeAccountPublicKey)(this.driftClient.program.programId, vault, spotMarketIndex);
|
|
1344
|
+
const ifVaultPublicKey = await (0, sdk_1.getInsuranceFundVaultPublicKey)(this.driftClient.program.programId, spotMarketIndex);
|
|
1345
|
+
const spotMarket = this.driftClient.getSpotMarketAccount(spotMarketIndex);
|
|
1346
|
+
if (!spotMarket) {
|
|
1347
|
+
throw new Error(`Spot market ${spotMarketIndex} not found on driftClient`);
|
|
1348
|
+
}
|
|
1349
|
+
return await this.program.methods
|
|
1350
|
+
.cancelRequestRemoveInsuranceFundStake(spotMarketIndex)
|
|
1351
|
+
.accounts({
|
|
1352
|
+
vault: vault,
|
|
1353
|
+
manager: this.driftClient.wallet.publicKey,
|
|
1354
|
+
driftSpotMarket: spotMarket.pubkey,
|
|
1355
|
+
insuranceFundStake: ifStakeAccountPublicKey,
|
|
1356
|
+
insuranceFundVault: ifVaultPublicKey,
|
|
1357
|
+
driftUserStats: vaultAccount.userStats,
|
|
1358
|
+
driftProgram: this.driftClient.program.programId,
|
|
1359
|
+
})
|
|
1360
|
+
.rpc();
|
|
1361
|
+
}
|
|
1362
|
+
async removeInsuranceFundStake(vault, spotMarketIndex, managerTokenAccount) {
|
|
1363
|
+
const vaultAccount = await this.program.account.vault.fetch(vault);
|
|
1364
|
+
const ifStakeAccountPublicKey = (0, sdk_1.getInsuranceFundStakeAccountPublicKey)(this.driftClient.program.programId, vault, spotMarketIndex);
|
|
1365
|
+
const ifVaultPublicKey = await (0, sdk_1.getInsuranceFundVaultPublicKey)(this.driftClient.program.programId, spotMarketIndex);
|
|
1366
|
+
const spotMarket = this.driftClient.getSpotMarketAccount(spotMarketIndex);
|
|
1367
|
+
if (!spotMarket) {
|
|
1368
|
+
throw new Error(`Spot market ${spotMarketIndex} not found on driftClient`);
|
|
1369
|
+
}
|
|
1370
|
+
if (!managerTokenAccount) {
|
|
1371
|
+
managerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, this.driftClient.wallet.publicKey);
|
|
1372
|
+
}
|
|
1373
|
+
const ifVaultTokenAccount = (0, addresses_1.getInsuranceFundTokenVaultAddressSync)(this.program.programId, vault, spotMarketIndex);
|
|
1374
|
+
return await this.program.methods
|
|
1375
|
+
.removeInsuranceFundStake(spotMarketIndex)
|
|
1376
|
+
.accounts({
|
|
1377
|
+
vault: vault,
|
|
1378
|
+
driftSpotMarket: spotMarket.pubkey,
|
|
1379
|
+
insuranceFundStake: ifStakeAccountPublicKey,
|
|
1380
|
+
insuranceFundVault: ifVaultPublicKey,
|
|
1381
|
+
managerTokenAccount,
|
|
1382
|
+
vaultIfTokenAccount: ifVaultTokenAccount,
|
|
1383
|
+
driftState: await this.driftClient.getStatePublicKey(),
|
|
1384
|
+
driftUserStats: vaultAccount.userStats,
|
|
1385
|
+
driftSigner: this.driftClient.getStateAccount().signer,
|
|
1386
|
+
driftProgram: this.driftClient.program.programId,
|
|
1387
|
+
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
1085
1388
|
})
|
|
1086
1389
|
.rpc();
|
|
1087
1390
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drift-labs/vaults-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.533",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"directories": {
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"@coral-xyz/anchor": "0.28.0",
|
|
11
|
-
"@drift-labs/competitions-sdk": "0.2.519",
|
|
12
11
|
"@drift-labs/sdk": "2.98.0-beta.9",
|
|
13
12
|
"@ledgerhq/hw-app-solana": "^7.1.1",
|
|
14
13
|
"@ledgerhq/hw-transport": "^6.30.1",
|
|
15
14
|
"@ledgerhq/hw-transport-node-hid": "^6.28.1",
|
|
15
|
+
"@metaplex-foundation/js": "^0.20.1",
|
|
16
16
|
"@solana/wallet-adapter-ledger": "^0.9.25",
|
|
17
17
|
"@solana/web3.js": "1.92.3",
|
|
18
18
|
"commander": "^11.0.0",
|