@polkadot-community-foundation/product-sdk-descriptors
@parity/product-sdk-descriptors
PAPI-generated chain descriptors for the Polkadot ecosystem. These provide fully typed APIs for interacting with specific chains.
Supported Chains
| Chain | Import Path | Network |
|---|---|---|
| Polkadot Asset Hub | @parity/product-sdk-descriptors/polkadot-asset-hub |
Production |
| Kusama Asset Hub | @parity/product-sdk-descriptors/kusama-asset-hub |
Production |
| Paseo Asset Hub | @parity/product-sdk-descriptors/paseo-asset-hub |
Testnet |
| Paseo Bulletin | @parity/product-sdk-descriptors/paseo-bulletin |
Testnet |
| Paseo Individuality | @parity/product-sdk-descriptors/paseo-individuality |
Testnet |
| Devnet Asset Hub | @parity/product-sdk-descriptors/devnet-asset-hub |
Paseo testnet (products devnet) |
| Devnet Bulletin | @parity/product-sdk-descriptors/devnet-bulletin |
Paseo testnet (products devnet) |
| Devnet Individuality | @parity/product-sdk-descriptors/devnet-individuality |
Paseo testnet (products devnet) |
Which network does each descriptor target?
paseo-*targets Paseo Next v2 (*-next-*.polkadot.iochain instances), not the long-lived public Paseo testnet. This was a deliberate migration when Paseo Next v1 shut down (seepackages/chain-client/CHANGELOG.md, the 1cc3790 entry) — per the Paseo team, Next v2 is the successor instance, so thepaseoname followed it.devnet-*targets the public Paseo testnet system chains (Asset Hub 1000, People 1004, Bulletin 1010) — the community-run "products devnet" operated by the Polkadot Community Foundation.
The wsUrl in each chain's .papi/polkadot-api.json is used only at descriptor
generation time (fetching metadata, pinning genesis/codeHash). At runtime the
SDK never dials these URLs: all connections route through the host container, which
selects the RPC endpoint for a given genesis hash. There is no standalone (non-host)
transport path in the SDK.
Usage
import { polkadot_asset_hub } from "@parity/product-sdk-descriptors/polkadot-asset-hub";
import { createClient } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
// Create a typed client for Polkadot Asset Hub
const client = createClient(
getWsProvider("wss://polkadot-asset-hub-rpc.polkadot.io")
);
const api = client.getTypedApi(polkadot_asset_hub);
// Now you have full type safety for all chain operations
const balance = await api.query.System.Account.getValue(address);
Regenerating Descriptors
To fetch the latest metadata from live chains and regenerate descriptors:
pnpm generate
To compile the generated TypeScript:
pnpm build
Adding a New Chain
Create a new directory under
chains/:mkdir -p chains/new-chain/.papiCreate the PAPI config file
chains/new-chain/.papi/polkadot-api.json:{ "version": 0, "descriptorPath": "generated", "entries": { "new_chain": { "wsUrl": "wss://new-chain-rpc.example.com", "metadata": "../../.papi/metadata/new_chain.scale" } } }Create
chains/new-chain/tsconfig.json(copy from an existing chain)Add the export to the main
package.json:"./new-chain": { "types": "./chains/new-chain/generated/new_chain.d.ts", "default": "./chains/new-chain/generated/new_chain.js" }Run
pnpm generateto fetch metadata and generate descriptors
Detecting Drift
PAPI's bundled type bindings are a frozen snapshot at the moment pnpm generate last ran. When a chain runtime upgrades, the bundled descriptors go stale — PAPI then either errors with Incompatible runtime entry RuntimeCall(...) or silently mis-decodes a subscription so it never emits an event.
The product-sdk: Descriptors drift workflow catches this before E2E does. It runs daily, connects to each chain's RPC via papi update --skip-codegen, and compares the live codeHash and genesis against what's pinned in chains/*/.papi/polkadot-api.json.
On drift it opens (or updates in place) a single tracking issue labeled descriptors-drift. On a fully-clean run it closes the issue.
What to do when the auto-issue fires
cd packages/descriptorspnpm generate— fetches fresh metadata from every chain RPC and rewriteschains/*/.papi/polkadot-api.json+ the.scalemetadata blobspnpm build— regenerates the TypeScript bindings underchains/*/generated/dist/git diff packages/descriptors/— verify nothing else changed unexpectedlypnpm changeset— add a@parity/product-sdk-descriptors: patchentry (orminorif the runtime added new pallets or changed decode shape)- Open a PR. Run
pnpm test:e2eagainst the regenerated bindings before merging — drift sometimes hides a real consumer-side break (e.g. a pallet rename)
The workflow will close the tracking issue automatically on the next scheduled run once every chain is clean.