@drift-labs/sdk 0.1.36-master.7 → 0.2.0-master.10
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 +6 -6
- package/lib/accounts/bulkAccountLoader.js +81 -95
- package/lib/accounts/bulkUserSubscription.js +13 -57
- package/lib/accounts/fetch.d.ts +4 -0
- package/lib/accounts/fetch.js +18 -0
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +34 -38
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +224 -224
- package/lib/accounts/pollingOracleSubscriber.d.ts +3 -3
- package/lib/accounts/pollingOracleSubscriber.js +37 -49
- package/lib/accounts/pollingTokenAccountSubscriber.d.ts +3 -3
- package/lib/accounts/pollingTokenAccountSubscriber.js +35 -50
- package/lib/accounts/pollingUserAccountSubscriber.d.ts +7 -13
- package/lib/accounts/pollingUserAccountSubscriber.js +71 -134
- package/lib/accounts/types.d.ts +34 -41
- package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -4
- package/lib/accounts/webSocketAccountSubscriber.js +39 -35
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +33 -28
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +153 -185
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts +5 -11
- package/lib/accounts/webSocketUserAccountSubscriber.js +22 -67
- package/lib/addresses/marketAddresses.d.ts +4 -0
- package/lib/addresses/marketAddresses.js +15 -0
- package/lib/addresses/pda.d.ts +12 -0
- package/lib/addresses/pda.js +83 -0
- package/lib/admin.d.ts +12 -18
- package/lib/admin.js +398 -558
- package/lib/clearingHouse.d.ts +83 -109
- package/lib/clearingHouse.js +832 -893
- package/lib/clearingHouseConfig.d.ts +34 -0
- package/lib/clearingHouseConfig.js +2 -0
- package/lib/clearingHouseUser.d.ts +19 -22
- package/lib/clearingHouseUser.js +155 -141
- package/lib/clearingHouseUserConfig.d.ts +14 -0
- package/lib/clearingHouseUserConfig.js +2 -0
- package/lib/config.d.ts +12 -0
- package/lib/config.js +35 -4
- package/lib/constants/banks.d.ts +16 -0
- package/lib/constants/banks.js +41 -0
- package/lib/constants/markets.d.ts +8 -3
- package/lib/constants/markets.js +13 -206
- package/lib/constants/numericConstants.d.ts +17 -0
- package/lib/constants/numericConstants.js +23 -6
- package/lib/events/eventList.d.ts +22 -0
- package/lib/events/eventList.js +77 -0
- package/lib/events/eventSubscriber.d.ts +34 -0
- package/lib/events/eventSubscriber.js +126 -0
- package/lib/events/fetchLogs.d.ts +13 -0
- package/lib/events/fetchLogs.js +39 -0
- package/lib/events/pollingLogProvider.d.ts +15 -0
- package/lib/events/pollingLogProvider.js +53 -0
- package/lib/events/sort.d.ts +2 -0
- package/lib/events/sort.js +44 -0
- package/lib/events/txEventCache.d.ts +24 -0
- package/lib/events/txEventCache.js +71 -0
- package/lib/events/types.d.ts +49 -0
- package/lib/events/types.js +20 -0
- package/lib/events/webSocketLogProvider.d.ts +12 -0
- package/lib/events/webSocketLogProvider.js +30 -0
- package/lib/examples/makeTradeExample.js +26 -27
- package/lib/factory/bigNum.d.ts +118 -0
- package/lib/factory/bigNum.js +364 -0
- package/lib/factory/oracleClient.d.ts +1 -2
- package/lib/factory/oracleClient.js +6 -2
- package/lib/idl/clearing_house.json +2258 -2774
- package/lib/index.d.ts +14 -5
- package/lib/index.js +18 -5
- package/lib/math/amm.d.ts +24 -29
- package/lib/math/amm.js +209 -176
- package/lib/math/auction.d.ts +5 -0
- package/lib/math/auction.js +42 -0
- package/lib/math/bankBalance.d.ts +9 -0
- package/lib/math/bankBalance.js +75 -0
- package/lib/math/conversion.d.ts +0 -1
- package/lib/math/conversion.js +1 -5
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +158 -175
- package/lib/math/market.d.ts +6 -6
- package/lib/math/market.js +10 -9
- package/lib/math/orders.d.ts +6 -1
- package/lib/math/orders.js +38 -1
- package/lib/math/position.d.ts +7 -5
- package/lib/math/position.js +29 -27
- package/lib/math/repeg.d.ts +22 -0
- package/lib/math/repeg.js +128 -0
- package/lib/math/trade.d.ts +5 -4
- package/lib/math/trade.js +29 -24
- package/lib/mockUSDCFaucet.js +87 -116
- package/lib/oracles/oracleClientCache.d.ts +8 -0
- package/lib/oracles/oracleClientCache.js +19 -0
- package/lib/oracles/pythClient.d.ts +3 -5
- package/lib/oracles/pythClient.js +12 -31
- package/lib/oracles/quoteAssetOracleClient.d.ts +9 -0
- package/lib/oracles/quoteAssetOracleClient.js +21 -0
- package/lib/oracles/switchboardClient.d.ts +3 -5
- package/lib/oracles/switchboardClient.js +29 -50
- package/lib/oracles/types.d.ts +6 -1
- package/lib/orderParams.d.ts +14 -5
- package/lib/orderParams.js +8 -96
- package/lib/orders.d.ts +6 -7
- package/lib/orders.js +11 -89
- package/lib/slot/SlotSubscriber.d.ts +19 -0
- package/lib/slot/SlotSubscriber.js +26 -0
- package/lib/tx/retryTxSender.d.ts +2 -2
- package/lib/tx/retryTxSender.js +108 -123
- package/lib/tx/types.d.ts +5 -1
- package/lib/tx/utils.d.ts +1 -1
- package/lib/tx/utils.js +11 -2
- package/lib/types.d.ts +180 -110
- package/lib/types.js +54 -1
- package/lib/userName.d.ts +4 -0
- package/lib/userName.js +20 -0
- package/lib/util/computeUnits.js +10 -21
- package/lib/util/tps.js +11 -22
- package/lib/wallet.js +7 -20
- package/package.json +11 -4
- package/src/accounts/bulkAccountLoader.js +197 -0
- package/src/accounts/bulkAccountLoader.ts +21 -15
- package/src/accounts/bulkUserSubscription.js +33 -0
- package/src/accounts/bulkUserSubscription.ts +1 -45
- package/src/accounts/fetch.js +29 -0
- package/src/accounts/fetch.ts +33 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +311 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +249 -214
- package/src/accounts/pollingOracleSubscriber.js +93 -0
- package/src/accounts/pollingOracleSubscriber.ts +16 -8
- package/src/accounts/pollingTokenAccountSubscriber.js +90 -0
- package/src/accounts/pollingTokenAccountSubscriber.ts +11 -8
- package/src/accounts/pollingUserAccountSubscriber.js +132 -0
- package/src/accounts/pollingUserAccountSubscriber.ts +21 -86
- package/src/accounts/types.js +10 -0
- package/src/accounts/types.ts +41 -70
- package/src/accounts/utils.js +7 -0
- package/src/accounts/webSocketAccountSubscriber.js +93 -0
- package/src/accounts/webSocketAccountSubscriber.ts +33 -16
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +233 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +190 -240
- package/src/accounts/webSocketUserAccountSubscriber.js +62 -0
- package/src/accounts/webSocketUserAccountSubscriber.ts +11 -71
- package/src/addresses/marketAddresses.js +26 -0
- package/src/addresses/marketAddresses.ts +18 -0
- package/{lib/addresses.js → src/addresses/pda.js} +45 -34
- package/src/addresses/pda.ts +118 -0
- package/src/admin.ts +247 -336
- package/src/assert/assert.js +9 -0
- package/src/clearingHouse.ts +1023 -1026
- package/src/clearingHouseConfig.ts +37 -0
- package/src/clearingHouseUser.ts +275 -185
- package/src/clearingHouseUserConfig.ts +18 -0
- package/src/config.ts +54 -1
- package/src/constants/banks.ts +50 -0
- package/src/constants/markets.ts +16 -207
- package/src/constants/numericConstants.ts +34 -5
- package/src/events/eventList.js +77 -0
- package/src/events/eventList.ts +94 -0
- package/src/events/eventSubscriber.js +139 -0
- package/src/events/eventSubscriber.ts +194 -0
- package/src/events/fetchLogs.js +50 -0
- package/src/events/fetchLogs.ts +80 -0
- package/src/events/pollingLogProvider.js +64 -0
- package/src/events/pollingLogProvider.ts +79 -0
- package/src/events/sort.js +44 -0
- package/src/events/sort.ts +65 -0
- package/src/events/txEventCache.js +71 -0
- package/src/events/txEventCache.ts +74 -0
- package/src/events/types.js +20 -0
- package/src/events/types.ts +98 -0
- package/src/events/webSocketLogProvider.js +41 -0
- package/src/events/webSocketLogProvider.ts +38 -0
- package/src/examples/makeTradeExample.js +80 -0
- package/src/examples/makeTradeExample.ts +20 -11
- package/src/factory/bigNum.js +364 -0
- package/src/factory/bigNum.ts +524 -0
- package/src/factory/oracleClient.js +20 -0
- package/src/factory/oracleClient.ts +7 -4
- package/src/idl/clearing_house.json +2258 -2774
- package/src/index.js +69 -0
- package/src/index.ts +14 -5
- package/src/math/amm.js +369 -0
- package/src/math/amm.ts +382 -243
- package/src/math/auction.js +42 -0
- package/src/math/auction.ts +43 -0
- package/src/math/bankBalance.js +75 -0
- package/src/math/bankBalance.ts +112 -0
- package/src/math/conversion.js +11 -0
- package/src/math/conversion.ts +1 -11
- package/src/math/funding.js +248 -0
- package/src/math/funding.ts +12 -9
- package/src/math/market.js +57 -0
- package/src/math/market.ts +37 -30
- package/src/math/oracles.js +26 -0
- package/src/math/orders.js +110 -0
- package/src/math/orders.ts +43 -1
- package/src/math/position.js +140 -0
- package/src/math/position.ts +52 -35
- package/src/math/repeg.js +128 -0
- package/src/math/repeg.ts +176 -0
- package/src/math/state.js +15 -0
- package/src/math/trade.js +253 -0
- package/src/math/trade.ts +55 -47
- package/src/math/utils.js +26 -0
- package/src/math/utils.js.map +1 -0
- package/src/mockUSDCFaucet.js +171 -0
- package/src/oracles/oracleClientCache.js +19 -0
- package/src/oracles/oracleClientCache.ts +20 -0
- package/src/oracles/pythClient.js +46 -0
- package/src/oracles/pythClient.ts +4 -11
- package/src/oracles/quoteAssetOracleClient.js +32 -0
- package/src/oracles/quoteAssetOracleClient.ts +25 -0
- package/src/oracles/switchboardClient.js +69 -0
- package/src/oracles/switchboardClient.ts +11 -24
- package/src/oracles/types.js +2 -0
- package/src/oracles/types.ts +7 -1
- package/src/orderParams.js +20 -0
- package/src/orderParams.ts +20 -141
- package/src/orders.js +134 -0
- package/src/orders.ts +25 -134
- package/src/slot/SlotSubscriber.js +39 -0
- package/src/slot/SlotSubscriber.ts +42 -0
- package/src/token/index.js +38 -0
- package/src/tx/retryTxSender.js +188 -0
- package/src/tx/retryTxSender.ts +6 -4
- package/src/tx/types.js +2 -0
- package/src/tx/types.ts +6 -1
- package/src/tx/utils.js +17 -0
- package/src/tx/utils.ts +22 -3
- package/src/types.js +114 -0
- package/src/types.ts +176 -124
- package/src/userName.js +20 -0
- package/src/userName.ts +20 -0
- package/src/util/promiseTimeout.js +14 -0
- package/src/util/tps.js +27 -0
- package/src/wallet.js +35 -0
- package/tests/bn/test.ts +255 -0
- package/tsconfig.json +12 -12
- package/lib/addresses.d.ts +0 -10
- package/lib/constants/accounts.d.ts +0 -15
- package/lib/constants/accounts.js +0 -18
- package/lib/factory/clearingHouse.d.ts +0 -35
- package/lib/factory/clearingHouse.js +0 -81
- package/lib/factory/clearingHouseUser.d.ts +0 -19
- package/lib/factory/clearingHouseUser.js +0 -34
- package/lib/math/insuranceFund.d.ts +0 -15
- package/lib/math/insuranceFund.js +0 -33
- package/lib/settlement.d.ts +0 -4
- package/lib/settlement.js +0 -10
- package/lib/tx/defaultTxSender.d.ts +0 -8
- package/lib/tx/defaultTxSender.js +0 -12
- package/src/addresses.ts +0 -82
- package/src/constants/accounts.ts +0 -26
- package/src/factory/clearingHouse.ts +0 -173
- package/src/factory/clearingHouseUser.ts +0 -73
- package/src/math/insuranceFund.ts +0 -29
- package/src/settlement.ts +0 -9
- package/src/tx/defaultTxSender.ts +0 -24
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drift-labs/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-master.10",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"author": "crispheaney",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"lint": "eslint './**/*.{ts,tsx}' --quiet",
|
|
14
14
|
"build": "yarn clean && tsc",
|
|
15
15
|
"clean": "rm -rf lib",
|
|
16
|
+
"test": "mocha -r ts-node/register tests/**/*.ts",
|
|
16
17
|
"patch-and-pub": "npm version patch --force && npm publish"
|
|
17
18
|
},
|
|
18
19
|
"keywords": [
|
|
@@ -29,19 +30,25 @@
|
|
|
29
30
|
},
|
|
30
31
|
"dependencies": {
|
|
31
32
|
"@project-serum/anchor": "0.24.2",
|
|
32
|
-
"@pythnetwork/client": "
|
|
33
|
+
"@pythnetwork/client": "2.5.3",
|
|
33
34
|
"@solana/spl-token": "^0.1.6",
|
|
34
|
-
"@solana/web3.js": "
|
|
35
|
+
"@solana/web3.js": "1.41.0",
|
|
35
36
|
"@switchboard-xyz/switchboard-v2": "^0.0.67",
|
|
36
37
|
"strict-event-emitter-types": "^2.0.0",
|
|
37
38
|
"uuid": "^8.3.2"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
41
|
+
"@types/chai": "^4.3.1",
|
|
42
|
+
"@types/jest": "^28.1.3",
|
|
43
|
+
"@types/mocha": "^9.1.1",
|
|
40
44
|
"@typescript-eslint/eslint-plugin": "^4.28.0",
|
|
41
45
|
"@typescript-eslint/parser": "^4.28.0",
|
|
46
|
+
"chai": "^4.3.6",
|
|
42
47
|
"eslint": "^7.29.0",
|
|
43
48
|
"eslint-config-prettier": "^8.3.0",
|
|
44
|
-
"eslint-plugin-prettier": "^3.4.0"
|
|
49
|
+
"eslint-plugin-prettier": "^3.4.0",
|
|
50
|
+
"mocha": "^10.0.0",
|
|
51
|
+
"ts-node": "^10.8.0"
|
|
45
52
|
},
|
|
46
53
|
"description": "SDK for Drift Protocol v1",
|
|
47
54
|
"engines": {
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.BulkAccountLoader = void 0;
|
|
13
|
+
const uuid_1 = require("uuid");
|
|
14
|
+
const promiseTimeout_1 = require("../util/promiseTimeout");
|
|
15
|
+
const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
|
|
16
|
+
const oneMinute = 60 * 1000;
|
|
17
|
+
class BulkAccountLoader {
|
|
18
|
+
constructor(connection, commitment, pollingFrequency) {
|
|
19
|
+
this.accountsToLoad = new Map();
|
|
20
|
+
this.bufferAndSlotMap = new Map();
|
|
21
|
+
this.errorCallbacks = new Map();
|
|
22
|
+
this.lastTimeLoadingPromiseCleared = Date.now();
|
|
23
|
+
this.mostRecentSlot = 0;
|
|
24
|
+
this.connection = connection;
|
|
25
|
+
this.commitment = commitment;
|
|
26
|
+
this.pollingFrequency = pollingFrequency;
|
|
27
|
+
}
|
|
28
|
+
addAccount(publicKey, callback) {
|
|
29
|
+
const existingSize = this.accountsToLoad.size;
|
|
30
|
+
const callbackId = uuid_1.v4();
|
|
31
|
+
const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
|
|
32
|
+
if (existingAccountToLoad) {
|
|
33
|
+
existingAccountToLoad.callbacks.set(callbackId, callback);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const callbacks = new Map();
|
|
37
|
+
callbacks.set(callbackId, callback);
|
|
38
|
+
const newAccountToLoad = {
|
|
39
|
+
publicKey,
|
|
40
|
+
callbacks,
|
|
41
|
+
};
|
|
42
|
+
this.accountsToLoad.set(publicKey.toString(), newAccountToLoad);
|
|
43
|
+
}
|
|
44
|
+
if (existingSize === 0) {
|
|
45
|
+
this.startPolling();
|
|
46
|
+
}
|
|
47
|
+
// if a new account needs to be polled, remove the cached loadPromise in case client calls load immediately after
|
|
48
|
+
this.loadPromise = undefined;
|
|
49
|
+
return callbackId;
|
|
50
|
+
}
|
|
51
|
+
removeAccount(publicKey, callbackId) {
|
|
52
|
+
const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
|
|
53
|
+
if (existingAccountToLoad) {
|
|
54
|
+
existingAccountToLoad.callbacks.delete(callbackId);
|
|
55
|
+
if (existingAccountToLoad.callbacks.size === 0) {
|
|
56
|
+
this.accountsToLoad.delete(existingAccountToLoad.publicKey.toString());
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (this.accountsToLoad.size === 0) {
|
|
60
|
+
this.stopPolling();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
addErrorCallbacks(callback) {
|
|
64
|
+
const callbackId = uuid_1.v4();
|
|
65
|
+
this.errorCallbacks.set(callbackId, callback);
|
|
66
|
+
return callbackId;
|
|
67
|
+
}
|
|
68
|
+
removeErrorCallbacks(callbackId) {
|
|
69
|
+
this.errorCallbacks.delete(callbackId);
|
|
70
|
+
}
|
|
71
|
+
chunks(array, size) {
|
|
72
|
+
return new Array(Math.ceil(array.length / size))
|
|
73
|
+
.fill(null)
|
|
74
|
+
.map((_, index) => index * size)
|
|
75
|
+
.map((begin) => array.slice(begin, begin + size));
|
|
76
|
+
}
|
|
77
|
+
load() {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
if (this.loadPromise) {
|
|
80
|
+
const now = Date.now();
|
|
81
|
+
if (now - this.lastTimeLoadingPromiseCleared > oneMinute) {
|
|
82
|
+
this.loadPromise = undefined;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
return this.loadPromise;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
this.loadPromise = new Promise((resolver) => {
|
|
89
|
+
this.loadPromiseResolver = resolver;
|
|
90
|
+
});
|
|
91
|
+
this.lastTimeLoadingPromiseCleared = Date.now();
|
|
92
|
+
try {
|
|
93
|
+
const chunks = this.chunks(Array.from(this.accountsToLoad.values()), GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE);
|
|
94
|
+
yield Promise.all(chunks.map((chunk) => {
|
|
95
|
+
return this.loadChunk(chunk);
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
console.error(`Error in bulkAccountLoader.load()`);
|
|
100
|
+
console.error(e);
|
|
101
|
+
for (const [_, callback] of this.errorCallbacks) {
|
|
102
|
+
callback(e);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
this.loadPromiseResolver();
|
|
107
|
+
this.loadPromise = undefined;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
loadChunk(accountsToLoad) {
|
|
112
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
+
if (accountsToLoad.length === 0) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const args = [
|
|
117
|
+
accountsToLoad.map((accountToLoad) => {
|
|
118
|
+
return accountToLoad.publicKey.toBase58();
|
|
119
|
+
}),
|
|
120
|
+
{ commitment: this.commitment },
|
|
121
|
+
];
|
|
122
|
+
const rpcResponse = yield promiseTimeout_1.promiseTimeout(
|
|
123
|
+
// @ts-ignore
|
|
124
|
+
this.connection._rpcRequest('getMultipleAccounts', args), 10 * 1000 // 30 second timeout
|
|
125
|
+
);
|
|
126
|
+
if (rpcResponse === null) {
|
|
127
|
+
this.log('request to rpc timed out');
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const newSlot = rpcResponse.result.context.slot;
|
|
131
|
+
if (newSlot > this.mostRecentSlot) {
|
|
132
|
+
this.mostRecentSlot = newSlot;
|
|
133
|
+
}
|
|
134
|
+
for (const i in accountsToLoad) {
|
|
135
|
+
const accountToLoad = accountsToLoad[i];
|
|
136
|
+
const key = accountToLoad.publicKey.toString();
|
|
137
|
+
const oldRPCResponse = this.bufferAndSlotMap.get(key);
|
|
138
|
+
let newBuffer = undefined;
|
|
139
|
+
if (rpcResponse.result.value[i]) {
|
|
140
|
+
const raw = rpcResponse.result.value[i].data[0];
|
|
141
|
+
const dataType = rpcResponse.result.value[i].data[1];
|
|
142
|
+
newBuffer = Buffer.from(raw, dataType);
|
|
143
|
+
}
|
|
144
|
+
if (!oldRPCResponse) {
|
|
145
|
+
this.bufferAndSlotMap.set(key, {
|
|
146
|
+
slot: newSlot,
|
|
147
|
+
buffer: newBuffer,
|
|
148
|
+
});
|
|
149
|
+
this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (newSlot <= oldRPCResponse.slot) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const oldBuffer = oldRPCResponse.buffer;
|
|
156
|
+
if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
|
|
157
|
+
this.bufferAndSlotMap.set(key, {
|
|
158
|
+
slot: newSlot,
|
|
159
|
+
buffer: newBuffer,
|
|
160
|
+
});
|
|
161
|
+
this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
handleAccountCallbacks(accountToLoad, buffer, slot) {
|
|
167
|
+
for (const [_, callback] of accountToLoad.callbacks) {
|
|
168
|
+
callback(buffer, slot);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
getBufferAndSlot(publicKey) {
|
|
172
|
+
return this.bufferAndSlotMap.get(publicKey.toString());
|
|
173
|
+
}
|
|
174
|
+
startPolling() {
|
|
175
|
+
if (this.intervalId) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
this.intervalId = setInterval(this.load.bind(this), this.pollingFrequency);
|
|
179
|
+
}
|
|
180
|
+
stopPolling() {
|
|
181
|
+
if (this.intervalId) {
|
|
182
|
+
clearInterval(this.intervalId);
|
|
183
|
+
this.intervalId = undefined;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
log(msg) {
|
|
187
|
+
console.log(msg);
|
|
188
|
+
}
|
|
189
|
+
updatePollingFrequency(pollingFrequency) {
|
|
190
|
+
this.stopPolling();
|
|
191
|
+
this.pollingFrequency = pollingFrequency;
|
|
192
|
+
if (this.accountsToLoad.size > 0) {
|
|
193
|
+
this.startPolling();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
exports.BulkAccountLoader = BulkAccountLoader;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Commitment, Connection, PublicKey } from '@solana/web3.js';
|
|
2
2
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
-
import {
|
|
3
|
+
import { BufferAndSlot } from './types';
|
|
4
4
|
import { promiseTimeout } from '../util/promiseTimeout';
|
|
5
5
|
|
|
6
6
|
type AccountToLoad = {
|
|
7
7
|
publicKey: PublicKey;
|
|
8
|
-
callbacks: Map<string, (buffer: Buffer) => void>;
|
|
8
|
+
callbacks: Map<string, (buffer: Buffer, slot: number) => void>;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
|
|
@@ -17,7 +17,7 @@ export class BulkAccountLoader {
|
|
|
17
17
|
commitment: Commitment;
|
|
18
18
|
pollingFrequency: number;
|
|
19
19
|
accountsToLoad = new Map<string, AccountToLoad>();
|
|
20
|
-
|
|
20
|
+
bufferAndSlotMap = new Map<string, BufferAndSlot>();
|
|
21
21
|
errorCallbacks = new Map<string, (e) => void>();
|
|
22
22
|
intervalId?: NodeJS.Timer;
|
|
23
23
|
// to handle clients spamming load
|
|
@@ -38,7 +38,7 @@ export class BulkAccountLoader {
|
|
|
38
38
|
|
|
39
39
|
public addAccount(
|
|
40
40
|
publicKey: PublicKey,
|
|
41
|
-
callback: (buffer: Buffer) => void
|
|
41
|
+
callback: (buffer: Buffer, slot: number) => void
|
|
42
42
|
): string {
|
|
43
43
|
const existingSize = this.accountsToLoad.size;
|
|
44
44
|
|
|
@@ -47,7 +47,10 @@ export class BulkAccountLoader {
|
|
|
47
47
|
if (existingAccountToLoad) {
|
|
48
48
|
existingAccountToLoad.callbacks.set(callbackId, callback);
|
|
49
49
|
} else {
|
|
50
|
-
const callbacks = new Map<
|
|
50
|
+
const callbacks = new Map<
|
|
51
|
+
string,
|
|
52
|
+
(buffer: Buffer, slot: number) => void
|
|
53
|
+
>();
|
|
51
54
|
callbacks.set(callbackId, callback);
|
|
52
55
|
const newAccountToLoad = {
|
|
53
56
|
publicKey,
|
|
@@ -167,7 +170,7 @@ export class BulkAccountLoader {
|
|
|
167
170
|
for (const i in accountsToLoad) {
|
|
168
171
|
const accountToLoad = accountsToLoad[i];
|
|
169
172
|
const key = accountToLoad.publicKey.toString();
|
|
170
|
-
const oldRPCResponse = this.
|
|
173
|
+
const oldRPCResponse = this.bufferAndSlotMap.get(key);
|
|
171
174
|
|
|
172
175
|
let newBuffer: Buffer | undefined = undefined;
|
|
173
176
|
if (rpcResponse.result.value[i]) {
|
|
@@ -177,11 +180,11 @@ export class BulkAccountLoader {
|
|
|
177
180
|
}
|
|
178
181
|
|
|
179
182
|
if (!oldRPCResponse) {
|
|
180
|
-
this.
|
|
183
|
+
this.bufferAndSlotMap.set(key, {
|
|
181
184
|
slot: newSlot,
|
|
182
185
|
buffer: newBuffer,
|
|
183
186
|
});
|
|
184
|
-
this.handleAccountCallbacks(accountToLoad, newBuffer);
|
|
187
|
+
this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
|
|
185
188
|
continue;
|
|
186
189
|
}
|
|
187
190
|
|
|
@@ -191,24 +194,27 @@ export class BulkAccountLoader {
|
|
|
191
194
|
|
|
192
195
|
const oldBuffer = oldRPCResponse.buffer;
|
|
193
196
|
if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
|
|
194
|
-
this.
|
|
197
|
+
this.bufferAndSlotMap.set(key, {
|
|
195
198
|
slot: newSlot,
|
|
196
199
|
buffer: newBuffer,
|
|
197
200
|
});
|
|
198
|
-
this.handleAccountCallbacks(accountToLoad, newBuffer);
|
|
201
|
+
this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
|
|
199
202
|
}
|
|
200
203
|
}
|
|
201
204
|
}
|
|
202
205
|
|
|
203
|
-
handleAccountCallbacks(
|
|
206
|
+
handleAccountCallbacks(
|
|
207
|
+
accountToLoad: AccountToLoad,
|
|
208
|
+
buffer: Buffer,
|
|
209
|
+
slot: number
|
|
210
|
+
): void {
|
|
204
211
|
for (const [_, callback] of accountToLoad.callbacks) {
|
|
205
|
-
callback(buffer);
|
|
212
|
+
callback(buffer, slot);
|
|
206
213
|
}
|
|
207
214
|
}
|
|
208
215
|
|
|
209
|
-
public
|
|
210
|
-
|
|
211
|
-
return accountData?.buffer;
|
|
216
|
+
public getBufferAndSlot(publicKey: PublicKey): BufferAndSlot | undefined {
|
|
217
|
+
return this.bufferAndSlotMap.get(publicKey.toString());
|
|
212
218
|
}
|
|
213
219
|
|
|
214
220
|
public startPolling(): void {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.bulkPollingUserSubscribe = void 0;
|
|
13
|
+
/**
|
|
14
|
+
* @param users
|
|
15
|
+
* @param accountLoader
|
|
16
|
+
*/
|
|
17
|
+
function bulkPollingUserSubscribe(users, accountLoader) {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
if (users.length === 0) {
|
|
20
|
+
yield accountLoader.load();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
yield Promise.all(users.map((user) => {
|
|
24
|
+
// Pull the keys from the authority map so we can skip fetching them in addToAccountLoader
|
|
25
|
+
return user.accountSubscriber.addToAccountLoader();
|
|
26
|
+
}));
|
|
27
|
+
yield accountLoader.load();
|
|
28
|
+
yield Promise.all(users.map((user) => __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
return user.subscribe();
|
|
30
|
+
})));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
exports.bulkPollingUserSubscribe = bulkPollingUserSubscribe;
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { ClearingHouseUser } from '../clearingHouseUser';
|
|
2
2
|
import { BulkAccountLoader } from './bulkAccountLoader';
|
|
3
3
|
import { PollingUserAccountSubscriber } from './pollingUserAccountSubscriber';
|
|
4
|
-
import { UserAccount, UserOrdersAccount } from '../types';
|
|
5
|
-
import { UserPublicKeys } from './types';
|
|
6
|
-
import { ProgramAccount } from '@project-serum/anchor';
|
|
7
4
|
|
|
8
5
|
/**
|
|
9
6
|
* @param users
|
|
@@ -18,53 +15,12 @@ export async function bulkPollingUserSubscribe(
|
|
|
18
15
|
return;
|
|
19
16
|
}
|
|
20
17
|
|
|
21
|
-
// Fetch all the accounts first
|
|
22
|
-
const program = users[0].clearingHouse.program;
|
|
23
|
-
let userProgramAccounts: ProgramAccount[];
|
|
24
|
-
let orderProgramAccounts: ProgramAccount[];
|
|
25
|
-
await Promise.all([
|
|
26
|
-
(async () => {
|
|
27
|
-
userProgramAccounts = await program.account.user.all();
|
|
28
|
-
})(),
|
|
29
|
-
(async () => {
|
|
30
|
-
orderProgramAccounts = await program.account.userOrders.all();
|
|
31
|
-
})(),
|
|
32
|
-
]);
|
|
33
|
-
|
|
34
|
-
// Create a map of the authority to keys
|
|
35
|
-
const authorityToKeys = new Map<string, UserPublicKeys>();
|
|
36
|
-
const userToAuthority = new Map<string, string>();
|
|
37
|
-
for (const userProgramAccount of userProgramAccounts) {
|
|
38
|
-
const userAccountPublicKey = userProgramAccount.publicKey;
|
|
39
|
-
const userAccount = userProgramAccount.account as UserAccount;
|
|
40
|
-
|
|
41
|
-
authorityToKeys.set(userAccount.authority.toString(), {
|
|
42
|
-
user: userAccountPublicKey,
|
|
43
|
-
userPositions: userAccount.positions,
|
|
44
|
-
userOrders: undefined,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
userToAuthority.set(
|
|
48
|
-
userAccountPublicKey.toString(),
|
|
49
|
-
userAccount.authority.toString()
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
for (const orderProgramAccount of orderProgramAccounts) {
|
|
53
|
-
const userOrderAccountPublicKey = orderProgramAccount.publicKey;
|
|
54
|
-
const userOrderAccount = orderProgramAccount.account as UserOrdersAccount;
|
|
55
|
-
|
|
56
|
-
const authority = userToAuthority.get(userOrderAccount.user.toString());
|
|
57
|
-
const userPublicKeys = authorityToKeys.get(authority);
|
|
58
|
-
userPublicKeys.userOrders = userOrderAccountPublicKey;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
18
|
await Promise.all(
|
|
62
19
|
users.map((user) => {
|
|
63
20
|
// Pull the keys from the authority map so we can skip fetching them in addToAccountLoader
|
|
64
|
-
const userPublicKeys = authorityToKeys.get(user.authority.toString());
|
|
65
21
|
return (
|
|
66
22
|
user.accountSubscriber as PollingUserAccountSubscriber
|
|
67
|
-
).addToAccountLoader(
|
|
23
|
+
).addToAccountLoader();
|
|
68
24
|
})
|
|
69
25
|
);
|
|
70
26
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.fetchUserAccounts = void 0;
|
|
13
|
+
const pda_1 = require("../addresses/pda");
|
|
14
|
+
function fetchUserAccounts(connection, program, authority, limit = 8) {
|
|
15
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
const userAccountPublicKeys = new Array();
|
|
17
|
+
for (let i = 0; i < limit; i++) {
|
|
18
|
+
userAccountPublicKeys.push(yield pda_1.getUserAccountPublicKey(program.programId, authority, i));
|
|
19
|
+
}
|
|
20
|
+
const accountInfos = yield connection.getMultipleAccountsInfo(userAccountPublicKeys, 'confirmed');
|
|
21
|
+
return accountInfos.map((accountInfo) => {
|
|
22
|
+
if (!accountInfo) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
return program.account.user.coder.accounts.decode('User', accountInfo.data);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
exports.fetchUserAccounts = fetchUserAccounts;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Connection, PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { UserAccount } from '../types';
|
|
3
|
+
import { getUserAccountPublicKey } from '../addresses/pda';
|
|
4
|
+
import { Program } from '@project-serum/anchor';
|
|
5
|
+
|
|
6
|
+
export async function fetchUserAccounts(
|
|
7
|
+
connection: Connection,
|
|
8
|
+
program: Program,
|
|
9
|
+
authority: PublicKey,
|
|
10
|
+
limit = 8
|
|
11
|
+
): Promise<(UserAccount | undefined)[]> {
|
|
12
|
+
const userAccountPublicKeys = new Array<PublicKey>();
|
|
13
|
+
for (let i = 0; i < limit; i++) {
|
|
14
|
+
userAccountPublicKeys.push(
|
|
15
|
+
await getUserAccountPublicKey(program.programId, authority, i)
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const accountInfos = await connection.getMultipleAccountsInfo(
|
|
20
|
+
userAccountPublicKeys,
|
|
21
|
+
'confirmed'
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
return accountInfos.map((accountInfo) => {
|
|
25
|
+
if (!accountInfo) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
return program.account.user.coder.accounts.decode(
|
|
29
|
+
'User',
|
|
30
|
+
accountInfo.data
|
|
31
|
+
) as UserAccount;
|
|
32
|
+
});
|
|
33
|
+
}
|