Hemera Doc
  • 👋Welcome
    • Introduction
    • Quick Start
    • Account Centric Indexing Protocol
      • What is Account-Centric Indexing?
      • Why "account-centric" indexing?
      • The advantages of Account-Centric Indexing
      • What's next for account-centric indexing?
      • Why create a new protocol here?
      • The Hemera Network
        • Network Roles
        • Indexers
        • Validators
        • Proprietary models & knowledge
        • Proprietary data and labels
        • Smart Contracts
        • Key roadmap items
        • Supported blockchains
      • Example Hemera use cases
        • SocialScan Explorers
        • Anti-sybil UML algorithm
        • Ethereum long term DA
        • EVM chain history preservation
        • Ecosystem AI Agents
        • User-defined AI Agents
  • 👩‍💻Developer Resources
    • Smart Contract Developers
    • EVM-compatible chains
      • Blockchain explorers
      • SocialScan explorer API doc
      • Ecosystem AI Agents
    • Dapp developers
    • User-defined Agent creators
    • AVS Operator
  • 🖥️Hemera Indexer
    • Introduction
    • Installation
      • Prerequisites
      • Install & Run
      • Export Result
    • Configurations
    • Benchmark
    • Data Class
      • Raw Data Tables
        • Blocks
        • Transactions
        • Logs
        • Traces
      • Generated Tables
        • Contract Internal Transactions
        • ERC20 Token Transfers
        • Tokens
        • ERC20 Token Holders
        • ERC721 Token Transfers
        • ERC721 Token Holders
        • ERC1155 Token Transfers
        • ERC1155 Token Holders
        • Address Coin Balances
        • Address Token Balances
        • Address Current Token Balances
        • Daily Wallet Address Stats
        • Contracts
      • Other Tables
        • Inscriptions
        • Bridges
          • L1 to L2 Transactions
          • L2 to L1 Transactions
          • Optimistic Rollup Data Availability Batches
          • Optimistic Rollup State Batches
    • Use Cases
      • UniSwap V3
        • Data Class
        • Trigger and Function
        • Run & Query
      • ENS
        • Data Class
        • Trigger and Function
        • Run & Query
      • OpenSea
        • Data Class
        • Trigger and Function
        • Run & Query
      • Deposit to L2
        • Data Class
        • Trigger and Function
        • Run & Query
      • User Profile
  • UDFs - User Defined Functions
    • Introduction
    • Components of UDFs
    • Building User Defined Functions(UDF)
    • Testing and Running UDF
    • Troubleshooting and Support
    • Supported UDFs
    • FAQs
  • 😄About us
    • The story behind building Hemera
    • Partners & Backers
    • Partnership inquiries
    • Hemera Powered Explorers
    • Active Developer Hackathons
    • Developer Contribution
  • Documentation feedback
Powered by GitBook
On this page
  1. Hemera Indexer
  2. Use Cases
  3. Deposit to L2

Trigger and Function

PreviousData ClassNextRun & Query

Last updated 8 months ago

The deposit_to_l2 job is triggered when an deposit-related transaction occurs or an event is produced. Specifically:

  • bridgeETHTo: When the transaction content involves depositing WETH to a specific L2 chain through a contract

  • depositERC20: When the transaction content involves depositing ERC20 to a specific L2 chain through a contract

def parse_deposit_transaction_function(
    transactions: List[Transaction],
    contract_set: set,
    chain_mapping: dict,
    sig_function_mapping: dict,
    sig_parse_mapping: dict,
) -> List[TokenDepositTransaction]:
    deposit_tokens = []
    for transaction in transactions:
        if transaction.to_address in contract_set:
            input_sig = transaction.input[0:10]
            if input_sig in sig_function_mapping:
                deposit_transaction = sig_parse_mapping[input_sig](
                    transaction=transaction,
                    chain_mapping=chain_mapping,
                    function=sig_function_mapping[input_sig],
                )
                deposit_tokens.append(deposit_transaction)
    return deposit_tokens

