@drift-labs/sdk 2.31.1-beta.9 → 2.32.1-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +1 -1
- package/lib/constants/perpMarkets.js +20 -0
- package/lib/dlob/orderBookLevels.js +2 -2
- package/lib/driftClient.d.ts +51 -4
- package/lib/driftClient.js +195 -194
- package/lib/idl/drift.json +31 -1
- package/lib/index.d.ts +3 -0
- package/lib/index.js +3 -0
- package/lib/marinade/index.d.ts +11 -0
- package/lib/marinade/index.js +36 -0
- package/lib/marinade/types.d.ts +1963 -0
- package/lib/marinade/types.js +1965 -0
- package/lib/math/spotBalance.d.ts +9 -2
- package/lib/math/spotBalance.js +54 -6
- package/lib/math/superStake.d.ts +22 -0
- package/lib/math/superStake.js +108 -0
- package/lib/math/utils.d.ts +1 -0
- package/lib/math/utils.js +5 -1
- package/lib/orderParams.d.ts +18 -5
- package/lib/orderParams.js +17 -1
- package/lib/user.d.ts +45 -1
- package/lib/user.js +227 -9
- package/package.json +1 -1
- package/src/constants/perpMarkets.ts +20 -0
- package/src/dlob/orderBookLevels.ts +3 -2
- package/src/driftClient.ts +373 -223
- package/src/idl/drift.json +31 -1
- package/src/index.ts +3 -0
- package/src/marinade/idl/idl.json +1962 -0
- package/src/marinade/index.ts +64 -0
- package/src/marinade/types.ts +3925 -0
- package/src/math/spotBalance.ts +83 -5
- package/src/math/superStake.ts +148 -0
- package/src/math/utils.ts +4 -0
- package/src/orderParams.ts +35 -5
- package/src/user.ts +453 -15
- package/tests/spot/test.ts +156 -0
package/src/driftClient.ts
CHANGED
|
@@ -27,7 +27,6 @@ import {
|
|
|
27
27
|
MakerInfo,
|
|
28
28
|
TakerInfo,
|
|
29
29
|
OptionalOrderParams,
|
|
30
|
-
DefaultOrderParams,
|
|
31
30
|
OrderType,
|
|
32
31
|
ReferrerInfo,
|
|
33
32
|
MarketType,
|
|
@@ -117,12 +116,14 @@ import { castNumberToSpotPrecision } from './math/spotMarket';
|
|
|
117
116
|
import { JupiterClient, Route, SwapMode } from './jupiter/jupiterClient';
|
|
118
117
|
import { getNonIdleUserFilter } from './memcmp';
|
|
119
118
|
import { UserStatsSubscriptionConfig } from './userStatsConfig';
|
|
119
|
+
import { getMarinadeDepositIx, getMarinadeFinanceProgram } from './marinade';
|
|
120
|
+
import { getOrderParams } from './orderParams';
|
|
120
121
|
|
|
121
122
|
type RemainingAccountParams = {
|
|
122
123
|
userAccounts: UserAccount[];
|
|
123
124
|
writablePerpMarketIndexes?: number[];
|
|
124
125
|
writableSpotMarketIndexes?: number[];
|
|
125
|
-
readablePerpMarketIndex?: number;
|
|
126
|
+
readablePerpMarketIndex?: number | number[];
|
|
126
127
|
readableSpotMarketIndexes?: number[];
|
|
127
128
|
useMarketLastSlotCache?: boolean;
|
|
128
129
|
};
|
|
@@ -148,6 +149,8 @@ export class DriftClient {
|
|
|
148
149
|
txSender: TxSender;
|
|
149
150
|
perpMarketLastSlotCache = new Map<number, number>();
|
|
150
151
|
spotMarketLastSlotCache = new Map<number, number>();
|
|
152
|
+
mustIncludePerpMarketIndexes = new Set<number>();
|
|
153
|
+
mustIncludeSpotMarketIndexes = new Set<number>();
|
|
151
154
|
authority: PublicKey;
|
|
152
155
|
marketLookupTable: PublicKey;
|
|
153
156
|
lookupTableAccount: AddressLookupTableAccount;
|
|
@@ -860,6 +863,43 @@ export class DriftClient {
|
|
|
860
863
|
return txSig;
|
|
861
864
|
}
|
|
862
865
|
|
|
866
|
+
public async getUpdateUserMarginTradingEnabledIx(
|
|
867
|
+
marginTradingEnabled: boolean,
|
|
868
|
+
subAccountId = 0,
|
|
869
|
+
userAccountPublicKey?: PublicKey
|
|
870
|
+
): Promise<TransactionInstruction> {
|
|
871
|
+
const userAccountPublicKeyToUse =
|
|
872
|
+
userAccountPublicKey ||
|
|
873
|
+
getUserAccountPublicKeySync(
|
|
874
|
+
this.program.programId,
|
|
875
|
+
this.wallet.publicKey,
|
|
876
|
+
subAccountId
|
|
877
|
+
);
|
|
878
|
+
|
|
879
|
+
await this.addUser(subAccountId, this.wallet.publicKey);
|
|
880
|
+
|
|
881
|
+
let remainingAccounts;
|
|
882
|
+
try {
|
|
883
|
+
remainingAccounts = this.getRemainingAccounts({
|
|
884
|
+
userAccounts: [this.getUserAccount(subAccountId)],
|
|
885
|
+
});
|
|
886
|
+
} catch (err) {
|
|
887
|
+
remainingAccounts = [];
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
return await this.program.instruction.updateUserMarginTradingEnabled(
|
|
891
|
+
subAccountId,
|
|
892
|
+
marginTradingEnabled,
|
|
893
|
+
{
|
|
894
|
+
accounts: {
|
|
895
|
+
user: userAccountPublicKeyToUse,
|
|
896
|
+
authority: this.wallet.publicKey,
|
|
897
|
+
},
|
|
898
|
+
remainingAccounts,
|
|
899
|
+
}
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
|
|
863
903
|
public async updateUserMarginTradingEnabled(
|
|
864
904
|
marginTradingEnabled: boolean,
|
|
865
905
|
subAccountId = 0
|
|
@@ -1197,6 +1237,29 @@ export class DriftClient {
|
|
|
1197
1237
|
return amount.mul(PRICE_PRECISION);
|
|
1198
1238
|
}
|
|
1199
1239
|
|
|
1240
|
+
/**
|
|
1241
|
+
* Each drift instruction must include perp and sport market accounts in the ix remaining accounts.
|
|
1242
|
+
* Use this function to force a subset of markets to be included in the remaining accounts for every ix
|
|
1243
|
+
*
|
|
1244
|
+
* @param perpMarketIndexes
|
|
1245
|
+
* @param spotMarketIndexes
|
|
1246
|
+
*/
|
|
1247
|
+
public mustIncludeMarketsInIx({
|
|
1248
|
+
perpMarketIndexes,
|
|
1249
|
+
spotMarketIndexes,
|
|
1250
|
+
}: {
|
|
1251
|
+
perpMarketIndexes: number[];
|
|
1252
|
+
spotMarketIndexes: number[];
|
|
1253
|
+
}): void {
|
|
1254
|
+
perpMarketIndexes.forEach((perpMarketIndex) => {
|
|
1255
|
+
this.mustIncludePerpMarketIndexes.add(perpMarketIndex);
|
|
1256
|
+
});
|
|
1257
|
+
|
|
1258
|
+
spotMarketIndexes.forEach((spotMarketIndex) => {
|
|
1259
|
+
this.mustIncludeSpotMarketIndexes.add(spotMarketIndex);
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1200
1263
|
getRemainingAccounts(params: RemainingAccountParams): AccountMeta[] {
|
|
1201
1264
|
const { oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap } =
|
|
1202
1265
|
this.getRemainingAccountMapsForUsers(params.userAccounts);
|
|
@@ -1210,32 +1273,13 @@ export class DriftClient {
|
|
|
1210
1273
|
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
1211
1274
|
// otherwise remove from slot
|
|
1212
1275
|
if (slot > lastUserSlot) {
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
1220
|
-
pubkey: perpMarketAccount.amm.oracle,
|
|
1221
|
-
isSigner: false,
|
|
1222
|
-
isWritable: false,
|
|
1223
|
-
});
|
|
1224
|
-
const spotMarketAccount = this.getSpotMarketAccount(
|
|
1225
|
-
perpMarketAccount.quoteSpotMarketIndex
|
|
1276
|
+
this.addPerpMarketToRemainingAccountMaps(
|
|
1277
|
+
marketIndex,
|
|
1278
|
+
false,
|
|
1279
|
+
oracleAccountMap,
|
|
1280
|
+
spotMarketAccountMap,
|
|
1281
|
+
perpMarketAccountMap
|
|
1226
1282
|
);
|
|
1227
|
-
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
1228
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1229
|
-
isSigner: false,
|
|
1230
|
-
isWritable: false,
|
|
1231
|
-
});
|
|
1232
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1233
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1234
|
-
pubkey: spotMarketAccount.oracle,
|
|
1235
|
-
isSigner: false,
|
|
1236
|
-
isWritable: false,
|
|
1237
|
-
});
|
|
1238
|
-
}
|
|
1239
1283
|
} else {
|
|
1240
1284
|
this.perpMarketLastSlotCache.delete(marketIndex);
|
|
1241
1285
|
}
|
|
@@ -1248,19 +1292,12 @@ export class DriftClient {
|
|
|
1248
1292
|
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
1249
1293
|
// otherwise remove from slot
|
|
1250
1294
|
if (slot > lastUserSlot) {
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1258
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1259
|
-
pubkey: spotMarketAccount.oracle,
|
|
1260
|
-
isSigner: false,
|
|
1261
|
-
isWritable: false,
|
|
1262
|
-
});
|
|
1263
|
-
}
|
|
1295
|
+
this.addSpotMarketToRemainingAccountMaps(
|
|
1296
|
+
marketIndex,
|
|
1297
|
+
false,
|
|
1298
|
+
oracleAccountMap,
|
|
1299
|
+
spotMarketAccountMap
|
|
1300
|
+
);
|
|
1264
1301
|
} else {
|
|
1265
1302
|
this.spotMarketLastSlotCache.delete(marketIndex);
|
|
1266
1303
|
}
|
|
@@ -1268,106 +1305,72 @@ export class DriftClient {
|
|
|
1268
1305
|
}
|
|
1269
1306
|
|
|
1270
1307
|
if (params.readablePerpMarketIndex !== undefined) {
|
|
1271
|
-
const
|
|
1308
|
+
const readablePerpMarketIndexes = Array.isArray(
|
|
1272
1309
|
params.readablePerpMarketIndex
|
|
1273
|
-
)
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
const spotMarketAccount = this.getSpotMarketAccount(
|
|
1285
|
-
perpMarketAccount.quoteSpotMarketIndex
|
|
1286
|
-
);
|
|
1287
|
-
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
1288
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1289
|
-
isSigner: false,
|
|
1290
|
-
isWritable: false,
|
|
1291
|
-
});
|
|
1292
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1293
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1294
|
-
pubkey: spotMarketAccount.oracle,
|
|
1295
|
-
isSigner: false,
|
|
1296
|
-
isWritable: false,
|
|
1297
|
-
});
|
|
1310
|
+
)
|
|
1311
|
+
? params.readablePerpMarketIndex
|
|
1312
|
+
: [params.readablePerpMarketIndex];
|
|
1313
|
+
for (const marketIndex of readablePerpMarketIndexes) {
|
|
1314
|
+
this.addPerpMarketToRemainingAccountMaps(
|
|
1315
|
+
marketIndex,
|
|
1316
|
+
false,
|
|
1317
|
+
oracleAccountMap,
|
|
1318
|
+
spotMarketAccountMap,
|
|
1319
|
+
perpMarketAccountMap
|
|
1320
|
+
);
|
|
1298
1321
|
}
|
|
1299
1322
|
}
|
|
1300
1323
|
|
|
1324
|
+
for (const perpMarketIndex of this.mustIncludePerpMarketIndexes.values()) {
|
|
1325
|
+
this.addPerpMarketToRemainingAccountMaps(
|
|
1326
|
+
perpMarketIndex,
|
|
1327
|
+
false,
|
|
1328
|
+
oracleAccountMap,
|
|
1329
|
+
spotMarketAccountMap,
|
|
1330
|
+
perpMarketAccountMap
|
|
1331
|
+
);
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1301
1334
|
if (params.readableSpotMarketIndexes !== undefined) {
|
|
1302
1335
|
for (const readableSpotMarketIndex of params.readableSpotMarketIndexes) {
|
|
1303
|
-
|
|
1304
|
-
readableSpotMarketIndex
|
|
1336
|
+
this.addSpotMarketToRemainingAccountMaps(
|
|
1337
|
+
readableSpotMarketIndex,
|
|
1338
|
+
false,
|
|
1339
|
+
oracleAccountMap,
|
|
1340
|
+
spotMarketAccountMap
|
|
1305
1341
|
);
|
|
1306
|
-
spotMarketAccountMap.set(readableSpotMarketIndex, {
|
|
1307
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1308
|
-
isSigner: false,
|
|
1309
|
-
isWritable: false,
|
|
1310
|
-
});
|
|
1311
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1312
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1313
|
-
pubkey: spotMarketAccount.oracle,
|
|
1314
|
-
isSigner: false,
|
|
1315
|
-
isWritable: false,
|
|
1316
|
-
});
|
|
1317
|
-
}
|
|
1318
1342
|
}
|
|
1319
1343
|
}
|
|
1320
1344
|
|
|
1345
|
+
for (const spotMarketIndex of this.mustIncludeSpotMarketIndexes.values()) {
|
|
1346
|
+
this.addSpotMarketToRemainingAccountMaps(
|
|
1347
|
+
spotMarketIndex,
|
|
1348
|
+
false,
|
|
1349
|
+
oracleAccountMap,
|
|
1350
|
+
spotMarketAccountMap
|
|
1351
|
+
);
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1321
1354
|
if (params.writablePerpMarketIndexes !== undefined) {
|
|
1322
1355
|
for (const writablePerpMarketIndex of params.writablePerpMarketIndexes) {
|
|
1323
|
-
|
|
1324
|
-
writablePerpMarketIndex
|
|
1356
|
+
this.addPerpMarketToRemainingAccountMaps(
|
|
1357
|
+
writablePerpMarketIndex,
|
|
1358
|
+
true,
|
|
1359
|
+
oracleAccountMap,
|
|
1360
|
+
spotMarketAccountMap,
|
|
1361
|
+
perpMarketAccountMap
|
|
1325
1362
|
);
|
|
1326
|
-
perpMarketAccountMap.set(writablePerpMarketIndex, {
|
|
1327
|
-
pubkey: perpMarketAccount.pubkey,
|
|
1328
|
-
isSigner: false,
|
|
1329
|
-
isWritable: true,
|
|
1330
|
-
});
|
|
1331
|
-
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
1332
|
-
pubkey: perpMarketAccount.amm.oracle,
|
|
1333
|
-
isSigner: false,
|
|
1334
|
-
isWritable: false,
|
|
1335
|
-
});
|
|
1336
|
-
const spotMarketAccount = this.getSpotMarketAccount(
|
|
1337
|
-
perpMarketAccount.quoteSpotMarketIndex
|
|
1338
|
-
);
|
|
1339
|
-
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
1340
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1341
|
-
isSigner: false,
|
|
1342
|
-
isWritable: false,
|
|
1343
|
-
});
|
|
1344
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1345
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1346
|
-
pubkey: spotMarketAccount.oracle,
|
|
1347
|
-
isSigner: false,
|
|
1348
|
-
isWritable: false,
|
|
1349
|
-
});
|
|
1350
|
-
}
|
|
1351
1363
|
}
|
|
1352
1364
|
}
|
|
1353
1365
|
|
|
1354
1366
|
if (params.writableSpotMarketIndexes !== undefined) {
|
|
1355
1367
|
for (const writableSpotMarketIndex of params.writableSpotMarketIndexes) {
|
|
1356
|
-
|
|
1357
|
-
writableSpotMarketIndex
|
|
1368
|
+
this.addSpotMarketToRemainingAccountMaps(
|
|
1369
|
+
writableSpotMarketIndex,
|
|
1370
|
+
true,
|
|
1371
|
+
oracleAccountMap,
|
|
1372
|
+
spotMarketAccountMap
|
|
1358
1373
|
);
|
|
1359
|
-
spotMarketAccountMap.set(spotMarketAccount.marketIndex, {
|
|
1360
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1361
|
-
isSigner: false,
|
|
1362
|
-
isWritable: true,
|
|
1363
|
-
});
|
|
1364
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1365
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1366
|
-
pubkey: spotMarketAccount.oracle,
|
|
1367
|
-
isSigner: false,
|
|
1368
|
-
isWritable: false,
|
|
1369
|
-
});
|
|
1370
|
-
}
|
|
1371
1374
|
}
|
|
1372
1375
|
}
|
|
1373
1376
|
|
|
@@ -1378,6 +1381,53 @@ export class DriftClient {
|
|
|
1378
1381
|
];
|
|
1379
1382
|
}
|
|
1380
1383
|
|
|
1384
|
+
addPerpMarketToRemainingAccountMaps(
|
|
1385
|
+
marketIndex: number,
|
|
1386
|
+
writable: boolean,
|
|
1387
|
+
oracleAccountMap: Map<string, AccountMeta>,
|
|
1388
|
+
spotMarketAccountMap: Map<number, AccountMeta>,
|
|
1389
|
+
perpMarketAccountMap: Map<number, AccountMeta>
|
|
1390
|
+
): void {
|
|
1391
|
+
const perpMarketAccount = this.getPerpMarketAccount(marketIndex);
|
|
1392
|
+
perpMarketAccountMap.set(marketIndex, {
|
|
1393
|
+
pubkey: perpMarketAccount.pubkey,
|
|
1394
|
+
isSigner: false,
|
|
1395
|
+
isWritable: writable,
|
|
1396
|
+
});
|
|
1397
|
+
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
1398
|
+
pubkey: perpMarketAccount.amm.oracle,
|
|
1399
|
+
isSigner: false,
|
|
1400
|
+
isWritable: false,
|
|
1401
|
+
});
|
|
1402
|
+
this.addSpotMarketToRemainingAccountMaps(
|
|
1403
|
+
perpMarketAccount.quoteSpotMarketIndex,
|
|
1404
|
+
false,
|
|
1405
|
+
oracleAccountMap,
|
|
1406
|
+
spotMarketAccountMap
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
addSpotMarketToRemainingAccountMaps(
|
|
1411
|
+
marketIndex: number,
|
|
1412
|
+
writable: boolean,
|
|
1413
|
+
oracleAccountMap: Map<string, AccountMeta>,
|
|
1414
|
+
spotMarketAccountMap: Map<number, AccountMeta>
|
|
1415
|
+
): void {
|
|
1416
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
1417
|
+
spotMarketAccountMap.set(spotMarketAccount.marketIndex, {
|
|
1418
|
+
pubkey: spotMarketAccount.pubkey,
|
|
1419
|
+
isSigner: false,
|
|
1420
|
+
isWritable: writable,
|
|
1421
|
+
});
|
|
1422
|
+
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1423
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1424
|
+
pubkey: spotMarketAccount.oracle,
|
|
1425
|
+
isSigner: false,
|
|
1426
|
+
isWritable: false,
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1381
1431
|
getRemainingAccountMapsForUsers(userAccounts: UserAccount[]): {
|
|
1382
1432
|
oracleAccountMap: Map<string, AccountMeta>;
|
|
1383
1433
|
spotMarketAccountMap: Map<number, AccountMeta>;
|
|
@@ -1390,73 +1440,35 @@ export class DriftClient {
|
|
|
1390
1440
|
for (const userAccount of userAccounts) {
|
|
1391
1441
|
for (const spotPosition of userAccount.spotPositions) {
|
|
1392
1442
|
if (!isSpotPositionAvailable(spotPosition)) {
|
|
1393
|
-
|
|
1394
|
-
spotPosition.marketIndex
|
|
1443
|
+
this.addSpotMarketToRemainingAccountMaps(
|
|
1444
|
+
spotPosition.marketIndex,
|
|
1445
|
+
false,
|
|
1446
|
+
oracleAccountMap,
|
|
1447
|
+
spotMarketAccountMap
|
|
1395
1448
|
);
|
|
1396
|
-
spotMarketAccountMap.set(spotPosition.marketIndex, {
|
|
1397
|
-
pubkey: spotMarket.pubkey,
|
|
1398
|
-
isSigner: false,
|
|
1399
|
-
isWritable: false,
|
|
1400
|
-
});
|
|
1401
|
-
|
|
1402
|
-
if (!spotMarket.oracle.equals(PublicKey.default)) {
|
|
1403
|
-
oracleAccountMap.set(spotMarket.oracle.toString(), {
|
|
1404
|
-
pubkey: spotMarket.oracle,
|
|
1405
|
-
isSigner: false,
|
|
1406
|
-
isWritable: false,
|
|
1407
|
-
});
|
|
1408
|
-
}
|
|
1409
1449
|
|
|
1410
1450
|
if (
|
|
1411
1451
|
!spotPosition.openAsks.eq(ZERO) ||
|
|
1412
1452
|
!spotPosition.openBids.eq(ZERO)
|
|
1413
1453
|
) {
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
if (!quoteSpotMarket.oracle.equals(PublicKey.default)) {
|
|
1421
|
-
oracleAccountMap.set(quoteSpotMarket.oracle.toString(), {
|
|
1422
|
-
pubkey: quoteSpotMarket.oracle,
|
|
1423
|
-
isSigner: false,
|
|
1424
|
-
isWritable: false,
|
|
1425
|
-
});
|
|
1426
|
-
}
|
|
1454
|
+
this.addSpotMarketToRemainingAccountMaps(
|
|
1455
|
+
QUOTE_SPOT_MARKET_INDEX,
|
|
1456
|
+
false,
|
|
1457
|
+
oracleAccountMap,
|
|
1458
|
+
spotMarketAccountMap
|
|
1459
|
+
);
|
|
1427
1460
|
}
|
|
1428
1461
|
}
|
|
1429
1462
|
}
|
|
1430
1463
|
for (const position of userAccount.perpPositions) {
|
|
1431
1464
|
if (!positionIsAvailable(position)) {
|
|
1432
|
-
|
|
1433
|
-
position.marketIndex
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
isSigner: false,
|
|
1439
|
-
});
|
|
1440
|
-
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
1441
|
-
pubkey: perpMarketAccount.amm.oracle,
|
|
1442
|
-
isWritable: false,
|
|
1443
|
-
isSigner: false,
|
|
1444
|
-
});
|
|
1445
|
-
const spotMarketAccount = this.getSpotMarketAccount(
|
|
1446
|
-
perpMarketAccount.quoteSpotMarketIndex
|
|
1465
|
+
this.addPerpMarketToRemainingAccountMaps(
|
|
1466
|
+
position.marketIndex,
|
|
1467
|
+
false,
|
|
1468
|
+
oracleAccountMap,
|
|
1469
|
+
spotMarketAccountMap,
|
|
1470
|
+
perpMarketAccountMap
|
|
1447
1471
|
);
|
|
1448
|
-
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
1449
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1450
|
-
isSigner: false,
|
|
1451
|
-
isWritable: false,
|
|
1452
|
-
});
|
|
1453
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1454
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1455
|
-
pubkey: spotMarketAccount.oracle,
|
|
1456
|
-
isSigner: false,
|
|
1457
|
-
isWritable: false,
|
|
1458
|
-
});
|
|
1459
|
-
}
|
|
1460
1472
|
}
|
|
1461
1473
|
}
|
|
1462
1474
|
}
|
|
@@ -1660,7 +1672,7 @@ export class DriftClient {
|
|
|
1660
1672
|
}
|
|
1661
1673
|
}
|
|
1662
1674
|
|
|
1663
|
-
|
|
1675
|
+
public async getWrappedSolAccountCreationIxs(
|
|
1664
1676
|
amount: BN,
|
|
1665
1677
|
includeRent?: boolean
|
|
1666
1678
|
): Promise<{
|
|
@@ -2510,19 +2522,10 @@ export class DriftClient {
|
|
|
2510
2522
|
return txSig;
|
|
2511
2523
|
}
|
|
2512
2524
|
|
|
2513
|
-
getOrderParams(
|
|
2514
|
-
optionalOrderParams: OptionalOrderParams,
|
|
2515
|
-
marketType: MarketType
|
|
2516
|
-
): OrderParams {
|
|
2517
|
-
return Object.assign({}, DefaultOrderParams, optionalOrderParams, {
|
|
2518
|
-
marketType,
|
|
2519
|
-
});
|
|
2520
|
-
}
|
|
2521
|
-
|
|
2522
2525
|
public async getPlacePerpOrderIx(
|
|
2523
2526
|
orderParams: OptionalOrderParams
|
|
2524
2527
|
): Promise<TransactionInstruction> {
|
|
2525
|
-
orderParams =
|
|
2528
|
+
orderParams = getOrderParams(orderParams, { marketType: MarketType.PERP });
|
|
2526
2529
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
2527
2530
|
|
|
2528
2531
|
const remainingAccounts = this.getRemainingAccounts({
|
|
@@ -2815,32 +2818,68 @@ export class DriftClient {
|
|
|
2815
2818
|
placeOrderParams: OrderParams[],
|
|
2816
2819
|
txParams?: TxParams
|
|
2817
2820
|
): Promise<TransactionSignature> {
|
|
2818
|
-
const
|
|
2821
|
+
const ixs = [
|
|
2819
2822
|
await this.getCancelOrdersIx(
|
|
2820
2823
|
cancelOrderParams.marketType,
|
|
2821
2824
|
cancelOrderParams.marketIndex,
|
|
2822
2825
|
cancelOrderParams.direction
|
|
2823
2826
|
),
|
|
2824
|
-
|
|
2825
|
-
|
|
2827
|
+
await this.getPlaceOrdersIx(placeOrderParams),
|
|
2828
|
+
];
|
|
2829
|
+
const tx = await this.buildTransaction(ixs, txParams);
|
|
2830
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
2831
|
+
return txSig;
|
|
2832
|
+
}
|
|
2833
|
+
|
|
2834
|
+
public async placeOrders(
|
|
2835
|
+
params: OrderParams[],
|
|
2836
|
+
txParams?: TxParams
|
|
2837
|
+
): Promise<TransactionSignature> {
|
|
2838
|
+
const { txSig } = await this.sendTransaction(
|
|
2839
|
+
await this.buildTransaction(
|
|
2840
|
+
await this.getPlaceOrdersIx(params),
|
|
2841
|
+
txParams
|
|
2842
|
+
),
|
|
2843
|
+
[],
|
|
2844
|
+
this.opts
|
|
2826
2845
|
);
|
|
2846
|
+
return txSig;
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2849
|
+
public async getPlaceOrdersIx(
|
|
2850
|
+
params: OrderParams[]
|
|
2851
|
+
): Promise<TransactionInstruction> {
|
|
2852
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
2827
2853
|
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2854
|
+
const readablePerpMarketIndex: number[] = [];
|
|
2855
|
+
const readableSpotMarketIndexes: number[] = [];
|
|
2856
|
+
for (const param of params) {
|
|
2857
|
+
if (!param.marketType) {
|
|
2858
|
+
throw new Error('must set param.marketType');
|
|
2832
2859
|
}
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
ix = this.getPlacePerpOrderIx(placeOrderParam);
|
|
2860
|
+
if (isVariant(param.marketType, 'perp')) {
|
|
2861
|
+
readablePerpMarketIndex.push(param.marketIndex);
|
|
2836
2862
|
} else {
|
|
2837
|
-
|
|
2863
|
+
readableSpotMarketIndexes.push(param.marketIndex);
|
|
2838
2864
|
}
|
|
2839
|
-
tx.add(ix);
|
|
2840
2865
|
}
|
|
2841
2866
|
|
|
2842
|
-
const
|
|
2843
|
-
|
|
2867
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2868
|
+
userAccounts: [this.getUserAccount()],
|
|
2869
|
+
readablePerpMarketIndex,
|
|
2870
|
+
readableSpotMarketIndexes,
|
|
2871
|
+
useMarketLastSlotCache: true,
|
|
2872
|
+
});
|
|
2873
|
+
|
|
2874
|
+
return await this.program.instruction.placeOrders(params, {
|
|
2875
|
+
accounts: {
|
|
2876
|
+
state: await this.getStatePublicKey(),
|
|
2877
|
+
user: userAccountPublicKey,
|
|
2878
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
2879
|
+
authority: this.wallet.publicKey,
|
|
2880
|
+
},
|
|
2881
|
+
remainingAccounts,
|
|
2882
|
+
});
|
|
2844
2883
|
}
|
|
2845
2884
|
|
|
2846
2885
|
public async fillPerpOrder(
|
|
@@ -2983,7 +3022,7 @@ export class DriftClient {
|
|
|
2983
3022
|
public async getPlaceSpotOrderIx(
|
|
2984
3023
|
orderParams: OptionalOrderParams
|
|
2985
3024
|
): Promise<TransactionInstruction> {
|
|
2986
|
-
orderParams =
|
|
3025
|
+
orderParams = getOrderParams(orderParams, { marketType: MarketType.SPOT });
|
|
2987
3026
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
2988
3027
|
|
|
2989
3028
|
const remainingAccounts = this.getRemainingAccounts({
|
|
@@ -3343,6 +3382,61 @@ export class DriftClient {
|
|
|
3343
3382
|
reduceOnly?: SwapReduceOnly;
|
|
3344
3383
|
txParams?: TxParams;
|
|
3345
3384
|
}): Promise<TransactionSignature> {
|
|
3385
|
+
const { ixs, lookupTables } = await this.getJupiterSwapIx({
|
|
3386
|
+
jupiterClient,
|
|
3387
|
+
outMarketIndex,
|
|
3388
|
+
inMarketIndex,
|
|
3389
|
+
outAssociatedTokenAccount,
|
|
3390
|
+
inAssociatedTokenAccount,
|
|
3391
|
+
amount,
|
|
3392
|
+
slippageBps,
|
|
3393
|
+
swapMode,
|
|
3394
|
+
route,
|
|
3395
|
+
reduceOnly,
|
|
3396
|
+
});
|
|
3397
|
+
|
|
3398
|
+
const tx = (await this.buildTransaction(
|
|
3399
|
+
ixs,
|
|
3400
|
+
txParams,
|
|
3401
|
+
0,
|
|
3402
|
+
lookupTables
|
|
3403
|
+
)) as VersionedTransaction;
|
|
3404
|
+
|
|
3405
|
+
const { txSig, slot } = await this.sendTransaction(tx);
|
|
3406
|
+
this.spotMarketLastSlotCache.set(outMarketIndex, slot);
|
|
3407
|
+
this.spotMarketLastSlotCache.set(inMarketIndex, slot);
|
|
3408
|
+
|
|
3409
|
+
return txSig;
|
|
3410
|
+
}
|
|
3411
|
+
|
|
3412
|
+
public async getJupiterSwapIx({
|
|
3413
|
+
jupiterClient,
|
|
3414
|
+
outMarketIndex,
|
|
3415
|
+
inMarketIndex,
|
|
3416
|
+
outAssociatedTokenAccount,
|
|
3417
|
+
inAssociatedTokenAccount,
|
|
3418
|
+
amount,
|
|
3419
|
+
slippageBps,
|
|
3420
|
+
swapMode,
|
|
3421
|
+
route,
|
|
3422
|
+
reduceOnly,
|
|
3423
|
+
userAccountPublicKey,
|
|
3424
|
+
}: {
|
|
3425
|
+
jupiterClient: JupiterClient;
|
|
3426
|
+
outMarketIndex: number;
|
|
3427
|
+
inMarketIndex: number;
|
|
3428
|
+
outAssociatedTokenAccount?: PublicKey;
|
|
3429
|
+
inAssociatedTokenAccount?: PublicKey;
|
|
3430
|
+
amount: BN;
|
|
3431
|
+
slippageBps?: number;
|
|
3432
|
+
swapMode?: SwapMode;
|
|
3433
|
+
route?: Route;
|
|
3434
|
+
reduceOnly?: SwapReduceOnly;
|
|
3435
|
+
userAccountPublicKey?: PublicKey;
|
|
3436
|
+
}): Promise<{
|
|
3437
|
+
ixs: TransactionInstruction[];
|
|
3438
|
+
lookupTables: AddressLookupTableAccount[];
|
|
3439
|
+
}> {
|
|
3346
3440
|
const outMarket = this.getSpotMarketAccount(outMarketIndex);
|
|
3347
3441
|
const inMarket = this.getSpotMarketAccount(inMarketIndex);
|
|
3348
3442
|
|
|
@@ -3429,27 +3523,17 @@ export class DriftClient {
|
|
|
3429
3523
|
inTokenAccount: inAssociatedTokenAccount,
|
|
3430
3524
|
outTokenAccount: outAssociatedTokenAccount,
|
|
3431
3525
|
reduceOnly,
|
|
3526
|
+
userAccountPublicKey,
|
|
3432
3527
|
});
|
|
3433
3528
|
|
|
3434
|
-
const
|
|
3529
|
+
const ixs = [
|
|
3435
3530
|
...preInstructions,
|
|
3436
3531
|
beginSwapIx,
|
|
3437
3532
|
...jupiterInstructions,
|
|
3438
3533
|
endSwapIx,
|
|
3439
3534
|
];
|
|
3440
3535
|
|
|
3441
|
-
|
|
3442
|
-
instructions,
|
|
3443
|
-
txParams,
|
|
3444
|
-
0,
|
|
3445
|
-
lookupTables
|
|
3446
|
-
)) as VersionedTransaction;
|
|
3447
|
-
|
|
3448
|
-
const { txSig, slot } = await this.sendTransaction(tx);
|
|
3449
|
-
this.spotMarketLastSlotCache.set(outMarketIndex, slot);
|
|
3450
|
-
this.spotMarketLastSlotCache.set(inMarketIndex, slot);
|
|
3451
|
-
|
|
3452
|
-
return txSig;
|
|
3536
|
+
return { ixs, lookupTables };
|
|
3453
3537
|
}
|
|
3454
3538
|
|
|
3455
3539
|
/**
|
|
@@ -3461,6 +3545,8 @@ export class DriftClient {
|
|
|
3461
3545
|
* @param inTokenAccount the token account to move the tokens being sold
|
|
3462
3546
|
* @param outTokenAccount the token account to receive the tokens being bought
|
|
3463
3547
|
* @param limitPrice the limit price of the swap
|
|
3548
|
+
* @param reduceOnly
|
|
3549
|
+
* @param userAccountPublicKey optional, specify a custom userAccountPublicKey to use instead of getting the current user account; can be helpful if the account is being created within the current tx
|
|
3464
3550
|
*/
|
|
3465
3551
|
public async getSwapIx({
|
|
3466
3552
|
outMarketIndex,
|
|
@@ -3470,6 +3556,7 @@ export class DriftClient {
|
|
|
3470
3556
|
outTokenAccount,
|
|
3471
3557
|
limitPrice,
|
|
3472
3558
|
reduceOnly,
|
|
3559
|
+
userAccountPublicKey,
|
|
3473
3560
|
}: {
|
|
3474
3561
|
outMarketIndex: number;
|
|
3475
3562
|
inMarketIndex: number;
|
|
@@ -3478,14 +3565,17 @@ export class DriftClient {
|
|
|
3478
3565
|
outTokenAccount: PublicKey;
|
|
3479
3566
|
limitPrice?: BN;
|
|
3480
3567
|
reduceOnly?: SwapReduceOnly;
|
|
3568
|
+
userAccountPublicKey?: PublicKey;
|
|
3481
3569
|
}): Promise<{
|
|
3482
3570
|
beginSwapIx: TransactionInstruction;
|
|
3483
3571
|
endSwapIx: TransactionInstruction;
|
|
3484
3572
|
}> {
|
|
3485
|
-
const
|
|
3573
|
+
const userAccountPublicKeyToUse =
|
|
3574
|
+
userAccountPublicKey || (await this.getUserAccountPublicKey());
|
|
3486
3575
|
|
|
3576
|
+
const userAccounts = this.hasUser() ? [this.getUserAccount()] : [];
|
|
3487
3577
|
const remainingAccounts = this.getRemainingAccounts({
|
|
3488
|
-
userAccounts
|
|
3578
|
+
userAccounts,
|
|
3489
3579
|
writableSpotMarketIndexes: [outMarketIndex, inMarketIndex],
|
|
3490
3580
|
});
|
|
3491
3581
|
|
|
@@ -3499,7 +3589,7 @@ export class DriftClient {
|
|
|
3499
3589
|
{
|
|
3500
3590
|
accounts: {
|
|
3501
3591
|
state: await this.getStatePublicKey(),
|
|
3502
|
-
user:
|
|
3592
|
+
user: userAccountPublicKeyToUse,
|
|
3503
3593
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
3504
3594
|
authority: this.authority,
|
|
3505
3595
|
outSpotMarketVault: outSpotMarket.vault,
|
|
@@ -3522,7 +3612,7 @@ export class DriftClient {
|
|
|
3522
3612
|
{
|
|
3523
3613
|
accounts: {
|
|
3524
3614
|
state: await this.getStatePublicKey(),
|
|
3525
|
-
user:
|
|
3615
|
+
user: userAccountPublicKeyToUse,
|
|
3526
3616
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
3527
3617
|
authority: this.authority,
|
|
3528
3618
|
outSpotMarketVault: outSpotMarket.vault,
|
|
@@ -3540,6 +3630,66 @@ export class DriftClient {
|
|
|
3540
3630
|
return { beginSwapIx, endSwapIx };
|
|
3541
3631
|
}
|
|
3542
3632
|
|
|
3633
|
+
public async stakeForMSOL({ amount }: { amount: BN }): Promise<TxSigAndSlot> {
|
|
3634
|
+
const ixs = await this.getStakeForMSOLIx({ amount });
|
|
3635
|
+
const tx = await this.buildTransaction(ixs);
|
|
3636
|
+
return this.sendTransaction(tx);
|
|
3637
|
+
}
|
|
3638
|
+
|
|
3639
|
+
public async getStakeForMSOLIx({
|
|
3640
|
+
amount,
|
|
3641
|
+
userAccountPublicKey,
|
|
3642
|
+
}: {
|
|
3643
|
+
amount: BN;
|
|
3644
|
+
userAccountPublicKey?: PublicKey;
|
|
3645
|
+
}): Promise<TransactionInstruction[]> {
|
|
3646
|
+
const wSOLMint = this.getSpotMarketAccount(1).mint;
|
|
3647
|
+
const mSOLAccount = await this.getAssociatedTokenAccount(2);
|
|
3648
|
+
const wSOLAccount = await this.getAssociatedTokenAccount(1, false);
|
|
3649
|
+
|
|
3650
|
+
const wSOLAccountExists = await this.checkIfAccountExists(wSOLAccount);
|
|
3651
|
+
|
|
3652
|
+
const closeWSOLIx = createCloseAccountInstruction(
|
|
3653
|
+
wSOLAccount,
|
|
3654
|
+
this.wallet.publicKey,
|
|
3655
|
+
this.wallet.publicKey
|
|
3656
|
+
);
|
|
3657
|
+
|
|
3658
|
+
const createWSOLIx =
|
|
3659
|
+
await this.createAssociatedTokenAccountIdempotentInstruction(
|
|
3660
|
+
wSOLAccount,
|
|
3661
|
+
this.wallet.publicKey,
|
|
3662
|
+
this.wallet.publicKey,
|
|
3663
|
+
wSOLMint
|
|
3664
|
+
);
|
|
3665
|
+
|
|
3666
|
+
const { beginSwapIx, endSwapIx } = await this.getSwapIx({
|
|
3667
|
+
inMarketIndex: 1,
|
|
3668
|
+
outMarketIndex: 2,
|
|
3669
|
+
amountIn: amount,
|
|
3670
|
+
inTokenAccount: wSOLAccount,
|
|
3671
|
+
outTokenAccount: mSOLAccount,
|
|
3672
|
+
userAccountPublicKey,
|
|
3673
|
+
});
|
|
3674
|
+
|
|
3675
|
+
const program = getMarinadeFinanceProgram(this.provider);
|
|
3676
|
+
const depositIx = await getMarinadeDepositIx({
|
|
3677
|
+
program,
|
|
3678
|
+
mSOLAccount: mSOLAccount,
|
|
3679
|
+
transferFrom: this.wallet.publicKey,
|
|
3680
|
+
amount,
|
|
3681
|
+
});
|
|
3682
|
+
|
|
3683
|
+
const ixs = [];
|
|
3684
|
+
|
|
3685
|
+
if (!wSOLAccountExists) {
|
|
3686
|
+
ixs.push(createWSOLIx);
|
|
3687
|
+
}
|
|
3688
|
+
ixs.push(beginSwapIx, closeWSOLIx, depositIx, createWSOLIx, endSwapIx);
|
|
3689
|
+
|
|
3690
|
+
return ixs;
|
|
3691
|
+
}
|
|
3692
|
+
|
|
3543
3693
|
public async triggerOrder(
|
|
3544
3694
|
userAccountPublicKey: PublicKey,
|
|
3545
3695
|
user: UserAccount,
|
|
@@ -3732,7 +3882,7 @@ export class DriftClient {
|
|
|
3732
3882
|
makerInfo?: MakerInfo | MakerInfo[],
|
|
3733
3883
|
referrerInfo?: ReferrerInfo
|
|
3734
3884
|
): Promise<TransactionInstruction> {
|
|
3735
|
-
orderParams =
|
|
3885
|
+
orderParams = getOrderParams(orderParams, { marketType: MarketType.PERP });
|
|
3736
3886
|
const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
3737
3887
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
3738
3888
|
|
|
@@ -3828,7 +3978,7 @@ export class DriftClient {
|
|
|
3828
3978
|
takerInfo: TakerInfo,
|
|
3829
3979
|
referrerInfo?: ReferrerInfo
|
|
3830
3980
|
): Promise<TransactionInstruction> {
|
|
3831
|
-
orderParams =
|
|
3981
|
+
orderParams = getOrderParams(orderParams, { marketType: MarketType.PERP });
|
|
3832
3982
|
const userStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
3833
3983
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
3834
3984
|
|
|
@@ -3900,7 +4050,7 @@ export class DriftClient {
|
|
|
3900
4050
|
makerInfo?: MakerInfo,
|
|
3901
4051
|
referrerInfo?: ReferrerInfo
|
|
3902
4052
|
): Promise<TransactionInstruction> {
|
|
3903
|
-
orderParams =
|
|
4053
|
+
orderParams = getOrderParams(orderParams, { marketType: MarketType.SPOT });
|
|
3904
4054
|
const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
3905
4055
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
3906
4056
|
|
|
@@ -3998,7 +4148,7 @@ export class DriftClient {
|
|
|
3998
4148
|
fulfillmentConfig?: SerumV3FulfillmentConfigAccount,
|
|
3999
4149
|
referrerInfo?: ReferrerInfo
|
|
4000
4150
|
): Promise<TransactionInstruction> {
|
|
4001
|
-
orderParams =
|
|
4151
|
+
orderParams = getOrderParams(orderParams, { marketType: MarketType.SPOT });
|
|
4002
4152
|
const userStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
4003
4153
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
4004
4154
|
|