.setGateway() (and optionally .setRpc()) over to a Portal data source. It works whether or not you have already migrated to a Portal for historical data.
If you self-host and hit a gateway API-key error after May 19, 2026 12:00 UTC, note that the Solana gateway is itself being retired — it shrinks to the last 30 days of data on June 1, 2026 and is scheduled for full removal later this year. Adding a key only buys a little time; Portal is the durable path, so migrate now.
Prerequisites
- An existing squid based on
@subsquid/solana-stream: 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
Jump to: Reference template · Common errors1
Stop using the RPC client
Remove the
SolanaRpcClient import and the .setRpc({...}) call from your data source. Your project still compiles on your current @subsquid/solana-stream version after this edit; once you bump to ^1.x.x in the next step (where SolanaRpcClient and .setRpc() disappear), you avoid a broken intermediate state.2
Upgrade SDK packages
From your squid’s folder, upgrade every This should bump
@subsquid/* package to its latest release:@subsquid/solana-stream to a 1.x.x version.Then install:- NPM
- Yarn
- PNPM
3
Switch the data source to Portal
Replace the gateway URL with the Portal URL:(The
SolanaRpcClient import and .setRpc({...}) call are already gone from 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.
If your project re-exports Use the solana-example template as a reference if your squid has unusual aliases.
Fields/Block/Transaction/Context aliases that handlers consume, re-derive them against the new packages:If your squid is not using real time data (.setGateway without .setRpcEndpoint)
If your squid is not using real time data (.setGateway without .setRpcEndpoint)
Previously, using a gateway data source only (without RPC) enabled the regime when the squid only consumes and processes finalized data. This introduces a significant delay between the data appearing on chain and in the indexer, but allows you to forward data to append-only destinations, which is not possible with real time data. To enable this regime in Portal-powered squids, explicitly disable hot blocks support in the target database, e.g.A data source streaming into such a target will automatically switch to ingesting from
/finalized-stream instead of /stream.4
Keep block ranges in slots
DataSourceBuilder.setBlockRange() uses the same slot-number coordinate returned
as block.header.number. Keep existing slot ranges unchanged. There is no separate
contiguous Portal-height coordinate for this API.5
Replace `block.header.slot` reads
If your handler code reads the
slot field of a block header, rename it to .number:6
Expand the field selection
transaction.accountKeys was never in the old SDK’s defaults either — add it if you read the fee payer via tx.accountKeys[0].Full set of fields the old `@subsquid/solana-stream` used to merge in for free
Full set of fields the old `@subsquid/solana-stream` used to merge in for free
block.header.number is always available and contains the slot. The current Portal source does not return height, even though @subsquid/[email protected] accepts it in the TypeScript field selection. Migrate height reads to number.instruction/log/balance/reward entries the same way. TypeScript errors at compile time will point you at any field still missing from the selection.7
Smoke-test locally
Build and run the squid locally before deploying. If the first batch lands without TypeScript or missing-field runtime errors, you’re ready to deploy:
8
Re-sync the squid
We highly recommend that all squids migrated to Portal are re-synced. This allows you to make sure that everything works as expected for the whole length of the chain and catch any bugs early.If your squid is deployed to the Cloud, follow the zero-downtime update procedure:
- 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 (Solana)
Common errors (Solana)
Reference template (Solana)
If you want to diff against a known-good shape, this is the canonical post-migration template:solana-example@master
Portal-based Solana indexer with the field selection, hot-block support, and types this guide produces
Next steps (Solana)
Portal Solana API
Complete Portal API documentation for Solana
Solana examples
More examples of Portal API usage on Solana