Skip to content

Testnet Development

The current public testnet is operated by the Koinos Foundation. It can reset, and its vKOIN has no monetary value. Do not reuse mainnet keys or assume old testnet addresses and chain IDs are still valid.

Setting Current value
JSON-RPC https://testnet.koinosfoundation.org/jsonrpc
Health https://testnet.koinosfoundation.org/health
KOIN contract 1FaSvLjQJsCJKq5ybmGsMMQs8RQYyVv8ju
Faucet KoinosTestnetFaucetBot
Operations source koinos/koinos-testnet

Connect and retrieve live chain data

export async function connectTestnet() {
  const provider = new Provider(TESTNET.rpc);
  const [chainId, head] = await Promise.all([
    provider.getChainId(),
    provider.getHeadInfo(),
  ]);
  return { chainId, head };
}

View complete file · Run example

Retrieve the chain ID at runtime because a testnet reset can change it.

Request vKOIN

export function faucetInstructions(address) {
  utils.decodeBase58(address);
  return {
    bot: TESTNET.faucet,
    command: `/faucet ${address}`,
    warning: "Test tokens have no monetary value",
  };
}

View complete file · Run example

Send the returned /faucet ADDRESS command to the Telegram bot. Never pay for testnet tokens and never send mainnet funds to a faucet address.

Create a testnet client

export function testnetClient() {
  return {
    provider: new Provider(TESTNET.rpc),
    koinContract: TESTNET.koinContract,
  };
}

View complete file · Run example

Prevent accidental mainnet use

export function networkConfig(env = process.env) {
  if (env.KOINOS_NETWORK === "mainnet") {
    throw new Error("This state-changing example is testnet-only");
  }
  return TESTNET;
}

View complete file · Run example

Unit-test operation encoding

export async function testTransferEncoding(from, to) {
  const preview = await previewTransfer({ from, to, amount: "0.00000001" });
  return preview.operations[0].call_contract.entry_point === 670398154;
}

View complete file · Run example

This verifies the encoded entry point without signing or broadcasting.

Integration-test availability

export async function testnetHealth(fetchImpl = fetch) {
  const response = await fetchImpl(TESTNET.health);
  if (!response.ok) throw new Error(`Testnet health HTTP ${response.status}`);
  return response.text();
}

View complete file · Run example

Plan a deployment

export function deploymentPlan(wasmFile) {
  if (!wasmFile?.endsWith(".wasm")) throw new Error("Provide a .wasm file");
  return {
    network: TESTNET.name,
    wasmFile,
    broadcast: false,
    requiredEnvironment: "TESTNET_WIF",
  };
}

View complete file · Run example

The runner validates and prints a plan. Actual deployment additionally requires compiled bytecode, its ABI, a dedicated funded testnet signer, and explicit broadcast.

Debug a transaction

export async function debugTransaction(transactionId) {
  const provider = new Provider(TESTNET.rpc);
  return provider.getTransactionReceipt(transactionId);
}

View complete file · Run example

Provide a real testnet transaction ID when calling this exported function. npm run smoke performs only health, head, and chain-ID reads.