@drift-labs/sdk 2.38.1-beta.1 → 2.38.1-beta.10
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/accounts/fetch.js +2 -2
- package/lib/accounts/pollingDriftClientAccountSubscriber.js +2 -14
- package/lib/accounts/pollingUserStatsAccountSubscriber.js +2 -2
- package/lib/adminClient.d.ts +1 -0
- package/lib/adminClient.js +11 -0
- package/lib/config.d.ts +1 -0
- package/lib/config.js +2 -0
- package/lib/driftClient.d.ts +22 -2
- package/lib/driftClient.js +101 -15
- package/lib/examples/loadDlob.js +3 -1
- package/lib/examples/makeTradeExample.js +3 -1
- package/lib/idl/drift.json +36 -1
- package/lib/index.d.ts +3 -0
- package/lib/index.js +3 -0
- package/lib/jupiter/jupiterClient.d.ts +197 -0
- package/lib/jupiter/jupiterClient.js +48 -3
- package/lib/math/spotBalance.d.ts +6 -5
- package/lib/math/spotBalance.js +28 -11
- package/lib/math/spotMarket.d.ts +1 -1
- package/lib/math/spotMarket.js +2 -2
- package/lib/math/spotPosition.d.ts +16 -3
- package/lib/math/spotPosition.js +53 -9
- package/lib/oracles/strictOraclePrice.d.ts +8 -0
- package/lib/oracles/strictOraclePrice.js +17 -0
- package/lib/priorityFee/priorityFeeSubscriber.d.ts +22 -0
- package/lib/priorityFee/priorityFeeSubscriber.js +46 -0
- package/lib/tokenFaucet.js +1 -0
- package/lib/types.d.ts +4 -0
- package/lib/types.js +3 -0
- package/lib/user.d.ts +5 -4
- package/lib/user.js +71 -105
- package/package.json +2 -2
- package/src/accounts/fetch.ts +2 -2
- package/src/accounts/pollingDriftClientAccountSubscriber.ts +5 -23
- package/src/accounts/pollingUserStatsAccountSubscriber.ts +10 -8
- package/src/adminClient.ts +23 -0
- package/src/config.ts +3 -0
- package/src/driftClient.ts +173 -13
- package/src/examples/loadDlob.ts +1 -0
- package/src/examples/makeTradeExample.ts +1 -0
- package/src/idl/drift.json +36 -1
- package/src/index.ts +3 -0
- package/src/jupiter/jupiterClient.ts +246 -3
- package/src/math/spotBalance.ts +37 -11
- package/src/math/spotMarket.ts +7 -1
- package/src/math/spotPosition.ts +133 -18
- package/src/oracles/strictOraclePrice.ts +19 -0
- package/src/priorityFee/priorityFeeSubscriber.ts +75 -0
- package/src/tokenFaucet.ts +1 -0
- package/src/types.ts +4 -0
- package/src/user.ts +171 -228
- package/tests/dlob/helpers.ts +10 -7
- package/tests/user/test.ts +77 -4
package/src/driftClient.ts
CHANGED
|
@@ -113,7 +113,12 @@ import { isSpotPositionAvailable } from './math/spotPosition';
|
|
|
113
113
|
import { calculateMarketMaxAvailableInsurance } from './math/market';
|
|
114
114
|
import { fetchUserStatsAccount } from './accounts/fetch';
|
|
115
115
|
import { castNumberToSpotPrecision } from './math/spotMarket';
|
|
116
|
-
import {
|
|
116
|
+
import {
|
|
117
|
+
JupiterClient,
|
|
118
|
+
QuoteResponse,
|
|
119
|
+
Route,
|
|
120
|
+
SwapMode,
|
|
121
|
+
} from './jupiter/jupiterClient';
|
|
117
122
|
import { getNonIdleUserFilter } from './memcmp';
|
|
118
123
|
import { UserStatsSubscriptionConfig } from './userStatsConfig';
|
|
119
124
|
import { getMarinadeDepositIx, getMarinadeFinanceProgram } from './marinade';
|
|
@@ -174,6 +179,7 @@ export class DriftClient {
|
|
|
174
179
|
this.opts = config.opts || AnchorProvider.defaultOptions();
|
|
175
180
|
this.provider = new AnchorProvider(
|
|
176
181
|
config.connection,
|
|
182
|
+
// @ts-ignore
|
|
177
183
|
config.wallet,
|
|
178
184
|
this.opts
|
|
179
185
|
);
|
|
@@ -512,6 +518,7 @@ export class DriftClient {
|
|
|
512
518
|
): Promise<boolean> {
|
|
513
519
|
const newProvider = new AnchorProvider(
|
|
514
520
|
this.connection,
|
|
521
|
+
// @ts-ignore
|
|
515
522
|
newWallet,
|
|
516
523
|
this.opts
|
|
517
524
|
);
|
|
@@ -2473,6 +2480,7 @@ export class DriftClient {
|
|
|
2473
2480
|
);
|
|
2474
2481
|
this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
|
|
2475
2482
|
|
|
2483
|
+
// @ts-ignore
|
|
2476
2484
|
return { txSig, signedFillTx: signedVersionedFillTx };
|
|
2477
2485
|
} else {
|
|
2478
2486
|
const marketOrderTx = wrapInTx(
|
|
@@ -3415,6 +3423,7 @@ export class DriftClient {
|
|
|
3415
3423
|
route,
|
|
3416
3424
|
reduceOnly,
|
|
3417
3425
|
txParams,
|
|
3426
|
+
v6,
|
|
3418
3427
|
}: {
|
|
3419
3428
|
jupiterClient: JupiterClient;
|
|
3420
3429
|
outMarketIndex: number;
|
|
@@ -3427,19 +3436,44 @@ export class DriftClient {
|
|
|
3427
3436
|
route?: Route;
|
|
3428
3437
|
reduceOnly?: SwapReduceOnly;
|
|
3429
3438
|
txParams?: TxParams;
|
|
3439
|
+
v6?: {
|
|
3440
|
+
quote?: QuoteResponse;
|
|
3441
|
+
};
|
|
3430
3442
|
}): Promise<TransactionSignature> {
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
+
let ixs: anchor.web3.TransactionInstruction[];
|
|
3444
|
+
let lookupTables: anchor.web3.AddressLookupTableAccount[];
|
|
3445
|
+
|
|
3446
|
+
if (v6) {
|
|
3447
|
+
const res = await this.getJupiterSwapIxV6({
|
|
3448
|
+
jupiterClient,
|
|
3449
|
+
outMarketIndex,
|
|
3450
|
+
inMarketIndex,
|
|
3451
|
+
outAssociatedTokenAccount,
|
|
3452
|
+
inAssociatedTokenAccount,
|
|
3453
|
+
amount,
|
|
3454
|
+
slippageBps,
|
|
3455
|
+
swapMode,
|
|
3456
|
+
quote: v6.quote,
|
|
3457
|
+
reduceOnly,
|
|
3458
|
+
});
|
|
3459
|
+
ixs = res.ixs;
|
|
3460
|
+
lookupTables = res.lookupTables;
|
|
3461
|
+
} else {
|
|
3462
|
+
const res = await this.getJupiterSwapIx({
|
|
3463
|
+
jupiterClient,
|
|
3464
|
+
outMarketIndex,
|
|
3465
|
+
inMarketIndex,
|
|
3466
|
+
outAssociatedTokenAccount,
|
|
3467
|
+
inAssociatedTokenAccount,
|
|
3468
|
+
amount,
|
|
3469
|
+
slippageBps,
|
|
3470
|
+
swapMode,
|
|
3471
|
+
route,
|
|
3472
|
+
reduceOnly,
|
|
3473
|
+
});
|
|
3474
|
+
ixs = res.ixs;
|
|
3475
|
+
lookupTables = res.lookupTables;
|
|
3476
|
+
}
|
|
3443
3477
|
|
|
3444
3478
|
const tx = (await this.buildTransaction(
|
|
3445
3479
|
ixs,
|
|
@@ -3585,6 +3619,132 @@ export class DriftClient {
|
|
|
3585
3619
|
return { ixs, lookupTables };
|
|
3586
3620
|
}
|
|
3587
3621
|
|
|
3622
|
+
public async getJupiterSwapIxV6({
|
|
3623
|
+
jupiterClient,
|
|
3624
|
+
outMarketIndex,
|
|
3625
|
+
inMarketIndex,
|
|
3626
|
+
outAssociatedTokenAccount,
|
|
3627
|
+
inAssociatedTokenAccount,
|
|
3628
|
+
amount,
|
|
3629
|
+
slippageBps,
|
|
3630
|
+
swapMode,
|
|
3631
|
+
onlyDirectRoutes,
|
|
3632
|
+
quote,
|
|
3633
|
+
reduceOnly,
|
|
3634
|
+
userAccountPublicKey,
|
|
3635
|
+
}: {
|
|
3636
|
+
jupiterClient: JupiterClient;
|
|
3637
|
+
outMarketIndex: number;
|
|
3638
|
+
inMarketIndex: number;
|
|
3639
|
+
outAssociatedTokenAccount?: PublicKey;
|
|
3640
|
+
inAssociatedTokenAccount?: PublicKey;
|
|
3641
|
+
amount: BN;
|
|
3642
|
+
slippageBps?: number;
|
|
3643
|
+
swapMode?: SwapMode;
|
|
3644
|
+
onlyDirectRoutes?: boolean;
|
|
3645
|
+
quote?: QuoteResponse;
|
|
3646
|
+
reduceOnly?: SwapReduceOnly;
|
|
3647
|
+
userAccountPublicKey?: PublicKey;
|
|
3648
|
+
}): Promise<{
|
|
3649
|
+
ixs: TransactionInstruction[];
|
|
3650
|
+
lookupTables: AddressLookupTableAccount[];
|
|
3651
|
+
}> {
|
|
3652
|
+
const outMarket = this.getSpotMarketAccount(outMarketIndex);
|
|
3653
|
+
const inMarket = this.getSpotMarketAccount(inMarketIndex);
|
|
3654
|
+
|
|
3655
|
+
if (!quote) {
|
|
3656
|
+
const fetchedQuote = await jupiterClient.getQuote({
|
|
3657
|
+
inputMint: inMarket.mint,
|
|
3658
|
+
outputMint: outMarket.mint,
|
|
3659
|
+
amount,
|
|
3660
|
+
slippageBps,
|
|
3661
|
+
swapMode,
|
|
3662
|
+
onlyDirectRoutes,
|
|
3663
|
+
});
|
|
3664
|
+
|
|
3665
|
+
quote = fetchedQuote;
|
|
3666
|
+
}
|
|
3667
|
+
|
|
3668
|
+
const transaction = await jupiterClient.getSwap({
|
|
3669
|
+
quote,
|
|
3670
|
+
userPublicKey: this.provider.wallet.publicKey,
|
|
3671
|
+
slippageBps,
|
|
3672
|
+
});
|
|
3673
|
+
|
|
3674
|
+
const { transactionMessage, lookupTables } =
|
|
3675
|
+
await jupiterClient.getTransactionMessageAndLookupTables({
|
|
3676
|
+
transaction,
|
|
3677
|
+
});
|
|
3678
|
+
|
|
3679
|
+
const jupiterInstructions = jupiterClient.getJupiterInstructions({
|
|
3680
|
+
transactionMessage,
|
|
3681
|
+
inputMint: inMarket.mint,
|
|
3682
|
+
outputMint: outMarket.mint,
|
|
3683
|
+
});
|
|
3684
|
+
|
|
3685
|
+
const preInstructions = [];
|
|
3686
|
+
if (!outAssociatedTokenAccount) {
|
|
3687
|
+
outAssociatedTokenAccount = await this.getAssociatedTokenAccount(
|
|
3688
|
+
outMarket.marketIndex,
|
|
3689
|
+
false
|
|
3690
|
+
);
|
|
3691
|
+
|
|
3692
|
+
const accountInfo = await this.connection.getAccountInfo(
|
|
3693
|
+
outAssociatedTokenAccount
|
|
3694
|
+
);
|
|
3695
|
+
if (!accountInfo) {
|
|
3696
|
+
preInstructions.push(
|
|
3697
|
+
this.createAssociatedTokenAccountIdempotentInstruction(
|
|
3698
|
+
outAssociatedTokenAccount,
|
|
3699
|
+
this.provider.wallet.publicKey,
|
|
3700
|
+
this.provider.wallet.publicKey,
|
|
3701
|
+
outMarket.mint
|
|
3702
|
+
)
|
|
3703
|
+
);
|
|
3704
|
+
}
|
|
3705
|
+
}
|
|
3706
|
+
|
|
3707
|
+
if (!inAssociatedTokenAccount) {
|
|
3708
|
+
inAssociatedTokenAccount = await this.getAssociatedTokenAccount(
|
|
3709
|
+
inMarket.marketIndex,
|
|
3710
|
+
false
|
|
3711
|
+
);
|
|
3712
|
+
|
|
3713
|
+
const accountInfo = await this.connection.getAccountInfo(
|
|
3714
|
+
inAssociatedTokenAccount
|
|
3715
|
+
);
|
|
3716
|
+
if (!accountInfo) {
|
|
3717
|
+
preInstructions.push(
|
|
3718
|
+
this.createAssociatedTokenAccountIdempotentInstruction(
|
|
3719
|
+
inAssociatedTokenAccount,
|
|
3720
|
+
this.provider.wallet.publicKey,
|
|
3721
|
+
this.provider.wallet.publicKey,
|
|
3722
|
+
inMarket.mint
|
|
3723
|
+
)
|
|
3724
|
+
);
|
|
3725
|
+
}
|
|
3726
|
+
}
|
|
3727
|
+
|
|
3728
|
+
const { beginSwapIx, endSwapIx } = await this.getSwapIx({
|
|
3729
|
+
outMarketIndex,
|
|
3730
|
+
inMarketIndex,
|
|
3731
|
+
amountIn: amount,
|
|
3732
|
+
inTokenAccount: inAssociatedTokenAccount,
|
|
3733
|
+
outTokenAccount: outAssociatedTokenAccount,
|
|
3734
|
+
reduceOnly,
|
|
3735
|
+
userAccountPublicKey,
|
|
3736
|
+
});
|
|
3737
|
+
|
|
3738
|
+
const ixs = [
|
|
3739
|
+
...preInstructions,
|
|
3740
|
+
beginSwapIx,
|
|
3741
|
+
...jupiterInstructions,
|
|
3742
|
+
endSwapIx,
|
|
3743
|
+
];
|
|
3744
|
+
|
|
3745
|
+
return { ixs, lookupTables };
|
|
3746
|
+
}
|
|
3747
|
+
|
|
3588
3748
|
/**
|
|
3589
3749
|
* Get the drift begin_swap and end_swap instructions
|
|
3590
3750
|
*
|
package/src/examples/loadDlob.ts
CHANGED
package/src/idl/drift.json
CHANGED
|
@@ -3538,6 +3538,32 @@
|
|
|
3538
3538
|
}
|
|
3539
3539
|
]
|
|
3540
3540
|
},
|
|
3541
|
+
{
|
|
3542
|
+
"name": "updateSpotMarketScaleInitialAssetWeightStart",
|
|
3543
|
+
"accounts": [
|
|
3544
|
+
{
|
|
3545
|
+
"name": "admin",
|
|
3546
|
+
"isMut": false,
|
|
3547
|
+
"isSigner": true
|
|
3548
|
+
},
|
|
3549
|
+
{
|
|
3550
|
+
"name": "state",
|
|
3551
|
+
"isMut": false,
|
|
3552
|
+
"isSigner": false
|
|
3553
|
+
},
|
|
3554
|
+
{
|
|
3555
|
+
"name": "spotMarket",
|
|
3556
|
+
"isMut": true,
|
|
3557
|
+
"isSigner": false
|
|
3558
|
+
}
|
|
3559
|
+
],
|
|
3560
|
+
"args": [
|
|
3561
|
+
{
|
|
3562
|
+
"name": "scaleInitialAssetWeightStart",
|
|
3563
|
+
"type": "u64"
|
|
3564
|
+
}
|
|
3565
|
+
]
|
|
3566
|
+
},
|
|
3541
3567
|
{
|
|
3542
3568
|
"name": "updateSpotMarketOracle",
|
|
3543
3569
|
"accounts": [
|
|
@@ -5357,12 +5383,21 @@
|
|
|
5357
5383
|
],
|
|
5358
5384
|
"type": "u64"
|
|
5359
5385
|
},
|
|
5386
|
+
{
|
|
5387
|
+
"name": "scaleInitialAssetWeightStart",
|
|
5388
|
+
"docs": [
|
|
5389
|
+
"When to begin scaling down the initial asset weight",
|
|
5390
|
+
"disabled when 0",
|
|
5391
|
+
"precision: QUOTE_PRECISION"
|
|
5392
|
+
],
|
|
5393
|
+
"type": "u64"
|
|
5394
|
+
},
|
|
5360
5395
|
{
|
|
5361
5396
|
"name": "padding",
|
|
5362
5397
|
"type": {
|
|
5363
5398
|
"array": [
|
|
5364
5399
|
"u8",
|
|
5365
|
-
|
|
5400
|
+
48
|
|
5366
5401
|
]
|
|
5367
5402
|
}
|
|
5368
5403
|
}
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import pyth from '@pythnetwork/client';
|
|
|
5
5
|
export * from './tokenFaucet';
|
|
6
6
|
export * from './oracles/types';
|
|
7
7
|
export * from './oracles/pythClient';
|
|
8
|
+
export * from './oracles/strictOraclePrice';
|
|
8
9
|
export * from './types';
|
|
9
10
|
export * from './constants/perpMarkets';
|
|
10
11
|
export * from './accounts/fetch';
|
|
@@ -49,6 +50,7 @@ export * from './math/repeg';
|
|
|
49
50
|
export * from './math/margin';
|
|
50
51
|
export * from './math/insurance';
|
|
51
52
|
export * from './math/superStake';
|
|
53
|
+
export * from './math/spotPosition';
|
|
52
54
|
export * from './marinade';
|
|
53
55
|
export * from './orderParams';
|
|
54
56
|
export * from './slot/SlotSubscriber';
|
|
@@ -60,6 +62,7 @@ export * from './constants/numericConstants';
|
|
|
60
62
|
export * from './serum/serumSubscriber';
|
|
61
63
|
export * from './serum/serumFulfillmentConfigMap';
|
|
62
64
|
export * from './phoenix/phoenixSubscriber';
|
|
65
|
+
export * from './priorityFee/priorityFeeSubscriber';
|
|
63
66
|
export * from './phoenix/phoenixFulfillmentConfigMap';
|
|
64
67
|
export * from './tx/fastSingleTxSender';
|
|
65
68
|
export * from './tx/retryTxSender';
|
|
@@ -41,8 +41,179 @@ export interface Route {
|
|
|
41
41
|
swapMode: SwapMode;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
/**
|
|
45
|
+
*
|
|
46
|
+
* @export
|
|
47
|
+
* @interface RoutePlanStep
|
|
48
|
+
*/
|
|
49
|
+
export interface RoutePlanStep {
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
* @type {SwapInfo}
|
|
53
|
+
* @memberof RoutePlanStep
|
|
54
|
+
*/
|
|
55
|
+
swapInfo: SwapInfo;
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* @type {number}
|
|
59
|
+
* @memberof RoutePlanStep
|
|
60
|
+
*/
|
|
61
|
+
percent: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface SwapInfo {
|
|
65
|
+
/**
|
|
66
|
+
*
|
|
67
|
+
* @type {string}
|
|
68
|
+
* @memberof SwapInfo
|
|
69
|
+
*/
|
|
70
|
+
ammKey: string;
|
|
71
|
+
/**
|
|
72
|
+
*
|
|
73
|
+
* @type {string}
|
|
74
|
+
* @memberof SwapInfo
|
|
75
|
+
*/
|
|
76
|
+
label?: string;
|
|
77
|
+
/**
|
|
78
|
+
*
|
|
79
|
+
* @type {string}
|
|
80
|
+
* @memberof SwapInfo
|
|
81
|
+
*/
|
|
82
|
+
inputMint: string;
|
|
83
|
+
/**
|
|
84
|
+
*
|
|
85
|
+
* @type {string}
|
|
86
|
+
* @memberof SwapInfo
|
|
87
|
+
*/
|
|
88
|
+
outputMint: string;
|
|
89
|
+
/**
|
|
90
|
+
*
|
|
91
|
+
* @type {string}
|
|
92
|
+
* @memberof SwapInfo
|
|
93
|
+
*/
|
|
94
|
+
inAmount: string;
|
|
95
|
+
/**
|
|
96
|
+
*
|
|
97
|
+
* @type {string}
|
|
98
|
+
* @memberof SwapInfo
|
|
99
|
+
*/
|
|
100
|
+
outAmount: string;
|
|
101
|
+
/**
|
|
102
|
+
*
|
|
103
|
+
* @type {string}
|
|
104
|
+
* @memberof SwapInfo
|
|
105
|
+
*/
|
|
106
|
+
feeAmount: string;
|
|
107
|
+
/**
|
|
108
|
+
*
|
|
109
|
+
* @type {string}
|
|
110
|
+
* @memberof SwapInfo
|
|
111
|
+
*/
|
|
112
|
+
feeMint: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
*
|
|
117
|
+
* @export
|
|
118
|
+
* @interface PlatformFee
|
|
119
|
+
*/
|
|
120
|
+
export interface PlatformFee {
|
|
121
|
+
/**
|
|
122
|
+
*
|
|
123
|
+
* @type {string}
|
|
124
|
+
* @memberof PlatformFee
|
|
125
|
+
*/
|
|
126
|
+
amount?: string;
|
|
127
|
+
/**
|
|
128
|
+
*
|
|
129
|
+
* @type {number}
|
|
130
|
+
* @memberof PlatformFee
|
|
131
|
+
*/
|
|
132
|
+
feeBps?: number;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
*
|
|
137
|
+
* @export
|
|
138
|
+
* @interface QuoteResponse
|
|
139
|
+
*/
|
|
140
|
+
export interface QuoteResponse {
|
|
141
|
+
/**
|
|
142
|
+
*
|
|
143
|
+
* @type {string}
|
|
144
|
+
* @memberof QuoteResponse
|
|
145
|
+
*/
|
|
146
|
+
inputMint: string;
|
|
147
|
+
/**
|
|
148
|
+
*
|
|
149
|
+
* @type {string}
|
|
150
|
+
* @memberof QuoteResponse
|
|
151
|
+
*/
|
|
152
|
+
inAmount: string;
|
|
153
|
+
/**
|
|
154
|
+
*
|
|
155
|
+
* @type {string}
|
|
156
|
+
* @memberof QuoteResponse
|
|
157
|
+
*/
|
|
158
|
+
outputMint: string;
|
|
159
|
+
/**
|
|
160
|
+
*
|
|
161
|
+
* @type {string}
|
|
162
|
+
* @memberof QuoteResponse
|
|
163
|
+
*/
|
|
164
|
+
outAmount: string;
|
|
165
|
+
/**
|
|
166
|
+
*
|
|
167
|
+
* @type {string}
|
|
168
|
+
* @memberof QuoteResponse
|
|
169
|
+
*/
|
|
170
|
+
otherAmountThreshold: string;
|
|
171
|
+
/**
|
|
172
|
+
*
|
|
173
|
+
* @type {SwapMode}
|
|
174
|
+
* @memberof QuoteResponse
|
|
175
|
+
*/
|
|
176
|
+
swapMode: SwapMode;
|
|
177
|
+
/**
|
|
178
|
+
*
|
|
179
|
+
* @type {number}
|
|
180
|
+
* @memberof QuoteResponse
|
|
181
|
+
*/
|
|
182
|
+
slippageBps: number;
|
|
183
|
+
/**
|
|
184
|
+
*
|
|
185
|
+
* @type {PlatformFee}
|
|
186
|
+
* @memberof QuoteResponse
|
|
187
|
+
*/
|
|
188
|
+
platformFee?: PlatformFee;
|
|
189
|
+
/**
|
|
190
|
+
*
|
|
191
|
+
* @type {string}
|
|
192
|
+
* @memberof QuoteResponse
|
|
193
|
+
*/
|
|
194
|
+
priceImpactPct: string;
|
|
195
|
+
/**
|
|
196
|
+
*
|
|
197
|
+
* @type {Array<RoutePlanStep>}
|
|
198
|
+
* @memberof QuoteResponse
|
|
199
|
+
*/
|
|
200
|
+
routePlan: Array<RoutePlanStep>;
|
|
201
|
+
/**
|
|
202
|
+
*
|
|
203
|
+
* @type {number}
|
|
204
|
+
* @memberof QuoteResponse
|
|
205
|
+
*/
|
|
206
|
+
contextSlot?: number;
|
|
207
|
+
/**
|
|
208
|
+
*
|
|
209
|
+
* @type {number}
|
|
210
|
+
* @memberof QuoteResponse
|
|
211
|
+
*/
|
|
212
|
+
timeTaken?: number;
|
|
213
|
+
}
|
|
214
|
+
|
|
44
215
|
export class JupiterClient {
|
|
45
|
-
url = 'https://quote-api.jup.ag
|
|
216
|
+
url = 'https://quote-api.jup.ag';
|
|
46
217
|
connection: Connection;
|
|
47
218
|
lookupTableCahce = new Map<string, AddressLookupTableAccount>();
|
|
48
219
|
|
|
@@ -51,6 +222,7 @@ export class JupiterClient {
|
|
|
51
222
|
}
|
|
52
223
|
|
|
53
224
|
/**
|
|
225
|
+
* ** @deprecated - use getQuote
|
|
54
226
|
* Get routes for a swap
|
|
55
227
|
* @param inputMint the mint of the input token
|
|
56
228
|
* @param outputMint the mint of the output token
|
|
@@ -84,13 +256,84 @@ export class JupiterClient {
|
|
|
84
256
|
}).toString();
|
|
85
257
|
|
|
86
258
|
const { data: routes } = await (
|
|
87
|
-
await fetch(
|
|
259
|
+
await fetch(`${this.url}/v4/quote?${params}`)
|
|
88
260
|
).json();
|
|
89
261
|
|
|
90
262
|
return routes;
|
|
91
263
|
}
|
|
92
264
|
|
|
93
265
|
/**
|
|
266
|
+
* Get routes for a swap
|
|
267
|
+
* @param inputMint the mint of the input token
|
|
268
|
+
* @param outputMint the mint of the output token
|
|
269
|
+
* @param amount the amount of the input token
|
|
270
|
+
* @param slippageBps the slippage tolerance in basis points
|
|
271
|
+
* @param swapMode the swap mode (ExactIn or ExactOut)
|
|
272
|
+
* @param onlyDirectRoutes whether to only return direct routes
|
|
273
|
+
*/
|
|
274
|
+
public async getQuote({
|
|
275
|
+
inputMint,
|
|
276
|
+
outputMint,
|
|
277
|
+
amount,
|
|
278
|
+
slippageBps = 50,
|
|
279
|
+
swapMode = 'ExactIn',
|
|
280
|
+
onlyDirectRoutes = false,
|
|
281
|
+
}: {
|
|
282
|
+
inputMint: PublicKey;
|
|
283
|
+
outputMint: PublicKey;
|
|
284
|
+
amount: BN;
|
|
285
|
+
slippageBps?: number;
|
|
286
|
+
swapMode?: SwapMode;
|
|
287
|
+
onlyDirectRoutes?: boolean;
|
|
288
|
+
}): Promise<QuoteResponse> {
|
|
289
|
+
const params = new URLSearchParams({
|
|
290
|
+
inputMint: inputMint.toString(),
|
|
291
|
+
outputMint: outputMint.toString(),
|
|
292
|
+
amount: amount.toString(),
|
|
293
|
+
slippageBps: slippageBps.toString(),
|
|
294
|
+
swapMode,
|
|
295
|
+
onlyDirectRoutes: onlyDirectRoutes.toString(),
|
|
296
|
+
}).toString();
|
|
297
|
+
const quote = await (await fetch(`${this.url}/v6/quote?${params}`)).json();
|
|
298
|
+
return quote;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Get a swap transaction for quote
|
|
303
|
+
* @param quoteResponse quote to perform swap
|
|
304
|
+
* @param userPublicKey the signer's wallet public key
|
|
305
|
+
* @param slippageBps the slippage tolerance in basis points
|
|
306
|
+
*/
|
|
307
|
+
public async getSwap({
|
|
308
|
+
quote,
|
|
309
|
+
userPublicKey,
|
|
310
|
+
slippageBps = 50,
|
|
311
|
+
}: {
|
|
312
|
+
quote: QuoteResponse;
|
|
313
|
+
userPublicKey: PublicKey;
|
|
314
|
+
slippageBps?: number;
|
|
315
|
+
}): Promise<VersionedTransaction> {
|
|
316
|
+
const resp = await (
|
|
317
|
+
await fetch(`${this.url}/v6/swap`, {
|
|
318
|
+
method: 'POST',
|
|
319
|
+
headers: {
|
|
320
|
+
'Content-Type': 'application/json',
|
|
321
|
+
},
|
|
322
|
+
body: JSON.stringify({
|
|
323
|
+
quoteResponse: quote,
|
|
324
|
+
userPublicKey,
|
|
325
|
+
slippageBps,
|
|
326
|
+
}),
|
|
327
|
+
})
|
|
328
|
+
).json();
|
|
329
|
+
const { swapTransaction } = resp;
|
|
330
|
+
|
|
331
|
+
const swapTransactionBuf = Buffer.from(swapTransaction, 'base64');
|
|
332
|
+
return VersionedTransaction.deserialize(swapTransactionBuf);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* ** @deprecated - use getSwap
|
|
94
337
|
* Get a swap transaction for a route
|
|
95
338
|
* @param route the route to perform swap
|
|
96
339
|
* @param userPublicKey the signer's wallet public key
|
|
@@ -106,7 +349,7 @@ export class JupiterClient {
|
|
|
106
349
|
slippageBps?: number;
|
|
107
350
|
}): Promise<VersionedTransaction> {
|
|
108
351
|
const resp = await (
|
|
109
|
-
await fetch(`${this.url}/swap`, {
|
|
352
|
+
await fetch(`${this.url}/v4/swap`, {
|
|
110
353
|
method: 'POST',
|
|
111
354
|
headers: {
|
|
112
355
|
'Content-Type': 'application/json',
|
package/src/math/spotBalance.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
import { OraclePriceData } from '../oracles/types';
|
|
23
23
|
import { PERCENTAGE_PRECISION } from '../constants/numericConstants';
|
|
24
24
|
import { divCeil } from './utils';
|
|
25
|
+
import { StrictOraclePrice } from '../oracles/strictOraclePrice';
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* Calculates the balance of a given token amount including any accumulated interest. This
|
|
@@ -102,25 +103,23 @@ export function getSignedTokenAmount(
|
|
|
102
103
|
*
|
|
103
104
|
* @param {BN} tokenAmount - The amount of tokens to calculate the value for (from `getTokenAmount`)
|
|
104
105
|
* @param {number} spotDecimals - The number of decimals in the token.
|
|
105
|
-
* @param {
|
|
106
|
-
* @param {BN} oraclePriceTwap - The Time-Weighted Average Price of the oracle.
|
|
106
|
+
* @param {StrictOraclePrice} strictOraclePrice - Contains oracle price and 5min twap.
|
|
107
107
|
* @return {BN} The calculated value of the given token amount, scaled by `PRICE_PRECISION`
|
|
108
108
|
*/
|
|
109
109
|
export function getStrictTokenValue(
|
|
110
110
|
tokenAmount: BN,
|
|
111
111
|
spotDecimals: number,
|
|
112
|
-
|
|
113
|
-
oraclePriceTwap: BN
|
|
112
|
+
strictOraclePrice: StrictOraclePrice
|
|
114
113
|
): BN {
|
|
115
114
|
if (tokenAmount.eq(ZERO)) {
|
|
116
115
|
return ZERO;
|
|
117
116
|
}
|
|
118
117
|
|
|
119
|
-
let price
|
|
120
|
-
if (tokenAmount.
|
|
121
|
-
price =
|
|
118
|
+
let price;
|
|
119
|
+
if (tokenAmount.gte(ZERO)) {
|
|
120
|
+
price = strictOraclePrice.min();
|
|
122
121
|
} else {
|
|
123
|
-
price =
|
|
122
|
+
price = strictOraclePrice.max();
|
|
124
123
|
}
|
|
125
124
|
|
|
126
125
|
const precisionDecrease = TEN.pow(new BN(spotDecimals));
|
|
@@ -139,7 +138,7 @@ export function getStrictTokenValue(
|
|
|
139
138
|
export function getTokenValue(
|
|
140
139
|
tokenAmount: BN,
|
|
141
140
|
spotDecimals: number,
|
|
142
|
-
oraclePriceData: OraclePriceData
|
|
141
|
+
oraclePriceData: Pick<OraclePriceData, 'price'>
|
|
143
142
|
): BN {
|
|
144
143
|
if (tokenAmount.eq(ZERO)) {
|
|
145
144
|
return ZERO;
|
|
@@ -152,6 +151,7 @@ export function getTokenValue(
|
|
|
152
151
|
|
|
153
152
|
export function calculateAssetWeight(
|
|
154
153
|
balanceAmount: BN,
|
|
154
|
+
oraclePrice: BN,
|
|
155
155
|
spotMarket: SpotMarketAccount,
|
|
156
156
|
marginCategory: MarginCategory
|
|
157
157
|
): BN {
|
|
@@ -174,7 +174,7 @@ export function calculateAssetWeight(
|
|
|
174
174
|
assetWeight = calculateSizeDiscountAssetWeight(
|
|
175
175
|
sizeInAmmReservePrecision,
|
|
176
176
|
new BN(spotMarket.imfFactor),
|
|
177
|
-
|
|
177
|
+
calculateScaledInitialAssetWeight(spotMarket, oraclePrice)
|
|
178
178
|
);
|
|
179
179
|
break;
|
|
180
180
|
case 'Maintenance':
|
|
@@ -185,13 +185,39 @@ export function calculateAssetWeight(
|
|
|
185
185
|
);
|
|
186
186
|
break;
|
|
187
187
|
default:
|
|
188
|
-
assetWeight =
|
|
188
|
+
assetWeight = calculateScaledInitialAssetWeight(spotMarket, oraclePrice);
|
|
189
189
|
break;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
return assetWeight;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
+
export function calculateScaledInitialAssetWeight(
|
|
196
|
+
spotMarket: SpotMarketAccount,
|
|
197
|
+
oraclePrice: BN
|
|
198
|
+
): BN {
|
|
199
|
+
if (spotMarket.scaleInitialAssetWeightStart.eq(ZERO)) {
|
|
200
|
+
return new BN(spotMarket.initialAssetWeight);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const deposits = getTokenAmount(
|
|
204
|
+
spotMarket.depositBalance,
|
|
205
|
+
spotMarket,
|
|
206
|
+
SpotBalanceType.DEPOSIT
|
|
207
|
+
);
|
|
208
|
+
const depositsValue = getTokenValue(deposits, spotMarket.decimals, {
|
|
209
|
+
price: oraclePrice,
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
if (depositsValue.lt(spotMarket.scaleInitialAssetWeightStart)) {
|
|
213
|
+
return new BN(spotMarket.initialAssetWeight);
|
|
214
|
+
} else {
|
|
215
|
+
return new BN(spotMarket.initialAssetWeight)
|
|
216
|
+
.mul(spotMarket.scaleInitialAssetWeightStart)
|
|
217
|
+
.div(depositsValue);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
195
221
|
export function calculateLiabilityWeight(
|
|
196
222
|
size: BN,
|
|
197
223
|
spotMarket: SpotMarketAccount,
|