# Development Setup

### Overview

This guide will help you set up a complete development environment for building on OPN Chain. Whether you're new to blockchain development or an experienced Ethereum developer, you'll find everything you need to get started.

### Prerequisites

#### Required Software

| Software | Version | Purpose            |
| -------- | ------- | ------------------ |
| Node.js  | 16.0+   | JavaScript runtime |
| npm/yarn | Latest  | Package management |
| Git      | 2.0+    | Version control    |
| VS Code  | Latest  | Recommended IDE    |

#### Optional Tools

| Tool   | Purpose                    |
| ------ | -------------------------- |
| Docker | Container deployment       |
| Python | For Brownie/Ape frameworks |
| Rust   | For Foundry framework      |

#### Step 1: Install Node.js

**macOS:**

```bash
# Using Homebrew
brew install node

# Or download from nodejs.org
```

**Linux:**

```bash
# Ubuntu/Debian
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs

# Fedora
sudo dnf install nodejs
```

**Windows:** Download installer from [nodejs.org](https://nodejs.org/)

#### Step 2: Install Development Framework

Choose your preferred framework:

**Hardhat (Recommended)**

```bash
# Create new project
mkdir my-opn-project
cd my-opn-project

# Initialize npm project
npm init -y

# Install Hardhat
npm install --save-dev hardhat

# Create Hardhat project
npx hardhat

# Install additional dependencies
npm install --save-dev \
  @nomiclabs/hardhat-waffle \
  @nomiclabs/hardhat-ethers \
  ethereum-waffle \
  chai \
  ethers
```

**Foundry**

```bash
# Install Foundry
curl -L https://foundry.paradigm.xyz | bash
foundryup

# Create new project
forge init my-opn-project
cd my-opn-project
```

**Truffle**

```bash
# Install Truffle globally
npm install -g truffle

# Create new project
mkdir my-opn-project
cd my-opn-project
truffle init
```

#### Step 3: Configure for OPN Chain

**Hardhat Configuration**

Create `hardhat.config.js`:

```javascript
require("@nomiclabs/hardhat-waffle");
require("@nomiclabs/hardhat-ethers");
require("dotenv").config();

// Tasks
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
  const accounts = await hre.ethers.getSigners();
  for (const account of accounts) {
    console.log(account.address);
  }
});

// Configuration
module.exports = {
  solidity: {
    version: "0.8.30",
    settings: {
      optimizer: {
        enabled: true,
        runs: 200
      },
      evmVersion: "pectra"
    }
  },
  networks: {
    // Local development
    hardhat: {
      chainId: 31337
    },
    
    // OPN Testnet
    opnTestnet: {
      url: process.env.OPN_TESTNET_RPC || "https://testnet-rpc.iopn.tech",
      chainId: 984,
      accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [],
      gasPrice: 7000000000, // 7 Gwei
      timeout: 60000
    },
    
    // OPN Mainnet (when available)
    opnMainnet: {
      url: process.env.OPN_MAINNET_RPC || "https://rpc.iopn.tech",
      chainId: 985, // Update when mainnet launches
      accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [],
      gasPrice: 7000000000,
      timeout: 60000
    }
  },
  
  // Etherscan-style verification (when available)
  etherscan: {
    apiKey: {
      opnTestnet: process.env.OPNSCAN_API_KEY || "placeholder"
    },
    customChains: [
      {
        network: "opnTestnet",
        chainId: 984,
        urls: {
          apiURL: "https://api-testnet.opnscan.io/api",
          browserURL: "https://testnet.opnscan.io"
        }
      }
    ]
  },
  
  // Gas reporter
  gasReporter: {
    enabled: process.env.REPORT_GAS !== undefined,
    currency: "USD",
    gasPrice: 7
  },
  
  // Paths
  paths: {
    sources: "./contracts",
    tests: "./test",
    cache: "./cache",
    artifacts: "./artifacts"
  }
};
```

**Foundry Configuration**

Create `foundry.toml`:

```toml
[profile.default]
src = 'src'
out = 'out'
libs = ['lib']
remappings = [
    '@openzeppelin/=lib/openzeppelin-contracts/',
]
solc_version = "0.8.30"
evm_version = "pectra"
optimizer = true
optimizer_runs = 200

[rpc_endpoints]
opn_testnet = "${OPN_TESTNET_RPC}"
opn_mainnet = "${OPN_MAINNET_RPC}"

[etherscan]
opn_testnet = { key = "${OPNSCAN_API_KEY}" }

# OPN specific settings
[profile.opn]
gas_price = 7000000000
```

#### Step 4: Environment Setup

Create `.env` file:

```bash
# Network RPC endpoints
OPN_TESTNET_RPC=https://testnet-rpc.iopn.tech
OPN_MAINNET_RPC=https://rpc.iopn.tech

# Private key (NEVER commit this!)
PRIVATE_KEY=your_private_key_here

# API Keys
OPNSCAN_API_KEY=your_api_key_here
INFURA_KEY=your_infura_key_here
ALCHEMY_KEY=your_alchemy_key_here

# Gas settings
GAS_PRICE=7000000000
GAS_LIMIT=3000000

# Other settings
REPORT_GAS=true
```

Add to `.gitignore`:

```bash
node_modules
.env
coverage
coverage.json
typechain
typechain-types

# Hardhat
cache
artifacts

# Foundry
out
cache_forge

# IDE
.vscode
.idea

# OS
.DS_Store
Thumbs.db
```

#### Step 5: Install Development Tools

**Essential npm Packages**

```bash
# Development dependencies
npm install --save-dev \
  @openzeppelin/contracts \
  @openzeppelin/test-helpers \
  @chainlink/contracts \
  hardhat-gas-reporter \
  hardhat-contract-sizer \
  solidity-coverage \
  prettier \
  prettier-plugin-solidity \
  eslint \
  eslint-config-standard \
  eslint-plugin-promise \
  solhint

# Regular dependencies
npm install \
  dotenv \
  @nomiclabs/hardhat-etherscan
```

**VS Code Extensions**

Install these extensions for the best development experience:

* Solidity (Juan Blanco)
* Hardhat Solidity
* Prettier - Code formatter
* ESLint
* GitLens
* Better Comments

Create `.vscode/settings.json`:

```json
{
  "editor.formatOnSave": true,
  "solidity.linter": "solhint",
  "solidity.defaultCompiler": "remote",
  "solidity.compileUsingRemoteVersion": "v0.8.30+commit.e5a0919f",
  "[solidity]": {
    "editor.defaultFormatter": "JuanBlanco.solidity"
  },
  "solidity.remappings": [
    "@openzeppelin/=node_modules/@openzeppelin/"
  ],
  "files.associations": {
    "*.sol": "solidity"
  }
}
```

#### Step 6: Create Project Structure

```bash
# Create directories
mkdir -p {contracts,scripts,test,deploy}

# Create initial contract
cat > contracts/Greeter.sol << 'EOF'
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract Greeter {
    string private greeting;
    
    event GreetingChanged(string oldGreeting, string newGreeting);
    
    constructor(string memory _greeting) {
        greeting = _greeting;
    }
    
    function greet() public view returns (string memory) {
        return greeting;
    }
    
    function setGreeting(string memory _greeting) public {
        string memory oldGreeting = greeting;
        greeting = _greeting;
        emit GreetingChanged(oldGreeting, _greeting);
    }
}
EOF

# Create test file
cat > test/Greeter.test.js << 'EOF'
const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("Greeter", function () {
  let greeter;
  let owner;
  let addr1;

  beforeEach(async function () {
    [owner, addr1] = await ethers.getSigners();
    
    const Greeter = await ethers.getContractFactory("Greeter");
    greeter = await Greeter.deploy("Hello, OPN Chain!");
    await greeter.deployed();
  });

  describe("Deployment", function () {
    it("Should set the right greeting", async function () {
      expect(await greeter.greet()).to.equal("Hello, OPN Chain!");
    });
  });

  describe("Transactions", function () {
    it("Should update greeting", async function () {
      await greeter.setGreeting("Hola, OPN Chain!");
      expect(await greeter.greet()).to.equal("Hola, OPN Chain!");
    });

    it("Should emit event on greeting change", async function () {
      await expect(greeter.setGreeting("New Greeting"))
        .to.emit(greeter, "GreetingChanged")
        .withArgs("Hello, OPN Chain!", "New Greeting");
    });
  });
});
EOF

# Create deployment script
cat > scripts/deploy.js << 'EOF'
async function main() {
  const [deployer] = await ethers.getSigners();

  console.log("Deploying contracts with the account:", deployer.address);
  console.log("Account balance:", (await deployer.getBalance()).toString());

  const Greeter = await ethers.getContractFactory("Greeter");
  const greeter = await Greeter.deploy("Hello, OPN Chain!");

  await greeter.deployed();

  console.log("Greeter deployed to:", greeter.address);
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });
EOF
```

#### Step 7: Configure Git

````bash
# Initialize git repository
git init

# Create .gitignore
cat > .gitignore << 'EOF'
# Dependencies
node_modules
package-lock.json
yarn.lock

# Environment
.env
.env.local
.env.*.local

# Hardhat
cache
artifacts
coverage
coverage.json
typechain
typechain-types

# Foundry
out
cache_forge

# IDE
.vscode
.idea
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Testing
test-results.xml
mochawesome-report

# Build
dist
build
EOF

# Create README
cat > README.md << 'EOF'
# OPN Chain Project

This project demonstrates a basic OPN Chain use case.

## Quick Start

```bash
npm install
npm test
npm run deploy:testnet
````

### Commands

```bash
# Compile contracts
npx hardhat compile

# Run tests
npx hardhat test

# Run tests with gas reporting
REPORT_GAS=true npx hardhat test

# Deploy to OPN testnet
npx hardhat run scripts/deploy.js --network opnTestnet

# Verify contract
npx hardhat verify --network opnTestnet DEPLOYED_CONTRACT_ADDRESS "Constructor argument"
```

## Initial commit

git add . git commit -m "Initial OPN Chain project setup"

````

## Development Workflow

### 1. Write Smart Contracts

```solidity
// contracts/MyToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyToken is ERC20, Ownable {
    constructor(uint256 initialSupply) ERC20("MyToken", "MTK") {
        _mint(msg.sender, initialSupply);
    }
    
    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }
}
````

