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

feat: getLogs #44

Merged
merged 10 commits into from
Feb 3, 2023
Merged

feat: getLogs #44

merged 10 commits into from
Feb 3, 2023

Conversation

0xOlias
Copy link
Contributor

@0xOlias 0xOlias commented Feb 2, 2023

Adds a getLogs action. Some discussion:

API

The API proposed here is basically the RPC API, which is at odds with the current API for eth_newFilter via the createEventFilter action. Per @jxom suggestion, I think it probably makes sense to consolidate these. One idea would be to replace the topics parameter entirely.

const logs = await getLogs(client, {
- topics: [hash('Transfer(address indexed, address indexed, uint256)'), ['0x1', '0x2']]
+ eventFilter: buildEventFilter({
+   event: 'Transfer(address indexed, address indexed, uint256)',
+   args: { from: ['0x1', '0x2'] }
+ })
})

The buildEventFilter function could be typed to allow either:

  • One event name + optional args
  • Many event names + no args
    which could help eliminate confusion around how topic sets work (and cover >99% of the ways people use topic sets).

Another idea would be to leave the getLogs API alone, and add a function buildTopicSet that works the same way as the proposed buildEventFilter but returns the topic set as a (Hex | Hex[])[].

const logs = await getLogs(client, {
- topics: [hash('Transfer(address indexed, address indexed, uint256)'), ['0x1', '0x2']]
+ topics: buildTopicSet({
+   event: 'Transfer(address indexed, address indexed, uint256)',
+   args: { from: ['0x1', '0x2'] }
+ })
})

@changeset-bot
Copy link

changeset-bot bot commented Feb 2, 2023

🦋 Changeset detected

Latest commit: 991066b

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Feb 2, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated
viem-benchmark ✅ Ready (Inspect) Visit Preview 💬 Add your feedback Feb 3, 2023 at 0:32AM (UTC)
viem-playground ✅ Ready (Inspect) Visit Preview 💬 Add your feedback Feb 3, 2023 at 0:32AM (UTC)
viem-site ✅ Ready (Inspect) Visit Preview 💬 Add your feedback Feb 3, 2023 at 0:32AM (UTC)

@github-actions
Copy link
Contributor

github-actions bot commented Feb 2, 2023

Size Change: +367 B (+1%)

Total Size: 33.1 kB

Filename Size Change
dist/chunk-4XREGFHD.js 0 B -1.43 kB (removed) 🏆
dist/chunk-WTXKCAG7.js 0 B -4.48 kB (removed) 🏆
dist/index.js 2.09 kB +23 B (+1%)
dist/public.js 490 B +6 B (+1%)
dist/wallet.js 296 B +1 B (0%)
dist/chunk-7E4DFIVL.js 1.52 kB +1.52 kB (new file) 🆕
dist/chunk-FHSQE76D.js 4.72 kB +4.72 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size
dist/chains.js 1.25 kB
dist/chunk-EWTLCB3N.js 18 kB
dist/chunk-LQXQPPTU.js 1.35 kB
dist/chunk-XJKOJIX3.js 1.84 kB
dist/clients/index.js 286 B
dist/test.js 509 B
dist/utils/index.js 779 B
dist/window.js 67 B

compressed-size-action

@codecov
Copy link

codecov bot commented Feb 2, 2023

Codecov upload limit reached ⚠️

This org is currently on the free Basic Plan; which includes 250 free private repo uploads each rolling month. This limit has been reached and additional reports cannot be generated. For unlimited uploads, upgrade to our pro plan.

Do you have questions or need help? Connect with our sales team today at sales@codecov.io

Copy link
Member

@jxom jxom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good start!

I agree that we should provide a way to pass in raw topics.

However, maybe we should include support for that in a future PR, and keep the API consistent with createEventFilter? Otherwise, we should add topics support to createEventFilter.

My suggestion for now would be:

await getLogs(publicClient, {
  address: '0x...',
  event: 'Transfer(...)',
  args: [...]
})

Then in a future PR, we should add support to be more flexible (multiple events, raw topics). Here are a few options:

Option 1: Support a union of params

This option explores supporting a union of params: { event, args } | { events } | { topics }

Single event w/ args

await getLogs(publicClient, {
  address: '0x...',
  event: 'Transfer(...)',
  args: [...]
})

Multiple events w/o args

await getLogs(publicClient, {
  address: '0x...',
  events: ['Transfer(...)', 'Foo(...)'],
})

Raw topics

await getLogs(publicClient, {
  address: '0x...',
  topics: ['0x...', '0x...', ['0x...', '0x...']]],
})

Think the downside to this approach is that DX might be a bit harder to navigate which parameters belong in the union without referencing the docs.

Option 2: Implement a "builder" function

Option 2 could be to suggest what you said in your PR, to have a builder helper.

Single event w/ args

await getLogs(publicClient, {
  address: '0x...',
  topics: buildEventTopics({
    event: 'Transfer(...)',
    args: [...]
  })
})

Multiple events w/o args

await getLogs(publicClient, {
  address: '0x...',
  topics: buildEventsTopics({
    events: ['Transfer(...)', 'Foo(...)']
  })
})

Raw topics

await getLogs(publicClient, {
  address: '0x...',
  topics: ['0x...', '0x...', ['0x...', '0x...']]],
})

I think I might like this approach better as:

  • it better guards the consumer from inserting the incorrect union parameters,
  • less magic behind the scenes, so it allows the consumer to learn how Ethereum log filters are built (they are a set of topics).

import { getLogs } from 'viem'
import { publicClient } from '.'

const logs = await getLogs(publicClient, { address, topics, fromBlock, toBlock })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should populate these attributes with example values.


### blockHash

- **Type:** [`bigint | 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized'`](/docs/glossary/types#TODO)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Type:** [`bigint | 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized'`](/docs/glossary/types#TODO)
- **Type:** `'0x${string}'`


- **Type:** [`bigint | 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized'`](/docs/glossary/types#TODO)

Block number or tag to include logs from. Mutually exclusive with `fromBlock`/`toBlock`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Block number or tag to include logs from. Mutually exclusive with `fromBlock`/`toBlock`.
Block hash to include logs from. Mutually exclusive with `fromBlock`/`toBlock`.

src/types/log.ts Outdated
Comment on lines 4 to 24
export type GetLogsParameters<TQuantity = bigint> = {
/** Address or list of addresses from which logs originated */
address?: Address | Address[]
/** List of order-dependent topics */
topics?: Hex[]
} & (
| {
/** Block number or tag after which to include logs */
fromBlock?: BlockNumber<TQuantity> | BlockTag
/** Block number or tag before which to include logs */
toBlock?: BlockNumber<TQuantity> | BlockTag
blockHash?: never
}
| {
fromBlock?: never
toBlock?: never
/** Hash of block to include logs from */
blockHash?: Hash
}
)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's put this in getLogs.ts.

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

Successfully merging this pull request may close these issues.

2 participants