Logo
New RPC users get 35% off their first monthView the offer
RPC Assistant

BNB Smart Chain Testnet Developer Guide for Contracts, CI/CD & Mainnet Readiness

Summary

BNB Smart Chain Testnet (chain ID 97 / 0x61) is an EVM-compatible sandbox that mirrors BNB Smart Chain mainnet and uses valueless tBNB for gas. This guide helps developers set up Hardhat and Foundry projects, deployment scripts, contract tests, frontend and backend integration, CI/CD pipelines, and a mainnet readiness checklist. OnFinality provides a public testnet endpoint at https://bnb-testnet.api.onfinality.io/public and a dedicated testnet endpoint page for workspace endpoints. Because testnet state can reset or faucets can rate-limit, treat it as a rehearsal environment: automate tBNB funding, isolate credentials, use environment variables, and add retries for transient RPC errors. The goal is not just to deploy a contract, but to validate the same request patterns, event subscriptions, and failure modes you will face on mainnet. This page focuses on BNB Smart Chain (BSC); opBNB and BNB Greenfield are separate networks. If you need endpoint details, see /rpc-assistant/bnb-chain-testnet-endpoint. Use /rpc-assistant/binance-smart-chain-developer for broader BSC developer workflows and /networks/bnb when you are ready for mainnet.

Key Takeaways

  • BNB Smart Chain Testnet (chain ID 97 / 0x61) uses tBNB and mirrors mainnet EVM behavior.
  • Set up Hardhat/Foundry with environment variables and idempotent deployment scripts.
  • Use dedicated testnet endpoints and automate CI/CD with separate secrets, retries, and faucet buffers.
  • Complete mainnet readiness checks for security, gas, nonces, finality, monitoring, and rollback before switching to chain ID 56.

Hardhat and Foundry Testnet Project Setup

BNB Smart Chain Testnet uses chain ID 97 (0x61) and tBNB. Configure your development tooling with a testnet RPC URL. For OnFinality's public testnet endpoint, use https://bnb-testnet.api.onfinality.io/public. Do not hardcode private keys in your repo; load them from environment variables.

For Hardhat, add a network entry in hardhat.config.js:

module.exports = { networks: { bscTestnet: { url: process.env.BSC_TESTNET_RPC_URL || 'https://bnb-testnet.api.onfinality.io/public', chainId: 97, accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [] } } };

For Foundry, set the RPC URL in foundry.toml or via environment variables:

[rpc_endpoints] bsc_testnet = "${BSC_TESTNET_RPC_URL}"

You can use forge script or cast to interact with the testnet. Always verify the chain ID and tBNB balance before deploying.

  • Use chain ID 97 / 0x61 for BNB Smart Chain Testnet.
  • Keep private keys in environment variables, never in source control.
  • Set a reasonable timeout and retry policy for RPC calls.
  • For isolated workspace endpoints, use the dedicated testnet endpoint page (/rpc-assistant/bnb-chain-testnet-endpoint).

Deployment Scripts for Reproducible Testnet Deploys

Testnet deployments should be repeatable and auditable. Use a deployment script that checks whether a contract is already deployed, returns the existing address if so, and logs the transaction hash and contract address for later verification.

In Hardhat, use deploy scripts with the run command. For Foundry, use forge script with --broadcast and a deterministic salt when possible. Example deploy snippet with ethers:

const factory = await ethers.getContractFactory('MyToken'); const token = await factory.deploy(); await token.waitForDeployment(); console.log('Deployed at', await token.getAddress());

  • Write idempotent deployment scripts that reuse existing addresses.
  • Store deployed address in a JSON file or CI artifact.
  • Verify contracts on testnet block explorer (testnet.bscscan.com) when available.
  • Consider using a deployment nonce manager to avoid nonce conflicts.

Contract Testing Against a Live Testnet

Testing against the live testnet complements local unit tests. Use a funded test account for each test run, and ensure your endpoint supports eth_getLogs and event subscriptions if your tests rely on those methods.

Run Hardhat tests with --network bscTestnet, or use Foundry's forge test with a fork of the testnet. For live testing, structure tests to be idempotent: create fresh contracts, use unique salt, or clean up state where possible.

Example Hardhat test that checks a transfer emits an event:

await expect(token.transfer(recipient, 100)).to.emit(token, 'Transfer').withArgs(owner.address, recipient.address, 100);

  • Use dedicated test accounts with sufficient tBNB.
  • Retry on transient RPC failures (429s, timeouts).
  • Check event logs with eth_getLogs or WebSocket subscriptions.
  • Test revert reasons and edge cases before considering mainnet readiness.

Frontend and Backend Integration with Wallet Flows

Connect your frontend to BNB Smart Chain Testnet by adding the network details to MetaMask or WalletConnect. Use the testnet RPC URL, chain ID 97, symbol tBNB, and block explorer https://testnet.bscscan.com.

In the backend, instantiate a provider with the same RPC endpoint. For ethers v6:

const provider = new ethers.JsonRpcProvider(process.env.BSC_TESTNET_RPC_URL);

For viem:

import { createPublicClient, http } from 'viem'; import { bscTestnet } from 'viem/chains'; const client = createPublicClient({ chain: bscTestnet, transport: http() });

Wallet flows should handle user rejection, network switching, and insufficient funds gracefully. Show clear network mismatch errors.

  • Add BNB Smart Chain Testnet to wallets with chain ID 97 and tBNB symbol.
  • Use the same RPC endpoint in frontend and backend to reduce inconsistencies.
  • Handle common wallet errors: rejected request, chain ID mismatch, insufficient tBNB.
  • Test on both desktop and mobile wallets if your product supports them.

