Use ethers.js or viem to query balances, send transactions, and interact with WKRC on StableNet Testnet.
This guide shows how to connect ethers.js or viem to StableNet Testnet, query balances, send transactions with the required priority fee, and interact with the WKRC ERC-20 contract.Tools: ethers.js v6 or viem
Network: StableNet Testnet (Chain ID 8283)
A funded testnet wallet — get free WKRC from the faucet:
Faucet
Request testnet WKRC — no sign-up required.
Explorer
Inspect transactions and balances on-chain.
Every transaction on StableNet must include maxPriorityFeePerGas of at least 27,600 Gwei (27600000000000 wei). Transactions below this threshold are rejected at the transaction pool level. You must also set maxFeePerGas — omitting it defaults to 0 and causes rejection.
Returns the governance-enforced value, not a fee estimate
WKRC is the native gas coin of StableNet exposed as a standard ERC-20 token via the NativeCoinAdapter system contract. The same balance used to pay gas is the balance returned by balanceOf() — no wrapping required.
// Always set both maxPriorityFeePerGas and maxFeePerGasconst tx = await wallet.sendTransaction({ to: "0xRecipientAddress", value: ethers.parseEther("1.0"), maxPriorityFeePerGas: ethers.parseUnits("27600", "gwei"), maxFeePerGas: ethers.parseUnits("80000", "gwei"),});const receipt = await tx.wait();console.log("Confirmed in block:", receipt.blockNumber);
tx.wait() polls eth_getTransactionReceipt until the transaction is included. Block time is ~1 second, but allow up to 2 minutes for mempool propagation (field-tested; actual time varies). Do not cancel and retry — that may cause a nonce conflict.
// Returns the governance-controlled minimum, not a market estimateconst tip = await provider.send("eth_maxPriorityFeePerGas", []);console.log("Enforced tip:", BigInt(tip).toString(), "wei");// e.g. 27600000000000
// Returns the governance-controlled minimum, not a market estimateconst tip = await publicClient.request({ method: "eth_maxPriorityFeePerGas",});console.log("Enforced tip:", BigInt(tip).toString(), "wei");// e.g. 27600000000000
The GovValidator governance contract enforces a network-wide minimum maxPriorityFeePerGas on every transaction type — native transfers, contract deploys, and contract calls. Omitting it causes immediate rejection.
Field
Minimum
Reference when slow
maxPriorityFeePerGas
27,600 Gwei
35,000 Gwei
maxFeePerGas
Must be ≥ maxPriorityFeePerGas
80,000 Gwei
The 35,000 Gwei / 80,000 Gwei values above are based on StableNet Testnet field testing. They are not official protocol specifications — adjust based on observed mempool conditions.
eth_maxPriorityFeePerGas on StableNet returns the governance-enforced value from GovValidator, not an oracle estimate based on recent blocks. You can use it to fetch the current minimum programmatically.
The NativeCoinAdapter at 0x0000000000000000000000000000000000001000 exposes the native gas coin as a standard ERC-20 token. You do not need to wrap it:
provider.getBalance() / publicClient.getBalance() — returns the same value as balanceOf()
Standard approve / transferFrom patterns work exactly as on Ethereum
transfer() on the WKRC contract moves the same balance used for gas
Transaction rejected / “fee too low” — set both maxPriorityFeePerGas (min 27,600 Gwei) and maxFeePerGas on every send.
maxFeePerGas defaults to 0 — always specify it explicitly alongside maxPriorityFeePerGas. Omitting it causes rejection even if the priority fee is correct.
Slow confirmation — increase to maxPriorityFeePerGas: parseGwei("35000") and maxFeePerGas: parseGwei("80000") (field-tested reference values, not official specs).
tx.wait() / waitForTransactionReceipt hangs — the transaction is in the mempool. Wait up to 2 minutes (field-tested; actual time varies); do not cancel and retry with the same nonce.
“replacement transaction underpriced” — raise both fee fields to replace a pending transaction with the same nonce.