Skip to content

Upgrading to v5

This release completes the migration of all @dfinity/* packages into @icp-sdk/core, upgrades the IC API endpoints to their latest versions, and introduces several new features for subnet and certificate management. This guide will help you upgrade your project from v4 to v5.

  • New API versions: Agent now uses the latest IC API endpoints: /api/v4 for calls and /api/v3 for queries/read_state.
  • Local replica upgrade required: Use dfx >=v0.30.1 or PocketIC >=v11.0.0.
  • Peer dependencies removed: @dfinity/* packages are no longer peer dependencies. Remove them before upgrading.

Before upgrading to v5, you must remove the @dfinity/{agent,candid,identity,identity-secp256k1,principal} (peer) dependencies from your project. These packages are now fully integrated into @icp-sdk/core and are no longer required as separate dependencies.

Terminal window
npm remove @dfinity/{agent,candid,identity,identity-secp256k1,principal}

Then, upgrade @icp-sdk/core to the latest version:

Terminal window
npm install @icp-sdk/core@latest

NOTE: If your project is using any package from the old ic-js suite (see Legacy single-entry packages), you should migrate to the new @icp-sdk/canisters package, which also doesn’t depend on the @dfinity/{agent,candid,identity,identity-secp256k1,principal} packages.

In v4, @icp-sdk/core re-exported the @dfinity/* packages as peer dependencies. In v5, the source code of all core packages has been moved directly into @icp-sdk/core. This means:

  • You no longer need to install @dfinity/agent, @dfinity/candid, @dfinity/identity, @dfinity/identity-secp256k1, or @dfinity/principal as separate packages.

  • All imports should use @icp-sdk/core/* submodules:

    Old ImportNew Import
    @dfinity/agent@icp-sdk/core/agent
    @dfinity/candid@icp-sdk/core/candid
    @dfinity/identity@icp-sdk/core/identity
    @dfinity/identity-secp256k1@icp-sdk/core/identity/secp256k1
    @dfinity/principal@icp-sdk/core/principal

    E.g.

    - import { HttpAgent } from '@dfinity/agent';
    + import { HttpAgent } from '@icp-sdk/core/agent';

    See more details in the v4 upgrading guide.

The agent now uses the latest IC API endpoints:

  • Call requests now use /api/v4 instead of /api/v3
  • Query and read_state requests now use /api/v3 instead of /api/v2

If you were using internal types related to these API versions, you’ll need to update them:

Old NameNew Name
v3ResponseBodyv4ResponseBody
isV3ResponseBodyisV4ResponseBody
HttpV3ApiNotSupportedErrorCodeHttpV4ApiNotSupportedErrorCode

If you’re developing locally with dfx, make sure you upgrade to v0.30.1 or later.

If you’re using PocketIC for testing, upgrade to v11.0.0 or later.

If you’re using @dfinity/pic-js for testing, upgrade to v0.17.0 or later.

Certificate Verification: canisterId Replaced with principal

Section titled “Certificate Verification: canisterId Replaced with principal”

The canisterId option in Certificate.create has been replaced with a more generic principal option that supports both subnet IDs and canister IDs for certificate verification.

Before:

import { Certificate } from '@icp-sdk/core/agent';
const canisterId = Principal.fromText('uqqxf-5h777-77774-qaaaa-cai');
const certificate = await Certificate.create({
certificate: certBytes,
rootKey: agent.rootKey,
canisterId,
});

After:

import { Certificate } from '@icp-sdk/core/agent';
const canisterId = Principal.fromText('uqqxf-5h777-77774-qaaaa-cai');
const certificate = await Certificate.create({
certificate: certBytes,
principal: { canisterId },
rootKey: agent.rootKey,
});
// or
const subnetId = Principal.fromText('jtdsg-3h6gi-hs7o5-z2soi-43w3z-soyl3-ajnp3-ekni5-sw553-5kw67-nqe');
const certificate = await Certificate.create({
certificate: certBytes,
principal: { subnetId },
rootKey: agent.rootKey,
});

See more details in the CreateCertificateOptions API docs.

New methods have been added to HttpAgent for interacting with subnet state:

import { HttpAgent } from '@icp-sdk/core/agent';
const agent = await HttpAgent.create();
// Get the subnet ID for a canister
const subnetId = await agent.getSubnetIdFromCanister(canisterId);
// Read subnet state directly
const subnetState = await agent.readSubnetState(subnetId, paths);
// Sync time with a specific subnet
await agent.syncTimeWithSubnet(subnetId);

API docs:

New utility functions for looking up canister ranges from certificate trees:

import {
lookupCanisterRanges,
decodeCanisterRanges,
} from '@icp-sdk/core/agent';
const canisterId = Principal.fromText('uqqxf-5h777-77774-qaaaa-cai');
const subnetId = Principal.fromText('jtdsg-3h6gi-hs7o5-z2soi-43w3z-soyl3-ajnp3-ekni5-sw553-5kw67-nqe');
const certificate = await Certificate.create({
certificate: certBytes,
principal: { canisterId },
rootKey: agent.rootKey,
});
const canisterRanges = lookupCanisterRanges({ subnetId, tree: certificate.tree, canisterId });
const ranges = decodeCanisterRanges(canisterRanges);
console.log(ranges);

API docs:

A new SubnetStatus namespace has been introduced to request subnet information directly from the IC public API:

import { SubnetStatus } from '@icp-sdk/core/agent';
const subnetId = Principal.fromText('jtdsg-3h6gi-hs7o5-z2soi-43w3z-soyl3-ajnp3-ekni5-sw553-5kw67-nqe');
const status = await SubnetStatus.request({
subnetId,
paths: ['time', 'nodeKeys'],
agent,
});
const time = status.get('time');
const nodeKeys = status.get('nodeKeys');
console.log(time);
console.log(nodeKeys);
  • getSubnetIdFromCertificate: Read the subnet ID from a certificate tree (API docs)
  • IC_STATE_ROOT_DOMAIN_SEPARATOR: Exported constant for certificate verification (API docs)

The @dfinity/auth-client package has been deprecated. Please migrate to @icp-sdk/auth.

The @dfinity/assets package has been deprecated. Its functionality is now part of @icp-sdk/canisters.

This release includes minor security improvements to how query and read_state responses are validated, strengthening certificate verification and query/read_state signature checks.


For a complete list of all changes, fixes, and improvements in this release, please refer to the CHANGELOG.