punm parser
This commit is contained in:
12
budget.go
12
budget.go
@@ -10,31 +10,31 @@ type setComputeData struct {
|
|||||||
Units uint64
|
Units uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func budgetParser(result *RawTx, instr Instruction, innerInstructions InnerInstructions, offset [2]uint, tx *Tx) ([2]uint, error) {
|
func budgetParser(tx *Tx, instr Instruction, _ InnerInstructions, offset [2]uint) ([2]uint, error) {
|
||||||
if offset[1] != 0 {
|
if offset[1] != 0 {
|
||||||
return increaseOffset(offset), nil
|
return increaseOffset(offset), nil
|
||||||
}
|
}
|
||||||
decode := result.Transaction.Message.Instructions[offset[0]].Data
|
decode := instr.Data
|
||||||
discriminator := decode[0]
|
discriminator := decode[0]
|
||||||
|
|
||||||
switch discriminator {
|
switch discriminator {
|
||||||
case setComputeUnitLimitDiscriminator:
|
case setComputeUnitLimitDiscriminator:
|
||||||
return computeUnitLimitParser(result, offset, tx, decode[1:])
|
return computeUnitLimitParser(offset, tx, decode[1:])
|
||||||
case setComputeUnitPriceDiscriminator:
|
case setComputeUnitPriceDiscriminator:
|
||||||
return computeUnitPriceParser(result, offset, tx, decode[1:])
|
return computeUnitPriceParser(offset, tx, decode[1:])
|
||||||
default:
|
default:
|
||||||
return increaseOffset(offset), nil
|
return increaseOffset(offset), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func computeUnitLimitParser(_ *RawTx, offset [2]uint, _ *Tx, decodedData []byte) ([2]uint, error) {
|
func computeUnitLimitParser(offset [2]uint, _ *Tx, decodedData []byte) ([2]uint, error) {
|
||||||
if len(decodedData) < 8 {
|
if len(decodedData) < 8 {
|
||||||
return increaseOffset(offset), nil
|
return increaseOffset(offset), nil
|
||||||
}
|
}
|
||||||
return increaseOffset(offset), nil
|
return increaseOffset(offset), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func computeUnitPriceParser(_ *RawTx, offset [2]uint, tx *Tx, decodedData []byte) ([2]uint, error) {
|
func computeUnitPriceParser(offset [2]uint, tx *Tx, decodedData []byte) ([2]uint, error) {
|
||||||
if len(decodedData) < 8 {
|
if len(decodedData) < 8 {
|
||||||
return increaseOffset(offset), nil
|
return increaseOffset(offset), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
package pump_parser
|
|
||||||
@@ -54,7 +54,7 @@ func main() {
|
|||||||
instructorErrIndex, customerErrCode, _ = txErr.GetCustomErrorCode()
|
instructorErrIndex, customerErrCode, _ = txErr.GetCustomErrorCode()
|
||||||
fmt.Printf("now: %s, block: %d, tx: %s, errInstr Code: %d, errInstrIndex: %d, err: %v\n", time.Now().Format("2006-01-02 15:04:05"), ptx.Block, ptx.GetTxHash(), customerErrCode, instructorErrIndex, ptx.Err)
|
fmt.Printf("now: %s, block: %d, tx: %s, errInstr Code: %d, errInstrIndex: %d, err: %v\n", time.Now().Format("2006-01-02 15:04:05"), ptx.Block, ptx.GetTxHash(), customerErrCode, instructorErrIndex, ptx.Err)
|
||||||
} else {
|
} else {
|
||||||
txs := example.FromTx(ptx, msg.RawTx)
|
txs := example.FromTx(ptx)
|
||||||
if len(txs) == 0 {
|
if len(txs) == 0 {
|
||||||
fmt.Printf("tx is empty, block: %d, tx %s \n", ptx.Block, ptx.GetTxHash())
|
fmt.Printf("tx is empty, block: %d, tx %s \n", ptx.Block, ptx.GetTxHash())
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -18,5 +18,4 @@ type SubscriptionMessage struct {
|
|||||||
|
|
||||||
Block *BlockInfo
|
Block *BlockInfo
|
||||||
Tx *pump_parser.Tx
|
Tx *pump_parser.Tx
|
||||||
RawTx *pump_parser.RawTx
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type PumpHandler struct {
|
type PumpHandler struct {
|
||||||
callback func(*types.Tx, *types.RawTx)
|
callback func(*types.Tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPumpHandler(cb func(*types.Tx, *types.RawTx)) *PumpHandler {
|
func NewPumpHandler(cb func(*types.Tx)) *PumpHandler {
|
||||||
return &PumpHandler{
|
return &PumpHandler{
|
||||||
callback: func(tx *types.Tx, tx2 *types.RawTx) {
|
callback: func(tx *types.Tx) {
|
||||||
//tx.Check(tx2)
|
//tx.Check(tx2)
|
||||||
cb(tx, tx2)
|
cb(tx)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,11 +40,13 @@ func (h *PumpHandler) HandleMessage(rawTx *types.RawTx) {
|
|||||||
|
|
||||||
BeforeSolBalance: beforeSolBalance,
|
BeforeSolBalance: beforeSolBalance,
|
||||||
AfterSOLBalance: afterSolBalance,
|
AfterSOLBalance: afterSolBalance,
|
||||||
}, rawTx)
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedTx, err := types.Parser(rawTx)
|
var parsedTx = &types.Tx{}
|
||||||
|
parsedTx.SetRawTx(rawTx)
|
||||||
|
err := parsedTx.Parser()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("parser error: %s, block: %d tx: %s\n", err, rawTx.Slot, rawTx.TxHash())
|
fmt.Printf("parser error: %s, block: %d tx: %s\n", err, rawTx.Slot, rawTx.TxHash())
|
||||||
return
|
return
|
||||||
@@ -55,6 +57,6 @@ func (h *PumpHandler) HandleMessage(rawTx *types.RawTx) {
|
|||||||
}
|
}
|
||||||
// fmt.Println(parsedTx.GetTxHash(), len(parsedTx.Swaps))
|
// fmt.Println(parsedTx.GetTxHash(), len(parsedTx.Swaps))
|
||||||
if h.callback != nil {
|
if h.callback != nil {
|
||||||
h.callback(parsedTx, rawTx)
|
h.callback(parsedTx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ func NewClientWithPumpSwap(endpoint string, ch chan SubscriptionMessage) *Client
|
|||||||
subStatus: false,
|
subStatus: false,
|
||||||
subscription: &subscription,
|
subscription: &subscription,
|
||||||
}
|
}
|
||||||
c.handler = NewPumpHandler(func(tx *types.Tx, tx2 *types.RawTx) {
|
c.handler = NewPumpHandler(func(tx *types.Tx) {
|
||||||
c.sendTx(tx, tx2)
|
c.sendTx(tx)
|
||||||
})
|
})
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
@@ -107,8 +107,8 @@ func NewClientWithLaunchLab(endpoint string, ch chan SubscriptionMessage) *Clien
|
|||||||
subStatus: false,
|
subStatus: false,
|
||||||
subscription: &subscription,
|
subscription: &subscription,
|
||||||
}
|
}
|
||||||
c.handler = NewPumpHandler(func(tx *types.Tx, tx2 *types.RawTx) {
|
c.handler = NewPumpHandler(func(tx *types.Tx) {
|
||||||
c.sendTx(tx, tx2)
|
c.sendTx(tx)
|
||||||
})
|
})
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
@@ -262,13 +262,12 @@ func (c *Client) computeDelay(slot uint64) int64 {
|
|||||||
return delay
|
return delay
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) sendTx(t *types.Tx, tx *types.RawTx) {
|
func (c *Client) sendTx(t *types.Tx) {
|
||||||
c.ch <- SubscriptionMessage{
|
c.ch <- SubscriptionMessage{
|
||||||
Reconnect: c.firstMessage,
|
Reconnect: c.firstMessage,
|
||||||
EstimateDelaySecond: c.computeDelay(tx.Slot),
|
EstimateDelaySecond: c.computeDelay(t.Block),
|
||||||
Block: nil,
|
Block: nil,
|
||||||
Tx: t,
|
Tx: t,
|
||||||
RawTx: tx,
|
|
||||||
}
|
}
|
||||||
c.firstMessage = false
|
c.firstMessage = false
|
||||||
}
|
}
|
||||||
@@ -288,7 +287,6 @@ func (c *Client) sendBlock(blockMeta *pb.SubscribeUpdateBlockMeta) {
|
|||||||
Height: c.leastBlock.Height,
|
Height: c.leastBlock.Height,
|
||||||
},
|
},
|
||||||
Tx: nil,
|
Tx: nil,
|
||||||
RawTx: nil,
|
|
||||||
}
|
}
|
||||||
c.firstMessage = false
|
c.firstMessage = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,14 +64,15 @@ func (tx *Tx) GetTxHash() string {
|
|||||||
return tx.CachedTxHash
|
return tx.CachedTxHash
|
||||||
}
|
}
|
||||||
|
|
||||||
func FromTx(tx *parser.Tx, raw *parser.RawTx) []*Tx {
|
func FromTx(tx *parser.Tx) []*Tx {
|
||||||
var txs []*Tx = make([]*Tx, 0, len(tx.Swaps))
|
var txs = make([]*Tx, 0, len(tx.Swaps))
|
||||||
mev, mevFee := tx.CheckMevAgent()
|
mev, mevFee := tx.CheckMevAgent()
|
||||||
for i, s := range tx.Swaps {
|
for i, s := range tx.Swaps {
|
||||||
var newTx *Tx
|
var newTx *Tx
|
||||||
platform, platformFee := tx.CheckPlatform(s, raw)
|
platform, platformFee := tx.CheckPlatform(s)
|
||||||
token0Program := s.BaseTokenProgram
|
token0Program := s.BaseTokenProgram
|
||||||
token0Address := s.BaseMint
|
token0Address := s.BaseMint
|
||||||
|
token0Decimals := s.BaseMintDecimals
|
||||||
if s.Program == "Pump" {
|
if s.Program == "Pump" {
|
||||||
newTx = &Tx{
|
newTx = &Tx{
|
||||||
Err: nil,
|
Err: nil,
|
||||||
@@ -126,6 +127,7 @@ func FromTx(tx *parser.Tx, raw *parser.RawTx) []*Tx {
|
|||||||
}
|
}
|
||||||
token0Program = s.QuoteTokenProgram
|
token0Program = s.QuoteTokenProgram
|
||||||
token0Address = s.QuoteMint
|
token0Address = s.QuoteMint
|
||||||
|
token0Decimals = s.QuoteMintDecimals
|
||||||
newTx = &Tx{
|
newTx = &Tx{
|
||||||
Err: nil,
|
Err: nil,
|
||||||
//BondingCurve: s.Pool.String(),
|
//BondingCurve: s.Pool.String(),
|
||||||
@@ -220,7 +222,7 @@ func FromTx(tx *parser.Tx, raw *parser.RawTx) []*Tx {
|
|||||||
}
|
}
|
||||||
if newTx.Maker == "HV1KXxWFaSeriyFvXyx48FqG9BoFbfinB8njCJonqP7K" && newTx.EntryContract == "oKXAggregatorV2" {
|
if newTx.Maker == "HV1KXxWFaSeriyFvXyx48FqG9BoFbfinB8njCJonqP7K" && newTx.EntryContract == "oKXAggregatorV2" {
|
||||||
newTx.Maker = tx.Signer.String()
|
newTx.Maker = tx.Signer.String()
|
||||||
newTx.AfterSignerToken0Balance = parser.GetTokenBalanceAfterTx(raw, 0, token0Program, token0Address)
|
newTx.AfterSignerToken0Balance = tx.GetSignerTokenBalanceAfterTx(token0Program, token0Address).Div(decimal.New(1, int32(token0Decimals)))
|
||||||
}
|
}
|
||||||
|
|
||||||
txs = append(txs, newTx)
|
txs = append(txs, newTx)
|
||||||
|
|||||||
51
globals.go
51
globals.go
@@ -2,6 +2,7 @@ package pump_parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/gagliardetto/solana-go"
|
"github.com/gagliardetto/solana-go"
|
||||||
)
|
)
|
||||||
@@ -20,42 +21,22 @@ var (
|
|||||||
InstructionIgnoredError = errors.New("instruction ignored")
|
InstructionIgnoredError = errors.New("instruction ignored")
|
||||||
)
|
)
|
||||||
|
|
||||||
type swapParser func(result *RawTx, instr Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error)
|
type swapParser func(tx *Tx, instr Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error)
|
||||||
type actionParser func(result *RawTx, instr Instruction, innerInstructions InnerInstructions, offset [2]uint, tx *Tx) ([2]uint, error)
|
type actionParser func(tx *Tx, instr Instruction, innerInstructions InnerInstructions, offset [2]uint) ([2]uint, error)
|
||||||
|
|
||||||
//type PumpComplete struct {
|
func getInnerInstructions(innerInstructions InnerInstructions, offset uint) ([]Instruction, error) {
|
||||||
// IsMayhem bool
|
var inners []Instruction
|
||||||
// IsToken2022 bool
|
var prefixLen = offset
|
||||||
//}
|
if prefixLen > uint(len(innerInstructions.Instructions)) {
|
||||||
|
return nil, fmt.Errorf("error inner instruction index out of range")
|
||||||
//type PumpStatusCache map[solana.PublicKey]PumpComplete
|
}
|
||||||
//
|
if prefixLen == 0 {
|
||||||
//var (
|
inners = innerInstructions.Instructions
|
||||||
// pumpCompleteCache PumpStatusCache = make(map[solana.PublicKey]PumpComplete)
|
} else {
|
||||||
// pumpCompleteCacheLock sync.Mutex
|
inners = innerInstructions.Instructions[prefixLen:]
|
||||||
//)
|
}
|
||||||
//
|
return inners, nil
|
||||||
//func getPumpCompleteStatus(pumpToken solana.PublicKey) (PumpComplete, bool) {
|
}
|
||||||
// pumpCompleteCacheLock.Lock()
|
|
||||||
// defer pumpCompleteCacheLock.Unlock()
|
|
||||||
// status, exists := pumpCompleteCache[pumpToken]
|
|
||||||
// return status, exists
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//func setPumpCompleteStatus(pumpToken solana.PublicKey, mayhem bool, token2022 bool) {
|
|
||||||
// pumpCompleteCacheLock.Lock()
|
|
||||||
// defer pumpCompleteCacheLock.Unlock()
|
|
||||||
// pumpCompleteCache[pumpToken] = PumpComplete{
|
|
||||||
// IsMayhem: mayhem,
|
|
||||||
// IsToken2022: token2022,
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//func removePumpCompleteStatus(pumpToken solana.PublicKey) {
|
|
||||||
// pumpCompleteCacheLock.Lock()
|
|
||||||
// defer pumpCompleteCacheLock.Unlock()
|
|
||||||
// delete(pumpCompleteCache, pumpToken)
|
|
||||||
//}
|
|
||||||
|
|
||||||
func isMayhemPump(feeAccount solana.PublicKey) bool {
|
func isMayhemPump(feeAccount solana.PublicKey) bool {
|
||||||
for _, mayhemFeeAccount := range mayhemFeeAccounts {
|
for _, mayhemFeeAccount := range mayhemFeeAccounts {
|
||||||
|
|||||||
49
parser.go
49
parser.go
@@ -17,40 +17,45 @@ var actionPrograms = map[solana.PublicKey]actionParser{
|
|||||||
budgGetProgram: budgetParser,
|
budgGetProgram: budgetParser,
|
||||||
}
|
}
|
||||||
|
|
||||||
func Parser(rawTx *RawTx) (*Tx, error) {
|
func (tx *Tx) Parser() error {
|
||||||
accountList := rawTx.getAccountList()
|
if tx.rawTx == nil {
|
||||||
var tx = &Tx{
|
return errors.New("rawTx is nil")
|
||||||
TxHash: (*[64]byte)((rawTx.Transaction.Signatures[0][:])),
|
|
||||||
Signer: rawTx.GetSigner(),
|
|
||||||
Block: rawTx.Slot,
|
|
||||||
BlockIndex: uint64(rawTx.IndexWithinBlock),
|
|
||||||
BlockAt: rawTx.BlockTime,
|
|
||||||
|
|
||||||
BeforeSolBalance: decimal.NewFromUint64(rawTx.Meta.PreBalances[0]).Div(decimal.NewFromInt(1e9)),
|
|
||||||
AfterSOLBalance: decimal.NewFromUint64(rawTx.Meta.PostBalances[0]).Div(decimal.NewFromInt(1e9)),
|
|
||||||
}
|
}
|
||||||
|
accountList := tx.rawTx.getAccountList()
|
||||||
|
|
||||||
|
tx.TxHash = (*[64]byte)((tx.rawTx.Transaction.Signatures[0][:]))
|
||||||
|
tx.Signer = tx.rawTx.GetSigner()
|
||||||
|
tx.Block = tx.rawTx.Slot
|
||||||
|
tx.BlockIndex = uint64(tx.rawTx.IndexWithinBlock)
|
||||||
|
tx.BlockAt = tx.rawTx.BlockTime
|
||||||
|
|
||||||
|
tx.BeforeSolBalance = decimal.NewFromUint64(tx.rawTx.Meta.PreBalances[0]).Div(decimal.NewFromInt(1e9))
|
||||||
|
tx.AfterSOLBalance = decimal.NewFromUint64(tx.rawTx.Meta.PostBalances[0]).Div(decimal.NewFromInt(1e9))
|
||||||
|
|
||||||
|
tx.Token = make(map[solana.PublicKey]TokenMeta)
|
||||||
|
|
||||||
var innersMap = make(map[int]InnerInstructions)
|
var innersMap = make(map[int]InnerInstructions)
|
||||||
for _, inner := range rawTx.Meta.InnerInstructions {
|
for _, inner := range tx.rawTx.Meta.InnerInstructions {
|
||||||
innersMap[inner.Index] = inner
|
innersMap[inner.Index] = inner
|
||||||
}
|
}
|
||||||
for i, instr := range rawTx.Transaction.Message.Instructions {
|
for i, instr := range tx.rawTx.Transaction.Message.Instructions {
|
||||||
programAccount := accountList[instr.ProgramIDIndex]
|
programAccount := accountList[instr.ProgramIDIndex]
|
||||||
if p, exists := swapPrograms[programAccount]; exists {
|
if p, exists := swapPrograms[programAccount]; exists {
|
||||||
swaps, _, err := p(rawTx, instr, innersMap[i], [2]uint{uint(i), uint(0)})
|
swaps, _, err := p(tx, instr, innersMap[i], [2]uint{uint(i), uint(0)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, InstructionIgnoredError) {
|
if errors.Is(err, InstructionIgnoredError) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
tx.Swaps = append(tx.Swaps, swaps...)
|
tx.Swaps = append(tx.Swaps, swaps...)
|
||||||
} else if p, exists := actionPrograms[programAccount]; exists {
|
} else if p, exists := actionPrograms[programAccount]; exists {
|
||||||
_, err := p(rawTx, instr, innersMap[i], [2]uint{uint(i), uint(0)}, tx)
|
_, err := p(tx, instr, innersMap[i], [2]uint{uint(i), uint(0)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, InstructionIgnoredError) {
|
if errors.Is(err, InstructionIgnoredError) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ii := i
|
ii := i
|
||||||
@@ -61,25 +66,25 @@ func Parser(rawTx *RawTx) (*Tx, error) {
|
|||||||
innerProgramAccount := accountList[innerInstr.ProgramIDIndex]
|
innerProgramAccount := accountList[innerInstr.ProgramIDIndex]
|
||||||
|
|
||||||
if p, exists := swapPrograms[innerProgramAccount]; exists {
|
if p, exists := swapPrograms[innerProgramAccount]; exists {
|
||||||
swaps, offset, err := p(rawTx, innerInstr, innersMap[i], [2]uint{uint(i), uint(j)})
|
swaps, offset, err := p(tx, innerInstr, innersMap[i], [2]uint{uint(i), uint(j)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, InstructionIgnoredError) {
|
if errors.Is(err, InstructionIgnoredError) {
|
||||||
j = int(offset[1])
|
j = int(offset[1])
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
tx.Swaps = append(tx.Swaps, swaps...)
|
tx.Swaps = append(tx.Swaps, swaps...)
|
||||||
j = int(offset[1])
|
j = int(offset[1])
|
||||||
ii = int(offset[0])
|
ii = int(offset[0])
|
||||||
} else if p, exists := actionPrograms[innerProgramAccount]; exists {
|
} else if p, exists := actionPrograms[innerProgramAccount]; exists {
|
||||||
offset, err := p(rawTx, innerInstr, innersMap[i], [2]uint{uint(i), uint(j)}, tx)
|
offset, err := p(tx, innerInstr, innersMap[i], [2]uint{uint(i), uint(j)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, InstructionIgnoredError) {
|
if errors.Is(err, InstructionIgnoredError) {
|
||||||
j = int(offset[1])
|
j = int(offset[1])
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
j = int(offset[1])
|
j = int(offset[1])
|
||||||
ii = int(offset[0])
|
ii = int(offset[0])
|
||||||
@@ -93,5 +98,5 @@ func Parser(rawTx *RawTx) (*Tx, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tx, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
57
pump.go
57
pump.go
@@ -19,9 +19,9 @@ func increaseOffset(offset [2]uint) [2]uint {
|
|||||||
// pumpParser // routes pump program instructions to their respective parsers,
|
// pumpParser // routes pump program instructions to their respective parsers,
|
||||||
// offset is [outerIndex, innerIndex] index of instructions in the transaction,
|
// offset is [outerIndex, innerIndex] index of instructions in the transaction,
|
||||||
// if innerIndex == 0 this is outer instruction,if it's an inner instruction, outerIndex is the index of the parent instruction.
|
// if innerIndex == 0 this is outer instruction,if it's an inner instruction, outerIndex is the index of the parent instruction.
|
||||||
func pumpParser(result *RawTx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
func pumpParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
||||||
|
|
||||||
if !result.accountList[instruction.ProgramIDIndex].Equals(pumpProgram) {
|
if !tx.rawTx.accountList[instruction.ProgramIDIndex].Equals(pumpProgram) {
|
||||||
return nil, increaseOffset(offset), fmt.Errorf("pump program instruction not found, offset, %d, %d", offset[0], offset[1])
|
return nil, increaseOffset(offset), fmt.Errorf("pump program instruction not found, offset, %d, %d", offset[0], offset[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,11 +35,11 @@ func pumpParser(result *RawTx, instruction Instruction, innerInstructions InnerI
|
|||||||
|
|
||||||
switch discriminator {
|
switch discriminator {
|
||||||
case pumpBuyV2Discriminator, pumpBuyDiscriminator, pumpSellDiscriminator:
|
case pumpBuyV2Discriminator, pumpBuyDiscriminator, pumpSellDiscriminator:
|
||||||
return BuyOrSellParser(result, instruction, innerInstructions, offset)
|
return BuyOrSellParser(tx, instruction, innerInstructions, offset)
|
||||||
case pumpCreateDiscriminator, pumpCreateV2Discriminator:
|
case pumpCreateDiscriminator, pumpCreateV2Discriminator:
|
||||||
return CreateParser(result, instruction, innerInstructions, offset)
|
return CreateParser(tx, instruction, innerInstructions, offset)
|
||||||
case pumpMigrateDiscriminator:
|
case pumpMigrateDiscriminator:
|
||||||
return MigrateParser(result, instruction, innerInstructions, offset)
|
return MigrateParser(tx, instruction, innerInstructions, offset)
|
||||||
default:
|
default:
|
||||||
return nil, increaseOffset(offset), InstructionIgnoredError
|
return nil, increaseOffset(offset), InstructionIgnoredError
|
||||||
}
|
}
|
||||||
@@ -82,21 +82,8 @@ type PumpCreateEvent struct {
|
|||||||
IsMayhemMode bool
|
IsMayhemMode bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func getInnerInstructions(innerInstructions InnerInstructions, offset uint) ([]Instruction, error) {
|
func CreateParser(tx *Tx, instr Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
||||||
var inners []Instruction
|
result := tx.rawTx
|
||||||
var prefixLen = offset
|
|
||||||
if prefixLen > uint(len(innerInstructions.Instructions)) {
|
|
||||||
return nil, fmt.Errorf("error inner instruction index out of range")
|
|
||||||
}
|
|
||||||
if prefixLen == 0 {
|
|
||||||
inners = innerInstructions.Instructions
|
|
||||||
} else {
|
|
||||||
inners = innerInstructions.Instructions[prefixLen:]
|
|
||||||
}
|
|
||||||
return inners, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateParser(result *RawTx, instr Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
|
||||||
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
||||||
|
|
||||||
var programIndex = instr.ProgramIDIndex
|
var programIndex = instr.ProgramIDIndex
|
||||||
@@ -134,6 +121,16 @@ func CreateParser(result *RawTx, instr Instruction, innerInstructions InnerInstr
|
|||||||
userBase := getAccountBalanceAfterTx(result, userIndex)
|
userBase := getAccountBalanceAfterTx(result, userIndex)
|
||||||
userQuote, _ := GetSolAfterTx(result, userIndex)
|
userQuote, _ := GetSolAfterTx(result, userIndex)
|
||||||
|
|
||||||
|
totalSupply := decimal.NewFromUint64(createEvent.TokenTotalSupply).Div(decimal.New(1, 6))
|
||||||
|
tx.Token[createEvent.Mint] = TokenMeta{
|
||||||
|
Mint: createEvent.Mint,
|
||||||
|
TokenProgram: createEvent.TokenProgram,
|
||||||
|
Decimals: 6,
|
||||||
|
Name: createEvent.Name,
|
||||||
|
Symbol: createEvent.Symbol,
|
||||||
|
Url: createEvent.Uri,
|
||||||
|
TotalSupply: &totalSupply,
|
||||||
|
}
|
||||||
return []Swap{
|
return []Swap{
|
||||||
{
|
{
|
||||||
Program: SolProgramPump,
|
Program: SolProgramPump,
|
||||||
@@ -186,7 +183,8 @@ type CompleteEvent struct {
|
|||||||
Timestamp int64
|
Timestamp int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuyOrSellParser(result *RawTx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
func BuyOrSellParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
||||||
|
result := tx.rawTx
|
||||||
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
||||||
var err error
|
var err error
|
||||||
var programIndex = instruction.ProgramIDIndex
|
var programIndex = instruction.ProgramIDIndex
|
||||||
@@ -255,6 +253,13 @@ func BuyOrSellParser(result *RawTx, instruction Instruction, innerInstructions I
|
|||||||
event = "sell"
|
event = "sell"
|
||||||
baseTokenProgram = result.accountList[instruction.Accounts[9]]
|
baseTokenProgram = result.accountList[instruction.Accounts[9]]
|
||||||
}
|
}
|
||||||
|
if _, exists := tx.Token[tradeEvent.Mint]; !exists {
|
||||||
|
tx.Token[tradeEvent.Mint] = TokenMeta{
|
||||||
|
Mint: tradeEvent.Mint,
|
||||||
|
TokenProgram: baseTokenProgram,
|
||||||
|
Decimals: 6,
|
||||||
|
}
|
||||||
|
}
|
||||||
swaps := []Swap{
|
swaps := []Swap{
|
||||||
{
|
{
|
||||||
Program: SolProgramPump,
|
Program: SolProgramPump,
|
||||||
@@ -314,7 +319,8 @@ type MigrateEvent struct {
|
|||||||
Pool solana.PublicKey
|
Pool solana.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func MigrateParser(result *RawTx, instr Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
func MigrateParser(tx *Tx, instr Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
||||||
|
result := tx.rawTx
|
||||||
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
||||||
var err error
|
var err error
|
||||||
programIndex := instr.ProgramIDIndex
|
programIndex := instr.ProgramIDIndex
|
||||||
@@ -389,6 +395,13 @@ func MigrateParser(result *RawTx, instr Instruction, innerInstructions InnerInst
|
|||||||
}
|
}
|
||||||
userQuote, _ := GetSolAfterTx(result, userIndex)
|
userQuote, _ := GetSolAfterTx(result, userIndex)
|
||||||
|
|
||||||
|
if _, exists := tx.Token[migrateEvent.Mint]; !exists {
|
||||||
|
tx.Token[migrateEvent.Mint] = TokenMeta{
|
||||||
|
Mint: migrateEvent.Mint,
|
||||||
|
TokenProgram: baseTokenProgram,
|
||||||
|
Decimals: 6,
|
||||||
|
}
|
||||||
|
}
|
||||||
swaps := []Swap{
|
swaps := []Swap{
|
||||||
{
|
{
|
||||||
Program: SolProgramPump,
|
Program: SolProgramPump,
|
||||||
|
|||||||
112
pumpamm.go
112
pumpamm.go
@@ -123,9 +123,8 @@ type ammWithdrawEvent struct {
|
|||||||
UserPoolTokenAccount solana.PublicKey
|
UserPoolTokenAccount solana.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func pumpAmmParser(result *RawTx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
func pumpAmmParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
||||||
|
if !tx.rawTx.accountList[instruction.ProgramIDIndex].Equals(pumpAmmProgram) {
|
||||||
if !result.accountList[instruction.ProgramIDIndex].Equals(pumpAmmProgram) {
|
|
||||||
return nil, increaseOffset(offset), fmt.Errorf("pump amm program instruction not found, offset: %d, %d", offset[0], offset[1])
|
return nil, increaseOffset(offset), fmt.Errorf("pump amm program instruction not found, offset: %d, %d", offset[0], offset[1])
|
||||||
}
|
}
|
||||||
decode := instruction.Data
|
decode := instruction.Data
|
||||||
@@ -137,21 +136,22 @@ func pumpAmmParser(result *RawTx, instruction Instruction, innerInstructions Inn
|
|||||||
discriminator := *(*[8]byte)(decode[:8])
|
discriminator := *(*[8]byte)(decode[:8])
|
||||||
switch discriminator {
|
switch discriminator {
|
||||||
case pumpAmmCreateDiscriminator:
|
case pumpAmmCreateDiscriminator:
|
||||||
return ammCreatePoolParser(result, instruction, innerInstructions, offset)
|
return ammCreatePoolParser(tx, instruction, innerInstructions, offset)
|
||||||
case pumpAmmBuyDiscriminator:
|
case pumpAmmBuyDiscriminator:
|
||||||
return ammBuyParser(result, instruction, innerInstructions, offset)
|
return ammBuyParser(tx, instruction, innerInstructions, offset)
|
||||||
case pumpAmmSellDiscriminator:
|
case pumpAmmSellDiscriminator:
|
||||||
return ammSellParser(result, instruction, innerInstructions, offset)
|
return ammSellParser(tx, instruction, innerInstructions, offset)
|
||||||
case pumpAmmDepositDiscriminator:
|
case pumpAmmDepositDiscriminator:
|
||||||
return depositParse(result, instruction, innerInstructions, offset)
|
return depositParse(tx, instruction, innerInstructions, offset)
|
||||||
case pumpAmmWithdrawDiscriminator:
|
case pumpAmmWithdrawDiscriminator:
|
||||||
return withdrawParse(result, instruction, innerInstructions, offset)
|
return withdrawParse(tx, instruction, innerInstructions, offset)
|
||||||
default:
|
default:
|
||||||
return nil, increaseOffset(offset), InstructionIgnoredError
|
return nil, increaseOffset(offset), InstructionIgnoredError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ammCreatePoolParser(result *RawTx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
func ammCreatePoolParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
||||||
|
result := tx.rawTx
|
||||||
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
||||||
var err error
|
var err error
|
||||||
var prefixLen = offset[1]
|
var prefixLen = offset[1]
|
||||||
@@ -182,6 +182,22 @@ func ammCreatePoolParser(result *RawTx, instruction Instruction, innerInstructio
|
|||||||
|
|
||||||
baseTokenProgram := result.accountList[instruction.Accounts[13]]
|
baseTokenProgram := result.accountList[instruction.Accounts[13]]
|
||||||
quoteTokenProgram := result.accountList[instruction.Accounts[14]]
|
quoteTokenProgram := result.accountList[instruction.Accounts[14]]
|
||||||
|
if _, exists := tx.Token[createEvent.BaseMint]; !exists && !createEvent.BaseMint.Equals(wSolMint) {
|
||||||
|
tx.Token[createEvent.BaseMint] = TokenMeta{
|
||||||
|
Mint: createEvent.BaseMint,
|
||||||
|
Decimals: createEvent.BaseMintDecimals,
|
||||||
|
TokenProgram: baseTokenProgram,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, exists := tx.Token[createEvent.QuoteMint]; !exists && !createEvent.QuoteMint.Equals(wSolMint) {
|
||||||
|
tx.Token[createEvent.QuoteMint] = TokenMeta{
|
||||||
|
Mint: createEvent.QuoteMint,
|
||||||
|
Decimals: createEvent.QuoteMintDecimals,
|
||||||
|
TokenProgram: quoteTokenProgram,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return []Swap{
|
return []Swap{
|
||||||
{
|
{
|
||||||
Program: SolProgramPumpAMM,
|
Program: SolProgramPumpAMM,
|
||||||
@@ -208,7 +224,8 @@ func ammCreatePoolParser(result *RawTx, instruction Instruction, innerInstructio
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ammBuyParser(result *RawTx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
func ammBuyParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
||||||
|
result := tx.rawTx
|
||||||
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
||||||
var err error
|
var err error
|
||||||
var prefixLen = offset[1]
|
var prefixLen = offset[1]
|
||||||
@@ -254,6 +271,21 @@ func ammBuyParser(result *RawTx, instruction Instruction, innerInstructions Inne
|
|||||||
quoteMintDecimals = uint8(meta.UITokenAmount.Decimals)
|
quoteMintDecimals = uint8(meta.UITokenAmount.Decimals)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if _, exists := tx.Token[baseMint]; !exists && !baseMint.Equals(wSolMint) {
|
||||||
|
tx.Token[baseMint] = TokenMeta{
|
||||||
|
Mint: baseMint,
|
||||||
|
Decimals: baseMintDecimals,
|
||||||
|
TokenProgram: baseTokenProgram,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, exists := tx.Token[quoteMint]; !exists && !quoteMint.Equals(wSolMint) {
|
||||||
|
tx.Token[quoteMint] = TokenMeta{
|
||||||
|
Mint: quoteMint,
|
||||||
|
Decimals: quoteMintDecimals,
|
||||||
|
TokenProgram: quoteTokenProgram,
|
||||||
|
}
|
||||||
|
}
|
||||||
return []Swap{
|
return []Swap{
|
||||||
{
|
{
|
||||||
Program: SolProgramPumpAMM,
|
Program: SolProgramPumpAMM,
|
||||||
@@ -279,7 +311,8 @@ func ammBuyParser(result *RawTx, instruction Instruction, innerInstructions Inne
|
|||||||
}, offset, nil
|
}, offset, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ammSellParser(result *RawTx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
func ammSellParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
||||||
|
result := tx.rawTx
|
||||||
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
||||||
var err error
|
var err error
|
||||||
var prefixLen = offset[1]
|
var prefixLen = offset[1]
|
||||||
@@ -325,6 +358,21 @@ func ammSellParser(result *RawTx, instruction Instruction, innerInstructions Inn
|
|||||||
quoteMintDecimals = uint8(meta.UITokenAmount.Decimals)
|
quoteMintDecimals = uint8(meta.UITokenAmount.Decimals)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if _, exists := tx.Token[baseMint]; !exists && !baseMint.Equals(wSolMint) {
|
||||||
|
tx.Token[baseMint] = TokenMeta{
|
||||||
|
Mint: baseMint,
|
||||||
|
Decimals: baseMintDecimals,
|
||||||
|
TokenProgram: baseTokenProgram,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, exists := tx.Token[quoteMint]; !exists && !quoteMint.Equals(wSolMint) {
|
||||||
|
tx.Token[quoteMint] = TokenMeta{
|
||||||
|
Mint: quoteMint,
|
||||||
|
Decimals: quoteMintDecimals,
|
||||||
|
TokenProgram: quoteTokenProgram,
|
||||||
|
}
|
||||||
|
}
|
||||||
return []Swap{
|
return []Swap{
|
||||||
{
|
{
|
||||||
Program: SolProgramPumpAMM,
|
Program: SolProgramPumpAMM,
|
||||||
@@ -350,7 +398,8 @@ func ammSellParser(result *RawTx, instruction Instruction, innerInstructions Inn
|
|||||||
}, offset, nil
|
}, offset, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func depositParse(result *RawTx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
func depositParse(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
||||||
|
result := tx.rawTx
|
||||||
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
||||||
var err error
|
var err error
|
||||||
var prefixLen = offset[1]
|
var prefixLen = offset[1]
|
||||||
@@ -405,14 +454,30 @@ func depositParse(result *RawTx, instruction Instruction, innerInstructions Inne
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
baseMint := result.accountList[instruction.Accounts[3]]
|
||||||
|
quoteMint := result.accountList[instruction.Accounts[4]]
|
||||||
|
if _, exists := tx.Token[baseMint]; !exists && !baseMint.Equals(wSolMint) {
|
||||||
|
tx.Token[baseMint] = TokenMeta{
|
||||||
|
Mint: baseMint,
|
||||||
|
Decimals: baseMintDecimals,
|
||||||
|
TokenProgram: baseMintProgram,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, exists := tx.Token[quoteMint]; !exists && !quoteMint.Equals(wSolMint) {
|
||||||
|
tx.Token[quoteMint] = TokenMeta{
|
||||||
|
Mint: quoteMint,
|
||||||
|
Decimals: quoteMintDecimals,
|
||||||
|
TokenProgram: quoteMintProgram,
|
||||||
|
}
|
||||||
|
}
|
||||||
return []Swap{
|
return []Swap{
|
||||||
{
|
{
|
||||||
Program: SolProgramPumpAMM,
|
Program: SolProgramPumpAMM,
|
||||||
Event: "deposit",
|
Event: "deposit",
|
||||||
Pool: event.Pool,
|
Pool: event.Pool,
|
||||||
BaseMint: result.accountList[instruction.Accounts[3]],
|
BaseMint: baseMint,
|
||||||
QuoteMint: result.accountList[instruction.Accounts[4]],
|
QuoteMint: quoteMint,
|
||||||
BaseTokenProgram: baseMintProgram,
|
BaseTokenProgram: baseMintProgram,
|
||||||
QuoteTokenProgram: quoteMintProgram,
|
QuoteTokenProgram: quoteMintProgram,
|
||||||
//Creator: solana.PublicKey{},
|
//Creator: solana.PublicKey{},
|
||||||
@@ -431,7 +496,8 @@ func depositParse(result *RawTx, instruction Instruction, innerInstructions Inne
|
|||||||
}, offset, nil
|
}, offset, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func withdrawParse(result *RawTx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
func withdrawParse(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
||||||
|
result := tx.rawTx
|
||||||
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
||||||
var err error
|
var err error
|
||||||
var prefixLen = offset[1]
|
var prefixLen = offset[1]
|
||||||
@@ -486,7 +552,23 @@ func withdrawParse(result *RawTx, instruction Instruction, innerInstructions Inn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
baseMint := result.accountList[instruction.Accounts[3]]
|
||||||
|
quoteMint := result.accountList[instruction.Accounts[4]]
|
||||||
|
if _, exists := tx.Token[baseMint]; !exists && !baseMint.Equals(wSolMint) {
|
||||||
|
tx.Token[baseMint] = TokenMeta{
|
||||||
|
Mint: baseMint,
|
||||||
|
Decimals: baseMintDecimals,
|
||||||
|
TokenProgram: baseMintProgram,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, exists := tx.Token[quoteMint]; !exists && !quoteMint.Equals(wSolMint) {
|
||||||
|
tx.Token[quoteMint] = TokenMeta{
|
||||||
|
Mint: quoteMint,
|
||||||
|
Decimals: quoteMintDecimals,
|
||||||
|
TokenProgram: quoteMintProgram,
|
||||||
|
}
|
||||||
|
}
|
||||||
return []Swap{
|
return []Swap{
|
||||||
{
|
{
|
||||||
Program: SolProgramPumpAMM,
|
Program: SolProgramPumpAMM,
|
||||||
|
|||||||
19
system.go
19
system.go
@@ -7,23 +7,10 @@ import (
|
|||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func systemParser(result *RawTx, instr Instruction, innerInstructions InnerInstructions, offset [2]uint, tx *Tx) ([2]uint, error) {
|
func systemParser(tx *Tx, instruction Instruction, _ InnerInstructions, offset [2]uint) ([2]uint, error) {
|
||||||
var instruction Instruction
|
|
||||||
|
|
||||||
var found bool
|
result := tx.rawTx
|
||||||
if offset[1] == 0 {
|
if !result.accountList[instruction.ProgramIDIndex].Equals(systemProgram) {
|
||||||
instruction = result.Transaction.Message.Instructions[offset[0]]
|
|
||||||
found = true
|
|
||||||
} else {
|
|
||||||
for _, innerInstruction := range result.Meta.InnerInstructions {
|
|
||||||
if innerInstruction.Index == int(offset[0]) {
|
|
||||||
instruction = innerInstruction.Instructions[offset[1]-1]
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
return increaseOffset(offset), fmt.Errorf("system program instruction not found, block: %d, tx: %s, outerIndex: %d, innerIndex: %d", result.Slot, result.TxHash(), offset[0], offset[1])
|
return increaseOffset(offset), fmt.Errorf("system program instruction not found, block: %d, tx: %s, outerIndex: %d, innerIndex: %d", result.Slot, result.TxHash(), offset[0], offset[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
tx.go
22
tx.go
@@ -48,6 +48,7 @@ type mevInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Tx struct {
|
type Tx struct {
|
||||||
|
rawTx *RawTx
|
||||||
Signer solana.PublicKey
|
Signer solana.PublicKey
|
||||||
Err interface{} `json:"err,omitempty"`
|
Err interface{} `json:"err,omitempty"`
|
||||||
Swaps []Swap `json:"swaps,omitempty"`
|
Swaps []Swap `json:"swaps,omitempty"`
|
||||||
@@ -65,20 +66,30 @@ type Tx struct {
|
|||||||
BeforeSolBalance decimal.Decimal `json:"-"`
|
BeforeSolBalance decimal.Decimal `json:"-"`
|
||||||
AfterSOLBalance decimal.Decimal `json:"after_sol_balance"`
|
AfterSOLBalance decimal.Decimal `json:"after_sol_balance"`
|
||||||
|
|
||||||
Token []TokenMeta `gorm:"-"`
|
// update tokenInfo
|
||||||
|
Token map[solana.PublicKey]TokenMeta `gorm:"-"`
|
||||||
|
|
||||||
|
// todo pool info ??
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) SetRawTx(t *RawTx) {
|
||||||
|
tx.rawTx = t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) GetSignerTokenBalanceAfterTx(tokenProgram, tokenMint solana.PublicKey) decimal.Decimal {
|
||||||
|
return GetTokenBalanceAfterTx(tx.rawTx, 0, tokenProgram, tokenMint)
|
||||||
}
|
}
|
||||||
|
|
||||||
type TokenMeta struct {
|
type TokenMeta struct {
|
||||||
Address solana.PublicKey `json:"address"`
|
Mint solana.PublicKey `json:"address"`
|
||||||
TokenProgram solana.PublicKey `json:"token_program"`
|
TokenProgram solana.PublicKey `json:"token_program"`
|
||||||
|
Decimals uint8 `json:"decimals"`
|
||||||
|
|
||||||
Name string
|
Name string
|
||||||
Symbol string
|
Symbol string
|
||||||
Decimal uint8
|
|
||||||
Url string
|
Url string
|
||||||
|
|
||||||
TotalSupply *decimal.Decimal
|
TotalSupply *decimal.Decimal
|
||||||
SignerBalance *decimal.Decimal
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Tx) GetTxHash() string {
|
func (tx *Tx) GetTxHash() string {
|
||||||
@@ -92,8 +103,9 @@ func (tx *Tx) GetTxHash() string {
|
|||||||
return tx.cachedTxHash
|
return tx.cachedTxHash
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Tx) CheckPlatform(swap Swap, rawTx *RawTx) (string, decimal.Decimal) {
|
func (tx *Tx) CheckPlatform(swap Swap) (string, decimal.Decimal) {
|
||||||
// hasSolProgramRaydiumLaunchLabBonk
|
// hasSolProgramRaydiumLaunchLabBonk
|
||||||
|
rawTx := tx.rawTx
|
||||||
var platform string
|
var platform string
|
||||||
var platformFee decimal.Decimal
|
var platformFee decimal.Decimal
|
||||||
if len(tx.Platform) == 0 {
|
if len(tx.Platform) == 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user