@drift-labs/vaults-sdk 0.1.530 → 0.1.532
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 +2 -0
- package/lib/addresses.js +16 -0
- package/lib/types/drift_vaults.d.ts +402 -51
- package/lib/types/drift_vaults.js +402 -51
- package/lib/utils.d.ts +2 -1
- package/lib/utils.js +20 -1
- package/lib/vaultClient.d.ts +31 -11
- package/lib/vaultClient.js +244 -55
- package/package.json +3 -3
- package/src/addresses.ts +30 -0
- package/src/idl/drift_vaults.json +1265 -207
- package/src/types/drift_vaults.ts +811 -109
- package/src/utils.ts +37 -1
- package/src/vaultClient.ts +456 -79
package/src/utils.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { AnchorProvider } from '@coral-xyz/anchor';
|
|
2
2
|
import { DriftClient, IWallet } from '@drift-labs/sdk';
|
|
3
|
-
import { Connection } from '@solana/web3.js';
|
|
3
|
+
import { Connection, PublicKey, TransactionInstruction } from '@solana/web3.js';
|
|
4
4
|
import { DriftVaults, IDL } from './types/drift_vaults';
|
|
5
5
|
import { VaultClient } from './vaultClient';
|
|
6
6
|
import * as anchor from '@coral-xyz/anchor';
|
|
7
7
|
import { VAULT_PROGRAM_ID } from './types/types';
|
|
8
|
+
import {
|
|
9
|
+
createAssociatedTokenAccountInstruction,
|
|
10
|
+
getAssociatedTokenAddress,
|
|
11
|
+
} from '@solana/spl-token';
|
|
8
12
|
|
|
9
13
|
export const getDriftVaultProgram = (
|
|
10
14
|
connection: Connection,
|
|
@@ -31,3 +35,35 @@ export const getVaultClient = (
|
|
|
31
35
|
|
|
32
36
|
return vaultClient;
|
|
33
37
|
};
|
|
38
|
+
|
|
39
|
+
export const getOrCreateATAInstruction = async (
|
|
40
|
+
tokenMint: PublicKey,
|
|
41
|
+
owner: PublicKey,
|
|
42
|
+
connection: Connection,
|
|
43
|
+
allowOwnerOffCurve = true,
|
|
44
|
+
payer = owner
|
|
45
|
+
): Promise<[PublicKey, TransactionInstruction?]> => {
|
|
46
|
+
let toAccount;
|
|
47
|
+
try {
|
|
48
|
+
toAccount = await getAssociatedTokenAddress(
|
|
49
|
+
tokenMint,
|
|
50
|
+
owner,
|
|
51
|
+
allowOwnerOffCurve
|
|
52
|
+
);
|
|
53
|
+
const account = await connection.getAccountInfo(toAccount);
|
|
54
|
+
if (!account) {
|
|
55
|
+
const ix = createAssociatedTokenAccountInstruction(
|
|
56
|
+
payer,
|
|
57
|
+
toAccount,
|
|
58
|
+
owner,
|
|
59
|
+
tokenMint
|
|
60
|
+
);
|
|
61
|
+
return [toAccount, ix];
|
|
62
|
+
}
|
|
63
|
+
return [toAccount, undefined];
|
|
64
|
+
} catch (e) {
|
|
65
|
+
/* handle error */
|
|
66
|
+
console.error('Error::getOrCreateATAInstruction', e);
|
|
67
|
+
throw e;
|
|
68
|
+
}
|
|
69
|
+
};
|
package/src/vaultClient.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BN,
|
|
3
3
|
DriftClient,
|
|
4
|
-
encodeName,
|
|
5
4
|
getInsuranceFundStakeAccountPublicKey,
|
|
6
5
|
getUserAccountPublicKey,
|
|
7
6
|
getUserAccountPublicKeySync,
|
|
@@ -14,11 +13,8 @@ import {
|
|
|
14
13
|
import { BorshAccountsCoder, Program, ProgramAccount } from '@coral-xyz/anchor';
|
|
15
14
|
import { DriftVaults } from './types/drift_vaults';
|
|
16
15
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
getCompetitorAddressSync,
|
|
20
|
-
} from '@drift-labs/competitions-sdk';
|
|
21
|
-
import {
|
|
16
|
+
getTokenizedVaultAddressSync,
|
|
17
|
+
getTokenizedVaultMintAddressSync,
|
|
22
18
|
getTokenVaultAddressSync,
|
|
23
19
|
getVaultAddressSync,
|
|
24
20
|
getVaultDepositorAddressSync,
|
|
@@ -30,6 +26,7 @@ import {
|
|
|
30
26
|
PublicKey,
|
|
31
27
|
SystemProgram,
|
|
32
28
|
SYSVAR_RENT_PUBKEY,
|
|
29
|
+
Transaction,
|
|
33
30
|
TransactionInstruction,
|
|
34
31
|
TransactionSignature,
|
|
35
32
|
VersionedTransaction,
|
|
@@ -51,6 +48,8 @@ import {
|
|
|
51
48
|
import { bs58 } from '@coral-xyz/anchor/dist/cjs/utils/bytes';
|
|
52
49
|
import { UserMapConfig } from '@drift-labs/sdk';
|
|
53
50
|
import { calculateRealizedVaultDepositorEquity } from './math';
|
|
51
|
+
import { Metaplex } from '@metaplex-foundation/js';
|
|
52
|
+
import { getOrCreateATAInstruction } from './utils';
|
|
54
53
|
|
|
55
54
|
export type TxParams = {
|
|
56
55
|
cuLimit?: number;
|
|
@@ -61,6 +60,7 @@ export type TxParams = {
|
|
|
61
60
|
|
|
62
61
|
export class VaultClient {
|
|
63
62
|
driftClient: DriftClient;
|
|
63
|
+
metaplex?: Metaplex;
|
|
64
64
|
program: Program<DriftVaults>;
|
|
65
65
|
cliMode: boolean;
|
|
66
66
|
|
|
@@ -72,15 +72,18 @@ export class VaultClient {
|
|
|
72
72
|
constructor({
|
|
73
73
|
driftClient,
|
|
74
74
|
program,
|
|
75
|
+
metaplex,
|
|
75
76
|
cliMode,
|
|
76
77
|
userMapConfig,
|
|
77
78
|
}: {
|
|
78
79
|
driftClient: DriftClient;
|
|
79
80
|
program: Program<DriftVaults>;
|
|
81
|
+
metaplex?: Metaplex;
|
|
80
82
|
cliMode?: boolean;
|
|
81
83
|
userMapConfig?: UserMapConfig;
|
|
82
84
|
}) {
|
|
83
85
|
this.driftClient = driftClient;
|
|
86
|
+
this.metaplex = metaplex;
|
|
84
87
|
this.program = program;
|
|
85
88
|
this.cliMode = !!cliMode;
|
|
86
89
|
|
|
@@ -876,6 +879,111 @@ export class VaultClient {
|
|
|
876
879
|
});
|
|
877
880
|
}
|
|
878
881
|
|
|
882
|
+
public async getApplyRebaseTokenizedDepositorIx(
|
|
883
|
+
vault: PublicKey,
|
|
884
|
+
tokenizedVaultDepositor: PublicKey
|
|
885
|
+
): Promise<TransactionInstruction> {
|
|
886
|
+
const vaultAccount = await this.program.account.vault.fetch(vault);
|
|
887
|
+
|
|
888
|
+
const user = await this.getSubscribedVaultUser(vaultAccount.user);
|
|
889
|
+
|
|
890
|
+
const spotMarket = this.driftClient.getSpotMarketAccount(
|
|
891
|
+
vaultAccount.spotMarketIndex
|
|
892
|
+
);
|
|
893
|
+
if (!spotMarket) {
|
|
894
|
+
throw new Error(
|
|
895
|
+
`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
const remainingAccounts = this.driftClient.getRemainingAccounts({
|
|
900
|
+
userAccounts: [user.getUserAccount()],
|
|
901
|
+
writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
const accounts = {
|
|
905
|
+
vault,
|
|
906
|
+
tokenizedVaultDepositor,
|
|
907
|
+
driftUser: await getUserAccountPublicKey(
|
|
908
|
+
this.driftClient.program.programId,
|
|
909
|
+
vault
|
|
910
|
+
),
|
|
911
|
+
driftState: await this.driftClient.getStatePublicKey(),
|
|
912
|
+
driftSigner: this.driftClient.getStateAccount().signer,
|
|
913
|
+
driftProgram: this.driftClient.program.programId,
|
|
914
|
+
};
|
|
915
|
+
|
|
916
|
+
return this.program.instruction.applyRebaseTokenizedDepositor({
|
|
917
|
+
accounts: {
|
|
918
|
+
...accounts,
|
|
919
|
+
},
|
|
920
|
+
remainingAccounts,
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
public async applyRebase(
|
|
925
|
+
vault: PublicKey,
|
|
926
|
+
vaultDepositor: PublicKey
|
|
927
|
+
): Promise<TransactionSignature> {
|
|
928
|
+
return await this.createAndSendTxn([
|
|
929
|
+
await this.getApplyRebaseIx(vault, vaultDepositor),
|
|
930
|
+
]);
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
public async getApplyRebaseIx(
|
|
934
|
+
vault: PublicKey,
|
|
935
|
+
vaultDepositor: PublicKey
|
|
936
|
+
): Promise<TransactionInstruction> {
|
|
937
|
+
const vaultAccount = await this.program.account.vault.fetch(vault);
|
|
938
|
+
|
|
939
|
+
const user = await this.getSubscribedVaultUser(vaultAccount.user);
|
|
940
|
+
|
|
941
|
+
const spotMarket = this.driftClient.getSpotMarketAccount(
|
|
942
|
+
vaultAccount.spotMarketIndex
|
|
943
|
+
);
|
|
944
|
+
if (!spotMarket) {
|
|
945
|
+
throw new Error(
|
|
946
|
+
`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`
|
|
947
|
+
);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
const remainingAccounts = this.driftClient.getRemainingAccounts({
|
|
951
|
+
userAccounts: [user.getUserAccount()],
|
|
952
|
+
writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
const accounts = {
|
|
956
|
+
vault,
|
|
957
|
+
vaultDepositor,
|
|
958
|
+
driftUser: await getUserAccountPublicKey(
|
|
959
|
+
this.driftClient.program.programId,
|
|
960
|
+
vault
|
|
961
|
+
),
|
|
962
|
+
driftState: await this.driftClient.getStatePublicKey(),
|
|
963
|
+
driftSigner: this.driftClient.getStateAccount().signer,
|
|
964
|
+
driftProgram: this.driftClient.program.programId,
|
|
965
|
+
};
|
|
966
|
+
|
|
967
|
+
return this.program.instruction.applyRebase({
|
|
968
|
+
accounts: {
|
|
969
|
+
...accounts,
|
|
970
|
+
},
|
|
971
|
+
remainingAccounts,
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
public async applyRebaseTokenizedDepositor(
|
|
976
|
+
vault: PublicKey,
|
|
977
|
+
tokenizedVaultDepositor: PublicKey
|
|
978
|
+
): Promise<TransactionSignature> {
|
|
979
|
+
return await this.createAndSendTxn([
|
|
980
|
+
await this.getApplyRebaseTokenizedDepositorIx(
|
|
981
|
+
vault,
|
|
982
|
+
tokenizedVaultDepositor
|
|
983
|
+
),
|
|
984
|
+
]);
|
|
985
|
+
}
|
|
986
|
+
|
|
879
987
|
private createInitVaultDepositorIx(vault: PublicKey, authority?: PublicKey) {
|
|
880
988
|
const vaultDepositor = getVaultDepositorAddressSync(
|
|
881
989
|
this.program.programId,
|
|
@@ -924,9 +1032,14 @@ export class VaultClient {
|
|
|
924
1032
|
};
|
|
925
1033
|
|
|
926
1034
|
if (this.cliMode) {
|
|
927
|
-
return
|
|
1035
|
+
return this.program.methods
|
|
928
1036
|
.initializeVaultDepositor()
|
|
929
|
-
.accounts(
|
|
1037
|
+
.accounts({
|
|
1038
|
+
...accounts,
|
|
1039
|
+
payer: authority || this.driftClient.wallet.publicKey,
|
|
1040
|
+
rent: SYSVAR_RENT_PUBKEY,
|
|
1041
|
+
systemProgram: SystemProgram.programId,
|
|
1042
|
+
})
|
|
930
1043
|
.rpc();
|
|
931
1044
|
} else {
|
|
932
1045
|
const initIx = this.createInitVaultDepositorIx(vault, authority);
|
|
@@ -934,13 +1047,297 @@ export class VaultClient {
|
|
|
934
1047
|
}
|
|
935
1048
|
}
|
|
936
1049
|
|
|
1050
|
+
public async initializeTokenizedVaultDepositor(params: {
|
|
1051
|
+
vault: PublicKey;
|
|
1052
|
+
tokenName: string;
|
|
1053
|
+
tokenSymbol: string;
|
|
1054
|
+
tokenUri: string;
|
|
1055
|
+
decimals?: number;
|
|
1056
|
+
sharesBase?: number;
|
|
1057
|
+
}): Promise<TransactionSignature> {
|
|
1058
|
+
if (!this.metaplex) {
|
|
1059
|
+
throw new Error(
|
|
1060
|
+
'Metaplex instance is required when constructing VaultClient to initialize a tokenized vault depositor'
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
let spotMarketDecimals = 6;
|
|
1065
|
+
let sharesBase = 0;
|
|
1066
|
+
if (params.decimals === undefined || params.sharesBase === undefined) {
|
|
1067
|
+
const vault = await this.program.account.vault.fetch(params.vault);
|
|
1068
|
+
const spotMarketAccount = this.driftClient.getSpotMarketAccount(
|
|
1069
|
+
vault.spotMarketIndex
|
|
1070
|
+
);
|
|
1071
|
+
if (!spotMarketAccount) {
|
|
1072
|
+
throw new Error(
|
|
1073
|
+
`DriftClient failed to load vault's spot market (marketIndex: ${vault.spotMarketIndex})`
|
|
1074
|
+
);
|
|
1075
|
+
}
|
|
1076
|
+
spotMarketDecimals = spotMarketAccount.decimals;
|
|
1077
|
+
sharesBase = vault.sharesBase;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
const mintAddress = getTokenizedVaultMintAddressSync(
|
|
1081
|
+
this.program.programId,
|
|
1082
|
+
params.vault,
|
|
1083
|
+
sharesBase
|
|
1084
|
+
);
|
|
1085
|
+
|
|
1086
|
+
const accounts = {
|
|
1087
|
+
vault: params.vault,
|
|
1088
|
+
vaultDepositor: getTokenizedVaultAddressSync(
|
|
1089
|
+
this.program.programId,
|
|
1090
|
+
params.vault,
|
|
1091
|
+
sharesBase
|
|
1092
|
+
),
|
|
1093
|
+
mintAccount: mintAddress,
|
|
1094
|
+
metadataAccount: this.metaplex.nfts().pdas().metadata({
|
|
1095
|
+
mint: mintAddress,
|
|
1096
|
+
}),
|
|
1097
|
+
tokenMetadataProgram: this.metaplex.programs().getTokenMetadata().address,
|
|
1098
|
+
payer: this.driftClient.wallet.publicKey,
|
|
1099
|
+
};
|
|
1100
|
+
|
|
1101
|
+
const vaultTokenAta = getAssociatedTokenAddressSync(
|
|
1102
|
+
mintAddress,
|
|
1103
|
+
params.vault,
|
|
1104
|
+
true
|
|
1105
|
+
);
|
|
1106
|
+
const createAtaIx = createAssociatedTokenAccountInstruction(
|
|
1107
|
+
this.driftClient.wallet.publicKey,
|
|
1108
|
+
vaultTokenAta,
|
|
1109
|
+
params.vault,
|
|
1110
|
+
mintAddress
|
|
1111
|
+
);
|
|
1112
|
+
|
|
1113
|
+
if (!this.cliMode) {
|
|
1114
|
+
throw new Error(
|
|
1115
|
+
'CLI mode is not supported for initializeTokenizedVaultDepositor'
|
|
1116
|
+
);
|
|
1117
|
+
}
|
|
1118
|
+
return await this.program.methods
|
|
1119
|
+
.initializeTokenizedVaultDepositor({
|
|
1120
|
+
...params,
|
|
1121
|
+
decimals: params.decimals ?? spotMarketDecimals,
|
|
1122
|
+
})
|
|
1123
|
+
.preInstructions([
|
|
1124
|
+
ComputeBudgetProgram.setComputeUnitPrice({
|
|
1125
|
+
microLamports: 50_000,
|
|
1126
|
+
}),
|
|
1127
|
+
])
|
|
1128
|
+
.postInstructions([createAtaIx])
|
|
1129
|
+
.accounts(accounts)
|
|
1130
|
+
.rpc();
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
public async createTokenizeSharesIx(
|
|
1134
|
+
vaultDepositor: PublicKey,
|
|
1135
|
+
amount: BN,
|
|
1136
|
+
unit: WithdrawUnit,
|
|
1137
|
+
mint?: PublicKey
|
|
1138
|
+
): Promise<TransactionInstruction[]> {
|
|
1139
|
+
const vaultDepositorAccount =
|
|
1140
|
+
await this.program.account.vaultDepositor.fetch(vaultDepositor);
|
|
1141
|
+
const vaultAccount = await this.program.account.vault.fetch(
|
|
1142
|
+
vaultDepositorAccount.vault
|
|
1143
|
+
);
|
|
1144
|
+
|
|
1145
|
+
mint =
|
|
1146
|
+
mint ??
|
|
1147
|
+
getTokenizedVaultMintAddressSync(
|
|
1148
|
+
this.program.programId,
|
|
1149
|
+
vaultDepositorAccount.vault,
|
|
1150
|
+
vaultAccount.sharesBase
|
|
1151
|
+
);
|
|
1152
|
+
|
|
1153
|
+
const userAta = getAssociatedTokenAddressSync(
|
|
1154
|
+
mint,
|
|
1155
|
+
this.driftClient.wallet.publicKey,
|
|
1156
|
+
true
|
|
1157
|
+
);
|
|
1158
|
+
|
|
1159
|
+
const ixs = [];
|
|
1160
|
+
|
|
1161
|
+
const userAtaExists = await this.driftClient.connection.getAccountInfo(
|
|
1162
|
+
userAta
|
|
1163
|
+
);
|
|
1164
|
+
if (userAtaExists === null) {
|
|
1165
|
+
ixs.push(
|
|
1166
|
+
createAssociatedTokenAccountInstruction(
|
|
1167
|
+
this.driftClient.wallet.publicKey,
|
|
1168
|
+
userAta,
|
|
1169
|
+
this.driftClient.wallet.publicKey,
|
|
1170
|
+
mint
|
|
1171
|
+
)
|
|
1172
|
+
);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
const user = await this.getSubscribedVaultUser(vaultAccount.user);
|
|
1176
|
+
const remainingAccounts = this.driftClient.getRemainingAccounts({
|
|
1177
|
+
userAccounts: [user.getUserAccount()],
|
|
1178
|
+
writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
|
|
1179
|
+
});
|
|
1180
|
+
|
|
1181
|
+
ixs.push(
|
|
1182
|
+
await this.program.methods
|
|
1183
|
+
// anchor idl bug: https://github.com/coral-xyz/anchor/issues/2914
|
|
1184
|
+
// @ts-ignore
|
|
1185
|
+
.tokenizeShares(amount, unit)
|
|
1186
|
+
.accounts({
|
|
1187
|
+
authority: this.driftClient.wallet.publicKey,
|
|
1188
|
+
vault: vaultDepositorAccount.vault,
|
|
1189
|
+
vaultDepositor,
|
|
1190
|
+
tokenizedVaultDepositor: getTokenizedVaultAddressSync(
|
|
1191
|
+
this.program.programId,
|
|
1192
|
+
vaultDepositorAccount.vault,
|
|
1193
|
+
vaultAccount.sharesBase
|
|
1194
|
+
),
|
|
1195
|
+
mint,
|
|
1196
|
+
userTokenAccount: userAta,
|
|
1197
|
+
driftUser: vaultAccount.user,
|
|
1198
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
1199
|
+
})
|
|
1200
|
+
.remainingAccounts(remainingAccounts)
|
|
1201
|
+
.instruction()
|
|
1202
|
+
);
|
|
1203
|
+
|
|
1204
|
+
return ixs;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
public async tokenizeShares(
|
|
1208
|
+
vaultDepositor: PublicKey,
|
|
1209
|
+
amount: BN,
|
|
1210
|
+
unit: WithdrawUnit,
|
|
1211
|
+
mint?: PublicKey,
|
|
1212
|
+
txParams?: TxParams
|
|
1213
|
+
): Promise<TransactionSignature> {
|
|
1214
|
+
const ixs = await this.createTokenizeSharesIx(
|
|
1215
|
+
vaultDepositor,
|
|
1216
|
+
amount,
|
|
1217
|
+
unit,
|
|
1218
|
+
mint
|
|
1219
|
+
);
|
|
1220
|
+
if (this.cliMode) {
|
|
1221
|
+
try {
|
|
1222
|
+
const tx = new Transaction().add(...ixs);
|
|
1223
|
+
const txSig = await this.driftClient.txSender.send(
|
|
1224
|
+
tx,
|
|
1225
|
+
undefined,
|
|
1226
|
+
undefined,
|
|
1227
|
+
false
|
|
1228
|
+
);
|
|
1229
|
+
return txSig.txSig;
|
|
1230
|
+
} catch (e) {
|
|
1231
|
+
console.error(e);
|
|
1232
|
+
throw e;
|
|
1233
|
+
}
|
|
1234
|
+
} else {
|
|
1235
|
+
return await this.createAndSendTxn(ixs, txParams);
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
public async createRedeemTokensIx(
|
|
1240
|
+
vaultDepositor: PublicKey,
|
|
1241
|
+
tokensToBurn: BN,
|
|
1242
|
+
sharesBase?: number
|
|
1243
|
+
): Promise<TransactionInstruction> {
|
|
1244
|
+
const vaultDepositorAccount =
|
|
1245
|
+
await this.program.account.vaultDepositor.fetch(vaultDepositor);
|
|
1246
|
+
const vaultAccount = await this.program.account.vault.fetch(
|
|
1247
|
+
vaultDepositorAccount.vault
|
|
1248
|
+
);
|
|
1249
|
+
|
|
1250
|
+
const mint = getTokenizedVaultMintAddressSync(
|
|
1251
|
+
this.program.programId,
|
|
1252
|
+
vaultDepositorAccount.vault,
|
|
1253
|
+
sharesBase ?? vaultAccount.sharesBase
|
|
1254
|
+
);
|
|
1255
|
+
|
|
1256
|
+
const userAta = getAssociatedTokenAddressSync(
|
|
1257
|
+
mint,
|
|
1258
|
+
this.driftClient.wallet.publicKey,
|
|
1259
|
+
true
|
|
1260
|
+
);
|
|
1261
|
+
|
|
1262
|
+
const vaultTokenAta = getAssociatedTokenAddressSync(
|
|
1263
|
+
mint,
|
|
1264
|
+
vaultDepositorAccount.vault,
|
|
1265
|
+
true
|
|
1266
|
+
);
|
|
1267
|
+
|
|
1268
|
+
const user = await this.getSubscribedVaultUser(vaultAccount.user);
|
|
1269
|
+
const remainingAccounts = this.driftClient.getRemainingAccounts({
|
|
1270
|
+
userAccounts: [user.getUserAccount()],
|
|
1271
|
+
writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
|
|
1272
|
+
});
|
|
1273
|
+
|
|
1274
|
+
return await this.program.methods
|
|
1275
|
+
.redeemTokens(tokensToBurn)
|
|
1276
|
+
.accounts({
|
|
1277
|
+
authority: this.driftClient.wallet.publicKey,
|
|
1278
|
+
vault: vaultDepositorAccount.vault,
|
|
1279
|
+
vaultDepositor,
|
|
1280
|
+
tokenizedVaultDepositor: getTokenizedVaultAddressSync(
|
|
1281
|
+
this.program.programId,
|
|
1282
|
+
vaultDepositorAccount.vault,
|
|
1283
|
+
sharesBase ?? vaultAccount.sharesBase
|
|
1284
|
+
),
|
|
1285
|
+
mint,
|
|
1286
|
+
userTokenAccount: userAta,
|
|
1287
|
+
vaultTokenAccount: vaultTokenAta,
|
|
1288
|
+
driftUser: vaultAccount.user,
|
|
1289
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
1290
|
+
})
|
|
1291
|
+
.remainingAccounts(remainingAccounts)
|
|
1292
|
+
.instruction();
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
/**
|
|
1296
|
+
* Redeems tokens from the vault.
|
|
1297
|
+
* @param vaultDepositor
|
|
1298
|
+
* @param tokensToBurn
|
|
1299
|
+
* @param mint optionally provide a mint, or infer the mint from the current vault share base
|
|
1300
|
+
* @param txParams
|
|
1301
|
+
* @returns
|
|
1302
|
+
*/
|
|
1303
|
+
public async redeemTokens(
|
|
1304
|
+
vaultDepositor: PublicKey,
|
|
1305
|
+
tokensToBurn: BN,
|
|
1306
|
+
sharesBase?: number,
|
|
1307
|
+
txParams?: TxParams
|
|
1308
|
+
): Promise<TransactionSignature> {
|
|
1309
|
+
const ix = await this.createRedeemTokensIx(
|
|
1310
|
+
vaultDepositor,
|
|
1311
|
+
tokensToBurn,
|
|
1312
|
+
sharesBase
|
|
1313
|
+
);
|
|
1314
|
+
if (this.cliMode) {
|
|
1315
|
+
try {
|
|
1316
|
+
const tx = new Transaction().add(ix);
|
|
1317
|
+
const txSig = await this.driftClient.txSender.send(
|
|
1318
|
+
tx,
|
|
1319
|
+
undefined,
|
|
1320
|
+
undefined,
|
|
1321
|
+
false
|
|
1322
|
+
);
|
|
1323
|
+
return txSig.txSig;
|
|
1324
|
+
} catch (e) {
|
|
1325
|
+
console.error(e);
|
|
1326
|
+
throw e;
|
|
1327
|
+
}
|
|
1328
|
+
} else {
|
|
1329
|
+
return await this.createAndSendTxn([ix], txParams);
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
|
|
937
1333
|
public async prepDepositTx(
|
|
938
1334
|
vaultDepositor: PublicKey,
|
|
939
1335
|
amount: BN,
|
|
940
1336
|
initVaultDepositor?: {
|
|
941
1337
|
authority: PublicKey;
|
|
942
1338
|
vault: PublicKey;
|
|
943
|
-
}
|
|
1339
|
+
},
|
|
1340
|
+
userTokenAccount?: PublicKey
|
|
944
1341
|
) {
|
|
945
1342
|
let vaultPubKey: PublicKey;
|
|
946
1343
|
if (initVaultDepositor) {
|
|
@@ -991,11 +1388,13 @@ export class VaultClient {
|
|
|
991
1388
|
driftUser: vaultAccount.user,
|
|
992
1389
|
driftState: driftStateKey,
|
|
993
1390
|
driftSpotMarketVault: spotMarket.vault,
|
|
994
|
-
userTokenAccount:
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1391
|
+
userTokenAccount:
|
|
1392
|
+
userTokenAccount ??
|
|
1393
|
+
getAssociatedTokenAddressSync(
|
|
1394
|
+
spotMarket.mint,
|
|
1395
|
+
this.driftClient.wallet.publicKey,
|
|
1396
|
+
true
|
|
1397
|
+
),
|
|
999
1398
|
driftProgram: this.driftClient.program.programId,
|
|
1000
1399
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
1001
1400
|
};
|
|
@@ -1067,11 +1466,17 @@ export class VaultClient {
|
|
|
1067
1466
|
authority: PublicKey;
|
|
1068
1467
|
vault: PublicKey;
|
|
1069
1468
|
},
|
|
1070
|
-
txParams?: TxParams
|
|
1469
|
+
txParams?: TxParams,
|
|
1470
|
+
userTokenAccount?: PublicKey
|
|
1071
1471
|
): Promise<TransactionSignature> {
|
|
1072
1472
|
if (this.cliMode) {
|
|
1073
1473
|
const { vaultAccount, accounts, remainingAccounts } =
|
|
1074
|
-
await this.prepDepositTx(
|
|
1474
|
+
await this.prepDepositTx(
|
|
1475
|
+
vaultDepositor,
|
|
1476
|
+
amount,
|
|
1477
|
+
initVaultDepositor,
|
|
1478
|
+
userTokenAccount
|
|
1479
|
+
);
|
|
1075
1480
|
|
|
1076
1481
|
if (initVaultDepositor) {
|
|
1077
1482
|
await this.initializeVaultDepositor(
|
|
@@ -1079,7 +1484,7 @@ export class VaultClient {
|
|
|
1079
1484
|
initVaultDepositor.authority
|
|
1080
1485
|
);
|
|
1081
1486
|
}
|
|
1082
|
-
return
|
|
1487
|
+
return this.program.methods
|
|
1083
1488
|
.deposit(amount)
|
|
1084
1489
|
.accounts(accounts)
|
|
1085
1490
|
.remainingAccounts(remainingAccounts)
|
|
@@ -1278,6 +1683,13 @@ export class VaultClient {
|
|
|
1278
1683
|
public async forceWithdraw(
|
|
1279
1684
|
vaultDepositor: PublicKey
|
|
1280
1685
|
): Promise<TransactionSignature> {
|
|
1686
|
+
const ix = await this.getForceWithdrawIx(vaultDepositor);
|
|
1687
|
+
return await this.createAndSendTxn(ix);
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
public async getForceWithdrawIx(
|
|
1691
|
+
vaultDepositor: PublicKey
|
|
1692
|
+
): Promise<TransactionInstruction[]> {
|
|
1281
1693
|
const vaultDepositorAccount =
|
|
1282
1694
|
await this.program.account.vaultDepositor.fetch(vaultDepositor);
|
|
1283
1695
|
const vaultAccount = await this.program.account.vault.fetch(
|
|
@@ -1316,6 +1728,20 @@ export class VaultClient {
|
|
|
1316
1728
|
);
|
|
1317
1729
|
}
|
|
1318
1730
|
|
|
1731
|
+
const [userTokenAccount, createAtaIx] = await getOrCreateATAInstruction(
|
|
1732
|
+
spotMarket.mint,
|
|
1733
|
+
vaultDepositorAccount.authority,
|
|
1734
|
+
this.driftClient.connection,
|
|
1735
|
+
true,
|
|
1736
|
+
this.driftClient.wallet.publicKey
|
|
1737
|
+
);
|
|
1738
|
+
|
|
1739
|
+
if (createAtaIx) {
|
|
1740
|
+
console.log(
|
|
1741
|
+
`Creating ATA for ${vaultDepositorAccount.authority.toBase58()} to ${userTokenAccount.toBase58()}`
|
|
1742
|
+
);
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1319
1745
|
const accounts = {
|
|
1320
1746
|
manager: this.driftClient.wallet.publicKey,
|
|
1321
1747
|
vault: vaultDepositorAccount.vault,
|
|
@@ -1326,38 +1752,26 @@ export class VaultClient {
|
|
|
1326
1752
|
driftState: driftStateKey,
|
|
1327
1753
|
driftSpotMarketVault: spotMarket.vault,
|
|
1328
1754
|
driftSigner: this.driftClient.getStateAccount().signer,
|
|
1329
|
-
userTokenAccount
|
|
1330
|
-
spotMarket.mint,
|
|
1331
|
-
vaultDepositorAccount.authority,
|
|
1332
|
-
true
|
|
1333
|
-
),
|
|
1755
|
+
userTokenAccount,
|
|
1334
1756
|
driftProgram: this.driftClient.program.programId,
|
|
1335
1757
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
1336
1758
|
};
|
|
1337
1759
|
|
|
1338
|
-
|
|
1339
|
-
|
|
1760
|
+
const ixs = [];
|
|
1761
|
+
|
|
1762
|
+
if (createAtaIx) {
|
|
1763
|
+
ixs.push(createAtaIx);
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
ixs.push(
|
|
1767
|
+
await this.program.methods
|
|
1340
1768
|
.forceWithdraw()
|
|
1341
|
-
.preInstructions([
|
|
1342
|
-
ComputeBudgetProgram.setComputeUnitLimit({
|
|
1343
|
-
units: 500_000,
|
|
1344
|
-
}),
|
|
1345
|
-
ComputeBudgetProgram.setComputeUnitPrice({
|
|
1346
|
-
microLamports: 50_000,
|
|
1347
|
-
}),
|
|
1348
|
-
])
|
|
1349
1769
|
.accounts(accounts)
|
|
1350
1770
|
.remainingAccounts(remainingAccounts)
|
|
1351
|
-
.
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
...accounts,
|
|
1356
|
-
},
|
|
1357
|
-
remainingAccounts,
|
|
1358
|
-
});
|
|
1359
|
-
return await this.createAndSendTxn([forceWithdrawIx]);
|
|
1360
|
-
}
|
|
1771
|
+
.instruction()
|
|
1772
|
+
);
|
|
1773
|
+
|
|
1774
|
+
return ixs;
|
|
1361
1775
|
}
|
|
1362
1776
|
|
|
1363
1777
|
public async cancelRequestWithdraw(
|
|
@@ -1593,43 +2007,6 @@ export class VaultClient {
|
|
|
1593
2007
|
.rpc();
|
|
1594
2008
|
}
|
|
1595
2009
|
|
|
1596
|
-
/**
|
|
1597
|
-
* Initializes a DriftCompetitions Competitor account for the vault.
|
|
1598
|
-
* @param vault vault address to initialize Competitor for
|
|
1599
|
-
* @param competitionName name of the competition to initialize for
|
|
1600
|
-
* @returns
|
|
1601
|
-
*/
|
|
1602
|
-
public async initializeCompetitor(
|
|
1603
|
-
vault: PublicKey,
|
|
1604
|
-
competitionsClient: CompetitionsClient,
|
|
1605
|
-
competitionName: string
|
|
1606
|
-
): Promise<TransactionSignature> {
|
|
1607
|
-
const vaultAccount = await this.program.account.vault.fetch(vault);
|
|
1608
|
-
|
|
1609
|
-
const encodedName = encodeName(competitionName);
|
|
1610
|
-
|
|
1611
|
-
const competitionAddress = getCompetitionAddressSync(
|
|
1612
|
-
competitionsClient.program.programId,
|
|
1613
|
-
encodedName
|
|
1614
|
-
);
|
|
1615
|
-
const competitorAddress = getCompetitorAddressSync(
|
|
1616
|
-
competitionsClient.program.programId,
|
|
1617
|
-
competitionAddress,
|
|
1618
|
-
vault
|
|
1619
|
-
);
|
|
1620
|
-
|
|
1621
|
-
return await this.program.methods
|
|
1622
|
-
.initializeCompetitor()
|
|
1623
|
-
.accounts({
|
|
1624
|
-
vault: vault,
|
|
1625
|
-
competitor: competitorAddress,
|
|
1626
|
-
driftCompetitions: competitionAddress,
|
|
1627
|
-
driftUserStats: vaultAccount.userStats,
|
|
1628
|
-
driftCompetitionsProgram: competitionsClient.program.programId,
|
|
1629
|
-
})
|
|
1630
|
-
.rpc();
|
|
1631
|
-
}
|
|
1632
|
-
|
|
1633
2010
|
public async protocolRequestWithdraw(
|
|
1634
2011
|
vault: PublicKey,
|
|
1635
2012
|
amount: BN,
|