Polkadot-API
Introduction
Section titled “Introduction”Polkadot-API (PAPI) is a set of libraries built to be modular, composable, and grounded in a “light-client first” approach. Its primary aim is to equip dApp developers with an extensive toolkit for building fully decentralized applications.
PAPI is optimized for light-client functionality, using the new JSON-RPC spec to support decentralized interactions fully. It provides strong TypeScript support with types and documentation generated directly from on-chain metadata, and it offers seamless access to storage reads, constants, transactions, events, and runtime calls. Developers can connect to multiple chains simultaneously and prepare for runtime updates through multi-descriptor generation and compatibility checks. PAPI is lightweight and performant, leveraging native BigInt, dynamic imports, and modular subpaths to avoid bundling unnecessary assets. It supports promise-based and observable-based APIs, integrates easily with Polkadot.js extensions, and offers signing options through browser extensions or private keys.
Get Started
Section titled “Get Started”API Instantiation
Section titled “API Instantiation”To instantiate the API, you can install the package by using the following command:
npm i polkadot-api@3.3.0pnpm add polkadot-api@3.3.0yarn add polkadot-api@3.3.0Then, obtain the latest metadata from the target chain and generate the necessary types:
# Add the target chainnpx papi add dot -n polkadotThe papi add command initializes the library by generating the corresponding types needed for the chain used. It assigns the chain a custom name and specifies downloading metadata from the Polkadot chain. You can replace dot with the name you prefer or with another chain if you want to add a different one. Once the latest metadata is downloaded, generate the required types:
# Generate the necessary typesnpx papiYou can now set up a PolkadotClient with your chosen provider to begin interacting with the API. Choose from Smoldot via WebWorker, Node.js, or direct usage, or connect through the WSS provider. The examples below show how to configure each option for your setup.
// `dot` is the identifier assigned during `npx papi add`import { dot } from '@polkadot-api/descriptors';import { createClient } from 'polkadot-api';import { getSmProvider } from 'polkadot-api/sm-provider';import { chainSpec } from 'polkadot-api/chains/polkadot';import { startFromWorker } from 'polkadot-api/smoldot/from-worker';import SmWorker from 'polkadot-api/smoldot/worker?worker';
const worker = new SmWorker();const smoldot = startFromWorker(worker);
// Establish connection to the Polkadot relay chainconst client = createClient( getSmProvider(() => smoldot.addChain({ chainSpec })),);
// To interact with the chain, obtain the `TypedApi`, which provides// the necessary types for every API call on this chainconst dotApi = client.getTypedApi(dot);// `dot` is the alias assigned during `npx papi add`import { dot } from '@polkadot-api/descriptors';import { createClient } from 'polkadot-api';import { getSmProvider } from 'polkadot-api/sm-provider';import { chainSpec } from 'polkadot-api/chains/polkadot';import { startFromWorker } from 'polkadot-api/smoldot/from-node-worker';import { fileURLToPath } from 'url';import { Worker } from 'worker_threads';
// Get the path for the worker file in ESMconst workerPath = fileURLToPath( import.meta.resolve('polkadot-api/smoldot/node-worker'),);
const worker = new Worker(workerPath);const smoldot = startFromWorker(worker);
// Set up a client to connect to the Polkadot relay chainconst client = createClient( getSmProvider(() => smoldot.addChain({ chainSpec })),);
// To interact with the chain's API, use `TypedApi` for access to// all the necessary types and calls associated with this chainconst dotApi = client.getTypedApi(dot);// `dot` is the alias assigned when running `npx papi add`import { dot } from '@polkadot-api/descriptors';import { createClient } from 'polkadot-api';import { getSmProvider } from 'polkadot-api/sm-provider';import { chainSpec } from 'polkadot-api/chains/polkadot';import { start } from 'polkadot-api/smoldot';
// Initialize Smoldot clientconst smoldot = start();
// Set up a client to connect to the Polkadot relay chainconst client = createClient( getSmProvider(() => smoldot.addChain({ chainSpec })),);
// Access the `TypedApi` to interact with all available chain calls and typesconst dotApi = client.getTypedApi(dot);// `dot` is the identifier assigned when executing `npx papi add`import { dot } from '@polkadot-api/descriptors';import { createClient } from 'polkadot-api';// Use this import for Node.js environmentsimport { getWsProvider } from 'polkadot-api/ws';
// Establish a connection to the Polkadot relay chainconst client = createClient(getWsProvider('wss://dot-rpc.stakeworld.io'));
// To interact with the chain, obtain the `TypedApi`, which provides// the types for all available calls in that chainconst dotApi = client.getTypedApi(dot);Now that you have set up the client, you can interact with the chain by reading and sending transactions.
Reading Chain Data
Section titled “Reading Chain Data”The TypedApi provides a streamlined way to read blockchain data through three main interfaces, each designed for specific data access patterns:
-
Constants: Access fixed values or configurations on the blockchain using the
constantsinterface.const version = await typedApi.constants.System.Version(); -
Storage queries: Retrieve stored values by querying the blockchain’s storage via the
queryinterface.const asset = await api.query.ForeignAssets.Asset.getValue(token.location,{ at: 'best' },); -
Runtime APIs: Interact directly with runtime APIs using the
apisinterface.const metadata = await typedApi.apis.Metadata.metadata();
To learn more about the different actions you can perform with the TypedApi, refer to the TypedApi reference.
Sending Transactions
Section titled “Sending Transactions”In PAPI, the TypedApi provides the tx and txFromCallData methods to send transactions.
-
The
txmethod allows you to directly send a transaction with the specified parameters by using thetypedApi.tx.Pallet.Callpattern:const tx: Transaction = typedApi.tx.Pallet.Call({arg1, arg2, arg3});For instance, to execute the
balances.transferKeepAlivecall, you can use the following snippet:import { MultiAddress } from '@polkadot-api/descriptors';const tx: Transaction = typedApi.tx.Balances.transfer_keep_alive({dest: MultiAddress.Id('INSERT_DESTINATION_ADDRESS'),value: BigInt(INSERT_VALUE),});Ensure you replace
INSERT_DESTINATION_ADDRESSandINSERT_VALUEwith the actual destination address and value, respectively. -
The
txFromCallDatamethod allows you to send a transaction using the call data. This option accepts binary call data and constructs the transaction from it. It validates the input upon creation and will throw an error if invalid data is provided. The pattern is as follows:const callData = Binary.fromHex('0x...');const tx: Transaction = typedApi.txFromCallData(callData);For instance, to execute a transaction using the call data, you can use the following snippet:
const callData = Binary.fromHex('0x00002470617065726d6f6f6e');const tx: Transaction = typedApi.txFromCallData(callData);
For more information about sending transactions, refer to the Transactions page.
Where to Go Next
Section titled “Where to Go Next”For an in-depth guide on how to use PAPI, refer to the official PAPI documentation.