@drift-labs/sdk 2.85.0-beta.8 → 2.86.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +1 -1
- package/bun.lockb +0 -0
- package/lib/addresses/pda.d.ts +1 -0
- package/lib/addresses/pda.js +8 -1
- package/lib/adminClient.d.ts +2 -0
- package/lib/adminClient.js +22 -0
- package/lib/blockhashSubscriber/BlockhashSubscriber.js +22 -15
- package/lib/config.d.ts +3 -0
- package/lib/config.js +4 -1
- package/lib/constants/perpMarkets.d.ts +1 -0
- package/lib/constants/perpMarkets.js +57 -0
- package/lib/constants/spotMarkets.d.ts +1 -0
- package/lib/constants/spotMarkets.js +20 -0
- package/lib/driftClient.d.ts +26 -1
- package/lib/driftClient.js +157 -31
- package/lib/driftClientConfig.d.ts +2 -1
- package/lib/idl/drift.json +161 -2
- package/lib/math/oracles.d.ts +2 -0
- package/lib/math/oracles.js +14 -1
- package/lib/oracles/pythPullClient.js +1 -1
- package/lib/tx/baseTxSender.js +1 -0
- package/lib/tx/blockhashFetcher/baseBlockhashFetcher.d.ts +8 -0
- package/lib/tx/blockhashFetcher/baseBlockhashFetcher.js +13 -0
- package/lib/tx/blockhashFetcher/cachedBlockhashFetcher.d.ts +28 -0
- package/lib/tx/blockhashFetcher/cachedBlockhashFetcher.js +73 -0
- package/lib/tx/blockhashFetcher/types.d.ts +4 -0
- package/lib/tx/blockhashFetcher/types.js +2 -0
- package/lib/tx/txHandler.d.ts +10 -0
- package/lib/tx/txHandler.js +16 -7
- package/lib/tx/utils.d.ts +2 -0
- package/lib/tx/utils.js +10 -0
- package/lib/util/pythPullOracleUtils.d.ts +2 -0
- package/lib/util/pythPullOracleUtils.js +15 -0
- package/package.json +3 -1
- package/src/addresses/pda.ts +13 -0
- package/src/adminClient.ts +39 -0
- package/src/blockhashSubscriber/BlockhashSubscriber.ts +24 -19
- package/src/config.ts +6 -0
- package/src/constants/perpMarkets.ts +115 -0
- package/src/constants/spotMarkets.ts +41 -0
- package/src/driftClient.ts +347 -41
- package/src/driftClientConfig.ts +2 -1
- package/src/idl/drift.json +161 -2
- package/src/math/oracles.ts +17 -0
- package/src/oracles/pythPullClient.ts +2 -3
- package/src/tx/baseTxSender.ts +1 -0
- package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +19 -0
- package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +90 -0
- package/src/tx/blockhashFetcher/types.ts +5 -0
- package/src/tx/txHandler.ts +38 -4
- package/src/tx/utils.ts +11 -0
- package/src/util/pythPullOracleUtils.ts +11 -0
- package/tests/tx/cachedBlockhashFetcher.test.ts +96 -0
|
@@ -14,6 +14,7 @@ exports.DevnetSpotMarkets = [
|
|
|
14
14
|
mint: new web3_js_1.PublicKey('8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2'),
|
|
15
15
|
precision: new __1.BN(10).pow(numericConstants_1.SIX),
|
|
16
16
|
precisionExp: numericConstants_1.SIX,
|
|
17
|
+
pythFeedId: '0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
|
|
17
18
|
},
|
|
18
19
|
{
|
|
19
20
|
symbol: 'SOL',
|
|
@@ -25,6 +26,7 @@ exports.DevnetSpotMarkets = [
|
|
|
25
26
|
precisionExp: numericConstants_1.LAMPORTS_EXP,
|
|
26
27
|
serumMarket: new web3_js_1.PublicKey('8N37SsnTu8RYxtjrV9SStjkkwVhmU8aCWhLvwduAPEKW'),
|
|
27
28
|
phoenixMarket: new web3_js_1.PublicKey('78ehDnHgbkFxqXZwdFxa8HK7saX58GymeX2wNGdkqYLp'),
|
|
29
|
+
pythFeedId: '0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d',
|
|
28
30
|
},
|
|
29
31
|
{
|
|
30
32
|
symbol: 'BTC',
|
|
@@ -35,6 +37,7 @@ exports.DevnetSpotMarkets = [
|
|
|
35
37
|
precision: new __1.BN(10).pow(numericConstants_1.SIX),
|
|
36
38
|
precisionExp: numericConstants_1.SIX,
|
|
37
39
|
serumMarket: new web3_js_1.PublicKey('AGsmbVu3MS9u68GEYABWosQQCZwmLcBHu4pWEuBYH7Za'),
|
|
40
|
+
pythFeedId: '0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43',
|
|
38
41
|
},
|
|
39
42
|
];
|
|
40
43
|
exports.MainnetSpotMarkets = [
|
|
@@ -46,6 +49,7 @@ exports.MainnetSpotMarkets = [
|
|
|
46
49
|
mint: new web3_js_1.PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
|
|
47
50
|
precision: numericConstants_1.QUOTE_PRECISION,
|
|
48
51
|
precisionExp: numericConstants_1.QUOTE_PRECISION_EXP,
|
|
52
|
+
pythFeedId: '0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
|
|
49
53
|
},
|
|
50
54
|
{
|
|
51
55
|
symbol: 'SOL',
|
|
@@ -57,6 +61,7 @@ exports.MainnetSpotMarkets = [
|
|
|
57
61
|
precisionExp: numericConstants_1.LAMPORTS_EXP,
|
|
58
62
|
serumMarket: new web3_js_1.PublicKey('8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6'),
|
|
59
63
|
phoenixMarket: new web3_js_1.PublicKey('4DoNfFBfF7UokCC2FQzriy7yHK6DY6NVdYpuekQ5pRgg'),
|
|
64
|
+
pythFeedId: '0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d',
|
|
60
65
|
},
|
|
61
66
|
{
|
|
62
67
|
symbol: 'mSOL',
|
|
@@ -67,6 +72,7 @@ exports.MainnetSpotMarkets = [
|
|
|
67
72
|
precision: new __1.BN(10).pow(numericConstants_1.NINE),
|
|
68
73
|
precisionExp: numericConstants_1.NINE,
|
|
69
74
|
serumMarket: new web3_js_1.PublicKey('9Lyhks5bQQxb9EyyX55NtgKQzpM4WK7JCmeaWuQ5MoXD'),
|
|
75
|
+
pythFeedId: '0xc2289a6a43d2ce91c6f55caec370f4acc38a2ed477f58813334c6d03749ff2a4',
|
|
70
76
|
},
|
|
71
77
|
{
|
|
72
78
|
symbol: 'wBTC',
|
|
@@ -77,6 +83,7 @@ exports.MainnetSpotMarkets = [
|
|
|
77
83
|
precision: new __1.BN(10).pow(numericConstants_1.EIGHT),
|
|
78
84
|
precisionExp: numericConstants_1.EIGHT,
|
|
79
85
|
serumMarket: new web3_js_1.PublicKey('3BAKsQd3RuhZKES2DGysMhjBdwjZYKYmxRqnSMtZ4KSN'),
|
|
86
|
+
pythFeedId: '0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43',
|
|
80
87
|
},
|
|
81
88
|
{
|
|
82
89
|
symbol: 'wETH',
|
|
@@ -88,6 +95,7 @@ exports.MainnetSpotMarkets = [
|
|
|
88
95
|
precisionExp: numericConstants_1.EIGHT,
|
|
89
96
|
serumMarket: new web3_js_1.PublicKey('BbJgE7HZMaDp5NTYvRh5jZSkQPVDTU8ubPFtpogUkEj4'),
|
|
90
97
|
phoenixMarket: new web3_js_1.PublicKey('Ew3vFDdtdGrknJAVVfraxCA37uNJtimXYPY4QjnfhFHH'),
|
|
98
|
+
pythFeedId: '0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace',
|
|
91
99
|
},
|
|
92
100
|
{
|
|
93
101
|
symbol: 'USDT',
|
|
@@ -98,6 +106,7 @@ exports.MainnetSpotMarkets = [
|
|
|
98
106
|
precision: numericConstants_1.QUOTE_PRECISION,
|
|
99
107
|
precisionExp: numericConstants_1.QUOTE_PRECISION_EXP,
|
|
100
108
|
serumMarket: new web3_js_1.PublicKey('B2na8Awyd7cpC59iEU43FagJAPLigr3AP3s38KM982bu'),
|
|
109
|
+
pythFeedId: '0x2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b',
|
|
101
110
|
},
|
|
102
111
|
{
|
|
103
112
|
symbol: 'jitoSOL',
|
|
@@ -109,6 +118,7 @@ exports.MainnetSpotMarkets = [
|
|
|
109
118
|
precisionExp: numericConstants_1.NINE,
|
|
110
119
|
serumMarket: new web3_js_1.PublicKey('DkbVbMhFxswS32xnn1K2UY4aoBugXooBTxdzkWWDWRkH'),
|
|
111
120
|
phoenixMarket: new web3_js_1.PublicKey('5LQLfGtqcC5rm2WuGxJf4tjqYmDjsQAbKo2AMLQ8KB7p'),
|
|
121
|
+
pythFeedId: '0x67be9f519b95cf24338801051f9a808eff0a578ccb388db73b7f6fe1de019ffb',
|
|
112
122
|
},
|
|
113
123
|
{
|
|
114
124
|
symbol: 'PYTH',
|
|
@@ -120,6 +130,7 @@ exports.MainnetSpotMarkets = [
|
|
|
120
130
|
precisionExp: numericConstants_1.SIX,
|
|
121
131
|
serumMarket: new web3_js_1.PublicKey('4E17F3BxtNVqzVsirxguuqkpYLtFgCR6NfTpccPh82WE'),
|
|
122
132
|
phoenixMarket: new web3_js_1.PublicKey('2sTMN9A1D1qeZLF95XQgJCUPiKe5DiV52jLfZGqMP46m'),
|
|
133
|
+
pythFeedId: '0x0bbf28e9a841a1cc788f6a361b17ca072d0ea3098a1e5df1c3922d06719579ff',
|
|
123
134
|
},
|
|
124
135
|
{
|
|
125
136
|
symbol: 'bSOL',
|
|
@@ -130,6 +141,7 @@ exports.MainnetSpotMarkets = [
|
|
|
130
141
|
precision: new __1.BN(10).pow(numericConstants_1.NINE),
|
|
131
142
|
precisionExp: numericConstants_1.NINE,
|
|
132
143
|
serumMarket: new web3_js_1.PublicKey('ARjaHVxGCQfTvvKjLd7U7srvk6orthZSE6uqWchCczZc'),
|
|
144
|
+
pythFeedId: '0x89875379e70f8fbadc17aef315adf3a8d5d160b811435537e03c97e8aac97d9c',
|
|
133
145
|
},
|
|
134
146
|
{
|
|
135
147
|
symbol: 'JTO',
|
|
@@ -141,6 +153,7 @@ exports.MainnetSpotMarkets = [
|
|
|
141
153
|
precisionExp: numericConstants_1.NINE,
|
|
142
154
|
serumMarket: new web3_js_1.PublicKey('H87FfmHABiZLRGrDsXRZtqq25YpARzaokCzL1vMYGiep'),
|
|
143
155
|
phoenixMarket: new web3_js_1.PublicKey('BRLLmdtPGuuFn3BU6orYw4KHaohAEptBToi3dwRUnHQZ'),
|
|
156
|
+
pythFeedId: '0xb43660a5f790c69354b0729a5ef9d50d68f1df92107540210b9cccba1f947cc2',
|
|
144
157
|
},
|
|
145
158
|
{
|
|
146
159
|
symbol: 'WIF',
|
|
@@ -152,6 +165,7 @@ exports.MainnetSpotMarkets = [
|
|
|
152
165
|
precisionExp: numericConstants_1.SIX,
|
|
153
166
|
serumMarket: new web3_js_1.PublicKey('2BtDHBTCTUxvdur498ZEcMgimasaFrY5GzLv8wS8XgCb'),
|
|
154
167
|
phoenixMarket: new web3_js_1.PublicKey('6ojSigXF7nDPyhFRgmn3V9ywhYseKF9J32ZrranMGVSX'),
|
|
168
|
+
pythFeedId: '0x4ca4beeca86f0d164160323817a4e42b10010a724c2217c6ee41b54cd4cc61fc',
|
|
155
169
|
},
|
|
156
170
|
{
|
|
157
171
|
symbol: 'JUP',
|
|
@@ -163,6 +177,7 @@ exports.MainnetSpotMarkets = [
|
|
|
163
177
|
precisionExp: numericConstants_1.SIX,
|
|
164
178
|
phoenixMarket: new web3_js_1.PublicKey('2pspvjWWaf3dNgt3jsgSzFCNvMGPb7t8FrEYvLGjvcCe'),
|
|
165
179
|
launchTs: 1706731200000,
|
|
180
|
+
pythFeedId: '0x0a0408d619e9380abad35060f9192039ed5042fa6f82301d0e48bb52be830996',
|
|
166
181
|
},
|
|
167
182
|
{
|
|
168
183
|
symbol: 'RNDR',
|
|
@@ -174,6 +189,7 @@ exports.MainnetSpotMarkets = [
|
|
|
174
189
|
precisionExp: numericConstants_1.EIGHT,
|
|
175
190
|
serumMarket: new web3_js_1.PublicKey('2m7ZLEKtxWF29727DSb5D91erpXPUY1bqhRWRC3wQX7u'),
|
|
176
191
|
launchTs: 1708964021000,
|
|
192
|
+
pythFeedId: '0xab7347771135fc733f8f38db462ba085ed3309955f42554a14fa13e855ac0e2f',
|
|
177
193
|
},
|
|
178
194
|
{
|
|
179
195
|
symbol: 'W',
|
|
@@ -185,6 +201,7 @@ exports.MainnetSpotMarkets = [
|
|
|
185
201
|
precisionExp: numericConstants_1.SIX,
|
|
186
202
|
phoenixMarket: new web3_js_1.PublicKey('8dFTCTAbtGuHsdDL8WEPrTU6pXFDrU1QSjBTutw8fwZk'),
|
|
187
203
|
launchTs: 1712149014000,
|
|
204
|
+
pythFeedId: '0xeff7446475e218517566ea99e72a4abec2e1bd8498b43b7d8331e29dcb059389',
|
|
188
205
|
},
|
|
189
206
|
{
|
|
190
207
|
symbol: 'TNSR',
|
|
@@ -196,6 +213,7 @@ exports.MainnetSpotMarkets = [
|
|
|
196
213
|
precisionExp: numericConstants_1.NINE,
|
|
197
214
|
phoenixMarket: new web3_js_1.PublicKey('AbJCZ9TAJiby5AY3cHcXS2gUdENC6mtsm6m7XpC2ZMvE'),
|
|
198
215
|
launchTs: 1712593532000,
|
|
216
|
+
pythFeedId: '0x05ecd4597cd48fe13d6cc3596c62af4f9675aee06e2e0b94c06d8bee2b659e05',
|
|
199
217
|
},
|
|
200
218
|
{
|
|
201
219
|
symbol: 'DRIFT',
|
|
@@ -207,6 +225,7 @@ exports.MainnetSpotMarkets = [
|
|
|
207
225
|
precisionExp: numericConstants_1.SIX,
|
|
208
226
|
phoenixMarket: new web3_js_1.PublicKey('8BV6rrWsUabnTDA3dE6A69oUDJAj3hMhtBHTJyXB7czp'),
|
|
209
227
|
launchTs: 1715860800000,
|
|
228
|
+
pythFeedId: '0x5c1690b27bb02446db17cdda13ccc2c1d609ad6d2ef5bf4983a85ea8b6f19d07',
|
|
210
229
|
},
|
|
211
230
|
{
|
|
212
231
|
symbol: 'INF',
|
|
@@ -217,6 +236,7 @@ exports.MainnetSpotMarkets = [
|
|
|
217
236
|
precision: new __1.BN(10).pow(numericConstants_1.NINE),
|
|
218
237
|
precisionExp: numericConstants_1.NINE,
|
|
219
238
|
launchTs: 1716595200000,
|
|
239
|
+
pythFeedId: '0xf51570985c642c49c2d6e50156390fdba80bb6d5f7fa389d2f012ced4f7d208f',
|
|
220
240
|
},
|
|
221
241
|
{
|
|
222
242
|
symbol: 'dSOL',
|
package/lib/driftClient.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="bn.js" />
|
|
3
|
+
/// <reference types="node" />
|
|
3
4
|
import { AnchorProvider, BN, Program, ProgramAccount } from '@coral-xyz/anchor';
|
|
4
5
|
import { StateAccount, IWallet, PositionDirection, UserAccount, PerpMarketAccount, OrderParams, Order, SpotMarketAccount, SpotPosition, MakerInfo, TakerInfo, OptionalOrderParams, ReferrerInfo, MarketType, TxParams, SerumV3FulfillmentConfigAccount, ReferrerNameAccount, OrderTriggerCondition, PerpMarketExtendedInfo, UserStatsAccount, PhoenixV1FulfillmentConfigAccount, ModifyOrderPolicy, SwapReduceOnly, SettlePnlMode, SignedTxData, MappedRecord } from './types';
|
|
5
6
|
import * as anchor from '@coral-xyz/anchor';
|
|
6
|
-
import { Connection, PublicKey, TransactionSignature, ConfirmOptions, Transaction, TransactionInstruction, AccountMeta, Signer, AddressLookupTableAccount, TransactionVersion, VersionedTransaction, BlockhashWithExpiryBlockHeight } from '@solana/web3.js';
|
|
7
|
+
import { Connection, PublicKey, TransactionSignature, ConfirmOptions, Transaction, TransactionInstruction, AccountMeta, Keypair, Signer, AddressLookupTableAccount, TransactionVersion, VersionedTransaction, BlockhashWithExpiryBlockHeight } from '@solana/web3.js';
|
|
7
8
|
import { TokenFaucet } from './tokenFaucet';
|
|
8
9
|
import { EventEmitter } from 'events';
|
|
9
10
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
@@ -18,6 +19,8 @@ import { UserStats } from './userStats';
|
|
|
18
19
|
import { JupiterClient, QuoteResponse, Route, SwapMode } from './jupiter/jupiterClient';
|
|
19
20
|
import { UserStatsSubscriptionConfig } from './userStatsConfig';
|
|
20
21
|
import { TxHandler } from './tx/txHandler';
|
|
22
|
+
import { WormholeCoreBridgeSolana } from '@pythnetwork/pyth-solana-receiver/lib/idl/wormhole_core_bridge_solana';
|
|
23
|
+
import { PythSolanaReceiver } from '@pythnetwork/pyth-solana-receiver/lib/idl/pyth_solana_receiver';
|
|
21
24
|
type RemainingAccountParams = {
|
|
22
25
|
userAccounts: UserAccount[];
|
|
23
26
|
writablePerpMarketIndexes?: number[];
|
|
@@ -60,6 +63,8 @@ export declare class DriftClient {
|
|
|
60
63
|
txParams: TxParams;
|
|
61
64
|
enableMetricsEvents?: boolean;
|
|
62
65
|
txHandler: TxHandler;
|
|
66
|
+
receiverProgram?: Program<PythSolanaReceiver>;
|
|
67
|
+
wormholeProgram?: Program<WormholeCoreBridgeSolana>;
|
|
63
68
|
get isSubscribed(): boolean;
|
|
64
69
|
set isSubscribed(val: boolean);
|
|
65
70
|
constructor(config: DriftClientConfig);
|
|
@@ -221,6 +226,7 @@ export declare class DriftClient {
|
|
|
221
226
|
*/
|
|
222
227
|
getAssociatedTokenAccount(marketIndex: number, useNative?: boolean): Promise<PublicKey>;
|
|
223
228
|
createAssociatedTokenAccountIdempotentInstruction(account: PublicKey, payer: PublicKey, owner: PublicKey, mint: PublicKey): TransactionInstruction;
|
|
229
|
+
createDepositTxn(amount: BN, marketIndex: number, associatedTokenAccount: PublicKey, subAccountId?: number, reduceOnly?: boolean, txParams?: TxParams): Promise<ReturnType<typeof this.buildTransaction>>;
|
|
224
230
|
/**
|
|
225
231
|
* Deposit funds into the given spot market
|
|
226
232
|
*
|
|
@@ -240,6 +246,7 @@ export declare class DriftClient {
|
|
|
240
246
|
pubkey: PublicKey;
|
|
241
247
|
}>;
|
|
242
248
|
getAssociatedTokenAccountCreationIx(tokenMintAddress: PublicKey, associatedTokenAddress: PublicKey): anchor.web3.TransactionInstruction;
|
|
249
|
+
createInitializeUserAccountAndDepositCollateral(amount: BN, userTokenAccount: PublicKey, marketIndex?: number, subAccountId?: number, name?: string, fromSubAccountId?: number, referrerInfo?: ReferrerInfo, donateAmount?: BN, txParams?: TxParams, customMaxMarginRatio?: number): Promise<[Transaction | VersionedTransaction, PublicKey]>;
|
|
243
250
|
/**
|
|
244
251
|
* Creates the User account for a user, and deposits some initial collateral
|
|
245
252
|
* @param amount
|
|
@@ -703,6 +710,24 @@ export declare class DriftClient {
|
|
|
703
710
|
marketIndex: number;
|
|
704
711
|
marketType: MarketType;
|
|
705
712
|
} | undefined;
|
|
713
|
+
getReceiverProgram(): Program<PythSolanaReceiver>;
|
|
714
|
+
postPythPullOracleUpdateAtomic(vaaString: string, feedId: string): Promise<TransactionSignature>;
|
|
715
|
+
getPostPythPullOracleUpdateAtomicIxs(vaaString: string, feedId: string, numSignatures?: number): Promise<TransactionInstruction[]>;
|
|
716
|
+
getSinglePostPythPullOracleAtomicIx(params: {
|
|
717
|
+
vaa: Buffer;
|
|
718
|
+
merklePriceUpdate: {
|
|
719
|
+
message: Buffer;
|
|
720
|
+
proof: number[][];
|
|
721
|
+
};
|
|
722
|
+
}, feedId: string, guardianSet: PublicKey): Promise<TransactionInstruction>;
|
|
723
|
+
updatePythPullOracle(vaaString: string, feedId: string): Promise<TransactionSignature>;
|
|
724
|
+
getUpdatePythPullOracleIxs(params: {
|
|
725
|
+
merklePriceUpdate: {
|
|
726
|
+
message: Buffer;
|
|
727
|
+
proof: number[][];
|
|
728
|
+
};
|
|
729
|
+
}, feedId: string, encodedVaaAddress: PublicKey): Promise<TransactionInstruction>;
|
|
730
|
+
getBuildEncodedVaaIxs(vaa: Buffer, guardianSet: PublicKey): Promise<[TransactionInstruction[], Keypair]>;
|
|
706
731
|
private handleSignedTransaction;
|
|
707
732
|
private handlePreSignedTransaction;
|
|
708
733
|
private isVersionedTransaction;
|
package/lib/driftClient.js
CHANGED
|
@@ -58,6 +58,12 @@ const utils_1 = require("./math/utils");
|
|
|
58
58
|
const txParamProcessor_1 = require("./tx/txParamProcessor");
|
|
59
59
|
const oracles_1 = require("./math/oracles");
|
|
60
60
|
const txHandler_1 = require("./tx/txHandler");
|
|
61
|
+
const pyth_solana_receiver_1 = require("@pythnetwork/pyth-solana-receiver");
|
|
62
|
+
const price_service_sdk_1 = require("@pythnetwork/price-service-sdk");
|
|
63
|
+
const address_1 = require("@pythnetwork/pyth-solana-receiver/lib/address");
|
|
64
|
+
const config_2 = require("./config");
|
|
65
|
+
const pythPullOracleUtils_1 = require("./util/pythPullOracleUtils");
|
|
66
|
+
const utils_2 = require("./tx/utils");
|
|
61
67
|
/**
|
|
62
68
|
* # DriftClient
|
|
63
69
|
* This class is the main way to interact with Drift Protocol. It allows you to subscribe to the various accounts where the Market's state is stored, as well as: opening positions, liquidating, settling funding, depositing & withdrawing, and more.
|
|
@@ -106,6 +112,7 @@ class DriftClient {
|
|
|
106
112
|
onSignedCb: this.handleSignedTransaction.bind(this),
|
|
107
113
|
preSignedCb: this.handlePreSignedTransaction.bind(this),
|
|
108
114
|
},
|
|
115
|
+
config: config.txHandlerConfig,
|
|
109
116
|
});
|
|
110
117
|
if (config.includeDelegates && config.subAccountIds) {
|
|
111
118
|
throw new Error('Can only pass one of includeDelegates or subAccountIds. If you want to specify subaccount ids for multiple authorities, pass authoritySubaccountMap instead');
|
|
@@ -1061,17 +1068,7 @@ class DriftClient {
|
|
|
1061
1068
|
data: Buffer.from([0x1]),
|
|
1062
1069
|
});
|
|
1063
1070
|
}
|
|
1064
|
-
|
|
1065
|
-
* Deposit funds into the given spot market
|
|
1066
|
-
*
|
|
1067
|
-
* @param amount to deposit
|
|
1068
|
-
* @param marketIndex spot market index to deposit into
|
|
1069
|
-
* @param associatedTokenAccount can be the wallet public key if using native sol
|
|
1070
|
-
* @param subAccountId subaccountId to deposit
|
|
1071
|
-
* @param reduceOnly if true, deposit must not increase account risk
|
|
1072
|
-
*/
|
|
1073
|
-
async deposit(amount, marketIndex, associatedTokenAccount, subAccountId, reduceOnly = false, txParams) {
|
|
1074
|
-
const additionalSigners = [];
|
|
1071
|
+
async createDepositTxn(amount, marketIndex, associatedTokenAccount, subAccountId, reduceOnly = false, txParams) {
|
|
1075
1072
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
1076
1073
|
const isSolMarket = spotMarketAccount.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
|
|
1077
1074
|
const signerAuthority = this.wallet.publicKey;
|
|
@@ -1090,7 +1087,20 @@ class DriftClient {
|
|
|
1090
1087
|
}
|
|
1091
1088
|
txParams = { ...(txParams !== null && txParams !== void 0 ? txParams : this.txParams), computeUnits: 600000 };
|
|
1092
1089
|
const tx = await this.buildTransaction(instructions, txParams);
|
|
1093
|
-
|
|
1090
|
+
return tx;
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Deposit funds into the given spot market
|
|
1094
|
+
*
|
|
1095
|
+
* @param amount to deposit
|
|
1096
|
+
* @param marketIndex spot market index to deposit into
|
|
1097
|
+
* @param associatedTokenAccount can be the wallet public key if using native sol
|
|
1098
|
+
* @param subAccountId subaccountId to deposit
|
|
1099
|
+
* @param reduceOnly if true, deposit must not increase account risk
|
|
1100
|
+
*/
|
|
1101
|
+
async deposit(amount, marketIndex, associatedTokenAccount, subAccountId, reduceOnly = false, txParams) {
|
|
1102
|
+
const tx = await this.createDepositTxn(amount, marketIndex, associatedTokenAccount, subAccountId, reduceOnly, txParams);
|
|
1103
|
+
const { txSig, slot } = await this.sendTransaction(tx, [], this.opts);
|
|
1094
1104
|
this.spotMarketLastSlotCache.set(marketIndex, slot);
|
|
1095
1105
|
return txSig;
|
|
1096
1106
|
}
|
|
@@ -1165,23 +1175,9 @@ class DriftClient {
|
|
|
1165
1175
|
getAssociatedTokenAccountCreationIx(tokenMintAddress, associatedTokenAddress) {
|
|
1166
1176
|
return (0, spl_token_1.createAssociatedTokenAccountInstruction)(this.wallet.publicKey, associatedTokenAddress, this.wallet.publicKey, tokenMintAddress);
|
|
1167
1177
|
}
|
|
1168
|
-
|
|
1169
|
-
* Creates the User account for a user, and deposits some initial collateral
|
|
1170
|
-
* @param amount
|
|
1171
|
-
* @param userTokenAccount
|
|
1172
|
-
* @param marketIndex
|
|
1173
|
-
* @param subAccountId
|
|
1174
|
-
* @param name
|
|
1175
|
-
* @param fromSubAccountId
|
|
1176
|
-
* @param referrerInfo
|
|
1177
|
-
* @param donateAmount
|
|
1178
|
-
* @param txParams
|
|
1179
|
-
* @returns
|
|
1180
|
-
*/
|
|
1181
|
-
async initializeUserAccountAndDepositCollateral(amount, userTokenAccount, marketIndex = 0, subAccountId = 0, name, fromSubAccountId, referrerInfo, donateAmount, txParams, customMaxMarginRatio) {
|
|
1178
|
+
async createInitializeUserAccountAndDepositCollateral(amount, userTokenAccount, marketIndex = 0, subAccountId = 0, name, fromSubAccountId, referrerInfo, donateAmount, txParams, customMaxMarginRatio) {
|
|
1182
1179
|
const ixs = [];
|
|
1183
1180
|
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(subAccountId, name, referrerInfo);
|
|
1184
|
-
const additionalSigners = [];
|
|
1185
1181
|
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
1186
1182
|
const isSolMarket = spotMarket.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
|
|
1187
1183
|
const authority = this.wallet.publicKey;
|
|
@@ -1226,6 +1222,24 @@ class DriftClient {
|
|
|
1226
1222
|
ixs.push((0, spl_token_1.createCloseAccountInstruction)(wsolTokenAccount, authority, authority, []));
|
|
1227
1223
|
}
|
|
1228
1224
|
const tx = await this.buildTransaction(ixs, txParams);
|
|
1225
|
+
return [tx, userAccountPublicKey];
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Creates the User account for a user, and deposits some initial collateral
|
|
1229
|
+
* @param amount
|
|
1230
|
+
* @param userTokenAccount
|
|
1231
|
+
* @param marketIndex
|
|
1232
|
+
* @param subAccountId
|
|
1233
|
+
* @param name
|
|
1234
|
+
* @param fromSubAccountId
|
|
1235
|
+
* @param referrerInfo
|
|
1236
|
+
* @param donateAmount
|
|
1237
|
+
* @param txParams
|
|
1238
|
+
* @returns
|
|
1239
|
+
*/
|
|
1240
|
+
async initializeUserAccountAndDepositCollateral(amount, userTokenAccount, marketIndex = 0, subAccountId = 0, name, fromSubAccountId, referrerInfo, donateAmount, txParams, customMaxMarginRatio) {
|
|
1241
|
+
const [tx, userAccountPublicKey] = await this.createInitializeUserAccountAndDepositCollateral(amount, userTokenAccount, marketIndex, subAccountId, name, fromSubAccountId, referrerInfo, donateAmount, txParams, customMaxMarginRatio);
|
|
1242
|
+
const additionalSigners = [];
|
|
1229
1243
|
const { txSig, slot } = await this.sendTransaction(tx, additionalSigners, this.opts);
|
|
1230
1244
|
this.spotMarketLastSlotCache.set(marketIndex, slot);
|
|
1231
1245
|
await this.addUser(subAccountId);
|
|
@@ -2267,6 +2281,9 @@ class DriftClient {
|
|
|
2267
2281
|
async getJupiterSwapIxV6({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, quote, reduceOnly, userAccountPublicKey, }) {
|
|
2268
2282
|
const outMarket = this.getSpotMarketAccount(outMarketIndex);
|
|
2269
2283
|
const inMarket = this.getSpotMarketAccount(inMarketIndex);
|
|
2284
|
+
const isExactOut = swapMode === 'ExactOut' || quote.swapMode === 'ExactOut';
|
|
2285
|
+
const amountIn = new anchor_1.BN(quote.inAmount);
|
|
2286
|
+
const exactOutBufferedAmountIn = amountIn.muln(1001).divn(1000); // Add 10bp buffer
|
|
2270
2287
|
if (!quote) {
|
|
2271
2288
|
const fetchedQuote = await jupiterClient.getQuote({
|
|
2272
2289
|
inputMint: inMarket.mint,
|
|
@@ -2312,7 +2329,7 @@ class DriftClient {
|
|
|
2312
2329
|
const { beginSwapIx, endSwapIx } = await this.getSwapIx({
|
|
2313
2330
|
outMarketIndex,
|
|
2314
2331
|
inMarketIndex,
|
|
2315
|
-
amountIn:
|
|
2332
|
+
amountIn: isExactOut ? exactOutBufferedAmountIn : amountIn,
|
|
2316
2333
|
inTokenAccount: inAssociatedTokenAccount,
|
|
2317
2334
|
outTokenAccount: outAssociatedTokenAccount,
|
|
2318
2335
|
reduceOnly,
|
|
@@ -3622,6 +3639,117 @@ class DriftClient {
|
|
|
3622
3639
|
}
|
|
3623
3640
|
return undefined;
|
|
3624
3641
|
}
|
|
3642
|
+
getReceiverProgram() {
|
|
3643
|
+
if (this.receiverProgram === undefined) {
|
|
3644
|
+
this.receiverProgram = new anchor_1.Program(pyth_solana_receiver_1.pythSolanaReceiverIdl, pyth_solana_receiver_1.DEFAULT_RECEIVER_PROGRAM_ID, this.provider);
|
|
3645
|
+
}
|
|
3646
|
+
return this.receiverProgram;
|
|
3647
|
+
}
|
|
3648
|
+
async postPythPullOracleUpdateAtomic(vaaString, feedId) {
|
|
3649
|
+
const postIxs = await this.getPostPythPullOracleUpdateAtomicIxs(vaaString, feedId);
|
|
3650
|
+
const tx = await this.buildTransaction(postIxs);
|
|
3651
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
3652
|
+
return txSig;
|
|
3653
|
+
}
|
|
3654
|
+
async getPostPythPullOracleUpdateAtomicIxs(vaaString, feedId, numSignatures = 2) {
|
|
3655
|
+
feedId = (0, pythPullOracleUtils_1.trimFeedId)(feedId);
|
|
3656
|
+
const accumulatorUpdateData = (0, price_service_sdk_1.parseAccumulatorUpdateData)(Buffer.from(vaaString, 'base64'));
|
|
3657
|
+
const guardianSetIndex = accumulatorUpdateData.vaa.readUInt32BE(1);
|
|
3658
|
+
const guardianSet = (0, address_1.getGuardianSetPda)(guardianSetIndex, address_1.DEFAULT_WORMHOLE_PROGRAM_ID);
|
|
3659
|
+
const trimmedVaa = (0, oracles_1.trimVaaSignatures)(accumulatorUpdateData.vaa, numSignatures);
|
|
3660
|
+
const postIxs = [];
|
|
3661
|
+
for (const update of accumulatorUpdateData.updates) {
|
|
3662
|
+
postIxs.push(await this.getSinglePostPythPullOracleAtomicIx({
|
|
3663
|
+
vaa: trimmedVaa,
|
|
3664
|
+
merklePriceUpdate: update,
|
|
3665
|
+
}, feedId, guardianSet));
|
|
3666
|
+
}
|
|
3667
|
+
return postIxs;
|
|
3668
|
+
}
|
|
3669
|
+
async getSinglePostPythPullOracleAtomicIx(params, feedId, guardianSet) {
|
|
3670
|
+
const feedIdBuffer = (0, pythPullOracleUtils_1.getFeedIdUint8Array)(feedId);
|
|
3671
|
+
const receiverProgram = this.getReceiverProgram();
|
|
3672
|
+
const encodedParams = receiverProgram.coder.types.encode('PostUpdateAtomicParams', params);
|
|
3673
|
+
return this.program.instruction.postPythPullOracleUpdateAtomic(feedIdBuffer, encodedParams, {
|
|
3674
|
+
accounts: {
|
|
3675
|
+
keeper: this.wallet.publicKey,
|
|
3676
|
+
pythSolanaReceiver: config_2.DRIFT_ORACLE_RECEIVER_ID,
|
|
3677
|
+
guardianSet,
|
|
3678
|
+
priceFeed: (0, pda_1.getPythPullOraclePublicKey)(this.program.programId, feedIdBuffer),
|
|
3679
|
+
},
|
|
3680
|
+
});
|
|
3681
|
+
}
|
|
3682
|
+
async updatePythPullOracle(vaaString, feedId) {
|
|
3683
|
+
feedId = (0, pythPullOracleUtils_1.trimFeedId)(feedId);
|
|
3684
|
+
const accumulatorUpdateData = (0, price_service_sdk_1.parseAccumulatorUpdateData)(Buffer.from(vaaString, 'base64'));
|
|
3685
|
+
const guardianSetIndex = accumulatorUpdateData.vaa.readUInt32BE(1);
|
|
3686
|
+
const guardianSet = (0, address_1.getGuardianSetPda)(guardianSetIndex, address_1.DEFAULT_WORMHOLE_PROGRAM_ID);
|
|
3687
|
+
const [postIxs, encodedVaaAddress] = await this.getBuildEncodedVaaIxs(accumulatorUpdateData.vaa, guardianSet);
|
|
3688
|
+
for (const update of accumulatorUpdateData.updates) {
|
|
3689
|
+
postIxs.push(await this.getUpdatePythPullOracleIxs({
|
|
3690
|
+
merklePriceUpdate: update,
|
|
3691
|
+
}, feedId, encodedVaaAddress.publicKey));
|
|
3692
|
+
}
|
|
3693
|
+
const tx = await this.buildTransaction(postIxs);
|
|
3694
|
+
const { txSig } = await this.sendTransaction(tx, [encodedVaaAddress], this.opts);
|
|
3695
|
+
return txSig;
|
|
3696
|
+
}
|
|
3697
|
+
async getUpdatePythPullOracleIxs(params, feedId, encodedVaaAddress) {
|
|
3698
|
+
const feedIdBuffer = (0, pythPullOracleUtils_1.getFeedIdUint8Array)(feedId);
|
|
3699
|
+
const receiverProgram = this.getReceiverProgram();
|
|
3700
|
+
const encodedParams = receiverProgram.coder.types.encode('PostUpdateParams', params);
|
|
3701
|
+
return this.program.instruction.updatePythPullOracle(feedIdBuffer, encodedParams, {
|
|
3702
|
+
accounts: {
|
|
3703
|
+
keeper: this.wallet.publicKey,
|
|
3704
|
+
pythSolanaReceiver: config_2.DRIFT_ORACLE_RECEIVER_ID,
|
|
3705
|
+
encodedVaa: encodedVaaAddress,
|
|
3706
|
+
priceFeed: (0, pda_1.getPythPullOraclePublicKey)(this.program.programId, feedIdBuffer),
|
|
3707
|
+
},
|
|
3708
|
+
});
|
|
3709
|
+
}
|
|
3710
|
+
async getBuildEncodedVaaIxs(vaa, guardianSet) {
|
|
3711
|
+
const postIxs = [];
|
|
3712
|
+
if (this.wormholeProgram === undefined) {
|
|
3713
|
+
this.wormholeProgram = new anchor_1.Program(pyth_solana_receiver_1.wormholeCoreBridgeIdl, address_1.DEFAULT_WORMHOLE_PROGRAM_ID, this.provider);
|
|
3714
|
+
}
|
|
3715
|
+
const encodedVaaKeypair = new web3_js_1.Keypair();
|
|
3716
|
+
postIxs.push(await this.wormholeProgram.account.encodedVaa.createInstruction(encodedVaaKeypair, vaa.length + 46));
|
|
3717
|
+
// Why do we need this too?
|
|
3718
|
+
postIxs.push(await this.wormholeProgram.methods
|
|
3719
|
+
.initEncodedVaa()
|
|
3720
|
+
.accounts({
|
|
3721
|
+
encodedVaa: encodedVaaKeypair.publicKey,
|
|
3722
|
+
})
|
|
3723
|
+
.instruction());
|
|
3724
|
+
// Split the write into two ixs
|
|
3725
|
+
postIxs.push(await this.wormholeProgram.methods
|
|
3726
|
+
.writeEncodedVaa({
|
|
3727
|
+
index: 0,
|
|
3728
|
+
data: vaa.subarray(0, 755),
|
|
3729
|
+
})
|
|
3730
|
+
.accounts({
|
|
3731
|
+
draftVaa: encodedVaaKeypair.publicKey,
|
|
3732
|
+
})
|
|
3733
|
+
.instruction());
|
|
3734
|
+
postIxs.push(await this.wormholeProgram.methods
|
|
3735
|
+
.writeEncodedVaa({
|
|
3736
|
+
index: 755,
|
|
3737
|
+
data: vaa.subarray(755),
|
|
3738
|
+
})
|
|
3739
|
+
.accounts({
|
|
3740
|
+
draftVaa: encodedVaaKeypair.publicKey,
|
|
3741
|
+
})
|
|
3742
|
+
.instruction());
|
|
3743
|
+
// Verify
|
|
3744
|
+
postIxs.push(await this.wormholeProgram.methods
|
|
3745
|
+
.verifyEncodedVaaV1()
|
|
3746
|
+
.accounts({
|
|
3747
|
+
guardianSet,
|
|
3748
|
+
draftVaa: encodedVaaKeypair.publicKey,
|
|
3749
|
+
})
|
|
3750
|
+
.instruction());
|
|
3751
|
+
return [postIxs, encodedVaaKeypair];
|
|
3752
|
+
}
|
|
3625
3753
|
handleSignedTransaction(signedTxs) {
|
|
3626
3754
|
if (this.enableMetricsEvents && this.metricsEventEmitter) {
|
|
3627
3755
|
this.metricsEventEmitter.emit('txSigned', signedTxs);
|
|
@@ -3633,9 +3761,7 @@ class DriftClient {
|
|
|
3633
3761
|
}
|
|
3634
3762
|
}
|
|
3635
3763
|
isVersionedTransaction(tx) {
|
|
3636
|
-
|
|
3637
|
-
const isVersionedTx = tx instanceof web3_js_1.VersionedTransaction || version !== undefined;
|
|
3638
|
-
return isVersionedTx;
|
|
3764
|
+
return (0, utils_2.isVersionedTransaction)(tx);
|
|
3639
3765
|
}
|
|
3640
3766
|
sendTransaction(tx, additionalSigners, opts, preSigned) {
|
|
3641
3767
|
const isVersionedTx = this.isVersionedTransaction(tx);
|
|
@@ -4,7 +4,7 @@ import { OracleInfo } from './oracles/types';
|
|
|
4
4
|
import { BulkAccountLoader } from './accounts/bulkAccountLoader';
|
|
5
5
|
import { DriftEnv } from './config';
|
|
6
6
|
import { TxSender } from './tx/types';
|
|
7
|
-
import { TxHandler } from './tx/txHandler';
|
|
7
|
+
import { TxHandler, TxHandlerConfig } from './tx/txHandler';
|
|
8
8
|
export type DriftClientConfig = {
|
|
9
9
|
connection: Connection;
|
|
10
10
|
wallet: IWallet;
|
|
@@ -28,6 +28,7 @@ export type DriftClientConfig = {
|
|
|
28
28
|
txVersion?: TransactionVersion;
|
|
29
29
|
txParams?: TxParams;
|
|
30
30
|
enableMetricsEvents?: boolean;
|
|
31
|
+
txHandlerConfig?: TxHandlerConfig;
|
|
31
32
|
};
|
|
32
33
|
export type DriftClientSubscriptionConfig = {
|
|
33
34
|
type: 'websocket';
|