@drift-labs/sdk 0.2.0-master.26 → 0.2.0-master.27
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/pollingClearingHouseAccountSubscriber.d.ts +1 -0
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +3 -0
- package/lib/accounts/types.d.ts +1 -0
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +1 -0
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +3 -0
- package/lib/admin.d.ts +5 -2
- package/lib/admin.js +30 -4
- package/lib/clearingHouse.d.ts +2 -0
- package/lib/clearingHouse.js +14 -1
- package/lib/clearingHouseUser.d.ts +11 -9
- package/lib/clearingHouseUser.js +182 -106
- package/lib/config.js +1 -1
- package/lib/dlob/DLOB.d.ts +73 -0
- package/lib/dlob/DLOB.js +557 -0
- package/lib/dlob/DLOBNode.d.ts +52 -0
- package/lib/dlob/DLOBNode.js +82 -0
- package/lib/dlob/NodeList.d.ts +26 -0
- package/lib/dlob/NodeList.js +138 -0
- package/lib/idl/clearing_house.json +122 -202
- package/lib/index.d.ts +5 -0
- package/lib/index.js +5 -0
- package/lib/math/market.d.ts +1 -1
- package/lib/math/market.js +1 -1
- package/lib/math/orders.d.ts +3 -3
- package/lib/math/orders.js +31 -16
- package/lib/math/spotBalance.d.ts +3 -0
- package/lib/math/spotBalance.js +18 -1
- package/lib/math/spotPosition.d.ts +5 -1
- package/lib/math/spotPosition.js +16 -1
- package/lib/types.d.ts +24 -23
- package/lib/types.js +9 -3
- package/lib/userMap/userMap.d.ts +25 -0
- package/lib/userMap/userMap.js +73 -0
- package/lib/userMap/userStatsMap.d.ts +19 -0
- package/lib/userMap/userStatsMap.js +68 -0
- package/package.json +6 -3
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +4 -0
- package/src/accounts/types.ts +1 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +6 -0
- package/src/addresses/marketAddresses.js +26 -0
- package/src/admin.ts +50 -8
- package/src/assert/assert.js +1 -1
- package/src/clearingHouse.ts +23 -1
- package/src/clearingHouseUser.ts +364 -165
- package/src/config.ts +1 -1
- package/src/constants/banks.js +42 -0
- package/src/constants/{perpMarkets.js → markets.js} +11 -11
- package/src/dlob/DLOB.ts +884 -0
- package/src/dlob/DLOBNode.ts +163 -0
- package/src/dlob/NodeList.ts +185 -0
- package/src/events/eventList.js +23 -66
- package/src/events/txEventCache.js +19 -22
- package/src/examples/makeTradeExample.js +157 -0
- package/src/factory/bigNum.js +180 -183
- package/src/factory/oracleClient.js +9 -9
- package/src/idl/clearing_house.json +122 -202
- package/src/index.ts +5 -0
- package/src/math/auction.js +10 -10
- package/src/math/conversion.js +3 -4
- package/src/math/funding.js +175 -223
- package/src/math/market.ts +1 -1
- package/src/math/orders.ts +29 -21
- package/src/math/repeg.js +40 -40
- package/src/math/spotBalance.ts +26 -0
- package/src/math/spotPosition.ts +42 -1
- package/src/math/trade.js +74 -81
- package/src/math/utils.js +7 -8
- package/src/math/utils.js.map +1 -0
- package/src/oracles/oracleClientCache.js +9 -10
- package/src/oracles/pythClient.js +17 -52
- package/src/oracles/quoteAssetOracleClient.js +13 -44
- package/src/oracles/switchboardClient.js +37 -69
- package/src/oracles/types.js +1 -1
- package/src/token/index.js +4 -4
- package/src/tx/types.js +1 -1
- package/src/tx/utils.js +6 -7
- package/src/types.ts +25 -23
- package/src/userMap/userMap.ts +100 -0
- package/src/userMap/userStatsMap.ts +110 -0
- package/src/userName.js +5 -5
- package/src/util/computeUnits.js +11 -46
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/promiseTimeout.js +5 -5
- package/src/util/tps.js +12 -46
- package/src/wallet.js +18 -55
- package/tests/bn/test.ts +2 -3
- package/tests/dlob/helpers.ts +322 -0
- package/tests/dlob/test.ts +2865 -0
- package/my-script/.env +0 -7
- package/my-script/getUserStats.ts +0 -106
- package/my-script/multiConnections.ts +0 -119
- package/my-script/test-regex.ts +0 -11
- package/my-script/utils.ts +0 -52
- package/src/accounts/bulkAccountLoader.js +0 -249
- package/src/accounts/bulkUserStatsSubscription.js +0 -75
- package/src/accounts/bulkUserSubscription.js +0 -75
- package/src/accounts/fetch.js +0 -92
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -465
- package/src/accounts/pollingOracleSubscriber.js +0 -156
- package/src/accounts/pollingTokenAccountSubscriber.js +0 -141
- package/src/accounts/pollingUserAccountSubscriber.js +0 -208
- package/src/accounts/pollingUserStatsAccountSubscriber.js +0 -208
- package/src/accounts/types.js +0 -28
- package/src/accounts/utils.js +0 -7
- package/src/accounts/webSocketAccountSubscriber.js +0 -138
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -433
- package/src/accounts/webSocketUserAccountSubscriber.js +0 -113
- package/src/accounts/webSocketUserStatsAccountSubsriber.js +0 -113
- package/src/addresses/pda.js +0 -186
- package/src/admin.js +0 -1284
- package/src/clearingHouse.js +0 -3433
- package/src/clearingHouseConfig.js +0 -2
- package/src/clearingHouseUser.js +0 -874
- package/src/clearingHouseUserConfig.js +0 -2
- package/src/clearingHouseUserStats.js +0 -115
- package/src/clearingHouseUserStatsConfig.js +0 -2
- package/src/config.js +0 -80
- package/src/constants/numericConstants.js +0 -48
- package/src/constants/spotMarkets.js +0 -51
- package/src/events/eventSubscriber.js +0 -202
- package/src/events/fetchLogs.js +0 -117
- package/src/events/pollingLogProvider.js +0 -113
- package/src/events/sort.js +0 -41
- package/src/events/types.js +0 -25
- package/src/events/webSocketLogProvider.js +0 -76
- package/src/index.js +0 -75
- package/src/math/amm.js +0 -422
- package/src/math/insurance.js +0 -27
- package/src/math/margin.js +0 -77
- package/src/math/market.js +0 -105
- package/src/math/oracles.js +0 -56
- package/src/math/orders.js +0 -153
- package/src/math/position.js +0 -172
- package/src/math/spotBalance.js +0 -176
- package/src/math/spotMarket.js +0 -8
- package/src/math/spotPosition.js +0 -8
- package/src/orderParams.js +0 -28
- package/src/serum/serumSubscriber.js +0 -102
- package/src/serum/types.js +0 -2
- package/src/slot/SlotSubscriber.js +0 -86
- package/src/tokenFaucet.js +0 -323
- package/src/tx/retryTxSender.js +0 -280
- package/src/types.js +0 -216
|
@@ -8,72 +8,37 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
exports.__esModule = true;
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
12
|
exports.convertPythPrice = exports.PythClient = void 0;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
13
|
+
const client_1 = require("@pythnetwork/client");
|
|
14
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
15
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
16
|
+
class PythClient {
|
|
17
|
+
constructor(connection) {
|
|
45
18
|
this.connection = connection;
|
|
46
19
|
}
|
|
47
|
-
|
|
48
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
49
|
-
|
|
50
|
-
return
|
|
51
|
-
switch (_a.label) {
|
|
52
|
-
case 0: return [4 /*yield*/, this.connection.getAccountInfo(pricePublicKey)];
|
|
53
|
-
case 1:
|
|
54
|
-
accountInfo = _a.sent();
|
|
55
|
-
return [2 /*return*/, this.getOraclePriceDataFromBuffer(accountInfo.data)];
|
|
56
|
-
}
|
|
57
|
-
});
|
|
20
|
+
getOraclePriceData(pricePublicKey) {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
const accountInfo = yield this.connection.getAccountInfo(pricePublicKey);
|
|
23
|
+
return this.getOraclePriceDataFromBuffer(accountInfo.data);
|
|
58
24
|
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
25
|
+
}
|
|
26
|
+
getOraclePriceDataFromBuffer(buffer) {
|
|
27
|
+
const priceData = client_1.parsePriceData(buffer);
|
|
62
28
|
return {
|
|
63
29
|
price: convertPythPrice(priceData.aggregate.price, priceData.exponent),
|
|
64
30
|
slot: new anchor_1.BN(priceData.lastSlot.toString()),
|
|
65
31
|
confidence: convertPythPrice(priceData.confidence, priceData.exponent),
|
|
66
32
|
twap: convertPythPrice(priceData.twap.value, priceData.exponent),
|
|
67
33
|
twapConfidence: convertPythPrice(priceData.twac.value, priceData.exponent),
|
|
68
|
-
hasSufficientNumberOfDataPoints: true
|
|
34
|
+
hasSufficientNumberOfDataPoints: true,
|
|
69
35
|
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
}());
|
|
36
|
+
}
|
|
37
|
+
}
|
|
73
38
|
exports.PythClient = PythClient;
|
|
74
39
|
function convertPythPrice(price, exponent) {
|
|
75
40
|
exponent = Math.abs(exponent);
|
|
76
|
-
|
|
41
|
+
const pythPrecision = numericConstants_1.TEN.pow(new anchor_1.BN(exponent).abs());
|
|
77
42
|
return new anchor_1.BN(price * Math.pow(10, exponent))
|
|
78
43
|
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
79
44
|
.div(pythPrecision);
|
|
@@ -8,56 +8,25 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
exports.__esModule = true;
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
12
|
exports.QuoteAssetOracleClient = exports.QUOTE_ORACLE_PRICE_DATA = void 0;
|
|
40
|
-
|
|
41
|
-
|
|
13
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
14
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
42
15
|
exports.QUOTE_ORACLE_PRICE_DATA = {
|
|
43
16
|
price: numericConstants_1.MARK_PRICE_PRECISION,
|
|
44
17
|
slot: new anchor_1.BN(0),
|
|
45
18
|
confidence: new anchor_1.BN(1),
|
|
46
|
-
hasSufficientNumberOfDataPoints: true
|
|
19
|
+
hasSufficientNumberOfDataPoints: true,
|
|
47
20
|
};
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return __generator(this, function (_a) {
|
|
54
|
-
return [2 /*return*/, Promise.resolve(exports.QUOTE_ORACLE_PRICE_DATA)];
|
|
55
|
-
});
|
|
21
|
+
class QuoteAssetOracleClient {
|
|
22
|
+
constructor() { }
|
|
23
|
+
getOraclePriceData(_pricePublicKey) {
|
|
24
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
return Promise.resolve(exports.QUOTE_ORACLE_PRICE_DATA);
|
|
56
26
|
});
|
|
57
|
-
}
|
|
58
|
-
|
|
27
|
+
}
|
|
28
|
+
getOraclePriceDataFromBuffer(_buffer) {
|
|
59
29
|
return exports.QUOTE_ORACLE_PRICE_DATA;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
}());
|
|
30
|
+
}
|
|
31
|
+
}
|
|
63
32
|
exports.QuoteAssetOracleClient = QuoteAssetOracleClient;
|
|
@@ -8,93 +8,61 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
13
|
};
|
|
38
|
-
exports
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
15
|
exports.SwitchboardClient = void 0;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
16
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
17
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
18
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
19
|
+
const wallet_1 = require("../wallet");
|
|
20
|
+
const switchboard_v2_json_1 = __importDefault(require("../idl/switchboard_v2.json"));
|
|
21
|
+
let program;
|
|
22
|
+
class SwitchboardClient {
|
|
23
|
+
constructor(connection) {
|
|
48
24
|
this.connection = connection;
|
|
49
25
|
}
|
|
50
|
-
|
|
51
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
52
|
-
|
|
53
|
-
return
|
|
54
|
-
switch (_a.label) {
|
|
55
|
-
case 0: return [4 /*yield*/, this.connection.getAccountInfo(pricePublicKey)];
|
|
56
|
-
case 1:
|
|
57
|
-
accountInfo = _a.sent();
|
|
58
|
-
return [2 /*return*/, this.getOraclePriceDataFromBuffer(accountInfo.data)];
|
|
59
|
-
}
|
|
60
|
-
});
|
|
26
|
+
getOraclePriceData(pricePublicKey) {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
const accountInfo = yield this.connection.getAccountInfo(pricePublicKey);
|
|
29
|
+
return this.getOraclePriceDataFromBuffer(accountInfo.data);
|
|
61
30
|
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
31
|
+
}
|
|
32
|
+
getOraclePriceDataFromBuffer(buffer) {
|
|
33
|
+
const program = this.getProgram();
|
|
34
|
+
const aggregatorAccountData = program.account.aggregatorAccountData.coder.accounts.decode('AggregatorAccountData', buffer);
|
|
35
|
+
const price = convertSwitchboardDecimal(aggregatorAccountData.latestConfirmedRound.result);
|
|
36
|
+
const confidence = convertSwitchboardDecimal(aggregatorAccountData.latestConfirmedRound
|
|
68
37
|
.stdDeviation);
|
|
69
|
-
|
|
38
|
+
const hasSufficientNumberOfDataPoints = aggregatorAccountData.latestConfirmedRound.numSuccess >=
|
|
70
39
|
aggregatorAccountData.minOracleResults;
|
|
71
|
-
|
|
40
|
+
const slot = aggregatorAccountData.latestConfirmedRound.roundOpenSlot;
|
|
72
41
|
return {
|
|
73
|
-
price
|
|
74
|
-
slot
|
|
75
|
-
confidence
|
|
76
|
-
hasSufficientNumberOfDataPoints
|
|
42
|
+
price,
|
|
43
|
+
slot,
|
|
44
|
+
confidence,
|
|
45
|
+
hasSufficientNumberOfDataPoints,
|
|
77
46
|
};
|
|
78
|
-
}
|
|
79
|
-
|
|
47
|
+
}
|
|
48
|
+
getProgram() {
|
|
80
49
|
if (program) {
|
|
81
50
|
return program;
|
|
82
51
|
}
|
|
83
52
|
program = getSwitchboardProgram(this.connection);
|
|
84
53
|
return program;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
}());
|
|
54
|
+
}
|
|
55
|
+
}
|
|
88
56
|
exports.SwitchboardClient = SwitchboardClient;
|
|
89
57
|
function getSwitchboardProgram(connection) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return new anchor_1.Program(switchboard_v2_json_1
|
|
58
|
+
const DEFAULT_KEYPAIR = web3_js_1.Keypair.fromSeed(new Uint8Array(32).fill(1));
|
|
59
|
+
const programId = web3_js_1.PublicKey.default;
|
|
60
|
+
const wallet = new wallet_1.Wallet(DEFAULT_KEYPAIR);
|
|
61
|
+
const provider = new anchor_1.AnchorProvider(connection, wallet, {});
|
|
62
|
+
return new anchor_1.Program(switchboard_v2_json_1.default, programId, provider);
|
|
95
63
|
}
|
|
96
64
|
function convertSwitchboardDecimal(switchboardDecimal) {
|
|
97
|
-
|
|
65
|
+
const switchboardPrecision = numericConstants_1.TEN.pow(new anchor_1.BN(switchboardDecimal.scale));
|
|
98
66
|
return switchboardDecimal.mantissa
|
|
99
67
|
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
100
68
|
.div(switchboardPrecision);
|
package/src/oracles/types.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
exports
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/src/token/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
exports
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseTokenAccount = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
const spl_token_1 = require("@solana/spl-token");
|
|
5
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
6
6
|
function parseTokenAccount(data) {
|
|
7
|
-
|
|
7
|
+
const accountInfo = spl_token_1.AccountLayout.decode(data);
|
|
8
8
|
accountInfo.mint = new web3_js_1.PublicKey(accountInfo.mint);
|
|
9
9
|
accountInfo.owner = new web3_js_1.PublicKey(accountInfo.owner);
|
|
10
10
|
accountInfo.amount = spl_token_1.u64.fromBuffer(accountInfo.amount);
|
package/src/tx/types.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
exports
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/src/tx/utils.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
exports
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.wrapInTx = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
function wrapInTx(instruction, computeUnits // TODO, requires less code change
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const COMPUTE_UNITS_DEFAULT = 200000;
|
|
6
|
+
function wrapInTx(instruction, computeUnits = 600000 // TODO, requires less code change
|
|
7
7
|
) {
|
|
8
|
-
|
|
9
|
-
var tx = new web3_js_1.Transaction();
|
|
8
|
+
const tx = new web3_js_1.Transaction();
|
|
10
9
|
if (computeUnits != COMPUTE_UNITS_DEFAULT) {
|
|
11
10
|
tx.add(web3_js_1.ComputeBudgetProgram.requestUnits({
|
|
12
11
|
units: computeUnits,
|
|
13
|
-
additionalFee: 0
|
|
12
|
+
additionalFee: 0,
|
|
14
13
|
}));
|
|
15
14
|
}
|
|
16
15
|
return tx.add(instruction);
|
package/src/types.ts
CHANGED
|
@@ -7,6 +7,7 @@ export class MarketStatus {
|
|
|
7
7
|
static readonly INITIALIZED = { initialized: {} };
|
|
8
8
|
static readonly REDUCEONLY = { reduceonly: {} };
|
|
9
9
|
static readonly SETTLEMENT = { settlement: {} };
|
|
10
|
+
static readonly DELISTED = { delisted: {} };
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export class ContractType {
|
|
@@ -47,6 +48,7 @@ export class OrderType {
|
|
|
47
48
|
static readonly MARKET = { market: {} };
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
export declare type MarketTypeStr = 'perp' | 'spot';
|
|
50
52
|
export class MarketType {
|
|
51
53
|
static readonly SPOT = { spot: {} };
|
|
52
54
|
static readonly PERP = { perp: {} };
|
|
@@ -113,6 +115,10 @@ export function isOneOfVariant(object: unknown, types: string[]) {
|
|
|
113
115
|
}, false);
|
|
114
116
|
}
|
|
115
117
|
|
|
118
|
+
export function getVariant(object: unknown): string {
|
|
119
|
+
return Object.keys(object)[0];
|
|
120
|
+
}
|
|
121
|
+
|
|
116
122
|
export enum TradeSide {
|
|
117
123
|
None = 0,
|
|
118
124
|
Buy = 1,
|
|
@@ -241,6 +247,7 @@ export type LiquidationRecord = {
|
|
|
241
247
|
marginRequirement: BN;
|
|
242
248
|
totalCollateral: BN;
|
|
243
249
|
liquidationId: number;
|
|
250
|
+
canceledOrderIds: BN[];
|
|
244
251
|
liquidatePerp: LiquidatePerpRecord;
|
|
245
252
|
liquidateBorrow: LiquidateBorrowRecord;
|
|
246
253
|
liquidateBorrowForPerpPnl: LiquidateBorrowForPerpPnlRecord;
|
|
@@ -268,17 +275,16 @@ export class LiquidationType {
|
|
|
268
275
|
|
|
269
276
|
export type LiquidatePerpRecord = {
|
|
270
277
|
marketIndex: BN;
|
|
271
|
-
orderIds: BN[];
|
|
272
278
|
oraclePrice: BN;
|
|
273
279
|
baseAssetAmount: BN;
|
|
274
280
|
quoteAssetAmount: BN;
|
|
275
281
|
lpShares: BN;
|
|
276
282
|
userPnl: BN;
|
|
277
283
|
liquidatorPnl: BN;
|
|
278
|
-
canceledOrdersFee: BN;
|
|
279
284
|
userOrderId: BN;
|
|
280
285
|
liquidatorOrderId: BN;
|
|
281
286
|
fillRecordId: BN;
|
|
287
|
+
ifFee: BN;
|
|
282
288
|
};
|
|
283
289
|
|
|
284
290
|
export type LiquidateBorrowRecord = {
|
|
@@ -288,6 +294,7 @@ export type LiquidateBorrowRecord = {
|
|
|
288
294
|
liabilityMarketIndex: BN;
|
|
289
295
|
liabilityPrice: BN;
|
|
290
296
|
liabilityTransfer: BN;
|
|
297
|
+
ifFee: BN;
|
|
291
298
|
};
|
|
292
299
|
|
|
293
300
|
export type LiquidateBorrowForPerpPnlRecord = {
|
|
@@ -378,17 +385,6 @@ export type StateAccount = {
|
|
|
378
385
|
exchangePaused: boolean;
|
|
379
386
|
adminControlsPrices: boolean;
|
|
380
387
|
insuranceVault: PublicKey;
|
|
381
|
-
marginRatioInitial: BN;
|
|
382
|
-
marginRatioMaintenance: BN;
|
|
383
|
-
marginRatioPartial: BN;
|
|
384
|
-
partialLiquidationClosePercentageNumerator: BN;
|
|
385
|
-
partialLiquidationClosePercentageDenominator: BN;
|
|
386
|
-
partialLiquidationPenaltyPercentageNumerator: BN;
|
|
387
|
-
partialLiquidationPenaltyPercentageDenominator: BN;
|
|
388
|
-
fullLiquidationPenaltyPercentageNumerator: BN;
|
|
389
|
-
fullLiquidationPenaltyPercentageDenominator: BN;
|
|
390
|
-
partialLiquidationLiquidatorShareDenominator: BN;
|
|
391
|
-
fullLiquidationLiquidatorShareDenominator: BN;
|
|
392
388
|
perpFeeStructure: FeeStructure;
|
|
393
389
|
spotFeeStructure: FeeStructure;
|
|
394
390
|
totalFee: BN;
|
|
@@ -402,8 +398,9 @@ export type StateAccount = {
|
|
|
402
398
|
minOrderQuoteAssetAmount: BN;
|
|
403
399
|
signer: PublicKey;
|
|
404
400
|
signerNonce: number;
|
|
405
|
-
|
|
406
|
-
|
|
401
|
+
defaultMarketOrderTimeInForce: number;
|
|
402
|
+
minPerpAuctionDuration: number;
|
|
403
|
+
defaultSpotAuctionDuration: number;
|
|
407
404
|
liquidationMarginBufferRatio: number;
|
|
408
405
|
};
|
|
409
406
|
|
|
@@ -423,7 +420,8 @@ export type PerpMarketAccount = {
|
|
|
423
420
|
marginRatioMaintenance: number;
|
|
424
421
|
nextFillRecordId: BN;
|
|
425
422
|
pnlPool: PoolBalance;
|
|
426
|
-
|
|
423
|
+
liquidatorFee: BN;
|
|
424
|
+
ifLiquidationFee: BN;
|
|
427
425
|
imfFactor: BN;
|
|
428
426
|
unrealizedImfFactor: BN;
|
|
429
427
|
unrealizedMaxImbalance: BN;
|
|
@@ -451,7 +449,7 @@ export type SpotMarketAccount = {
|
|
|
451
449
|
|
|
452
450
|
userIfFactor: BN;
|
|
453
451
|
totalIfFactor: BN;
|
|
454
|
-
|
|
452
|
+
ifLiquidationFee: BN;
|
|
455
453
|
|
|
456
454
|
decimals: number;
|
|
457
455
|
optimalUtilization: BN;
|
|
@@ -468,7 +466,7 @@ export type SpotMarketAccount = {
|
|
|
468
466
|
maintenanceAssetWeight: BN;
|
|
469
467
|
initialLiabilityWeight: BN;
|
|
470
468
|
maintenanceLiabilityWeight: BN;
|
|
471
|
-
|
|
469
|
+
liquidatorFee: BN;
|
|
472
470
|
imfFactor: BN;
|
|
473
471
|
|
|
474
472
|
withdrawGuardThreshold: BN;
|
|
@@ -600,6 +598,7 @@ export type UserAccount = {
|
|
|
600
598
|
bankrupt: boolean;
|
|
601
599
|
nextLiquidationId: number;
|
|
602
600
|
nextOrderId: BN;
|
|
601
|
+
customMarginRatio: number;
|
|
603
602
|
};
|
|
604
603
|
|
|
605
604
|
export type SpotPosition = {
|
|
@@ -638,6 +637,7 @@ export type Order = {
|
|
|
638
637
|
auctionDuration: number;
|
|
639
638
|
auctionStartPrice: BN;
|
|
640
639
|
auctionEndPrice: BN;
|
|
640
|
+
timeInForce: number;
|
|
641
641
|
};
|
|
642
642
|
|
|
643
643
|
export type OrderParams = {
|
|
@@ -655,8 +655,9 @@ export type OrderParams = {
|
|
|
655
655
|
triggerCondition: OrderTriggerCondition;
|
|
656
656
|
positionLimit: BN;
|
|
657
657
|
oraclePriceOffset: BN;
|
|
658
|
-
|
|
659
|
-
|
|
658
|
+
auctionDuration: number | null;
|
|
659
|
+
timeInForce: number | null;
|
|
660
|
+
auctionStartPrice: BN | null;
|
|
660
661
|
};
|
|
661
662
|
|
|
662
663
|
export type NecessaryOrderParams = {
|
|
@@ -685,8 +686,9 @@ export const DefaultOrderParams = {
|
|
|
685
686
|
triggerCondition: OrderTriggerCondition.ABOVE,
|
|
686
687
|
positionLimit: ZERO,
|
|
687
688
|
oraclePriceOffset: ZERO,
|
|
688
|
-
|
|
689
|
-
|
|
689
|
+
auctionDuration: null,
|
|
690
|
+
timeInForce: null,
|
|
691
|
+
auctionStartPrice: null,
|
|
690
692
|
};
|
|
691
693
|
|
|
692
694
|
export type MakerInfo = {
|
|
@@ -748,7 +750,7 @@ export type FeeStructure = {
|
|
|
748
750
|
makerRebateNumerator: BN;
|
|
749
751
|
makerRebateDenominator: BN;
|
|
750
752
|
fillerRewardStructure: OrderFillerRewardStructure;
|
|
751
|
-
|
|
753
|
+
flatFillerFee: BN;
|
|
752
754
|
};
|
|
753
755
|
|
|
754
756
|
export type OracleGuardRails = {
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ClearingHouseUser,
|
|
3
|
+
ClearingHouse,
|
|
4
|
+
UserAccount,
|
|
5
|
+
bulkPollingUserSubscribe,
|
|
6
|
+
OrderRecord,
|
|
7
|
+
ClearingHouseUserAccountSubscriptionConfig,
|
|
8
|
+
} from '..';
|
|
9
|
+
import { ProgramAccount } from '@project-serum/anchor';
|
|
10
|
+
|
|
11
|
+
import { PublicKey } from '@solana/web3.js';
|
|
12
|
+
|
|
13
|
+
export class UserMap {
|
|
14
|
+
private userMap = new Map<string, ClearingHouseUser>();
|
|
15
|
+
private clearingHouse: ClearingHouse;
|
|
16
|
+
private accountSubscription: ClearingHouseUserAccountSubscriptionConfig;
|
|
17
|
+
|
|
18
|
+
constructor(
|
|
19
|
+
clearingHouse: ClearingHouse,
|
|
20
|
+
accountSubscription: ClearingHouseUserAccountSubscriptionConfig
|
|
21
|
+
) {
|
|
22
|
+
this.clearingHouse = clearingHouse;
|
|
23
|
+
this.accountSubscription = accountSubscription;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public async fetchAllUsers() {
|
|
27
|
+
const userArray: ClearingHouseUser[] = [];
|
|
28
|
+
|
|
29
|
+
const programUserAccounts =
|
|
30
|
+
(await this.clearingHouse.program.account.user.all()) as ProgramAccount<UserAccount>[];
|
|
31
|
+
for (const programUserAccount of programUserAccounts) {
|
|
32
|
+
if (this.userMap.has(programUserAccount.publicKey.toString())) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const user = new ClearingHouseUser({
|
|
37
|
+
clearingHouse: this.clearingHouse,
|
|
38
|
+
userAccountPublicKey: programUserAccount.publicKey,
|
|
39
|
+
accountSubscription: this.accountSubscription,
|
|
40
|
+
});
|
|
41
|
+
userArray.push(user);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (this.accountSubscription.type === 'polling') {
|
|
45
|
+
await bulkPollingUserSubscribe(
|
|
46
|
+
userArray,
|
|
47
|
+
this.accountSubscription.accountLoader
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
for (const user of userArray) {
|
|
52
|
+
this.userMap.set(user.getUserAccountPublicKey().toString(), user);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public async addPubkey(userAccountPublicKey: PublicKey) {
|
|
57
|
+
const user = new ClearingHouseUser({
|
|
58
|
+
clearingHouse: this.clearingHouse,
|
|
59
|
+
userAccountPublicKey,
|
|
60
|
+
accountSubscription: this.accountSubscription,
|
|
61
|
+
});
|
|
62
|
+
await user.subscribe();
|
|
63
|
+
this.userMap.set(userAccountPublicKey.toString(), user);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public has(key: string): boolean {
|
|
67
|
+
return this.userMap.has(key);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* gets the ClearingHouseUser for a particular userAccountPublicKey, if no ClearingHouseUser exists, undefined is returned
|
|
72
|
+
* @param key userAccountPublicKey to get ClearngHouseUserFor
|
|
73
|
+
* @returns user ClearingHouseUser | undefined
|
|
74
|
+
*/
|
|
75
|
+
public get(key: string): ClearingHouseUser | undefined {
|
|
76
|
+
return this.userMap.get(key);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* gets the ClearingHouseUser for a particular userAccountPublicKey, if no ClearingHouseUser exists, new one is created
|
|
81
|
+
* @param key userAccountPublicKey to get ClearngHouseUserFor
|
|
82
|
+
* @returns ClearingHouseUser
|
|
83
|
+
*/
|
|
84
|
+
public async mustGet(key: string): Promise<ClearingHouseUser> {
|
|
85
|
+
if (!this.has(key)) {
|
|
86
|
+
await this.addPubkey(new PublicKey(key));
|
|
87
|
+
}
|
|
88
|
+
const user = this.userMap.get(key);
|
|
89
|
+
await user.fetchAccounts();
|
|
90
|
+
return user;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public async updateWithOrderRecord(record: OrderRecord) {
|
|
94
|
+
await this.addPubkey(record.user);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public values(): IterableIterator<ClearingHouseUser> {
|
|
98
|
+
return this.userMap.values();
|
|
99
|
+
}
|
|
100
|
+
}
|