@drift-labs/sdk 2.12.0-beta.2 → 2.12.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 (57) hide show
  1. package/lib/accounts/bulkAccountLoader.js +3 -3
  2. package/lib/accounts/fetch.js +2 -2
  3. package/lib/accounts/pollingDriftClientAccountSubscriber.js +7 -7
  4. package/lib/accounts/pollingTokenAccountSubscriber.js +2 -2
  5. package/lib/accounts/pollingUserAccountSubscriber.js +2 -2
  6. package/lib/accounts/pollingUserStatsAccountSubscriber.js +2 -2
  7. package/lib/accounts/webSocketAccountSubscriber.js +1 -1
  8. package/lib/accounts/webSocketDriftClientAccountSubscriber.js +3 -3
  9. package/lib/addresses/marketAddresses.js +1 -1
  10. package/lib/addresses/pda.js +1 -5
  11. package/lib/adminClient.js +57 -61
  12. package/lib/dlob/DLOB.d.ts +8 -8
  13. package/lib/dlob/DLOB.js +91 -84
  14. package/lib/dlob/DLOBNode.js +7 -7
  15. package/lib/dlob/NodeList.js +2 -2
  16. package/lib/driftClient.d.ts +3 -3
  17. package/lib/driftClient.js +83 -87
  18. package/lib/events/eventSubscriber.js +2 -2
  19. package/lib/events/pollingLogProvider.js +1 -1
  20. package/lib/examples/makeTradeExample.js +9 -9
  21. package/lib/factory/bigNum.js +9 -9
  22. package/lib/factory/oracleClient.js +2 -2
  23. package/lib/idl/drift.json +1 -1
  24. package/lib/index.js +1 -5
  25. package/lib/math/amm.js +23 -23
  26. package/lib/math/auction.js +6 -6
  27. package/lib/math/exchangeStatus.js +2 -2
  28. package/lib/math/funding.js +2 -2
  29. package/lib/math/margin.js +5 -5
  30. package/lib/math/market.js +12 -12
  31. package/lib/math/oracles.js +1 -1
  32. package/lib/math/orders.js +23 -23
  33. package/lib/math/position.js +5 -5
  34. package/lib/math/repeg.js +1 -1
  35. package/lib/math/spotBalance.js +7 -7
  36. package/lib/math/spotPosition.js +3 -3
  37. package/lib/math/trade.d.ts +35 -3
  38. package/lib/math/trade.js +225 -47
  39. package/lib/oracles/oracleClientCache.js +1 -1
  40. package/lib/oracles/pythClient.js +1 -1
  41. package/lib/tokenFaucet.js +1 -5
  42. package/lib/tx/retryTxSender.js +1 -1
  43. package/lib/tx/utils.d.ts +1 -1
  44. package/lib/tx/utils.js +7 -4
  45. package/lib/types.d.ts +4 -0
  46. package/lib/user.js +47 -47
  47. package/lib/userMap/userMap.js +1 -1
  48. package/lib/userMap/userStatsMap.js +3 -3
  49. package/lib/userStats.js +2 -2
  50. package/package.json +1 -1
  51. package/src/dlob/DLOB.ts +34 -26
  52. package/src/driftClient.ts +11 -4
  53. package/src/idl/drift.json +1 -1
  54. package/src/math/trade.ts +322 -16
  55. package/src/tx/utils.ts +11 -3
  56. package/src/types.ts +5 -0
  57. package/tests/dlob/test.ts +307 -38
package/src/math/trade.ts CHANGED
@@ -1,4 +1,9 @@
1
- import { MarketType, PerpMarketAccount, PositionDirection } from '../types';
1
+ import {
2
+ MarketType,
3
+ PerpMarketAccount,
4
+ PositionDirection,
5
+ SpotMarketAccount,
6
+ } from '../types';
2
7
  import { BN } from '@project-serum/anchor';
3
8
  import { assert } from '../assert/assert';
