@usebutr/polkadot
injectedWeb3 and Wallet Standard discovery, the adapter builders, and the Polkadot signer.
Discovery
discoverInjectedPolkadotAdapters(onAdapter, options?): () => void
Reads window.injectedWeb3 without prompting: adapters are built without
calling enable(). It scans at once and again on a poll schedule for
late-injecting extensions; the returned function cancels pending polls. It is
a WalletSource as-is:
import type { WalletManagerConfig } from "@usebutr/core";
import { discoverInjectedPolkadotAdapters } from "@usebutr/polkadot";
const config: WalletManagerConfig = { sources: [discoverInjectedPolkadotAdapters] };InjectedPolkadotDiscoveryOptions: pollMs?: ReadonlyArray<number> (offsets
in milliseconds, default [250, 750]; [] for a single synchronous scan) and
target? (overrides window).
discoverPolkadotWalletStandardAdapters(onAdapter, loadModule?): () => void
Discovers wallets advertising a polkadot: chain through Wallet Standard.
Requires @wallet-standard/app; loadModule replaces that import (tests).
A wallet on both channels mints two unrelated ids, so passing both sources
lists it twice. autoDiscovery(["polkadot"]) from @usebutr/wallets lists it
once, including an extension that injects late, and keeps Wallet Standard
wallets that no injectedWeb3 extension matches.
Adapter builders
buildInjectedPolkadotAdapter(extensionName, displayName, provider): PolkadotAdapter
provider is the window.injectedWeb3[extensionName] entry. The id is
injected:polkadot:<extension-name>. connect() calls enable("butr"),
which may prompt; construction does not. connect({ silent: true }) reuses
only an existing in-memory session, otherwise it rejects with NotConnected
before calling enable. A persisted connection stays dormant until an explicit
connect grants access again. signMessage appears once
connect() has enabled an extension that exposes signRaw, and subscribe
once it exposes accounts.subscribe. There is no switchChain: an injected
extension has no network to switch. An account pinned to a network through
genesisHash carries that chain; others are labelled Polkadot.
buildPolkadotWalletStandardAdapter(wallet, registerDisconnector?): PolkadotAdapter | null
Wraps a Wallet Standard wallet, or returns null when it speaks no Polkadot.
The id is slugify("polkadot", wallet.name). signMessage exists when the
wallet advertises polkadot:signMessage, and switchChain when it
advertises more than one Polkadot chain.
Neither adapter has sendTx, getBalance or getTransactionReceipt:
building an extrinsic needs chain metadata over RPC, which butr does not
ship.
Signers
Importing the package registers the polkadot-injected kind:
type PolkadotInjectedSigner = {
extension: Injected; // the object `enable()` resolved: `accounts` and `signer`
extensionName: string; // the `window.injectedWeb3` key
kind: "polkadot-injected";
};It carries no address: sign as the connected wallet's account.
extensionName is what polkadot-api's connectInjectedExtension takes. On an
injected adapter that is not connected, getSigner() rejects. Wallet Standard
adapters resolve { kind: "wallet-standard", wallet }. See the
PAPI integration.
Both transports wrap the message in <Bytes>…</Bytes> and hand the wallet
those bytes: injected through signRaw, Wallet Standard through
polkadot:signMessage. signedMessage is the wrapped bytes, or what a
Wallet Standard wallet reports it signed; verify against it.
Types
InjectedPolkadotDiscoveryOptions, PolkadotSignMessageFeature,
PolkadotSignMessageInput, PolkadotSignMessageOutput.
The Polkadot chain registry (POLKADOT_CHAINS, POLKADOT_CHAINS_LIST) lives
in @usebutr/core. Chain ids are polkadot: plus the first 32 hex characters
of the genesis hash.
Source: packages/polkadot/src/index.ts.