Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subscribe only to event signature #99

Open
elier opened this issue Jul 30, 2024 · 7 comments
Open

Subscribe only to event signature #99

elier opened this issue Jul 30, 2024 · 7 comments
Labels
enhancement New feature or request

Comments

@elier
Copy link

elier commented Jul 30, 2024

Overview

I would like to subscribe to events independently of the contract address.

Specification

This is what is supported today to listen only to USDC_WETH swaps.

USDC_WETH = Contract('0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc')

@app.on_(USDC_WETH.Swap)
def handle_swaps(event):
    print(f"Swap: {event}")

This is what I would like to do to listen to any swap:

ANY = ... <= Load something here

@app.on_(ANY.Swap)
def handle_swaps(event):
    print(f"Swap: {event}")
@elier elier added the enhancement New feature or request label Jul 30, 2024
Copy link

linear bot commented Jul 30, 2024

@elier
Copy link
Author

elier commented Jul 30, 2024

I tried by removing "address=contract_address" but it crashes even though address argument is optional in poll_logs.

Fragment from PollingRunner:

        async for event in async_wrap_iter(
            self.provider.poll_logs(
                # NOTE: No start block because we should begin polling from head
                address=contract_address,
                new_block_timeout=new_block_timeout,
                events=[event_abi],
            )
        ):
            await self._checkpoint(last_block_seen=event.block_number)
            await self._handle_task(await event_log_task_kicker.kiq(event))
            await self._checkpoint(last_block_processed=event.block_number)

@fubuloubu
Copy link
Member

fubuloubu commented Jul 30, 2024

Hmm, would this look like the UX you are after?

from ape import project

# Set up this dependendency in `ape-config.yaml`
UniswapV2Pair = project.dependencies["uniswap-v2"]["1.0.1"].UniswapV2Pair


@app.on_(UniswapV2Pair.Swap)
async def all_univ2_clone_swaps(log):
    ...

Edit: this might be lower lift:

from ethpm_types import EventABI

Swap: EventABI  # ... = EventABI.parse_file("./uni-v2-swap.json")

@app.on_(Swap)
async def all_univ2_clone_swaps(log):
    ...

@elier
Copy link
Author

elier commented Jul 30, 2024

Yes, that's the idea. I find both proposals valid.

@fubuloubu
Copy link
Member

fubuloubu commented Jul 30, 2024

Option 1 would need all event definitions exposed in ContractContainer objects (signifying an event with no contract address), which would require some changes in ape (cc @antazoey for your thoughts)

Option 2 is something we can try and ship sooner in silverback, also note you can get an EventABI object from UniswapV2Pair.contract_type.events from the first example (so just a little extra code to pull out the one you want, doesn't require loading the json from scratch)

@antazoey
Copy link
Member

Option 1 would need all event definitions exposed in ContractContainer objects (signifying an event with no contract address), which would require some changes in ape (cc @antazoey for your thoughts)

I believe these are already available:

In [1]: type(project.VyperContract)
Out[1]: ape.contracts.base.ContractContainer

In [3]: project.VyperContract.NumberChange
Out[3]: NumberChange(bytes32 b, uint256 prevNum, string dynData, uint256 indexed newNum, string indexed 
dynIndexed)

In [4]: type(project.VyperContract.NumberChange)
Out[4]: ape.contracts.base.ContractEvent

You can do project.VyperContract.events to see them all as well.

@fubuloubu
Copy link
Member

Option 1 would need all event definitions exposed in ContractContainer objects (signifying an event with no contract address), which would require some changes in ape (cc @antazoey for your thoughts)

I believe these are already available:

In [1]: type(project.VyperContract)
Out[1]: ape.contracts.base.ContractContainer

In [3]: project.VyperContract.NumberChange
Out[3]: NumberChange(bytes32 b, uint256 prevNum, string dynData, uint256 indexed newNum, string indexed 
dynIndexed)

In [4]: type(project.VyperContract.NumberChange)
Out[4]: ape.contracts.base.ContractEvent

You can do project.VyperContract.events to see them all as well.

Okay perfect, that means the non-silverback code is ready for a feature addition here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants