@drift-labs/sdk 2.30.0-beta.1 → 2.31.0-beta.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.
Files changed (46) hide show
  1. package/lib/accounts/pollingTokenAccountSubscriber.d.ts +3 -3
  2. package/lib/accounts/pollingTokenAccountSubscriber.js +5 -2
  3. package/lib/accounts/types.d.ts +3 -3
  4. package/lib/adminClient.d.ts +1 -0
  5. package/lib/adminClient.js +9 -0
  6. package/lib/constants/spotMarkets.js +10 -0
  7. package/lib/dlob/DLOB.d.ts +20 -1
  8. package/lib/dlob/DLOB.js +39 -0
  9. package/lib/driftClient.d.ts +13 -8
  10. package/lib/driftClient.js +32 -27
  11. package/lib/examples/makeTradeExample.js +1 -1
  12. package/lib/idl/drift.json +106 -15
  13. package/lib/jupiter/jupiterClient.d.ts +1 -1
  14. package/lib/jupiter/jupiterClient.js +7 -2
  15. package/lib/math/spotBalance.d.ts +41 -0
  16. package/lib/math/spotBalance.js +41 -0
  17. package/lib/token/index.d.ts +3 -2
  18. package/lib/token/index.js +9 -32
  19. package/lib/tokenFaucet.d.ts +3 -3
  20. package/lib/tokenFaucet.js +4 -9
  21. package/lib/tx/retryTxSender.js +3 -0
  22. package/lib/types.d.ts +22 -2
  23. package/lib/types.js +12 -1
  24. package/lib/wallet.d.ts +5 -3
  25. package/lib/wallet.js +19 -7
  26. package/package.json +2 -2
  27. package/src/accounts/pollingTokenAccountSubscriber.ts +8 -5
  28. package/src/accounts/types.ts +3 -3
  29. package/src/adminClient.ts +19 -0
  30. package/src/constants/spotMarkets.ts +11 -0
  31. package/src/dlob/DLOB.ts +75 -0
  32. package/src/driftClient.ts +57 -53
  33. package/src/examples/makeTradeExample.ts +2 -4
  34. package/src/idl/drift.json +106 -15
  35. package/src/jupiter/jupiterClient.ts +10 -2
  36. package/src/math/spotBalance.ts +41 -0
  37. package/src/token/index.ts +12 -36
  38. package/src/tokenFaucet.ts +15 -34
  39. package/src/tx/retryTxSender.ts +4 -0
  40. package/src/types.ts +23 -2
  41. package/src/wallet.ts +34 -12
  42. package/tests/dlob/helpers.ts +1 -0
  43. package/tests/dlob/test.ts +218 -40
  44. package/lib/util/getTokenAddress.d.ts +0 -2
  45. package/lib/util/getTokenAddress.js +0 -9
  46. package/src/util/getTokenAddress.ts +0 -18
@@ -20,6 +20,8 @@ import {
20
20
  isMarketOrder,
21
21
  isLimitOrder,
22
22
  ZERO,
23
+ convertToNumber,
24
+ QUOTE_PRECISION,
23
25
  } from '../../src';
24
26
 
25
27
  import { mockPerpMarkets, mockSpotMarkets, mockStateAccount } from './helpers';
