@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.
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  BN,
3
3
  DriftClient,
4
- encodeName,
5
4
  getInsuranceFundStakeAccountPublicKey,
6
5
  getUserAccountPublicKey,
7
6
  getUserAccountPublicKeySync,
@@ -10,15 +9,14 @@ import {
10
9
  UserMap,
11
10
  unstakeSharesToAmount as depositSharesToVaultAmount,
12
11
  ZERO,
12
+ getInsuranceFundVaultPublicKey,
13
13
  } from '@drift-labs/sdk';
14
14
  import { BorshAccountsCoder, Program, ProgramAccount } from '@coral-xyz/anchor';
15
15
  import { DriftVaults } from './types/drift_vaults';
16
16
  import {
17
- CompetitionsClient,
18
- getCompetitionAddressSync,
19
- getCompetitorAddressSync,
20
- } from '@drift-labs/competitions-sdk';
21
- import {
17
+ getTokenizedVaultAddressSync,
18
+ getTokenizedVaultMintAddressSync,
19
+ getInsuranceFundTokenVaultAddressSync,
22
20
  getTokenVaultAddressSync,
23
21
  getVaultAddressSync,
24
22
  getVaultDepositorAddressSync,
@@ -30,6 +28,7 @@ import {
30
28
  PublicKey,
31
29
  SystemProgram,
32
30
  SYSVAR_RENT_PUBKEY,
31
+ Transaction,
33
32
  TransactionInstruction,
34
33
  TransactionSignature,
35
34
  VersionedTransaction,
@@ -51,6 +50,8 @@ import {
51
50
  import { bs58 } from '@coral-xyz/anchor/dist/cjs/utils/bytes';
52
51
  import { UserMapConfig } from '@drift-labs/sdk';
53
52
  import { calculateRealizedVaultDepositorEquity } from './math';
53
+ import { Metaplex } from '@metaplex-foundation/js';
54
+ import { getOrCreateATAInstruction } from './utils';
54
55
 
55
56
  export type TxParams = {
56
57
  cuLimit?: number;
@@ -61,6 +62,7 @@ export type TxParams = {
61
62
 
62
63
  export class VaultClient {
63
64
  driftClient: DriftClient;
65
+ metaplex?: Metaplex;
64
66
  program: Program<DriftVaults>;
65
67
  cliMode: boolean;
66
68
 
@@ -72,15 +74,18 @@ export class VaultClient {
72
74
  constructor({
73
75
  driftClient,
74
76
  program,
77
+ metaplex,
75
78
  cliMode,
76
79
  userMapConfig,
77
80
  }: {
78
81
  driftClient: DriftClient;
79
82
  program: Program<DriftVaults>;
83
+ metaplex?: Metaplex;
80
84
  cliMode?: boolean;
81
85
  userMapConfig?: UserMapConfig;
82
86
  }) {
83
87
  this.driftClient = driftClient;
88
+ this.metaplex = metaplex;
84
89
  this.program = program;
85
90
  this.cliMode = !!cliMode;
86
91
 
@@ -876,6 +881,111 @@ export class VaultClient {
876
881
  });
877
882
  }
878
883
 
884
+ public async getApplyRebaseTokenizedDepositorIx(
885
+ vault: PublicKey,
886
+ tokenizedVaultDepositor: PublicKey
887
+ ): Promise<TransactionInstruction> {
888
+ const vaultAccount = await this.program.account.vault.fetch(vault);
889
+
890
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
891
+
892
+ const spotMarket = this.driftClient.getSpotMarketAccount(
893
+ vaultAccount.spotMarketIndex
894
+ );
895
+ if (!spotMarket) {
896
+ throw new Error(
897
+ `Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`
898
+ );
899
+ }
900
+
901
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
902
+ userAccounts: [user.getUserAccount()],
903
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
904
+ });
905
+
906
+ const accounts = {
907
+ vault,
908
+ tokenizedVaultDepositor,
909
+ driftUser: await getUserAccountPublicKey(
910
+ this.driftClient.program.programId,
911
+ vault
912
+ ),
913
+ driftState: await this.driftClient.getStatePublicKey(),
914
+ driftSigner: this.driftClient.getStateAccount().signer,
915
+ driftProgram: this.driftClient.program.programId,
916
+ };
917
+
918
+ return this.program.instruction.applyRebaseTokenizedDepositor({
919
+ accounts: {
920
+ ...accounts,
921
+ },
922
+ remainingAccounts,
923
+ });
924
+ }
925
+
926
+ public async applyRebase(
927
+ vault: PublicKey,
928
+ vaultDepositor: PublicKey
929
+ ): Promise<TransactionSignature> {
930
+ return await this.createAndSendTxn([
931
+ await this.getApplyRebaseIx(vault, vaultDepositor),
932
+ ]);
933
+ }
934
+
935
+ public async getApplyRebaseIx(
936
+ vault: PublicKey,
937
+ vaultDepositor: PublicKey
938
+ ): Promise<TransactionInstruction> {
939
+ const vaultAccount = await this.program.account.vault.fetch(vault);
940
+
941
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
942
+
943
+ const spotMarket = this.driftClient.getSpotMarketAccount(
944
+ vaultAccount.spotMarketIndex
945
+ );
946
+ if (!spotMarket) {
947
+ throw new Error(
948
+ `Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`
949
+ );
950
+ }
951
+
952
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
953
+ userAccounts: [user.getUserAccount()],
954
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
955
+ });
956
+
957
+ const accounts = {
958
+ vault,
959
+ vaultDepositor,
960
+ driftUser: await getUserAccountPublicKey(
961
+ this.driftClient.program.programId,
962
+ vault
963
+ ),
964
+ driftState: await this.driftClient.getStatePublicKey(),
965
+ driftSigner: this.driftClient.getStateAccount().signer,
966
+ driftProgram: this.driftClient.program.programId,
967
+ };
968
+
969
+ return this.program.instruction.applyRebase({
970
+ accounts: {
971
+ ...accounts,
972
+ },
973
+ remainingAccounts,
974
+ });
975
+ }
976
+
977
+ public async applyRebaseTokenizedDepositor(
978
+ vault: PublicKey,
979
+ tokenizedVaultDepositor: PublicKey
980
+ ): Promise<TransactionSignature> {
981
+ return await this.createAndSendTxn([
982
+ await this.getApplyRebaseTokenizedDepositorIx(
983
+ vault,
984
+ tokenizedVaultDepositor
985
+ ),
986
+ ]);
987
+ }
988
+
879
989
  private createInitVaultDepositorIx(vault: PublicKey, authority?: PublicKey) {
880
990
  const vaultDepositor = getVaultDepositorAddressSync(
881
991
  this.program.programId,
@@ -924,9 +1034,14 @@ export class VaultClient {
924
1034
  };
925
1035
 
926
1036
  if (this.cliMode) {
927
- return await this.program.methods
1037
+ return this.program.methods
928
1038
  .initializeVaultDepositor()
929
- .accounts(accounts)
1039
+ .accounts({
1040
+ ...accounts,
1041
+ payer: authority || this.driftClient.wallet.publicKey,
1042
+ rent: SYSVAR_RENT_PUBKEY,
1043
+ systemProgram: SystemProgram.programId,
1044
+ })
930
1045
  .rpc();
931
1046
  } else {
932
1047
  const initIx = this.createInitVaultDepositorIx(vault, authority);
@@ -934,13 +1049,297 @@ export class VaultClient {
934
1049
  }
935
1050
  }
936
1051
 
1052
+ public async initializeTokenizedVaultDepositor(params: {
1053
+ vault: PublicKey;
1054
+ tokenName: string;
1055
+ tokenSymbol: string;
1056
+ tokenUri: string;
1057
+ decimals?: number;
1058
+ sharesBase?: number;
1059
+ }): Promise<TransactionSignature> {
1060
+ if (!this.metaplex) {
1061
+ throw new Error(
1062
+ 'Metaplex instance is required when constructing VaultClient to initialize a tokenized vault depositor'
1063
+ );
1064
+ }
1065
+
1066
+ let spotMarketDecimals = 6;
1067
+ let sharesBase = 0;
1068
+ if (params.decimals === undefined || params.sharesBase === undefined) {
1069
+ const vault = await this.program.account.vault.fetch(params.vault);
1070
+ const spotMarketAccount = this.driftClient.getSpotMarketAccount(
1071
+ vault.spotMarketIndex
1072
+ );
1073
+ if (!spotMarketAccount) {
1074
+ throw new Error(
1075
+ `DriftClient failed to load vault's spot market (marketIndex: ${vault.spotMarketIndex})`
1076
+ );
1077
+ }
1078
+ spotMarketDecimals = spotMarketAccount.decimals;
1079
+ sharesBase = vault.sharesBase;
1080
+ }
1081
+
1082
+ const mintAddress = getTokenizedVaultMintAddressSync(
1083
+ this.program.programId,
1084
+ params.vault,
1085
+ sharesBase
1086
+ );
1087
+
1088
+ const accounts = {
1089
+ vault: params.vault,
1090
+ vaultDepositor: getTokenizedVaultAddressSync(
1091
+ this.program.programId,
1092
+ params.vault,
1093
+ sharesBase
1094
+ ),
1095
+ mintAccount: mintAddress,
1096
+ metadataAccount: this.metaplex.nfts().pdas().metadata({
1097
+ mint: mintAddress,
1098
+ }),
1099
+ tokenMetadataProgram: this.metaplex.programs().getTokenMetadata().address,
1100
+ payer: this.driftClient.wallet.publicKey,
1101
+ };
1102
+
1103
+ const vaultTokenAta = getAssociatedTokenAddressSync(
1104
+ mintAddress,
1105
+ params.vault,
1106
+ true
1107
+ );
1108
+ const createAtaIx = createAssociatedTokenAccountInstruction(
1109
+ this.driftClient.wallet.publicKey,
1110
+ vaultTokenAta,
1111
+ params.vault,
1112
+ mintAddress
1113
+ );
1114
+
1115
+ if (!this.cliMode) {
1116
+ throw new Error(
1117
+ 'CLI mode is not supported for initializeTokenizedVaultDepositor'
1118
+ );
1119
+ }
1120
+ return await this.program.methods
1121
+ .initializeTokenizedVaultDepositor({
1122
+ ...params,
1123
+ decimals: params.decimals ?? spotMarketDecimals,
1124
+ })
1125
+ .preInstructions([
1126
+ ComputeBudgetProgram.setComputeUnitPrice({
1127
+ microLamports: 50_000,
1128
+ }),
1129
+ ])
1130
+ .postInstructions([createAtaIx])
1131
+ .accounts(accounts)
1132
+ .rpc();
1133
+ }
1134
+
1135
+ public async createTokenizeSharesIx(
1136
+ vaultDepositor: PublicKey,
1137
+ amount: BN,
1138
+ unit: WithdrawUnit,
1139
+ mint?: PublicKey
1140
+ ): Promise<TransactionInstruction[]> {
1141
+ const vaultDepositorAccount =
1142
+ await this.program.account.vaultDepositor.fetch(vaultDepositor);
1143
+ const vaultAccount = await this.program.account.vault.fetch(
1144
+ vaultDepositorAccount.vault
1145
+ );
1146
+
1147
+ mint =
1148
+ mint ??
1149
+ getTokenizedVaultMintAddressSync(
1150
+ this.program.programId,
1151
+ vaultDepositorAccount.vault,
1152
+ vaultAccount.sharesBase
1153
+ );
1154
+
1155
+ const userAta = getAssociatedTokenAddressSync(
1156
+ mint,
1157
+ this.driftClient.wallet.publicKey,
1158
+ true
1159
+ );
1160
+
1161
+ const ixs = [];
1162
+
1163
+ const userAtaExists = await this.driftClient.connection.getAccountInfo(
1164
+ userAta
1165
+ );
1166
+ if (userAtaExists === null) {
1167
+ ixs.push(
1168
+ createAssociatedTokenAccountInstruction(
1169
+ this.driftClient.wallet.publicKey,
1170
+ userAta,
1171
+ this.driftClient.wallet.publicKey,
1172
+ mint
1173
+ )
1174
+ );
1175
+ }
1176
+
1177
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1178
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
1179
+ userAccounts: [user.getUserAccount()],
1180
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
1181
+ });
1182
+
1183
+ ixs.push(
1184
+ await this.program.methods
1185
+ // anchor idl bug: https://github.com/coral-xyz/anchor/issues/2914
1186
+ // @ts-ignore
1187
+ .tokenizeShares(amount, unit)
1188
+ .accounts({
1189
+ authority: this.driftClient.wallet.publicKey,
1190
+ vault: vaultDepositorAccount.vault,
1191
+ vaultDepositor,
1192
+ tokenizedVaultDepositor: getTokenizedVaultAddressSync(
1193
+ this.program.programId,
1194
+ vaultDepositorAccount.vault,
1195
+ vaultAccount.sharesBase
1196
+ ),
1197
+ mint,
1198
+ userTokenAccount: userAta,
1199
+ driftUser: vaultAccount.user,
1200
+ tokenProgram: TOKEN_PROGRAM_ID,
1201
+ })
1202
+ .remainingAccounts(remainingAccounts)
1203
+ .instruction()
1204
+ );
1205
+
1206
+ return ixs;
1207
+ }
1208
+
1209
+ public async tokenizeShares(
1210
+ vaultDepositor: PublicKey,
1211
+ amount: BN,
1212
+ unit: WithdrawUnit,
1213
+ mint?: PublicKey,
1214
+ txParams?: TxParams
1215
+ ): Promise<TransactionSignature> {
1216
+ const ixs = await this.createTokenizeSharesIx(
1217
+ vaultDepositor,
1218
+ amount,
1219
+ unit,
1220
+ mint
1221
+ );
1222
+ if (this.cliMode) {
1223
+ try {
1224
+ const tx = new Transaction().add(...ixs);
1225
+ const txSig = await this.driftClient.txSender.send(
1226
+ tx,
1227
+ undefined,
1228
+ undefined,
1229
+ false
1230
+ );
1231
+ return txSig.txSig;
1232
+ } catch (e) {
1233
+ console.error(e);
1234
+ throw e;
1235
+ }
1236
+ } else {
1237
+ return await this.createAndSendTxn(ixs, txParams);
1238
+ }
1239
+ }
1240
+
1241
+ public async createRedeemTokensIx(
1242
+ vaultDepositor: PublicKey,
1243
+ tokensToBurn: BN,
1244
+ sharesBase?: number
1245
+ ): Promise<TransactionInstruction> {
1246
+ const vaultDepositorAccount =
1247
+ await this.program.account.vaultDepositor.fetch(vaultDepositor);
1248
+ const vaultAccount = await this.program.account.vault.fetch(
1249
+ vaultDepositorAccount.vault
1250
+ );
1251
+
1252
+ const mint = getTokenizedVaultMintAddressSync(
1253
+ this.program.programId,
1254
+ vaultDepositorAccount.vault,
1255
+ sharesBase ?? vaultAccount.sharesBase
1256
+ );
1257
+
1258
+ const userAta = getAssociatedTokenAddressSync(
1259
+ mint,
1260
+ this.driftClient.wallet.publicKey,
1261
+ true
1262
+ );
1263
+
1264
+ const vaultTokenAta = getAssociatedTokenAddressSync(
1265
+ mint,
1266
+ vaultDepositorAccount.vault,
1267
+ true
1268
+ );
1269
+
1270
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
1271
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
1272
+ userAccounts: [user.getUserAccount()],
1273
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
1274
+ });
1275
+
1276
+ return await this.program.methods
1277
+ .redeemTokens(tokensToBurn)
1278
+ .accounts({
1279
+ authority: this.driftClient.wallet.publicKey,
1280
+ vault: vaultDepositorAccount.vault,
1281
+ vaultDepositor,
1282
+ tokenizedVaultDepositor: getTokenizedVaultAddressSync(
1283
+ this.program.programId,
1284
+ vaultDepositorAccount.vault,
1285
+ sharesBase ?? vaultAccount.sharesBase
1286
+ ),
1287
+ mint,
1288
+ userTokenAccount: userAta,
1289
+ vaultTokenAccount: vaultTokenAta,
1290
+ driftUser: vaultAccount.user,
1291
+ tokenProgram: TOKEN_PROGRAM_ID,
1292
+ })
1293
+ .remainingAccounts(remainingAccounts)
1294
+ .instruction();
1295
+ }
1296
+
1297
+ /**
1298
+ * Redeems tokens from the vault.
1299
+ * @param vaultDepositor
1300
+ * @param tokensToBurn
1301
+ * @param mint optionally provide a mint, or infer the mint from the current vault share base
1302
+ * @param txParams
1303
+ * @returns
1304
+ */
1305
+ public async redeemTokens(
1306
+ vaultDepositor: PublicKey,
1307
+ tokensToBurn: BN,
1308
+ sharesBase?: number,
1309
+ txParams?: TxParams
1310
+ ): Promise<TransactionSignature> {
1311
+ const ix = await this.createRedeemTokensIx(
1312
+ vaultDepositor,
1313
+ tokensToBurn,
1314
+ sharesBase
1315
+ );
1316
+ if (this.cliMode) {
1317
+ try {
1318
+ const tx = new Transaction().add(ix);
1319
+ const txSig = await this.driftClient.txSender.send(
1320
+ tx,
1321
+ undefined,
1322
+ undefined,
1323
+ false
1324
+ );
1325
+ return txSig.txSig;
1326
+ } catch (e) {
1327
+ console.error(e);
1328
+ throw e;
1329
+ }
1330
+ } else {
1331
+ return await this.createAndSendTxn([ix], txParams);
1332
+ }
1333
+ }
1334
+
937
1335
  public async prepDepositTx(
938
1336
  vaultDepositor: PublicKey,
939
1337
  amount: BN,
940
1338
  initVaultDepositor?: {
941
1339
  authority: PublicKey;
942
1340
  vault: PublicKey;
943
- }
1341
+ },
1342
+ userTokenAccount?: PublicKey
944
1343
  ) {
945
1344
  let vaultPubKey: PublicKey;
946
1345
  if (initVaultDepositor) {
@@ -991,11 +1390,13 @@ export class VaultClient {
991
1390
  driftUser: vaultAccount.user,
992
1391
  driftState: driftStateKey,
993
1392
  driftSpotMarketVault: spotMarket.vault,
994
- userTokenAccount: getAssociatedTokenAddressSync(
995
- spotMarket.mint,
996
- this.driftClient.wallet.publicKey,
997
- true
998
- ),
1393
+ userTokenAccount:
1394
+ userTokenAccount ??
1395
+ getAssociatedTokenAddressSync(
1396
+ spotMarket.mint,
1397
+ this.driftClient.wallet.publicKey,
1398
+ true
1399
+ ),
999
1400
  driftProgram: this.driftClient.program.programId,
1000
1401
  tokenProgram: TOKEN_PROGRAM_ID,
1001
1402
  };
@@ -1067,11 +1468,17 @@ export class VaultClient {
1067
1468
  authority: PublicKey;
1068
1469
  vault: PublicKey;
1069
1470
  },
1070
- txParams?: TxParams
1471
+ txParams?: TxParams,
1472
+ userTokenAccount?: PublicKey
1071
1473
  ): Promise<TransactionSignature> {
1072
1474
  if (this.cliMode) {
1073
1475
  const { vaultAccount, accounts, remainingAccounts } =
1074
- await this.prepDepositTx(vaultDepositor, amount, initVaultDepositor);
1476
+ await this.prepDepositTx(
1477
+ vaultDepositor,
1478
+ amount,
1479
+ initVaultDepositor,
1480
+ userTokenAccount
1481
+ );
1075
1482
 
1076
1483
  if (initVaultDepositor) {
1077
1484
  await this.initializeVaultDepositor(
@@ -1079,7 +1486,7 @@ export class VaultClient {
1079
1486
  initVaultDepositor.authority
1080
1487
  );
1081
1488
  }
1082
- return await this.program.methods
1489
+ return this.program.methods
1083
1490
  .deposit(amount)
1084
1491
  .accounts(accounts)
1085
1492
  .remainingAccounts(remainingAccounts)
@@ -1278,6 +1685,13 @@ export class VaultClient {
1278
1685
  public async forceWithdraw(
1279
1686
  vaultDepositor: PublicKey
1280
1687
  ): Promise<TransactionSignature> {
1688
+ const ix = await this.getForceWithdrawIx(vaultDepositor);
1689
+ return await this.createAndSendTxn(ix);
1690
+ }
1691
+
1692
+ public async getForceWithdrawIx(
1693
+ vaultDepositor: PublicKey
1694
+ ): Promise<TransactionInstruction[]> {
1281
1695
  const vaultDepositorAccount =
1282
1696
  await this.program.account.vaultDepositor.fetch(vaultDepositor);
1283
1697
  const vaultAccount = await this.program.account.vault.fetch(
@@ -1316,6 +1730,20 @@ export class VaultClient {
1316
1730
  );
1317
1731
  }
1318
1732
 
1733
+ const [userTokenAccount, createAtaIx] = await getOrCreateATAInstruction(
1734
+ spotMarket.mint,
1735
+ vaultDepositorAccount.authority,
1736
+ this.driftClient.connection,
1737
+ true,
1738
+ this.driftClient.wallet.publicKey
1739
+ );
1740
+
1741
+ if (createAtaIx) {
1742
+ console.log(
1743
+ `Creating ATA for ${vaultDepositorAccount.authority.toBase58()} to ${userTokenAccount.toBase58()}`
1744
+ );
1745
+ }
1746
+
1319
1747
  const accounts = {
1320
1748
  manager: this.driftClient.wallet.publicKey,
1321
1749
  vault: vaultDepositorAccount.vault,
@@ -1326,38 +1754,26 @@ export class VaultClient {
1326
1754
  driftState: driftStateKey,
1327
1755
  driftSpotMarketVault: spotMarket.vault,
1328
1756
  driftSigner: this.driftClient.getStateAccount().signer,
1329
- userTokenAccount: getAssociatedTokenAddressSync(
1330
- spotMarket.mint,
1331
- vaultDepositorAccount.authority,
1332
- true
1333
- ),
1757
+ userTokenAccount,
1334
1758
  driftProgram: this.driftClient.program.programId,
1335
1759
  tokenProgram: TOKEN_PROGRAM_ID,
1336
1760
  };
1337
1761
 
1338
- if (this.cliMode) {
1339
- return await this.program.methods
1762
+ const ixs = [];
1763
+
1764
+ if (createAtaIx) {
1765
+ ixs.push(createAtaIx);
1766
+ }
1767
+
1768
+ ixs.push(
1769
+ await this.program.methods
1340
1770
  .forceWithdraw()
1341
- .preInstructions([
1342
- ComputeBudgetProgram.setComputeUnitLimit({
1343
- units: 500_000,
1344
- }),
1345
- ComputeBudgetProgram.setComputeUnitPrice({
1346
- microLamports: 50_000,
1347
- }),
1348
- ])
1349
1771
  .accounts(accounts)
1350
1772
  .remainingAccounts(remainingAccounts)
1351
- .rpc();
1352
- } else {
1353
- const forceWithdrawIx = this.program.instruction.forceWithdraw({
1354
- accounts: {
1355
- ...accounts,
1356
- },
1357
- remainingAccounts,
1358
- });
1359
- return await this.createAndSendTxn([forceWithdrawIx]);
1360
- }
1773
+ .instruction()
1774
+ );
1775
+
1776
+ return ixs;
1361
1777
  }
1362
1778
 
1363
1779
  public async cancelRequestWithdraw(
@@ -1580,11 +1996,19 @@ export class VaultClient {
1580
1996
  );
1581
1997
  }
1582
1998
 
1999
+ const ifVaultTokenAccount = getInsuranceFundTokenVaultAddressSync(
2000
+ this.program.programId,
2001
+ vault,
2002
+ spotMarketIndex
2003
+ );
2004
+
1583
2005
  return await this.program.methods
1584
2006
  .initializeInsuranceFundStake(spotMarketIndex)
1585
2007
  .accounts({
1586
2008
  vault: vault,
1587
2009
  driftSpotMarket: spotMarket.pubkey,
2010
+ driftSpotMarketMint: spotMarket.mint,
2011
+ vaultTokenAccount: ifVaultTokenAccount,
1588
2012
  insuranceFundStake: ifStakeAccountPublicKey,
1589
2013
  driftUserStats: vaultAccount.userStats,
1590
2014
  driftState: await this.driftClient.getStatePublicKey(),
@@ -1594,38 +2018,196 @@ export class VaultClient {
1594
2018
  }
1595
2019
 
1596
2020
  /**
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
2021
+ * Adds an amount to an insurance fund stake for the vault.
2022
+ * @param vault vault address to update
2023
+ * @param spotMarketIndex spot market index of the insurance fund stake
2024
+ * @param amount amount to add to the insurance fund stake, in spotMarketIndex precision
1600
2025
  * @returns
1601
2026
  */
1602
- public async initializeCompetitor(
2027
+ public async addToInsuranceFundStake(
1603
2028
  vault: PublicKey,
1604
- competitionsClient: CompetitionsClient,
1605
- competitionName: string
2029
+ spotMarketIndex: number,
2030
+ amount: BN,
2031
+ managerTokenAccount?: PublicKey
1606
2032
  ): Promise<TransactionSignature> {
1607
2033
  const vaultAccount = await this.program.account.vault.fetch(vault);
1608
2034
 
1609
- const encodedName = encodeName(competitionName);
2035
+ if (!vaultAccount.manager.equals(this.driftClient.wallet.publicKey)) {
2036
+ throw new Error(
2037
+ `Only the manager of the vault can add to the insurance fund stake.`
2038
+ );
2039
+ }
1610
2040
 
1611
- const competitionAddress = getCompetitionAddressSync(
1612
- competitionsClient.program.programId,
1613
- encodedName
2041
+ const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
2042
+ this.driftClient.program.programId,
2043
+ vault,
2044
+ spotMarketIndex
1614
2045
  );
1615
- const competitorAddress = getCompetitorAddressSync(
1616
- competitionsClient.program.programId,
1617
- competitionAddress,
1618
- vault
2046
+ const ifVaultPublicKey = await getInsuranceFundVaultPublicKey(
2047
+ this.driftClient.program.programId,
2048
+ spotMarketIndex
2049
+ );
2050
+
2051
+ const spotMarket = this.driftClient.getSpotMarketAccount(spotMarketIndex);
2052
+ if (!spotMarket) {
2053
+ throw new Error(
2054
+ `Spot market ${spotMarketIndex} not found on driftClient`
2055
+ );
2056
+ }
2057
+
2058
+ if (!managerTokenAccount) {
2059
+ managerTokenAccount = getAssociatedTokenAddressSync(
2060
+ spotMarket.mint,
2061
+ this.driftClient.wallet.publicKey
2062
+ );
2063
+ }
2064
+
2065
+ const ifVaultTokenAccount = getInsuranceFundTokenVaultAddressSync(
2066
+ this.program.programId,
2067
+ vault,
2068
+ spotMarketIndex
1619
2069
  );
1620
2070
 
1621
2071
  return await this.program.methods
1622
- .initializeCompetitor()
2072
+ .addInsuranceFundStake(spotMarketIndex, amount)
1623
2073
  .accounts({
1624
2074
  vault: vault,
1625
- competitor: competitorAddress,
1626
- driftCompetitions: competitionAddress,
2075
+ driftSpotMarket: spotMarket.pubkey,
2076
+ driftSpotMarketVault: spotMarket.vault,
2077
+ insuranceFundStake: ifStakeAccountPublicKey,
2078
+ insuranceFundVault: ifVaultPublicKey,
2079
+ managerTokenAccount,
2080
+ vaultIfTokenAccount: ifVaultTokenAccount,
1627
2081
  driftUserStats: vaultAccount.userStats,
1628
- driftCompetitionsProgram: competitionsClient.program.programId,
2082
+ driftState: await this.driftClient.getStatePublicKey(),
2083
+ driftProgram: this.driftClient.program.programId,
2084
+ driftSigner: this.driftClient.getStateAccount().signer,
2085
+ tokenProgram: TOKEN_PROGRAM_ID,
2086
+ })
2087
+ .rpc();
2088
+ }
2089
+
2090
+ public async requestRemoveInsuranceFundStake(
2091
+ vault: PublicKey,
2092
+ spotMarketIndex: number,
2093
+ amount: BN
2094
+ ): Promise<TransactionSignature> {
2095
+ const vaultAccount = await this.program.account.vault.fetch(vault);
2096
+ const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
2097
+ this.driftClient.program.programId,
2098
+ vault,
2099
+ spotMarketIndex
2100
+ );
2101
+ const ifVaultPublicKey = await getInsuranceFundVaultPublicKey(
2102
+ this.driftClient.program.programId,
2103
+ spotMarketIndex
2104
+ );
2105
+
2106
+ const spotMarket = this.driftClient.getSpotMarketAccount(spotMarketIndex);
2107
+ if (!spotMarket) {
2108
+ throw new Error(
2109
+ `Spot market ${spotMarketIndex} not found on driftClient`
2110
+ );
2111
+ }
2112
+
2113
+ return await this.program.methods
2114
+ .requestRemoveInsuranceFundStake(spotMarketIndex, amount)
2115
+ .accounts({
2116
+ vault,
2117
+ manager: this.driftClient.wallet.publicKey,
2118
+ driftSpotMarket: spotMarket.pubkey,
2119
+ insuranceFundStake: ifStakeAccountPublicKey,
2120
+ insuranceFundVault: ifVaultPublicKey,
2121
+ driftUserStats: vaultAccount.userStats,
2122
+ driftProgram: this.driftClient.program.programId,
2123
+ })
2124
+ .rpc();
2125
+ }
2126
+
2127
+ public async cancelRequestRemoveInsuranceFundStake(
2128
+ vault: PublicKey,
2129
+ spotMarketIndex: number
2130
+ ): Promise<TransactionSignature> {
2131
+ const vaultAccount = await this.program.account.vault.fetch(vault);
2132
+ const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
2133
+ this.driftClient.program.programId,
2134
+ vault,
2135
+ spotMarketIndex
2136
+ );
2137
+ const ifVaultPublicKey = await getInsuranceFundVaultPublicKey(
2138
+ this.driftClient.program.programId,
2139
+ spotMarketIndex
2140
+ );
2141
+ const spotMarket = this.driftClient.getSpotMarketAccount(spotMarketIndex);
2142
+ if (!spotMarket) {
2143
+ throw new Error(
2144
+ `Spot market ${spotMarketIndex} not found on driftClient`
2145
+ );
2146
+ }
2147
+
2148
+ return await this.program.methods
2149
+ .cancelRequestRemoveInsuranceFundStake(spotMarketIndex)
2150
+ .accounts({
2151
+ vault: vault,
2152
+ manager: this.driftClient.wallet.publicKey,
2153
+ driftSpotMarket: spotMarket.pubkey,
2154
+ insuranceFundStake: ifStakeAccountPublicKey,
2155
+ insuranceFundVault: ifVaultPublicKey,
2156
+ driftUserStats: vaultAccount.userStats,
2157
+ driftProgram: this.driftClient.program.programId,
2158
+ })
2159
+ .rpc();
2160
+ }
2161
+
2162
+ public async removeInsuranceFundStake(
2163
+ vault: PublicKey,
2164
+ spotMarketIndex: number,
2165
+ managerTokenAccount?: PublicKey
2166
+ ): Promise<TransactionSignature> {
2167
+ const vaultAccount = await this.program.account.vault.fetch(vault);
2168
+ const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
2169
+ this.driftClient.program.programId,
2170
+ vault,
2171
+ spotMarketIndex
2172
+ );
2173
+ const ifVaultPublicKey = await getInsuranceFundVaultPublicKey(
2174
+ this.driftClient.program.programId,
2175
+ spotMarketIndex
2176
+ );
2177
+ const spotMarket = this.driftClient.getSpotMarketAccount(spotMarketIndex);
2178
+ if (!spotMarket) {
2179
+ throw new Error(
2180
+ `Spot market ${spotMarketIndex} not found on driftClient`
2181
+ );
2182
+ }
2183
+
2184
+ if (!managerTokenAccount) {
2185
+ managerTokenAccount = getAssociatedTokenAddressSync(
2186
+ spotMarket.mint,
2187
+ this.driftClient.wallet.publicKey
2188
+ );
2189
+ }
2190
+
2191
+ const ifVaultTokenAccount = getInsuranceFundTokenVaultAddressSync(
2192
+ this.program.programId,
2193
+ vault,
2194
+ spotMarketIndex
2195
+ );
2196
+
2197
+ return await this.program.methods
2198
+ .removeInsuranceFundStake(spotMarketIndex)
2199
+ .accounts({
2200
+ vault: vault,
2201
+ driftSpotMarket: spotMarket.pubkey,
2202
+ insuranceFundStake: ifStakeAccountPublicKey,
2203
+ insuranceFundVault: ifVaultPublicKey,
2204
+ managerTokenAccount,
2205
+ vaultIfTokenAccount: ifVaultTokenAccount,
2206
+ driftState: await this.driftClient.getStatePublicKey(),
2207
+ driftUserStats: vaultAccount.userStats,
2208
+ driftSigner: this.driftClient.getStateAccount().signer,
2209
+ driftProgram: this.driftClient.program.programId,
2210
+ tokenProgram: TOKEN_PROGRAM_ID,
1629
2211
  })
1630
2212
  .rpc();
1631
2213
  }