Chainvoice is a decentralized invoicing dApp for EVM-compatible chains. Create, send and pay invoices on-chain in the network's native coin or any ERC-20 token, with invoice details encrypted end to end. The contract has no owner and isn't upgradeable, and it can be deployed to any EVM chain. Live deployments are listed in Deployments.md.
- Overview
- Features
- Project Structure
- Getting Started
- Frontend Setup
- Run with Docker
- Smart Contract Testing
- Deploy to an EVM Chain
- Environment Variables
- Community and Support
Chainvoice transforms traditional invoicing by leveraging blockchain technology to create a trustless, automated payment system. Users can create invoices, manage payments, and track transaction history with complete transparency and security.
- Decentralized Invoice Creation - Create and manage invoices on-chain
- Multi-Token Support - Pay using native currency or ERC-20 tokens
- Immutable Records - Verifiable transaction history and status tracking
- Treasury Management - Built-in fee management for platform sustainability
- Privacy Protection - Encrypted invoice data with access control
- User-Friendly Interface - Intuitive web application with wallet integration: browser wallets connect through WalletLink (EIP-6963), with no WalletConnect relay or project ID
Chainvoice/
├── frontend/ # Web application (UI/UX, wallet integration)
├── contracts/ # Solidity smart contracts (core invoicing logic)
├── docs/ # Documentation and guides
└── README.md # This file
- Fork the repository
- Clone your fork
git clone https://github.com/YOUR_USERNAME/Chainvoice.git
cd Chainvoice
-
Navigate to frontend directory
cd frontend -
Install dependencies
npm install -
Start development server
npm run dev -
Open application Navigate to
http://localhost:5173in your browser
Prefer containers? One command brings up the frontend together with a ThruBox relay, which invoice sending and receiving depend on — no Node.js install, and no second repository to clone:
cp frontend/.env.example frontend/.env
docker buildx build -t chainvoice/thrubox-relay:main "https://github.com/AOSSIE-Org/ThruBox-Server.git#main"
docker compose up --buildThe app is then at http://localhost:5173 and the relay at
http://localhost:3000. See docs/docker.md for the full
guide, including the production profile that serves the built bundle behind
nginx.
Prerequisites: Foundry must be installed
-
Navigate to contracts directory
cd contracts -
Run test suite
forge test -
Run tests with verbosity (optional)
forge test -vvv
The same contract and deploy script work on any EVM chain.
- Foundry installed
- A wallet funded with the chain's native coin
- An RPC URL for the chain
-
Configure environment variables
cp contracts/.env.example contracts/.env
Edit contracts/.env with your actual values -
Compile contracts
cd contracts
forge build -
Load environment variables
source .env -
Deploy
The script readsDEV_ADDRESSandDEV_FEE_RECEIVER(both required, non-zero) and an optionalDEV_FEE_WEI(default0.0005 ether, must not be0) from.env, and passes them to the constructor. Thedevaddress setsdevFeeanddevFeeReceiverand hands its own role over in two steps (proposeDev, thenacceptDevfrom the new address), so use a multisig;devFeeReceiverreceives withdrawn fees. The compiler targetsevm_version = "london"withvia_ir(seecontracts/foundry.toml), so one bytecode also runs on chains that have not adopted newer EVM upgrades.
RPC_URL=https://your-chain-rpc.example # the chain's RPC endpoint
forge script script/Chainvoice.s.sol:DeployChainvoice --rpc-url "$RPC_URL" --account deployer --broadcastChain-specific flags:
- No EIP-1559 (no base fee): add
--legacy, orforge scriptfails withunsupported feature: eip1559. - Verification (recommended): add
--verifyon a chain Etherscan supports (needsETHERSCAN_API_KEY). For a chain with a Blockscout explorer, add--verify --verifier blockscout --verifier-url "$EXPLORER_URL/api/"instead, withEXPLORER_URLset to the explorer's base URL (no key needed). - Higher on-chain gas than forge simulates (Sepolia, for example): add
--gas-estimate-multiplier 800. - Block gas limit: a full 30-invoice batch needs about 6.2M gas, so the chain's block gas limit should be at least 8M.
After deploying, record the address in Deployments.md.
-
Configure frontend
cp frontend/.env.example frontend/.env
Edit frontend/.env and set the variable for the chain you deployed to — the frontend readsVITE_CONTRACT_ADDRESS_<chainId>, not a single shared variable, for example:
VITE_CONTRACT_ADDRESS_=your_deployed_contract_address_here
See Environment Variables for the full list. -
Restart frontend development server
cd frontend
npm run dev
#Base (8453)
VITE_CONTRACT_ADDRESS_8453=0x9b31091AA0b4F287114B2A9a3D239Db04a9A07E1
#Ethereum Sepolia (11155111)
VITE_CONTRACT_ADDRESS_11155111=0x6E5Ac5C2c10b4eD34909CFf0DF776832504E9677
#Mordor Testnet (63)
VITE_CONTRACT_ADDRESS_63=0x9b306924Eef2f021E1BC8a54202E90057E3988d8
#Polygon Amoy (80002)
VITE_CONTRACT_ADDRESS_80002=0xBee456a4eF315273E9b6bC1C9eE0737aefD461e0
#Polygon Mainnet (137)
VITE_CONTRACT_ADDRESS_137=0x9b31091AA0b4F287114B2A9a3D239Db04a9A07E1
#Ethereum Classic (61) — blank until redeployed, see note below
VITE_CONTRACT_ADDRESS_61=
⚠️ Renaming the key registry functions changed their selectors, so only a contract deployed from the currentcontracts/src/Chainvoice.solwill answer. The addresses above are such deployments, and Deployments.md is the record of every deployment. Keys registered against an earlier deployment do not carry over; those users must register again.
⚠️ Ethereum Classic is left blank on purpose. It still runs only the v1 contract, which stores invoice payloads on-chain as strings and has no public key registry, so it does not match the current ABI. The app treats any non-empty address as supported, so filling it in would send calls that contract cannot decode. Populate it only after a v2 deployment.
⚠️ Security Note: Never commit.envfiles to version control. Keep your private keys secure.
Invoice payloads travel encrypted over a ThruBox relay, configured with:
VITE_RELAY_URL=http://localhost:3000
VITE_RELAY_API_KEY=
VITE_RELAY_TIMEOUT_MS=VITE_RELAY_URL— in development this is the target the Vite dev server proxies/relayto, so the browser stays same-origin. In production, either an absolutehttps://URL (which requires CORS on the relay) or a path such as/relaythat your host rewrites to it (Vercel rewrites, Netlify redirects, nginxproxy_pass), which avoids CORS entirely.VITE_RELAY_API_KEY— only needed if the relay setssecurity.api_key. This is not a secret: Vite inlines everyVITE_-prefixed variable into the built JavaScript, so any visitor can read it. Treat it as a spam speed-bump, not access control. To keep a relay key private, proxy relay calls server-side and inject it there.VITE_RELAY_TIMEOUT_MS— request timeout, default15000. Raise it (around60000) on hosts that suspend idle instances: a cold start can take most of a minute, and sends are deliberately not retried, so a timeout means an undelivered invoice.
Stores only keccak256 of the invoice data on-chain and exposes the public key
registry. Deployments.md is the full record, including
constructor parameters and deployment blocks.
- Base (8453), mainnet
0x9b31091AA0b4F287114B2A9a3D239Db04a9A07E1 - Polygon (137), mainnet
0x9b31091AA0b4F287114B2A9a3D239Db04a9A07E1 - Ethereum Sepolia (11155111), testnet
0x6E5Ac5C2c10b4eD34909CFf0DF776832504E9677 - Mordor (63), Ethereum Classic testnet
0x9b306924Eef2f021E1BC8a54202E90057E3988d8 - Polygon Amoy (80002), testnet
0xBee456a4eF315273E9b6bC1C9eE0737aefD461e0
Stores the invoice payload on-chain as strings. Superseded, kept for reference.
- Ethereum Sepolia (11155111)
0x54a542dCDC306eE281b5De4613EcEfe6e6ABc562 - Ethereum Classic (61)
0xD044A85a5daC307217B9bF313A90E8a60AF7DdCe - Polygon Mainnet (137)
0xD044A85a5daC307217B9bF313A90E8a60AF7DdCe
Release: release v1
Join our community for support, updates, and discussions:
- Telegram - t.me/StabilityNexus
- Discord - discord.gg/YzDKeEfWtS
- X (Twitter) - @StabilityNexus
- Stable Viewpoints - viewpoints.stability.nexus
- LinkedIn - linkedin.com/company/stability-nexus
- YouTube - youtube.com/@StabilityNexus
We welcome contributions! Please read our contributing guidelines and submit pull requests for any improvements.
Before making or updating any smart contract changes, please review the Smart Contract Contribution Guidelines to ensure compliance with testing, design, and review requirements.
Built with ❤️ by Stability Nexus.

