Skip to main content

Prerequisites

Before getting started, ensure you have the following installed:

Node.js 18+

Required for running the Hardhat development environment

Yarn 4

Package manager used for dependency management

Foundry

Required for forge command to run Foundry-based tests

Git

For cloning the repository and version control
The project uses Yarn 4 (Berry) with PnP. Make sure you have the correct version by running yarn --version.

Installation

1

Clone the Repository

Clone the zkp2p-v2-contracts repository from GitHub:
git clone https://github.com/zkp2p/zkp2p-v2-contracts.git
cd zkp2p-v2-contracts
2

Install Dependencies

Install all project dependencies using Yarn:
yarn install
This will install all necessary packages including:
  • Hardhat development framework
  • OpenZeppelin contracts
  • TypeChain for TypeScript bindings
  • Testing utilities (Chai, Mocha)
  • Foundry integration
3

Configure Environment Variables

Copy the default environment configuration and set your API keys:
cp .env.default .env
Edit the .env file and add your keys:
.env
# Required for deployment
ALCHEMY_API_KEY=your_alchemy_api_key_here
BASE_DEPLOY_PRIVATE_KEY=your_mainnet_private_key_here
TESTNET_DEPLOY_PRIVATE_KEY=your_testnet_private_key_here

# Required for contract verification
BASESCAN_API_KEY=your_basescan_api_key_here
ETHERSCAN_KEY=your_etherscan_api_key_here
INFURA_TOKEN=your_infura_token_here
Never commit your .env file to version control. The .gitignore is already configured to exclude it.

Build the Project

The build process compiles Solidity contracts, generates TypeScript type definitions, and transpiles TypeScript code.
# Clean, compile contracts, generate typechain, and transpile TypeScript
yarn build
The yarn build command runs: yarn clean && yarn compile && yarn build:ts:latestThis ensures a clean build with updated TypeChain bindings.

Build Artifacts

After building, you’ll find:
  • artifacts/ - Compiled contract ABIs and bytecode
  • typechain/ - TypeScript type definitions for contracts
  • cache/ - Hardhat compilation cache
  • dist/ - Transpiled TypeScript files

Run Tests

ZKP2P includes comprehensive test coverage using both Hardhat and Foundry.

Hardhat Tests

# Run the complete Hardhat test suite
yarn test

Foundry Tests

# Run all Foundry test suites
yarn test:forge
Use yarn test:fast during development to skip compilation and run tests faster. Only use yarn test when you’ve made contract changes.

Test Coverage

Generate coverage reports to ensure comprehensive test coverage:
# Generate coverage report with Solidity Coverage
yarn coverage
The project maintains high test coverage across all core components. Coverage reports are also published to Codecov.

Local Development

Run a local Hardhat node for development and testing.
1

Start Local Node

Launch a local Hardhat network in a separate terminal:
yarn chain
This starts a local Ethereum node at http://localhost:8545 with:
  • 10 prefunded test accounts
  • Instant mining (no block time)
  • Deterministic account generation
2

Deploy Contracts Locally

In another terminal, deploy the complete contract system:
yarn deploy:localhost
This runs the deployment scripts in order:
  1. 00_deploy_system.ts - Core registries and system contracts
  2. 01_deploy_unified_verifier.ts - Unified payment verifier
  3. 02_add_venmo_payment_method.ts - Venmo configuration
  4. And subsequent payment method configurations…
3

Verify Deployment

Check that all contracts deployed successfully:
ls deployments/localhost/
You should see deployment artifacts for:
  • Orchestrator.json
  • Escrow.json
  • UnifiedPaymentVerifier.json
  • PaymentVerifierRegistry.json
  • And other system contracts
Local deployment includes a USDC mock token for testing. In production deployments, the actual USDC token address is used.

Interact with Contracts

Once deployed locally, you can interact with contracts using Hardhat console or scripts.

Using Hardhat Console

npx hardhat console --network localhost
Then interact with deployed contracts:
const escrow = await ethers.getContract("Escrow");
const orchestrator = await ethers.getContract("Orchestrator");
const usdc = await ethers.getContract("USDCMock");

// Check balances
const [deployer] = await ethers.getSigners();
const balance = await usdc.balanceOf(deployer.address);
console.log("USDC Balance:", ethers.utils.formatUnits(balance, 6));

// Get protocol state
const protocolFee = await orchestrator.protocolFee();
console.log("Protocol Fee:", protocolFee.toString());

Create a Test Deposit

Here’s a complete example of creating a maker deposit:
import { ethers } from "hardhat";

