Polkadot-API¶
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¶
API Instantiation¶
To instantiate the API, you can install the package by using the following command:
Then, obtain the latest metadata from the target chain and generate the necessary types:
The 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:
You 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);
const chain = await smoldot.addChain({ chainSpec });
// Establish connection to the Polkadot relay chain
const client = createClient(getSmProvider(chain));
// To interact with the chain, obtain the `TypedApi`, which provides
// the necessary types for every API call on this chain
const 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 ESM
const workerPath = fileURLToPath(
import.meta.resolve('polkadot-api/smoldot/node-worker'),
);
const worker = new Worker(workerPath);
const smoldot = startFromWorker(worker);
const chain = await smoldot.addChain({ chainSpec });
// Set up a client to connect to the Polkadot relay chain
const client = createClient(getSmProvider(chain));
// To interact with the chain's API, use `TypedApi` for access to
// all the necessary types and calls associated with this chain
const 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 client
const smoldot = start();
const chain = await smoldot.addChain({ chainSpec });
// Set up a client to connect to the Polkadot relay chain
const client = createClient(getSmProvider(chain));
// Access the `TypedApi` to interact with all available chain calls and types
const 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 environments
import { getWsProvider } from 'polkadot-api/ws-provider/web';
import { withPolkadotSdkCompat } from 'polkadot-api/polkadot-sdk-compat';
// Establish a connection to the Polkadot relay chain
const client = createClient(
// The Polkadot SDK nodes may have compatibility issues; using this enhancer is recommended.
// Refer to the Requirements page for additional details
withPolkadotSdkCompat(getWsProvider('wss://dot-rpc.stakeworld.io')),
);
// To interact with the chain, obtain the `TypedApi`, which provides
// the types for all available calls in that chain
const 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¶
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
constants
interface: -
Storage queries - retrieve stored values by querying the blockchain’s storage via the
query
interface: -
Runtime APIs - interact directly with runtime APIs using the
apis
interface:
To learn more about the different actions you can perform with the TypedApi
, refer to the TypedApi reference.
Sending Transactions¶
In PAPI, the TypedApi
provides the tx
and txFromCallData
methods to send transactions.
-
The
tx
method allows you to directly send a transaction with the specified parameters by using thetypedApi.tx.Pallet.Call
pattern:For instance, to execute the
balances.transferKeepAlive
call, 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_ADDRESS
andINSERT_VALUE
with the actual destination address and value, respectively. -
The
txFromCallData
method 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:
For more information about sending transactions, refer to the Transactions page.
Where to Go Next¶
For an in-depth guide on how to use PAPI, refer to the official PAPI documentation.
| Created: October 18, 2024