and the function to extract the deposit info from the transaction input data:

def eth_deposit_parse(transaction: Transaction, chain_mapping: dict, function: ABIFunction) -> TokenDepositTransaction:
    return TokenDepositTransaction(
        transaction_hash=transaction.hash,
        wallet_address=transaction.from_address,
        chain_id=chain_mapping[transaction.to_address],
        contract_address=transaction.to_address,
        token_address=ETH_ADDRESS,
        value=transaction.value,
        block_number=transaction.block_number,
        block_timestamp=transaction.block_timestamp,
    )


def usdc_deposit_parse(transaction: Transaction, chain_mapping: dict, function: ABIFunction) -> TokenDepositTransaction:
    decoded_input = decode_transaction_data(function, HexStr(transaction.input))
    return TokenDepositTransaction(
        transaction_hash=transaction.hash,
        wallet_address=transaction.from_address,
        chain_id=chain_mapping[transaction.to_address],
        contract_address=transaction.to_address,
        token_address=USDC_ADDRESS,
        value=decoded_input["_amount"],
        block_number=transaction.block_number,
        block_timestamp=transaction.block_timestamp,
    )


def token_deposit_parse(
    transaction: Transaction, chain_mapping: dict, function: ABIFunction
) -> TokenDepositTransaction:
    decoded_input = decode_transaction_data(function, HexStr(transaction.input))
    return TokenDepositTransaction(
        transaction_hash=transaction.hash,
        wallet_address=transaction.from_address,
        chain_id=chain_mapping[transaction.to_address],
        contract_address=transaction.to_address,
        token_address=decoded_input["_l1Token"],
        value=decoded_input["_amount"],
        block_number=transaction.block_number,
        block_timestamp=transaction.block_timestamp,
    )

Meanwhile, after deposit_to_l2_job is triggered, the AddressTokenDeposit value is continuously aggregated by TokenDepositTransaction:

    for deposit in pre_aggregate_deposit_in_same_block(deposit_tokens):
        cache_key = (deposit.wallet_address, deposit.chain_id, deposit.contract_address, deposit.token_address)
        cache_value = self.cache.get(cache_key)
        if cache_value and cache_value.block_number < deposit.block_number:
            # add and save 2 cache
            token_deposit = AddressTokenDeposit(
                wallet_address=deposit.wallet_address,
                chain_id=deposit.chain_id,
                contract_address=deposit.contract_address,
                token_address=deposit.token_address,
                value=deposit.value + cache_value.value,
                block_number=deposit.block_number,
                block_timestamp=deposit.block_timestamp,
            )
    
            self.cache.set(cache_key, token_deposit)
            self._collect_item(AddressTokenDeposit.type(), token_deposit)
    
        elif cache_value is None:
            # check from db and save 2 cache
            history_deposit = self.check_history_deposit_from_db(
                deposit.wallet_address, deposit.chain_id, deposit.token_address
            )
            if history_deposit is None or history_deposit.block_number < deposit.block_number:
                token_deposit = AddressTokenDeposit(
                    wallet_address=deposit.wallet_address,
                    chain_id=deposit.chain_id,
                    contract_address=deposit.contract_address,
                    token_address=deposit.token_address,
                    value=deposit.value + history_deposit.value if history_deposit else deposit.value,
                    block_number=deposit.block_number,
                    block_timestamp=deposit.block_timestamp,
                )
                self.cache.set(cache_key, token_deposit)
                self._collect_item(AddressTokenDeposit.type(), token_deposit)
    
    self._data_buff[AddressTokenDeposit.type()] = distinct_collections_by_group(
        collections=self._data_buff[AddressTokenDeposit.type()],
        group_by=["wallet_address", "chain_id", "contract_address", "token_address"],
        max_key="block_number",
    )
🖥️