Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c732bb2b46 | ||
| 99ff9968bd |
62
cmd/debug_jupv6/main.go
Normal file
62
cmd/debug_jupv6/main.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
hexData := "bb64facc31c4af14be34e6edcc0000006f03a4df67000000b903320000000300000064342100024b00000000dc0500026310270203"
|
||||||
|
b, err := hex.DecodeString(hexData)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
payload := b[8:]
|
||||||
|
|
||||||
|
off := 0
|
||||||
|
read := func(n int) []byte {
|
||||||
|
if off+n > len(payload) {
|
||||||
|
fmt.Printf("OOB read: off=%d n=%d len=%d\n", off, n, len(payload))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
out := payload[off : off+n]
|
||||||
|
off += n
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
u8 := func() uint8 { return read(1)[0] }
|
||||||
|
leU16 := func() uint16 {
|
||||||
|
b := read(2)
|
||||||
|
return uint16(b[0]) | uint16(b[1])<<8
|
||||||
|
}
|
||||||
|
leU32 := func() uint32 {
|
||||||
|
b := read(4)
|
||||||
|
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
||||||
|
}
|
||||||
|
leU64 := func() uint64 {
|
||||||
|
b := read(8)
|
||||||
|
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
|
||||||
|
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("payload len=%d\n", len(payload))
|
||||||
|
amountIn := leU64()
|
||||||
|
quotedOut := leU64()
|
||||||
|
slippage := leU16()
|
||||||
|
platform := leU16()
|
||||||
|
posSlip := leU16()
|
||||||
|
fmt.Printf("in=%d out=%d slip=%d plat=%d pos=%d\n", amountIn, quotedOut, slippage, platform, posSlip)
|
||||||
|
|
||||||
|
planLen := leU32()
|
||||||
|
fmt.Printf("planLen=%d\n", planLen)
|
||||||
|
for i := uint32(0); i < planLen; i++ {
|
||||||
|
swapTag := u8()
|
||||||
|
fmt.Printf("step[%d] swapTag=%d (0x%02x) off=%d\n", i, swapTag, swapTag, off)
|
||||||
|
// payload depends on swapTag; we don't know, so just print next few bytes and stop
|
||||||
|
bps := leU16()
|
||||||
|
inIdx := u8()
|
||||||
|
outIdx := u8()
|
||||||
|
fmt.Printf(" bps=%d inIdx=%d outIdx=%d off=%d\n", bps, inIdx, outIdx, off)
|
||||||
|
}
|
||||||
|
fmt.Printf("done off=%d\n", off)
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@ func main() {
|
|||||||
"pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA",
|
"pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA",
|
||||||
"GS4CU59F31iL7aR2Q8zVS8DRrcRnXX1yjQ66TqNVQnaR", //Event Authority
|
"GS4CU59F31iL7aR2Q8zVS8DRrcRnXX1yjQ66TqNVQnaR", //Event Authority
|
||||||
"5PHirr8joyTMp9JMm6nW7hNDVyEYdkzDqazxPD7RaTjx", // Fee Config
|
"5PHirr8joyTMp9JMm6nW7hNDVyEYdkzDqazxPD7RaTjx", // Fee Config
|
||||||
|
"pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ", // pump fee program
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"photon": {
|
"photon": {
|
||||||
@@ -44,6 +45,11 @@ func main() {
|
|||||||
"BSfD6SHZigAfDWSjzD5Q41jw8LmKwtmjskPH9XW1mrRW",
|
"BSfD6SHZigAfDWSjzD5Q41jw8LmKwtmjskPH9XW1mrRW",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"jupiterV6": {
|
||||||
|
AccountRequired: []string{
|
||||||
|
"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",
|
||||||
|
},
|
||||||
|
},
|
||||||
// TODO: axiom, gmgn, etc.
|
// TODO: axiom, gmgn, etc.
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -77,7 +83,12 @@ func main() {
|
|||||||
return
|
return
|
||||||
case txBatch := <-txCh:
|
case txBatch := <-txCh:
|
||||||
//jsonData, _ := json.MarshalIndent(txBatch, "", " ")
|
//jsonData, _ := json.MarshalIndent(txBatch, "", " ")
|
||||||
fmt.Println(txBatch[0].TxHash)
|
for _, tx := range txBatch {
|
||||||
|
if tx.Label == "jupiterV6" {
|
||||||
|
fmt.Println("===============", tx.TxHash, tx.Token0Address, tx.Token0Amount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//fmt.Println(txBatch[0].TxHash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ type AddressTables struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewAddressTables(rpcClient *rpc.Client) *AddressTables {
|
func NewAddressTables(rpcClient *rpc.Client) *AddressTables {
|
||||||
pool, _ := ants.NewPool(10, ants.WithPreAlloc(true), ants.WithNonblocking(true))
|
pool, _ := ants.NewPool(5, ants.WithPreAlloc(true), ants.WithNonblocking(true))
|
||||||
cache, _ := lru.New[solana.PublicKey, []solana.PublicKey](10000)
|
cache, _ := lru.New[solana.PublicKey, []solana.PublicKey](10000)
|
||||||
return &AddressTables{
|
return &AddressTables{
|
||||||
rpcClient: rpcClient,
|
rpcClient: rpcClient,
|
||||||
@@ -91,8 +91,8 @@ func (at *AddressTables) GetAddressTable(tablePubkey solana.PublicKey, idx []uin
|
|||||||
at.mux.RUnlock()
|
at.mux.RUnlock()
|
||||||
|
|
||||||
var result solana.PublicKeySlice = make([]solana.PublicKey, 0, len(idx))
|
var result solana.PublicKeySlice = make([]solana.PublicKey, 0, len(idx))
|
||||||
for i := range idx {
|
for _, i := range idx {
|
||||||
if int(idx[i]) >= len(addresses) {
|
if int(i) >= len(addresses) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
result = append(result, addresses[i])
|
result = append(result, addresses[i])
|
||||||
|
|||||||
2570
pkg/shreder/juptierv6-idl.json
Normal file
2570
pkg/shreder/juptierv6-idl.json
Normal file
File diff suppressed because it is too large
Load Diff
983
pkg/shreder/juptierv6.go
Normal file
983
pkg/shreder/juptierv6.go
Normal file
@@ -0,0 +1,983 @@
|
|||||||
|
package shreder
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
bin "github.com/gagliardetto/binary"
|
||||||
|
"github.com/gagliardetto/solana-go"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
jupiterRouteV2 = []byte{187, 100, 250, 204, 49, 196, 175, 20}
|
||||||
|
jupiterExactOutRouteV2 = []byte{157, 138, 184, 82, 21, 244, 243, 36}
|
||||||
|
|
||||||
|
jupiterRoute = []byte{229, 23, 203, 151, 122, 227, 173, 42}
|
||||||
|
jupiterRouteWithTokenLedger = []byte{150, 86, 71, 116, 167, 93, 14, 104}
|
||||||
|
jupiterSharedAccountsExactOutRoute = []byte{176, 209, 105, 168, 154, 125, 69, 62}
|
||||||
|
jupiterSharedAccountsRoute = []byte{193, 32, 155, 51, 65, 214, 156, 129}
|
||||||
|
jupiterSharedAccountsRouteWithTokenLedger = []byte{230, 121, 143, 80, 119, 159, 106, 170}
|
||||||
|
|
||||||
|
jupiterSharedAccountsExactOutRouteV2 = []byte{53, 96, 229, 202, 216, 187, 250, 24}
|
||||||
|
jupiterSharedAccountsRouteV2 = []byte{209, 152, 83, 147, 124, 254, 216, 233}
|
||||||
|
)
|
||||||
|
|
||||||
|
type Side uint8
|
||||||
|
|
||||||
|
type SwapKind uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
Saber SwapKind = iota
|
||||||
|
SaberAddDecimalsDeposit
|
||||||
|
SaberAddDecimalsWithdraw
|
||||||
|
TokenSwap
|
||||||
|
Sencha
|
||||||
|
Step
|
||||||
|
Cropper
|
||||||
|
Raydium
|
||||||
|
Crema
|
||||||
|
Lifinity
|
||||||
|
Mercurial
|
||||||
|
Cykura
|
||||||
|
Serum
|
||||||
|
MarinadeDeposit
|
||||||
|
MarinadeUnstake
|
||||||
|
Aldrin
|
||||||
|
AldrinV2
|
||||||
|
Whirlpool
|
||||||
|
Invariant
|
||||||
|
Meteora
|
||||||
|
GooseFX
|
||||||
|
DeltaFi
|
||||||
|
Balansol
|
||||||
|
MarcoPolo
|
||||||
|
Dradex
|
||||||
|
LifinityV2
|
||||||
|
RaydiumClmm
|
||||||
|
Openbook
|
||||||
|
Phoenix
|
||||||
|
Symmetry
|
||||||
|
TokenSwapV2
|
||||||
|
HeliumTreasuryManagementRedeemV0
|
||||||
|
StakeDexStakeWrappedSol
|
||||||
|
StakeDexSwapViaStake
|
||||||
|
GooseFXV2
|
||||||
|
Perps
|
||||||
|
PerpsAddLiquidity
|
||||||
|
PerpsRemoveLiquidity
|
||||||
|
MeteoraDlmm
|
||||||
|
OpenBookV2
|
||||||
|
RaydiumClmmV2
|
||||||
|
StakeDexPrefundWithdrawStakeAndDepositStake
|
||||||
|
Clone
|
||||||
|
SanctumS
|
||||||
|
SanctumSAddLiquidity
|
||||||
|
SanctumSRemoveLiquidity
|
||||||
|
RaydiumCP
|
||||||
|
WhirlpoolSwapV2
|
||||||
|
OneIntro
|
||||||
|
PumpWrappedBuy
|
||||||
|
PumpWrappedSell
|
||||||
|
PerpsV2
|
||||||
|
PerpsV2AddLiquidity
|
||||||
|
PerpsV2RemoveLiquidity
|
||||||
|
MoonshotWrappedBuy
|
||||||
|
MoonshotWrappedSell
|
||||||
|
StabbleStableSwap
|
||||||
|
StabbleWeightedSwap
|
||||||
|
Obric
|
||||||
|
FoxBuyFromEstimatedCost
|
||||||
|
FoxClaimPartial
|
||||||
|
SolFi
|
||||||
|
SolayerDelegateNoInit
|
||||||
|
SolayerUndelegateNoInit
|
||||||
|
TokenMill
|
||||||
|
DaosFunBuy
|
||||||
|
DaosFunSell
|
||||||
|
ZeroFi
|
||||||
|
StakeDexWithdrawWrappedSol
|
||||||
|
VirtualsBuy
|
||||||
|
VirtualsSell
|
||||||
|
Perena
|
||||||
|
PumpSwapBuy
|
||||||
|
PumpSwapSell
|
||||||
|
Gamma
|
||||||
|
MeteoraDlmmSwapV2
|
||||||
|
Woofi
|
||||||
|
MeteoraDammV2
|
||||||
|
MeteoraDynamicBondingCurveSwap
|
||||||
|
StabbleStableSwapV2
|
||||||
|
StabbleWeightedSwapV2
|
||||||
|
RaydiumLaunchlabBuy
|
||||||
|
RaydiumLaunchlabSell
|
||||||
|
BoopdotfunWrappedBuy
|
||||||
|
BoopdotfunWrappedSell
|
||||||
|
Plasma
|
||||||
|
GoonFi
|
||||||
|
HumidiFi
|
||||||
|
MeteoraDynamicBondingCurveSwapWithRemainingAccounts
|
||||||
|
TesseraV
|
||||||
|
PumpWrappedBuyV2
|
||||||
|
PumpWrappedSellV2
|
||||||
|
PumpSwapBuyV2
|
||||||
|
PumpSwapSellV2
|
||||||
|
Heaven
|
||||||
|
SolFiV2
|
||||||
|
Aquifer
|
||||||
|
PumpWrappedBuyV3
|
||||||
|
PumpWrappedSellV3
|
||||||
|
PumpSwapBuyV3
|
||||||
|
PumpSwapSellV3
|
||||||
|
JupiterLendDeposit
|
||||||
|
JupiterLendRedeem
|
||||||
|
DefiTuna
|
||||||
|
AlphaQ
|
||||||
|
RaydiumV2
|
||||||
|
SarosDlmm
|
||||||
|
Futarchy
|
||||||
|
MeteoraDammV2WithRemainingAccounts
|
||||||
|
Obsidian
|
||||||
|
WhaleStreet
|
||||||
|
DynamicV1
|
||||||
|
PumpWrappedBuyV4
|
||||||
|
PumpWrappedSellV4
|
||||||
|
CarrotIssue
|
||||||
|
CarrotRedeem
|
||||||
|
Manifest
|
||||||
|
BisonFi
|
||||||
|
HumidiFiV2
|
||||||
|
PerenaStar
|
||||||
|
JupiterRfqV2
|
||||||
|
GoonFiV2
|
||||||
|
)
|
||||||
|
|
||||||
|
var swapKindNames = [122]string{"Saber", "SaberAddDecimalsDeposit", "SaberAddDecimalsWithdraw", "TokenSwap", "Sencha", "Step", "Cropper",
|
||||||
|
"Raydium", "Crema", "Lifinity", "Mercurial", "Cykura", "Serum", "MarinadeDeposit", "MarinadeUnstake", "Aldrin", "AldrinV2", "Whirlpool",
|
||||||
|
"Invariant", "Meteora", "GooseFX", "DeltaFi", "Balansol", "MarcoPolo", "Dradex", "LifinityV2", "RaydiumClmm", "Openbook", "Phoenix",
|
||||||
|
"Symmetry", "TokenSwapV2", "HeliumTreasuryManagementRedeemV0", "StakeDexStakeWrappedSol", "StakeDexSwapViaStake", "GooseFXV2", "Perps",
|
||||||
|
"PerpsAddLiquidity", "PerpsRemoveLiquidity", "MeteoraDlmm", "OpenBookV2", "RaydiumClmmV2", "StakeDexPrefundWithdrawStakeAndDepositStake",
|
||||||
|
"Clone", "SanctumS", "SanctumSAddLiquidity", "SanctumSRemoveLiquidity", "RaydiumCP", "WhirlpoolSwapV2", "OneIntro", "PumpWrappedBuy",
|
||||||
|
"PumpWrappedSell", "PerpsV2", "PerpsV2AddLiquidity", "PerpsV2RemoveLiquidity", "MoonshotWrappedBuy", "MoonshotWrappedSell", "StabbleStableSwap",
|
||||||
|
"StabbleWeightedSwap", "Obric", "FoxBuyFromEstimatedCost", "FoxClaimPartial", "SolFi", "SolayerDelegateNoInit", "SolayerUndelegateNoInit", "TokenMill",
|
||||||
|
"DaosFunBuy", "DaosFunSell", "ZeroFi", "StakeDexWithdrawWrappedSol", "VirtualsBuy", "VirtualsSell", "Perena", "PumpSwapBuy", "PumpSwapSell", "Gamma",
|
||||||
|
"MeteoraDlmmSwapV2", "Woofi", "MeteoraDammV2", "MeteoraDynamicBondingCurveSwap", "StabbleStableSwapV2", "StabbleWeightedSwapV2", "RaydiumLaunchlabBuy",
|
||||||
|
"RaydiumLaunchlabSell", "BoopdotfunWrappedBuy", "BoopdotfunWrappedSell", "Plasma", "GoonFi", "HumidiFi",
|
||||||
|
"MeteoraDynamicBondingCurveSwapWithRemainingAccounts", "TesseraV", "PumpWrappedBuyV2", "PumpWrappedSellV2", "PumpSwapBuyV2", "PumpSwapSellV2",
|
||||||
|
"Heaven", "SolFiV2", "Aquifer", "PumpWrappedBuyV3", "PumpWrappedSellV3", "PumpSwapBuyV3", "PumpSwapSellV3", "JupiterLendDeposit", "JupiterLendRedeem",
|
||||||
|
"DefiTuna", "AlphaQ", "RaydiumV2", "SarosDlmm", "Futarchy", "MeteoraDammV2WithRemainingAccounts", "Obsidian", "WhaleStreet", "DynamicV1",
|
||||||
|
"PumpWrappedBuyV4", "PumpWrappedSellV4", "CarrotIssue", "CarrotRedeem", "Manifest", "BisonFi", "HumidiFiV2", "PerenaStar", "JupiterRfqV2", "GoonFiV2"}
|
||||||
|
|
||||||
|
func (s SwapKind) String() string {
|
||||||
|
idx := int(s)
|
||||||
|
if idx < 0 || idx >= len(swapKindNames) {
|
||||||
|
return fmt.Sprintf("SwapKind(%d)", uint8(s))
|
||||||
|
}
|
||||||
|
return swapKindNames[idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
type Swap struct {
|
||||||
|
Kind SwapKind
|
||||||
|
}
|
||||||
|
|
||||||
|
type RoutePlanStepV2 struct {
|
||||||
|
Swap Swap
|
||||||
|
Bps uint16
|
||||||
|
|
||||||
|
InputIdx uint8
|
||||||
|
OutputIdx uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
type RoutePlanStep struct {
|
||||||
|
Swap Swap
|
||||||
|
Percent uint8
|
||||||
|
|
||||||
|
InputIdx uint8
|
||||||
|
OutputIdx uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
type JupiterV6RouteV2Arg struct {
|
||||||
|
In uint64
|
||||||
|
Out uint64
|
||||||
|
|
||||||
|
SlippageBps uint16
|
||||||
|
PlatformFeeBps uint16
|
||||||
|
PositiveSlippageBps uint16
|
||||||
|
|
||||||
|
Plan []RoutePlanStepV2
|
||||||
|
}
|
||||||
|
|
||||||
|
func skipRemainingAccountsInfo(dec *bin.Decoder) error {
|
||||||
|
// RemainingAccountsInfo { slices: Vec<RemainingAccountsSlice> }
|
||||||
|
// RemainingAccountsSlice { accounts_type: u8, length: u8 }
|
||||||
|
ln, err := dec.ReadUint32(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// each slice is 2 bytes
|
||||||
|
return dec.SkipBytes(uint(ln) * 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func skipOptionRemainingAccountsInfo(dec *bin.Decoder) error {
|
||||||
|
pos := dec.Position()
|
||||||
|
tag, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch tag {
|
||||||
|
case 0:
|
||||||
|
return nil
|
||||||
|
case 1:
|
||||||
|
return skipRemainingAccountsInfo(dec)
|
||||||
|
default:
|
||||||
|
// Version drift: sometimes a swap variant we think has Option<RemainingAccountsInfo> is actually no-payload.
|
||||||
|
_ = dec.SetPosition(pos)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func skipCandidateSwap(dec *bin.Decoder) error {
|
||||||
|
// CandidateSwap enum (this IDL variant):
|
||||||
|
// 0 HumidiFi { u64, bool }
|
||||||
|
// 1 TesseraV { Side(u8) }
|
||||||
|
// NOTE: other IDL versions may include more variants (e.g. HumidiFiV2).
|
||||||
|
tag, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch tag {
|
||||||
|
case 0:
|
||||||
|
// HumidiFi u64 + bool
|
||||||
|
if err := dec.SkipBytes(8); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return dec.SkipBytes(1)
|
||||||
|
case 1:
|
||||||
|
// TesseraV (Side: u8)
|
||||||
|
return dec.SkipBytes(1)
|
||||||
|
case 2:
|
||||||
|
// Seen in other IDLs: HumidiFiV2 { u64, bool }
|
||||||
|
if err := dec.SkipBytes(8); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return dec.SkipBytes(1)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown CandidateSwap variant: %d", tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func skipDynamicV1(dec *bin.Decoder) error {
|
||||||
|
// DynamicV1 { candidate_swaps: Vec<CandidateSwap> }
|
||||||
|
ln, err := dec.ReadUint32(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i := uint32(0); i < ln; i++ {
|
||||||
|
if err := skipCandidateSwap(dec); err != nil {
|
||||||
|
return fmt.Errorf("CandidateSwap[%d]: %w", i, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSwap(dec *bin.Decoder) (Swap, error) {
|
||||||
|
tag, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return Swap{}, fmt.Errorf("read Swap variant: %w", err)
|
||||||
|
}
|
||||||
|
k := SwapKind(tag)
|
||||||
|
out := Swap{Kind: k}
|
||||||
|
|
||||||
|
skipU8 := func() error { return dec.SkipBytes(1) }
|
||||||
|
skipBool := func() error { return dec.SkipBytes(1) }
|
||||||
|
skipU32 := func() error { return dec.SkipBytes(4) }
|
||||||
|
skipU64 := func() error { return dec.SkipBytes(8) }
|
||||||
|
skipTwoU64 := func() error { return dec.SkipBytes(16) }
|
||||||
|
skipRemaining := func() error { return skipRemainingAccountsInfo(dec) }
|
||||||
|
skipOptRemaining := func() error { return skipOptionRemainingAccountsInfo(dec) }
|
||||||
|
|
||||||
|
switch k {
|
||||||
|
// -------- payload-less variants --------
|
||||||
|
case Saber, SaberAddDecimalsDeposit, SaberAddDecimalsWithdraw, TokenSwap, Sencha, Step, Cropper, Raydium, Lifinity,
|
||||||
|
Mercurial, Cykura, MarinadeDeposit, MarinadeUnstake, Meteora, GooseFX, Balansol, LifinityV2, RaydiumClmm,
|
||||||
|
TokenSwapV2, HeliumTreasuryManagementRedeemV0, StakeDexStakeWrappedSol, GooseFXV2, Perps, PerpsAddLiquidity,
|
||||||
|
PerpsRemoveLiquidity, MeteoraDlmm, RaydiumClmmV2, RaydiumCP, OneIntro, PumpWrappedBuy, PumpWrappedSell, PerpsV2,
|
||||||
|
PerpsV2AddLiquidity, PerpsV2RemoveLiquidity, MoonshotWrappedBuy, MoonshotWrappedSell, StabbleStableSwap,
|
||||||
|
StabbleWeightedSwap, FoxBuyFromEstimatedCost, SolayerDelegateNoInit, SolayerUndelegateNoInit, DaosFunBuy,
|
||||||
|
DaosFunSell, ZeroFi, StakeDexWithdrawWrappedSol, VirtualsBuy, VirtualsSell, PumpSwapBuy, PumpSwapSell,
|
||||||
|
Gamma, Woofi, MeteoraDammV2, MeteoraDynamicBondingCurveSwap, StabbleStableSwapV2, StabbleWeightedSwapV2,
|
||||||
|
BoopdotfunWrappedBuy, BoopdotfunWrappedSell, MeteoraDynamicBondingCurveSwapWithRemainingAccounts,
|
||||||
|
PumpWrappedBuyV2, PumpWrappedSellV2, PumpSwapBuyV2, PumpSwapSellV2, Aquifer, PumpWrappedBuyV3, PumpWrappedSellV3,
|
||||||
|
PumpSwapBuyV3, PumpSwapSellV3, JupiterLendDeposit, JupiterLendRedeem, RaydiumV2,
|
||||||
|
MeteoraDammV2WithRemainingAccounts, Obsidian, PumpWrappedBuyV4, PumpWrappedSellV4, CarrotIssue, CarrotRedeem:
|
||||||
|
return out, nil
|
||||||
|
|
||||||
|
// -------- bool payload --------
|
||||||
|
case Crema, Whirlpool, Invariant, DeltaFi, MarcoPolo, Obric, FoxClaimPartial, SolFi, Heaven, SolFiV2, AlphaQ,
|
||||||
|
SarosDlmm, BisonFi, PerenaStar, GoonFiV2:
|
||||||
|
return out, skipBool()
|
||||||
|
// -------- u32 --------
|
||||||
|
case StakeDexSwapViaStake, StakeDexPrefundWithdrawStakeAndDepositStake:
|
||||||
|
return out, skipU32()
|
||||||
|
// -------- u64 --------
|
||||||
|
case RaydiumLaunchlabBuy, RaydiumLaunchlabSell:
|
||||||
|
return out, skipU64()
|
||||||
|
// -------- Side(u8) payload --------
|
||||||
|
case Serum, Aldrin, AldrinV2, Dradex, Openbook, Phoenix, OpenBookV2, TokenMill, Plasma, TesseraV, Futarchy, WhaleStreet, Manifest:
|
||||||
|
return out, skipU8()
|
||||||
|
// -------- MeteoraDlmmSwapV2: RemainingAccountsInfo --------
|
||||||
|
case MeteoraDlmmSwapV2:
|
||||||
|
return out, skipRemaining()
|
||||||
|
// -------- DynamicV1: Vec<CandidateSwap> --------
|
||||||
|
case DynamicV1:
|
||||||
|
return out, skipDynamicV1(dec)
|
||||||
|
// -------- u64 + u64 --------
|
||||||
|
case Symmetry:
|
||||||
|
return out, skipTwoU64()
|
||||||
|
// -------- Clone: u8 + bool + bool --------
|
||||||
|
case Clone:
|
||||||
|
if err := skipU8(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
if err := skipBool(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
return out, skipBool()
|
||||||
|
// -------- SanctumS: u8 + u8 + u32 + u32 --------
|
||||||
|
case SanctumS:
|
||||||
|
if err := skipU8(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
if err := skipU8(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
if err := skipU32(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
return out, skipU32()
|
||||||
|
// -------- SanctumS(Add/Remove)Liquidity: u8 + u32 --------
|
||||||
|
case SanctumSAddLiquidity, SanctumSRemoveLiquidity:
|
||||||
|
if err := skipU8(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
return out, skipU32()
|
||||||
|
// -------- WhirlpoolSwapV2 / DefiTuna: bool + Option<RemainingAccountsInfo> --------
|
||||||
|
case WhirlpoolSwapV2, DefiTuna:
|
||||||
|
if err := skipBool(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
return out, skipOptRemaining()
|
||||||
|
// -------- Perena: u8 + u8 --------
|
||||||
|
case Perena:
|
||||||
|
if err := skipU8(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
return out, skipU8()
|
||||||
|
case GoonFi:
|
||||||
|
if err := skipBool(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
return out, skipU8()
|
||||||
|
// -------- HumidiFi/HumidiFiV2: u64 + bool --------
|
||||||
|
case HumidiFi, HumidiFiV2:
|
||||||
|
if err := skipU64(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
return out, skipBool()
|
||||||
|
|
||||||
|
// -------- JupiterRfqV2: Side(u8) + bytes --------
|
||||||
|
case JupiterRfqV2:
|
||||||
|
// side
|
||||||
|
if err := skipU8(); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
ln, err := dec.ReadUint32(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
if err := dec.SkipBytes(uint(ln)); err != nil {
|
||||||
|
return Swap{}, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
default:
|
||||||
|
// Unknown/new variant: assume no payload (keeps decoder aligned for RoutePlanStepV2 if it really is no-payload).
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeRoutePlanStepV2(dec *bin.Decoder) (RoutePlanStepV2, error) {
|
||||||
|
sw, err := decodeSwap(dec)
|
||||||
|
if err != nil {
|
||||||
|
return RoutePlanStepV2{}, err
|
||||||
|
}
|
||||||
|
bps, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return RoutePlanStepV2{}, err
|
||||||
|
}
|
||||||
|
inIdx, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return RoutePlanStepV2{}, err
|
||||||
|
}
|
||||||
|
outIdx, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return RoutePlanStepV2{}, err
|
||||||
|
}
|
||||||
|
return RoutePlanStepV2{Swap: sw, Bps: bps, InputIdx: inIdx, OutputIdx: outIdx}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeRoutePlanStep(dec *bin.Decoder) (RoutePlanStep, error) {
|
||||||
|
sw, err := decodeSwap(dec)
|
||||||
|
if err != nil {
|
||||||
|
return RoutePlanStep{}, err
|
||||||
|
}
|
||||||
|
percent, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return RoutePlanStep{}, err
|
||||||
|
}
|
||||||
|
inIdx, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return RoutePlanStep{}, err
|
||||||
|
}
|
||||||
|
outIdx, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return RoutePlanStep{}, err
|
||||||
|
}
|
||||||
|
return RoutePlanStep{Swap: sw, Percent: percent, InputIdx: inIdx, OutputIdx: outIdx}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeJupiterV6RouteV2Arg(data []byte) (*JupiterV6RouteV2Arg, error) {
|
||||||
|
dec := bin.NewBorshDecoder(data)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
out := &JupiterV6RouteV2Arg{}
|
||||||
|
if out.In, err = dec.ReadUint64(binary.LittleEndian); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if out.Out, err = dec.ReadUint64(binary.LittleEndian); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if out.SlippageBps, err = dec.ReadUint16(binary.LittleEndian); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if out.PlatformFeeBps, err = dec.ReadUint16(binary.LittleEndian); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if out.PositiveSlippageBps, err = dec.ReadUint16(binary.LittleEndian); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec<RoutePlanStepV2>: u32 length + elements
|
||||||
|
ln, err := dec.ReadUint32(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
out.Plan = make([]RoutePlanStepV2, 0, ln)
|
||||||
|
for i := uint32(0); i < ln; i++ {
|
||||||
|
step, err := decodeRoutePlanStepV2(dec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("decode Plan[%d]: %w", i, err)
|
||||||
|
}
|
||||||
|
out.Plan = append(out.Plan, step)
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type JupiterV6RouteArg struct {
|
||||||
|
Plan []RoutePlanStep
|
||||||
|
|
||||||
|
In uint64
|
||||||
|
QuotedOut uint64
|
||||||
|
SlippageBps uint16
|
||||||
|
PlatformFeeBps uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
type JupiterV6RouteWithTokenLedgerArg struct {
|
||||||
|
Plan []RoutePlanStep
|
||||||
|
|
||||||
|
QuotedOut uint64
|
||||||
|
SlippageBps uint16
|
||||||
|
PlatformFeeBps uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
type JupiterV6SharedAccountsExactOutRouteArg struct {
|
||||||
|
ID uint8
|
||||||
|
|
||||||
|
Plan []RoutePlanStep
|
||||||
|
|
||||||
|
Out uint64
|
||||||
|
QuotedIn uint64
|
||||||
|
SlippageBps uint16
|
||||||
|
PlatformFeeBps uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
type JupiterV6SharedAccountsRouteArg struct {
|
||||||
|
ID uint8
|
||||||
|
|
||||||
|
Plan []RoutePlanStep
|
||||||
|
|
||||||
|
In uint64
|
||||||
|
QuotedOut uint64
|
||||||
|
SlippageBps uint16
|
||||||
|
PlatformFeeBps uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
type JupiterV6SharedAccountsRouteWithTokenLedgerArg struct {
|
||||||
|
ID uint8
|
||||||
|
|
||||||
|
Plan []RoutePlanStep
|
||||||
|
|
||||||
|
QuotedOut uint64
|
||||||
|
SlippageBps uint16
|
||||||
|
PlatformFeeBps uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
type JupiterV6ExactOutRouteV2Arg struct {
|
||||||
|
Out uint64
|
||||||
|
QuotedIn uint64
|
||||||
|
Slippage uint16
|
||||||
|
PlatFee uint16
|
||||||
|
PosSlip uint16
|
||||||
|
RoutePlan []RoutePlanStepV2
|
||||||
|
}
|
||||||
|
|
||||||
|
type JupiterV6SharedAccountsExactOutRouteV2Arg struct {
|
||||||
|
ID uint8
|
||||||
|
|
||||||
|
Out uint64
|
||||||
|
QuotedIn uint64
|
||||||
|
Slippage uint16
|
||||||
|
PlatFee uint16
|
||||||
|
PosSlip uint16
|
||||||
|
RoutePlan []RoutePlanStepV2
|
||||||
|
}
|
||||||
|
|
||||||
|
type JupiterV6SharedAccountsRouteV2Arg struct {
|
||||||
|
ID uint8
|
||||||
|
|
||||||
|
In uint64
|
||||||
|
QuotedOut uint64
|
||||||
|
Slippage uint16
|
||||||
|
PlatFee uint16
|
||||||
|
PosSlip uint16
|
||||||
|
RoutePlan []RoutePlanStepV2
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeVecRoutePlanStep(dec *bin.Decoder) ([]RoutePlanStep, error) {
|
||||||
|
ln, err := dec.ReadUint32(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
out := make([]RoutePlanStep, 0, ln)
|
||||||
|
for i := uint32(0); i < ln; i++ {
|
||||||
|
step, err := decodeRoutePlanStep(dec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("decode RoutePlanStep[%d]: %w", i, err)
|
||||||
|
}
|
||||||
|
out = append(out, step)
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeVecRoutePlanStepV2(dec *bin.Decoder) ([]RoutePlanStepV2, error) {
|
||||||
|
ln, err := dec.ReadUint32(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
out := make([]RoutePlanStepV2, 0, ln)
|
||||||
|
for i := uint32(0); i < ln; i++ {
|
||||||
|
step, err := decodeRoutePlanStepV2(dec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("decode RoutePlanStepV2[%d]: %w", i, err)
|
||||||
|
}
|
||||||
|
out = append(out, step)
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeJupiterV6RouteArg(data []byte) (*JupiterV6RouteArg, error) {
|
||||||
|
dec := bin.NewBorshDecoder(data)
|
||||||
|
plan, err := decodeVecRoutePlanStep(dec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
in, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
quotedOut, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
slippage, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pf, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &JupiterV6RouteArg{Plan: plan, In: in, QuotedOut: quotedOut, SlippageBps: slippage, PlatformFeeBps: pf}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeJupiterV6RouteWithTokenLedgerArg(data []byte) (*JupiterV6RouteWithTokenLedgerArg, error) {
|
||||||
|
dec := bin.NewBorshDecoder(data)
|
||||||
|
plan, err := decodeVecRoutePlanStep(dec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
quotedOut, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
slippage, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pf, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &JupiterV6RouteWithTokenLedgerArg{Plan: plan, QuotedOut: quotedOut, SlippageBps: slippage, PlatformFeeBps: pf}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeJupiterV6SharedAccountsExactOutRouteArg(data []byte) (*JupiterV6SharedAccountsExactOutRouteArg, error) {
|
||||||
|
dec := bin.NewBorshDecoder(data)
|
||||||
|
id, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
plan, err := decodeVecRoutePlanStep(dec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
outAmt, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
quotedIn, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
slippage, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pf, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &JupiterV6SharedAccountsExactOutRouteArg{ID: id, Plan: plan, Out: outAmt, QuotedIn: quotedIn, SlippageBps: slippage, PlatformFeeBps: pf}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeJupiterV6SharedAccountsRouteArg(data []byte) (*JupiterV6SharedAccountsRouteArg, error) {
|
||||||
|
dec := bin.NewBorshDecoder(data)
|
||||||
|
id, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
plan, err := decodeVecRoutePlanStep(dec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
inAmt, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
quotedOut, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
slippage, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pf, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &JupiterV6SharedAccountsRouteArg{ID: id, Plan: plan, In: inAmt, QuotedOut: quotedOut, SlippageBps: slippage, PlatformFeeBps: pf}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeJupiterV6SharedAccountsRouteWithTokenLedgerArg(data []byte) (*JupiterV6SharedAccountsRouteWithTokenLedgerArg, error) {
|
||||||
|
dec := bin.NewBorshDecoder(data)
|
||||||
|
id, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
plan, err := decodeVecRoutePlanStep(dec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
quotedOut, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
slippage, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pf, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &JupiterV6SharedAccountsRouteWithTokenLedgerArg{ID: id, Plan: plan, QuotedOut: quotedOut, SlippageBps: slippage, PlatformFeeBps: pf}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeJupiterV6ExactOutRouteV2Arg(data []byte) (*JupiterV6ExactOutRouteV2Arg, error) {
|
||||||
|
dec := bin.NewBorshDecoder(data)
|
||||||
|
outAmt, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
quotedIn, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
slippage, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pf, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pos, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
plan, err := decodeVecRoutePlanStepV2(dec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &JupiterV6ExactOutRouteV2Arg{Out: outAmt, QuotedIn: quotedIn, Slippage: slippage, PlatFee: pf, PosSlip: pos, RoutePlan: plan}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeJupiterV6SharedAccountsExactOutRouteV2Arg(data []byte) (*JupiterV6SharedAccountsExactOutRouteV2Arg, error) {
|
||||||
|
dec := bin.NewBorshDecoder(data)
|
||||||
|
id, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
outAmt, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
quotedIn, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
slippage, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pf, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pos, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
plan, err := decodeVecRoutePlanStepV2(dec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &JupiterV6SharedAccountsExactOutRouteV2Arg{ID: id, Out: outAmt, QuotedIn: quotedIn, Slippage: slippage, PlatFee: pf, PosSlip: pos, RoutePlan: plan}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeJupiterV6SharedAccountsRouteV2Arg(data []byte) (*JupiterV6SharedAccountsRouteV2Arg, error) {
|
||||||
|
dec := bin.NewBorshDecoder(data)
|
||||||
|
id, err := dec.ReadUint8()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
inAmt, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
quotedOut, err := dec.ReadUint64(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
slippage, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pf, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pos, err := dec.ReadUint16(binary.LittleEndian)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
plan, err := decodeVecRoutePlanStepV2(dec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &JupiterV6SharedAccountsRouteV2Arg{ID: id, In: inAmt, QuotedOut: quotedOut, Slippage: slippage, PlatFee: pf, PosSlip: pos, RoutePlan: plan}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func pumpSwapSellAtIdx0(amount uint64, plan []RoutePlanStep) uint64 {
|
||||||
|
var ret uint64
|
||||||
|
for _, step := range plan {
|
||||||
|
if step.InputIdx == 0 &&
|
||||||
|
(step.Swap.Kind == PumpSwapSell || step.Swap.Kind == PumpSwapSellV2 || step.Swap.Kind == PumpSwapSellV3) {
|
||||||
|
ret += amount * uint64(step.Percent) / 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func pumpSwapSellAtIdx0V2(amount uint64, plan []RoutePlanStepV2) uint64 {
|
||||||
|
var ret uint64
|
||||||
|
for _, step := range plan {
|
||||||
|
if step.InputIdx == 0 &&
|
||||||
|
(step.Swap.Kind == PumpSwapSell || step.Swap.Kind == PumpSwapSellV2 || step.Swap.Kind == PumpSwapSellV3) {
|
||||||
|
ret += amount * uint64(step.Bps) / 10000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// only decodes inputIdx = 0 container pumpSwap instructions for now
|
||||||
|
func parseJupiterV6Instruction(tx *versionedTransaction, instructionIndex int) (*TxSignal, error) {
|
||||||
|
msg := tx.Message
|
||||||
|
if instructionIndex >= len(msg.Instructions) {
|
||||||
|
return nil, fmt.Errorf("instruction index out of bounds")
|
||||||
|
}
|
||||||
|
|
||||||
|
instruction := msg.Instructions[instructionIndex]
|
||||||
|
if len(instruction.Data) == 0 {
|
||||||
|
return nil, fmt.Errorf("data is empty")
|
||||||
|
}
|
||||||
|
if len(instruction.Data) < 8 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
disc := instruction.Data[:8]
|
||||||
|
|
||||||
|
var (
|
||||||
|
sourceMint solana.PublicKey
|
||||||
|
inputAmount uint64
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
// route_v2 / exact_out_route_v2 / shared_accounts_*_v2 use accounts[3]/[4] as src/dst mints (per IDL)
|
||||||
|
// route/shared_accounts_* (v1) use different account layouts; we only decode args here.
|
||||||
|
switch {
|
||||||
|
case bytes.Equal(disc, jupiterRouteV2):
|
||||||
|
args, err := decodeJupiterV6RouteV2Arg(instruction.Data[8:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
inputAmount = pumpSwapSellAtIdx0V2(args.In, args.Plan)
|
||||||
|
|
||||||
|
case bytes.Equal(disc, jupiterSharedAccountsRouteV2):
|
||||||
|
args, err := decodeJupiterV6SharedAccountsRouteV2Arg(instruction.Data[8:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
inputAmount = pumpSwapSellAtIdx0V2(args.In, args.RoutePlan)
|
||||||
|
|
||||||
|
case bytes.Equal(disc, jupiterRoute):
|
||||||
|
args, err := decodeJupiterV6RouteArg(instruction.Data[8:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_ = args
|
||||||
|
inputAmount = pumpSwapSellAtIdx0(args.In, args.Plan)
|
||||||
|
|
||||||
|
case bytes.Equal(disc, jupiterSharedAccountsRoute):
|
||||||
|
args, err := decodeJupiterV6SharedAccountsRouteArg(instruction.Data[8:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_ = args
|
||||||
|
inputAmount = pumpSwapSellAtIdx0(args.In, args.Plan)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if inputAmount == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// existing mint extraction logic only valid for route_v2/ exact_out_route_v2. Keep it but guard.
|
||||||
|
if bytes.Equal(disc, jupiterRouteV2) || bytes.Equal(disc, jupiterSharedAccountsRouteV2) {
|
||||||
|
if len(instruction.Accounts) < 6 {
|
||||||
|
return nil, fmt.Errorf("not enough accounts for jupiter v6 v2 instruction")
|
||||||
|
}
|
||||||
|
sourceMint, err = getStaticKey(tx.Message.StaticAccountKeys, int(instruction.Accounts[3]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else if bytes.Equal(disc, jupiterSharedAccountsRoute) {
|
||||||
|
if len(instruction.Accounts) < 12 {
|
||||||
|
return nil, fmt.Errorf("not enough accounts for jupiter v6 jupiterSharedAccountsRoute instruction")
|
||||||
|
}
|
||||||
|
sourceMint, err = getStaticKey(tx.Message.StaticAccountKeys, int(instruction.Accounts[7]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if len(instruction.Accounts) < 10 {
|
||||||
|
return nil, fmt.Errorf("not enough accounts for jupiter v6 jupiterRoute instruction")
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
srcIdx uint8
|
||||||
|
)
|
||||||
|
|
||||||
|
for i, acctIdx := range instruction.Accounts {
|
||||||
|
if i <= 9 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
key, err := getStaticKey(tx.Message.StaticAccountKeys, int(acctIdx))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if key.Equals(pumpAmmProgramID) {
|
||||||
|
srcIdx = uint8(i + 4)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if srcIdx == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
sourceMint, err = getStaticKey(tx.Message.StaticAccountKeys, int(instruction.Accounts[srcIdx]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
distMint, err := getStaticKey(tx.Message.StaticAccountKeys, int(instruction.Accounts[srcIdx+1]))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !distMint.Equals(solana.WrappedSol) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signal := &TxSignal{
|
||||||
|
Label: "jupiterV6",
|
||||||
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Maker: tx.Message.StaticAccountKeys[0].String(),
|
||||||
|
Token0Address: sourceMint.String(),
|
||||||
|
Token1Address: wsolMint,
|
||||||
|
Token0Amount: formatTokenAmount(inputAmount),
|
||||||
|
Token1Amount: decimal.Zero,
|
||||||
|
Program: "PumpAMM",
|
||||||
|
Event: "buy",
|
||||||
|
IsToken2022: false,
|
||||||
|
IsMayhemMode: false,
|
||||||
|
ExactSOL: false,
|
||||||
|
Block: tx.Block,
|
||||||
|
Token0AmountUint64: inputAmount,
|
||||||
|
Token1AmountUint64: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
return signal, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep lints happy if solana-go isn't referenced elsewhere in this file for build tags
|
||||||
|
var _ = solana.PublicKey{}
|
||||||
88
pkg/shreder/juptierv6_test.go
Normal file
88
pkg/shreder/juptierv6_test.go
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
package shreder
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDecodeRouteV2Arg(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
hexData string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Jupiter V6 RouteV2Arg Test 0",
|
||||||
|
hexData: "bb64facc31c4af14809fd500000000002222e8db1800000064000a000000020000005601fe102700016310270102",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Jupiter V6 RouteV2Arg Test 1",
|
||||||
|
hexData: "bb64facc31c4af144ff91634b90000004e6c4d05000000002c013200000003000000520000000000000000102700014f102701024310270203",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Jupiter V6 RouteV2Arg Test 2",
|
||||||
|
hexData: "bb64facc31c4af14ba2eafa02c1d0000777a9b2200000000f4010a0000000100000052000000000000000010270001",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Jupiter V6 RouteV2Arg Test 3",
|
||||||
|
hexData: "bb64facc31c4af144a3521186b07000030508d0e00000000c201320000000300000052000000000000000010270001740110270102590010270203",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Jupiter V6 RouteV2Arg Test 4",
|
||||||
|
hexData: "bb64facc31c4af14092d05050000000013701f198c0100008102380100000300000059011027000168001027010251000000000000000010270203",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Jupiter V6 RouteV2Arg Test 5",
|
||||||
|
hexData: "bb64facc31c4af1480969800000000006f44ad39bd0000001202320000000200000068001027000151000000000000000010270102",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
instrData, err := hex.DecodeString(tt.hexData)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to decode hex string: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("raw bytes: %x", instrData[8:])
|
||||||
|
args, err := decodeJupiterV6RouteV2Arg(instrData[8:])
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to decode jupiter arguments: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("decoded args: %+v", args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDecodeRouteArg(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
hexData string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Jupiter V6 RouteArg Test 0",
|
||||||
|
hexData: "e517cb977ae3ad2a030000004f6400014f64010251000000000000000064020340420f00000000005c1c81900e000000640000",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Jupiter V6 RouteArg Test 1",
|
||||||
|
hexData: "e517cb977ae3ad2a0200000028640001510000000000000000640102c09ee605000000005e1bc48efa000000d00700",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
instrData, err := hex.DecodeString(tt.hexData)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to decode hex string: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("raw bytes: %x", instrData[8:])
|
||||||
|
args, err := decodeJupiterV6RouteArg(instrData[8:])
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to decode jupiter arguments: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("decoded args: %+v", args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
1
pkg/shreder/okxonchainlab.go
Normal file
1
pkg/shreder/okxonchainlab.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package shreder
|
||||||
@@ -29,6 +29,7 @@ func SetLogLevel(level slog.Level) {
|
|||||||
|
|
||||||
type TxSignal struct {
|
type TxSignal struct {
|
||||||
Source string `json:"source"`
|
Source string `json:"source"`
|
||||||
|
Label string `json:"label"`
|
||||||
TxHash string `json:"tx_hash"`
|
TxHash string `json:"tx_hash"`
|
||||||
Maker string `json:"maker"`
|
Maker string `json:"maker"`
|
||||||
Token0Address string `json:"token0_address"`
|
Token0Address string `json:"token0_address"`
|
||||||
|
|||||||
@@ -42,8 +42,23 @@ var (
|
|||||||
flasProgramID = solana.MustPublicKeyFromBase58("FLASHX8DrLbgeR8FcfNV1F5krxYcYMUdBkrP1EPBtxB9")
|
flasProgramID = solana.MustPublicKeyFromBase58("FLASHX8DrLbgeR8FcfNV1F5krxYcYMUdBkrP1EPBtxB9")
|
||||||
|
|
||||||
terminalProgramID = solana.MustPublicKeyFromBase58("term9YPb9mzAsABaqN71A4xdbxHmpBNZavpBiQKZzN3")
|
terminalProgramID = solana.MustPublicKeyFromBase58("term9YPb9mzAsABaqN71A4xdbxHmpBNZavpBiQKZzN3")
|
||||||
|
|
||||||
|
jupiterV6ProgramID = solana.MustPublicKeyFromBase58("JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type AccountNotFoundError struct {
|
||||||
|
Index int
|
||||||
|
Len int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAccountNotFoundError(i, l int) error {
|
||||||
|
return &AccountNotFoundError{i, l}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e AccountNotFoundError) Error() string {
|
||||||
|
return fmt.Sprintf("account index %d out of range, len=%d", e.Index, e.Len)
|
||||||
|
}
|
||||||
|
|
||||||
// instruction discriminators
|
// instruction discriminators
|
||||||
var (
|
var (
|
||||||
pumpCreateCoinIX = []byte{24, 30, 200, 40, 5, 28, 7, 119}
|
pumpCreateCoinIX = []byte{24, 30, 200, 40, 5, 28, 7, 119}
|
||||||
@@ -198,18 +213,30 @@ func ParseTransaction(update *SubscribeUpdateTransaction, loader *AddressTables)
|
|||||||
instructions := versioned.Message.Instructions
|
instructions := versioned.Message.Instructions
|
||||||
|
|
||||||
if loader != nil && len(versioned.Message.AddressTableLookups) > 0 {
|
if loader != nil && len(versioned.Message.AddressTableLookups) > 0 {
|
||||||
// currently we only care about photon table lookup
|
lookupTableOk := true
|
||||||
for _, lookup := range versioned.Message.AddressTableLookups {
|
for _, lookup := range versioned.Message.AddressTableLookups {
|
||||||
|
if len(lookup.WritableIndexes) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
accounts := loader.GetAddressTable(lookup.AccountKey, lookup.WritableIndexes)
|
accounts := loader.GetAddressTable(lookup.AccountKey, lookup.WritableIndexes)
|
||||||
if len(accounts) != len(lookup.WritableIndexes) {
|
if len(accounts) != len(lookup.WritableIndexes) {
|
||||||
|
lookupTableOk = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
staticKeys = append(staticKeys, accounts...)
|
staticKeys = append(staticKeys, accounts...)
|
||||||
accounts2 := loader.GetAddressTable(lookup.AccountKey, lookup.ReadonlyIndexes)
|
|
||||||
if len(accounts2) != len(lookup.ReadonlyIndexes) {
|
}
|
||||||
|
if lookupTableOk {
|
||||||
|
for _, lookup := range versioned.Message.AddressTableLookups {
|
||||||
|
if len(lookup.ReadonlyIndexes) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
accounts := loader.GetAddressTable(lookup.AccountKey, lookup.ReadonlyIndexes)
|
||||||
|
if len(accounts) != len(lookup.ReadonlyIndexes) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
staticKeys = append(staticKeys, accounts2...)
|
staticKeys = append(staticKeys, accounts...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,6 +280,9 @@ func ParseTransaction(update *SubscribeUpdateTransaction, loader *AddressTables)
|
|||||||
case terminalProgramID:
|
case terminalProgramID:
|
||||||
txRes, err := parseTermInstruction(versioned, i)
|
txRes, err := parseTermInstruction(versioned, i)
|
||||||
parsed = appendParsed(parsed, txRes, err, txHash, "terminal")
|
parsed = appendParsed(parsed, txRes, err, txHash, "terminal")
|
||||||
|
//case jupiterV6ProgramID:
|
||||||
|
// txRes, err := parseJupiterV6Instruction(versioned, i)
|
||||||
|
// parsed = appendParsed(parsed, txRes, err, txHash, "jupiterv6")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,6 +291,9 @@ func ParseTransaction(update *SubscribeUpdateTransaction, loader *AddressTables)
|
|||||||
|
|
||||||
func appendParsed(list []*TxSignal, parsed *TxSignal, err error, txHash [64]byte, label string) []*TxSignal {
|
func appendParsed(list []*TxSignal, parsed *TxSignal, err error, txHash [64]byte, label string) []*TxSignal {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
//if errors.Is(err, &AccountNotFoundError{}) {
|
||||||
|
//
|
||||||
|
//}
|
||||||
logger.Debug("txparser: failed to parse", "label", label, "instruction", err, "tx_hash", base58.Encode(txHash[:]))
|
logger.Debug("txparser: failed to parse", "label", label, "instruction", err, "tx_hash", base58.Encode(txHash[:]))
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
@@ -331,11 +364,8 @@ func formatSolAmount(lamports uint64) decimal.Decimal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getStaticKey(static []solana.PublicKey, index int) (solana.PublicKey, error) {
|
func getStaticKey(static []solana.PublicKey, index int) (solana.PublicKey, error) {
|
||||||
if index < 0 {
|
if index < 0 || index >= len(static) {
|
||||||
return solana.PublicKey{}, fmt.Errorf("account index %d less then 0", index)
|
return solana.PublicKey{}, NewAccountNotFoundError(index, len(static))
|
||||||
}
|
|
||||||
if index >= len(static) {
|
|
||||||
return solana.PublicKey{}, fmt.Errorf("account index %d out of range", index)
|
|
||||||
}
|
}
|
||||||
return static[index], nil
|
return static[index], nil
|
||||||
}
|
}
|
||||||
@@ -381,6 +411,7 @@ func parsePumpCreate(tx *versionedTransaction, instruction *compiledInstruction)
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "pump",
|
||||||
Maker: creator.String(),
|
Maker: creator.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -421,6 +452,7 @@ func parsePumpCreateV2(tx *versionedTransaction, instruction *compiledInstructio
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "pump",
|
||||||
Maker: args.Creator.String(),
|
Maker: args.Creator.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -484,6 +516,7 @@ func parsePumpBuy(tx *versionedTransaction, instruction *compiledInstruction) (*
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "pump",
|
||||||
Maker: buyer.String(),
|
Maker: buyer.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -541,6 +574,7 @@ func parsePumpSell(tx *versionedTransaction, instruction *compiledInstruction) (
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "pump",
|
||||||
Maker: seller.String(),
|
Maker: seller.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -599,6 +633,7 @@ func parseAzczAmmBuy(tx *versionedTransaction, instructionIndex int) (*TxSignal,
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "azcz",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -642,6 +677,7 @@ func parseAzczBuy(tx *versionedTransaction, instructionIndex int) (*TxSignal, er
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "azcz",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -696,6 +732,7 @@ func parseF5tfInstruction(tx *versionedTransaction, instructionIndex int) (*TxSi
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "f5tf",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -766,6 +803,7 @@ func parseFlasAmmSell(tx *versionedTransaction, instructionIndex int) (*TxSignal
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "flas",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -805,6 +843,7 @@ func parseFlasAmmBuy(tx *versionedTransaction, instructionIndex int) (*TxSignal,
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "flas",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -844,6 +883,7 @@ func parseFlasSell(tx *versionedTransaction, instructionIndex int) (*TxSignal, e
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "flas",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -882,6 +922,7 @@ func parseFlasBuy(tx *versionedTransaction, instructionIndex int) (*TxSignal, er
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "flas",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -948,6 +989,7 @@ func parsePhotonBuy(tx *versionedTransaction, instruction *compiledInstruction)
|
|||||||
solAmount := args.SolAmount * (100000000 - 1234568) / 100000000
|
solAmount := args.SolAmount * (100000000 - 1234568) / 100000000
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "photon",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -1003,6 +1045,7 @@ func parsePhotonSwap(tx *versionedTransaction, instruction *compiledInstruction)
|
|||||||
solAmount := args.FromAmount * (100000000 - 1234568) / 100000000
|
solAmount := args.FromAmount * (100000000 - 1234568) / 100000000
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "photon",
|
||||||
Maker: buyer.String(),
|
Maker: buyer.String(),
|
||||||
Token0Address: base.String(),
|
Token0Address: base.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -1084,6 +1127,7 @@ func parseTermAmmSell(tx *versionedTransaction, instruction *compiledInstruction
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "term",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -1119,6 +1163,7 @@ func parseTermBuy(tx *versionedTransaction, instruction *compiledInstruction) (*
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "term",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -1153,6 +1198,7 @@ func parseTermSell(tx *versionedTransaction, instruction *compiledInstruction) (
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "term",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -1224,6 +1270,7 @@ func parsePumpAmmBuy(tx *versionedTransaction, instruction *compiledInstruction)
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "pumpamm",
|
||||||
Maker: buyer.String(),
|
Maker: buyer.String(),
|
||||||
Token0Address: base.String(),
|
Token0Address: base.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -1270,6 +1317,7 @@ func parsePumpAmmSell(tx *versionedTransaction, instruction *compiledInstruction
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "pumpamm",
|
||||||
Maker: buyer.String(),
|
Maker: buyer.String(),
|
||||||
Token0Address: base.String(),
|
Token0Address: base.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -1323,6 +1371,7 @@ func parseBoboInstruction(tx *versionedTransaction, instructionIndex int) (*TxSi
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "bobo",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -1383,6 +1432,7 @@ func parseQtkvSell(tx *versionedTransaction, instructionIndex int) (*TxSignal, e
|
|||||||
tokenAmount := binary.LittleEndian.Uint64(instruction.Data[19:25])
|
tokenAmount := binary.LittleEndian.Uint64(instruction.Data[19:25])
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "qtkv",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -1421,6 +1471,7 @@ func parseQtkvAmmSell(tx *versionedTransaction, instructionIndex int) (*TxSignal
|
|||||||
tokenAmount := binary.LittleEndian.Uint64(instruction.Data[19:25])
|
tokenAmount := binary.LittleEndian.Uint64(instruction.Data[19:25])
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "qtkv",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -1459,6 +1510,7 @@ func parseQtkvBuy(tx *versionedTransaction, instructionIndex int) (*TxSignal, er
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "qtkv",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
@@ -1512,6 +1564,7 @@ func parseFjszInstruction(tx *versionedTransaction, instructionIndex int) (*TxSi
|
|||||||
|
|
||||||
return &TxSignal{
|
return &TxSignal{
|
||||||
TxHash: tx.Signatures[0].String(),
|
TxHash: tx.Signatures[0].String(),
|
||||||
|
Label: "fjsz",
|
||||||
Maker: user.String(),
|
Maker: user.String(),
|
||||||
Token0Address: mint.String(),
|
Token0Address: mint.String(),
|
||||||
Token1Address: wsolMint,
|
Token1Address: wsolMint,
|
||||||
|
|||||||
Reference in New Issue
Block a user