.setGateway() (and optionally .setRpc()) over to Portal data sources. It works whether or not you have already migrated to a Portal for historical data.
Prerequisites
- An existing squid based on
@subsquid/evm-processoron EVM: will typically use.setGateway()and.setRpcEndpoint(), in rare cases without either or with a.setPortal()- all of these cases are covered@subsquid/solana-streamon Solana: using.setGateway()and/or.setRpc()
- Node.js 22+ and npm installed
- An SQD Portal URL for your dataset:
- For public Portal:
https://portal.sqd.dev/datasets/<slug>(find your slug on the networks page) - For a private Portal: get an URL from SQD or supply your own if self-hosting
- For public Portal:
Migration steps
Pick your chain.- EVM
- Solana
Install new packages
@subsquid/archive-registry and lookupArchive are deprecated. Remove the package and all lookupArchive(...) calls (we cover the data source replacement in Step 3).decodeHex or assertNotNull from @subsquid/evm-processor, move those imports too. They are exported only by their utility packages now (both pulled in transitively by @subsquid/evm-stream and @subsquid/batch-processor, so no extra install needed):Switch the processor to a Portal data source
src/processor.ts or src/main.ts, swap the processor imports and initialization:If your squid still uses the older `.setDataSource({archive, chain})` shape
If your squid still uses the older `.setDataSource({archive, chain})` shape
setGateway API:.setPortal(...) and drop the lookupArchive import (@subsquid/archive-registry is gone, see Step 1).Have data & context type aliases exported alongside the processor object? Rewrite them here.
Have data & context type aliases exported alongside the processor object? Rewrite them here.
@subsquid/evm-stream exports FieldSelection; @subsquid/evm-objects exports the augmented block data types (BlockHeader, Block — previously BlockData — Log, Transaction, Trace, StateDiff). Three changes to be aware of:BlockData<F>is renamed toBlock<F>. The single-block type previously calledBlock(just the header) is nowBlockHeader<F>.- The upstream
DataHandlerContextlives in@subsquid/batch-processor. Its generic arguments are flipped (DataHandlerContext<Block, Store>, not<Store, Fields>) and it has only{store, blocks, isHead}. Addlog(and_chainif you make RPC calls) yourself. - The
Fieldstype alias should be derived from the samefieldsconstant you pass to.setFields().
If your squid uses `.setPortal()` alongside `.setRpcEndpoint()` (Portal beta participants)
If your squid uses `.setPortal()` alongside `.setRpcEndpoint()` (Portal beta participants)
.setPortal call in the same way as you would a .setGateway call - remove it alongside the processor initialization and set up a new one.If your squid is not using real time data (.setGateway without .setRpcEndpont)
If your squid is not using real time data (.setGateway without .setRpcEndpont)
/finalized-stream instead of /stream.Expand the field selection
transaction/trace/stateDiff entries as needed. TypeScript errors at compile time will point you at any field still missing.The top-level block.height and block.timestamp shortcuts are also gone. Read them from block.header.number and block.header.timestamp. block.header.height still exists but is @deprecated.@subsquid/[email protected] era, rename evmLog to log.Update the run function
processor.run() with the unified run function. Add the import, create a logger, and enrich the context with augmentBlock:Used `.setPrometheusPort()` / `.setPrometheusServer()`? Move them here.
Used `.setPrometheusPort()` / `.setPrometheusServer()`? Move them here.
PrometheusServer is now passed to run() via the prometheus option instead of being attached to the processor. Construct one and hand it over; the runner still attaches the built-in sqd_processor_* metrics and calls .serve() itself.setPort() overrides PROCESSOR_PROMETHEUS_PORT / PROMETHEUS_PORT. For custom metrics, register them on the server’s registry via addMetricsSink() so they share the /metrics endpoint with sqd_processor_* — see this branch for a worked example.Add an RPC client
RpcClient, and enrich the batch context with a _chain field:DataHandlerContext<Store> alias in src/processor.ts, extend it so _chain is part of the type your handlers see:Smoke-test locally
Re-sync the squid
- Deploy your squid into a new slot.
- Wait for it to sync, observing the improved data fetching.
- Assign your production tag to the new deployment to redirect the GraphQL requests there.
Common errors (EVM)
Common errors (EVM)
| Symptom | Root cause | Fix |
|---|---|---|
Property 'transactionHash' does not exist on type 'Log' (used log key) | Forgot to list transactionHash: true under .setFields().log | Add transactionHash: true (and any other fields you read) under .setFields().log |
Property 'height' does not exist on type 'BlockHeader' (or 'timestamp') | Top-level block.height/block.timestamp shortcuts removed | Use block.header.number / block.header.timestamp. block.header.height still works (deprecated) if .height is baked into entity columns and you want a literal rename. |
'apiKey' does not exist in type 'GatewaySettings' | You’re on evm-processor < 1.30.0 and tried to add apiKey before bumping the package. | Either (a) migrate to evm-stream / .setPortal('...'): Portal needs no API key today. (b) Bump @subsquid/evm-processor to ^1.30.0 to get the apiKey field on GatewaySettings. |
Module '"@subsquid/evm-processor"' has no exported member 'decodeHex' | decodeHex is only exported by @subsquid/util-internal-hex now | See Step 1 Install new packages |
Module '"@subsquid/evm-processor"' has no exported member 'assertNotNull' | assertNotNull is only exported by @subsquid/util-internal now | Same step |
Module '"@subsquid/archive-registry"' has no exported member 'lookupArchive' (or Cannot find module) | Package removed entirely | Uninstall @subsquid/archive-registry and replace the whole data source block with .setPortal(...) |
Object literal may only specify known properties, and 'evmLog' does not exist | .setFields() key renamed in evm-processor@^1.21.0 | Rename evmLog to log in .setFields() (see Expand the field selection) |
Property 'transactionHash' does not exist on type 'Log' (used evmLog key) | evmLog key no longer projects transactionHash onto Log | Rename evmLog to log in .setFields() |
Reference templates (EVM)
If you want to diff against a known-good shape, these are the canonical post-migration templates:squid-evm-rt-template@with-logger
squid-evm-rt-template@with-rpc-client
RpcClient wired into the context for state queries