docs: Cookbook tab with six recipes, plus event and Foundry fixes - #91
alexander-sei wants to merge 16 commits into
Conversation
Add a Cookbook tab that groups the twelve existing example pages with six new recipes: read a balance, send SEI, deploy an ERC-20, listen to events, sponsor gas with Pimlico, and read a price feed. The recipes show viem, ethers, and web3.py in code groups with matching labels, so the reader's library choice applies to every block on the page. The example pages keep their URLs. The one-page Cosmos-SDK tab moves into Learn next to the SIP-03 guides, and /cookbook and /evm/evm-parity/examples redirect to the new overview. The price-feed recipe reads the API3 SEI/USD push feed, because the Oracle precompile is retired and the pull oracles need a signed update per call. Co-authored-by: Cursor <cursoragent@cursor.com>
On the public endpoints, filter-based watchers over HTTP miss or repeat events, and eth_uninstallFilter returns 403 on Sei Mainnet, which crashes ethers when a listener stops. eth_getLogs also rejects ranges longer than 2,000 blocks, so the ERC-20 history query from block 0 always failed. Watch over the WebSocket endpoint in the ERC-20, ERC-721, ERC-1155, and ethers quickstart examples, and query the latest 2,000 blocks for history. The ethers listener also declares the Transfer event that it listens for. Co-authored-by: Cursor <cursoragent@cursor.com>
Current Foundry releases only simulate forge create unless --broadcast is set, so the documented commands deployed nothing. Add the flag before --constructor-args, which takes every value after it, and pass plain constructor values: forge create rejects ABI-encoded arguments. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
PR SummaryLow Risk Overview Fixes across existing docs: event examples use WebSocket subscriptions and cap Reviewed by Cursor Bugbot for commit 0d78c93. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
This PR adds a well-structured Cookbook tab with six recipes. It also fixes real problems in the existing pages: event watching now uses WebSocket, eth_getLogs queries now stay within the 2,000-block limit, and the forge create examples now pass --broadcast. Redirects and navigation look correct, and nothing blocks the merge. The main open issue is that the TypeScript run instructions use top-level await, which fails when tsx treats the scripts as CommonJS.
Findings: 0 blocking | 7 non-blocking | 3 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- REVIEW_GUIDELINES.md is empty, so this review applies only the AGENTS.md conventions.
- The Cursor second-opinion pass produced no output (cursor-review.md is empty).
- The other example pages under evm/evm-parity/examples/ could also use the 'You are done when you see' blocks and the synced viem/ethers/web3.py tab labels. Without them, the Cookbook tab mixes two page styles.
- After merge, run the 'Regenerate llms.txt' workflow, as the PR description notes. The new Cookbook section in generate-llms.mjs sits before 'EVM Development', so it matches pages correctly.
- 3 suggestion(s)/nit(s) flagged inline on specific lines.
Put back the contractions that were spelled out before the PR was opened to match the ASD-STE100 pass. The recipes keep the wording they were written and tested with. Co-authored-by: Cursor <cursoragent@cursor.com>
In a new npm project, tsx compiles a plain .ts file as CommonJS, so the recipe and quickstart examples fail with "Top-level await is currently not supported with the "cjs" output format". Tell readers to save TypeScript examples as .mts files, add the missing install step to the ERC-20 read-back, and note the convention in STYLE_GUIDE.md and the llms.txt config. Co-authored-by: Cursor <cursoragent@cursor.com>
Foundry resolves @openzeppelin/contracts on its own, but editors and other Solidity tools read the mapping from remappings.txt. The Foundry guide already has the same step. Co-authored-by: Cursor <cursoragent@cursor.com>
…g it The guide has you store PIMLICO_API_KEY in .env, and then the script wrote the generated PRIVATE_KEY over the whole file, so the API key was gone after the first run. Append the key instead, and drop a top-level return from the sending snippet. Co-authored-by: Cursor <cursoragent@cursor.com>
…ontract Since Pyth's Core upgrade on August 26, 2026, Hermes rejects requests without an API key, and Pyth lists 0x16392B49EA47D4A21bb17F69aA9E7aD570284838 as the Sei Mainnet contract. Send the key as a bearer token to Pyth's recommended Hermes base URL, list the mainnet and testnet addresses separately, replace the Pythnet description, and note that the update fee is currently zero on both networks. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
This PR adds a solid Cookbook tab with six recipes. It also fixes real problems in existing pages: event watchers now use WebSocket, log queries stay within the 2,000-block cap, Foundry commands pass --broadcast, the Pimlico script no longer overwrites .env, and the Pyth guide reflects the Core upgrade. Redirects, nav, link targets, and terminology all check out; only minor robustness and wording nits remain.
Findings: 0 blocking | 8 non-blocking | 4 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- REVIEW_GUIDELINES.md is empty, so this review applies AGENTS.md conventions only. The Cursor second-opinion pass produced no output. Codex reported no material issues.
- Several statements describe current network state and will go stale: the Pyth Mainnet contract has no SEI/USD price yet, the Pyth update fee is currently zero, and the API3 testnet feed was months old when tested. AGENTS.md prefers linking to live sources over hard-coding state that changes. Consider wording these so they age gracefully, or link to the authoritative page.
- In the ERC-20, ERC-721, and ERC-1155 example pages, the new ethers watchers open a
WebSocketProvider, butoff()never callswsProvider.destroy(). A copied script therefore keeps running after it stops listening. Consider addingawait wsProvider.destroy()to the stop example. - Follow-up already noted in the PR: bring the older example pages in line with the recipe conventions ("You are done when you see" blocks and web3.py tabs).
- 4 suggestion(s)/nit(s) flagged inline on specific lines.
off() removes the listener, but the WebSocket stays open, so a copied script keeps running after it stops listening. The stop examples now destroy the provider too, and the ERC-1155 example gets a stop example. Co-authored-by: Cursor <cursoragent@cursor.com>
web3.py rejects addresses that aren't checksummed, so pasting a lowercase address from a CLI raised InvalidAddress. Wrap the address placeholders in Web3.to_checksum_address. Co-authored-by: Cursor <cursoragent@cursor.com>
Describe network state in a way that doesn't go stale: the API3 testnet warning, the note about the new Pyth Mainnet contract, and the Pyth update fee. The Pyth fetch example now stops with a clear error when PYTH_API_KEY isn't set, instead of sending "Bearer undefined". Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
This PR adds a well-organized Cookbook tab with six recipes. It also fixes real problems in existing pages: forge create without --broadcast, unbounded eth_getLogs queries, HTTP filter watchers, the .env overwrite in the Pimlico guide, and the Pyth Core changes. I found no blockers. The main remaining issue is that the ethers watcher snippets tear down their listeners right after registering them.
Findings: 0 blocking | 7 non-blocking | 2 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- The Cursor review pass produced no output (
cursor-review.mdwas empty).REVIEW_GUIDELINES.mdwas also empty, so this review follows AGENTS.md conventions only. - The ethers watcher snippets in
erc20.mdx,erc721.mdxandethers-quickstart.mdxshow the same thing as theerc1155.mdxinline comment: they register a listener, then immediatelyawait off()anddestroy()the provider. The old snippets also calledoffright away, but now the WebSocket provider is destroyed too. A reader who copies a snippet as-is gets a watcher that never fires. The cookbook recipe shows the better pattern: put the cleanup in a comment or a shutdown handler (for example,process.on('SIGINT', ...)). - I couldn't verify the Pyth changes, the new Hermes base URL (
pyth.dourolabs.app/hermes) and the new Sei Mainnet address0x16392B49…, from inside the repo. The PR says the end-to-end flow wasn't tested with a real key. Have someone confirm both against Pyth's contract-addresses page before merging, because a wrong oracle address in docs is costly. - The Pyth
<Warning>("Pyth upgraded Pyth Core on August 26, 2026...") is point-in-time wording. Consider removing or softening it once the upgrade is no longer recent. - After merge, remember to trigger the "Regenerate llms.txt" workflow so
llms.txtandllms-full.txtpick up the new Cookbook section. I couldn't runscripts/check-redirects.mjsin this environment, so rely on the CI result for the two new redirects. - 2 suggestion(s)/nit(s) flagged inline on specific lines.
The watcher snippets stopped right after they started, so a copied snippet never received an event, and destroying an ethers provider before it connected threw an error. Show the stop calls as a comment instead, as the listen-to-events recipe does. The WebSocket page had the same pattern. Co-authored-by: Cursor <cursoragent@cursor.com>
The note said to add constructor arguments after the contract path, but the example now has --broadcast in between. Say to put --constructor-args last instead, as the Foundry guide does. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
This is a well-scoped, carefully tested docs PR. It adds a Cookbook tab with six recipes and fixes real problems in existing pages: forge create --broadcast, WebSocket event watchers, bounded eth_getLogs ranges, and the Pimlico .env overwrite. I found no blocking issues, only a few small polish nits.
Findings: 0 blocking | 7 non-blocking | 2 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- The Cursor second-opinion file (
cursor-review.md) was empty, so that pass produced no output. The Codex pass reported no material issues, and I agree that nothing here blocks the merge. - I couldn't run
node scripts/check-redirects.mjsin this environment. I checked by hand instead. Both new redirects (/cookbookand/evm/evm-parity/examples) point toevm/cookbook/index.mdx, which exists. Neither source collides with an existing redirect or page, since there's noevm/evm-parity/examples/index.mdx. CI should confirm this. - After merge, remember to run the "Regenerate llms.txt" workflow, as the PR notes say. The new
Cookbookmatcher inscripts/generate-llms.mjscomes beforeEVM Development, so the/evm/evm-parity/examples/*pages move into the new section. That looks intentional. - The ERC-20/721/1155 pages add a second
import { webSocket } from 'viem';in the middle of the page. That's fine for a snippet, but addingwebSocketto the page's top-level viem import would make a copy-pasted script cleaner. - Optional follow-up, already noted by the author: bring the older
evm-parity/examplespages in line with the recipe conventions ("You are done when you see" blocks and web3.py tabs) so the Cookbook tab reads consistently. - 2 suggestion(s)/nit(s) flagged inline on specific lines.
The watcher snippets imported webSocket a second time in the middle of the page. Add it to the setup block's viem import instead, so a copied script has one import line. Co-authored-by: Cursor <cursoragent@cursor.com>
… testnet address The ERC-20 recipe's Remix payload used a plain import, while the page shows a named import. Re-encode the exact source from the page. The Pyth guide now links the Sei Testnet address to Seiscan, like the mainnet one. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
This is a well-tested docs PR. It adds a Cookbook tab with six recipes and fixes real problems in the existing examples: HTTP-polled watchers, unbounded eth_getLogs ranges, a missing forge create --broadcast, the Pimlico script overwriting .env, and the changes from Pyth's Core upgrade. I found no blockers, only a few small consistency notes.
Findings: 0 blocking | 8 non-blocking | 2 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- The Cursor second-opinion review (
cursor-review.md) was empty, so that pass produced no output. Codex reported no material issues. REVIEW_GUIDELINES.mdwas empty, so this review applied only the rules in AGENTS.md.- I couldn't run
node scripts/check-redirects.mjsin this environment because the command needed approval. CI should confirm that the new/cookbookand/evm/evm-parity/examplesredirects resolve toevm/cookbook/index. - I checked that the ERC-20, ERC-721, and ERC-1155 ABIs already declare the events their new WebSocket watchers subscribe to, and that
websocket.mdxuses aWebSocketProvider. Thedestroy()cleanup comments are correct. - The Pyth changes depend on external facts I can't verify here: the August 26, 2026 Core upgrade, the
pyth.dourolabs.app/hermesbase URL, and the new mainnet address0x16392B49…. The PR says the flow wasn't verified end to end with a real key. Have someone with a Pyth API key confirm before merge. - After merge, remember to trigger the 'Regenerate llms.txt' workflow, as the PR notes, so the new Cookbook section appears in
llms.txtandllms-full.txt. - 2 suggestion(s)/nit(s) flagged inline on specific lines.
Comments that couldn't be anchored to the diff
evm/evm-foundry.mdx:1410-- [nit] Good fix moving to plain constructor values.YOUR_ADDRESSis unquoted here, while the NFT line below quotes the URL. That's fine for an address, but readers sometimes paste values that contain spaces. Consider quoting placeholders the same way.
| // To stop: await usdc.removeAllListeners(); await provider.destroy(); | ||
| ``` | ||
|
|
||
| ```python web3.py |
There was a problem hiding this comment.
[nit] This page uses await usdc.on(...), but the updated ERC-20, ERC-721, and ERC-1155 pages call wsContract.on(...) without await. Both work, but awaiting on() surfaces subscription errors. Consider using the same form on every page.
|
|
||
| ```text | ||
| 1384.115892177302953913 SEI | ||
| ``` |
There was a problem hiding this comment.
[nit] The sample output shows a balance of about 1384 SEI, but the snippet reads the zero address. The text already calls the number illustrative. A neutral placeholder value, or a note to swap in your own address first, would make that clearer. The ERC-20 section below already does this.
Apply the ASD-STE100 rules from the language pass in #90 to the prose that this PR adds or changes. This undoes 7baa037, which put the contractions back. - Spell out contractions. - Give one instruction per sentence, and put the condition or purpose first. - Use the active voice, for example "tsx compiles a plain .ts file as CommonJS". - Replace figurative words ("lives in", "split the work", "go live") and -ing phrases. - Start the Pyth warning with the commands, then give the reason. Only prose changes. Code blocks, link targets, and heading anchors are unchanged. Three recipe descriptions in the frontmatter are shorter or no longer end in "using". Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
This PR adds a Cookbook tab with six recipes. It also fixes examples that were broken: event watching now uses WebSocket, log queries are bounded, forge create passes --broadcast, the Pimlico guide no longer overwrites .env, and the Pyth guide reflects Pyth's August 2026 upgrade. The navigation, redirects and code samples look correct. I found nothing blocking, only a couple of small notes.
Findings: 0 blocking | 6 non-blocking | 1 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- The Cursor review file (
cursor-review.md) was empty, so that pass produced no output. Codex reported no material issues.REVIEW_GUIDELINES.mdwas also empty, so I used the AGENTS.md conventions instead. - I checked the redirects. The new ones (
/cookbookand/evm/evm-parity/examples→/evm/cookbook) point toevm/cookbook/index.mdx, which this PR adds. The old example pages keep their URLs, so they need no redirects. - Because the Cosmos-SDK tab is gone,
cosmos-sdk/indexnow appears only in the Learn group. The many existing redirects to/cosmos-sdkstill resolve. Please confirm the deprecation notice on that page still shows as intended in the new location (AGENTS.md requires it to stay visible). - Several recipes show hard-coded example output: block numbers, transaction hashes, the SEI/USD price, and the count of 319 transfers. Most are already labelled as illustrative. Consider marking all of them that way so readers don't treat the numbers as real network data.
- Follow-up, as the author already noted: bring the older
evm-parity/examplespages in line with the recipe conventions (web3.py tabs and "You are done when you see" blocks). After merge, run the llms.txt regeneration workflow. - 1 suggestion(s)/nit(s) flagged inline on specific lines.
Comments that couldn't be anchored to the diff
evm/oracles/pyth-network.mdx:1813-- [nit] This warning says the guide was updated for the Pyth Core upgrade on August 26, 2026, which is a point-in-time statement. Elsewhere this PR deliberately removes point-in-time wording. Consider rewording to describe the current requirements (Hermes needs an API key, and these are the current addresses) and keep the upgrade-guide link for background. That way the warning won't go stale.
| match: (p) => p.startsWith('/evm/cookbook') || p.startsWith('/evm/evm-parity/examples/'), | ||
| overview: [ | ||
| 'The Cookbook has task-focused recipes with runnable code, most of them in viem, ethers, and web3.py. The recipes read balances, send SEI, deploy and use ERC-20, ERC-721, and ERC-1155 tokens, listen to events, batch reads with Multicall3, sponsor gas with an ERC-4337 paymaster, and read the API3 SEI/USD price feed.', | ||
| 'The recipes rely on this public endpoint behavior. Watch live events over WebSocket (wss://evm-ws.sei-apis.com, wss://evm-ws-testnet.sei-apis.com), because HTTP polling watchers can miss or repeat events. The WebSocket endpoints do not serve eth_getLogs or filters. Fetch past events over HTTP with eth_getLogs, which covers at most 2,000 blocks per request.', |
There was a problem hiding this comment.
[nit] This overview says the WebSocket endpoints don't serve eth_getLogs or filters. The PR description only shows that eth_getLogs isn't served over WebSocket; the filter problem it describes is HTTP eth_uninstallFilter returning 403. Unless you've confirmed that WebSocket filter methods are also unavailable, drop "or filters" so the llms.txt text doesn't state something unverified.
What is the purpose of the change?
This adds a Cookbook tab. The tab holds short, task-focused recipes for developers who want working code for one job. The code is in the library that they already use: viem, ethers, or web3.py. It closes the cookbook gap from the docs review against Solana's docs.
It also fixes existing pages whose examples do not work against the public endpoints or with current tooling. I found those while I tested the new recipes, and review found a few more.
1fca868e4f950fb352221forge create --broadcastin four pages7baa037f565cc3.mtsfiles (review feedback)a519486bee848f.env9275f0e1bda1f91c6e52a42801c6PYTH_API_KEY(review feedback)5f417aa21aec1c--constructor-argslast (review feedback)5a18ce3webSocketwith the other viem helpers (review feedback)28a37700d78c937baa037)Describe the changes to the documentation
Cookbook
/cookbookand/evm/evm-parity/examplesredirect to the new overview at/evm/cookbook.evm/cookbook/: read a balance, send SEI, deploy an ERC-20 (Foundry, Hardhat, or Remix), listen to events, sponsor gas with Pimlico, and read a price feed. Two of them have aRunSnippet.STYLE_GUIDE.mddescribes the Cookbook conventions, andscripts/generate-llms.mjsgets a Cookbook section for the weekly llms.txt run.The price-feed recipe uses the API3 SEI/USD push feed (
0x09c6e594DE2EB633902f00B87A43b27F80a31a60), which you can read with one free view call. Chainlink on Sei is Data Streams (credentials from Chainlink), and Pyth needs a signed update from its API before a read is current.Event watching and log queries
Tests against the public endpoints showed that HTTP watchers built on filters miss or repeat events. In one 40-second window, viem reported 2 of 12 transfers, and ethers reported 14. On Sei Mainnet,
eth_uninstallFilterreturns 403, which crashes ethers when a listener stops. The WebSocket endpoints serveeth_subscribebut noteth_getLogs.eth_getLogscaps a request at 2,000 blocks, so the ERC-20 history query from block 0 always failed.The ERC-20, ERC-721, ERC-1155, and ethers quickstart pages now watch events over WebSocket. The ERC-20 history query reads the latest 2,000 blocks. The ethers quickstart listener declares the
Transferevent that it listens for. Each watcher shows its cleanup as a comment. The cleanup removes the listener and closes the WebSocket provider. A copied snippet therefore listens until you stop it.Foundry
Current Foundry only simulates
forge createwithout--broadcast, so the documented commands deployed nothing. The examples inevm-foundry.mdx,deploy-verify.mdx,evm-verify-contracts.mdx, andmigrate-from-solana.mdxnow pass the flag, before--constructor-args(which takes every value after it). The Foundry guide also passed ABI-encoded constructor arguments, whichforge createrejects. It now passes plain values.Review follow-ups
.mtsfiles. In a new npm project,tsxcompiles a plain.tsfile as CommonJS, and top-levelawaitfails withTop-level await is currently not supported with the "cjs" output format. The recipes and the viem and ethers quickstarts now tell readers to save TypeScript examples as.mtsfiles.forge remappings > remappings.txt, like the Foundry guide.Web3.to_checksum_address.Pimlico guide
The guide tells you to put
PIMLICO_API_KEYin.env. Its script then wrote the generatedPRIVATE_KEYover the whole file, so the API key disappeared after the first run. It now appends the key. I also removed a top-levelreturnfrom one snippet.Pyth guide
Since Pyth's Core upgrade on August 26, 2026, Hermes rejects requests without an API key. Pyth's address list also shows
0x16392B49EA47D4A21bb17F69aA9E7aD570284838for Sei Mainnet instead of0x2880aB155794e7179c9eE2e38200202908C17B43, which Pyth still lists for Sei Testnet. The guide now:https://pyth.dourolabs.app/hermes)getLatestSeiPrice()revertsNotes
eth_getLogsfor the same blocks. Python ran on web3.py 7.7, 7.16, and 8.0, and all TypeScript passes a strict type check..mtsfiles in a fresh npm project without"type": "module"(the live watcher caught 36 of 36 transfers). The web3.py read-back worked with a lowercase USDC address, which raisedInvalidAddresswithout the checksum call. With the cleanup lines run after a pause, the ethers watchers exit on their own afterdestroy(). The Pimlico snippet keptPIMLICO_API_KEYin.env. The repo checks andmint broken-linkspass.llms.txtandllms-full.txtinclude the Cookbook.