Update juptier pumpfun usdc usdt usd1 filter
This commit is contained in:
@@ -22,6 +22,10 @@ var (
|
|||||||
|
|
||||||
jupiterSharedAccountsExactOutRouteV2 = []byte{53, 96, 229, 202, 216, 187, 250, 24}
|
jupiterSharedAccountsExactOutRouteV2 = []byte{53, 96, 229, 202, 216, 187, 250, 24}
|
||||||
jupiterSharedAccountsRouteV2 = []byte{209, 152, 83, 147, 124, 254, 216, 233}
|
jupiterSharedAccountsRouteV2 = []byte{209, 152, 83, 147, 124, 254, 216, 233}
|
||||||
|
|
||||||
|
usdcMint = solana.MustPublicKeyFromBase58("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v")
|
||||||
|
usd1Mint = solana.MustPublicKeyFromBase58("USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB")
|
||||||
|
usdtMint = solana.MustPublicKeyFromBase58("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Side uint8
|
type Side uint8
|
||||||
@@ -882,6 +886,32 @@ func isPumpWrappedSell(kind SwapKind) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isStableMint(mint solana.PublicKey) bool {
|
||||||
|
if mint.Equals(usdcMint) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if mint.Equals(usd1Mint) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if mint.Equals(usdtMint) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isToken1Mint(mint solana.PublicKey) bool {
|
||||||
|
return mint.Equals(solana.WrappedSol) || mint.Equals(solana.SystemProgramID) || isStableMint(mint)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isJupiterV6Token1RequiredDisc(disc []byte) bool {
|
||||||
|
return bytes.Equal(disc, jupiterRouteV2) ||
|
||||||
|
bytes.Equal(disc, jupiterSharedAccountsRouteV2) ||
|
||||||
|
bytes.Equal(disc, jupiterExactOutRouteV2) ||
|
||||||
|
bytes.Equal(disc, jupiterSharedAccountsExactOutRouteV2) ||
|
||||||
|
bytes.Equal(disc, jupiterSharedAccountsRoute) ||
|
||||||
|
bytes.Equal(disc, jupiterSharedAccountsExactOutRoute)
|
||||||
|
}
|
||||||
|
|
||||||
func pumpWrappedAtIdx0(in uint64, out uint64, plan []RoutePlanStep) (pumpWrappedMatch, int) {
|
func pumpWrappedAtIdx0(in uint64, out uint64, plan []RoutePlanStep) (pumpWrappedMatch, int) {
|
||||||
var (
|
var (
|
||||||
ret pumpWrappedMatch
|
ret pumpWrappedMatch
|
||||||
@@ -932,6 +962,42 @@ func pumpWrappedAtIdx0V2(in uint64, out uint64, plan []RoutePlanStepV2) (pumpWra
|
|||||||
return ret, count
|
return ret, count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func pumpWrappedAny(plan []RoutePlanStep) (pumpWrappedMatch, int) {
|
||||||
|
var (
|
||||||
|
ret pumpWrappedMatch
|
||||||
|
count int
|
||||||
|
)
|
||||||
|
for _, step := range plan {
|
||||||
|
if !isPumpWrappedBuy(step.Swap.Kind) && !isPumpWrappedSell(step.Swap.Kind) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
count++
|
||||||
|
if count > 1 {
|
||||||
|
return pumpWrappedMatch{}, count
|
||||||
|
}
|
||||||
|
ret.IsBuy = isPumpWrappedBuy(step.Swap.Kind)
|
||||||
|
}
|
||||||
|
return ret, count
|
||||||
|
}
|
||||||
|
|
||||||
|
func pumpWrappedAnyV2(plan []RoutePlanStepV2) (pumpWrappedMatch, int) {
|
||||||
|
var (
|
||||||
|
ret pumpWrappedMatch
|
||||||
|
count int
|
||||||
|
)
|
||||||
|
for _, step := range plan {
|
||||||
|
if !isPumpWrappedBuy(step.Swap.Kind) && !isPumpWrappedSell(step.Swap.Kind) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
count++
|
||||||
|
if count > 1 {
|
||||||
|
return pumpWrappedMatch{}, count
|
||||||
|
}
|
||||||
|
ret.IsBuy = isPumpWrappedBuy(step.Swap.Kind)
|
||||||
|
}
|
||||||
|
return ret, count
|
||||||
|
}
|
||||||
|
|
||||||
func findPumpFunMint(staticKeys []solana.PublicKey, accounts []uint8) (solana.PublicKey, bool, error) {
|
func findPumpFunMint(staticKeys []solana.PublicKey, accounts []uint8) (solana.PublicKey, bool, error) {
|
||||||
for i, acctIdx := range accounts {
|
for i, acctIdx := range accounts {
|
||||||
key, err := getStaticKey(staticKeys, int(acctIdx))
|
key, err := getStaticKey(staticKeys, int(acctIdx))
|
||||||
@@ -953,6 +1019,43 @@ func findPumpFunMint(staticKeys []solana.PublicKey, accounts []uint8) (solana.Pu
|
|||||||
return solana.PublicKey{}, false, nil
|
return solana.PublicKey{}, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func jupiterV6SourceDestMints(msg versionedMessage, instruction compiledInstruction, disc []byte) (solana.PublicKey, solana.PublicKey, bool, error) {
|
||||||
|
switch {
|
||||||
|
case bytes.Equal(disc, jupiterRouteV2),
|
||||||
|
bytes.Equal(disc, jupiterSharedAccountsRouteV2),
|
||||||
|
bytes.Equal(disc, jupiterExactOutRouteV2),
|
||||||
|
bytes.Equal(disc, jupiterSharedAccountsExactOutRouteV2):
|
||||||
|
if len(instruction.Accounts) < 5 {
|
||||||
|
return solana.PublicKey{}, solana.PublicKey{}, false, fmt.Errorf("not enough accounts for jupiter v6 v2 instruction")
|
||||||
|
}
|
||||||
|
src, err := getStaticKey(msg.StaticAccountKeys, int(instruction.Accounts[3]))
|
||||||
|
if err != nil {
|
||||||
|
return solana.PublicKey{}, solana.PublicKey{}, false, err
|
||||||
|
}
|
||||||
|
dst, err := getStaticKey(msg.StaticAccountKeys, int(instruction.Accounts[4]))
|
||||||
|
if err != nil {
|
||||||
|
return solana.PublicKey{}, solana.PublicKey{}, false, err
|
||||||
|
}
|
||||||
|
return src, dst, true, nil
|
||||||
|
case bytes.Equal(disc, jupiterSharedAccountsRoute),
|
||||||
|
bytes.Equal(disc, jupiterSharedAccountsExactOutRoute):
|
||||||
|
if len(instruction.Accounts) < 9 {
|
||||||
|
return solana.PublicKey{}, solana.PublicKey{}, false, fmt.Errorf("not enough accounts for jupiter v6 shared accounts instruction")
|
||||||
|
}
|
||||||
|
src, err := getStaticKey(msg.StaticAccountKeys, int(instruction.Accounts[7]))
|
||||||
|
if err != nil {
|
||||||
|
return solana.PublicKey{}, solana.PublicKey{}, false, err
|
||||||
|
}
|
||||||
|
dst, err := getStaticKey(msg.StaticAccountKeys, int(instruction.Accounts[8]))
|
||||||
|
if err != nil {
|
||||||
|
return solana.PublicKey{}, solana.PublicKey{}, false, err
|
||||||
|
}
|
||||||
|
return src, dst, true, nil
|
||||||
|
default:
|
||||||
|
return solana.PublicKey{}, solana.PublicKey{}, false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// only decodes inputIdx = 0 container pumpSwap instructions for now
|
// only decodes inputIdx = 0 container pumpSwap instructions for now
|
||||||
func parseJupiterV6Instruction(tx *versionedTransaction, instructionIndex int) (*TxSignal, error) {
|
func parseJupiterV6Instruction(tx *versionedTransaction, instructionIndex int) (*TxSignal, error) {
|
||||||
msg := tx.Message
|
msg := tx.Message
|
||||||
@@ -973,9 +1076,13 @@ func parseJupiterV6Instruction(tx *versionedTransaction, instructionIndex int) (
|
|||||||
var (
|
var (
|
||||||
sourceMint solana.PublicKey
|
sourceMint solana.PublicKey
|
||||||
inputAmount uint64
|
inputAmount uint64
|
||||||
|
routeIn uint64
|
||||||
|
routeOut uint64
|
||||||
planCount int
|
planCount int
|
||||||
wrapped pumpWrappedMatch
|
wrapped pumpWrappedMatch
|
||||||
wrappedCnt int
|
wrappedCnt int
|
||||||
|
wrappedAny pumpWrappedMatch
|
||||||
|
wrappedAnyC int
|
||||||
exactOut bool
|
exactOut bool
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
@@ -990,6 +1097,9 @@ func parseJupiterV6Instruction(tx *versionedTransaction, instructionIndex int) (
|
|||||||
}
|
}
|
||||||
inputAmount, planCount = pumpSwapSellAtIdx0V2(args.In, args.Plan)
|
inputAmount, planCount = pumpSwapSellAtIdx0V2(args.In, args.Plan)
|
||||||
wrapped, wrappedCnt = pumpWrappedAtIdx0V2(args.In, args.Out, args.Plan)
|
wrapped, wrappedCnt = pumpWrappedAtIdx0V2(args.In, args.Out, args.Plan)
|
||||||
|
wrappedAny, wrappedAnyC = pumpWrappedAnyV2(args.Plan)
|
||||||
|
routeIn = args.In
|
||||||
|
routeOut = args.Out
|
||||||
case bytes.Equal(disc, jupiterSharedAccountsRouteV2):
|
case bytes.Equal(disc, jupiterSharedAccountsRouteV2):
|
||||||
args, err := decodeJupiterV6SharedAccountsRouteV2Arg(instruction.Data[8:])
|
args, err := decodeJupiterV6SharedAccountsRouteV2Arg(instruction.Data[8:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -997,6 +1107,9 @@ func parseJupiterV6Instruction(tx *versionedTransaction, instructionIndex int) (
|
|||||||
}
|
}
|
||||||
inputAmount, planCount = pumpSwapSellAtIdx0V2(args.In, args.RoutePlan)
|
inputAmount, planCount = pumpSwapSellAtIdx0V2(args.In, args.RoutePlan)
|
||||||
wrapped, wrappedCnt = pumpWrappedAtIdx0V2(args.In, args.QuotedOut, args.RoutePlan)
|
wrapped, wrappedCnt = pumpWrappedAtIdx0V2(args.In, args.QuotedOut, args.RoutePlan)
|
||||||
|
wrappedAny, wrappedAnyC = pumpWrappedAnyV2(args.RoutePlan)
|
||||||
|
routeIn = args.In
|
||||||
|
routeOut = args.QuotedOut
|
||||||
case bytes.Equal(disc, jupiterExactOutRouteV2):
|
case bytes.Equal(disc, jupiterExactOutRouteV2):
|
||||||
args, err := decodeJupiterV6ExactOutRouteV2Arg(instruction.Data[8:])
|
args, err := decodeJupiterV6ExactOutRouteV2Arg(instruction.Data[8:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1004,6 +1117,9 @@ func parseJupiterV6Instruction(tx *versionedTransaction, instructionIndex int) (
|
|||||||
}
|
}
|
||||||
exactOut = true
|
exactOut = true
|
||||||
wrapped, wrappedCnt = pumpWrappedAtIdx0V2(args.QuotedIn, args.Out, args.RoutePlan)
|
wrapped, wrappedCnt = pumpWrappedAtIdx0V2(args.QuotedIn, args.Out, args.RoutePlan)
|
||||||
|
wrappedAny, wrappedAnyC = pumpWrappedAnyV2(args.RoutePlan)
|
||||||
|
routeIn = args.QuotedIn
|
||||||
|
routeOut = args.Out
|
||||||
case bytes.Equal(disc, jupiterSharedAccountsExactOutRouteV2):
|
case bytes.Equal(disc, jupiterSharedAccountsExactOutRouteV2):
|
||||||
args, err := decodeJupiterV6SharedAccountsExactOutRouteV2Arg(instruction.Data[8:])
|
args, err := decodeJupiterV6SharedAccountsExactOutRouteV2Arg(instruction.Data[8:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1011,6 +1127,9 @@ func parseJupiterV6Instruction(tx *versionedTransaction, instructionIndex int) (
|
|||||||
}
|
}
|
||||||
exactOut = true
|
exactOut = true
|
||||||
wrapped, wrappedCnt = pumpWrappedAtIdx0V2(args.QuotedIn, args.Out, args.RoutePlan)
|
wrapped, wrappedCnt = pumpWrappedAtIdx0V2(args.QuotedIn, args.Out, args.RoutePlan)
|
||||||
|
wrappedAny, wrappedAnyC = pumpWrappedAnyV2(args.RoutePlan)
|
||||||
|
routeIn = args.QuotedIn
|
||||||
|
routeOut = args.Out
|
||||||
case bytes.Equal(disc, jupiterRoute):
|
case bytes.Equal(disc, jupiterRoute):
|
||||||
args, err := decodeJupiterV6RouteArg(instruction.Data[8:])
|
args, err := decodeJupiterV6RouteArg(instruction.Data[8:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1019,6 +1138,9 @@ func parseJupiterV6Instruction(tx *versionedTransaction, instructionIndex int) (
|
|||||||
_ = args
|
_ = args
|
||||||
inputAmount, planCount = pumpSwapSellAtIdx0(args.In, args.Plan)
|
inputAmount, planCount = pumpSwapSellAtIdx0(args.In, args.Plan)
|
||||||
wrapped, wrappedCnt = pumpWrappedAtIdx0(args.In, args.QuotedOut, args.Plan)
|
wrapped, wrappedCnt = pumpWrappedAtIdx0(args.In, args.QuotedOut, args.Plan)
|
||||||
|
wrappedAny, wrappedAnyC = pumpWrappedAny(args.Plan)
|
||||||
|
routeIn = args.In
|
||||||
|
routeOut = args.QuotedOut
|
||||||
case bytes.Equal(disc, jupiterSharedAccountsExactOutRoute):
|
case bytes.Equal(disc, jupiterSharedAccountsExactOutRoute):
|
||||||
args, err := decodeJupiterV6SharedAccountsExactOutRouteArg(instruction.Data[8:])
|
args, err := decodeJupiterV6SharedAccountsExactOutRouteArg(instruction.Data[8:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1026,6 +1148,9 @@ func parseJupiterV6Instruction(tx *versionedTransaction, instructionIndex int) (
|
|||||||
}
|
}
|
||||||
exactOut = true
|
exactOut = true
|
||||||
wrapped, wrappedCnt = pumpWrappedAtIdx0(args.QuotedIn, args.Out, args.Plan)
|
wrapped, wrappedCnt = pumpWrappedAtIdx0(args.QuotedIn, args.Out, args.Plan)
|
||||||
|
wrappedAny, wrappedAnyC = pumpWrappedAny(args.Plan)
|
||||||
|
routeIn = args.QuotedIn
|
||||||
|
routeOut = args.Out
|
||||||
case bytes.Equal(disc, jupiterSharedAccountsRoute):
|
case bytes.Equal(disc, jupiterSharedAccountsRoute):
|
||||||
args, err := decodeJupiterV6SharedAccountsRouteArg(instruction.Data[8:])
|
args, err := decodeJupiterV6SharedAccountsRouteArg(instruction.Data[8:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1034,9 +1159,74 @@ func parseJupiterV6Instruction(tx *versionedTransaction, instructionIndex int) (
|
|||||||
_ = args
|
_ = args
|
||||||
inputAmount, planCount = pumpSwapSellAtIdx0(args.In, args.Plan)
|
inputAmount, planCount = pumpSwapSellAtIdx0(args.In, args.Plan)
|
||||||
wrapped, wrappedCnt = pumpWrappedAtIdx0(args.In, args.QuotedOut, args.Plan)
|
wrapped, wrappedCnt = pumpWrappedAtIdx0(args.In, args.QuotedOut, args.Plan)
|
||||||
|
wrappedAny, wrappedAnyC = pumpWrappedAny(args.Plan)
|
||||||
|
routeIn = args.In
|
||||||
|
routeOut = args.QuotedOut
|
||||||
default:
|
default:
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
if bytes.Equal(disc, jupiterRoute) {
|
||||||
|
if len(instruction.Accounts) < 13 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
destMint, err := getStaticKey(tx.Message.StaticAccountKeys, int(instruction.Accounts[5]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if isToken1Mint(destMint) {
|
||||||
|
pumpKey, err := getStaticKey(tx.Message.StaticAccountKeys, int(instruction.Accounts[9]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !pumpKey.Equals(pumpProgramID) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
token0Mint, err := getStaticKey(tx.Message.StaticAccountKeys, int(instruction.Accounts[12]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
token0Amount := decimal.Zero
|
||||||
|
if routeIn > 0 {
|
||||||
|
token0Amount = formatTokenAmount(routeIn)
|
||||||
|
}
|
||||||
|
return &TxSignal{
|
||||||
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Maker: tx.Message.StaticAccountKeys[0].String(),
|
||||||
|
Token0Address: token0Mint.String(),
|
||||||
|
Token1Address: destMint.String(),
|
||||||
|
Token0Amount: token0Amount,
|
||||||
|
Token1Amount: decimal.Zero,
|
||||||
|
Program: "Pump",
|
||||||
|
Event: "sell",
|
||||||
|
IsToken2022: false,
|
||||||
|
IsMayhemMode: false,
|
||||||
|
ExactSOL: false,
|
||||||
|
Block: tx.Block,
|
||||||
|
Token0AmountUint64: routeIn,
|
||||||
|
Token1AmountUint64: 0,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
token0Amount := decimal.Zero
|
||||||
|
if routeOut > 0 {
|
||||||
|
token0Amount = formatTokenAmount(routeOut)
|
||||||
|
}
|
||||||
|
return &TxSignal{
|
||||||
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Maker: tx.Message.StaticAccountKeys[0].String(),
|
||||||
|
Token0Address: destMint.String(),
|
||||||
|
Token1Address: wsolMint,
|
||||||
|
Token0Amount: token0Amount,
|
||||||
|
Token1Amount: decimal.Zero,
|
||||||
|
Program: "Pump",
|
||||||
|
Event: "buy",
|
||||||
|
IsToken2022: false,
|
||||||
|
IsMayhemMode: false,
|
||||||
|
ExactSOL: false,
|
||||||
|
Block: tx.Block,
|
||||||
|
Token0AmountUint64: routeOut,
|
||||||
|
Token1AmountUint64: 0,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
if wrappedCnt > 1 {
|
if wrappedCnt > 1 {
|
||||||
logger.Warn("pumpWrapped at inputIdx=0: multiple instances found", "tx", tx.Signatures[0].String(), "planCount", wrappedCnt)
|
logger.Warn("pumpWrapped at inputIdx=0: multiple instances found", "tx", tx.Signatures[0].String(), "planCount", wrappedCnt)
|
||||||
}
|
}
|
||||||
@@ -1048,6 +1238,31 @@ func parseJupiterV6Instruction(tx *versionedTransaction, instructionIndex int) (
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
token1Mint := solana.WrappedSol
|
||||||
|
token1IsStable := false
|
||||||
|
srcMint, dstMint, ok, err := jupiterV6SourceDestMints(tx.Message, instruction, disc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if isJupiterV6Token1RequiredDisc(disc) {
|
||||||
|
if !ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if !isToken1Mint(srcMint) && !isToken1Mint(dstMint) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ok {
|
||||||
|
if srcMint.Equals(solana.WrappedSol) || dstMint.Equals(solana.WrappedSol) {
|
||||||
|
token1Mint = solana.WrappedSol
|
||||||
|
} else if isStableMint(srcMint) {
|
||||||
|
token1Mint = srcMint
|
||||||
|
token1IsStable = true
|
||||||
|
} else if isStableMint(dstMint) {
|
||||||
|
token1Mint = dstMint
|
||||||
|
token1IsStable = true
|
||||||
|
}
|
||||||
|
}
|
||||||
event := "sell"
|
event := "sell"
|
||||||
exactSol := false
|
exactSol := false
|
||||||
var (
|
var (
|
||||||
@@ -1070,13 +1285,106 @@ func parseJupiterV6Instruction(tx *versionedTransaction, instructionIndex int) (
|
|||||||
}
|
}
|
||||||
token1Amount := decimal.Zero
|
token1Amount := decimal.Zero
|
||||||
if token1AmountUint64 > 0 {
|
if token1AmountUint64 > 0 {
|
||||||
token1Amount = formatSolAmount(token1AmountUint64)
|
if token1IsStable {
|
||||||
|
token1Amount = formatTokenAmount(token1AmountUint64)
|
||||||
|
} else {
|
||||||
|
token1Amount = formatSolAmount(token1AmountUint64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token1Address := wsolMint
|
||||||
|
if token1IsStable {
|
||||||
|
token1Address = token1Mint.String()
|
||||||
}
|
}
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
Maker: tx.Message.StaticAccountKeys[0].String(),
|
Maker: tx.Message.StaticAccountKeys[0].String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: token1Address,
|
||||||
|
Token0Amount: token0Amount,
|
||||||
|
Token1Amount: token1Amount,
|
||||||
|
Program: "Pump",
|
||||||
|
Event: event,
|
||||||
|
IsToken2022: false,
|
||||||
|
IsMayhemMode: false,
|
||||||
|
ExactSOL: exactSol,
|
||||||
|
Block: tx.Block,
|
||||||
|
Token0AmountUint64: token0AmountUint64,
|
||||||
|
Token1AmountUint64: token1AmountUint64,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
if wrappedAnyC > 1 {
|
||||||
|
logger.Warn("pumpWrapped at inputIdx!=0: multiple instances found", "tx", tx.Signatures[0].String(), "planCount", wrappedAnyC)
|
||||||
|
}
|
||||||
|
if wrappedAnyC == 1 && routeIn > 0 && routeOut > 0 {
|
||||||
|
mint, ok, err := findPumpFunMint(tx.Message.StaticAccountKeys, instruction.Accounts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
token1Mint := solana.WrappedSol
|
||||||
|
token1IsStable := false
|
||||||
|
srcMint, dstMint, ok, err := jupiterV6SourceDestMints(tx.Message, instruction, disc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if isJupiterV6Token1RequiredDisc(disc) {
|
||||||
|
if !ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if !isToken1Mint(srcMint) && !isToken1Mint(dstMint) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ok {
|
||||||
|
if srcMint.Equals(solana.WrappedSol) || dstMint.Equals(solana.WrappedSol) {
|
||||||
|
token1Mint = solana.WrappedSol
|
||||||
|
} else if isStableMint(srcMint) {
|
||||||
|
token1Mint = srcMint
|
||||||
|
token1IsStable = true
|
||||||
|
} else if isStableMint(dstMint) {
|
||||||
|
token1Mint = dstMint
|
||||||
|
token1IsStable = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event := "sell"
|
||||||
|
exactSol := false
|
||||||
|
var (
|
||||||
|
token0AmountUint64 uint64
|
||||||
|
token1AmountUint64 uint64
|
||||||
|
)
|
||||||
|
if wrappedAny.IsBuy {
|
||||||
|
event = "buy"
|
||||||
|
exactSol = !exactOut
|
||||||
|
token0AmountUint64 = routeOut
|
||||||
|
token1AmountUint64 = routeIn
|
||||||
|
} else {
|
||||||
|
exactSol = exactOut && routeOut > 0
|
||||||
|
token0AmountUint64 = routeIn
|
||||||
|
token1AmountUint64 = routeOut
|
||||||
|
}
|
||||||
|
token0Amount := decimal.Zero
|
||||||
|
if token0AmountUint64 > 0 {
|
||||||
|
token0Amount = formatTokenAmount(token0AmountUint64)
|
||||||
|
}
|
||||||
|
token1Amount := decimal.Zero
|
||||||
|
if token1AmountUint64 > 0 {
|
||||||
|
if token1IsStable {
|
||||||
|
token1Amount = formatTokenAmount(token1AmountUint64)
|
||||||
|
} else {
|
||||||
|
token1Amount = formatSolAmount(token1AmountUint64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token1Address := wsolMint
|
||||||
|
if token1IsStable {
|
||||||
|
token1Address = token1Mint.String()
|
||||||
|
}
|
||||||
|
return &TxSignal{
|
||||||
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Maker: tx.Message.StaticAccountKeys[0].String(),
|
||||||
|
Token0Address: mint.String(),
|
||||||
|
Token1Address: token1Address,
|
||||||
Token0Amount: token0Amount,
|
Token0Amount: token0Amount,
|
||||||
Token1Amount: token1Amount,
|
Token1Amount: token1Amount,
|
||||||
Program: "Pump",
|
Program: "Pump",
|
||||||
|
|||||||
Reference in New Issue
Block a user