from typing import List from mev_inspect.schemas.traces import ( ClassifiedTrace, Classification, DecodedCallTrace, ) from mev_inspect.schemas.punk_bid import PunkBid from mev_inspect.schemas.punk_accept_bid import PunkBidAcceptance from mev_inspect.schemas.punk_snipe import PunkSnipe from mev_inspect.traces import get_traces_by_transaction_hash def get_punk_snipes( punk_bids: List[PunkBid], punk_bid_acceptances: List[PunkBidAcceptance] ) -> List[PunkSnipe]: punk_snipe_list = [] for punk_bid in punk_bids: for punk_bid_acceptance in punk_bid_acceptances: if punk_bid.punk_index == punk_bid_acceptance.punk_index: if punk_bid.price > punk_bid_acceptance.min_price: punk_snipe = PunkSnipe( block_number=punk_bid.block_number, transaction_hash=punk_bid.transaction_hash, trace_address=punk_bid.trace_address, from_address=punk_bid.from_address, punk_index=punk_bid.punk_index, min_acceptance_price=punk_bid_acceptance.min_price, acceptance_price=punk_bid.price, ) punk_snipe_list.append(punk_snipe) return punk_snipe_list def get_punk_bid_acceptances(traces: List[ClassifiedTrace]) -> List[PunkBidAcceptance]: punk_bid_acceptances = [] for _, transaction_traces in get_traces_by_transaction_hash(traces).items(): punk_bid_acceptances += _get_punk_bid_acceptances_for_transaction( list(transaction_traces) ) return punk_bid_acceptances def _get_punk_bid_acceptances_for_transaction( traces: List[ClassifiedTrace], ) -> List[PunkBidAcceptance]: ordered_traces = list(sorted(traces, key=lambda t: t.trace_address)) punk_bid_acceptances = [] for trace in ordered_traces: if not isinstance(trace, DecodedCallTrace): continue elif trace.classification == Classification.punk_accept_bid: punk_accept_bid = PunkBidAcceptance( block_number=trace.block_number, transaction_hash=trace.transaction_hash, trace_address=trace.trace_address, from_address=trace.from_address, punk_index=trace.inputs["punkIndex"], min_price=trace.inputs["minPrice"], ) punk_bid_acceptances.append(punk_accept_bid) return punk_bid_acceptances def get_punk_bids(traces: List[ClassifiedTrace]) -> List[PunkBid]: punk_bids = [] for _, transaction_traces in get_traces_by_transaction_hash(traces).items(): punk_bids += _get_punk_bids_for_transaction(list(transaction_traces)) return punk_bids def _get_punk_bids_for_transaction(traces: List[ClassifiedTrace]) -> List[PunkBid]: ordered_traces = list(sorted(traces, key=lambda t: t.trace_address)) punk_bids = [] for trace in ordered_traces: if not isinstance(trace, DecodedCallTrace): continue elif trace.classification == Classification.punk_bid: punk_bid = PunkBid( transaction_hash=trace.transaction_hash, block_number=trace.block_number, trace_address=trace.trace_address, from_address=trace.from_address, punk_index=trace.inputs["punkIndex"], price=trace.value, ) punk_bids.append(punk_bid) return punk_bids