Developer Guide

Getting Started

Building on Panoptis Chain offers the familiar Ethereum development experience with significant performance improvements. This guide will help you leverage Panoptis Chain's unique capabilities.

Familiar Tools: Panoptis Chain is fully EVM-compatible, so you can use existing Ethereum development tools like Hardhat, Foundry, and Remix without modification.

Development Environment Setup

1. Network Configuration

Add Panoptis Chain to your development environment:

// hardhat.config.js
module.exports = {
  networks: {
    panoptis: {
      url: "https://rpc.panoptis.chain",
      chainId: 4095,
      accounts: [process.env.PRIVATE_KEY]
    },
    panoptisTestnet: {
      url: "https://testnet-rpc.panoptis.chain", 
      chainId: 4093,
      accounts: [process.env.PRIVATE_KEY]
    }
  }
};

2. MetaMask Configuration

Configure MetaMask for Panoptis Chain:

const panoptisNetwork = {
  chainId: '0xfff', // 4095 in hex
  chainName: 'Panoptis Chain',
  nativeCurrency: {
    name: 'PANO',
    symbol: 'PANO',
    decimals: 18
  },
  rpcUrls: ['https://rpc.panoptis.chain'],
  blockExplorerUrls: ['https://explorer.panoptis.chain']
};
 
// Add network to MetaMask
await window.ethereum.request({
  method: 'wallet_addEthereumChain',
  params: [panoptisNetwork]
});

Leveraging Fast Finality

Panoptis Chain's ~400ms block times enable new development patterns:

1. Minimal Confirmation Waits

// Leverage sub-second finality
async function sendTransaction(tx) {
  const signedTx = await wallet.signTransaction(tx);
  const txResponse = await provider.sendTransaction(signedTx);
  
  // Wait for just ONE block confirmation (~400ms)
  const receipt = await txResponse.wait(1);
  
  console.log(`Transaction confirmed in ${receipt.blockNumber} (~400ms)`);
  return receipt; // Proceed with confidence
}

2. Multi-Step Operations

Complex sequences become user-friendly:

// Multi-step DeFi operation (Approve + Swap + Deposit)
async function executeDeFiStrategy(tokenAddress, amount) {
  const approveTx = await erc20.approve(ROUTER_ADDRESS, amount);
  await approveTx.wait(1); // ~400ms
 
  const swapTx = await router.swapExactTokensForETH(/* ... */);
  await swapTx.wait(1); // ~400ms
 
  const depositTx = await lendingPool.deposit(/* ... */);
  await depositTx.wait(1); // ~400ms
 
  // Total time ~1.2 seconds
  console.log('Multi-step strategy completed.');
}

Smart Contract Optimization

Parallel Execution Best Practices

Design contracts to maximize parallel execution benefits:

1. State Isolation Pattern

// ✅ Good: User-isolated state
contract ParallelFriendlyToken {
    mapping(address => uint256) private balances;
    mapping(address => mapping(address => uint256)) private allowances;
    
    function transfer(address to, uint256 amount) external {
        // Only touches sender and recipient balances
        balances[msg.sender] -= amount;
        balances[to] += amount;
        emit Transfer(msg.sender, to, amount);
    }
}
 
// ❌ Bad: Global state dependencies
contract SerialContract {
    uint256 public globalCounter; // Creates conflicts
    
    function increment() external {
        globalCounter++; // All transactions conflict here
    }
}

2. Batch Operations

// Efficient batch processing
contract BatchProcessor {
    function batchTransfer(
        address[] calldata recipients,
        uint256[] calldata amounts
    ) external {
        require(recipients.length == amounts.length, "Length mismatch");
        
        for (uint i = 0; i < recipients.length; i++) {
            _transfer(msg.sender, recipients[i], amounts[i]);
        }
    }
    
    function batchMint(
        address[] calldata recipients,
        uint256[] calldata amounts
    ) external onlyOwner {
        for (uint i = 0; i < recipients.length; i++) {
            _mint(recipients[i], amounts[i]);
        }
    }
}

Gas Optimization Patterns

1. Struct Packing

// ✅ Optimized: Packed into single storage slot
struct PackedData {
    uint128 amount;    // 16 bytes
    uint64 timestamp;  // 8 bytes  
    uint32 id;         // 4 bytes
    bool active;       // 1 byte -> 1 slot total
}
 
// ❌ Unoptimized: Uses multiple slots
struct UnpackedData {
    uint256 amount;    // 32 bytes -> 1 slot
    uint256 timestamp; // 32 bytes -> 1 slot
    uint256 id;        // 32 bytes -> 1 slot
    bool active;       // 32 bytes -> 1 slot (4 slots total)
}

2. Event-Driven Architecture

contract EventOptimized {
    event StateChange(address indexed user, uint256 indexed action, bytes data);
    
    function performAction(uint256 actionType, bytes calldata data) external {
        // Minimal on-chain state
        userLastAction[msg.sender] = block.timestamp;
        
        // Detailed data in events (cheaper than storage)
        emit StateChange(msg.sender, actionType, data);
    }
}

Frontend Integration

React Hook Examples

// hooks/useContract.ts
import { useContractRead, useContractWrite } from 'wagmi';
import { parseEther } from 'viem';
 
export function useTokenBalance(address: `0x${string}`) {
  return useContractRead({
    address: TOKEN_ADDRESS,
    abi: TokenABI,
    functionName: 'balanceOf',
    args: [address],
    watch: true // Auto-refresh on new blocks (~400ms)
  });
}
 
