Add dlmm open and close

This commit is contained in:
bijianing97
2026-03-19 14:10:14 +08:00
parent db8c8727f4
commit 401dca225a
3 changed files with 334 additions and 25 deletions

59
meta.go
View File

@@ -68,31 +68,40 @@ var (
) )
var ( var (
meteoraInitializeLbPairDiscriminator = calculateDiscriminator("global:initialize_lb_pair2") meteoraInitializeLbPairDiscriminator = calculateDiscriminator("global:initialize_lb_pair2")
meteoraInitializeLbPairEventDiscriminator = calculateDiscriminator("event:LbPairCreate") meteoraInitializeLbPairEventDiscriminator = calculateDiscriminator("event:LbPairCreate")
meteoraDlmmSwapDiscriminator = calculateDiscriminator("global:swap") meteoraDlmmSwapDiscriminator = calculateDiscriminator("global:swap")
meteoraDlmmSwap2Discriminator = calculateDiscriminator("global:swap2") meteoraDlmmSwap2Discriminator = calculateDiscriminator("global:swap2")
meteoraDlmmSwapExactOutDiscriminator = calculateDiscriminator("global:swap_exact_out") meteoraDlmmSwapExactOutDiscriminator = calculateDiscriminator("global:swap_exact_out")
meteoraDlmmSwapExactOut2Discriminator = calculateDiscriminator("global:swap_exact_out2") meteoraDlmmSwapExactOut2Discriminator = calculateDiscriminator("global:swap_exact_out2")
meteoraDlmmSwapWithPriceImpactDiscriminator = calculateDiscriminator("global:swap_with_price_impact") meteoraDlmmSwapWithPriceImpactDiscriminator = calculateDiscriminator("global:swap_with_price_impact")
meteoraDlmmSwapWithPriceImpact2Discriminator = calculateDiscriminator("global:swap_with_price_impact2") meteoraDlmmSwapWithPriceImpact2Discriminator = calculateDiscriminator("global:swap_with_price_impact2")
meteoraDlmmSwapEventDiscriminator = calculateDiscriminator("event:Swap") meteoraDlmmInitializePositionDiscriminator = calculateDiscriminator("global:initialize_position")
meteoraDlmmAddLiquidityDiscriminator = calculateDiscriminator("global:add_liquidity") meteoraDlmmInitializePosition2Discriminator = calculateDiscriminator("global:initialize_position2")
meteoraDlmmAddLiquidity2Discriminator = calculateDiscriminator("global:add_liquidity2") meteoraDlmmInitializePositionByOperatorDiscriminator = calculateDiscriminator("global:initialize_position_by_operator")
meteoraDlmmAddLiquidityByStrategyDiscriminator = calculateDiscriminator("global:add_liquidity_by_strategy") meteoraDlmmInitializePositionPdaDiscriminator = calculateDiscriminator("global:initialize_position_pda")
meteoraDlmmAddLiquidityByStrategy2Discriminator = calculateDiscriminator("global:add_liquidity_by_strategy2") meteoraDlmmClosePositionDiscriminator = calculateDiscriminator("global:close_position")
meteoraDlmmClaimFeeDiscriminator = calculateDiscriminator("global:claim_fee") meteoraDlmmClosePosition2Discriminator = calculateDiscriminator("global:close_position2")
meteoraDlmmClaimFee2Discriminator = calculateDiscriminator("global:claim_fee2") meteoraDlmmClosePositionIfEmptyDiscriminator = calculateDiscriminator("global:close_position_if_empty")
meteoraDlmmRebalanceLiquidityDiscriminator = calculateDiscriminator("global:rebalance_liquidity") meteoraDlmmSwapEventDiscriminator = calculateDiscriminator("event:Swap")
meteoraDlmmRemoveLiquidityDiscriminator = calculateDiscriminator("global:remove_liquidity") meteoraDlmmAddLiquidityDiscriminator = calculateDiscriminator("global:add_liquidity")
meteoraDlmmRemoveLiquidity2Discriminator = calculateDiscriminator("global:remove_liquidity2") meteoraDlmmAddLiquidity2Discriminator = calculateDiscriminator("global:add_liquidity2")
meteoraDlmmRemoveLiquidityByRangeDiscriminator = calculateDiscriminator("global:remove_liquidity_by_range") meteoraDlmmAddLiquidityByStrategyDiscriminator = calculateDiscriminator("global:add_liquidity_by_strategy")
meteoraDlmmRemoveLiquidityByRange2Discriminator = calculateDiscriminator("global:remove_liquidity_by_range2") meteoraDlmmAddLiquidityByStrategy2Discriminator = calculateDiscriminator("global:add_liquidity_by_strategy2")
meteoraDlmmAddLiquidityEventDiscriminator = calculateDiscriminator("event:AddLiquidity") meteoraDlmmClaimFeeDiscriminator = calculateDiscriminator("global:claim_fee")
meteoraDlmmClaimFeeEventDiscriminator = calculateDiscriminator("event:ClaimFee") meteoraDlmmClaimFee2Discriminator = calculateDiscriminator("global:claim_fee2")
meteoraDlmmClaimFee2EventDiscriminator = calculateDiscriminator("event:ClaimFee2") meteoraDlmmRebalanceLiquidityDiscriminator = calculateDiscriminator("global:rebalance_liquidity")
meteoraDlmmRebalancingEventDiscriminator = calculateDiscriminator("event:Rebalancing") meteoraDlmmRemoveLiquidityDiscriminator = calculateDiscriminator("global:remove_liquidity")
meteoraDlmmRemoveLiquidityEventDiscriminator = calculateDiscriminator("event:RemoveLiquidity") meteoraDlmmRemoveLiquidity2Discriminator = calculateDiscriminator("global:remove_liquidity2")
meteoraDlmmRemoveLiquidityByRangeDiscriminator = calculateDiscriminator("global:remove_liquidity_by_range")
meteoraDlmmRemoveLiquidityByRange2Discriminator = calculateDiscriminator("global:remove_liquidity_by_range2")
meteoraDlmmAddLiquidityEventDiscriminator = calculateDiscriminator("event:AddLiquidity")
meteoraDlmmClaimFeeEventDiscriminator = calculateDiscriminator("event:ClaimFee")
meteoraDlmmClaimFee2EventDiscriminator = calculateDiscriminator("event:ClaimFee2")
meteoraDlmmPositionCloseEventDiscriminator = calculateDiscriminator("event:PositionClose")
meteoraDlmmPositionCreateEventDiscriminator = calculateDiscriminator("event:PositionCreate")
meteoraDlmmRebalancingEventDiscriminator = calculateDiscriminator("event:Rebalancing")
meteoraDlmmRemoveLiquidityEventDiscriminator = calculateDiscriminator("event:RemoveLiquidity")
) )
var ( var (

View File

@@ -55,6 +55,17 @@ type dlmmRemoveLiquidityEvent struct {
ActiveBinId int32 ActiveBinId int32
} }
type dlmmPositionCreateEvent struct {
LbPair solana.PublicKey
Position solana.PublicKey
Owner solana.PublicKey
}
type dlmmPositionCloseEvent struct {
Position solana.PublicKey
Owner solana.PublicKey
}
type dlmmClaimFeeInnerEvent struct { type dlmmClaimFeeInnerEvent struct {
LbPair solana.PublicKey LbPair solana.PublicKey
Position solana.PublicKey Position solana.PublicKey
@@ -172,6 +183,18 @@ type dlmmRemoveLiquidityByRange2Args struct {
RemainingAccountsInfo dlmmRemainingAccountsInfo RemainingAccountsInfo dlmmRemainingAccountsInfo
} }
type dlmmInitializePositionArgs struct {
LowerBinId int32
Width int32
}
type dlmmInitializePositionByOperatorArgs struct {
LowerBinId int32
Width int32
FeeOwner solana.PublicKey
LockReleasePoint uint64
}
type dlmmRemainingAccountsInfo struct{} type dlmmRemainingAccountsInfo struct{}
func (dlmmRemainingAccountsInfo) UnmarshalWithDecoder(decoder *agbinary.Decoder) error { func (dlmmRemainingAccountsInfo) UnmarshalWithDecoder(decoder *agbinary.Decoder) error {
@@ -245,6 +268,9 @@ func metaoradlmmParser(tx *Tx, instruction Instruction, innerInstructions InnerI
switch discriminator { switch discriminator {
case meteoraInitializeLbPairDiscriminator: case meteoraInitializeLbPairDiscriminator:
return metaoradlmmInitializeParser(tx, instruction, innerInstructions, offset) return metaoradlmmInitializeParser(tx, instruction, innerInstructions, offset)
case meteoraDlmmInitializePositionDiscriminator, meteoraDlmmInitializePosition2Discriminator,
meteoraDlmmInitializePositionByOperatorDiscriminator, meteoraDlmmInitializePositionPdaDiscriminator:
return metaoradlmmPositionCreateParser(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:
@@ -259,6 +285,8 @@ func metaoradlmmParser(tx *Tx, instruction Instruction, innerInstructions InnerI
case meteoraDlmmRemoveLiquidityDiscriminator, meteoraDlmmRemoveLiquidity2Discriminator, case meteoraDlmmRemoveLiquidityDiscriminator, meteoraDlmmRemoveLiquidity2Discriminator,
meteoraDlmmRemoveLiquidityByRangeDiscriminator, meteoraDlmmRemoveLiquidityByRange2Discriminator: meteoraDlmmRemoveLiquidityByRangeDiscriminator, meteoraDlmmRemoveLiquidityByRange2Discriminator:
return metaoradlmmRemoveLiquidityParser(tx, instruction, innerInstructions, offset) return metaoradlmmRemoveLiquidityParser(tx, instruction, innerInstructions, offset)
case meteoraDlmmClosePositionDiscriminator, meteoraDlmmClosePosition2Discriminator, meteoraDlmmClosePositionIfEmptyDiscriminator:
return metaoradlmmPositionCloseParser(tx, instruction, innerInstructions, offset)
default: default:
return nil, increaseOffset(offset), InstructionIgnoredError return nil, increaseOffset(offset), InstructionIgnoredError
} }
@@ -315,6 +343,141 @@ func metaoradlmmInitializeParser(tx *Tx, instruction Instruction, innerInstructi
return []Swap{swap}, offset, nil return []Swap{swap}, offset, nil
} }
func metaoradlmmPositionCreateParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
result := tx.rawTx
entryContract := result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
if instruction.StackHeight != nil && *instruction.StackHeight > 2 {
for _, innerInstr := range innerInstructions.Instructions {
if innerInstr.StackHeight != nil && *innerInstr.StackHeight == *instruction.StackHeight-1 {
entryContract = result.accountList[innerInstr.ProgramIDIndex]
break
}
}
}
decode := instruction.Data
if len(decode) < 8 {
offset[1] += 1
return nil, increaseOffset(offset), fmt.Errorf("meteora dlmm create position instruction data too short, offset, %d, %d", offset[0], offset[1])
}
discriminator := *(*[8]byte)(decode[:8])
var (
lowerBinId int32
width int32
)
switch discriminator {
case meteoraDlmmInitializePositionDiscriminator, meteoraDlmmInitializePosition2Discriminator, meteoraDlmmInitializePositionPdaDiscriminator:
var args dlmmInitializePositionArgs
if err := agbinary.NewBorshDecoder(decode[8:]).Decode(&args); err != nil {
return nil, increaseOffset(offset), fmt.Errorf("meteora dlmm create position decode error: %v, offset, %d, %d", err, offset[0], offset[1])
}
lowerBinId = args.LowerBinId
width = args.Width
case meteoraDlmmInitializePositionByOperatorDiscriminator:
var args dlmmInitializePositionByOperatorArgs
if err := agbinary.NewBorshDecoder(decode[8:]).Decode(&args); err != nil {
return nil, increaseOffset(offset), fmt.Errorf("meteora dlmm create position by operator decode error: %v, offset, %d, %d", err, offset[0], offset[1])
}
lowerBinId = args.LowerBinId
width = args.Width
default:
return nil, increaseOffset(offset), InstructionIgnoredError
}
pool, positionAccount, eventUser, err := dlmmPositionCreateInstructionAccounts(result, discriminator, instruction.Accounts)
if err != nil {
return nil, increaseOffset(offset), fmt.Errorf("meteora dlmm create position accounts parse error: %v, offset, %d, %d", err, offset[0], offset[1])
}
createEvent, nextOffset, err := dlmmPositionCreateEventFromInnerInstructions(innerInstructions, instruction, offset)
if err != nil {
return nil, nextOffset, err
}
offset = nextOffset
if !createEvent.LbPair.IsZero() {
pool = createEvent.LbPair
}
if !createEvent.Position.IsZero() {
positionAccount = createEvent.Position
}
if !createEvent.Owner.IsZero() {
eventUser = createEvent.Owner
}
swap := Swap{
Program: SolProgramMeteoraDLMM,
Event: "open",
Pool: pool,
User: eventUser,
EntryContract: entryContract,
StartBinId: lowerBinId,
EndBinId: dlmmPositionUpperBinId(lowerBinId, width),
PositionAccount: positionAccount,
}
return []Swap{swap}, offset, nil
}
func metaoradlmmPositionCloseParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
result := tx.rawTx
entryContract := result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
if instruction.StackHeight != nil && *instruction.StackHeight > 2 {
for _, innerInstr := range innerInstructions.Instructions {
if innerInstr.StackHeight != nil && *innerInstr.StackHeight == *instruction.StackHeight-1 {
entryContract = result.accountList[innerInstr.ProgramIDIndex]
break
}
}
}
decode := instruction.Data
if len(decode) < 8 {
offset[1] += 1
return nil, increaseOffset(offset), fmt.Errorf("meteora dlmm close position instruction data too short, offset, %d, %d", offset[0], offset[1])
}
discriminator := *(*[8]byte)(decode[:8])
pool, positionAccount, eventUser, err := dlmmPositionCloseInstructionAccounts(result, discriminator, instruction.Accounts)
if err != nil {
return nil, increaseOffset(offset), fmt.Errorf("meteora dlmm close position accounts parse error: %v, offset, %d, %d", err, offset[0], offset[1])
}
closeEvent, nextOffset, found, err := dlmmPositionCloseEventFromInnerInstructions(innerInstructions, instruction, offset)
if err != nil {
return nil, nextOffset, err
}
if !found {
if discriminator == meteoraDlmmClosePositionIfEmptyDiscriminator {
return nil, nextOffset, InstructionIgnoredError
}
return nil, nextOffset, fmt.Errorf("meteora dlmm close position event not found, offset, %d, %d", nextOffset[0], nextOffset[1])
}
offset = nextOffset
if !closeEvent.Position.IsZero() {
positionAccount = closeEvent.Position
}
if !closeEvent.Owner.IsZero() {
eventUser = closeEvent.Owner
}
swap := Swap{
Program: SolProgramMeteoraDLMM,
Event: "close",
Pool: pool,
User: eventUser,
EntryContract: entryContract,
PositionAccount: positionAccount,
}
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
@@ -704,6 +867,7 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
StartBinId: startBinId, StartBinId: startBinId,
EndBinId: endBinId, EndBinId: endBinId,
BinChanges: binChanges, BinChanges: binChanges,
PositionAccount: result.accountList[accounts.positionIdx],
} }
return []Swap{swap}, offset, nil return []Swap{swap}, offset, nil
@@ -879,6 +1043,7 @@ func metaoradlmmRemoveLiquidityParser(tx *Tx, instruction Instruction, innerInst
EndBinId: endBinId, EndBinId: endBinId,
RemoveBp: removeBp, RemoveBp: removeBp,
BinChanges: binChanges, BinChanges: binChanges,
PositionAccount: result.accountList[accounts.positionIdx],
} }
return []Swap{swap}, offset, nil return []Swap{swap}, offset, nil
@@ -994,6 +1159,7 @@ func metaoradlmmClaimFeeParser(tx *Tx, instruction Instruction, innerInstruction
UserBaseBalance: userBase, UserBaseBalance: userBase,
UserQuoteBalance: userQuote, UserQuoteBalance: userQuote,
EntryContract: entryContract, EntryContract: entryContract,
PositionAccount: result.accountList[accounts.positionIdx],
} }
if claimEvent.HasActiveBin { if claimEvent.HasActiveBin {
swap.ActiveBinId = claimEvent.ActiveBinId swap.ActiveBinId = claimEvent.ActiveBinId
@@ -1121,6 +1287,7 @@ func metaoradlmmRebalanceLiquidityParser(tx *Tx, instruction Instruction, innerI
StartBinId: event.OldMinBinId, StartBinId: event.OldMinBinId,
EndBinId: event.OldMaxBinId, EndBinId: event.OldMaxBinId,
BinChanges: dlmmBinChangesFromRange(event.OldMinBinId, event.OldMaxBinId, 0), BinChanges: dlmmBinChangesFromRange(event.OldMinBinId, event.OldMaxBinId, 0),
PositionAccount: result.accountList[accounts.positionIdx],
}) })
} }
if addBase > 0 || addQuote > 0 { if addBase > 0 || addQuote > 0 {
@@ -1146,6 +1313,7 @@ func metaoradlmmRebalanceLiquidityParser(tx *Tx, instruction Instruction, innerI
StartBinId: event.NewMinBinId, StartBinId: event.NewMinBinId,
EndBinId: event.NewMaxBinId, EndBinId: event.NewMaxBinId,
BinChanges: dlmmBinChangesFromRange(event.NewMinBinId, event.NewMaxBinId, 0), BinChanges: dlmmBinChangesFromRange(event.NewMinBinId, event.NewMaxBinId, 0),
PositionAccount: result.accountList[accounts.positionIdx],
}) })
} }
if len(swaps) == 0 { if len(swaps) == 0 {
@@ -1278,6 +1446,54 @@ func dlmmRebalancingEventFromInnerInstructions(innerInstructions InnerInstructio
return dlmmRebalancingEvent{}, increaseOffset(offset), fmt.Errorf("meteora dlmm rebalance liquidity event not found, offset, %d, %d", offset[0], prefixLen) return dlmmRebalancingEvent{}, increaseOffset(offset), fmt.Errorf("meteora dlmm rebalance liquidity event not found, offset, %d, %d", offset[0], prefixLen)
} }
func dlmmPositionCreateEventFromInnerInstructions(innerInstructions InnerInstructions, instruction Instruction, offset [2]uint) (dlmmPositionCreateEvent, [2]uint, error) {
var prefixLen = offset[1]
inners, err := getInnerInstructions(innerInstructions, prefixLen)
if err != nil {
return dlmmPositionCreateEvent{}, increaseOffset(offset), fmt.Errorf("meteora dlmm create position get inner instructions error: %v, offset, %d, %d", err, offset[0], prefixLen)
}
for innerIndex, innerInstr := range inners {
if innerInstr.ProgramIDIndex != instruction.ProgramIDIndex {
continue
}
event, ok := dlmmDecodePositionCreateEvent(innerInstr.Data)
if !ok {
continue
}
if offset[1] == 0 {
offset[0] += 1
} else {
offset[1] = uint(innerIndex) + 1 + prefixLen
}
return event, offset, nil
}
return dlmmPositionCreateEvent{}, increaseOffset(offset), fmt.Errorf("meteora dlmm create position event not found, offset, %d, %d", offset[0], prefixLen)
}
func dlmmPositionCloseEventFromInnerInstructions(innerInstructions InnerInstructions, instruction Instruction, offset [2]uint) (dlmmPositionCloseEvent, [2]uint, bool, error) {
var prefixLen = offset[1]
inners, err := getInnerInstructions(innerInstructions, prefixLen)
if err != nil {
return dlmmPositionCloseEvent{}, increaseOffset(offset), false, fmt.Errorf("meteora dlmm close position get inner instructions error: %v, offset, %d, %d", err, offset[0], prefixLen)
}
for innerIndex, innerInstr := range inners {
if innerInstr.ProgramIDIndex != instruction.ProgramIDIndex {
continue
}
event, ok := dlmmDecodePositionCloseEvent(innerInstr.Data)
if !ok {
continue
}
if offset[1] == 0 {
offset[0] += 1
} else {
offset[1] = uint(innerIndex) + 1 + prefixLen
}
return event, offset, true, nil
}
return dlmmPositionCloseEvent{}, increaseOffset(offset), false, nil
}
func dlmmDecodeAddLiquidityEvent(data []byte) (dlmmAddLiquidityEvent, bool) { func dlmmDecodeAddLiquidityEvent(data []byte) (dlmmAddLiquidityEvent, bool) {
switch { switch {
case len(data) >= 8 && bytes.Equal(data[:8], meteoraDlmmAddLiquidityEventDiscriminator[:]): case len(data) >= 8 && bytes.Equal(data[:8], meteoraDlmmAddLiquidityEventDiscriminator[:]):
@@ -1320,6 +1536,48 @@ func dlmmDecodeRemoveLiquidityEvent(data []byte) (dlmmRemoveLiquidityEvent, bool
} }
} }
func dlmmDecodePositionCreateEvent(data []byte) (dlmmPositionCreateEvent, bool) {
switch {
case len(data) >= 8 && bytes.Equal(data[:8], meteoraDlmmPositionCreateEventDiscriminator[:]):
var event dlmmPositionCreateEvent
if err := agbinary.NewBorshDecoder(data[8:]).Decode(&event); err != nil {
return dlmmPositionCreateEvent{}, false
}
return event, true
case len(data) >= 16 &&
bytes.Equal(data[:8], eventDiscriminator[:]) &&
bytes.Equal(data[8:16], meteoraDlmmPositionCreateEventDiscriminator[:]):
var event dlmmPositionCreateEvent
if err := agbinary.NewBorshDecoder(data[16:]).Decode(&event); err != nil {
return dlmmPositionCreateEvent{}, false
}
return event, true
default:
return dlmmPositionCreateEvent{}, false
}
}
func dlmmDecodePositionCloseEvent(data []byte) (dlmmPositionCloseEvent, bool) {
switch {
case len(data) >= 8 && bytes.Equal(data[:8], meteoraDlmmPositionCloseEventDiscriminator[:]):
var event dlmmPositionCloseEvent
if err := agbinary.NewBorshDecoder(data[8:]).Decode(&event); err != nil {
return dlmmPositionCloseEvent{}, false
}
return event, true
case len(data) >= 16 &&
bytes.Equal(data[:8], eventDiscriminator[:]) &&
bytes.Equal(data[8:16], meteoraDlmmPositionCloseEventDiscriminator[:]):
var event dlmmPositionCloseEvent
if err := agbinary.NewBorshDecoder(data[16:]).Decode(&event); err != nil {
return dlmmPositionCloseEvent{}, false
}
return event, true
default:
return dlmmPositionCloseEvent{}, false
}
}
func dlmmDecodeClaimFeeEvent(data []byte) (dlmmClaimFeeInnerEvent, bool) { func dlmmDecodeClaimFeeEvent(data []byte) (dlmmClaimFeeInnerEvent, bool) {
switch { switch {
case len(data) >= 16 && case len(data) >= 16 &&
@@ -1378,6 +1636,40 @@ func dlmmDecodeRebalancingEvent(data []byte) (dlmmRebalancingEvent, bool) {
} }
} }
func dlmmPositionCreateInstructionAccounts(result *RawTx, discriminator [8]byte, accounts []int) (pool, position, owner solana.PublicKey, err error) {
switch discriminator {
case meteoraDlmmInitializePositionDiscriminator, meteoraDlmmInitializePosition2Discriminator:
if len(accounts) < 4 {
return solana.PublicKey{}, solana.PublicKey{}, solana.PublicKey{}, fmt.Errorf("accounts too short, expected at least 4")
}
return result.accountList[accounts[2]], result.accountList[accounts[1]], result.accountList[accounts[3]], nil
case meteoraDlmmInitializePositionByOperatorDiscriminator, meteoraDlmmInitializePositionPdaDiscriminator:
if len(accounts) < 5 {
return solana.PublicKey{}, solana.PublicKey{}, solana.PublicKey{}, fmt.Errorf("accounts too short, expected at least 5")
}
return result.accountList[accounts[3]], result.accountList[accounts[2]], result.accountList[accounts[4]], nil
default:
return solana.PublicKey{}, solana.PublicKey{}, solana.PublicKey{}, fmt.Errorf("unsupported create position discriminator")
}
}
func dlmmPositionCloseInstructionAccounts(result *RawTx, discriminator [8]byte, accounts []int) (pool, position, owner solana.PublicKey, err error) {
switch discriminator {
case meteoraDlmmClosePositionDiscriminator:
if len(accounts) < 5 {
return solana.PublicKey{}, solana.PublicKey{}, solana.PublicKey{}, fmt.Errorf("accounts too short, expected at least 5")
}
return result.accountList[accounts[1]], result.accountList[accounts[0]], result.accountList[accounts[4]], nil
case meteoraDlmmClosePosition2Discriminator, meteoraDlmmClosePositionIfEmptyDiscriminator:
if len(accounts) < 2 {
return solana.PublicKey{}, solana.PublicKey{}, solana.PublicKey{}, fmt.Errorf("accounts too short, expected at least 2")
}
return solana.PublicKey{}, result.accountList[accounts[0]], result.accountList[accounts[1]], nil
default:
return solana.PublicKey{}, solana.PublicKey{}, solana.PublicKey{}, fmt.Errorf("unsupported close position discriminator")
}
}
func resolveDlmmSwapAccounts(result *RawTx, accounts []int) (dlmmSwapAccounts, error) { func resolveDlmmSwapAccounts(result *RawTx, accounts []int) (dlmmSwapAccounts, error) {
if len(accounts) < 13 { if len(accounts) < 13 {
return dlmmSwapAccounts{}, fmt.Errorf("accounts too short, expected at least 13") return dlmmSwapAccounts{}, fmt.Errorf("accounts too short, expected at least 13")
@@ -1731,6 +2023,13 @@ func dlmmCommonRemoveBp(reduction []dlmmBinLiquidityReduction) int32 {
return int32(bpsToRemove) return int32(bpsToRemove)
} }
func dlmmPositionUpperBinId(lowerBinId, width int32) int32 {
if width <= 0 {
return lowerBinId
}
return lowerBinId + width - 1
}
func dlmmMinMaxBinIdFromDistribution(dist []dlmmBinLiquidityDistribution) (int32, int32) { func dlmmMinMaxBinIdFromDistribution(dist []dlmmBinLiquidityDistribution) (int32, int32) {
if len(dist) == 0 { if len(dist) == 0 {
return 0, 0 return 0, 0

1
tx.go
View File

@@ -53,6 +53,7 @@ type Swap struct {
EndBinId int32 EndBinId int32
RemoveBp int32 RemoveBp int32
BinChanges []DlmmBinLiquidityChange BinChanges []DlmmBinLiquidityChange
PositionAccount solana.PublicKey
ConsumeUnit uint64 ConsumeUnit uint64
} }