Migrate to v5
Version 5 of Squid introduced many changes, and a good part of them are not retro-compatible, so some actions are required to update and make sure the project still runs as it's supposed to.

Package update

The first thing to do is remove old packages named hydra, since package names have changed and those are not used anymore, and install new ones.
Here is a list of commands to this:
1
npm uninstall @subsquid/hydra-common
2
npm uninstall @subsquid/hydra-processor
3
npm uninstall @subsquid/openreader
4
npm uninstall @subsquid/hydra-cli
5
npm uninstall @subsquid/hydra-typegen
6
npm uninstall typeorm
7
8
npm install dotenv
9
npm install @subsquid/[email protected]
10
npm install @subsquid/[email protected]
11
npm install @subsquid/[email protected]
12
npm install @subsquid/[email protected] --save-dev
13
npm install @subsquid/[email protected] --save-dev
14
npm install @subsquid/[email protected] --save-dev
Copied!
Note: these can be wrapped in a shell file and executed.

Scripts update

Because of package name changes, some scripts in package.json have changed as well. These can simply be replaced with new ones found here.
Be aware that custom scripts might need changing as well.

File structure updates

The overall file structure of the project has changed, although thankfully, this did not have any impacts on GraphQL schema and codegen parts.
The best thing to do in this case is to delete the src/generated folder and recreate the models with codegen. Then create and apply a database migration.
Here is a list of commands to accomplish this:
1
rm -rf src/generated/
2
npx sqd codegen
3
npm run build
4
npx sqd db create-migration
5
npx sqd db migrate
Copied!
Also, Dockerfile , docker-compose.yml, .env, files should be replaced with the ones from this repository.

Types update (optional but recommended)

Just as with the previous version, it is possible to circumvent the typegen feature and parse all received JSON documents manually.
However, the newest version brings massive upgrades to types. Now it can automatically create different types for the same event, depending on the spec version, preventing future crashes and bugs.
For this reason, it is recommended to replace the old types with new ones.
The process to generate types is explained in the dedicated tutorial and details about type bundles can be found in the Cheatsheet.

Mappings

One more thing to do is to update package paths and names in the codebase.
Furthermore, manifest.yml is no longer used. The typegen section contained in it has been transferred to the typegen.json file as mentioned in the previous section. The other part, referring to mappings, now uses the logic of the processor class.
Instead of specifying the necessary parameters in manifest.yml, you should define a processor object and set them there (for more information head to the conceptual guide on the subject). Here is an example, let's go through it:

Initialization

The parameter passed is a custom name
1
const processor = new SubstrateProcessor('kusama_balances')
Copied!

Setting the number of blocks per request to be processed

1
processor.setBatchSize(500)
Copied!

Setting Squid Archive and chain addresses:

1
processor.setDataSource({
2
archive: 'https://kusama.indexer.gc.subsquid.io/v4/graphql',
3
chain: 'wss://kusama-rpc.polkadot.io'
4
})
Copied!
Moreover, you can set demanded range of blocks with:
1
processor.setBlockRange({from: , to: })
Copied!

Add events and extrinsic handlers or pre/postBlock hooks, using:

1
processor.addEventHandler(eventName, fn)
2
processor.addExtrinsicHandler(extrinsicName, fn)
Copied!
The function fn can be one of the existing handlers. For example:
1
processor.addEventHandler('balances.Transfer', ctx => balancesTransfer(ctx));
Copied!
Where balancesTransfer(ctx) is the previously existing handler, as defined:
1
export async function balancesTransfer({
2
store,
3
event,
4
block,
5
extrinsic,
6
}: EventContext & StoreContext): Promise<void> {
7
// your code here
8
}
Copied!
However, it’s recommended to modify the event arguments handling inside the function according to new type processing. From the example linked above, it should go from this:
1
const [from, to, value] = new Balances.TransferEvent(event).params;
Copied!
To this:
1
function getTransferEvent(ctx: EventHandlerContext): TransferEvent {
2
let event = new BalancesTransferEvent(ctx)
3
if (event.isV1020) {
4
let [from, to, amount] = event.asV1020
5
return {from, to, amount}
6
} else if (event.isV1050) {
7
let [from, to, amount] = event.asV1050
8
return {from, to, amount}
9
} else {
10
return event.asLatest
11
}
12
}
13
14
// other code here
15
16
const {from, to, amount} = getTransferEvent(ctx);
Copied!
Where BalancesTransferEvent and TransferEvent are, respectively, a class and an interface generated by typegen.