4
9
  import {
@@ -7,6 +12,7 @@ import {
7
12
  AMM_TO_QUOTE_PRECISION_RATIO,
8
13
  ZERO,
9
14
  BASE_PRECISION,
15
+ BN_MAX,
10
16
  } from '../constants/numericConstants';
11
17
  import {
12
18
  calculateBidPrice,
@@ -20,11 +26,14 @@ import {
20
26
  AssetType,
21
27
  calculateUpdatedAMMSpreadReserves,
22
28
  calculateQuoteAssetAmountSwapped,
29
+ calculateMarketOpenBidAsk,
23
30
  } from './amm';
24
31
  import { squareRootBN } from './utils';
25
32
  import { isVariant } from '../types';
26
33
  import { OraclePriceData } from '../oracles/types';
27
34
  import { DLOB } from '../dlob/DLOB';
35
+ import { PublicKey } from '@solana/web3.js';
36
+ import { Orderbook } from '@project-serum/serum';
28
37
 
29
38
  const MAXPCT = new BN(1000); //percentage units are [0,1000] => [0,1]
30
39
 
@@ -363,7 +372,7 @@ export function calculateTargetPriceTrade(
363
372
  * @param oraclePriceData
364
373
  * @param dlob
365
374
  * @param slot
366
- * @param minPerpAuctionDuration
375
+ * @param usersToSkip
367
376
  */
368
377
  export function calculateEstimatedPerpEntryPrice(
369
378
  assetType: AssetType,
@@ -373,21 +382,37 @@ export function calculateEstimatedPerpEntryPrice(
373
382
  oraclePriceData: OraclePriceData,
374
383
  dlob: DLOB,
375
384
  slot: number,
376
- minPerpAuctionDuration: number
377
- ): [BN, BN] {
385
+ usersToSkip = new Map<PublicKey, boolean>()
386
+ ): {
387
+ entryPrice: BN;
388
+ priceImpact: BN;
389
+ bestPrice: BN;
390
+ worstPrice: BN;
391
+ baseFilled: BN;
392
+ quoteFilled: BN;
393
+ } {
378
394
  if (amount.eq(ZERO)) {
379
- return [ZERO, ZERO];
395
+ return {
396
+ entryPrice: ZERO,
397
+ priceImpact: ZERO,
398
+ bestPrice: ZERO,
399
+ worstPrice: ZERO,
400
+ baseFilled: ZERO,
401
+ quoteFilled: ZERO,
402
+ };
380
403
  }
381
404
 
382
405
  const takerIsLong = isVariant(direction, 'long');
383
406
  const limitOrders = dlob[
384
- takerIsLong ? 'getRestingLimitAsks' : 'getRestingLimitBids'
407
+ takerIsLong ? 'getMakerLimitAsks' : 'getMakerLimitBids'
385
408
  ](
386
409
  market.marketIndex,
387
410
  slot,
388
411
  MarketType.PERP,
389
412
  oraclePriceData,
390
- minPerpAuctionDuration
413
+ takerIsLong
414
+ ? calculateBidPrice(market, oraclePriceData)
415
+ : calculateAskPrice(market, oraclePriceData)
391
416
  );
392
417
 
393
418
  const swapDirection = getSwapDirection(assetType, direction);
@@ -401,9 +426,34 @@ export function calculateEstimatedPerpEntryPrice(
401
426
  pegMultiplier: newPeg,
402
427
  };
403
428
 
429
+ const [ammBids, ammAsks] = calculateMarketOpenBidAsk(
430
+ market.amm.baseAssetReserve,
431
+ market.amm.minBaseAssetReserve,
432
+ market.amm.maxBaseAssetReserve,
433
+ market.amm.orderStepSize
434
+ );
435
+
436
+ let ammLiquidity: BN;
437
+ if (assetType === 'base') {
438
+ ammLiquidity = takerIsLong ? ammAsks.abs() : ammBids;
439
+ } else {
440
+ const [afterSwapQuoteReserves, _] = calculateAmmReservesAfterSwap(
441
+ amm,
442
+ 'base',
443
+ takerIsLong ? ammAsks.abs() : ammBids,
444
+ getSwapDirection('base', direction)
445
+ );
446
+
447
+ ammLiquidity = calculateQuoteAssetAmountSwapped(
448
+ amm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(),
449
+ amm.pegMultiplier,
450
+ swapDirection
451
+ );
452
+ }
453
+
404
454
  const invariant = amm.sqrtK.mul(amm.sqrtK);
405
455
 
406
- let initialPrice = calculatePrice(
456
+ let bestPrice = calculatePrice(
407
457
  amm.baseAssetReserve,
408
458
  amm.quoteAssetReserve,
409
459
  amm.pegMultiplier
@@ -415,13 +465,18 @@ export function calculateEstimatedPerpEntryPrice(
415
465
  let limitOrder = limitOrders.next().value;
416
466
  if (limitOrder) {
417
467
  const limitOrderPrice = limitOrder.getPrice(oraclePriceData, slot);
418
- initialPrice = takerIsLong
419
- ? BN.min(limitOrderPrice, initialPrice)
420
- : BN.max(limitOrderPrice, initialPrice);
468
+ bestPrice = takerIsLong
469
+ ? BN.min(limitOrderPrice, bestPrice)
470
+ : BN.max(limitOrderPrice, bestPrice);
421
471
  }
422
472
 
473
+ let worstPrice = bestPrice;
474
+
423
475
  if (assetType === 'base') {
424
- while (!cumulativeBaseFilled.eq(amount)) {
476
+ while (
477
+ !cumulativeBaseFilled.eq(amount) &&
478
+ (ammLiquidity.gt(ZERO) || limitOrder)
479
+ ) {
425
480
  const limitOrderPrice = limitOrder?.getPrice(oraclePriceData, slot);
426
481
 
427
482
  let maxAmmFill: BN;
@@ -442,11 +497,15 @@ export function calculateEstimatedPerpEntryPrice(
442
497
  maxAmmFill = amount.sub(cumulativeBaseFilled);
443
498
  }
444
499
 
500
+ maxAmmFill = BN.min(maxAmmFill, ammLiquidity);
501
+
445
502
  if (maxAmmFill.gt(ZERO)) {
446
503
  const baseFilled = BN.min(amount.sub(cumulativeBaseFilled), maxAmmFill);
447
504
  const [afterSwapQuoteReserves, afterSwapBaseReserves] =
448
505
  calculateAmmReservesAfterSwap(amm, 'base', baseFilled, swapDirection);
449
506
 
507
+ ammLiquidity = ammLiquidity.sub(baseFilled);
508
+
450
509
  const quoteFilled = calculateQuoteAssetAmountSwapped(
451
510
  amm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(),
452
511
  amm.pegMultiplier,
@@ -459,11 +518,21 @@ export function calculateEstimatedPerpEntryPrice(
459
518
  amm.baseAssetReserve = afterSwapBaseReserves;
460
519
  amm.quoteAssetReserve = afterSwapQuoteReserves;
461
520
 
521
+ worstPrice = calculatePrice(
522
+ amm.baseAssetReserve,
523
+ amm.quoteAssetReserve,
524
+ amm.pegMultiplier
525
+ );
526
+
462
527
  if (cumulativeBaseFilled.eq(amount)) {
463
528
  break;
464
529
  }
465
530
  }
466
531
 
532
+ if (limitOrder && usersToSkip.has(limitOrder.userAccount)) {
533
+ continue;
534
+ }
535
+
467
536
  const baseFilled = BN.min(
468
537
  limitOrder.order.baseAssetAmount.sub(
469
538
  limitOrder.order.baseAssetAmountFilled
@@ -475,6 +544,8 @@ export function calculateEstimatedPerpEntryPrice(
475
544
  cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
476
545
  cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
477
546
 
547
+ worstPrice = limitOrderPrice;
548
+
478
549
  if (cumulativeBaseFilled.eq(amount)) {
479
550
  break;
480
551
  }
@@ -482,7 +553,10 @@ export function calculateEstimatedPerpEntryPrice(
482
553
  limitOrder = limitOrders.next().value;
483
554
  }
484
555
  } else {
485
- while (!cumulativeQuoteFilled.eq(amount)) {
556
+ while (
557
+ !cumulativeQuoteFilled.eq(amount) &&
558
+ (ammLiquidity.gt(ZERO) || limitOrder)
559
+ ) {
486
560
  const limitOrderPrice = limitOrder?.getPrice(oraclePriceData, slot);
487
561
 
488
562
  let maxAmmFill: BN;
@@ -503,6 +577,8 @@ export function calculateEstimatedPerpEntryPrice(
503
577
  maxAmmFill = amount.sub(cumulativeQuoteFilled);
504
578
  }
505
579
 
580
+ maxAmmFill = BN.min(maxAmmFill, ammLiquidity);
581
+
506
582
  if (maxAmmFill.gt(ZERO)) {
507
583
  const quoteFilled = BN.min(
508
584
  amount.sub(cumulativeQuoteFilled),
@@ -516,6 +592,8 @@ export function calculateEstimatedPerpEntryPrice(
516
592
  swapDirection
517
593
  );
518
594
 
595
+ ammLiquidity = ammLiquidity.sub(quoteFilled);
596
+
519
597
  const baseFilled = afterSwapBaseReserves
520
598
  .sub(amm.baseAssetReserve)
521
599
  .abs();
@@ -526,11 +604,21 @@ export function calculateEstimatedPerpEntryPrice(
526
604
  amm.baseAssetReserve = afterSwapBaseReserves;
527
605
  amm.quoteAssetReserve = afterSwapQuoteReserves;
528
606
 
607
+ worstPrice = calculatePrice(
608
+ amm.baseAssetReserve,
609
+ amm.quoteAssetReserve,
610
+ amm.pegMultiplier
611
+ );
612
+
529
613
  if (cumulativeQuoteFilled.eq(amount)) {
530
614
  break;
531
615
  }
532
616
  }
533
617
 
618
+ if (limitOrder && usersToSkip.has(limitOrder.userAccount)) {
619
+ continue;
620
+ }
621
+
534
622
  const quoteFilled = BN.min(
535
623
  limitOrder.order.baseAssetAmount
536
624
  .sub(limitOrder.order.baseAssetAmountFilled)
@@ -544,6 +632,8 @@ export function calculateEstimatedPerpEntryPrice(
544
632
  cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
545
633
  cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
546
634
 
635
+ worstPrice = limitOrderPrice;
636
+
547
637
  if (cumulativeQuoteFilled.eq(amount)) {
548
638
  break;
549
639
  }
@@ -557,10 +647,226 @@ export function calculateEstimatedPerpEntryPrice(
557
647
  .div(cumulativeBaseFilled);
558
648
 
559
649
  const priceImpact = entryPrice
560
- .sub(initialPrice)
650
+ .sub(bestPrice)
651
+ .mul(PRICE_PRECISION)
652
+ .div(bestPrice)
653
+ .abs();
654
+
655
+ return {
656
+ entryPrice,
657
+ priceImpact,
658
+ bestPrice,
659
+ worstPrice,
660
+ baseFilled: cumulativeBaseFilled,
661
+ quoteFilled: cumulativeQuoteFilled,
662
+ };
663
+ }
664
+
665
+ /**
666
+ * Calculates the estimated entry price and price impact of order, in base or quote
667
+ * Price impact is based on the difference between the entry price and the best bid/ask price (whether it's dlob or serum)
668
+ *
669
+ * @param assetType
670
+ * @param amount
671
+ * @param direction
672
+ * @param market
673
+ * @param oraclePriceData
674
+ * @param dlob
675
+ * @param serumBids
676
+ * @param serumAsks
677
+ * @param slot
678
+ * @param usersToSkip
679
+ */
680
+ export function calculateEstimatedSpotEntryPrice(
681
+ assetType: AssetType,
682
+ amount: BN,
683
+ direction: PositionDirection,
684
+ market: SpotMarketAccount,
685
+ oraclePriceData: OraclePriceData,
686
+ dlob: DLOB,
687
+ serumBids: Orderbook,
688
+ serumAsks: Orderbook,
689
+ slot: number,
690
+ usersToSkip = new Map<PublicKey, boolean>()
691
+ ): {
692
+ entryPrice: BN;
693
+ priceImpact: BN;
694
+ bestPrice: BN;
695
+ worstPrice: BN;
696
+ baseFilled: BN;
697
+ quoteFilled: BN;
698
+ } {
699
+ if (amount.eq(ZERO)) {
700
+ return {
701
+ entryPrice: ZERO,
702
+ priceImpact: ZERO,
703
+ bestPrice: ZERO,
704
+ worstPrice: ZERO,
705
+ baseFilled: ZERO,
706
+ quoteFilled: ZERO,
707
+ };
708
+ }
709
+
710
+ const basePrecision = new BN(Math.pow(10, market.decimals));
711
+
712
+ const takerIsLong = isVariant(direction, 'long');
713
+ const dlobLimitOrders = dlob[
714
+ takerIsLong ? 'getMakerLimitAsks' : 'getMakerLimitBids'
715
+ ](market.marketIndex, slot, MarketType.SPOT, oraclePriceData);
716
+ const serumLimitOrders = takerIsLong
717
+ ? serumAsks.getL2(100)
718
+ : serumBids.getL2(100);
719
+
720
+ let cumulativeBaseFilled = ZERO;
721
+ let cumulativeQuoteFilled = ZERO;
722
+
723
+ let dlobLimitOrder = dlobLimitOrders.next().value;
724
+ let serumLimitOrder = serumLimitOrders.shift();
725
+
726
+ const dlobLimitOrderPrice = dlobLimitOrder?.getPrice(oraclePriceData, slot);
727
+ const serumLimitOrderPrice = serumLimitOrder
728
+ ? new BN(serumLimitOrder[0] * PRICE_PRECISION.toNumber())
729
+ : undefined;
730
+
731
+ const bestPrice = takerIsLong
732
+ ? BN.min(serumLimitOrderPrice || BN_MAX, dlobLimitOrderPrice || BN_MAX)
733
+ : BN.max(serumLimitOrderPrice || ZERO, dlobLimitOrderPrice || ZERO);
734
+ let worstPrice = bestPrice;
735
+
736
+ if (assetType === 'base') {
737
+ while (
738
+ !cumulativeBaseFilled.eq(amount) &&
739
+ (dlobLimitOrder || serumLimitOrder)
740
+ ) {
741
+ const dlobLimitOrderPrice = dlobLimitOrder?.getPrice(
742
+ oraclePriceData,
743
+ slot
744
+ );
745
+ const serumLimitOrderPrice = serumLimitOrder
746
+ ? new BN(serumLimitOrder[0] * PRICE_PRECISION.toNumber())
747
+ : undefined;
748
+
749
+ const useSerum = takerIsLong
750
+ ? (serumLimitOrderPrice || BN_MAX).lt(dlobLimitOrderPrice || BN_MAX)
751
+ : (serumLimitOrderPrice || ZERO).gt(dlobLimitOrderPrice || ZERO);
752
+
753
+ if (!useSerum) {
754
+ if (dlobLimitOrder && usersToSkip.has(dlobLimitOrder.userAccount)) {
755
+ continue;
756
+ }
757
+
758
+ const baseFilled = BN.min(
759
+ dlobLimitOrder.order.baseAssetAmount.sub(
760
+ dlobLimitOrder.order.baseAssetAmountFilled
761
+ ),
762
+ amount.sub(cumulativeBaseFilled)
763
+ );
764
+ const quoteFilled = baseFilled
765
+ .mul(dlobLimitOrderPrice)
766
+ .div(basePrecision);
767
+
768
+ cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
769
+ cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
770
+
771
+ worstPrice = dlobLimitOrder;
772
+
773
+ dlobLimitOrder = dlobLimitOrders.next().value;
774
+ } else {
775
+ const baseFilled = BN.min(
776
+ new BN(serumLimitOrder[1] * basePrecision.toNumber()),
777
+ amount.sub(cumulativeBaseFilled)
778
+ );
779
+ const quoteFilled = baseFilled
780
+ .mul(serumLimitOrderPrice)
781
+ .div(basePrecision);
782
+
783
+ cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
784
+ cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
785
+
786
+ worstPrice = serumLimitOrderPrice;
787
+
788
+ serumLimitOrder = serumLimitOrders.shift();
789
+ }
790
+ }
791
+ } else {
792
+ while (
793
+ !cumulativeQuoteFilled.eq(amount) &&
794
+ (dlobLimitOrder || serumLimitOrder)
795
+ ) {
796
+ const dlobLimitOrderPrice = dlobLimitOrder?.getPrice(
797
+ oraclePriceData,
798
+ slot
799
+ );
800
+ const serumLimitOrderPrice = serumLimitOrder
801
+ ? new BN(serumLimitOrder[0] * PRICE_PRECISION.toNumber())
802
+ : undefined;
803
+
804
+ const useSerum = takerIsLong
805
+ ? (serumLimitOrderPrice || BN_MAX).lt(dlobLimitOrderPrice || BN_MAX)
806
+ : (serumLimitOrderPrice || ZERO).gt(dlobLimitOrderPrice || ZERO);
807
+
808
+ if (!useSerum) {
809
+ if (dlobLimitOrder && usersToSkip.has(dlobLimitOrder.userAccount)) {
810
+ continue;
811
+ }
812
+
813
+ const quoteFilled = BN.min(
814
+ dlobLimitOrder.order.baseAssetAmount
815
+ .sub(dlobLimitOrder.order.baseAssetAmountFilled)
816
+ .mul(dlobLimitOrderPrice)
817
+ .div(basePrecision),
818
+ amount.sub(cumulativeQuoteFilled)
819
+ );
820
+
821
+ const baseFilled = quoteFilled
822
+ .mul(basePrecision)
823
+ .div(dlobLimitOrderPrice);
824
+
825
+ cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
826
+ cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
827
+
828
+ worstPrice = dlobLimitOrderPrice;
829
+
830
+ dlobLimitOrder = dlobLimitOrders.next().value;
831
+ } else {
832
+ const serumOrderBaseAmount = new BN(
833
+ serumLimitOrder[1] * basePrecision.toNumber()
834
+ );
835
+ const quoteFilled = BN.min(
836
+ serumOrderBaseAmount.mul(serumLimitOrderPrice).div(basePrecision),
837
+ amount.sub(cumulativeQuoteFilled)
838
+ );
839
+
840
+ const baseFilled = quoteFilled
841
+ .mul(basePrecision)
842
+ .div(serumLimitOrderPrice);
843
+
844
+ cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
845
+ cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
846
+
847
+ worstPrice = serumLimitOrderPrice;
848
+
849
+ serumLimitOrder = serumLimitOrders.shift();
850
+ }
851
+ }
852
+ }
853
+
854
+ const entryPrice = cumulativeQuoteFilled
855
+ .mul(basePrecision)
856
+ .div(cumulativeBaseFilled);
857
+
858
+ const priceImpact = entryPrice
859
+ .sub(bestPrice)
561
860
  .mul(PRICE_PRECISION)
562
- .div(initialPrice)
861
+ .div(bestPrice)
563
862
  .abs();
564
863
 
565
- return [entryPrice, priceImpact];
864
+ return {
865
+ entryPrice,
866
+ priceImpact,
867
+ bestPrice,
868
+ worstPrice,
869
+ baseFilled: cumulativeBaseFilled,
870
+ quoteFilled: cumulativeQuoteFilled,
871
+ };
566
872
  }
package/src/tx/utils.ts CHANGED
@@ -8,14 +8,22 @@ const COMPUTE_UNITS_DEFAULT = 200_000;
8
8
 
9
9
  export function wrapInTx(
10
10
  instruction: TransactionInstruction,
11
- computeUnits = 600_000 // TODO, requires less code change
11
+ computeUnits = 600_000,
12
+ computeUnitsPrice = 0
12
13
  ): Transaction {
13
14
  const tx = new Transaction();
14
15
  if (computeUnits != COMPUTE_UNITS_DEFAULT) {
15
16
  tx.add(
16
- ComputeBudgetProgram.requestUnits({
17
+ ComputeBudgetProgram.setComputeUnitLimit({
17
18
  units: computeUnits,
18
- additionalFee: 0,
19
+ })
20
+ );
21
+ }
22
+
23
+ if (computeUnitsPrice != 0) {
24
+ tx.add(
25
+ ComputeBudgetProgram.setComputeUnitPrice({
26
+ microLamports: computeUnitsPrice,
19
27
  })
20
28
  );
21
29
  }
package/src/types.ts CHANGED
@@ -909,6 +909,11 @@ export type ReferrerInfo = {
909
909
  referrerStats: PublicKey;
910
910
  };
911
911
 
912
+ export type TxParams = {
913
+ computeUnits?: number;
914
+ computeUnitsPrice?: number;
915
+ };
916
+
912
917
  // # Misc Types
913
918
  export interface IWallet {
914
919
  signTransaction(tx: Transaction): Promise<Transaction>;