Event and WebSocket Testing on BNB Smart Chain Testnet

Event testing requires reliable log access. If your endpoint supports WebSocket, use a WebSocketProvider to subscribe to new blocks or contract events. For OnFinality, check the dedicated testnet endpoint page for WebSocket availability for your plan.

Example with ethers v6:

const wsProvider = new ethers.WebSocketProvider(process.env.BSC_TESTNET_WS_URL); const contract = new ethers.Contract(address, abi, wsProvider); contract.on('Transfer', (from, to, value, event) => { console.log(event); });

If WebSocket is not available, poll eth_getLogs with a backoff. Note that some public official endpoints disable eth_getLogs or apply rate limits; verify that your provider supports the methods you need.

  • Subscribe to events with WebSocket when possible for low latency.
  • Use eth_getLogs with block ranges for bulk historical queries.
  • Check that eth_getLogs is supported and not restricted before relying on it.
  • Handle reconnects and missed events with a resubscription strategy.

CI/CD Pipelines: Secrets, Faucets, Retries, and Environments

Treat testnet like a production environment: store RPC URLs and private keys in CI/CD secrets, use separate environment names (dev, staging, testnet), and keep mainnet credentials completely separate.

Faucet handling: tBNB is rate-limited and may require a mainnet balance or captcha. Automate claims only if the faucet permits it; otherwise, maintain a buffer of funded test accounts. In CI, use a funded account from a secret vault and top it up manually.

Retries: wrap RPC calls with exponential backoff for 429s and timeouts. Ensure deployment scripts are idempotent so retries do not duplicate contracts.

Example GitHub Actions secret usage:

env: BSC_TESTNET_RPC_URL: ${{ secrets.BSC_TESTNET_RPC_URL }} PRIVATE_KEY: ${{ secrets.TESTNET_PRIVATE_KEY }}

Environment separation: use different chain IDs (97 vs 56) and endpoint URLs to avoid accidental mainnet deployments.

  • Store RPC URLs and private keys as encrypted CI secrets.
  • Never reuse mainnet private keys on testnet.
  • Automate faucet claims only if stable; otherwise use pre-funded accounts.
  • Add retry logic with jitter to avoid cascading failures.

Testnet Endpoint and Faucet Summary

For full endpoint details, private workspace URLs, and current rate limits, see the dedicated testnet endpoint page at /rpc-assistant/bnb-chain-testnet-endpoint. The core network facts: chain ID 97 (0x61), symbol tBNB, public OnFinality endpoint https://bnb-testnet.api.onfinality.io/public.

Test tokens: Use the official BNB Chain faucet or OnFinality's workspace faucet if available. Faucets may require a small BNB balance on mainnet or have daily limits. Keep a funded account for automated tests.

Also review /networks/bnb-testnet for network config and /networks/bnb for mainnet.

Mainnet Readiness Checklist: Security, Gas, Nonces, Finality, Monitoring, Rollback

Before deploying to BNB Smart Chain mainnet (chain ID 56 / 0x38), go through this checklist with your team. Validate each item on testnet first.

Security: Complete a contract audit, test access control and pausability, and use a multisig for admin operations.

Gas: Estimate gas under realistic load; set appropriate gas limits and priority fees. BNB Smart Chain gas costs differ from Ethereum, so calibrate on testnet.

Nonces: Ensure your application can handle nonce gaps when transactions are sent concurrently. Use a nonce manager or sequential submission.

Finality: BNB Smart Chain has fast probabilistic and economic finality. If your app depends on finalized blocks, use eth_getFinalizedHeader or eth_getFinalizedBlock if supported by your provider.

Monitoring: Set up alerts for failed transactions, contract events, and RPC errors. Monitor balances and gas usage on testnet and mainnet.

Rollback: Have an upgrade or pause plan. Use proxy patterns or emergency stop functions. Document rollback steps and rehearse them on testnet.

Next steps: BNB Smart Chain Developer Guide · BSC API & JSON-RPC Methods.

  • Use chain ID 56 for mainnet; never mix with testnet.
  • Verify all methods your app uses are supported on mainnet endpoint.
  • Run a staged deployment: testnet, staging, then mainnet with incremental traffic.
  • Keep a rollback plan: proxy upgrades, pause buttons, and snapshot states.

Frequently Asked Questions

What is the chain ID for BNB Smart Chain Testnet?

Chain ID 97 (0x61). Mainnet uses 56 (0x38).

How do I get tBNB for testing?

Use the official BNB Chain faucet or OnFinality's workspace faucet if available. Faucets may require a small mainnet BNB balance and have daily limits.

Can I use Hardhat or Foundry with BNB Smart Chain Testnet?

Yes. Add a network entry with chain ID 97 and your testnet RPC URL. Keep private keys in environment variables.

How do I test events and WebSockets on testnet?

Use WebSocketProvider if your endpoint supports it; otherwise poll eth_getLogs. Verify method support on the dedicated endpoint page.

Should I reuse my testnet configuration for mainnet?

No. Use separate environment variables and chain IDs. Update to mainnet chain ID 56 and a mainnet RPC endpoint after completing readiness checks.

RPC Knowledge Base

Related RPC details

Never Worry about Infrastructure Again

OnFinality takes away the heavy lifting of DevOps so you can build smarter and faster.

Get Started