#### 2. Write Tests

```javascript
// test/MyToken.test.js
const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("MyToken", function () {
  let token;
  let owner;
  let addr1;
  let addr2;
  
  beforeEach(async function () {
    [owner, addr1, addr2] = await ethers.getSigners();
    
    const Token = await ethers.getContractFactory("MyToken");
    token = await Token.deploy(ethers.utils.parseEther("1000000"));
    await token.deployed();
  });
  
  describe("Deployment", function () {
    it("Should assign total supply to owner", async function () {
      const ownerBalance = await token.balanceOf(owner.address);
      expect(await token.totalSupply()).to.equal(ownerBalance);
    });
  });
  
  describe("Transactions", function () {
    it("Should transfer tokens between accounts", async function () {
      await token.transfer(addr1.address, 50);
      expect(await token.balanceOf(addr1.address)).to.equal(50);
      
      await token.connect(addr1).transfer(addr2.address, 50);
      expect(await token.balanceOf(addr2.address)).to.equal(50);
      expect(await token.balanceOf(addr1.address)).to.equal(0);
    });
  });
});
```

#### 3. Run Tests

```bash
# Run all tests
npx hardhat test

# Run specific test file
npx hardhat test test/MyToken.test.js

# Run with gas reporting
REPORT_GAS=true npx hardhat test

# Run with coverage
npx hardhat coverage
```

