Skip to content

Hardhat plugin ​

@bkc-network-lib/hardhat makes hardhat run, hardhat test, Hardhat Ignition and hardhat verify work against BKC without changing your scripts.

Install ​

The plugin targets Hardhat 2. On that line, several Nomic packages have released majors that require Hardhat 3 and npm picks those by default, so pin the versions:

bash
npm i -D hardhat@^2.26.0 "@nomicfoundation/hardhat-ethers@^3.0.8" ethers@^6
npm i -D @bkc-network-lib/hardhat
npm i -D @nomicfoundation/hardhat-verify                          # for hardhat verify
npm i -D "@nomicfoundation/hardhat-ignition-ethers@^0.15.0"       # only if you use Ignition

Configure ​

js
// hardhat.config.js
require("@nomicfoundation/hardhat-ethers");
require("@bkc-network-lib/hardhat");
require("dotenv").config();

module.exports = {
  solidity: { version: "0.8.24", settings: { optimizer: { enabled: true, runs: 200 } } },
  sourcify: { enabled: false },                 // BKC is not on Sourcify
  networks: {
    bkc: {
      url: process.env.BKC_EVM_RPC,             // https://rpc.bkc.network — reads
      chainId: 262144,
      bkc: {
        cosmosRpcUrl: process.env.BKC_COSMOS_RPC, // https://comet-rpc.bkc.network — writes
        seed: process.env.BKC_SEED,               // 32-byte hex ML-DSA-65 seed
        gasPrice: "5000000bkc",
        explorerUrl: process.env.BKC_EXPLORER,    // https://explorer.bkc.network
      },
    },
  },
};
FieldRequiredMeaning
urlyesEVM JSON-RPC
chainIdrecommended262144
bkc.cosmosRpcUrlyesCometBFT RPC, where writes are broadcast
bkc.seedone of32-byte ML-DSA-65 seed, hex, 0x optional
bkc.mnemonicone ofBIP-39 phrase, derived with BKC's HKDF scheme
bkc.hdPathnodefault m/44'/118'/0'/0/0
bkc.bech32Prefixnodefault bkc
bkc.gasPriceno, but set it5000000bkc. Unset, the SDK default applies (66,666,666,667 per gas, ~13,000× the minimum) — bkc-doctor flags it
bkc.baseGasLimitnoCosmos gas for the signature envelope, before the EVM budget
bkc.explorerUrlnoBlockscout URL — enough for hardhat verify
bkc.explorerApiUrlnowhen the API is not at <explorerUrl>/api

Nothing about the chain is compiled into the package: endpoints, chain id, gas price and explorer all come from your config, so a testnet reset or a moved node is an .env edit, not a plugin release. The published package reads no environment variables itself.

TypeScript configs (hardhat.config.ts) work and the bkc block is typed; Hardhat 2 loads them through ts-node, which needs TypeScript 5.

Tasks ​

bash
npx hardhat bkc-new-account              # a development account: seed + addresses
npx hardhat bkc-doctor --network bkc     # checks endpoints, account, balance, gas price
npx hardhat bkc-account --network bkc    # the account in use, balance and nonce

Run bkc-doctor first on a new machine; every failing line says what to fix.

What the plugin does ​

  • eth_sendTransaction is wrapped in MsgExecuteEvmCall, signed and broadcast; the EVM hash comes back so tx.wait() resolves against a real receipt.
  • Accounts come from the chain. The network is forced to accounts: "remote" and eth_accounts returns the ML-DSA account, so ethers.getSigners() works. A private key in networks.<name>.accounts is ignored with a warning.
  • Writes are serialised. call_nonce must equal the Cosmos sequence exactly, so concurrent writes would reject each other; Promise.all([...]) in a script is queued instead.
  • Reads are untouched — eth_call, eth_getLogs, receipts and gas estimation go straight to the EVM endpoint.
  • hre.network.bkc.address() returns { bech32, evm }.
js
const factory = await hre.ethers.getContractFactory("Storage");
const storage = await factory.deploy();
await storage.waitForDeployment();
await (await storage.set(42)).wait();

Hardhat Ignition ​

Works, with two adjustments:

js
module.exports = {
  // …
  ignition: { requiredConfirmations: 1 },   // blocks are under a second
};
bash
npx hardhat ignition deploy ignition/modules/Storage.js --network bkc

Ignition refuses to start while earlier transactions from the same account are still settling (IGN403); let a block or two pass after a script that sent some.

Limits ​

  • No local signing: eth_sign, personal_sign, eth_signTypedData_v4 fail with an explanation.
  • eth_sendRawTransaction is not supported, and never will be.
  • One account per network.

See What does not work for Foundry, Remix and other tools.

BKC testnet is unaudited. Do not hold value on it.