Dedot¶
Introduction¶
Dedot is a next-generation JavaScript client for Polkadot and Polkadot SDK-based blockchains. Designed to elevate the dApp development experience, Dedot is built and optimized to be lightweight and tree-shakable, offering precise types and APIs suggestions for individual Polkadot SDK-based blockchains and ink! smart contracts.
Key Features¶
-
Lightweight and tree-shakable – no more bn.js or WebAssembly blobs, optimized for dapps bundle size
-
Fully typed API – comprehensive TypeScript support for seamless on-chain interaction and ink! smart contract integration
-
Multi-version JSON-RPC support – compatible with both legacy and new JSON-RPC APIs for broad ecosystem interoperability
-
Light client support – designed to work with light clients such as Smoldot
-
Native TypeScript for scale codec – implements scale codec parsing directly in TypeScript without relying on custom wrappers
-
Wallet integration – works out-of-the-box with @polkadot/extension-based wallets
-
Familiar API design – similar API style to Polkadot.js for easy and fast migration
Installation¶
To add Dedot to your project, use the following command:
To enable auto-completion/IntelliSense for individual chains, install the @dedot/chaintypes
package as a development dependency:
Get Started¶
Initialize a Client Instance¶
To connect to and interact with different networks, Dedot provides two client options depending on your needs:
DedotClient
- interacts with chains via the new JSON-RPC APIsLegacyClient
- interacts with chains via the legacy JSON-RPC APIs
Use the following snippets to connect to Polkadot using DedotClient
:
import { DedotClient, SmoldotProvider } from 'dedot';
import type { PolkadotApi } from '@dedot/chaintypes';
import * as smoldot from 'smoldot';
// import `polkadot` chain spec to connect to Polkadot
import { polkadot } from '@substrate/connect-known-chains';
// Start smoldot instance & initialize a chain
const client = smoldot.start();
const chain = await client.addChain({ chainSpec: polkadot });
// Initialize providers & clients
const provider = new SmoldotProvider(chain);
const client = await DedotClient.new<PolkadotApi>(provider);
If the node doesn't support new JSON-RPC APIs yet, you can connect to the network using the LegacyClient
, which is built on top of the legacy JSON-RPC APIs.
import { LegacyClient, WsProvider } from 'dedot';
import type { PolkadotApi } from '@dedot/chaintypes';
const provider = new WsProvider('wss://rpc.polkadot.io');
const client = await LegacyClient.new<PolkadotApi>(provider);
Enable Type and API Suggestions¶
It is recommended to specify the ChainApi
interface (e.g., PolkadotApi
in the example in the previous section) of the chain you want to interact with. This enables type and API suggestions/autocompletion for that particular chain (via IntelliSense). If you don't specify a ChainApi
interface, a default SubstrateApi
interface will be used.
import { DedotClient, WsProvider } from 'dedot';
import type { PolkadotApi, KusamaApi } from '@dedot/chaintypes';
const polkadotClient = await DedotClient.new<PolkadotApi>(
new WsProvider('wss://rpc.polkadot.io')
);
const kusamaClient = await DedotClient.new<KusamaApi>(
new WsProvider('wss://kusama-rpc.polkadot.io')
);
const genericClient = await DedotClient.new(
new WsProvider('ws://localhost:9944')
);
If you don't find the ChainApi
for the network you're working with in the list, you can generate the ChainApi
(types and APIs) using the built-in dedot
cli.
# Generate ChainApi interface for Polkadot network via rpc endpoint: wss://rpc.polkadot.io
npx dedot chaintypes -w wss://rpc.polkadot.io
Or open a pull request to add your favorite network to the @dedot/chaintypes
repo.
Read On-Chain Data¶
Dedot provides several ways to read data from the chain:
-
Access runtime constants - use the syntax
client.consts.<pallet>.<constantName>
to inspect runtime constants (parameter types): -
Storage queries - use the syntax
client.query.<pallet>.<storgeEntry>
to query on-chain storage: -
Subscribe to storage changes:
-
Call Runtime APIs - use the syntax
client.call.<runtimeApi>.<methodName>
to execute Runtime APIs: -
Watch on-chain events - use the syntax
client.events.<pallet>.<eventName>
to access pallet events:
Sign and Send Transactions¶
Sign the transaction using IKeyringPair
from Keyring (@polkadot/keyring
) and send the transaction.
import { cryptoWaitReady } from '@polkadot/util-crypto';
import { Keyring } from '@polkadot/keyring';
// Setup keyring
await cryptoWaitReady();
const keyring = new Keyring({ type: 'sr25519' });
const alice = keyring.addFromUri('//Alice');
// Send transaction
const unsub = await client.tx.balances
.transferKeepAlive('INSERT_DEST_ADDRESS', 2_000_000_000_000n)
.signAndSend(alice, async ({ status }) => {
console.log('Transaction status', status.type);
if (status.type === 'BestChainBlockIncluded') {
console.log(`Transaction is included in best block`);
}
if (status.type === 'Finalized') {
console.log(
`Transaction completed at block hash ${status.value.blockHash}`
);
await unsub();
}
});
You can also use Signer
from wallet extensions:
const injected = await window.injectedWeb3['polkadot-js'].enable('My dApp');
const account = (await injected.accounts.get())[0];
const signer = injected.signer;
const unsub = await client.tx.balances
.transferKeepAlive('INSERT_DEST_ADDRESS', 2_000_000_000_000n)
.signAndSend(account.address, { signer }, async ({ status }) => {
console.log('Transaction status', status.type);
if (status.type === 'BestChainBlockIncluded') {
console.log(`Transaction is included in best block`);
}
if (status.type === 'Finalized') {
console.log(
`Transaction completed at block hash ${status.value.blockHash}`
);
await unsub();
}
});
Where to Go Next¶
For more detailed information about Dedot, check the official documentation.
| Created: May 12, 2025