Polkadot
UKey Wallet Polkadot Provider is used to connect Polkadot/Substrate accounts, sign transactions and messages in web applications, and send transactions with the Polkadot.js API. The page is accessible via window.$ukey.polkadot or the standard Polkadot.js extension API.
ℹ️
UKey Wallet implements the Polkadot.js extension interface and can be recognized by wallet tools and DApps compatible with Substrate extensions.
Fast Links
Find Provider
// UKey Wallet appears as a Polkadot.js extension
const provider = window.$ukey?.polkadot;
// Note: Or use the standard web3Enable API
import { web3Enable, web3Accounts } from "@polkadot/extension-dapp";
Get Going
Enable extension
// Note: Use UKey Wallet provider directly
const enabled = await provider.web3Enable("UKey Wallet Demo");
if (enabled) {
const accounts = await provider.web3Accounts();
console.log("Selected account:", accounts);
}
Extend the API using Polkadot.js (preferred)
import { web3Enable, web3Accounts } from "@polkadot/extension-dapp";
// Enable every extension, including UKey Wallet
const extensions = await web3Enable("UKey Wallet Demo");
if (extensions.length === 0) {
throw new Error("Extension not found");
}
// Retrieve all accounts
const allAccounts = await web3Accounts();
console.log("Selected account:", allAccounts);
Account management
Read wallet
const accounts = await provider.web3Accounts();
accounts.forEach((account) => {
console.log({
address: account.address, // Note: Substrate address
name: account.name, // Note: Account name
type: account.type, // one of 'sr25519' | 'ed25519' | 'ecdsa'
genesisHash: account.genesisHash, // Chain genesis hash when needed
});
});
Subscribe to account changes
const unsubscribe = provider.web3AccountsSubscribe((accounts) => {
console.log("Active account changed:", accounts);
});
// Remember to call unsubscribe() later when cleaning up
Signing
Signature transaction payload
Transaction payload is usually generated by the Polkadot.js API, and the wallet is responsible for displaying and signing:
import { web3FromAddress } from '@polkadot/extension-dapp'
// Retrieve the injector of a specific account
const injector = await web3FromAddress(accountAddress)
// Note: Signature payload
const payload = {
address: accountAddress,
blockHash: '0x...',
blockNumber: '0x...',
era: '0x...',
genesisHash: '0x...',
method: '0x...',
nonce: '0x...',
specVersion: '0x...',
tip: '0x...',
transactionVersion: '0x...',
signedExtensions: [...],
version: 4,
}
const callResult = await provider.web3SignPayload(payload)
console.log({
id: callResult.id,
signature: callResult.signature, // Note: Hexadecimal signature
})
Sign original message
const payload = {
address: accountAddress,
data: "0x48656c6c6f", // Note: Hexadecimal encoded message
type: "bytes",
};
const callResult = await provider.web3SignRaw(payload);
console.log({
id: callResult.id,
signature: callResult.signature,
});
Used with Polkadot.js API
set up
npm install @polkadot/api @polkadot/extension-dapp
Connect and sign transactions
import { ApiPromise, WsProvider } from "@polkadot/api";
import {
web3Enable,
web3FromAddress,
web3Accounts,
} from "@polkadot/extension-dapp";
// Note: Enable extension
await web3Enable("UKey Wallet Demo");
// Retrieve an account
const accounts = await web3Accounts();
const account = accounts[0];
// establish connectioned to chain
const wsProvider = new WsProvider("wss:/rpc.polkadot.io");
const api = await ApiPromise.create({ provider: wsProvider });
// Retrieve injector
const injector = await web3FromAddress(account.address);
// Note: Create and sign transactions
const tx = api.tx.balances.transfer(
recipientAddress,
1000000000000, // equals 1 DOT in planck units
);
// Note: Sign and send
const hash = await tx.signAndSend(account.address, { signer: injector.signer });
console.log("Tx hash:", hash.toHex());
Listen for transaction events
await tx.signAndSend(
account.address,
{ signer: injector.signer },
({ status, events }) => {
if (status.isInBlock) {
console.log("Included at block:", status.asInBlock.toHex());
}
if (status.isFinalized) {
console.log("Final confirmation at:", status.asFinalized.toHex());
events.forEach(({ event }) => {
if (api.events.system.ExtrinsicSuccess.is(event)) {
console.log("Transaction completed successfully");
}
if (api.events.system.ExtrinsicFailed.is(event)) {
console.log("Transaction execution failed");
}
});
}
},
);
RPC method
Send RPC request
const requestResult = await provider.web3RpcSend({
method: "chain_getHeader",
requestParams: [],
});
console.log("Latest block header data:", requestResult.result);
Subscribe to RPC events
const subscriptionId = await provider.web3RpcSubscribe(
{
method: "chain_subscribeNewHeads",
requestParams: [],
},
(response) => {
console.log("Observed new block:", response.result);
},
);
// Note: Unsubscribe later
await provider.web3RpcUnSubscribe();
List available providers
const providers = await provider.web3RpcListProviders();
console.log("Discovered providers:", providers);
API Notes
Methods
| Method | Details |
|---|---|
web3Enable(dappName) | Enable extensions for dApps |
web3Accounts(anyType?) | Get all accounts |
web3AccountsSubscribe(callback) | Subscribe to account changes |
web3SignPayload(payload) | Signature transaction payload |
web3SignRaw(payload) | Sign original message |
web3RpcSend(request) | Send RPC request |
web3RpcSubscribe(request, callback) | Subscribe to RPC events |
web3RpcUnSubscribe() | Cancel all subscriptions |
web3RpcListProviders() | List RPC providers |
web3RpcStartProvider(key) | Start a specific provider |
Types
interface InjectedAccount {
address: string; // Note: Substrate address
name?: string; // Note: Account name
type?: "sr25519" | "ed25519" | "ecdsa";
genesisHash?: string; // Chain restriction when needed
}
interface SignerPayloadJSON {
address: string;
blockHash: string;
blockNumber: string;
era: string;
genesisHash: string;
method: string;
nonce: string;
specVersion: string;
tip: string;
transactionVersion: string;
signedExtensions: string[];
version: number;
}
interface SignerPayloadRaw {
address: string;
data: string; // Note: Hexadecimal encoded data
type: "bytes" | "payload";
}
interface SignerResult {
id: number;
signature: string; // Note: Hexadecimal signature
}
Chain List
| Network | Details |
|---|---|
| Polkadot | Primary relay network |
| Kusama | Experimental canary network |
| Acala | DeFi-focused network |
| Moonbeam | EVM-ready network |
| Astar | Smart-contract focused network |
| Any Substrate | User-defined chain |
Handle Errors
try {
const callResult = await provider.web3SignPayload(payload);
} catch (error) {
if (error.message === "Cancelled") {
console.log("Signing was canceled by the user");
} else {
console.error("Signature generation failed:", error);
}
}
Use with React
import { useState, useEffect } from "react";
import { web3Enable, web3Accounts } from "@polkadot/extension-dapp";
function usePolkadotAccounts() {
const [accounts, setAccounts] = useState([]);
const [isConnected, setIsConnected] = useState(false);
const connect = async () => {
const extensions = await web3Enable("UKey Wallet Demo");
if (extensions.length > 0) {
const allAccounts = await web3Accounts();
setAccounts(allAccounts);
setIsConnected(true);
}
};
return { accounts, isConnected, connect };
}