@drift-labs/sdk 0.2.0-master.20 → 0.2.0-master.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/lib/accounts/types.d.ts +0 -1
- package/lib/clearingHouse.d.ts +2 -2
- package/lib/clearingHouse.js +25 -19
- package/lib/clearingHouseUser.d.ts +9 -1
- package/lib/clearingHouseUser.js +57 -20
- package/lib/math/orders.d.ts +2 -1
- package/lib/math/orders.js +14 -5
- package/lib/types.d.ts +3 -0
- package/my-script/.env +7 -0
- package/my-script/getUserStats.ts +124 -0
- package/my-script/multiConnections.ts +137 -0
- package/my-script/test-regex.ts +11 -0
- package/my-script/utils.ts +52 -0
- package/my-script/ww18NdhuLSQPCrHSx7V68eZJpe2y311heWeXJfSmP3Q.json +1 -0
- package/my-script/ww2z7N9TG1PLLUQGQF2VKzCFaPtQ5FBhRfeEAuy6c5C.json +1 -0
- package/my-script/ww3StJtTubhwssqAhvSSAc5ifCgKjzmF8hz7Gt2DmSa.json +1 -0
- package/package.json +1 -1
- package/src/clearingHouse.ts +27 -23
- package/src/clearingHouseUser.ts +67 -42
- package/src/math/orders.ts +26 -9
- package/src/types.ts +3 -0
- package/src/addresses/marketAddresses.js +0 -26
- package/src/assert/assert.js +0 -9
- package/src/constants/banks.js +0 -42
- package/src/constants/markets.js +0 -42
- package/src/constants/numericConstants.js +0 -41
- package/src/events/eventList.js +0 -77
- package/src/events/eventSubscriber.js +0 -139
- package/src/events/fetchLogs.js +0 -50
- package/src/events/pollingLogProvider.js +0 -64
- package/src/events/sort.js +0 -44
- package/src/events/txEventCache.js +0 -71
- package/src/events/webSocketLogProvider.js +0 -41
- package/src/examples/makeTradeExample.js +0 -80
- package/src/factory/bigNum.js +0 -390
- package/src/factory/oracleClient.js +0 -20
- package/src/math/auction.js +0 -42
- package/src/math/conversion.js +0 -11
- package/src/math/funding.js +0 -248
- package/src/math/oracles.js +0 -26
- package/src/math/repeg.js +0 -128
- package/src/math/state.js +0 -15
- package/src/math/trade.js +0 -253
- package/src/math/utils.js +0 -26
- package/src/math/utils.js.map +0 -1
- package/src/oracles/oracleClientCache.js +0 -19
- package/src/oracles/pythClient.js +0 -46
- package/src/oracles/quoteAssetOracleClient.js +0 -32
- package/src/oracles/switchboardClient.js +0 -69
- package/src/oracles/types.js +0 -2
- package/src/orderParams.js +0 -20
- package/src/slot/SlotSubscriber.js +0 -39
- package/src/token/index.js +0 -38
- package/src/tokenFaucet.js +0 -189
- package/src/tx/types.js +0 -2
- package/src/tx/utils.js +0 -17
- package/src/userName.js +0 -20
- package/src/util/computeUnits.js +0 -27
- package/src/util/getTokenAddress.js +0 -9
- package/src/util/promiseTimeout.js +0 -14
- package/src/util/tps.js +0 -27
- package/src/wallet.js +0 -35
package/lib/accounts/types.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="bn.js" />
|
|
3
|
-
/// <reference types="node" />
|
|
4
3
|
import { BankAccount, MarketAccount, OracleSource, StateAccount, UserAccount, UserStatsAccount } from '../types';
|
|
5
4
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
6
5
|
import { EventEmitter } from 'events';
|
package/lib/clearingHouse.d.ts
CHANGED
|
@@ -153,8 +153,8 @@ export declare class ClearingHouse {
|
|
|
153
153
|
getResolvePerpBankruptcyIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: BN): Promise<TransactionInstruction>;
|
|
154
154
|
resolveBorrowBankruptcy(userAccountPublicKey: PublicKey, userAccount: UserAccount, bankIndex: BN): Promise<TransactionSignature>;
|
|
155
155
|
getResolveBorrowBankruptcyIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, bankIndex: BN): Promise<TransactionInstruction>;
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
getRemainingAccountsWithCounterparty(params: {
|
|
157
|
+
counterPartyUserAccount: UserAccount;
|
|
158
158
|
writableMarketIndex?: BN;
|
|
159
159
|
writableBankIndexes?: BN[];
|
|
160
160
|
}): AccountMeta[];
|
package/lib/clearingHouse.js
CHANGED
|
@@ -133,9 +133,13 @@ class ClearingHouse {
|
|
|
133
133
|
* Forces the accountSubscriber to fetch account updates from rpc
|
|
134
134
|
*/
|
|
135
135
|
async fetchAccounts() {
|
|
136
|
-
|
|
136
|
+
const promises = [...this.users.values()]
|
|
137
137
|
.map((user) => user.fetchAccounts())
|
|
138
|
-
.concat(this.accountSubscriber.fetch())
|
|
138
|
+
.concat(this.accountSubscriber.fetch());
|
|
139
|
+
if (this.userStats) {
|
|
140
|
+
promises.concat(this.userStats.fetchAccounts());
|
|
141
|
+
}
|
|
142
|
+
await Promise.all(promises);
|
|
139
143
|
}
|
|
140
144
|
async unsubscribe() {
|
|
141
145
|
const unsubscribePromises = this.unsubscribeUsers().concat(this.accountSubscriber.unsubscribe());
|
|
@@ -1077,7 +1081,9 @@ class ClearingHouse {
|
|
|
1077
1081
|
orderParams = this.getOrderParams(orderParams);
|
|
1078
1082
|
const userStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
1079
1083
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1080
|
-
|
|
1084
|
+
// todo merge this with getRemainingAccounts
|
|
1085
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
1086
|
+
counterPartyUserAccount: takerInfo.takerUserAccount,
|
|
1081
1087
|
writableMarketIndex: orderParams.marketIndex,
|
|
1082
1088
|
});
|
|
1083
1089
|
if (referrerInfo) {
|
|
@@ -1216,9 +1222,9 @@ class ClearingHouse {
|
|
|
1216
1222
|
const userStatsPublicKey = (0, pda_1.getUserStatsAccountPublicKey)(this.program.programId, userAccount.authority);
|
|
1217
1223
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1218
1224
|
const liquidatorStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
1219
|
-
const remainingAccounts = this.
|
|
1225
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
1220
1226
|
writableMarketIndex: marketIndex,
|
|
1221
|
-
userAccount,
|
|
1227
|
+
counterPartyUserAccount: userAccount,
|
|
1222
1228
|
});
|
|
1223
1229
|
return await this.program.instruction.liquidatePerp(marketIndex, maxBaseAssetAmount, {
|
|
1224
1230
|
accounts: {
|
|
@@ -1238,8 +1244,8 @@ class ClearingHouse {
|
|
|
1238
1244
|
}
|
|
1239
1245
|
async getLiquidateBorrowIx(userAccountPublicKey, userAccount, assetBankIndex, liabilityBankIndex, maxLiabilityTransfer) {
|
|
1240
1246
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1241
|
-
const remainingAccounts = this.
|
|
1242
|
-
userAccount,
|
|
1247
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
1248
|
+
counterPartyUserAccount: userAccount,
|
|
1243
1249
|
writableBankIndexes: [liabilityBankIndex, assetBankIndex],
|
|
1244
1250
|
});
|
|
1245
1251
|
return await this.program.instruction.liquidateBorrow(assetBankIndex, liabilityBankIndex, maxLiabilityTransfer, {
|
|
@@ -1258,8 +1264,8 @@ class ClearingHouse {
|
|
|
1258
1264
|
}
|
|
1259
1265
|
async getLiquidateBorrowForPerpPnlIx(userAccountPublicKey, userAccount, perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer) {
|
|
1260
1266
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1261
|
-
const remainingAccounts = this.
|
|
1262
|
-
userAccount,
|
|
1267
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
1268
|
+
counterPartyUserAccount: userAccount,
|
|
1263
1269
|
writableMarketIndex: perpMarketIndex,
|
|
1264
1270
|
writableBankIndexes: [liabilityBankIndex],
|
|
1265
1271
|
});
|
|
@@ -1279,8 +1285,8 @@ class ClearingHouse {
|
|
|
1279
1285
|
}
|
|
1280
1286
|
async getLiquidatePerpPnlForDepositIx(userAccountPublicKey, userAccount, perpMarketIndex, assetBankIndex, maxPnlTransfer) {
|
|
1281
1287
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1282
|
-
const remainingAccounts = this.
|
|
1283
|
-
userAccount,
|
|
1288
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
1289
|
+
counterPartyUserAccount: userAccount,
|
|
1284
1290
|
writableMarketIndex: perpMarketIndex,
|
|
1285
1291
|
writableBankIndexes: [assetBankIndex],
|
|
1286
1292
|
});
|
|
@@ -1300,9 +1306,9 @@ class ClearingHouse {
|
|
|
1300
1306
|
}
|
|
1301
1307
|
async getResolvePerpBankruptcyIx(userAccountPublicKey, userAccount, marketIndex) {
|
|
1302
1308
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1303
|
-
const remainingAccounts = this.
|
|
1309
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
1304
1310
|
writableMarketIndex: marketIndex,
|
|
1305
|
-
userAccount,
|
|
1311
|
+
counterPartyUserAccount: userAccount,
|
|
1306
1312
|
});
|
|
1307
1313
|
return await this.program.instruction.resolvePerpBankruptcy(marketIndex, {
|
|
1308
1314
|
accounts: {
|
|
@@ -1320,9 +1326,9 @@ class ClearingHouse {
|
|
|
1320
1326
|
}
|
|
1321
1327
|
async getResolveBorrowBankruptcyIx(userAccountPublicKey, userAccount, bankIndex) {
|
|
1322
1328
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1323
|
-
const remainingAccounts = this.
|
|
1329
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
1324
1330
|
writableBankIndexes: [bankIndex],
|
|
1325
|
-
userAccount,
|
|
1331
|
+
counterPartyUserAccount: userAccount,
|
|
1326
1332
|
});
|
|
1327
1333
|
return await this.program.instruction.resolveBorrowBankruptcy(bankIndex, {
|
|
1328
1334
|
accounts: {
|
|
@@ -1334,12 +1340,12 @@ class ClearingHouse {
|
|
|
1334
1340
|
remainingAccounts: remainingAccounts,
|
|
1335
1341
|
});
|
|
1336
1342
|
}
|
|
1337
|
-
|
|
1338
|
-
const
|
|
1343
|
+
getRemainingAccountsWithCounterparty(params) {
|
|
1344
|
+
const counterPartyUserAccount = params.counterPartyUserAccount;
|
|
1339
1345
|
const oracleAccountMap = new Map();
|
|
1340
1346
|
const bankAccountMap = new Map();
|
|
1341
1347
|
const marketAccountMap = new Map();
|
|
1342
|
-
for (const bankBalance of
|
|
1348
|
+
for (const bankBalance of counterPartyUserAccount.bankBalances) {
|
|
1343
1349
|
if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
|
|
1344
1350
|
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
1345
1351
|
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
@@ -1356,7 +1362,7 @@ class ClearingHouse {
|
|
|
1356
1362
|
}
|
|
1357
1363
|
}
|
|
1358
1364
|
}
|
|
1359
|
-
for (const position of
|
|
1365
|
+
for (const position of counterPartyUserAccount.positions) {
|
|
1360
1366
|
if (!(0, position_1.positionIsAvailable)(position)) {
|
|
1361
1367
|
const market = this.getMarketAccount(position.marketIndex);
|
|
1362
1368
|
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
@@ -37,6 +37,7 @@ export declare class ClearingHouseUser {
|
|
|
37
37
|
*/
|
|
38
38
|
getUserPosition(marketIndex: BN): UserPosition | undefined;
|
|
39
39
|
getEmptyPosition(marketIndex: BN): UserPosition;
|
|
40
|
+
getClonedPosition(position: UserPosition): UserPosition;
|
|
40
41
|
/**
|
|
41
42
|
* @param orderId
|
|
42
43
|
* @returns Order
|
|
@@ -53,7 +54,7 @@ export declare class ClearingHouseUser {
|
|
|
53
54
|
* calculates the market position if the lp position was settled
|
|
54
55
|
* @returns : userPosition
|
|
55
56
|
*/
|
|
56
|
-
getSettledLPPosition(marketIndex: BN): [UserPosition, BN];
|
|
57
|
+
getSettledLPPosition(marketIndex: BN): [UserPosition, BN, BN];
|
|
57
58
|
/**
|
|
58
59
|
* calculates Buying Power = FC * MAX_LEVERAGE
|
|
59
60
|
* @returns : Precision QUOTE_PRECISION
|
|
@@ -64,6 +65,13 @@ export declare class ClearingHouseUser {
|
|
|
64
65
|
* @returns : Precision QUOTE_PRECISION
|
|
65
66
|
*/
|
|
66
67
|
getFreeCollateral(): BN;
|
|
68
|
+
/**
|
|
69
|
+
* @returns The margin requirement of a certain type (Initial or Maintenance) in USDC. : QUOTE_PRECISION
|
|
70
|
+
*/
|
|
71
|
+
getMarginRequirement(type: MarginCategory): BN;
|
|
72
|
+
/**
|
|
73
|
+
* @returns The initial margin requirement in USDC. : QUOTE_PRECISION
|
|
74
|
+
*/
|
|
67
75
|
getInitialMarginRequirement(): BN;
|
|
68
76
|
/**
|
|
69
77
|
* @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
|
package/lib/clearingHouseUser.js
CHANGED
|
@@ -78,6 +78,10 @@ class ClearingHouseUser {
|
|
|
78
78
|
lastNetQuoteAssetAmountPerLp: numericConstants_1.ZERO,
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
|
+
getClonedPosition(position) {
|
|
82
|
+
const clonedPosition = Object.assign({}, position);
|
|
83
|
+
return clonedPosition;
|
|
84
|
+
}
|
|
81
85
|
/**
|
|
82
86
|
* @param orderId
|
|
83
87
|
* @returns Order
|
|
@@ -104,7 +108,8 @@ class ClearingHouseUser {
|
|
|
104
108
|
* @returns : userPosition
|
|
105
109
|
*/
|
|
106
110
|
getSettledLPPosition(marketIndex) {
|
|
107
|
-
const
|
|
111
|
+
const _position = this.getUserPosition(marketIndex);
|
|
112
|
+
const position = this.getClonedPosition(_position);
|
|
108
113
|
const market = this.clearingHouse.getMarketAccount(position.marketIndex);
|
|
109
114
|
const nShares = position.lpShares;
|
|
110
115
|
const deltaBaa = market.amm.marketPositionPerLp.baseAssetAmount
|
|
@@ -180,7 +185,7 @@ class ClearingHouseUser {
|
|
|
180
185
|
else {
|
|
181
186
|
position.lastCumulativeFundingRate = numericConstants_1.ZERO;
|
|
182
187
|
}
|
|
183
|
-
return [position, pnl];
|
|
188
|
+
return [position, remainderBaa, pnl];
|
|
184
189
|
}
|
|
185
190
|
/**
|
|
186
191
|
* calculates Buying Power = FC * MAX_LEVERAGE
|
|
@@ -201,37 +206,69 @@ class ClearingHouseUser {
|
|
|
201
206
|
const freeCollateral = totalCollateral.sub(initialMarginRequirement);
|
|
202
207
|
return freeCollateral.gte(numericConstants_1.ZERO) ? freeCollateral : numericConstants_1.ZERO;
|
|
203
208
|
}
|
|
204
|
-
getInitialMarginRequirement() {
|
|
205
|
-
const postionMarginRequirement = this.getUserAccount().positions.reduce((marginRequirement, marketPosition) => {
|
|
206
|
-
const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
|
|
207
|
-
const worstCaseBaseAssetAmount = (0, margin_1.calculateWorstCaseBaseAssetAmount)(marketPosition);
|
|
208
|
-
const worstCaseAssetValue = worstCaseBaseAssetAmount
|
|
209
|
-
.abs()
|
|
210
|
-
.mul(this.getOracleDataForMarket(market.marketIndex).price)
|
|
211
|
-
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
|
|
212
|
-
const marketMarginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(market, worstCaseBaseAssetAmount.abs(), 'Initial'));
|
|
213
|
-
return marginRequirement.add(worstCaseAssetValue.mul(marketMarginRatio).div(numericConstants_1.MARGIN_PRECISION));
|
|
214
|
-
}, numericConstants_1.ZERO);
|
|
215
|
-
const bankMarginRequirement = this.getBankLiabilityValue(undefined, 'Initial');
|
|
216
|
-
return bankMarginRequirement.add(postionMarginRequirement);
|
|
217
|
-
}
|
|
218
209
|
/**
|
|
219
|
-
* @returns The
|
|
210
|
+
* @returns The margin requirement of a certain type (Initial or Maintenance) in USDC. : QUOTE_PRECISION
|
|
220
211
|
*/
|
|
221
|
-
|
|
212
|
+
getMarginRequirement(type) {
|
|
222
213
|
return this.getUserAccount()
|
|
223
214
|
.positions.reduce((marginRequirement, marketPosition) => {
|
|
224
215
|
const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
|
|
216
|
+
if (marketPosition.lpShares.gt(numericConstants_1.ZERO)) {
|
|
217
|
+
// is an lp
|
|
218
|
+
// clone so we dont mutate the position
|
|
219
|
+
marketPosition = this.getClonedPosition(marketPosition);
|
|
220
|
+
// settle position
|
|
221
|
+
const [settledPosition, dustBaa, _] = this.getSettledLPPosition(market.marketIndex);
|
|
222
|
+
marketPosition.baseAssetAmount =
|
|
223
|
+
settledPosition.baseAssetAmount.add(dustBaa);
|
|
224
|
+
marketPosition.quoteAssetAmount = settledPosition.quoteAssetAmount;
|
|
225
|
+
// open orders
|
|
226
|
+
let openAsks;
|
|
227
|
+
if (market.amm.maxBaseAssetReserve > market.amm.baseAssetReserve) {
|
|
228
|
+
openAsks = market.amm.maxBaseAssetReserve
|
|
229
|
+
.sub(market.amm.baseAssetReserve)
|
|
230
|
+
.mul(marketPosition.lpShares)
|
|
231
|
+
.div(market.amm.sqrtK)
|
|
232
|
+
.mul(new _1.BN(-1));
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
openAsks = numericConstants_1.ZERO;
|
|
236
|
+
}
|
|
237
|
+
let openBids;
|
|
238
|
+
if (market.amm.minBaseAssetReserve < market.amm.baseAssetReserve) {
|
|
239
|
+
openBids = market.amm.baseAssetReserve
|
|
240
|
+
.sub(market.amm.minBaseAssetReserve)
|
|
241
|
+
.mul(marketPosition.lpShares)
|
|
242
|
+
.div(market.amm.sqrtK);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
openBids = numericConstants_1.ZERO;
|
|
246
|
+
}
|
|
247
|
+
marketPosition.openAsks = marketPosition.openAsks.add(openAsks);
|
|
248
|
+
marketPosition.openBids = marketPosition.openBids.add(openBids);
|
|
249
|
+
}
|
|
225
250
|
const worstCaseBaseAssetAmount = (0, margin_1.calculateWorstCaseBaseAssetAmount)(marketPosition);
|
|
226
251
|
const worstCaseAssetValue = worstCaseBaseAssetAmount
|
|
227
252
|
.abs()
|
|
228
253
|
.mul(this.getOracleDataForMarket(market.marketIndex).price)
|
|
229
254
|
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
|
|
230
255
|
return marginRequirement.add(worstCaseAssetValue
|
|
231
|
-
.mul(new _1.BN((0, _1.calculateMarketMarginRatio)(market, worstCaseBaseAssetAmount.abs(),
|
|
256
|
+
.mul(new _1.BN((0, _1.calculateMarketMarginRatio)(market, worstCaseBaseAssetAmount.abs(), type)))
|
|
232
257
|
.div(numericConstants_1.MARGIN_PRECISION));
|
|
233
258
|
}, numericConstants_1.ZERO)
|
|
234
|
-
.add(this.getBankLiabilityValue(undefined,
|
|
259
|
+
.add(this.getBankLiabilityValue(undefined, type));
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* @returns The initial margin requirement in USDC. : QUOTE_PRECISION
|
|
263
|
+
*/
|
|
264
|
+
getInitialMarginRequirement() {
|
|
265
|
+
return this.getMarginRequirement('Initial');
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
|
|
269
|
+
*/
|
|
270
|
+
getMaintenanceMarginRequirement() {
|
|
271
|
+
return this.getMarginRequirement('Maintenance');
|
|
235
272
|
}
|
|
236
273
|
/**
|
|
237
274
|
* calculates unrealized position price pnl
|
package/lib/math/orders.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare function isOrderRiskIncreasingInSameDirection(user: ClearingHouse
|
|
|
8
8
|
export declare function isOrderReduceOnly(user: ClearingHouseUser, order: Order): boolean;
|
|
9
9
|
export declare function standardizeBaseAssetAmount(baseAssetAmount: BN, stepSize: BN): BN;
|
|
10
10
|
export declare function getLimitPrice(order: Order, market: MarketAccount, oraclePriceData: OraclePriceData, slot: number): BN;
|
|
11
|
-
export declare function isFillableByVAMM(order: Order, market: MarketAccount, oraclePriceData: OraclePriceData, slot: number): boolean;
|
|
11
|
+
export declare function isFillableByVAMM(order: Order, market: MarketAccount, oraclePriceData: OraclePriceData, slot: number, maxAuctionDuration: number): boolean;
|
|
12
12
|
export declare function calculateBaseAssetAmountForAmmToFulfill(order: Order, market: MarketAccount, oraclePriceData: OraclePriceData, slot: number): BN;
|
|
13
13
|
export declare function calculateBaseAssetAmountToFillUpToLimitPrice(order: Order, market: MarketAccount, limitPrice: BN, oraclePriceData: OraclePriceData): BN;
|
|
14
|
+
export declare function isOrderExpired(order: Order, slot: number, maxAuctionDuration: number): boolean;
|
package/lib/math/orders.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
3
|
+
exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const anchor_1 = require("@project-serum/anchor");
|
|
@@ -86,7 +86,7 @@ function getLimitPrice(order, market, oraclePriceData, slot) {
|
|
|
86
86
|
limitPrice = oraclePriceData.price.add(order.oraclePriceOffset);
|
|
87
87
|
}
|
|
88
88
|
else if ((0, types_1.isOneOfVariant)(order.orderType, ['market', 'triggerMarket'])) {
|
|
89
|
-
if ((0, auction_1.isAuctionComplete)(order, slot)) {
|
|
89
|
+
if (!(0, auction_1.isAuctionComplete)(order, slot)) {
|
|
90
90
|
limitPrice = (0, auction_1.getAuctionPrice)(order, slot);
|
|
91
91
|
}
|
|
92
92
|
else if (!order.price.eq(numericConstants_1.ZERO)) {
|
|
@@ -109,9 +109,10 @@ function getLimitPrice(order, market, oraclePriceData, slot) {
|
|
|
109
109
|
return limitPrice;
|
|
110
110
|
}
|
|
111
111
|
exports.getLimitPrice = getLimitPrice;
|
|
112
|
-
function isFillableByVAMM(order, market, oraclePriceData, slot) {
|
|
113
|
-
return ((0, auction_1.isAuctionComplete)(order, slot) &&
|
|
114
|
-
!calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot).eq(numericConstants_1.ZERO))
|
|
112
|
+
function isFillableByVAMM(order, market, oraclePriceData, slot, maxAuctionDuration) {
|
|
113
|
+
return (((0, auction_1.isAuctionComplete)(order, slot) &&
|
|
114
|
+
!calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot).eq(numericConstants_1.ZERO)) ||
|
|
115
|
+
isOrderExpired(order, slot, maxAuctionDuration));
|
|
115
116
|
}
|
|
116
117
|
exports.isFillableByVAMM = isFillableByVAMM;
|
|
117
118
|
function calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot) {
|
|
@@ -142,3 +143,11 @@ function isSameDirection(firstDirection, secondDirection) {
|
|
|
142
143
|
return (((0, types_1.isVariant)(firstDirection, 'long') && (0, types_1.isVariant)(secondDirection, 'long')) ||
|
|
143
144
|
((0, types_1.isVariant)(firstDirection, 'short') && (0, types_1.isVariant)(secondDirection, 'short')));
|
|
144
145
|
}
|
|
146
|
+
function isOrderExpired(order, slot, maxAuctionDuration) {
|
|
147
|
+
if (!(0, types_1.isVariant)(order.orderType, 'market') ||
|
|
148
|
+
!(0, types_1.isVariant)(order.status, 'open')) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
return new anchor_1.BN(slot).sub(order.slot).gt(new anchor_1.BN(maxAuctionDuration));
|
|
152
|
+
}
|
|
153
|
+
exports.isOrderExpired = isOrderExpired;
|
package/lib/types.d.ts
CHANGED
|
@@ -345,6 +345,8 @@ export declare type StateAccount = {
|
|
|
345
345
|
numberOfMarkets: BN;
|
|
346
346
|
numberOfBanks: BN;
|
|
347
347
|
minOrderQuoteAssetAmount: BN;
|
|
348
|
+
maxAuctionDuration: number;
|
|
349
|
+
minAuctionDuration: number;
|
|
348
350
|
};
|
|
349
351
|
export declare type MarketAccount = {
|
|
350
352
|
initialized: boolean;
|
|
@@ -597,6 +599,7 @@ export declare type MakerInfo = {
|
|
|
597
599
|
export declare type TakerInfo = {
|
|
598
600
|
taker: PublicKey;
|
|
599
601
|
takerStats: PublicKey;
|
|
602
|
+
takerUserAccount: UserAccount;
|
|
600
603
|
order: Order;
|
|
601
604
|
};
|
|
602
605
|
export declare type ReferrerInfo = {
|
package/my-script/.env
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#ANCHOR_WALLET=/Users/ww/.config/solana/id.json
|
|
2
|
+
|
|
3
|
+
#ANCHOR_WALLET=/Users/ww/.config/solana/bot2RzYy9oY5s3z71Yubo4MmRxyDBQP3qNNCqyqLcPp.json
|
|
4
|
+
|
|
5
|
+
ANCHOR_WALLET=./ww18NdhuLSQPCrHSx7V68eZJpe2y311heWeXJfSmP3Q.json
|
|
6
|
+
#ANCHOR_WALLET=./ww2z7N9TG1PLLUQGQF2VKzCFaPtQ5FBhRfeEAuy6c5C.json
|
|
7
|
+
#ANCHOR_WALLET=./ww3StJtTubhwssqAhvSSAc5ifCgKjzmF8hz7Gt2DmSa.json
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import * as anchor from '@project-serum/anchor';
|
|
2
|
+
// import { AnchorProvider } from '@project-serum/anchor';
|
|
3
|
+
import { PublicKey, clusterApiUrl } from '@solana/web3.js';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
DriftEnv,
|
|
7
|
+
initialize,
|
|
8
|
+
BN,
|
|
9
|
+
BulkAccountLoader,
|
|
10
|
+
convertToNumber,
|
|
11
|
+
calculateAdjustKCost,
|
|
12
|
+
calculateBidAskPrice,
|
|
13
|
+
EventSubscriber,
|
|
14
|
+
UserAccount,
|
|
15
|
+
DevnetBanks,
|
|
16
|
+
DevnetMarkets,
|
|
17
|
+
MARK_PRICE_PRECISION,
|
|
18
|
+
BASE_PRECISION,
|
|
19
|
+
QUOTE_PRECISION,
|
|
20
|
+
ClearingHouse,
|
|
21
|
+
getMarketOrderParams,
|
|
22
|
+
PositionDirection,
|
|
23
|
+
ZERO,
|
|
24
|
+
} from '..';
|
|
25
|
+
import { printUserStats } from './utils';
|
|
26
|
+
|
|
27
|
+
require('dotenv').config();
|
|
28
|
+
const driftEnv = process.env.ENV as DriftEnv;
|
|
29
|
+
|
|
30
|
+
function sleep(ms) {
|
|
31
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function main(provider: anchor.AnchorProvider) {
|
|
35
|
+
const connection = provider.connection;
|
|
36
|
+
const config = initialize({ env: 'devnet' });
|
|
37
|
+
const clearingHousePublicKey = new PublicKey(
|
|
38
|
+
config.CLEARING_HOUSE_PROGRAM_ID
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const bulkAccountLoader = new BulkAccountLoader(connection, 'confirmed', 1000);
|
|
42
|
+
const clearingHouse = new ClearingHouse({
|
|
43
|
+
connection,
|
|
44
|
+
wallet: provider.wallet,
|
|
45
|
+
programID: clearingHousePublicKey,
|
|
46
|
+
env: 'devnet',
|
|
47
|
+
// accountSubscription: {
|
|
48
|
+
// type: 'websocket',
|
|
49
|
+
// }
|
|
50
|
+
accountSubscription: {
|
|
51
|
+
type: 'polling',
|
|
52
|
+
accountLoader: bulkAccountLoader,
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
console.log(`clearingHouseProgramID: ${clearingHousePublicKey}`)
|
|
57
|
+
console.log(`provider.wallet: ${provider.wallet.publicKey.toBase58()}`)
|
|
58
|
+
|
|
59
|
+
const eventSubscriber = new EventSubscriber(connection, clearingHouse.program, {
|
|
60
|
+
maxTx: 8192,
|
|
61
|
+
maxEventsPerType: 4096,
|
|
62
|
+
orderBy: 'blockchain',
|
|
63
|
+
orderDir: 'desc',
|
|
64
|
+
commitment: 'confirmed',
|
|
65
|
+
logProviderConfig: {
|
|
66
|
+
type: 'websocket',
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (!(await clearingHouse.getUser().exists())) {
|
|
71
|
+
console.error(`ClearingHouseUser for ${provider.wallet.publicKey} does not exist`);
|
|
72
|
+
console.info(`Creating ClearingHouseUser for ${provider.wallet.publicKey}`);
|
|
73
|
+
const [txSig] = await clearingHouse.initializeUserAccount();
|
|
74
|
+
console.log(`Initialized user account in transaction: ${txSig}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!await clearingHouse.subscribe()) {
|
|
78
|
+
throw new Error("fail clearingHouse.subscribe");
|
|
79
|
+
}
|
|
80
|
+
if (!await clearingHouse.accountSubscriber.subscribe()) {
|
|
81
|
+
throw new Error("fail clearingHouse.accountSubscriber.subscribe");
|
|
82
|
+
}
|
|
83
|
+
if (!eventSubscriber.subscribe()) {
|
|
84
|
+
throw new Error("fail eventSubscriber.subscribe");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const chUser = clearingHouse.getUser();
|
|
88
|
+
const chUserAccount = clearingHouse.getUserAccount();
|
|
89
|
+
console.log(`chUserAcc.authority: ${chUserAccount!.authority.toBase58()}`);
|
|
90
|
+
console.log(` chUserAccount pubkey: ${chUser.userAccountPublicKey.toBase58()}`)
|
|
91
|
+
|
|
92
|
+
const keyToSymbol = new Map<string, string>();
|
|
93
|
+
const marketIndexToSymbol = new Map<number, string>();
|
|
94
|
+
for (const market of DevnetMarkets) {
|
|
95
|
+
keyToSymbol.set(market.oracle.toBase58(), market.baseAssetSymbol);
|
|
96
|
+
marketIndexToSymbol.set(market.marketIndex.toNumber(), market.symbol);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const run = async () => {
|
|
100
|
+
await clearingHouse.fetchAccounts();
|
|
101
|
+
await chUser.fetchAccounts();
|
|
102
|
+
printUserStats(chUserAccount!, marketIndexToSymbol);
|
|
103
|
+
}
|
|
104
|
+
await run();
|
|
105
|
+
setInterval(run, 1000);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
if (!process.env.ANCHOR_WALLET) {
|
|
111
|
+
throw new Error('ANCHOR_WALLET must be set.');
|
|
112
|
+
}
|
|
113
|
+
main(
|
|
114
|
+
anchor.AnchorProvider.local(clusterApiUrl("devnet"), {
|
|
115
|
+
// anchor.AnchorProvider.local('https://devnet.genesysgo.net', {
|
|
116
|
+
preflightCommitment: 'confirmed',
|
|
117
|
+
skipPreflight: false,
|
|
118
|
+
commitment: 'confirmed',
|
|
119
|
+
})
|
|
120
|
+
);
|
|
121
|
+
// anchor.AnchorProvider.local('https://psytrbhymqlkfrhudd.dev.genesysgo.net:8899/');
|
|
122
|
+
} catch (e) {
|
|
123
|
+
console.error(e);
|
|
124
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import * as anchor from '@project-serum/anchor';
|
|
2
|
+
// import { AnchorProvider } from '@project-serum/anchor';
|
|
3
|
+
import { PublicKey, clusterApiUrl } from '@solana/web3.js';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
DriftEnv,
|
|
7
|
+
initialize,
|
|
8
|
+
BN,
|
|
9
|
+
BulkAccountLoader,
|
|
10
|
+
convertToNumber,
|
|
11
|
+
calculateAdjustKCost,
|
|
12
|
+
calculateBidAskPrice,
|
|
13
|
+
EventSubscriber,
|
|
14
|
+
UserAccount,
|
|
15
|
+
DevnetBanks,
|
|
16
|
+
DevnetMarkets,
|
|
17
|
+
MARK_PRICE_PRECISION,
|
|
18
|
+
BASE_PRECISION,
|
|
19
|
+
QUOTE_PRECISION,
|
|
20
|
+
ClearingHouse,
|
|
21
|
+
getMarketOrderParams,
|
|
22
|
+
PositionDirection,
|
|
23
|
+
ZERO,
|
|
24
|
+
} from '..';
|
|
25
|
+
import { printUserStats } from './utils';
|
|
26
|
+
|
|
27
|
+
require('dotenv').config();
|
|
28
|
+
const driftEnv = process.env.ENV as DriftEnv;
|
|
29
|
+
|
|
30
|
+
function sleep(ms) {
|
|
31
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function main(provider: anchor.AnchorProvider) {
|
|
35
|
+
const connection = provider.connection;
|
|
36
|
+
const config = initialize({ env: 'devnet' });
|
|
37
|
+
const clearingHousePublicKey = new PublicKey(
|
|
38
|
+
config.CLEARING_HOUSE_PROGRAM_ID
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const bulkAccountLoader = new BulkAccountLoader(
|
|
42
|
+
connection,
|
|
43
|
+
'confirmed',
|
|
44
|
+
1000
|
|
45
|
+
);
|
|
46
|
+
const clearingHouse = new ClearingHouse({
|
|
47
|
+
connection,
|
|
48
|
+
wallet: provider.wallet,
|
|
49
|
+
programID: clearingHousePublicKey,
|
|
50
|
+
env: 'devnet',
|
|
51
|
+
// accountSubscription: {
|
|
52
|
+
// type: 'websocket',
|
|
53
|
+
// }
|
|
54
|
+
accountSubscription: {
|
|
55
|
+
type: 'polling',
|
|
56
|
+
accountLoader: bulkAccountLoader,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
console.log(`clearingHouseProgramID: ${clearingHousePublicKey}`);
|
|
61
|
+
console.log(
|
|
62
|
+
`provider.wallet: ${provider.wallet.publicKey.toBase58()}`
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const eventSubscriber = new EventSubscriber(
|
|
66
|
+
connection,
|
|
67
|
+
clearingHouse.program,
|
|
68
|
+
{
|
|
69
|
+
maxTx: 8192,
|
|
70
|
+
maxEventsPerType: 4096,
|
|
71
|
+
orderBy: 'blockchain',
|
|
72
|
+
orderDir: 'desc',
|
|
73
|
+
commitment: 'confirmed',
|
|
74
|
+
logProviderConfig: {
|
|
75
|
+
type: 'websocket',
|
|
76
|
+
},
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
if (!(await clearingHouse.getUser().exists())) {
|
|
81
|
+
console.error(
|
|
82
|
+
`ClearingHouseUser for ${provider.wallet.publicKey} does not exist`
|
|
83
|
+
);
|
|
84
|
+
console.info(`Creating ClearingHouseUser for ${provider.wallet.publicKey}`);
|
|
85
|
+
const [txSig] = await clearingHouse.initializeUserAccount();
|
|
86
|
+
console.log(`Initialized user account in transaction: ${txSig}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!(await clearingHouse.subscribe())) {
|
|
90
|
+
throw new Error('fail clearingHouse.subscribe');
|
|
91
|
+
}
|
|
92
|
+
if (!(await clearingHouse.accountSubscriber.subscribe())) {
|
|
93
|
+
throw new Error('fail clearingHouse.accountSubscriber.subscribe');
|
|
94
|
+
}
|
|
95
|
+
if (!eventSubscriber.subscribe()) {
|
|
96
|
+
throw new Error('fail eventSubscriber.subscribe');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const chUser = clearingHouse.getUser();
|
|
100
|
+
const chUserAccount = clearingHouse.getUserAccount();
|
|
101
|
+
console.log(`chUserAcc.authority: ${chUserAccount!.authority.toBase58()}`);
|
|
102
|
+
console.log(
|
|
103
|
+
` chUserAccount pubkey: ${chUser.userAccountPublicKey.toBase58()}`
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const keyToSymbol = new Map<string, string>();
|
|
107
|
+
const marketIndexToSymbol = new Map<number, string>();
|
|
108
|
+
for (const market of DevnetMarkets) {
|
|
109
|
+
keyToSymbol.set(market.oracle.toBase58(), market.baseAssetSymbol);
|
|
110
|
+
marketIndexToSymbol.set(market.marketIndex.toNumber(), market.symbol);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const run = async () => {
|
|
114
|
+
await clearingHouse.fetchAccounts();
|
|
115
|
+
await chUser.fetchAccounts();
|
|
116
|
+
printUserStats(chUserAccount!, marketIndexToSymbol);
|
|
117
|
+
};
|
|
118
|
+
await run();
|
|
119
|
+
setInterval(run, 1000);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
if (!process.env.ANCHOR_WALLET) {
|
|
124
|
+
throw new Error('ANCHOR_WALLET must be set.');
|
|
125
|
+
}
|
|
126
|
+
main(
|
|
127
|
+
anchor.AnchorProvider.local(clusterApiUrl('devnet'), {
|
|
128
|
+
// anchor.AnchorProvider.local('https://devnet.genesysgo.net', {
|
|
129
|
+
preflightCommitment: 'confirmed',
|
|
130
|
+
skipPreflight: false,
|
|
131
|
+
commitment: 'confirmed',
|
|
132
|
+
})
|
|
133
|
+
);
|
|
134
|
+
// anchor.AnchorProvider.local('https://psytrbhymqlkfrhudd.dev.genesysgo.net:8899/');
|
|
135
|
+
} catch (e) {
|
|
136
|
+
console.error(e);
|
|
137
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
try {
|
|
2
|
+
// const msg = 'Program 65sz7dRiWDRPZjiRxcTxPM7AE6VK4Nag9HEK6oBJXhJn failed: custom program error: 0x179e'
|
|
3
|
+
const msg = 'Program log: AnchorError occurred. Error Code: OrderDoesNotExist. Error Number: 6046. Error Message: Order does not exist.'
|
|
4
|
+
const code = msg.match(
|
|
5
|
+
/Program log: AnchorError occurred. Error Code: ([0-9,a-z,A-Z]+). Error Number/
|
|
6
|
+
);
|
|
7
|
+
console.log(code[1]);
|
|
8
|
+
} catch (e) {
|
|
9
|
+
console.log("nothing");
|
|
10
|
+
// no problem if couldn't match error code
|
|
11
|
+
}
|