#### 4. Deploy Contracts

```javascript
// scripts/deploy-token.js
async function main() {
  const [deployer] = await ethers.getSigners();
  
  console.log("Deploying MyToken with account:", deployer.address);
  
  const Token = await ethers.getContractFactory("MyToken");
  const token = await Token.deploy(ethers.utils.parseEther("1000000"));
  
  await token.deployed();
  
  console.log("MyToken deployed to:", token.address);
  console.log("Transaction hash:", token.deployTransaction.hash);
  
  // Wait for confirmations
  await token.deployTransaction.wait(5);
  
  // Verify the deployment
  const totalSupply = await token.totalSupply();
  console.log("Total supply:", ethers.utils.formatEther(totalSupply));
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });
```

Deploy with:

```bash
npx hardhat run scripts/deploy-token.js --network opnTestnet
```

#### 5. Verify Contracts

```bash
# Verify on OPNScan (when available)
npx hardhat verify --network opnTestnet \
  DEPLOYED_CONTRACT_ADDRESS \
  "1000000000000000000000000"
```

### Advanced Setup

#### Multi-Signature Wallet Setup

For production deployments, use a multi-sig:

```javascript
// scripts/setup-multisig.js
const { ethers } = require("hardhat");

async function main() {
  const signers = [
    "0x...", // Owner 1
    "0x...", // Owner 2
    "0x...", // Owner 3
  ];
  
  const MultiSigWallet = await ethers.getContractFactory("MultiSigWallet");
  const multiSig = await MultiSigWallet.deploy(signers, 2); // 2 of 3
  
  await multiSig.deployed();
  console.log("MultiSig deployed to:", multiSig.address);
}
```

#### CI/CD Pipeline

Create `.github/workflows/test.yml`:

```yaml
name: Test

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
        cache: 'npm'
    
    - name: Install dependencies
      run: npm ci
    
    - name: Compile contracts
      run: npx hardhat compile
    
    - name: Run tests
      run: npm test
    
    - name: Run coverage
      run: npx hardhat coverage
    
    - name: Upload coverage to Codecov
      uses: codecov/codecov-action@v3
```

#### Security Setup

Install security tools:

```bash
# Install Slither
pip3 install slither-analyzer

# Install MythX CLI
npm install -g @mythx/cli

# Install Echidna (fuzzer)
# Follow instructions at: https://github.com/crytic/echidna
```

Create security check script:

```bash
#!/bin/bash
# scripts/security-check.sh

echo "Running Slither..."
slither . --json slither-report.json

echo "Running Solhint..."
npx solhint 'contracts/**/*.sol'

echo "Checking contract sizes..."
npx hardhat size-contracts

echo "Security check complete!"
```

### Troubleshooting

#### Common Issues

**1. "Cannot find module" errors**

```bash
# Clear cache and reinstall
rm -rf node_modules package-lock.json
npm install
```

**2. Compilation errors**

```bash
# Clear Hardhat cache
npx hardhat clean
npx hardhat compile
```

**3. Network connection issues**

```javascript
// Add timeout and retry logic
module.exports = {
  networks: {
    opnTestnet: {
      url: "https://testnet-rpc.iopn.tech",
      timeout: 60000, // 60 seconds
      httpHeaders: {
        "User-Agent": "Hardhat"
      }
    }
  }
};
```

**4. Gas estimation errors**

```javascript
// Manually set gas limits
const tx = await contract.method({
  gasLimit: 300000,
  gasPrice: ethers.utils.parseUnits('7', 'gwei')
});
```

#### Getting Help

1. Join our [Discord](https://discord.gg/iopn)

***
