sol-trade-sdk 0.1.0 → 0.1.2

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 (50) hide show
  1. package/README.md +12 -5
  2. package/dist/cache/index.d.mts +70 -0
  3. package/dist/cache/index.d.ts +70 -0
  4. package/dist/cache/index.js +259 -0
  5. package/dist/cache/index.mjs +19 -0
  6. package/dist/chunk-64JY4YH6.mjs +227 -0
  7. package/dist/chunk-6BWS3CLP.mjs +16 -0
  8. package/dist/{chunk-NEZDFAYA.mjs → chunk-H4ZUMTTP.mjs} +864 -336
  9. package/dist/{chunk-MMQAMIKR.mjs → chunk-L6RZIXXN.mjs} +4 -11
  10. package/dist/{clients-VITWK7B6.mjs → chunk-V7QDWUXJ.mjs} +39 -39
  11. package/dist/clients-PSG35HN4.mjs +107 -0
  12. package/dist/index-hZh5hrGj.d.mts +3089 -0
  13. package/dist/index-yJ5AsNfm.d.ts +3089 -0
  14. package/dist/index.d.mts +2 -2658
  15. package/dist/index.d.ts +2 -2658
  16. package/dist/index.js +794 -278
  17. package/dist/index.mjs +21 -4
  18. package/dist/perf/index.mjs +2 -1
  19. package/dist/pool/index.d.mts +88 -0
  20. package/dist/pool/index.d.ts +88 -0
  21. package/dist/pool/index.js +262 -0
  22. package/dist/pool/index.mjs +233 -0
  23. package/dist/rpc/index.d.mts +77 -0
  24. package/dist/rpc/index.d.ts +77 -0
  25. package/dist/rpc/index.js +447 -0
  26. package/dist/rpc/index.mjs +223 -0
  27. package/dist/swqos/index.d.mts +416 -0
  28. package/dist/swqos/index.d.ts +416 -0
  29. package/dist/swqos/index.js +3450 -0
  30. package/dist/swqos/index.mjs +1375 -0
  31. package/dist/trading/index.d.mts +998 -0
  32. package/dist/trading/index.d.ts +998 -0
  33. package/dist/trading/index.js +4302 -0
  34. package/dist/trading/index.mjs +2097 -0
  35. package/package.json +5 -4
  36. package/src/__tests__/hotpath.test.ts +33 -0
  37. package/src/__tests__/parser-compat.test.ts +82 -0
  38. package/src/__tests__/protocol-parity.test.ts +242 -0
  39. package/src/__tests__/sdk.test.ts +16 -0
  40. package/src/cache/index.ts +1 -0
  41. package/src/hotpath/executor.ts +25 -18
  42. package/src/index.ts +330 -92
  43. package/src/instruction/meteora_damm_v2_builder.ts +88 -20
  44. package/src/instruction/pumpfun_builder.ts +133 -43
  45. package/src/instruction/raydium_amm_v4_builder.ts +244 -35
  46. package/src/instruction/raydium_cpmm_builder.ts +87 -69
  47. package/src/params/index.ts +38 -5
  48. package/src/pool/index.ts +1 -0
  49. package/src/rpc/index.ts +1 -0
  50. package/src/trading/factory.ts +10 -0
package/dist/index.js CHANGED
@@ -373,7 +373,36 @@ function effectivePumpMintTokenProgram(mint, protocolParams) {
373
373
  return import_spl_token.TOKEN_2022_PROGRAM_ID;
374
374
  }
375
375
  function effectiveQuoteMint(protocolParams) {
376
- return isUsablePubkey(protocolParams.quoteMint) ? protocolParams.quoteMint : import_spl_token.NATIVE_MINT;
376
+ if (!isUsablePubkey(protocolParams.quoteMint) || protocolParams.quoteMint.equals(SOL_TOKEN_ACCOUNT2)) {
377
+ return import_spl_token.NATIVE_MINT;
378
+ }
379
+ return protocolParams.quoteMint;
380
+ }
381
+ function usesPumpFunV2Layout(protocolParams) {
382
+ return isUsablePubkey(protocolParams.quoteMint) && !protocolParams.quoteMint.equals(SOL_TOKEN_ACCOUNT2);
383
+ }
384
+ function isSolQuoteMint(mint) {
385
+ return mint.equals(SOL_TOKEN_ACCOUNT2) || mint.equals(import_spl_token.NATIVE_MINT);
386
+ }
387
+ function validateV2BuyQuoteMint(inputMint, quoteMint) {
388
+ if (isSolQuoteMint(quoteMint)) {
389
+ if (inputMint.equals(SOL_TOKEN_ACCOUNT2) || inputMint.equals(import_spl_token.NATIVE_MINT)) return;
390
+ } else if (inputMint.equals(quoteMint)) {
391
+ return;
392
+ }
393
+ throw new Error(
394
+ `PumpFun V2 buy input_mint ${inputMint.toBase58()} does not match quote_mint ${quoteMint.toBase58()}; USDC quote pools must be bought with USDC, not SOL`
395
+ );
396
+ }
397
+ function validateV2SellQuoteMint(outputMint, quoteMint) {
398
+ if (isSolQuoteMint(quoteMint)) {
399
+ if (outputMint.equals(SOL_TOKEN_ACCOUNT2) || outputMint.equals(import_spl_token.NATIVE_MINT)) return;
400
+ } else if (outputMint.equals(quoteMint)) {
401
+ return;
402
+ }
403
+ throw new Error(
404
+ `PumpFun V2 sell output_mint ${outputMint.toBase58()} does not match quote_mint ${quoteMint.toBase58()}; USDC quote pools settle to USDC, not SOL`
405
+ );
377
406
  }
