@drift-labs/sdk 2.31.1-beta.8 → 2.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +1 -1
- package/lib/constants/perpMarkets.js +20 -0
- package/lib/dlob/orderBookLevels.js +2 -2
- package/lib/driftClient.d.ts +53 -5
- package/lib/driftClient.js +203 -196
- package/lib/idl/drift.json +31 -1
- package/lib/index.d.ts +3 -0
- package/lib/index.js +3 -0
- package/lib/marinade/index.d.ts +11 -0
- package/lib/marinade/index.js +36 -0
- package/lib/marinade/types.d.ts +1963 -0
- package/lib/marinade/types.js +1965 -0
- package/lib/math/spotBalance.d.ts +9 -2
- package/lib/math/spotBalance.js +54 -6
- package/lib/math/superStake.d.ts +22 -0
- package/lib/math/superStake.js +108 -0
- package/lib/math/utils.d.ts +1 -0
- package/lib/math/utils.js +5 -1
- package/lib/orderParams.d.ts +18 -5
- package/lib/orderParams.js +17 -1
- package/lib/user.d.ts +45 -1
- package/lib/user.js +227 -9
- package/package.json +1 -1
- package/src/assert/assert.js +9 -0
- package/src/constants/perpMarkets.ts +20 -0
- package/src/dlob/orderBookLevels.ts +3 -2
- package/src/driftClient.ts +383 -225
- package/src/idl/drift.json +31 -1
- package/src/index.ts +3 -0
- package/src/marinade/idl/idl.json +1962 -0
- package/src/marinade/index.ts +64 -0
- package/src/marinade/types.ts +3925 -0
- package/src/math/spotBalance.ts +83 -5
- package/src/math/superStake.ts +148 -0
- package/src/math/utils.ts +4 -0
- package/src/orderParams.ts +35 -5
- package/src/token/index.js +38 -0
- package/src/user.ts +453 -15
- package/src/util/computeUnits.js +27 -0
- package/src/util/promiseTimeout.js +14 -0
- package/src/util/tps.js +27 -0
- package/tests/spot/test.ts +156 -0
package/lib/driftClient.js
CHANGED
|
@@ -52,6 +52,8 @@ const market_1 = require("./math/market");
|
|
|
52
52
|
const fetch_1 = require("./accounts/fetch");
|
|
53
53
|
const spotMarket_1 = require("./math/spotMarket");
|
|
54
54
|
const memcmp_1 = require("./memcmp");
|
|
55
|
+
const marinade_1 = require("./marinade");
|
|
56
|
+
const orderParams_1 = require("./orderParams");
|
|
55
57
|
/**
|
|
56
58
|
* # DriftClient
|
|
57
59
|
* This class is the main way to interact with Drift Protocol. It allows you to subscribe to the various accounts where the Market's state is stored, as well as: opening positions, liquidating, settling funding, depositing & withdrawing, and more.
|
|
@@ -69,6 +71,8 @@ class DriftClient {
|
|
|
69
71
|
this._isSubscribed = false;
|
|
70
72
|
this.perpMarketLastSlotCache = new Map();
|
|
71
73
|
this.spotMarketLastSlotCache = new Map();
|
|
74
|
+
this.mustIncludePerpMarketIndexes = new Set();
|
|
75
|
+
this.mustIncludeSpotMarketIndexes = new Set();
|
|
72
76
|
this.connection = config.connection;
|
|
73
77
|
this.wallet = config.wallet;
|
|
74
78
|
this.opts = config.opts || anchor_1.AnchorProvider.defaultOptions();
|
|
@@ -505,6 +509,27 @@ class DriftClient {
|
|
|
505
509
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
506
510
|
return txSig;
|
|
507
511
|
}
|
|
512
|
+
async getUpdateUserMarginTradingEnabledIx(marginTradingEnabled, subAccountId = 0, userAccountPublicKey) {
|
|
513
|
+
const userAccountPublicKeyToUse = userAccountPublicKey ||
|
|
514
|
+
(0, pda_1.getUserAccountPublicKeySync)(this.program.programId, this.wallet.publicKey, subAccountId);
|
|
515
|
+
await this.addUser(subAccountId, this.wallet.publicKey);
|
|
516
|
+
let remainingAccounts;
|
|
517
|
+
try {
|
|
518
|
+
remainingAccounts = this.getRemainingAccounts({
|
|
519
|
+
userAccounts: [this.getUserAccount(subAccountId)],
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
catch (err) {
|
|
523
|
+
remainingAccounts = [];
|
|
524
|
+
}
|
|
525
|
+
return await this.program.instruction.updateUserMarginTradingEnabled(subAccountId, marginTradingEnabled, {
|
|
526
|
+
accounts: {
|
|
527
|
+
user: userAccountPublicKeyToUse,
|
|
528
|
+
authority: this.wallet.publicKey,
|
|
529
|
+
},
|
|
530
|
+
remainingAccounts,
|
|
531
|
+
});
|
|
532
|
+
}
|
|
508
533
|
async updateUserMarginTradingEnabled(marginTradingEnabled, subAccountId = 0) {
|
|
509
534
|
const userAccountPublicKey = (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, this.wallet.publicKey, subAccountId);
|
|
510
535
|
await this.addUser(subAccountId, this.wallet.publicKey);
|
|
@@ -624,10 +649,16 @@ class DriftClient {
|
|
|
624
649
|
authority = authority !== null && authority !== void 0 ? authority : this.authority;
|
|
625
650
|
const userMapKey = this.getUserMapKey(subAccountId, authority);
|
|
626
651
|
if (!this.users.has(userMapKey)) {
|
|
627
|
-
throw new Error(`
|
|
652
|
+
throw new Error(`DriftClient has no user for user id ${userMapKey}`);
|
|
628
653
|
}
|
|
629
654
|
return this.users.get(userMapKey);
|
|
630
655
|
}
|
|
656
|
+
hasUser(subAccountId, authority) {
|
|
657
|
+
subAccountId = subAccountId !== null && subAccountId !== void 0 ? subAccountId : this.activeSubAccountId;
|
|
658
|
+
authority = authority !== null && authority !== void 0 ? authority : this.authority;
|
|
659
|
+
const userMapKey = this.getUserMapKey(subAccountId, authority);
|
|
660
|
+
return this.users.has(userMapKey);
|
|
661
|
+
}
|
|
631
662
|
getUsers() {
|
|
632
663
|
// delegate users get added to the end
|
|
633
664
|
return [...this.users.values()]
|
|
@@ -710,6 +741,21 @@ class DriftClient {
|
|
|
710
741
|
amount = typeof amount === 'number' ? new anchor_1.BN(amount) : amount;
|
|
711
742
|
return amount.mul(numericConstants_1.PRICE_PRECISION);
|
|
712
743
|
}
|
|
744
|
+
/**
|
|
745
|
+
* Each drift instruction must include perp and sport market accounts in the ix remaining accounts.
|
|
746
|
+
* Use this function to force a subset of markets to be included in the remaining accounts for every ix
|
|
747
|
+
*
|
|
748
|
+
* @param perpMarketIndexes
|
|
749
|
+
* @param spotMarketIndexes
|
|
750
|
+
*/
|
|
751
|
+
mustIncludeMarketsInIx({ perpMarketIndexes, spotMarketIndexes, }) {
|
|
752
|
+
perpMarketIndexes.forEach((perpMarketIndex) => {
|
|
753
|
+
this.mustIncludePerpMarketIndexes.add(perpMarketIndex);
|
|
754
|
+
});
|
|
755
|
+
spotMarketIndexes.forEach((spotMarketIndex) => {
|
|
756
|
+
this.mustIncludeSpotMarketIndexes.add(spotMarketIndex);
|
|
757
|
+
});
|
|
758
|
+
}
|
|
713
759
|
getRemainingAccounts(params) {
|
|
714
760
|
var _a;
|
|
715
761
|
const { oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap } = this.getRemainingAccountMapsForUsers(params.userAccounts);
|
|
@@ -719,30 +765,7 @@ class DriftClient {
|
|
|
719
765
|
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
720
766
|
// otherwise remove from slot
|
|
721
767
|
if (slot > lastUserSlot) {
|
|
722
|
-
|
|
723
|
-
perpMarketAccountMap.set(marketIndex, {
|
|
724
|
-
pubkey: perpMarketAccount.pubkey,
|
|
725
|
-
isSigner: false,
|
|
726
|
-
isWritable: false,
|
|
727
|
-
});
|
|
728
|
-
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
729
|
-
pubkey: perpMarketAccount.amm.oracle,
|
|
730
|
-
isSigner: false,
|
|
731
|
-
isWritable: false,
|
|
732
|
-
});
|
|
733
|
-
const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
|
|
734
|
-
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
735
|
-
pubkey: spotMarketAccount.pubkey,
|
|
736
|
-
isSigner: false,
|
|
737
|
-
isWritable: false,
|
|
738
|
-
});
|
|
739
|
-
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
740
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
741
|
-
pubkey: spotMarketAccount.oracle,
|
|
742
|
-
isSigner: false,
|
|
743
|
-
isWritable: false,
|
|
744
|
-
});
|
|
745
|
-
}
|
|
768
|
+
this.addPerpMarketToRemainingAccountMaps(marketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
|
|
746
769
|
}
|
|
747
770
|
else {
|
|
748
771
|
this.perpMarketLastSlotCache.delete(marketIndex);
|
|
@@ -752,19 +775,7 @@ class DriftClient {
|
|
|
752
775
|
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
753
776
|
// otherwise remove from slot
|
|
754
777
|
if (slot > lastUserSlot) {
|
|
755
|
-
|
|
756
|
-
spotMarketAccountMap.set(marketIndex, {
|
|
757
|
-
pubkey: spotMarketAccount.pubkey,
|
|
758
|
-
isSigner: false,
|
|
759
|
-
isWritable: false,
|
|
760
|
-
});
|
|
761
|
-
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
762
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
763
|
-
pubkey: spotMarketAccount.oracle,
|
|
764
|
-
isSigner: false,
|
|
765
|
-
isWritable: false,
|
|
766
|
-
});
|
|
767
|
-
}
|
|
778
|
+
this.addSpotMarketToRemainingAccountMaps(marketIndex, false, oracleAccountMap, spotMarketAccountMap);
|
|
768
779
|
}
|
|
769
780
|
else {
|
|
770
781
|
this.spotMarketLastSlotCache.delete(marketIndex);
|
|
@@ -772,91 +783,32 @@ class DriftClient {
|
|
|
772
783
|
}
|
|
773
784
|
}
|
|
774
785
|
if (params.readablePerpMarketIndex !== undefined) {
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
});
|
|
781
|
-
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
782
|
-
pubkey: perpMarketAccount.amm.oracle,
|
|
783
|
-
isSigner: false,
|
|
784
|
-
isWritable: false,
|
|
785
|
-
});
|
|
786
|
-
const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
|
|
787
|
-
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
788
|
-
pubkey: spotMarketAccount.pubkey,
|
|
789
|
-
isSigner: false,
|
|
790
|
-
isWritable: false,
|
|
791
|
-
});
|
|
792
|
-
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
793
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
794
|
-
pubkey: spotMarketAccount.oracle,
|
|
795
|
-
isSigner: false,
|
|
796
|
-
isWritable: false,
|
|
797
|
-
});
|
|
786
|
+
const readablePerpMarketIndexes = Array.isArray(params.readablePerpMarketIndex)
|
|
787
|
+
? params.readablePerpMarketIndex
|
|
788
|
+
: [params.readablePerpMarketIndex];
|
|
789
|
+
for (const marketIndex of readablePerpMarketIndexes) {
|
|
790
|
+
this.addPerpMarketToRemainingAccountMaps(marketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
|
|
798
791
|
}
|
|
799
792
|
}
|
|
793
|
+
for (const perpMarketIndex of this.mustIncludePerpMarketIndexes.values()) {
|
|
794
|
+
this.addPerpMarketToRemainingAccountMaps(perpMarketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
|
|
795
|
+
}
|
|
800
796
|
if (params.readableSpotMarketIndexes !== undefined) {
|
|
801
797
|
for (const readableSpotMarketIndex of params.readableSpotMarketIndexes) {
|
|
802
|
-
|
|
803
|
-
spotMarketAccountMap.set(readableSpotMarketIndex, {
|
|
804
|
-
pubkey: spotMarketAccount.pubkey,
|
|
805
|
-
isSigner: false,
|
|
806
|
-
isWritable: false,
|
|
807
|
-
});
|
|
808
|
-
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
809
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
810
|
-
pubkey: spotMarketAccount.oracle,
|
|
811
|
-
isSigner: false,
|
|
812
|
-
isWritable: false,
|
|
813
|
-
});
|
|
814
|
-
}
|
|
798
|
+
this.addSpotMarketToRemainingAccountMaps(readableSpotMarketIndex, false, oracleAccountMap, spotMarketAccountMap);
|
|
815
799
|
}
|
|
816
800
|
}
|
|
801
|
+
for (const spotMarketIndex of this.mustIncludeSpotMarketIndexes.values()) {
|
|
802
|
+
this.addSpotMarketToRemainingAccountMaps(spotMarketIndex, false, oracleAccountMap, spotMarketAccountMap);
|
|
803
|
+
}
|
|
817
804
|
if (params.writablePerpMarketIndexes !== undefined) {
|
|
818
805
|
for (const writablePerpMarketIndex of params.writablePerpMarketIndexes) {
|
|
819
|
-
|
|
820
|
-
perpMarketAccountMap.set(writablePerpMarketIndex, {
|
|
821
|
-
pubkey: perpMarketAccount.pubkey,
|
|
822
|
-
isSigner: false,
|
|
823
|
-
isWritable: true,
|
|
824
|
-
});
|
|
825
|
-
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
826
|
-
pubkey: perpMarketAccount.amm.oracle,
|
|
827
|
-
isSigner: false,
|
|
828
|
-
isWritable: false,
|
|
829
|
-
});
|
|
830
|
-
const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
|
|
831
|
-
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
832
|
-
pubkey: spotMarketAccount.pubkey,
|
|
833
|
-
isSigner: false,
|
|
834
|
-
isWritable: false,
|
|
835
|
-
});
|
|
836
|
-
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
837
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
838
|
-
pubkey: spotMarketAccount.oracle,
|
|
839
|
-
isSigner: false,
|
|
840
|
-
isWritable: false,
|
|
841
|
-
});
|
|
842
|
-
}
|
|
806
|
+
this.addPerpMarketToRemainingAccountMaps(writablePerpMarketIndex, true, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
|
|
843
807
|
}
|
|
844
808
|
}
|
|
845
809
|
if (params.writableSpotMarketIndexes !== undefined) {
|
|
846
810
|
for (const writableSpotMarketIndex of params.writableSpotMarketIndexes) {
|
|
847
|
-
|
|
848
|
-
spotMarketAccountMap.set(spotMarketAccount.marketIndex, {
|
|
849
|
-
pubkey: spotMarketAccount.pubkey,
|
|
850
|
-
isSigner: false,
|
|
851
|
-
isWritable: true,
|
|
852
|
-
});
|
|
853
|
-
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
854
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
855
|
-
pubkey: spotMarketAccount.oracle,
|
|
856
|
-
isSigner: false,
|
|
857
|
-
isWritable: false,
|
|
858
|
-
});
|
|
859
|
-
}
|
|
811
|
+
this.addSpotMarketToRemainingAccountMaps(writableSpotMarketIndex, true, oracleAccountMap, spotMarketAccountMap);
|
|
860
812
|
}
|
|
861
813
|
}
|
|
862
814
|
return [
|
|
@@ -865,6 +817,35 @@ class DriftClient {
|
|
|
865
817
|
...perpMarketAccountMap.values(),
|
|
866
818
|
];
|
|
867
819
|
}
|
|
820
|
+
addPerpMarketToRemainingAccountMaps(marketIndex, writable, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap) {
|
|
821
|
+
const perpMarketAccount = this.getPerpMarketAccount(marketIndex);
|
|
822
|
+
perpMarketAccountMap.set(marketIndex, {
|
|
823
|
+
pubkey: perpMarketAccount.pubkey,
|
|
824
|
+
isSigner: false,
|
|
825
|
+
isWritable: writable,
|
|
826
|
+
});
|
|
827
|
+
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
828
|
+
pubkey: perpMarketAccount.amm.oracle,
|
|
829
|
+
isSigner: false,
|
|
830
|
+
isWritable: false,
|
|
831
|
+
});
|
|
832
|
+
this.addSpotMarketToRemainingAccountMaps(perpMarketAccount.quoteSpotMarketIndex, false, oracleAccountMap, spotMarketAccountMap);
|
|
833
|
+
}
|
|
834
|
+
addSpotMarketToRemainingAccountMaps(marketIndex, writable, oracleAccountMap, spotMarketAccountMap) {
|
|
835
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
836
|
+
spotMarketAccountMap.set(spotMarketAccount.marketIndex, {
|
|
837
|
+
pubkey: spotMarketAccount.pubkey,
|
|
838
|
+
isSigner: false,
|
|
839
|
+
isWritable: writable,
|
|
840
|
+
});
|
|
841
|
+
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
842
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
843
|
+
pubkey: spotMarketAccount.oracle,
|
|
844
|
+
isSigner: false,
|
|
845
|
+
isWritable: false,
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
}
|
|
868
849
|
getRemainingAccountMapsForUsers(userAccounts) {
|
|
869
850
|
const oracleAccountMap = new Map();
|
|
870
851
|
const spotMarketAccountMap = new Map();
|
|
@@ -872,63 +853,16 @@ class DriftClient {
|
|
|
872
853
|
for (const userAccount of userAccounts) {
|
|
873
854
|
for (const spotPosition of userAccount.spotPositions) {
|
|
874
855
|
if (!(0, spotPosition_1.isSpotPositionAvailable)(spotPosition)) {
|
|
875
|
-
|
|
876
|
-
spotMarketAccountMap.set(spotPosition.marketIndex, {
|
|
877
|
-
pubkey: spotMarket.pubkey,
|
|
878
|
-
isSigner: false,
|
|
879
|
-
isWritable: false,
|
|
880
|
-
});
|
|
881
|
-
if (!spotMarket.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
882
|
-
oracleAccountMap.set(spotMarket.oracle.toString(), {
|
|
883
|
-
pubkey: spotMarket.oracle,
|
|
884
|
-
isSigner: false,
|
|
885
|
-
isWritable: false,
|
|
886
|
-
});
|
|
887
|
-
}
|
|
856
|
+
this.addSpotMarketToRemainingAccountMaps(spotPosition.marketIndex, false, oracleAccountMap, spotMarketAccountMap);
|
|
888
857
|
if (!spotPosition.openAsks.eq(numericConstants_1.ZERO) ||
|
|
889
858
|
!spotPosition.openBids.eq(numericConstants_1.ZERO)) {
|
|
890
|
-
|
|
891
|
-
spotMarketAccountMap.set(numericConstants_1.QUOTE_SPOT_MARKET_INDEX, {
|
|
892
|
-
pubkey: quoteSpotMarket.pubkey,
|
|
893
|
-
isSigner: false,
|
|
894
|
-
isWritable: false,
|
|
895
|
-
});
|
|
896
|
-
if (!quoteSpotMarket.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
897
|
-
oracleAccountMap.set(quoteSpotMarket.oracle.toString(), {
|
|
898
|
-
pubkey: quoteSpotMarket.oracle,
|
|
899
|
-
isSigner: false,
|
|
900
|
-
isWritable: false,
|
|
901
|
-
});
|
|
902
|
-
}
|
|
859
|
+
this.addSpotMarketToRemainingAccountMaps(numericConstants_1.QUOTE_SPOT_MARKET_INDEX, false, oracleAccountMap, spotMarketAccountMap);
|
|
903
860
|
}
|
|
904
861
|
}
|
|
905
862
|
}
|
|
906
863
|
for (const position of userAccount.perpPositions) {
|
|
907
864
|
if (!(0, position_1.positionIsAvailable)(position)) {
|
|
908
|
-
|
|
909
|
-
perpMarketAccountMap.set(position.marketIndex, {
|
|
910
|
-
pubkey: perpMarketAccount.pubkey,
|
|
911
|
-
isWritable: false,
|
|
912
|
-
isSigner: false,
|
|
913
|
-
});
|
|
914
|
-
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
|
|
915
|
-
pubkey: perpMarketAccount.amm.oracle,
|
|
916
|
-
isWritable: false,
|
|
917
|
-
isSigner: false,
|
|
918
|
-
});
|
|
919
|
-
const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
|
|
920
|
-
spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
|
|
921
|
-
pubkey: spotMarketAccount.pubkey,
|
|
922
|
-
isSigner: false,
|
|
923
|
-
isWritable: false,
|
|
924
|
-
});
|
|
925
|
-
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
926
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
927
|
-
pubkey: spotMarketAccount.oracle,
|
|
928
|
-
isSigner: false,
|
|
929
|
-
isWritable: false,
|
|
930
|
-
});
|
|
931
|
-
}
|
|
865
|
+
this.addPerpMarketToRemainingAccountMaps(position.marketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
|
|
932
866
|
}
|
|
933
867
|
}
|
|
934
868
|
}
|
|
@@ -1082,7 +1016,7 @@ class DriftClient {
|
|
|
1082
1016
|
return (0, spl_token_1.createAssociatedTokenAccountInstruction)(this.wallet.publicKey, associatedTokenAddress, this.wallet.publicKey, tokenMintAddress);
|
|
1083
1017
|
}
|
|
1084
1018
|
/**
|
|
1085
|
-
* Creates the
|
|
1019
|
+
* Creates the User account for a user, and deposits some initial collateral
|
|
1086
1020
|
* @param amount
|
|
1087
1021
|
* @param userTokenAccount
|
|
1088
1022
|
* @param marketIndex
|
|
@@ -1460,13 +1394,8 @@ class DriftClient {
|
|
|
1460
1394
|
this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
|
|
1461
1395
|
return txSig;
|
|
1462
1396
|
}
|
|
1463
|
-
getOrderParams(optionalOrderParams, marketType) {
|
|
1464
|
-
return Object.assign({}, types_1.DefaultOrderParams, optionalOrderParams, {
|
|
1465
|
-
marketType,
|
|
1466
|
-
});
|
|
1467
|
-
}
|
|
1468
1397
|
async getPlacePerpOrderIx(orderParams) {
|
|
1469
|
-
orderParams =
|
|
1398
|
+
orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.PERP });
|
|
1470
1399
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1471
1400
|
const remainingAccounts = this.getRemainingAccounts({
|
|
1472
1401
|
userAccounts: [this.getUserAccount()],
|
|
@@ -1639,23 +1568,48 @@ class DriftClient {
|
|
|
1639
1568
|
});
|
|
1640
1569
|
}
|
|
1641
1570
|
async cancelAndPlaceOrders(cancelOrderParams, placeOrderParams, txParams) {
|
|
1642
|
-
const
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1571
|
+
const ixs = [
|
|
1572
|
+
await this.getCancelOrdersIx(cancelOrderParams.marketType, cancelOrderParams.marketIndex, cancelOrderParams.direction),
|
|
1573
|
+
await this.getPlaceOrdersIx(placeOrderParams),
|
|
1574
|
+
];
|
|
1575
|
+
const tx = await this.buildTransaction(ixs, txParams);
|
|
1576
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
1577
|
+
return txSig;
|
|
1578
|
+
}
|
|
1579
|
+
async placeOrders(params, txParams) {
|
|
1580
|
+
const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getPlaceOrdersIx(params), txParams), [], this.opts);
|
|
1581
|
+
return txSig;
|
|
1582
|
+
}
|
|
1583
|
+
async getPlaceOrdersIx(params) {
|
|
1584
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1585
|
+
const readablePerpMarketIndex = [];
|
|
1586
|
+
const readableSpotMarketIndexes = [];
|
|
1587
|
+
for (const param of params) {
|
|
1588
|
+
if (!param.marketType) {
|
|
1589
|
+
throw new Error('must set param.marketType');
|
|
1647
1590
|
}
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
ix = this.getPlacePerpOrderIx(placeOrderParam);
|
|
1591
|
+
if ((0, types_1.isVariant)(param.marketType, 'perp')) {
|
|
1592
|
+
readablePerpMarketIndex.push(param.marketIndex);
|
|
1651
1593
|
}
|
|
1652
1594
|
else {
|
|
1653
|
-
|
|
1595
|
+
readableSpotMarketIndexes.push(param.marketIndex);
|
|
1654
1596
|
}
|
|
1655
|
-
tx.add(ix);
|
|
1656
1597
|
}
|
|
1657
|
-
const
|
|
1658
|
-
|
|
1598
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
1599
|
+
userAccounts: [this.getUserAccount()],
|
|
1600
|
+
readablePerpMarketIndex,
|
|
1601
|
+
readableSpotMarketIndexes,
|
|
1602
|
+
useMarketLastSlotCache: true,
|
|
1603
|
+
});
|
|
1604
|
+
return await this.program.instruction.placeOrders(params, {
|
|
1605
|
+
accounts: {
|
|
1606
|
+
state: await this.getStatePublicKey(),
|
|
1607
|
+
user: userAccountPublicKey,
|
|
1608
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
1609
|
+
authority: this.wallet.publicKey,
|
|
1610
|
+
},
|
|
1611
|
+
remainingAccounts,
|
|
1612
|
+
});
|
|
1659
1613
|
}
|
|
1660
1614
|
async fillPerpOrder(userAccountPublicKey, user, order, makerInfo, referrerInfo, txParams) {
|
|
1661
1615
|
const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getFillPerpOrderIx(userAccountPublicKey, user, order, makerInfo, referrerInfo), txParams), [], this.opts);
|
|
@@ -1741,7 +1695,7 @@ class DriftClient {
|
|
|
1741
1695
|
return txSig;
|
|
1742
1696
|
}
|
|
1743
1697
|
async getPlaceSpotOrderIx(orderParams) {
|
|
1744
|
-
orderParams =
|
|
1698
|
+
orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.SPOT });
|
|
1745
1699
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1746
1700
|
const remainingAccounts = this.getRemainingAccounts({
|
|
1747
1701
|
userAccounts: [this.getUserAccount()],
|
|
@@ -1991,6 +1945,25 @@ class DriftClient {
|
|
|
1991
1945
|
* @param txParams
|
|
1992
1946
|
*/
|
|
1993
1947
|
async swap({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, route, reduceOnly, txParams, }) {
|
|
1948
|
+
const { ixs, lookupTables } = await this.getJupiterSwapIx({
|
|
1949
|
+
jupiterClient,
|
|
1950
|
+
outMarketIndex,
|
|
1951
|
+
inMarketIndex,
|
|
1952
|
+
outAssociatedTokenAccount,
|
|
1953
|
+
inAssociatedTokenAccount,
|
|
1954
|
+
amount,
|
|
1955
|
+
slippageBps,
|
|
1956
|
+
swapMode,
|
|
1957
|
+
route,
|
|
1958
|
+
reduceOnly,
|
|
1959
|
+
});
|
|
1960
|
+
const tx = (await this.buildTransaction(ixs, txParams, 0, lookupTables));
|
|
1961
|
+
const { txSig, slot } = await this.sendTransaction(tx);
|
|
1962
|
+
this.spotMarketLastSlotCache.set(outMarketIndex, slot);
|
|
1963
|
+
this.spotMarketLastSlotCache.set(inMarketIndex, slot);
|
|
1964
|
+
return txSig;
|
|
1965
|
+
}
|
|
1966
|
+
async getJupiterSwapIx({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, route, reduceOnly, userAccountPublicKey, }) {
|
|
1994
1967
|
const outMarket = this.getSpotMarketAccount(outMarketIndex);
|
|
1995
1968
|
const inMarket = this.getSpotMarketAccount(inMarketIndex);
|
|
1996
1969
|
if (!route) {
|
|
@@ -2041,18 +2014,15 @@ class DriftClient {
|
|
|
2041
2014
|
inTokenAccount: inAssociatedTokenAccount,
|
|
2042
2015
|
outTokenAccount: outAssociatedTokenAccount,
|
|
2043
2016
|
reduceOnly,
|
|
2017
|
+
userAccountPublicKey,
|
|
2044
2018
|
});
|
|
2045
|
-
const
|
|
2019
|
+
const ixs = [
|
|
2046
2020
|
...preInstructions,
|
|
2047
2021
|
beginSwapIx,
|
|
2048
2022
|
...jupiterInstructions,
|
|
2049
2023
|
endSwapIx,
|
|
2050
2024
|
];
|
|
2051
|
-
|
|
2052
|
-
const { txSig, slot } = await this.sendTransaction(tx);
|
|
2053
|
-
this.spotMarketLastSlotCache.set(outMarketIndex, slot);
|
|
2054
|
-
this.spotMarketLastSlotCache.set(inMarketIndex, slot);
|
|
2055
|
-
return txSig;
|
|
2025
|
+
return { ixs, lookupTables };
|
|
2056
2026
|
}
|
|
2057
2027
|
/**
|
|
2058
2028
|
* Get the drift begin_swap and end_swap instructions
|
|
@@ -2063,11 +2033,14 @@ class DriftClient {
|
|
|
2063
2033
|
* @param inTokenAccount the token account to move the tokens being sold
|
|
2064
2034
|
* @param outTokenAccount the token account to receive the tokens being bought
|
|
2065
2035
|
* @param limitPrice the limit price of the swap
|
|
2036
|
+
* @param reduceOnly
|
|
2037
|
+
* @param userAccountPublicKey optional, specify a custom userAccountPublicKey to use instead of getting the current user account; can be helpful if the account is being created within the current tx
|
|
2066
2038
|
*/
|
|
2067
|
-
async getSwapIx({ outMarketIndex, inMarketIndex, amountIn, inTokenAccount, outTokenAccount, limitPrice, reduceOnly, }) {
|
|
2068
|
-
const
|
|
2039
|
+
async getSwapIx({ outMarketIndex, inMarketIndex, amountIn, inTokenAccount, outTokenAccount, limitPrice, reduceOnly, userAccountPublicKey, }) {
|
|
2040
|
+
const userAccountPublicKeyToUse = userAccountPublicKey || (await this.getUserAccountPublicKey());
|
|
2041
|
+
const userAccounts = this.hasUser() ? [this.getUserAccount()] : [];
|
|
2069
2042
|
const remainingAccounts = this.getRemainingAccounts({
|
|
2070
|
-
userAccounts
|
|
2043
|
+
userAccounts,
|
|
2071
2044
|
writableSpotMarketIndexes: [outMarketIndex, inMarketIndex],
|
|
2072
2045
|
});
|
|
2073
2046
|
const outSpotMarket = this.getSpotMarketAccount(outMarketIndex);
|
|
@@ -2075,7 +2048,7 @@ class DriftClient {
|
|
|
2075
2048
|
const beginSwapIx = await this.program.instruction.beginSwap(inMarketIndex, outMarketIndex, amountIn, {
|
|
2076
2049
|
accounts: {
|
|
2077
2050
|
state: await this.getStatePublicKey(),
|
|
2078
|
-
user:
|
|
2051
|
+
user: userAccountPublicKeyToUse,
|
|
2079
2052
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
2080
2053
|
authority: this.authority,
|
|
2081
2054
|
outSpotMarketVault: outSpotMarket.vault,
|
|
@@ -2091,7 +2064,7 @@ class DriftClient {
|
|
|
2091
2064
|
const endSwapIx = await this.program.instruction.endSwap(inMarketIndex, outMarketIndex, limitPrice !== null && limitPrice !== void 0 ? limitPrice : null, reduceOnly !== null && reduceOnly !== void 0 ? reduceOnly : null, {
|
|
2092
2065
|
accounts: {
|
|
2093
2066
|
state: await this.getStatePublicKey(),
|
|
2094
|
-
user:
|
|
2067
|
+
user: userAccountPublicKeyToUse,
|
|
2095
2068
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
2096
2069
|
authority: this.authority,
|
|
2097
2070
|
outSpotMarketVault: outSpotMarket.vault,
|
|
@@ -2106,6 +2079,40 @@ class DriftClient {
|
|
|
2106
2079
|
});
|
|
2107
2080
|
return { beginSwapIx, endSwapIx };
|
|
2108
2081
|
}
|
|
2082
|
+
async stakeForMSOL({ amount }) {
|
|
2083
|
+
const ixs = await this.getStakeForMSOLIx({ amount });
|
|
2084
|
+
const tx = await this.buildTransaction(ixs);
|
|
2085
|
+
return this.sendTransaction(tx);
|
|
2086
|
+
}
|
|
2087
|
+
async getStakeForMSOLIx({ amount, userAccountPublicKey, }) {
|
|
2088
|
+
const wSOLMint = this.getSpotMarketAccount(1).mint;
|
|
2089
|
+
const mSOLAccount = await this.getAssociatedTokenAccount(2);
|
|
2090
|
+
const wSOLAccount = await this.getAssociatedTokenAccount(1, false);
|
|
2091
|
+
const wSOLAccountExists = await this.checkIfAccountExists(wSOLAccount);
|
|
2092
|
+
const closeWSOLIx = (0, spl_token_1.createCloseAccountInstruction)(wSOLAccount, this.wallet.publicKey, this.wallet.publicKey);
|
|
2093
|
+
const createWSOLIx = await this.createAssociatedTokenAccountIdempotentInstruction(wSOLAccount, this.wallet.publicKey, this.wallet.publicKey, wSOLMint);
|
|
2094
|
+
const { beginSwapIx, endSwapIx } = await this.getSwapIx({
|
|
2095
|
+
inMarketIndex: 1,
|
|
2096
|
+
outMarketIndex: 2,
|
|
2097
|
+
amountIn: amount,
|
|
2098
|
+
inTokenAccount: wSOLAccount,
|
|
2099
|
+
outTokenAccount: mSOLAccount,
|
|
2100
|
+
userAccountPublicKey,
|
|
2101
|
+
});
|
|
2102
|
+
const program = (0, marinade_1.getMarinadeFinanceProgram)(this.provider);
|
|
2103
|
+
const depositIx = await (0, marinade_1.getMarinadeDepositIx)({
|
|
2104
|
+
program,
|
|
2105
|
+
mSOLAccount: mSOLAccount,
|
|
2106
|
+
transferFrom: this.wallet.publicKey,
|
|
2107
|
+
amount,
|
|
2108
|
+
});
|
|
2109
|
+
const ixs = [];
|
|
2110
|
+
if (!wSOLAccountExists) {
|
|
2111
|
+
ixs.push(createWSOLIx);
|
|
2112
|
+
}
|
|
2113
|
+
ixs.push(beginSwapIx, closeWSOLIx, depositIx, createWSOLIx, endSwapIx);
|
|
2114
|
+
return ixs;
|
|
2115
|
+
}
|
|
2109
2116
|
async triggerOrder(userAccountPublicKey, user, order, txParams) {
|
|
2110
2117
|
const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getTriggerOrderIx(userAccountPublicKey, user, order), txParams), [], this.opts);
|
|
2111
2118
|
return txSig;
|
|
@@ -2201,7 +2208,7 @@ class DriftClient {
|
|
|
2201
2208
|
return txSig;
|
|
2202
2209
|
}
|
|
2203
2210
|
async getPlaceAndTakePerpOrderIx(orderParams, makerInfo, referrerInfo) {
|
|
2204
|
-
orderParams =
|
|
2211
|
+
orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.PERP });
|
|
2205
2212
|
const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
2206
2213
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
2207
2214
|
makerInfo = Array.isArray(makerInfo)
|
|
@@ -2262,7 +2269,7 @@ class DriftClient {
|
|
|
2262
2269
|
return txSig;
|
|
2263
2270
|
}
|
|
2264
2271
|
async getPlaceAndMakePerpOrderIx(orderParams, takerInfo, referrerInfo) {
|
|
2265
|
-
orderParams =
|
|
2272
|
+
orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.PERP });
|
|
2266
2273
|
const userStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
2267
2274
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
2268
2275
|
const remainingAccounts = this.getRemainingAccounts({
|
|
@@ -2302,7 +2309,7 @@ class DriftClient {
|
|
|
2302
2309
|
return txSig;
|
|
2303
2310
|
}
|
|
2304
2311
|
async getPlaceAndTakeSpotOrderIx(orderParams, fulfillmentConfig, makerInfo, referrerInfo) {
|
|
2305
|
-
orderParams =
|
|
2312
|
+
orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.SPOT });
|
|
2306
2313
|
const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
2307
2314
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
2308
2315
|
const userAccounts = [this.getUserAccount()];
|
|
@@ -2361,7 +2368,7 @@ class DriftClient {
|
|
|
2361
2368
|
return txSig;
|
|
2362
2369
|
}
|
|
2363
2370
|
async getPlaceAndMakeSpotOrderIx(orderParams, takerInfo, fulfillmentConfig, referrerInfo) {
|
|
2364
|
-
orderParams =
|
|
2371
|
+
orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.SPOT });
|
|
2365
2372
|
const userStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
2366
2373
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
2367
2374
|
const remainingAccounts = this.getRemainingAccounts({
|
package/lib/idl/drift.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.32.0",
|
|
3
3
|
"name": "drift",
|
|
4
4
|
"instructions": [
|
|
5
5
|
{
|
|
@@ -710,6 +710,36 @@
|
|
|
710
710
|
}
|
|
711
711
|
]
|
|
712
712
|
},
|
|
713
|
+
{
|
|
714
|
+
"name": "placeOrders",
|
|
715
|
+
"accounts": [
|
|
716
|
+
{
|
|
717
|
+
"name": "state",
|
|
718
|
+
"isMut": false,
|
|
719
|
+
"isSigner": false
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
"name": "user",
|
|
723
|
+
"isMut": true,
|
|
724
|
+
"isSigner": false
|
|
725
|
+
},
|
|
726
|
+
{
|
|
727
|
+
"name": "authority",
|
|
728
|
+
"isMut": false,
|
|
729
|
+
"isSigner": true
|
|
730
|
+
}
|
|
731
|
+
],
|
|
732
|
+
"args": [
|
|
733
|
+
{
|
|
734
|
+
"name": "params",
|
|
735
|
+
"type": {
|
|
736
|
+
"vec": {
|
|
737
|
+
"defined": "OrderParams"
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
]
|
|
742
|
+
},
|
|
713
743
|
{
|
|
714
744
|
"name": "beginSwap",
|
|
715
745
|
"accounts": [
|
package/lib/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export * from './accounts/pollingOracleAccountSubscriber';
|
|
|
16
16
|
export * from './accounts/pollingTokenAccountSubscriber';
|
|
17
17
|
export * from './accounts/pollingUserAccountSubscriber';
|
|
18
18
|
export * from './accounts/pollingUserStatsAccountSubscriber';
|
|
19
|
+
export * from './accounts/mockUserAccountSubscriber';
|
|
19
20
|
export * from './accounts/types';
|
|
20
21
|
export * from './addresses/pda';
|
|
21
22
|
export * from './adminClient';
|
|
@@ -45,6 +46,8 @@ export * from './math/orders';
|
|
|
45
46
|
export * from './math/repeg';
|
|
46
47
|
export * from './math/margin';
|
|
47
48
|
export * from './math/insurance';
|
|
49
|
+
export * from './math/superStake';
|
|
50
|
+
export * from './marinade';
|
|
48
51
|
export * from './orderParams';
|
|
49
52
|
export * from './slot/SlotSubscriber';
|
|
50
53
|
export * from './wallet';
|