Quick Start

Prerequisites

Before you begin, make sure you have:

  • MetaMask browser extension installed

  • Basic familiarity with Ethereum and Web3

  • Node.js installed (for code examples)

  • A few minutes to spare!

Step 1: Connect to OPN Testnet

Chain Configuration

  1. Open MetaMask and click the network dropdown (usually shows "Ethereum Mainnet")

  2. Click "Add Network" at the bottom

  3. Click "Add a network manually"

  4. Enter these details:

Field
Value

Network Name

OPN Testnet

RPC URL

https://testnet-rpc.iopn.tech

Chain ID

984(0x3d8)

Currency Symbol

OPN

  1. Click "Save"

Verify Connection

Once connected, you should see "OPN Testnet" in your network dropdown. Test the connection:

# Using curl
curl -X POST https://testnet-rpc.iopn.tech \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'

# Expected response
# {"jsonrpc":"2.0","id":1,"result":"0x3d8"}

Step 2: Get Test Tokens

You'll need test OPN tokens to pay for gas fees:

Web Faucet

  1. Connect your wallet or enter your address

  2. Complete the CAPTCHA

  3. Click "Request Tokens"

You should receive tokens within a few seconds. Check your balance in MetaMask!

Step 3: Make Your First Transaction

Let's test that everything is working by sending a transaction.

Using MetaMask UI

  1. In MetaMask, click "Send"

  2. Enter recipient address

  3. Enter amount: 2 OPN

  4. Click "Next"

  5. Review the gas fee (should be very low!)

  6. Click "Confirm"

Your transaction should confirm within 1-2 seconds!

Using Ethers.js

const { ethers } = require('ethers');

async function sendWithEthers() {
    // Connect to OPN
    const provider = new ethers.providers.JsonRpcProvider('https://testnet-rpc.iopn.tech');
    
    // Create wallet
    const wallet = new ethers.Wallet('YOUR_PRIVATE_KEY', provider);
    
    // Check balance
    const balance = await wallet.getBalance();
    console.log('Balance:', ethers.utils.formatEther(balance), 'OPN');
    
    // Send transaction
    const tx = await wallet.sendTransaction({
        to: 'USERS_ADDRESS',
        value: ethers.utils.parseEther('0.01')
    });
    
    console.log('Transaction sent:', tx.hash);
    
    // Wait for confirmation
    const receipt = await tx.wait();
    console.log('Confirmed in block:', receipt.blockNumber);
}

sendWithEthers().catch(console.error);

Using Viem.js

// Using Viem
import { createWalletClient, createPublicClient, http, parseEther, formatEther } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';

// Define OPN Chain
const opnTestnet = {
  id: 984,
  name: 'OPN Testnet',
  network: 'opn-testnet',
  nativeCurrency: {
    decimals: 18,
    name: 'OPN',
    symbol: 'OPN',
  },
  rpcUrls: {
    default: { http: ['https://testnet-rpc.iopn.tech'] },
    public: { http: ['https://testnet-rpc.iopn.tech'] },
  },
};

async function sendWithViem() {
  // Create account from private key
  const account = privateKeyToAccount('0xYOUR_PRIVATE_KEY');
  
  // Create public client (for reading)
  const publicClient = createPublicClient({
    chain: opnTestnet,
    transport: http(),
  });
  
  // Create wallet client (for writing)
  const walletClient = createWalletClient({
    account,
    chain: opnTestnet,
    transport: http(),
  });
  
  // Check balance
  const balance = await publicClient.getBalance({
    address: account.address,
  });
  console.log('Balance:', formatEther(balance), 'OPN');
  
  // Send transaction
  const hash = await walletClient.sendTransaction({
    to: '0xUSERS_ADDRESS',
    value: parseEther('0.01'),
  });
  console.log('Transaction sent:', hash);
  
  // Wait for confirmation
  const receipt = await publicClient.waitForTransactionReceipt({ hash });
  console.log('Confirmed in block:', receipt.blockNumber);
}

sendWithViem().catch(console.error);

Using Web3.js-⚠️ Note: Web3.js has been sunset, but we understand some developers still use it. Please use with caution and consider migrating to actively maintained alternatives like Ethers.js or Viem for production applications.

const Web3 = require('web3');

// Connect to OPN
const web3 = new Web3('https://testnet-rpc.iopn.tech');

async function sendFirstTransaction() {
    try {
        // Check connection
        const chainId = await web3.eth.getChainId();
        console.log('✅ Connected to OPN Chain:', chainId);
        
        // Get current gas price
        const gasPrice = await web3.eth.getGasPrice();
        console.log('⛽ Gas Price:', web3.utils.fromWei(gasPrice, 'gwei'), 'Gwei');
        
        // Create account from private key
        const account = web3.eth.accounts.privateKeyToAccount('YOUR_PRIVATE_KEY');
        web3.eth.accounts.wallet.add(account);
        
        // Check balance
        const balance = await web3.eth.getBalance(account.address);
        console.log('💰 Balance:', web3.utils.fromWei(balance, 'ether'), 'OPN');
        
        // Send transaction
        const tx = {
            from: account.address,
            to: 'USER_ADDRESS',
            value: web3.utils.toWei('0.01', 'ether'),
            gas: 21000,
            gasPrice: gasPrice
        };
        
        console.log('📤 Sending transaction...');
        const receipt = await web3.eth.sendTransaction(tx);
        console.log('✅ Success! Hash:', receipt.transactionHash);
        console.log('📦 Block:', receipt.blockNumber);
        
    } catch (error) {
        console.error('❌ Error:', error.message);
    }
}

