boltAsyncSRC20EventWatcher

Asynchronous SRC20 event watcher class

Polling-based SRC20 event watcher that runs as an asyncio task (asynchronous).

Overview

AsyncSRC20EventWatcher is a task-based event watcher that polls for SRC20 Transfer and Approval events, decrypts encrypted amounts using a viewing key, and invokes async callbacks with decoded event data.

The watcher runs as an asyncio.Task and polls at a configurable interval. It automatically handles block number tracking, log fetching, decryption, and callback invocation in an async context.

Typically created via async_watch_src20_events() or async_watch_src20_events_with_key() rather than instantiated directly.

Class Definition

class AsyncSRC20EventWatcher:
    """Polling-based SRC20 event watcher (async, runs as an asyncio.Task)."""

    def __init__(
        self,
        w3: AsyncWeb3,
        aes_key: Bytes32,
        *,
        token_address: ChecksumAddress | None = None,
        on_transfer: AsyncTransferCallback | TransferCallback | None = None,
        on_approval: AsyncApprovalCallback | ApprovalCallback | None = None,
        on_error: AsyncErrorCallback | ErrorCallback | None = None,
        poll_interval: float = 2.0,
        from_block: int | str = "latest",
    ) -> None

Constructor Parameters

Parameter
Type
Required
Description

w3

AsyncWeb3

Yes

Async Web3 instance

aes_key

Yes

32-byte AES-256 viewing key

token_address

ChecksumAddress

No

SRC20 contract to filter. If None, watches all tokens

on_transfer

Callback

No

Async or sync callback invoked for Transfer events

on_approval

Callback

No

Async or sync callback invoked for Approval events

on_error

Callback

No

Async or sync callback for errors

poll_interval

float

No

Seconds between polls (default 2.0)

from_block

int or "latest"

No

Starting block number or "latest" (default)

Methods

start()

Start the async polling task.

stop()

Cancel the polling task and wait for it to finish.

Properties

is_running

Check if the watcher is currently running.

Returns True if the task exists and is not done, False otherwise.

Context Manager Support

The watcher can be used as an async context manager:

The watcher starts automatically on __aenter__ and stops on __aexit__.

Examples

Manual Start/Stop

Async Context Manager

Check Running Status

Async Callback

Sync Callback (Also Works)

Filter by Token Address

Custom Poll Interval

Historical Events

Error Handling

Both Transfer and Approval

How It Works

  1. Task creation - Creates an asyncio.Task that runs the polling loop

  2. Polling loop - In the async task:

    • Fetches latest block number

    • Builds eth_getLogs filter with key hash

    • Fetches logs for the block range

    • Decodes and decrypts each log

    • Invokes callbacks with decrypted data (awaits if async)

    • Waits for poll_interval seconds with asyncio.sleep()

  3. Cleanup - When stopped, cancels the task and suppresses CancelledError

Callback Signatures

Transfer Callback

The watcher automatically detects if the callback is async (using asyncio.iscoroutine()) and awaits it if needed.

See DecryptedTransferLog for field details.

Approval Callback

See DecryptedApprovalLog for field details.

Error Callback

Invoked for:

  • RPC errors (network issues, rate limiting)

  • Decryption failures (wrong key, corrupted data)

  • Any exceptions during log processing

Notes

  • The polling task runs in the current event loop

  • Block tracking is automatic; watcher remembers the last processed block

  • Events are processed in order by block number

  • If on_error is not provided, errors are logged at DEBUG level

  • The watcher computes keccak256(aes_key) once at initialization

  • Callbacks can be sync or async; the watcher detects and handles both

Warnings

  • Async context required - Must be run within an asyncio event loop

  • Cleanup required - Always call await watcher.stop() or use async context manager

  • Network failures - Errors are silently logged unless on_error is provided

  • CancelledError - Properly suppressed during shutdown; don't worry about it

  • Memory usage - Keep poll interval reasonable to avoid excessive log fetching

See Also

Last updated