Browser dApps & wallets
A dApp holds no key — the user's wallet does. The BKC Wallet browser extension injects a Keplr-compatible provider (window.keplr), and the SDK turns it into the same ethers Signer the rest of these docs use.
Connect
import { connectBkcWallet, Contract } from "@bkc-network-lib/sdk";
const endpoints = {
evmRpcUrl: "https://rpc.bkc.network",
cosmosRpcUrl: "https://comet-rpc.bkc.network",
};
const { account, signer, provider, cosmosSigner, wallet } = await connectBkcWallet(endpoints);
// account.address bkc1… the Cosmos address
// account.evmAddress 0x… the same account, as the EVM sees it| Returned | Use it for |
|---|---|
signer | Contract, ContractFactory — writes are signed by the wallet with ML-DSA-65 |
provider | reads |
cosmosSigner | the same account as an OfflineDirectSigner, for SigningStargateClient |
wallet | the raw injected provider (e.g. signArbitrary) |
connectBkcWallet(endpoints, { chainId, timeoutMs }): chainId is the identifier passed to the wallet's enable()/getKey() (default "BKC"); timeoutMs is how long to wait for the extension to inject itself (default 3 s). If no wallet appears it throws No BKC wallet found. Install the extension and reload the page.
A full interaction
const { account, signer } = await connectBkcWallet(endpoints);
const counter = new Contract(address, abi, signer);
console.log(await counter.get()); // read — no wallet prompt
const tx = await counter.set(42); // write — the wallet asks the user to approve
const receipt = await tx.wait();
console.log(receipt.hash, receipt.logs);Design around two chain facts
- Gas is higher than on an EVM chain. An ML-DSA-65 signature is ~3.3 KB and gas is per byte; budget from
bkcChain.baseGasLimit. - Gas cannot be simulated (
bkcChain.isSimulable === false); the estimate comes from the budget, not the node.
And: receipt.fee is 0 — show getEvmTransactionCost() instead if you display fees.
Sign-in with a BKC account
signer.signMessage() cannot work (no ECDSA key). Use ADR-36 signing through the wallet and verify on your backend with verifyMessage(), or inside a contract through the ML-DSA verify precompile.
Endpoints from the browser
All public endpoints send Access-Control-Allow-Origin: *, including the EVM WebSocket (wss://ws.bkc.network), so a page can subscribe to newHeads directly. Wrapped-call logs are not pushed over eth_subscribe("logs"); poll eth_getLogs for contract events.