async function createDeposit() {
  const escrow = await ethers.getContract("Escrow");
  const usdc = await ethers.getContract("USDCMock");
  const [maker] = await ethers.getSigners();
  
  // Payment method hash for Venmo
  const venmoHash = ethers.utils.keccak256(
    ethers.utils.toUtf8Bytes("venmo")
  );
  
  // Approve USDC
  const depositAmount = ethers.utils.parseUnits("1000", 6); // 1000 USDC
  await usdc.approve(escrow.address, depositAmount);
  
  // Create deposit
  const tx = await escrow.createDeposit({
    token: usdc.address,
    amount: depositAmount,
    intentAmountRange: {
      min: ethers.utils.parseUnits("10", 6),  // Min 10 USDC
      max: ethers.utils.parseUnits("500", 6)  // Max 500 USDC
    },
    delegate: ethers.constants.AddressZero,
    intentGuardian: ethers.constants.AddressZero,
    retainOnEmpty: false,
    paymentMethods: [venmoHash],
    paymentMethodData: [{
      payeeDetails: ethers.utils.keccak256(
        ethers.utils.toUtf8Bytes("@myvenmo")
      ),
      intentGatingService: ethers.constants.AddressZero
    }],
    currencies: [[
      {
        code: ethers.utils.keccak256(ethers.utils.toUtf8Bytes("USD")),
        minConversionRate: ethers.utils.parseUnits("1", 18) // 1:1 rate
      }
    ]]
  });
  
  const receipt = await tx.wait();
  console.log("Deposit created!", receipt.transactionHash);
}

createDeposit().catch(console.error);
Check out the test files in test/escrow/ and test/orchestrator/ for more comprehensive examples of contract interactions.

Deploy to Testnet

Deploy to Base Sepolia testnet for testing in a live environment.
1

Fund Deployment Account

Ensure your testnet private key account has ETH on Base Sepolia for gas fees. Get testnet ETH from:
2

Deploy to Base Sepolia

Run the deployment script:
yarn deploy:base_sepolia
This deploys the complete system to Base Sepolia testnet.
3

Verify Contracts

Verify contracts on Basescan for public transparency:
yarn etherscan:base_sepolia
Verification uses a 600-second delay between submissions to avoid rate limiting.

Deploy to Production

Production deployments require extreme care! Ensure you:
  • Have thoroughly tested on testnet
  • Reviewed all deployment parameters
  • Verified multisig addresses
  • Have sufficient ETH for gas fees
  • Understand the implications of contract ownership
# Deploy to Base mainnet
yarn deploy:base

Deployment Parameters

Key parameters are configured in deployments/parameters.ts:
export const PROTOCOL_TAKER_FEE = {
  base: ethers.utils.parseUnits("0.01", 18), // 1% fee
};

export const INTENT_EXPIRATION_PERIOD = {
  base: 60 * 60 * 2, // 2 hours
};

export const MAX_INTENTS_PER_DEPOSIT = {
  base: 100,
};

export const ESCROW_DUST_THRESHOLD = {
  base: ethers.utils.parseUnits("1", 6), // 1 USDC
};

Hardhat Configuration

The project uses Hardhat with the following key settings:
hardhat.config.ts
export default {
  solidity: {
    compilers: [{
      version: "0.8.18",
      settings: {
        optimizer: {
          enabled: true,
          runs: 200,
        },
        viaIR: true  // Enable IR optimization
      },
    }],
  },
  networks: {
    localhost: {
      allowBlocksWithSameTimestamp: true,
    },
    base: {
      url: "https://base-mainnet.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY,
      accounts: [`0x${process.env.BASE_DEPLOY_PRIVATE_KEY}`],
    },
    base_sepolia: {
      url: "https://base-sepolia.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY,
      accounts: [`0x${process.env.TESTNET_DEPLOY_PRIVATE_KEY}`],
    },
  },
};

Next Steps

Now that you have the contracts running locally, explore:

Architecture Guide

Deep dive into system design and component interactions

Contract Reference

Detailed API documentation for all contracts

Integration Examples

Learn how to integrate ZKP2P into your application

Architecture Guide

Understand the protocol architecture and components

Troubleshooting

Ensure you’re using the correct Node.js version (18+) and have the latest Hardhat installed:
node --version
yarn add -D hardhat@latest
The project uses viaIR optimization which can increase gas costs. For local testing, the gas limit is set to 100M:
hardhat: {
  blockGasLimit: 100_000_000,
  gas: 100_000_000,
}
Regenerate TypeChain types:
yarn clean
yarn compile
yarn typechain
This occurs when non-TypeScript files exist in the deploy/ folder. The project is configured to skip .md, .mdx, and .txt files automatically.
For more help, check the GitHub Issues or join the community discussion.

Build docs developers (and LLMs) love