378
407
  function associatedTokenAddress(mint, owner, tokenProgram) {
379
408
  return (0, import_spl_token.getAssociatedTokenAddressSync)(
@@ -384,6 +413,28 @@ function associatedTokenAddress(mint, owner, tokenProgram) {
384
413
  import_spl_token.ASSOCIATED_TOKEN_PROGRAM_ID
385
414
  );
386
415
  }
416
+ function pushCreateOrWrapUserTokenAccount(instructions, payer, ata, mint, tokenProgram, amount) {
417
+ instructions.push(
418
+ (0, import_spl_token.createAssociatedTokenAccountIdempotentInstruction)(
419
+ payer,
420
+ ata,
421
+ payer,
422
+ mint,
423
+ tokenProgram,
424
+ import_spl_token.ASSOCIATED_TOKEN_PROGRAM_ID
425
+ )
426
+ );
427
+ if (mint.equals(import_spl_token.NATIVE_MINT)) {
428
+ instructions.push(
429
+ import_web32.SystemProgram.transfer({
430
+ fromPubkey: payer,
431
+ toPubkey: ata,
432
+ lamports: amount
433
+ })
434
+ );
435
+ instructions.push((0, import_spl_token.createSyncNativeInstruction)(ata));
436
+ }
437
+ }
387
438
  function getBuyTokenAmountFromSolAmount(amount, bondingCurve, creator) {
388
439
  if (amount === 0n || bondingCurve.virtualTokenReserves === 0n) {
389
440
  return 0n;
@@ -413,21 +464,23 @@ function getSellSolAmountFromTokenAmount(amount, bondingCurve, creator) {
413
464
  function buildPumpFunBuyInstructions(params) {
414
465
  const {
415
466
  payer,
467
+ inputMint = SOL_TOKEN_ACCOUNT2,
416
468
  outputMint,
417
469
  inputAmount,
418
470
  slippageBasisPoints = BigInt(1e3),
419
471
  fixedOutputAmount,
420
472
  createOutputMintAta = true,
421
473
  createInputMintAta = false,
474
+ closeInputMintAta = false,
422
475
  protocolParams,
423
- useExactSolAmount = true,
424
- usePumpFunV2 = false
476
+ useExactSolAmount = true
425
477
  } = params;
426
- if (usePumpFunV2 || protocolParams.useV2Ix || isUsablePubkey(protocolParams.quoteMint)) {
478
+ if (usesPumpFunV2Layout(protocolParams)) {
427
479
  return buildPumpFunBuyV2Instructions({
428
480
  ...params,
481
+ inputMint,
429
482
  createInputMintAta,
430
- usePumpFunV2: true
483
+ closeInputMintAta
431
484
  });
432
485
  }
433
486
  if (inputAmount === BigInt(0)) {
@@ -451,34 +504,41 @@ function buildPumpFunBuyInstructions(params) {
451
504
  const userVolumeAccumulator = getPumpFunUserVolumeAccumulatorPda(payerPubkey);
452
505
  if (createOutputMintAta) {
453
506
  instructions.push(
454
- (0, import_spl_token.createAssociatedTokenAccountInstruction)(
507
+ (0, import_spl_token.createAssociatedTokenAccountIdempotentInstruction)(
455
508
  payerPubkey,
456
509
  userTokenAccount,
457
510
  payerPubkey,
458
511
  outputMint,
459
- tokenProgramId
512
+ tokenProgramId,
513
+ import_spl_token.ASSOCIATED_TOKEN_PROGRAM_ID
460
514
  )
461
515
  );
462
516
  }
463
517
  const feeRecipientPk = pumpFunFeeRecipientMeta(feeRecipient, bondingCurve.isMayhemMode);
464
518
  const bondingCurveV2 = getBondingCurveV2Pda(outputMint);
465
- const trackVolume = bondingCurve.isCashbackCoin ? Buffer.from([1, 1]) : Buffer.from([1, 0]);
519
+ const trackVolume = bondingCurve.isCashbackCoin ? 1 : 0;
466
520
  const buyTokenAmount = fixedOutputAmount ? fixedOutputAmount : getBuyTokenAmountFromSolAmount(inputAmount, bondingCurve, creator);
467
521
  const maxSolCost = calculateWithSlippageBuy(inputAmount, slippageBasisPoints);
468
522
  let data;
469
- if (useExactSolAmount) {
470
- const minTokensOut = fixedOutputAmount ? fixedOutputAmount : calculateWithSlippageSell(buyTokenAmount, slippageBasisPoints);
471
- data = Buffer.alloc(26);
523
+ if (fixedOutputAmount !== void 0) {
524
+ data = Buffer.alloc(25);
525
+ PUMPFUN_BUY_DISCRIMINATOR.copy(data, 0);
526
+ data.writeBigUInt64LE(fixedOutputAmount, 8);
527
+ data.writeBigUInt64LE(inputAmount, 16);
528
+ data[24] = trackVolume;
529
+ } else if (useExactSolAmount) {
530
+ const minTokensOut = calculateWithSlippageSell(buyTokenAmount, slippageBasisPoints);
531
+ data = Buffer.alloc(25);
472
532
  PUMPFUN_BUY_EXACT_SOL_IN_DISCRIMINATOR.copy(data, 0);
473
533
  data.writeBigUInt64LE(inputAmount, 8);
474
534
  data.writeBigUInt64LE(minTokensOut, 16);
475
- trackVolume.copy(data, 24);
535
+ data[24] = trackVolume;
476
536
  } else {
477
- data = Buffer.alloc(26);
537
+ data = Buffer.alloc(25);
478
538
  PUMPFUN_BUY_DISCRIMINATOR.copy(data, 0);
479
539
  data.writeBigUInt64LE(buyTokenAmount, 8);
480
540
  data.writeBigUInt64LE(maxSolCost, 16);
481
- trackVolume.copy(data, 24);
541
+ data[24] = trackVolume;
482
542
  }
483
543
  const keys = [
484
544
  { pubkey: PUMPFUN_GLOBAL_ACCOUNT, isSigner: false, isWritable: false },
@@ -513,19 +573,19 @@ function buildPumpFunSellInstructions(params) {
513
573
  const {
514
574
  payer,
515
575
  inputMint,
576
+ outputMint = SOL_TOKEN_ACCOUNT2,
516
577
  inputAmount,
517
578
  slippageBasisPoints = BigInt(1e3),
518
579
  fixedOutputAmount,
519
580
  createOutputMintAta = false,
520
581
  closeInputMintAta = false,
521
- protocolParams,
522
- usePumpFunV2 = false
582
+ protocolParams
523
583
  } = params;
524
- if (usePumpFunV2 || protocolParams.useV2Ix || isUsablePubkey(protocolParams.quoteMint)) {
584
+ if (usesPumpFunV2Layout(protocolParams)) {
525
585
  return buildPumpFunSellV2Instructions({
526
586
  ...params,
527
- createOutputMintAta,
528
- usePumpFunV2: true
587
+ outputMint,
588
+ createOutputMintAta
529
589
  });
530
590
  }
531
591
  if (inputAmount === BigInt(0)) {
@@ -605,12 +665,14 @@ function buildPumpFunSellInstructions(params) {
605
665
  function buildPumpFunBuyV2Instructions(params) {
606
666
  const {
607
667
  payer,
668
+ inputMint = SOL_TOKEN_ACCOUNT2,
608
669
  outputMint,
609
670
  inputAmount,
610
671
  slippageBasisPoints = BigInt(1e3),
611
672
  fixedOutputAmount,
612
673
  createOutputMintAta = true,
613
674
  createInputMintAta = false,
675
+ closeInputMintAta = false,
614
676
  protocolParams,
615
677
  useExactSolAmount = true
616
678
  } = params;
@@ -625,6 +687,7 @@ function buildPumpFunBuyV2Instructions(params) {
625
687
  const bondingCurveAddr = bondingCurve.account.equals(import_web32.PublicKey.default) || !bondingCurve.account ? getBondingCurvePda(outputMint) : bondingCurve.account;
626
688
  const baseTokenProgram = effectivePumpMintTokenProgram(outputMint, protocolParams);
627
689
  const quoteMint = effectiveQuoteMint(protocolParams);
690
+ validateV2BuyQuoteMint(inputMint, quoteMint);
628
691
  const quoteTokenProgram = import_spl_token.TOKEN_PROGRAM_ID;
629
692
  const associatedBaseBondingCurve = associatedTokenAddress(
630
693
  outputMint,
@@ -677,32 +740,39 @@ function buildPumpFunBuyV2Instructions(params) {
677
740
  )
678
741
  );
679
742
  }
680
- if (createInputMintAta) {
681
- instructions.push(
682
- (0, import_spl_token.createAssociatedTokenAccountIdempotentInstruction)(
683
- payerPubkey,
684
- associatedQuoteUser,
685
- payerPubkey,
686
- quoteMint,
687
- quoteTokenProgram,
688
- import_spl_token.ASSOCIATED_TOKEN_PROGRAM_ID
689
- )
690
- );
691
- }
692
743
  const buyTokenAmount = fixedOutputAmount ? fixedOutputAmount : getBuyTokenAmountFromSolAmount(inputAmount, bondingCurve, creator);
693
744
  const maxSolCost = calculateWithSlippageBuy(inputAmount, slippageBasisPoints);
694
745
  let data;
695
- if (useExactSolAmount) {
696
- const minTokensOut = fixedOutputAmount ? fixedOutputAmount : calculateWithSlippageSell(buyTokenAmount, slippageBasisPoints);
746
+ let quoteAmountToFund;
747
+ if (fixedOutputAmount !== void 0) {
748
+ data = Buffer.alloc(24);
749
+ PUMPFUN_BUY_V2_DISCRIMINATOR.copy(data, 0);
750
+ data.writeBigUInt64LE(fixedOutputAmount, 8);
751
+ data.writeBigUInt64LE(inputAmount, 16);
752
+ quoteAmountToFund = inputAmount;
753
+ } else if (useExactSolAmount) {
754
+ const minTokensOut = calculateWithSlippageSell(buyTokenAmount, slippageBasisPoints);
697
755
  data = Buffer.alloc(24);
698
756
  PUMPFUN_BUY_EXACT_QUOTE_IN_V2_DISCRIMINATOR.copy(data, 0);
699
757
  data.writeBigUInt64LE(inputAmount, 8);
700
758
  data.writeBigUInt64LE(minTokensOut, 16);
759
+ quoteAmountToFund = inputAmount;
701
760
  } else {
702
761
  data = Buffer.alloc(24);
703
762
  PUMPFUN_BUY_V2_DISCRIMINATOR.copy(data, 0);
704
763
  data.writeBigUInt64LE(buyTokenAmount, 8);
705
764
  data.writeBigUInt64LE(maxSolCost, 16);
765
+ quoteAmountToFund = maxSolCost;
766
+ }
767
+ if (createInputMintAta) {
768
+ pushCreateOrWrapUserTokenAccount(
769
+ instructions,
770
+ payerPubkey,
771
+ associatedQuoteUser,
772
+ quoteMint,
773
+ quoteTokenProgram,
774
+ quoteAmountToFund
775
+ );
706
776
  }
707
777
  const keys = [
708
778
  { pubkey: PUMPFUN_GLOBAL_ACCOUNT, isSigner: false, isWritable: false },
@@ -740,12 +810,24 @@ function buildPumpFunBuyV2Instructions(params) {
740
810
  data
741
811
  })
742
812
  );
813
+ if (closeInputMintAta && quoteMint.equals(import_spl_token.NATIVE_MINT)) {
814
+ instructions.push(
815
+ (0, import_spl_token.createCloseAccountInstruction)(
816
+ associatedQuoteUser,
817
+ payerPubkey,
818
+ payerPubkey,
819
+ [],
820
+ quoteTokenProgram
821
+ )
822
+ );
823
+ }
743
824
  return instructions;
744
825
  }
745
826
  function buildPumpFunSellV2Instructions(params) {
746
827
  const {
747
828
  payer,
748
829
  inputMint,
830
+ outputMint = SOL_TOKEN_ACCOUNT2,
749
831
  inputAmount,
750
832
  slippageBasisPoints = BigInt(1e3),
751
833
  fixedOutputAmount,
@@ -764,6 +846,7 @@ function buildPumpFunSellV2Instructions(params) {
764
846
  const bondingCurveAddr = bondingCurve.account.equals(import_web32.PublicKey.default) || !bondingCurve.account ? getBondingCurvePda(inputMint) : bondingCurve.account;
765
847
  const baseTokenProgram = effectivePumpMintTokenProgram(inputMint, protocolParams);
766
848
  const quoteMint = effectiveQuoteMint(protocolParams);
849
+ validateV2SellQuoteMint(outputMint, quoteMint);
767
850
  const quoteTokenProgram = import_spl_token.TOKEN_PROGRAM_ID;
768
851
  const associatedBaseBondingCurve = associatedTokenAddress(
769
852
  inputMint,
@@ -943,12 +1026,13 @@ function getBuyPrice(amount, virtualSolReserves, virtualTokenReserves, realToken
943
1026
  const s = virtualTokenReserves - r;
944
1027
  return s < realTokenReserves ? s : realTokenReserves;
945
1028
  }
946
- var import_web32, import_spl_token, PUMPFUN_PROGRAM_ID, PUMPFUN_EVENT_AUTHORITY, PUMPFUN_FEE_PROGRAM, PUMPFUN_GLOBAL_VOLUME_ACCUMULATOR, PUMPFUN_FEE_CONFIG, PUMPFUN_GLOBAL_ACCOUNT, PUMPFUN_FEE_RECIPIENT, PUMPFUN_STANDARD_FEE_RECIPIENTS, PUMPFUN_PROTOCOL_EXTRA_FEE_RECIPIENTS, PUMPFUN_BUYBACK_FEE_RECIPIENTS, PUMPFUN_MAYHEM_FEE_RECIPIENTS, PUMPFUN_BUY_DISCRIMINATOR, PUMPFUN_BUY_EXACT_SOL_IN_DISCRIMINATOR, PUMPFUN_SELL_DISCRIMINATOR, PUMPFUN_BUY_V2_DISCRIMINATOR, PUMPFUN_SELL_V2_DISCRIMINATOR, PUMPFUN_BUY_EXACT_QUOTE_IN_V2_DISCRIMINATOR, PUMPFUN_CLAIM_CASHBACK_DISCRIMINATOR, PUMPFUN_BONDING_CURVE_SEED, PUMPFUN_BONDING_CURVE_V2_SEED, PUMPFUN_CREATOR_VAULT_SEED, PUMPFUN_USER_VOLUME_ACCUMULATOR_SEED, PUMPFUN_SHARING_CONFIG_SEED, MAX_SLIPPAGE_BPS, PUMPFUN_FEE_BASIS_POINTS, PUMPFUN_CREATOR_FEE_BASIS_POINTS, PHANTOM_DEFAULT_CREATOR_VAULT;
1029
+ var import_web32, import_spl_token, SOL_TOKEN_ACCOUNT2, PUMPFUN_PROGRAM_ID, PUMPFUN_EVENT_AUTHORITY, PUMPFUN_FEE_PROGRAM, PUMPFUN_GLOBAL_VOLUME_ACCUMULATOR, PUMPFUN_FEE_CONFIG, PUMPFUN_GLOBAL_ACCOUNT, PUMPFUN_FEE_RECIPIENT, PUMPFUN_STANDARD_FEE_RECIPIENTS, PUMPFUN_PROTOCOL_EXTRA_FEE_RECIPIENTS, PUMPFUN_BUYBACK_FEE_RECIPIENTS, PUMPFUN_MAYHEM_FEE_RECIPIENTS, PUMPFUN_BUY_DISCRIMINATOR, PUMPFUN_BUY_EXACT_SOL_IN_DISCRIMINATOR, PUMPFUN_SELL_DISCRIMINATOR, PUMPFUN_BUY_V2_DISCRIMINATOR, PUMPFUN_SELL_V2_DISCRIMINATOR, PUMPFUN_BUY_EXACT_QUOTE_IN_V2_DISCRIMINATOR, PUMPFUN_CLAIM_CASHBACK_DISCRIMINATOR, PUMPFUN_BONDING_CURVE_SEED, PUMPFUN_BONDING_CURVE_V2_SEED, PUMPFUN_CREATOR_VAULT_SEED, PUMPFUN_USER_VOLUME_ACCUMULATOR_SEED, PUMPFUN_SHARING_CONFIG_SEED, MAX_SLIPPAGE_BPS, PUMPFUN_FEE_BASIS_POINTS, PUMPFUN_CREATOR_FEE_BASIS_POINTS, PHANTOM_DEFAULT_CREATOR_VAULT;
947
1030
  var init_pumpfun_builder = __esm({
948
1031
  "src/instruction/pumpfun_builder.ts"() {
949
1032
  "use strict";
950
1033
  import_web32 = require("@solana/web3.js");
951
1034
  import_spl_token = require("@solana/spl-token");
1035
+ SOL_TOKEN_ACCOUNT2 = new import_web32.PublicKey("So11111111111111111111111111111111111111111");
952
1036
  PUMPFUN_PROGRAM_ID = new import_web32.PublicKey(
953
1037
  "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"
954
1038
  );
@@ -2414,34 +2498,38 @@ function buildRaydiumCpmmBuyInstructions(params) {
2414
2498
  throw new Error("Pool must contain WSOL or USDC");
2415
2499
  }
2416
2500
  const isBaseIn = baseMint.equals(WSOL_TOKEN_ACCOUNT2) || baseMint.equals(USDC_TOKEN_ACCOUNT2);
2417
- const mintTokenProgram = isBaseIn ? quoteTokenProgram : baseTokenProgram;
2501
+ const inputMint = isBaseIn ? baseMint : quoteMint;
2502
+ const inputTokenProgram = isBaseIn ? baseTokenProgram : quoteTokenProgram;
2503
+ const expectedOutputMint = isBaseIn ? quoteMint : baseMint;
2504
+ const outputTokenProgram = isBaseIn ? quoteTokenProgram : baseTokenProgram;
2505
+ if (!outputMint.equals(expectedOutputMint)) {
2506
+ throw new Error(`outputMint must match Raydium CPMM pool side ${expectedOutputMint.toBase58()}`);
2507
+ }
2418
2508
  const poolState = protocolParams.poolState && !protocolParams.poolState.equals(import_web35.PublicKey.default) ? protocolParams.poolState : getRaydiumCpmmPoolPda(ammConfig, baseMint, quoteMint);
2419
- const swapResult = computeRaydiumCpmmSwapAmount(
2509
+ const minimumAmountOut = fixedOutputAmount ?? computeRaydiumCpmmSwapAmount(
2420
2510
  baseReserve,
2421
2511
  quoteReserve,
2422
2512
  isBaseIn,
2423
2513
  inputAmount,
2424
2514
  slippageBasisPoints
2425
- );
2426
- const minimumAmountOut = fixedOutputAmount || swapResult.minAmountOut;
2427
- const inputMint = isWsol ? WSOL_TOKEN_ACCOUNT2 : USDC_TOKEN_ACCOUNT2;
2515
+ ).minAmountOut;
2428
2516
  const inputTokenAccount = (0, import_spl_token3.getAssociatedTokenAddressSync)(
2429
2517
  inputMint,
2430
2518
  payerPubkey,
2431
2519
  true,
2432
- import_spl_token3.TOKEN_PROGRAM_ID
2520
+ inputTokenProgram
2433
2521
  );
2434
2522
  const outputTokenAccount = (0, import_spl_token3.getAssociatedTokenAddressSync)(
2435
2523
  outputMint,
2436
2524
  payerPubkey,
2437
2525
  true,
2438
- mintTokenProgram
2526
+ outputTokenProgram
2439
2527
  );
2440
2528
  const inputVaultAccount = (() => {
2441
- if (isWsol && baseMint.equals(inputMint) && baseVault && !baseVault.equals(import_web35.PublicKey.default)) {
2529
+ if (baseMint.equals(inputMint) && baseVault && !baseVault.equals(import_web35.PublicKey.default)) {
2442
2530
  return baseVault;
2443
2531
  }
2444
- if (!isWsol && quoteMint.equals(inputMint) && quoteVault && !quoteVault.equals(import_web35.PublicKey.default)) {
2532
+ if (quoteMint.equals(inputMint) && quoteVault && !quoteVault.equals(import_web35.PublicKey.default)) {
2445
2533
  return quoteVault;
2446
2534
  }
2447
2535
  return getRaydiumCpmmVaultPda(poolState, inputMint);
@@ -2456,34 +2544,43 @@ function buildRaydiumCpmmBuyInstructions(params) {
2456
2544
  return getRaydiumCpmmVaultPda(poolState, outputMint);
2457
2545
  })();
2458
2546
  const observationStateAccount = observationState && !observationState.equals(import_web35.PublicKey.default) ? observationState : getRaydiumCpmmObservationStatePda(poolState);
2459
- if (createInputMintAta && isWsol) {
2460
- const wsolAta = (0, import_spl_token3.getAssociatedTokenAddressSync)(import_spl_token3.NATIVE_MINT, payerPubkey, true);
2547
+ if (createInputMintAta) {
2548
+ const isInputWsol = inputMint.equals(WSOL_TOKEN_ACCOUNT2);
2461
2549
  instructions.push(
2462
- (0, import_spl_token3.createAssociatedTokenAccountInstruction)(
2550
+ (0, import_spl_token3.createAssociatedTokenAccountIdempotentInstruction)(
2463
2551
  payerPubkey,
2464
- wsolAta,
2552
+ inputTokenAccount,
2465
2553
  payerPubkey,
2466
- import_spl_token3.NATIVE_MINT,
2467
- import_spl_token3.TOKEN_PROGRAM_ID
2554
+ inputMint,
2555
+ inputTokenProgram
2468
2556
  )
2469
2557
  );
2470
- instructions.push((0, import_spl_token3.createSyncNativeInstruction)(wsolAta));
2558
+ if (isInputWsol) {
2559
+ instructions.push(
2560
+ import_web35.SystemProgram.transfer({
2561
+ fromPubkey: payerPubkey,
2562
+ toPubkey: inputTokenAccount,
2563
+ lamports: inputAmount
2564
+ })
2565
+ );
2566
+ instructions.push((0, import_spl_token3.createSyncNativeInstruction)(inputTokenAccount));
2567
+ }
2471
2568
  }
2472
2569
  if (createOutputMintAta) {
2473
2570
  instructions.push(
2474
- (0, import_spl_token3.createAssociatedTokenAccountInstruction)(
2571
+ (0, import_spl_token3.createAssociatedTokenAccountIdempotentInstruction)(
2475
2572
  payerPubkey,
2476
2573
  outputTokenAccount,
2477
2574
  payerPubkey,
2478
2575
  outputMint,
2479
- mintTokenProgram
2576
+ outputTokenProgram
2480
2577
  )
2481
2578
  );
2482
2579
  }
2483
2580
  const data = Buffer.alloc(24);
2484
- RAYDIUM_CPMM_SWAP_BASE_IN_DISCRIMINATOR.copy(data, 0);
2581
+ (fixedOutputAmount !== void 0 ? RAYDIUM_CPMM_SWAP_BASE_OUT_DISCRIMINATOR : RAYDIUM_CPMM_SWAP_BASE_IN_DISCRIMINATOR).copy(data, 0);
2485
2582
  data.writeBigUInt64LE(inputAmount, 8);
2486
- data.writeBigUInt64LE(minimumAmountOut, 16);
2583
+ data.writeBigUInt64LE(fixedOutputAmount ?? minimumAmountOut, 16);
2487
2584
  const accounts = [
2488
2585
  { pubkey: payerPubkey, isSigner: true, isWritable: true },
2489
2586
  { pubkey: RAYDIUM_CPMM_AUTHORITY, isSigner: false, isWritable: false },
@@ -2493,8 +2590,8 @@ function buildRaydiumCpmmBuyInstructions(params) {
2493
2590
  { pubkey: outputTokenAccount, isSigner: false, isWritable: true },
2494
2591
  { pubkey: inputVaultAccount, isSigner: false, isWritable: true },
2495
2592
  { pubkey: outputVaultAccount, isSigner: false, isWritable: true },
2496
- { pubkey: import_spl_token3.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
2497
- { pubkey: mintTokenProgram, isSigner: false, isWritable: false },
2593
+ { pubkey: inputTokenProgram, isSigner: false, isWritable: false },
2594
+ { pubkey: outputTokenProgram, isSigner: false, isWritable: false },
2498
2595
  { pubkey: inputMint, isSigner: false, isWritable: false },
2499
2596
  { pubkey: outputMint, isSigner: false, isWritable: false },
2500
2597
  { pubkey: observationStateAccount, isSigner: false, isWritable: true }
@@ -2506,10 +2603,9 @@ function buildRaydiumCpmmBuyInstructions(params) {
2506
2603
  data
2507
2604
  })
2508
2605
  );
2509
- if (closeInputMintAta && isWsol) {
2510
- const wsolAta = (0, import_spl_token3.getAssociatedTokenAddressSync)(import_spl_token3.NATIVE_MINT, payerPubkey, true);
2606
+ if (closeInputMintAta && inputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
2511
2607
  instructions.push(
2512
- (0, import_spl_token3.createCloseAccountInstruction)(wsolAta, payerPubkey, payerPubkey, [], import_spl_token3.TOKEN_PROGRAM_ID)
2608
+ (0, import_spl_token3.createCloseAccountInstruction)(inputTokenAccount, payerPubkey, payerPubkey, [], inputTokenProgram)
2513
2609
  );
2514
2610
  }
2515
2611
  return instructions;
@@ -2551,28 +2647,32 @@ function buildRaydiumCpmmSellInstructions(params) {
2551
2647
  throw new Error("Pool must contain WSOL or USDC");
2552
2648
  }
2553
2649
  const isQuoteOut = quoteMint.equals(WSOL_TOKEN_ACCOUNT2) || quoteMint.equals(USDC_TOKEN_ACCOUNT2);
2554
- const mintTokenProgram = isQuoteOut ? baseTokenProgram : quoteTokenProgram;
2650
+ const expectedInputMint = isQuoteOut ? baseMint : quoteMint;
2651
+ const inputTokenProgram = isQuoteOut ? baseTokenProgram : quoteTokenProgram;
2652
+ const outputMint = isQuoteOut ? quoteMint : baseMint;
2653
+ const outputTokenProgram = isQuoteOut ? quoteTokenProgram : baseTokenProgram;
2654
+ if (!inputMint.equals(expectedInputMint)) {
2655
+ throw new Error(`inputMint must match Raydium CPMM pool side ${expectedInputMint.toBase58()}`);
2656
+ }
2555
2657
  const poolState = protocolParams.poolState && !protocolParams.poolState.equals(import_web35.PublicKey.default) ? protocolParams.poolState : getRaydiumCpmmPoolPda(ammConfig, baseMint, quoteMint);
2556
- const swapResult = computeRaydiumCpmmSwapAmount(
2658
+ const minimumAmountOut = fixedOutputAmount ?? computeRaydiumCpmmSwapAmount(
2557
2659
  baseReserve,
2558
2660
  quoteReserve,
2559
2661
  isQuoteOut,
2560
2662
  inputAmount,
2561
2663
  slippageBasisPoints
2562
- );
2563
- const minimumAmountOut = fixedOutputAmount || swapResult.minAmountOut;
2564
- const outputMint = isWsol ? WSOL_TOKEN_ACCOUNT2 : USDC_TOKEN_ACCOUNT2;
2664
+ ).minAmountOut;
2565
2665
  const inputTokenAccount = (0, import_spl_token3.getAssociatedTokenAddressSync)(
2566
2666
  inputMint,
2567
2667
  payerPubkey,
2568
2668
  true,
2569
- mintTokenProgram
2669
+ inputTokenProgram
2570
2670
  );
2571
2671
  const outputTokenAccount = (0, import_spl_token3.getAssociatedTokenAddressSync)(
2572
2672
  outputMint,
2573
2673
  payerPubkey,
2574
2674
  true,
2575
- import_spl_token3.TOKEN_PROGRAM_ID
2675
+ outputTokenProgram
2576
2676
  );
2577
2677
  const inputVaultAccount = (() => {
2578
2678
  if (baseMint.equals(inputMint) && baseVault && !baseVault.equals(import_web35.PublicKey.default)) {
@@ -2584,31 +2684,30 @@ function buildRaydiumCpmmSellInstructions(params) {
2584
2684
  return getRaydiumCpmmVaultPda(poolState, inputMint);
2585
2685
  })();
2586
2686
  const outputVaultAccount = (() => {
2587
- if (isWsol && baseMint.equals(outputMint) && baseVault && !baseVault.equals(import_web35.PublicKey.default)) {
2687
+ if (baseMint.equals(outputMint) && baseVault && !baseVault.equals(import_web35.PublicKey.default)) {
2588
2688
  return baseVault;
2589
2689
  }
2590
- if (!isWsol && quoteMint.equals(outputMint) && quoteVault && !quoteVault.equals(import_web35.PublicKey.default)) {
2690
+ if (quoteMint.equals(outputMint) && quoteVault && !quoteVault.equals(import_web35.PublicKey.default)) {
2591
2691
  return quoteVault;
2592
2692
  }
2593
2693
  return getRaydiumCpmmVaultPda(poolState, outputMint);
2594
2694
  })();
2595
2695
  const observationStateAccount = observationState && !observationState.equals(import_web35.PublicKey.default) ? observationState : getRaydiumCpmmObservationStatePda(poolState);
2596
- if (createOutputMintAta && isWsol) {
2597
- const wsolAta = (0, import_spl_token3.getAssociatedTokenAddressSync)(import_spl_token3.NATIVE_MINT, payerPubkey, true);
2696
+ if (createOutputMintAta) {
2598
2697
  instructions.push(
2599
- (0, import_spl_token3.createAssociatedTokenAccountInstruction)(
2698
+ (0, import_spl_token3.createAssociatedTokenAccountIdempotentInstruction)(
2600
2699
  payerPubkey,
2601
- wsolAta,
2700
+ outputTokenAccount,
2602
2701
  payerPubkey,
2603
- import_spl_token3.NATIVE_MINT,
2604
- import_spl_token3.TOKEN_PROGRAM_ID
2702
+ outputMint,
2703
+ outputTokenProgram
2605
2704
  )
2606
2705
  );
2607
2706
  }
2608
2707
  const data = Buffer.alloc(24);
2609
- RAYDIUM_CPMM_SWAP_BASE_IN_DISCRIMINATOR.copy(data, 0);
2708
+ (fixedOutputAmount !== void 0 ? RAYDIUM_CPMM_SWAP_BASE_OUT_DISCRIMINATOR : RAYDIUM_CPMM_SWAP_BASE_IN_DISCRIMINATOR).copy(data, 0);
2610
2709
  data.writeBigUInt64LE(inputAmount, 8);
2611
- data.writeBigUInt64LE(minimumAmountOut, 16);
2710
+ data.writeBigUInt64LE(fixedOutputAmount ?? minimumAmountOut, 16);
2612
2711
  const accounts = [
2613
2712
  { pubkey: payerPubkey, isSigner: true, isWritable: true },
2614
2713
  { pubkey: RAYDIUM_CPMM_AUTHORITY, isSigner: false, isWritable: false },
@@ -2618,8 +2717,8 @@ function buildRaydiumCpmmSellInstructions(params) {
2618
2717
  { pubkey: outputTokenAccount, isSigner: false, isWritable: true },
2619
2718
  { pubkey: inputVaultAccount, isSigner: false, isWritable: true },
2620
2719
  { pubkey: outputVaultAccount, isSigner: false, isWritable: true },
2621
- { pubkey: mintTokenProgram, isSigner: false, isWritable: false },
2622
- { pubkey: import_spl_token3.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
2720
+ { pubkey: inputTokenProgram, isSigner: false, isWritable: false },
2721
+ { pubkey: outputTokenProgram, isSigner: false, isWritable: false },
2623
2722
  { pubkey: inputMint, isSigner: false, isWritable: false },
2624
2723
  { pubkey: outputMint, isSigner: false, isWritable: false },
2625
2724
  { pubkey: observationStateAccount, isSigner: false, isWritable: true }
@@ -2631,10 +2730,9 @@ function buildRaydiumCpmmSellInstructions(params) {
2631
2730
  data
2632
2731
  })
2633
2732
  );
2634
- if (closeOutputMintAta && isWsol) {
2635
- const wsolAta = (0, import_spl_token3.getAssociatedTokenAddressSync)(import_spl_token3.NATIVE_MINT, payerPubkey, true);
2733
+ if (closeOutputMintAta && outputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
2636
2734
  instructions.push(
2637
- (0, import_spl_token3.createCloseAccountInstruction)(wsolAta, payerPubkey, payerPubkey, [], import_spl_token3.TOKEN_PROGRAM_ID)
2735
+ (0, import_spl_token3.createCloseAccountInstruction)(outputTokenAccount, payerPubkey, payerPubkey, [], outputTokenProgram)
2638
2736
  );
2639
2737
  }
2640
2738
  if (closeInputMintAta) {
@@ -2644,7 +2742,7 @@ function buildRaydiumCpmmSellInstructions(params) {
2644
2742
  payerPubkey,
2645
2743
  payerPubkey,
2646
2744
  [],
2647
- mintTokenProgram
2745
+ inputTokenProgram
2648
2746
  )
2649
2747
  );
2650
2748
  }
@@ -2829,10 +2927,44 @@ function computeRaydiumAmmV4SwapAmount(coinReserve, pcReserve, isCoinIn, amountI
2829
2927
  const minAmountOut = amountOut - amountOut * slippageBasisPoints / BigInt(1e4);
2830
2928
  return { amountOut, minAmountOut };
2831
2929
  }
2930
+ function isDefaultPublicKey(pubkey) {
2931
+ return pubkey.equals(import_web36.PublicKey.default);
2932
+ }
2933
+ function isMintMatch(requested, expected) {
2934
+ return requested.equals(expected) || expected.equals(import_spl_token4.NATIVE_MINT) && requested.equals(SOL_TOKEN_ACCOUNT3);
2935
+ }
2936
+ function ensureExpectedMint(label, requested, expected) {
2937
+ if (!isDefaultPublicKey(requested) && !isMintMatch(requested, expected)) {
2938
+ throw new Error(
2939
+ `${label} must match the Raydium AMM v4 pool side (${expected.toBase58()}), got ${requested.toBase58()}`
2940
+ );
2941
+ }
2942
+ }
2943
+ function ensureMarketAccounts(params) {
2944
+ const required = [
2945
+ ["ammOpenOrders", params.ammOpenOrders],
2946
+ ["ammTargetOrders", params.ammTargetOrders],
2947
+ ["serumProgram", params.serumProgram],
2948
+ ["serumMarket", params.serumMarket],
2949
+ ["serumBids", params.serumBids],
2950
+ ["serumAsks", params.serumAsks],
2951
+ ["serumEventQueue", params.serumEventQueue],
2952
+ ["serumCoinVaultAccount", params.serumCoinVaultAccount],
2953
+ ["serumPcVaultAccount", params.serumPcVaultAccount],
2954
+ ["serumVaultSigner", params.serumVaultSigner]
2955
+ ];
2956
+ for (const [name, account] of required) {
2957
+ if (isDefaultPublicKey(account)) {
2958
+ throw new Error(
2959
+ `Raydium AMM v4 requires ${name}; pass real market accounts from the AMM/market state`
2960
+ );
2961
+ }
2962
+ }
2963
+ }
2832
2964
  function buildRaydiumAmmV4BuyInstructions(params) {
2833
2965
  const {
2834
2966
  payer,
2835
- outputMint,
2967
+ outputMint: requestedOutputMint,
2836
2968
  inputAmount,
2837
2969
  slippageBasisPoints = BigInt(1e3),
2838
2970
  fixedOutputAmount,
@@ -2854,9 +2986,20 @@ function buildRaydiumAmmV4BuyInstructions(params) {
2854
2986
  pcMint,
2855
2987
  tokenCoin,
2856
2988
  tokenPc,
2989
+ ammOpenOrders,
2990
+ ammTargetOrders,
2991
+ serumProgram,
2992
+ serumMarket,
2993
+ serumBids,
2994
+ serumAsks,
2995
+ serumEventQueue,
2996
+ serumCoinVaultAccount,
2997
+ serumPcVaultAccount,
2998
+ serumVaultSigner,
2857
2999
  coinReserve,
2858
3000
  pcReserve
2859
3001
  } = protocolParams;
3002
+ ensureMarketAccounts(protocolParams);
2860
3003
  const isWsol = coinMint.equals(WSOL_TOKEN_ACCOUNT2) || pcMint.equals(WSOL_TOKEN_ACCOUNT2);
2861
3004
  const isUsdc = coinMint.equals(USDC_TOKEN_ACCOUNT2) || pcMint.equals(USDC_TOKEN_ACCOUNT2);
2862
3005
  if (!isWsol && !isUsdc) {
@@ -2870,8 +3013,10 @@ function buildRaydiumAmmV4BuyInstructions(params) {
2870
3013
  inputAmount,
2871
3014
  slippageBasisPoints
2872
3015
  );
2873
- const minimumAmountOut = fixedOutputAmount || swapResult.minAmountOut;
2874
- const inputMint = isWsol ? WSOL_TOKEN_ACCOUNT2 : USDC_TOKEN_ACCOUNT2;
3016
+ const minimumAmountOut = fixedOutputAmount ?? swapResult.minAmountOut;
3017
+ const inputMint = isBaseIn ? coinMint : pcMint;
3018
+ const outputMint = isBaseIn ? pcMint : coinMint;
3019
+ ensureExpectedMint("outputMint", requestedOutputMint, outputMint);
2875
3020
  const userSourceTokenAccount = (0, import_spl_token4.getAssociatedTokenAddressSync)(
2876
3021
  inputMint,
2877
3022
  payerPubkey,
@@ -2884,7 +3029,7 @@ function buildRaydiumAmmV4BuyInstructions(params) {
2884
3029
  true,
2885
3030
  import_spl_token4.TOKEN_PROGRAM_ID
2886
3031
  );
2887
- if (createInputMintAta && isWsol) {
3032
+ if (createInputMintAta && inputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
2888
3033
  const wsolAta = (0, import_spl_token4.getAssociatedTokenAddressSync)(import_spl_token4.NATIVE_MINT, payerPubkey, true);
2889
3034
  instructions.push(
2890
3035
  (0, import_spl_token4.createAssociatedTokenAccountInstruction)(
@@ -2895,7 +3040,24 @@ function buildRaydiumAmmV4BuyInstructions(params) {
2895
3040
  import_spl_token4.TOKEN_PROGRAM_ID
2896
3041
  )
2897
3042
  );
3043
+ instructions.push(
3044
+ import_web36.SystemProgram.transfer({
3045
+ fromPubkey: payerPubkey,
3046
+ toPubkey: wsolAta,
3047
+ lamports: Number(inputAmount)
3048
+ })
3049
+ );
2898
3050
  instructions.push((0, import_spl_token4.createSyncNativeInstruction)(wsolAta));
3051
+ } else if (createInputMintAta) {
3052
+ instructions.push(
3053
+ (0, import_spl_token4.createAssociatedTokenAccountInstruction)(
3054
+ payerPubkey,
3055
+ userSourceTokenAccount,
3056
+ payerPubkey,
3057
+ inputMint,
3058
+ import_spl_token4.TOKEN_PROGRAM_ID
3059
+ )
3060
+ );
2899
3061
  }
2900
3062
  if (createOutputMintAta) {
2901
3063
  instructions.push(
@@ -2909,38 +3071,30 @@ function buildRaydiumAmmV4BuyInstructions(params) {
2909
3071
  );
2910
3072
  }
2911
3073
  const data = Buffer.alloc(17);
2912
- RAYDIUM_AMM_V4_SWAP_BASE_IN_DISCRIMINATOR.copy(data, 0);
3074
+ (fixedOutputAmount !== void 0 ? RAYDIUM_AMM_V4_SWAP_BASE_OUT_DISCRIMINATOR : RAYDIUM_AMM_V4_SWAP_BASE_IN_DISCRIMINATOR).copy(data, 0);
2913
3075
  data.writeBigUInt64LE(inputAmount, 1);
2914
3076
  data.writeBigUInt64LE(minimumAmountOut, 9);
2915
3077
  const accounts = [
2916
3078
  { pubkey: import_spl_token4.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
2917
3079
  { pubkey: amm, isSigner: false, isWritable: true },
2918
3080
  { pubkey: RAYDIUM_AMM_V4_AUTHORITY, isSigner: false, isWritable: false },
2919
- { pubkey: amm, isSigner: false, isWritable: true },
2920
- // Amm Open Orders (same as amm for simplicity)
3081
+ { pubkey: ammOpenOrders, isSigner: false, isWritable: true },
3082
+ { pubkey: ammTargetOrders, isSigner: false, isWritable: true },
2921
3083
  { pubkey: tokenCoin, isSigner: false, isWritable: true },
2922
3084
  // Pool Coin Token Account
2923
3085
  { pubkey: tokenPc, isSigner: false, isWritable: true },
2924
3086
  // Pool Pc Token Account
2925
- { pubkey: amm, isSigner: false, isWritable: false },
2926
- // Serum Program (placeholder)
2927
- { pubkey: amm, isSigner: false, isWritable: false },
2928
- // Serum Market (placeholder)
2929
- { pubkey: amm, isSigner: false, isWritable: false },
2930
- // Serum Bids (placeholder)
2931
- { pubkey: amm, isSigner: false, isWritable: false },
2932
- // Serum Asks (placeholder)
2933
- { pubkey: amm, isSigner: false, isWritable: false },
2934
- // Serum Event Queue (placeholder)
2935
- { pubkey: amm, isSigner: false, isWritable: false },
2936
- // Serum Coin Vault Account (placeholder)
2937
- { pubkey: amm, isSigner: false, isWritable: false },
2938
- // Serum Pc Vault Account (placeholder)
2939
- { pubkey: amm, isSigner: false, isWritable: false },
2940
- // Serum Vault Signer (placeholder)
3087
+ { pubkey: serumProgram, isSigner: false, isWritable: false },
3088
+ { pubkey: serumMarket, isSigner: false, isWritable: true },
3089
+ { pubkey: serumBids, isSigner: false, isWritable: true },
3090
+ { pubkey: serumAsks, isSigner: false, isWritable: true },
3091
+ { pubkey: serumEventQueue, isSigner: false, isWritable: true },
3092
+ { pubkey: serumCoinVaultAccount, isSigner: false, isWritable: true },
3093
+ { pubkey: serumPcVaultAccount, isSigner: false, isWritable: true },
3094
+ { pubkey: serumVaultSigner, isSigner: false, isWritable: false },
2941
3095
  { pubkey: userSourceTokenAccount, isSigner: false, isWritable: true },
2942
3096
  { pubkey: userDestinationTokenAccount, isSigner: false, isWritable: true },
2943
- { pubkey: payerPubkey, isSigner: true, isWritable: true }
3097
+ { pubkey: payerPubkey, isSigner: true, isWritable: false }
2944
3098
  ];
2945
3099
  instructions.push(
2946
3100
  new import_web36.TransactionInstruction({
@@ -2949,7 +3103,7 @@ function buildRaydiumAmmV4BuyInstructions(params) {
2949
3103
  data
2950
3104
  })
2951
3105
  );
2952
- if (closeInputMintAta && isWsol) {
3106
+ if (closeInputMintAta && inputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
2953
3107
  const wsolAta = (0, import_spl_token4.getAssociatedTokenAddressSync)(import_spl_token4.NATIVE_MINT, payerPubkey, true);
2954
3108
  instructions.push(
2955
3109
  (0, import_spl_token4.createCloseAccountInstruction)(wsolAta, payerPubkey, payerPubkey, [], import_spl_token4.TOKEN_PROGRAM_ID)
@@ -2960,7 +3114,8 @@ function buildRaydiumAmmV4BuyInstructions(params) {
2960
3114
  function buildRaydiumAmmV4SellInstructions(params) {
2961
3115
  const {
2962
3116
  payer,
2963
- inputMint,
3117
+ inputMint: requestedInputMint,
3118
+ outputMint: requestedOutputMint,
2964
3119
  inputAmount,
2965
3120
  slippageBasisPoints = BigInt(1e3),
2966
3121
  fixedOutputAmount,
@@ -2982,9 +3137,20 @@ function buildRaydiumAmmV4SellInstructions(params) {
2982
3137
  pcMint,
2983
3138
  tokenCoin,
2984
3139
  tokenPc,
3140
+ ammOpenOrders,
3141
+ ammTargetOrders,
3142
+ serumProgram,
3143
+ serumMarket,
3144
+ serumBids,
3145
+ serumAsks,
3146
+ serumEventQueue,
3147
+ serumCoinVaultAccount,
3148
+ serumPcVaultAccount,
3149
+ serumVaultSigner,
2985
3150
  coinReserve,
2986
3151
  pcReserve
2987
3152
  } = protocolParams;
3153
+ ensureMarketAccounts(protocolParams);
2988
3154
  const isWsol = coinMint.equals(WSOL_TOKEN_ACCOUNT2) || pcMint.equals(WSOL_TOKEN_ACCOUNT2);
2989
3155
  const isUsdc = coinMint.equals(USDC_TOKEN_ACCOUNT2) || pcMint.equals(USDC_TOKEN_ACCOUNT2);
2990
3156
  if (!isWsol && !isUsdc) {
@@ -2998,8 +3164,13 @@ function buildRaydiumAmmV4SellInstructions(params) {
2998
3164
  inputAmount,
2999
3165
  slippageBasisPoints
3000
3166
  );
3001
- const minimumAmountOut = fixedOutputAmount || swapResult.minAmountOut;
3002
- const outputMint = isWsol ? WSOL_TOKEN_ACCOUNT2 : USDC_TOKEN_ACCOUNT2;
3167
+ const minimumAmountOut = fixedOutputAmount ?? swapResult.minAmountOut;
3168
+ const outputMint = isBaseIn ? pcMint : coinMint;
3169
+ const inputMint = isBaseIn ? coinMint : pcMint;
3170
+ ensureExpectedMint("inputMint", requestedInputMint, inputMint);
3171
+ if (requestedOutputMint) {
3172
+ ensureExpectedMint("outputMint", requestedOutputMint, outputMint);
3173
+ }
3003
3174
  const userSourceTokenAccount = (0, import_spl_token4.getAssociatedTokenAddressSync)(
3004
3175
  inputMint,
3005
3176
  payerPubkey,
@@ -3012,7 +3183,7 @@ function buildRaydiumAmmV4SellInstructions(params) {
3012
3183
  true,
3013
3184
  import_spl_token4.TOKEN_PROGRAM_ID
3014
3185
  );
3015
- if (createOutputMintAta && isWsol) {
3186
+ if (createOutputMintAta && outputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
3016
3187
  const wsolAta = (0, import_spl_token4.getAssociatedTokenAddressSync)(import_spl_token4.NATIVE_MINT, payerPubkey, true);
3017
3188
  instructions.push(
3018
3189
  (0, import_spl_token4.createAssociatedTokenAccountInstruction)(
@@ -3023,40 +3194,42 @@ function buildRaydiumAmmV4SellInstructions(params) {
3023
3194
  import_spl_token4.TOKEN_PROGRAM_ID
3024
3195
  )
3025
3196
  );
3197
+ } else if (createOutputMintAta) {
3198
+ instructions.push(
3199
+ (0, import_spl_token4.createAssociatedTokenAccountInstruction)(
3200
+ payerPubkey,
3201
+ userDestinationTokenAccount,
3202
+ payerPubkey,
3203
+ outputMint,
3204
+ import_spl_token4.TOKEN_PROGRAM_ID
3205
+ )
3206
+ );
3026
3207
  }
3027
3208
  const data = Buffer.alloc(17);
3028
- RAYDIUM_AMM_V4_SWAP_BASE_IN_DISCRIMINATOR.copy(data, 0);
3209
+ (fixedOutputAmount !== void 0 ? RAYDIUM_AMM_V4_SWAP_BASE_OUT_DISCRIMINATOR : RAYDIUM_AMM_V4_SWAP_BASE_IN_DISCRIMINATOR).copy(data, 0);
3029
3210
  data.writeBigUInt64LE(inputAmount, 1);
3030
3211
  data.writeBigUInt64LE(minimumAmountOut, 9);
3031
3212
  const accounts = [
3032
3213
  { pubkey: import_spl_token4.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
3033
3214
  { pubkey: amm, isSigner: false, isWritable: true },
3034
3215
  { pubkey: RAYDIUM_AMM_V4_AUTHORITY, isSigner: false, isWritable: false },
3035
- { pubkey: amm, isSigner: false, isWritable: true },
3036
- // Amm Open Orders
3216
+ { pubkey: ammOpenOrders, isSigner: false, isWritable: true },
3217
+ { pubkey: ammTargetOrders, isSigner: false, isWritable: true },
3037
3218
  { pubkey: tokenCoin, isSigner: false, isWritable: true },
3038
3219
  // Pool Coin Token Account
3039
3220
  { pubkey: tokenPc, isSigner: false, isWritable: true },
3040
3221
  // Pool Pc Token Account
3041
- { pubkey: amm, isSigner: false, isWritable: false },
3042
- // Serum Program
3043
- { pubkey: amm, isSigner: false, isWritable: false },
3044
- // Serum Market
3045
- { pubkey: amm, isSigner: false, isWritable: false },
3046
- // Serum Bids
3047
- { pubkey: amm, isSigner: false, isWritable: false },
3048
- // Serum Asks
3049
- { pubkey: amm, isSigner: false, isWritable: false },
3050
- // Serum Event Queue
3051
- { pubkey: amm, isSigner: false, isWritable: false },
3052
- // Serum Coin Vault Account
3053
- { pubkey: amm, isSigner: false, isWritable: false },
3054
- // Serum Pc Vault Account
3055
- { pubkey: amm, isSigner: false, isWritable: false },
3056
- // Serum Vault Signer
3222
+ { pubkey: serumProgram, isSigner: false, isWritable: false },
3223
+ { pubkey: serumMarket, isSigner: false, isWritable: true },
3224
+ { pubkey: serumBids, isSigner: false, isWritable: true },
3225
+ { pubkey: serumAsks, isSigner: false, isWritable: true },
3226
+ { pubkey: serumEventQueue, isSigner: false, isWritable: true },
3227
+ { pubkey: serumCoinVaultAccount, isSigner: false, isWritable: true },
3228
+ { pubkey: serumPcVaultAccount, isSigner: false, isWritable: true },
3229
+ { pubkey: serumVaultSigner, isSigner: false, isWritable: false },
3057
3230
  { pubkey: userSourceTokenAccount, isSigner: false, isWritable: true },
3058
3231
  { pubkey: userDestinationTokenAccount, isSigner: false, isWritable: true },
3059
- { pubkey: payerPubkey, isSigner: true, isWritable: true }
3232
+ { pubkey: payerPubkey, isSigner: true, isWritable: false }
3060
3233
  ];
3061
3234
  instructions.push(
3062
3235
  new import_web36.TransactionInstruction({
@@ -3065,7 +3238,7 @@ function buildRaydiumAmmV4SellInstructions(params) {
3065
3238
  data
3066
3239
  })
3067
3240
  );
3068
- if (closeOutputMintAta && isWsol) {
3241
+ if (closeOutputMintAta && outputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
3069
3242
  const wsolAta = (0, import_spl_token4.getAssociatedTokenAddressSync)(import_spl_token4.NATIVE_MINT, payerPubkey, true);
3070
3243
  instructions.push(
3071
3244
  (0, import_spl_token4.createCloseAccountInstruction)(wsolAta, payerPubkey, payerPubkey, [], import_spl_token4.TOKEN_PROGRAM_ID)
@@ -3201,6 +3374,65 @@ function decodeAmmInfo(data) {
3201
3374
  return null;
3202
3375
  }
3203
3376
  }
3377
+ function decodeMarketState(data) {
3378
+ if (data.length < MARKET_STATE_SIZE) {
3379
+ return null;
3380
+ }
3381
+ try {
3382
+ let offset = 5;
3383
+ const readU64 = () => {
3384
+ const val = data.readBigUInt64LE(offset);
3385
+ offset += 8;
3386
+ return val;
3387
+ };
3388
+ const readPubkey = () => {
3389
+ const val = new import_web36.PublicKey(data.subarray(offset, offset + 32));
3390
+ offset += 32;
3391
+ return val;
3392
+ };
3393
+ readU64();
3394
+ readPubkey();
3395
+ const vaultSignerNonce = readU64();
3396
+ readPubkey();
3397
+ readPubkey();
3398
+ const serumCoinVaultAccount = readPubkey();
3399
+ readU64();
3400
+ readU64();
3401
+ const serumPcVaultAccount = readPubkey();
3402
+ readU64();
3403
+ readU64();
3404
+ readU64();
3405
+ readPubkey();
3406
+ const serumEventQueue = readPubkey();
3407
+ const serumBids = readPubkey();
3408
+ const serumAsks = readPubkey();
3409
+ return {
3410
+ vaultSignerNonce,
3411
+ serumCoinVaultAccount,
3412
+ serumPcVaultAccount,
3413
+ serumEventQueue,
3414
+ serumBids,
3415
+ serumAsks
3416
+ };
3417
+ } catch {
3418
+ return null;
3419
+ }
3420
+ }
3421
+ function deriveSerumVaultSigner(serumProgram, serumMarket, vaultSignerNonce) {
3422
+ const nonce = Buffer.alloc(8);
3423
+ nonce.writeBigUInt64LE(vaultSignerNonce);
3424
+ try {
3425
+ return import_web36.PublicKey.createProgramAddressSync(
3426
+ [serumMarket.toBuffer(), nonce],
3427
+ serumProgram
3428
+ );
3429
+ } catch {
3430
+ return import_web36.PublicKey.createProgramAddressSync(
3431
+ [serumMarket.toBuffer(), Buffer.from([Number(vaultSignerNonce & 0xffn)])],
3432
+ serumProgram
3433
+ );
3434
+ }
3435
+ }
3204
3436
  async function fetchAmmInfo(connection, amm) {
3205
3437
  const account = await connection.getAccountInfo(amm);
3206
3438
  if (!account?.value?.data) {
@@ -3208,12 +3440,20 @@ async function fetchAmmInfo(connection, amm) {
3208
3440
  }
3209
3441
  return decodeAmmInfo(account.value.data);
3210
3442
  }
3211
- var import_web36, import_spl_token4, RAYDIUM_AMM_V4_PROGRAM_ID, RAYDIUM_AMM_V4_AUTHORITY, RAYDIUM_AMM_V4_TRADE_FEE_NUMERATOR2, RAYDIUM_AMM_V4_TRADE_FEE_DENOMINATOR2, RAYDIUM_AMM_V4_SWAP_FEE_NUMERATOR2, RAYDIUM_AMM_V4_SWAP_FEE_DENOMINATOR2, RAYDIUM_AMM_V4_SWAP_BASE_IN_DISCRIMINATOR, RAYDIUM_AMM_V4_SWAP_BASE_OUT_DISCRIMINATOR, RAYDIUM_AMM_V4_POOL_SEED, AMM_INFO_SIZE;
3443
+ async function fetchMarketState(connection, market) {
3444
+ const account = await connection.getAccountInfo(market);
3445
+ if (!account?.value?.data) {
3446
+ return null;
3447
+ }
3448
+ return decodeMarketState(account.value.data);
3449
+ }
3450
+ var import_web36, import_spl_token4, SOL_TOKEN_ACCOUNT3, RAYDIUM_AMM_V4_PROGRAM_ID, RAYDIUM_AMM_V4_AUTHORITY, RAYDIUM_AMM_V4_TRADE_FEE_NUMERATOR2, RAYDIUM_AMM_V4_TRADE_FEE_DENOMINATOR2, RAYDIUM_AMM_V4_SWAP_FEE_NUMERATOR2, RAYDIUM_AMM_V4_SWAP_FEE_DENOMINATOR2, RAYDIUM_AMM_V4_SWAP_BASE_IN_DISCRIMINATOR, RAYDIUM_AMM_V4_SWAP_BASE_OUT_DISCRIMINATOR, RAYDIUM_AMM_V4_POOL_SEED, AMM_INFO_SIZE, MARKET_STATE_SIZE;
3212
3451
  var init_raydium_amm_v4_builder = __esm({
3213
3452
  "src/instruction/raydium_amm_v4_builder.ts"() {
3214
3453
  "use strict";
3215
3454
  import_web36 = require("@solana/web3.js");
3216
3455
  import_spl_token4 = require("@solana/spl-token");
3456
+ SOL_TOKEN_ACCOUNT3 = new import_web36.PublicKey("So11111111111111111111111111111111111111111");
3217
3457
  RAYDIUM_AMM_V4_PROGRAM_ID = new import_web36.PublicKey(
3218
3458
  "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"
3219
3459
  );
@@ -3228,6 +3468,7 @@ var init_raydium_amm_v4_builder = __esm({
3228
3468
  RAYDIUM_AMM_V4_SWAP_BASE_OUT_DISCRIMINATOR = Buffer.from([11]);
3229
3469
  RAYDIUM_AMM_V4_POOL_SEED = Buffer.from("pool");
3230
3470
  AMM_INFO_SIZE = 752;
3471
+ MARKET_STATE_SIZE = 388;
3231
3472
  }
3232
3473
  });
3233
3474
 
@@ -3239,11 +3480,24 @@ function getMeteoraDammV2EventAuthorityPda() {
3239
3480
  );
3240
3481
  return pda;
3241
3482
  }
3483
+ function isDefaultPublicKey2(pubkey) {
3484
+ return pubkey.equals(import_web37.PublicKey.default);
3485
+ }
3486
+ function isMintMatch2(requested, expected) {
3487
+ return requested.equals(expected) || expected.equals(import_spl_token5.NATIVE_MINT) && requested.equals(SOL_TOKEN_ACCOUNT4);
3488
+ }
3489
+ function ensureExpectedMint2(label, requested, expected) {
3490
+ if (!isDefaultPublicKey2(requested) && !isMintMatch2(requested, expected)) {
3491
+ throw new Error(
3492
+ `${label} must match the Meteora DAMM v2 pool side (${expected.toBase58()}), got ${requested.toBase58()}`
3493
+ );
3494
+ }
3495
+ }
3242
3496
  function buildMeteoraDammV2BuyInstructions(params) {
3243
3497
  const {
3244
3498
  payer,
3245
- inputMint,
3246
- outputMint,
3499
+ inputMint: requestedInputMint,
3500
+ outputMint: requestedOutputMint,
3247
3501
  inputAmount,
3248
3502
  fixedOutputAmount,
3249
3503
  createInputMintAta = true,
@@ -3276,6 +3530,10 @@ function buildMeteoraDammV2BuyInstructions(params) {
3276
3530
  throw new Error("Pool must contain WSOL or USDC");
3277
3531
  }
3278
3532
  const isAIn = tokenAMint.equals(WSOL_TOKEN_ACCOUNT2) || tokenAMint.equals(USDC_TOKEN_ACCOUNT2);
3533
+ const inputMint = isAIn ? tokenAMint : tokenBMint;
3534
+ const outputMint = isAIn ? tokenBMint : tokenAMint;
3535
+ ensureExpectedMint2("inputMint", requestedInputMint, inputMint);
3536
+ ensureExpectedMint2("outputMint", requestedOutputMint, outputMint);
3279
3537
  const inputTokenAccount = (0, import_spl_token5.getAssociatedTokenAddressSync)(
3280
3538
  inputMint,
3281
3539
  payerPubkey,
@@ -3289,7 +3547,9 @@ function buildMeteoraDammV2BuyInstructions(params) {
3289
3547
  isAIn ? tokenBProgram : tokenAProgram
3290
3548
  );
3291
3549
  const eventAuthority = getMeteoraDammV2EventAuthorityPda();
3292
- if (createInputMintAta && isWsol) {
3550
+ const inputTokenProgram = isAIn ? tokenAProgram : tokenBProgram;
3551
+ const outputTokenProgram = isAIn ? tokenBProgram : tokenAProgram;
3552
+ if (createInputMintAta && inputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
3293
3553
  const wsolAta = (0, import_spl_token5.getAssociatedTokenAddressSync)(import_spl_token5.NATIVE_MINT, payerPubkey, true);
3294
3554
  instructions.push(
3295
3555
  (0, import_spl_token5.createAssociatedTokenAccountInstruction)(
@@ -3300,7 +3560,24 @@ function buildMeteoraDammV2BuyInstructions(params) {
3300
3560
  import_spl_token5.TOKEN_PROGRAM_ID
3301
3561
  )
3302
3562
  );
3563
+ instructions.push(
3564
+ import_web37.SystemProgram.transfer({
3565
+ fromPubkey: payerPubkey,
3566
+ toPubkey: wsolAta,
3567
+ lamports: Number(inputAmount)
3568
+ })
3569
+ );
3303
3570
  instructions.push((0, import_spl_token5.createSyncNativeInstruction)(wsolAta));
3571
+ } else if (createInputMintAta) {
3572
+ instructions.push(
3573
+ (0, import_spl_token5.createAssociatedTokenAccountInstruction)(
3574
+ payerPubkey,
3575
+ inputTokenAccount,
3576
+ payerPubkey,
3577
+ inputMint,
3578
+ inputTokenProgram
3579
+ )
3580
+ );
3304
3581
  }
3305
3582
  if (createOutputMintAta) {
3306
3583
  instructions.push(
@@ -3309,14 +3586,15 @@ function buildMeteoraDammV2BuyInstructions(params) {
3309
3586
  outputTokenAccount,
3310
3587
  payerPubkey,
3311
3588
  outputMint,
3312
- import_spl_token5.TOKEN_PROGRAM_ID
3589
+ outputTokenProgram
3313
3590
  )
3314
3591
  );
3315
3592
  }
3316
- const data = Buffer.alloc(24);
3317
- METEORA_DAMM_V2_SWAP_DISCRIMINATOR.copy(data, 0);
3593
+ const data = Buffer.alloc(25);
3594
+ METEORA_DAMM_V2_SWAP2_DISCRIMINATOR.copy(data, 0);
3318
3595
  data.writeBigUInt64LE(inputAmount, 8);
3319
3596
  data.writeBigUInt64LE(fixedOutputAmount, 16);
3597
+ data.writeUInt8(METEORA_DAMM_V2_SWAP_MODE_PARTIAL_FILL, 24);
3320
3598
  const accounts = [
3321
3599
  { pubkey: METEORA_DAMM_V2_AUTHORITY, isSigner: false, isWritable: false },
3322
3600
  { pubkey: pool, isSigner: false, isWritable: true },
@@ -3329,8 +3607,6 @@ function buildMeteoraDammV2BuyInstructions(params) {
3329
3607
  { pubkey: payerPubkey, isSigner: true, isWritable: true },
3330
3608
  { pubkey: tokenAProgram, isSigner: false, isWritable: false },
3331
3609
  { pubkey: tokenBProgram, isSigner: false, isWritable: false },
3332
- { pubkey: METEORA_DAMM_V2_PROGRAM_ID, isSigner: false, isWritable: false },
3333
- // Referral Token Account (placeholder)
3334
3610
  { pubkey: eventAuthority, isSigner: false, isWritable: false },
3335
3611
  { pubkey: METEORA_DAMM_V2_PROGRAM_ID, isSigner: false, isWritable: false }
3336
3612
  ];
@@ -3341,7 +3617,7 @@ function buildMeteoraDammV2BuyInstructions(params) {
3341
3617
  data
3342
3618
  })
3343
3619
  );
3344
- if (closeInputMintAta && isWsol) {
3620
+ if (closeInputMintAta && inputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
3345
3621
  const wsolAta = (0, import_spl_token5.getAssociatedTokenAddressSync)(import_spl_token5.NATIVE_MINT, payerPubkey, true);
3346
3622
  instructions.push(
3347
3623
  (0, import_spl_token5.createCloseAccountInstruction)(wsolAta, payerPubkey, payerPubkey, [], import_spl_token5.TOKEN_PROGRAM_ID)
@@ -3352,8 +3628,8 @@ function buildMeteoraDammV2BuyInstructions(params) {
3352
3628
  function buildMeteoraDammV2SellInstructions(params) {
3353
3629
  const {
3354
3630
  payer,
3355
- inputMint,
3356
- outputMint,
3631
+ inputMint: requestedInputMint,
3632
+ outputMint: requestedOutputMint,
3357
3633
  inputAmount,
3358
3634
  fixedOutputAmount,
3359
3635
  createOutputMintAta = true,
@@ -3386,6 +3662,10 @@ function buildMeteoraDammV2SellInstructions(params) {
3386
3662
  throw new Error("Pool must contain WSOL or USDC");
3387
3663
  }
3388
3664
  const isAIn = tokenBMint.equals(WSOL_TOKEN_ACCOUNT2) || tokenBMint.equals(USDC_TOKEN_ACCOUNT2);
3665
+ const inputMint = isAIn ? tokenAMint : tokenBMint;
3666
+ const outputMint = isAIn ? tokenBMint : tokenAMint;
3667
+ ensureExpectedMint2("inputMint", requestedInputMint, inputMint);
3668
+ ensureExpectedMint2("outputMint", requestedOutputMint, outputMint);
3389
3669
  const inputTokenAccount = (0, import_spl_token5.getAssociatedTokenAddressSync)(
3390
3670
  inputMint,
3391
3671
  payerPubkey,
@@ -3399,7 +3679,9 @@ function buildMeteoraDammV2SellInstructions(params) {
3399
3679
  isAIn ? tokenBProgram : tokenAProgram
3400
3680
  );
3401
3681
  const eventAuthority = getMeteoraDammV2EventAuthorityPda();
3402
- if (createOutputMintAta && isWsol) {
3682
+ const inputTokenProgram = isAIn ? tokenAProgram : tokenBProgram;
3683
+ const outputTokenProgram = isAIn ? tokenBProgram : tokenAProgram;
3684
+ if (createOutputMintAta && outputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
3403
3685
  const wsolAta = (0, import_spl_token5.getAssociatedTokenAddressSync)(import_spl_token5.NATIVE_MINT, payerPubkey, true);
3404
3686
  instructions.push(
3405
3687
  (0, import_spl_token5.createAssociatedTokenAccountInstruction)(
@@ -3410,11 +3692,22 @@ function buildMeteoraDammV2SellInstructions(params) {
3410
3692
  import_spl_token5.TOKEN_PROGRAM_ID
3411
3693
  )
3412
3694
  );
3695
+ } else if (createOutputMintAta) {
3696
+ instructions.push(
3697
+ (0, import_spl_token5.createAssociatedTokenAccountInstruction)(
3698
+ payerPubkey,
3699
+ outputTokenAccount,
3700
+ payerPubkey,
3701
+ outputMint,
3702
+ outputTokenProgram
3703
+ )
3704
+ );
3413
3705
  }
3414
- const data = Buffer.alloc(24);
3415
- METEORA_DAMM_V2_SWAP_DISCRIMINATOR.copy(data, 0);
3706
+ const data = Buffer.alloc(25);
3707
+ METEORA_DAMM_V2_SWAP2_DISCRIMINATOR.copy(data, 0);
3416
3708
  data.writeBigUInt64LE(inputAmount, 8);
3417
3709
  data.writeBigUInt64LE(fixedOutputAmount, 16);
3710
+ data.writeUInt8(METEORA_DAMM_V2_SWAP_MODE_PARTIAL_FILL, 24);
3418
3711
  const accounts = [
3419
3712
  { pubkey: METEORA_DAMM_V2_AUTHORITY, isSigner: false, isWritable: false },
3420
3713
  { pubkey: pool, isSigner: false, isWritable: true },
@@ -3427,8 +3720,6 @@ function buildMeteoraDammV2SellInstructions(params) {
3427
3720
  { pubkey: payerPubkey, isSigner: true, isWritable: true },
3428
3721
  { pubkey: tokenAProgram, isSigner: false, isWritable: false },
3429
3722
  { pubkey: tokenBProgram, isSigner: false, isWritable: false },
3430
- { pubkey: METEORA_DAMM_V2_PROGRAM_ID, isSigner: false, isWritable: false },
3431
- // Referral Token Account
3432
3723
  { pubkey: eventAuthority, isSigner: false, isWritable: false },
3433
3724
  { pubkey: METEORA_DAMM_V2_PROGRAM_ID, isSigner: false, isWritable: false }
3434
3725
  ];
@@ -3439,7 +3730,7 @@ function buildMeteoraDammV2SellInstructions(params) {
3439
3730
  data
3440
3731
  })
3441
3732
  );
3442
- if (closeOutputMintAta && isWsol) {
3733
+ if (closeOutputMintAta && outputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
3443
3734
  const wsolAta = (0, import_spl_token5.getAssociatedTokenAddressSync)(import_spl_token5.NATIVE_MINT, payerPubkey, true);
3444
3735
  instructions.push(
3445
3736
  (0, import_spl_token5.createCloseAccountInstruction)(wsolAta, payerPubkey, payerPubkey, [], import_spl_token5.TOKEN_PROGRAM_ID)
@@ -3509,12 +3800,13 @@ async function fetchMeteoraPool(connection, poolAddress) {
3509
3800
  }
3510
3801
  return decodeMeteoraPool(account.value.data.slice(8));
3511
3802
  }
3512
- var import_web37, import_spl_token5, METEORA_DAMM_V2_PROGRAM_ID, METEORA_DAMM_V2_AUTHORITY, METEORA_DAMM_V2_SWAP_DISCRIMINATOR, METEORA_DAMM_V2_EVENT_AUTHORITY_SEED, METEORA_POOL_SIZE;
3803
+ var import_web37, import_spl_token5, SOL_TOKEN_ACCOUNT4, METEORA_DAMM_V2_PROGRAM_ID, METEORA_DAMM_V2_AUTHORITY, METEORA_DAMM_V2_SWAP_DISCRIMINATOR, METEORA_DAMM_V2_SWAP2_DISCRIMINATOR, METEORA_DAMM_V2_SWAP_MODE_PARTIAL_FILL, METEORA_DAMM_V2_EVENT_AUTHORITY_SEED, METEORA_POOL_SIZE;
3513
3804
  var init_meteora_damm_v2_builder = __esm({
3514
3805
  "src/instruction/meteora_damm_v2_builder.ts"() {
3515
3806
  "use strict";
3516
3807
  import_web37 = require("@solana/web3.js");
3517
3808
  import_spl_token5 = require("@solana/spl-token");
3809
+ SOL_TOKEN_ACCOUNT4 = new import_web37.PublicKey("So11111111111111111111111111111111111111111");
3518
3810
  METEORA_DAMM_V2_PROGRAM_ID = new import_web37.PublicKey(
3519
3811
  "cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG"
3520
3812
  );
@@ -3531,25 +3823,36 @@ var init_meteora_damm_v2_builder = __esm({
3531
3823
  135,
3532
3824
  200
3533
3825
  ]);
3826
+ METEORA_DAMM_V2_SWAP2_DISCRIMINATOR = Buffer.from([
3827
+ 65,
3828
+ 75,
3829
+ 63,
3830
+ 76,
3831
+ 235,
3832
+ 91,
3833
+ 91,
3834
+ 136
3835
+ ]);
3836
+ METEORA_DAMM_V2_SWAP_MODE_PARTIAL_FILL = 1;
3534
3837
  METEORA_DAMM_V2_EVENT_AUTHORITY_SEED = Buffer.from("__event_authority");
3535
3838
  METEORA_POOL_SIZE = 1104;
3536
3839
  }
3537
3840
  });
3538
3841
 
3539
3842
  // src/common/spl-token.ts
3540
- var import_web38, TOKEN_PROGRAM_ID6, TOKEN_2022_PROGRAM_ID2, ASSOCIATED_TOKEN_PROGRAM_ID, TokenInstructionBuilder, TokenUtil, WSOL_MINT2, NATIVE_MINT6, USDC_MINT2, USDT_MINT;
3843
+ var import_web38, TOKEN_PROGRAM_ID5, TOKEN_2022_PROGRAM_ID2, ASSOCIATED_TOKEN_PROGRAM_ID, TokenInstructionBuilder, TokenUtil, WSOL_MINT2, NATIVE_MINT5, USDC_MINT2, USDT_MINT;
3541
3844
  var init_spl_token = __esm({
3542
3845
  "src/common/spl-token.ts"() {
3543
3846
  "use strict";
3544
3847
  import_web38 = require("@solana/web3.js");
3545
- TOKEN_PROGRAM_ID6 = new import_web38.PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
3848
+ TOKEN_PROGRAM_ID5 = new import_web38.PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
3546
3849
  TOKEN_2022_PROGRAM_ID2 = new import_web38.PublicKey("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb");
3547
3850
  ASSOCIATED_TOKEN_PROGRAM_ID = new import_web38.PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
3548
3851
  TokenInstructionBuilder = class {
3549
3852
  /**
3550
3853
  * Create InitializeMint instruction
3551
3854
  */
3552
- static initializeMint(mint, decimals, mintAuthority, freezeAuthority, tokenProgram = TOKEN_PROGRAM_ID6) {
3855
+ static initializeMint(mint, decimals, mintAuthority, freezeAuthority, tokenProgram = TOKEN_PROGRAM_ID5) {
3553
3856
  const keys = [
3554
3857
  { pubkey: mint, isSigner: false, isWritable: true },
3555
3858
  { pubkey: import_web38.SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }
@@ -3572,7 +3875,7 @@ var init_spl_token = __esm({
3572
3875
  /**
3573
3876
  * Create InitializeAccount instruction
3574
3877
  */
3575
- static initializeAccount(account, mint, owner, tokenProgram = TOKEN_PROGRAM_ID6) {
3878
+ static initializeAccount(account, mint, owner, tokenProgram = TOKEN_PROGRAM_ID5) {
3576
3879
  const keys = [
3577
3880
  { pubkey: account, isSigner: false, isWritable: true },
3578
3881
  { pubkey: mint, isSigner: false, isWritable: false },
@@ -3589,7 +3892,7 @@ var init_spl_token = __esm({
3589
3892
  /**
3590
3893
  * Create Transfer instruction
3591
3894
  */
3592
- static transfer(source, destination, owner, amount, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID6) {
3895
+ static transfer(source, destination, owner, amount, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
3593
3896
  const keys = [
3594
3897
  { pubkey: source, isSigner: false, isWritable: true },
3595
3898
  { pubkey: destination, isSigner: false, isWritable: true },
@@ -3612,7 +3915,7 @@ var init_spl_token = __esm({
3612
3915
  /**
3613
3916
  * Create TransferChecked instruction
3614
3917
  */
3615
- static transferChecked(source, mint, destination, owner, amount, decimals, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID6) {
3918
+ static transferChecked(source, mint, destination, owner, amount, decimals, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
3616
3919
  const keys = [
3617
3920
  { pubkey: source, isSigner: false, isWritable: true },
3618
3921
  { pubkey: mint, isSigner: false, isWritable: false },
@@ -3637,7 +3940,7 @@ var init_spl_token = __esm({
3637
3940
  /**
3638
3941
  * Create MintTo instruction
3639
3942
  */
3640
- static mintTo(mint, destination, authority, amount, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID6) {
3943
+ static mintTo(mint, destination, authority, amount, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
3641
3944
  const keys = [
3642
3945
  { pubkey: mint, isSigner: false, isWritable: true },
3643
3946
  { pubkey: destination, isSigner: false, isWritable: true },
@@ -3660,7 +3963,7 @@ var init_spl_token = __esm({
3660
3963
  /**
3661
3964
  * Create Burn instruction
3662
3965
  */
3663
- static burn(account, mint, owner, amount, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID6) {
3966
+ static burn(account, mint, owner, amount, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
3664
3967
  const keys = [
3665
3968
  { pubkey: account, isSigner: false, isWritable: true },
3666
3969
  { pubkey: mint, isSigner: false, isWritable: true },
@@ -3683,7 +3986,7 @@ var init_spl_token = __esm({
3683
3986
  /**
3684
3987
  * Create Approve instruction
3685
3988
  */
3686
- static approve(account, delegate, owner, amount, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID6) {
3989
+ static approve(account, delegate, owner, amount, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
3687
3990
  const keys = [
3688
3991
  { pubkey: account, isSigner: false, isWritable: true },
3689
3992
  { pubkey: delegate, isSigner: false, isWritable: false },
@@ -3706,7 +4009,7 @@ var init_spl_token = __esm({
3706
4009
  /**
3707
4010
  * Create Revoke instruction
3708
4011
  */
3709
- static revoke(account, owner, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID6) {
4012
+ static revoke(account, owner, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
3710
4013
  const keys = [
3711
4014
  { pubkey: account, isSigner: false, isWritable: true },
3712
4015
  { pubkey: owner, isSigner: multiSigners.length === 0, isWritable: false },
@@ -3726,7 +4029,7 @@ var init_spl_token = __esm({
3726
4029
  /**
3727
4030
  * Create CloseAccount instruction
3728
4031
  */
3729
- static closeAccount(account, destination, owner, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID6) {
4032
+ static closeAccount(account, destination, owner, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
3730
4033
  const keys = [
3731
4034
  { pubkey: account, isSigner: false, isWritable: true },
3732
4035
  { pubkey: destination, isSigner: false, isWritable: true },
@@ -3747,7 +4050,7 @@ var init_spl_token = __esm({
3747
4050
  /**
3748
4051
  * Create SyncNative instruction (for WSOL accounts)
3749
4052
  */
3750
- static syncNative(nativeAccount, tokenProgram = TOKEN_PROGRAM_ID6) {
4053
+ static syncNative(nativeAccount, tokenProgram = TOKEN_PROGRAM_ID5) {
3751
4054
  const keys = [{ pubkey: nativeAccount, isSigner: false, isWritable: true }];
3752
4055
  const data = Buffer.from([17 /* SyncNative */]);
3753
4056
  return new import_web38.TransactionInstruction({
@@ -3761,7 +4064,7 @@ var init_spl_token = __esm({
3761
4064
  /**
3762
4065
  * Calculate associated token account address
3763
4066
  */
3764
- static async getAssociatedTokenAddress(mint, owner, _allowOwnerOffCurve = false, tokenProgram = TOKEN_PROGRAM_ID6, associatedTokenProgram = ASSOCIATED_TOKEN_PROGRAM_ID) {
4067
+ static async getAssociatedTokenAddress(mint, owner, _allowOwnerOffCurve = false, tokenProgram = TOKEN_PROGRAM_ID5, associatedTokenProgram = ASSOCIATED_TOKEN_PROGRAM_ID) {
3765
4068
  const [address] = await import_web38.PublicKey.findProgramAddress(
3766
4069
  [owner.toBuffer(), tokenProgram.toBuffer(), mint.toBuffer()],
3767
4070
  associatedTokenProgram
@@ -3771,7 +4074,7 @@ var init_spl_token = __esm({
3771
4074
  /**
3772
4075
  * Create associated token account idempotent instruction
3773
4076
  */
3774
- static createAssociatedTokenAccountIdempotentInstruction(payer, associatedToken, owner, mint, tokenProgram = TOKEN_PROGRAM_ID6, associatedTokenProgram = ASSOCIATED_TOKEN_PROGRAM_ID) {
4077
+ static createAssociatedTokenAccountIdempotentInstruction(payer, associatedToken, owner, mint, tokenProgram = TOKEN_PROGRAM_ID5, associatedTokenProgram = ASSOCIATED_TOKEN_PROGRAM_ID) {
3775
4078
  const keys = [
3776
4079
  { pubkey: payer, isSigner: true, isWritable: true },
3777
4080
  { pubkey: associatedToken, isSigner: false, isWritable: true },
@@ -3791,7 +4094,7 @@ var init_spl_token = __esm({
3791
4094
  /**
3792
4095
  * Create associated token account instruction
3793
4096
  */
3794
- static createAssociatedTokenAccountInstruction(payer, associatedToken, owner, mint, tokenProgram = TOKEN_PROGRAM_ID6, associatedTokenProgram = ASSOCIATED_TOKEN_PROGRAM_ID) {
4097
+ static createAssociatedTokenAccountInstruction(payer, associatedToken, owner, mint, tokenProgram = TOKEN_PROGRAM_ID5, associatedTokenProgram = ASSOCIATED_TOKEN_PROGRAM_ID) {
3795
4098
  const keys = [
3796
4099
  { pubkey: payer, isSigner: true, isWritable: true },
3797
4100
  { pubkey: associatedToken, isSigner: false, isWritable: true },
@@ -3837,7 +4140,7 @@ var init_spl_token = __esm({
3837
4140
  }
3838
4141
  };
3839
4142
  WSOL_MINT2 = new import_web38.PublicKey("So11111111111111111111111111111111111111112");
3840
- NATIVE_MINT6 = new import_web38.PublicKey("So11111111111111111111111111111111111111111");
4143
+ NATIVE_MINT5 = new import_web38.PublicKey("So11111111111111111111111111111111111111111");
3841
4144
  USDC_MINT2 = new import_web38.PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
3842
4145
  USDT_MINT = new import_web38.PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");
3843
4146
  }
@@ -4106,28 +4409,6 @@ var init_confirm_any_signature = __esm({
4106
4409
  }
4107
4410
  });
4108
4411
 
4109
- // src/common/map-pool.ts
4110
- async function mapWithConcurrencyLimit(items, concurrency, fn) {
4111
- if (items.length === 0) return [];
4112
- const limit = Math.max(1, Math.min(concurrency, items.length));
4113
- const results = new Array(items.length);
4114
- let next = 0;
4115
- const worker = async () => {
4116
- for (; ; ) {
4117
- const i = next++;
4118
- if (i >= items.length) return;
4119
- results[i] = await fn(items[i], i);
4120
- }
4121
- };
4122
- await Promise.all(Array.from({ length: limit }, () => worker()));
4123
- return results;
4124
- }
4125
- var init_map_pool = __esm({
4126
- "src/common/map-pool.ts"() {
4127
- "use strict";
4128
- }
4129
- });
4130
-
4131
4412
  // src/execution/execution.ts
4132
4413
  function instructionAccountCount(ix) {
4133
4414
  if (ix.keys !== void 0) return ix.keys.length;
@@ -4584,12 +4865,22 @@ var init_params = __esm({
4584
4865
  }
4585
4866
  };
4586
4867
  RaydiumAmmV4Params = class _RaydiumAmmV4Params {
4587
- constructor(amm, coinMint, pcMint, tokenCoin, tokenPc, coinReserve, pcReserve) {
4868
+ constructor(amm, coinMint, pcMint, tokenCoin, tokenPc, ammOpenOrders, ammTargetOrders, serumProgram, serumMarket, serumBids, serumAsks, serumEventQueue, serumCoinVaultAccount, serumPcVaultAccount, serumVaultSigner, coinReserve, pcReserve) {
4588
4869
  this.amm = amm;
4589
4870
  this.coinMint = coinMint;
4590
4871
  this.pcMint = pcMint;
4591
4872
  this.tokenCoin = tokenCoin;
4592
4873
  this.tokenPc = tokenPc;
4874
+ this.ammOpenOrders = ammOpenOrders;
4875
+ this.ammTargetOrders = ammTargetOrders;
4876
+ this.serumProgram = serumProgram;
4877
+ this.serumMarket = serumMarket;
4878
+ this.serumBids = serumBids;
4879
+ this.serumAsks = serumAsks;
4880
+ this.serumEventQueue = serumEventQueue;
4881
+ this.serumCoinVaultAccount = serumCoinVaultAccount;
4882
+ this.serumPcVaultAccount = serumPcVaultAccount;
4883
+ this.serumVaultSigner = serumVaultSigner;
4593
4884
  this.coinReserve = coinReserve;
4594
4885
  this.pcReserve = pcReserve;
4595
4886
  }
@@ -4598,6 +4889,16 @@ var init_params = __esm({
4598
4889
  pcMint;
4599
4890
  tokenCoin;
4600
4891
  tokenPc;
4892
+ ammOpenOrders;
4893
+ ammTargetOrders;
4894
+ serumProgram;
4895
+ serumMarket;
4896
+ serumBids;
4897
+ serumAsks;
4898
+ serumEventQueue;
4899
+ serumCoinVaultAccount;
4900
+ serumPcVaultAccount;
4901
+ serumVaultSigner;
4601
4902
  coinReserve;
4602
4903
  pcReserve;
4603
4904
  static async fromAmmAddressByRpc(connection, amm) {
@@ -4605,16 +4906,35 @@ var init_params = __esm({
4605
4906
  if (!ammInfo) {
4606
4907
  throw new Error("Raydium AMM account not found");
4607
4908
  }
4909
+ const marketState = await fetchMarketState(wrapConnection(connection), ammInfo.market);
4910
+ if (!marketState) {
4911
+ throw new Error("Raydium AMM market account not found");
4912
+ }
4913
+ const serumVaultSigner = deriveSerumVaultSigner(
4914
+ ammInfo.serumDex,
4915
+ ammInfo.market,
4916
+ marketState.vaultSignerNonce
4917
+ );
4608
4918
  const coinBal = await connection.getTokenAccountBalance(ammInfo.tokenCoin);
4609
4919
  const pcBal = await connection.getTokenAccountBalance(ammInfo.tokenPc);
4610
- const coinReserve = Number(coinBal.value.amount);
4611
- const pcReserve = Number(pcBal.value.amount);
4920
+ const coinReserve = BigInt(coinBal.value.amount);
4921
+ const pcReserve = BigInt(pcBal.value.amount);
4612
4922
  return new _RaydiumAmmV4Params(
4613
4923
  amm,
4614
4924
  ammInfo.coinMint,
4615
4925
  ammInfo.pcMint,
4616
4926
  ammInfo.tokenCoin,
4617
4927
  ammInfo.tokenPc,
4928
+ ammInfo.openOrders,
4929
+ ammInfo.targetOrders,
4930
+ ammInfo.serumDex,
4931
+ ammInfo.market,
4932
+ marketState.serumBids,
4933
+ marketState.serumAsks,
4934
+ marketState.serumEventQueue,
4935
+ marketState.serumCoinVaultAccount,
4936
+ marketState.serumPcVaultAccount,
4937
+ serumVaultSigner,
4618
4938
  coinReserve,
4619
4939
  pcReserve
4620
4940
  );
@@ -5243,20 +5563,30 @@ var init_executor = __esm({
5243
5563
  }
5244
5564
  };
5245
5565
  const promises = clients.map(submitToClient);
5246
- try {
5247
- const result = await Promise.any(promises);
5248
- return result;
5249
- } catch {
5250
- const results = await Promise.allSettled(promises);
5251
- const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
5252
- return {
5253
- signature: "",
5254
- success: false,
5255
- error: `All parallel submissions failed: ${errors.join(", ")}`,
5256
- latencyMs: 0,
5257
- blockhashUsed: ""
5258
- };
5566
+ const pending = new Map(
5567
+ promises.map((promise, index) => [
5568
+ index,
5569
+ promise.then((result) => ({ index, result }))
5570
+ ])
5571
+ );
5572
+ const errors = [];
5573
+ while (pending.size > 0) {
5574
+ const { index, result } = await Promise.race(pending.values());
5575
+ pending.delete(index);
5576
+ if (result.success) {
5577
+ return result;
5578
+ }
5579
+ if (result.error) {
5580
+ errors.push(`${result.swqosType ?? "unknown"}: ${result.error}`);
5581
+ }
5259
5582
  }
5583
+ return {
5584
+ signature: "",
5585
+ success: false,
5586
+ error: `All parallel submissions failed${errors.length ? `: ${errors.join(", ")}` : ""}`,
5587
+ latencyMs: 0,
5588
+ blockhashUsed: ""
5589
+ };
5260
5590
  }
5261
5591
  /**
5262
5592
  * Submit to SWQoS clients sequentially - NO RPC
@@ -9034,6 +9364,28 @@ var init_perf = __esm({
9034
9364
  }
9035
9365
  });
9036
9366
 
9367
+ // src/common/map-pool.ts
9368
+ async function mapWithConcurrencyLimit(items, concurrency, fn) {
9369
+ if (items.length === 0) return [];
9370
+ const limit = Math.max(1, Math.min(concurrency, items.length));
9371
+ const results = new Array(items.length);
9372
+ let next = 0;
9373
+ const worker = async () => {
9374
+ for (; ; ) {
9375
+ const i = next++;
9376
+ if (i >= items.length) return;
9377
+ results[i] = await fn(items[i], i);
9378
+ }
9379
+ };
9380
+ await Promise.all(Array.from({ length: limit }, () => worker()));
9381
+ return results;
9382
+ }
9383
+ var init_map_pool = __esm({
9384
+ "src/common/map-pool.ts"() {
9385
+ "use strict";
9386
+ }
9387
+ });
9388
+
9037
9389
  // src/common/nonce.ts
9038
9390
  async function fetchDurableNonceInfo(connection, nonceAccount) {
9039
9391
  const account = await connection.getAccountInfo(nonceAccount);
@@ -11381,12 +11733,15 @@ __export(index_exports, {
11381
11733
  KNOWN_PROGRAM_IDS: () => KNOWN_PROGRAM_IDS,
11382
11734
  KeyNotAvailableError: () => KeyNotAvailableError,
11383
11735
  LoggingMiddleware: () => LoggingMiddleware,
11736
+ MARKET_STATE_SIZE: () => MARKET_STATE_SIZE,
11384
11737
  MAX_INSTRUCTIONS_WARN: () => MAX_INSTRUCTIONS_WARN,
11385
11738
  METEORA_DAMM_V2_AUTHORITY: () => METEORA_DAMM_V2_AUTHORITY,
11386
11739
  METEORA_DAMM_V2_EVENT_AUTHORITY_SEED: () => METEORA_DAMM_V2_EVENT_AUTHORITY_SEED,
11387
11740
  METEORA_DAMM_V2_PROGRAM: () => METEORA_DAMM_V2_PROGRAM,
11388
11741
  METEORA_DAMM_V2_PROGRAM_ID: () => METEORA_DAMM_V2_PROGRAM_ID,
11742
+ METEORA_DAMM_V2_SWAP2_DISCRIMINATOR: () => METEORA_DAMM_V2_SWAP2_DISCRIMINATOR,
11389
11743
  METEORA_DAMM_V2_SWAP_DISCRIMINATOR: () => METEORA_DAMM_V2_SWAP_DISCRIMINATOR,
11744
+ METEORA_DAMM_V2_SWAP_MODE_PARTIAL_FILL: () => METEORA_DAMM_V2_SWAP_MODE_PARTIAL_FILL,
11390
11745
  METEORA_POOL_SIZE: () => METEORA_POOL_SIZE,
11391
11746
  MeteoraDammV2Executor: () => MeteoraDammV2Executor,
11392
11747
  MeteoraDammV2Params: () => MeteoraDammV2Params,
@@ -11532,18 +11887,21 @@ __export(index_exports, {
11532
11887
  createTradeConfig: () => createTradeConfig,
11533
11888
  decodeAmmInfo: () => decodeAmmInfo,
11534
11889
  decodeBonkPoolState: () => decodeBonkPoolState,
11890
+ decodeMarketState: () => decodeMarketState,
11535
11891
  decodeMeteoraPool: () => decodeMeteoraPool,
11536
11892
  decodePool: () => decodePool,
11537
11893
  decodeRaydiumCPMMpoolState: () => decodeRaydiumCPMMpoolState,
11538
11894
  defaultExecuteOptions: () => defaultExecuteOptions,
11539
11895
  defaultHotPathConfig: () => defaultHotPathConfig,
11540
11896
  defaultTradeExecuteOptions: () => defaultTradeExecuteOptions,
11897
+ deriveSerumVaultSigner: () => deriveSerumVaultSigner,
11541
11898
  extractHintsFromLogs: () => extractHintsFromLogs,
11542
11899
  fetchAddressLookupTableAccount: () => fetchAddressLookupTableAccount,
11543
11900
  fetchAmmInfo: () => fetchAmmInfo,
11544
11901
  fetchBondingCurveAccount: () => fetchBondingCurveAccount,
11545
11902
  fetchBonkPoolState: () => fetchBonkPoolState,
11546
11903
  fetchDurableNonceInfo: () => fetchDurableNonceInfo,
11904
+ fetchMarketState: () => fetchMarketState,
11547
11905
  fetchMeteoraPool: () => fetchMeteoraPool,
11548
11906
  fetchPool: () => fetchPool,
11549
11907
  fetchRaydiumCPMMpoolState: () => fetchRaydiumCPMMpoolState,
@@ -11603,6 +11961,8 @@ __export(index_exports, {
11603
11961
  parseAddressLookupTable: () => parseAddressLookupTable,
11604
11962
  perf: () => perf_exports,
11605
11963
  pumpFunFeeRecipientMeta: () => pumpFunFeeRecipientMeta,
11964
+ pumpFunParamsFromParserTrade: () => pumpFunParamsFromParserTrade,
11965
+ pumpSwapParamsFromParserTrade: () => pumpSwapParamsFromParserTrade,
11606
11966
  recommendedSenderThreadCoreIndices: () => recommendedSenderThreadCoreIndices,
11607
11967
  retryWithBackoff: () => retryWithBackoff,
11608
11968
  signWithKeypair: () => signWithKeypair,
@@ -11620,6 +11980,88 @@ __export(index_exports, {
11620
11980
  withStandardMiddlewares: () => withStandardMiddlewares
11621
11981
  });
11622
11982
  module.exports = __toCommonJS(index_exports);
11983
+ function normalizeSwqosConfigs(rpcUrl, configs) {
11984
+ if (configs.length === 0 || configs.some((c) => c.type === "Default" /* Default */)) {
11985
+ return configs;
11986
+ }
11987
+ return [
11988
+ ...configs,
11989
+ {
11990
+ type: "Default" /* Default */,
11991
+ region: "Default" /* Default */,
11992
+ apiKey: "",
11993
+ customUrl: rpcUrl
11994
+ }
11995
+ ];
11996
+ }
11997
+ function parserPublicKey(value) {
11998
+ if (!value) return import_web321.PublicKey.default;
11999
+ if (value instanceof import_web321.PublicKey) return value;
12000
+ if (value === import_web321.PublicKey.default.toBase58()) return import_web321.PublicKey.default;
12001
+ return new import_web321.PublicKey(value);
12002
+ }
12003
+ function pumpFunQuoteMintForLayout(quoteMint) {
12004
+ if (quoteMint.equals(import_web321.PublicKey.default) || quoteMint.equals(CONSTANTS.SOL_TOKEN_ACCOUNT)) {
12005
+ return import_web321.PublicKey.default;
12006
+ }
12007
+ return quoteMint;
12008
+ }
12009
+ function parserU64(value) {
12010
+ if (value === void 0 || value === null || value === "") return 0;
12011
+ const n = typeof value === "bigint" ? value : BigInt(value);
12012
+ if (n > BigInt(Number.MAX_SAFE_INTEGER)) {
12013
+ throw new TradeError(106, `parser u64 value ${n.toString()} exceeds JavaScript safe integer range`);
12014
+ }
12015
+ return Number(n);
12016
+ }
12017
+ function pumpFunParamsFromParserTrade(event, closeTokenAccountWhenSell) {
12018
+ const quoteMint = parserPublicKey(event.quote_mint);
12019
+ const legacySolQuote = quoteMint.equals(import_web321.PublicKey.default) || quoteMint.equals(CONSTANTS.SOL_TOKEN_ACCOUNT);
12020
+ const hasVirtualQuote = event.virtual_quote_reserves !== void 0;
12021
+ const hasRealQuote = event.real_quote_reserves !== void 0;
12022
+ const virtualQuote = !legacySolQuote && hasVirtualQuote ? parserU64(event.virtual_quote_reserves) : parserU64(event.virtual_sol_reserves);
12023
+ const realQuote = !legacySolQuote && hasRealQuote ? parserU64(event.real_quote_reserves) : parserU64(event.real_sol_reserves);
12024
+ const creator = parserPublicKey(event.creator);
12025
+ return {
12026
+ bondingCurve: {
12027
+ discriminator: 0,
12028
+ account: parserPublicKey(event.bonding_curve),
12029
+ virtualTokenReserves: parserU64(event.virtual_token_reserves),
12030
+ virtualSolReserves: virtualQuote,
12031
+ realTokenReserves: parserU64(event.real_token_reserves),
12032
+ realSolReserves: realQuote,
12033
+ tokenTotalSupply: 0,
12034
+ complete: false,
12035
+ creator,
12036
+ isMayhemMode: !!event.mayhem_mode,
12037
+ isCashbackCoin: !!event.is_cashback_coin
12038
+ },
12039
+ associatedBondingCurve: parserPublicKey(event.associated_bonding_curve),
12040
+ creatorVault: parserPublicKey(event.creator_vault),
12041
+ tokenProgram: parserPublicKey(event.token_program),
12042
+ closeTokenAccountWhenSell,
12043
+ feeRecipient: parserPublicKey(event.fee_recipient),
12044
+ quoteMint: pumpFunQuoteMintForLayout(quoteMint),
12045
+ observedTradeCreator: creator.equals(import_web321.PublicKey.default) ? void 0 : creator
12046
+ };
12047
+ }
12048
+ function pumpSwapParamsFromParserTrade(event) {
12049
+ return {
12050
+ pool: parserPublicKey(event.pool),
12051
+ baseMint: parserPublicKey(event.base_mint),
12052
+ quoteMint: parserPublicKey(event.quote_mint),
12053
+ poolBaseTokenAccount: parserPublicKey(event.pool_base_token_account),
12054
+ poolQuoteTokenAccount: parserPublicKey(event.pool_quote_token_account),
12055
+ poolBaseTokenReserves: parserU64(event.pool_base_token_reserves),
12056
+ poolQuoteTokenReserves: parserU64(event.pool_quote_token_reserves),
12057
+ coinCreatorVaultAta: parserPublicKey(event.coin_creator_vault_ata),
12058
+ coinCreatorVaultAuthority: parserPublicKey(event.coin_creator_vault_authority),
12059
+ baseTokenProgram: parserPublicKey(event.base_token_program),
12060
+ quoteTokenProgram: parserPublicKey(event.quote_token_program),
12061
+ isMayhemMode: !!event.is_mayhem_mode,
12062
+ isCashbackCoin: !!event.is_cashback_coin
12063
+ };
12064
+ }
11623
12065
  function recommendedSenderThreadCoreIndices(swqosCount, availableCores = (0, import_node_os.cpus)().length, fromEnd = true) {
11624
12066
  if (swqosCount <= 0 || availableCores <= 0) {
11625
12067
  return [];
@@ -11657,8 +12099,7 @@ function mapPumpFunParams(p) {
11657
12099
  feeSharingCreatorVaultIfActive: p.feeSharingCreatorVaultIfActive,
11658
12100
  closeTokenAccountWhenSell: p.closeTokenAccountWhenSell,
11659
12101
  feeRecipient: p.feeRecipient,
11660
- quoteMint: p.quoteMint,
11661
- useV2Ix: p.useV2Ix
12102
+ quoteMint: p.quoteMint
11662
12103
  };
11663
12104
  }
11664
12105
  async function findPoolByMint2(connection, mint, dexType) {
@@ -11752,7 +12193,24 @@ function gasConfigFromStrategyValue(value, tradeType) {
11752
12193
  sellTipLamports: !isBuy ? tipLam : 0
11753
12194
  };
11754
12195
  }
11755
- function expandSwqosGasTasks(effectiveSwqos, tradeType, execGas, configGas, gasStrategy, useStrategyRowMinTip, checkMinTip, withTip, swqosMod, mevProtection, rpcUrl, logEnabled) {
12196
+ async function collectUntilFirstSuccess(promises, isSuccess) {
12197
+ if (promises.length === 0) return [];
12198
+ const results = [];
12199
+ const pending = new Map(
12200
+ promises.map((promise, index) => [
12201
+ index,
12202
+ promise.then((result) => ({ index, result }))
12203
+ ])
12204
+ );
12205
+ while (pending.size > 0) {
12206
+ const { index, result } = await Promise.race(pending.values());
12207
+ pending.delete(index);
12208
+ results.push(result);
12209
+ if (isSuccess(result)) return results;
12210
+ }
12211
+ return results;
12212
+ }
12213
+ function expandSwqosGasTasks(effectiveSwqos, tradeType, execGas, configGas, gasStrategy, useStrategyRowMinTip, checkMinTip, withTip, swqosMod, mevProtection, rpcUrl, logEnabled, getClient) {
11756
12214
  const out = [];
11757
12215
  if (execGas || configGas) {
11758
12216
  for (const cfg of effectiveSwqos) {
@@ -11777,10 +12235,7 @@ function expandSwqosGasTasks(effectiveSwqos, tradeType, execGas, configGas, gasS
11777
12235
  for (const row of matching) {
11778
12236
  const tipLamports = Math.floor(row.value.tip * 1e9);
11779
12237
  if (checkMinTip && withTip && cfg.type !== "Default" /* Default */) {
11780
- const client = swqosMod.ClientFactory.createClient(
11781
- mapSwqosToClientConfig(cfg, mevProtection),
11782
- rpcUrl
11783
- );
12238
+ const client = getClient?.(cfg) ?? swqosMod.ClientFactory.createClient(mapSwqosToClientConfig(cfg, mevProtection), rpcUrl);
11784
12239
  const minLamports = Math.ceil(client.minTipSol() * 1e9);
11785
12240
  if (tipLamports < minLamports) {
11786
12241
  if (logEnabled) {
@@ -11818,7 +12273,7 @@ function filterSwqosConfigsForWithTip(configs, withTip) {
11818
12273
  if (withTip) return configs;
11819
12274
  return configs.filter((c) => c.type === "Default" /* Default */);
11820
12275
  }
11821
- function filterSwqosConfigsByMinTip(swqosMod, configs, tradeType, gas, mevProtection, rpcUrl, logEnabled) {
12276
+ function filterSwqosConfigsByMinTip(swqosMod, configs, tradeType, gas, mevProtection, rpcUrl, logEnabled, getClient) {
11822
12277
  const tipLamports = gas ? tradeType === "Buy" /* Buy */ ? gas.buyTipLamports : gas.sellTipLamports : 0;
11823
12278
  const out = [];
11824
12279
  for (const cfg of configs) {
@@ -11826,10 +12281,7 @@ function filterSwqosConfigsByMinTip(swqosMod, configs, tradeType, gas, mevProtec
11826
12281
  out.push(cfg);
11827
12282
  continue;
11828
12283
  }
11829
- const client = swqosMod.ClientFactory.createClient(
11830
- mapSwqosToClientConfig(cfg, mevProtection),
11831
- rpcUrl
11832
- );
12284
+ const client = getClient?.(cfg) ?? swqosMod.ClientFactory.createClient(mapSwqosToClientConfig(cfg, mevProtection), rpcUrl);
11833
12285
  const minLamports = Math.ceil(client.minTipSol() * 1e9);
11834
12286
  if (tipLamports < minLamports) {
11835
12287
  if (logEnabled) {
@@ -11843,13 +12295,10 @@ function filterSwqosConfigsByMinTip(swqosMod, configs, tradeType, gas, mevProtec
11843
12295
  }
11844
12296
  return out;
11845
12297
  }
11846
- function resolveTipRecipientPubkey(swqosMod, configs, mevProtection, rpcUrl) {
12298
+ function resolveTipRecipientPubkey(swqosMod, configs, mevProtection, rpcUrl, getClient) {
11847
12299
  const preferred = configs.find((c) => c.type !== "Default" /* Default */) ?? configs[0];
11848
12300
  if (!preferred) return null;
11849
- const client = swqosMod.ClientFactory.createClient(
11850
- mapSwqosToClientConfig(preferred, mevProtection),
11851
- rpcUrl
11852
- );
12301
+ const client = getClient?.(preferred) ?? swqosMod.ClientFactory.createClient(mapSwqosToClientConfig(preferred, mevProtection), rpcUrl);
11853
12302
  const acc = client.getTipAccount();
11854
12303
  if (!acc) return null;
11855
12304
  try {
@@ -11865,7 +12314,7 @@ function createTradeConfig(rpcUrl, swqosConfigs = [], options) {
11865
12314
  const { commitment, logEnabled, ...rest } = options ?? {};
11866
12315
  return {
11867
12316
  rpcUrl,
11868
- swqosConfigs,
12317
+ swqosConfigs: normalizeSwqosConfigs(rpcUrl, swqosConfigs),
11869
12318
  ...rest,
11870
12319
  commitment: commitment ?? "confirmed",
11871
12320
  logEnabled: logEnabled ?? true
@@ -11887,7 +12336,6 @@ var init_index = __esm({
11887
12336
  init_wsol_manager();
11888
12337
  init_compute_budget();
11889
12338
  init_confirm_any_signature();
11890
- init_map_pool();
11891
12339
  init_execution();
11892
12340
  init_sdk_errors();
11893
12341
  init_sdk_errors();
@@ -11983,7 +12431,6 @@ var init_index = __esm({
11983
12431
  _checkMinTip = false;
11984
12432
  _mevProtection = false;
11985
12433
  _useSeedOptimize = true;
11986
- _usePumpfunV2 = false;
11987
12434
  _swqosCoresFromEnd = true;
11988
12435
  _createWsolAtaOnStartup = false;
11989
12436
  _gasFeeStrategy;
@@ -11997,7 +12444,7 @@ var init_index = __esm({
11997
12444
  return new _TradeConfigBuilder(rpcUrl);
11998
12445
  }
11999
12446
  swqosConfigs(configs) {
12000
- this._swqosConfigs = configs;
12447
+ this._swqosConfigs = normalizeSwqosConfigs(this._rpcUrl, configs);
12001
12448
  return this;
12002
12449
  }
12003
12450
  commitment(commitment) {
@@ -12026,10 +12473,6 @@ var init_index = __esm({
12026
12473
  this._useSeedOptimize = enabled;
12027
12474
  return this;
12028
12475
  }
12029
- usePumpfunV2(enabled) {
12030
- this._usePumpfunV2 = enabled;
12031
- return this;
12032
- }
12033
12476
  swqosCoresFromEnd(enabled) {
12034
12477
  this._swqosCoresFromEnd = enabled;
12035
12478
  return this;
@@ -12061,13 +12504,12 @@ var init_index = __esm({
12061
12504
  build() {
12062
12505
  return {
12063
12506
  rpcUrl: this._rpcUrl,
12064
- swqosConfigs: this._swqosConfigs,
12507
+ swqosConfigs: normalizeSwqosConfigs(this._rpcUrl, this._swqosConfigs),
12065
12508
  commitment: this._commitment,
12066
12509
  logEnabled: this._logEnabled,
12067
12510
  checkMinTip: this._checkMinTip,
12068
12511
  mevProtection: this._mevProtection,
12069
12512
  useSeedOptimize: this._useSeedOptimize,
12070
- usePumpfunV2: this._usePumpfunV2,
12071
12513
  swqosCoresFromEnd: this._swqosCoresFromEnd,
12072
12514
  createWsolAtaOnStartup: this._createWsolAtaOnStartup,
12073
12515
  gasFeeStrategy: this._gasFeeStrategy,
@@ -12077,7 +12519,7 @@ var init_index = __esm({
12077
12519
  };
12078
12520
  }
12079
12521
  };
12080
- SWQOS_SUBMIT_TIMEOUT_MS_WHEN_NO_CONFIRM = 2e3;
12522
+ SWQOS_SUBMIT_TIMEOUT_MS_WHEN_NO_CONFIRM = 5e3;
12081
12523
  RUST_PARITY_SIMULATE_CONFIG = {
12082
12524
  sigVerify: false,
12083
12525
  replaceRecentBlockhash: false,
@@ -12090,14 +12532,48 @@ var init_index = __esm({
12090
12532
  _config;
12091
12533
  middlewares = [];
12092
12534
  _logEnabled;
12535
+ _swqosModulePromise;
12536
+ _swqosClientCache = /* @__PURE__ */ new Map();
12093
12537
  constructor(payer, config) {
12094
12538
  this.payer = payer;
12095
- this._config = config;
12539
+ this._config = {
12540
+ ...config,
12541
+ swqosConfigs: normalizeSwqosConfigs(config.rpcUrl, config.swqosConfigs ?? [])
12542
+ };
12096
12543
  this.connection = new import_web321.Connection(config.rpcUrl, {
12097
12544
  commitment: config.commitment ?? "confirmed"
12098
12545
  });
12099
12546
  this._logEnabled = config.logEnabled ?? true;
12100
12547
  }
12548
+ getSwqosModule() {
12549
+ this._swqosModulePromise ??= Promise.resolve().then(() => (init_clients(), clients_exports));
12550
+ return this._swqosModulePromise;
12551
+ }
12552
+ swqosClientCacheKey(cfg) {
12553
+ return JSON.stringify([
12554
+ this._config.rpcUrl,
12555
+ this._config.mevProtection ?? false,
12556
+ cfg.type,
12557
+ cfg.region ?? null,
12558
+ cfg.customUrl ?? null,
12559
+ cfg.apiKey ?? null,
12560
+ cfg.transport ?? null,
12561
+ cfg.astralaneTransport ?? null,
12562
+ cfg.swqosOnly ?? null,
12563
+ cfg.mevProtection ?? null
12564
+ ]);
12565
+ }
12566
+ getSwqosClient(swqosMod, cfg) {
12567
+ const key = this.swqosClientCacheKey(cfg);
12568
+ const cached = this._swqosClientCache.get(key);
12569
+ if (cached) return cached;
12570
+ const client = swqosMod.ClientFactory.createClient(
12571
+ mapSwqosToClientConfig(cfg, this._config.mevProtection),
12572
+ this._config.rpcUrl
12573
+ );
12574
+ this._swqosClientCache.set(key, client);
12575
+ return client;
12576
+ }
12101
12577
  /** Get the current configuration */
12102
12578
  get config() {
12103
12579
  return this._config;
@@ -12332,9 +12808,10 @@ var init_index = __esm({
12332
12808
  fixedOutputAmount: params.fixedOutputTokenAmount !== void 0 ? BigInt(params.fixedOutputTokenAmount) : void 0,
12333
12809
  createOutputMintAta: params.createMintAta ?? true,
12334
12810
  createInputMintAta: params.createInputTokenAta ?? false,
12811
+ closeInputMintAta: params.closeInputTokenAta ?? false,
12335
12812
  protocolParams: mapPumpFunParams(ext.params),
12336
12813
  useExactSolAmount: params.useExactSolAmount ?? true,
12337
- usePumpFunV2: this._config.usePumpfunV2 ?? ext.params.useV2Ix ?? false
12814
+ inputMint: this.getInputMint(params.inputTokenType)
12338
12815
  });
12339
12816
  }
12340
12817
  case "PumpSwap" /* PumpSwap */: {
@@ -12433,8 +12910,18 @@ var init_index = __esm({
12433
12910
  pcMint: p.pcMint,
12434
12911
  tokenCoin: p.tokenCoin,
12435
12912
  tokenPc: p.tokenPc,
12436
- coinReserve: BigInt(p.coinReserve),
12437
- pcReserve: BigInt(p.pcReserve)
12913
+ ammOpenOrders: p.ammOpenOrders,
12914
+ ammTargetOrders: p.ammTargetOrders,
12915
+ serumProgram: p.serumProgram,
12916
+ serumMarket: p.serumMarket,
12917
+ serumBids: p.serumBids,
12918
+ serumAsks: p.serumAsks,
12919
+ serumEventQueue: p.serumEventQueue,
12920
+ serumCoinVaultAccount: p.serumCoinVaultAccount,
12921
+ serumPcVaultAccount: p.serumPcVaultAccount,
12922
+ serumVaultSigner: p.serumVaultSigner,
12923
+ coinReserve: p.coinReserve,
12924
+ pcReserve: p.pcReserve
12438
12925
  };
12439
12926
  return buildRaydiumAmmV4BuyInstructions({
12440
12927
  payer: this.payer.publicKey,
@@ -12500,7 +12987,7 @@ var init_index = __esm({
12500
12987
  closeInputMintAta: params.closeMintTokenAta ?? false,
12501
12988
  createOutputMintAta: params.createOutputTokenAta ?? false,
12502
12989
  protocolParams: mapPumpFunParams(ext.params),
12503
- usePumpFunV2: this._config.usePumpfunV2 ?? ext.params.useV2Ix ?? false
12990
+ outputMint: this.getOutputMint(params.outputTokenType)
12504
12991
  });
12505
12992
  }
12506
12993
  case "PumpSwap" /* PumpSwap */: {
@@ -12598,12 +13085,23 @@ var init_index = __esm({
12598
13085
  pcMint: p.pcMint,
12599
13086
  tokenCoin: p.tokenCoin,
12600
13087
  tokenPc: p.tokenPc,
12601
- coinReserve: BigInt(p.coinReserve),
12602
- pcReserve: BigInt(p.pcReserve)
13088
+ ammOpenOrders: p.ammOpenOrders,
13089
+ ammTargetOrders: p.ammTargetOrders,
13090
+ serumProgram: p.serumProgram,
13091
+ serumMarket: p.serumMarket,
13092
+ serumBids: p.serumBids,
13093
+ serumAsks: p.serumAsks,
13094
+ serumEventQueue: p.serumEventQueue,
13095
+ serumCoinVaultAccount: p.serumCoinVaultAccount,
13096
+ serumPcVaultAccount: p.serumPcVaultAccount,
13097
+ serumVaultSigner: p.serumVaultSigner,
13098
+ coinReserve: p.coinReserve,
13099
+ pcReserve: p.pcReserve
12603
13100
  };
12604
13101
  return buildRaydiumAmmV4SellInstructions({
12605
13102
  payer: this.payer.publicKey,
12606
13103
  inputMint: params.mint,
13104
+ outputMint: this.getOutputMint(params.outputTokenType),
12607
13105
  inputAmount: inputAmt,
12608
13106
  slippageBasisPoints: slippage,
12609
13107
  fixedOutputAmount: params.fixedOutputTokenAmount !== void 0 ? BigInt(params.fixedOutputTokenAmount) : void 0,
@@ -12679,11 +13177,23 @@ var init_index = __esm({
12679
13177
  return result;
12680
13178
  }
12681
13179
  async executeTransaction(instructions, recentBlockhash, lookupTableAccount, waitConfirmed, simulate, execCtx) {
12682
- const blockhash = recentBlockhash ?? execCtx?.durableNonce?.nonceHash ?? (await this.connection.getLatestBlockhash(this.rpcCommitment())).blockhash;
13180
+ const blockhash = recentBlockhash ?? execCtx?.durableNonce?.nonceHash;
13181
+ if (!blockhash) {
13182
+ return {
13183
+ success: false,
13184
+ signatures: [],
13185
+ error: new TradeError(
13186
+ 105,
13187
+ "recentBlockhash or durableNonce.nonceHash is required; trade execution hot path does not query RPC for blockhash"
13188
+ ),
13189
+ timings: []
13190
+ };
13191
+ }
12683
13192
  const swqosList = this._config.swqosConfigs ?? [];
12684
13193
  const tradeType = execCtx?.tradeType ?? "Buy" /* Buy */;
12685
13194
  const withTip = execCtx?.withTip ?? true;
12686
- const swqosMod = swqosList.length > 0 ? await Promise.resolve().then(() => (init_clients(), clients_exports)) : null;
13195
+ const swqosMod = swqosList.length > 0 ? await this.getSwqosModule() : null;
13196
+ const swqosClientForConfig = swqosMod ? (cfg) => this.getSwqosClient(swqosMod, cfg) : void 0;
12687
13197
  let effectiveSwqos = swqosList;
12688
13198
  if (swqosMod && !withTip) {
12689
13199
  effectiveSwqos = filterSwqosConfigsForWithTip(swqosList, withTip);
@@ -12715,7 +13225,8 @@ var init_index = __esm({
12715
13225
  gasMerged,
12716
13226
  this._config.mevProtection,
12717
13227
  this._config.rpcUrl,
12718
- this._logEnabled
13228
+ this._logEnabled,
13229
+ swqosClientForConfig
12719
13230
  );
12720
13231
  if (effectiveSwqos.length === 0) {
12721
13232
  return {
@@ -12749,7 +13260,8 @@ var init_index = __esm({
12749
13260
  swqosMod,
12750
13261
  this._config.mevProtection,
12751
13262
  this._config.rpcUrl,
12752
- this._logEnabled
13263
+ this._logEnabled,
13264
+ swqosClientForConfig
12753
13265
  );
12754
13266
  if (swqosTasks.length === 0) {
12755
13267
  return {
@@ -12811,7 +13323,8 @@ var init_index = __esm({
12811
13323
  swqosMod,
12812
13324
  [t.cfg],
12813
13325
  this._config.mevProtection,
12814
- this._config.rpcUrl
13326
+ this._config.rpcUrl,
13327
+ swqosClientForConfig
12815
13328
  ) : null;
12816
13329
  const txSim2 = buildSignedVersionedTransaction(
12817
13330
  this.payer,
@@ -12866,17 +13379,15 @@ var init_index = __esm({
12866
13379
  if (swqosMod) {
12867
13380
  const timings = [];
12868
13381
  const signatures = [];
12869
- const submitConcurrency = this._config.maxSwqosSubmitConcurrency ?? swqosTasks.length;
12870
- const results = await mapWithConcurrencyLimit(
12871
- swqosTasks,
12872
- submitConcurrency,
12873
- async (task) => {
12874
- const t0 = performance.now();
13382
+ const submitTask = async (task) => {
13383
+ const t0 = performance.now();
13384
+ try {
12875
13385
  const tipPk = withTip ? resolveTipRecipientPubkey(
12876
13386
  swqosMod,
12877
13387
  [task.cfg],
12878
13388
  this._config.mevProtection,
12879
- this._config.rpcUrl
13389
+ this._config.rpcUrl,
13390
+ swqosClientForConfig
12880
13391
  ) : null;
12881
13392
  const tx = buildSignedVersionedTransaction(
12882
13393
  this.payer,
@@ -12885,33 +13396,30 @@ var init_index = __esm({
12885
13396
  lookupTableAccount
12886
13397
  );
12887
13398
  const raw = Buffer.from(tx.serialize());
12888
- const client = swqosMod.ClientFactory.createClient(
12889
- mapSwqosToClientConfig(task.cfg, this._config.mevProtection),
12890
- this._config.rpcUrl
12891
- );
12892
- try {
12893
- const pending = client.sendTransaction(tradeType, raw, false);
12894
- const sig = await (!waitConfirmed ? Promise.race([
12895
- pending,
12896
- new Promise(
12897
- (_, reject) => setTimeout(
12898
- () => reject(
12899
- new Error(
12900
- `SWQOS submit timed out after ${SWQOS_SUBMIT_TIMEOUT_MS_WHEN_NO_CONFIRM}ms`
12901
- )
12902
- ),
12903
- SWQOS_SUBMIT_TIMEOUT_MS_WHEN_NO_CONFIRM
12904
- )
13399
+ const client = swqosClientForConfig(task.cfg);
13400
+ const pending = client.sendTransaction(tradeType, raw, false);
13401
+ const sig = await (!waitConfirmed ? Promise.race([
13402
+ pending,
13403
+ new Promise(
13404
+ (_, reject) => setTimeout(
13405
+ () => reject(
13406
+ new Error(
13407
+ `SWQOS submit timed out after ${SWQOS_SUBMIT_TIMEOUT_MS_WHEN_NO_CONFIRM}ms`
13408
+ )
13409
+ ),
13410
+ SWQOS_SUBMIT_TIMEOUT_MS_WHEN_NO_CONFIRM
12905
13411
  )
12906
- ]) : pending);
12907
- const duration = Math.round((performance.now() - t0) * 1e3);
12908
- return { ok: true, sig, task, duration };
12909
- } catch (e) {
12910
- const duration = Math.round((performance.now() - t0) * 1e3);
12911
- return { ok: false, err: e, task, duration };
12912
- }
13412
+ )
13413
+ ]) : pending);
13414
+ const duration = Math.round((performance.now() - t0) * 1e3);
13415
+ return { ok: true, sig, task, duration };
13416
+ } catch (e) {
13417
+ const duration = Math.round((performance.now() - t0) * 1e3);
13418
+ return { ok: false, err: e, task, duration };
12913
13419
  }
12914
- );
13420
+ };
13421
+ const submitPromises = swqosTasks.map((task) => submitTask(task));
13422
+ const results = waitConfirmed ? await Promise.all(submitPromises) : await collectUntilFirstSuccess(submitPromises, (result) => result.ok);
12915
13423
  for (const v of results) {
12916
13424
  timings.push({
12917
13425
  swqosType: v.task.cfg.type,
@@ -12919,7 +13427,7 @@ var init_index = __esm({
12919
13427
  gasFeeStrategyType: v.task.strategyType
12920
13428
  });
12921
13429
  if (v.ok) {
12922
- signatures.push(v.sig);
13430
+ if (v.sig) signatures.push(v.sig);
12923
13431
  }
12924
13432
  }
12925
13433
  const success = signatures.length > 0;
@@ -13025,12 +13533,15 @@ init_index();
13025
13533
  KNOWN_PROGRAM_IDS,
13026
13534
  KeyNotAvailableError,
13027
13535
  LoggingMiddleware,
13536
+ MARKET_STATE_SIZE,
13028
13537
  MAX_INSTRUCTIONS_WARN,
13029
13538
  METEORA_DAMM_V2_AUTHORITY,
13030
13539
  METEORA_DAMM_V2_EVENT_AUTHORITY_SEED,
13031
13540
  METEORA_DAMM_V2_PROGRAM,
13032
13541
  METEORA_DAMM_V2_PROGRAM_ID,
13542
+ METEORA_DAMM_V2_SWAP2_DISCRIMINATOR,
13033
13543
  METEORA_DAMM_V2_SWAP_DISCRIMINATOR,
13544
+ METEORA_DAMM_V2_SWAP_MODE_PARTIAL_FILL,
13034
13545
  METEORA_POOL_SIZE,
13035
13546
  MeteoraDammV2Executor,
13036
13547
  MeteoraDammV2Params,
@@ -13176,18 +13687,21 @@ init_index();
13176
13687
  createTradeConfig,
13177
13688
  decodeAmmInfo,
13178
13689
  decodeBonkPoolState,
13690
+ decodeMarketState,
13179
13691
  decodeMeteoraPool,
13180
13692
  decodePool,
13181
13693
  decodeRaydiumCPMMpoolState,
13182
13694
  defaultExecuteOptions,
13183
13695
  defaultHotPathConfig,
13184
13696
  defaultTradeExecuteOptions,
13697
+ deriveSerumVaultSigner,
13185
13698
  extractHintsFromLogs,
13186
13699
  fetchAddressLookupTableAccount,
13187
13700
  fetchAmmInfo,
13188
13701
  fetchBondingCurveAccount,
13189
13702
  fetchBonkPoolState,
13190
13703
  fetchDurableNonceInfo,
13704
+ fetchMarketState,
13191
13705
  fetchMeteoraPool,
13192
13706
  fetchPool,
13193
13707
  fetchRaydiumCPMMpoolState,
@@ -13247,6 +13761,8 @@ init_index();
13247
13761
  parseAddressLookupTable,
13248
13762
  perf,
13249
13763
  pumpFunFeeRecipientMeta,
13764
+ pumpFunParamsFromParserTrade,
13765
+ pumpSwapParamsFromParserTrade,
13250
13766
  recommendedSenderThreadCoreIndices,
13251
13767
  retryWithBackoff,
13252
13768
  signWithKeypair,