swap amount input

This commit is contained in:
thloyi
2026-04-16 14:24:14 +08:00
parent ab0e87a48a
commit e761fd6f84
29 changed files with 1542 additions and 214 deletions

View File

@@ -1,11 +1,26 @@
package pump_parser
import (
"encoding/binary"
"fmt"
"github.com/shopspring/decimal"
)
func decodeRaydiumV4SwapArgs(data []byte) (amountSpecified uint64, otherAmountThreshold uint64, swapMode SwapMode, err error) {
if len(data) < 17 {
return 0, 0, SwapModeUnknown, fmt.Errorf("raydium v4 swap instruction data too short")
}
switch data[0] {
case raydiumV4SwapBaseInDiscriminator, raydiumV4SwapBaseInV2Discriminator:
return binary.LittleEndian.Uint64(data[1:9]), binary.LittleEndian.Uint64(data[9:17]), SwapModeExactIn, nil
case raydiumV4SwapBaseOutDiscriminator, raydiumV4SwapBaseOutV2Discriminator:
return binary.LittleEndian.Uint64(data[9:17]), binary.LittleEndian.Uint64(data[1:9]), SwapModeExactOut, nil
default:
return 0, 0, SwapModeUnknown, InstructionIgnoredError
}
}
func raydiumV4Parser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
if !tx.rawTx.accountList[instruction.ProgramIDIndex].Equals(raydiumV4Program) {
return nil, increaseOffset(offset), fmt.Errorf("raydiumv4 instruction not found, offset, %d, %d", offset[0], offset[1])
@@ -314,6 +329,10 @@ func raydiumv4SwapParser(tx *Tx, instruction Instruction, innerInstructions Inne
vaultQuoteIdx = instruction.Accounts[6]
}
var entryContract = tx.rawTx.accountList[tx.rawTx.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
amountSpecified, otherAmountThreshold, swapMode, err := decodeRaydiumV4SwapArgs(instruction.Data)
if err != nil {
return nil, increaseOffset(offset), err
}
ammAccount := tx.rawTx.accountList[instruction.Accounts[1]]
@@ -376,28 +395,28 @@ func raydiumv4SwapParser(tx *Tx, instruction Instruction, innerInstructions Inne
baseReserve, _ := decimal.NewFromString(baseTokenbalance.UITokenAmount.Amount)
quoteReserve, _ := decimal.NewFromString(quoteTokenbalance.UITokenAmount.Amount)
return []Swap{
{
Program: SolProgramRaydiumV4,
Event: event,
Pool: ammAccount,
BaseMint: baseTokenbalance.MintAccount,
QuoteMint: quoteTokenbalance.MintAccount,
BaseTokenProgram: baseTokenbalance.ProgramIDAccount,
QuoteTokenProgram: quoteTokenbalance.ProgramIDAccount,
BaseMintDecimals: uint8(baseTokenbalance.UITokenAmount.Decimals),
QuoteMintDecimals: uint8(quoteTokenbalance.UITokenAmount.Decimals),
User: user,
BaseAmount: baseAmount,
QuoteAmount: quoteAmount,
BaseReserve: baseReserve,
QuoteReserve: quoteReserve,
Mayhem: false,
UserBaseBalance: userBase,
UserQuoteBalance: userQuote,
EntryContract: entryContract,
},
}, offset, nil
swap := Swap{
Program: SolProgramRaydiumV4,
Event: event,
Pool: ammAccount,
BaseMint: baseTokenbalance.MintAccount,
QuoteMint: quoteTokenbalance.MintAccount,
BaseTokenProgram: baseTokenbalance.ProgramIDAccount,
QuoteTokenProgram: quoteTokenbalance.ProgramIDAccount,
BaseMintDecimals: uint8(baseTokenbalance.UITokenAmount.Decimals),
QuoteMintDecimals: uint8(quoteTokenbalance.UITokenAmount.Decimals),
User: user,
BaseAmount: baseAmount,
QuoteAmount: quoteAmount,
BaseReserve: baseReserve,
QuoteReserve: quoteReserve,
Mayhem: false,
UserBaseBalance: userBase,
UserQuoteBalance: userQuote,
EntryContract: entryContract,
}
swap.SetSwapAmountInfo(swapMode, decimal.NewFromUint64(amountSpecified), decimal.NewFromUint64(otherAmountThreshold))
return []Swap{swap}, offset, nil
}
func raydiumv4SwapV2Parser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
@@ -406,6 +425,10 @@ func raydiumv4SwapV2Parser(tx *Tx, instruction Instruction, innerInstructions In
return nil, increaseOffset(offset), fmt.Errorf("invalid number of accounts for raydiumv4 swapv2 instruction, offset %d, %d", offset[0], offset[1])
}
var entryContract = tx.rawTx.accountList[tx.rawTx.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
amountSpecified, otherAmountThreshold, swapMode, err := decodeRaydiumV4SwapArgs(instruction.Data)
if err != nil {
return nil, increaseOffset(offset), err
}
// Raydium's documented V2 layout uses the first 8 accounts. Routed CPI calls
// may append extra readonly accounts (for example the Raydium program id) at
@@ -475,26 +498,26 @@ func raydiumv4SwapV2Parser(tx *Tx, instruction Instruction, innerInstructions In
baseReserve, _ := decimal.NewFromString(baseTokenbalance.UITokenAmount.Amount)
quoteReserve, _ := decimal.NewFromString(quoteTokenbalance.UITokenAmount.Amount)
return []Swap{
{
Program: SolProgramRaydiumV4,
Event: event,
Pool: ammAccount,
BaseMint: baseTokenbalance.MintAccount,
QuoteMint: quoteTokenbalance.MintAccount,
BaseTokenProgram: baseTokenbalance.ProgramIDAccount,
QuoteTokenProgram: quoteTokenbalance.ProgramIDAccount,
BaseMintDecimals: uint8(baseTokenbalance.UITokenAmount.Decimals),
QuoteMintDecimals: uint8(quoteTokenbalance.UITokenAmount.Decimals),
User: user,
BaseAmount: baseAmount,
QuoteAmount: quoteAmount,
BaseReserve: baseReserve,
QuoteReserve: quoteReserve,
Mayhem: false,
UserBaseBalance: userBase,
UserQuoteBalance: userQuote,
EntryContract: entryContract,
},
}, offset, nil
swap := Swap{
Program: SolProgramRaydiumV4,
Event: event,
Pool: ammAccount,
BaseMint: baseTokenbalance.MintAccount,
QuoteMint: quoteTokenbalance.MintAccount,
BaseTokenProgram: baseTokenbalance.ProgramIDAccount,
QuoteTokenProgram: quoteTokenbalance.ProgramIDAccount,
BaseMintDecimals: uint8(baseTokenbalance.UITokenAmount.Decimals),
QuoteMintDecimals: uint8(quoteTokenbalance.UITokenAmount.Decimals),
User: user,
BaseAmount: baseAmount,
QuoteAmount: quoteAmount,
BaseReserve: baseReserve,
QuoteReserve: quoteReserve,
Mayhem: false,
UserBaseBalance: userBase,
UserQuoteBalance: userQuote,
EntryContract: entryContract,
}
swap.SetSwapAmountInfo(swapMode, decimal.NewFromUint64(amountSpecified), decimal.NewFromUint64(otherAmountThreshold))
return []Swap{swap}, offset, nil
}