@drift-labs/sdk 0.1.36-master.5 → 0.2.0-master.0
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 +7 -6
- package/lib/accounts/bulkAccountLoader.js +83 -93
- 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 +8 -12
- package/lib/admin.js +366 -490
- package/lib/clearingHouse.d.ts +84 -103
- package/lib/clearingHouse.js +779 -810
- package/lib/clearingHouseConfig.d.ts +34 -0
- package/lib/clearingHouseConfig.js +2 -0
- package/lib/clearingHouseUser.d.ts +19 -18
- package/lib/clearingHouseUser.js +157 -115
- 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 +34 -0
- package/lib/constants/markets.d.ts +8 -3
- package/lib/constants/markets.js +13 -206
- package/lib/constants/numericConstants.d.ts +16 -0
- package/lib/constants/numericConstants.js +22 -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 +112 -0
- package/lib/factory/bigNum.js +356 -0
- package/lib/factory/oracleClient.d.ts +1 -2
- package/lib/factory/oracleClient.js +6 -2
- package/lib/idl/clearing_house.json +1739 -2287
- package/lib/index.d.ts +13 -4
- package/lib/index.js +13 -4
- package/lib/math/amm.d.ts +19 -29
- package/lib/math/amm.js +129 -179
- package/lib/math/auction.d.ts +5 -0
- package/lib/math/auction.js +39 -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/oracles.d.ts +3 -0
- package/lib/math/oracles.js +26 -0
- package/lib/math/orders.d.ts +5 -0
- package/lib/math/orders.js +31 -1
- package/lib/math/position.d.ts +7 -4
- package/lib/math/position.js +27 -9
- package/lib/math/repeg.d.ts +22 -0
- package/lib/math/repeg.js +128 -0
- package/lib/math/trade.d.ts +13 -8
- package/lib/math/trade.js +85 -22
- 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 -30
- 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 -47
- package/lib/oracles/types.d.ts +7 -1
- package/lib/orders.d.ts +6 -6
- package/lib/orders.js +10 -9
- package/lib/slot/SlotSubscriber.d.ts +12 -0
- package/lib/slot/SlotSubscriber.js +23 -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 +105 -98
- package/lib/types.js +13 -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 +10 -3
- package/src/accounts/bulkAccountLoader.ts +26 -15
- package/src/accounts/bulkUserSubscription.ts +1 -45
- package/src/accounts/fetch.ts +33 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +249 -214
- package/src/accounts/pollingOracleSubscriber.ts +16 -8
- package/src/accounts/pollingTokenAccountSubscriber.ts +11 -8
- package/src/accounts/pollingUserAccountSubscriber.ts +21 -86
- package/src/accounts/types.ts +41 -70
- package/src/accounts/webSocketAccountSubscriber.ts +33 -16
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +190 -240
- package/src/accounts/webSocketUserAccountSubscriber.ts +11 -71
- package/src/addresses/marketAddresses.ts +18 -0
- package/src/addresses/pda.ts +118 -0
- package/src/admin.ts +209 -267
- package/src/clearingHouse.ts +921 -829
- package/src/clearingHouseConfig.ts +37 -0
- package/src/clearingHouseUser.ts +280 -127
- package/src/clearingHouseUserConfig.ts +18 -0
- package/src/config.ts +54 -1
- package/src/constants/banks.ts +43 -0
- package/src/constants/markets.ts +16 -207
- package/src/constants/numericConstants.ts +33 -5
- package/src/events/eventList.ts +94 -0
- package/src/events/eventSubscriber.ts +194 -0
- package/src/events/fetchLogs.ts +80 -0
- package/src/events/pollingLogProvider.ts +79 -0
- package/src/events/sort.ts +65 -0
- package/src/events/txEventCache.ts +74 -0
- package/src/events/types.ts +98 -0
- package/src/events/webSocketLogProvider.ts +38 -0
- package/src/examples/makeTradeExample.ts +20 -11
- package/src/factory/bigNum.ts +507 -0
- package/src/factory/oracleClient.ts +7 -4
- package/src/idl/clearing_house.json +1739 -2287
- package/src/index.ts +13 -4
- package/src/math/amm.ts +229 -245
- package/src/math/auction.ts +39 -0
- package/src/math/bankBalance.ts +112 -0
- package/src/math/conversion.ts +1 -11
- package/src/math/funding.ts +12 -9
- package/src/math/market.ts +37 -30
- package/src/math/oracles.ts +36 -0
- package/src/math/orders.ts +38 -0
- package/src/math/position.ts +48 -13
- package/src/math/repeg.ts +175 -0
- package/src/math/trade.ts +114 -36
- package/src/math/utils.js +27 -0
- package/src/math/utils.js.map +1 -0
- package/src/oracles/oracleClientCache.ts +20 -0
- package/src/oracles/pythClient.ts +5 -11
- package/src/oracles/quoteAssetOracleClient.ts +25 -0
- package/src/oracles/switchboardClient.ts +16 -24
- package/src/oracles/types.ts +8 -1
- package/src/orders.ts +35 -20
- package/src/slot/SlotSubscriber.ts +32 -0
- package/src/tx/retryTxSender.ts +6 -4
- package/src/tx/types.ts +6 -1
- package/src/tx/utils.ts +22 -3
- package/src/types.ts +108 -110
- package/src/userName.ts +20 -0
- package/src/util/computeUnits.js +17 -0
- package/src/util/computeUnits.js.map +1 -0
- package/tests/bn/test.ts +255 -0
- package/tsconfig.json +12 -12
- package/lib/addresses.d.ts +0 -9
- package/lib/addresses.js +0 -87
- 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/tx/defaultTxSender.d.ts +0 -8
- package/lib/tx/defaultTxSender.js +0 -12
- package/src/addresses.ts +0 -71
- 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/tx/defaultTxSender.ts +0 -24
package/lib/types.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TradeSide = exports.isVariant = exports.OrderTriggerCondition = exports.OrderAction = exports.OrderDiscountTier = exports.OrderStatus = exports.OrderType = exports.OracleSource = exports.PositionDirection = exports.SwapDirection = void 0;
|
|
3
|
+
exports.TradeSide = exports.isOneOfVariant = exports.isVariant = exports.OrderTriggerCondition = exports.OrderAction = exports.OrderDiscountTier = exports.OrderStatus = exports.OrderType = exports.OracleSource = exports.PositionDirection = exports.BankBalanceType = exports.SwapDirection = void 0;
|
|
4
4
|
// # Utility Types / Enums / Constants
|
|
5
5
|
class SwapDirection {
|
|
6
6
|
}
|
|
7
7
|
exports.SwapDirection = SwapDirection;
|
|
8
8
|
SwapDirection.ADD = { add: {} };
|
|
9
9
|
SwapDirection.REMOVE = { remove: {} };
|
|
10
|
+
class BankBalanceType {
|
|
11
|
+
}
|
|
12
|
+
exports.BankBalanceType = BankBalanceType;
|
|
13
|
+
BankBalanceType.DEPOSIT = { deposit: {} };
|
|
14
|
+
BankBalanceType.BORROW = { borrow: {} };
|
|
10
15
|
class PositionDirection {
|
|
11
16
|
}
|
|
12
17
|
exports.PositionDirection = PositionDirection;
|
|
@@ -17,6 +22,7 @@ class OracleSource {
|
|
|
17
22
|
exports.OracleSource = OracleSource;
|
|
18
23
|
OracleSource.PYTH = { pyth: {} };
|
|
19
24
|
OracleSource.SWITCHBOARD = { switchboard: {} };
|
|
25
|
+
OracleSource.QUOTE_ASSET = { quoteAsset: {} };
|
|
20
26
|
class OrderType {
|
|
21
27
|
}
|
|
22
28
|
exports.OrderType = OrderType;
|
|
@@ -53,6 +59,12 @@ function isVariant(object, type) {
|
|
|
53
59
|
return object.hasOwnProperty(type);
|
|
54
60
|
}
|
|
55
61
|
exports.isVariant = isVariant;
|
|
62
|
+
function isOneOfVariant(object, types) {
|
|
63
|
+
return types.reduce((result, type) => {
|
|
64
|
+
return result || object.hasOwnProperty(type);
|
|
65
|
+
}, false);
|
|
66
|
+
}
|
|
67
|
+
exports.isOneOfVariant = isOneOfVariant;
|
|
56
68
|
var TradeSide;
|
|
57
69
|
(function (TradeSide) {
|
|
58
70
|
TradeSide[TradeSide["None"] = 0] = "None";
|
package/lib/userName.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.decodeName = exports.encodeName = exports.DEFAULT_USER_NAME = exports.MAX_NAME_LENGTH = void 0;
|
|
4
|
+
exports.MAX_NAME_LENGTH = 32;
|
|
5
|
+
exports.DEFAULT_USER_NAME = 'Main Account';
|
|
6
|
+
function encodeName(name) {
|
|
7
|
+
if (name.length > exports.MAX_NAME_LENGTH) {
|
|
8
|
+
throw Error(`User name (${name}) longer than 32 characters`);
|
|
9
|
+
}
|
|
10
|
+
const buffer = Buffer.alloc(32);
|
|
11
|
+
buffer.fill(name);
|
|
12
|
+
buffer.fill(' ', name.length);
|
|
13
|
+
return Array(...buffer);
|
|
14
|
+
}
|
|
15
|
+
exports.encodeName = encodeName;
|
|
16
|
+
function decodeName(bytes) {
|
|
17
|
+
const buffer = Buffer.from(bytes);
|
|
18
|
+
return buffer.toString('utf8').trim();
|
|
19
|
+
}
|
|
20
|
+
exports.decodeName = decodeName;
|
package/lib/util/computeUnits.js
CHANGED
|
@@ -1,27 +1,16 @@
|
|
|
1
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
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.findComputeUnitConsumption = void 0;
|
|
13
|
-
function findComputeUnitConsumption(programId, connection, txSignature, commitment = 'confirmed') {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
return computeUnits;
|
|
4
|
+
async function findComputeUnitConsumption(programId, connection, txSignature, commitment = 'confirmed') {
|
|
5
|
+
const tx = await connection.getTransaction(txSignature, { commitment });
|
|
6
|
+
const computeUnits = [];
|
|
7
|
+
const regex = new RegExp(`Program ${programId.toString()} consumed ([0-9]{0,6}) of 200000 compute units`);
|
|
8
|
+
tx.meta.logMessages.forEach((logMessage) => {
|
|
9
|
+
const match = logMessage.match(regex);
|
|
10
|
+
if (match && match[1]) {
|
|
11
|
+
computeUnits.push(match[1]);
|
|
12
|
+
}
|
|
25
13
|
});
|
|
14
|
+
return computeUnits;
|
|
26
15
|
}
|
|
27
16
|
exports.findComputeUnitConsumption = findComputeUnitConsumption;
|
package/lib/util/tps.js
CHANGED
|
@@ -1,27 +1,16 @@
|
|
|
1
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
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.estimateTps = void 0;
|
|
13
|
-
function estimateTps(programId, connection, failed) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
(signatures[0].blockTime - signatures[numberOfSignatures - 1].blockTime));
|
|
25
|
-
});
|
|
4
|
+
async function estimateTps(programId, connection, failed) {
|
|
5
|
+
let signatures = await connection.getSignaturesForAddress(programId, undefined, 'finalized');
|
|
6
|
+
if (failed) {
|
|
7
|
+
signatures = signatures.filter((signature) => signature.err);
|
|
8
|
+
}
|
|
9
|
+
const numberOfSignatures = signatures.length;
|
|
10
|
+
if (numberOfSignatures === 0) {
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
return (numberOfSignatures /
|
|
14
|
+
(signatures[0].blockTime - signatures[numberOfSignatures - 1].blockTime));
|
|
26
15
|
}
|
|
27
16
|
exports.estimateTps = estimateTps;
|
package/lib/wallet.js
CHANGED
|
@@ -1,31 +1,18 @@
|
|
|
1
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
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.Wallet = void 0;
|
|
13
4
|
class Wallet {
|
|
14
5
|
constructor(payer) {
|
|
15
6
|
this.payer = payer;
|
|
16
7
|
}
|
|
17
|
-
signTransaction(tx) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return tx;
|
|
21
|
-
});
|
|
8
|
+
async signTransaction(tx) {
|
|
9
|
+
tx.partialSign(this.payer);
|
|
10
|
+
return tx;
|
|
22
11
|
}
|
|
23
|
-
signAllTransactions(txs) {
|
|
24
|
-
return
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return t;
|
|
28
|
-
});
|
|
12
|
+
async signAllTransactions(txs) {
|
|
13
|
+
return txs.map((t) => {
|
|
14
|
+
t.partialSign(this.payer);
|
|
15
|
+
return t;
|
|
29
16
|
});
|
|
30
17
|
}
|
|
31
18
|
get publicKey() {
|
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.0",
|
|
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": [
|
|
@@ -31,17 +32,23 @@
|
|
|
31
32
|
"@project-serum/anchor": "0.24.2",
|
|
32
33
|
"@pythnetwork/client": "^2.5.1",
|
|
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/mocha": "^9.1.1",
|
|
40
43
|
"@typescript-eslint/eslint-plugin": "^4.28.0",
|
|
41
44
|
"@typescript-eslint/parser": "^4.28.0",
|
|
45
|
+
"@types/jest": "^28.1.3",
|
|
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": {
|
|
@@ -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,13 +17,14 @@ 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
|
|
24
24
|
loadPromise?: Promise<void>;
|
|
25
25
|
loadPromiseResolver: () => void;
|
|
26
26
|
lastTimeLoadingPromiseCleared = Date.now();
|
|
27
|
+
mostRecentSlot = 0;
|
|
27
28
|
|
|
28
29
|
public constructor(
|
|
29
30
|
connection: Connection,
|
|
@@ -37,7 +38,7 @@ export class BulkAccountLoader {
|
|
|
37
38
|
|
|
38
39
|
public addAccount(
|
|
39
40
|
publicKey: PublicKey,
|
|
40
|
-
callback: (buffer: Buffer) => void
|
|
41
|
+
callback: (buffer: Buffer, slot: number) => void
|
|
41
42
|
): string {
|
|
42
43
|
const existingSize = this.accountsToLoad.size;
|
|
43
44
|
|
|
@@ -46,7 +47,10 @@ export class BulkAccountLoader {
|
|
|
46
47
|
if (existingAccountToLoad) {
|
|
47
48
|
existingAccountToLoad.callbacks.set(callbackId, callback);
|
|
48
49
|
} else {
|
|
49
|
-
const callbacks = new Map<
|
|
50
|
+
const callbacks = new Map<
|
|
51
|
+
string,
|
|
52
|
+
(buffer: Buffer, slot: number) => void
|
|
53
|
+
>();
|
|
50
54
|
callbacks.set(callbackId, callback);
|
|
51
55
|
const newAccountToLoad = {
|
|
52
56
|
publicKey,
|
|
@@ -159,10 +163,14 @@ export class BulkAccountLoader {
|
|
|
159
163
|
|
|
160
164
|
const newSlot = rpcResponse.result.context.slot;
|
|
161
165
|
|
|
166
|
+
if (newSlot > this.mostRecentSlot) {
|
|
167
|
+
this.mostRecentSlot = newSlot;
|
|
168
|
+
}
|
|
169
|
+
|
|
162
170
|
for (const i in accountsToLoad) {
|
|
163
171
|
const accountToLoad = accountsToLoad[i];
|
|
164
172
|
const key = accountToLoad.publicKey.toString();
|
|
165
|
-
const oldRPCResponse = this.
|
|
173
|
+
const oldRPCResponse = this.bufferAndSlotMap.get(key);
|
|
166
174
|
|
|
167
175
|
let newBuffer: Buffer | undefined = undefined;
|
|
168
176
|
if (rpcResponse.result.value[i]) {
|
|
@@ -172,11 +180,11 @@ export class BulkAccountLoader {
|
|
|
172
180
|
}
|
|
173
181
|
|
|
174
182
|
if (!oldRPCResponse) {
|
|
175
|
-
this.
|
|
183
|
+
this.bufferAndSlotMap.set(key, {
|
|
176
184
|
slot: newSlot,
|
|
177
185
|
buffer: newBuffer,
|
|
178
186
|
});
|
|
179
|
-
this.handleAccountCallbacks(accountToLoad, newBuffer);
|
|
187
|
+
this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
|
|
180
188
|
continue;
|
|
181
189
|
}
|
|
182
190
|
|
|
@@ -186,24 +194,27 @@ export class BulkAccountLoader {
|
|
|
186
194
|
|
|
187
195
|
const oldBuffer = oldRPCResponse.buffer;
|
|
188
196
|
if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
|
|
189
|
-
this.
|
|
197
|
+
this.bufferAndSlotMap.set(key, {
|
|
190
198
|
slot: newSlot,
|
|
191
199
|
buffer: newBuffer,
|
|
192
200
|
});
|
|
193
|
-
this.handleAccountCallbacks(accountToLoad, newBuffer);
|
|
201
|
+
this.handleAccountCallbacks(accountToLoad, newBuffer, newSlot);
|
|
194
202
|
}
|
|
195
203
|
}
|
|
196
204
|
}
|
|
197
205
|
|
|
198
|
-
handleAccountCallbacks(
|
|
206
|
+
handleAccountCallbacks(
|
|
207
|
+
accountToLoad: AccountToLoad,
|
|
208
|
+
buffer: Buffer,
|
|
209
|
+
slot: number
|
|
210
|
+
): void {
|
|
199
211
|
for (const [_, callback] of accountToLoad.callbacks) {
|
|
200
|
-
callback(buffer);
|
|
212
|
+
callback(buffer, slot);
|
|
201
213
|
}
|
|
202
214
|
}
|
|
203
215
|
|
|
204
|
-
public
|
|
205
|
-
|
|
206
|
-
return accountData?.buffer;
|
|
216
|
+
public getBufferAndSlot(publicKey: PublicKey): BufferAndSlot | undefined {
|
|
217
|
+
return this.bufferAndSlotMap.get(publicKey.toString());
|
|
207
218
|
}
|
|
208
219
|
|
|
209
220
|
public startPolling(): void {
|
|
@@ -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,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
|
+
}
|