// Run it!
sendFirstTransaction();

Step 4: Deploy Your First Smart Contract

Now let's deploy a simple smart contract!

Simple Storage Contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract SimpleStorage {
    uint256 public storedData;
    
    event DataStored(uint256 indexed oldValue, uint256 indexed newValue, address indexed setter);
    
    constructor(uint256 initialValue) {
        storedData = initialValue;
        emit DataStored(0, initialValue, msg.sender);
    }
    
    function set(uint256 x) public {
        uint256 oldValue = storedData;
        storedData = x;
        emit DataStored(oldValue, x, msg.sender);
    }
    
    function get() public view returns (uint256) {
        return storedData;
    }
}

Deploy Using Remix

  1. Create a new file: SimpleStorage.sol

  2. Paste the contract code above

  3. Go to "Solidity Compiler" tab and compile (Ctrl/Cmd + S)

  4. Go to "Deploy & Run Transactions" tab

  5. Change Environment to "Injected Provider - MetaMask"

  6. Ensure OPN Testnet is selected in MetaMask

  7. Set initial value (e.g., 42)

  8. Click "Deploy"

  9. Confirm transaction in MetaMask

Deploy Using Hardhat

// hardhat.config.js
require("@nomiclabs/hardhat-waffle");

module.exports = {
  solidity: "0.8.30",
  networks: {
    opn: {
      url: "https://testnet-rpc.iopn.tech",
      chainId: 984,
      accounts: ["YOUR_PRIVATE_KEY"]
    }
  }
};

// scripts/deploy.js
async function main() {
  const SimpleStorage = await ethers.getContractFactory("SimpleStorage");
  const storage = await SimpleStorage.deploy(42);
  await storage.deployed();
  
  console.log("SimpleStorage deployed to:", storage.address);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

Deploy with:

npx hardhat run scripts/deploy.js --network opn

Step 5: Interact with Your Contract

Using Ethers.js

const contractAddress = 'YOUR_CONTRACT_ADDRESS';
const contractABI = [
  "function get() view returns (uint256)",
  "function set(uint256 x)",
  "event DataStored(uint256 indexed oldValue, uint256 indexed newValue, address indexed setter)"
];

async function interactWithContract() {
  const provider = new ethers.providers.JsonRpcProvider('https://testnet-rpc.iopn.tech');
  const wallet = new ethers.Wallet('YOUR_PRIVATE_KEY', provider);
  
  // Create contract instance
  const contract = new ethers.Contract(contractAddress, contractABI, wallet);
  
  // Read current value
  const currentValue = await contract.get();
  console.log('Current value:', currentValue.toString());
  
  // Set new value
  const tx = await contract.set(123);
  console.log('Transaction sent:', tx.hash);
  
  // Wait for confirmation
  const receipt = await tx.wait();
  console.log('Transaction confirmed!');
  
  // Read new value
  const newValue = await contract.get();
  console.log('New value:', newValue.toString());
  
  // Listen for events
  contract.on("DataStored", (oldValue, newValue, setter) => {
    console.log(`Value changed from ${oldValue} to ${newValue} by ${setter}`);
  });
}

interactWithContract().catch(console.error);

Quick Reference

Network Details

const OPN_CONFIG = {
  chainId: 984,
  chainIdHex: '0x3d8',
  rpcUrl: 'https://testnet-rpc.iopn.tech',
  symbol: 'OPN',
  name: 'OPN Testnet',
  decimals: 18,
  minGasPrice: '7000000000' // 7 Gwei in wei
};

Common Commands

# Check sync status
curl -s https://testnet-rpc.iopn.tech \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}'

# Get latest block
curl -s https://testnet-rpc.iopn.tech \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'

# Get gas price
curl -s https://testnet-rpc.iopn.tech \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":1}'

Congratulations! You've successfully:

  • ✅ Connected to OPN Chain

  • ✅ Received test tokens

  • ✅ Sent your first transaction

  • ✅ Deployed a smart contract

Get Support

Troubleshooting

Transaction Stuck?

  • Ensure gas price is at least 7 Gwei

  • Check if you have enough OPN for gas

  • Try resending with slightly higher gas

Can't Connect to Network?

  • Verify RPC URL: https://testnet-rpc.iopn.tech

  • Check Chain ID is exactly 984

  • Try clearing MetaMask cache

Contract Deployment Failed?

  • Ensure contract compiles without errors

  • Check account has sufficient balance

  • Verify gas limit is appropriate


Ready for more? Check out our Discord for community events and learning about OPN Chain!

Last updated