Automated Action cae8527a4b s
2025-05-28 22:44:22 +00:00

93 lines
3.5 KiB
Python

"""
Parser for the Jupiter Aggregator swap instructions
"""
import base64
from typing import Dict, List, Optional, Tuple
from app.parsers.base import SwapParser
# Jupiter Program IDs
JUPITER_PROGRAM_ID = "JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB" # Jupiter V4
JUPITER_V3_PROGRAM_ID = "JUP3c2Uh3WA4Ng34tw6kPd2G4C5BB21Xo36Je1s32Ph" # Jupiter V3
JUPITER_V6_PROGRAM_ID = "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4" # Jupiter V6
class JupiterParser(SwapParser):
"""
Parser for the Jupiter Aggregator swap instructions
"""
@property
def program_id(self) -> str:
return JUPITER_PROGRAM_ID
def can_handle(self, program_id: str) -> bool:
"""
Check if this parser can handle instructions from a given program
"""
return program_id in [JUPITER_PROGRAM_ID, JUPITER_V3_PROGRAM_ID, JUPITER_V6_PROGRAM_ID]
def parse_instruction(self, instruction: Dict, accounts: List[str], instruction_data: bytes) -> Dict:
"""
Parse a Jupiter instruction
"""
if not instruction_data:
return {"type": "unknown", "error": "No instruction data"}
# Get accounts referenced by the instruction
instruction_accounts = instruction.get("accounts", [])
referenced_accounts = [accounts[idx] for idx in instruction_accounts if idx < len(accounts)]
# Basic metadata about the instruction
result = {
"type": "jupiter_swap",
"program": "jupiter_aggregator",
"program_id": instruction.get("programId", JUPITER_PROGRAM_ID),
"accounts": referenced_accounts,
"data": base64.b64encode(instruction_data).decode("utf-8"),
}
# Jupiter instructions are complex and version-dependent
# Here we'll implement a simplified version for demonstration
# In Jupiter V4+, the accounts typically follow this pattern:
# 0: Token program
# 1: User's token account (source)
# 2: User's token account (destination)
# 3: User's wallet
# (additional accounts depend on the route)
if len(referenced_accounts) >= 4:
result.update({
"source_account": referenced_accounts[1],
"destination_account": referenced_accounts[2],
"user_wallet": referenced_accounts[3],
})
# Note: Parsing the exact amount and path would require deeper
# instruction-specific knowledge and likely additional context
return result
def extract_swap_info(self, parsed_instruction: Dict) -> Tuple[Optional[str], Optional[str], Optional[float], Optional[float]]:
"""
Extract swap information from a parsed instruction
Returns:
Tuple of (token_in_address, token_out_address, amount_in, amount_out)
"""
if parsed_instruction.get("type") != "jupiter_swap":
return None, None, None, None
# For a full implementation, we would need to:
# 1. Look up token mint addresses from the token accounts
# 2. Parse amounts from instruction data
# 3. Handle different Jupiter versions
# This is a simplified implementation
source_account = parsed_instruction.get("source_account")
destination_account = parsed_instruction.get("destination_account")
# We don't have enough information to determine amounts from just the instruction
return None, source_account, destination_account, None