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.
- package/README.md +12 -5
- package/dist/cache/index.d.mts +70 -0
- package/dist/cache/index.d.ts +70 -0
- package/dist/cache/index.js +259 -0
- package/dist/cache/index.mjs +19 -0
- package/dist/chunk-64JY4YH6.mjs +227 -0
- package/dist/chunk-6BWS3CLP.mjs +16 -0
- package/dist/{chunk-NEZDFAYA.mjs → chunk-H4ZUMTTP.mjs} +864 -336
- package/dist/{chunk-MMQAMIKR.mjs → chunk-L6RZIXXN.mjs} +4 -11
- package/dist/{clients-VITWK7B6.mjs → chunk-V7QDWUXJ.mjs} +39 -39
- package/dist/clients-PSG35HN4.mjs +107 -0
- package/dist/index-hZh5hrGj.d.mts +3089 -0
- package/dist/index-yJ5AsNfm.d.ts +3089 -0
- package/dist/index.d.mts +2 -2658
- package/dist/index.d.ts +2 -2658
- package/dist/index.js +794 -278
- package/dist/index.mjs +21 -4
- package/dist/perf/index.mjs +2 -1
- package/dist/pool/index.d.mts +88 -0
- package/dist/pool/index.d.ts +88 -0
- package/dist/pool/index.js +262 -0
- package/dist/pool/index.mjs +233 -0
- package/dist/rpc/index.d.mts +77 -0
- package/dist/rpc/index.d.ts +77 -0
- package/dist/rpc/index.js +447 -0
- package/dist/rpc/index.mjs +223 -0
- package/dist/swqos/index.d.mts +416 -0
- package/dist/swqos/index.d.ts +416 -0
- package/dist/swqos/index.js +3450 -0
- package/dist/swqos/index.mjs +1375 -0
- package/dist/trading/index.d.mts +998 -0
- package/dist/trading/index.d.ts +998 -0
- package/dist/trading/index.js +4302 -0
- package/dist/trading/index.mjs +2097 -0
- package/package.json +5 -4
- package/src/__tests__/hotpath.test.ts +33 -0
- package/src/__tests__/parser-compat.test.ts +82 -0
- package/src/__tests__/protocol-parity.test.ts +242 -0
- package/src/__tests__/sdk.test.ts +16 -0
- package/src/cache/index.ts +1 -0
- package/src/hotpath/executor.ts +25 -18
- package/src/index.ts +330 -92
- package/src/instruction/meteora_damm_v2_builder.ts +88 -20
- package/src/instruction/pumpfun_builder.ts +133 -43
- package/src/instruction/raydium_amm_v4_builder.ts +244 -35
- package/src/instruction/raydium_cpmm_builder.ts +87 -69
- package/src/params/index.ts +38 -5
- package/src/pool/index.ts +1 -0
- package/src/rpc/index.ts +1 -0
- package/src/trading/factory.ts +10 -0
|
@@ -230,14 +230,15 @@ import {
|
|
|
230
230
|
} from "@solana/web3.js";
|
|
231
231
|
import {
|
|
232
232
|
getAssociatedTokenAddressSync,
|
|
233
|
-
createAssociatedTokenAccountInstruction,
|
|
234
233
|
createAssociatedTokenAccountIdempotentInstruction,
|
|
235
234
|
TOKEN_PROGRAM_ID,
|
|
236
235
|
TOKEN_2022_PROGRAM_ID,
|
|
237
236
|
ASSOCIATED_TOKEN_PROGRAM_ID as SPL_ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
238
237
|
createCloseAccountInstruction,
|
|
238
|
+
createSyncNativeInstruction,
|
|
239
239
|
NATIVE_MINT
|
|
240
240
|
} from "@solana/spl-token";
|
|
241
|
+
var SOL_TOKEN_ACCOUNT2 = new PublicKey2("So11111111111111111111111111111111111111111");
|
|
241
242
|
var PUMPFUN_PROGRAM_ID = new PublicKey2(
|
|
242
243
|
"6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"
|
|
243
244
|
);
|
|
@@ -489,7 +490,36 @@ function effectivePumpMintTokenProgram(mint, protocolParams) {
|
|
|
489
490
|
return TOKEN_2022_PROGRAM_ID;
|
|
490
491
|
}
|
|
491
492
|
function effectiveQuoteMint(protocolParams) {
|
|
492
|
-
|
|
493
|
+
if (!isUsablePubkey(protocolParams.quoteMint) || protocolParams.quoteMint.equals(SOL_TOKEN_ACCOUNT2)) {
|
|
494
|
+
return NATIVE_MINT;
|
|
495
|
+
}
|
|
496
|
+
return protocolParams.quoteMint;
|
|
497
|
+
}
|
|
498
|
+
function usesPumpFunV2Layout(protocolParams) {
|
|
499
|
+
return isUsablePubkey(protocolParams.quoteMint) && !protocolParams.quoteMint.equals(SOL_TOKEN_ACCOUNT2);
|
|
500
|
+
}
|
|
501
|
+
function isSolQuoteMint(mint) {
|
|
502
|
+
return mint.equals(SOL_TOKEN_ACCOUNT2) || mint.equals(NATIVE_MINT);
|
|
503
|
+
}
|
|
504
|
+
function validateV2BuyQuoteMint(inputMint, quoteMint) {
|
|
505
|
+
if (isSolQuoteMint(quoteMint)) {
|
|
506
|
+
if (inputMint.equals(SOL_TOKEN_ACCOUNT2) || inputMint.equals(NATIVE_MINT)) return;
|
|
507
|
+
} else if (inputMint.equals(quoteMint)) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
throw new Error(
|
|
511
|
+
`PumpFun V2 buy input_mint ${inputMint.toBase58()} does not match quote_mint ${quoteMint.toBase58()}; USDC quote pools must be bought with USDC, not SOL`
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
function validateV2SellQuoteMint(outputMint, quoteMint) {
|
|
515
|
+
if (isSolQuoteMint(quoteMint)) {
|
|
516
|
+
if (outputMint.equals(SOL_TOKEN_ACCOUNT2) || outputMint.equals(NATIVE_MINT)) return;
|
|
517
|
+
} else if (outputMint.equals(quoteMint)) {
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
throw new Error(
|
|
521
|
+
`PumpFun V2 sell output_mint ${outputMint.toBase58()} does not match quote_mint ${quoteMint.toBase58()}; USDC quote pools settle to USDC, not SOL`
|
|
522
|
+
);
|
|
493
523
|
}
|
|
494
524
|
function associatedTokenAddress(mint, owner, tokenProgram) {
|
|
495
525
|
return getAssociatedTokenAddressSync(
|
|
@@ -500,6 +530,28 @@ function associatedTokenAddress(mint, owner, tokenProgram) {
|
|
|
500
530
|
SPL_ASSOCIATED_TOKEN_PROGRAM_ID
|
|
501
531
|
);
|
|
502
532
|
}
|
|
533
|
+
function pushCreateOrWrapUserTokenAccount(instructions, payer, ata, mint, tokenProgram, amount) {
|
|
534
|
+
instructions.push(
|
|
535
|
+
createAssociatedTokenAccountIdempotentInstruction(
|
|
536
|
+
payer,
|
|
537
|
+
ata,
|
|
538
|
+
payer,
|
|
539
|
+
mint,
|
|
540
|
+
tokenProgram,
|
|
541
|
+
SPL_ASSOCIATED_TOKEN_PROGRAM_ID
|
|
542
|
+
)
|
|
543
|
+
);
|
|
544
|
+
if (mint.equals(NATIVE_MINT)) {
|
|
545
|
+
instructions.push(
|
|
546
|
+
SystemProgram.transfer({
|
|
547
|
+
fromPubkey: payer,
|
|
548
|
+
toPubkey: ata,
|
|
549
|
+
lamports: amount
|
|
550
|
+
})
|
|
551
|
+
);
|
|
552
|
+
instructions.push(createSyncNativeInstruction(ata));
|
|
553
|
+
}
|
|
554
|
+
}
|
|
503
555
|
function getBuyTokenAmountFromSolAmount(amount, bondingCurve, creator) {
|
|
504
556
|
if (amount === 0n || bondingCurve.virtualTokenReserves === 0n) {
|
|
505
557
|
return 0n;
|
|
@@ -529,21 +581,23 @@ function getSellSolAmountFromTokenAmount(amount, bondingCurve, creator) {
|
|
|
529
581
|
function buildPumpFunBuyInstructions(params) {
|
|
530
582
|
const {
|
|
531
583
|
payer,
|
|
584
|
+
inputMint = SOL_TOKEN_ACCOUNT2,
|
|
532
585
|
outputMint,
|
|
533
586
|
inputAmount,
|
|
534
587
|
slippageBasisPoints = BigInt(1e3),
|
|
535
588
|
fixedOutputAmount,
|
|
536
589
|
createOutputMintAta = true,
|
|
537
590
|
createInputMintAta = false,
|
|
591
|
+
closeInputMintAta = false,
|
|
538
592
|
protocolParams,
|
|
539
|
-
useExactSolAmount = true
|
|
540
|
-
usePumpFunV2 = false
|
|
593
|
+
useExactSolAmount = true
|
|
541
594
|
} = params;
|
|
542
|
-
if (
|
|
595
|
+
if (usesPumpFunV2Layout(protocolParams)) {
|
|
543
596
|
return buildPumpFunBuyV2Instructions({
|
|
544
597
|
...params,
|
|
598
|
+
inputMint,
|
|
545
599
|
createInputMintAta,
|
|
546
|
-
|
|
600
|
+
closeInputMintAta
|
|
547
601
|
});
|
|
548
602
|
}
|
|
549
603
|
if (inputAmount === BigInt(0)) {
|
|
@@ -567,34 +621,41 @@ function buildPumpFunBuyInstructions(params) {
|
|
|
567
621
|
const userVolumeAccumulator = getPumpFunUserVolumeAccumulatorPda(payerPubkey);
|
|
568
622
|
if (createOutputMintAta) {
|
|
569
623
|
instructions.push(
|
|
570
|
-
|
|
624
|
+
createAssociatedTokenAccountIdempotentInstruction(
|
|
571
625
|
payerPubkey,
|
|
572
626
|
userTokenAccount,
|
|
573
627
|
payerPubkey,
|
|
574
628
|
outputMint,
|
|
575
|
-
tokenProgramId
|
|
629
|
+
tokenProgramId,
|
|
630
|
+
SPL_ASSOCIATED_TOKEN_PROGRAM_ID
|
|
576
631
|
)
|
|
577
632
|
);
|
|
578
633
|
}
|
|
579
634
|
const feeRecipientPk = pumpFunFeeRecipientMeta(feeRecipient, bondingCurve.isMayhemMode);
|
|
580
635
|
const bondingCurveV2 = getBondingCurveV2Pda(outputMint);
|
|
581
|
-
const trackVolume = bondingCurve.isCashbackCoin ?
|
|
636
|
+
const trackVolume = bondingCurve.isCashbackCoin ? 1 : 0;
|
|
582
637
|
const buyTokenAmount = fixedOutputAmount ? fixedOutputAmount : getBuyTokenAmountFromSolAmount(inputAmount, bondingCurve, creator);
|
|
583
638
|
const maxSolCost = calculateWithSlippageBuy(inputAmount, slippageBasisPoints);
|
|
584
639
|
let data;
|
|
585
|
-
if (
|
|
586
|
-
|
|
587
|
-
data
|
|
640
|
+
if (fixedOutputAmount !== void 0) {
|
|
641
|
+
data = Buffer.alloc(25);
|
|
642
|
+
PUMPFUN_BUY_DISCRIMINATOR.copy(data, 0);
|
|
643
|
+
data.writeBigUInt64LE(fixedOutputAmount, 8);
|
|
644
|
+
data.writeBigUInt64LE(inputAmount, 16);
|
|
645
|
+
data[24] = trackVolume;
|
|
646
|
+
} else if (useExactSolAmount) {
|
|
647
|
+
const minTokensOut = calculateWithSlippageSell(buyTokenAmount, slippageBasisPoints);
|
|
648
|
+
data = Buffer.alloc(25);
|
|
588
649
|
PUMPFUN_BUY_EXACT_SOL_IN_DISCRIMINATOR.copy(data, 0);
|
|
589
650
|
data.writeBigUInt64LE(inputAmount, 8);
|
|
590
651
|
data.writeBigUInt64LE(minTokensOut, 16);
|
|
591
|
-
|
|
652
|
+
data[24] = trackVolume;
|
|
592
653
|
} else {
|
|
593
|
-
data = Buffer.alloc(
|
|
654
|
+
data = Buffer.alloc(25);
|
|
594
655
|
PUMPFUN_BUY_DISCRIMINATOR.copy(data, 0);
|
|
595
656
|
data.writeBigUInt64LE(buyTokenAmount, 8);
|
|
596
657
|
data.writeBigUInt64LE(maxSolCost, 16);
|
|
597
|
-
|
|
658
|
+
data[24] = trackVolume;
|
|
598
659
|
}
|
|
599
660
|
const keys = [
|
|
600
661
|
{ pubkey: PUMPFUN_GLOBAL_ACCOUNT, isSigner: false, isWritable: false },
|
|
@@ -629,19 +690,19 @@ function buildPumpFunSellInstructions(params) {
|
|
|
629
690
|
const {
|
|
630
691
|
payer,
|
|
631
692
|
inputMint,
|
|
693
|
+
outputMint = SOL_TOKEN_ACCOUNT2,
|
|
632
694
|
inputAmount,
|
|
633
695
|
slippageBasisPoints = BigInt(1e3),
|
|
634
696
|
fixedOutputAmount,
|
|
635
697
|
createOutputMintAta = false,
|
|
636
698
|
closeInputMintAta = false,
|
|
637
|
-
protocolParams
|
|
638
|
-
usePumpFunV2 = false
|
|
699
|
+
protocolParams
|
|
639
700
|
} = params;
|
|
640
|
-
if (
|
|
701
|
+
if (usesPumpFunV2Layout(protocolParams)) {
|
|
641
702
|
return buildPumpFunSellV2Instructions({
|
|
642
703
|
...params,
|
|
643
|
-
|
|
644
|
-
|
|
704
|
+
outputMint,
|
|
705
|
+
createOutputMintAta
|
|
645
706
|
});
|
|
646
707
|
}
|
|
647
708
|
if (inputAmount === BigInt(0)) {
|
|
@@ -721,12 +782,14 @@ function buildPumpFunSellInstructions(params) {
|
|
|
721
782
|
function buildPumpFunBuyV2Instructions(params) {
|
|
722
783
|
const {
|
|
723
784
|
payer,
|
|
785
|
+
inputMint = SOL_TOKEN_ACCOUNT2,
|
|
724
786
|
outputMint,
|
|
725
787
|
inputAmount,
|
|
726
788
|
slippageBasisPoints = BigInt(1e3),
|
|
727
789
|
fixedOutputAmount,
|
|
728
790
|
createOutputMintAta = true,
|
|
729
791
|
createInputMintAta = false,
|
|
792
|
+
closeInputMintAta = false,
|
|
730
793
|
protocolParams,
|
|
731
794
|
useExactSolAmount = true
|
|
732
795
|
} = params;
|
|
@@ -741,6 +804,7 @@ function buildPumpFunBuyV2Instructions(params) {
|
|
|
741
804
|
const bondingCurveAddr = bondingCurve.account.equals(PublicKey2.default) || !bondingCurve.account ? getBondingCurvePda(outputMint) : bondingCurve.account;
|
|
742
805
|
const baseTokenProgram = effectivePumpMintTokenProgram(outputMint, protocolParams);
|
|
743
806
|
const quoteMint = effectiveQuoteMint(protocolParams);
|
|
807
|
+
validateV2BuyQuoteMint(inputMint, quoteMint);
|
|
744
808
|
const quoteTokenProgram = TOKEN_PROGRAM_ID;
|
|
745
809
|
const associatedBaseBondingCurve = associatedTokenAddress(
|
|
746
810
|
outputMint,
|
|
@@ -793,32 +857,39 @@ function buildPumpFunBuyV2Instructions(params) {
|
|
|
793
857
|
)
|
|
794
858
|
);
|
|
795
859
|
}
|
|
796
|
-
if (createInputMintAta) {
|
|
797
|
-
instructions.push(
|
|
798
|
-
createAssociatedTokenAccountIdempotentInstruction(
|
|
799
|
-
payerPubkey,
|
|
800
|
-
associatedQuoteUser,
|
|
801
|
-
payerPubkey,
|
|
802
|
-
quoteMint,
|
|
803
|
-
quoteTokenProgram,
|
|
804
|
-
SPL_ASSOCIATED_TOKEN_PROGRAM_ID
|
|
805
|
-
)
|
|
806
|
-
);
|
|
807
|
-
}
|
|
808
860
|
const buyTokenAmount = fixedOutputAmount ? fixedOutputAmount : getBuyTokenAmountFromSolAmount(inputAmount, bondingCurve, creator);
|
|
809
861
|
const maxSolCost = calculateWithSlippageBuy(inputAmount, slippageBasisPoints);
|
|
810
862
|
let data;
|
|
811
|
-
|
|
812
|
-
|
|
863
|
+
let quoteAmountToFund;
|
|
864
|
+
if (fixedOutputAmount !== void 0) {
|
|
865
|
+
data = Buffer.alloc(24);
|
|
866
|
+
PUMPFUN_BUY_V2_DISCRIMINATOR.copy(data, 0);
|
|
867
|
+
data.writeBigUInt64LE(fixedOutputAmount, 8);
|
|
868
|
+
data.writeBigUInt64LE(inputAmount, 16);
|
|
869
|
+
quoteAmountToFund = inputAmount;
|
|
870
|
+
} else if (useExactSolAmount) {
|
|
871
|
+
const minTokensOut = calculateWithSlippageSell(buyTokenAmount, slippageBasisPoints);
|
|
813
872
|
data = Buffer.alloc(24);
|
|
814
873
|
PUMPFUN_BUY_EXACT_QUOTE_IN_V2_DISCRIMINATOR.copy(data, 0);
|
|
815
874
|
data.writeBigUInt64LE(inputAmount, 8);
|
|
816
875
|
data.writeBigUInt64LE(minTokensOut, 16);
|
|
876
|
+
quoteAmountToFund = inputAmount;
|
|
817
877
|
} else {
|
|
818
878
|
data = Buffer.alloc(24);
|
|
819
879
|
PUMPFUN_BUY_V2_DISCRIMINATOR.copy(data, 0);
|
|
820
880
|
data.writeBigUInt64LE(buyTokenAmount, 8);
|
|
821
881
|
data.writeBigUInt64LE(maxSolCost, 16);
|
|
882
|
+
quoteAmountToFund = maxSolCost;
|
|
883
|
+
}
|
|
884
|
+
if (createInputMintAta) {
|
|
885
|
+
pushCreateOrWrapUserTokenAccount(
|
|
886
|
+
instructions,
|
|
887
|
+
payerPubkey,
|
|
888
|
+
associatedQuoteUser,
|
|
889
|
+
quoteMint,
|
|
890
|
+
quoteTokenProgram,
|
|
891
|
+
quoteAmountToFund
|
|
892
|
+
);
|
|
822
893
|
}
|
|
823
894
|
const keys = [
|
|
824
895
|
{ pubkey: PUMPFUN_GLOBAL_ACCOUNT, isSigner: false, isWritable: false },
|
|
@@ -856,12 +927,24 @@ function buildPumpFunBuyV2Instructions(params) {
|
|
|
856
927
|
data
|
|
857
928
|
})
|
|
858
929
|
);
|
|
930
|
+
if (closeInputMintAta && quoteMint.equals(NATIVE_MINT)) {
|
|
931
|
+
instructions.push(
|
|
932
|
+
createCloseAccountInstruction(
|
|
933
|
+
associatedQuoteUser,
|
|
934
|
+
payerPubkey,
|
|
935
|
+
payerPubkey,
|
|
936
|
+
[],
|
|
937
|
+
quoteTokenProgram
|
|
938
|
+
)
|
|
939
|
+
);
|
|
940
|
+
}
|
|
859
941
|
return instructions;
|
|
860
942
|
}
|
|
861
943
|
function buildPumpFunSellV2Instructions(params) {
|
|
862
944
|
const {
|
|
863
945
|
payer,
|
|
864
946
|
inputMint,
|
|
947
|
+
outputMint = SOL_TOKEN_ACCOUNT2,
|
|
865
948
|
inputAmount,
|
|
866
949
|
slippageBasisPoints = BigInt(1e3),
|
|
867
950
|
fixedOutputAmount,
|
|
@@ -880,6 +963,7 @@ function buildPumpFunSellV2Instructions(params) {
|
|
|
880
963
|
const bondingCurveAddr = bondingCurve.account.equals(PublicKey2.default) || !bondingCurve.account ? getBondingCurvePda(inputMint) : bondingCurve.account;
|
|
881
964
|
const baseTokenProgram = effectivePumpMintTokenProgram(inputMint, protocolParams);
|
|
882
965
|
const quoteMint = effectiveQuoteMint(protocolParams);
|
|
966
|
+
validateV2SellQuoteMint(outputMint, quoteMint);
|
|
883
967
|
const quoteTokenProgram = TOKEN_PROGRAM_ID;
|
|
884
968
|
const associatedBaseBondingCurve = associatedTokenAddress(
|
|
885
969
|
inputMint,
|
|
@@ -1895,7 +1979,7 @@ import {
|
|
|
1895
1979
|
} from "@solana/web3.js";
|
|
1896
1980
|
import {
|
|
1897
1981
|
getAssociatedTokenAddressSync as getAssociatedTokenAddressSync2,
|
|
1898
|
-
createAssociatedTokenAccountInstruction
|
|
1982
|
+
createAssociatedTokenAccountInstruction,
|
|
1899
1983
|
TOKEN_PROGRAM_ID as TOKEN_PROGRAM_ID2,
|
|
1900
1984
|
createCloseAccountInstruction as createCloseAccountInstruction2,
|
|
1901
1985
|
NATIVE_MINT as NATIVE_MINT2,
|
|
@@ -2040,7 +2124,7 @@ function buildBonkBuyInstructions(params) {
|
|
|
2040
2124
|
if (createInputMintAta && !isUsd1Pool) {
|
|
2041
2125
|
const wsolAta = getAssociatedTokenAddressSync2(NATIVE_MINT2, payerPubkey, true, TOKEN_PROGRAM_ID2);
|
|
2042
2126
|
instructions.push(
|
|
2043
|
-
|
|
2127
|
+
createAssociatedTokenAccountInstruction(payerPubkey, wsolAta, payerPubkey, NATIVE_MINT2)
|
|
2044
2128
|
);
|
|
2045
2129
|
const transferIx = SystemProgram3.transfer({
|
|
2046
2130
|
fromPubkey: payerPubkey,
|
|
@@ -2052,7 +2136,7 @@ function buildBonkBuyInstructions(params) {
|
|
|
2052
2136
|
}
|
|
2053
2137
|
if (createOutputMintAta) {
|
|
2054
2138
|
instructions.push(
|
|
2055
|
-
|
|
2139
|
+
createAssociatedTokenAccountInstruction(
|
|
2056
2140
|
payerPubkey,
|
|
2057
2141
|
userBaseTokenAccount,
|
|
2058
2142
|
payerPubkey,
|
|
@@ -2151,7 +2235,7 @@ function buildBonkSellInstructions(params) {
|
|
|
2151
2235
|
if (createOutputMintAta && !isUsd1Pool) {
|
|
2152
2236
|
const wsolAta = getAssociatedTokenAddressSync2(NATIVE_MINT2, payerPubkey, true, TOKEN_PROGRAM_ID2);
|
|
2153
2237
|
instructions.push(
|
|
2154
|
-
|
|
2238
|
+
createAssociatedTokenAccountInstruction(payerPubkey, wsolAta, payerPubkey, NATIVE_MINT2)
|
|
2155
2239
|
);
|
|
2156
2240
|
}
|
|
2157
2241
|
const shareFeeRate = BigInt(0);
|
|
@@ -2318,14 +2402,13 @@ function getBonkVaultPDA(poolState, mint) {
|
|
|
2318
2402
|
import {
|
|
2319
2403
|
PublicKey as PublicKey5,
|
|
2320
2404
|
Keypair as Keypair3,
|
|
2321
|
-
TransactionInstruction as TransactionInstruction4
|
|
2405
|
+
TransactionInstruction as TransactionInstruction4,
|
|
2406
|
+
SystemProgram as SystemProgram4
|
|
2322
2407
|
} from "@solana/web3.js";
|
|
2323
2408
|
import {
|
|
2324
2409
|
getAssociatedTokenAddressSync as getAssociatedTokenAddressSync3,
|
|
2325
|
-
|
|
2326
|
-
TOKEN_PROGRAM_ID as TOKEN_PROGRAM_ID3,
|
|
2410
|
+
createAssociatedTokenAccountIdempotentInstruction as createAssociatedTokenAccountIdempotentInstruction2,
|
|
2327
2411
|
createCloseAccountInstruction as createCloseAccountInstruction3,
|
|
2328
|
-
NATIVE_MINT as NATIVE_MINT3,
|
|
2329
2412
|
createSyncNativeInstruction as createSyncNativeInstruction3
|
|
2330
2413
|
} from "@solana/spl-token";
|
|
2331
2414
|
var RAYDIUM_CPMM_PROGRAM_ID = new PublicKey5(
|
|
@@ -2435,34 +2518,38 @@ function buildRaydiumCpmmBuyInstructions(params) {
|
|
|
2435
2518
|
throw new Error("Pool must contain WSOL or USDC");
|
|
2436
2519
|
}
|
|
2437
2520
|
const isBaseIn = baseMint.equals(WSOL_TOKEN_ACCOUNT2) || baseMint.equals(USDC_TOKEN_ACCOUNT2);
|
|
2438
|
-
const
|
|
2521
|
+
const inputMint = isBaseIn ? baseMint : quoteMint;
|
|
2522
|
+
const inputTokenProgram = isBaseIn ? baseTokenProgram : quoteTokenProgram;
|
|
2523
|
+
const expectedOutputMint = isBaseIn ? quoteMint : baseMint;
|
|
2524
|
+
const outputTokenProgram = isBaseIn ? quoteTokenProgram : baseTokenProgram;
|
|
2525
|
+
if (!outputMint.equals(expectedOutputMint)) {
|
|
2526
|
+
throw new Error(`outputMint must match Raydium CPMM pool side ${expectedOutputMint.toBase58()}`);
|
|
2527
|
+
}
|
|
2439
2528
|
const poolState = protocolParams.poolState && !protocolParams.poolState.equals(PublicKey5.default) ? protocolParams.poolState : getRaydiumCpmmPoolPda(ammConfig, baseMint, quoteMint);
|
|
2440
|
-
const
|
|
2529
|
+
const minimumAmountOut = fixedOutputAmount ?? computeRaydiumCpmmSwapAmount(
|
|
2441
2530
|
baseReserve,
|
|
2442
2531
|
quoteReserve,
|
|
2443
2532
|
isBaseIn,
|
|
2444
2533
|
inputAmount,
|
|
2445
2534
|
slippageBasisPoints
|
|
2446
|
-
);
|
|
2447
|
-
const minimumAmountOut = fixedOutputAmount || swapResult.minAmountOut;
|
|
2448
|
-
const inputMint = isWsol ? WSOL_TOKEN_ACCOUNT2 : USDC_TOKEN_ACCOUNT2;
|
|
2535
|
+
).minAmountOut;
|
|
2449
2536
|
const inputTokenAccount = getAssociatedTokenAddressSync3(
|
|
2450
2537
|
inputMint,
|
|
2451
2538
|
payerPubkey,
|
|
2452
2539
|
true,
|
|
2453
|
-
|
|
2540
|
+
inputTokenProgram
|
|
2454
2541
|
);
|
|
2455
2542
|
const outputTokenAccount = getAssociatedTokenAddressSync3(
|
|
2456
2543
|
outputMint,
|
|
2457
2544
|
payerPubkey,
|
|
2458
2545
|
true,
|
|
2459
|
-
|
|
2546
|
+
outputTokenProgram
|
|
2460
2547
|
);
|
|
2461
2548
|
const inputVaultAccount = (() => {
|
|
2462
|
-
if (
|
|
2549
|
+
if (baseMint.equals(inputMint) && baseVault && !baseVault.equals(PublicKey5.default)) {
|
|
2463
2550
|
return baseVault;
|
|
2464
2551
|
}
|
|
2465
|
-
if (
|
|
2552
|
+
if (quoteMint.equals(inputMint) && quoteVault && !quoteVault.equals(PublicKey5.default)) {
|
|
2466
2553
|
return quoteVault;
|
|
2467
2554
|
}
|
|
2468
2555
|
return getRaydiumCpmmVaultPda(poolState, inputMint);
|
|
@@ -2477,34 +2564,43 @@ function buildRaydiumCpmmBuyInstructions(params) {
|
|
|
2477
2564
|
return getRaydiumCpmmVaultPda(poolState, outputMint);
|
|
2478
2565
|
})();
|
|
2479
2566
|
const observationStateAccount = observationState && !observationState.equals(PublicKey5.default) ? observationState : getRaydiumCpmmObservationStatePda(poolState);
|
|
2480
|
-
if (createInputMintAta
|
|
2481
|
-
const
|
|
2567
|
+
if (createInputMintAta) {
|
|
2568
|
+
const isInputWsol = inputMint.equals(WSOL_TOKEN_ACCOUNT2);
|
|
2482
2569
|
instructions.push(
|
|
2483
|
-
|
|
2570
|
+
createAssociatedTokenAccountIdempotentInstruction2(
|
|
2484
2571
|
payerPubkey,
|
|
2485
|
-
|
|
2572
|
+
inputTokenAccount,
|
|
2486
2573
|
payerPubkey,
|
|
2487
|
-
|
|
2488
|
-
|
|
2574
|
+
inputMint,
|
|
2575
|
+
inputTokenProgram
|
|
2489
2576
|
)
|
|
2490
2577
|
);
|
|
2491
|
-
|
|
2578
|
+
if (isInputWsol) {
|
|
2579
|
+
instructions.push(
|
|
2580
|
+
SystemProgram4.transfer({
|
|
2581
|
+
fromPubkey: payerPubkey,
|
|
2582
|
+
toPubkey: inputTokenAccount,
|
|
2583
|
+
lamports: inputAmount
|
|
2584
|
+
})
|
|
2585
|
+
);
|
|
2586
|
+
instructions.push(createSyncNativeInstruction3(inputTokenAccount));
|
|
2587
|
+
}
|
|
2492
2588
|
}
|
|
2493
2589
|
if (createOutputMintAta) {
|
|
2494
2590
|
instructions.push(
|
|
2495
|
-
|
|
2591
|
+
createAssociatedTokenAccountIdempotentInstruction2(
|
|
2496
2592
|
payerPubkey,
|
|
2497
2593
|
outputTokenAccount,
|
|
2498
2594
|
payerPubkey,
|
|
2499
2595
|
outputMint,
|
|
2500
|
-
|
|
2596
|
+
outputTokenProgram
|
|
2501
2597
|
)
|
|
2502
2598
|
);
|
|
2503
2599
|
}
|
|
2504
2600
|
const data = Buffer.alloc(24);
|
|
2505
|
-
RAYDIUM_CPMM_SWAP_BASE_IN_DISCRIMINATOR.copy(data, 0);
|
|
2601
|
+
(fixedOutputAmount !== void 0 ? RAYDIUM_CPMM_SWAP_BASE_OUT_DISCRIMINATOR : RAYDIUM_CPMM_SWAP_BASE_IN_DISCRIMINATOR).copy(data, 0);
|
|
2506
2602
|
data.writeBigUInt64LE(inputAmount, 8);
|
|
2507
|
-
data.writeBigUInt64LE(minimumAmountOut, 16);
|
|
2603
|
+
data.writeBigUInt64LE(fixedOutputAmount ?? minimumAmountOut, 16);
|
|
2508
2604
|
const accounts = [
|
|
2509
2605
|
{ pubkey: payerPubkey, isSigner: true, isWritable: true },
|
|
2510
2606
|
{ pubkey: RAYDIUM_CPMM_AUTHORITY, isSigner: false, isWritable: false },
|
|
@@ -2514,8 +2610,8 @@ function buildRaydiumCpmmBuyInstructions(params) {
|
|
|
2514
2610
|
{ pubkey: outputTokenAccount, isSigner: false, isWritable: true },
|
|
2515
2611
|
{ pubkey: inputVaultAccount, isSigner: false, isWritable: true },
|
|
2516
2612
|
{ pubkey: outputVaultAccount, isSigner: false, isWritable: true },
|
|
2517
|
-
{ pubkey:
|
|
2518
|
-
{ pubkey:
|
|
2613
|
+
{ pubkey: inputTokenProgram, isSigner: false, isWritable: false },
|
|
2614
|
+
{ pubkey: outputTokenProgram, isSigner: false, isWritable: false },
|
|
2519
2615
|
{ pubkey: inputMint, isSigner: false, isWritable: false },
|
|
2520
2616
|
{ pubkey: outputMint, isSigner: false, isWritable: false },
|
|
2521
2617
|
{ pubkey: observationStateAccount, isSigner: false, isWritable: true }
|
|
@@ -2527,10 +2623,9 @@ function buildRaydiumCpmmBuyInstructions(params) {
|
|
|
2527
2623
|
data
|
|
2528
2624
|
})
|
|
2529
2625
|
);
|
|
2530
|
-
if (closeInputMintAta &&
|
|
2531
|
-
const wsolAta = getAssociatedTokenAddressSync3(NATIVE_MINT3, payerPubkey, true);
|
|
2626
|
+
if (closeInputMintAta && inputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
|
|
2532
2627
|
instructions.push(
|
|
2533
|
-
createCloseAccountInstruction3(
|
|
2628
|
+
createCloseAccountInstruction3(inputTokenAccount, payerPubkey, payerPubkey, [], inputTokenProgram)
|
|
2534
2629
|
);
|
|
2535
2630
|
}
|
|
2536
2631
|
return instructions;
|
|
@@ -2572,28 +2667,32 @@ function buildRaydiumCpmmSellInstructions(params) {
|
|
|
2572
2667
|
throw new Error("Pool must contain WSOL or USDC");
|
|
2573
2668
|
}
|
|
2574
2669
|
const isQuoteOut = quoteMint.equals(WSOL_TOKEN_ACCOUNT2) || quoteMint.equals(USDC_TOKEN_ACCOUNT2);
|
|
2575
|
-
const
|
|
2670
|
+
const expectedInputMint = isQuoteOut ? baseMint : quoteMint;
|
|
2671
|
+
const inputTokenProgram = isQuoteOut ? baseTokenProgram : quoteTokenProgram;
|
|
2672
|
+
const outputMint = isQuoteOut ? quoteMint : baseMint;
|
|
2673
|
+
const outputTokenProgram = isQuoteOut ? quoteTokenProgram : baseTokenProgram;
|
|
2674
|
+
if (!inputMint.equals(expectedInputMint)) {
|
|
2675
|
+
throw new Error(`inputMint must match Raydium CPMM pool side ${expectedInputMint.toBase58()}`);
|
|
2676
|
+
}
|
|
2576
2677
|
const poolState = protocolParams.poolState && !protocolParams.poolState.equals(PublicKey5.default) ? protocolParams.poolState : getRaydiumCpmmPoolPda(ammConfig, baseMint, quoteMint);
|
|
2577
|
-
const
|
|
2678
|
+
const minimumAmountOut = fixedOutputAmount ?? computeRaydiumCpmmSwapAmount(
|
|
2578
2679
|
baseReserve,
|
|
2579
2680
|
quoteReserve,
|
|
2580
2681
|
isQuoteOut,
|
|
2581
2682
|
inputAmount,
|
|
2582
2683
|
slippageBasisPoints
|
|
2583
|
-
);
|
|
2584
|
-
const minimumAmountOut = fixedOutputAmount || swapResult.minAmountOut;
|
|
2585
|
-
const outputMint = isWsol ? WSOL_TOKEN_ACCOUNT2 : USDC_TOKEN_ACCOUNT2;
|
|
2684
|
+
).minAmountOut;
|
|
2586
2685
|
const inputTokenAccount = getAssociatedTokenAddressSync3(
|
|
2587
2686
|
inputMint,
|
|
2588
2687
|
payerPubkey,
|
|
2589
2688
|
true,
|
|
2590
|
-
|
|
2689
|
+
inputTokenProgram
|
|
2591
2690
|
);
|
|
2592
2691
|
const outputTokenAccount = getAssociatedTokenAddressSync3(
|
|
2593
2692
|
outputMint,
|
|
2594
2693
|
payerPubkey,
|
|
2595
2694
|
true,
|
|
2596
|
-
|
|
2695
|
+
outputTokenProgram
|
|
2597
2696
|
);
|
|
2598
2697
|
const inputVaultAccount = (() => {
|
|
2599
2698
|
if (baseMint.equals(inputMint) && baseVault && !baseVault.equals(PublicKey5.default)) {
|
|
@@ -2605,31 +2704,30 @@ function buildRaydiumCpmmSellInstructions(params) {
|
|
|
2605
2704
|
return getRaydiumCpmmVaultPda(poolState, inputMint);
|
|
2606
2705
|
})();
|
|
2607
2706
|
const outputVaultAccount = (() => {
|
|
2608
|
-
if (
|
|
2707
|
+
if (baseMint.equals(outputMint) && baseVault && !baseVault.equals(PublicKey5.default)) {
|
|
2609
2708
|
return baseVault;
|
|
2610
2709
|
}
|
|
2611
|
-
if (
|
|
2710
|
+
if (quoteMint.equals(outputMint) && quoteVault && !quoteVault.equals(PublicKey5.default)) {
|
|
2612
2711
|
return quoteVault;
|
|
2613
2712
|
}
|
|
2614
2713
|
return getRaydiumCpmmVaultPda(poolState, outputMint);
|
|
2615
2714
|
})();
|
|
2616
2715
|
const observationStateAccount = observationState && !observationState.equals(PublicKey5.default) ? observationState : getRaydiumCpmmObservationStatePda(poolState);
|
|
2617
|
-
if (createOutputMintAta
|
|
2618
|
-
const wsolAta = getAssociatedTokenAddressSync3(NATIVE_MINT3, payerPubkey, true);
|
|
2716
|
+
if (createOutputMintAta) {
|
|
2619
2717
|
instructions.push(
|
|
2620
|
-
|
|
2718
|
+
createAssociatedTokenAccountIdempotentInstruction2(
|
|
2621
2719
|
payerPubkey,
|
|
2622
|
-
|
|
2720
|
+
outputTokenAccount,
|
|
2623
2721
|
payerPubkey,
|
|
2624
|
-
|
|
2625
|
-
|
|
2722
|
+
outputMint,
|
|
2723
|
+
outputTokenProgram
|
|
2626
2724
|
)
|
|
2627
2725
|
);
|
|
2628
2726
|
}
|
|
2629
2727
|
const data = Buffer.alloc(24);
|
|
2630
|
-
RAYDIUM_CPMM_SWAP_BASE_IN_DISCRIMINATOR.copy(data, 0);
|
|
2728
|
+
(fixedOutputAmount !== void 0 ? RAYDIUM_CPMM_SWAP_BASE_OUT_DISCRIMINATOR : RAYDIUM_CPMM_SWAP_BASE_IN_DISCRIMINATOR).copy(data, 0);
|
|
2631
2729
|
data.writeBigUInt64LE(inputAmount, 8);
|
|
2632
|
-
data.writeBigUInt64LE(minimumAmountOut, 16);
|
|
2730
|
+
data.writeBigUInt64LE(fixedOutputAmount ?? minimumAmountOut, 16);
|
|
2633
2731
|
const accounts = [
|
|
2634
2732
|
{ pubkey: payerPubkey, isSigner: true, isWritable: true },
|
|
2635
2733
|
{ pubkey: RAYDIUM_CPMM_AUTHORITY, isSigner: false, isWritable: false },
|
|
@@ -2639,8 +2737,8 @@ function buildRaydiumCpmmSellInstructions(params) {
|
|
|
2639
2737
|
{ pubkey: outputTokenAccount, isSigner: false, isWritable: true },
|
|
2640
2738
|
{ pubkey: inputVaultAccount, isSigner: false, isWritable: true },
|
|
2641
2739
|
{ pubkey: outputVaultAccount, isSigner: false, isWritable: true },
|
|
2642
|
-
{ pubkey:
|
|
2643
|
-
{ pubkey:
|
|
2740
|
+
{ pubkey: inputTokenProgram, isSigner: false, isWritable: false },
|
|
2741
|
+
{ pubkey: outputTokenProgram, isSigner: false, isWritable: false },
|
|
2644
2742
|
{ pubkey: inputMint, isSigner: false, isWritable: false },
|
|
2645
2743
|
{ pubkey: outputMint, isSigner: false, isWritable: false },
|
|
2646
2744
|
{ pubkey: observationStateAccount, isSigner: false, isWritable: true }
|
|
@@ -2652,10 +2750,9 @@ function buildRaydiumCpmmSellInstructions(params) {
|
|
|
2652
2750
|
data
|
|
2653
2751
|
})
|
|
2654
2752
|
);
|
|
2655
|
-
if (closeOutputMintAta &&
|
|
2656
|
-
const wsolAta = getAssociatedTokenAddressSync3(NATIVE_MINT3, payerPubkey, true);
|
|
2753
|
+
if (closeOutputMintAta && outputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
|
|
2657
2754
|
instructions.push(
|
|
2658
|
-
createCloseAccountInstruction3(
|
|
2755
|
+
createCloseAccountInstruction3(outputTokenAccount, payerPubkey, payerPubkey, [], outputTokenProgram)
|
|
2659
2756
|
);
|
|
2660
2757
|
}
|
|
2661
2758
|
if (closeInputMintAta) {
|
|
@@ -2665,7 +2762,7 @@ function buildRaydiumCpmmSellInstructions(params) {
|
|
|
2665
2762
|
payerPubkey,
|
|
2666
2763
|
payerPubkey,
|
|
2667
2764
|
[],
|
|
2668
|
-
|
|
2765
|
+
inputTokenProgram
|
|
2669
2766
|
)
|
|
2670
2767
|
);
|
|
2671
2768
|
}
|
|
@@ -2798,16 +2895,18 @@ async function getRaydiumCPMMpoolTokenBalances(connection, poolState, token0Mint
|
|
|
2798
2895
|
import {
|
|
2799
2896
|
PublicKey as PublicKey6,
|
|
2800
2897
|
Keypair as Keypair4,
|
|
2801
|
-
TransactionInstruction as TransactionInstruction5
|
|
2898
|
+
TransactionInstruction as TransactionInstruction5,
|
|
2899
|
+
SystemProgram as SystemProgram5
|
|
2802
2900
|
} from "@solana/web3.js";
|
|
2803
2901
|
import {
|
|
2804
2902
|
getAssociatedTokenAddressSync as getAssociatedTokenAddressSync4,
|
|
2805
|
-
createAssociatedTokenAccountInstruction as
|
|
2806
|
-
TOKEN_PROGRAM_ID as
|
|
2903
|
+
createAssociatedTokenAccountInstruction as createAssociatedTokenAccountInstruction2,
|
|
2904
|
+
TOKEN_PROGRAM_ID as TOKEN_PROGRAM_ID3,
|
|
2807
2905
|
createCloseAccountInstruction as createCloseAccountInstruction4,
|
|
2808
|
-
NATIVE_MINT as
|
|
2906
|
+
NATIVE_MINT as NATIVE_MINT3,
|
|
2809
2907
|
createSyncNativeInstruction as createSyncNativeInstruction4
|
|
2810
2908
|
} from "@solana/spl-token";
|
|
2909
|
+
var SOL_TOKEN_ACCOUNT3 = new PublicKey6("So11111111111111111111111111111111111111111");
|
|
2811
2910
|
var RAYDIUM_AMM_V4_PROGRAM_ID = new PublicKey6(
|
|
2812
2911
|
"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"
|
|
2813
2912
|
);
|
|
@@ -2834,10 +2933,44 @@ function computeRaydiumAmmV4SwapAmount(coinReserve, pcReserve, isCoinIn, amountI
|
|
|
2834
2933
|
const minAmountOut = amountOut - amountOut * slippageBasisPoints / BigInt(1e4);
|
|
2835
2934
|
return { amountOut, minAmountOut };
|
|
2836
2935
|
}
|
|
2936
|
+
function isDefaultPublicKey(pubkey) {
|
|
2937
|
+
return pubkey.equals(PublicKey6.default);
|
|
2938
|
+
}
|
|
2939
|
+
function isMintMatch(requested, expected) {
|
|
2940
|
+
return requested.equals(expected) || expected.equals(NATIVE_MINT3) && requested.equals(SOL_TOKEN_ACCOUNT3);
|
|
2941
|
+
}
|
|
2942
|
+
function ensureExpectedMint(label, requested, expected) {
|
|
2943
|
+
if (!isDefaultPublicKey(requested) && !isMintMatch(requested, expected)) {
|
|
2944
|
+
throw new Error(
|
|
2945
|
+
`${label} must match the Raydium AMM v4 pool side (${expected.toBase58()}), got ${requested.toBase58()}`
|
|
2946
|
+
);
|
|
2947
|
+
}
|
|
2948
|
+
}
|
|
2949
|
+
function ensureMarketAccounts(params) {
|
|
2950
|
+
const required = [
|
|
2951
|
+
["ammOpenOrders", params.ammOpenOrders],
|
|
2952
|
+
["ammTargetOrders", params.ammTargetOrders],
|
|
2953
|
+
["serumProgram", params.serumProgram],
|
|
2954
|
+
["serumMarket", params.serumMarket],
|
|
2955
|
+
["serumBids", params.serumBids],
|
|
2956
|
+
["serumAsks", params.serumAsks],
|
|
2957
|
+
["serumEventQueue", params.serumEventQueue],
|
|
2958
|
+
["serumCoinVaultAccount", params.serumCoinVaultAccount],
|
|
2959
|
+
["serumPcVaultAccount", params.serumPcVaultAccount],
|
|
2960
|
+
["serumVaultSigner", params.serumVaultSigner]
|
|
2961
|
+
];
|
|
2962
|
+
for (const [name, account] of required) {
|
|
2963
|
+
if (isDefaultPublicKey(account)) {
|
|
2964
|
+
throw new Error(
|
|
2965
|
+
`Raydium AMM v4 requires ${name}; pass real market accounts from the AMM/market state`
|
|
2966
|
+
);
|
|
2967
|
+
}
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2837
2970
|
function buildRaydiumAmmV4BuyInstructions(params) {
|
|
2838
2971
|
const {
|
|
2839
2972
|
payer,
|
|
2840
|
-
outputMint,
|
|
2973
|
+
outputMint: requestedOutputMint,
|
|
2841
2974
|
inputAmount,
|
|
2842
2975
|
slippageBasisPoints = BigInt(1e3),
|
|
2843
2976
|
fixedOutputAmount,
|
|
@@ -2859,9 +2992,20 @@ function buildRaydiumAmmV4BuyInstructions(params) {
|
|
|
2859
2992
|
pcMint,
|
|
2860
2993
|
tokenCoin,
|
|
2861
2994
|
tokenPc,
|
|
2995
|
+
ammOpenOrders,
|
|
2996
|
+
ammTargetOrders,
|
|
2997
|
+
serumProgram,
|
|
2998
|
+
serumMarket,
|
|
2999
|
+
serumBids,
|
|
3000
|
+
serumAsks,
|
|
3001
|
+
serumEventQueue,
|
|
3002
|
+
serumCoinVaultAccount,
|
|
3003
|
+
serumPcVaultAccount,
|
|
3004
|
+
serumVaultSigner,
|
|
2862
3005
|
coinReserve,
|
|
2863
3006
|
pcReserve
|
|
2864
3007
|
} = protocolParams;
|
|
3008
|
+
ensureMarketAccounts(protocolParams);
|
|
2865
3009
|
const isWsol = coinMint.equals(WSOL_TOKEN_ACCOUNT2) || pcMint.equals(WSOL_TOKEN_ACCOUNT2);
|
|
2866
3010
|
const isUsdc = coinMint.equals(USDC_TOKEN_ACCOUNT2) || pcMint.equals(USDC_TOKEN_ACCOUNT2);
|
|
2867
3011
|
if (!isWsol && !isUsdc) {
|
|
@@ -2875,77 +3019,88 @@ function buildRaydiumAmmV4BuyInstructions(params) {
|
|
|
2875
3019
|
inputAmount,
|
|
2876
3020
|
slippageBasisPoints
|
|
2877
3021
|
);
|
|
2878
|
-
const minimumAmountOut = fixedOutputAmount
|
|
2879
|
-
const inputMint =
|
|
3022
|
+
const minimumAmountOut = fixedOutputAmount ?? swapResult.minAmountOut;
|
|
3023
|
+
const inputMint = isBaseIn ? coinMint : pcMint;
|
|
3024
|
+
const outputMint = isBaseIn ? pcMint : coinMint;
|
|
3025
|
+
ensureExpectedMint("outputMint", requestedOutputMint, outputMint);
|
|
2880
3026
|
const userSourceTokenAccount = getAssociatedTokenAddressSync4(
|
|
2881
3027
|
inputMint,
|
|
2882
3028
|
payerPubkey,
|
|
2883
3029
|
true,
|
|
2884
|
-
|
|
3030
|
+
TOKEN_PROGRAM_ID3
|
|
2885
3031
|
);
|
|
2886
3032
|
const userDestinationTokenAccount = getAssociatedTokenAddressSync4(
|
|
2887
3033
|
outputMint,
|
|
2888
3034
|
payerPubkey,
|
|
2889
3035
|
true,
|
|
2890
|
-
|
|
3036
|
+
TOKEN_PROGRAM_ID3
|
|
2891
3037
|
);
|
|
2892
|
-
if (createInputMintAta &&
|
|
2893
|
-
const wsolAta = getAssociatedTokenAddressSync4(
|
|
3038
|
+
if (createInputMintAta && inputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
|
|
3039
|
+
const wsolAta = getAssociatedTokenAddressSync4(NATIVE_MINT3, payerPubkey, true);
|
|
2894
3040
|
instructions.push(
|
|
2895
|
-
|
|
3041
|
+
createAssociatedTokenAccountInstruction2(
|
|
2896
3042
|
payerPubkey,
|
|
2897
3043
|
wsolAta,
|
|
2898
3044
|
payerPubkey,
|
|
2899
|
-
|
|
2900
|
-
|
|
3045
|
+
NATIVE_MINT3,
|
|
3046
|
+
TOKEN_PROGRAM_ID3
|
|
2901
3047
|
)
|
|
2902
3048
|
);
|
|
3049
|
+
instructions.push(
|
|
3050
|
+
SystemProgram5.transfer({
|
|
3051
|
+
fromPubkey: payerPubkey,
|
|
3052
|
+
toPubkey: wsolAta,
|
|
3053
|
+
lamports: Number(inputAmount)
|
|
3054
|
+
})
|
|
3055
|
+
);
|
|
2903
3056
|
instructions.push(createSyncNativeInstruction4(wsolAta));
|
|
3057
|
+
} else if (createInputMintAta) {
|
|
3058
|
+
instructions.push(
|
|
3059
|
+
createAssociatedTokenAccountInstruction2(
|
|
3060
|
+
payerPubkey,
|
|
3061
|
+
userSourceTokenAccount,
|
|
3062
|
+
payerPubkey,
|
|
3063
|
+
inputMint,
|
|
3064
|
+
TOKEN_PROGRAM_ID3
|
|
3065
|
+
)
|
|
3066
|
+
);
|
|
2904
3067
|
}
|
|
2905
3068
|
if (createOutputMintAta) {
|
|
2906
3069
|
instructions.push(
|
|
2907
|
-
|
|
3070
|
+
createAssociatedTokenAccountInstruction2(
|
|
2908
3071
|
payerPubkey,
|
|
2909
3072
|
userDestinationTokenAccount,
|
|
2910
3073
|
payerPubkey,
|
|
2911
3074
|
outputMint,
|
|
2912
|
-
|
|
3075
|
+
TOKEN_PROGRAM_ID3
|
|
2913
3076
|
)
|
|
2914
3077
|
);
|
|
2915
3078
|
}
|
|
2916
3079
|
const data = Buffer.alloc(17);
|
|
2917
|
-
RAYDIUM_AMM_V4_SWAP_BASE_IN_DISCRIMINATOR.copy(data, 0);
|
|
3080
|
+
(fixedOutputAmount !== void 0 ? RAYDIUM_AMM_V4_SWAP_BASE_OUT_DISCRIMINATOR : RAYDIUM_AMM_V4_SWAP_BASE_IN_DISCRIMINATOR).copy(data, 0);
|
|
2918
3081
|
data.writeBigUInt64LE(inputAmount, 1);
|
|
2919
3082
|
data.writeBigUInt64LE(minimumAmountOut, 9);
|
|
2920
3083
|
const accounts = [
|
|
2921
|
-
{ pubkey:
|
|
3084
|
+
{ pubkey: TOKEN_PROGRAM_ID3, isSigner: false, isWritable: false },
|
|
2922
3085
|
{ pubkey: amm, isSigner: false, isWritable: true },
|
|
2923
3086
|
{ pubkey: RAYDIUM_AMM_V4_AUTHORITY, isSigner: false, isWritable: false },
|
|
2924
|
-
{ pubkey:
|
|
2925
|
-
|
|
3087
|
+
{ pubkey: ammOpenOrders, isSigner: false, isWritable: true },
|
|
3088
|
+
{ pubkey: ammTargetOrders, isSigner: false, isWritable: true },
|
|
2926
3089
|
{ pubkey: tokenCoin, isSigner: false, isWritable: true },
|
|
2927
3090
|
// Pool Coin Token Account
|
|
2928
3091
|
{ pubkey: tokenPc, isSigner: false, isWritable: true },
|
|
2929
3092
|
// Pool Pc Token Account
|
|
2930
|
-
{ pubkey:
|
|
2931
|
-
|
|
2932
|
-
{ pubkey:
|
|
2933
|
-
|
|
2934
|
-
{ pubkey:
|
|
2935
|
-
|
|
2936
|
-
{ pubkey:
|
|
2937
|
-
|
|
2938
|
-
{ pubkey: amm, isSigner: false, isWritable: false },
|
|
2939
|
-
// Serum Event Queue (placeholder)
|
|
2940
|
-
{ pubkey: amm, isSigner: false, isWritable: false },
|
|
2941
|
-
// Serum Coin Vault Account (placeholder)
|
|
2942
|
-
{ pubkey: amm, isSigner: false, isWritable: false },
|
|
2943
|
-
// Serum Pc Vault Account (placeholder)
|
|
2944
|
-
{ pubkey: amm, isSigner: false, isWritable: false },
|
|
2945
|
-
// Serum Vault Signer (placeholder)
|
|
3093
|
+
{ pubkey: serumProgram, isSigner: false, isWritable: false },
|
|
3094
|
+
{ pubkey: serumMarket, isSigner: false, isWritable: true },
|
|
3095
|
+
{ pubkey: serumBids, isSigner: false, isWritable: true },
|
|
3096
|
+
{ pubkey: serumAsks, isSigner: false, isWritable: true },
|
|
3097
|
+
{ pubkey: serumEventQueue, isSigner: false, isWritable: true },
|
|
3098
|
+
{ pubkey: serumCoinVaultAccount, isSigner: false, isWritable: true },
|
|
3099
|
+
{ pubkey: serumPcVaultAccount, isSigner: false, isWritable: true },
|
|
3100
|
+
{ pubkey: serumVaultSigner, isSigner: false, isWritable: false },
|
|
2946
3101
|
{ pubkey: userSourceTokenAccount, isSigner: false, isWritable: true },
|
|
2947
3102
|
{ pubkey: userDestinationTokenAccount, isSigner: false, isWritable: true },
|
|
2948
|
-
{ pubkey: payerPubkey, isSigner: true, isWritable:
|
|
3103
|
+
{ pubkey: payerPubkey, isSigner: true, isWritable: false }
|
|
2949
3104
|
];
|
|
2950
3105
|
instructions.push(
|
|
2951
3106
|
new TransactionInstruction5({
|
|
@@ -2954,10 +3109,10 @@ function buildRaydiumAmmV4BuyInstructions(params) {
|
|
|
2954
3109
|
data
|
|
2955
3110
|
})
|
|
2956
3111
|
);
|
|
2957
|
-
if (closeInputMintAta &&
|
|
2958
|
-
const wsolAta = getAssociatedTokenAddressSync4(
|
|
3112
|
+
if (closeInputMintAta && inputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
|
|
3113
|
+
const wsolAta = getAssociatedTokenAddressSync4(NATIVE_MINT3, payerPubkey, true);
|
|
2959
3114
|
instructions.push(
|
|
2960
|
-
createCloseAccountInstruction4(wsolAta, payerPubkey, payerPubkey, [],
|
|
3115
|
+
createCloseAccountInstruction4(wsolAta, payerPubkey, payerPubkey, [], TOKEN_PROGRAM_ID3)
|
|
2961
3116
|
);
|
|
2962
3117
|
}
|
|
2963
3118
|
return instructions;
|
|
@@ -2965,7 +3120,8 @@ function buildRaydiumAmmV4BuyInstructions(params) {
|
|
|
2965
3120
|
function buildRaydiumAmmV4SellInstructions(params) {
|
|
2966
3121
|
const {
|
|
2967
3122
|
payer,
|
|
2968
|
-
inputMint,
|
|
3123
|
+
inputMint: requestedInputMint,
|
|
3124
|
+
outputMint: requestedOutputMint,
|
|
2969
3125
|
inputAmount,
|
|
2970
3126
|
slippageBasisPoints = BigInt(1e3),
|
|
2971
3127
|
fixedOutputAmount,
|
|
@@ -2987,9 +3143,20 @@ function buildRaydiumAmmV4SellInstructions(params) {
|
|
|
2987
3143
|
pcMint,
|
|
2988
3144
|
tokenCoin,
|
|
2989
3145
|
tokenPc,
|
|
3146
|
+
ammOpenOrders,
|
|
3147
|
+
ammTargetOrders,
|
|
3148
|
+
serumProgram,
|
|
3149
|
+
serumMarket,
|
|
3150
|
+
serumBids,
|
|
3151
|
+
serumAsks,
|
|
3152
|
+
serumEventQueue,
|
|
3153
|
+
serumCoinVaultAccount,
|
|
3154
|
+
serumPcVaultAccount,
|
|
3155
|
+
serumVaultSigner,
|
|
2990
3156
|
coinReserve,
|
|
2991
3157
|
pcReserve
|
|
2992
3158
|
} = protocolParams;
|
|
3159
|
+
ensureMarketAccounts(protocolParams);
|
|
2993
3160
|
const isWsol = coinMint.equals(WSOL_TOKEN_ACCOUNT2) || pcMint.equals(WSOL_TOKEN_ACCOUNT2);
|
|
2994
3161
|
const isUsdc = coinMint.equals(USDC_TOKEN_ACCOUNT2) || pcMint.equals(USDC_TOKEN_ACCOUNT2);
|
|
2995
3162
|
if (!isWsol && !isUsdc) {
|
|
@@ -3003,65 +3170,72 @@ function buildRaydiumAmmV4SellInstructions(params) {
|
|
|
3003
3170
|
inputAmount,
|
|
3004
3171
|
slippageBasisPoints
|
|
3005
3172
|
);
|
|
3006
|
-
const minimumAmountOut = fixedOutputAmount
|
|
3007
|
-
const outputMint =
|
|
3173
|
+
const minimumAmountOut = fixedOutputAmount ?? swapResult.minAmountOut;
|
|
3174
|
+
const outputMint = isBaseIn ? pcMint : coinMint;
|
|
3175
|
+
const inputMint = isBaseIn ? coinMint : pcMint;
|
|
3176
|
+
ensureExpectedMint("inputMint", requestedInputMint, inputMint);
|
|
3177
|
+
if (requestedOutputMint) {
|
|
3178
|
+
ensureExpectedMint("outputMint", requestedOutputMint, outputMint);
|
|
3179
|
+
}
|
|
3008
3180
|
const userSourceTokenAccount = getAssociatedTokenAddressSync4(
|
|
3009
3181
|
inputMint,
|
|
3010
3182
|
payerPubkey,
|
|
3011
3183
|
true,
|
|
3012
|
-
|
|
3184
|
+
TOKEN_PROGRAM_ID3
|
|
3013
3185
|
);
|
|
3014
3186
|
const userDestinationTokenAccount = getAssociatedTokenAddressSync4(
|
|
3015
3187
|
outputMint,
|
|
3016
3188
|
payerPubkey,
|
|
3017
3189
|
true,
|
|
3018
|
-
|
|
3190
|
+
TOKEN_PROGRAM_ID3
|
|
3019
3191
|
);
|
|
3020
|
-
if (createOutputMintAta &&
|
|
3021
|
-
const wsolAta = getAssociatedTokenAddressSync4(
|
|
3192
|
+
if (createOutputMintAta && outputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
|
|
3193
|
+
const wsolAta = getAssociatedTokenAddressSync4(NATIVE_MINT3, payerPubkey, true);
|
|
3022
3194
|
instructions.push(
|
|
3023
|
-
|
|
3195
|
+
createAssociatedTokenAccountInstruction2(
|
|
3024
3196
|
payerPubkey,
|
|
3025
3197
|
wsolAta,
|
|
3026
3198
|
payerPubkey,
|
|
3027
|
-
|
|
3028
|
-
|
|
3199
|
+
NATIVE_MINT3,
|
|
3200
|
+
TOKEN_PROGRAM_ID3
|
|
3201
|
+
)
|
|
3202
|
+
);
|
|
3203
|
+
} else if (createOutputMintAta) {
|
|
3204
|
+
instructions.push(
|
|
3205
|
+
createAssociatedTokenAccountInstruction2(
|
|
3206
|
+
payerPubkey,
|
|
3207
|
+
userDestinationTokenAccount,
|
|
3208
|
+
payerPubkey,
|
|
3209
|
+
outputMint,
|
|
3210
|
+
TOKEN_PROGRAM_ID3
|
|
3029
3211
|
)
|
|
3030
3212
|
);
|
|
3031
3213
|
}
|
|
3032
3214
|
const data = Buffer.alloc(17);
|
|
3033
|
-
RAYDIUM_AMM_V4_SWAP_BASE_IN_DISCRIMINATOR.copy(data, 0);
|
|
3215
|
+
(fixedOutputAmount !== void 0 ? RAYDIUM_AMM_V4_SWAP_BASE_OUT_DISCRIMINATOR : RAYDIUM_AMM_V4_SWAP_BASE_IN_DISCRIMINATOR).copy(data, 0);
|
|
3034
3216
|
data.writeBigUInt64LE(inputAmount, 1);
|
|
3035
3217
|
data.writeBigUInt64LE(minimumAmountOut, 9);
|
|
3036
3218
|
const accounts = [
|
|
3037
|
-
{ pubkey:
|
|
3219
|
+
{ pubkey: TOKEN_PROGRAM_ID3, isSigner: false, isWritable: false },
|
|
3038
3220
|
{ pubkey: amm, isSigner: false, isWritable: true },
|
|
3039
3221
|
{ pubkey: RAYDIUM_AMM_V4_AUTHORITY, isSigner: false, isWritable: false },
|
|
3040
|
-
{ pubkey:
|
|
3041
|
-
|
|
3222
|
+
{ pubkey: ammOpenOrders, isSigner: false, isWritable: true },
|
|
3223
|
+
{ pubkey: ammTargetOrders, isSigner: false, isWritable: true },
|
|
3042
3224
|
{ pubkey: tokenCoin, isSigner: false, isWritable: true },
|
|
3043
3225
|
// Pool Coin Token Account
|
|
3044
3226
|
{ pubkey: tokenPc, isSigner: false, isWritable: true },
|
|
3045
3227
|
// Pool Pc Token Account
|
|
3046
|
-
{ pubkey:
|
|
3047
|
-
|
|
3048
|
-
{ pubkey:
|
|
3049
|
-
|
|
3050
|
-
{ pubkey:
|
|
3051
|
-
|
|
3052
|
-
{ pubkey:
|
|
3053
|
-
|
|
3054
|
-
{ pubkey: amm, isSigner: false, isWritable: false },
|
|
3055
|
-
// Serum Event Queue
|
|
3056
|
-
{ pubkey: amm, isSigner: false, isWritable: false },
|
|
3057
|
-
// Serum Coin Vault Account
|
|
3058
|
-
{ pubkey: amm, isSigner: false, isWritable: false },
|
|
3059
|
-
// Serum Pc Vault Account
|
|
3060
|
-
{ pubkey: amm, isSigner: false, isWritable: false },
|
|
3061
|
-
// Serum Vault Signer
|
|
3228
|
+
{ pubkey: serumProgram, isSigner: false, isWritable: false },
|
|
3229
|
+
{ pubkey: serumMarket, isSigner: false, isWritable: true },
|
|
3230
|
+
{ pubkey: serumBids, isSigner: false, isWritable: true },
|
|
3231
|
+
{ pubkey: serumAsks, isSigner: false, isWritable: true },
|
|
3232
|
+
{ pubkey: serumEventQueue, isSigner: false, isWritable: true },
|
|
3233
|
+
{ pubkey: serumCoinVaultAccount, isSigner: false, isWritable: true },
|
|
3234
|
+
{ pubkey: serumPcVaultAccount, isSigner: false, isWritable: true },
|
|
3235
|
+
{ pubkey: serumVaultSigner, isSigner: false, isWritable: false },
|
|
3062
3236
|
{ pubkey: userSourceTokenAccount, isSigner: false, isWritable: true },
|
|
3063
3237
|
{ pubkey: userDestinationTokenAccount, isSigner: false, isWritable: true },
|
|
3064
|
-
{ pubkey: payerPubkey, isSigner: true, isWritable:
|
|
3238
|
+
{ pubkey: payerPubkey, isSigner: true, isWritable: false }
|
|
3065
3239
|
];
|
|
3066
3240
|
instructions.push(
|
|
3067
3241
|
new TransactionInstruction5({
|
|
@@ -3070,10 +3244,10 @@ function buildRaydiumAmmV4SellInstructions(params) {
|
|
|
3070
3244
|
data
|
|
3071
3245
|
})
|
|
3072
3246
|
);
|
|
3073
|
-
if (closeOutputMintAta &&
|
|
3074
|
-
const wsolAta = getAssociatedTokenAddressSync4(
|
|
3247
|
+
if (closeOutputMintAta && outputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
|
|
3248
|
+
const wsolAta = getAssociatedTokenAddressSync4(NATIVE_MINT3, payerPubkey, true);
|
|
3075
3249
|
instructions.push(
|
|
3076
|
-
createCloseAccountInstruction4(wsolAta, payerPubkey, payerPubkey, [],
|
|
3250
|
+
createCloseAccountInstruction4(wsolAta, payerPubkey, payerPubkey, [], TOKEN_PROGRAM_ID3)
|
|
3077
3251
|
);
|
|
3078
3252
|
}
|
|
3079
3253
|
if (closeInputMintAta) {
|
|
@@ -3083,13 +3257,14 @@ function buildRaydiumAmmV4SellInstructions(params) {
|
|
|
3083
3257
|
payerPubkey,
|
|
3084
3258
|
payerPubkey,
|
|
3085
3259
|
[],
|
|
3086
|
-
|
|
3260
|
+
TOKEN_PROGRAM_ID3
|
|
3087
3261
|
)
|
|
3088
3262
|
);
|
|
3089
3263
|
}
|
|
3090
3264
|
return instructions;
|
|
3091
3265
|
}
|
|
3092
3266
|
var AMM_INFO_SIZE = 752;
|
|
3267
|
+
var MARKET_STATE_SIZE = 388;
|
|
3093
3268
|
function decodeAmmInfo(data) {
|
|
3094
3269
|
if (data.length < AMM_INFO_SIZE) {
|
|
3095
3270
|
return null;
|
|
@@ -3207,6 +3382,65 @@ function decodeAmmInfo(data) {
|
|
|
3207
3382
|
return null;
|
|
3208
3383
|
}
|
|
3209
3384
|
}
|
|
3385
|
+
function decodeMarketState(data) {
|
|
3386
|
+
if (data.length < MARKET_STATE_SIZE) {
|
|
3387
|
+
return null;
|
|
3388
|
+
}
|
|
3389
|
+
try {
|
|
3390
|
+
let offset = 5;
|
|
3391
|
+
const readU64 = () => {
|
|
3392
|
+
const val = data.readBigUInt64LE(offset);
|
|
3393
|
+
offset += 8;
|
|
3394
|
+
return val;
|
|
3395
|
+
};
|
|
3396
|
+
const readPubkey = () => {
|
|
3397
|
+
const val = new PublicKey6(data.subarray(offset, offset + 32));
|
|
3398
|
+
offset += 32;
|
|
3399
|
+
return val;
|
|
3400
|
+
};
|
|
3401
|
+
readU64();
|
|
3402
|
+
readPubkey();
|
|
3403
|
+
const vaultSignerNonce = readU64();
|
|
3404
|
+
readPubkey();
|
|
3405
|
+
readPubkey();
|
|
3406
|
+
const serumCoinVaultAccount = readPubkey();
|
|
3407
|
+
readU64();
|
|
3408
|
+
readU64();
|
|
3409
|
+
const serumPcVaultAccount = readPubkey();
|
|
3410
|
+
readU64();
|
|
3411
|
+
readU64();
|
|
3412
|
+
readU64();
|
|
3413
|
+
readPubkey();
|
|
3414
|
+
const serumEventQueue = readPubkey();
|
|
3415
|
+
const serumBids = readPubkey();
|
|
3416
|
+
const serumAsks = readPubkey();
|
|
3417
|
+
return {
|
|
3418
|
+
vaultSignerNonce,
|
|
3419
|
+
serumCoinVaultAccount,
|
|
3420
|
+
serumPcVaultAccount,
|
|
3421
|
+
serumEventQueue,
|
|
3422
|
+
serumBids,
|
|
3423
|
+
serumAsks
|
|
3424
|
+
};
|
|
3425
|
+
} catch {
|
|
3426
|
+
return null;
|
|
3427
|
+
}
|
|
3428
|
+
}
|
|
3429
|
+
function deriveSerumVaultSigner(serumProgram, serumMarket, vaultSignerNonce) {
|
|
3430
|
+
const nonce = Buffer.alloc(8);
|
|
3431
|
+
nonce.writeBigUInt64LE(vaultSignerNonce);
|
|
3432
|
+
try {
|
|
3433
|
+
return PublicKey6.createProgramAddressSync(
|
|
3434
|
+
[serumMarket.toBuffer(), nonce],
|
|
3435
|
+
serumProgram
|
|
3436
|
+
);
|
|
3437
|
+
} catch {
|
|
3438
|
+
return PublicKey6.createProgramAddressSync(
|
|
3439
|
+
[serumMarket.toBuffer(), Buffer.from([Number(vaultSignerNonce & 0xffn)])],
|
|
3440
|
+
serumProgram
|
|
3441
|
+
);
|
|
3442
|
+
}
|
|
3443
|
+
}
|
|
3210
3444
|
async function fetchAmmInfo(connection, amm) {
|
|
3211
3445
|
const account = await connection.getAccountInfo(amm);
|
|
3212
3446
|
if (!account?.value?.data) {
|
|
@@ -3214,21 +3448,30 @@ async function fetchAmmInfo(connection, amm) {
|
|
|
3214
3448
|
}
|
|
3215
3449
|
return decodeAmmInfo(account.value.data);
|
|
3216
3450
|
}
|
|
3451
|
+
async function fetchMarketState(connection, market) {
|
|
3452
|
+
const account = await connection.getAccountInfo(market);
|
|
3453
|
+
if (!account?.value?.data) {
|
|
3454
|
+
return null;
|
|
3455
|
+
}
|
|
3456
|
+
return decodeMarketState(account.value.data);
|
|
3457
|
+
}
|
|
3217
3458
|
|
|
3218
3459
|
// src/instruction/meteora_damm_v2_builder.ts
|
|
3219
3460
|
import {
|
|
3220
3461
|
PublicKey as PublicKey7,
|
|
3221
3462
|
Keypair as Keypair5,
|
|
3222
|
-
TransactionInstruction as TransactionInstruction6
|
|
3463
|
+
TransactionInstruction as TransactionInstruction6,
|
|
3464
|
+
SystemProgram as SystemProgram6
|
|
3223
3465
|
} from "@solana/web3.js";
|
|
3224
3466
|
import {
|
|
3225
3467
|
getAssociatedTokenAddressSync as getAssociatedTokenAddressSync5,
|
|
3226
|
-
createAssociatedTokenAccountInstruction as
|
|
3227
|
-
TOKEN_PROGRAM_ID as
|
|
3468
|
+
createAssociatedTokenAccountInstruction as createAssociatedTokenAccountInstruction3,
|
|
3469
|
+
TOKEN_PROGRAM_ID as TOKEN_PROGRAM_ID4,
|
|
3228
3470
|
createCloseAccountInstruction as createCloseAccountInstruction5,
|
|
3229
|
-
NATIVE_MINT as
|
|
3471
|
+
NATIVE_MINT as NATIVE_MINT4,
|
|
3230
3472
|
createSyncNativeInstruction as createSyncNativeInstruction5
|
|
3231
3473
|
} from "@solana/spl-token";
|
|
3474
|
+
var SOL_TOKEN_ACCOUNT4 = new PublicKey7("So11111111111111111111111111111111111111111");
|
|
3232
3475
|
var METEORA_DAMM_V2_PROGRAM_ID = new PublicKey7(
|
|
3233
3476
|
"cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG"
|
|
3234
3477
|
);
|
|
@@ -3245,6 +3488,17 @@ var METEORA_DAMM_V2_SWAP_DISCRIMINATOR = Buffer.from([
|
|
|
3245
3488
|
135,
|
|
3246
3489
|
200
|
|
3247
3490
|
]);
|
|
3491
|
+
var METEORA_DAMM_V2_SWAP2_DISCRIMINATOR = Buffer.from([
|
|
3492
|
+
65,
|
|
3493
|
+
75,
|
|
3494
|
+
63,
|
|
3495
|
+
76,
|
|
3496
|
+
235,
|
|
3497
|
+
91,
|
|
3498
|
+
91,
|
|
3499
|
+
136
|
|
3500
|
+
]);
|
|
3501
|
+
var METEORA_DAMM_V2_SWAP_MODE_PARTIAL_FILL = 1;
|
|
3248
3502
|
var METEORA_DAMM_V2_EVENT_AUTHORITY_SEED = Buffer.from("__event_authority");
|
|
3249
3503
|
function getMeteoraDammV2EventAuthorityPda() {
|
|
3250
3504
|
const [pda] = PublicKey7.findProgramAddressSync(
|
|
@@ -3253,11 +3507,24 @@ function getMeteoraDammV2EventAuthorityPda() {
|
|
|
3253
3507
|
);
|
|
3254
3508
|
return pda;
|
|
3255
3509
|
}
|
|
3510
|
+
function isDefaultPublicKey2(pubkey) {
|
|
3511
|
+
return pubkey.equals(PublicKey7.default);
|
|
3512
|
+
}
|
|
3513
|
+
function isMintMatch2(requested, expected) {
|
|
3514
|
+
return requested.equals(expected) || expected.equals(NATIVE_MINT4) && requested.equals(SOL_TOKEN_ACCOUNT4);
|
|
3515
|
+
}
|
|
3516
|
+
function ensureExpectedMint2(label, requested, expected) {
|
|
3517
|
+
if (!isDefaultPublicKey2(requested) && !isMintMatch2(requested, expected)) {
|
|
3518
|
+
throw new Error(
|
|
3519
|
+
`${label} must match the Meteora DAMM v2 pool side (${expected.toBase58()}), got ${requested.toBase58()}`
|
|
3520
|
+
);
|
|
3521
|
+
}
|
|
3522
|
+
}
|
|
3256
3523
|
function buildMeteoraDammV2BuyInstructions(params) {
|
|
3257
3524
|
const {
|
|
3258
3525
|
payer,
|
|
3259
|
-
inputMint,
|
|
3260
|
-
outputMint,
|
|
3526
|
+
inputMint: requestedInputMint,
|
|
3527
|
+
outputMint: requestedOutputMint,
|
|
3261
3528
|
inputAmount,
|
|
3262
3529
|
fixedOutputAmount,
|
|
3263
3530
|
createInputMintAta = true,
|
|
@@ -3290,6 +3557,10 @@ function buildMeteoraDammV2BuyInstructions(params) {
|
|
|
3290
3557
|
throw new Error("Pool must contain WSOL or USDC");
|
|
3291
3558
|
}
|
|
3292
3559
|
const isAIn = tokenAMint.equals(WSOL_TOKEN_ACCOUNT2) || tokenAMint.equals(USDC_TOKEN_ACCOUNT2);
|
|
3560
|
+
const inputMint = isAIn ? tokenAMint : tokenBMint;
|
|
3561
|
+
const outputMint = isAIn ? tokenBMint : tokenAMint;
|
|
3562
|
+
ensureExpectedMint2("inputMint", requestedInputMint, inputMint);
|
|
3563
|
+
ensureExpectedMint2("outputMint", requestedOutputMint, outputMint);
|
|
3293
3564
|
const inputTokenAccount = getAssociatedTokenAddressSync5(
|
|
3294
3565
|
inputMint,
|
|
3295
3566
|
payerPubkey,
|
|
@@ -3303,34 +3574,54 @@ function buildMeteoraDammV2BuyInstructions(params) {
|
|
|
3303
3574
|
isAIn ? tokenBProgram : tokenAProgram
|
|
3304
3575
|
);
|
|
3305
3576
|
const eventAuthority = getMeteoraDammV2EventAuthorityPda();
|
|
3306
|
-
|
|
3307
|
-
|
|
3577
|
+
const inputTokenProgram = isAIn ? tokenAProgram : tokenBProgram;
|
|
3578
|
+
const outputTokenProgram = isAIn ? tokenBProgram : tokenAProgram;
|
|
3579
|
+
if (createInputMintAta && inputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
|
|
3580
|
+
const wsolAta = getAssociatedTokenAddressSync5(NATIVE_MINT4, payerPubkey, true);
|
|
3308
3581
|
instructions.push(
|
|
3309
|
-
|
|
3582
|
+
createAssociatedTokenAccountInstruction3(
|
|
3310
3583
|
payerPubkey,
|
|
3311
3584
|
wsolAta,
|
|
3312
3585
|
payerPubkey,
|
|
3313
|
-
|
|
3314
|
-
|
|
3586
|
+
NATIVE_MINT4,
|
|
3587
|
+
TOKEN_PROGRAM_ID4
|
|
3315
3588
|
)
|
|
3316
3589
|
);
|
|
3590
|
+
instructions.push(
|
|
3591
|
+
SystemProgram6.transfer({
|
|
3592
|
+
fromPubkey: payerPubkey,
|
|
3593
|
+
toPubkey: wsolAta,
|
|
3594
|
+
lamports: Number(inputAmount)
|
|
3595
|
+
})
|
|
3596
|
+
);
|
|
3317
3597
|
instructions.push(createSyncNativeInstruction5(wsolAta));
|
|
3598
|
+
} else if (createInputMintAta) {
|
|
3599
|
+
instructions.push(
|
|
3600
|
+
createAssociatedTokenAccountInstruction3(
|
|
3601
|
+
payerPubkey,
|
|
3602
|
+
inputTokenAccount,
|
|
3603
|
+
payerPubkey,
|
|
3604
|
+
inputMint,
|
|
3605
|
+
inputTokenProgram
|
|
3606
|
+
)
|
|
3607
|
+
);
|
|
3318
3608
|
}
|
|
3319
3609
|
if (createOutputMintAta) {
|
|
3320
3610
|
instructions.push(
|
|
3321
|
-
|
|
3611
|
+
createAssociatedTokenAccountInstruction3(
|
|
3322
3612
|
payerPubkey,
|
|
3323
3613
|
outputTokenAccount,
|
|
3324
3614
|
payerPubkey,
|
|
3325
3615
|
outputMint,
|
|
3326
|
-
|
|
3616
|
+
outputTokenProgram
|
|
3327
3617
|
)
|
|
3328
3618
|
);
|
|
3329
3619
|
}
|
|
3330
|
-
const data = Buffer.alloc(
|
|
3331
|
-
|
|
3620
|
+
const data = Buffer.alloc(25);
|
|
3621
|
+
METEORA_DAMM_V2_SWAP2_DISCRIMINATOR.copy(data, 0);
|
|
3332
3622
|
data.writeBigUInt64LE(inputAmount, 8);
|
|
3333
3623
|
data.writeBigUInt64LE(fixedOutputAmount, 16);
|
|
3624
|
+
data.writeUInt8(METEORA_DAMM_V2_SWAP_MODE_PARTIAL_FILL, 24);
|
|
3334
3625
|
const accounts = [
|
|
3335
3626
|
{ pubkey: METEORA_DAMM_V2_AUTHORITY, isSigner: false, isWritable: false },
|
|
3336
3627
|
{ pubkey: pool, isSigner: false, isWritable: true },
|
|
@@ -3343,8 +3634,6 @@ function buildMeteoraDammV2BuyInstructions(params) {
|
|
|
3343
3634
|
{ pubkey: payerPubkey, isSigner: true, isWritable: true },
|
|
3344
3635
|
{ pubkey: tokenAProgram, isSigner: false, isWritable: false },
|
|
3345
3636
|
{ pubkey: tokenBProgram, isSigner: false, isWritable: false },
|
|
3346
|
-
{ pubkey: METEORA_DAMM_V2_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
3347
|
-
// Referral Token Account (placeholder)
|
|
3348
3637
|
{ pubkey: eventAuthority, isSigner: false, isWritable: false },
|
|
3349
3638
|
{ pubkey: METEORA_DAMM_V2_PROGRAM_ID, isSigner: false, isWritable: false }
|
|
3350
3639
|
];
|
|
@@ -3355,10 +3644,10 @@ function buildMeteoraDammV2BuyInstructions(params) {
|
|
|
3355
3644
|
data
|
|
3356
3645
|
})
|
|
3357
3646
|
);
|
|
3358
|
-
if (closeInputMintAta &&
|
|
3359
|
-
const wsolAta = getAssociatedTokenAddressSync5(
|
|
3647
|
+
if (closeInputMintAta && inputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
|
|
3648
|
+
const wsolAta = getAssociatedTokenAddressSync5(NATIVE_MINT4, payerPubkey, true);
|
|
3360
3649
|
instructions.push(
|
|
3361
|
-
createCloseAccountInstruction5(wsolAta, payerPubkey, payerPubkey, [],
|
|
3650
|
+
createCloseAccountInstruction5(wsolAta, payerPubkey, payerPubkey, [], TOKEN_PROGRAM_ID4)
|
|
3362
3651
|
);
|
|
3363
3652
|
}
|
|
3364
3653
|
return instructions;
|
|
@@ -3366,8 +3655,8 @@ function buildMeteoraDammV2BuyInstructions(params) {
|
|
|
3366
3655
|
function buildMeteoraDammV2SellInstructions(params) {
|
|
3367
3656
|
const {
|
|
3368
3657
|
payer,
|
|
3369
|
-
inputMint,
|
|
3370
|
-
outputMint,
|
|
3658
|
+
inputMint: requestedInputMint,
|
|
3659
|
+
outputMint: requestedOutputMint,
|
|
3371
3660
|
inputAmount,
|
|
3372
3661
|
fixedOutputAmount,
|
|
3373
3662
|
createOutputMintAta = true,
|
|
@@ -3400,6 +3689,10 @@ function buildMeteoraDammV2SellInstructions(params) {
|
|
|
3400
3689
|
throw new Error("Pool must contain WSOL or USDC");
|
|
3401
3690
|
}
|
|
3402
3691
|
const isAIn = tokenBMint.equals(WSOL_TOKEN_ACCOUNT2) || tokenBMint.equals(USDC_TOKEN_ACCOUNT2);
|
|
3692
|
+
const inputMint = isAIn ? tokenAMint : tokenBMint;
|
|
3693
|
+
const outputMint = isAIn ? tokenBMint : tokenAMint;
|
|
3694
|
+
ensureExpectedMint2("inputMint", requestedInputMint, inputMint);
|
|
3695
|
+
ensureExpectedMint2("outputMint", requestedOutputMint, outputMint);
|
|
3403
3696
|
const inputTokenAccount = getAssociatedTokenAddressSync5(
|
|
3404
3697
|
inputMint,
|
|
3405
3698
|
payerPubkey,
|
|
@@ -3413,22 +3706,35 @@ function buildMeteoraDammV2SellInstructions(params) {
|
|
|
3413
3706
|
isAIn ? tokenBProgram : tokenAProgram
|
|
3414
3707
|
);
|
|
3415
3708
|
const eventAuthority = getMeteoraDammV2EventAuthorityPda();
|
|
3416
|
-
|
|
3417
|
-
|
|
3709
|
+
const inputTokenProgram = isAIn ? tokenAProgram : tokenBProgram;
|
|
3710
|
+
const outputTokenProgram = isAIn ? tokenBProgram : tokenAProgram;
|
|
3711
|
+
if (createOutputMintAta && outputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
|
|
3712
|
+
const wsolAta = getAssociatedTokenAddressSync5(NATIVE_MINT4, payerPubkey, true);
|
|
3418
3713
|
instructions.push(
|
|
3419
|
-
|
|
3714
|
+
createAssociatedTokenAccountInstruction3(
|
|
3420
3715
|
payerPubkey,
|
|
3421
3716
|
wsolAta,
|
|
3422
3717
|
payerPubkey,
|
|
3423
|
-
|
|
3424
|
-
|
|
3718
|
+
NATIVE_MINT4,
|
|
3719
|
+
TOKEN_PROGRAM_ID4
|
|
3720
|
+
)
|
|
3721
|
+
);
|
|
3722
|
+
} else if (createOutputMintAta) {
|
|
3723
|
+
instructions.push(
|
|
3724
|
+
createAssociatedTokenAccountInstruction3(
|
|
3725
|
+
payerPubkey,
|
|
3726
|
+
outputTokenAccount,
|
|
3727
|
+
payerPubkey,
|
|
3728
|
+
outputMint,
|
|
3729
|
+
outputTokenProgram
|
|
3425
3730
|
)
|
|
3426
3731
|
);
|
|
3427
3732
|
}
|
|
3428
|
-
const data = Buffer.alloc(
|
|
3429
|
-
|
|
3733
|
+
const data = Buffer.alloc(25);
|
|
3734
|
+
METEORA_DAMM_V2_SWAP2_DISCRIMINATOR.copy(data, 0);
|
|
3430
3735
|
data.writeBigUInt64LE(inputAmount, 8);
|
|
3431
3736
|
data.writeBigUInt64LE(fixedOutputAmount, 16);
|
|
3737
|
+
data.writeUInt8(METEORA_DAMM_V2_SWAP_MODE_PARTIAL_FILL, 24);
|
|
3432
3738
|
const accounts = [
|
|
3433
3739
|
{ pubkey: METEORA_DAMM_V2_AUTHORITY, isSigner: false, isWritable: false },
|
|
3434
3740
|
{ pubkey: pool, isSigner: false, isWritable: true },
|
|
@@ -3441,8 +3747,6 @@ function buildMeteoraDammV2SellInstructions(params) {
|
|
|
3441
3747
|
{ pubkey: payerPubkey, isSigner: true, isWritable: true },
|
|
3442
3748
|
{ pubkey: tokenAProgram, isSigner: false, isWritable: false },
|
|
3443
3749
|
{ pubkey: tokenBProgram, isSigner: false, isWritable: false },
|
|
3444
|
-
{ pubkey: METEORA_DAMM_V2_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
3445
|
-
// Referral Token Account
|
|
3446
3750
|
{ pubkey: eventAuthority, isSigner: false, isWritable: false },
|
|
3447
3751
|
{ pubkey: METEORA_DAMM_V2_PROGRAM_ID, isSigner: false, isWritable: false }
|
|
3448
3752
|
];
|
|
@@ -3453,10 +3757,10 @@ function buildMeteoraDammV2SellInstructions(params) {
|
|
|
3453
3757
|
data
|
|
3454
3758
|
})
|
|
3455
3759
|
);
|
|
3456
|
-
if (closeOutputMintAta &&
|
|
3457
|
-
const wsolAta = getAssociatedTokenAddressSync5(
|
|
3760
|
+
if (closeOutputMintAta && outputMint.equals(WSOL_TOKEN_ACCOUNT2)) {
|
|
3761
|
+
const wsolAta = getAssociatedTokenAddressSync5(NATIVE_MINT4, payerPubkey, true);
|
|
3458
3762
|
instructions.push(
|
|
3459
|
-
createCloseAccountInstruction5(wsolAta, payerPubkey, payerPubkey, [],
|
|
3763
|
+
createCloseAccountInstruction5(wsolAta, payerPubkey, payerPubkey, [], TOKEN_PROGRAM_ID4)
|
|
3460
3764
|
);
|
|
3461
3765
|
}
|
|
3462
3766
|
if (closeInputMintAta) {
|
|
@@ -3541,14 +3845,14 @@ import {
|
|
|
3541
3845
|
SystemProgram as SystemProgram7,
|
|
3542
3846
|
SYSVAR_RENT_PUBKEY as SYSVAR_RENT_PUBKEY2
|
|
3543
3847
|
} from "@solana/web3.js";
|
|
3544
|
-
var
|
|
3848
|
+
var TOKEN_PROGRAM_ID5 = new PublicKey8("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
|
|
3545
3849
|
var TOKEN_2022_PROGRAM_ID2 = new PublicKey8("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb");
|
|
3546
3850
|
var ASSOCIATED_TOKEN_PROGRAM_ID = new PublicKey8("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
|
|
3547
3851
|
var TokenInstructionBuilder = class {
|
|
3548
3852
|
/**
|
|
3549
3853
|
* Create InitializeMint instruction
|
|
3550
3854
|
*/
|
|
3551
|
-
static initializeMint(mint, decimals, mintAuthority, freezeAuthority, tokenProgram =
|
|
3855
|
+
static initializeMint(mint, decimals, mintAuthority, freezeAuthority, tokenProgram = TOKEN_PROGRAM_ID5) {
|
|
3552
3856
|
const keys = [
|
|
3553
3857
|
{ pubkey: mint, isSigner: false, isWritable: true },
|
|
3554
3858
|
{ pubkey: SYSVAR_RENT_PUBKEY2, isSigner: false, isWritable: false }
|
|
@@ -3571,7 +3875,7 @@ var TokenInstructionBuilder = class {
|
|
|
3571
3875
|
/**
|
|
3572
3876
|
* Create InitializeAccount instruction
|
|
3573
3877
|
*/
|
|
3574
|
-
static initializeAccount(account, mint, owner, tokenProgram =
|
|
3878
|
+
static initializeAccount(account, mint, owner, tokenProgram = TOKEN_PROGRAM_ID5) {
|
|
3575
3879
|
const keys = [
|
|
3576
3880
|
{ pubkey: account, isSigner: false, isWritable: true },
|
|
3577
3881
|
{ pubkey: mint, isSigner: false, isWritable: false },
|
|
@@ -3588,7 +3892,7 @@ var TokenInstructionBuilder = class {
|
|
|
3588
3892
|
/**
|
|
3589
3893
|
* Create Transfer instruction
|
|
3590
3894
|
*/
|
|
3591
|
-
static transfer(source, destination, owner, amount, multiSigners = [], tokenProgram =
|
|
3895
|
+
static transfer(source, destination, owner, amount, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
|
|
3592
3896
|
const keys = [
|
|
3593
3897
|
{ pubkey: source, isSigner: false, isWritable: true },
|
|
3594
3898
|
{ pubkey: destination, isSigner: false, isWritable: true },
|
|
@@ -3611,7 +3915,7 @@ var TokenInstructionBuilder = class {
|
|
|
3611
3915
|
/**
|
|
3612
3916
|
* Create TransferChecked instruction
|
|
3613
3917
|
*/
|
|
3614
|
-
static transferChecked(source, mint, destination, owner, amount, decimals, multiSigners = [], tokenProgram =
|
|
3918
|
+
static transferChecked(source, mint, destination, owner, amount, decimals, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
|
|
3615
3919
|
const keys = [
|
|
3616
3920
|
{ pubkey: source, isSigner: false, isWritable: true },
|
|
3617
3921
|
{ pubkey: mint, isSigner: false, isWritable: false },
|
|
@@ -3636,7 +3940,7 @@ var TokenInstructionBuilder = class {
|
|
|
3636
3940
|
/**
|
|
3637
3941
|
* Create MintTo instruction
|
|
3638
3942
|
*/
|
|
3639
|
-
static mintTo(mint, destination, authority, amount, multiSigners = [], tokenProgram =
|
|
3943
|
+
static mintTo(mint, destination, authority, amount, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
|
|
3640
3944
|
const keys = [
|
|
3641
3945
|
{ pubkey: mint, isSigner: false, isWritable: true },
|
|
3642
3946
|
{ pubkey: destination, isSigner: false, isWritable: true },
|
|
@@ -3659,7 +3963,7 @@ var TokenInstructionBuilder = class {
|
|
|
3659
3963
|
/**
|
|
3660
3964
|
* Create Burn instruction
|
|
3661
3965
|
*/
|
|
3662
|
-
static burn(account, mint, owner, amount, multiSigners = [], tokenProgram =
|
|
3966
|
+
static burn(account, mint, owner, amount, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
|
|
3663
3967
|
const keys = [
|
|
3664
3968
|
{ pubkey: account, isSigner: false, isWritable: true },
|
|
3665
3969
|
{ pubkey: mint, isSigner: false, isWritable: true },
|
|
@@ -3682,7 +3986,7 @@ var TokenInstructionBuilder = class {
|
|
|
3682
3986
|
/**
|
|
3683
3987
|
* Create Approve instruction
|
|
3684
3988
|
*/
|
|
3685
|
-
static approve(account, delegate, owner, amount, multiSigners = [], tokenProgram =
|
|
3989
|
+
static approve(account, delegate, owner, amount, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
|
|
3686
3990
|
const keys = [
|
|
3687
3991
|
{ pubkey: account, isSigner: false, isWritable: true },
|
|
3688
3992
|
{ pubkey: delegate, isSigner: false, isWritable: false },
|
|
@@ -3705,7 +4009,7 @@ var TokenInstructionBuilder = class {
|
|
|
3705
4009
|
/**
|
|
3706
4010
|
* Create Revoke instruction
|
|
3707
4011
|
*/
|
|
3708
|
-
static revoke(account, owner, multiSigners = [], tokenProgram =
|
|
4012
|
+
static revoke(account, owner, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
|
|
3709
4013
|
const keys = [
|
|
3710
4014
|
{ pubkey: account, isSigner: false, isWritable: true },
|
|
3711
4015
|
{ pubkey: owner, isSigner: multiSigners.length === 0, isWritable: false },
|
|
@@ -3725,7 +4029,7 @@ var TokenInstructionBuilder = class {
|
|
|
3725
4029
|
/**
|
|
3726
4030
|
* Create CloseAccount instruction
|
|
3727
4031
|
*/
|
|
3728
|
-
static closeAccount(account, destination, owner, multiSigners = [], tokenProgram =
|
|
4032
|
+
static closeAccount(account, destination, owner, multiSigners = [], tokenProgram = TOKEN_PROGRAM_ID5) {
|
|
3729
4033
|
const keys = [
|
|
3730
4034
|
{ pubkey: account, isSigner: false, isWritable: true },
|
|
3731
4035
|
{ pubkey: destination, isSigner: false, isWritable: true },
|
|
@@ -3746,7 +4050,7 @@ var TokenInstructionBuilder = class {
|
|
|
3746
4050
|
/**
|
|
3747
4051
|
* Create SyncNative instruction (for WSOL accounts)
|
|
3748
4052
|
*/
|
|
3749
|
-
static syncNative(nativeAccount, tokenProgram =
|
|
4053
|
+
static syncNative(nativeAccount, tokenProgram = TOKEN_PROGRAM_ID5) {
|
|
3750
4054
|
const keys = [{ pubkey: nativeAccount, isSigner: false, isWritable: true }];
|
|
3751
4055
|
const data = Buffer.from([17 /* SyncNative */]);
|
|
3752
4056
|
return new TransactionInstruction7({
|
|
@@ -3760,7 +4064,7 @@ var TokenUtil = class {
|
|
|
3760
4064
|
/**
|
|
3761
4065
|
* Calculate associated token account address
|
|
3762
4066
|
*/
|
|
3763
|
-
static async getAssociatedTokenAddress(mint, owner, _allowOwnerOffCurve = false, tokenProgram =
|
|
4067
|
+
static async getAssociatedTokenAddress(mint, owner, _allowOwnerOffCurve = false, tokenProgram = TOKEN_PROGRAM_ID5, associatedTokenProgram = ASSOCIATED_TOKEN_PROGRAM_ID) {
|
|
3764
4068
|
const [address] = await PublicKey8.findProgramAddress(
|
|
3765
4069
|
[owner.toBuffer(), tokenProgram.toBuffer(), mint.toBuffer()],
|
|
3766
4070
|
associatedTokenProgram
|
|
@@ -3770,7 +4074,7 @@ var TokenUtil = class {
|
|
|
3770
4074
|
/**
|
|
3771
4075
|
* Create associated token account idempotent instruction
|
|
3772
4076
|
*/
|
|
3773
|
-
static createAssociatedTokenAccountIdempotentInstruction(payer, associatedToken, owner, mint, tokenProgram =
|
|
4077
|
+
static createAssociatedTokenAccountIdempotentInstruction(payer, associatedToken, owner, mint, tokenProgram = TOKEN_PROGRAM_ID5, associatedTokenProgram = ASSOCIATED_TOKEN_PROGRAM_ID) {
|
|
3774
4078
|
const keys = [
|
|
3775
4079
|
{ pubkey: payer, isSigner: true, isWritable: true },
|
|
3776
4080
|
{ pubkey: associatedToken, isSigner: false, isWritable: true },
|
|
@@ -3790,7 +4094,7 @@ var TokenUtil = class {
|
|
|
3790
4094
|
/**
|
|
3791
4095
|
* Create associated token account instruction
|
|
3792
4096
|
*/
|
|
3793
|
-
static createAssociatedTokenAccountInstruction(payer, associatedToken, owner, mint, tokenProgram =
|
|
4097
|
+
static createAssociatedTokenAccountInstruction(payer, associatedToken, owner, mint, tokenProgram = TOKEN_PROGRAM_ID5, associatedTokenProgram = ASSOCIATED_TOKEN_PROGRAM_ID) {
|
|
3794
4098
|
const keys = [
|
|
3795
4099
|
{ pubkey: payer, isSigner: true, isWritable: true },
|
|
3796
4100
|
{ pubkey: associatedToken, isSigner: false, isWritable: true },
|
|
@@ -3836,7 +4140,7 @@ var TokenUtil = class {
|
|
|
3836
4140
|
}
|
|
3837
4141
|
};
|
|
3838
4142
|
var WSOL_MINT2 = new PublicKey8("So11111111111111111111111111111111111111112");
|
|
3839
|
-
var
|
|
4143
|
+
var NATIVE_MINT5 = new PublicKey8("So11111111111111111111111111111111111111111");
|
|
3840
4144
|
var USDC_MINT2 = new PublicKey8("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
|
|
3841
4145
|
var USDT_MINT = new PublicKey8("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");
|
|
3842
4146
|
|
|
@@ -4075,23 +4379,6 @@ async function confirmAnyTransactionSignature(connection, signatures, options) {
|
|
|
4075
4379
|
);
|
|
4076
4380
|
}
|
|
4077
4381
|
|
|
4078
|
-
// src/common/map-pool.ts
|
|
4079
|
-
async function mapWithConcurrencyLimit(items, concurrency, fn) {
|
|
4080
|
-
if (items.length === 0) return [];
|
|
4081
|
-
const limit = Math.max(1, Math.min(concurrency, items.length));
|
|
4082
|
-
const results = new Array(items.length);
|
|
4083
|
-
let next = 0;
|
|
4084
|
-
const worker = async () => {
|
|
4085
|
-
for (; ; ) {
|
|
4086
|
-
const i = next++;
|
|
4087
|
-
if (i >= items.length) return;
|
|
4088
|
-
results[i] = await fn(items[i], i);
|
|
4089
|
-
}
|
|
4090
|
-
};
|
|
4091
|
-
await Promise.all(Array.from({ length: limit }, () => worker()));
|
|
4092
|
-
return results;
|
|
4093
|
-
}
|
|
4094
|
-
|
|
4095
4382
|
// src/execution/execution.ts
|
|
4096
4383
|
var BYTES_PER_ACCOUNT = 32;
|
|
4097
4384
|
var MAX_INSTRUCTIONS_WARN = 64;
|
|
@@ -4517,12 +4804,22 @@ var RaydiumCpmmParams = class _RaydiumCpmmParams {
|
|
|
4517
4804
|
}
|
|
4518
4805
|
};
|
|
4519
4806
|
var RaydiumAmmV4Params = class _RaydiumAmmV4Params {
|
|
4520
|
-
constructor(amm, coinMint, pcMint, tokenCoin, tokenPc, coinReserve, pcReserve) {
|
|
4807
|
+
constructor(amm, coinMint, pcMint, tokenCoin, tokenPc, ammOpenOrders, ammTargetOrders, serumProgram, serumMarket, serumBids, serumAsks, serumEventQueue, serumCoinVaultAccount, serumPcVaultAccount, serumVaultSigner, coinReserve, pcReserve) {
|
|
4521
4808
|
this.amm = amm;
|
|
4522
4809
|
this.coinMint = coinMint;
|
|
4523
4810
|
this.pcMint = pcMint;
|
|
4524
4811
|
this.tokenCoin = tokenCoin;
|
|
4525
4812
|
this.tokenPc = tokenPc;
|
|
4813
|
+
this.ammOpenOrders = ammOpenOrders;
|
|
4814
|
+
this.ammTargetOrders = ammTargetOrders;
|
|
4815
|
+
this.serumProgram = serumProgram;
|
|
4816
|
+
this.serumMarket = serumMarket;
|
|
4817
|
+
this.serumBids = serumBids;
|
|
4818
|
+
this.serumAsks = serumAsks;
|
|
4819
|
+
this.serumEventQueue = serumEventQueue;
|
|
4820
|
+
this.serumCoinVaultAccount = serumCoinVaultAccount;
|
|
4821
|
+
this.serumPcVaultAccount = serumPcVaultAccount;
|
|
4822
|
+
this.serumVaultSigner = serumVaultSigner;
|
|
4526
4823
|
this.coinReserve = coinReserve;
|
|
4527
4824
|
this.pcReserve = pcReserve;
|
|
4528
4825
|
}
|
|
@@ -4531,6 +4828,16 @@ var RaydiumAmmV4Params = class _RaydiumAmmV4Params {
|
|
|
4531
4828
|
pcMint;
|
|
4532
4829
|
tokenCoin;
|
|
4533
4830
|
tokenPc;
|
|
4831
|
+
ammOpenOrders;
|
|
4832
|
+
ammTargetOrders;
|
|
4833
|
+
serumProgram;
|
|
4834
|
+
serumMarket;
|
|
4835
|
+
serumBids;
|
|
4836
|
+
serumAsks;
|
|
4837
|
+
serumEventQueue;
|
|
4838
|
+
serumCoinVaultAccount;
|
|
4839
|
+
serumPcVaultAccount;
|
|
4840
|
+
serumVaultSigner;
|
|
4534
4841
|
coinReserve;
|
|
4535
4842
|
pcReserve;
|
|
4536
4843
|
static async fromAmmAddressByRpc(connection, amm) {
|
|
@@ -4538,16 +4845,35 @@ var RaydiumAmmV4Params = class _RaydiumAmmV4Params {
|
|
|
4538
4845
|
if (!ammInfo) {
|
|
4539
4846
|
throw new Error("Raydium AMM account not found");
|
|
4540
4847
|
}
|
|
4848
|
+
const marketState = await fetchMarketState(wrapConnection(connection), ammInfo.market);
|
|
4849
|
+
if (!marketState) {
|
|
4850
|
+
throw new Error("Raydium AMM market account not found");
|
|
4851
|
+
}
|
|
4852
|
+
const serumVaultSigner = deriveSerumVaultSigner(
|
|
4853
|
+
ammInfo.serumDex,
|
|
4854
|
+
ammInfo.market,
|
|
4855
|
+
marketState.vaultSignerNonce
|
|
4856
|
+
);
|
|
4541
4857
|
const coinBal = await connection.getTokenAccountBalance(ammInfo.tokenCoin);
|
|
4542
4858
|
const pcBal = await connection.getTokenAccountBalance(ammInfo.tokenPc);
|
|
4543
|
-
const coinReserve =
|
|
4544
|
-
const pcReserve =
|
|
4859
|
+
const coinReserve = BigInt(coinBal.value.amount);
|
|
4860
|
+
const pcReserve = BigInt(pcBal.value.amount);
|
|
4545
4861
|
return new _RaydiumAmmV4Params(
|
|
4546
4862
|
amm,
|
|
4547
4863
|
ammInfo.coinMint,
|
|
4548
4864
|
ammInfo.pcMint,
|
|
4549
4865
|
ammInfo.tokenCoin,
|
|
4550
4866
|
ammInfo.tokenPc,
|
|
4867
|
+
ammInfo.openOrders,
|
|
4868
|
+
ammInfo.targetOrders,
|
|
4869
|
+
ammInfo.serumDex,
|
|
4870
|
+
ammInfo.market,
|
|
4871
|
+
marketState.serumBids,
|
|
4872
|
+
marketState.serumAsks,
|
|
4873
|
+
marketState.serumEventQueue,
|
|
4874
|
+
marketState.serumCoinVaultAccount,
|
|
4875
|
+
marketState.serumPcVaultAccount,
|
|
4876
|
+
serumVaultSigner,
|
|
4551
4877
|
coinReserve,
|
|
4552
4878
|
pcReserve
|
|
4553
4879
|
);
|
|
@@ -5148,20 +5474,30 @@ var HotPathExecutor = class {
|
|
|
5148
5474
|
}
|
|
5149
5475
|
};
|
|
5150
5476
|
const promises = clients.map(submitToClient);
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
}
|
|
5477
|
+
const pending = new Map(
|
|
5478
|
+
promises.map((promise, index) => [
|
|
5479
|
+
index,
|
|
5480
|
+
promise.then((result) => ({ index, result }))
|
|
5481
|
+
])
|
|
5482
|
+
);
|
|
5483
|
+
const errors = [];
|
|
5484
|
+
while (pending.size > 0) {
|
|
5485
|
+
const { index, result } = await Promise.race(pending.values());
|
|
5486
|
+
pending.delete(index);
|
|
5487
|
+
if (result.success) {
|
|
5488
|
+
return result;
|
|
5489
|
+
}
|
|
5490
|
+
if (result.error) {
|
|
5491
|
+
errors.push(`${result.swqosType ?? "unknown"}: ${result.error}`);
|
|
5492
|
+
}
|
|
5164
5493
|
}
|
|
5494
|
+
return {
|
|
5495
|
+
signature: "",
|
|
5496
|
+
success: false,
|
|
5497
|
+
error: `All parallel submissions failed${errors.length ? `: ${errors.join(", ")}` : ""}`,
|
|
5498
|
+
latencyMs: 0,
|
|
5499
|
+
blockhashUsed: ""
|
|
5500
|
+
};
|
|
5165
5501
|
}
|
|
5166
5502
|
/**
|
|
5167
5503
|
* Submit to SWQoS clients sequentially - NO RPC
|
|
@@ -5253,6 +5589,23 @@ function createHotPathExecutor(connection, swqosClients, config) {
|
|
|
5253
5589
|
return executor;
|
|
5254
5590
|
}
|
|
5255
5591
|
|
|
5592
|
+
// src/common/map-pool.ts
|
|
5593
|
+
async function mapWithConcurrencyLimit(items, concurrency, fn) {
|
|
5594
|
+
if (items.length === 0) return [];
|
|
5595
|
+
const limit = Math.max(1, Math.min(concurrency, items.length));
|
|
5596
|
+
const results = new Array(items.length);
|
|
5597
|
+
let next = 0;
|
|
5598
|
+
const worker = async () => {
|
|
5599
|
+
for (; ; ) {
|
|
5600
|
+
const i = next++;
|
|
5601
|
+
if (i >= items.length) return;
|
|
5602
|
+
results[i] = await fn(items[i], i);
|
|
5603
|
+
}
|
|
5604
|
+
};
|
|
5605
|
+
await Promise.all(Array.from({ length: limit }, () => worker()));
|
|
5606
|
+
return results;
|
|
5607
|
+
}
|
|
5608
|
+
|
|
5256
5609
|
// src/common/nonce.ts
|
|
5257
5610
|
import { PublicKey as PublicKey15 } from "@solana/web3.js";
|
|
5258
5611
|
import bs58 from "bs58";
|
|
@@ -5790,6 +6143,22 @@ var AddressLookupTableCache = class {
|
|
|
5790
6143
|
var addressLookupTableCache = new AddressLookupTableCache();
|
|
5791
6144
|
|
|
5792
6145
|
// src/trading/factory.ts
|
|
6146
|
+
var DexType = /* @__PURE__ */ ((DexType3) => {
|
|
6147
|
+
DexType3["PumpFun"] = "PumpFun";
|
|
6148
|
+
DexType3["PumpSwap"] = "PumpSwap";
|
|
6149
|
+
DexType3["Bonk"] = "Bonk";
|
|
6150
|
+
DexType3["RaydiumCpmm"] = "RaydiumCpmm";
|
|
6151
|
+
DexType3["RaydiumAmmV4"] = "RaydiumAmmV4";
|
|
6152
|
+
DexType3["MeteoraDammV2"] = "MeteoraDammV2";
|
|
6153
|
+
return DexType3;
|
|
6154
|
+
})(DexType || {});
|
|
6155
|
+
var TradeType = /* @__PURE__ */ ((TradeType4) => {
|
|
6156
|
+
TradeType4["Buy"] = "Buy";
|
|
6157
|
+
TradeType4["Sell"] = "Sell";
|
|
6158
|
+
TradeType4["Create"] = "Create";
|
|
6159
|
+
TradeType4["CreateAndBuy"] = "CreateAndBuy";
|
|
6160
|
+
return TradeType4;
|
|
6161
|
+
})(TradeType || {});
|
|
5793
6162
|
function defaultTradeExecuteOptions() {
|
|
5794
6163
|
return {
|
|
5795
6164
|
waitConfirmation: true,
|
|
@@ -6138,15 +6507,15 @@ function withAllBuiltinMiddlewares() {
|
|
|
6138
6507
|
}
|
|
6139
6508
|
|
|
6140
6509
|
// src/index.ts
|
|
6141
|
-
var
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
return
|
|
6149
|
-
})(
|
|
6510
|
+
var DexType2 = /* @__PURE__ */ ((DexType3) => {
|
|
6511
|
+
DexType3["PumpFun"] = "PumpFun";
|
|
6512
|
+
DexType3["PumpSwap"] = "PumpSwap";
|
|
6513
|
+
DexType3["Bonk"] = "Bonk";
|
|
6514
|
+
DexType3["RaydiumCpmm"] = "RaydiumCpmm";
|
|
6515
|
+
DexType3["RaydiumAmmV4"] = "RaydiumAmmV4";
|
|
6516
|
+
DexType3["MeteoraDammV2"] = "MeteoraDammV2";
|
|
6517
|
+
return DexType3;
|
|
6518
|
+
})(DexType2 || {});
|
|
6150
6519
|
var TradeTokenType = /* @__PURE__ */ ((TradeTokenType2) => {
|
|
6151
6520
|
TradeTokenType2["SOL"] = "SOL";
|
|
6152
6521
|
TradeTokenType2["WSOL"] = "WSOL";
|
|
@@ -6154,11 +6523,11 @@ var TradeTokenType = /* @__PURE__ */ ((TradeTokenType2) => {
|
|
|
6154
6523
|
TradeTokenType2["USDC"] = "USDC";
|
|
6155
6524
|
return TradeTokenType2;
|
|
6156
6525
|
})(TradeTokenType || {});
|
|
6157
|
-
var
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
return
|
|
6161
|
-
})(
|
|
6526
|
+
var TradeType3 = /* @__PURE__ */ ((TradeType4) => {
|
|
6527
|
+
TradeType4["Buy"] = "Buy";
|
|
6528
|
+
TradeType4["Sell"] = "Sell";
|
|
6529
|
+
return TradeType4;
|
|
6530
|
+
})(TradeType3 || {});
|
|
6162
6531
|
var SwqosRegion = /* @__PURE__ */ ((SwqosRegion2) => {
|
|
6163
6532
|
SwqosRegion2["Frankfurt"] = "Frankfurt";
|
|
6164
6533
|
SwqosRegion2["NewYork"] = "NewYork";
|
|
@@ -6207,6 +6576,88 @@ var AstralaneTransport = /* @__PURE__ */ ((AstralaneTransport2) => {
|
|
|
6207
6576
|
AstralaneTransport2["Quic"] = "Quic";
|
|
6208
6577
|
return AstralaneTransport2;
|
|
6209
6578
|
})(AstralaneTransport || {});
|
|
6579
|
+
function normalizeSwqosConfigs(rpcUrl, configs) {
|
|
6580
|
+
if (configs.length === 0 || configs.some((c) => c.type === "Default" /* Default */)) {
|
|
6581
|
+
return configs;
|
|
6582
|
+
}
|
|
6583
|
+
return [
|
|
6584
|
+
...configs,
|
|
6585
|
+
{
|
|
6586
|
+
type: "Default" /* Default */,
|
|
6587
|
+
region: "Default" /* Default */,
|
|
6588
|
+
apiKey: "",
|
|
6589
|
+
customUrl: rpcUrl
|
|
6590
|
+
}
|
|
6591
|
+
];
|
|
6592
|
+
}
|
|
6593
|
+
function parserPublicKey(value) {
|
|
6594
|
+
if (!value) return PublicKey20.default;
|
|
6595
|
+
if (value instanceof PublicKey20) return value;
|
|
6596
|
+
if (value === PublicKey20.default.toBase58()) return PublicKey20.default;
|
|
6597
|
+
return new PublicKey20(value);
|
|
6598
|
+
}
|
|
6599
|
+
function pumpFunQuoteMintForLayout(quoteMint) {
|
|
6600
|
+
if (quoteMint.equals(PublicKey20.default) || quoteMint.equals(CONSTANTS.SOL_TOKEN_ACCOUNT)) {
|
|
6601
|
+
return PublicKey20.default;
|
|
6602
|
+
}
|
|
6603
|
+
return quoteMint;
|
|
6604
|
+
}
|
|
6605
|
+
function parserU64(value) {
|
|
6606
|
+
if (value === void 0 || value === null || value === "") return 0;
|
|
6607
|
+
const n = typeof value === "bigint" ? value : BigInt(value);
|
|
6608
|
+
if (n > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
6609
|
+
throw new TradeError(106, `parser u64 value ${n.toString()} exceeds JavaScript safe integer range`);
|
|
6610
|
+
}
|
|
6611
|
+
return Number(n);
|
|
6612
|
+
}
|
|
6613
|
+
function pumpFunParamsFromParserTrade(event, closeTokenAccountWhenSell) {
|
|
6614
|
+
const quoteMint = parserPublicKey(event.quote_mint);
|
|
6615
|
+
const legacySolQuote = quoteMint.equals(PublicKey20.default) || quoteMint.equals(CONSTANTS.SOL_TOKEN_ACCOUNT);
|
|
6616
|
+
const hasVirtualQuote = event.virtual_quote_reserves !== void 0;
|
|
6617
|
+
const hasRealQuote = event.real_quote_reserves !== void 0;
|
|
6618
|
+
const virtualQuote = !legacySolQuote && hasVirtualQuote ? parserU64(event.virtual_quote_reserves) : parserU64(event.virtual_sol_reserves);
|
|
6619
|
+
const realQuote = !legacySolQuote && hasRealQuote ? parserU64(event.real_quote_reserves) : parserU64(event.real_sol_reserves);
|
|
6620
|
+
const creator = parserPublicKey(event.creator);
|
|
6621
|
+
return {
|
|
6622
|
+
bondingCurve: {
|
|
6623
|
+
discriminator: 0,
|
|
6624
|
+
account: parserPublicKey(event.bonding_curve),
|
|
6625
|
+
virtualTokenReserves: parserU64(event.virtual_token_reserves),
|
|
6626
|
+
virtualSolReserves: virtualQuote,
|
|
6627
|
+
realTokenReserves: parserU64(event.real_token_reserves),
|
|
6628
|
+
realSolReserves: realQuote,
|
|
6629
|
+
tokenTotalSupply: 0,
|
|
6630
|
+
complete: false,
|
|
6631
|
+
creator,
|
|
6632
|
+
isMayhemMode: !!event.mayhem_mode,
|
|
6633
|
+
isCashbackCoin: !!event.is_cashback_coin
|
|
6634
|
+
},
|
|
6635
|
+
associatedBondingCurve: parserPublicKey(event.associated_bonding_curve),
|
|
6636
|
+
creatorVault: parserPublicKey(event.creator_vault),
|
|
6637
|
+
tokenProgram: parserPublicKey(event.token_program),
|
|
6638
|
+
closeTokenAccountWhenSell,
|
|
6639
|
+
feeRecipient: parserPublicKey(event.fee_recipient),
|
|
6640
|
+
quoteMint: pumpFunQuoteMintForLayout(quoteMint),
|
|
6641
|
+
observedTradeCreator: creator.equals(PublicKey20.default) ? void 0 : creator
|
|
6642
|
+
};
|
|
6643
|
+
}
|
|
6644
|
+
function pumpSwapParamsFromParserTrade(event) {
|
|
6645
|
+
return {
|
|
6646
|
+
pool: parserPublicKey(event.pool),
|
|
6647
|
+
baseMint: parserPublicKey(event.base_mint),
|
|
6648
|
+
quoteMint: parserPublicKey(event.quote_mint),
|
|
6649
|
+
poolBaseTokenAccount: parserPublicKey(event.pool_base_token_account),
|
|
6650
|
+
poolQuoteTokenAccount: parserPublicKey(event.pool_quote_token_account),
|
|
6651
|
+
poolBaseTokenReserves: parserU64(event.pool_base_token_reserves),
|
|
6652
|
+
poolQuoteTokenReserves: parserU64(event.pool_quote_token_reserves),
|
|
6653
|
+
coinCreatorVaultAta: parserPublicKey(event.coin_creator_vault_ata),
|
|
6654
|
+
coinCreatorVaultAuthority: parserPublicKey(event.coin_creator_vault_authority),
|
|
6655
|
+
baseTokenProgram: parserPublicKey(event.base_token_program),
|
|
6656
|
+
quoteTokenProgram: parserPublicKey(event.quote_token_program),
|
|
6657
|
+
isMayhemMode: !!event.is_mayhem_mode,
|
|
6658
|
+
isCashbackCoin: !!event.is_cashback_coin
|
|
6659
|
+
};
|
|
6660
|
+
}
|
|
6210
6661
|
var TradeConfigBuilder = class _TradeConfigBuilder {
|
|
6211
6662
|
_rpcUrl;
|
|
6212
6663
|
_swqosConfigs = [];
|
|
@@ -6215,7 +6666,6 @@ var TradeConfigBuilder = class _TradeConfigBuilder {
|
|
|
6215
6666
|
_checkMinTip = false;
|
|
6216
6667
|
_mevProtection = false;
|
|
6217
6668
|
_useSeedOptimize = true;
|
|
6218
|
-
_usePumpfunV2 = false;
|
|
6219
6669
|
_swqosCoresFromEnd = true;
|
|
6220
6670
|
_createWsolAtaOnStartup = false;
|
|
6221
6671
|
_gasFeeStrategy;
|
|
@@ -6229,7 +6679,7 @@ var TradeConfigBuilder = class _TradeConfigBuilder {
|
|
|
6229
6679
|
return new _TradeConfigBuilder(rpcUrl);
|
|
6230
6680
|
}
|
|
6231
6681
|
swqosConfigs(configs) {
|
|
6232
|
-
this._swqosConfigs = configs;
|
|
6682
|
+
this._swqosConfigs = normalizeSwqosConfigs(this._rpcUrl, configs);
|
|
6233
6683
|
return this;
|
|
6234
6684
|
}
|
|
6235
6685
|
commitment(commitment) {
|
|
@@ -6258,10 +6708,6 @@ var TradeConfigBuilder = class _TradeConfigBuilder {
|
|
|
6258
6708
|
this._useSeedOptimize = enabled;
|
|
6259
6709
|
return this;
|
|
6260
6710
|
}
|
|
6261
|
-
usePumpfunV2(enabled) {
|
|
6262
|
-
this._usePumpfunV2 = enabled;
|
|
6263
|
-
return this;
|
|
6264
|
-
}
|
|
6265
6711
|
swqosCoresFromEnd(enabled) {
|
|
6266
6712
|
this._swqosCoresFromEnd = enabled;
|
|
6267
6713
|
return this;
|
|
@@ -6293,13 +6739,12 @@ var TradeConfigBuilder = class _TradeConfigBuilder {
|
|
|
6293
6739
|
build() {
|
|
6294
6740
|
return {
|
|
6295
6741
|
rpcUrl: this._rpcUrl,
|
|
6296
|
-
swqosConfigs: this._swqosConfigs,
|
|
6742
|
+
swqosConfigs: normalizeSwqosConfigs(this._rpcUrl, this._swqosConfigs),
|
|
6297
6743
|
commitment: this._commitment,
|
|
6298
6744
|
logEnabled: this._logEnabled,
|
|
6299
6745
|
checkMinTip: this._checkMinTip,
|
|
6300
6746
|
mevProtection: this._mevProtection,
|
|
6301
6747
|
useSeedOptimize: this._useSeedOptimize,
|
|
6302
|
-
usePumpfunV2: this._usePumpfunV2,
|
|
6303
6748
|
swqosCoresFromEnd: this._swqosCoresFromEnd,
|
|
6304
6749
|
createWsolAtaOnStartup: this._createWsolAtaOnStartup,
|
|
6305
6750
|
gasFeeStrategy: this._gasFeeStrategy,
|
|
@@ -6346,8 +6791,7 @@ function mapPumpFunParams(p) {
|
|
|
6346
6791
|
feeSharingCreatorVaultIfActive: p.feeSharingCreatorVaultIfActive,
|
|
6347
6792
|
closeTokenAccountWhenSell: p.closeTokenAccountWhenSell,
|
|
6348
6793
|
feeRecipient: p.feeRecipient,
|
|
6349
|
-
quoteMint: p.quoteMint
|
|
6350
|
-
useV2Ix: p.useV2Ix
|
|
6794
|
+
quoteMint: p.quoteMint
|
|
6351
6795
|
};
|
|
6352
6796
|
}
|
|
6353
6797
|
async function findPoolByMint2(connection, mint, dexType) {
|
|
@@ -6371,7 +6815,7 @@ async function findPoolByMint2(connection, mint, dexType) {
|
|
|
6371
6815
|
}
|
|
6372
6816
|
return found.poolAddress;
|
|
6373
6817
|
}
|
|
6374
|
-
var SWQOS_SUBMIT_TIMEOUT_MS_WHEN_NO_CONFIRM =
|
|
6818
|
+
var SWQOS_SUBMIT_TIMEOUT_MS_WHEN_NO_CONFIRM = 5e3;
|
|
6375
6819
|
var RUST_PARITY_SIMULATE_CONFIG = {
|
|
6376
6820
|
sigVerify: false,
|
|
6377
6821
|
replaceRecentBlockhash: false,
|
|
@@ -6448,7 +6892,24 @@ function gasConfigFromStrategyValue(value, tradeType) {
|
|
|
6448
6892
|
sellTipLamports: !isBuy ? tipLam : 0
|
|
6449
6893
|
};
|
|
6450
6894
|
}
|
|
6451
|
-
function
|
|
6895
|
+
async function collectUntilFirstSuccess(promises, isSuccess) {
|
|
6896
|
+
if (promises.length === 0) return [];
|
|
6897
|
+
const results = [];
|
|
6898
|
+
const pending = new Map(
|
|
6899
|
+
promises.map((promise, index) => [
|
|
6900
|
+
index,
|
|
6901
|
+
promise.then((result) => ({ index, result }))
|
|
6902
|
+
])
|
|
6903
|
+
);
|
|
6904
|
+
while (pending.size > 0) {
|
|
6905
|
+
const { index, result } = await Promise.race(pending.values());
|
|
6906
|
+
pending.delete(index);
|
|
6907
|
+
results.push(result);
|
|
6908
|
+
if (isSuccess(result)) return results;
|
|
6909
|
+
}
|
|
6910
|
+
return results;
|
|
6911
|
+
}
|
|
6912
|
+
function expandSwqosGasTasks(effectiveSwqos, tradeType, execGas, configGas, gasStrategy, useStrategyRowMinTip, checkMinTip, withTip, swqosMod, mevProtection, rpcUrl, logEnabled, getClient) {
|
|
6452
6913
|
const out = [];
|
|
6453
6914
|
if (execGas || configGas) {
|
|
6454
6915
|
for (const cfg of effectiveSwqos) {
|
|
@@ -6473,10 +6934,7 @@ function expandSwqosGasTasks(effectiveSwqos, tradeType, execGas, configGas, gasS
|
|
|
6473
6934
|
for (const row of matching) {
|
|
6474
6935
|
const tipLamports = Math.floor(row.value.tip * 1e9);
|
|
6475
6936
|
if (checkMinTip && withTip && cfg.type !== "Default" /* Default */) {
|
|
6476
|
-
const client = swqosMod.ClientFactory.createClient(
|
|
6477
|
-
mapSwqosToClientConfig(cfg, mevProtection),
|
|
6478
|
-
rpcUrl
|
|
6479
|
-
);
|
|
6937
|
+
const client = getClient?.(cfg) ?? swqosMod.ClientFactory.createClient(mapSwqosToClientConfig(cfg, mevProtection), rpcUrl);
|
|
6480
6938
|
const minLamports = Math.ceil(client.minTipSol() * 1e9);
|
|
6481
6939
|
if (tipLamports < minLamports) {
|
|
6482
6940
|
if (logEnabled) {
|
|
@@ -6514,7 +6972,7 @@ function filterSwqosConfigsForWithTip(configs, withTip) {
|
|
|
6514
6972
|
if (withTip) return configs;
|
|
6515
6973
|
return configs.filter((c) => c.type === "Default" /* Default */);
|
|
6516
6974
|
}
|
|
6517
|
-
function filterSwqosConfigsByMinTip(swqosMod, configs, tradeType, gas, mevProtection, rpcUrl, logEnabled) {
|
|
6975
|
+
function filterSwqosConfigsByMinTip(swqosMod, configs, tradeType, gas, mevProtection, rpcUrl, logEnabled, getClient) {
|
|
6518
6976
|
const tipLamports = gas ? tradeType === "Buy" /* Buy */ ? gas.buyTipLamports : gas.sellTipLamports : 0;
|
|
6519
6977
|
const out = [];
|
|
6520
6978
|
for (const cfg of configs) {
|
|
@@ -6522,10 +6980,7 @@ function filterSwqosConfigsByMinTip(swqosMod, configs, tradeType, gas, mevProtec
|
|
|
6522
6980
|
out.push(cfg);
|
|
6523
6981
|
continue;
|
|
6524
6982
|
}
|
|
6525
|
-
const client = swqosMod.ClientFactory.createClient(
|
|
6526
|
-
mapSwqosToClientConfig(cfg, mevProtection),
|
|
6527
|
-
rpcUrl
|
|
6528
|
-
);
|
|
6983
|
+
const client = getClient?.(cfg) ?? swqosMod.ClientFactory.createClient(mapSwqosToClientConfig(cfg, mevProtection), rpcUrl);
|
|
6529
6984
|
const minLamports = Math.ceil(client.minTipSol() * 1e9);
|
|
6530
6985
|
if (tipLamports < minLamports) {
|
|
6531
6986
|
if (logEnabled) {
|
|
@@ -6539,13 +6994,10 @@ function filterSwqosConfigsByMinTip(swqosMod, configs, tradeType, gas, mevProtec
|
|
|
6539
6994
|
}
|
|
6540
6995
|
return out;
|
|
6541
6996
|
}
|
|
6542
|
-
function resolveTipRecipientPubkey(swqosMod, configs, mevProtection, rpcUrl) {
|
|
6997
|
+
function resolveTipRecipientPubkey(swqosMod, configs, mevProtection, rpcUrl, getClient) {
|
|
6543
6998
|
const preferred = configs.find((c) => c.type !== "Default" /* Default */) ?? configs[0];
|
|
6544
6999
|
if (!preferred) return null;
|
|
6545
|
-
const client = swqosMod.ClientFactory.createClient(
|
|
6546
|
-
mapSwqosToClientConfig(preferred, mevProtection),
|
|
6547
|
-
rpcUrl
|
|
6548
|
-
);
|
|
7000
|
+
const client = getClient?.(preferred) ?? swqosMod.ClientFactory.createClient(mapSwqosToClientConfig(preferred, mevProtection), rpcUrl);
|
|
6549
7001
|
const acc = client.getTipAccount();
|
|
6550
7002
|
if (!acc) return null;
|
|
6551
7003
|
try {
|
|
@@ -6560,14 +7012,48 @@ var TradingClient = class {
|
|
|
6560
7012
|
_config;
|
|
6561
7013
|
middlewares = [];
|
|
6562
7014
|
_logEnabled;
|
|
7015
|
+
_swqosModulePromise;
|
|
7016
|
+
_swqosClientCache = /* @__PURE__ */ new Map();
|
|
6563
7017
|
constructor(payer, config) {
|
|
6564
7018
|
this.payer = payer;
|
|
6565
|
-
this._config =
|
|
7019
|
+
this._config = {
|
|
7020
|
+
...config,
|
|
7021
|
+
swqosConfigs: normalizeSwqosConfigs(config.rpcUrl, config.swqosConfigs ?? [])
|
|
7022
|
+
};
|
|
6566
7023
|
this.connection = new Connection6(config.rpcUrl, {
|
|
6567
7024
|
commitment: config.commitment ?? "confirmed"
|
|
6568
7025
|
});
|
|
6569
7026
|
this._logEnabled = config.logEnabled ?? true;
|
|
6570
7027
|
}
|
|
7028
|
+
getSwqosModule() {
|
|
7029
|
+
this._swqosModulePromise ??= import("./clients-PSG35HN4.mjs");
|
|
7030
|
+
return this._swqosModulePromise;
|
|
7031
|
+
}
|
|
7032
|
+
swqosClientCacheKey(cfg) {
|
|
7033
|
+
return JSON.stringify([
|
|
7034
|
+
this._config.rpcUrl,
|
|
7035
|
+
this._config.mevProtection ?? false,
|
|
7036
|
+
cfg.type,
|
|
7037
|
+
cfg.region ?? null,
|
|
7038
|
+
cfg.customUrl ?? null,
|
|
7039
|
+
cfg.apiKey ?? null,
|
|
7040
|
+
cfg.transport ?? null,
|
|
7041
|
+
cfg.astralaneTransport ?? null,
|
|
7042
|
+
cfg.swqosOnly ?? null,
|
|
7043
|
+
cfg.mevProtection ?? null
|
|
7044
|
+
]);
|
|
7045
|
+
}
|
|
7046
|
+
getSwqosClient(swqosMod, cfg) {
|
|
7047
|
+
const key = this.swqosClientCacheKey(cfg);
|
|
7048
|
+
const cached = this._swqosClientCache.get(key);
|
|
7049
|
+
if (cached) return cached;
|
|
7050
|
+
const client = swqosMod.ClientFactory.createClient(
|
|
7051
|
+
mapSwqosToClientConfig(cfg, this._config.mevProtection),
|
|
7052
|
+
this._config.rpcUrl
|
|
7053
|
+
);
|
|
7054
|
+
this._swqosClientCache.set(key, client);
|
|
7055
|
+
return client;
|
|
7056
|
+
}
|
|
6571
7057
|
/** Get the current configuration */
|
|
6572
7058
|
get config() {
|
|
6573
7059
|
return this._config;
|
|
@@ -6802,9 +7288,10 @@ var TradingClient = class {
|
|
|
6802
7288
|
fixedOutputAmount: params.fixedOutputTokenAmount !== void 0 ? BigInt(params.fixedOutputTokenAmount) : void 0,
|
|
6803
7289
|
createOutputMintAta: params.createMintAta ?? true,
|
|
6804
7290
|
createInputMintAta: params.createInputTokenAta ?? false,
|
|
7291
|
+
closeInputMintAta: params.closeInputTokenAta ?? false,
|
|
6805
7292
|
protocolParams: mapPumpFunParams(ext.params),
|
|
6806
7293
|
useExactSolAmount: params.useExactSolAmount ?? true,
|
|
6807
|
-
|
|
7294
|
+
inputMint: this.getInputMint(params.inputTokenType)
|
|
6808
7295
|
});
|
|
6809
7296
|
}
|
|
6810
7297
|
case "PumpSwap" /* PumpSwap */: {
|
|
@@ -6903,8 +7390,18 @@ var TradingClient = class {
|
|
|
6903
7390
|
pcMint: p.pcMint,
|
|
6904
7391
|
tokenCoin: p.tokenCoin,
|
|
6905
7392
|
tokenPc: p.tokenPc,
|
|
6906
|
-
|
|
6907
|
-
|
|
7393
|
+
ammOpenOrders: p.ammOpenOrders,
|
|
7394
|
+
ammTargetOrders: p.ammTargetOrders,
|
|
7395
|
+
serumProgram: p.serumProgram,
|
|
7396
|
+
serumMarket: p.serumMarket,
|
|
7397
|
+
serumBids: p.serumBids,
|
|
7398
|
+
serumAsks: p.serumAsks,
|
|
7399
|
+
serumEventQueue: p.serumEventQueue,
|
|
7400
|
+
serumCoinVaultAccount: p.serumCoinVaultAccount,
|
|
7401
|
+
serumPcVaultAccount: p.serumPcVaultAccount,
|
|
7402
|
+
serumVaultSigner: p.serumVaultSigner,
|
|
7403
|
+
coinReserve: p.coinReserve,
|
|
7404
|
+
pcReserve: p.pcReserve
|
|
6908
7405
|
};
|
|
6909
7406
|
return buildRaydiumAmmV4BuyInstructions({
|
|
6910
7407
|
payer: this.payer.publicKey,
|
|
@@ -6970,7 +7467,7 @@ var TradingClient = class {
|
|
|
6970
7467
|
closeInputMintAta: params.closeMintTokenAta ?? false,
|
|
6971
7468
|
createOutputMintAta: params.createOutputTokenAta ?? false,
|
|
6972
7469
|
protocolParams: mapPumpFunParams(ext.params),
|
|
6973
|
-
|
|
7470
|
+
outputMint: this.getOutputMint(params.outputTokenType)
|
|
6974
7471
|
});
|
|
6975
7472
|
}
|
|
6976
7473
|
case "PumpSwap" /* PumpSwap */: {
|
|
@@ -7068,12 +7565,23 @@ var TradingClient = class {
|
|
|
7068
7565
|
pcMint: p.pcMint,
|
|
7069
7566
|
tokenCoin: p.tokenCoin,
|
|
7070
7567
|
tokenPc: p.tokenPc,
|
|
7071
|
-
|
|
7072
|
-
|
|
7568
|
+
ammOpenOrders: p.ammOpenOrders,
|
|
7569
|
+
ammTargetOrders: p.ammTargetOrders,
|
|
7570
|
+
serumProgram: p.serumProgram,
|
|
7571
|
+
serumMarket: p.serumMarket,
|
|
7572
|
+
serumBids: p.serumBids,
|
|
7573
|
+
serumAsks: p.serumAsks,
|
|
7574
|
+
serumEventQueue: p.serumEventQueue,
|
|
7575
|
+
serumCoinVaultAccount: p.serumCoinVaultAccount,
|
|
7576
|
+
serumPcVaultAccount: p.serumPcVaultAccount,
|
|
7577
|
+
serumVaultSigner: p.serumVaultSigner,
|
|
7578
|
+
coinReserve: p.coinReserve,
|
|
7579
|
+
pcReserve: p.pcReserve
|
|
7073
7580
|
};
|
|
7074
7581
|
return buildRaydiumAmmV4SellInstructions({
|
|
7075
7582
|
payer: this.payer.publicKey,
|
|
7076
7583
|
inputMint: params.mint,
|
|
7584
|
+
outputMint: this.getOutputMint(params.outputTokenType),
|
|
7077
7585
|
inputAmount: inputAmt,
|
|
7078
7586
|
slippageBasisPoints: slippage,
|
|
7079
7587
|
fixedOutputAmount: params.fixedOutputTokenAmount !== void 0 ? BigInt(params.fixedOutputTokenAmount) : void 0,
|
|
@@ -7149,11 +7657,23 @@ var TradingClient = class {
|
|
|
7149
7657
|
return result;
|
|
7150
7658
|
}
|
|
7151
7659
|
async executeTransaction(instructions, recentBlockhash, lookupTableAccount, waitConfirmed, simulate, execCtx) {
|
|
7152
|
-
const blockhash = recentBlockhash ?? execCtx?.durableNonce?.nonceHash
|
|
7660
|
+
const blockhash = recentBlockhash ?? execCtx?.durableNonce?.nonceHash;
|
|
7661
|
+
if (!blockhash) {
|
|
7662
|
+
return {
|
|
7663
|
+
success: false,
|
|
7664
|
+
signatures: [],
|
|
7665
|
+
error: new TradeError(
|
|
7666
|
+
105,
|
|
7667
|
+
"recentBlockhash or durableNonce.nonceHash is required; trade execution hot path does not query RPC for blockhash"
|
|
7668
|
+
),
|
|
7669
|
+
timings: []
|
|
7670
|
+
};
|
|
7671
|
+
}
|
|
7153
7672
|
const swqosList = this._config.swqosConfigs ?? [];
|
|
7154
7673
|
const tradeType = execCtx?.tradeType ?? "Buy" /* Buy */;
|
|
7155
7674
|
const withTip = execCtx?.withTip ?? true;
|
|
7156
|
-
const swqosMod = swqosList.length > 0 ? await
|
|
7675
|
+
const swqosMod = swqosList.length > 0 ? await this.getSwqosModule() : null;
|
|
7676
|
+
const swqosClientForConfig = swqosMod ? (cfg) => this.getSwqosClient(swqosMod, cfg) : void 0;
|
|
7157
7677
|
let effectiveSwqos = swqosList;
|
|
7158
7678
|
if (swqosMod && !withTip) {
|
|
7159
7679
|
effectiveSwqos = filterSwqosConfigsForWithTip(swqosList, withTip);
|
|
@@ -7185,7 +7705,8 @@ var TradingClient = class {
|
|
|
7185
7705
|
gasMerged,
|
|
7186
7706
|
this._config.mevProtection,
|
|
7187
7707
|
this._config.rpcUrl,
|
|
7188
|
-
this._logEnabled
|
|
7708
|
+
this._logEnabled,
|
|
7709
|
+
swqosClientForConfig
|
|
7189
7710
|
);
|
|
7190
7711
|
if (effectiveSwqos.length === 0) {
|
|
7191
7712
|
return {
|
|
@@ -7219,7 +7740,8 @@ var TradingClient = class {
|
|
|
7219
7740
|
swqosMod,
|
|
7220
7741
|
this._config.mevProtection,
|
|
7221
7742
|
this._config.rpcUrl,
|
|
7222
|
-
this._logEnabled
|
|
7743
|
+
this._logEnabled,
|
|
7744
|
+
swqosClientForConfig
|
|
7223
7745
|
);
|
|
7224
7746
|
if (swqosTasks.length === 0) {
|
|
7225
7747
|
return {
|
|
@@ -7281,7 +7803,8 @@ var TradingClient = class {
|
|
|
7281
7803
|
swqosMod,
|
|
7282
7804
|
[t.cfg],
|
|
7283
7805
|
this._config.mevProtection,
|
|
7284
|
-
this._config.rpcUrl
|
|
7806
|
+
this._config.rpcUrl,
|
|
7807
|
+
swqosClientForConfig
|
|
7285
7808
|
) : null;
|
|
7286
7809
|
const txSim2 = buildSignedVersionedTransaction(
|
|
7287
7810
|
this.payer,
|
|
@@ -7336,17 +7859,15 @@ var TradingClient = class {
|
|
|
7336
7859
|
if (swqosMod) {
|
|
7337
7860
|
const timings = [];
|
|
7338
7861
|
const signatures = [];
|
|
7339
|
-
const
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
submitConcurrency,
|
|
7343
|
-
async (task) => {
|
|
7344
|
-
const t0 = performance.now();
|
|
7862
|
+
const submitTask = async (task) => {
|
|
7863
|
+
const t0 = performance.now();
|
|
7864
|
+
try {
|
|
7345
7865
|
const tipPk = withTip ? resolveTipRecipientPubkey(
|
|
7346
7866
|
swqosMod,
|
|
7347
7867
|
[task.cfg],
|
|
7348
7868
|
this._config.mevProtection,
|
|
7349
|
-
this._config.rpcUrl
|
|
7869
|
+
this._config.rpcUrl,
|
|
7870
|
+
swqosClientForConfig
|
|
7350
7871
|
) : null;
|
|
7351
7872
|
const tx = buildSignedVersionedTransaction(
|
|
7352
7873
|
this.payer,
|
|
@@ -7355,33 +7876,30 @@ var TradingClient = class {
|
|
|
7355
7876
|
lookupTableAccount
|
|
7356
7877
|
);
|
|
7357
7878
|
const raw = Buffer.from(tx.serialize());
|
|
7358
|
-
const client =
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
`SWQOS submit timed out after ${SWQOS_SUBMIT_TIMEOUT_MS_WHEN_NO_CONFIRM}ms`
|
|
7371
|
-
)
|
|
7372
|
-
),
|
|
7373
|
-
SWQOS_SUBMIT_TIMEOUT_MS_WHEN_NO_CONFIRM
|
|
7374
|
-
)
|
|
7879
|
+
const client = swqosClientForConfig(task.cfg);
|
|
7880
|
+
const pending = client.sendTransaction(tradeType, raw, false);
|
|
7881
|
+
const sig = await (!waitConfirmed ? Promise.race([
|
|
7882
|
+
pending,
|
|
7883
|
+
new Promise(
|
|
7884
|
+
(_, reject) => setTimeout(
|
|
7885
|
+
() => reject(
|
|
7886
|
+
new Error(
|
|
7887
|
+
`SWQOS submit timed out after ${SWQOS_SUBMIT_TIMEOUT_MS_WHEN_NO_CONFIRM}ms`
|
|
7888
|
+
)
|
|
7889
|
+
),
|
|
7890
|
+
SWQOS_SUBMIT_TIMEOUT_MS_WHEN_NO_CONFIRM
|
|
7375
7891
|
)
|
|
7376
|
-
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
}
|
|
7892
|
+
)
|
|
7893
|
+
]) : pending);
|
|
7894
|
+
const duration = Math.round((performance.now() - t0) * 1e3);
|
|
7895
|
+
return { ok: true, sig, task, duration };
|
|
7896
|
+
} catch (e) {
|
|
7897
|
+
const duration = Math.round((performance.now() - t0) * 1e3);
|
|
7898
|
+
return { ok: false, err: e, task, duration };
|
|
7383
7899
|
}
|
|
7384
|
-
|
|
7900
|
+
};
|
|
7901
|
+
const submitPromises = swqosTasks.map((task) => submitTask(task));
|
|
7902
|
+
const results = waitConfirmed ? await Promise.all(submitPromises) : await collectUntilFirstSuccess(submitPromises, (result) => result.ok);
|
|
7385
7903
|
for (const v of results) {
|
|
7386
7904
|
timings.push({
|
|
7387
7905
|
swqosType: v.task.cfg.type,
|
|
@@ -7389,7 +7907,7 @@ var TradingClient = class {
|
|
|
7389
7907
|
gasFeeStrategyType: v.task.strategyType
|
|
7390
7908
|
});
|
|
7391
7909
|
if (v.ok) {
|
|
7392
|
-
signatures.push(v.sig);
|
|
7910
|
+
if (v.sig) signatures.push(v.sig);
|
|
7393
7911
|
}
|
|
7394
7912
|
}
|
|
7395
7913
|
const success = signatures.length > 0;
|
|
@@ -7456,7 +7974,7 @@ function createTradeConfig(rpcUrl, swqosConfigs = [], options) {
|
|
|
7456
7974
|
const { commitment, logEnabled, ...rest } = options ?? {};
|
|
7457
7975
|
return {
|
|
7458
7976
|
rpcUrl,
|
|
7459
|
-
swqosConfigs,
|
|
7977
|
+
swqosConfigs: normalizeSwqosConfigs(rpcUrl, swqosConfigs),
|
|
7460
7978
|
...rest,
|
|
7461
7979
|
commitment: commitment ?? "confirmed",
|
|
7462
7980
|
logEnabled: logEnabled ?? true
|
|
@@ -7638,11 +8156,17 @@ export {
|
|
|
7638
8156
|
buildRaydiumAmmV4BuyInstructions,
|
|
7639
8157
|
buildRaydiumAmmV4SellInstructions,
|
|
7640
8158
|
AMM_INFO_SIZE,
|
|
8159
|
+
MARKET_STATE_SIZE,
|
|
7641
8160
|
decodeAmmInfo,
|
|
8161
|
+
decodeMarketState,
|
|
8162
|
+
deriveSerumVaultSigner,
|
|
7642
8163
|
fetchAmmInfo,
|
|
8164
|
+
fetchMarketState,
|
|
7643
8165
|
METEORA_DAMM_V2_PROGRAM_ID,
|
|
7644
8166
|
METEORA_DAMM_V2_AUTHORITY,
|
|
7645
8167
|
METEORA_DAMM_V2_SWAP_DISCRIMINATOR,
|
|
8168
|
+
METEORA_DAMM_V2_SWAP2_DISCRIMINATOR,
|
|
8169
|
+
METEORA_DAMM_V2_SWAP_MODE_PARTIAL_FILL,
|
|
7646
8170
|
METEORA_DAMM_V2_EVENT_AUTHORITY_SEED,
|
|
7647
8171
|
getMeteoraDammV2EventAuthorityPda,
|
|
7648
8172
|
buildMeteoraDammV2BuyInstructions,
|
|
@@ -7655,7 +8179,6 @@ export {
|
|
|
7655
8179
|
extractHintsFromLogs,
|
|
7656
8180
|
instructionErrorCodeFromMetaErr,
|
|
7657
8181
|
confirmAnyTransactionSignature,
|
|
7658
|
-
mapWithConcurrencyLimit,
|
|
7659
8182
|
BYTES_PER_ACCOUNT,
|
|
7660
8183
|
MAX_INSTRUCTIONS_WARN,
|
|
7661
8184
|
Prefetch,
|
|
@@ -7691,6 +8214,7 @@ export {
|
|
|
7691
8214
|
HotPathExecutor,
|
|
7692
8215
|
TransactionBuilder,
|
|
7693
8216
|
createHotPathExecutor,
|
|
8217
|
+
mapWithConcurrencyLimit,
|
|
7694
8218
|
fetchDurableNonceInfo,
|
|
7695
8219
|
SecureKeyError,
|
|
7696
8220
|
KeyNotAvailableError,
|
|
@@ -7710,6 +8234,8 @@ export {
|
|
|
7710
8234
|
parseAddressLookupTable,
|
|
7711
8235
|
AddressLookupTableCache,
|
|
7712
8236
|
addressLookupTableCache,
|
|
8237
|
+
DexType,
|
|
8238
|
+
TradeType,
|
|
7713
8239
|
defaultTradeExecuteOptions,
|
|
7714
8240
|
BaseExecutor,
|
|
7715
8241
|
PumpFunExecutor,
|
|
@@ -7727,13 +8253,15 @@ export {
|
|
|
7727
8253
|
MetricsMiddleware,
|
|
7728
8254
|
withStandardMiddlewares,
|
|
7729
8255
|
withAllBuiltinMiddlewares,
|
|
7730
|
-
|
|
8256
|
+
DexType2,
|
|
7731
8257
|
TradeTokenType,
|
|
7732
|
-
|
|
8258
|
+
TradeType3 as TradeType2,
|
|
7733
8259
|
SwqosRegion,
|
|
7734
8260
|
SwqosType,
|
|
7735
8261
|
SwqosTransport,
|
|
7736
8262
|
AstralaneTransport,
|
|
8263
|
+
pumpFunParamsFromParserTrade,
|
|
8264
|
+
pumpSwapParamsFromParserTrade,
|
|
7737
8265
|
TradeConfigBuilder,
|
|
7738
8266
|
recommendedSenderThreadCoreIndices,
|
|
7739
8267
|
findPoolByMint2 as findPoolByMint,
|