@drift-labs/sdk 2.22.0 → 2.23.0-beta.1
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/constants/spotMarkets.js +4 -4
- package/lib/driftClient.d.ts +2 -1
- package/lib/driftClient.js +123 -36
- package/lib/factory/oracleClient.js +3 -0
- package/lib/idl/drift.json +13 -2
- package/lib/oracles/pythClient.d.ts +2 -1
- package/lib/oracles/pythClient.js +18 -3
- package/lib/tx/utils.js +6 -2
- package/lib/types.d.ts +4 -0
- package/lib/types.js +1 -0
- package/lib/user.d.ts +3 -3
- package/lib/user.js +44 -25
- package/package.json +1 -1
- package/src/constants/spotMarkets.ts +4 -4
- package/src/driftClient.ts +127 -30
- package/src/factory/oracleClient.ts +4 -0
- package/src/idl/drift.json +13 -2
- package/src/oracles/pythClient.ts +38 -12
- package/src/tx/utils.ts +2 -0
- package/src/types.ts +2 -0
- package/src/user.ts +104 -44
- package/tests/dlob/helpers.ts +3 -0
|
@@ -9,8 +9,8 @@ exports.DevnetSpotMarkets = [
|
|
|
9
9
|
{
|
|
10
10
|
symbol: 'USDC',
|
|
11
11
|
marketIndex: 0,
|
|
12
|
-
oracle: web3_js_1.PublicKey
|
|
13
|
-
oracleSource: __1.OracleSource.
|
|
12
|
+
oracle: new web3_js_1.PublicKey('5SSkXsEKQepHHAewytPVwdej4epN1nxgLVM84L4KXgy7'),
|
|
13
|
+
oracleSource: __1.OracleSource.PYTH_STABLE_COIN,
|
|
14
14
|
mint: new web3_js_1.PublicKey('8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2'),
|
|
15
15
|
precision: new __1.BN(10).pow(numericConstants_1.SIX),
|
|
16
16
|
precisionExp: numericConstants_1.SIX,
|
|
@@ -40,8 +40,8 @@ exports.MainnetSpotMarkets = [
|
|
|
40
40
|
{
|
|
41
41
|
symbol: 'USDC',
|
|
42
42
|
marketIndex: 0,
|
|
43
|
-
oracle: web3_js_1.PublicKey
|
|
44
|
-
oracleSource: __1.OracleSource.
|
|
43
|
+
oracle: new web3_js_1.PublicKey('Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD'),
|
|
44
|
+
oracleSource: __1.OracleSource.PYTH_STABLE_COIN,
|
|
45
45
|
mint: new web3_js_1.PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
|
|
46
46
|
precision: numericConstants_1.QUOTE_PRECISION,
|
|
47
47
|
precisionExp: numericConstants_1.QUOTE_PRECISION_EXP,
|
package/lib/driftClient.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="bn.js" />
|
|
3
3
|
import { AnchorProvider, BN, Program, ProgramAccount } from '@project-serum/anchor';
|
|
4
|
-
import { StateAccount, IWallet, PositionDirection, UserAccount, PerpMarketAccount, OrderParams, Order, SpotMarketAccount, SpotPosition, MakerInfo, TakerInfo, OptionalOrderParams, OrderType, ReferrerInfo, MarketType, TxParams, SerumV3FulfillmentConfigAccount, ReferrerNameAccount, OrderTriggerCondition, PerpMarketExtendedInfo } from './types';
|
|
4
|
+
import { StateAccount, IWallet, PositionDirection, UserAccount, PerpMarketAccount, OrderParams, Order, SpotMarketAccount, SpotPosition, MakerInfo, TakerInfo, OptionalOrderParams, OrderType, ReferrerInfo, MarketType, TxParams, SerumV3FulfillmentConfigAccount, ReferrerNameAccount, OrderTriggerCondition, PerpMarketExtendedInfo, UserStatsAccount } from './types';
|
|
5
5
|
import * as anchor from '@project-serum/anchor';
|
|
6
6
|
import { Connection, PublicKey, TransactionSignature, ConfirmOptions, Transaction, TransactionInstruction, AccountMeta, Signer, AddressLookupTableAccount } from '@solana/web3.js';
|
|
7
7
|
import { TokenFaucet } from './tokenFaucet';
|
|
@@ -104,6 +104,7 @@ export declare class DriftClient {
|
|
|
104
104
|
fetchAllUserAccounts(includeIdle?: boolean): Promise<ProgramAccount<UserAccount>[]>;
|
|
105
105
|
getUserAccountsForDelegate(delegate: PublicKey): Promise<UserAccount[]>;
|
|
106
106
|
getUserAccountsForAuthority(authority: PublicKey): Promise<UserAccount[]>;
|
|
107
|
+
getReferredUserStatsAccountsByReferrer(referrer: PublicKey): Promise<UserStatsAccount[]>;
|
|
107
108
|
getReferrerNameAccountsForAuthority(authority: PublicKey): Promise<ReferrerNameAccount[]>;
|
|
108
109
|
deleteUser(subAccountId?: number, txParams?: TxParams): Promise<TransactionSignature>;
|
|
109
110
|
getUser(subAccountId?: number): User;
|
package/lib/driftClient.js
CHANGED
|
@@ -246,6 +246,7 @@ class DriftClient {
|
|
|
246
246
|
if (!this.marketLookupTable) {
|
|
247
247
|
throw Error('Market lookup table address not set');
|
|
248
248
|
}
|
|
249
|
+
// @ts-ignore
|
|
249
250
|
return (await this.connection.getAddressLookupTable(this.marketLookupTable))
|
|
250
251
|
.value;
|
|
251
252
|
}
|
|
@@ -464,6 +465,18 @@ class DriftClient {
|
|
|
464
465
|
]);
|
|
465
466
|
return programAccounts.map((programAccount) => programAccount.account);
|
|
466
467
|
}
|
|
468
|
+
async getReferredUserStatsAccountsByReferrer(referrer) {
|
|
469
|
+
const programAccounts = await this.program.account.userStats.all([
|
|
470
|
+
{
|
|
471
|
+
memcmp: {
|
|
472
|
+
offset: 40,
|
|
473
|
+
/** data to match, as base-58 encoded string and limited to less than 129 bytes */
|
|
474
|
+
bytes: bs58_1.default.encode(referrer.toBuffer()),
|
|
475
|
+
},
|
|
476
|
+
},
|
|
477
|
+
]);
|
|
478
|
+
return programAccounts.map((programAccount) => programAccount.account);
|
|
479
|
+
}
|
|
467
480
|
async getReferrerNameAccountsForAuthority(authority) {
|
|
468
481
|
const programAccounts = await this.program.account.referrerName.all([
|
|
469
482
|
{
|
|
@@ -559,17 +572,30 @@ class DriftClient {
|
|
|
559
572
|
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
560
573
|
// otherwise remove from slot
|
|
561
574
|
if (slot > lastUserSlot) {
|
|
562
|
-
const
|
|
575
|
+
const perpMarketAccount = this.getPerpMarketAccount(marketIndex);
|
|
563
576
|
perpMarketAccountMap.set(marketIndex, {
|
|
564
|
-
pubkey:
|
|
577
|
+
pubkey: perpMarketAccount.pubkey,
|
|
565
578
|
isSigner: false,
|
|
566
579
|
isWritable: false,
|
|
567
580
|
});
|
|
568
|
-
oracleAccountMap.set(
|
|
569
|
-
pubkey:
|
|
581
|
+
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
582
|
+
pubkey: perpMarketAccount.amm.oracle,
|
|
570
583
|
isSigner: false,
|
|
571
584
|
isWritable: false,
|
|
572
585
|
});
|
|
586
|
+
const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
|
|
587
|
+
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
588
|
+
pubkey: spotMarketAccount.pubkey,
|
|
589
|
+
isSigner: false,
|
|
590
|
+
isWritable: false,
|
|
591
|
+
});
|
|
592
|
+
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
593
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
594
|
+
pubkey: spotMarketAccount.oracle,
|
|
595
|
+
isSigner: false,
|
|
596
|
+
isWritable: false,
|
|
597
|
+
});
|
|
598
|
+
}
|
|
573
599
|
}
|
|
574
600
|
else {
|
|
575
601
|
this.perpMarketLastSlotCache.delete(marketIndex);
|
|
@@ -579,15 +605,15 @@ class DriftClient {
|
|
|
579
605
|
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
580
606
|
// otherwise remove from slot
|
|
581
607
|
if (slot > lastUserSlot) {
|
|
582
|
-
const
|
|
608
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
583
609
|
spotMarketAccountMap.set(marketIndex, {
|
|
584
|
-
pubkey:
|
|
610
|
+
pubkey: spotMarketAccount.pubkey,
|
|
585
611
|
isSigner: false,
|
|
586
612
|
isWritable: false,
|
|
587
613
|
});
|
|
588
|
-
if (!
|
|
589
|
-
oracleAccountMap.set(
|
|
590
|
-
pubkey:
|
|
614
|
+
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
615
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
616
|
+
pubkey: spotMarketAccount.oracle,
|
|
591
617
|
isSigner: false,
|
|
592
618
|
isWritable: false,
|
|
593
619
|
});
|
|
@@ -599,42 +625,68 @@ class DriftClient {
|
|
|
599
625
|
}
|
|
600
626
|
}
|
|
601
627
|
if (params.readablePerpMarketIndex !== undefined) {
|
|
602
|
-
const
|
|
628
|
+
const perpMarketAccount = this.getPerpMarketAccount(params.readablePerpMarketIndex);
|
|
603
629
|
perpMarketAccountMap.set(params.readablePerpMarketIndex, {
|
|
604
|
-
pubkey:
|
|
630
|
+
pubkey: perpMarketAccount.pubkey,
|
|
605
631
|
isSigner: false,
|
|
606
632
|
isWritable: false,
|
|
607
633
|
});
|
|
608
|
-
oracleAccountMap.set(
|
|
609
|
-
pubkey:
|
|
634
|
+
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
635
|
+
pubkey: perpMarketAccount.amm.oracle,
|
|
610
636
|
isSigner: false,
|
|
611
637
|
isWritable: false,
|
|
612
638
|
});
|
|
639
|
+
const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
|
|
640
|
+
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
641
|
+
pubkey: spotMarketAccount.pubkey,
|
|
642
|
+
isSigner: false,
|
|
643
|
+
isWritable: false,
|
|
644
|
+
});
|
|
645
|
+
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
646
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
647
|
+
pubkey: spotMarketAccount.oracle,
|
|
648
|
+
isSigner: false,
|
|
649
|
+
isWritable: false,
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
if (params.readableSpotMarketIndexes !== undefined) {
|
|
654
|
+
for (const readableSpotMarketIndex of params.readableSpotMarketIndexes) {
|
|
655
|
+
const spotMarketAccount = this.getSpotMarketAccount(readableSpotMarketIndex);
|
|
656
|
+
spotMarketAccountMap.set(readableSpotMarketIndex, {
|
|
657
|
+
pubkey: spotMarketAccount.pubkey,
|
|
658
|
+
isSigner: false,
|
|
659
|
+
isWritable: false,
|
|
660
|
+
});
|
|
661
|
+
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
662
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
663
|
+
pubkey: spotMarketAccount.oracle,
|
|
664
|
+
isSigner: false,
|
|
665
|
+
isWritable: false,
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
}
|
|
613
669
|
}
|
|
614
670
|
if (params.writablePerpMarketIndexes !== undefined) {
|
|
615
671
|
for (const writablePerpMarketIndex of params.writablePerpMarketIndexes) {
|
|
616
|
-
const
|
|
672
|
+
const perpMarketAccount = this.getPerpMarketAccount(writablePerpMarketIndex);
|
|
617
673
|
perpMarketAccountMap.set(writablePerpMarketIndex, {
|
|
618
|
-
pubkey:
|
|
674
|
+
pubkey: perpMarketAccount.pubkey,
|
|
619
675
|
isSigner: false,
|
|
620
676
|
isWritable: true,
|
|
621
677
|
});
|
|
622
|
-
oracleAccountMap.set(
|
|
623
|
-
pubkey:
|
|
678
|
+
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
679
|
+
pubkey: perpMarketAccount.amm.oracle,
|
|
624
680
|
isSigner: false,
|
|
625
681
|
isWritable: false,
|
|
626
682
|
});
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
if (params.readableSpotMarketIndexes !== undefined) {
|
|
630
|
-
for (const readableSpotMarketIndex of params.readableSpotMarketIndexes) {
|
|
631
|
-
const spotMarketAccount = this.getSpotMarketAccount(readableSpotMarketIndex);
|
|
632
|
-
spotMarketAccountMap.set(readableSpotMarketIndex, {
|
|
683
|
+
const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
|
|
684
|
+
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
633
685
|
pubkey: spotMarketAccount.pubkey,
|
|
634
686
|
isSigner: false,
|
|
635
687
|
isWritable: false,
|
|
636
688
|
});
|
|
637
|
-
if (spotMarketAccount.
|
|
689
|
+
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
638
690
|
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
639
691
|
pubkey: spotMarketAccount.oracle,
|
|
640
692
|
isSigner: false,
|
|
@@ -688,27 +740,48 @@ class DriftClient {
|
|
|
688
740
|
}
|
|
689
741
|
if (!spotPosition.openAsks.eq(numericConstants_1.ZERO) ||
|
|
690
742
|
!spotPosition.openBids.eq(numericConstants_1.ZERO)) {
|
|
743
|
+
const quoteSpotMarket = this.getQuoteSpotMarketAccount();
|
|
691
744
|
spotMarketAccountMap.set(numericConstants_1.QUOTE_SPOT_MARKET_INDEX, {
|
|
692
|
-
pubkey:
|
|
745
|
+
pubkey: quoteSpotMarket.pubkey,
|
|
693
746
|
isSigner: false,
|
|
694
747
|
isWritable: false,
|
|
695
748
|
});
|
|
749
|
+
if (!quoteSpotMarket.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
750
|
+
oracleAccountMap.set(quoteSpotMarket.oracle.toString(), {
|
|
751
|
+
pubkey: quoteSpotMarket.oracle,
|
|
752
|
+
isSigner: false,
|
|
753
|
+
isWritable: false,
|
|
754
|
+
});
|
|
755
|
+
}
|
|
696
756
|
}
|
|
697
757
|
}
|
|
698
758
|
}
|
|
699
759
|
for (const position of userAccount.perpPositions) {
|
|
700
760
|
if (!(0, position_1.positionIsAvailable)(position)) {
|
|
701
|
-
const
|
|
761
|
+
const perpMarketAccount = this.getPerpMarketAccount(position.marketIndex);
|
|
702
762
|
perpMarketAccountMap.set(position.marketIndex, {
|
|
703
|
-
pubkey:
|
|
763
|
+
pubkey: perpMarketAccount.pubkey,
|
|
704
764
|
isWritable: false,
|
|
705
765
|
isSigner: false,
|
|
706
766
|
});
|
|
707
|
-
oracleAccountMap.set(
|
|
708
|
-
pubkey:
|
|
767
|
+
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
768
|
+
pubkey: perpMarketAccount.amm.oracle,
|
|
709
769
|
isWritable: false,
|
|
710
770
|
isSigner: false,
|
|
711
771
|
});
|
|
772
|
+
const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
|
|
773
|
+
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
774
|
+
pubkey: spotMarketAccount.pubkey,
|
|
775
|
+
isSigner: false,
|
|
776
|
+
isWritable: false,
|
|
777
|
+
});
|
|
778
|
+
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
779
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
780
|
+
pubkey: spotMarketAccount.oracle,
|
|
781
|
+
isSigner: false,
|
|
782
|
+
isWritable: false,
|
|
783
|
+
});
|
|
784
|
+
}
|
|
712
785
|
}
|
|
713
786
|
}
|
|
714
787
|
}
|
|
@@ -728,7 +801,9 @@ class DriftClient {
|
|
|
728
801
|
}
|
|
729
802
|
async deposit(amount, marketIndex, collateralAccountPublicKey, subAccountId, reduceOnly = false) {
|
|
730
803
|
const tx = new web3_js_1.Transaction();
|
|
731
|
-
tx.add(
|
|
804
|
+
tx.add(
|
|
805
|
+
// @ts-ignore
|
|
806
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
732
807
|
units: 600000,
|
|
733
808
|
}));
|
|
734
809
|
const additionalSigners = [];
|
|
@@ -841,11 +916,15 @@ class DriftClient {
|
|
|
841
916
|
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
842
917
|
const isSolMarket = spotMarket.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
|
|
843
918
|
const tx = new web3_js_1.Transaction();
|
|
844
|
-
tx.add(
|
|
919
|
+
tx.add(
|
|
920
|
+
// @ts-ignore
|
|
921
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
845
922
|
units: (_a = txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits) !== null && _a !== void 0 ? _a : 600000,
|
|
846
923
|
}));
|
|
847
924
|
if (txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice) {
|
|
848
|
-
tx.add(
|
|
925
|
+
tx.add(
|
|
926
|
+
// @ts-ignore
|
|
927
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
|
|
849
928
|
microLamports: txParams.computeUnitsPrice,
|
|
850
929
|
}));
|
|
851
930
|
}
|
|
@@ -892,7 +971,9 @@ class DriftClient {
|
|
|
892
971
|
}
|
|
893
972
|
async withdraw(amount, marketIndex, userTokenAccount, reduceOnly = false) {
|
|
894
973
|
const tx = new web3_js_1.Transaction();
|
|
895
|
-
tx.add(
|
|
974
|
+
tx.add(
|
|
975
|
+
// @ts-ignore
|
|
976
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
896
977
|
units: 600000,
|
|
897
978
|
}));
|
|
898
979
|
const additionalSigners = [];
|
|
@@ -1967,7 +2048,9 @@ class DriftClient {
|
|
|
1967
2048
|
? await this.getPlaceSpotOrderIx(newOrderParams)
|
|
1968
2049
|
: await this.getPlacePerpOrderIx(newOrderParams);
|
|
1969
2050
|
const tx = new web3_js_1.Transaction();
|
|
1970
|
-
tx.add(
|
|
2051
|
+
tx.add(
|
|
2052
|
+
// @ts-ignore
|
|
2053
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
1971
2054
|
units: 1000000,
|
|
1972
2055
|
}));
|
|
1973
2056
|
tx.add(cancelOrderIx);
|
|
@@ -2042,7 +2125,9 @@ class DriftClient {
|
|
|
2042
2125
|
? await this.getPlaceSpotOrderIx(newOrderParams)
|
|
2043
2126
|
: await this.getPlacePerpOrderIx(newOrderParams);
|
|
2044
2127
|
const tx = new web3_js_1.Transaction();
|
|
2045
|
-
tx.add(
|
|
2128
|
+
tx.add(
|
|
2129
|
+
// @ts-ignore
|
|
2130
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
2046
2131
|
units: 1000000,
|
|
2047
2132
|
}));
|
|
2048
2133
|
tx.add(cancelOrderIx);
|
|
@@ -2065,7 +2150,9 @@ class DriftClient {
|
|
|
2065
2150
|
}
|
|
2066
2151
|
}
|
|
2067
2152
|
const tx = new web3_js_1.Transaction()
|
|
2068
|
-
.add(
|
|
2153
|
+
.add(
|
|
2154
|
+
// @ts-ignore
|
|
2155
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
2069
2156
|
units: 1000000,
|
|
2070
2157
|
}))
|
|
2071
2158
|
.add(...ixs);
|
|
@@ -16,6 +16,9 @@ function getOracleClient(oracleSource, connection) {
|
|
|
16
16
|
if ((0, types_1.isVariant)(oracleSource, 'pyth1M')) {
|
|
17
17
|
return new pythClient_1.PythClient(connection, new anchor_1.BN(1000000));
|
|
18
18
|
}
|
|
19
|
+
if ((0, types_1.isVariant)(oracleSource, 'pythStableCoin')) {
|
|
20
|
+
return new pythClient_1.PythClient(connection, undefined, true);
|
|
21
|
+
}
|
|
19
22
|
// if (isVariant(oracleSource, 'switchboard')) {
|
|
20
23
|
// return new SwitchboardClient(connection);
|
|
21
24
|
// }
|
package/lib/idl/drift.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.23.0-beta.1",
|
|
3
3
|
"name": "drift",
|
|
4
4
|
"instructions": [
|
|
5
5
|
{
|
|
@@ -4081,12 +4081,20 @@
|
|
|
4081
4081
|
"defined": "ContractTier"
|
|
4082
4082
|
}
|
|
4083
4083
|
},
|
|
4084
|
+
{
|
|
4085
|
+
"name": "padding1",
|
|
4086
|
+
"type": "bool"
|
|
4087
|
+
},
|
|
4088
|
+
{
|
|
4089
|
+
"name": "quoteSpotMarketIndex",
|
|
4090
|
+
"type": "u16"
|
|
4091
|
+
},
|
|
4084
4092
|
{
|
|
4085
4093
|
"name": "padding",
|
|
4086
4094
|
"type": {
|
|
4087
4095
|
"array": [
|
|
4088
4096
|
"u8",
|
|
4089
|
-
|
|
4097
|
+
48
|
|
4090
4098
|
]
|
|
4091
4099
|
}
|
|
4092
4100
|
}
|
|
@@ -6383,6 +6391,9 @@
|
|
|
6383
6391
|
},
|
|
6384
6392
|
{
|
|
6385
6393
|
"name": "Pyth1M"
|
|
6394
|
+
},
|
|
6395
|
+
{
|
|
6396
|
+
"name": "PythStableCoin"
|
|
6386
6397
|
}
|
|
6387
6398
|
]
|
|
6388
6399
|
}
|
|
@@ -6,7 +6,8 @@ import { BN } from '@project-serum/anchor';
|
|
|
6
6
|
export declare class PythClient implements OracleClient {
|
|
7
7
|
private connection;
|
|
8
8
|
private multiple;
|
|
9
|
-
|
|
9
|
+
private stableCoin;
|
|
10
|
+
constructor(connection: Connection, multiple?: BN, stableCoin?: boolean);
|
|
10
11
|
getOraclePriceData(pricePublicKey: PublicKey): Promise<OraclePriceData>;
|
|
11
12
|
getOraclePriceDataFromBuffer(buffer: Buffer): OraclePriceData;
|
|
12
13
|
}
|
|
@@ -5,9 +5,10 @@ const client_1 = require("@pythnetwork/client");
|
|
|
5
5
|
const anchor_1 = require("@project-serum/anchor");
|
|
6
6
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
7
7
|
class PythClient {
|
|
8
|
-
constructor(connection, multiple = numericConstants_1.ONE) {
|
|
8
|
+
constructor(connection, multiple = numericConstants_1.ONE, stableCoin = false) {
|
|
9
9
|
this.connection = connection;
|
|
10
10
|
this.multiple = multiple;
|
|
11
|
+
this.stableCoin = stableCoin;
|
|
11
12
|
}
|
|
12
13
|
async getOraclePriceData(pricePublicKey) {
|
|
13
14
|
const accountInfo = await this.connection.getAccountInfo(pricePublicKey);
|
|
@@ -15,10 +16,15 @@ class PythClient {
|
|
|
15
16
|
}
|
|
16
17
|
getOraclePriceDataFromBuffer(buffer) {
|
|
17
18
|
const priceData = (0, client_1.parsePriceData)(buffer);
|
|
19
|
+
const confidence = convertPythPrice(priceData.confidence, priceData.exponent, this.multiple);
|
|
20
|
+
let price = convertPythPrice(priceData.aggregate.price, priceData.exponent, this.multiple);
|
|
21
|
+
if (this.stableCoin) {
|
|
22
|
+
price = getStableCoinPrice(price, confidence);
|
|
23
|
+
}
|
|
18
24
|
return {
|
|
19
|
-
price
|
|
25
|
+
price,
|
|
20
26
|
slot: new anchor_1.BN(priceData.lastSlot.toString()),
|
|
21
|
-
confidence
|
|
27
|
+
confidence,
|
|
22
28
|
twap: convertPythPrice(priceData.twap.value, priceData.exponent, this.multiple),
|
|
23
29
|
twapConfidence: convertPythPrice(priceData.twac.value, priceData.exponent, this.multiple),
|
|
24
30
|
hasSufficientNumberOfDataPoints: true,
|
|
@@ -34,3 +40,12 @@ function convertPythPrice(price, exponent, multiple) {
|
|
|
34
40
|
.div(pythPrecision);
|
|
35
41
|
}
|
|
36
42
|
exports.convertPythPrice = convertPythPrice;
|
|
43
|
+
const fiveBPS = new anchor_1.BN(500);
|
|
44
|
+
function getStableCoinPrice(price, confidence) {
|
|
45
|
+
if (price.sub(numericConstants_1.QUOTE_PRECISION).abs().lt(anchor_1.BN.min(confidence, fiveBPS))) {
|
|
46
|
+
return numericConstants_1.QUOTE_PRECISION;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
return price;
|
|
50
|
+
}
|
|
51
|
+
}
|
package/lib/tx/utils.js
CHANGED
|
@@ -6,12 +6,16 @@ const COMPUTE_UNITS_DEFAULT = 200000;
|
|
|
6
6
|
function wrapInTx(instruction, computeUnits = 600000, computeUnitsPrice = 0) {
|
|
7
7
|
const tx = new web3_js_1.Transaction();
|
|
8
8
|
if (computeUnits != COMPUTE_UNITS_DEFAULT) {
|
|
9
|
-
tx.add(
|
|
9
|
+
tx.add(
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
10
12
|
units: computeUnits,
|
|
11
13
|
}));
|
|
12
14
|
}
|
|
13
15
|
if (computeUnitsPrice != 0) {
|
|
14
|
-
tx.add(
|
|
16
|
+
tx.add(
|
|
17
|
+
// @ts-ignore
|
|
18
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
|
|
15
19
|
microLamports: computeUnitsPrice,
|
|
16
20
|
}));
|
|
17
21
|
}
|
package/lib/types.d.ts
CHANGED
|
@@ -139,6 +139,9 @@ export declare class OracleSource {
|
|
|
139
139
|
static readonly QUOTE_ASSET: {
|
|
140
140
|
quoteAsset: {};
|
|
141
141
|
};
|
|
142
|
+
static readonly PYTH_STABLE_COIN: {
|
|
143
|
+
pythStableCoin: {};
|
|
144
|
+
};
|
|
142
145
|
}
|
|
143
146
|
export declare class OrderType {
|
|
144
147
|
static readonly LIMIT: {
|
|
@@ -635,6 +638,7 @@ export type PerpMarketAccount = {
|
|
|
635
638
|
quoteSettledInsurance: BN;
|
|
636
639
|
quoteMaxInsurance: BN;
|
|
637
640
|
};
|
|
641
|
+
quoteSpotMarketIndex: number;
|
|
638
642
|
};
|
|
639
643
|
export type HistoricalOracleData = {
|
|
640
644
|
lastOraclePrice: BN;
|
package/lib/types.js
CHANGED
|
@@ -82,6 +82,7 @@ OracleSource.PYTH_1K = { pyth1K: {} };
|
|
|
82
82
|
OracleSource.PYTH_1M = { pyth1M: {} };
|
|
83
83
|
// static readonly SWITCHBOARD = { switchboard: {} };
|
|
84
84
|
OracleSource.QUOTE_ASSET = { quoteAsset: {} };
|
|
85
|
+
OracleSource.PYTH_STABLE_COIN = { pythStableCoin: {} };
|
|
85
86
|
class OrderType {
|
|
86
87
|
}
|
|
87
88
|
exports.OrderType = OrderType;
|
package/lib/user.d.ts
CHANGED
|
@@ -104,7 +104,7 @@ export declare class User {
|
|
|
104
104
|
* calculates unrealized position price pnl
|
|
105
105
|
* @returns : Precision QUOTE_PRECISION
|
|
106
106
|
*/
|
|
107
|
-
getUnrealizedPNL(withFunding?: boolean, marketIndex?: number, withWeightMarginCategory?: MarginCategory): BN;
|
|
107
|
+
getUnrealizedPNL(withFunding?: boolean, marketIndex?: number, withWeightMarginCategory?: MarginCategory, strict?: boolean): BN;
|
|
108
108
|
/**
|
|
109
109
|
* calculates unrealized funding payment pnl
|
|
110
110
|
* @returns : Precision QUOTE_PRECISION
|
|
@@ -125,7 +125,7 @@ export declare class User {
|
|
|
125
125
|
* calculates TotalCollateral: collateral + unrealized pnl
|
|
126
126
|
* @returns : Precision QUOTE_PRECISION
|
|
127
127
|
*/
|
|
128
|
-
getTotalCollateral(marginCategory?: MarginCategory): BN;
|
|
128
|
+
getTotalCollateral(marginCategory?: MarginCategory, strict?: boolean): BN;
|
|
129
129
|
/**
|
|
130
130
|
* calculates User Health by comparing total collateral and maint. margin requirement
|
|
131
131
|
* @returns : number (value from [0, 100])
|
|
@@ -135,7 +135,7 @@ export declare class User {
|
|
|
135
135
|
* calculates sum of position value across all positions in margin system
|
|
136
136
|
* @returns : Precision QUOTE_PRECISION
|
|
137
137
|
*/
|
|
138
|
-
getTotalPerpPositionValue(marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean): BN;
|
|
138
|
+
getTotalPerpPositionValue(marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean): BN;
|
|
139
139
|
/**
|
|
140
140
|
* calculates position value in margin system
|
|
141
141
|
* @returns : Precision QUOTE_PRECISION
|