@drift-labs/sdk 2.98.0-beta.9 → 2.99.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +1 -1
- package/lib/browser/accounts/pollingHighLeverageModeConfigAccountSubscriber.d.ts +29 -0
- package/lib/browser/accounts/pollingHighLeverageModeConfigAccountSubscriber.js +111 -0
- package/lib/browser/accounts/types.d.ts +14 -1
- package/lib/browser/accounts/webSocketHighLeverageModeConfigAccountSubscriber.d.ts +23 -0
- package/lib/browser/accounts/webSocketHighLeverageModeConfigAccountSubscriber.js +69 -0
- package/lib/browser/addresses/pda.d.ts +1 -0
- package/lib/browser/addresses/pda.js +8 -1
- package/lib/browser/constants/perpMarkets.js +11 -0
- package/lib/browser/constants/spotMarkets.js +2 -2
- package/lib/browser/driftClient.d.ts +14 -4
- package/lib/browser/driftClient.js +64 -19
- package/lib/browser/idl/drift.json +199 -8
- package/lib/browser/index.d.ts +4 -0
- package/lib/browser/index.js +4 -0
- package/lib/browser/jupiter/jupiterClient.d.ts +6 -0
- package/lib/browser/memcmp.d.ts +3 -0
- package/lib/browser/memcmp.js +28 -1
- package/lib/browser/slot/SlothashSubscriber.d.ts +26 -0
- package/lib/browser/slot/SlothashSubscriber.js +85 -0
- package/lib/browser/types.d.ts +4 -3
- package/lib/browser/user.js +3 -0
- package/lib/browser/userMap/referrerMap.d.ts +45 -0
- package/lib/browser/userMap/referrerMap.js +180 -0
- package/lib/browser/util/digest.d.ts +1 -0
- package/lib/browser/util/digest.js +5 -1
- package/lib/node/accounts/pollingHighLeverageModeConfigAccountSubscriber.d.ts +29 -0
- package/lib/node/accounts/pollingHighLeverageModeConfigAccountSubscriber.js +111 -0
- package/lib/node/accounts/types.d.ts +14 -1
- package/lib/node/accounts/webSocketHighLeverageModeConfigAccountSubscriber.d.ts +23 -0
- package/lib/node/accounts/webSocketHighLeverageModeConfigAccountSubscriber.js +69 -0
- package/lib/node/addresses/pda.d.ts +1 -0
- package/lib/node/addresses/pda.js +8 -1
- package/lib/node/constants/perpMarkets.js +11 -0
- package/lib/node/constants/spotMarkets.js +2 -2
- package/lib/node/driftClient.d.ts +14 -4
- package/lib/node/driftClient.js +64 -19
- package/lib/node/idl/drift.json +199 -8
- package/lib/node/index.d.ts +4 -0
- package/lib/node/index.js +4 -0
- package/lib/node/jupiter/jupiterClient.d.ts +6 -0
- package/lib/node/memcmp.d.ts +3 -0
- package/lib/node/memcmp.js +28 -1
- package/lib/node/slot/SlothashSubscriber.d.ts +26 -0
- package/lib/node/slot/SlothashSubscriber.js +85 -0
- package/lib/node/types.d.ts +4 -3
- package/lib/node/user.js +3 -0
- package/lib/node/userMap/referrerMap.d.ts +45 -0
- package/lib/node/userMap/referrerMap.js +180 -0
- package/lib/node/util/digest.d.ts +1 -0
- package/lib/node/util/digest.js +5 -1
- package/package.json +1 -1
- package/src/accounts/pollingHighLeverageModeConfigAccountSubscriber.ts +189 -0
- package/src/accounts/types.ts +25 -1
- package/src/accounts/webSocketHighLeverageModeConfigAccountSubscriber.ts +131 -0
- package/src/addresses/pda.ts +13 -0
- package/src/constants/perpMarkets.ts +12 -0
- package/src/constants/spotMarkets.ts +2 -2
- package/src/driftClient.ts +129 -36
- package/src/idl/drift.json +226 -9
- package/src/index.ts +4 -0
- package/src/jupiter/jupiterClient.ts +6 -0
- package/src/memcmp.ts +27 -0
- package/src/slot/SlothashSubscriber.ts +126 -0
- package/src/types.ts +4 -3
- package/src/user.ts +4 -0
- package/src/userMap/referrerMap.ts +283 -0
- package/src/util/digest.ts +4 -0
- package/tests/ci/verifyConstants.ts +16 -2
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReferrerMap = void 0;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const bulkAccountLoader_1 = require("../accounts/bulkAccountLoader");
|
|
6
|
+
const pda_1 = require("../addresses/pda");
|
|
7
|
+
const memcmp_1 = require("../memcmp");
|
|
8
|
+
const bytes_1 = require("@coral-xyz/anchor/dist/cjs/utils/bytes");
|
|
9
|
+
const DEFAULT_PUBLIC_KEY = web3_js_1.PublicKey.default.toBase58();
|
|
10
|
+
class ReferrerMap {
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new UserStatsMap instance.
|
|
13
|
+
*
|
|
14
|
+
* @param {DriftClient} driftClient - The DriftClient instance.
|
|
15
|
+
* @param {BulkAccountLoader} [bulkAccountLoader] - If not provided, a new BulkAccountLoader with polling disabled will be created.
|
|
16
|
+
*/
|
|
17
|
+
constructor(driftClient, bulkAccountLoader, parallelSync) {
|
|
18
|
+
/**
|
|
19
|
+
* map from authority pubkey to ReferrerInfo.
|
|
20
|
+
* - if a user has not been entered into the map, the value is undefined
|
|
21
|
+
* - if a user has no referrer, the value is null
|
|
22
|
+
* - if a user has a referrer, the value is a ReferrerInfo object
|
|
23
|
+
*/
|
|
24
|
+
this.referrerMap = new Map();
|
|
25
|
+
this.driftClient = driftClient;
|
|
26
|
+
if (!bulkAccountLoader) {
|
|
27
|
+
bulkAccountLoader = new bulkAccountLoader_1.BulkAccountLoader(driftClient.connection, driftClient.opts.commitment, 0);
|
|
28
|
+
}
|
|
29
|
+
this.bulkAccountLoader = bulkAccountLoader;
|
|
30
|
+
this.parallelSync = parallelSync !== undefined ? parallelSync : true;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Subscribe to all UserStats accounts.
|
|
34
|
+
*/
|
|
35
|
+
async subscribe() {
|
|
36
|
+
if (this.size() > 0) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
await this.driftClient.subscribe();
|
|
40
|
+
await this.sync();
|
|
41
|
+
}
|
|
42
|
+
has(authorityPublicKey) {
|
|
43
|
+
return this.referrerMap.has(authorityPublicKey);
|
|
44
|
+
}
|
|
45
|
+
get(authorityPublicKey) {
|
|
46
|
+
const info = this.referrerMap.get(authorityPublicKey);
|
|
47
|
+
return info === null ? undefined : info;
|
|
48
|
+
}
|
|
49
|
+
async addReferrerInfo(authority, referrerInfo) {
|
|
50
|
+
if (referrerInfo || referrerInfo === null) {
|
|
51
|
+
this.referrerMap.set(authority, referrerInfo);
|
|
52
|
+
}
|
|
53
|
+
else if (referrerInfo === undefined) {
|
|
54
|
+
const userStatsAccountPublicKey = (0, pda_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, new web3_js_1.PublicKey(authority));
|
|
55
|
+
const buffer = (await this.driftClient.connection.getAccountInfo(userStatsAccountPublicKey, 'processed')).data;
|
|
56
|
+
const referrer = bytes_1.bs58.encode(buffer.subarray(40, 72));
|
|
57
|
+
const referrerKey = new web3_js_1.PublicKey(referrer);
|
|
58
|
+
this.addReferrerInfo(authority, referrer === DEFAULT_PUBLIC_KEY
|
|
59
|
+
? null
|
|
60
|
+
: {
|
|
61
|
+
referrer: (0, pda_1.getUserAccountPublicKeySync)(this.driftClient.program.programId, referrerKey, 0),
|
|
62
|
+
referrerStats: (0, pda_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, referrerKey),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Enforce that a UserStats will exist for the given authorityPublicKey,
|
|
68
|
+
* reading one from the blockchain if necessary.
|
|
69
|
+
* @param authorityPublicKey
|
|
70
|
+
* @returns
|
|
71
|
+
*/
|
|
72
|
+
async mustGet(authorityPublicKey) {
|
|
73
|
+
if (!this.has(authorityPublicKey)) {
|
|
74
|
+
await this.addReferrerInfo(authorityPublicKey);
|
|
75
|
+
}
|
|
76
|
+
return this.get(authorityPublicKey);
|
|
77
|
+
}
|
|
78
|
+
values() {
|
|
79
|
+
return this.referrerMap.values();
|
|
80
|
+
}
|
|
81
|
+
size() {
|
|
82
|
+
return this.referrerMap.size;
|
|
83
|
+
}
|
|
84
|
+
async sync() {
|
|
85
|
+
if (this.fetchPromise) {
|
|
86
|
+
return this.fetchPromise;
|
|
87
|
+
}
|
|
88
|
+
this.fetchPromise = new Promise((resolver) => {
|
|
89
|
+
this.fetchPromiseResolver = resolver;
|
|
90
|
+
});
|
|
91
|
+
try {
|
|
92
|
+
if (this.parallelSync) {
|
|
93
|
+
await Promise.all([
|
|
94
|
+
this.syncAll(),
|
|
95
|
+
this.syncReferrer((0, memcmp_1.getUserStatsIsReferredFilter)()),
|
|
96
|
+
this.syncReferrer((0, memcmp_1.getUserStatsIsReferredOrReferrerFilter)()),
|
|
97
|
+
]);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
await this.syncAll();
|
|
101
|
+
await this.syncReferrer((0, memcmp_1.getUserStatsIsReferredFilter)());
|
|
102
|
+
await this.syncReferrer((0, memcmp_1.getUserStatsIsReferredOrReferrerFilter)());
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
console.error('error in referrerMap.sync', e);
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
this.fetchPromiseResolver();
|
|
110
|
+
this.fetchPromise = undefined;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async syncAll() {
|
|
114
|
+
const rpcRequestArgs = [
|
|
115
|
+
this.driftClient.program.programId.toBase58(),
|
|
116
|
+
{
|
|
117
|
+
commitment: this.driftClient.opts.commitment,
|
|
118
|
+
filters: [(0, memcmp_1.getUserStatsFilter)()],
|
|
119
|
+
encoding: 'base64',
|
|
120
|
+
dataSlice: {
|
|
121
|
+
offset: 0,
|
|
122
|
+
length: 0,
|
|
123
|
+
},
|
|
124
|
+
withContext: true,
|
|
125
|
+
},
|
|
126
|
+
];
|
|
127
|
+
const rpcJSONResponse =
|
|
128
|
+
// @ts-ignore
|
|
129
|
+
await this.driftClient.connection._rpcRequest('getProgramAccounts', rpcRequestArgs);
|
|
130
|
+
const rpcResponseAndContext = rpcJSONResponse.result;
|
|
131
|
+
for (const account of rpcResponseAndContext.value) {
|
|
132
|
+
// only add if it isn't already in the map
|
|
133
|
+
// so that if syncReferrer already set it, we dont overwrite
|
|
134
|
+
if (!this.has(account.pubkey)) {
|
|
135
|
+
this.addReferrerInfo(account.pubkey, null);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async syncReferrer(referrerFilter) {
|
|
140
|
+
const rpcRequestArgs = [
|
|
141
|
+
this.driftClient.program.programId.toBase58(),
|
|
142
|
+
{
|
|
143
|
+
commitment: this.driftClient.opts.commitment,
|
|
144
|
+
filters: [(0, memcmp_1.getUserStatsFilter)(), referrerFilter],
|
|
145
|
+
encoding: 'base64',
|
|
146
|
+
dataSlice: {
|
|
147
|
+
offset: 0,
|
|
148
|
+
length: 72,
|
|
149
|
+
},
|
|
150
|
+
withContext: true,
|
|
151
|
+
},
|
|
152
|
+
];
|
|
153
|
+
const rpcJSONResponse =
|
|
154
|
+
// @ts-ignore
|
|
155
|
+
await this.driftClient.connection._rpcRequest('getProgramAccounts', rpcRequestArgs);
|
|
156
|
+
const rpcResponseAndContext = rpcJSONResponse.result;
|
|
157
|
+
const batchSize = 1000;
|
|
158
|
+
for (let i = 0; i < rpcResponseAndContext.value.length; i += batchSize) {
|
|
159
|
+
const batch = rpcResponseAndContext.value.slice(i, i + batchSize);
|
|
160
|
+
await Promise.all(batch.map(async (programAccount) => {
|
|
161
|
+
// @ts-ignore
|
|
162
|
+
const buffer = Buffer.from(programAccount.account.data[0], programAccount.account.data[1]);
|
|
163
|
+
const authority = bytes_1.bs58.encode(buffer.subarray(8, 40));
|
|
164
|
+
const referrer = bytes_1.bs58.encode(buffer.subarray(40, 72));
|
|
165
|
+
const referrerKey = new web3_js_1.PublicKey(referrer);
|
|
166
|
+
this.addReferrerInfo(authority, referrer === DEFAULT_PUBLIC_KEY
|
|
167
|
+
? null
|
|
168
|
+
: {
|
|
169
|
+
referrer: (0, pda_1.getUserAccountPublicKeySync)(this.driftClient.program.programId, referrerKey, 0),
|
|
170
|
+
referrerStats: (0, pda_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, referrerKey),
|
|
171
|
+
});
|
|
172
|
+
}));
|
|
173
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async unsubscribe() {
|
|
177
|
+
this.referrerMap.clear();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
exports.ReferrerMap = ReferrerMap;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.digest = void 0;
|
|
3
|
+
exports.digestSignature = exports.digest = void 0;
|
|
4
4
|
const crypto_1 = require("crypto");
|
|
5
5
|
function digest(data) {
|
|
6
6
|
const hash = (0, crypto_1.createHash)('sha256');
|
|
@@ -8,3 +8,7 @@ function digest(data) {
|
|
|
8
8
|
return hash.digest();
|
|
9
9
|
}
|
|
10
10
|
exports.digest = digest;
|
|
11
|
+
function digestSignature(signature) {
|
|
12
|
+
return (0, crypto_1.createHash)('sha256').update(signature).digest('base64');
|
|
13
|
+
}
|
|
14
|
+
exports.digestSignature = digestSignature;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { DataAndSlot, HighLeverageModeConfigAccountEvents, HighLeverageModeConfigAccountSubscriber } from './types';
|
|
3
|
+
import { Program } from '@coral-xyz/anchor';
|
|
4
|
+
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
import { PublicKey } from '@solana/web3.js';
|
|
7
|
+
import { BulkAccountLoader } from './bulkAccountLoader';
|
|
8
|
+
import { HighLeverageModeConfig } from '../types';
|
|
9
|
+
export declare class PollingHighLeverageModeConfigAccountSubscriber implements HighLeverageModeConfigAccountSubscriber {
|
|
10
|
+
isSubscribed: boolean;
|
|
11
|
+
program: Program;
|
|
12
|
+
eventEmitter: StrictEventEmitter<EventEmitter, HighLeverageModeConfigAccountEvents>;
|
|
13
|
+
highLeverageModeConfigAccountPublicKey: PublicKey;
|
|
14
|
+
accountLoader: BulkAccountLoader;
|
|
15
|
+
callbackId?: string;
|
|
16
|
+
errorCallbackId?: string;
|
|
17
|
+
highLeverageModeConfigAccountAndSlot?: DataAndSlot<HighLeverageModeConfig>;
|
|
18
|
+
constructor(program: Program, publicKey: PublicKey, accountLoader: BulkAccountLoader);
|
|
19
|
+
subscribe(highLeverageModeConfig?: HighLeverageModeConfig): Promise<boolean>;
|
|
20
|
+
addToAccountLoader(): Promise<void>;
|
|
21
|
+
fetchIfUnloaded(): Promise<void>;
|
|
22
|
+
fetch(): Promise<void>;
|
|
23
|
+
doesAccountExist(): boolean;
|
|
24
|
+
unsubscribe(): Promise<void>;
|
|
25
|
+
assertIsSubscribed(): void;
|
|
26
|
+
getHighLeverageModeConfigAccountAndSlot(): DataAndSlot<HighLeverageModeConfig>;
|
|
27
|
+
didSubscriptionSucceed(): boolean;
|
|
28
|
+
updateData(highLeverageModeConfig: HighLeverageModeConfig, slot: number): void;
|
|
29
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PollingHighLeverageModeConfigAccountSubscriber = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
const events_1 = require("events");
|
|
6
|
+
class PollingHighLeverageModeConfigAccountSubscriber {
|
|
7
|
+
constructor(program, publicKey, accountLoader) {
|
|
8
|
+
this.isSubscribed = false;
|
|
9
|
+
this.program = program;
|
|
10
|
+
this.highLeverageModeConfigAccountPublicKey = publicKey;
|
|
11
|
+
this.accountLoader = accountLoader;
|
|
12
|
+
this.eventEmitter = new events_1.EventEmitter();
|
|
13
|
+
}
|
|
14
|
+
async subscribe(highLeverageModeConfig) {
|
|
15
|
+
if (this.isSubscribed) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
if (highLeverageModeConfig) {
|
|
19
|
+
this.highLeverageModeConfigAccountAndSlot = {
|
|
20
|
+
data: highLeverageModeConfig,
|
|
21
|
+
slot: undefined,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
await this.addToAccountLoader();
|
|
25
|
+
await this.fetchIfUnloaded();
|
|
26
|
+
if (this.doesAccountExist()) {
|
|
27
|
+
this.eventEmitter.emit('update');
|
|
28
|
+
}
|
|
29
|
+
this.isSubscribed = true;
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
async addToAccountLoader() {
|
|
33
|
+
if (this.callbackId) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
this.callbackId = await this.accountLoader.addAccount(this.highLeverageModeConfigAccountPublicKey, (buffer, slot) => {
|
|
37
|
+
if (!buffer) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (this.highLeverageModeConfigAccountAndSlot &&
|
|
41
|
+
this.highLeverageModeConfigAccountAndSlot.slot > slot) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const account = this.program.account.user.coder.accounts.decode('HighLeverageModeConfig', buffer);
|
|
45
|
+
this.highLeverageModeConfigAccountAndSlot = { data: account, slot };
|
|
46
|
+
this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', account);
|
|
47
|
+
this.eventEmitter.emit('update');
|
|
48
|
+
});
|
|
49
|
+
this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
|
|
50
|
+
this.eventEmitter.emit('error', error);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async fetchIfUnloaded() {
|
|
54
|
+
if (this.highLeverageModeConfigAccountAndSlot === undefined) {
|
|
55
|
+
await this.fetch();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async fetch() {
|
|
59
|
+
var _a, _b;
|
|
60
|
+
try {
|
|
61
|
+
const dataAndContext = await this.program.account.highLeverageModeConfig.fetchAndContext(this.highLeverageModeConfigAccountPublicKey, this.accountLoader.commitment);
|
|
62
|
+
if (dataAndContext.context.slot >
|
|
63
|
+
((_b = (_a = this.highLeverageModeConfigAccountAndSlot) === null || _a === void 0 ? void 0 : _a.slot) !== null && _b !== void 0 ? _b : 0)) {
|
|
64
|
+
this.highLeverageModeConfigAccountAndSlot = {
|
|
65
|
+
data: dataAndContext.data,
|
|
66
|
+
slot: dataAndContext.context.slot,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
console.log(`PollingHighLeverageModeConfigAccountSubscriber.fetch() HighLeverageModeConfig does not exist: ${e.message}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
doesAccountExist() {
|
|
75
|
+
return this.highLeverageModeConfigAccountAndSlot !== undefined;
|
|
76
|
+
}
|
|
77
|
+
async unsubscribe() {
|
|
78
|
+
if (!this.isSubscribed) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
this.accountLoader.removeAccount(this.highLeverageModeConfigAccountPublicKey, this.callbackId);
|
|
82
|
+
this.callbackId = undefined;
|
|
83
|
+
this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
|
|
84
|
+
this.errorCallbackId = undefined;
|
|
85
|
+
this.isSubscribed = false;
|
|
86
|
+
}
|
|
87
|
+
assertIsSubscribed() {
|
|
88
|
+
if (!this.isSubscribed) {
|
|
89
|
+
throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
getHighLeverageModeConfigAccountAndSlot() {
|
|
93
|
+
this.assertIsSubscribed();
|
|
94
|
+
return this.highLeverageModeConfigAccountAndSlot;
|
|
95
|
+
}
|
|
96
|
+
didSubscriptionSucceed() {
|
|
97
|
+
return !!this.highLeverageModeConfigAccountAndSlot;
|
|
98
|
+
}
|
|
99
|
+
updateData(highLeverageModeConfig, slot) {
|
|
100
|
+
if (!this.highLeverageModeConfigAccountAndSlot ||
|
|
101
|
+
this.highLeverageModeConfigAccountAndSlot.slot < slot) {
|
|
102
|
+
this.highLeverageModeConfigAccountAndSlot = {
|
|
103
|
+
data: highLeverageModeConfig,
|
|
104
|
+
slot,
|
|
105
|
+
};
|
|
106
|
+
this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', highLeverageModeConfig);
|
|
107
|
+
this.eventEmitter.emit('update');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
exports.PollingHighLeverageModeConfigAccountSubscriber = PollingHighLeverageModeConfigAccountSubscriber;
|
|
@@ -6,7 +6,7 @@ import StrictEventEmitter from 'strict-event-emitter-types';
|
|
|
6
6
|
import { EventEmitter } from 'events';
|
|
7
7
|
import { Context, PublicKey } from '@solana/web3.js';
|
|
8
8
|
import { Account } from '@solana/spl-token';
|
|
9
|
-
import { OracleInfo, OraclePriceData } from '..';
|
|
9
|
+
import { HighLeverageModeConfig, OracleInfo, OraclePriceData } from '..';
|
|
10
10
|
import { ChannelOptions, CommitmentLevel } from '../isomorphic/grpc';
|
|
11
11
|
export interface AccountSubscriber<T> {
|
|
12
12
|
dataAndSlot?: DataAndSlot<T>;
|
|
@@ -153,3 +153,16 @@ export type GrpcConfigs = {
|
|
|
153
153
|
commitmentLevel?: CommitmentLevel;
|
|
154
154
|
channelOptions?: ChannelOptions;
|
|
155
155
|
};
|
|
156
|
+
export interface HighLeverageModeConfigAccountSubscriber {
|
|
157
|
+
eventEmitter: StrictEventEmitter<EventEmitter, HighLeverageModeConfigAccountEvents>;
|
|
158
|
+
isSubscribed: boolean;
|
|
159
|
+
subscribe(highLeverageModeConfigAccount?: HighLeverageModeConfig): Promise<boolean>;
|
|
160
|
+
fetch(): Promise<void>;
|
|
161
|
+
unsubscribe(): Promise<void>;
|
|
162
|
+
getHighLeverageModeConfigAccountAndSlot(): DataAndSlot<HighLeverageModeConfig>;
|
|
163
|
+
}
|
|
164
|
+
export interface HighLeverageModeConfigAccountEvents {
|
|
165
|
+
highLeverageModeConfigAccountUpdate: (payload: HighLeverageModeConfig) => void;
|
|
166
|
+
update: void;
|
|
167
|
+
error: (e: Error) => void;
|
|
168
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { DataAndSlot, AccountSubscriber, HighLeverageModeConfigAccountEvents, HighLeverageModeConfigAccountSubscriber } from './types';
|
|
3
|
+
import { Program } from '@coral-xyz/anchor';
|
|
4
|
+
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
import { Commitment, PublicKey } from '@solana/web3.js';
|
|
7
|
+
import { HighLeverageModeConfig } from '../types';
|
|
8
|
+
export declare class WebSocketHighLeverageModeConfigAccountSubscriber implements HighLeverageModeConfigAccountSubscriber {
|
|
9
|
+
isSubscribed: boolean;
|
|
10
|
+
resubTimeoutMs?: number;
|
|
11
|
+
commitment?: Commitment;
|
|
12
|
+
program: Program;
|
|
13
|
+
eventEmitter: StrictEventEmitter<EventEmitter, HighLeverageModeConfigAccountEvents>;
|
|
14
|
+
highLeverageModeConfigAccountPublicKey: PublicKey;
|
|
15
|
+
highLeverageModeConfigDataAccountSubscriber: AccountSubscriber<HighLeverageModeConfig>;
|
|
16
|
+
constructor(program: Program, highLeverageModeConfigAccountPublicKey: PublicKey, resubTimeoutMs?: number, commitment?: Commitment);
|
|
17
|
+
subscribe(highLeverageModeConfigAccount?: HighLeverageModeConfig): Promise<boolean>;
|
|
18
|
+
fetch(): Promise<void>;
|
|
19
|
+
unsubscribe(): Promise<void>;
|
|
20
|
+
assertIsSubscribed(): void;
|
|
21
|
+
getHighLeverageModeConfigAccountAndSlot(): DataAndSlot<HighLeverageModeConfig>;
|
|
22
|
+
updateData(highLeverageModeConfig: HighLeverageModeConfig, slot: number): void;
|
|
23
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebSocketHighLeverageModeConfigAccountSubscriber = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
const events_1 = require("events");
|
|
6
|
+
const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
|
|
7
|
+
class WebSocketHighLeverageModeConfigAccountSubscriber {
|
|
8
|
+
constructor(program, highLeverageModeConfigAccountPublicKey, resubTimeoutMs, commitment) {
|
|
9
|
+
this.isSubscribed = false;
|
|
10
|
+
this.program = program;
|
|
11
|
+
this.highLeverageModeConfigAccountPublicKey =
|
|
12
|
+
highLeverageModeConfigAccountPublicKey;
|
|
13
|
+
this.eventEmitter = new events_1.EventEmitter();
|
|
14
|
+
this.resubTimeoutMs = resubTimeoutMs;
|
|
15
|
+
this.commitment = commitment;
|
|
16
|
+
}
|
|
17
|
+
async subscribe(highLeverageModeConfigAccount) {
|
|
18
|
+
if (this.isSubscribed) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
this.highLeverageModeConfigDataAccountSubscriber =
|
|
22
|
+
new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('highLeverageModeConfig', this.program, this.highLeverageModeConfigAccountPublicKey, undefined, {
|
|
23
|
+
resubTimeoutMs: this.resubTimeoutMs,
|
|
24
|
+
}, this.commitment);
|
|
25
|
+
if (highLeverageModeConfigAccount) {
|
|
26
|
+
this.highLeverageModeConfigDataAccountSubscriber.setData(highLeverageModeConfigAccount);
|
|
27
|
+
}
|
|
28
|
+
await this.highLeverageModeConfigDataAccountSubscriber.subscribe((data) => {
|
|
29
|
+
this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', data);
|
|
30
|
+
this.eventEmitter.emit('update');
|
|
31
|
+
});
|
|
32
|
+
this.eventEmitter.emit('update');
|
|
33
|
+
this.isSubscribed = true;
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
async fetch() {
|
|
37
|
+
await Promise.all([
|
|
38
|
+
this.highLeverageModeConfigDataAccountSubscriber.fetch(),
|
|
39
|
+
]);
|
|
40
|
+
}
|
|
41
|
+
async unsubscribe() {
|
|
42
|
+
if (!this.isSubscribed) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
await Promise.all([
|
|
46
|
+
this.highLeverageModeConfigDataAccountSubscriber.unsubscribe(),
|
|
47
|
+
]);
|
|
48
|
+
this.isSubscribed = false;
|
|
49
|
+
}
|
|
50
|
+
assertIsSubscribed() {
|
|
51
|
+
if (!this.isSubscribed) {
|
|
52
|
+
throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
getHighLeverageModeConfigAccountAndSlot() {
|
|
56
|
+
this.assertIsSubscribed();
|
|
57
|
+
return this.highLeverageModeConfigDataAccountSubscriber.dataAndSlot;
|
|
58
|
+
}
|
|
59
|
+
updateData(highLeverageModeConfig, slot) {
|
|
60
|
+
var _a;
|
|
61
|
+
const currentDataSlot = ((_a = this.highLeverageModeConfigDataAccountSubscriber.dataAndSlot) === null || _a === void 0 ? void 0 : _a.slot) || 0;
|
|
62
|
+
if (currentDataSlot <= slot) {
|
|
63
|
+
this.highLeverageModeConfigDataAccountSubscriber.setData(highLeverageModeConfig, slot);
|
|
64
|
+
this.eventEmitter.emit('highLeverageModeConfigAccountUpdate', highLeverageModeConfig);
|
|
65
|
+
this.eventEmitter.emit('update');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.WebSocketHighLeverageModeConfigAccountSubscriber = WebSocketHighLeverageModeConfigAccountSubscriber;
|
|
@@ -9,6 +9,7 @@ export declare function getUserAccountPublicKey(programId: PublicKey, authority:
|
|
|
9
9
|
export declare function getUserAccountPublicKeySync(programId: PublicKey, authority: PublicKey, subAccountId?: number): PublicKey;
|
|
10
10
|
export declare function getUserStatsAccountPublicKey(programId: PublicKey, authority: PublicKey): PublicKey;
|
|
11
11
|
export declare function getRFQUserAccountPublicKey(programId: PublicKey, userAccountPublicKey: PublicKey): PublicKey;
|
|
12
|
+
export declare function getSwiftUserAccountPublicKey(programId: PublicKey, userAccountPublicKey: PublicKey): PublicKey;
|
|
12
13
|
export declare function getPerpMarketPublicKey(programId: PublicKey, marketIndex: number): Promise<PublicKey>;
|
|
13
14
|
export declare function getPerpMarketPublicKeySync(programId: PublicKey, marketIndex: number): PublicKey;
|
|
14
15
|
export declare function getSpotMarketPublicKey(programId: PublicKey, marketIndex: number): Promise<PublicKey>;
|
|
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.getHighLeverageModeConfigPublicKey = exports.getTokenProgramForSpotMarket = exports.getPythPullOraclePublicKey = exports.getPrelaunchOraclePublicKey = exports.getProtocolIfSharesTransferConfigPublicKey = exports.getReferrerNamePublicKeySync = exports.getOpenbookV2FulfillmentConfigPublicKey = exports.getPhoenixFulfillmentConfigPublicKey = exports.getSerumFulfillmentConfigPublicKey = exports.getSerumSignerPublicKey = exports.getSerumOpenOrdersPublicKey = exports.getDriftSignerPublicKey = exports.getInsuranceFundStakeAccountPublicKey = exports.getInsuranceFundVaultPublicKey = exports.getSpotMarketVaultPublicKey = exports.getSpotMarketPublicKeySync = exports.getSpotMarketPublicKey = exports.getPerpMarketPublicKeySync = exports.getPerpMarketPublicKey = exports.getRFQUserAccountPublicKey = exports.getUserStatsAccountPublicKey = exports.getUserAccountPublicKeySync = exports.getUserAccountPublicKey = exports.getUserAccountPublicKeyAndNonce = exports.getDriftStateAccountPublicKey = exports.getDriftStateAccountPublicKeyAndNonce = void 0;
|
|
26
|
+
exports.getHighLeverageModeConfigPublicKey = exports.getTokenProgramForSpotMarket = exports.getPythPullOraclePublicKey = exports.getPrelaunchOraclePublicKey = exports.getProtocolIfSharesTransferConfigPublicKey = exports.getReferrerNamePublicKeySync = exports.getOpenbookV2FulfillmentConfigPublicKey = exports.getPhoenixFulfillmentConfigPublicKey = exports.getSerumFulfillmentConfigPublicKey = exports.getSerumSignerPublicKey = exports.getSerumOpenOrdersPublicKey = exports.getDriftSignerPublicKey = exports.getInsuranceFundStakeAccountPublicKey = exports.getInsuranceFundVaultPublicKey = exports.getSpotMarketVaultPublicKey = exports.getSpotMarketPublicKeySync = exports.getSpotMarketPublicKey = exports.getPerpMarketPublicKeySync = exports.getPerpMarketPublicKey = exports.getSwiftUserAccountPublicKey = exports.getRFQUserAccountPublicKey = exports.getUserStatsAccountPublicKey = exports.getUserAccountPublicKeySync = exports.getUserAccountPublicKey = exports.getUserAccountPublicKeyAndNonce = exports.getDriftStateAccountPublicKey = exports.getDriftStateAccountPublicKeyAndNonce = void 0;
|
|
27
27
|
const web3_js_1 = require("@solana/web3.js");
|
|
28
28
|
const anchor = __importStar(require("@coral-xyz/anchor"));
|
|
29
29
|
const spl_token_1 = require("@solana/spl-token");
|
|
@@ -69,6 +69,13 @@ function getRFQUserAccountPublicKey(programId, userAccountPublicKey) {
|
|
|
69
69
|
], programId)[0];
|
|
70
70
|
}
|
|
71
71
|
exports.getRFQUserAccountPublicKey = getRFQUserAccountPublicKey;
|
|
72
|
+
function getSwiftUserAccountPublicKey(programId, userAccountPublicKey) {
|
|
73
|
+
return web3_js_1.PublicKey.findProgramAddressSync([
|
|
74
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('SWIFT')),
|
|
75
|
+
userAccountPublicKey.toBuffer(),
|
|
76
|
+
], programId)[0];
|
|
77
|
+
}
|
|
78
|
+
exports.getSwiftUserAccountPublicKey = getSwiftUserAccountPublicKey;
|
|
72
79
|
async function getPerpMarketPublicKey(programId, marketIndex) {
|
|
73
80
|
return (await web3_js_1.PublicKey.findProgramAddress([
|
|
74
81
|
Buffer.from(anchor.utils.bytes.utf8.encode('perp_market')),
|
|
@@ -872,6 +872,17 @@ exports.MainnetPerpMarkets = [
|
|
|
872
872
|
oracleSource: __1.OracleSource.PYTH_1K_PULL,
|
|
873
873
|
pythFeedId: '0x514aed52ca5294177f20187ae883cec4a018619772ddce41efcc36a6448f5d5d',
|
|
874
874
|
},
|
|
875
|
+
{
|
|
876
|
+
fullName: 'MICHI',
|
|
877
|
+
category: ['Meme'],
|
|
878
|
+
symbol: 'MICHI-PERP',
|
|
879
|
+
baseAssetSymbol: 'MICHI',
|
|
880
|
+
marketIndex: 52,
|
|
881
|
+
oracle: new web3_js_1.PublicKey('GHzvsMDMSiuyZoWhEAuM27MKFdN2Y4fA4wSDuSd6dLMA'),
|
|
882
|
+
launchTs: 1730402722000,
|
|
883
|
+
oracleSource: __1.OracleSource.PYTH_PULL,
|
|
884
|
+
pythFeedId: '0x63a45218d6b13ffd28ca04748615511bf70eff80a3411c97d96b8ed74a6decab',
|
|
885
|
+
},
|
|
875
886
|
];
|
|
876
887
|
exports.PerpMarkets = {
|
|
877
888
|
devnet: exports.DevnetPerpMarkets,
|
|
@@ -337,12 +337,12 @@ exports.MainnetSpotMarkets = [
|
|
|
337
337
|
{
|
|
338
338
|
symbol: 'BNSOL',
|
|
339
339
|
marketIndex: 25,
|
|
340
|
-
oracle: new web3_js_1.PublicKey('
|
|
340
|
+
oracle: new web3_js_1.PublicKey('8DmXTfhhtb9kTcpTVfb6Ygx8WhZ8wexGqcpxfn23zooe'),
|
|
341
341
|
oracleSource: __1.OracleSource.PYTH_PULL,
|
|
342
342
|
mint: new web3_js_1.PublicKey('BNso1VUJnh4zcfpZa6986Ea66P6TCp59hvtNJ8b1X85'),
|
|
343
343
|
precision: numericConstants_1.LAMPORTS_PRECISION,
|
|
344
344
|
precisionExp: numericConstants_1.LAMPORTS_EXP,
|
|
345
|
-
pythFeedId: '
|
|
345
|
+
pythFeedId: '0x55f8289be7450f1ae564dd9798e49e7d797d89adbc54fe4f8c906b1fcb94b0c3',
|
|
346
346
|
},
|
|
347
347
|
{
|
|
348
348
|
symbol: 'MOTHER',
|
|
@@ -22,6 +22,7 @@ import { UserStatsSubscriptionConfig } from './userStatsConfig';
|
|
|
22
22
|
import { TxHandler } from './tx/txHandler';
|
|
23
23
|
import { WormholeCoreBridgeSolana } from '@pythnetwork/pyth-solana-receiver/lib/idl/wormhole_core_bridge_solana';
|
|
24
24
|
import { PythSolanaReceiver } from '@pythnetwork/pyth-solana-receiver/lib/idl/pyth_solana_receiver';
|
|
25
|
+
import { Slothash } from './slot/SlothashSubscriber';
|
|
25
26
|
type RemainingAccountParams = {
|
|
26
27
|
userAccounts: UserAccount[];
|
|
27
28
|
writablePerpMarketIndexes?: number[];
|
|
@@ -140,6 +141,8 @@ export declare class DriftClient {
|
|
|
140
141
|
getInitializeUserStatsIx(): Promise<TransactionInstruction>;
|
|
141
142
|
initializeRFQUser(userAccountPublicKey: PublicKey, txParams?: TxParams): Promise<[TransactionSignature, PublicKey]>;
|
|
142
143
|
getInitializeRFQUserInstruction(userAccountPublicKey: PublicKey): Promise<[PublicKey, TransactionInstruction]>;
|
|
144
|
+
initializeSwiftUserOrdersAccount(userAccountPublicKey: PublicKey, txParams?: TxParams): Promise<[TransactionSignature, PublicKey]>;
|
|
145
|
+
getInitializeSwiftUserOrdersAccountInstruction(userAccountPublicKey: PublicKey): Promise<[PublicKey, TransactionInstruction]>;
|
|
143
146
|
getInitializeUserInstructions(subAccountId?: number, name?: string, referrerInfo?: ReferrerInfo): Promise<[PublicKey, TransactionInstruction]>;
|
|
144
147
|
getNextSubAccountId(): Promise<number>;
|
|
145
148
|
initializeReferrerName(name: string): Promise<TransactionSignature>;
|
|
@@ -531,12 +534,12 @@ export declare class DriftClient {
|
|
|
531
534
|
takerStats: PublicKey;
|
|
532
535
|
takerUserAccount: UserAccount;
|
|
533
536
|
}): Promise<TransactionInstruction[]>;
|
|
534
|
-
placeAndMakeSwiftPerpOrder(encodedSwiftMessage: Buffer, swiftSignature: Buffer, encodedSwiftOrderParamsMessage: Buffer, swiftOrderParamsSignature: Buffer,
|
|
537
|
+
placeAndMakeSwiftPerpOrder(encodedSwiftMessage: Buffer, swiftSignature: Buffer, encodedSwiftOrderParamsMessage: Buffer, swiftOrderParamsSignature: Buffer, swiftOrderUuid: Uint8Array, takerInfo: {
|
|
535
538
|
taker: PublicKey;
|
|
536
539
|
takerStats: PublicKey;
|
|
537
540
|
takerUserAccount: UserAccount;
|
|
538
541
|
}, orderParams: OptionalOrderParams, referrerInfo?: ReferrerInfo, txParams?: TxParams, subAccountId?: number): Promise<TransactionSignature>;
|
|
539
|
-
getPlaceAndMakeSwiftPerpOrderIxs(encodedSwiftMessage: Buffer, swiftSignature: Buffer, encodedSwiftOrderParamsMessage: Buffer, swiftOrderParamsSignature: Buffer,
|
|
542
|
+
getPlaceAndMakeSwiftPerpOrderIxs(encodedSwiftMessage: Buffer, swiftSignature: Buffer, encodedSwiftOrderParamsMessage: Buffer, swiftOrderParamsSignature: Buffer, swiftOrderUuid: Uint8Array, takerInfo: {
|
|
540
543
|
taker: PublicKey;
|
|
541
544
|
takerStats: PublicKey;
|
|
542
545
|
takerUserAccount: UserAccount;
|
|
@@ -759,6 +762,13 @@ export declare class DriftClient {
|
|
|
759
762
|
resolvePerpPnlDeficit(spotMarketIndex: number, perpMarketIndex: number, txParams?: TxParams): Promise<TransactionSignature>;
|
|
760
763
|
getResolvePerpPnlDeficitIx(spotMarketIndex: number, perpMarketIndex: number): Promise<TransactionInstruction>;
|
|
761
764
|
getDepositIntoSpotMarketRevenuePoolIx(marketIndex: number, amount: BN, userTokenAccountPublicKey: PublicKey): Promise<TransactionInstruction>;
|
|
765
|
+
/**
|
|
766
|
+
* This ix will donate your funds to drift revenue pool. It does not deposit into your user account
|
|
767
|
+
* @param marketIndex
|
|
768
|
+
* @param amount
|
|
769
|
+
* @param userTokenAccountPublicKey
|
|
770
|
+
* @returns
|
|
771
|
+
*/
|
|
762
772
|
depositIntoSpotMarketRevenuePool(marketIndex: number, amount: BN, userTokenAccountPublicKey: PublicKey): Promise<TransactionSignature>;
|
|
763
773
|
getPerpMarketExtendedInfo(marketIndex: number): PerpMarketExtendedInfo;
|
|
764
774
|
/**
|
|
@@ -794,8 +804,8 @@ export declare class DriftClient {
|
|
|
794
804
|
proof: number[][];
|
|
795
805
|
};
|
|
796
806
|
}, feedId: string, encodedVaaAddress: PublicKey): Promise<TransactionInstruction>;
|
|
797
|
-
getPostSwitchboardOnDemandUpdateAtomicIx(feed: PublicKey, numSignatures?: number): Promise<TransactionInstruction | undefined>;
|
|
798
|
-
postSwitchboardOnDemandUpdate(feed: PublicKey, numSignatures?: number): Promise<TransactionSignature>;
|
|
807
|
+
getPostSwitchboardOnDemandUpdateAtomicIx(feed: PublicKey, recentSlothash?: Slothash, numSignatures?: number): Promise<TransactionInstruction | undefined>;
|
|
808
|
+
postSwitchboardOnDemandUpdate(feed: PublicKey, recentSlothash?: Slothash, numSignatures?: number): Promise<TransactionSignature>;
|
|
799
809
|
private getBuildEncodedVaaIxs;
|
|
800
810
|
enableUserHighLeverageMode(subAccountId: number, txParams?: TxParams): Promise<TransactionSignature>;
|
|
801
811
|
getEnableHighLeverageModeIx(subAccountId: number, depositToTradeArgs?: {
|