@drift-labs/sdk 2.84.0-beta.5 → 2.84.0-beta.7
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/adminClient.d.ts +4 -2
- package/lib/adminClient.js +21 -4
- package/lib/blockhashSubscriber/BlockhashSubscriber.d.ts +7 -1
- package/lib/blockhashSubscriber/BlockhashSubscriber.js +11 -2
- package/lib/constants/spotMarkets.js +10 -0
- package/lib/driftClient.d.ts +30 -3
- package/lib/driftClient.js +108 -82
- package/lib/factory/oracleClient.js +13 -0
- package/lib/idl/drift.json +17 -0
- package/lib/math/spotBalance.js +7 -1
- package/lib/oracles/pythPullClient.d.ts +18 -0
- package/lib/oracles/pythPullClient.js +60 -0
- package/lib/tx/txHandler.d.ts +23 -20
- package/lib/tx/txHandler.js +56 -57
- package/lib/types.d.ts +17 -0
- package/lib/types.js +4 -0
- package/package.json +11 -9
- package/src/adminClient.ts +45 -3
- package/src/blockhashSubscriber/BlockhashSubscriber.ts +15 -2
- package/src/constants/spotMarkets.ts +10 -0
- package/src/driftClient.ts +308 -167
- package/src/factory/oracleClient.ts +17 -0
- package/src/idl/drift.json +17 -0
- package/src/math/spotBalance.ts +15 -1
- package/src/oracles/pythPullClient.ts +112 -0
- package/src/tx/txHandler.ts +87 -78
- package/src/types.ts +12 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertPythPrice = exports.PythPullClient = void 0;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const anchor_1 = require("@coral-xyz/anchor");
|
|
6
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
7
|
+
const pyth_solana_receiver_1 = require("@pythnetwork/pyth-solana-receiver");
|
|
8
|
+
const __1 = require("..");
|
|
9
|
+
class PythPullClient {
|
|
10
|
+
constructor(connection, multiple = numericConstants_1.ONE, stableCoin = false) {
|
|
11
|
+
this.connection = connection;
|
|
12
|
+
this.multiple = multiple;
|
|
13
|
+
this.stableCoin = stableCoin;
|
|
14
|
+
const provider = new anchor_1.AnchorProvider(this.connection,
|
|
15
|
+
//@ts-ignore
|
|
16
|
+
new __1.Wallet(new web3_js_1.Keypair()), {
|
|
17
|
+
commitment: connection.commitment,
|
|
18
|
+
});
|
|
19
|
+
this.receiver = new anchor_1.Program(pyth_solana_receiver_1.pythSolanaReceiverIdl, pyth_solana_receiver_1.DEFAULT_RECEIVER_PROGRAM_ID, provider);
|
|
20
|
+
this.decodeFunc =
|
|
21
|
+
this.receiver.account.priceUpdateV2.coder.accounts.decodeUnchecked.bind(this.receiver.account.priceUpdateV2.coder.accounts);
|
|
22
|
+
}
|
|
23
|
+
async getOraclePriceData(pricePublicKey) {
|
|
24
|
+
const accountInfo = await this.connection.getAccountInfo(pricePublicKey);
|
|
25
|
+
return this.getOraclePriceDataFromBuffer(accountInfo.data);
|
|
26
|
+
}
|
|
27
|
+
getOraclePriceDataFromBuffer(buffer) {
|
|
28
|
+
const message = this.decodeFunc('priceUpdateV2', buffer);
|
|
29
|
+
const priceData = message.priceMessage;
|
|
30
|
+
const confidence = convertPythPrice(priceData.conf, priceData.exponent, this.multiple);
|
|
31
|
+
let price = convertPythPrice(priceData.price, priceData.exponent, this.multiple);
|
|
32
|
+
if (this.stableCoin) {
|
|
33
|
+
price = getStableCoinPrice(price, confidence);
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
price,
|
|
37
|
+
slot: message.postedSlot,
|
|
38
|
+
confidence,
|
|
39
|
+
twap: convertPythPrice(priceData.price, priceData.exponent, this.multiple),
|
|
40
|
+
twapConfidence: convertPythPrice(priceData.price, priceData.exponent, this.multiple),
|
|
41
|
+
hasSufficientNumberOfDataPoints: true,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.PythPullClient = PythPullClient;
|
|
46
|
+
function convertPythPrice(price, exponent, multiple) {
|
|
47
|
+
exponent = Math.abs(exponent);
|
|
48
|
+
const pythPrecision = numericConstants_1.TEN.pow(new anchor_1.BN(exponent).abs()).div(multiple);
|
|
49
|
+
return price.mul(numericConstants_1.PRICE_PRECISION).div(pythPrecision);
|
|
50
|
+
}
|
|
51
|
+
exports.convertPythPrice = convertPythPrice;
|
|
52
|
+
const fiveBPS = new anchor_1.BN(500);
|
|
53
|
+
function getStableCoinPrice(price, confidence) {
|
|
54
|
+
if (price.sub(numericConstants_1.QUOTE_PRECISION).abs().lt(anchor_1.BN.min(confidence, fiveBPS))) {
|
|
55
|
+
return numericConstants_1.QUOTE_PRECISION;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
return price;
|
|
59
|
+
}
|
|
60
|
+
}
|
package/lib/tx/txHandler.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AddressLookupTableAccount, BlockhashWithExpiryBlockHeight, Commitment, ConfirmOptions, Connection, Signer, Transaction, TransactionInstruction, TransactionVersion, VersionedTransaction } from '@solana/web3.js';
|
|
2
|
-
import { DriftClientMetricsEvents, IWallet, TxParams } from '../types';
|
|
2
|
+
import { DriftClientMetricsEvents, IWallet, MappedRecord, SignedTxData, TxParams } from '../types';
|
|
3
3
|
export declare const COMPUTE_UNITS_DEFAULT = 200000;
|
|
4
4
|
export type TxBuildingProps = {
|
|
5
5
|
instructions: TransactionInstruction | TransactionInstruction[];
|
|
@@ -61,6 +61,7 @@ export declare class TxHandler {
|
|
|
61
61
|
*/
|
|
62
62
|
prepareTx(tx: Transaction, additionalSigners: Array<Signer>, wallet?: IWallet, confirmationOpts?: ConfirmOptions, preSigned?: boolean, recentBlockhash?: BlockhashWithExpiryBlockHeight): Promise<Transaction>;
|
|
63
63
|
private isVersionedTransaction;
|
|
64
|
+
private isLegacyTransaction;
|
|
64
65
|
private getTxSigFromSignedTx;
|
|
65
66
|
private getBlockhashFromSignedTx;
|
|
66
67
|
private signTx;
|
|
@@ -75,7 +76,7 @@ export declare class TxHandler {
|
|
|
75
76
|
private _generateVersionedTransaction;
|
|
76
77
|
generateLegacyVersionedTransaction(recentBlockhash: BlockhashWithExpiryBlockHeight, ixs: TransactionInstruction[], wallet?: IWallet): VersionedTransaction;
|
|
77
78
|
generateVersionedTransaction(recentBlockhash: BlockhashWithExpiryBlockHeight, ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], wallet?: IWallet): VersionedTransaction;
|
|
78
|
-
generateLegacyTransaction(ixs: TransactionInstruction[]): Transaction;
|
|
79
|
+
generateLegacyTransaction(ixs: TransactionInstruction[], recentBlockhash?: BlockhashWithExpiryBlockHeight): Transaction;
|
|
79
80
|
/**
|
|
80
81
|
* Accepts multiple instructions and builds a transaction for each. Prevents needing to spam RPC with requests for the same blockhash.
|
|
81
82
|
* @param props
|
|
@@ -96,46 +97,48 @@ export declare class TxHandler {
|
|
|
96
97
|
buildTransaction(props: TxBuildingProps): Promise<Transaction | VersionedTransaction>;
|
|
97
98
|
wrapInTx(instruction: TransactionInstruction, computeUnits?: number, computeUnitsPrice?: number): Transaction;
|
|
98
99
|
/**
|
|
99
|
-
*
|
|
100
|
+
* Get a map of signed and prepared transactions from an array of legacy transactions
|
|
100
101
|
* @param txsToSign
|
|
101
102
|
* @param keys
|
|
102
103
|
* @param wallet
|
|
103
104
|
* @param commitment
|
|
104
105
|
* @returns
|
|
105
106
|
*/
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
getPreparedAndSignedLegacyTransactionMap<T extends Record<string, Transaction | undefined>>(txsMap: T, wallet?: IWallet, commitment?: Commitment, recentBlockhash?: BlockhashWithExpiryBlockHeight): Promise<{
|
|
108
|
+
signedTxMap: T;
|
|
109
|
+
signedTxData: SignedTxData[];
|
|
108
110
|
}>;
|
|
109
111
|
/**
|
|
110
|
-
* Get a map of signed
|
|
112
|
+
* Get a map of signed transactions from an array of transactions to sign.
|
|
111
113
|
* @param txsToSign
|
|
112
114
|
* @param keys
|
|
113
115
|
* @param wallet
|
|
114
|
-
* @param commitment
|
|
115
116
|
* @returns
|
|
116
117
|
*/
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
getSignedTransactionMap<T extends Record<string, Transaction | VersionedTransaction | undefined>>(txsToSignMap: T, wallet?: IWallet): Promise<{
|
|
119
|
+
signedTxMap: T;
|
|
120
|
+
signedTxData: SignedTxData[];
|
|
119
121
|
}>;
|
|
120
122
|
/**
|
|
121
|
-
*
|
|
122
|
-
* @param
|
|
123
|
-
* @param keys
|
|
124
|
-
* @param wallet
|
|
123
|
+
* Accepts multiple instructions and builds a transaction for each. Prevents needing to spam RPC with requests for the same blockhash.
|
|
124
|
+
* @param props
|
|
125
125
|
* @returns
|
|
126
126
|
*/
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
127
|
+
buildTransactionsMap<T extends Record<string, TransactionInstruction | TransactionInstruction[]>>(props: Omit<TxBuildingProps, 'instructions'> & {
|
|
128
|
+
instructionsMap: T;
|
|
129
|
+
}): Promise<MappedRecord<T, Transaction | VersionedTransaction>>;
|
|
130
130
|
/**
|
|
131
131
|
* Builds and signs transactions from a given array of instructions for multiple transactions.
|
|
132
132
|
* @param props
|
|
133
133
|
* @returns
|
|
134
134
|
*/
|
|
135
|
-
buildAndSignTransactionMap(props: Omit<TxBuildingProps, 'instructions'> & {
|
|
136
|
-
|
|
137
|
-
instructions: (TransactionInstruction | TransactionInstruction[])[];
|
|
135
|
+
buildAndSignTransactionMap<T extends Record<string, TransactionInstruction | TransactionInstruction[]>>(props: Omit<TxBuildingProps, 'instructions'> & {
|
|
136
|
+
instructionsMap: T;
|
|
138
137
|
}): Promise<{
|
|
139
|
-
|
|
138
|
+
signedTxMap: Record<string, Transaction>;
|
|
139
|
+
signedTxData: SignedTxData[];
|
|
140
|
+
} | {
|
|
141
|
+
signedTxMap: MappedRecord<T, Transaction | VersionedTransaction>;
|
|
142
|
+
signedTxData: SignedTxData[];
|
|
140
143
|
}>;
|
|
141
144
|
}
|
package/lib/tx/txHandler.js
CHANGED
|
@@ -82,6 +82,9 @@ class TxHandler {
|
|
|
82
82
|
isVersionedTransaction(tx) {
|
|
83
83
|
return (tx === null || tx === void 0 ? void 0 : tx.message) && true;
|
|
84
84
|
}
|
|
85
|
+
isLegacyTransaction(tx) {
|
|
86
|
+
return !this.isVersionedTransaction(tx);
|
|
87
|
+
}
|
|
85
88
|
getTxSigFromSignedTx(signedTx) {
|
|
86
89
|
if (this.isVersionedTransaction(signedTx)) {
|
|
87
90
|
return bs58_1.default.encode(Buffer.from(signedTx.signatures[0]));
|
|
@@ -152,7 +155,7 @@ class TxHandler {
|
|
|
152
155
|
}
|
|
153
156
|
return;
|
|
154
157
|
}
|
|
155
|
-
const
|
|
158
|
+
const signedTxData = txData.map((tx) => {
|
|
156
159
|
const lastValidBlockHeight = this.blockHashToLastValidBlockHeightLookup[tx.blockHash];
|
|
157
160
|
return {
|
|
158
161
|
...tx,
|
|
@@ -160,8 +163,9 @@ class TxHandler {
|
|
|
160
163
|
};
|
|
161
164
|
});
|
|
162
165
|
if (this.onSignedCb) {
|
|
163
|
-
this.onSignedCb(
|
|
166
|
+
this.onSignedCb(signedTxData);
|
|
164
167
|
}
|
|
168
|
+
return signedTxData;
|
|
165
169
|
}
|
|
166
170
|
/**
|
|
167
171
|
* Gets transaction params with extra processing applied, like using the simulated compute units or using a dynamically calculated compute unit price.
|
|
@@ -225,8 +229,12 @@ class TxHandler {
|
|
|
225
229
|
tx.SIGNATURE_BLOCK_AND_EXPIRY = recentBlockhash;
|
|
226
230
|
return tx;
|
|
227
231
|
}
|
|
228
|
-
generateLegacyTransaction(ixs) {
|
|
229
|
-
|
|
232
|
+
generateLegacyTransaction(ixs, recentBlockhash) {
|
|
233
|
+
const tx = new web3_js_1.Transaction().add(...ixs);
|
|
234
|
+
if (recentBlockhash) {
|
|
235
|
+
tx.recentBlockhash = recentBlockhash.blockhash;
|
|
236
|
+
}
|
|
237
|
+
return tx;
|
|
230
238
|
}
|
|
231
239
|
/**
|
|
232
240
|
* Accepts multiple instructions and builds a transaction for each. Prevents needing to spam RPC with requests for the same blockhash.
|
|
@@ -302,7 +310,7 @@ class TxHandler {
|
|
|
302
310
|
return this.generateLegacyVersionedTransaction(recentBlockhash, allIx);
|
|
303
311
|
}
|
|
304
312
|
else {
|
|
305
|
-
return this.generateLegacyTransaction(allIx);
|
|
313
|
+
return this.generateLegacyTransaction(allIx, recentBlockhash);
|
|
306
314
|
}
|
|
307
315
|
}
|
|
308
316
|
else {
|
|
@@ -332,30 +340,6 @@ class TxHandler {
|
|
|
332
340
|
}
|
|
333
341
|
return tx.add(instruction);
|
|
334
342
|
}
|
|
335
|
-
/**
|
|
336
|
-
* Build a map of transactions from an array of instructions for multiple transactions.
|
|
337
|
-
* @param txsToSign
|
|
338
|
-
* @param keys
|
|
339
|
-
* @param wallet
|
|
340
|
-
* @param commitment
|
|
341
|
-
* @returns
|
|
342
|
-
*/
|
|
343
|
-
async buildTransactionMap(txsToSign, keys, wallet, commitment, recentBlockhash) {
|
|
344
|
-
var _a, _b;
|
|
345
|
-
recentBlockhash = recentBlockhash
|
|
346
|
-
? recentBlockhash
|
|
347
|
-
: await this.getLatestBlockhashForTransaction();
|
|
348
|
-
this.addHashAndExpiryToLookup(recentBlockhash);
|
|
349
|
-
for (const tx of txsToSign) {
|
|
350
|
-
if (!tx)
|
|
351
|
-
continue;
|
|
352
|
-
tx.recentBlockhash = recentBlockhash.blockhash;
|
|
353
|
-
tx.feePayer = (_a = wallet === null || wallet === void 0 ? void 0 : wallet.publicKey) !== null && _a !== void 0 ? _a : (_b = this.wallet) === null || _b === void 0 ? void 0 : _b.publicKey;
|
|
354
|
-
// @ts-ignore
|
|
355
|
-
tx.SIGNATURE_BLOCK_AND_EXPIRY = recentBlockhash;
|
|
356
|
-
}
|
|
357
|
-
return this.getSignedTransactionMap(txsToSign, keys, wallet);
|
|
358
|
-
}
|
|
359
343
|
/**
|
|
360
344
|
* Get a map of signed and prepared transactions from an array of legacy transactions
|
|
361
345
|
* @param txsToSign
|
|
@@ -364,13 +348,13 @@ class TxHandler {
|
|
|
364
348
|
* @param commitment
|
|
365
349
|
* @returns
|
|
366
350
|
*/
|
|
367
|
-
async getPreparedAndSignedLegacyTransactionMap(
|
|
351
|
+
async getPreparedAndSignedLegacyTransactionMap(txsMap, wallet, commitment, recentBlockhash) {
|
|
368
352
|
var _a, _b;
|
|
369
353
|
recentBlockhash = recentBlockhash
|
|
370
354
|
? recentBlockhash
|
|
371
355
|
: await this.getLatestBlockhashForTransaction();
|
|
372
356
|
this.addHashAndExpiryToLookup(recentBlockhash);
|
|
373
|
-
for (const tx of
|
|
357
|
+
for (const tx of Object.values(txsMap)) {
|
|
374
358
|
if (!tx)
|
|
375
359
|
continue;
|
|
376
360
|
tx.recentBlockhash = recentBlockhash.blockhash;
|
|
@@ -378,7 +362,7 @@ class TxHandler {
|
|
|
378
362
|
// @ts-ignore
|
|
379
363
|
tx.SIGNATURE_BLOCK_AND_EXPIRY = recentBlockhash;
|
|
380
364
|
}
|
|
381
|
-
return this.getSignedTransactionMap(
|
|
365
|
+
return this.getSignedTransactionMap(txsMap, wallet);
|
|
382
366
|
}
|
|
383
367
|
/**
|
|
384
368
|
* Get a map of signed transactions from an array of transactions to sign.
|
|
@@ -387,44 +371,59 @@ class TxHandler {
|
|
|
387
371
|
* @param wallet
|
|
388
372
|
* @returns
|
|
389
373
|
*/
|
|
390
|
-
async getSignedTransactionMap(
|
|
374
|
+
async getSignedTransactionMap(txsToSignMap, wallet) {
|
|
391
375
|
var _a;
|
|
392
376
|
[wallet] = this.getProps(wallet);
|
|
393
|
-
const
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
377
|
+
const txsToSignEntries = Object.entries(txsToSignMap);
|
|
378
|
+
// Create a map of the same keys as the input map, but with the values set to undefined. We'll populate the filtered (non-undefined) values with signed transactions.
|
|
379
|
+
const signedTxMap = txsToSignEntries.reduce((acc, [key]) => {
|
|
380
|
+
acc[key] = undefined;
|
|
381
|
+
return acc;
|
|
382
|
+
}, {});
|
|
383
|
+
const filteredTxEntries = txsToSignEntries.filter(([_, tx]) => !!tx);
|
|
384
|
+
// Extra handling for legacy transactions
|
|
385
|
+
for (const [_key, tx] of filteredTxEntries) {
|
|
386
|
+
if (this.isLegacyTransaction(tx)) {
|
|
387
|
+
tx.feePayer = wallet.publicKey;
|
|
401
388
|
}
|
|
402
|
-
}
|
|
389
|
+
}
|
|
403
390
|
(_a = this.preSignedCb) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
404
|
-
const
|
|
405
|
-
|
|
406
|
-
return tx;
|
|
407
|
-
})
|
|
408
|
-
.filter((tx) => tx !== undefined);
|
|
409
|
-
const signedTxs = await wallet.signAllTransactions(filteredTxs);
|
|
410
|
-
signedTxs.forEach((signedTx, index) => {
|
|
391
|
+
const signedFilteredTxs = await wallet.signAllTransactions(filteredTxEntries.map(([_, tx]) => tx));
|
|
392
|
+
signedFilteredTxs.forEach((signedTx, index) => {
|
|
411
393
|
var _a;
|
|
412
394
|
// @ts-ignore
|
|
413
395
|
signedTx.SIGNATURE_BLOCK_AND_EXPIRY =
|
|
414
396
|
// @ts-ignore
|
|
415
|
-
(_a =
|
|
397
|
+
(_a = filteredTxEntries[index][1]) === null || _a === void 0 ? void 0 : _a.SIGNATURE_BLOCK_AND_EXPIRY;
|
|
416
398
|
});
|
|
417
|
-
this.handleSignedTxData(
|
|
399
|
+
const signedTxData = this.handleSignedTxData(signedFilteredTxs.map((signedTx) => {
|
|
418
400
|
return {
|
|
419
401
|
txSig: this.getTxSigFromSignedTx(signedTx),
|
|
420
402
|
signedTx,
|
|
421
403
|
blockHash: this.getBlockhashFromSignedTx(signedTx),
|
|
422
404
|
};
|
|
423
405
|
}));
|
|
424
|
-
|
|
425
|
-
|
|
406
|
+
filteredTxEntries.forEach(([key], index) => {
|
|
407
|
+
const signedTx = signedFilteredTxs[index];
|
|
408
|
+
// @ts-ignore
|
|
409
|
+
signedTxMap[key] = signedTx;
|
|
410
|
+
});
|
|
411
|
+
return { signedTxMap, signedTxData };
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Accepts multiple instructions and builds a transaction for each. Prevents needing to spam RPC with requests for the same blockhash.
|
|
415
|
+
* @param props
|
|
416
|
+
* @returns
|
|
417
|
+
*/
|
|
418
|
+
async buildTransactionsMap(props) {
|
|
419
|
+
const builtTxs = await this.buildBulkTransactions({
|
|
420
|
+
...props,
|
|
421
|
+
instructions: Object.values(props.instructionsMap),
|
|
426
422
|
});
|
|
427
|
-
return
|
|
423
|
+
return Object.keys(props.instructionsMap).reduce((acc, key, index) => {
|
|
424
|
+
acc[key] = builtTxs[index];
|
|
425
|
+
return acc;
|
|
426
|
+
}, {});
|
|
428
427
|
}
|
|
429
428
|
/**
|
|
430
429
|
* Builds and signs transactions from a given array of instructions for multiple transactions.
|
|
@@ -432,10 +431,10 @@ class TxHandler {
|
|
|
432
431
|
* @returns
|
|
433
432
|
*/
|
|
434
433
|
async buildAndSignTransactionMap(props) {
|
|
435
|
-
const
|
|
434
|
+
const builtTxs = await this.buildTransactionsMap(props);
|
|
436
435
|
const preppedTransactions = await (props.txVersion === 'legacy'
|
|
437
|
-
? this.getPreparedAndSignedLegacyTransactionMap(
|
|
438
|
-
: this.getSignedTransactionMap(
|
|
436
|
+
? this.getPreparedAndSignedLegacyTransactionMap(builtTxs, props.wallet, props.preFlightCommitment)
|
|
437
|
+
: this.getSignedTransactionMap(builtTxs, props.wallet));
|
|
439
438
|
return preppedTransactions;
|
|
440
439
|
}
|
|
441
440
|
}
|
package/lib/types.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js';
|
|
3
3
|
import { BN } from '.';
|
|
4
|
+
export type MappedRecord<A extends Record<string, unknown>, B> = {
|
|
5
|
+
[K in keyof A]: B;
|
|
6
|
+
};
|
|
4
7
|
export declare enum ExchangeStatus {
|
|
5
8
|
ACTIVE = 0,
|
|
6
9
|
DEPOSIT_PAUSED = 1,
|
|
@@ -154,6 +157,15 @@ export declare class OracleSource {
|
|
|
154
157
|
static readonly PYTH_1M: {
|
|
155
158
|
pyth1M: {};
|
|
156
159
|
};
|
|
160
|
+
static readonly PYTH_PULL: {
|
|
161
|
+
pythPull: {};
|
|
162
|
+
};
|
|
163
|
+
static readonly PYTH_1K_PULL: {
|
|
164
|
+
pyth1KPull: {};
|
|
165
|
+
};
|
|
166
|
+
static readonly PYTH_1M_PULL: {
|
|
167
|
+
pyth1MPull: {};
|
|
168
|
+
};
|
|
157
169
|
static readonly SWITCHBOARD: {
|
|
158
170
|
switchboard: {};
|
|
159
171
|
};
|
|
@@ -163,6 +175,9 @@ export declare class OracleSource {
|
|
|
163
175
|
static readonly PYTH_STABLE_COIN: {
|
|
164
176
|
pythStableCoin: {};
|
|
165
177
|
};
|
|
178
|
+
static readonly PYTH_STABLE_COIN_PULL: {
|
|
179
|
+
pythStableCoinPull: {};
|
|
180
|
+
};
|
|
166
181
|
static readonly Prelaunch: {
|
|
167
182
|
prelaunch: {};
|
|
168
183
|
};
|
|
@@ -795,6 +810,8 @@ export type SpotMarketAccount = {
|
|
|
795
810
|
ordersEnabled: boolean;
|
|
796
811
|
pausedOperations: number;
|
|
797
812
|
ifPausedOperations: number;
|
|
813
|
+
maxTokenBorrowsFraction: number;
|
|
814
|
+
minBorrowRate: number;
|
|
798
815
|
};
|
|
799
816
|
export type PoolBalance = {
|
|
800
817
|
scaledBalance: BN;
|
package/lib/types.js
CHANGED
|
@@ -105,9 +105,13 @@ exports.OracleSource = OracleSource;
|
|
|
105
105
|
OracleSource.PYTH = { pyth: {} };
|
|
106
106
|
OracleSource.PYTH_1K = { pyth1K: {} };
|
|
107
107
|
OracleSource.PYTH_1M = { pyth1M: {} };
|
|
108
|
+
OracleSource.PYTH_PULL = { pythPull: {} };
|
|
109
|
+
OracleSource.PYTH_1K_PULL = { pyth1KPull: {} };
|
|
110
|
+
OracleSource.PYTH_1M_PULL = { pyth1MPull: {} };
|
|
108
111
|
OracleSource.SWITCHBOARD = { switchboard: {} };
|
|
109
112
|
OracleSource.QUOTE_ASSET = { quoteAsset: {} };
|
|
110
113
|
OracleSource.PYTH_STABLE_COIN = { pythStableCoin: {} };
|
|
114
|
+
OracleSource.PYTH_STABLE_COIN_PULL = { pythStableCoinPull: {} };
|
|
111
115
|
OracleSource.Prelaunch = { prelaunch: {} };
|
|
112
116
|
class OrderType {
|
|
113
117
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drift-labs/sdk",
|
|
3
|
-
"version": "2.84.0-beta.
|
|
3
|
+
"version": "2.84.0-beta.7",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"author": "crispheaney",
|
|
@@ -34,12 +34,14 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@coral-xyz/anchor": "0.
|
|
37
|
+
"@coral-xyz/anchor": "0.28.0",
|
|
38
38
|
"@ellipsis-labs/phoenix-sdk": "^1.4.2",
|
|
39
39
|
"@project-serum/serum": "^0.13.38",
|
|
40
40
|
"@pythnetwork/client": "2.5.3",
|
|
41
|
-
"@
|
|
41
|
+
"@pythnetwork/pyth-solana-receiver": "^0.7.0",
|
|
42
|
+
"@solana/spl-token": "0.3.7",
|
|
42
43
|
"@solana/web3.js": "1.92.3",
|
|
44
|
+
"rpc-websockets": "7.5.1",
|
|
43
45
|
"strict-event-emitter-types": "^2.0.0",
|
|
44
46
|
"uuid": "^8.3.2",
|
|
45
47
|
"zstddec": "^0.1.0"
|
|
@@ -50,17 +52,17 @@
|
|
|
50
52
|
"@types/chai": "^4.3.1",
|
|
51
53
|
"@types/jest": "^28.1.3",
|
|
52
54
|
"@types/mocha": "^9.1.1",
|
|
53
|
-
"@typescript-eslint/eslint-plugin": "
|
|
54
|
-
"@typescript-eslint/parser": "
|
|
55
|
+
"@typescript-eslint/eslint-plugin": "4.28.0",
|
|
56
|
+
"@typescript-eslint/parser": "4.28.0",
|
|
55
57
|
"chai": "^4.3.6",
|
|
56
58
|
"encoding": "^0.1.13",
|
|
57
|
-
"eslint": "
|
|
58
|
-
"eslint-config-prettier": "
|
|
59
|
-
"eslint-plugin-prettier": "
|
|
59
|
+
"eslint": "7.29.0",
|
|
60
|
+
"eslint-config-prettier": "8.3.0",
|
|
61
|
+
"eslint-plugin-prettier": "3.4.0",
|
|
60
62
|
"lodash": "^4.17.21",
|
|
61
63
|
"mocha": "^10.0.0",
|
|
62
64
|
"object-sizeof": "^2.6.3",
|
|
63
|
-
"prettier": "
|
|
65
|
+
"prettier": "3.0.1",
|
|
64
66
|
"ts-node": "^10.8.0",
|
|
65
67
|
"typescript": "^4.9.5"
|
|
66
68
|
},
|
package/src/adminClient.ts
CHANGED
|
@@ -1812,6 +1812,44 @@ export class AdminClient extends DriftClient {
|
|
|
1812
1812
|
);
|
|
1813
1813
|
}
|
|
1814
1814
|
|
|
1815
|
+
public async updateSpotMarketMaxTokenBorrows(
|
|
1816
|
+
spotMarketIndex: number,
|
|
1817
|
+
maxTokenBorrows: BN
|
|
1818
|
+
): Promise<TransactionSignature> {
|
|
1819
|
+
const updateSpotMarketMaxTokenBorrowsIx =
|
|
1820
|
+
await this.getUpdateSpotMarketMaxTokenBorrowsIx(
|
|
1821
|
+
spotMarketIndex,
|
|
1822
|
+
maxTokenBorrows
|
|
1823
|
+
);
|
|
1824
|
+
|
|
1825
|
+
const tx = await this.buildTransaction(updateSpotMarketMaxTokenBorrowsIx);
|
|
1826
|
+
|
|
1827
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
1828
|
+
|
|
1829
|
+
return txSig;
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
public async getUpdateSpotMarketMaxTokenBorrowsIx(
|
|
1833
|
+
spotMarketIndex: number,
|
|
1834
|
+
maxTokenBorrows: BN
|
|
1835
|
+
): Promise<TransactionInstruction> {
|
|
1836
|
+
return this.program.instruction.updateSpotMarketMaxTokenBorrows(
|
|
1837
|
+
maxTokenBorrows,
|
|
1838
|
+
{
|
|
1839
|
+
accounts: {
|
|
1840
|
+
admin: this.isSubscribed
|
|
1841
|
+
? this.getStateAccount().admin
|
|
1842
|
+
: this.wallet.publicKey,
|
|
1843
|
+
state: await this.getStatePublicKey(),
|
|
1844
|
+
spotMarket: await getSpotMarketPublicKey(
|
|
1845
|
+
this.program.programId,
|
|
1846
|
+
spotMarketIndex
|
|
1847
|
+
),
|
|
1848
|
+
},
|
|
1849
|
+
}
|
|
1850
|
+
);
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1815
1853
|
public async updateSpotMarketScaleInitialAssetWeightStart(
|
|
1816
1854
|
spotMarketIndex: number,
|
|
1817
1855
|
scaleInitialAssetWeightStart: BN
|
|
@@ -2506,14 +2544,16 @@ export class AdminClient extends DriftClient {
|
|
|
2506
2544
|
spotMarketIndex: number,
|
|
2507
2545
|
optimalUtilization: number,
|
|
2508
2546
|
optimalBorrowRate: number,
|
|
2509
|
-
optimalMaxRate: number
|
|
2547
|
+
optimalMaxRate: number,
|
|
2548
|
+
minBorrowRate?: number | undefined
|
|
2510
2549
|
): Promise<TransactionSignature> {
|
|
2511
2550
|
const updateSpotMarketBorrowRateIx =
|
|
2512
2551
|
await this.getUpdateSpotMarketBorrowRateIx(
|
|
2513
2552
|
spotMarketIndex,
|
|
2514
2553
|
optimalUtilization,
|
|
2515
2554
|
optimalBorrowRate,
|
|
2516
|
-
optimalMaxRate
|
|
2555
|
+
optimalMaxRate,
|
|
2556
|
+
minBorrowRate
|
|
2517
2557
|
);
|
|
2518
2558
|
|
|
2519
2559
|
const tx = await this.buildTransaction(updateSpotMarketBorrowRateIx);
|
|
@@ -2527,12 +2567,14 @@ export class AdminClient extends DriftClient {
|
|
|
2527
2567
|
spotMarketIndex: number,
|
|
2528
2568
|
optimalUtilization: number,
|
|
2529
2569
|
optimalBorrowRate: number,
|
|
2530
|
-
optimalMaxRate: number
|
|
2570
|
+
optimalMaxRate: number,
|
|
2571
|
+
minBorrowRate?: number | undefined
|
|
2531
2572
|
): Promise<TransactionInstruction> {
|
|
2532
2573
|
return await this.program.instruction.updateSpotMarketBorrowRate(
|
|
2533
2574
|
optimalUtilization,
|
|
2534
2575
|
optimalBorrowRate,
|
|
2535
2576
|
optimalMaxRate,
|
|
2577
|
+
minBorrowRate,
|
|
2536
2578
|
{
|
|
2537
2579
|
accounts: {
|
|
2538
2580
|
admin: this.isSubscribed
|
|
@@ -39,15 +39,28 @@ export class BlockhashSubscriber {
|
|
|
39
39
|
return this.latestBlockHeightContext;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Returns the latest cached blockhash, based on an offset from the latest obtained
|
|
44
|
+
* @param offset Offset to use, defaulting to 0
|
|
45
|
+
* @param offsetType If 'seconds', it will use calculate the actual element offset based on the update interval; otherwise it will return a fixed index
|
|
46
|
+
* @returns Cached blockhash at the given offset, or undefined
|
|
47
|
+
*/
|
|
42
48
|
getLatestBlockhash(
|
|
43
|
-
offset
|
|
49
|
+
offset = 0,
|
|
50
|
+
offsetType: 'index' | 'seconds' = 'index'
|
|
44
51
|
): BlockhashWithExpiryBlockHeight | undefined {
|
|
45
52
|
if (this.blockhashes.length === 0) {
|
|
46
53
|
return undefined;
|
|
47
54
|
}
|
|
55
|
+
|
|
56
|
+
const elementOffset =
|
|
57
|
+
offsetType == 'seconds'
|
|
58
|
+
? Math.floor((offset * 1000) / this.updateIntervalMs)
|
|
59
|
+
: offset;
|
|
60
|
+
|
|
48
61
|
const clampedOffset = Math.max(
|
|
49
62
|
0,
|
|
50
|
-
Math.min(this.blockhashes.length - 1,
|
|
63
|
+
Math.min(this.blockhashes.length - 1, elementOffset)
|
|
51
64
|
);
|
|
52
65
|
|
|
53
66
|
return this.blockhashes[this.blockhashes.length - 1 - clampedOffset];
|
|
@@ -273,6 +273,16 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
273
273
|
precisionExp: NINE,
|
|
274
274
|
launchTs: 1716595200000,
|
|
275
275
|
},
|
|
276
|
+
{
|
|
277
|
+
symbol: 'USDY',
|
|
278
|
+
marketIndex: 18,
|
|
279
|
+
oracle: new PublicKey('DiqUGbq5CV8Tjcae1whjrX97qPo6gU7BKAvKNFc2vrX8'),
|
|
280
|
+
oracleSource: OracleSource.SWITCHBOARD,
|
|
281
|
+
mint: new PublicKey('A1KLoBrKBde8Ty9qtNQUtq3C2ortoC3u7twggz7sEto6'),
|
|
282
|
+
precision: new BN(10).pow(SIX),
|
|
283
|
+
precisionExp: SIX,
|
|
284
|
+
launchTs: 1718811089000,
|
|
285
|
+
},
|
|
276
286
|
];
|
|
277
287
|
|
|
278
288
|
export const SpotMarkets: { [key in DriftEnv]: SpotMarketConfig[] } = {
|