export function useTokenTransfer() {
  const { writeAsync } = useContractWrite({
    address: TOKEN_ADDRESS,
    abi: TokenABI,
    functionName: 'transfer'
  });
 
  const transfer = async (to: string, amount: string) => {
    const tx = await writeAsync({
      args: [to, parseEther(amount)]
    });
    
    // Fast confirmation on Panoptis Chain
    return tx.wait(1); // ~400ms
  };
 
  return { transfer };
}

Real-Time Updates

Leverage fast block times for responsive UIs:

// Real-time balance tracking
function useRealTimeBalance(address: string) {
  const [balance, setBalance] = useState('0');
  
  useEffect(() => {
    const updateBalance = async () => {
      const newBalance = await provider.getBalance(address);
      setBalance(formatEther(newBalance));
    };
    
    // Update every block (~400ms)
    const subscription = provider.on('block', updateBalance);
    
    return () => provider.off('block', subscription);
  }, [address]);
  
  return balance;
}

Advanced Patterns

1. State Channels

Panoptis Chain's fast finality makes state channels more practical:

contract StateChannel {
    struct Channel {
        address[2] participants;
        uint256 deposit;
        uint256 nonce;
        uint256 timeout;
    }
    
    function closeChannel(
        uint256 channelId,
        uint256 finalBalance0,
        uint256 finalBalance1,
        bytes[] calldata signatures
    ) external {
        // Fast settlement due to quick finality
        _settleChannel(channelId, finalBalance0, finalBalance1);
    }
}

2. Oracle Integration

Real-time price feeds become feasible:

contract FastOracle {
    struct PriceData {
        uint256 price;
        uint256 timestamp;
        uint256 blockNumber;
    }
    
    mapping(string => PriceData) public prices;
    
    function updatePrice(string calldata asset, uint256 newPrice) external onlyOracle {
        prices[asset] = PriceData({
            price: newPrice,
            timestamp: block.timestamp,
            blockNumber: block.number
        });
        
        emit PriceUpdate(asset, newPrice, block.timestamp);
    }
    
    function getPrice(string calldata asset) external view returns (uint256) {
        PriceData memory data = prices[asset];
        
        // Price data is fresh due to fast blocks
        require(block.timestamp - data.timestamp < 5, "Price too old");
        return data.price;
    }
}

Testing Strategies

1. Fast Test Iteration

// test/FastTest.js
describe("Token Contract", function() {
  it("should handle rapid transactions", async function() {
    const [owner, user1, user2] = await ethers.getSigners();
    const token = await Token.deploy();
    
    // Multiple rapid transactions possible due to fast blocks
    const tx1 = await token.transfer(user1.address, 100);
    const tx2 = await token.transfer(user2.address, 200);
    
    // Both confirm quickly
    await Promise.all([tx1.wait(1), tx2.wait(1)]);
    
    expect(await token.balanceOf(user1.address)).to.equal(100);
    expect(await token.balanceOf(user2.address)).to.equal(200);
  });
});

2. Parallel Execution Testing

// Test parallel transaction handling
describe("Parallel Execution", function() {
  it("should handle non-conflicting transactions in parallel", async function() {
    const users = await ethers.getSigners();
    const token = await Token.deploy();
    
    // Mint to different users (non-conflicting)
    const mintPromises = users.slice(0, 10).map(user => 
      token.mint(user.address, 1000)
    );
    
    // All should succeed in parallel
    const receipts = await Promise.all(
      mintPromises.map(p => p.then(tx => tx.wait(1)))
    );
    
    // Verify all transactions succeeded
    receipts.forEach(receipt => {
      expect(receipt.status).to.equal(1);
    });
  });
});

Deployment Strategies

1. Progressive Deployment

// deploy/001_deploy_contracts.js
module.exports = async ({getNamedAccounts, deployments}) => {
  const {deploy} = deployments;
  const {deployer} = await getNamedAccounts();
 
  // Deploy core contract
  const token = await deploy('PanoptisToken', {
    from: deployer,
    args: ['Panoptis Token', 'PANO', ethers.parseEther('1000000')],
    log: true,
    waitConfirmations: 1 // Fast on Panoptis Chain
  });
  
  console.log(`Token deployed at ${token.address}`);
};

2. Verification

# Fast contract verification due to quick finality
npx hardhat verify --network panoptis CONTRACT_ADDRESS "Constructor" "Arguments"

Best Practices Summary

Architecture Guidelines

  1. State Isolation: Design contracts where operations on different entities don't conflict
  2. Batch Operations: Group multiple operations to amortize gas costs
  3. Event-Driven: Use events for off-chain data and indexing
  4. Upgrade Patterns: Implement proxy patterns for upgradability
  5. Access Control: Use role-based permissions for admin functions

Gas Optimization Checklist

  • ✅ Pack structs to minimize storage slots
  • ✅ Use events for historical data
  • ✅ Cache array lengths in loops
  • ✅ Use unchecked blocks where safe
  • ✅ Batch operations when possible
  • ✅ Minimize external calls

Parallel Execution Checklist

  • ✅ Isolate state by user/entity
  • ✅ Avoid global counters
  • ✅ Use mapping over arrays for lookups
  • ✅ Design for optimistic execution
  • ✅ Minimize shared state dependencies

Next Steps

Now that you understand Panoptis Chain development patterns:

  1. Explore Examples: Review sample contracts and dApps
  2. Join Community: Connect with other developers building on Panoptis Chain
  3. Deploy & Test: Start with testnet deployment and testing
  4. Optimize: Leverage parallel execution patterns for maximum performance
  5. Launch: Deploy to mainnet and benefit from sub-second finality

Ready to build lightning-fast dApps? Panoptis Chain provides the performance foundation for next-generation decentralized applications.