@@ -134,16 +136,11 @@ function printOrderNode(
134
136
  slot: number | undefined
135
137
  ) {
136
138
  console.log(
137
- ` . vAMMNode? ${node.isVammNode()},\t${
138
- node.order ? getVariant(node.order?.orderType) : '~'
139
- } ${node.order ? getVariant(node.order?.direction) : '~'}\t, slot: ${
140
- node.order?.slot.toString() || '~'
141
- }, orderId: ${node.order?.orderId.toString() || '~'},\tnode.getPrice: ${
142
- oracle ? node.getPrice(oracle, slot!) : '~'
143
- }, node.price: ${node.order?.price.toString() || '~'}, priceOffset: ${
144
- node.order?.oraclePriceOffset.toString() || '~'
145
- } quantity: ${node.order?.baseAssetAmountFilled.toString() || '~'}/${
146
- node.order?.baseAssetAmount.toString() || '~'
139
+ ` . vAMMNode? ${node.isVammNode()},\t${node.order ? getVariant(node.order?.orderType) : '~'
140
+ } ${node.order ? getVariant(node.order?.direction) : '~'}\t, slot: ${node.order?.slot.toString() || '~'
141
+ }, orderId: ${node.order?.orderId.toString() || '~'},\tnode.getPrice: ${oracle ? node.getPrice(oracle, slot!) : '~'
142
+ }, node.price: ${node.order?.price.toString() || '~'}, priceOffset: ${node.order?.oraclePriceOffset.toString() || '~'
143
+ } quantity: ${node.order?.baseAssetAmountFilled.toString() || '~'}/${node.order?.baseAssetAmount.toString() || '~'
147
144
  }`
148
145
  );
149
146
  }
@@ -190,8 +187,7 @@ function printBookState(
190
187
 
191
188
  function printCrossedNodes(n: NodeToFill, slot: number) {
192
189
  console.log(
193
- `Cross Found, takerExists: ${n.node.order !== undefined}, makerExists: ${
194
- n.makerNodes !== undefined
190
+ `Cross Found, takerExists: ${n.node.order !== undefined}, makerExists: ${n.makerNodes !== undefined
195
191
  }`
196
192
  );
197
193
  console.log(
@@ -213,10 +209,8 @@ function printCrossedNodes(n: NodeToFill, slot: number) {
213
209
  console.log(
214
210
  ` orderId: ${o.orderId}, ${getVariant(o.orderType)}, ${getVariant(
215
211
  o.direction
216
- )},\texpired: ${isOrderExpired(o, slot)}, postOnly: ${
217
- o.postOnly
218
- }, reduceOnly: ${
219
- o.reduceOnly
212
+ )},\texpired: ${isOrderExpired(o, slot)}, postOnly: ${o.postOnly
213
+ }, reduceOnly: ${o.reduceOnly
220
214
  }, price: ${o.price.toString()}, priceOffset: ${o.oraclePriceOffset.toString()}, baseAmtFileld: ${o.baseAssetAmountFilled.toString()}/${o.baseAssetAmount.toString()}`
221
215
  );
222
216
  };
@@ -621,9 +615,9 @@ describe('DLOB Tests', () => {
621
615
  );
622
616
 
623
617
  expect(takingBids.length).to.equal(3);
624
- expect(takingBids[0].order.orderId).to.equal(1);
625
- expect(takingBids[1].order.orderId).to.equal(2);
626
- expect(takingBids[2].order.orderId).to.equal(3);
618
+ expect(takingBids[0].order!.orderId).to.equal(1);
619
+ expect(takingBids[1].order!.orderId).to.equal(2);
620
+ expect(takingBids[2].order!.orderId).to.equal(3);
627
621
 
628
622
  let restingBids = Array.from(
629
623
  dlob.getRestingLimitBids(marketIndex, slot, marketType, oracle)
@@ -638,15 +632,15 @@ describe('DLOB Tests', () => {
638
632
  );
639
633
 
640
634
  expect(takingBids.length).to.equal(2);
641
- expect(takingBids[0].order.orderId).to.equal(2);
642
- expect(takingBids[1].order.orderId).to.equal(3);
635
+ expect(takingBids[0].order!.orderId).to.equal(2);
636
+ expect(takingBids[1].order!.orderId).to.equal(3);
643
637
 
644
638
  restingBids = Array.from(
645
639
  dlob.getRestingLimitBids(marketIndex, slot, marketType, oracle)
646
640
  );
647
641
 
648
642
  expect(restingBids.length).to.equal(1);
649
- expect(restingBids[0].order.orderId).to.equal(1);
643
+ expect(restingBids[0].order!.orderId).to.equal(1);
650
644
 
651
645
  slot += 11;
652
646
 
@@ -655,15 +649,15 @@ describe('DLOB Tests', () => {
655
649
  );
656
650
 
657
651
  expect(takingBids.length).to.equal(1);
658
- expect(takingBids[0].order.orderId).to.equal(3);
652
+ expect(takingBids[0].order!.orderId).to.equal(3);
659
653
 
660
654
  restingBids = Array.from(
661
655
  dlob.getRestingLimitBids(marketIndex, slot, marketType, oracle)
662
656
  );
663
657
 
664
658
  expect(restingBids.length).to.equal(2);
665
- expect(restingBids[0].order.orderId).to.equal(2);
666
- expect(restingBids[1].order.orderId).to.equal(1);
659
+ expect(restingBids[0].order!.orderId).to.equal(2);
660
+ expect(restingBids[1].order!.orderId).to.equal(1);
667
661
 
668
662
  slot += 11;
669
663
 
@@ -678,9 +672,9 @@ describe('DLOB Tests', () => {
678
672
  );
679
673
 
680
674
  expect(restingBids.length).to.equal(3);
681
- expect(restingBids[0].order.orderId).to.equal(3);
682
- expect(restingBids[1].order.orderId).to.equal(2);
683
- expect(restingBids[2].order.orderId).to.equal(1);
675
+ expect(restingBids[0].order!.orderId).to.equal(3);
676
+ expect(restingBids[1].order!.orderId).to.equal(2);
677
+ expect(restingBids[2].order!.orderId).to.equal(1);
684
678
  });
685
679
 
686
680
  it('DLOB update resting limit orders asks', () => {
@@ -751,9 +745,9 @@ describe('DLOB Tests', () => {
751
745
  );
752
746
 
753
747
  expect(takingBids.length).to.equal(3);
754
- expect(takingBids[0].order.orderId).to.equal(1);
755
- expect(takingBids[1].order.orderId).to.equal(2);
756
- expect(takingBids[2].order.orderId).to.equal(3);
748
+ expect(takingBids[0].order!.orderId).to.equal(1);
749
+ expect(takingBids[1].order!.orderId).to.equal(2);
750
+ expect(takingBids[2].order!.orderId).to.equal(3);
757
751
 
758
752
  let restingBids = Array.from(
759
753
  dlob.getRestingLimitAsks(marketIndex, slot, marketType, oracle)
@@ -768,15 +762,15 @@ describe('DLOB Tests', () => {
768
762
  );
769
763
 
770
764
  expect(takingBids.length).to.equal(2);
771
- expect(takingBids[0].order.orderId).to.equal(2);
772
- expect(takingBids[1].order.orderId).to.equal(3);
765
+ expect(takingBids[0].order!.orderId).to.equal(2);
766
+ expect(takingBids[1].order!.orderId).to.equal(3);
773
767
 
774
768
  restingBids = Array.from(
775
769
  dlob.getRestingLimitAsks(marketIndex, slot, marketType, oracle)
776
770
  );
777
771
 
778
772
  expect(restingBids.length).to.equal(1);
779
- expect(restingBids[0].order.orderId).to.equal(1);
773
+ expect(restingBids[0].order!.orderId).to.equal(1);
780
774
 
781
775
  slot += 11;
782
776
 
@@ -785,15 +779,15 @@ describe('DLOB Tests', () => {
785
779
  );
786
780
 
787
781
  expect(takingBids.length).to.equal(1);
788
- expect(takingBids[0].order.orderId).to.equal(3);
782
+ expect(takingBids[0].order!.orderId).to.equal(3);
789
783
 
790
784
  restingBids = Array.from(
791
785
  dlob.getRestingLimitAsks(marketIndex, slot, marketType, oracle)
792
786
  );
793
787
 
794
788
  expect(restingBids.length).to.equal(2);
795
- expect(restingBids[0].order.orderId).to.equal(2);
796
- expect(restingBids[1].order.orderId).to.equal(1);
789
+ expect(restingBids[0].order!.orderId).to.equal(2);
790
+ expect(restingBids[1].order!.orderId).to.equal(1);
797
791
 
798
792
  slot += 11;
799
793
 
@@ -808,9 +802,9 @@ describe('DLOB Tests', () => {
808
802
  );
809
803
 
810
804
  expect(restingBids.length).to.equal(3);
811
- expect(restingBids[0].order.orderId).to.equal(3);
812
- expect(restingBids[1].order.orderId).to.equal(2);
813
- expect(restingBids[2].order.orderId).to.equal(1);
805
+ expect(restingBids[0].order!.orderId).to.equal(3);
806
+ expect(restingBids[1].order!.orderId).to.equal(2);
807
+ expect(restingBids[2].order!.orderId).to.equal(1);
814
808
  });
815
809
  });
816
810
 
@@ -5711,4 +5705,188 @@ describe('DLOB Spot Tests', () => {
5711
5705
  expect(nodesToFillAfter[0].makerNodes.length).to.equal(0);
5712
5706
  expect(nodesToFillAfter[1].makerNodes.length).to.equal(0);
5713
5707
  });
5708
+
5709
+ it('DLOB estimateFillExactBaseAmount spot buy', () => {
5710
+ const vAsk = new BN(20790000);
5711
+ const vBid = new BN(20580000);
5712
+
5713
+ let slot = 1;
5714
+ const oracle = {
5715
+ price: vBid.add(vAsk).div(new BN(2)),
5716
+ slot: new BN(slot),
5717
+ confidence: new BN(1),
5718
+ hasSufficientNumberOfDataPoints: true,
5719
+ };
5720
+
5721
+ const user0 = Keypair.generate();
5722
+ const user1 = Keypair.generate();
5723
+ const user2 = Keypair.generate();
5724
+
5725
+ const dlob = new DLOB();
5726
+ const marketIndex = 0;
5727
+ const marketType = MarketType.SPOT;
5728
+
5729
+ const b1 = BASE_PRECISION;
5730
+ insertOrderToDLOB(
5731
+ dlob,
5732
+ user0.publicKey,
5733
+ OrderType.LIMIT,
5734
+ marketType,
5735
+ 1, // orderId
5736
+ marketIndex,
5737
+ new BN(20690000), // price
5738
+ b1, // quantity
5739
+ PositionDirection.SHORT,
5740
+ vAsk,
5741
+ vBid,
5742
+ new BN(1)
5743
+ );
5744
+ const b2 = new BN(2).mul(BASE_PRECISION);
5745
+ insertOrderToDLOB(
5746
+ dlob,
5747
+ user1.publicKey,
5748
+ OrderType.LIMIT,
5749
+ marketType,
5750
+ 2, // orderId
5751
+ marketIndex,
5752
+ new BN(20700000), // price
5753
+ b2, // quantity
5754
+ PositionDirection.SHORT,
5755
+ vAsk,
5756
+ vBid,
5757
+ new BN(1)
5758
+ );
5759
+ const b3 = new BN(3).mul(BASE_PRECISION);
5760
+ insertOrderToDLOB(
5761
+ dlob,
5762
+ user2.publicKey,
5763
+ OrderType.LIMIT,
5764
+ marketType,
5765
+ 3, // orderId
5766
+ marketIndex,
5767
+ new BN(20710000), // price
5768
+ b3, // quantity
5769
+ PositionDirection.SHORT,
5770
+ vAsk,
5771
+ vBid,
5772
+ new BN(1)
5773
+ );
5774
+
5775
+ slot += 11;
5776
+
5777
+ const restingAsks = Array.from(
5778
+ dlob.getRestingLimitAsks(marketIndex, slot, marketType, oracle)
5779
+ );
5780
+
5781
+ expect(restingAsks.length).to.equal(3);
5782
+
5783
+ const baseAmount = new BN(4).mul(BASE_PRECISION);
5784
+ const out = dlob.estimateFillWithExactBaseAmount({
5785
+ marketIndex,
5786
+ marketType,
5787
+ baseAmount,
5788
+ orderDirection: PositionDirection.LONG,
5789
+ slot,
5790
+ oraclePriceData: oracle,
5791
+ });
5792
+ const quoteAmtOut = convertToNumber(
5793
+ out,
5794
+ QUOTE_PRECISION
5795
+ );
5796
+
5797
+ // 1 * 20.69 + 2 * 20.70 + 1 * 20.71 = 82.8
5798
+ expect(quoteAmtOut === 82.8).to.be.true;
5799
+ });
5800
+
5801
+ it('DLOB estimateFillExactBaseAmount spot sell', () => {
5802
+ const vAsk = new BN(20790000);
5803
+ const vBid = new BN(20580000);
5804
+
5805
+ let slot = 1;
5806
+ const oracle = {
5807
+ price: vBid.add(vAsk).div(new BN(2)),
5808
+ slot: new BN(slot),
5809
+ confidence: new BN(1),
5810
+ hasSufficientNumberOfDataPoints: true,
5811
+ };
5812
+
5813
+ const user0 = Keypair.generate();
5814
+ const user1 = Keypair.generate();
5815
+ const user2 = Keypair.generate();
5816
+
5817
+ const dlob = new DLOB();
5818
+ const marketIndex = 0;
5819
+ const marketType = MarketType.SPOT;
5820
+
5821
+ const b1 = BASE_PRECISION;
5822
+ insertOrderToDLOB(
5823
+ dlob,
5824
+ user0.publicKey,
5825
+ OrderType.LIMIT,
5826
+ marketType,
5827
+ 1, // orderId
5828
+ marketIndex,
5829
+ new BN(20690000), // price
5830
+ b1, // quantity
5831
+ PositionDirection.LONG,
5832
+ vBid,
5833
+ vAsk,
5834
+ new BN(1)
5835
+ );
5836
+ const b2 = new BN(2).mul(BASE_PRECISION);
5837
+ insertOrderToDLOB(
5838
+ dlob,
5839
+ user1.publicKey,
5840
+ OrderType.LIMIT,
5841
+ marketType,
5842
+ 2, // orderId
5843
+ marketIndex,
5844
+ new BN(20680000), // price
5845
+ b2, // quantity
5846
+ PositionDirection.LONG,
5847
+ vBid,
5848
+ vAsk,
5849
+ new BN(1)
5850
+ );
5851
+ const b3 = new BN(3).mul(BASE_PRECISION);
5852
+ insertOrderToDLOB(
5853
+ dlob,
5854
+ user2.publicKey,
5855
+ OrderType.LIMIT,
5856
+ marketType,
5857
+ 3, // orderId
5858
+ marketIndex,
5859
+ new BN(20670000), // price
5860
+ b3, // quantity
5861
+ PositionDirection.LONG,
5862
+ vBid,
5863
+ vAsk,
5864
+ new BN(1)
5865
+ );
5866
+
5867
+ slot += 11;
5868
+
5869
+ const restingBids = Array.from(
5870
+ dlob.getRestingLimitBids(marketIndex, slot, marketType, oracle)
5871
+ );
5872
+
5873
+ expect(restingBids.length).to.equal(3);
5874
+
5875
+ const baseAmount = new BN(4).mul(BASE_PRECISION);
5876
+ const out = dlob.estimateFillWithExactBaseAmount({
5877
+ marketIndex,
5878
+ marketType,
5879
+ baseAmount,
5880
+ orderDirection: PositionDirection.SHORT,
5881
+ slot,
5882
+ oraclePriceData: oracle,
5883
+ });
5884
+ const quoteAmtOut = convertToNumber(
5885
+ out,
5886
+ QUOTE_PRECISION
5887
+ );
5888
+
5889
+ // 1 * 20.69 + 2 * 20.68 + 1 * 20.67 = 82.72
5890
+ expect(quoteAmtOut === 82.72).to.be.true;
5891
+ });
5714
5892
  });
@@ -1,2 +0,0 @@
1
- import { PublicKey } from '@solana/web3.js';
2
- export declare const getTokenAddress: (mintAddress: string, userPubKey: string) => Promise<PublicKey>;
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getTokenAddress = void 0;
4
- const spl_token_1 = require("@solana/spl-token");
5
- const web3_js_1 = require("@solana/web3.js");
6
- const getTokenAddress = (mintAddress, userPubKey) => {
7
- return spl_token_1.Token.getAssociatedTokenAddress(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, new web3_js_1.PublicKey(mintAddress), new web3_js_1.PublicKey(userPubKey));
8
- };
9
- exports.getTokenAddress = getTokenAddress;
@@ -1,18 +0,0 @@
1
- import {
2
- Token,
3
- ASSOCIATED_TOKEN_PROGRAM_ID,
4
- TOKEN_PROGRAM_ID,
5
- } from '@solana/spl-token';
6
- import { PublicKey } from '@solana/web3.js';
7
-
8
- export const getTokenAddress = (
9
- mintAddress: string,
10
- userPubKey: string
11
- ): Promise<PublicKey> => {
12
- return Token.getAssociatedTokenAddress(
13
- ASSOCIATED_TOKEN_PROGRAM_ID,
14
- TOKEN_PROGRAM_ID,
15
- new PublicKey(mintAddress),
16
- new PublicKey(userPubKey)
17
- );
18
- };