Complete implementation of an EVVM Service demonstrating a gasless transaction pattern where users sign off-chain and fishers execute on-chain with economic incentives.
This is a full-stack example implementing the EVVM Service architecture, where:
- Users sign transactions off-chain without paying gas fees
- Users pay only for the service value, not computation
- Any participant can execute transactions as a "fisher" and earn rewards
- Service providers can stake tokens to earn automatic rewards
Documentation: evvm.info/docs/HowToMakeAEVVMService
contracts/
src/
EVVMCafe.sol # Main service contract
script/
EVVMCafe.s.sol # Deployment script
foundry.toml # Foundry configuration
makefile # Build and deploy commands
front/
src/
app/ # Next.js app router
components/
CafeComponent.tsx # Order flow component
Ticket.tsx # Receipt display
VisualExecution.tsx # Transaction preview
ConnectButton.tsx # Wallet connection
config/index.ts # Wagmi and AppKit setup
context/index.tsx # React context providers
utils/ # Helper functions
constant/ # ABI definitions and addresses
package.json
next.config.ts
Implements the EVVM Service pattern with the following core function:
function orderCoffee(
address clientAddress,
string memory coffeeType,
uint256 quantity,
uint256 totalPrice,
uint256 nonce,
bytes memory signature,
uint256 priorityFee_EVVM,
uint256 nonce_EVVM,
bool priorityFlag_EVVM,
bytes memory signature_EVVM
) externalThis function:
- Validates the customer signature
- Prevents replay attacks using nonces
- Processes payment through EVVM without gas fees
- Distributes rewards to the transaction executor (fisher)
- Records nonce usage
Built with Next.js and React, providing:
- Wallet connection via Reown AppKit
- Off-chain signature generation using @evvm/viem-signature-library
- Real-time nonce management
- Transaction preview and receipt display
The contract implements a coffee ordering service with the following characteristics:
| Item | Price |
|---|---|
| Fisher Espresso | 0.001 ETH |
| Virtual Cappuccino | 0.002 ETH |
| Decentralized Latte | 0.003 ETH |
| Nonce Mocha | 0.0067 ETH |
orderCoffee()- Process a coffee order with EVVM paymentstake()- Owner stakes tokens to earn automatic rewardsunstake()- Owner unstakes tokenswithdrawRewards()- Owner withdraws accumulated EVVM rewardswithdrawFunds()- Owner withdraws accumulated ETH- View functions for balances and configuration
- Node.js >= 18.x
- Foundry (for smart contracts)
- Git
cd contracts
forge install
forge buildcd front
npm install
# Create environment file
cp .env.example .env.local
# Add your Reown Project ID from https://dashboard.reown.comnpm run devOpen http://localhost:3000 in your browser.
Update addresses in front/src/constant/address.json:
{
"CafeAddress": "0xCea5836f0c56E4F9D5c535834FEc090aE1c6C859",
"EVVMAddress": "0x9902984d86059234c3B6e11D5eAEC55f9627dD0f"
}Default network is Sepolia testnet. To use a different network,
update front/src/config/index.ts:
import { mainnet, sepolia } from '@reown/appkit/networks'
export const networks = [mainnet, sepolia]Deploy to Sepolia testnet using Foundry:
cd contracts
export RPC_URL_ETH_SEPOLIA=your_rpc_url
export ETHERSCAN_API=your_etherscan_api_key
make deployContractThe service uses two-level signing:
-
Service Signature (orderCoffee authorization)
format: "<evvmID>,orderCoffee,<coffeeType>,<quantity>,<totalPrice>,<nonce>" signer: customer -
Payment Signature (EVVM payment authorization)
signer: customer includes: amount, nonce, priority fee, executor address
Two types of nonces are used:
- Sync nonces: Sequential (1, 2, 3...) - managed by EVVM
- Async nonces: Any unused number - managed by contract
This contract uses async nonces for flexibility in transaction ordering.
When the coffee shop is registered as an EVVM staker, transaction executors (fishers) receive automatic rewards:
if (evvm.isAddressStaker(address(this))) {
// Priority fee payment
makeCaPay(msg.sender, getEtherAddress(), priorityFee_EVVM);
// Half of EVVM generated rewards
makeCaPay(msg.sender, getPrincipalTokenAddress(),
evvm.getRewardAmount() / 2);
}Main ordering component managing the flow:
- Coffee selection and quantity input
- Price calculation
- Random nonce generation
- Signature creation and management
- EVVM integration
Displays order receipt with:
- Coffee details (type, quantity, price)
- Payment information
- Transaction signatures
Shows transaction data preview and execution interface.
- Connect wallet using AppKit integration
- Select coffee type and quantity
- Review order and price details
- Generate random nonce for transaction
- Create signatures off-chain (no gas fees)
- Review receipt with order and payment details
- Execute transaction on blockchain
- Fishers are incentivized to process the transaction
- Customize coffee menu in CafeComponent.tsx
- Adjust reward distribution in EVVMCafe.sol
- Configure network in src/config/index.ts
- Deploy contract using Foundry
- Update contract addresses in constant/address.json
- EVVM Official Docs - Complete EVVM guide
- How to Make an EVVM Service - Detailed tutorial
- Signature Structures - Signing guide
- EVVMCafe.sol - Implementation example
- CafeComponent.tsx - Frontend integration
- executeTransactionData.tsx - Transaction execution
# Contract tests
cd contracts
forge test
# Frontend tests
cd front
npm run testEdit front/src/components/CafeComponent.tsx:
const coffePriceMap: { [key: string]: bigint } = {
"Custom Coffee": BigInt(5000000000000000), // 0.005 ETH
};Edit contracts/src/EVVMCafe.sol in orderCoffee function to change
how rewards are distributed to fishers.
- All transactions require cryptographic signatures from users
- Nonces prevent replay attacks (each can only be used once)
- Only contract owner can withdraw funds and rewards
- EVVM handles payment validation
- Permission checks protect sensitive operations
Open an issue on GitHub with:
- Clear title and description
- Steps to reproduce (for bugs)
- Environment details (Node version, OS)
- Fork and clone:
git clone https://github.com/your-username/Hackathon-CoffeShop-Example.git - Create branch:
git checkout -b feature/description - Make changes and test
- Commit:
git commit -m 'Clear description' - Push:
git push origin feature/description - Open pull request
- Reference issues: "Fixes #123"
- Include tests for new features
- Update documentation
- Follow existing code style
- Keep commits focused
Discuss major changes in an issue before starting work.
MIT License - See LICENSE file
- EVVM Website: https://evvm.info
- GitHub: https://github.com/EVVM-org
Q: Do users pay gas fees? A: No. Users sign transactions off-chain without fees. Fishers execute on-chain and receive economic rewards.
Q: What is a fisher? A: Any participant who executes EVVM transactions. Staker fishers receive automatic rewards; custom rewards can be configured for others.
Q: How does the service provider earn revenue? A: The provider keeps all service payments (coffee prices). If registered as a staker, also earns EVVM protocol rewards.
Q: What happens if no one executes a transaction? A: Fishers have economic incentives. Higher priority fees encourage faster execution and prioritization.
Q: How can I customize pricing or rewards? A: Modify coffePriceMap in CafeComponent.tsx and adjust reward logic in EVVMCafe.sol orderCoffee function.