@drift-labs/sdk 2.31.1-beta.2 → 2.31.1-beta.21
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/accounts/mockUserAccountSubscriber.d.ts +23 -0
- package/lib/accounts/mockUserAccountSubscriber.js +31 -0
- package/lib/constants/perpMarkets.js +20 -0
- package/lib/dlob/orderBookLevels.js +2 -2
- package/lib/driftClient.d.ts +57 -4
- package/lib/driftClient.js +244 -205
- package/lib/driftClientConfig.d.ts +2 -1
- package/lib/idl/drift.json +31 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -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/tiers.d.ts +4 -0
- package/lib/math/tiers.js +52 -0
- package/lib/tx/retryTxSender.d.ts +12 -3
- package/lib/tx/retryTxSender.js +22 -22
- package/lib/tx/types.d.ts +2 -2
- package/lib/user.d.ts +10 -1
- package/lib/user.js +39 -8
- package/lib/userConfig.d.ts +4 -0
- package/lib/userStats.js +4 -1
- package/lib/userStatsConfig.d.ts +2 -0
- package/package.json +1 -1
- package/src/accounts/mockUserAccountSubscriber.ts +53 -0
- package/src/config.ts +2 -2
- package/src/constants/perpMarkets.ts +20 -0
- package/src/dlob/orderBookLevels.ts +3 -2
- package/src/driftClient.ts +440 -224
- package/src/driftClientConfig.ts +2 -1
- package/src/idl/drift.json +31 -1
- package/src/index.ts +2 -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/tiers.ts +44 -0
- package/src/tx/retryTxSender.ts +39 -35
- package/src/tx/types.ts +2 -2
- package/src/user.ts +63 -12
- package/src/userConfig.ts +5 -0
- package/src/userStats.ts +4 -0
- package/src/userStatsConfig.ts +3 -0
- package/tests/spot/test.ts +156 -0
package/src/driftClient.ts
CHANGED
|
@@ -95,6 +95,7 @@ import {
|
|
|
95
95
|
PRICE_PRECISION,
|
|
96
96
|
QUOTE_SPOT_MARKET_INDEX,
|
|
97
97
|
ZERO,
|
|
98
|
+
QUOTE_PRECISION,
|
|
98
99
|
} from './constants/numericConstants';
|
|
99
100
|
import { findDirectionToClose, positionIsAvailable } from './math/position';
|
|
100
101
|
import { getSignedTokenAmount, getTokenAmount } from './math/spotBalance';
|
|
@@ -115,12 +116,14 @@ import { fetchUserStatsAccount } from './accounts/fetch';
|
|
|
115
116
|
import { castNumberToSpotPrecision } from './math/spotMarket';
|
|
116
117
|
import { JupiterClient, Route, SwapMode } from './jupiter/jupiterClient';
|
|
117
118
|
import { getNonIdleUserFilter } from './memcmp';
|
|
119
|
+
import { UserStatsSubscriptionConfig } from './userStatsConfig';
|
|
120
|
+
import { getMarinadeDepositIx, getMarinadeFinanceProgram } from './marinade';
|
|
118
121
|
|
|
119
122
|
type RemainingAccountParams = {
|
|
120
123
|
userAccounts: UserAccount[];
|
|
121
124
|
writablePerpMarketIndexes?: number[];
|
|
122
125
|
writableSpotMarketIndexes?: number[];
|
|
123
|
-
readablePerpMarketIndex?: number;
|
|
126
|
+
readablePerpMarketIndex?: number | number[];
|
|
124
127
|
readableSpotMarketIndexes?: number[];
|
|
125
128
|
useMarketLastSlotCache?: boolean;
|
|
126
129
|
};
|
|
@@ -139,12 +142,15 @@ export class DriftClient {
|
|
|
139
142
|
userStats?: UserStats;
|
|
140
143
|
activeSubAccountId: number;
|
|
141
144
|
userAccountSubscriptionConfig: UserSubscriptionConfig;
|
|
145
|
+
userStatsAccountSubscriptionConfig: UserStatsSubscriptionConfig;
|
|
142
146
|
accountSubscriber: DriftClientAccountSubscriber;
|
|
143
147
|
eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
|
|
144
148
|
_isSubscribed = false;
|
|
145
149
|
txSender: TxSender;
|
|
146
150
|
perpMarketLastSlotCache = new Map<number, number>();
|
|
147
151
|
spotMarketLastSlotCache = new Map<number, number>();
|
|
152
|
+
mustIncludePerpMarketIndexes = new Set<number>();
|
|
153
|
+
mustIncludeSpotMarketIndexes = new Set<number>();
|
|
148
154
|
authority: PublicKey;
|
|
149
155
|
marketLookupTable: PublicKey;
|
|
150
156
|
lookupTableAccount: AddressLookupTableAccount;
|
|
@@ -152,6 +158,7 @@ export class DriftClient {
|
|
|
152
158
|
authoritySubAccountMap?: Map<string, number[]>;
|
|
153
159
|
skipLoadUsers?: boolean;
|
|
154
160
|
txVersion: TransactionVersion;
|
|
161
|
+
txParams: TxParams;
|
|
155
162
|
|
|
156
163
|
public get isSubscribed() {
|
|
157
164
|
return this._isSubscribed && this.accountSubscriber.isSubscribed;
|
|
@@ -180,6 +187,10 @@ export class DriftClient {
|
|
|
180
187
|
this.activeSubAccountId = config.activeSubAccountId ?? 0;
|
|
181
188
|
this.skipLoadUsers = config.skipLoadUsers ?? false;
|
|
182
189
|
this.txVersion = config.txVersion ?? 'legacy';
|
|
190
|
+
this.txParams = {
|
|
191
|
+
computeUnits: config.txParams?.computeUnits ?? 600_000,
|
|
192
|
+
computeUnitsPrice: config.txParams?.computeUnitsPrice ?? 0,
|
|
193
|
+
};
|
|
183
194
|
|
|
184
195
|
if (config.includeDelegates && config.subAccountIds) {
|
|
185
196
|
throw new Error(
|
|
@@ -206,15 +217,23 @@ export class DriftClient {
|
|
|
206
217
|
: new Map<string, number[]>();
|
|
207
218
|
|
|
208
219
|
this.includeDelegates = config.includeDelegates ?? false;
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
:
|
|
216
|
-
|
|
217
|
-
|
|
220
|
+
if (config.accountSubscription?.type === 'polling') {
|
|
221
|
+
this.userAccountSubscriptionConfig = {
|
|
222
|
+
type: 'polling',
|
|
223
|
+
accountLoader: config.accountSubscription.accountLoader,
|
|
224
|
+
};
|
|
225
|
+
this.userStatsAccountSubscriptionConfig = {
|
|
226
|
+
type: 'polling',
|
|
227
|
+
accountLoader: config.accountSubscription.accountLoader,
|
|
228
|
+
};
|
|
229
|
+
} else {
|
|
230
|
+
this.userAccountSubscriptionConfig = {
|
|
231
|
+
type: 'websocket',
|
|
232
|
+
};
|
|
233
|
+
this.userStatsAccountSubscriptionConfig = {
|
|
234
|
+
type: 'websocket',
|
|
235
|
+
};
|
|
236
|
+
}
|
|
218
237
|
|
|
219
238
|
if (config.userStats) {
|
|
220
239
|
this.userStats = new UserStats({
|
|
@@ -257,7 +276,13 @@ export class DriftClient {
|
|
|
257
276
|
);
|
|
258
277
|
}
|
|
259
278
|
this.eventEmitter = this.accountSubscriber.eventEmitter;
|
|
260
|
-
this.txSender =
|
|
279
|
+
this.txSender =
|
|
280
|
+
config.txSender ??
|
|
281
|
+
new RetryTxSender({
|
|
282
|
+
connection: this.connection,
|
|
283
|
+
wallet: this.wallet,
|
|
284
|
+
opts: this.opts,
|
|
285
|
+
});
|
|
261
286
|
}
|
|
262
287
|
|
|
263
288
|
public getUserMapKey(subAccountId: number, authority: PublicKey): string {
|
|
@@ -498,7 +523,7 @@ export class DriftClient {
|
|
|
498
523
|
|
|
499
524
|
this.skipLoadUsers = false;
|
|
500
525
|
// Update provider for txSender with new wallet details
|
|
501
|
-
this.txSender.
|
|
526
|
+
this.txSender.wallet = newWallet;
|
|
502
527
|
this.wallet = newWallet;
|
|
503
528
|
this.provider = newProvider;
|
|
504
529
|
this.program = newProgram;
|
|
@@ -542,7 +567,7 @@ export class DriftClient {
|
|
|
542
567
|
this.userStats = new UserStats({
|
|
543
568
|
driftClient: this,
|
|
544
569
|
userStatsAccountPublicKey: this.getUserStatsAccountPublicKey(),
|
|
545
|
-
accountSubscription: this.
|
|
570
|
+
accountSubscription: this.userStatsAccountSubscriptionConfig,
|
|
546
571
|
});
|
|
547
572
|
|
|
548
573
|
await this.userStats.subscribe();
|
|
@@ -838,6 +863,43 @@ export class DriftClient {
|
|
|
838
863
|
return txSig;
|
|
839
864
|
}
|
|
840
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
|
+
|
|
841
903
|
public async updateUserMarginTradingEnabled(
|
|
842
904
|
marginTradingEnabled: boolean,
|
|
843
905
|
subAccountId = 0
|
|
@@ -1028,11 +1090,19 @@ export class DriftClient {
|
|
|
1028
1090
|
const userMapKey = this.getUserMapKey(subAccountId, authority);
|
|
1029
1091
|
|
|
1030
1092
|
if (!this.users.has(userMapKey)) {
|
|
1031
|
-
throw new Error(`
|
|
1093
|
+
throw new Error(`DriftClient has no user for user id ${userMapKey}`);
|
|
1032
1094
|
}
|
|
1033
1095
|
return this.users.get(userMapKey);
|
|
1034
1096
|
}
|
|
1035
1097
|
|
|
1098
|
+
public hasUser(subAccountId?: number, authority?: PublicKey): boolean {
|
|
1099
|
+
subAccountId = subAccountId ?? this.activeSubAccountId;
|
|
1100
|
+
authority = authority ?? this.authority;
|
|
1101
|
+
const userMapKey = this.getUserMapKey(subAccountId, authority);
|
|
1102
|
+
|
|
1103
|
+
return this.users.has(userMapKey);
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1036
1106
|
public getUsers(): User[] {
|
|
1037
1107
|
// delegate users get added to the end
|
|
1038
1108
|
return [...this.users.values()]
|
|
@@ -1167,6 +1237,29 @@ export class DriftClient {
|
|
|
1167
1237
|
return amount.mul(PRICE_PRECISION);
|
|
1168
1238
|
}
|
|
1169
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
|
+
|
|
1170
1263
|
getRemainingAccounts(params: RemainingAccountParams): AccountMeta[] {
|
|
1171
1264
|
const { oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap } =
|
|
1172
1265
|
this.getRemainingAccountMapsForUsers(params.userAccounts);
|
|
@@ -1180,32 +1273,13 @@ export class DriftClient {
|
|
|
1180
1273
|
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
1181
1274
|
// otherwise remove from slot
|
|
1182
1275
|
if (slot > lastUserSlot) {
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
1190
|
-
pubkey: perpMarketAccount.amm.oracle,
|
|
1191
|
-
isSigner: false,
|
|
1192
|
-
isWritable: false,
|
|
1193
|
-
});
|
|
1194
|
-
const spotMarketAccount = this.getSpotMarketAccount(
|
|
1195
|
-
perpMarketAccount.quoteSpotMarketIndex
|
|
1276
|
+
this.addPerpMarketToRemainingAccountMaps(
|
|
1277
|
+
marketIndex,
|
|
1278
|
+
false,
|
|
1279
|
+
oracleAccountMap,
|
|
1280
|
+
spotMarketAccountMap,
|
|
1281
|
+
perpMarketAccountMap
|
|
1196
1282
|
);
|
|
1197
|
-
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
1198
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1199
|
-
isSigner: false,
|
|
1200
|
-
isWritable: false,
|
|
1201
|
-
});
|
|
1202
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1203
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1204
|
-
pubkey: spotMarketAccount.oracle,
|
|
1205
|
-
isSigner: false,
|
|
1206
|
-
isWritable: false,
|
|
1207
|
-
});
|
|
1208
|
-
}
|
|
1209
1283
|
} else {
|
|
1210
1284
|
this.perpMarketLastSlotCache.delete(marketIndex);
|
|
1211
1285
|
}
|
|
@@ -1218,19 +1292,12 @@ export class DriftClient {
|
|
|
1218
1292
|
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
1219
1293
|
// otherwise remove from slot
|
|
1220
1294
|
if (slot > lastUserSlot) {
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1228
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1229
|
-
pubkey: spotMarketAccount.oracle,
|
|
1230
|
-
isSigner: false,
|
|
1231
|
-
isWritable: false,
|
|
1232
|
-
});
|
|
1233
|
-
}
|
|
1295
|
+
this.addSpotMarketToRemainingAccountMaps(
|
|
1296
|
+
marketIndex,
|
|
1297
|
+
false,
|
|
1298
|
+
oracleAccountMap,
|
|
1299
|
+
spotMarketAccountMap
|
|
1300
|
+
);
|
|
1234
1301
|
} else {
|
|
1235
1302
|
this.spotMarketLastSlotCache.delete(marketIndex);
|
|
1236
1303
|
}
|
|
@@ -1238,106 +1305,72 @@ export class DriftClient {
|
|
|
1238
1305
|
}
|
|
1239
1306
|
|
|
1240
1307
|
if (params.readablePerpMarketIndex !== undefined) {
|
|
1241
|
-
const
|
|
1308
|
+
const readablePerpMarketIndexes = Array.isArray(
|
|
1242
1309
|
params.readablePerpMarketIndex
|
|
1243
|
-
)
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
const spotMarketAccount = this.getSpotMarketAccount(
|
|
1255
|
-
perpMarketAccount.quoteSpotMarketIndex
|
|
1256
|
-
);
|
|
1257
|
-
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
1258
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1259
|
-
isSigner: false,
|
|
1260
|
-
isWritable: false,
|
|
1261
|
-
});
|
|
1262
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1263
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1264
|
-
pubkey: spotMarketAccount.oracle,
|
|
1265
|
-
isSigner: false,
|
|
1266
|
-
isWritable: false,
|
|
1267
|
-
});
|
|
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
|
+
);
|
|
1268
1321
|
}
|
|
1269
1322
|
}
|
|
1270
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
|
+
|
|
1271
1334
|
if (params.readableSpotMarketIndexes !== undefined) {
|
|
1272
1335
|
for (const readableSpotMarketIndex of params.readableSpotMarketIndexes) {
|
|
1273
|
-
|
|
1274
|
-
readableSpotMarketIndex
|
|
1336
|
+
this.addSpotMarketToRemainingAccountMaps(
|
|
1337
|
+
readableSpotMarketIndex,
|
|
1338
|
+
false,
|
|
1339
|
+
oracleAccountMap,
|
|
1340
|
+
spotMarketAccountMap
|
|
1275
1341
|
);
|
|
1276
|
-
spotMarketAccountMap.set(readableSpotMarketIndex, {
|
|
1277
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1278
|
-
isSigner: false,
|
|
1279
|
-
isWritable: false,
|
|
1280
|
-
});
|
|
1281
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1282
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1283
|
-
pubkey: spotMarketAccount.oracle,
|
|
1284
|
-
isSigner: false,
|
|
1285
|
-
isWritable: false,
|
|
1286
|
-
});
|
|
1287
|
-
}
|
|
1288
1342
|
}
|
|
1289
1343
|
}
|
|
1290
1344
|
|
|
1345
|
+
for (const spotMarketIndex of this.mustIncludeSpotMarketIndexes.values()) {
|
|
1346
|
+
this.addSpotMarketToRemainingAccountMaps(
|
|
1347
|
+
spotMarketIndex,
|
|
1348
|
+
false,
|
|
1349
|
+
oracleAccountMap,
|
|
1350
|
+
spotMarketAccountMap
|
|
1351
|
+
);
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1291
1354
|
if (params.writablePerpMarketIndexes !== undefined) {
|
|
1292
1355
|
for (const writablePerpMarketIndex of params.writablePerpMarketIndexes) {
|
|
1293
|
-
|
|
1294
|
-
writablePerpMarketIndex
|
|
1356
|
+
this.addPerpMarketToRemainingAccountMaps(
|
|
1357
|
+
writablePerpMarketIndex,
|
|
1358
|
+
true,
|
|
1359
|
+
oracleAccountMap,
|
|
1360
|
+
spotMarketAccountMap,
|
|
1361
|
+
perpMarketAccountMap
|
|
1295
1362
|
);
|
|
1296
|
-
perpMarketAccountMap.set(writablePerpMarketIndex, {
|
|
1297
|
-
pubkey: perpMarketAccount.pubkey,
|
|
1298
|
-
isSigner: false,
|
|
1299
|
-
isWritable: true,
|
|
1300
|
-
});
|
|
1301
|
-
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
1302
|
-
pubkey: perpMarketAccount.amm.oracle,
|
|
1303
|
-
isSigner: false,
|
|
1304
|
-
isWritable: false,
|
|
1305
|
-
});
|
|
1306
|
-
const spotMarketAccount = this.getSpotMarketAccount(
|
|
1307
|
-
perpMarketAccount.quoteSpotMarketIndex
|
|
1308
|
-
);
|
|
1309
|
-
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
1310
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1311
|
-
isSigner: false,
|
|
1312
|
-
isWritable: false,
|
|
1313
|
-
});
|
|
1314
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1315
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1316
|
-
pubkey: spotMarketAccount.oracle,
|
|
1317
|
-
isSigner: false,
|
|
1318
|
-
isWritable: false,
|
|
1319
|
-
});
|
|
1320
|
-
}
|
|
1321
1363
|
}
|
|
1322
1364
|
}
|
|
1323
1365
|
|
|
1324
1366
|
if (params.writableSpotMarketIndexes !== undefined) {
|
|
1325
1367
|
for (const writableSpotMarketIndex of params.writableSpotMarketIndexes) {
|
|
1326
|
-
|
|
1327
|
-
writableSpotMarketIndex
|
|
1368
|
+
this.addSpotMarketToRemainingAccountMaps(
|
|
1369
|
+
writableSpotMarketIndex,
|
|
1370
|
+
true,
|
|
1371
|
+
oracleAccountMap,
|
|
1372
|
+
spotMarketAccountMap
|
|
1328
1373
|
);
|
|
1329
|
-
spotMarketAccountMap.set(spotMarketAccount.marketIndex, {
|
|
1330
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1331
|
-
isSigner: false,
|
|
1332
|
-
isWritable: true,
|
|
1333
|
-
});
|
|
1334
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1335
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1336
|
-
pubkey: spotMarketAccount.oracle,
|
|
1337
|
-
isSigner: false,
|
|
1338
|
-
isWritable: false,
|
|
1339
|
-
});
|
|
1340
|
-
}
|
|
1341
1374
|
}
|
|
1342
1375
|
}
|
|
1343
1376
|
|
|
@@ -1348,6 +1381,53 @@ export class DriftClient {
|
|
|
1348
1381
|
];
|
|
1349
1382
|
}
|
|
1350
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
|
+
|
|
1351
1431
|
getRemainingAccountMapsForUsers(userAccounts: UserAccount[]): {
|
|
1352
1432
|
oracleAccountMap: Map<string, AccountMeta>;
|
|
1353
1433
|
spotMarketAccountMap: Map<number, AccountMeta>;
|
|
@@ -1360,73 +1440,35 @@ export class DriftClient {
|
|
|
1360
1440
|
for (const userAccount of userAccounts) {
|
|
1361
1441
|
for (const spotPosition of userAccount.spotPositions) {
|
|
1362
1442
|
if (!isSpotPositionAvailable(spotPosition)) {
|
|
1363
|
-
|
|
1364
|
-
spotPosition.marketIndex
|
|
1443
|
+
this.addSpotMarketToRemainingAccountMaps(
|
|
1444
|
+
spotPosition.marketIndex,
|
|
1445
|
+
false,
|
|
1446
|
+
oracleAccountMap,
|
|
1447
|
+
spotMarketAccountMap
|
|
1365
1448
|
);
|
|
1366
|
-
spotMarketAccountMap.set(spotPosition.marketIndex, {
|
|
1367
|
-
pubkey: spotMarket.pubkey,
|
|
1368
|
-
isSigner: false,
|
|
1369
|
-
isWritable: false,
|
|
1370
|
-
});
|
|
1371
|
-
|
|
1372
|
-
if (!spotMarket.oracle.equals(PublicKey.default)) {
|
|
1373
|
-
oracleAccountMap.set(spotMarket.oracle.toString(), {
|
|
1374
|
-
pubkey: spotMarket.oracle,
|
|
1375
|
-
isSigner: false,
|
|
1376
|
-
isWritable: false,
|
|
1377
|
-
});
|
|
1378
|
-
}
|
|
1379
1449
|
|
|
1380
1450
|
if (
|
|
1381
1451
|
!spotPosition.openAsks.eq(ZERO) ||
|
|
1382
1452
|
!spotPosition.openBids.eq(ZERO)
|
|
1383
1453
|
) {
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
if (!quoteSpotMarket.oracle.equals(PublicKey.default)) {
|
|
1391
|
-
oracleAccountMap.set(quoteSpotMarket.oracle.toString(), {
|
|
1392
|
-
pubkey: quoteSpotMarket.oracle,
|
|
1393
|
-
isSigner: false,
|
|
1394
|
-
isWritable: false,
|
|
1395
|
-
});
|
|
1396
|
-
}
|
|
1454
|
+
this.addSpotMarketToRemainingAccountMaps(
|
|
1455
|
+
QUOTE_SPOT_MARKET_INDEX,
|
|
1456
|
+
false,
|
|
1457
|
+
oracleAccountMap,
|
|
1458
|
+
spotMarketAccountMap
|
|
1459
|
+
);
|
|
1397
1460
|
}
|
|
1398
1461
|
}
|
|
1399
1462
|
}
|
|
1400
1463
|
for (const position of userAccount.perpPositions) {
|
|
1401
1464
|
if (!positionIsAvailable(position)) {
|
|
1402
|
-
|
|
1403
|
-
position.marketIndex
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
isSigner: false,
|
|
1409
|
-
});
|
|
1410
|
-
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
1411
|
-
pubkey: perpMarketAccount.amm.oracle,
|
|
1412
|
-
isWritable: false,
|
|
1413
|
-
isSigner: false,
|
|
1414
|
-
});
|
|
1415
|
-
const spotMarketAccount = this.getSpotMarketAccount(
|
|
1416
|
-
perpMarketAccount.quoteSpotMarketIndex
|
|
1465
|
+
this.addPerpMarketToRemainingAccountMaps(
|
|
1466
|
+
position.marketIndex,
|
|
1467
|
+
false,
|
|
1468
|
+
oracleAccountMap,
|
|
1469
|
+
spotMarketAccountMap,
|
|
1470
|
+
perpMarketAccountMap
|
|
1417
1471
|
);
|
|
1418
|
-
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
1419
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1420
|
-
isSigner: false,
|
|
1421
|
-
isWritable: false,
|
|
1422
|
-
});
|
|
1423
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1424
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1425
|
-
pubkey: spotMarketAccount.oracle,
|
|
1426
|
-
isSigner: false,
|
|
1427
|
-
isWritable: false,
|
|
1428
|
-
});
|
|
1429
|
-
}
|
|
1430
1472
|
}
|
|
1431
1473
|
}
|
|
1432
1474
|
}
|
|
@@ -1630,7 +1672,7 @@ export class DriftClient {
|
|
|
1630
1672
|
}
|
|
1631
1673
|
}
|
|
1632
1674
|
|
|
1633
|
-
|
|
1675
|
+
public async getWrappedSolAccountCreationIxs(
|
|
1634
1676
|
amount: BN,
|
|
1635
1677
|
includeRent?: boolean
|
|
1636
1678
|
): Promise<{
|
|
@@ -1690,7 +1732,7 @@ export class DriftClient {
|
|
|
1690
1732
|
}
|
|
1691
1733
|
|
|
1692
1734
|
/**
|
|
1693
|
-
* Creates the
|
|
1735
|
+
* Creates the User account for a user, and deposits some initial collateral
|
|
1694
1736
|
* @param amount
|
|
1695
1737
|
* @param userTokenAccount
|
|
1696
1738
|
* @param marketIndex
|
|
@@ -2291,6 +2333,35 @@ export class DriftClient {
|
|
|
2291
2333
|
});
|
|
2292
2334
|
}
|
|
2293
2335
|
|
|
2336
|
+
public getQuoteValuePerLpShare(marketIndex: number): BN {
|
|
2337
|
+
const perpMarketAccount = this.getPerpMarketAccount(marketIndex);
|
|
2338
|
+
|
|
2339
|
+
const openBids = BN.max(
|
|
2340
|
+
perpMarketAccount.amm.baseAssetReserve.sub(
|
|
2341
|
+
perpMarketAccount.amm.minBaseAssetReserve
|
|
2342
|
+
),
|
|
2343
|
+
ZERO
|
|
2344
|
+
);
|
|
2345
|
+
|
|
2346
|
+
const openAsks = BN.max(
|
|
2347
|
+
perpMarketAccount.amm.maxBaseAssetReserve.sub(
|
|
2348
|
+
perpMarketAccount.amm.baseAssetReserve
|
|
2349
|
+
),
|
|
2350
|
+
ZERO
|
|
2351
|
+
);
|
|
2352
|
+
|
|
2353
|
+
const oraclePriceData = this.getOracleDataForPerpMarket(marketIndex);
|
|
2354
|
+
|
|
2355
|
+
const maxOpenBidsAsks = BN.max(openBids, openAsks);
|
|
2356
|
+
const quoteValuePerLpShare = maxOpenBidsAsks
|
|
2357
|
+
.mul(oraclePriceData.price)
|
|
2358
|
+
.mul(QUOTE_PRECISION)
|
|
2359
|
+
.div(PRICE_PRECISION)
|
|
2360
|
+
.div(perpMarketAccount.amm.sqrtK);
|
|
2361
|
+
|
|
2362
|
+
return quoteValuePerLpShare;
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2294
2365
|
/**
|
|
2295
2366
|
* @deprecated use {@link placePerpOrder} or {@link placeAndTakePerpOrder} instead
|
|
2296
2367
|
*/
|
|
@@ -2756,32 +2827,65 @@ export class DriftClient {
|
|
|
2756
2827
|
placeOrderParams: OrderParams[],
|
|
2757
2828
|
txParams?: TxParams
|
|
2758
2829
|
): Promise<TransactionSignature> {
|
|
2759
|
-
const
|
|
2830
|
+
const ixs = [
|
|
2760
2831
|
await this.getCancelOrdersIx(
|
|
2761
2832
|
cancelOrderParams.marketType,
|
|
2762
2833
|
cancelOrderParams.marketIndex,
|
|
2763
2834
|
cancelOrderParams.direction
|
|
2764
2835
|
),
|
|
2765
|
-
|
|
2766
|
-
|
|
2836
|
+
await this.getPlaceOrdersIx(placeOrderParams),
|
|
2837
|
+
];
|
|
2838
|
+
const tx = await this.buildTransaction(ixs, txParams);
|
|
2839
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
2840
|
+
return txSig;
|
|
2841
|
+
}
|
|
2842
|
+
|
|
2843
|
+
public async placeOrders(
|
|
2844
|
+
params: OrderParams[],
|
|
2845
|
+
txParams?: TxParams
|
|
2846
|
+
): Promise<TransactionSignature> {
|
|
2847
|
+
const { txSig } = await this.sendTransaction(
|
|
2848
|
+
await this.buildTransaction(
|
|
2849
|
+
await this.getPlaceOrdersIx(params),
|
|
2850
|
+
txParams
|
|
2851
|
+
),
|
|
2852
|
+
[],
|
|
2853
|
+
this.opts
|
|
2767
2854
|
);
|
|
2855
|
+
return txSig;
|
|
2856
|
+
}
|
|
2768
2857
|
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2858
|
+
public async getPlaceOrdersIx(
|
|
2859
|
+
params: OrderParams[]
|
|
2860
|
+
): Promise<TransactionInstruction> {
|
|
2861
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
2862
|
+
|
|
2863
|
+
const readablePerpMarketIndex: number[] = [];
|
|
2864
|
+
const readableSpotMarketIndexes: number[] = [];
|
|
2865
|
+
for (const param of params) {
|
|
2866
|
+
if (isVariant(param.marketType, 'perp')) {
|
|
2867
|
+
readablePerpMarketIndex.push(param.marketIndex);
|
|
2777
2868
|
} else {
|
|
2778
|
-
|
|
2869
|
+
readableSpotMarketIndexes.push(param.marketIndex);
|
|
2779
2870
|
}
|
|
2780
|
-
tx.add(ix);
|
|
2781
2871
|
}
|
|
2782
2872
|
|
|
2783
|
-
const
|
|
2784
|
-
|
|
2873
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2874
|
+
userAccounts: [this.getUserAccount()],
|
|
2875
|
+
readablePerpMarketIndex,
|
|
2876
|
+
readableSpotMarketIndexes,
|
|
2877
|
+
useMarketLastSlotCache: true,
|
|
2878
|
+
});
|
|
2879
|
+
|
|
2880
|
+
return await this.program.instruction.placeOrders(params, {
|
|
2881
|
+
accounts: {
|
|
2882
|
+
state: await this.getStatePublicKey(),
|
|
2883
|
+
user: userAccountPublicKey,
|
|
2884
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
2885
|
+
authority: this.wallet.publicKey,
|
|
2886
|
+
},
|
|
2887
|
+
remainingAccounts,
|
|
2888
|
+
});
|
|
2785
2889
|
}
|
|
2786
2890
|
|
|
2787
2891
|
public async fillPerpOrder(
|
|
@@ -3284,6 +3388,61 @@ export class DriftClient {
|
|
|
3284
3388
|
reduceOnly?: SwapReduceOnly;
|
|
3285
3389
|
txParams?: TxParams;
|
|
3286
3390
|
}): Promise<TransactionSignature> {
|
|
3391
|
+
const { ixs, lookupTables } = await this.getJupiterSwapIx({
|
|
3392
|
+
jupiterClient,
|
|
3393
|
+
outMarketIndex,
|
|
3394
|
+
inMarketIndex,
|
|
3395
|
+
outAssociatedTokenAccount,
|
|
3396
|
+
inAssociatedTokenAccount,
|
|
3397
|
+
amount,
|
|
3398
|
+
slippageBps,
|
|
3399
|
+
swapMode,
|
|
3400
|
+
route,
|
|
3401
|
+
reduceOnly,
|
|
3402
|
+
});
|
|
3403
|
+
|
|
3404
|
+
const tx = (await this.buildTransaction(
|
|
3405
|
+
ixs,
|
|
3406
|
+
txParams,
|
|
3407
|
+
0,
|
|
3408
|
+
lookupTables
|
|
3409
|
+
)) as VersionedTransaction;
|
|
3410
|
+
|
|
3411
|
+
const { txSig, slot } = await this.sendTransaction(tx);
|
|
3412
|
+
this.spotMarketLastSlotCache.set(outMarketIndex, slot);
|
|
3413
|
+
this.spotMarketLastSlotCache.set(inMarketIndex, slot);
|
|
3414
|
+
|
|
3415
|
+
return txSig;
|
|
3416
|
+
}
|
|
3417
|
+
|
|
3418
|
+
public async getJupiterSwapIx({
|
|
3419
|
+
jupiterClient,
|
|
3420
|
+
outMarketIndex,
|
|
3421
|
+
inMarketIndex,
|
|
3422
|
+
outAssociatedTokenAccount,
|
|
3423
|
+
inAssociatedTokenAccount,
|
|
3424
|
+
amount,
|
|
3425
|
+
slippageBps,
|
|
3426
|
+
swapMode,
|
|
3427
|
+
route,
|
|
3428
|
+
reduceOnly,
|
|
3429
|
+
userAccountPublicKey,
|
|
3430
|
+
}: {
|
|
3431
|
+
jupiterClient: JupiterClient;
|
|
3432
|
+
outMarketIndex: number;
|
|
3433
|
+
inMarketIndex: number;
|
|
3434
|
+
outAssociatedTokenAccount?: PublicKey;
|
|
3435
|
+
inAssociatedTokenAccount?: PublicKey;
|
|
3436
|
+
amount: BN;
|
|
3437
|
+
slippageBps?: number;
|
|
3438
|
+
swapMode?: SwapMode;
|
|
3439
|
+
route?: Route;
|
|
3440
|
+
reduceOnly?: SwapReduceOnly;
|
|
3441
|
+
userAccountPublicKey?: PublicKey;
|
|
3442
|
+
}): Promise<{
|
|
3443
|
+
ixs: TransactionInstruction[];
|
|
3444
|
+
lookupTables: AddressLookupTableAccount[];
|
|
3445
|
+
}> {
|
|
3287
3446
|
const outMarket = this.getSpotMarketAccount(outMarketIndex);
|
|
3288
3447
|
const inMarket = this.getSpotMarketAccount(inMarketIndex);
|
|
3289
3448
|
|
|
@@ -3370,27 +3529,17 @@ export class DriftClient {
|
|
|
3370
3529
|
inTokenAccount: inAssociatedTokenAccount,
|
|
3371
3530
|
outTokenAccount: outAssociatedTokenAccount,
|
|
3372
3531
|
reduceOnly,
|
|
3532
|
+
userAccountPublicKey,
|
|
3373
3533
|
});
|
|
3374
3534
|
|
|
3375
|
-
const
|
|
3535
|
+
const ixs = [
|
|
3376
3536
|
...preInstructions,
|
|
3377
3537
|
beginSwapIx,
|
|
3378
3538
|
...jupiterInstructions,
|
|
3379
3539
|
endSwapIx,
|
|
3380
3540
|
];
|
|
3381
3541
|
|
|
3382
|
-
|
|
3383
|
-
instructions,
|
|
3384
|
-
txParams,
|
|
3385
|
-
0,
|
|
3386
|
-
lookupTables
|
|
3387
|
-
)) as VersionedTransaction;
|
|
3388
|
-
|
|
3389
|
-
const { txSig, slot } = await this.sendTransaction(tx);
|
|
3390
|
-
this.spotMarketLastSlotCache.set(outMarketIndex, slot);
|
|
3391
|
-
this.spotMarketLastSlotCache.set(inMarketIndex, slot);
|
|
3392
|
-
|
|
3393
|
-
return txSig;
|
|
3542
|
+
return { ixs, lookupTables };
|
|
3394
3543
|
}
|
|
3395
3544
|
|
|
3396
3545
|
/**
|
|
@@ -3402,6 +3551,8 @@ export class DriftClient {
|
|
|
3402
3551
|
* @param inTokenAccount the token account to move the tokens being sold
|
|
3403
3552
|
* @param outTokenAccount the token account to receive the tokens being bought
|
|
3404
3553
|
* @param limitPrice the limit price of the swap
|
|
3554
|
+
* @param reduceOnly
|
|
3555
|
+
* @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
|
|
3405
3556
|
*/
|
|
3406
3557
|
public async getSwapIx({
|
|
3407
3558
|
outMarketIndex,
|
|
@@ -3411,6 +3562,7 @@ export class DriftClient {
|
|
|
3411
3562
|
outTokenAccount,
|
|
3412
3563
|
limitPrice,
|
|
3413
3564
|
reduceOnly,
|
|
3565
|
+
userAccountPublicKey,
|
|
3414
3566
|
}: {
|
|
3415
3567
|
outMarketIndex: number;
|
|
3416
3568
|
inMarketIndex: number;
|
|
@@ -3419,14 +3571,17 @@ export class DriftClient {
|
|
|
3419
3571
|
outTokenAccount: PublicKey;
|
|
3420
3572
|
limitPrice?: BN;
|
|
3421
3573
|
reduceOnly?: SwapReduceOnly;
|
|
3574
|
+
userAccountPublicKey?: PublicKey;
|
|
3422
3575
|
}): Promise<{
|
|
3423
3576
|
beginSwapIx: TransactionInstruction;
|
|
3424
3577
|
endSwapIx: TransactionInstruction;
|
|
3425
3578
|
}> {
|
|
3426
|
-
const
|
|
3579
|
+
const userAccountPublicKeyToUse =
|
|
3580
|
+
userAccountPublicKey || (await this.getUserAccountPublicKey());
|
|
3427
3581
|
|
|
3582
|
+
const userAccounts = this.hasUser() ? [this.getUserAccount()] : [];
|
|
3428
3583
|
const remainingAccounts = this.getRemainingAccounts({
|
|
3429
|
-
userAccounts
|
|
3584
|
+
userAccounts,
|
|
3430
3585
|
writableSpotMarketIndexes: [outMarketIndex, inMarketIndex],
|
|
3431
3586
|
});
|
|
3432
3587
|
|
|
@@ -3440,7 +3595,7 @@ export class DriftClient {
|
|
|
3440
3595
|
{
|
|
3441
3596
|
accounts: {
|
|
3442
3597
|
state: await this.getStatePublicKey(),
|
|
3443
|
-
user:
|
|
3598
|
+
user: userAccountPublicKeyToUse,
|
|
3444
3599
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
3445
3600
|
authority: this.authority,
|
|
3446
3601
|
outSpotMarketVault: outSpotMarket.vault,
|
|
@@ -3463,7 +3618,7 @@ export class DriftClient {
|
|
|
3463
3618
|
{
|
|
3464
3619
|
accounts: {
|
|
3465
3620
|
state: await this.getStatePublicKey(),
|
|
3466
|
-
user:
|
|
3621
|
+
user: userAccountPublicKeyToUse,
|
|
3467
3622
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
3468
3623
|
authority: this.authority,
|
|
3469
3624
|
outSpotMarketVault: outSpotMarket.vault,
|
|
@@ -3481,6 +3636,66 @@ export class DriftClient {
|
|
|
3481
3636
|
return { beginSwapIx, endSwapIx };
|
|
3482
3637
|
}
|
|
3483
3638
|
|
|
3639
|
+
public async stakeForMSOL({ amount }: { amount: BN }): Promise<TxSigAndSlot> {
|
|
3640
|
+
const ixs = await this.getStakeForMSOLIx({ amount });
|
|
3641
|
+
const tx = await this.buildTransaction(ixs);
|
|
3642
|
+
return this.sendTransaction(tx);
|
|
3643
|
+
}
|
|
3644
|
+
|
|
3645
|
+
public async getStakeForMSOLIx({
|
|
3646
|
+
amount,
|
|
3647
|
+
userAccountPublicKey,
|
|
3648
|
+
}: {
|
|
3649
|
+
amount: BN;
|
|
3650
|
+
userAccountPublicKey?: PublicKey;
|
|
3651
|
+
}): Promise<TransactionInstruction[]> {
|
|
3652
|
+
const wSOLMint = this.getSpotMarketAccount(1).mint;
|
|
3653
|
+
const mSOLAccount = await this.getAssociatedTokenAccount(2);
|
|
3654
|
+
const wSOLAccount = await this.getAssociatedTokenAccount(1, false);
|
|
3655
|
+
|
|
3656
|
+
const wSOLAccountExists = await this.checkIfAccountExists(wSOLAccount);
|
|
3657
|
+
|
|
3658
|
+
const closeWSOLIx = createCloseAccountInstruction(
|
|
3659
|
+
wSOLAccount,
|
|
3660
|
+
this.wallet.publicKey,
|
|
3661
|
+
this.wallet.publicKey
|
|
3662
|
+
);
|
|
3663
|
+
|
|
3664
|
+
const createWSOLIx =
|
|
3665
|
+
await this.createAssociatedTokenAccountIdempotentInstruction(
|
|
3666
|
+
wSOLAccount,
|
|
3667
|
+
this.wallet.publicKey,
|
|
3668
|
+
this.wallet.publicKey,
|
|
3669
|
+
wSOLMint
|
|
3670
|
+
);
|
|
3671
|
+
|
|
3672
|
+
const { beginSwapIx, endSwapIx } = await this.getSwapIx({
|
|
3673
|
+
inMarketIndex: 1,
|
|
3674
|
+
outMarketIndex: 2,
|
|
3675
|
+
amountIn: amount,
|
|
3676
|
+
inTokenAccount: wSOLAccount,
|
|
3677
|
+
outTokenAccount: mSOLAccount,
|
|
3678
|
+
userAccountPublicKey,
|
|
3679
|
+
});
|
|
3680
|
+
|
|
3681
|
+
const program = getMarinadeFinanceProgram(this.provider);
|
|
3682
|
+
const depositIx = await getMarinadeDepositIx({
|
|
3683
|
+
program,
|
|
3684
|
+
mSOLAccount: mSOLAccount,
|
|
3685
|
+
transferFrom: this.wallet.publicKey,
|
|
3686
|
+
amount,
|
|
3687
|
+
});
|
|
3688
|
+
|
|
3689
|
+
const ixs = [];
|
|
3690
|
+
|
|
3691
|
+
if (!wSOLAccountExists) {
|
|
3692
|
+
ixs.push(createWSOLIx);
|
|
3693
|
+
}
|
|
3694
|
+
ixs.push(beginSwapIx, closeWSOLIx, depositIx, createWSOLIx, endSwapIx);
|
|
3695
|
+
|
|
3696
|
+
return ixs;
|
|
3697
|
+
}
|
|
3698
|
+
|
|
3484
3699
|
public async triggerOrder(
|
|
3485
3700
|
userAccountPublicKey: PublicKey,
|
|
3486
3701
|
user: UserAccount,
|
|
@@ -5361,7 +5576,7 @@ export class DriftClient {
|
|
|
5361
5576
|
lookupTables?: AddressLookupTableAccount[]
|
|
5362
5577
|
): Promise<Transaction | VersionedTransaction> {
|
|
5363
5578
|
const allIx = [];
|
|
5364
|
-
const computeUnits = txParams?.computeUnits ??
|
|
5579
|
+
const computeUnits = txParams?.computeUnits ?? this.txParams.computeUnits;
|
|
5365
5580
|
if (computeUnits !== 200_000) {
|
|
5366
5581
|
allIx.push(
|
|
5367
5582
|
ComputeBudgetProgram.setComputeUnitLimit({
|
|
@@ -5369,7 +5584,8 @@ export class DriftClient {
|
|
|
5369
5584
|
})
|
|
5370
5585
|
);
|
|
5371
5586
|
}
|
|
5372
|
-
const computeUnitsPrice =
|
|
5587
|
+
const computeUnitsPrice =
|
|
5588
|
+
txParams?.computeUnitsPrice ?? this.txParams.computeUnitsPrice;
|
|
5373
5589
|
if (computeUnitsPrice !== 0) {
|
|
5374
5590
|
allIx.push(
|
|
5375
5591
|
ComputeBudgetProgram.setComputeUnitPrice({
|