| name | private-app-channels |
| description | Activate when the user works with Tokamak Private App Channels, zkp-channel-manager, L2 state channels with ZK proof verification, BridgeCore, BridgeDepositManager, BridgeProofManager, BridgeWithdrawManager, channel lifecycle (open/deposit/initialize/transact/close/withdraw), MPT keys, Groth16 channel proofs, or off-chain ERC20 transfers.
|
| license | MIT |
| metadata | {"author":"tokamak-network","version":"1.0.0"} |
Tokamak Private App Channels
Layer 2 state channel solution with zero-knowledge proof verification on Ethereum. Enables off-chain ERC20 transactions with trustless on-chain settlement.
Source: https://github.com/tokamak-network/private-app-channel-manager
Architecture
private-app-channel-manager (Next.js 15 + React 19)
│
├── Smart Contracts (Sepolia)
│ ├── BridgeCore — Channel creation, state management
│ ├── BridgeDepositManager — Token deposits, MPT key registration
│ ├── BridgeProofManager — Proof submission, state initialization
│ └── BridgeWithdrawManager — Withdrawals after channel closure
│
├── ZK Proof: Browser (snarkjs)
│ └── Groth16 proofs for channel initialization + closing
│ Tree sizes: 16, 32, 64, 128 leaves
│
├── ZK Proof: Server (Tokamak-Zk-EVM)
│ └── tokamak-cli --synthesize → --prove → --verify → --extract-proof
│ Used for L2 ERC20 transaction proofs
│
└── Tokamak-Zk-EVM/ (git submodule)
└── Synthesizer + QAP compiler + prover
Channel Lifecycle
1. CREATE → openChannel(participants, targetContract) State: Initialized (1)
2. DEPOSIT → depositToken(channelId, amount, mptKey) State: Initialized (1)
3. INITIALIZE → initializeChannelState(channelId, proof) State: Open (2)
4. TRANSACT → Off-chain L2 ERC20 transfers via Tokamak-Zk-EVM
5. SUBMIT → submitProofAndSignature(channelId, proofs) State: Closing (3)
6. CLOSE → verifyFinalBalancesGroth16() State: Closed (4)
7. WITHDRAW → withdraw(channelId, token)
State transitions are one-way only: None(0) → Initialized(1) → Open(2) → Closing(3) → Closed(4).
Common Mistakes
| Mistake | Fix |
|---|
| Non-leader trying to initialize/close | Only the channel leader (first participant) can initialize, approve proofs, submit, and close |
| Forgetting MPT key registration | Deposit with mptKey param — even 0 TON deposit registers the key |
| Extracting unverified proof | --verify must pass before --extract-proof — invalid proofs are rejected |
| Wrong tree size | Tree size (16/32/64/128) is auto-selected based on participantCount + preAllocatedLeaves |
| Checking participants before initialization | State < 2: use isChannelWhitelisted. State >= 2: use getChannelParticipants |
Smart Contract Functions
openChannel(participants, targetContract)
getChannelState(channelId)
getChannelParticipants(channelId)
getChannelLeader(channelId)
getL2MptKey(channelId, participant)
getParticipantDeposit(channelId, participant)
depositToken(channelId, amount, mptKey)
initializeChannelState(channelId, proof)
submitProofAndSignature(channelId, proofs, signature)
withdraw(channelId, token)
getWithdrawableAmount(channelId, user, token)
Proof Generation
A. Initialize/Close Proof (Browser — snarkjs)
Generated in-browser using Groth16. Circuit files at public/zk-assets/.
import { useBridgeProofManagerWrite } from "@/hooks/contract";
B. Transaction Proof (Server — Tokamak-Zk-EVM)
tokamak-cli --synthesize <input.json>
tokamak-cli --prove
tokamak-cli --preprocess && tokamak-cli --verify
tokamak-cli --extract-proof <output.zip>
Local Database
Proofs stored at data/uploads/channels/{channelId}/:
proofs/{proofKey}/ — Generated proofs
submittedProofs/ — Pending leader review
verifiedProofs/ — Approved by leader
rejectedProofs/ — Rejected proofs
Project Structure
private-app-channel-manager/
├── app/
│ ├── create-channel/ # Channel creation
│ ├── join-channel/ # Join existing channel
│ ├── state-explorer/ # Main channel management
│ │ ├── deposit/ # Token deposit
│ │ ├── transaction/ # L2 transactions & proofs
│ │ ├── state3/ # Channel closing
│ │ └── withdraw/ # Token withdrawal
│ └── api/
│ ├── tokamak-zk-evm/ # Synthesis & proof API
│ ├── channels/ # Channel CRUD
│ └── save-proof-zip/ # Proof file storage
├── hooks/contract/ # Smart contract hooks
│ ├── useBridgeCore.ts
│ ├── useBridgeDepositManager.ts
│ ├── useBridgeProofManager.ts
│ └── useBridgeWithdrawManager.ts
├── lib/
│ ├── clientProofGeneration.ts # Browser Groth16
│ ├── createERC20TransferTx.ts # L2 tx signing
│ └── db/ # Local file-based DB
├── packages/
│ ├── config/ # Network + contract config
│ ├── frost/ # FROST signatures (planned)
│ └── ui/ # Shared UI components
├── stores/ # Zustand state stores
├── Tokamak-Zk-EVM/ # Git submodule
└── public/zk-assets/ # Circuit WASM + zkey files
Prerequisites
| Dependency | Purpose |
|---|
| Node.js >= 18 | App framework |
| Alchemy API Key | Sepolia RPC |
| MetaMask / Web3 wallet | User authentication |
| Tokamak-Zk-EVM submodule | L2 transaction proofs |
Quick Start
npm install
npm run dev
Tech Stack
| Technology | Purpose |
|---|
| Next.js 15 (App Router) | Web framework |
| React 19 + Zustand | UI + state management |
| wagmi + viem | Blockchain interaction |
| snarkjs | Browser-side Groth16 proofs |
| Tokamak-Zk-EVM | L2 transaction synthesis |
| tokamak-l2js | L2 primitives (EdDSA, Poseidon) |
Related Skills
- zk-evm: Tokamak zk-EVM pipeline used as submodule for transaction proofs
- tokamak-contracts: Contract addresses and proxy patterns