@drift-labs/sdk 0.1.29-master.1 → 0.1.30-master.1
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/bulkAccountLoader.d.ts +2 -1
- package/lib/accounts/bulkAccountLoader.js +44 -32
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +15 -0
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +50 -23
- package/lib/clearingHouse.d.ts +4 -2
- package/lib/clearingHouse.js +49 -14
- package/lib/constants/accounts.d.ts +15 -0
- package/lib/constants/accounts.js +18 -0
- package/lib/constants/markets.js +11 -0
- package/lib/factory/clearingHouse.d.ts +14 -4
- package/lib/factory/clearingHouse.js +23 -6
- package/lib/idl/clearing_house.json +53 -33
- package/lib/math/amm.d.ts +18 -0
- package/lib/math/amm.js +88 -1
- package/lib/oracles/pythClient.js +1 -1
- package/lib/orderParams.d.ts +1 -1
- package/lib/orderParams.js +2 -2
- package/lib/tx/retryTxSender.d.ts +5 -2
- package/lib/tx/retryTxSender.js +14 -1
- package/lib/util/promiseTimeout.d.ts +1 -0
- package/lib/util/promiseTimeout.js +14 -0
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.ts +51 -40
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +73 -30
- package/src/clearingHouse.ts +71 -13
- package/src/constants/accounts.ts +26 -0
- package/src/constants/markets.ts +11 -0
- package/src/factory/clearingHouse.ts +47 -7
- package/src/idl/clearing_house.json +53 -33
- package/src/math/amm.ts +127 -2
- package/src/oracles/pythClient.ts +1 -1
- package/src/orderParams.ts +3 -2
- package/src/tx/retryTxSender.ts +19 -1
- package/src/util/promiseTimeout.ts +14 -0
- package/lib/math/repeg.d.ts +0 -32
- package/lib/math/repeg.js +0 -178
- package/src/accounts/bulkUserSubscription.js +0 -56
- package/src/accounts/bulkUserSubscription.js.map +0 -1
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -210
- package/src/accounts/pollingClearingHouseAccountSubscriber.js.map +0 -1
- package/src/accounts/pollingOracleSubscriber.js +0 -65
- package/src/accounts/pollingOracleSubscriber.js.map +0 -1
- package/src/accounts/pollingTokenAccountSubscriber.js +0 -65
- package/src/accounts/pollingTokenAccountSubscriber.js.map +0 -1
- package/src/accounts/pollingUserAccountSubscriber.js +0 -139
- package/src/accounts/pollingUserAccountSubscriber.js.map +0 -1
- package/src/accounts/types.js +0 -11
- package/src/accounts/types.js.map +0 -1
- package/src/accounts/utils.js +0 -8
- package/src/accounts/utils.js.map +0 -1
- package/src/accounts/webSocketAccountSubscriber.js +0 -64
- package/src/accounts/webSocketAccountSubscriber.js.map +0 -1
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -212
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js.map +0 -1
- package/src/accounts/webSocketUserAccountSubscriber.js +0 -78
- package/src/accounts/webSocketUserAccountSubscriber.js.map +0 -1
- package/src/constants/markets.js +0 -167
- package/src/constants/markets.js.map +0 -1
- package/src/constants/numericConstants.js +0 -22
- package/src/constants/numericConstants.js.map +0 -1
- package/src/factory/clearingHouse.js +0 -65
- package/src/factory/clearingHouse.js.map +0 -1
- package/src/factory/clearingHouseUser.js +0 -35
- package/src/factory/clearingHouseUser.js.map +0 -1
- package/src/factory/oracleClient.js +0 -17
- package/src/factory/oracleClient.js.map +0 -1
- package/src/math/amm.js +0 -285
- package/src/math/amm.js.map +0 -1
- package/src/math/repeg.ts +0 -253
- package/src/oracles/pythClient.js +0 -39
- package/src/oracles/pythClient.js.map +0 -1
- package/src/tx/retryTxSender.js +0 -137
- package/src/tx/retryTxSender.js.map +0 -1
|
@@ -11,18 +11,19 @@ const webSocketClearingHouseAccountSubscriber_1 = require("../accounts/webSocket
|
|
|
11
11
|
const defaultTxSender_1 = require("../tx/defaultTxSender");
|
|
12
12
|
const pollingClearingHouseAccountSubscriber_1 = require("../accounts/pollingClearingHouseAccountSubscriber");
|
|
13
13
|
const admin_1 = require("../admin");
|
|
14
|
-
|
|
14
|
+
const retryTxSender_1 = require("../tx/retryTxSender");
|
|
15
|
+
function getWebSocketClearingHouseConfig(connection, wallet, programID, opts = anchor_1.Provider.defaultOptions(), txSenderConfig) {
|
|
15
16
|
return {
|
|
16
17
|
type: 'websocket',
|
|
17
18
|
connection,
|
|
18
19
|
wallet,
|
|
19
20
|
programID,
|
|
20
21
|
opts,
|
|
21
|
-
|
|
22
|
+
txSenderConfig,
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
25
|
exports.getWebSocketClearingHouseConfig = getWebSocketClearingHouseConfig;
|
|
25
|
-
function getPollingClearingHouseConfig(connection, wallet, programID, accountLoader, opts = anchor_1.Provider.defaultOptions(),
|
|
26
|
+
function getPollingClearingHouseConfig(connection, wallet, programID, accountLoader, opts = anchor_1.Provider.defaultOptions(), txSenderConfig) {
|
|
26
27
|
return {
|
|
27
28
|
type: 'polling',
|
|
28
29
|
connection,
|
|
@@ -30,11 +31,12 @@ function getPollingClearingHouseConfig(connection, wallet, programID, accountLoa
|
|
|
30
31
|
programID,
|
|
31
32
|
accountLoader,
|
|
32
33
|
opts,
|
|
33
|
-
|
|
34
|
+
txSenderConfig,
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
37
|
exports.getPollingClearingHouseConfig = getPollingClearingHouseConfig;
|
|
37
38
|
function getClearingHouse(config) {
|
|
39
|
+
var _a;
|
|
38
40
|
const provider = new anchor_1.Provider(config.connection, config.wallet, config.opts);
|
|
39
41
|
const program = new anchor_1.Program(clearing_house_json_1.default, config.programID, provider);
|
|
40
42
|
let accountSubscriber;
|
|
@@ -44,11 +46,19 @@ function getClearingHouse(config) {
|
|
|
44
46
|
else if (config.type === 'polling') {
|
|
45
47
|
accountSubscriber = new pollingClearingHouseAccountSubscriber_1.PollingClearingHouseAccountSubscriber(program, config.accountLoader);
|
|
46
48
|
}
|
|
47
|
-
|
|
49
|
+
let txSender;
|
|
50
|
+
if (((_a = config.txSenderConfig) === null || _a === void 0 ? void 0 : _a.type) === 'retry') {
|
|
51
|
+
const txSenderConfig = config.txSenderConfig;
|
|
52
|
+
txSender = new retryTxSender_1.RetryTxSender(provider, txSenderConfig.timeout, txSenderConfig.retrySleep, txSenderConfig.additionalConnections);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
txSender = new defaultTxSender_1.DefaultTxSender(provider);
|
|
56
|
+
}
|
|
48
57
|
return new clearingHouse_1.ClearingHouse(config.connection, config.wallet, program, accountSubscriber, txSender, config.opts);
|
|
49
58
|
}
|
|
50
59
|
exports.getClearingHouse = getClearingHouse;
|
|
51
60
|
function getAdmin(config) {
|
|
61
|
+
var _a;
|
|
52
62
|
const provider = new anchor_1.Provider(config.connection, config.wallet, config.opts);
|
|
53
63
|
const program = new anchor_1.Program(clearing_house_json_1.default, config.programID, provider);
|
|
54
64
|
let accountSubscriber;
|
|
@@ -58,7 +68,14 @@ function getAdmin(config) {
|
|
|
58
68
|
else if (config.type === 'polling') {
|
|
59
69
|
accountSubscriber = new pollingClearingHouseAccountSubscriber_1.PollingClearingHouseAccountSubscriber(program, config.accountLoader);
|
|
60
70
|
}
|
|
61
|
-
|
|
71
|
+
let txSender;
|
|
72
|
+
if (((_a = config.txSenderConfig) === null || _a === void 0 ? void 0 : _a.type) === 'retry') {
|
|
73
|
+
const txSenderConfig = config.txSenderConfig;
|
|
74
|
+
txSender = new retryTxSender_1.RetryTxSender(provider, txSenderConfig.timeout, txSenderConfig.retrySleep, txSenderConfig.additionalConnections);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
txSender = new defaultTxSender_1.DefaultTxSender(provider);
|
|
78
|
+
}
|
|
62
79
|
return new admin_1.Admin(config.connection, config.wallet, program, accountSubscriber, txSender, config.opts);
|
|
63
80
|
}
|
|
64
81
|
exports.getAdmin = getAdmin;
|
|
@@ -677,6 +677,57 @@
|
|
|
677
677
|
}
|
|
678
678
|
]
|
|
679
679
|
},
|
|
680
|
+
{
|
|
681
|
+
"name": "cancelAllOrders",
|
|
682
|
+
"accounts": [
|
|
683
|
+
{
|
|
684
|
+
"name": "state",
|
|
685
|
+
"isMut": false,
|
|
686
|
+
"isSigner": false
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
"name": "orderState",
|
|
690
|
+
"isMut": false,
|
|
691
|
+
"isSigner": false
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
"name": "user",
|
|
695
|
+
"isMut": false,
|
|
696
|
+
"isSigner": false
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
"name": "authority",
|
|
700
|
+
"isMut": false,
|
|
701
|
+
"isSigner": true
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
"name": "markets",
|
|
705
|
+
"isMut": false,
|
|
706
|
+
"isSigner": false
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
"name": "userPositions",
|
|
710
|
+
"isMut": true,
|
|
711
|
+
"isSigner": false
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
"name": "userOrders",
|
|
715
|
+
"isMut": true,
|
|
716
|
+
"isSigner": false
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
"name": "fundingPaymentHistory",
|
|
720
|
+
"isMut": true,
|
|
721
|
+
"isSigner": false
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
"name": "orderHistory",
|
|
725
|
+
"isMut": true,
|
|
726
|
+
"isSigner": false
|
|
727
|
+
}
|
|
728
|
+
],
|
|
729
|
+
"args": []
|
|
730
|
+
},
|
|
680
731
|
{
|
|
681
732
|
"name": "expireOrders",
|
|
682
733
|
"accounts": [
|
|
@@ -1431,32 +1482,6 @@
|
|
|
1431
1482
|
}
|
|
1432
1483
|
]
|
|
1433
1484
|
},
|
|
1434
|
-
{
|
|
1435
|
-
"name": "deleteUser",
|
|
1436
|
-
"accounts": [
|
|
1437
|
-
{
|
|
1438
|
-
"name": "user",
|
|
1439
|
-
"isMut": true,
|
|
1440
|
-
"isSigner": false
|
|
1441
|
-
},
|
|
1442
|
-
{
|
|
1443
|
-
"name": "userPositions",
|
|
1444
|
-
"isMut": true,
|
|
1445
|
-
"isSigner": false
|
|
1446
|
-
},
|
|
1447
|
-
{
|
|
1448
|
-
"name": "userOrders",
|
|
1449
|
-
"isMut": true,
|
|
1450
|
-
"isSigner": false
|
|
1451
|
-
},
|
|
1452
|
-
{
|
|
1453
|
-
"name": "authority",
|
|
1454
|
-
"isMut": false,
|
|
1455
|
-
"isSigner": true
|
|
1456
|
-
}
|
|
1457
|
-
],
|
|
1458
|
-
"args": []
|
|
1459
|
-
},
|
|
1460
1485
|
{
|
|
1461
1486
|
"name": "settleFundingPayment",
|
|
1462
1487
|
"accounts": [
|
|
@@ -3241,8 +3266,8 @@
|
|
|
3241
3266
|
"type": "u128"
|
|
3242
3267
|
},
|
|
3243
3268
|
{
|
|
3244
|
-
"name": "
|
|
3245
|
-
"type": "
|
|
3269
|
+
"name": "padding1",
|
|
3270
|
+
"type": "u64"
|
|
3246
3271
|
},
|
|
3247
3272
|
{
|
|
3248
3273
|
"name": "padding2",
|
|
@@ -4249,11 +4274,6 @@
|
|
|
4249
4274
|
"code": 6060,
|
|
4250
4275
|
"name": "CantExpireOrders",
|
|
4251
4276
|
"msg": "CantExpireOrders"
|
|
4252
|
-
},
|
|
4253
|
-
{
|
|
4254
|
-
"code": 6061,
|
|
4255
|
-
"name": "InvalidRepegPriceImpact",
|
|
4256
|
-
"msg": "AMM repeg mark price impact vs oracle too large"
|
|
4257
4277
|
}
|
|
4258
4278
|
]
|
|
4259
4279
|
}
|
package/lib/math/amm.d.ts
CHANGED
|
@@ -38,6 +38,24 @@ export declare function calculateSwapOutput(inputAssetReserve: BN, swapAmount: B
|
|
|
38
38
|
* @param positionDirection
|
|
39
39
|
*/
|
|
40
40
|
export declare function getSwapDirection(inputAssetType: AssetType, positionDirection: PositionDirection): SwapDirection;
|
|
41
|
+
/**
|
|
42
|
+
* Helper function calculating adjust k cost
|
|
43
|
+
* @param market
|
|
44
|
+
* @param marketIndex
|
|
45
|
+
* @param numerator
|
|
46
|
+
* @param denomenator
|
|
47
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
48
|
+
*/
|
|
49
|
+
export declare function calculateAdjustKCost(market: Market, marketIndex: BN, numerator: BN, denomenator: BN): BN;
|
|
50
|
+
/**
|
|
51
|
+
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
52
|
+
*
|
|
53
|
+
* @param market
|
|
54
|
+
* @param marketIndex
|
|
55
|
+
* @param newPeg
|
|
56
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
57
|
+
*/
|
|
58
|
+
export declare function calculateRepegCost(market: Market, marketIndex: BN, newPeg: BN): BN;
|
|
41
59
|
/**
|
|
42
60
|
* Helper function calculating terminal price of amm
|
|
43
61
|
*
|
package/lib/math/amm.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateBudgetedPeg = exports.calculateBudgetedK = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = void 0;
|
|
3
|
+
exports.calculateBudgetedPeg = exports.calculateBudgetedK = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.calculateRepegCost = exports.calculateAdjustKCost = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = void 0;
|
|
4
4
|
const anchor_1 = require("@project-serum/anchor");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
|
+
const position_1 = require("./position");
|
|
6
7
|
const types_1 = require("../types");
|
|
7
8
|
const assert_1 = require("../assert/assert");
|
|
8
9
|
const __1 = require("..");
|
|
@@ -87,6 +88,92 @@ function getSwapDirection(inputAssetType, positionDirection) {
|
|
|
87
88
|
return types_1.SwapDirection.ADD;
|
|
88
89
|
}
|
|
89
90
|
exports.getSwapDirection = getSwapDirection;
|
|
91
|
+
/**
|
|
92
|
+
* Helper function calculating adjust k cost
|
|
93
|
+
* @param market
|
|
94
|
+
* @param marketIndex
|
|
95
|
+
* @param numerator
|
|
96
|
+
* @param denomenator
|
|
97
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
98
|
+
*/
|
|
99
|
+
function calculateAdjustKCost(market, marketIndex, numerator, denomenator) {
|
|
100
|
+
const netUserPosition = {
|
|
101
|
+
baseAssetAmount: market.baseAssetAmount,
|
|
102
|
+
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
103
|
+
marketIndex: new anchor_1.BN(marketIndex),
|
|
104
|
+
quoteAssetAmount: new anchor_1.BN(0),
|
|
105
|
+
openOrders: new anchor_1.BN(0),
|
|
106
|
+
};
|
|
107
|
+
const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
|
|
108
|
+
const marketNewK = Object.assign({}, market);
|
|
109
|
+
marketNewK.amm = Object.assign({}, market.amm);
|
|
110
|
+
marketNewK.amm.baseAssetReserve = market.amm.baseAssetReserve
|
|
111
|
+
.mul(numerator)
|
|
112
|
+
.div(denomenator);
|
|
113
|
+
marketNewK.amm.quoteAssetReserve = market.amm.quoteAssetReserve
|
|
114
|
+
.mul(numerator)
|
|
115
|
+
.div(denomenator);
|
|
116
|
+
marketNewK.amm.sqrtK = market.amm.sqrtK.mul(numerator).div(denomenator);
|
|
117
|
+
netUserPosition.quoteAssetAmount = currentValue;
|
|
118
|
+
const cost = (0, __1.calculatePositionPNL)(marketNewK, netUserPosition);
|
|
119
|
+
const p = numericConstants_1.PEG_PRECISION.mul(numerator).div(denomenator);
|
|
120
|
+
const x = market.amm.baseAssetReserve;
|
|
121
|
+
const y = market.amm.quoteAssetReserve;
|
|
122
|
+
const delta = market.baseAssetAmount;
|
|
123
|
+
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
124
|
+
const numer1 = numericConstants_1.PEG_PRECISION.sub(p).mul(y).div(numericConstants_1.PEG_PRECISION);
|
|
125
|
+
const numer20 = k
|
|
126
|
+
.mul(p)
|
|
127
|
+
.mul(p)
|
|
128
|
+
.div(numericConstants_1.PEG_PRECISION)
|
|
129
|
+
.div(numericConstants_1.PEG_PRECISION)
|
|
130
|
+
.div(x.mul(p).div(numericConstants_1.PEG_PRECISION).add(delta));
|
|
131
|
+
const numer21 = k.div(x.add(delta));
|
|
132
|
+
const formulaCost = numer21
|
|
133
|
+
.sub(numer20)
|
|
134
|
+
.sub(numer1)
|
|
135
|
+
.mul(market.amm.pegMultiplier)
|
|
136
|
+
.div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
137
|
+
console.log((0, __1.convertToNumber)(formulaCost, numericConstants_1.QUOTE_PRECISION));
|
|
138
|
+
// p.div(p.mul(x).add(delta)).sub()
|
|
139
|
+
return cost;
|
|
140
|
+
}
|
|
141
|
+
exports.calculateAdjustKCost = calculateAdjustKCost;
|
|
142
|
+
/**
|
|
143
|
+
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
144
|
+
*
|
|
145
|
+
* @param market
|
|
146
|
+
* @param marketIndex
|
|
147
|
+
* @param newPeg
|
|
148
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
149
|
+
*/
|
|
150
|
+
function calculateRepegCost(market, marketIndex, newPeg) {
|
|
151
|
+
const netUserPosition = {
|
|
152
|
+
baseAssetAmount: market.baseAssetAmount,
|
|
153
|
+
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
154
|
+
marketIndex: new anchor_1.BN(marketIndex),
|
|
155
|
+
quoteAssetAmount: new anchor_1.BN(0),
|
|
156
|
+
openOrders: new anchor_1.BN(0),
|
|
157
|
+
};
|
|
158
|
+
const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
|
|
159
|
+
netUserPosition.quoteAssetAmount = currentValue;
|
|
160
|
+
const prevMarketPrice = (0, __1.calculateMarkPrice)(market);
|
|
161
|
+
const marketNewPeg = Object.assign({}, market);
|
|
162
|
+
marketNewPeg.amm = Object.assign({}, market.amm);
|
|
163
|
+
// const marketNewPeg = JSON.parse(JSON.stringify(market));
|
|
164
|
+
marketNewPeg.amm.pegMultiplier = newPeg;
|
|
165
|
+
console.log('Price moves from', (0, __1.convertToNumber)(prevMarketPrice), 'to', (0, __1.convertToNumber)((0, __1.calculateMarkPrice)(marketNewPeg)));
|
|
166
|
+
const cost = (0, __1.calculatePositionPNL)(marketNewPeg, netUserPosition);
|
|
167
|
+
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
168
|
+
const newQuoteAssetReserve = k.div(market.amm.baseAssetReserve.add(netUserPosition.baseAssetAmount));
|
|
169
|
+
const deltaQuoteAssetReserves = newQuoteAssetReserve.sub(market.amm.quoteAssetReserve);
|
|
170
|
+
const cost2 = deltaQuoteAssetReserves
|
|
171
|
+
.mul(market.amm.pegMultiplier.sub(newPeg))
|
|
172
|
+
.div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
173
|
+
console.log((0, __1.convertToNumber)(cost2, numericConstants_1.QUOTE_PRECISION));
|
|
174
|
+
return cost;
|
|
175
|
+
}
|
|
176
|
+
exports.calculateRepegCost = calculateRepegCost;
|
|
90
177
|
/**
|
|
91
178
|
* Helper function calculating terminal price of amm
|
|
92
179
|
*
|
|
@@ -33,7 +33,7 @@ class PythClient {
|
|
|
33
33
|
return __awaiter(this, void 0, void 0, function* () {
|
|
34
34
|
const priceData = (0, client_1.parsePriceData)(buffer);
|
|
35
35
|
return {
|
|
36
|
-
price: convertPythPrice(priceData.price, priceData.exponent),
|
|
36
|
+
price: convertPythPrice(priceData.aggregate.price, priceData.exponent),
|
|
37
37
|
slot: new anchor_1.BN(priceData.lastSlot.toString()),
|
|
38
38
|
confidence: convertPythPrice(priceData.confidence, priceData.exponent),
|
|
39
39
|
twap: convertPythPrice(priceData.twap.value, priceData.exponent),
|
package/lib/orderParams.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { OrderParams, OrderTriggerCondition, PositionDirection } from './types';
|
|
3
3
|
import { BN } from '@project-serum/anchor';
|
|
4
|
-
export declare function getLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number, postOnly?: boolean, oraclePriceOffset?: BN): OrderParams;
|
|
4
|
+
export declare function getLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number, postOnly?: boolean, oraclePriceOffset?: BN, immediateOrCancel?: boolean): OrderParams;
|
|
5
5
|
export declare function getTriggerMarketOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, triggerPrice: BN, triggerCondition: OrderTriggerCondition, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number): OrderParams;
|
|
6
6
|
export declare function getTriggerLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, triggerPrice: BN, triggerCondition: OrderTriggerCondition, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number): OrderParams;
|
|
7
7
|
export declare function getMarketOrderParams(marketIndex: BN, direction: PositionDirection, quoteAssetAmount: BN, baseAssetAmount: BN, reduceOnly: boolean, price?: BN, discountToken?: boolean, referrer?: boolean): OrderParams;
|
package/lib/orderParams.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getMarketOrderParams = exports.getTriggerLimitOrderParams = exports.getTriggerMarketOrderParams = exports.getLimitOrderParams = void 0;
|
|
4
4
|
const types_1 = require("./types");
|
|
5
5
|
const numericConstants_1 = require("./constants/numericConstants");
|
|
6
|
-
function getLimitOrderParams(marketIndex, direction, baseAssetAmount, price, reduceOnly, discountToken = false, referrer = false, userOrderId = 0, postOnly = false, oraclePriceOffset = numericConstants_1.ZERO) {
|
|
6
|
+
function getLimitOrderParams(marketIndex, direction, baseAssetAmount, price, reduceOnly, discountToken = false, referrer = false, userOrderId = 0, postOnly = false, oraclePriceOffset = numericConstants_1.ZERO, immediateOrCancel = false) {
|
|
7
7
|
return {
|
|
8
8
|
orderType: types_1.OrderType.LIMIT,
|
|
9
9
|
userOrderId,
|
|
@@ -14,7 +14,7 @@ function getLimitOrderParams(marketIndex, direction, baseAssetAmount, price, red
|
|
|
14
14
|
price,
|
|
15
15
|
reduceOnly,
|
|
16
16
|
postOnly,
|
|
17
|
-
immediateOrCancel
|
|
17
|
+
immediateOrCancel,
|
|
18
18
|
positionLimit: numericConstants_1.ZERO,
|
|
19
19
|
padding0: true,
|
|
20
20
|
padding1: numericConstants_1.ZERO,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { TxSender } from './types';
|
|
2
|
-
import { Commitment, ConfirmOptions, RpcResponseAndContext, Signer, SignatureResult, Transaction, TransactionSignature } from '@solana/web3.js';
|
|
3
|
+
import { Commitment, ConfirmOptions, RpcResponseAndContext, Signer, SignatureResult, Transaction, TransactionSignature, Connection } from '@solana/web3.js';
|
|
3
4
|
import { Provider } from '@project-serum/anchor';
|
|
4
5
|
declare type ResolveReference = {
|
|
5
6
|
resolve?: () => void;
|
|
@@ -8,12 +9,14 @@ export declare class RetryTxSender implements TxSender {
|
|
|
8
9
|
provider: Provider;
|
|
9
10
|
timeout: number;
|
|
10
11
|
retrySleep: number;
|
|
11
|
-
|
|
12
|
+
additionalConnections: Connection[];
|
|
13
|
+
constructor(provider: Provider, timeout?: number, retrySleep?: number, additionalConnections?: Connection[]);
|
|
12
14
|
send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<TransactionSignature>;
|
|
13
15
|
prepareTx(tx: Transaction, additionalSigners: Array<Signer>, opts: ConfirmOptions): Promise<Transaction>;
|
|
14
16
|
confirmTransaction(signature: TransactionSignature, commitment?: Commitment): Promise<RpcResponseAndContext<SignatureResult>>;
|
|
15
17
|
getTimestamp(): number;
|
|
16
18
|
sleep(reference: ResolveReference): Promise<void>;
|
|
17
19
|
promiseTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T | null>;
|
|
20
|
+
sendToAdditionalConnections(rawTx: Buffer, opts: ConfirmOptions): void;
|
|
18
21
|
}
|
|
19
22
|
export {};
|
package/lib/tx/retryTxSender.js
CHANGED
|
@@ -18,10 +18,11 @@ const bs58_1 = __importDefault(require("bs58"));
|
|
|
18
18
|
const DEFAULT_TIMEOUT = 35000;
|
|
19
19
|
const DEFAULT_RETRY = 8000;
|
|
20
20
|
class RetryTxSender {
|
|
21
|
-
constructor(provider, timeout, retrySleep) {
|
|
21
|
+
constructor(provider, timeout, retrySleep, additionalConnections = new Array()) {
|
|
22
22
|
this.provider = provider;
|
|
23
23
|
this.timeout = timeout !== null && timeout !== void 0 ? timeout : DEFAULT_TIMEOUT;
|
|
24
24
|
this.retrySleep = retrySleep !== null && retrySleep !== void 0 ? retrySleep : DEFAULT_RETRY;
|
|
25
|
+
this.additionalConnections = additionalConnections;
|
|
25
26
|
}
|
|
26
27
|
send(tx, additionalSigners, opts) {
|
|
27
28
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -35,6 +36,7 @@ class RetryTxSender {
|
|
|
35
36
|
const rawTransaction = tx.serialize();
|
|
36
37
|
const startTime = this.getTimestamp();
|
|
37
38
|
const txid = yield this.provider.connection.sendRawTransaction(rawTransaction, opts);
|
|
39
|
+
this.sendToAdditionalConnections(rawTransaction, opts);
|
|
38
40
|
let done = false;
|
|
39
41
|
const resolveReference = {
|
|
40
42
|
resolve: undefined,
|
|
@@ -55,6 +57,7 @@ class RetryTxSender {
|
|
|
55
57
|
console.error(e);
|
|
56
58
|
stopWaiting();
|
|
57
59
|
});
|
|
60
|
+
this.sendToAdditionalConnections(rawTransaction, opts);
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
63
|
}))();
|
|
@@ -149,5 +152,15 @@ class RetryTxSender {
|
|
|
149
152
|
return result;
|
|
150
153
|
});
|
|
151
154
|
}
|
|
155
|
+
sendToAdditionalConnections(rawTx, opts) {
|
|
156
|
+
this.additionalConnections.map((connection) => {
|
|
157
|
+
connection.sendRawTransaction(rawTx, opts).catch((e) => {
|
|
158
|
+
console.error(
|
|
159
|
+
// @ts-ignore
|
|
160
|
+
`error sending tx to additional connection ${connection._rpcEndpoint}`);
|
|
161
|
+
console.error(e);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
}
|
|
152
165
|
}
|
|
153
166
|
exports.RetryTxSender = RetryTxSender;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function promiseTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T | null>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.promiseTimeout = void 0;
|
|
4
|
+
function promiseTimeout(promise, timeoutMs) {
|
|
5
|
+
let timeoutId;
|
|
6
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
7
|
+
timeoutId = setTimeout(() => resolve(null), timeoutMs);
|
|
8
|
+
});
|
|
9
|
+
return Promise.race([promise, timeoutPromise]).then((result) => {
|
|
10
|
+
clearTimeout(timeoutId);
|
|
11
|
+
return result;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
exports.promiseTimeout = promiseTimeout;
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Commitment, Connection, PublicKey } from '@solana/web3.js';
|
|
2
2
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
3
|
import { AccountData } from './types';
|
|
4
|
+
import { promiseTimeout } from '../util/promiseTimeout';
|
|
4
5
|
|
|
5
6
|
type AccountToLoad = {
|
|
6
7
|
publicKey: PublicKey;
|
|
@@ -10,7 +11,6 @@ type AccountToLoad = {
|
|
|
10
11
|
const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
|
|
11
12
|
|
|
12
13
|
const oneMinute = 60 * 1000;
|
|
13
|
-
const fiveMinutes = 5 * 60 * 1000;
|
|
14
14
|
|
|
15
15
|
export class BulkAccountLoader {
|
|
16
16
|
connection: Connection;
|
|
@@ -24,7 +24,7 @@ export class BulkAccountLoader {
|
|
|
24
24
|
loadPromise?: Promise<void>;
|
|
25
25
|
loadPromiseResolver: () => void;
|
|
26
26
|
loggingEnabled = false;
|
|
27
|
-
|
|
27
|
+
lastTimeLoadingPromiseCleared = Date.now();
|
|
28
28
|
|
|
29
29
|
public constructor(
|
|
30
30
|
connection: Connection,
|
|
@@ -43,10 +43,15 @@ export class BulkAccountLoader {
|
|
|
43
43
|
const existingSize = this.accountsToLoad.size;
|
|
44
44
|
|
|
45
45
|
const callbackId = uuidv4();
|
|
46
|
+
this.log(
|
|
47
|
+
`Adding account ${publicKey.toString()} callback id ${callbackId}`
|
|
48
|
+
);
|
|
46
49
|
const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
|
|
47
50
|
if (existingAccountToLoad) {
|
|
51
|
+
this.log(`account already exists`);
|
|
48
52
|
existingAccountToLoad.callbacks.set(callbackId, callback);
|
|
49
53
|
} else {
|
|
54
|
+
this.log(`account doesn't already exist. creating new callback map`);
|
|
50
55
|
const callbacks = new Map<string, (buffer: Buffer) => void>();
|
|
51
56
|
callbacks.set(callbackId, callback);
|
|
52
57
|
const newAccountToLoad = {
|
|
@@ -67,6 +72,9 @@ export class BulkAccountLoader {
|
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
public removeAccount(publicKey: PublicKey, callbackId: string): void {
|
|
75
|
+
this.log(
|
|
76
|
+
`Removing account ${publicKey.toString()} callback id ${callbackId}`
|
|
77
|
+
);
|
|
70
78
|
const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
|
|
71
79
|
if (existingAccountToLoad) {
|
|
72
80
|
existingAccountToLoad.callbacks.delete(callbackId);
|
|
@@ -99,17 +107,29 @@ export class BulkAccountLoader {
|
|
|
99
107
|
|
|
100
108
|
public async load(): Promise<void> {
|
|
101
109
|
if (this.loadPromise) {
|
|
102
|
-
|
|
110
|
+
const now = Date.now();
|
|
111
|
+
if (now - this.lastTimeLoadingPromiseCleared > oneMinute) {
|
|
112
|
+
this.log(`Load promise hasnt been clearing for one minute. Clearing.`);
|
|
113
|
+
this.loadPromise = undefined;
|
|
114
|
+
} else {
|
|
115
|
+
this.log(`Load promise exists. Returning early`);
|
|
116
|
+
return this.loadPromise;
|
|
117
|
+
}
|
|
103
118
|
}
|
|
119
|
+
|
|
104
120
|
this.loadPromise = new Promise((resolver) => {
|
|
105
121
|
this.loadPromiseResolver = resolver;
|
|
106
122
|
});
|
|
123
|
+
this.lastTimeLoadingPromiseCleared = Date.now();
|
|
124
|
+
|
|
125
|
+
this.log(`Loading`);
|
|
107
126
|
|
|
108
127
|
try {
|
|
109
128
|
const chunks = this.chunks(
|
|
110
129
|
Array.from(this.accountsToLoad.values()),
|
|
111
130
|
GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE
|
|
112
131
|
);
|
|
132
|
+
this.log(`${chunks.length} chunks`);
|
|
113
133
|
|
|
114
134
|
await Promise.all(
|
|
115
135
|
chunks.map((chunk) => {
|
|
@@ -122,28 +142,17 @@ export class BulkAccountLoader {
|
|
|
122
142
|
for (const [_, callback] of this.errorCallbacks) {
|
|
123
143
|
callback(e);
|
|
124
144
|
}
|
|
145
|
+
this.log('finished error callbacks');
|
|
125
146
|
} finally {
|
|
147
|
+
this.log(`resetting load promise`);
|
|
126
148
|
this.loadPromiseResolver();
|
|
127
149
|
this.loadPromise = undefined;
|
|
128
|
-
|
|
129
|
-
const now = Date.now();
|
|
130
|
-
if (now - this.lastUpdate > fiveMinutes) {
|
|
131
|
-
if (this.loggingEnabled) {
|
|
132
|
-
console.log(
|
|
133
|
-
"Haven't seen updated account in five minutes. Bulk account loader creating new Connection Object"
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
this.connection = new Connection(
|
|
137
|
-
// @ts-ignore
|
|
138
|
-
this.connection._rpcEndpoint,
|
|
139
|
-
this.connection.commitment
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
150
|
}
|
|
143
151
|
}
|
|
144
152
|
|
|
145
153
|
async loadChunk(accountsToLoad: AccountToLoad[]): Promise<void> {
|
|
146
154
|
if (accountsToLoad.length === 0) {
|
|
155
|
+
this.log(`no accounts in chunk`);
|
|
147
156
|
return;
|
|
148
157
|
}
|
|
149
158
|
|
|
@@ -154,15 +163,15 @@ export class BulkAccountLoader {
|
|
|
154
163
|
{ commitment: this.commitment },
|
|
155
164
|
];
|
|
156
165
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
'getMultipleAccounts',
|
|
160
|
-
|
|
166
|
+
const rpcResponse: any | null = await promiseTimeout(
|
|
167
|
+
// @ts-ignore
|
|
168
|
+
this.connection._rpcRequest('getMultipleAccounts', args),
|
|
169
|
+
10 * 1000 // 30 second timeout
|
|
161
170
|
);
|
|
162
171
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
172
|
+
if (rpcResponse === null) {
|
|
173
|
+
this.log('request to rpc timed out', true);
|
|
174
|
+
return;
|
|
166
175
|
}
|
|
167
176
|
|
|
168
177
|
const newSlot = rpcResponse.result.context.slot;
|
|
@@ -179,44 +188,44 @@ export class BulkAccountLoader {
|
|
|
179
188
|
newBuffer = Buffer.from(raw, dataType);
|
|
180
189
|
}
|
|
181
190
|
|
|
182
|
-
if (this.loggingEnabled && oneMinuteSinceLastUpdate) {
|
|
183
|
-
console.log('oldRPCResponse', oldRPCResponse);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
191
|
if (!oldRPCResponse) {
|
|
192
|
+
this.log('No old rpc response, updating account data');
|
|
187
193
|
this.accountData.set(key, {
|
|
188
194
|
slot: newSlot,
|
|
189
195
|
buffer: newBuffer,
|
|
190
196
|
});
|
|
191
197
|
this.handleAccountCallbacks(accountToLoad, newBuffer);
|
|
192
|
-
this.lastUpdate = Date.now();
|
|
193
198
|
continue;
|
|
194
199
|
}
|
|
195
200
|
|
|
196
201
|
if (newSlot <= oldRPCResponse.slot) {
|
|
202
|
+
this.log(`new slot ${newSlot} old slot ${oldRPCResponse.slot}`);
|
|
197
203
|
continue;
|
|
198
204
|
}
|
|
199
205
|
|
|
200
206
|
const oldBuffer = oldRPCResponse.buffer;
|
|
201
207
|
if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
|
|
208
|
+
this.log('new buffer, updating account data');
|
|
202
209
|
this.accountData.set(key, {
|
|
203
210
|
slot: newSlot,
|
|
204
211
|
buffer: newBuffer,
|
|
205
212
|
});
|
|
206
213
|
this.handleAccountCallbacks(accountToLoad, newBuffer);
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
214
|
+
} else {
|
|
215
|
+
this.log('unable to update account for newest slot');
|
|
216
|
+
this.log('oldBuffer ' + oldBuffer);
|
|
217
|
+
this.log('newBuffer ' + newBuffer);
|
|
218
|
+
this.log('buffers equal ' + newBuffer.equals(oldBuffer));
|
|
212
219
|
}
|
|
213
220
|
}
|
|
214
221
|
}
|
|
215
222
|
|
|
216
223
|
handleAccountCallbacks(accountToLoad: AccountToLoad, buffer: Buffer): void {
|
|
224
|
+
this.log('handling account callbacks');
|
|
217
225
|
for (const [_, callback] of accountToLoad.callbacks) {
|
|
218
226
|
callback(buffer);
|
|
219
227
|
}
|
|
228
|
+
this.log('finished account callbacks');
|
|
220
229
|
}
|
|
221
230
|
|
|
222
231
|
public getAccountData(publicKey: PublicKey): Buffer | undefined {
|
|
@@ -229,9 +238,7 @@ export class BulkAccountLoader {
|
|
|
229
238
|
return;
|
|
230
239
|
}
|
|
231
240
|
|
|
232
|
-
|
|
233
|
-
console.log(`startPolling`);
|
|
234
|
-
}
|
|
241
|
+
this.log('startPolling');
|
|
235
242
|
|
|
236
243
|
this.intervalId = setInterval(this.load.bind(this), this.pollingFrequency);
|
|
237
244
|
}
|
|
@@ -241,9 +248,13 @@ export class BulkAccountLoader {
|
|
|
241
248
|
clearInterval(this.intervalId);
|
|
242
249
|
this.intervalId = undefined;
|
|
243
250
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
251
|
+
this.log('stopPolling');
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
public log(msg: string, force = false): void {
|
|
256
|
+
if (this.loggingEnabled || force) {
|
|
257
|
+
console.log(msg);
|
|
247
258
|
}
|
|
248
259
|
}
|
|
249
260
|
}
|