swap amount input

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

View File

@@ -188,6 +188,42 @@ type meteoraDammSwapEvent struct {
ReserveBAmount uint64
}
func meteoraDammSwapAmountInfo(event string, params *struct {
Amount0 uint64
Amount1 uint64
SwapMode uint8
}) (swapMode SwapMode, fixedAmount decimal.Decimal, limitAmount decimal.Decimal, ok bool) {
if params == nil {
return SwapModeUnknown, decimal.Zero, decimal.Zero, false
}
// Meteora DAMM v2 IDL defines:
// - swap: SwapParameters{ amountIn, minimumAmountOut }
// - swap2: SwapParameters2{ amount0, amount1, swapMode }
// - ExactIn / PartialFill: amount0=amount_in, amount1=minimum_amount_out
// - ExactOut: amount0=amount_out, amount1=maximum_amount_in
//
// The emitted event is normalized as token A <-> token B:
// - `sell` means A -> B, so A is the input side and B is the output side
// - `buy` means B -> A, so B is the input side and A is the output side
switch params.SwapMode {
case 0, 1: // ExactIn / PartialFill
swapMode = SwapModeExactIn
if event == TxEventSell {
return swapMode, decimal.NewFromUint64(params.Amount0), decimal.NewFromUint64(params.Amount1), true
}
return swapMode, decimal.NewFromUint64(params.Amount1), decimal.NewFromUint64(params.Amount0), true
case 2: // ExactOut
swapMode = SwapModeExactOut
if event == TxEventSell {
return swapMode, decimal.NewFromUint64(params.Amount1), decimal.NewFromUint64(params.Amount0), true
}
return swapMode, decimal.NewFromUint64(params.Amount0), decimal.NewFromUint64(params.Amount1), true
default:
return SwapModeUnknown, decimal.Zero, decimal.Zero, false
}
}
func meteoraDammV2Swap(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
if len(instruction.Accounts) < 9 {
return nil, increaseOffset(offset), fmt.Errorf("invalid instruction accounts length")
@@ -276,28 +312,30 @@ func meteoraDammV2Swap(tx *Tx, instruction Instruction, innerInstructions InnerI
return nil, offset, fmt.Errorf("invalid trade direction")
}
return []Swap{
{
Program: SolProgramMeteoraAmmV2,
Event: event,
Pool: swapEvent.Pool,
BaseMint: baseMint,
QuoteMint: quoteMint,
BaseTokenProgram: baseTokenProgram,
QuoteTokenProgram: quoteTokenProgram,
Creator: solana.PublicKey{},
BaseMintDecimals: baseMintDecimals,
QuoteMintDecimals: quoteMintDecimals,
User: payer,
BaseAmount: baseAmount,
QuoteAmount: quoteAmount,
BaseReserve: baseReserve,
QuoteReserve: quoteReserve,
UserBaseBalance: userBase,
UserQuoteBalance: userQuote,
EntryContract: entryContract,
},
}, offset, nil
swap := Swap{
Program: SolProgramMeteoraAmmV2,
Event: event,
Pool: swapEvent.Pool,
BaseMint: baseMint,
QuoteMint: quoteMint,
BaseTokenProgram: baseTokenProgram,
QuoteTokenProgram: quoteTokenProgram,
Creator: solana.PublicKey{},
BaseMintDecimals: baseMintDecimals,
QuoteMintDecimals: quoteMintDecimals,
User: payer,
BaseAmount: baseAmount,
QuoteAmount: quoteAmount,
BaseReserve: baseReserve,
QuoteReserve: quoteReserve,
UserBaseBalance: userBase,
UserQuoteBalance: userQuote,
EntryContract: entryContract,
}
if swapMode, fixedAmount, limitAmount, ok := meteoraDammSwapAmountInfo(event, swapEvent.Params); ok {
swap.SetSwapAmountInfo(swapMode, fixedAmount, limitAmount)
}
return []Swap{swap}, offset, nil
}