metaora dlmm init

This commit is contained in:
thloyi
2026-02-02 17:59:47 +08:00
parent 0eb1628119
commit 5da088ce13
4 changed files with 152 additions and 12 deletions

20
meta.go
View File

@@ -67,15 +67,17 @@ var (
) )
var ( var (
meteoraDlmmSwapDiscriminator = calculateDiscriminator("global:swap") meteoraInitializeLbPairDiscriminator = calculateDiscriminator("global:initialize_lb_pair2")
meteoraDlmmSwap2Discriminator = calculateDiscriminator("global:swap2") meteoraInitializeLbPairEventDiscriminator = calculateDiscriminator("event:LbPairCreate")
meteoraDlmmSwapExactOutDiscriminator = calculateDiscriminator("global:swap_exact_out") meteoraDlmmSwapDiscriminator = calculateDiscriminator("global:swap")
meteoraDlmmSwapExactOut2Discriminator = calculateDiscriminator("global:swap_exact_out2") meteoraDlmmSwap2Discriminator = calculateDiscriminator("global:swap2")
meteoraDlmmSwapWithPriceImpactDiscriminator = calculateDiscriminator("global:swap_with_price_impact") meteoraDlmmSwapExactOutDiscriminator = calculateDiscriminator("global:swap_exact_out")
meteoraDlmmSwapWithPriceImpact2Discriminator = calculateDiscriminator("global:swap_with_price_impact2") meteoraDlmmSwapExactOut2Discriminator = calculateDiscriminator("global:swap_exact_out2")
meteoraDlmmSwapEventDiscriminator = calculateDiscriminator("event:Swap") meteoraDlmmSwapWithPriceImpactDiscriminator = calculateDiscriminator("global:swap_with_price_impact")
meteoraDlmmAddLiquidityDiscriminator = calculateDiscriminator("global:add_liquidity") meteoraDlmmSwapWithPriceImpact2Discriminator = calculateDiscriminator("global:swap_with_price_impact2")
meteoraDlmmAddLiquidity2Discriminator = calculateDiscriminator("global:add_liquidity2") meteoraDlmmSwapEventDiscriminator = calculateDiscriminator("event:Swap")
meteoraDlmmAddLiquidityDiscriminator = calculateDiscriminator("global:add_liquidity")
meteoraDlmmAddLiquidity2Discriminator = calculateDiscriminator("global:add_liquidity2")
meteoraDlmmAddLiquidityByStrategyDiscriminator = calculateDiscriminator("global:add_liquidity_by_strategy") meteoraDlmmAddLiquidityByStrategyDiscriminator = calculateDiscriminator("global:add_liquidity_by_strategy")
meteoraDlmmAddLiquidityByStrategy2Discriminator = calculateDiscriminator("global:add_liquidity_by_strategy2") meteoraDlmmAddLiquidityByStrategy2Discriminator = calculateDiscriminator("global:add_liquidity_by_strategy2")
meteoraDlmmRemoveLiquidityDiscriminator = calculateDiscriminator("global:remove_liquidity") meteoraDlmmRemoveLiquidityDiscriminator = calculateDiscriminator("global:remove_liquidity")

View File

@@ -199,6 +199,8 @@ func metaoradlmmParser(tx *Tx, instruction Instruction, innerInstructions InnerI
discriminator := *(*[8]byte)(decode[:8]) discriminator := *(*[8]byte)(decode[:8])
switch discriminator { switch discriminator {
case meteoraInitializeLbPairDiscriminator:
return metaoradlmmInitializeParser(tx, instruction, innerInstructions, offset)
case meteoraDlmmSwapDiscriminator, meteoraDlmmSwapExactOutDiscriminator, meteoraDlmmSwapWithPriceImpactDiscriminator: case meteoraDlmmSwapDiscriminator, meteoraDlmmSwapExactOutDiscriminator, meteoraDlmmSwapWithPriceImpactDiscriminator:
return metaoradlmmSwapParser(tx, instruction, innerInstructions, offset) return metaoradlmmSwapParser(tx, instruction, innerInstructions, offset)
case meteoraDlmmSwap2Discriminator, meteoraDlmmSwapExactOut2Discriminator, meteoraDlmmSwapWithPriceImpact2Discriminator: case meteoraDlmmSwap2Discriminator, meteoraDlmmSwapExactOut2Discriminator, meteoraDlmmSwapWithPriceImpact2Discriminator:
@@ -214,6 +216,57 @@ func metaoradlmmParser(tx *Tx, instruction Instruction, innerInstructions InnerI
} }
} }
func metaoradlmmInitializeParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
market := tx.rawTx.accountList[instruction.Accounts[0]]
token0 := tx.rawTx.accountList[instruction.Accounts[2]]
token1 := tx.rawTx.accountList[instruction.Accounts[3]]
entryContract := tx.rawTx.accountList[tx.rawTx.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
var baseDecimals uint8
var quoteDecimals uint8
for _, acc := range tx.rawTx.Meta.PostTokenBalances {
if acc.MintAccount.Equals(token0) {
baseDecimals = uint8(acc.UITokenAmount.Decimals)
}
if acc.MintAccount.Equals(token1) {
quoteDecimals = uint8(acc.UITokenAmount.Decimals)
}
}
swap := Swap{
Program: SolProgramMeteoraDLMM,
Event: "create",
Pool: market,
BaseMint: token0,
QuoteMint: token1,
BaseTokenProgram: tx.rawTx.accountList[instruction.Accounts[11]],
QuoteTokenProgram: tx.rawTx.accountList[instruction.Accounts[12]],
Creator: tx.rawTx.accountList[0],
BaseMintDecimals: baseDecimals,
QuoteMintDecimals: quoteDecimals,
User: tx.rawTx.accountList[instruction.Accounts[8]],
EntryContract: entryContract,
}
var prefixLen = offset[1]
inners, err := getInnerInstructions(innerInstructions, prefixLen)
if err != nil {
return nil, increaseOffset(offset), fmt.Errorf("pump create get inner instructions error: %v, offset, %d, %d", err, offset[0], offset[1])
}
var programIndex = instruction.ProgramIDIndex
for innerIndex, innerInstr := range inners {
if innerInstr.ProgramIDIndex == programIndex && bytes.Equal(innerInstr.Data[:8], pumpEventDiscriminator[:]) && bytes.Equal(innerInstr.Data[8:16], meteoraInitializeLbPairEventDiscriminator[:]) {
if offset[1] == 0 {
offset[0] += 1
} else {
offset[1] += uint(innerIndex) + 1 + prefixLen
}
break
}
}
return []Swap{swap}, offset, nil
}
func metaoradlmmSwapParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) { func metaoradlmmSwapParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
result := tx.rawTx result := tx.rawTx

View File

@@ -29,3 +29,9 @@ func TestTradeEvent(t *testing.T) {
fmt.Println(len(xx), err) fmt.Println(len(xx), err)
} }
func TestCal(t *testing.T) {
//e445a52e51cb9a1db94afc7d1bd7bc6f5e99e54b
// . b94afc7d1bd7bc6f
s := calculateDiscriminator("event:LbPairCreate")
fmt.Println(hex.EncodeToString(s[:]))
}

View File

@@ -513,6 +513,78 @@ func intSliceFromUint16Slice(in []uint16) []int {
} }
return out return out
} }
func getAtaIdxByOwner(result *RawTx, owner solana.PublicKey, mint solana.PublicKey) (int, error) {
var preBalance *TokenBalance
for _, pre := range result.Meta.PreTokenBalances {
if pre.MintAccount == mint && pre.OwnerAccount != nil && pre.OwnerAccount.Equals(owner) {
preBalance = &pre
break
}
}
var postBalance *TokenBalance
for _, post := range result.Meta.PostTokenBalances {
if post.MintAccount == mint && post.OwnerAccount != nil && post.OwnerAccount.Equals(owner) {
// post.ParseAccount()
postBalance = &post
break
}
}
if preBalance == nil && postBalance == nil {
return 0, fmt.Errorf("account not found")
}
if preBalance != nil && postBalance != nil && preBalance.AccountIndex != postBalance.AccountIndex {
return 0, fmt.Errorf("ata index not match")
}
if postBalance == nil {
return preBalance.AccountIndex, nil
}
return postBalance.AccountIndex, nil
}
func getAtaByOwner(result *RawTx, owner solana.PublicKey, mint solana.PublicKey) (*TokenBalance, error) {
var preBalance *TokenBalance
for _, pre := range result.Meta.PreTokenBalances {
if pre.MintAccount == mint && pre.OwnerAccount != nil && pre.OwnerAccount.Equals(owner) {
preBalance = &pre
break
}
}
var postBalance *TokenBalance
for _, post := range result.Meta.PostTokenBalances {
if post.MintAccount == mint && post.OwnerAccount != nil && post.OwnerAccount.Equals(owner) {
// post.ParseAccount()
postBalance = &post
break
}
}
if preBalance == nil && postBalance == nil {
return nil, fmt.Errorf("account not found")
}
if preBalance != nil && postBalance != nil && preBalance.AccountIndex != postBalance.AccountIndex {
return nil, fmt.Errorf("ata index not match")
}
if postBalance == nil {
preBalance.ParseAccount()
return &TokenBalance{
AccountIndex: preBalance.AccountIndex,
MintAccount: preBalance.MintAccount,
OwnerAccount: preBalance.OwnerAccount,
ProgramIDAccount: preBalance.ProgramIDAccount,
Mint: preBalance.Mint,
Owner: preBalance.Owner,
ProgramID: preBalance.ProgramID,
UITokenAmount: UITokenAmount{
Amount: "0",
Decimals: preBalance.UITokenAmount.Decimals,
UIAmount: 0,
UIAmountString: "0",
},
}, nil
}
return postBalance, nil
}
func getTokenBalanceAfterTx(result *RawTx, accountIndex int) (*TokenBalance, error) { func getTokenBalanceAfterTx(result *RawTx, accountIndex int) (*TokenBalance, error) {
var preBalance *TokenBalance var preBalance *TokenBalance
@@ -581,8 +653,12 @@ func tokenBalanceChange(result *RawTx, accountIndex int, tokenProgram, mint sola
break break
} }
} }
var err error
if ataIndex == 0 { if ataIndex == 0 {
return decimal.Zero, ataIndex ataIndex, err = getAtaIdxByOwner(result, result.accountList[accountIndex], mint)
if err != nil {
return decimal.Zero, ataIndex
}
} }
before := decimal.Zero before := decimal.Zero
after := decimal.Zero after := decimal.Zero
@@ -625,10 +701,13 @@ func GetTokenBalanceAfterTx(result *RawTx, accountIndex int, tokenProgram, mint
break break
} }
} }
var x *TokenBalance
var err error
if ataIndex == 0 { if ataIndex == 0 {
return decimal.Zero x, err = getAtaByOwner(result, result.accountList[accountIndex], mint)
} else {
x, err = getTokenBalanceAfterTx(result, ataIndex)
} }
x, err := getTokenBalanceAfterTx(result, ataIndex)
if err != nil { if err != nil {
return decimal.Zero return decimal.Zero
} }