@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
|
@@ -21,6 +21,7 @@ export type SpotMarketConfig = {
|
|
|
21
21
|
serumMarket?: PublicKey;
|
|
22
22
|
phoenixMarket?: PublicKey;
|
|
23
23
|
launchTs?: number;
|
|
24
|
+
pythFeedId?: string;
|
|
24
25
|
};
|
|
25
26
|
|
|
26
27
|
export const WRAPPED_SOL_MINT = new PublicKey(
|
|
@@ -36,6 +37,8 @@ export const DevnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
36
37
|
mint: new PublicKey('8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2'),
|
|
37
38
|
precision: new BN(10).pow(SIX),
|
|
38
39
|
precisionExp: SIX,
|
|
40
|
+
pythFeedId:
|
|
41
|
+
'0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
|
|
39
42
|
},
|
|
40
43
|
{
|
|
41
44
|
symbol: 'SOL',
|
|
@@ -49,6 +52,8 @@ export const DevnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
49
52
|
phoenixMarket: new PublicKey(
|
|
50
53
|
'78ehDnHgbkFxqXZwdFxa8HK7saX58GymeX2wNGdkqYLp'
|
|
51
54
|
),
|
|
55
|
+
pythFeedId:
|
|
56
|
+
'0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d',
|
|
52
57
|
},
|
|
53
58
|
{
|
|
54
59
|
symbol: 'BTC',
|
|
@@ -59,6 +64,8 @@ export const DevnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
59
64
|
precision: new BN(10).pow(SIX),
|
|
60
65
|
precisionExp: SIX,
|
|
61
66
|
serumMarket: new PublicKey('AGsmbVu3MS9u68GEYABWosQQCZwmLcBHu4pWEuBYH7Za'),
|
|
67
|
+
pythFeedId:
|
|
68
|
+
'0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43',
|
|
62
69
|
},
|
|
63
70
|
];
|
|
64
71
|
|
|
@@ -71,6 +78,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
71
78
|
mint: new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
|
|
72
79
|
precision: QUOTE_PRECISION,
|
|
73
80
|
precisionExp: QUOTE_PRECISION_EXP,
|
|
81
|
+
pythFeedId:
|
|
82
|
+
'0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
|
|
74
83
|
},
|
|
75
84
|
{
|
|
76
85
|
symbol: 'SOL',
|
|
@@ -84,6 +93,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
84
93
|
phoenixMarket: new PublicKey(
|
|
85
94
|
'4DoNfFBfF7UokCC2FQzriy7yHK6DY6NVdYpuekQ5pRgg'
|
|
86
95
|
),
|
|
96
|
+
pythFeedId:
|
|
97
|
+
'0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d',
|
|
87
98
|
},
|
|
88
99
|
{
|
|
89
100
|
symbol: 'mSOL',
|
|
@@ -94,6 +105,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
94
105
|
precision: new BN(10).pow(NINE),
|
|
95
106
|
precisionExp: NINE,
|
|
96
107
|
serumMarket: new PublicKey('9Lyhks5bQQxb9EyyX55NtgKQzpM4WK7JCmeaWuQ5MoXD'),
|
|
108
|
+
pythFeedId:
|
|
109
|
+
'0xc2289a6a43d2ce91c6f55caec370f4acc38a2ed477f58813334c6d03749ff2a4',
|
|
97
110
|
},
|
|
98
111
|
{
|
|
99
112
|
symbol: 'wBTC',
|
|
@@ -104,6 +117,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
104
117
|
precision: new BN(10).pow(EIGHT),
|
|
105
118
|
precisionExp: EIGHT,
|
|
106
119
|
serumMarket: new PublicKey('3BAKsQd3RuhZKES2DGysMhjBdwjZYKYmxRqnSMtZ4KSN'),
|
|
120
|
+
pythFeedId:
|
|
121
|
+
'0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43',
|
|
107
122
|
},
|
|
108
123
|
{
|
|
109
124
|
symbol: 'wETH',
|
|
@@ -117,6 +132,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
117
132
|
phoenixMarket: new PublicKey(
|
|
118
133
|
'Ew3vFDdtdGrknJAVVfraxCA37uNJtimXYPY4QjnfhFHH'
|
|
119
134
|
),
|
|
135
|
+
pythFeedId:
|
|
136
|
+
'0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace',
|
|
120
137
|
},
|
|
121
138
|
{
|
|
122
139
|
symbol: 'USDT',
|
|
@@ -127,6 +144,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
127
144
|
precision: QUOTE_PRECISION,
|
|
128
145
|
precisionExp: QUOTE_PRECISION_EXP,
|
|
129
146
|
serumMarket: new PublicKey('B2na8Awyd7cpC59iEU43FagJAPLigr3AP3s38KM982bu'),
|
|
147
|
+
pythFeedId:
|
|
148
|
+
'0x2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b',
|
|
130
149
|
},
|
|
131
150
|
{
|
|
132
151
|
symbol: 'jitoSOL',
|
|
@@ -140,6 +159,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
140
159
|
phoenixMarket: new PublicKey(
|
|
141
160
|
'5LQLfGtqcC5rm2WuGxJf4tjqYmDjsQAbKo2AMLQ8KB7p'
|
|
142
161
|
),
|
|
162
|
+
pythFeedId:
|
|
163
|
+
'0x67be9f519b95cf24338801051f9a808eff0a578ccb388db73b7f6fe1de019ffb',
|
|
143
164
|
},
|
|
144
165
|
{
|
|
145
166
|
symbol: 'PYTH',
|
|
@@ -153,6 +174,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
153
174
|
phoenixMarket: new PublicKey(
|
|
154
175
|
'2sTMN9A1D1qeZLF95XQgJCUPiKe5DiV52jLfZGqMP46m'
|
|
155
176
|
),
|
|
177
|
+
pythFeedId:
|
|
178
|
+
'0x0bbf28e9a841a1cc788f6a361b17ca072d0ea3098a1e5df1c3922d06719579ff',
|
|
156
179
|
},
|
|
157
180
|
{
|
|
158
181
|
symbol: 'bSOL',
|
|
@@ -163,6 +186,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
163
186
|
precision: new BN(10).pow(NINE),
|
|
164
187
|
precisionExp: NINE,
|
|
165
188
|
serumMarket: new PublicKey('ARjaHVxGCQfTvvKjLd7U7srvk6orthZSE6uqWchCczZc'),
|
|
189
|
+
pythFeedId:
|
|
190
|
+
'0x89875379e70f8fbadc17aef315adf3a8d5d160b811435537e03c97e8aac97d9c',
|
|
166
191
|
},
|
|
167
192
|
{
|
|
168
193
|
symbol: 'JTO',
|
|
@@ -176,6 +201,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
176
201
|
phoenixMarket: new PublicKey(
|
|
177
202
|
'BRLLmdtPGuuFn3BU6orYw4KHaohAEptBToi3dwRUnHQZ'
|
|
178
203
|
),
|
|
204
|
+
pythFeedId:
|
|
205
|
+
'0xb43660a5f790c69354b0729a5ef9d50d68f1df92107540210b9cccba1f947cc2',
|
|
179
206
|
},
|
|
180
207
|
{
|
|
181
208
|
symbol: 'WIF',
|
|
@@ -189,6 +216,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
189
216
|
phoenixMarket: new PublicKey(
|
|
190
217
|
'6ojSigXF7nDPyhFRgmn3V9ywhYseKF9J32ZrranMGVSX'
|
|
191
218
|
),
|
|
219
|
+
pythFeedId:
|
|
220
|
+
'0x4ca4beeca86f0d164160323817a4e42b10010a724c2217c6ee41b54cd4cc61fc',
|
|
192
221
|
},
|
|
193
222
|
{
|
|
194
223
|
symbol: 'JUP',
|
|
@@ -202,6 +231,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
202
231
|
'2pspvjWWaf3dNgt3jsgSzFCNvMGPb7t8FrEYvLGjvcCe'
|
|
203
232
|
),
|
|
204
233
|
launchTs: 1706731200000,
|
|
234
|
+
pythFeedId:
|
|
235
|
+
'0x0a0408d619e9380abad35060f9192039ed5042fa6f82301d0e48bb52be830996',
|
|
205
236
|
},
|
|
206
237
|
{
|
|
207
238
|
symbol: 'RNDR',
|
|
@@ -213,6 +244,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
213
244
|
precisionExp: EIGHT,
|
|
214
245
|
serumMarket: new PublicKey('2m7ZLEKtxWF29727DSb5D91erpXPUY1bqhRWRC3wQX7u'),
|
|
215
246
|
launchTs: 1708964021000,
|
|
247
|
+
pythFeedId:
|
|
248
|
+
'0xab7347771135fc733f8f38db462ba085ed3309955f42554a14fa13e855ac0e2f',
|
|
216
249
|
},
|
|
217
250
|
{
|
|
218
251
|
symbol: 'W',
|
|
@@ -226,6 +259,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
226
259
|
'8dFTCTAbtGuHsdDL8WEPrTU6pXFDrU1QSjBTutw8fwZk'
|
|
227
260
|
),
|
|
228
261
|
launchTs: 1712149014000,
|
|
262
|
+
pythFeedId:
|
|
263
|
+
'0xeff7446475e218517566ea99e72a4abec2e1bd8498b43b7d8331e29dcb059389',
|
|
229
264
|
},
|
|
230
265
|
{
|
|
231
266
|
symbol: 'TNSR',
|
|
@@ -239,6 +274,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
239
274
|
'AbJCZ9TAJiby5AY3cHcXS2gUdENC6mtsm6m7XpC2ZMvE'
|
|
240
275
|
),
|
|
241
276
|
launchTs: 1712593532000,
|
|
277
|
+
pythFeedId:
|
|
278
|
+
'0x05ecd4597cd48fe13d6cc3596c62af4f9675aee06e2e0b94c06d8bee2b659e05',
|
|
242
279
|
},
|
|
243
280
|
{
|
|
244
281
|
symbol: 'DRIFT',
|
|
@@ -252,6 +289,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
252
289
|
'8BV6rrWsUabnTDA3dE6A69oUDJAj3hMhtBHTJyXB7czp'
|
|
253
290
|
),
|
|
254
291
|
launchTs: 1715860800000,
|
|
292
|
+
pythFeedId:
|
|
293
|
+
'0x5c1690b27bb02446db17cdda13ccc2c1d609ad6d2ef5bf4983a85ea8b6f19d07',
|
|
255
294
|
},
|
|
256
295
|
{
|
|
257
296
|
symbol: 'INF',
|
|
@@ -262,6 +301,8 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
262
301
|
precision: new BN(10).pow(NINE),
|
|
263
302
|
precisionExp: NINE,
|
|
264
303
|
launchTs: 1716595200000,
|
|
304
|
+
pythFeedId:
|
|
305
|
+
'0xf51570985c642c49c2d6e50156390fdba80bb6d5f7fa389d2f012ced4f7d208f',
|
|
265
306
|
},
|
|
266
307
|
{
|
|
267
308
|
symbol: 'dSOL',
|
package/src/driftClient.ts
CHANGED
|
@@ -76,6 +76,7 @@ import {
|
|
|
76
76
|
getInsuranceFundStakeAccountPublicKey,
|
|
77
77
|
getPerpMarketPublicKey,
|
|
78
78
|
getPhoenixFulfillmentConfigPublicKey,
|
|
79
|
+
getPythPullOraclePublicKey,
|
|
79
80
|
getReferrerNamePublicKeySync,
|
|
80
81
|
getSerumFulfillmentConfigPublicKey,
|
|
81
82
|
getSerumSignerPublicKey,
|
|
@@ -127,8 +128,23 @@ import { getMarinadeDepositIx, getMarinadeFinanceProgram } from './marinade';
|
|
|
127
128
|
import { getOrderParams } from './orderParams';
|
|
128
129
|
import { numberToSafeBN } from './math/utils';
|
|
129
130
|
import { TransactionParamProcessor } from './tx/txParamProcessor';
|
|
130
|
-
import { isOracleValid } from './math/oracles';
|
|
131
|
+
import { isOracleValid, trimVaaSignatures } from './math/oracles';
|
|
131
132
|
import { TxHandler } from './tx/txHandler';
|
|
133
|
+
import {
|
|
134
|
+
wormholeCoreBridgeIdl,
|
|
135
|
+
pythSolanaReceiverIdl,
|
|
136
|
+
DEFAULT_RECEIVER_PROGRAM_ID,
|
|
137
|
+
} from '@pythnetwork/pyth-solana-receiver';
|
|
138
|
+
import { parseAccumulatorUpdateData } from '@pythnetwork/price-service-sdk';
|
|
139
|
+
import {
|
|
140
|
+
DEFAULT_WORMHOLE_PROGRAM_ID,
|
|
141
|
+
getGuardianSetPda,
|
|
142
|
+
} from '@pythnetwork/pyth-solana-receiver/lib/address';
|
|
143
|
+
import { DRIFT_ORACLE_RECEIVER_ID } from './config';
|
|
144
|
+
import { WormholeCoreBridgeSolana } from '@pythnetwork/pyth-solana-receiver/lib/idl/wormhole_core_bridge_solana';
|
|
145
|
+
import { PythSolanaReceiver } from '@pythnetwork/pyth-solana-receiver/lib/idl/pyth_solana_receiver';
|
|
146
|
+
import { getFeedIdUint8Array, trimFeedId } from './util/pythPullOracleUtils';
|
|
147
|
+
import { isVersionedTransaction } from './tx/utils';
|
|
132
148
|
|
|
133
149
|
type RemainingAccountParams = {
|
|
134
150
|
userAccounts: UserAccount[];
|
|
@@ -178,6 +194,9 @@ export class DriftClient {
|
|
|
178
194
|
|
|
179
195
|
txHandler: TxHandler;
|
|
180
196
|
|
|
197
|
+
receiverProgram?: Program<PythSolanaReceiver>;
|
|
198
|
+
wormholeProgram?: Program<WormholeCoreBridgeSolana>;
|
|
199
|
+
|
|
181
200
|
public get isSubscribed() {
|
|
182
201
|
return this._isSubscribed && this.accountSubscriber.isSubscribed;
|
|
183
202
|
}
|
|
@@ -227,6 +246,7 @@ export class DriftClient {
|
|
|
227
246
|
onSignedCb: this.handleSignedTransaction.bind(this),
|
|
228
247
|
preSignedCb: this.handlePreSignedTransaction.bind(this),
|
|
229
248
|
},
|
|
249
|
+
config: config.txHandlerConfig,
|
|
230
250
|
});
|
|
231
251
|
|
|
232
252
|
if (config.includeDelegates && config.subAccountIds) {
|
|
@@ -1800,25 +1820,14 @@ export class DriftClient {
|
|
|
1800
1820
|
});
|
|
1801
1821
|
}
|
|
1802
1822
|
|
|
1803
|
-
|
|
1804
|
-
* Deposit funds into the given spot market
|
|
1805
|
-
*
|
|
1806
|
-
* @param amount to deposit
|
|
1807
|
-
* @param marketIndex spot market index to deposit into
|
|
1808
|
-
* @param associatedTokenAccount can be the wallet public key if using native sol
|
|
1809
|
-
* @param subAccountId subaccountId to deposit
|
|
1810
|
-
* @param reduceOnly if true, deposit must not increase account risk
|
|
1811
|
-
*/
|
|
1812
|
-
public async deposit(
|
|
1823
|
+
public async createDepositTxn(
|
|
1813
1824
|
amount: BN,
|
|
1814
1825
|
marketIndex: number,
|
|
1815
1826
|
associatedTokenAccount: PublicKey,
|
|
1816
1827
|
subAccountId?: number,
|
|
1817
1828
|
reduceOnly = false,
|
|
1818
1829
|
txParams?: TxParams
|
|
1819
|
-
): Promise<
|
|
1820
|
-
const additionalSigners: Array<Signer> = [];
|
|
1821
|
-
|
|
1830
|
+
): Promise<ReturnType<typeof this.buildTransaction>> {
|
|
1822
1831
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
1823
1832
|
|
|
1824
1833
|
const isSolMarket = spotMarketAccount.mint.equals(WRAPPED_SOL_MINT);
|
|
@@ -1868,11 +1877,36 @@ export class DriftClient {
|
|
|
1868
1877
|
|
|
1869
1878
|
const tx = await this.buildTransaction(instructions, txParams);
|
|
1870
1879
|
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1880
|
+
return tx;
|
|
1881
|
+
}
|
|
1882
|
+
|
|
1883
|
+
/**
|
|
1884
|
+
* Deposit funds into the given spot market
|
|
1885
|
+
*
|
|
1886
|
+
* @param amount to deposit
|
|
1887
|
+
* @param marketIndex spot market index to deposit into
|
|
1888
|
+
* @param associatedTokenAccount can be the wallet public key if using native sol
|
|
1889
|
+
* @param subAccountId subaccountId to deposit
|
|
1890
|
+
* @param reduceOnly if true, deposit must not increase account risk
|
|
1891
|
+
*/
|
|
1892
|
+
public async deposit(
|
|
1893
|
+
amount: BN,
|
|
1894
|
+
marketIndex: number,
|
|
1895
|
+
associatedTokenAccount: PublicKey,
|
|
1896
|
+
subAccountId?: number,
|
|
1897
|
+
reduceOnly = false,
|
|
1898
|
+
txParams?: TxParams
|
|
1899
|
+
): Promise<TransactionSignature> {
|
|
1900
|
+
const tx = await this.createDepositTxn(
|
|
1901
|
+
amount,
|
|
1902
|
+
marketIndex,
|
|
1903
|
+
associatedTokenAccount,
|
|
1904
|
+
subAccountId,
|
|
1905
|
+
reduceOnly,
|
|
1906
|
+
txParams
|
|
1875
1907
|
);
|
|
1908
|
+
|
|
1909
|
+
const { txSig, slot } = await this.sendTransaction(tx, [], this.opts);
|
|
1876
1910
|
this.spotMarketLastSlotCache.set(marketIndex, slot);
|
|
1877
1911
|
return txSig;
|
|
1878
1912
|
}
|
|
@@ -2005,20 +2039,7 @@ export class DriftClient {
|
|
|
2005
2039
|
);
|
|
2006
2040
|
}
|
|
2007
2041
|
|
|
2008
|
-
|
|
2009
|
-
* Creates the User account for a user, and deposits some initial collateral
|
|
2010
|
-
* @param amount
|
|
2011
|
-
* @param userTokenAccount
|
|
2012
|
-
* @param marketIndex
|
|
2013
|
-
* @param subAccountId
|
|
2014
|
-
* @param name
|
|
2015
|
-
* @param fromSubAccountId
|
|
2016
|
-
* @param referrerInfo
|
|
2017
|
-
* @param donateAmount
|
|
2018
|
-
* @param txParams
|
|
2019
|
-
* @returns
|
|
2020
|
-
*/
|
|
2021
|
-
public async initializeUserAccountAndDepositCollateral(
|
|
2042
|
+
public async createInitializeUserAccountAndDepositCollateral(
|
|
2022
2043
|
amount: BN,
|
|
2023
2044
|
userTokenAccount: PublicKey,
|
|
2024
2045
|
marketIndex = 0,
|
|
@@ -2029,7 +2050,7 @@ export class DriftClient {
|
|
|
2029
2050
|
donateAmount?: BN,
|
|
2030
2051
|
txParams?: TxParams,
|
|
2031
2052
|
customMaxMarginRatio?: number
|
|
2032
|
-
): Promise<[
|
|
2053
|
+
): Promise<[Transaction | VersionedTransaction, PublicKey]> {
|
|
2033
2054
|
const ixs = [];
|
|
2034
2055
|
|
|
2035
2056
|
const [userAccountPublicKey, initializeUserAccountIx] =
|
|
@@ -2039,8 +2060,6 @@ export class DriftClient {
|
|
|
2039
2060
|
referrerInfo
|
|
2040
2061
|
);
|
|
2041
2062
|
|
|
2042
|
-
const additionalSigners: Array<Signer> = [];
|
|
2043
|
-
|
|
2044
2063
|
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
2045
2064
|
|
|
2046
2065
|
const isSolMarket = spotMarket.mint.equals(WRAPPED_SOL_MINT);
|
|
@@ -2134,6 +2153,49 @@ export class DriftClient {
|
|
|
2134
2153
|
|
|
2135
2154
|
const tx = await this.buildTransaction(ixs, txParams);
|
|
2136
2155
|
|
|
2156
|
+
return [tx, userAccountPublicKey];
|
|
2157
|
+
}
|
|
2158
|
+
|
|
2159
|
+
/**
|
|
2160
|
+
* Creates the User account for a user, and deposits some initial collateral
|
|
2161
|
+
* @param amount
|
|
2162
|
+
* @param userTokenAccount
|
|
2163
|
+
* @param marketIndex
|
|
2164
|
+
* @param subAccountId
|
|
2165
|
+
* @param name
|
|
2166
|
+
* @param fromSubAccountId
|
|
2167
|
+
* @param referrerInfo
|
|
2168
|
+
* @param donateAmount
|
|
2169
|
+
* @param txParams
|
|
2170
|
+
* @returns
|
|
2171
|
+
*/
|
|
2172
|
+
public async initializeUserAccountAndDepositCollateral(
|
|
2173
|
+
amount: BN,
|
|
2174
|
+
userTokenAccount: PublicKey,
|
|
2175
|
+
marketIndex = 0,
|
|
2176
|
+
subAccountId = 0,
|
|
2177
|
+
name?: string,
|
|
2178
|
+
fromSubAccountId?: number,
|
|
2179
|
+
referrerInfo?: ReferrerInfo,
|
|
2180
|
+
donateAmount?: BN,
|
|
2181
|
+
txParams?: TxParams,
|
|
2182
|
+
customMaxMarginRatio?: number
|
|
2183
|
+
): Promise<[TransactionSignature, PublicKey]> {
|
|
2184
|
+
const [tx, userAccountPublicKey] =
|
|
2185
|
+
await this.createInitializeUserAccountAndDepositCollateral(
|
|
2186
|
+
amount,
|
|
2187
|
+
userTokenAccount,
|
|
2188
|
+
marketIndex,
|
|
2189
|
+
subAccountId,
|
|
2190
|
+
name,
|
|
2191
|
+
fromSubAccountId,
|
|
2192
|
+
referrerInfo,
|
|
2193
|
+
donateAmount,
|
|
2194
|
+
txParams,
|
|
2195
|
+
customMaxMarginRatio
|
|
2196
|
+
);
|
|
2197
|
+
const additionalSigners: Array<Signer> = [];
|
|
2198
|
+
|
|
2137
2199
|
const { txSig, slot } = await this.sendTransaction(
|
|
2138
2200
|
tx,
|
|
2139
2201
|
additionalSigners,
|
|
@@ -4118,6 +4180,10 @@ export class DriftClient {
|
|
|
4118
4180
|
const outMarket = this.getSpotMarketAccount(outMarketIndex);
|
|
4119
4181
|
const inMarket = this.getSpotMarketAccount(inMarketIndex);
|
|
4120
4182
|
|
|
4183
|
+
const isExactOut = swapMode === 'ExactOut' || quote.swapMode === 'ExactOut';
|
|
4184
|
+
const amountIn = new BN(quote.inAmount);
|
|
4185
|
+
const exactOutBufferedAmountIn = amountIn.muln(1001).divn(1000); // Add 10bp buffer
|
|
4186
|
+
|
|
4121
4187
|
if (!quote) {
|
|
4122
4188
|
const fetchedQuote = await jupiterClient.getQuote({
|
|
4123
4189
|
inputMint: inMarket.mint,
|
|
@@ -4198,7 +4264,7 @@ export class DriftClient {
|
|
|
4198
4264
|
const { beginSwapIx, endSwapIx } = await this.getSwapIx({
|
|
4199
4265
|
outMarketIndex,
|
|
4200
4266
|
inMarketIndex,
|
|
4201
|
-
amountIn:
|
|
4267
|
+
amountIn: isExactOut ? exactOutBufferedAmountIn : amountIn,
|
|
4202
4268
|
inTokenAccount: inAssociatedTokenAccount,
|
|
4203
4269
|
outTokenAccount: outAssociatedTokenAccount,
|
|
4204
4270
|
reduceOnly,
|
|
@@ -6844,6 +6910,250 @@ export class DriftClient {
|
|
|
6844
6910
|
return undefined;
|
|
6845
6911
|
}
|
|
6846
6912
|
|
|
6913
|
+
public getReceiverProgram(): Program<PythSolanaReceiver> {
|
|
6914
|
+
if (this.receiverProgram === undefined) {
|
|
6915
|
+
this.receiverProgram = new Program(
|
|
6916
|
+
pythSolanaReceiverIdl,
|
|
6917
|
+
DEFAULT_RECEIVER_PROGRAM_ID,
|
|
6918
|
+
this.provider
|
|
6919
|
+
);
|
|
6920
|
+
}
|
|
6921
|
+
return this.receiverProgram;
|
|
6922
|
+
}
|
|
6923
|
+
|
|
6924
|
+
public async postPythPullOracleUpdateAtomic(
|
|
6925
|
+
vaaString: string,
|
|
6926
|
+
feedId: string
|
|
6927
|
+
): Promise<TransactionSignature> {
|
|
6928
|
+
const postIxs = await this.getPostPythPullOracleUpdateAtomicIxs(
|
|
6929
|
+
vaaString,
|
|
6930
|
+
feedId
|
|
6931
|
+
);
|
|
6932
|
+
const tx = await this.buildTransaction(postIxs);
|
|
6933
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
6934
|
+
|
|
6935
|
+
return txSig;
|
|
6936
|
+
}
|
|
6937
|
+
|
|
6938
|
+
public async getPostPythPullOracleUpdateAtomicIxs(
|
|
6939
|
+
vaaString: string,
|
|
6940
|
+
feedId: string,
|
|
6941
|
+
numSignatures = 2
|
|
6942
|
+
): Promise<TransactionInstruction[]> {
|
|
6943
|
+
feedId = trimFeedId(feedId);
|
|
6944
|
+
const accumulatorUpdateData = parseAccumulatorUpdateData(
|
|
6945
|
+
Buffer.from(vaaString, 'base64')
|
|
6946
|
+
);
|
|
6947
|
+
const guardianSetIndex = accumulatorUpdateData.vaa.readUInt32BE(1);
|
|
6948
|
+
const guardianSet = getGuardianSetPda(
|
|
6949
|
+
guardianSetIndex,
|
|
6950
|
+
DEFAULT_WORMHOLE_PROGRAM_ID
|
|
6951
|
+
);
|
|
6952
|
+
const trimmedVaa = trimVaaSignatures(
|
|
6953
|
+
accumulatorUpdateData.vaa,
|
|
6954
|
+
numSignatures
|
|
6955
|
+
);
|
|
6956
|
+
|
|
6957
|
+
const postIxs: TransactionInstruction[] = [];
|
|
6958
|
+
for (const update of accumulatorUpdateData.updates) {
|
|
6959
|
+
postIxs.push(
|
|
6960
|
+
await this.getSinglePostPythPullOracleAtomicIx(
|
|
6961
|
+
{
|
|
6962
|
+
vaa: trimmedVaa,
|
|
6963
|
+
merklePriceUpdate: update,
|
|
6964
|
+
},
|
|
6965
|
+
feedId,
|
|
6966
|
+
guardianSet
|
|
6967
|
+
)
|
|
6968
|
+
);
|
|
6969
|
+
}
|
|
6970
|
+
|
|
6971
|
+
return postIxs;
|
|
6972
|
+
}
|
|
6973
|
+
|
|
6974
|
+
public async getSinglePostPythPullOracleAtomicIx(
|
|
6975
|
+
params: {
|
|
6976
|
+
vaa: Buffer;
|
|
6977
|
+
merklePriceUpdate: {
|
|
6978
|
+
message: Buffer;
|
|
6979
|
+
proof: number[][];
|
|
6980
|
+
};
|
|
6981
|
+
},
|
|
6982
|
+
feedId: string,
|
|
6983
|
+
guardianSet: PublicKey
|
|
6984
|
+
): Promise<TransactionInstruction> {
|
|
6985
|
+
const feedIdBuffer = getFeedIdUint8Array(feedId);
|
|
6986
|
+
const receiverProgram = this.getReceiverProgram();
|
|
6987
|
+
|
|
6988
|
+
const encodedParams = receiverProgram.coder.types.encode(
|
|
6989
|
+
'PostUpdateAtomicParams',
|
|
6990
|
+
params
|
|
6991
|
+
);
|
|
6992
|
+
|
|
6993
|
+
return this.program.instruction.postPythPullOracleUpdateAtomic(
|
|
6994
|
+
feedIdBuffer,
|
|
6995
|
+
encodedParams,
|
|
6996
|
+
{
|
|
6997
|
+
accounts: {
|
|
6998
|
+
keeper: this.wallet.publicKey,
|
|
6999
|
+
pythSolanaReceiver: DRIFT_ORACLE_RECEIVER_ID,
|
|
7000
|
+
guardianSet,
|
|
7001
|
+
priceFeed: getPythPullOraclePublicKey(
|
|
7002
|
+
this.program.programId,
|
|
7003
|
+
feedIdBuffer
|
|
7004
|
+
),
|
|
7005
|
+
},
|
|
7006
|
+
}
|
|
7007
|
+
);
|
|
7008
|
+
}
|
|
7009
|
+
|
|
7010
|
+
public async updatePythPullOracle(
|
|
7011
|
+
vaaString: string,
|
|
7012
|
+
feedId: string
|
|
7013
|
+
): Promise<TransactionSignature> {
|
|
7014
|
+
feedId = trimFeedId(feedId);
|
|
7015
|
+
const accumulatorUpdateData = parseAccumulatorUpdateData(
|
|
7016
|
+
Buffer.from(vaaString, 'base64')
|
|
7017
|
+
);
|
|
7018
|
+
const guardianSetIndex = accumulatorUpdateData.vaa.readUInt32BE(1);
|
|
7019
|
+
const guardianSet = getGuardianSetPda(
|
|
7020
|
+
guardianSetIndex,
|
|
7021
|
+
DEFAULT_WORMHOLE_PROGRAM_ID
|
|
7022
|
+
);
|
|
7023
|
+
|
|
7024
|
+
const [postIxs, encodedVaaAddress] = await this.getBuildEncodedVaaIxs(
|
|
7025
|
+
accumulatorUpdateData.vaa,
|
|
7026
|
+
guardianSet
|
|
7027
|
+
);
|
|
7028
|
+
|
|
7029
|
+
for (const update of accumulatorUpdateData.updates) {
|
|
7030
|
+
postIxs.push(
|
|
7031
|
+
await this.getUpdatePythPullOracleIxs(
|
|
7032
|
+
{
|
|
7033
|
+
merklePriceUpdate: update,
|
|
7034
|
+
},
|
|
7035
|
+
feedId,
|
|
7036
|
+
encodedVaaAddress.publicKey
|
|
7037
|
+
)
|
|
7038
|
+
);
|
|
7039
|
+
}
|
|
7040
|
+
|
|
7041
|
+
const tx = await this.buildTransaction(postIxs);
|
|
7042
|
+
const { txSig } = await this.sendTransaction(
|
|
7043
|
+
tx,
|
|
7044
|
+
[encodedVaaAddress],
|
|
7045
|
+
this.opts
|
|
7046
|
+
);
|
|
7047
|
+
|
|
7048
|
+
return txSig;
|
|
7049
|
+
}
|
|
7050
|
+
|
|
7051
|
+
public async getUpdatePythPullOracleIxs(
|
|
7052
|
+
params: {
|
|
7053
|
+
merklePriceUpdate: {
|
|
7054
|
+
message: Buffer;
|
|
7055
|
+
proof: number[][];
|
|
7056
|
+
};
|
|
7057
|
+
},
|
|
7058
|
+
feedId: string,
|
|
7059
|
+
encodedVaaAddress: PublicKey
|
|
7060
|
+
): Promise<TransactionInstruction> {
|
|
7061
|
+
const feedIdBuffer = getFeedIdUint8Array(feedId);
|
|
7062
|
+
const receiverProgram = this.getReceiverProgram();
|
|
7063
|
+
|
|
7064
|
+
const encodedParams = receiverProgram.coder.types.encode(
|
|
7065
|
+
'PostUpdateParams',
|
|
7066
|
+
params
|
|
7067
|
+
);
|
|
7068
|
+
|
|
7069
|
+
return this.program.instruction.updatePythPullOracle(
|
|
7070
|
+
feedIdBuffer,
|
|
7071
|
+
encodedParams,
|
|
7072
|
+
{
|
|
7073
|
+
accounts: {
|
|
7074
|
+
keeper: this.wallet.publicKey,
|
|
7075
|
+
pythSolanaReceiver: DRIFT_ORACLE_RECEIVER_ID,
|
|
7076
|
+
encodedVaa: encodedVaaAddress,
|
|
7077
|
+
priceFeed: getPythPullOraclePublicKey(
|
|
7078
|
+
this.program.programId,
|
|
7079
|
+
feedIdBuffer
|
|
7080
|
+
),
|
|
7081
|
+
},
|
|
7082
|
+
}
|
|
7083
|
+
);
|
|
7084
|
+
}
|
|
7085
|
+
|
|
7086
|
+
public async getBuildEncodedVaaIxs(
|
|
7087
|
+
vaa: Buffer,
|
|
7088
|
+
guardianSet: PublicKey
|
|
7089
|
+
): Promise<[TransactionInstruction[], Keypair]> {
|
|
7090
|
+
const postIxs: TransactionInstruction[] = [];
|
|
7091
|
+
|
|
7092
|
+
if (this.wormholeProgram === undefined) {
|
|
7093
|
+
this.wormholeProgram = new Program(
|
|
7094
|
+
wormholeCoreBridgeIdl,
|
|
7095
|
+
DEFAULT_WORMHOLE_PROGRAM_ID,
|
|
7096
|
+
this.provider
|
|
7097
|
+
);
|
|
7098
|
+
}
|
|
7099
|
+
|
|
7100
|
+
const encodedVaaKeypair = new Keypair();
|
|
7101
|
+
postIxs.push(
|
|
7102
|
+
await this.wormholeProgram.account.encodedVaa.createInstruction(
|
|
7103
|
+
encodedVaaKeypair,
|
|
7104
|
+
vaa.length + 46
|
|
7105
|
+
)
|
|
7106
|
+
);
|
|
7107
|
+
|
|
7108
|
+
// Why do we need this too?
|
|
7109
|
+
postIxs.push(
|
|
7110
|
+
await this.wormholeProgram.methods
|
|
7111
|
+
.initEncodedVaa()
|
|
7112
|
+
.accounts({
|
|
7113
|
+
encodedVaa: encodedVaaKeypair.publicKey,
|
|
7114
|
+
})
|
|
7115
|
+
.instruction()
|
|
7116
|
+
);
|
|
7117
|
+
|
|
7118
|
+
// Split the write into two ixs
|
|
7119
|
+
postIxs.push(
|
|
7120
|
+
await this.wormholeProgram.methods
|
|
7121
|
+
.writeEncodedVaa({
|
|
7122
|
+
index: 0,
|
|
7123
|
+
data: vaa.subarray(0, 755),
|
|
7124
|
+
})
|
|
7125
|
+
.accounts({
|
|
7126
|
+
draftVaa: encodedVaaKeypair.publicKey,
|
|
7127
|
+
})
|
|
7128
|
+
.instruction()
|
|
7129
|
+
);
|
|
7130
|
+
|
|
7131
|
+
postIxs.push(
|
|
7132
|
+
await this.wormholeProgram.methods
|
|
7133
|
+
.writeEncodedVaa({
|
|
7134
|
+
index: 755,
|
|
7135
|
+
data: vaa.subarray(755),
|
|
7136
|
+
})
|
|
7137
|
+
.accounts({
|
|
7138
|
+
draftVaa: encodedVaaKeypair.publicKey,
|
|
7139
|
+
})
|
|
7140
|
+
.instruction()
|
|
7141
|
+
);
|
|
7142
|
+
|
|
7143
|
+
// Verify
|
|
7144
|
+
postIxs.push(
|
|
7145
|
+
await this.wormholeProgram.methods
|
|
7146
|
+
.verifyEncodedVaaV1()
|
|
7147
|
+
.accounts({
|
|
7148
|
+
guardianSet,
|
|
7149
|
+
draftVaa: encodedVaaKeypair.publicKey,
|
|
7150
|
+
})
|
|
7151
|
+
.instruction()
|
|
7152
|
+
);
|
|
7153
|
+
|
|
7154
|
+
return [postIxs, encodedVaaKeypair];
|
|
7155
|
+
}
|
|
7156
|
+
|
|
6847
7157
|
private handleSignedTransaction(signedTxs: SignedTxData[]) {
|
|
6848
7158
|
if (this.enableMetricsEvents && this.metricsEventEmitter) {
|
|
6849
7159
|
this.metricsEventEmitter.emit('txSigned', signedTxs);
|
|
@@ -6859,11 +7169,7 @@ export class DriftClient {
|
|
|
6859
7169
|
private isVersionedTransaction(
|
|
6860
7170
|
tx: Transaction | VersionedTransaction
|
|
6861
7171
|
): boolean {
|
|
6862
|
-
|
|
6863
|
-
const isVersionedTx =
|
|
6864
|
-
tx instanceof VersionedTransaction || version !== undefined;
|
|
6865
|
-
|
|
6866
|
-
return isVersionedTx;
|
|
7172
|
+
return isVersionedTransaction(tx);
|
|
6867
7173
|
}
|
|
6868
7174
|
|
|
6869
7175
|
sendTransaction(
|
package/src/driftClientConfig.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { OracleInfo } from './oracles/types';
|
|
|
10
10
|
import { BulkAccountLoader } from './accounts/bulkAccountLoader';
|
|
11
11
|
import { DriftEnv } from './config';
|
|
12
12
|
import { TxSender } from './tx/types';
|
|
13
|
-
import { TxHandler } from './tx/txHandler';
|
|
13
|
+
import { TxHandler, TxHandlerConfig } from './tx/txHandler';
|
|
14
14
|
|
|
15
15
|
export type DriftClientConfig = {
|
|
16
16
|
connection: Connection;
|
|
@@ -35,6 +35,7 @@ export type DriftClientConfig = {
|
|
|
35
35
|
txVersion?: TransactionVersion; // which tx version to use
|
|
36
36
|
txParams?: TxParams; // default tx params to use
|
|
37
37
|
enableMetricsEvents?: boolean;
|
|
38
|
+
txHandlerConfig?: TxHandlerConfig;
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
export type DriftClientSubscriptionConfig =
|