@drift-labs/sdk 2.28.0-beta.4 → 2.28.0-beta.5
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/lib/config.d.ts +1 -0
- package/lib/config.js +4 -3
- package/lib/constants/perpMarkets.js +20 -0
- package/lib/driftClient.d.ts +62 -7
- package/lib/driftClient.js +186 -66
- package/lib/driftClientConfig.d.ts +4 -3
- package/lib/idl/drift.json +856 -1
- package/lib/math/spotMarket.d.ts +1 -1
- package/lib/math/spotMarket.js +6 -1
- package/lib/math/utils.d.ts +9 -0
- package/lib/math/utils.js +39 -1
- package/lib/phoenix/phoenixSubscriber.js +1 -2
- package/lib/tx/retryTxSender.d.ts +1 -1
- package/lib/tx/retryTxSender.js +1 -2
- package/lib/tx/types.d.ts +1 -1
- package/lib/types.d.ts +0 -1
- package/lib/types.js +0 -1
- package/lib/user.d.ts +8 -0
- package/lib/user.js +18 -0
- package/package.json +1 -1
- package/src/assert/assert.js +9 -0
- package/src/config.ts +4 -2
- package/src/constants/perpMarkets.ts +20 -0
- package/src/driftClient.ts +273 -138
- package/src/driftClientConfig.ts +9 -3
- package/src/idl/drift.json +856 -1
- package/src/math/spotMarket.ts +6 -2
- package/src/math/utils.ts +46 -0
- package/src/phoenix/phoenixSubscriber.ts +4 -2
- package/src/token/index.js +38 -0
- package/src/tx/retryTxSender.ts +1 -9
- package/src/tx/types.ts +1 -2
- package/src/types.ts +0 -2
- package/src/user.ts +28 -0
- package/src/util/computeUnits.js +27 -0
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/promiseTimeout.js +14 -0
- package/src/util/tps.js +27 -0
- package/tests/insurance/test.ts +40 -0
- package/dlob_read.ts +0 -155
package/lib/math/spotMarket.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { BN } from '@coral-xyz/anchor';
|
|
2
2
|
import { MarginCategory, SpotBalanceType, SpotMarketAccount } from '../types';
|
|
3
|
-
export declare function castNumberToSpotPrecision(value: number, spotMarket: SpotMarketAccount): BN;
|
|
3
|
+
export declare function castNumberToSpotPrecision(value: number | BN, spotMarket: SpotMarketAccount): BN;
|
|
4
4
|
export declare function calculateSpotMarketMarginRatio(market: SpotMarketAccount, marginCategory: MarginCategory, size: BN, balanceType: SpotBalanceType): number;
|
package/lib/math/spotMarket.js
CHANGED
|
@@ -6,7 +6,12 @@ const types_1 = require("../types");
|
|
|
6
6
|
const spotBalance_1 = require("./spotBalance");
|
|
7
7
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
8
8
|
function castNumberToSpotPrecision(value, spotMarket) {
|
|
9
|
-
|
|
9
|
+
if (typeof value === 'number') {
|
|
10
|
+
return new anchor_1.BN(value * Math.pow(10, spotMarket.decimals));
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
return value.mul(new anchor_1.BN(Math.pow(10, spotMarket.decimals)));
|
|
14
|
+
}
|
|
10
15
|
}
|
|
11
16
|
exports.castNumberToSpotPrecision = castNumberToSpotPrecision;
|
|
12
17
|
function calculateSpotMarketMarginRatio(market, marginCategory, size, balanceType) {
|
package/lib/math/utils.d.ts
CHANGED
|
@@ -2,3 +2,12 @@ import { BN } from '../';
|
|
|
2
2
|
export declare function clampBN(x: BN, min: BN, max: BN): BN;
|
|
3
3
|
export declare const squareRootBN: (n: BN) => BN;
|
|
4
4
|
export declare const divCeil: (a: BN, b: BN) => BN;
|
|
5
|
+
/**
|
|
6
|
+
* calculates the time remaining until the next update based on a rounded, "on-the-hour" update schedule
|
|
7
|
+
* this schedule is used for Perpetual Funding Rate and Revenue -> Insurance Updates
|
|
8
|
+
* @param now: current blockchain unix timestamp
|
|
9
|
+
* @param lastUpdateTs: the unix timestamp of the last update
|
|
10
|
+
* @param updatePeriod: desired interval between updates (in seconds)
|
|
11
|
+
* @returns: timeRemainingUntilUpdate (in seconds)
|
|
12
|
+
*/
|
|
13
|
+
export declare function timeRemainingUntilUpdate(now: BN, lastUpdateTs: BN, updatePeriod: BN): BN;
|
package/lib/math/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.divCeil = exports.squareRootBN = exports.clampBN = void 0;
|
|
3
|
+
exports.timeRemainingUntilUpdate = exports.divCeil = exports.squareRootBN = exports.clampBN = void 0;
|
|
4
4
|
const __1 = require("../");
|
|
5
5
|
function clampBN(x, min, max) {
|
|
6
6
|
return __1.BN.max(min, __1.BN.min(x, max));
|
|
@@ -34,3 +34,41 @@ const divCeil = (a, b) => {
|
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
36
|
exports.divCeil = divCeil;
|
|
37
|
+
/**
|
|
38
|
+
* calculates the time remaining until the next update based on a rounded, "on-the-hour" update schedule
|
|
39
|
+
* this schedule is used for Perpetual Funding Rate and Revenue -> Insurance Updates
|
|
40
|
+
* @param now: current blockchain unix timestamp
|
|
41
|
+
* @param lastUpdateTs: the unix timestamp of the last update
|
|
42
|
+
* @param updatePeriod: desired interval between updates (in seconds)
|
|
43
|
+
* @returns: timeRemainingUntilUpdate (in seconds)
|
|
44
|
+
*/
|
|
45
|
+
function timeRemainingUntilUpdate(now, lastUpdateTs, updatePeriod) {
|
|
46
|
+
const timeSinceLastUpdate = now.sub(lastUpdateTs);
|
|
47
|
+
// round next update time to be available on the hour
|
|
48
|
+
let nextUpdateWait = updatePeriod;
|
|
49
|
+
if (updatePeriod.gt(new __1.BN(1))) {
|
|
50
|
+
const lastUpdateDelay = lastUpdateTs.umod(updatePeriod);
|
|
51
|
+
if (!lastUpdateDelay.isZero()) {
|
|
52
|
+
const maxDelayForNextPeriod = updatePeriod.div(new __1.BN(3));
|
|
53
|
+
const twoFundingPeriods = updatePeriod.mul(new __1.BN(2));
|
|
54
|
+
if (lastUpdateDelay.gt(maxDelayForNextPeriod)) {
|
|
55
|
+
// too late for on the hour next period, delay to following period
|
|
56
|
+
nextUpdateWait = twoFundingPeriods.sub(lastUpdateDelay);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// allow update on the hour
|
|
60
|
+
nextUpdateWait = updatePeriod.sub(lastUpdateDelay);
|
|
61
|
+
}
|
|
62
|
+
if (nextUpdateWait.gt(twoFundingPeriods)) {
|
|
63
|
+
nextUpdateWait = nextUpdateWait.sub(updatePeriod);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const timeRemainingUntilUpdate = nextUpdateWait
|
|
68
|
+
.sub(timeSinceLastUpdate)
|
|
69
|
+
.isNeg()
|
|
70
|
+
? __1.ZERO
|
|
71
|
+
: nextUpdateWait.sub(timeSinceLastUpdate);
|
|
72
|
+
return timeRemainingUntilUpdate;
|
|
73
|
+
}
|
|
74
|
+
exports.timeRemainingUntilUpdate = timeRemainingUntilUpdate;
|
|
@@ -99,8 +99,7 @@ class PhoenixSubscriber {
|
|
|
99
99
|
return this.getL2Levels('asks');
|
|
100
100
|
}
|
|
101
101
|
*getL2Levels(side) {
|
|
102
|
-
|
|
103
|
-
const basePrecision = Math.pow(10, this.market.header.baseParams.decimals);
|
|
102
|
+
const basePrecision = Math.pow(10, this.market.data.header.baseParams.decimals);
|
|
104
103
|
const pricePrecision = numericConstants_1.PRICE_PRECISION.toNumber();
|
|
105
104
|
const ladder = (0, phoenix_sdk_1.getMarketUiLadder)(this.market, this.lastSlot, this.lastUnixTimestamp, 20);
|
|
106
105
|
for (let i = 0; i < ladder[side].length; i++) {
|
|
@@ -14,7 +14,7 @@ export declare class RetryTxSender implements TxSender {
|
|
|
14
14
|
send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
|
|
15
15
|
prepareTx(tx: Transaction, additionalSigners: Array<Signer>, opts: ConfirmOptions): Promise<Transaction>;
|
|
16
16
|
getVersionedTransaction(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<VersionedTransaction>;
|
|
17
|
-
sendVersionedTransaction(
|
|
17
|
+
sendVersionedTransaction(tx: VersionedTransaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<TxSigAndSlot>;
|
|
18
18
|
sendRawTransaction(rawTransaction: Buffer | Uint8Array, opts: ConfirmOptions): Promise<TxSigAndSlot>;
|
|
19
19
|
confirmTransaction(signature: TransactionSignature, commitment?: Commitment): Promise<RpcResponseAndContext<SignatureResult>>;
|
|
20
20
|
getTimestamp(): number;
|
package/lib/tx/retryTxSender.js
CHANGED
|
@@ -54,8 +54,7 @@ class RetryTxSender {
|
|
|
54
54
|
const tx = new web3_js_1.VersionedTransaction(message);
|
|
55
55
|
return tx;
|
|
56
56
|
}
|
|
57
|
-
async sendVersionedTransaction(
|
|
58
|
-
const tx = await this.getVersionedTransaction(ixs, lookupTableAccounts, additionalSigners, opts);
|
|
57
|
+
async sendVersionedTransaction(tx, additionalSigners, opts) {
|
|
59
58
|
// @ts-ignore
|
|
60
59
|
tx.sign(additionalSigners.concat(this.provider.wallet.payer));
|
|
61
60
|
return this.sendRawTransaction(tx.serialize(), opts);
|
package/lib/tx/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type TxSigAndSlot = {
|
|
|
8
8
|
export interface TxSender {
|
|
9
9
|
provider: Provider;
|
|
10
10
|
send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
|
|
11
|
-
sendVersionedTransaction(
|
|
11
|
+
sendVersionedTransaction(tx: VersionedTransaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<TxSigAndSlot>;
|
|
12
12
|
getVersionedTransaction(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<VersionedTransaction>;
|
|
13
13
|
sendRawTransaction(rawTransaction: Buffer | Uint8Array, opts: ConfirmOptions): Promise<TxSigAndSlot>;
|
|
14
14
|
}
|
package/lib/types.d.ts
CHANGED
package/lib/types.js
CHANGED
package/lib/user.d.ts
CHANGED
|
@@ -42,6 +42,13 @@ export declare class User {
|
|
|
42
42
|
* @returns userSpotPosition
|
|
43
43
|
*/
|
|
44
44
|
getSpotPosition(marketIndex: number): SpotPosition | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Returns the token amount for a given market. The spot market precision is based on the token mint decimals.
|
|
47
|
+
* Positive if it is a deposit, negative if it is a borrow.
|
|
48
|
+
*
|
|
49
|
+
* @param marketIndex
|
|
50
|
+
*/
|
|
51
|
+
getTokenAmount(marketIndex: number): BN;
|
|
45
52
|
getEmptyPosition(marketIndex: number): PerpPosition;
|
|
46
53
|
getClonedPosition(position: PerpPosition): PerpPosition;
|
|
47
54
|
/**
|
|
@@ -54,6 +61,7 @@ export declare class User {
|
|
|
54
61
|
* @returns Order
|
|
55
62
|
*/
|
|
56
63
|
getOrderByUserOrderId(userOrderId: number): Order | undefined;
|
|
64
|
+
getOpenOrders(): Order[];
|
|
57
65
|
getUserAccountPublicKey(): PublicKey;
|
|
58
66
|
exists(): Promise<boolean>;
|
|
59
67
|
/**
|
package/lib/user.js
CHANGED
|
@@ -76,6 +76,20 @@ class User {
|
|
|
76
76
|
getSpotPosition(marketIndex) {
|
|
77
77
|
return this.getUserAccount().spotPositions.find((position) => position.marketIndex === marketIndex);
|
|
78
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns the token amount for a given market. The spot market precision is based on the token mint decimals.
|
|
81
|
+
* Positive if it is a deposit, negative if it is a borrow.
|
|
82
|
+
*
|
|
83
|
+
* @param marketIndex
|
|
84
|
+
*/
|
|
85
|
+
getTokenAmount(marketIndex) {
|
|
86
|
+
const spotPosition = this.getSpotPosition(marketIndex);
|
|
87
|
+
if (spotPosition === undefined) {
|
|
88
|
+
return numericConstants_1.ZERO;
|
|
89
|
+
}
|
|
90
|
+
const spotMarket = this.driftClient.getSpotMarketAccount(marketIndex);
|
|
91
|
+
return (0, _1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarket, spotPosition.balanceType), spotPosition.balanceType);
|
|
92
|
+
}
|
|
79
93
|
getEmptyPosition(marketIndex) {
|
|
80
94
|
return {
|
|
81
95
|
baseAssetAmount: numericConstants_1.ZERO,
|
|
@@ -112,6 +126,10 @@ class User {
|
|
|
112
126
|
getOrderByUserOrderId(userOrderId) {
|
|
113
127
|
return this.getUserAccount().orders.find((order) => order.userOrderId === userOrderId);
|
|
114
128
|
}
|
|
129
|
+
getOpenOrders() {
|
|
130
|
+
var _a;
|
|
131
|
+
return (_a = this.getUserAccount()) === null || _a === void 0 ? void 0 : _a.orders.filter((order) => (0, types_1.isVariant)(order.status, 'open'));
|
|
132
|
+
}
|
|
115
133
|
getUserAccountPublicKey() {
|
|
116
134
|
return this.userAccountPublicKey;
|
|
117
135
|
}
|
package/package.json
CHANGED
package/src/config.ts
CHANGED
|
@@ -27,11 +27,13 @@ type DriftConfig = {
|
|
|
27
27
|
|
|
28
28
|
export type DriftEnv = 'devnet' | 'mainnet-beta';
|
|
29
29
|
|
|
30
|
+
export const DRIFT_PROGRAM_ID = 'dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH';
|
|
31
|
+
|
|
30
32
|
export const configs: { [key in DriftEnv]: DriftConfig } = {
|
|
31
33
|
devnet: {
|
|
32
34
|
ENV: 'devnet',
|
|
33
35
|
PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
|
|
34
|
-
DRIFT_PROGRAM_ID
|
|
36
|
+
DRIFT_PROGRAM_ID,
|
|
35
37
|
USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
|
|
36
38
|
SERUM_V3: 'DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY',
|
|
37
39
|
PHOENIX: 'PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY',
|
|
@@ -44,7 +46,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
|
|
|
44
46
|
'mainnet-beta': {
|
|
45
47
|
ENV: 'mainnet-beta',
|
|
46
48
|
PYTH_ORACLE_MAPPING_ADDRESS: 'AHtgzX45WTKfkPG53L6WYhGEXwQkN1BVknET3sVsLL8J',
|
|
47
|
-
DRIFT_PROGRAM_ID
|
|
49
|
+
DRIFT_PROGRAM_ID,
|
|
48
50
|
USDC_MINT_ADDRESS: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
49
51
|
SERUM_V3: 'srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX',
|
|
50
52
|
PHOENIX: 'PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY',
|
|
@@ -114,6 +114,16 @@ export const DevnetPerpMarkets: PerpMarketConfig[] = [
|
|
|
114
114
|
launchTs: 1683125906000,
|
|
115
115
|
oracleSource: OracleSource.PYTH,
|
|
116
116
|
},
|
|
117
|
+
{
|
|
118
|
+
fullName: 'Pepe',
|
|
119
|
+
category: ['Meme'],
|
|
120
|
+
symbol: '1MPEPE-PERP',
|
|
121
|
+
baseAssetSymbol: '1MPEPE',
|
|
122
|
+
marketIndex: 10,
|
|
123
|
+
oracle: new PublicKey('Gz9RfgDeAFSsH7BHDGyNTgCik74rjNwsodJpsCizzmkj'),
|
|
124
|
+
launchTs: 1683125906000,
|
|
125
|
+
oracleSource: OracleSource.PYTH_1M,
|
|
126
|
+
},
|
|
117
127
|
];
|
|
118
128
|
|
|
119
129
|
export const MainnetPerpMarkets: PerpMarketConfig[] = [
|
|
@@ -217,6 +227,16 @@ export const MainnetPerpMarkets: PerpMarketConfig[] = [
|
|
|
217
227
|
launchTs: 1683125906000,
|
|
218
228
|
oracleSource: OracleSource.PYTH,
|
|
219
229
|
},
|
|
230
|
+
{
|
|
231
|
+
fullName: 'Pepe',
|
|
232
|
+
category: ['Meme'],
|
|
233
|
+
symbol: '1MPEPE-PERP',
|
|
234
|
+
baseAssetSymbol: '1MPEPE',
|
|
235
|
+
marketIndex: 10,
|
|
236
|
+
oracle: new PublicKey('FSfxunDmjjbDV2QxpyxFCAPKmYJHSLnLuvQXDLkMzLBm'),
|
|
237
|
+
launchTs: 1683125906000,
|
|
238
|
+
oracleSource: OracleSource.PYTH_1M,
|
|
239
|
+
},
|
|
220
240
|
];
|
|
221
241
|
|
|
222
242
|
export const PerpMarkets: { [key in DriftEnv]: PerpMarketConfig[] } = {
|