@drift-labs/sdk 2.109.0-beta.1 → 2.109.0-beta.11
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/VERSION +1 -1
- package/lib/browser/accounts/grpcAccountSubscriber.d.ts +5 -5
- package/lib/browser/accounts/grpcAccountSubscriber.js +11 -6
- package/lib/browser/accounts/grpcDriftClientAccountSubscriber.js +5 -4
- package/lib/browser/accounts/grpcInsuranceFundStakeAccountSubscriber.js +4 -3
- package/lib/browser/accounts/grpcProgramAccountSubscriber.d.ts +6 -6
- package/lib/browser/accounts/grpcProgramAccountSubscriber.js +13 -6
- package/lib/browser/accounts/grpcUserAccountSubscriber.js +1 -1
- package/lib/browser/accounts/grpcUserStatsAccountSubscriber.js +1 -1
- package/lib/browser/auctionSubscriber/auctionSubscriberGrpc.js +1 -1
- package/lib/browser/constants/perpMarkets.js +11 -0
- package/lib/browser/decode/user.js +3 -1
- package/lib/browser/dlob/DLOB.js +2 -6
- package/lib/browser/driftClient.d.ts +2 -2
- package/lib/browser/driftClient.js +4 -4
- package/lib/browser/factory/oracleClient.js +3 -0
- package/lib/browser/idl/drift.json +11 -1
- package/lib/browser/oracles/oracleId.js +2 -0
- package/lib/browser/orderSubscriber/grpcSubscription.js +1 -1
- package/lib/browser/tx/baseTxSender.js +1 -1
- package/lib/browser/types.d.ts +7 -2
- package/lib/browser/types.js +4 -2
- package/lib/browser/userMap/grpcSubscription.js +1 -1
- package/lib/browser/userMap/userMap.d.ts +10 -0
- package/lib/browser/userMap/userMap.js +10 -0
- package/lib/browser/userMap/userStatsMap.d.ts +17 -2
- package/lib/browser/userMap/userStatsMap.js +108 -1
- package/lib/node/accounts/grpcAccountSubscriber.d.ts +5 -5
- package/lib/node/accounts/grpcAccountSubscriber.js +11 -6
- package/lib/node/accounts/grpcDriftClientAccountSubscriber.js +5 -4
- package/lib/node/accounts/grpcInsuranceFundStakeAccountSubscriber.js +4 -3
- package/lib/node/accounts/grpcProgramAccountSubscriber.d.ts +6 -6
- package/lib/node/accounts/grpcProgramAccountSubscriber.js +13 -6
- package/lib/node/accounts/grpcUserAccountSubscriber.js +1 -1
- package/lib/node/accounts/grpcUserStatsAccountSubscriber.js +1 -1
- package/lib/node/auctionSubscriber/auctionSubscriberGrpc.js +1 -1
- package/lib/node/constants/perpMarkets.js +11 -0
- package/lib/node/decode/user.js +3 -1
- package/lib/node/dlob/DLOB.js +2 -6
- package/lib/node/driftClient.d.ts +2 -2
- package/lib/node/driftClient.js +4 -4
- package/lib/node/factory/oracleClient.js +3 -0
- package/lib/node/idl/drift.json +11 -1
- package/lib/node/isomorphic/grpc.d.ts +3 -3
- package/lib/node/isomorphic/grpc.js +26 -11
- package/lib/node/isomorphic/grpc.node.d.ts +3 -3
- package/lib/node/isomorphic/grpc.node.js +26 -11
- package/lib/node/oracles/oracleId.js +2 -0
- package/lib/node/orderSubscriber/grpcSubscription.js +1 -1
- package/lib/node/tx/baseTxSender.js +1 -1
- package/lib/node/types.d.ts +7 -2
- package/lib/node/types.js +4 -2
- package/lib/node/userMap/grpcSubscription.js +1 -1
- package/lib/node/userMap/userMap.d.ts +10 -0
- package/lib/node/userMap/userMap.js +10 -0
- package/lib/node/userMap/userStatsMap.d.ts +17 -2
- package/lib/node/userMap/userStatsMap.js +108 -1
- package/package.json +1 -1
- package/src/accounts/grpcAccountSubscriber.ts +31 -8
- package/src/accounts/grpcDriftClientAccountSubscriber.ts +38 -34
- package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +11 -10
- package/src/accounts/grpcProgramAccountSubscriber.ts +35 -8
- package/src/accounts/grpcUserAccountSubscriber.ts +1 -1
- package/src/accounts/grpcUserStatsAccountSubscriber.ts +1 -1
- package/src/auctionSubscriber/auctionSubscriberGrpc.ts +1 -1
- package/src/constants/perpMarkets.ts +12 -0
- package/src/decode/user.ts +3 -1
- package/src/dlob/DLOB.ts +2 -6
- package/src/driftClient.ts +6 -3
- package/src/factory/oracleClient.ts +4 -0
- package/src/idl/drift.json +11 -1
- package/src/isomorphic/grpc.node.ts +6 -5
- package/src/oracles/oracleId.ts +2 -0
- package/src/orderSubscriber/grpcSubscription.ts +1 -1
- package/src/tx/baseTxSender.ts +1 -1
- package/src/types.ts +5 -2
- package/src/userMap/grpcSubscription.ts +1 -1
- package/src/userMap/userMap.ts +10 -0
- package/src/userMap/userStatsMap.ts +148 -1
- package/tests/user/helpers.ts +1 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.109.0-beta.
|
|
1
|
+
2.109.0-beta.11
|
|
@@ -4,13 +4,13 @@ import { ResubOpts, GrpcConfigs } from './types';
|
|
|
4
4
|
import { Program } from '@coral-xyz/anchor';
|
|
5
5
|
import { PublicKey } from '@solana/web3.js';
|
|
6
6
|
import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
|
|
7
|
-
import { Client, ClientDuplexStream, CommitmentLevel, SubscribeRequest, SubscribeUpdate } from '../isomorphic/grpc';
|
|
8
7
|
export declare class grpcAccountSubscriber<T> extends WebSocketAccountSubscriber<T> {
|
|
9
|
-
client
|
|
10
|
-
stream
|
|
11
|
-
commitmentLevel
|
|
8
|
+
private client;
|
|
9
|
+
private stream;
|
|
10
|
+
private commitmentLevel;
|
|
12
11
|
listenerId?: number;
|
|
13
|
-
constructor(
|
|
12
|
+
private constructor();
|
|
13
|
+
static create<U>(grpcConfigs: GrpcConfigs, accountName: string, program: Program, accountPublicKey: PublicKey, decodeBuffer?: (buffer: Buffer) => U, resubOpts?: ResubOpts): Promise<grpcAccountSubscriber<U>>;
|
|
14
14
|
subscribe(onChange: (data: T) => void): Promise<void>;
|
|
15
15
|
unsubscribe(onResub?: boolean): Promise<void>;
|
|
16
16
|
}
|
|
@@ -29,13 +29,18 @@ const Buffer = __importStar(require("buffer"));
|
|
|
29
29
|
const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
|
|
30
30
|
const grpc_1 = require("../isomorphic/grpc");
|
|
31
31
|
class grpcAccountSubscriber extends webSocketAccountSubscriber_1.WebSocketAccountSubscriber {
|
|
32
|
-
constructor(
|
|
33
|
-
var _a, _b;
|
|
32
|
+
constructor(client, commitmentLevel, accountName, program, accountPublicKey, decodeBuffer, resubOpts) {
|
|
34
33
|
super(accountName, program, accountPublicKey, decodeBuffer, resubOpts);
|
|
35
|
-
this.client =
|
|
36
|
-
this.commitmentLevel =
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
this.client = client;
|
|
35
|
+
this.commitmentLevel = commitmentLevel;
|
|
36
|
+
}
|
|
37
|
+
static async create(grpcConfigs, accountName, program, accountPublicKey, decodeBuffer, resubOpts) {
|
|
38
|
+
var _a, _b;
|
|
39
|
+
const client = await (0, grpc_1.createClient)(grpcConfigs.endpoint, grpcConfigs.token, (_a = grpcConfigs.channelOptions) !== null && _a !== void 0 ? _a : {});
|
|
40
|
+
const commitmentLevel =
|
|
41
|
+
// @ts-ignore :: isomorphic exported enum fails typescript but will work at runtime
|
|
42
|
+
(_b = grpcConfigs.commitmentLevel) !== null && _b !== void 0 ? _b : CommitmentLevel.CONFIRMED;
|
|
43
|
+
return new grpcAccountSubscriber(client, commitmentLevel, accountName, program, accountPublicKey, decodeBuffer, resubOpts);
|
|
39
44
|
}
|
|
40
45
|
async subscribe(onChange) {
|
|
41
46
|
if (this.listenerId != null || this.isUnsubscribing) {
|
|
@@ -33,7 +33,8 @@ class gprcDriftClientAccountSubscriber extends webSocketDriftClientAccountSubscr
|
|
|
33
33
|
}
|
|
34
34
|
const statePublicKey = await (0, pda_1.getDriftStateAccountPublicKey)(this.program.programId);
|
|
35
35
|
// create and activate main state account subscription
|
|
36
|
-
this.stateAccountSubscriber =
|
|
36
|
+
this.stateAccountSubscriber =
|
|
37
|
+
await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'state', this.program, statePublicKey, undefined, undefined);
|
|
37
38
|
await this.stateAccountSubscriber.subscribe((data) => {
|
|
38
39
|
this.eventEmitter.emit('stateAccountUpdate', data);
|
|
39
40
|
this.eventEmitter.emit('update');
|
|
@@ -60,7 +61,7 @@ class gprcDriftClientAccountSubscriber extends webSocketDriftClientAccountSubscr
|
|
|
60
61
|
}
|
|
61
62
|
async subscribeToSpotMarketAccount(marketIndex) {
|
|
62
63
|
const marketPublicKey = await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex);
|
|
63
|
-
const accountSubscriber =
|
|
64
|
+
const accountSubscriber = await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'spotMarket', this.program, marketPublicKey, undefined, this.resubOpts);
|
|
64
65
|
accountSubscriber.setData(this.initialSpotMarketAccountData.get(marketIndex));
|
|
65
66
|
await accountSubscriber.subscribe((data) => {
|
|
66
67
|
this.eventEmitter.emit('spotMarketAccountUpdate', data);
|
|
@@ -71,7 +72,7 @@ class gprcDriftClientAccountSubscriber extends webSocketDriftClientAccountSubscr
|
|
|
71
72
|
}
|
|
72
73
|
async subscribeToPerpMarketAccount(marketIndex) {
|
|
73
74
|
const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex);
|
|
74
|
-
const accountSubscriber =
|
|
75
|
+
const accountSubscriber = await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'perpMarket', this.program, perpMarketPublicKey, undefined, this.resubOpts);
|
|
75
76
|
accountSubscriber.setData(this.initialPerpMarketAccountData.get(marketIndex));
|
|
76
77
|
await accountSubscriber.subscribe((data) => {
|
|
77
78
|
this.eventEmitter.emit('perpMarketAccountUpdate', data);
|
|
@@ -83,7 +84,7 @@ class gprcDriftClientAccountSubscriber extends webSocketDriftClientAccountSubscr
|
|
|
83
84
|
async subscribeToOracle(oracleInfo) {
|
|
84
85
|
const oracleId = (0, oracleId_1.getOracleId)(oracleInfo.publicKey, oracleInfo.source);
|
|
85
86
|
const client = this.oracleClientCache.get(oracleInfo.source, this.program.provider.connection, this.program);
|
|
86
|
-
const accountSubscriber =
|
|
87
|
+
const accountSubscriber = await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'oracle', this.program, oracleInfo.publicKey, (buffer) => {
|
|
87
88
|
return client.getOraclePriceDataFromBuffer(buffer);
|
|
88
89
|
}, this.resubOpts);
|
|
89
90
|
accountSubscriber.setData(this.initialOraclePriceData.get(oracleId));
|
|
@@ -12,9 +12,10 @@ class grpcInsuranceFundStakeAccountSubscriber extends webSocketInsuranceFundStak
|
|
|
12
12
|
if (this.isSubscribed) {
|
|
13
13
|
return true;
|
|
14
14
|
}
|
|
15
|
-
this.insuranceFundStakeDataAccountSubscriber =
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
this.insuranceFundStakeDataAccountSubscriber =
|
|
16
|
+
await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'insuranceFundStake', this.program, this.insuranceFundStakeAccountPublicKey, undefined, {
|
|
17
|
+
resubTimeoutMs: this.resubTimeoutMs,
|
|
18
|
+
});
|
|
18
19
|
if (insuranceFundStakeAccount) {
|
|
19
20
|
this.insuranceFundStakeDataAccountSubscriber.setData(insuranceFundStakeAccount);
|
|
20
21
|
}
|
|
@@ -4,15 +4,15 @@ import { ResubOpts, GrpcConfigs } from './types';
|
|
|
4
4
|
import { Program } from '@coral-xyz/anchor';
|
|
5
5
|
import { Context, MemcmpFilter, PublicKey } from '@solana/web3.js';
|
|
6
6
|
import { WebSocketProgramAccountSubscriber } from './webSocketProgramAccountSubscriber';
|
|
7
|
-
import { Client, ClientDuplexStream, CommitmentLevel, SubscribeRequest, SubscribeUpdate } from '../isomorphic/grpc';
|
|
8
7
|
export declare class grpcProgramAccountSubscriber<T> extends WebSocketProgramAccountSubscriber<T> {
|
|
9
|
-
client
|
|
10
|
-
stream
|
|
11
|
-
commitmentLevel
|
|
8
|
+
private client;
|
|
9
|
+
private stream;
|
|
10
|
+
private commitmentLevel;
|
|
12
11
|
listenerId?: number;
|
|
13
|
-
constructor(
|
|
12
|
+
private constructor();
|
|
13
|
+
static create<U>(grpcConfigs: GrpcConfigs, subscriptionName: string, accountDiscriminator: string, program: Program, decodeBufferFn: (accountName: string, ix: Buffer) => U, options?: {
|
|
14
14
|
filters: MemcmpFilter[];
|
|
15
|
-
}, resubOpts?: ResubOpts)
|
|
15
|
+
}, resubOpts?: ResubOpts): Promise<grpcProgramAccountSubscriber<U>>;
|
|
16
16
|
subscribe(onChange: (accountId: PublicKey, data: T, context: Context, buffer: Buffer) => void): Promise<void>;
|
|
17
17
|
unsubscribe(onResub?: boolean): Promise<void>;
|
|
18
18
|
}
|
|
@@ -33,15 +33,22 @@ const Buffer = __importStar(require("buffer"));
|
|
|
33
33
|
const webSocketProgramAccountSubscriber_1 = require("./webSocketProgramAccountSubscriber");
|
|
34
34
|
const grpc_1 = require("../isomorphic/grpc");
|
|
35
35
|
class grpcProgramAccountSubscriber extends webSocketProgramAccountSubscriber_1.WebSocketProgramAccountSubscriber {
|
|
36
|
-
constructor(
|
|
36
|
+
constructor(client, commitmentLevel, subscriptionName, accountDiscriminator, program, decodeBufferFn, options = {
|
|
37
37
|
filters: [],
|
|
38
38
|
}, resubOpts) {
|
|
39
|
-
var _a, _b;
|
|
40
39
|
super(subscriptionName, accountDiscriminator, program, decodeBufferFn, options, resubOpts);
|
|
41
|
-
this.client =
|
|
42
|
-
this.commitmentLevel =
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
this.client = client;
|
|
41
|
+
this.commitmentLevel = commitmentLevel;
|
|
42
|
+
}
|
|
43
|
+
static async create(grpcConfigs, subscriptionName, accountDiscriminator, program, decodeBufferFn, options = {
|
|
44
|
+
filters: [],
|
|
45
|
+
}, resubOpts) {
|
|
46
|
+
var _a, _b;
|
|
47
|
+
const client = await (0, grpc_1.createClient)(grpcConfigs.endpoint, grpcConfigs.token, (_a = grpcConfigs.channelOptions) !== null && _a !== void 0 ? _a : {});
|
|
48
|
+
const commitmentLevel =
|
|
49
|
+
// @ts-ignore :: isomorphic exported enum fails typescript but will work at runtime
|
|
50
|
+
(_b = grpcConfigs.commitmentLevel) !== null && _b !== void 0 ? _b : CommitmentLevel.CONFIRMED;
|
|
51
|
+
return new grpcProgramAccountSubscriber(client, commitmentLevel, subscriptionName, accountDiscriminator, program, decodeBufferFn, options, resubOpts);
|
|
45
52
|
}
|
|
46
53
|
async subscribe(onChange) {
|
|
47
54
|
if (this.listenerId != null || this.isUnsubscribing) {
|
|
@@ -12,7 +12,7 @@ class grpcUserAccountSubscriber extends webSocketUserAccountSubscriber_1.WebSock
|
|
|
12
12
|
if (this.isSubscribed) {
|
|
13
13
|
return true;
|
|
14
14
|
}
|
|
15
|
-
this.userDataAccountSubscriber =
|
|
15
|
+
this.userDataAccountSubscriber = await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'user', this.program, this.userAccountPublicKey, undefined, this.resubOpts);
|
|
16
16
|
if (userAccount) {
|
|
17
17
|
this.userDataAccountSubscriber.setData(userAccount);
|
|
18
18
|
}
|
|
@@ -12,7 +12,7 @@ class grpcUserStatsAccountSubscriber extends webSocketUserStatsAccountSubsriber_
|
|
|
12
12
|
if (this.isSubscribed) {
|
|
13
13
|
return true;
|
|
14
14
|
}
|
|
15
|
-
this.userStatsAccountSubscriber =
|
|
15
|
+
this.userStatsAccountSubscriber = await grpcAccountSubscriber_1.grpcAccountSubscriber.create(this.grpcConfigs, 'userStats', this.program, this.userStatsAccountPublicKey, undefined, this.resubOpts);
|
|
16
16
|
if (userStatsAccount) {
|
|
17
17
|
this.userStatsAccountSubscriber.setData(userStatsAccount);
|
|
18
18
|
}
|
|
@@ -14,7 +14,7 @@ class AuctionSubscriberGrpc {
|
|
|
14
14
|
}
|
|
15
15
|
async subscribe() {
|
|
16
16
|
if (!this.subscriber) {
|
|
17
|
-
this.subscriber =
|
|
17
|
+
this.subscriber = await grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber.create(this.grpcConfigs, 'AuctionSubscriber', 'User', this.driftClient.program, this.driftClient.program.account.user.coder.accounts.decode.bind(this.driftClient.program.account.user.coder.accounts), {
|
|
18
18
|
filters: [(0, memcmp_1.getUserFilter)(), (0, memcmp_1.getUserWithAuctionFilter)()],
|
|
19
19
|
}, this.resubOpts);
|
|
20
20
|
}
|
|
@@ -1089,6 +1089,17 @@ exports.MainnetPerpMarkets = [
|
|
|
1089
1089
|
oracleSource: __1.OracleSource.PYTH_PULL,
|
|
1090
1090
|
pythFeedId: '0x8fef7d52c7f4e3a6258d663f9d27e64a1b6fd95ab5f7d545dbf9a515353d0064',
|
|
1091
1091
|
},
|
|
1092
|
+
{
|
|
1093
|
+
fullName: 'BERA',
|
|
1094
|
+
category: ['L1', 'EVM'],
|
|
1095
|
+
symbol: 'BERA-PERP',
|
|
1096
|
+
baseAssetSymbol: 'BERA',
|
|
1097
|
+
marketIndex: 66,
|
|
1098
|
+
oracle: new web3_js_1.PublicKey('53Ae7ArP9yCnjqL2CqxJ1zdv3ba64NoVTqRcwjrCg181'),
|
|
1099
|
+
launchTs: 1738850177000,
|
|
1100
|
+
oracleSource: __1.OracleSource.PYTH_PULL,
|
|
1101
|
+
pythFeedId: '0x962088abcfdbdb6e30db2e340c8cf887d9efb311b1f2f17b155a63dbb6d40265',
|
|
1102
|
+
},
|
|
1092
1103
|
];
|
|
1093
1104
|
exports.PerpMarkets = {
|
|
1094
1105
|
devnet: exports.DevnetPerpMarkets,
|
|
@@ -228,7 +228,8 @@ function decodeUser(buffer) {
|
|
|
228
228
|
offset += 1;
|
|
229
229
|
const auctionDuration = buffer.readUInt8(offset);
|
|
230
230
|
offset += 1;
|
|
231
|
-
|
|
231
|
+
const postedSlotTail = buffer.readUint8(offset);
|
|
232
|
+
offset += 2; // padding
|
|
232
233
|
orders.push({
|
|
233
234
|
slot,
|
|
234
235
|
price,
|
|
@@ -254,6 +255,7 @@ function decodeUser(buffer) {
|
|
|
254
255
|
immediateOrCancel,
|
|
255
256
|
triggerCondition,
|
|
256
257
|
auctionDuration,
|
|
258
|
+
postedSlotTail,
|
|
257
259
|
});
|
|
258
260
|
}
|
|
259
261
|
const lastAddPerpLpSharesTs = readSignedBigInt64LE(buffer, offset);
|
package/lib/browser/dlob/DLOB.js
CHANGED
|
@@ -573,10 +573,8 @@ class DLOB {
|
|
|
573
573
|
const generatorList = [
|
|
574
574
|
nodeLists.restingLimit.ask.getGenerator(),
|
|
575
575
|
nodeLists.floatingLimit.ask.getGenerator(),
|
|
576
|
+
nodeLists.protectedFloatingLimit.ask.getGenerator(),
|
|
576
577
|
];
|
|
577
|
-
if (this.protectedMakerView) {
|
|
578
|
-
generatorList.push(nodeLists.protectedFloatingLimit.ask.getGenerator());
|
|
579
|
-
}
|
|
580
578
|
yield* this.getBestNode(generatorList, oraclePriceData, slot, (bestNode, currentNode, slot, oraclePriceData) => {
|
|
581
579
|
return bestNode
|
|
582
580
|
.getPrice(oraclePriceData, slot)
|
|
@@ -596,10 +594,8 @@ class DLOB {
|
|
|
596
594
|
const generatorList = [
|
|
597
595
|
nodeLists.restingLimit.bid.getGenerator(),
|
|
598
596
|
nodeLists.floatingLimit.bid.getGenerator(),
|
|
597
|
+
nodeLists.protectedFloatingLimit.bid.getGenerator(),
|
|
599
598
|
];
|
|
600
|
-
if (this.protectedMakerView) {
|
|
601
|
-
generatorList.push(nodeLists.protectedFloatingLimit.bid.getGenerator());
|
|
602
|
-
}
|
|
603
599
|
yield* this.getBestNode(generatorList, oraclePriceData, slot, (bestNode, currentNode, slot, oraclePriceData) => {
|
|
604
600
|
return bestNode
|
|
605
601
|
.getPrice(oraclePriceData, slot)
|
|
@@ -888,8 +888,8 @@ export declare class DriftClient {
|
|
|
888
888
|
disableUserHighLeverageMode(user: PublicKey, userAccount?: UserAccount, txParams?: TxParams): Promise<TransactionSignature>;
|
|
889
889
|
getDisableHighLeverageModeIx(user: PublicKey, userAccount?: UserAccount): Promise<TransactionInstruction>;
|
|
890
890
|
fetchHighLeverageModeConfig(): Promise<HighLeverageModeConfig>;
|
|
891
|
-
updateUserProtectedMakerOrders(subAccountId: number, protectedOrders: boolean, txParams?: TxParams): Promise<TransactionSignature>;
|
|
892
|
-
getUpdateUserProtectedMakerOrdersIx(subAccountId: number, protectedOrders: boolean): Promise<TransactionInstruction>;
|
|
891
|
+
updateUserProtectedMakerOrders(subAccountId: number, protectedOrders: boolean, authority?: PublicKey, txParams?: TxParams): Promise<TransactionSignature>;
|
|
892
|
+
getUpdateUserProtectedMakerOrdersIx(subAccountId: number, protectedOrders: boolean, authority?: PublicKey): Promise<TransactionInstruction>;
|
|
893
893
|
getPauseSpotMarketDepositWithdrawIx(spotMarketIndex: number): Promise<TransactionInstruction>;
|
|
894
894
|
pauseSpotMarketDepositWithdraw(spotMarketIndex: number, txParams?: TxParams): Promise<TransactionSignature>;
|
|
895
895
|
private handleSignedTransaction;
|
|
@@ -4847,15 +4847,15 @@ class DriftClient {
|
|
|
4847
4847
|
const config = await this.program.account.highLeverageModeConfig.fetch((0, pda_1.getHighLeverageModeConfigPublicKey)(this.program.programId));
|
|
4848
4848
|
return config;
|
|
4849
4849
|
}
|
|
4850
|
-
async updateUserProtectedMakerOrders(subAccountId, protectedOrders, txParams) {
|
|
4851
|
-
const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getUpdateUserProtectedMakerOrdersIx(subAccountId, protectedOrders), txParams), [], this.opts);
|
|
4850
|
+
async updateUserProtectedMakerOrders(subAccountId, protectedOrders, authority, txParams) {
|
|
4851
|
+
const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getUpdateUserProtectedMakerOrdersIx(subAccountId, protectedOrders, authority), txParams), [], this.opts);
|
|
4852
4852
|
return txSig;
|
|
4853
4853
|
}
|
|
4854
|
-
async getUpdateUserProtectedMakerOrdersIx(subAccountId, protectedOrders) {
|
|
4854
|
+
async getUpdateUserProtectedMakerOrdersIx(subAccountId, protectedOrders, authority) {
|
|
4855
4855
|
const ix = await this.program.instruction.updateUserProtectedMakerOrders(subAccountId, protectedOrders, {
|
|
4856
4856
|
accounts: {
|
|
4857
4857
|
state: await this.getStatePublicKey(),
|
|
4858
|
-
user: (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, this.
|
|
4858
|
+
user: (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, authority !== null && authority !== void 0 ? authority : this.authority, subAccountId),
|
|
4859
4859
|
authority: this.wallet.publicKey,
|
|
4860
4860
|
protectedMakerModeConfig: (0, pda_1.getProtectedMakerModeConfigPublicKey)(this.program.programId),
|
|
4861
4861
|
},
|
|
@@ -57,6 +57,9 @@ function getOracleClient(oracleSource, connection, program) {
|
|
|
57
57
|
if ((0, types_1.isVariant)(oracleSource, 'pythLazer1M')) {
|
|
58
58
|
return new pythLazerClient_1.PythLazerClient(connection, new anchor_1.BN(1000000));
|
|
59
59
|
}
|
|
60
|
+
if ((0, types_1.isVariant)(oracleSource, 'pythLazerStableCoin')) {
|
|
61
|
+
return new pythLazerClient_1.PythLazerClient(connection, undefined, true);
|
|
62
|
+
}
|
|
60
63
|
throw new Error(`Unknown oracle source ${oracleSource}`);
|
|
61
64
|
}
|
|
62
65
|
exports.getOracleClient = getOracleClient;
|
|
@@ -10875,12 +10875,19 @@
|
|
|
10875
10875
|
],
|
|
10876
10876
|
"type": "u8"
|
|
10877
10877
|
},
|
|
10878
|
+
{
|
|
10879
|
+
"name": "postedSlotTail",
|
|
10880
|
+
"docs": [
|
|
10881
|
+
"Last 8 bits of the slot the order was posted on-chain (not order slot for swift orders)"
|
|
10882
|
+
],
|
|
10883
|
+
"type": "u8"
|
|
10884
|
+
},
|
|
10878
10885
|
{
|
|
10879
10886
|
"name": "padding",
|
|
10880
10887
|
"type": {
|
|
10881
10888
|
"array": [
|
|
10882
10889
|
"u8",
|
|
10883
|
-
|
|
10890
|
+
2
|
|
10884
10891
|
]
|
|
10885
10892
|
}
|
|
10886
10893
|
}
|
|
@@ -11463,6 +11470,9 @@
|
|
|
11463
11470
|
},
|
|
11464
11471
|
{
|
|
11465
11472
|
"name": "PythLazer1M"
|
|
11473
|
+
},
|
|
11474
|
+
{
|
|
11475
|
+
"name": "PythLazerStableCoin"
|
|
11466
11476
|
}
|
|
11467
11477
|
]
|
|
11468
11478
|
}
|
|
@@ -33,6 +33,8 @@ function getOracleSourceNum(source) {
|
|
|
33
33
|
return types_1.OracleSourceNum.PYTH_LAZER_1K;
|
|
34
34
|
if ('pythLazer1M' in source)
|
|
35
35
|
return types_1.OracleSourceNum.PYTH_LAZER_1M;
|
|
36
|
+
if ('pythLazerStableCoin' in source)
|
|
37
|
+
return types_1.OracleSourceNum.PYTH_LAZER_STABLE_COIN;
|
|
36
38
|
throw new Error('Invalid oracle source');
|
|
37
39
|
}
|
|
38
40
|
exports.getOracleSourceNum = getOracleSourceNum;
|
|
@@ -16,7 +16,7 @@ class grpcSubscription {
|
|
|
16
16
|
if (this.subscriber) {
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
|
-
this.subscriber =
|
|
19
|
+
this.subscriber = await grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber.create(this.grpcConfigs, 'OrderSubscriber', 'User', this.orderSubscriber.driftClient.program, this.orderSubscriber.decodeFn, {
|
|
20
20
|
filters: [(0, memcmp_1.getUserFilter)(), (0, memcmp_1.getNonIdleUserFilter)()],
|
|
21
21
|
}, this.resubOpts);
|
|
22
22
|
await this.subscriber.subscribe((accountId, account, context, buffer) => {
|
|
@@ -60,7 +60,7 @@ class BaseTxSender {
|
|
|
60
60
|
return this.txHandler.prepareTx(tx, additionalSigners, undefined, opts, preSigned);
|
|
61
61
|
}
|
|
62
62
|
async getVersionedTransaction(ixs, lookupTableAccounts, _additionalSigners, opts, blockhash) {
|
|
63
|
-
return this.txHandler.generateVersionedTransaction(blockhash, ixs, lookupTableAccounts, this.wallet);
|
|
63
|
+
return this.txHandler.generateVersionedTransaction(blockhash !== null && blockhash !== void 0 ? blockhash : (await this.connection.getLatestBlockhash()), ixs, lookupTableAccounts, this.wallet);
|
|
64
64
|
}
|
|
65
65
|
async sendVersionedTransaction(tx, additionalSigners, opts, preSigned) {
|
|
66
66
|
let signedTx;
|
package/lib/browser/types.d.ts
CHANGED
|
@@ -207,6 +207,9 @@ export declare class OracleSource {
|
|
|
207
207
|
static readonly PYTH_LAZER_1M: {
|
|
208
208
|
pythLazer1M: {};
|
|
209
209
|
};
|
|
210
|
+
static readonly PYTH_LAZER_STABLE_COIN: {
|
|
211
|
+
pythLazerStableCoin: {};
|
|
212
|
+
};
|
|
210
213
|
}
|
|
211
214
|
export declare class OracleSourceNum {
|
|
212
215
|
static readonly PYTH = 0;
|
|
@@ -222,8 +225,9 @@ export declare class OracleSourceNum {
|
|
|
222
225
|
static readonly PRELAUNCH = 10;
|
|
223
226
|
static readonly SWITCHBOARD_ON_DEMAND = 11;
|
|
224
227
|
static readonly PYTH_LAZER = 12;
|
|
225
|
-
static readonly PYTH_LAZER_1K =
|
|
226
|
-
static readonly PYTH_LAZER_1M =
|
|
228
|
+
static readonly PYTH_LAZER_1K = 13;
|
|
229
|
+
static readonly PYTH_LAZER_1M = 14;
|
|
230
|
+
static readonly PYTH_LAZER_STABLE_COIN = 15;
|
|
227
231
|
}
|
|
228
232
|
export declare class OrderType {
|
|
229
233
|
static readonly LIMIT: {
|
|
@@ -1096,6 +1100,7 @@ export type Order = {
|
|
|
1096
1100
|
auctionStartPrice: BN;
|
|
1097
1101
|
auctionEndPrice: BN;
|
|
1098
1102
|
maxTs: BN;
|
|
1103
|
+
postedSlotTail: number;
|
|
1099
1104
|
};
|
|
1100
1105
|
export type OrderParams = {
|
|
1101
1106
|
orderType: OrderType;
|
package/lib/browser/types.js
CHANGED
|
@@ -126,6 +126,7 @@ OracleSource.SWITCHBOARD_ON_DEMAND = { switchboardOnDemand: {} };
|
|
|
126
126
|
OracleSource.PYTH_LAZER = { pythLazer: {} };
|
|
127
127
|
OracleSource.PYTH_LAZER_1K = { pythLazer1K: {} };
|
|
128
128
|
OracleSource.PYTH_LAZER_1M = { pythLazer1M: {} };
|
|
129
|
+
OracleSource.PYTH_LAZER_STABLE_COIN = { pythLazerStableCoin: {} };
|
|
129
130
|
class OracleSourceNum {
|
|
130
131
|
}
|
|
131
132
|
exports.OracleSourceNum = OracleSourceNum;
|
|
@@ -142,8 +143,9 @@ OracleSourceNum.PYTH_STABLE_COIN_PULL = 9;
|
|
|
142
143
|
OracleSourceNum.PRELAUNCH = 10;
|
|
143
144
|
OracleSourceNum.SWITCHBOARD_ON_DEMAND = 11;
|
|
144
145
|
OracleSourceNum.PYTH_LAZER = 12;
|
|
145
|
-
OracleSourceNum.PYTH_LAZER_1K =
|
|
146
|
-
OracleSourceNum.PYTH_LAZER_1M =
|
|
146
|
+
OracleSourceNum.PYTH_LAZER_1K = 13;
|
|
147
|
+
OracleSourceNum.PYTH_LAZER_1M = 14;
|
|
148
|
+
OracleSourceNum.PYTH_LAZER_STABLE_COIN = 15;
|
|
147
149
|
class OrderType {
|
|
148
150
|
}
|
|
149
151
|
exports.OrderType = OrderType;
|
|
@@ -22,7 +22,7 @@ class grpcSubscription {
|
|
|
22
22
|
if (this.additionalFilters) {
|
|
23
23
|
filters.push(...this.additionalFilters);
|
|
24
24
|
}
|
|
25
|
-
this.subscriber =
|
|
25
|
+
this.subscriber = await grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber.create(this.grpcConfigs, 'UserMap', 'User', this.userMap.driftClient.program, this.decodeFn, {
|
|
26
26
|
filters,
|
|
27
27
|
}, this.resubOpts);
|
|
28
28
|
}
|
|
@@ -81,7 +81,17 @@ export declare class UserMap implements UserMapInterface {
|
|
|
81
81
|
*/
|
|
82
82
|
getUniqueAuthorities(filterCriteria?: UserFilterCriteria): PublicKey[];
|
|
83
83
|
sync(): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Syncs the UserMap using the default sync method (single getProgramAccounts call with filters).
|
|
86
|
+
* This method may fail when drift has too many users. (nodejs response size limits)
|
|
87
|
+
* @returns
|
|
88
|
+
*/
|
|
84
89
|
private defaultSync;
|
|
90
|
+
/**
|
|
91
|
+
* Syncs the UserMap using the paginated sync method (multiple getMultipleAccounts calls with filters).
|
|
92
|
+
* This method is more reliable when drift has many users.
|
|
93
|
+
* @returns
|
|
94
|
+
*/
|
|
85
95
|
private paginatedSync;
|
|
86
96
|
unsubscribe(): Promise<void>;
|
|
87
97
|
updateUserAccount(key: string, userAccount: UserAccount, slot: number): Promise<void>;
|
|
@@ -259,6 +259,11 @@ class UserMap {
|
|
|
259
259
|
return this.paginatedSync();
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
|
+
/**
|
|
263
|
+
* Syncs the UserMap using the default sync method (single getProgramAccounts call with filters).
|
|
264
|
+
* This method may fail when drift has too many users. (nodejs response size limits)
|
|
265
|
+
* @returns
|
|
266
|
+
*/
|
|
262
267
|
async defaultSync() {
|
|
263
268
|
var _a;
|
|
264
269
|
if (this.syncPromise) {
|
|
@@ -334,6 +339,11 @@ class UserMap {
|
|
|
334
339
|
this.syncPromise = undefined;
|
|
335
340
|
}
|
|
336
341
|
}
|
|
342
|
+
/**
|
|
343
|
+
* Syncs the UserMap using the paginated sync method (multiple getMultipleAccounts calls with filters).
|
|
344
|
+
* This method is more reliable when drift has many users.
|
|
345
|
+
* @returns
|
|
346
|
+
*/
|
|
337
347
|
async paginatedSync() {
|
|
338
348
|
var _a, _b;
|
|
339
349
|
if (this.syncPromise) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DriftClient, OrderRecord, UserStatsAccount, UserStats, WrappedEvent, BulkAccountLoader } from '..';
|
|
1
|
+
import { DriftClient, OrderRecord, UserStatsAccount, UserStats, WrappedEvent, BulkAccountLoader, SyncConfig } from '..';
|
|
2
2
|
import { PublicKey } from '@solana/web3.js';
|
|
3
3
|
import { UserMap } from './userMap';
|
|
4
4
|
export declare class UserStatsMap {
|
|
@@ -8,13 +8,17 @@ export declare class UserStatsMap {
|
|
|
8
8
|
private userStatsMap;
|
|
9
9
|
private driftClient;
|
|
10
10
|
private bulkAccountLoader;
|
|
11
|
+
private decode;
|
|
12
|
+
private syncConfig;
|
|
13
|
+
private syncPromise?;
|
|
14
|
+
private syncPromiseResolver;
|
|
11
15
|
/**
|
|
12
16
|
* Creates a new UserStatsMap instance.
|
|
13
17
|
*
|
|
14
18
|
* @param {DriftClient} driftClient - The DriftClient instance.
|
|
15
19
|
* @param {BulkAccountLoader} [bulkAccountLoader] - If not provided, a new BulkAccountLoader with polling disabled will be created.
|
|
16
20
|
*/
|
|
17
|
-
constructor(driftClient: DriftClient, bulkAccountLoader?: BulkAccountLoader);
|
|
21
|
+
constructor(driftClient: DriftClient, bulkAccountLoader?: BulkAccountLoader, syncConfig?: SyncConfig);
|
|
18
22
|
subscribe(authorities: PublicKey[]): Promise<void>;
|
|
19
23
|
/**
|
|
20
24
|
*
|
|
@@ -42,5 +46,16 @@ export declare class UserStatsMap {
|
|
|
42
46
|
* You may want to get this list from UserMap in order to filter out idle users
|
|
43
47
|
*/
|
|
44
48
|
sync(authorities: PublicKey[]): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Sync the UserStatsMap using the default sync method, which loads individual users into the bulkAccountLoader and
|
|
51
|
+
* loads them. (bulkAccountLoader uses batch getMultipleAccounts)
|
|
52
|
+
* @param authorities
|
|
53
|
+
*/
|
|
54
|
+
private defaultSync;
|
|
55
|
+
/**
|
|
56
|
+
* Sync the UserStatsMap using the paginated sync method, which uses multiple getMultipleAccounts calls (without RPC batching), and limits concurrency.
|
|
57
|
+
* @param authorities
|
|
58
|
+
*/
|
|
59
|
+
private paginatedSync;
|
|
45
60
|
unsubscribe(): Promise<void>;
|
|
46
61
|
}
|
|
@@ -10,7 +10,7 @@ class UserStatsMap {
|
|
|
10
10
|
* @param {DriftClient} driftClient - The DriftClient instance.
|
|
11
11
|
* @param {BulkAccountLoader} [bulkAccountLoader] - If not provided, a new BulkAccountLoader with polling disabled will be created.
|
|
12
12
|
*/
|
|
13
|
-
constructor(driftClient, bulkAccountLoader) {
|
|
13
|
+
constructor(driftClient, bulkAccountLoader, syncConfig) {
|
|
14
14
|
/**
|
|
15
15
|
* map from authority pubkey to UserStats
|
|
16
16
|
*/
|
|
@@ -20,6 +20,11 @@ class UserStatsMap {
|
|
|
20
20
|
bulkAccountLoader = new __1.BulkAccountLoader(driftClient.connection, driftClient.opts.commitment, 0);
|
|
21
21
|
}
|
|
22
22
|
this.bulkAccountLoader = bulkAccountLoader;
|
|
23
|
+
this.syncConfig = syncConfig !== null && syncConfig !== void 0 ? syncConfig : {
|
|
24
|
+
type: 'default',
|
|
25
|
+
};
|
|
26
|
+
this.decode =
|
|
27
|
+
this.driftClient.program.account.userStats.coder.accounts.decodeUnchecked.bind(this.driftClient.program.account.userStats.coder.accounts);
|
|
23
28
|
}
|
|
24
29
|
async subscribe(authorities) {
|
|
25
30
|
if (this.size() > 0) {
|
|
@@ -152,9 +157,111 @@ class UserStatsMap {
|
|
|
152
157
|
* You may want to get this list from UserMap in order to filter out idle users
|
|
153
158
|
*/
|
|
154
159
|
async sync(authorities) {
|
|
160
|
+
if (this.syncConfig.type === 'default') {
|
|
161
|
+
return this.defaultSync(authorities);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
return this.paginatedSync(authorities);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Sync the UserStatsMap using the default sync method, which loads individual users into the bulkAccountLoader and
|
|
169
|
+
* loads them. (bulkAccountLoader uses batch getMultipleAccounts)
|
|
170
|
+
* @param authorities
|
|
171
|
+
*/
|
|
172
|
+
async defaultSync(authorities) {
|
|
155
173
|
await Promise.all(authorities.map((authority) => this.addUserStat(authority, undefined, true)));
|
|
156
174
|
await this.bulkAccountLoader.load();
|
|
157
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Sync the UserStatsMap using the paginated sync method, which uses multiple getMultipleAccounts calls (without RPC batching), and limits concurrency.
|
|
178
|
+
* @param authorities
|
|
179
|
+
*/
|
|
180
|
+
async paginatedSync(authorities) {
|
|
181
|
+
var _a, _b;
|
|
182
|
+
if (this.syncPromise) {
|
|
183
|
+
return this.syncPromise;
|
|
184
|
+
}
|
|
185
|
+
this.syncPromise = new Promise((resolve) => {
|
|
186
|
+
this.syncPromiseResolver = resolve;
|
|
187
|
+
});
|
|
188
|
+
try {
|
|
189
|
+
let accountsToLoad = authorities;
|
|
190
|
+
if (authorities.length === 0) {
|
|
191
|
+
const accountsPrefetch = await this.driftClient.connection.getProgramAccounts(this.driftClient.program.programId, {
|
|
192
|
+
dataSlice: { offset: 0, length: 0 },
|
|
193
|
+
filters: [(0, __1.getUserStatsFilter)()],
|
|
194
|
+
});
|
|
195
|
+
accountsToLoad = accountsPrefetch.map((account) => account.pubkey);
|
|
196
|
+
}
|
|
197
|
+
const limitConcurrency = async (tasks, limit) => {
|
|
198
|
+
const executing = [];
|
|
199
|
+
const results = [];
|
|
200
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
201
|
+
const executor = Promise.resolve().then(tasks[i]);
|
|
202
|
+
results.push(executor);
|
|
203
|
+
if (executing.length < limit) {
|
|
204
|
+
executing.push(executor);
|
|
205
|
+
executor.finally(() => {
|
|
206
|
+
const index = executing.indexOf(executor);
|
|
207
|
+
if (index > -1) {
|
|
208
|
+
executing.splice(index, 1);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
await Promise.race(executing);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return Promise.all(results);
|
|
217
|
+
};
|
|
218
|
+
const programAccountBufferMap = new Set();
|
|
219
|
+
// @ts-ignore
|
|
220
|
+
const chunkSize = (_a = this.syncConfig.chunkSize) !== null && _a !== void 0 ? _a : 100;
|
|
221
|
+
const tasks = [];
|
|
222
|
+
for (let i = 0; i < accountsToLoad.length; i += chunkSize) {
|
|
223
|
+
const chunk = accountsToLoad.slice(i, i + chunkSize);
|
|
224
|
+
tasks.push(async () => {
|
|
225
|
+
const accountInfos = await this.driftClient.connection.getMultipleAccountsInfoAndContext(chunk, {
|
|
226
|
+
commitment: this.driftClient.opts.commitment,
|
|
227
|
+
});
|
|
228
|
+
for (let j = 0; j < accountInfos.value.length; j += 1) {
|
|
229
|
+
const accountInfo = accountInfos.value[j];
|
|
230
|
+
if (accountInfo === null)
|
|
231
|
+
continue;
|
|
232
|
+
const publicKeyString = chunk[j].toString();
|
|
233
|
+
if (!this.has(publicKeyString)) {
|
|
234
|
+
const buffer = Buffer.from(accountInfo.data);
|
|
235
|
+
const decodedUserStats = this.decode('UserStats', buffer);
|
|
236
|
+
programAccountBufferMap.add(decodedUserStats.authority.toBase58());
|
|
237
|
+
this.addUserStat(decodedUserStats.authority, decodedUserStats, false);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
// @ts-ignore
|
|
243
|
+
const concurrencyLimit = (_b = this.syncConfig.concurrencyLimit) !== null && _b !== void 0 ? _b : 10;
|
|
244
|
+
await limitConcurrency(tasks, concurrencyLimit);
|
|
245
|
+
for (const [key] of this.userStatsMap.entries()) {
|
|
246
|
+
if (!programAccountBufferMap.has(key)) {
|
|
247
|
+
const user = this.get(key);
|
|
248
|
+
if (user) {
|
|
249
|
+
await user.unsubscribe();
|
|
250
|
+
this.userStatsMap.delete(key);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
catch (err) {
|
|
256
|
+
console.error(`Error in UserStatsMap.paginatedSync():`, err);
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
if (this.syncPromiseResolver) {
|
|
260
|
+
this.syncPromiseResolver();
|
|
261
|
+
}
|
|
262
|
+
this.syncPromise = undefined;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
158
265
|
async unsubscribe() {
|
|
159
266
|
for (const [key, userStats] of this.userStatsMap.entries()) {
|
|
160
267
|
await userStats.unsubscribe();
|