@drift-labs/sdk 2.112.0-beta.1 → 2.112.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +1 -1
- package/lib/browser/decode/user.js +4 -1
- package/lib/browser/dlob/DLOB.js +18 -2
- package/lib/browser/driftClient.d.ts +3 -1
- package/lib/browser/driftClient.js +20 -13
- package/lib/browser/fastlane/fastlaneOrderSubscriber.d.ts +5 -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/idl/drift.json +9 -1
- package/lib/browser/index.d.ts +1 -0
- package/lib/browser/index.js +1 -0
- package/lib/browser/math/orders.d.ts +1 -0
- package/lib/browser/math/orders.js +6 -1
- package/lib/browser/memcmp.d.ts +1 -0
- package/lib/browser/memcmp.js +10 -1
- package/lib/browser/types.d.ts +17 -1
- package/lib/node/decode/user.js +4 -1
- package/lib/node/dlob/DLOB.js +18 -2
- package/lib/node/driftClient.d.ts +3 -1
- package/lib/node/driftClient.js +20 -13
- package/lib/node/fastlane/fastlaneOrderSubscriber.d.ts +5 -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/idl/drift.json +9 -1
- package/lib/node/index.d.ts +1 -0
- package/lib/node/index.js +1 -0
- package/lib/node/math/orders.d.ts +1 -0
- package/lib/node/math/orders.js +6 -1
- package/lib/node/memcmp.d.ts +1 -0
- package/lib/node/memcmp.js +10 -1
- package/lib/node/types.d.ts +17 -1
- package/package.json +2 -2
- package/src/decode/user.ts +4 -1
- package/src/dlob/DLOB.ts +23 -6
- package/src/driftClient.ts +22 -9
- package/src/fastlane/fastlaneOrderSubscriber.ts +5 -0
- package/src/fastlane/grpcSignedMsgUserAccountSubscriber.ts +95 -0
- package/src/fastlane/index.ts +3 -0
- package/src/fastlane/signedMsgUserAccountSubscriber.ts +234 -0
- package/src/idl/drift.json +9 -1
- package/src/index.ts +1 -0
- package/src/math/orders.ts +5 -0
- package/src/memcmp.ts +11 -0
- package/src/types.ts +23 -0
- package/tests/user/helpers.ts +1 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.112.0-beta.
|
|
1
|
+
2.112.0-beta.10
|
|
@@ -230,7 +230,9 @@ function decodeUser(buffer) {
|
|
|
230
230
|
offset += 1;
|
|
231
231
|
const postedSlotTail = buffer.readUint8(offset);
|
|
232
232
|
offset += 1;
|
|
233
|
-
|
|
233
|
+
const bitFlags = buffer.readUint8(offset);
|
|
234
|
+
offset += 1;
|
|
235
|
+
offset += 1; // padding
|
|
234
236
|
orders.push({
|
|
235
237
|
slot,
|
|
236
238
|
price,
|
|
@@ -256,6 +258,7 @@ function decodeUser(buffer) {
|
|
|
256
258
|
immediateOrCancel,
|
|
257
259
|
triggerCondition,
|
|
258
260
|
auctionDuration,
|
|
261
|
+
bitFlags,
|
|
259
262
|
postedSlotTail,
|
|
260
263
|
});
|
|
261
264
|
}
|
package/lib/browser/dlob/DLOB.js
CHANGED
|
@@ -402,7 +402,16 @@ class DLOB {
|
|
|
402
402
|
const newTakerOrder = { ...takerOrder };
|
|
403
403
|
newTakerOrder.baseAssetAmountFilled =
|
|
404
404
|
takerOrder.baseAssetAmountFilled.add(baseFilled);
|
|
405
|
-
|
|
405
|
+
if (takerNode.isSignedMsg) {
|
|
406
|
+
const marketTypeStr = (0, __1.getVariant)(marketType);
|
|
407
|
+
const orderList = (0, __1.isVariant)(takerOrder.direction, 'long')
|
|
408
|
+
? this.orderLists.get(marketTypeStr).get(marketIndex).signedMsg.bid
|
|
409
|
+
: this.orderLists.get(marketTypeStr).get(marketIndex).signedMsg.ask;
|
|
410
|
+
orderList.update(newTakerOrder, takerNode.userAccount);
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
this.getListForOnChainOrder(newTakerOrder, slot, takerNode.isProtectedMaker).update(newTakerOrder, takerNode.userAccount);
|
|
414
|
+
}
|
|
406
415
|
if (newTakerOrder.baseAssetAmountFilled.eq(takerOrder.baseAssetAmount)) {
|
|
407
416
|
break;
|
|
408
417
|
}
|
|
@@ -478,7 +487,14 @@ class DLOB {
|
|
|
478
487
|
}
|
|
479
488
|
for (const askGenerator of askGenerators) {
|
|
480
489
|
for (const ask of askGenerator) {
|
|
481
|
-
if (
|
|
490
|
+
if (ask.isSignedMsg &&
|
|
491
|
+
slot.gt(ask.order.slot.addn(ask.order.auctionDuration))) {
|
|
492
|
+
this.orderLists
|
|
493
|
+
.get(marketTypeStr)
|
|
494
|
+
.get(marketIndex)
|
|
495
|
+
.signedMsg.ask.remove(ask.order, ask.userAccount);
|
|
496
|
+
}
|
|
497
|
+
else if ((0, __1.isOrderExpired)(ask.order, ts, true, 25)) {
|
|
482
498
|
nodesToFill.push({
|
|
483
499
|
node: ask,
|
|
484
500
|
makerNodes: [],
|
|
@@ -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';
|
|
@@ -125,6 +125,7 @@ export declare class DriftClient {
|
|
|
125
125
|
/** @deprecated use fetchAllLookupTableAccounts() */
|
|
126
126
|
fetchMarketLookupTableAccount(): Promise<AddressLookupTableAccount>;
|
|
127
127
|
fetchAllLookupTableAccounts(): Promise<AddressLookupTableAccount[]>;
|
|
128
|
+
private getTxVersionForNewWallet;
|
|
128
129
|
/**
|
|
129
130
|
* Update the wallet to use for drift transactions and linked user account
|
|
130
131
|
* @param newWallet
|
|
@@ -915,6 +916,7 @@ export declare class DriftClient {
|
|
|
915
916
|
disableUserHighLeverageMode(user: PublicKey, userAccount?: UserAccount, txParams?: TxParams): Promise<TransactionSignature>;
|
|
916
917
|
getDisableHighLeverageModeIx(user: PublicKey, userAccount?: UserAccount): Promise<TransactionInstruction>;
|
|
917
918
|
fetchHighLeverageModeConfig(): Promise<HighLeverageModeConfig>;
|
|
919
|
+
fetchProtectedMakerModeConfig(): Promise<ProtectedMakerModeConfig>;
|
|
918
920
|
updateUserProtectedMakerOrders(subAccountId: number, protectedOrders: boolean, authority?: PublicKey, txParams?: TxParams): Promise<TransactionSignature>;
|
|
919
921
|
getUpdateUserProtectedMakerOrdersIx(subAccountId: number, protectedOrders: boolean, authority?: PublicKey): Promise<TransactionInstruction>;
|
|
920
922
|
getPauseSpotMarketDepositWithdrawIx(spotMarketIndex: number): Promise<TransactionInstruction>;
|
|
@@ -110,7 +110,8 @@ class DriftClient {
|
|
|
110
110
|
this.authority = (_e = config.authority) !== null && _e !== void 0 ? _e : this.wallet.publicKey;
|
|
111
111
|
this.activeSubAccountId = (_f = config.activeSubAccountId) !== null && _f !== void 0 ? _f : 0;
|
|
112
112
|
this.skipLoadUsers = (_g = config.skipLoadUsers) !== null && _g !== void 0 ? _g : false;
|
|
113
|
-
this.txVersion =
|
|
113
|
+
this.txVersion =
|
|
114
|
+
(_h = config.txVersion) !== null && _h !== void 0 ? _h : this.getTxVersionForNewWallet(config.wallet);
|
|
114
115
|
this.txParams = {
|
|
115
116
|
computeUnits: (_k = (_j = config.txParams) === null || _j === void 0 ? void 0 : _j.computeUnits) !== null && _k !== void 0 ? _k : 600000,
|
|
116
117
|
computeUnitsPrice: (_m = (_l = config.txParams) === null || _l === void 0 ? void 0 : _l.computeUnitsPrice) !== null && _m !== void 0 ? _m : 0,
|
|
@@ -395,6 +396,14 @@ class DriftClient {
|
|
|
395
396
|
this.lookupTableAccounts = lookupTableAccounts;
|
|
396
397
|
return lookupTableAccounts;
|
|
397
398
|
}
|
|
399
|
+
getTxVersionForNewWallet(newWallet) {
|
|
400
|
+
var _a, _b, _c;
|
|
401
|
+
if (!(newWallet === null || newWallet === void 0 ? void 0 : newWallet.supportedTransactionVersions))
|
|
402
|
+
return 0; // Assume versioned txs supported if wallet doesn't have a supportedTransactionVersions property
|
|
403
|
+
const walletSupportsVersionedTxns = ((_a = newWallet.supportedTransactionVersions) === null || _a === void 0 ? void 0 : _a.has(0)) ||
|
|
404
|
+
((_c = (_b = newWallet.supportedTransactionVersions) === null || _b === void 0 ? void 0 : _b.size) !== null && _c !== void 0 ? _c : 0) > 1;
|
|
405
|
+
return walletSupportsVersionedTxns ? 0 : 'legacy';
|
|
406
|
+
}
|
|
398
407
|
/**
|
|
399
408
|
* Update the wallet to use for drift transactions and linked user account
|
|
400
409
|
* @param newWallet
|
|
@@ -403,7 +412,7 @@ class DriftClient {
|
|
|
403
412
|
* @param includeDelegates
|
|
404
413
|
*/
|
|
405
414
|
async updateWallet(newWallet, subAccountIds, activeSubAccountId, includeDelegates, authoritySubaccountMap) {
|
|
406
|
-
var _a
|
|
415
|
+
var _a;
|
|
407
416
|
const newProvider = new anchor_1.AnchorProvider(this.connection,
|
|
408
417
|
// @ts-ignore
|
|
409
418
|
newWallet, this.opts);
|
|
@@ -419,10 +428,7 @@ class DriftClient {
|
|
|
419
428
|
this.activeSubAccountId = activeSubAccountId;
|
|
420
429
|
this.userStatsAccountPublicKey = undefined;
|
|
421
430
|
this.includeDelegates = includeDelegates !== null && includeDelegates !== void 0 ? includeDelegates : false;
|
|
422
|
-
|
|
423
|
-
//@ts-ignore
|
|
424
|
-
(_b = (_a = this.wallet.supportedTransactionVersions) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0 > 1;
|
|
425
|
-
this.txVersion = walletSupportsVersionedTxns ? 0 : 'legacy';
|
|
431
|
+
this.txVersion = this.getTxVersionForNewWallet(this.wallet);
|
|
426
432
|
if (includeDelegates && subAccountIds) {
|
|
427
433
|
throw new Error('Can only pass one of includeDelegates or subAccountIds. If you want to specify subaccount ids for multiple authorities, pass authoritySubaccountMap instead');
|
|
428
434
|
}
|
|
@@ -438,7 +444,7 @@ class DriftClient {
|
|
|
438
444
|
? new Map([[this.authority.toString(), subAccountIds]])
|
|
439
445
|
: new Map();
|
|
440
446
|
/* Reset user stats account */
|
|
441
|
-
if ((
|
|
447
|
+
if ((_a = this.userStats) === null || _a === void 0 ? void 0 : _a.isSubscribed) {
|
|
442
448
|
await this.userStats.unsubscribe();
|
|
443
449
|
}
|
|
444
450
|
this.userStats = undefined;
|
|
@@ -467,19 +473,16 @@ class DriftClient {
|
|
|
467
473
|
* @param emulateAuthority
|
|
468
474
|
*/
|
|
469
475
|
async emulateAccount(emulateAuthority) {
|
|
470
|
-
var _a
|
|
476
|
+
var _a;
|
|
471
477
|
this.skipLoadUsers = false;
|
|
472
478
|
// Update provider for txSender with new wallet details
|
|
473
479
|
this.authority = emulateAuthority;
|
|
474
480
|
this.userStatsAccountPublicKey = undefined;
|
|
475
481
|
this.includeDelegates = true;
|
|
476
|
-
|
|
477
|
-
//@ts-ignore
|
|
478
|
-
(_b = (_a = this.wallet.supportedTransactionVersions) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0 > 1;
|
|
479
|
-
this.txVersion = walletSupportsVersionedTxns ? 0 : 'legacy';
|
|
482
|
+
this.txVersion = this.getTxVersionForNewWallet(this.wallet);
|
|
480
483
|
this.authoritySubAccountMap = new Map();
|
|
481
484
|
/* Reset user stats account */
|
|
482
|
-
if ((
|
|
485
|
+
if ((_a = this.userStats) === null || _a === void 0 ? void 0 : _a.isSubscribed) {
|
|
483
486
|
await this.userStats.unsubscribe();
|
|
484
487
|
}
|
|
485
488
|
this.userStats = undefined;
|
|
@@ -4898,6 +4901,10 @@ class DriftClient {
|
|
|
4898
4901
|
const config = await this.program.account.highLeverageModeConfig.fetch((0, pda_1.getHighLeverageModeConfigPublicKey)(this.program.programId));
|
|
4899
4902
|
return config;
|
|
4900
4903
|
}
|
|
4904
|
+
async fetchProtectedMakerModeConfig() {
|
|
4905
|
+
const config = await this.program.account.protectedMakerModeConfig.fetch((0, pda_1.getProtectedMakerModeConfigPublicKey)(this.program.programId));
|
|
4906
|
+
return config;
|
|
4907
|
+
}
|
|
4901
4908
|
async updateUserProtectedMakerOrders(subAccountId, protectedOrders, authority, txParams) {
|
|
4902
4909
|
const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getUpdateUserProtectedMakerOrdersIx(subAccountId, protectedOrders, authority), txParams), [], this.opts);
|
|
4903
4910
|
return txSig;
|
|
@@ -6,6 +6,11 @@ export type FastlaneOrderSubscriberConfig = {
|
|
|
6
6
|
driftEnv: DriftEnv;
|
|
7
7
|
endpoint?: string;
|
|
8
8
|
marketIndexes: number[];
|
|
9
|
+
/**
|
|
10
|
+
In the future, this will be used for verifying $DRIFT stake as we add
|
|
11
|
+
authentication for delegate signers
|
|
12
|
+
For now, pass a new keypair or a keypair to an empty wallet
|
|
13
|
+
*/
|
|
9
14
|
keypair: Keypair;
|
|
10
15
|
};
|
|
11
16
|
export declare class FastlaneOrderSubscriber {
|
|
@@ -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;
|
|
@@ -10912,12 +10912,20 @@
|
|
|
10912
10912
|
],
|
|
10913
10913
|
"type": "u8"
|
|
10914
10914
|
},
|
|
10915
|
+
{
|
|
10916
|
+
"name": "bitFlags",
|
|
10917
|
+
"docs": [
|
|
10918
|
+
"Bitflags for further classification",
|
|
10919
|
+
"0: is_signed_message"
|
|
10920
|
+
],
|
|
10921
|
+
"type": "u8"
|
|
10922
|
+
},
|
|
10915
10923
|
{
|
|
10916
10924
|
"name": "padding",
|
|
10917
10925
|
"type": {
|
|
10918
10926
|
"array": [
|
|
10919
10927
|
"u8",
|
|
10920
|
-
|
|
10928
|
+
1
|
|
10921
10929
|
]
|
|
10922
10930
|
}
|
|
10923
10931
|
}
|
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);
|
|
@@ -21,3 +21,4 @@ export declare function mustBeTriggered(order: Order): boolean;
|
|
|
21
21
|
export declare function isTriggered(order: Order): boolean;
|
|
22
22
|
export declare function isRestingLimitOrder(order: Order, slot: number): boolean;
|
|
23
23
|
export declare function isTakingOrder(order: Order, slot: number): boolean;
|
|
24
|
+
export declare function isSignedMsgOrder(order: Order): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isTakingOrder = exports.isRestingLimitOrder = exports.isTriggered = exports.mustBeTriggered = exports.isLimitOrder = exports.isMarketOrder = exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.hasAuctionPrice = exports.hasLimitPrice = exports.getLimitPrice = exports.standardizePrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
3
|
+
exports.isSignedMsgOrder = exports.isTakingOrder = exports.isRestingLimitOrder = exports.isTriggered = exports.mustBeTriggered = exports.isLimitOrder = exports.isMarketOrder = exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.hasAuctionPrice = exports.hasLimitPrice = exports.getLimitPrice = exports.standardizePrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
@@ -223,3 +223,8 @@ function isTakingOrder(order, slot) {
|
|
|
223
223
|
return isMarketOrder(order) || !isRestingLimitOrder(order, slot);
|
|
224
224
|
}
|
|
225
225
|
exports.isTakingOrder = isTakingOrder;
|
|
226
|
+
const FLAG_IS_SIGNED_MSG = 0x01;
|
|
227
|
+
function isSignedMsgOrder(order) {
|
|
228
|
+
return (order.bitFlags & FLAG_IS_SIGNED_MSG) !== 0;
|
|
229
|
+
}
|
|
230
|
+
exports.isSignedMsgOrder = isSignedMsgOrder;
|
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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
/// <reference types="node" />
|
|
4
|
-
import { Keypair, PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js';
|
|
4
|
+
import { Keypair, PublicKey, Transaction, TransactionVersion, VersionedTransaction } from '@solana/web3.js';
|
|
5
5
|
import { BN } from '.';
|
|
6
6
|
export type MappedRecord<A extends Record<string, unknown>, B> = {
|
|
7
7
|
[K in keyof A]: B;
|
|
@@ -1142,6 +1142,7 @@ export type Order = {
|
|
|
1142
1142
|
auctionStartPrice: BN;
|
|
1143
1143
|
auctionEndPrice: BN;
|
|
1144
1144
|
maxTs: BN;
|
|
1145
|
+
bitFlags: number;
|
|
1145
1146
|
postedSlotTail: number;
|
|
1146
1147
|
};
|
|
1147
1148
|
export type OrderParams = {
|
|
@@ -1261,6 +1262,7 @@ export interface IWallet {
|
|
|
1261
1262
|
signAllTransactions(txs: Transaction[]): Promise<Transaction[]>;
|
|
1262
1263
|
publicKey: PublicKey;
|
|
1263
1264
|
payer?: Keypair;
|
|
1265
|
+
supportedTransactionVersions?: ReadonlySet<TransactionVersion> | null | undefined;
|
|
1264
1266
|
}
|
|
1265
1267
|
export interface IVersionedWallet {
|
|
1266
1268
|
signVersionedTransaction(tx: VersionedTransaction): Promise<VersionedTransaction>;
|
|
@@ -1417,6 +1419,11 @@ export type HighLeverageModeConfig = {
|
|
|
1417
1419
|
currentUsers: number;
|
|
1418
1420
|
reduceOnly: boolean;
|
|
1419
1421
|
};
|
|
1422
|
+
export type ProtectedMakerModeConfig = {
|
|
1423
|
+
maxUsers: number;
|
|
1424
|
+
currentUsers: number;
|
|
1425
|
+
reduceOnly: boolean;
|
|
1426
|
+
};
|
|
1420
1427
|
export interface SignedMsgOrderParams {
|
|
1421
1428
|
/**
|
|
1422
1429
|
* The encoded order params that were signed (borsh encoded then hexified).
|
|
@@ -1427,4 +1434,13 @@ export interface SignedMsgOrderParams {
|
|
|
1427
1434
|
*/
|
|
1428
1435
|
signature: Buffer;
|
|
1429
1436
|
}
|
|
1437
|
+
export type SignedMsgOrderId = {
|
|
1438
|
+
maxSlot: BN;
|
|
1439
|
+
uuid: Uint8Array;
|
|
1440
|
+
orderId: number;
|
|
1441
|
+
};
|
|
1442
|
+
export type SignedMsgUserOrdersAccount = {
|
|
1443
|
+
authorityPubkey: PublicKey;
|
|
1444
|
+
signedMsgOrderData: SignedMsgOrderId[];
|
|
1445
|
+
};
|
|
1430
1446
|
export {};
|
package/lib/node/decode/user.js
CHANGED
|
@@ -230,7 +230,9 @@ function decodeUser(buffer) {
|
|
|
230
230
|
offset += 1;
|
|
231
231
|
const postedSlotTail = buffer.readUint8(offset);
|
|
232
232
|
offset += 1;
|
|
233
|
-
|
|
233
|
+
const bitFlags = buffer.readUint8(offset);
|
|
234
|
+
offset += 1;
|
|
235
|
+
offset += 1; // padding
|
|
234
236
|
orders.push({
|
|
235
237
|
slot,
|
|
236
238
|
price,
|
|
@@ -256,6 +258,7 @@ function decodeUser(buffer) {
|
|
|
256
258
|
immediateOrCancel,
|
|
257
259
|
triggerCondition,
|
|
258
260
|
auctionDuration,
|
|
261
|
+
bitFlags,
|
|
259
262
|
postedSlotTail,
|
|
260
263
|
});
|
|
261
264
|
}
|