@drift-labs/sdk 2.112.0-beta.3 → 2.112.0-beta.5
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/driftClient.d.ts +2 -1
- package/lib/browser/driftClient.js +4 -0
- package/lib/browser/fastlane/grpcSignedMsgUserAccountSubscriber.d.ts +22 -0
- package/lib/browser/fastlane/grpcSignedMsgUserAccountSubscriber.js +57 -0
- package/lib/browser/fastlane/index.d.ts +3 -0
- package/lib/browser/fastlane/index.js +19 -0
- package/lib/browser/fastlane/signedMsgUserAccountSubscriber.d.ts +43 -0
- package/lib/browser/fastlane/signedMsgUserAccountSubscriber.js +116 -0
- package/lib/browser/index.d.ts +1 -0
- package/lib/browser/index.js +1 -0
- package/lib/browser/memcmp.d.ts +1 -0
- package/lib/browser/memcmp.js +10 -1
- package/lib/browser/types.d.ts +14 -0
- package/lib/node/driftClient.d.ts +2 -1
- package/lib/node/driftClient.js +4 -0
- package/lib/node/fastlane/grpcSignedMsgUserAccountSubscriber.d.ts +22 -0
- package/lib/node/fastlane/grpcSignedMsgUserAccountSubscriber.js +57 -0
- package/lib/node/fastlane/index.d.ts +3 -0
- package/lib/node/fastlane/index.js +19 -0
- package/lib/node/fastlane/signedMsgUserAccountSubscriber.d.ts +43 -0
- package/lib/node/fastlane/signedMsgUserAccountSubscriber.js +116 -0
- package/lib/node/index.d.ts +1 -0
- package/lib/node/index.js +1 -0
- package/lib/node/memcmp.d.ts +1 -0
- package/lib/node/memcmp.js +10 -1
- package/lib/node/types.d.ts +14 -0
- package/package.json +1 -1
- package/src/driftClient.ts +8 -0
- package/src/fastlane/grpcSignedMsgUserAccountSubscriber.ts +95 -0
- package/src/fastlane/index.ts +3 -0
- package/src/fastlane/signedMsgUserAccountSubscriber.ts +234 -0
- package/src/index.ts +1 -0
- package/src/memcmp.ts +11 -0
- package/src/types.ts +17 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.112.0-beta.
|
|
1
|
+
2.112.0-beta.5
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import * as anchor from '@coral-xyz/anchor';
|
|
6
6
|
import { AnchorProvider, BN, Program, ProgramAccount } from '@coral-xyz/anchor';
|
|
7
7
|
import { Idl as Idl30, Program as Program30 } from '@coral-xyz/anchor-30';
|
|
8
|
-
import { DriftClientMetricsEvents, HighLeverageModeConfig, IWallet, MakerInfo, MappedRecord, MarketType, ModifyOrderPolicy, OpenbookV2FulfillmentConfigAccount, OptionalOrderParams, OracleSource, Order, OrderParams, OrderTriggerCondition, PerpMarketAccount, PerpMarketExtendedInfo, PhoenixV1FulfillmentConfigAccount, PlaceAndTakeOrderSuccessCondition, PositionDirection, ReferrerInfo, ReferrerNameAccount, SerumV3FulfillmentConfigAccount, SettlePnlMode, SignedTxData, SpotMarketAccount, SpotPosition, StateAccount, SwapReduceOnly, SignedMsgOrderParamsMessage, TakerInfo, TxParams, UserAccount, UserStatsAccount } from './types';
|
|
8
|
+
import { DriftClientMetricsEvents, HighLeverageModeConfig, IWallet, MakerInfo, MappedRecord, MarketType, ModifyOrderPolicy, OpenbookV2FulfillmentConfigAccount, OptionalOrderParams, OracleSource, Order, OrderParams, OrderTriggerCondition, PerpMarketAccount, PerpMarketExtendedInfo, PhoenixV1FulfillmentConfigAccount, PlaceAndTakeOrderSuccessCondition, PositionDirection, ReferrerInfo, ReferrerNameAccount, SerumV3FulfillmentConfigAccount, SettlePnlMode, SignedTxData, SpotMarketAccount, SpotPosition, StateAccount, SwapReduceOnly, SignedMsgOrderParamsMessage, TakerInfo, TxParams, UserAccount, UserStatsAccount, ProtectedMakerModeConfig } from './types';
|
|
9
9
|
import { AccountMeta, AddressLookupTableAccount, BlockhashWithExpiryBlockHeight, ConfirmOptions, Connection, Keypair, PublicKey, Signer, Transaction, TransactionInstruction, TransactionSignature, TransactionVersion, VersionedTransaction } from '@solana/web3.js';
|
|
10
10
|
import { TokenFaucet } from './tokenFaucet';
|
|
11
11
|
import { EventEmitter } from 'events';
|
|
@@ -915,6 +915,7 @@ export declare class DriftClient {
|
|
|
915
915
|
disableUserHighLeverageMode(user: PublicKey, userAccount?: UserAccount, txParams?: TxParams): Promise<TransactionSignature>;
|
|
916
916
|
getDisableHighLeverageModeIx(user: PublicKey, userAccount?: UserAccount): Promise<TransactionInstruction>;
|
|
917
917
|
fetchHighLeverageModeConfig(): Promise<HighLeverageModeConfig>;
|
|
918
|
+
fetchProtectedMakerModeConfig(): Promise<ProtectedMakerModeConfig>;
|
|
918
919
|
updateUserProtectedMakerOrders(subAccountId: number, protectedOrders: boolean, authority?: PublicKey, txParams?: TxParams): Promise<TransactionSignature>;
|
|
919
920
|
getUpdateUserProtectedMakerOrdersIx(subAccountId: number, protectedOrders: boolean, authority?: PublicKey): Promise<TransactionInstruction>;
|
|
920
921
|
getPauseSpotMarketDepositWithdrawIx(spotMarketIndex: number): Promise<TransactionInstruction>;
|
|
@@ -4898,6 +4898,10 @@ class DriftClient {
|
|
|
4898
4898
|
const config = await this.program.account.highLeverageModeConfig.fetch((0, pda_1.getHighLeverageModeConfigPublicKey)(this.program.programId));
|
|
4899
4899
|
return config;
|
|
4900
4900
|
}
|
|
4901
|
+
async fetchProtectedMakerModeConfig() {
|
|
4902
|
+
const config = await this.program.account.protectedMakerModeConfig.fetch((0, pda_1.getProtectedMakerModeConfigPublicKey)(this.program.programId));
|
|
4903
|
+
return config;
|
|
4904
|
+
}
|
|
4901
4905
|
async updateUserProtectedMakerOrders(subAccountId, protectedOrders, authority, txParams) {
|
|
4902
4906
|
const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getUpdateUserProtectedMakerOrdersIx(subAccountId, protectedOrders, authority), txParams), [], this.opts);
|
|
4903
4907
|
return txSig;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { Commitment } from '@solana/web3.js';
|
|
4
|
+
import { grpcProgramAccountSubscriber } from '../accounts/grpcProgramAccountSubscriber';
|
|
5
|
+
import { GrpcConfigs, ResubOpts } from '../accounts/types';
|
|
6
|
+
import { SignedMsgUserOrdersAccount } from '../types';
|
|
7
|
+
import { SignedMsgUserOrdersAccountSubscriber } from './signedMsgUserAccountSubscriber';
|
|
8
|
+
import { DriftClient } from '../driftClient';
|
|
9
|
+
export declare class grpcSignedMsgUserOrdersAccountSubscriber extends SignedMsgUserOrdersAccountSubscriber {
|
|
10
|
+
private grpcConfigs;
|
|
11
|
+
subscriber: grpcProgramAccountSubscriber<SignedMsgUserOrdersAccount>;
|
|
12
|
+
constructor({ grpcConfigs, driftClient, commitment, resubOpts, decodeFn, resyncIntervalMs, }: {
|
|
13
|
+
grpcConfigs: GrpcConfigs;
|
|
14
|
+
driftClient: DriftClient;
|
|
15
|
+
commitment: Commitment;
|
|
16
|
+
resubOpts?: ResubOpts;
|
|
17
|
+
decodeFn: (name: string, data: Buffer) => SignedMsgUserOrdersAccount;
|
|
18
|
+
resyncIntervalMs?: number;
|
|
19
|
+
});
|
|
20
|
+
subscribe(): Promise<void>;
|
|
21
|
+
unsubscribe(): Promise<void>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.grpcSignedMsgUserOrdersAccountSubscriber = void 0;
|
|
4
|
+
const grpcProgramAccountSubscriber_1 = require("../accounts/grpcProgramAccountSubscriber");
|
|
5
|
+
const memcmp_1 = require("../memcmp");
|
|
6
|
+
const signedMsgUserAccountSubscriber_1 = require("./signedMsgUserAccountSubscriber");
|
|
7
|
+
class grpcSignedMsgUserOrdersAccountSubscriber extends signedMsgUserAccountSubscriber_1.SignedMsgUserOrdersAccountSubscriber {
|
|
8
|
+
constructor({ grpcConfigs, driftClient, commitment, resubOpts, decodeFn, resyncIntervalMs, }) {
|
|
9
|
+
super({
|
|
10
|
+
driftClient,
|
|
11
|
+
commitment,
|
|
12
|
+
resubOpts,
|
|
13
|
+
decodeFn,
|
|
14
|
+
resyncIntervalMs,
|
|
15
|
+
});
|
|
16
|
+
this.grpcConfigs = grpcConfigs;
|
|
17
|
+
}
|
|
18
|
+
async subscribe() {
|
|
19
|
+
if (!this.subscriber) {
|
|
20
|
+
this.subscriber =
|
|
21
|
+
await grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber.create(this.grpcConfigs, 'OrderSubscriber', 'User', this.driftClient.program, this.decodeFn, {
|
|
22
|
+
filters: [(0, memcmp_1.getSignedMsgUserOrdersFilter)()],
|
|
23
|
+
}, this.resubOpts);
|
|
24
|
+
}
|
|
25
|
+
await this.subscriber.subscribe((_accountId, account, context) => {
|
|
26
|
+
this.tryUpdateSignedMsgUserOrdersAccount(account, 'decoded', context.slot);
|
|
27
|
+
});
|
|
28
|
+
if (this.resyncIntervalMs) {
|
|
29
|
+
const recursiveResync = () => {
|
|
30
|
+
this.resyncTimeoutId = setTimeout(() => {
|
|
31
|
+
this.fetch()
|
|
32
|
+
.catch((e) => {
|
|
33
|
+
console.error('Failed to resync in OrderSubscriber');
|
|
34
|
+
console.log(e);
|
|
35
|
+
})
|
|
36
|
+
.finally(() => {
|
|
37
|
+
if (!this.resyncTimeoutId)
|
|
38
|
+
return;
|
|
39
|
+
recursiveResync();
|
|
40
|
+
});
|
|
41
|
+
}, this.resyncIntervalMs);
|
|
42
|
+
};
|
|
43
|
+
recursiveResync();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async unsubscribe() {
|
|
47
|
+
if (!this.subscriber)
|
|
48
|
+
return;
|
|
49
|
+
await this.subscriber.unsubscribe();
|
|
50
|
+
this.subscriber = undefined;
|
|
51
|
+
if (this.resyncTimeoutId !== undefined) {
|
|
52
|
+
clearTimeout(this.resyncTimeoutId);
|
|
53
|
+
this.resyncTimeoutId = undefined;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.grpcSignedMsgUserOrdersAccountSubscriber = grpcSignedMsgUserOrdersAccountSubscriber;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./fastlaneOrderSubscriber"), exports);
|
|
18
|
+
__exportStar(require("./signedMsgUserAccountSubscriber"), exports);
|
|
19
|
+
__exportStar(require("./grpcSignedMsgUserAccountSubscriber"), exports);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
/// <reference types="node" />
|
|
5
|
+
import { WebSocketProgramAccountSubscriber } from '../accounts/webSocketProgramAccountSubscriber';
|
|
6
|
+
import { SignedMsgOrderId, SignedMsgUserOrdersAccount } from '../types';
|
|
7
|
+
import { Commitment, PublicKey } from '@solana/web3.js';
|
|
8
|
+
import { ResubOpts } from '../accounts/types';
|
|
9
|
+
import { DriftClient } from '../driftClient';
|
|
10
|
+
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
11
|
+
import { EventEmitter } from 'events';
|
|
12
|
+
export interface SignedMsgUserOrdersAccountSubscriberEvents {
|
|
13
|
+
onAccountUpdate: (activeSignedMsgOrderIds: SignedMsgOrderId[], authorityPubkey: PublicKey, slot: number) => void;
|
|
14
|
+
newSignedMsgOrderIds: (newSignedMsgOrderIds: SignedMsgOrderId[], authorityPubkey: PublicKey, slot: number) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare class SignedMsgUserOrdersAccountSubscriber {
|
|
17
|
+
protected driftClient: DriftClient;
|
|
18
|
+
protected commitment: Commitment;
|
|
19
|
+
protected resubOpts?: ResubOpts;
|
|
20
|
+
protected resyncTimeoutId?: NodeJS.Timeout;
|
|
21
|
+
protected resyncIntervalMs?: number;
|
|
22
|
+
protected decodeFn: (name: string, data: Buffer) => SignedMsgUserOrdersAccount;
|
|
23
|
+
protected signedMsgUserOrderAccounts: Map<string, {
|
|
24
|
+
slot: number;
|
|
25
|
+
signedMsgUserOrdersAccount: SignedMsgUserOrdersAccount;
|
|
26
|
+
}>;
|
|
27
|
+
mostRecentSlot: number;
|
|
28
|
+
fetchPromise?: Promise<void>;
|
|
29
|
+
fetchPromiseResolver: () => void;
|
|
30
|
+
protected subscriber: WebSocketProgramAccountSubscriber<SignedMsgUserOrdersAccount>;
|
|
31
|
+
eventEmitter: StrictEventEmitter<EventEmitter, SignedMsgUserOrdersAccountSubscriberEvents>;
|
|
32
|
+
constructor({ driftClient, commitment, resubOpts, decodeFn, resyncIntervalMs, }: {
|
|
33
|
+
driftClient: DriftClient;
|
|
34
|
+
commitment: Commitment;
|
|
35
|
+
resubOpts?: ResubOpts;
|
|
36
|
+
decodeFn: (name: string, data: Buffer) => SignedMsgUserOrdersAccount;
|
|
37
|
+
resyncIntervalMs?: number;
|
|
38
|
+
});
|
|
39
|
+
subscribe(): Promise<void>;
|
|
40
|
+
fetch(): Promise<void>;
|
|
41
|
+
tryUpdateSignedMsgUserOrdersAccount(data: Buffer | SignedMsgUserOrdersAccount, dataType: 'buffer' | 'decoded', slot: number, skipEventEmitting?: boolean): void;
|
|
42
|
+
unsubscribe(): Promise<void>;
|
|
43
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SignedMsgUserOrdersAccountSubscriber = void 0;
|
|
4
|
+
const memcmp_1 = require("../memcmp");
|
|
5
|
+
const webSocketProgramAccountSubscriber_1 = require("../accounts/webSocketProgramAccountSubscriber");
|
|
6
|
+
const events_1 = require("events");
|
|
7
|
+
class SignedMsgUserOrdersAccountSubscriber {
|
|
8
|
+
constructor({ driftClient, commitment, resubOpts, decodeFn, resyncIntervalMs, }) {
|
|
9
|
+
this.signedMsgUserOrderAccounts = new Map();
|
|
10
|
+
this.commitment = commitment;
|
|
11
|
+
this.resubOpts = resubOpts;
|
|
12
|
+
this.decodeFn = decodeFn;
|
|
13
|
+
this.driftClient = driftClient;
|
|
14
|
+
this.resyncIntervalMs = resyncIntervalMs;
|
|
15
|
+
this.eventEmitter = new events_1.EventEmitter();
|
|
16
|
+
this.resubOpts = resubOpts;
|
|
17
|
+
}
|
|
18
|
+
async subscribe() {
|
|
19
|
+
if (!this.subscriber) {
|
|
20
|
+
const filters = [(0, memcmp_1.getSignedMsgUserOrdersFilter)()];
|
|
21
|
+
this.subscriber =
|
|
22
|
+
new webSocketProgramAccountSubscriber_1.WebSocketProgramAccountSubscriber('SingedMsgUserOrdersAccountMap', 'SignedMsgUserOrders', this.driftClient.program, this.decodeFn, {
|
|
23
|
+
filters,
|
|
24
|
+
commitment: this.commitment,
|
|
25
|
+
}, this.resubOpts);
|
|
26
|
+
}
|
|
27
|
+
await this.subscriber.subscribe((_accountId, account, context) => {
|
|
28
|
+
this.tryUpdateSignedMsgUserOrdersAccount(account, 'decoded', context.slot);
|
|
29
|
+
});
|
|
30
|
+
await this.fetch();
|
|
31
|
+
if (this.resyncIntervalMs) {
|
|
32
|
+
const recursiveResync = () => {
|
|
33
|
+
this.resyncTimeoutId = setTimeout(() => {
|
|
34
|
+
this.fetch()
|
|
35
|
+
.catch((e) => {
|
|
36
|
+
console.error('Failed to resync in OrderSubscriber');
|
|
37
|
+
console.log(e);
|
|
38
|
+
})
|
|
39
|
+
.finally(() => {
|
|
40
|
+
if (!this.resyncTimeoutId)
|
|
41
|
+
return;
|
|
42
|
+
recursiveResync();
|
|
43
|
+
});
|
|
44
|
+
}, this.resyncIntervalMs);
|
|
45
|
+
};
|
|
46
|
+
recursiveResync();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async fetch() {
|
|
50
|
+
if (this.fetchPromise) {
|
|
51
|
+
return this.fetchPromise;
|
|
52
|
+
}
|
|
53
|
+
this.fetchPromise = new Promise((resolver) => {
|
|
54
|
+
this.fetchPromiseResolver = resolver;
|
|
55
|
+
});
|
|
56
|
+
const skipEventEmitting = this.signedMsgUserOrderAccounts.size === 0;
|
|
57
|
+
try {
|
|
58
|
+
const rpcResponseAndContext = await this.driftClient.connection.getProgramAccounts(this.driftClient.program.programId, {
|
|
59
|
+
commitment: this.commitment,
|
|
60
|
+
filters: [(0, memcmp_1.getSignedMsgUserOrdersFilter)()],
|
|
61
|
+
encoding: 'base64',
|
|
62
|
+
withContext: true,
|
|
63
|
+
});
|
|
64
|
+
const slot = rpcResponseAndContext.context.slot;
|
|
65
|
+
for (const programAccount of rpcResponseAndContext.value) {
|
|
66
|
+
this.tryUpdateSignedMsgUserOrdersAccount(programAccount.account.data, 'buffer', slot, skipEventEmitting);
|
|
67
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
console.error(e);
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
this.fetchPromiseResolver();
|
|
75
|
+
this.fetchPromise = undefined;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
tryUpdateSignedMsgUserOrdersAccount(data, dataType, slot, skipEventEmitting = false) {
|
|
79
|
+
var _a;
|
|
80
|
+
if (!this.mostRecentSlot || slot > this.mostRecentSlot) {
|
|
81
|
+
this.mostRecentSlot = slot;
|
|
82
|
+
}
|
|
83
|
+
const signedMsgUserOrdersAccount = dataType === 'buffer'
|
|
84
|
+
? this.decodeFn('SignedMsgUserOrders', data)
|
|
85
|
+
: data;
|
|
86
|
+
const key = signedMsgUserOrdersAccount.authorityPubkey.toBase58();
|
|
87
|
+
const slotAndSignedMsgUserOrdersAccount = this.signedMsgUserOrderAccounts.get(key);
|
|
88
|
+
if (!slotAndSignedMsgUserOrdersAccount ||
|
|
89
|
+
slotAndSignedMsgUserOrdersAccount.slot <= slot) {
|
|
90
|
+
if (!skipEventEmitting) {
|
|
91
|
+
this.eventEmitter.emit('onAccountUpdate', signedMsgUserOrdersAccount.signedMsgOrderData.filter((signedMsgOrderId) => signedMsgOrderId.orderId !== 0), signedMsgUserOrdersAccount.authorityPubkey, slot);
|
|
92
|
+
}
|
|
93
|
+
const existingSignedMsgOrderIds = (_a = slotAndSignedMsgUserOrdersAccount === null || slotAndSignedMsgUserOrdersAccount === void 0 ? void 0 : slotAndSignedMsgUserOrdersAccount.signedMsgUserOrdersAccount.signedMsgOrderData.map((signedMsgOrderId) => signedMsgOrderId.orderId)) !== null && _a !== void 0 ? _a : [];
|
|
94
|
+
const newSignedMsgOrderIds = signedMsgUserOrdersAccount.signedMsgOrderData.filter((signedMsgOrderId) => !existingSignedMsgOrderIds.includes(signedMsgOrderId.orderId) &&
|
|
95
|
+
signedMsgOrderId.orderId !== 0);
|
|
96
|
+
if (newSignedMsgOrderIds.length > 0 && !skipEventEmitting) {
|
|
97
|
+
this.eventEmitter.emit('newSignedMsgOrderIds', newSignedMsgOrderIds, signedMsgUserOrdersAccount.authorityPubkey, slot);
|
|
98
|
+
}
|
|
99
|
+
this.signedMsgUserOrderAccounts.set(key, {
|
|
100
|
+
slot,
|
|
101
|
+
signedMsgUserOrdersAccount,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async unsubscribe() {
|
|
106
|
+
if (!this.subscriber)
|
|
107
|
+
return;
|
|
108
|
+
await this.subscriber.unsubscribe();
|
|
109
|
+
this.subscriber = undefined;
|
|
110
|
+
if (this.resyncTimeoutId !== undefined) {
|
|
111
|
+
clearTimeout(this.resyncTimeoutId);
|
|
112
|
+
this.resyncTimeoutId = undefined;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.SignedMsgUserOrdersAccountSubscriber = SignedMsgUserOrdersAccountSubscriber;
|
package/lib/browser/index.d.ts
CHANGED
|
@@ -88,6 +88,7 @@ export * from './oracles/pythLazerClient';
|
|
|
88
88
|
export * from './oracles/switchboardOnDemandClient';
|
|
89
89
|
export * from './oracles/oracleId';
|
|
90
90
|
export * from './fastlane/fastlaneOrderSubscriber';
|
|
91
|
+
export * from './fastlane/signedMsgUserAccountSubscriber';
|
|
91
92
|
export * from './tx/fastSingleTxSender';
|
|
92
93
|
export * from './tx/retryTxSender';
|
|
93
94
|
export * from './tx/whileValidTxSender';
|
package/lib/browser/index.js
CHANGED
|
@@ -111,6 +111,7 @@ __exportStar(require("./oracles/pythLazerClient"), exports);
|
|
|
111
111
|
__exportStar(require("./oracles/switchboardOnDemandClient"), exports);
|
|
112
112
|
__exportStar(require("./oracles/oracleId"), exports);
|
|
113
113
|
__exportStar(require("./fastlane/fastlaneOrderSubscriber"), exports);
|
|
114
|
+
__exportStar(require("./fastlane/signedMsgUserAccountSubscriber"), exports);
|
|
114
115
|
__exportStar(require("./tx/fastSingleTxSender"), exports);
|
|
115
116
|
__exportStar(require("./tx/retryTxSender"), exports);
|
|
116
117
|
__exportStar(require("./tx/whileValidTxSender"), exports);
|
package/lib/browser/memcmp.d.ts
CHANGED
|
@@ -9,3 +9,4 @@ export declare function getUserWithName(name: string): MemcmpFilter;
|
|
|
9
9
|
export declare function getUserStatsFilter(): MemcmpFilter;
|
|
10
10
|
export declare function getUserStatsIsReferredFilter(): MemcmpFilter;
|
|
11
11
|
export declare function getUserStatsIsReferredOrReferrerFilter(): MemcmpFilter;
|
|
12
|
+
export declare function getSignedMsgUserOrdersFilter(): MemcmpFilter;
|
package/lib/browser/memcmp.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getUserStatsIsReferredOrReferrerFilter = exports.getUserStatsIsReferredFilter = exports.getUserStatsFilter = exports.getUserWithName = exports.getUserThatHasBeenLP = exports.getUserWithAuctionFilter = exports.getUserWithoutOrderFilter = exports.getUserWithOrderFilter = exports.getNonIdleUserFilter = exports.getUserFilter = void 0;
|
|
6
|
+
exports.getSignedMsgUserOrdersFilter = exports.getUserStatsIsReferredOrReferrerFilter = exports.getUserStatsIsReferredFilter = exports.getUserStatsFilter = exports.getUserWithName = exports.getUserThatHasBeenLP = exports.getUserWithAuctionFilter = exports.getUserWithoutOrderFilter = exports.getUserWithOrderFilter = exports.getNonIdleUserFilter = exports.getUserFilter = void 0;
|
|
7
7
|
const bs58_1 = __importDefault(require("bs58"));
|
|
8
8
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
9
9
|
const userName_1 = require("./userName");
|
|
@@ -97,3 +97,12 @@ function getUserStatsIsReferredOrReferrerFilter() {
|
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
99
|
exports.getUserStatsIsReferredOrReferrerFilter = getUserStatsIsReferredOrReferrerFilter;
|
|
100
|
+
function getSignedMsgUserOrdersFilter() {
|
|
101
|
+
return {
|
|
102
|
+
memcmp: {
|
|
103
|
+
offset: 0,
|
|
104
|
+
bytes: bs58_1.default.encode(anchor_1.BorshAccountsCoder.accountDiscriminator('SignedMsgUserOrders')),
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
exports.getSignedMsgUserOrdersFilter = getSignedMsgUserOrdersFilter;
|
package/lib/browser/types.d.ts
CHANGED
|
@@ -1417,6 +1417,11 @@ export type HighLeverageModeConfig = {
|
|
|
1417
1417
|
currentUsers: number;
|
|
1418
1418
|
reduceOnly: boolean;
|
|
1419
1419
|
};
|
|
1420
|
+
export type ProtectedMakerModeConfig = {
|
|
1421
|
+
maxUsers: number;
|
|
1422
|
+
currentUsers: number;
|
|
1423
|
+
reduceOnly: boolean;
|
|
1424
|
+
};
|
|
1420
1425
|
export interface SignedMsgOrderParams {
|
|
1421
1426
|
/**
|
|
1422
1427
|
* The encoded order params that were signed (borsh encoded then hexified).
|
|
@@ -1427,4 +1432,13 @@ export interface SignedMsgOrderParams {
|
|
|
1427
1432
|
*/
|
|
1428
1433
|
signature: Buffer;
|
|
1429
1434
|
}
|
|
1435
|
+
export type SignedMsgOrderId = {
|
|
1436
|
+
maxSlot: BN;
|
|
1437
|
+
uuid: Uint8Array;
|
|
1438
|
+
orderId: number;
|
|
1439
|
+
};
|
|
1440
|
+
export type SignedMsgUserOrdersAccount = {
|
|
1441
|
+
authorityPubkey: PublicKey;
|
|
1442
|
+
signedMsgOrderData: SignedMsgOrderId[];
|
|
1443
|
+
};
|
|
1430
1444
|
export {};
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import * as anchor from '@coral-xyz/anchor';
|
|
6
6
|
import { AnchorProvider, BN, Program, ProgramAccount } from '@coral-xyz/anchor';
|
|
7
7
|
import { Idl as Idl30, Program as Program30 } from '@coral-xyz/anchor-30';
|
|
8
|
-
import { DriftClientMetricsEvents, HighLeverageModeConfig, IWallet, MakerInfo, MappedRecord, MarketType, ModifyOrderPolicy, OpenbookV2FulfillmentConfigAccount, OptionalOrderParams, OracleSource, Order, OrderParams, OrderTriggerCondition, PerpMarketAccount, PerpMarketExtendedInfo, PhoenixV1FulfillmentConfigAccount, PlaceAndTakeOrderSuccessCondition, PositionDirection, ReferrerInfo, ReferrerNameAccount, SerumV3FulfillmentConfigAccount, SettlePnlMode, SignedTxData, SpotMarketAccount, SpotPosition, StateAccount, SwapReduceOnly, SignedMsgOrderParamsMessage, TakerInfo, TxParams, UserAccount, UserStatsAccount } from './types';
|
|
8
|
+
import { DriftClientMetricsEvents, HighLeverageModeConfig, IWallet, MakerInfo, MappedRecord, MarketType, ModifyOrderPolicy, OpenbookV2FulfillmentConfigAccount, OptionalOrderParams, OracleSource, Order, OrderParams, OrderTriggerCondition, PerpMarketAccount, PerpMarketExtendedInfo, PhoenixV1FulfillmentConfigAccount, PlaceAndTakeOrderSuccessCondition, PositionDirection, ReferrerInfo, ReferrerNameAccount, SerumV3FulfillmentConfigAccount, SettlePnlMode, SignedTxData, SpotMarketAccount, SpotPosition, StateAccount, SwapReduceOnly, SignedMsgOrderParamsMessage, TakerInfo, TxParams, UserAccount, UserStatsAccount, ProtectedMakerModeConfig } from './types';
|
|
9
9
|
import { AccountMeta, AddressLookupTableAccount, BlockhashWithExpiryBlockHeight, ConfirmOptions, Connection, Keypair, PublicKey, Signer, Transaction, TransactionInstruction, TransactionSignature, TransactionVersion, VersionedTransaction } from '@solana/web3.js';
|
|
10
10
|
import { TokenFaucet } from './tokenFaucet';
|
|
11
11
|
import { EventEmitter } from 'events';
|
|
@@ -915,6 +915,7 @@ export declare class DriftClient {
|
|
|
915
915
|
disableUserHighLeverageMode(user: PublicKey, userAccount?: UserAccount, txParams?: TxParams): Promise<TransactionSignature>;
|
|
916
916
|
getDisableHighLeverageModeIx(user: PublicKey, userAccount?: UserAccount): Promise<TransactionInstruction>;
|
|
917
917
|
fetchHighLeverageModeConfig(): Promise<HighLeverageModeConfig>;
|
|
918
|
+
fetchProtectedMakerModeConfig(): Promise<ProtectedMakerModeConfig>;
|
|
918
919
|
updateUserProtectedMakerOrders(subAccountId: number, protectedOrders: boolean, authority?: PublicKey, txParams?: TxParams): Promise<TransactionSignature>;
|
|
919
920
|
getUpdateUserProtectedMakerOrdersIx(subAccountId: number, protectedOrders: boolean, authority?: PublicKey): Promise<TransactionInstruction>;
|
|
920
921
|
getPauseSpotMarketDepositWithdrawIx(spotMarketIndex: number): Promise<TransactionInstruction>;
|
package/lib/node/driftClient.js
CHANGED
|
@@ -4898,6 +4898,10 @@ class DriftClient {
|
|
|
4898
4898
|
const config = await this.program.account.highLeverageModeConfig.fetch((0, pda_1.getHighLeverageModeConfigPublicKey)(this.program.programId));
|
|
4899
4899
|
return config;
|
|
4900
4900
|
}
|
|
4901
|
+
async fetchProtectedMakerModeConfig() {
|
|
4902
|
+
const config = await this.program.account.protectedMakerModeConfig.fetch((0, pda_1.getProtectedMakerModeConfigPublicKey)(this.program.programId));
|
|
4903
|
+
return config;
|
|
4904
|
+
}
|
|
4901
4905
|
async updateUserProtectedMakerOrders(subAccountId, protectedOrders, authority, txParams) {
|
|
4902
4906
|
const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getUpdateUserProtectedMakerOrdersIx(subAccountId, protectedOrders, authority), txParams), [], this.opts);
|
|
4903
4907
|
return txSig;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { Commitment } from '@solana/web3.js';
|
|
4
|
+
import { grpcProgramAccountSubscriber } from '../accounts/grpcProgramAccountSubscriber';
|
|
5
|
+
import { GrpcConfigs, ResubOpts } from '../accounts/types';
|
|
6
|
+
import { SignedMsgUserOrdersAccount } from '../types';
|
|
7
|
+
import { SignedMsgUserOrdersAccountSubscriber } from './signedMsgUserAccountSubscriber';
|
|
8
|
+
import { DriftClient } from '../driftClient';
|
|
9
|
+
export declare class grpcSignedMsgUserOrdersAccountSubscriber extends SignedMsgUserOrdersAccountSubscriber {
|
|
10
|
+
private grpcConfigs;
|
|
11
|
+
subscriber: grpcProgramAccountSubscriber<SignedMsgUserOrdersAccount>;
|
|
12
|
+
constructor({ grpcConfigs, driftClient, commitment, resubOpts, decodeFn, resyncIntervalMs, }: {
|
|
13
|
+
grpcConfigs: GrpcConfigs;
|
|
14
|
+
driftClient: DriftClient;
|
|
15
|
+
commitment: Commitment;
|
|
16
|
+
resubOpts?: ResubOpts;
|
|
17
|
+
decodeFn: (name: string, data: Buffer) => SignedMsgUserOrdersAccount;
|
|
18
|
+
resyncIntervalMs?: number;
|
|
19
|
+
});
|
|
20
|
+
subscribe(): Promise<void>;
|
|
21
|
+
unsubscribe(): Promise<void>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.grpcSignedMsgUserOrdersAccountSubscriber = void 0;
|
|
4
|
+
const grpcProgramAccountSubscriber_1 = require("../accounts/grpcProgramAccountSubscriber");
|
|
5
|
+
const memcmp_1 = require("../memcmp");
|
|
6
|
+
const signedMsgUserAccountSubscriber_1 = require("./signedMsgUserAccountSubscriber");
|
|
7
|
+
class grpcSignedMsgUserOrdersAccountSubscriber extends signedMsgUserAccountSubscriber_1.SignedMsgUserOrdersAccountSubscriber {
|
|
8
|
+
constructor({ grpcConfigs, driftClient, commitment, resubOpts, decodeFn, resyncIntervalMs, }) {
|
|
9
|
+
super({
|
|
10
|
+
driftClient,
|
|
11
|
+
commitment,
|
|
12
|
+
resubOpts,
|
|
13
|
+
decodeFn,
|
|
14
|
+
resyncIntervalMs,
|
|
15
|
+
});
|
|
16
|
+
this.grpcConfigs = grpcConfigs;
|
|
17
|
+
}
|
|
18
|
+
async subscribe() {
|
|
19
|
+
if (!this.subscriber) {
|
|
20
|
+
this.subscriber =
|
|
21
|
+
await grpcProgramAccountSubscriber_1.grpcProgramAccountSubscriber.create(this.grpcConfigs, 'OrderSubscriber', 'User', this.driftClient.program, this.decodeFn, {
|
|
22
|
+
filters: [(0, memcmp_1.getSignedMsgUserOrdersFilter)()],
|
|
23
|
+
}, this.resubOpts);
|
|
24
|
+
}
|
|
25
|
+
await this.subscriber.subscribe((_accountId, account, context) => {
|
|
26
|
+
this.tryUpdateSignedMsgUserOrdersAccount(account, 'decoded', context.slot);
|
|
27
|
+
});
|
|
28
|
+
if (this.resyncIntervalMs) {
|
|
29
|
+
const recursiveResync = () => {
|
|
30
|
+
this.resyncTimeoutId = setTimeout(() => {
|
|
31
|
+
this.fetch()
|
|
32
|
+
.catch((e) => {
|
|
33
|
+
console.error('Failed to resync in OrderSubscriber');
|
|
34
|
+
console.log(e);
|
|
35
|
+
})
|
|
36
|
+
.finally(() => {
|
|
37
|
+
if (!this.resyncTimeoutId)
|
|
38
|
+
return;
|
|
39
|
+
recursiveResync();
|
|
40
|
+
});
|
|
41
|
+
}, this.resyncIntervalMs);
|
|
42
|
+
};
|
|
43
|
+
recursiveResync();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async unsubscribe() {
|
|
47
|
+
if (!this.subscriber)
|
|
48
|
+
return;
|
|
49
|
+
await this.subscriber.unsubscribe();
|
|
50
|
+
this.subscriber = undefined;
|
|
51
|
+
if (this.resyncTimeoutId !== undefined) {
|
|
52
|
+
clearTimeout(this.resyncTimeoutId);
|
|
53
|
+
this.resyncTimeoutId = undefined;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.grpcSignedMsgUserOrdersAccountSubscriber = grpcSignedMsgUserOrdersAccountSubscriber;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./fastlaneOrderSubscriber"), exports);
|
|
18
|
+
__exportStar(require("./signedMsgUserAccountSubscriber"), exports);
|
|
19
|
+
__exportStar(require("./grpcSignedMsgUserAccountSubscriber"), exports);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
/// <reference types="node" />
|
|
5
|
+
import { WebSocketProgramAccountSubscriber } from '../accounts/webSocketProgramAccountSubscriber';
|
|
6
|
+
import { SignedMsgOrderId, SignedMsgUserOrdersAccount } from '../types';
|
|
7
|
+
import { Commitment, PublicKey } from '@solana/web3.js';
|
|
8
|
+
import { ResubOpts } from '../accounts/types';
|
|
9
|
+
import { DriftClient } from '../driftClient';
|
|
10
|
+
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
11
|
+
import { EventEmitter } from 'events';
|
|
12
|
+
export interface SignedMsgUserOrdersAccountSubscriberEvents {
|
|
13
|
+
onAccountUpdate: (activeSignedMsgOrderIds: SignedMsgOrderId[], authorityPubkey: PublicKey, slot: number) => void;
|
|
14
|
+
newSignedMsgOrderIds: (newSignedMsgOrderIds: SignedMsgOrderId[], authorityPubkey: PublicKey, slot: number) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare class SignedMsgUserOrdersAccountSubscriber {
|
|
17
|
+
protected driftClient: DriftClient;
|
|
18
|
+
protected commitment: Commitment;
|
|
19
|
+
protected resubOpts?: ResubOpts;
|
|
20
|
+
protected resyncTimeoutId?: NodeJS.Timeout;
|
|
21
|
+
protected resyncIntervalMs?: number;
|
|
22
|
+
protected decodeFn: (name: string, data: Buffer) => SignedMsgUserOrdersAccount;
|
|
23
|
+
protected signedMsgUserOrderAccounts: Map<string, {
|
|
24
|
+
slot: number;
|
|
25
|
+
signedMsgUserOrdersAccount: SignedMsgUserOrdersAccount;
|
|
26
|
+
}>;
|
|
27
|
+
mostRecentSlot: number;
|
|
28
|
+
fetchPromise?: Promise<void>;
|
|
29
|
+
fetchPromiseResolver: () => void;
|
|
30
|
+
protected subscriber: WebSocketProgramAccountSubscriber<SignedMsgUserOrdersAccount>;
|
|
31
|
+
eventEmitter: StrictEventEmitter<EventEmitter, SignedMsgUserOrdersAccountSubscriberEvents>;
|
|
32
|
+
constructor({ driftClient, commitment, resubOpts, decodeFn, resyncIntervalMs, }: {
|
|
33
|
+
driftClient: DriftClient;
|
|
34
|
+
commitment: Commitment;
|
|
35
|
+
resubOpts?: ResubOpts;
|
|
36
|
+
decodeFn: (name: string, data: Buffer) => SignedMsgUserOrdersAccount;
|
|
37
|
+
resyncIntervalMs?: number;
|
|
38
|
+
});
|
|
39
|
+
subscribe(): Promise<void>;
|
|
40
|
+
fetch(): Promise<void>;
|
|
41
|
+
tryUpdateSignedMsgUserOrdersAccount(data: Buffer | SignedMsgUserOrdersAccount, dataType: 'buffer' | 'decoded', slot: number, skipEventEmitting?: boolean): void;
|
|
42
|
+
unsubscribe(): Promise<void>;
|
|
43
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SignedMsgUserOrdersAccountSubscriber = void 0;
|
|
4
|
+
const memcmp_1 = require("../memcmp");
|
|
5
|
+
const webSocketProgramAccountSubscriber_1 = require("../accounts/webSocketProgramAccountSubscriber");
|
|
6
|
+
const events_1 = require("events");
|
|
7
|
+
class SignedMsgUserOrdersAccountSubscriber {
|
|
8
|
+
constructor({ driftClient, commitment, resubOpts, decodeFn, resyncIntervalMs, }) {
|
|
9
|
+
this.signedMsgUserOrderAccounts = new Map();
|
|
10
|
+
this.commitment = commitment;
|
|
11
|
+
this.resubOpts = resubOpts;
|
|
12
|
+
this.decodeFn = decodeFn;
|
|
13
|
+
this.driftClient = driftClient;
|
|
14
|
+
this.resyncIntervalMs = resyncIntervalMs;
|
|
15
|
+
this.eventEmitter = new events_1.EventEmitter();
|
|
16
|
+
this.resubOpts = resubOpts;
|
|
17
|
+
}
|
|
18
|
+
async subscribe() {
|
|
19
|
+
if (!this.subscriber) {
|
|
20
|
+
const filters = [(0, memcmp_1.getSignedMsgUserOrdersFilter)()];
|
|
21
|
+
this.subscriber =
|
|
22
|
+
new webSocketProgramAccountSubscriber_1.WebSocketProgramAccountSubscriber('SingedMsgUserOrdersAccountMap', 'SignedMsgUserOrders', this.driftClient.program, this.decodeFn, {
|
|
23
|
+
filters,
|
|
24
|
+
commitment: this.commitment,
|
|
25
|
+
}, this.resubOpts);
|
|
26
|
+
}
|
|
27
|
+
await this.subscriber.subscribe((_accountId, account, context) => {
|
|
28
|
+
this.tryUpdateSignedMsgUserOrdersAccount(account, 'decoded', context.slot);
|
|
29
|
+
});
|
|
30
|
+
await this.fetch();
|
|
31
|
+
if (this.resyncIntervalMs) {
|
|
32
|
+
const recursiveResync = () => {
|
|
33
|
+
this.resyncTimeoutId = setTimeout(() => {
|
|
34
|
+
this.fetch()
|
|
35
|
+
.catch((e) => {
|
|
36
|
+
console.error('Failed to resync in OrderSubscriber');
|
|
37
|
+
console.log(e);
|
|
38
|
+
})
|
|
39
|
+
.finally(() => {
|
|
40
|
+
if (!this.resyncTimeoutId)
|
|
41
|
+
return;
|
|
42
|
+
recursiveResync();
|
|
43
|
+
});
|
|
44
|
+
}, this.resyncIntervalMs);
|
|
45
|
+
};
|
|
46
|
+
recursiveResync();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async fetch() {
|
|
50
|
+
if (this.fetchPromise) {
|
|
51
|
+
return this.fetchPromise;
|
|
52
|
+
}
|
|
53
|
+
this.fetchPromise = new Promise((resolver) => {
|
|
54
|
+
this.fetchPromiseResolver = resolver;
|
|
55
|
+
});
|
|
56
|
+
const skipEventEmitting = this.signedMsgUserOrderAccounts.size === 0;
|
|
57
|
+
try {
|
|
58
|
+
const rpcResponseAndContext = await this.driftClient.connection.getProgramAccounts(this.driftClient.program.programId, {
|
|
59
|
+
commitment: this.commitment,
|
|
60
|
+
filters: [(0, memcmp_1.getSignedMsgUserOrdersFilter)()],
|
|
61
|
+
encoding: 'base64',
|
|
62
|
+
withContext: true,
|
|
63
|
+
});
|
|
64
|
+
const slot = rpcResponseAndContext.context.slot;
|
|
65
|
+
for (const programAccount of rpcResponseAndContext.value) {
|
|
66
|
+
this.tryUpdateSignedMsgUserOrdersAccount(programAccount.account.data, 'buffer', slot, skipEventEmitting);
|
|
67
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
console.error(e);
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
this.fetchPromiseResolver();
|
|
75
|
+
this.fetchPromise = undefined;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
tryUpdateSignedMsgUserOrdersAccount(data, dataType, slot, skipEventEmitting = false) {
|
|
79
|
+
var _a;
|
|
80
|
+
if (!this.mostRecentSlot || slot > this.mostRecentSlot) {
|
|
81
|
+
this.mostRecentSlot = slot;
|
|
82
|
+
}
|
|
83
|
+
const signedMsgUserOrdersAccount = dataType === 'buffer'
|
|
84
|
+
? this.decodeFn('SignedMsgUserOrders', data)
|
|
85
|
+
: data;
|
|
86
|
+
const key = signedMsgUserOrdersAccount.authorityPubkey.toBase58();
|
|
87
|
+
const slotAndSignedMsgUserOrdersAccount = this.signedMsgUserOrderAccounts.get(key);
|
|
88
|
+
if (!slotAndSignedMsgUserOrdersAccount ||
|
|
89
|
+
slotAndSignedMsgUserOrdersAccount.slot <= slot) {
|
|
90
|
+
if (!skipEventEmitting) {
|
|
91
|
+
this.eventEmitter.emit('onAccountUpdate', signedMsgUserOrdersAccount.signedMsgOrderData.filter((signedMsgOrderId) => signedMsgOrderId.orderId !== 0), signedMsgUserOrdersAccount.authorityPubkey, slot);
|
|
92
|
+
}
|
|
93
|
+
const existingSignedMsgOrderIds = (_a = slotAndSignedMsgUserOrdersAccount === null || slotAndSignedMsgUserOrdersAccount === void 0 ? void 0 : slotAndSignedMsgUserOrdersAccount.signedMsgUserOrdersAccount.signedMsgOrderData.map((signedMsgOrderId) => signedMsgOrderId.orderId)) !== null && _a !== void 0 ? _a : [];
|
|
94
|
+
const newSignedMsgOrderIds = signedMsgUserOrdersAccount.signedMsgOrderData.filter((signedMsgOrderId) => !existingSignedMsgOrderIds.includes(signedMsgOrderId.orderId) &&
|
|
95
|
+
signedMsgOrderId.orderId !== 0);
|
|
96
|
+
if (newSignedMsgOrderIds.length > 0 && !skipEventEmitting) {
|
|
97
|
+
this.eventEmitter.emit('newSignedMsgOrderIds', newSignedMsgOrderIds, signedMsgUserOrdersAccount.authorityPubkey, slot);
|
|
98
|
+
}
|
|
99
|
+
this.signedMsgUserOrderAccounts.set(key, {
|
|
100
|
+
slot,
|
|
101
|
+
signedMsgUserOrdersAccount,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async unsubscribe() {
|
|
106
|
+
if (!this.subscriber)
|
|
107
|
+
return;
|
|
108
|
+
await this.subscriber.unsubscribe();
|
|
109
|
+
this.subscriber = undefined;
|
|
110
|
+
if (this.resyncTimeoutId !== undefined) {
|
|
111
|
+
clearTimeout(this.resyncTimeoutId);
|
|
112
|
+
this.resyncTimeoutId = undefined;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.SignedMsgUserOrdersAccountSubscriber = SignedMsgUserOrdersAccountSubscriber;
|
package/lib/node/index.d.ts
CHANGED
|
@@ -88,6 +88,7 @@ export * from './oracles/pythLazerClient';
|
|
|
88
88
|
export * from './oracles/switchboardOnDemandClient';
|
|
89
89
|
export * from './oracles/oracleId';
|
|
90
90
|
export * from './fastlane/fastlaneOrderSubscriber';
|
|
91
|
+
export * from './fastlane/signedMsgUserAccountSubscriber';
|
|
91
92
|
export * from './tx/fastSingleTxSender';
|
|
92
93
|
export * from './tx/retryTxSender';
|
|
93
94
|
export * from './tx/whileValidTxSender';
|
package/lib/node/index.js
CHANGED
|
@@ -111,6 +111,7 @@ __exportStar(require("./oracles/pythLazerClient"), exports);
|
|
|
111
111
|
__exportStar(require("./oracles/switchboardOnDemandClient"), exports);
|
|
112
112
|
__exportStar(require("./oracles/oracleId"), exports);
|
|
113
113
|
__exportStar(require("./fastlane/fastlaneOrderSubscriber"), exports);
|
|
114
|
+
__exportStar(require("./fastlane/signedMsgUserAccountSubscriber"), exports);
|
|
114
115
|
__exportStar(require("./tx/fastSingleTxSender"), exports);
|
|
115
116
|
__exportStar(require("./tx/retryTxSender"), exports);
|
|
116
117
|
__exportStar(require("./tx/whileValidTxSender"), exports);
|
package/lib/node/memcmp.d.ts
CHANGED
|
@@ -9,3 +9,4 @@ export declare function getUserWithName(name: string): MemcmpFilter;
|
|
|
9
9
|
export declare function getUserStatsFilter(): MemcmpFilter;
|
|
10
10
|
export declare function getUserStatsIsReferredFilter(): MemcmpFilter;
|
|
11
11
|
export declare function getUserStatsIsReferredOrReferrerFilter(): MemcmpFilter;
|
|
12
|
+
export declare function getSignedMsgUserOrdersFilter(): MemcmpFilter;
|
package/lib/node/memcmp.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getUserStatsIsReferredOrReferrerFilter = exports.getUserStatsIsReferredFilter = exports.getUserStatsFilter = exports.getUserWithName = exports.getUserThatHasBeenLP = exports.getUserWithAuctionFilter = exports.getUserWithoutOrderFilter = exports.getUserWithOrderFilter = exports.getNonIdleUserFilter = exports.getUserFilter = void 0;
|
|
6
|
+
exports.getSignedMsgUserOrdersFilter = exports.getUserStatsIsReferredOrReferrerFilter = exports.getUserStatsIsReferredFilter = exports.getUserStatsFilter = exports.getUserWithName = exports.getUserThatHasBeenLP = exports.getUserWithAuctionFilter = exports.getUserWithoutOrderFilter = exports.getUserWithOrderFilter = exports.getNonIdleUserFilter = exports.getUserFilter = void 0;
|
|
7
7
|
const bs58_1 = __importDefault(require("bs58"));
|
|
8
8
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
9
9
|
const userName_1 = require("./userName");
|
|
@@ -97,3 +97,12 @@ function getUserStatsIsReferredOrReferrerFilter() {
|
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
99
|
exports.getUserStatsIsReferredOrReferrerFilter = getUserStatsIsReferredOrReferrerFilter;
|
|
100
|
+
function getSignedMsgUserOrdersFilter() {
|
|
101
|
+
return {
|
|
102
|
+
memcmp: {
|
|
103
|
+
offset: 0,
|
|
104
|
+
bytes: bs58_1.default.encode(anchor_1.BorshAccountsCoder.accountDiscriminator('SignedMsgUserOrders')),
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
exports.getSignedMsgUserOrdersFilter = getSignedMsgUserOrdersFilter;
|
package/lib/node/types.d.ts
CHANGED
|
@@ -1417,6 +1417,11 @@ export type HighLeverageModeConfig = {
|
|
|
1417
1417
|
currentUsers: number;
|
|
1418
1418
|
reduceOnly: boolean;
|
|
1419
1419
|
};
|
|
1420
|
+
export type ProtectedMakerModeConfig = {
|
|
1421
|
+
maxUsers: number;
|
|
1422
|
+
currentUsers: number;
|
|
1423
|
+
reduceOnly: boolean;
|
|
1424
|
+
};
|
|
1420
1425
|
export interface SignedMsgOrderParams {
|
|
1421
1426
|
/**
|
|
1422
1427
|
* The encoded order params that were signed (borsh encoded then hexified).
|
|
@@ -1427,4 +1432,13 @@ export interface SignedMsgOrderParams {
|
|
|
1427
1432
|
*/
|
|
1428
1433
|
signature: Buffer;
|
|
1429
1434
|
}
|
|
1435
|
+
export type SignedMsgOrderId = {
|
|
1436
|
+
maxSlot: BN;
|
|
1437
|
+
uuid: Uint8Array;
|
|
1438
|
+
orderId: number;
|
|
1439
|
+
};
|
|
1440
|
+
export type SignedMsgUserOrdersAccount = {
|
|
1441
|
+
authorityPubkey: PublicKey;
|
|
1442
|
+
signedMsgOrderData: SignedMsgOrderId[];
|
|
1443
|
+
};
|
|
1430
1444
|
export {};
|
package/package.json
CHANGED
package/src/driftClient.ts
CHANGED
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
TxParams,
|
|
57
57
|
UserAccount,
|
|
58
58
|
UserStatsAccount,
|
|
59
|
+
ProtectedMakerModeConfig,
|
|
59
60
|
} from './types';
|
|
60
61
|
import driftIDL from './idl/drift.json';
|
|
61
62
|
|
|
@@ -9339,6 +9340,13 @@ export class DriftClient {
|
|
|
9339
9340
|
return config as HighLeverageModeConfig;
|
|
9340
9341
|
}
|
|
9341
9342
|
|
|
9343
|
+
public async fetchProtectedMakerModeConfig(): Promise<ProtectedMakerModeConfig> {
|
|
9344
|
+
const config = await this.program.account.protectedMakerModeConfig.fetch(
|
|
9345
|
+
getProtectedMakerModeConfigPublicKey(this.program.programId)
|
|
9346
|
+
);
|
|
9347
|
+
return config as ProtectedMakerModeConfig;
|
|
9348
|
+
}
|
|
9349
|
+
|
|
9342
9350
|
public async updateUserProtectedMakerOrders(
|
|
9343
9351
|
subAccountId: number,
|
|
9344
9352
|
protectedOrders: boolean,
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Commitment, Context, PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { grpcProgramAccountSubscriber } from '../accounts/grpcProgramAccountSubscriber';
|
|
3
|
+
import { GrpcConfigs, ResubOpts } from '../accounts/types';
|
|
4
|
+
import { SignedMsgUserOrdersAccount } from '../types';
|
|
5
|
+
import { getSignedMsgUserOrdersFilter } from '../memcmp';
|
|
6
|
+
import { SignedMsgUserOrdersAccountSubscriber } from './signedMsgUserAccountSubscriber';
|
|
7
|
+
import { DriftClient } from '../driftClient';
|
|
8
|
+
|
|
9
|
+
export class grpcSignedMsgUserOrdersAccountSubscriber extends SignedMsgUserOrdersAccountSubscriber {
|
|
10
|
+
private grpcConfigs: GrpcConfigs;
|
|
11
|
+
override subscriber: grpcProgramAccountSubscriber<SignedMsgUserOrdersAccount>;
|
|
12
|
+
|
|
13
|
+
constructor({
|
|
14
|
+
grpcConfigs,
|
|
15
|
+
driftClient,
|
|
16
|
+
commitment,
|
|
17
|
+
resubOpts,
|
|
18
|
+
decodeFn,
|
|
19
|
+
resyncIntervalMs,
|
|
20
|
+
}: {
|
|
21
|
+
grpcConfigs: GrpcConfigs;
|
|
22
|
+
driftClient: DriftClient;
|
|
23
|
+
commitment: Commitment;
|
|
24
|
+
resubOpts?: ResubOpts;
|
|
25
|
+
decodeFn: (name: string, data: Buffer) => SignedMsgUserOrdersAccount;
|
|
26
|
+
resyncIntervalMs?: number;
|
|
27
|
+
}) {
|
|
28
|
+
super({
|
|
29
|
+
driftClient,
|
|
30
|
+
commitment,
|
|
31
|
+
resubOpts,
|
|
32
|
+
decodeFn,
|
|
33
|
+
resyncIntervalMs,
|
|
34
|
+
});
|
|
35
|
+
this.grpcConfigs = grpcConfigs;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public async subscribe(): Promise<void> {
|
|
39
|
+
if (!this.subscriber) {
|
|
40
|
+
this.subscriber =
|
|
41
|
+
await grpcProgramAccountSubscriber.create<SignedMsgUserOrdersAccount>(
|
|
42
|
+
this.grpcConfigs,
|
|
43
|
+
'OrderSubscriber',
|
|
44
|
+
'User',
|
|
45
|
+
this.driftClient.program,
|
|
46
|
+
this.decodeFn,
|
|
47
|
+
{
|
|
48
|
+
filters: [getSignedMsgUserOrdersFilter()],
|
|
49
|
+
},
|
|
50
|
+
this.resubOpts
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
await this.subscriber.subscribe(
|
|
55
|
+
(
|
|
56
|
+
_accountId: PublicKey,
|
|
57
|
+
account: SignedMsgUserOrdersAccount,
|
|
58
|
+
context: Context
|
|
59
|
+
) => {
|
|
60
|
+
this.tryUpdateSignedMsgUserOrdersAccount(
|
|
61
|
+
account,
|
|
62
|
+
'decoded',
|
|
63
|
+
context.slot
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
if (this.resyncIntervalMs) {
|
|
69
|
+
const recursiveResync = () => {
|
|
70
|
+
this.resyncTimeoutId = setTimeout(() => {
|
|
71
|
+
this.fetch()
|
|
72
|
+
.catch((e) => {
|
|
73
|
+
console.error('Failed to resync in OrderSubscriber');
|
|
74
|
+
console.log(e);
|
|
75
|
+
})
|
|
76
|
+
.finally(() => {
|
|
77
|
+
if (!this.resyncTimeoutId) return;
|
|
78
|
+
recursiveResync();
|
|
79
|
+
});
|
|
80
|
+
}, this.resyncIntervalMs);
|
|
81
|
+
};
|
|
82
|
+
recursiveResync();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public async unsubscribe(): Promise<void> {
|
|
87
|
+
if (!this.subscriber) return;
|
|
88
|
+
await this.subscriber.unsubscribe();
|
|
89
|
+
this.subscriber = undefined;
|
|
90
|
+
if (this.resyncTimeoutId !== undefined) {
|
|
91
|
+
clearTimeout(this.resyncTimeoutId);
|
|
92
|
+
this.resyncTimeoutId = undefined;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { getSignedMsgUserOrdersFilter } from '../memcmp';
|
|
2
|
+
import { WebSocketProgramAccountSubscriber } from '../accounts/webSocketProgramAccountSubscriber';
|
|
3
|
+
import { SignedMsgOrderId, SignedMsgUserOrdersAccount } from '../types';
|
|
4
|
+
import { Commitment, Context, PublicKey } from '@solana/web3.js';
|
|
5
|
+
import { ResubOpts } from '../accounts/types';
|
|
6
|
+
import { DriftClient } from '../driftClient';
|
|
7
|
+
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
8
|
+
import { EventEmitter } from 'events';
|
|
9
|
+
|
|
10
|
+
export interface SignedMsgUserOrdersAccountSubscriberEvents {
|
|
11
|
+
onAccountUpdate: (
|
|
12
|
+
activeSignedMsgOrderIds: SignedMsgOrderId[],
|
|
13
|
+
authorityPubkey: PublicKey,
|
|
14
|
+
slot: number
|
|
15
|
+
) => void;
|
|
16
|
+
|
|
17
|
+
newSignedMsgOrderIds: (
|
|
18
|
+
newSignedMsgOrderIds: SignedMsgOrderId[],
|
|
19
|
+
authorityPubkey: PublicKey,
|
|
20
|
+
slot: number
|
|
21
|
+
) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class SignedMsgUserOrdersAccountSubscriber {
|
|
25
|
+
protected driftClient: DriftClient;
|
|
26
|
+
protected commitment: Commitment;
|
|
27
|
+
protected resubOpts?: ResubOpts;
|
|
28
|
+
protected resyncTimeoutId?: NodeJS.Timeout;
|
|
29
|
+
protected resyncIntervalMs?: number;
|
|
30
|
+
protected decodeFn: (
|
|
31
|
+
name: string,
|
|
32
|
+
data: Buffer
|
|
33
|
+
) => SignedMsgUserOrdersAccount;
|
|
34
|
+
protected signedMsgUserOrderAccounts = new Map<
|
|
35
|
+
string,
|
|
36
|
+
{ slot: number; signedMsgUserOrdersAccount: SignedMsgUserOrdersAccount }
|
|
37
|
+
>();
|
|
38
|
+
mostRecentSlot: number;
|
|
39
|
+
|
|
40
|
+
fetchPromise?: Promise<void>;
|
|
41
|
+
fetchPromiseResolver: () => void;
|
|
42
|
+
|
|
43
|
+
protected subscriber: WebSocketProgramAccountSubscriber<SignedMsgUserOrdersAccount>;
|
|
44
|
+
public eventEmitter: StrictEventEmitter<
|
|
45
|
+
EventEmitter,
|
|
46
|
+
SignedMsgUserOrdersAccountSubscriberEvents
|
|
47
|
+
>;
|
|
48
|
+
|
|
49
|
+
constructor({
|
|
50
|
+
driftClient,
|
|
51
|
+
commitment,
|
|
52
|
+
resubOpts,
|
|
53
|
+
decodeFn,
|
|
54
|
+
resyncIntervalMs,
|
|
55
|
+
}: {
|
|
56
|
+
driftClient: DriftClient;
|
|
57
|
+
commitment: Commitment;
|
|
58
|
+
resubOpts?: ResubOpts;
|
|
59
|
+
decodeFn: (name: string, data: Buffer) => SignedMsgUserOrdersAccount;
|
|
60
|
+
resyncIntervalMs?: number;
|
|
61
|
+
}) {
|
|
62
|
+
this.commitment = commitment;
|
|
63
|
+
this.resubOpts = resubOpts;
|
|
64
|
+
this.decodeFn = decodeFn;
|
|
65
|
+
this.driftClient = driftClient;
|
|
66
|
+
this.resyncIntervalMs = resyncIntervalMs;
|
|
67
|
+
this.eventEmitter = new EventEmitter();
|
|
68
|
+
this.resubOpts = resubOpts;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public async subscribe(): Promise<void> {
|
|
72
|
+
if (!this.subscriber) {
|
|
73
|
+
const filters = [getSignedMsgUserOrdersFilter()];
|
|
74
|
+
this.subscriber =
|
|
75
|
+
new WebSocketProgramAccountSubscriber<SignedMsgUserOrdersAccount>(
|
|
76
|
+
'SingedMsgUserOrdersAccountMap',
|
|
77
|
+
'SignedMsgUserOrders',
|
|
78
|
+
this.driftClient.program,
|
|
79
|
+
this.decodeFn,
|
|
80
|
+
{
|
|
81
|
+
filters,
|
|
82
|
+
commitment: this.commitment,
|
|
83
|
+
},
|
|
84
|
+
this.resubOpts
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
await this.subscriber.subscribe(
|
|
89
|
+
(
|
|
90
|
+
_accountId: PublicKey,
|
|
91
|
+
account: SignedMsgUserOrdersAccount,
|
|
92
|
+
context: Context
|
|
93
|
+
) => {
|
|
94
|
+
this.tryUpdateSignedMsgUserOrdersAccount(
|
|
95
|
+
account,
|
|
96
|
+
'decoded',
|
|
97
|
+
context.slot
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
await this.fetch();
|
|
103
|
+
|
|
104
|
+
if (this.resyncIntervalMs) {
|
|
105
|
+
const recursiveResync = () => {
|
|
106
|
+
this.resyncTimeoutId = setTimeout(() => {
|
|
107
|
+
this.fetch()
|
|
108
|
+
.catch((e) => {
|
|
109
|
+
console.error('Failed to resync in OrderSubscriber');
|
|
110
|
+
console.log(e);
|
|
111
|
+
})
|
|
112
|
+
.finally(() => {
|
|
113
|
+
if (!this.resyncTimeoutId) return;
|
|
114
|
+
recursiveResync();
|
|
115
|
+
});
|
|
116
|
+
}, this.resyncIntervalMs);
|
|
117
|
+
};
|
|
118
|
+
recursiveResync();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async fetch(): Promise<void> {
|
|
123
|
+
if (this.fetchPromise) {
|
|
124
|
+
return this.fetchPromise;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
this.fetchPromise = new Promise((resolver) => {
|
|
128
|
+
this.fetchPromiseResolver = resolver;
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const skipEventEmitting = this.signedMsgUserOrderAccounts.size === 0;
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
const rpcResponseAndContext =
|
|
135
|
+
await this.driftClient.connection.getProgramAccounts(
|
|
136
|
+
this.driftClient.program.programId,
|
|
137
|
+
{
|
|
138
|
+
commitment: this.commitment,
|
|
139
|
+
filters: [getSignedMsgUserOrdersFilter()],
|
|
140
|
+
encoding: 'base64',
|
|
141
|
+
withContext: true,
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const slot: number = rpcResponseAndContext.context.slot;
|
|
146
|
+
|
|
147
|
+
for (const programAccount of rpcResponseAndContext.value) {
|
|
148
|
+
this.tryUpdateSignedMsgUserOrdersAccount(
|
|
149
|
+
programAccount.account.data,
|
|
150
|
+
'buffer',
|
|
151
|
+
slot,
|
|
152
|
+
skipEventEmitting
|
|
153
|
+
);
|
|
154
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
155
|
+
}
|
|
156
|
+
} catch (e) {
|
|
157
|
+
console.error(e);
|
|
158
|
+
} finally {
|
|
159
|
+
this.fetchPromiseResolver();
|
|
160
|
+
this.fetchPromise = undefined;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
tryUpdateSignedMsgUserOrdersAccount(
|
|
165
|
+
data: Buffer | SignedMsgUserOrdersAccount,
|
|
166
|
+
dataType: 'buffer' | 'decoded',
|
|
167
|
+
slot: number,
|
|
168
|
+
skipEventEmitting = false
|
|
169
|
+
): void {
|
|
170
|
+
if (!this.mostRecentSlot || slot > this.mostRecentSlot) {
|
|
171
|
+
this.mostRecentSlot = slot;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const signedMsgUserOrdersAccount =
|
|
175
|
+
dataType === 'buffer'
|
|
176
|
+
? this.decodeFn('SignedMsgUserOrders', data as Buffer)
|
|
177
|
+
: (data as SignedMsgUserOrdersAccount);
|
|
178
|
+
|
|
179
|
+
const key = signedMsgUserOrdersAccount.authorityPubkey.toBase58();
|
|
180
|
+
|
|
181
|
+
const slotAndSignedMsgUserOrdersAccount =
|
|
182
|
+
this.signedMsgUserOrderAccounts.get(key);
|
|
183
|
+
if (
|
|
184
|
+
!slotAndSignedMsgUserOrdersAccount ||
|
|
185
|
+
slotAndSignedMsgUserOrdersAccount.slot <= slot
|
|
186
|
+
) {
|
|
187
|
+
if (!skipEventEmitting) {
|
|
188
|
+
this.eventEmitter.emit(
|
|
189
|
+
'onAccountUpdate',
|
|
190
|
+
signedMsgUserOrdersAccount.signedMsgOrderData.filter(
|
|
191
|
+
(signedMsgOrderId) => signedMsgOrderId.orderId !== 0
|
|
192
|
+
),
|
|
193
|
+
signedMsgUserOrdersAccount.authorityPubkey,
|
|
194
|
+
slot
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const existingSignedMsgOrderIds =
|
|
199
|
+
slotAndSignedMsgUserOrdersAccount?.signedMsgUserOrdersAccount.signedMsgOrderData.map(
|
|
200
|
+
(signedMsgOrderId) => signedMsgOrderId.orderId
|
|
201
|
+
) ?? [];
|
|
202
|
+
|
|
203
|
+
const newSignedMsgOrderIds =
|
|
204
|
+
signedMsgUserOrdersAccount.signedMsgOrderData.filter(
|
|
205
|
+
(signedMsgOrderId: SignedMsgOrderId) =>
|
|
206
|
+
!existingSignedMsgOrderIds.includes(signedMsgOrderId.orderId) &&
|
|
207
|
+
signedMsgOrderId.orderId !== 0
|
|
208
|
+
);
|
|
209
|
+
if (newSignedMsgOrderIds.length > 0 && !skipEventEmitting) {
|
|
210
|
+
this.eventEmitter.emit(
|
|
211
|
+
'newSignedMsgOrderIds',
|
|
212
|
+
newSignedMsgOrderIds,
|
|
213
|
+
signedMsgUserOrdersAccount.authorityPubkey,
|
|
214
|
+
slot
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
this.signedMsgUserOrderAccounts.set(key, {
|
|
219
|
+
slot,
|
|
220
|
+
signedMsgUserOrdersAccount,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
public async unsubscribe(): Promise<void> {
|
|
226
|
+
if (!this.subscriber) return;
|
|
227
|
+
await this.subscriber.unsubscribe();
|
|
228
|
+
this.subscriber = undefined;
|
|
229
|
+
if (this.resyncTimeoutId !== undefined) {
|
|
230
|
+
clearTimeout(this.resyncTimeoutId);
|
|
231
|
+
this.resyncTimeoutId = undefined;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -89,6 +89,7 @@ export * from './oracles/pythLazerClient';
|
|
|
89
89
|
export * from './oracles/switchboardOnDemandClient';
|
|
90
90
|
export * from './oracles/oracleId';
|
|
91
91
|
export * from './fastlane/fastlaneOrderSubscriber';
|
|
92
|
+
export * from './fastlane/signedMsgUserAccountSubscriber';
|
|
92
93
|
export * from './tx/fastSingleTxSender';
|
|
93
94
|
export * from './tx/retryTxSender';
|
|
94
95
|
export * from './tx/whileValidTxSender';
|
package/src/memcmp.ts
CHANGED
|
@@ -92,3 +92,14 @@ export function getUserStatsIsReferredOrReferrerFilter(): MemcmpFilter {
|
|
|
92
92
|
},
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
|
+
|
|
96
|
+
export function getSignedMsgUserOrdersFilter(): MemcmpFilter {
|
|
97
|
+
return {
|
|
98
|
+
memcmp: {
|
|
99
|
+
offset: 0,
|
|
100
|
+
bytes: bs58.encode(
|
|
101
|
+
BorshAccountsCoder.accountDiscriminator('SignedMsgUserOrders')
|
|
102
|
+
),
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1413,6 +1413,12 @@ export type HighLeverageModeConfig = {
|
|
|
1413
1413
|
reduceOnly: boolean;
|
|
1414
1414
|
};
|
|
1415
1415
|
|
|
1416
|
+
export type ProtectedMakerModeConfig = {
|
|
1417
|
+
maxUsers: number;
|
|
1418
|
+
currentUsers: number;
|
|
1419
|
+
reduceOnly: boolean;
|
|
1420
|
+
};
|
|
1421
|
+
|
|
1416
1422
|
/* Represents proof of a signed msg taker order
|
|
1417
1423
|
* It can be provided to drift program to fill a signed msg order
|
|
1418
1424
|
*/
|
|
@@ -1426,3 +1432,14 @@ export interface SignedMsgOrderParams {
|
|
|
1426
1432
|
*/
|
|
1427
1433
|
signature: Buffer;
|
|
1428
1434
|
}
|
|
1435
|
+
|
|
1436
|
+
export type SignedMsgOrderId = {
|
|
1437
|
+
maxSlot: BN;
|
|
1438
|
+
uuid: Uint8Array;
|
|
1439
|
+
orderId: number;
|
|
1440
|
+
};
|
|
1441
|
+
|
|
1442
|
+
export type SignedMsgUserOrdersAccount = {
|
|
1443
|
+
authorityPubkey: PublicKey;
|
|
1444
|
+
signedMsgOrderData: SignedMsgOrderId[];
|
|
1445
|
+
};
|