Reusable Payment Architecture on Base Sepolia
Intent → Authorization → Settlement → Receipt
This project implements a production-ready agent-based payment pattern combining:
- AP2: Authorization Protocol with signature verification
- x402: Settlement execution on Base Sepolia
- Clean Agent Separation: 5 microservices for modularity
- Audit Trail: Immutable receipt registry
User Prompt
↓
Shopping Agent (Intent)
↓
Merchant Agent (Mandate)
↓
Credentials Provider (AP2 Authorization) ← USER APPROVAL HERE
↓
Settlement Agent (x402 Settlement)
↓
Receipt Generator (Audit Trail)
| Agent | Responsibility | Blockchain Interaction |
|---|---|---|
| Shopping Agent | Create payment intents | ❌ No |
| Merchant Agent | Sign cart mandates | ❌ No |
| Credentials Provider | AP2 Authorization - User signature | ✅ Read (nonce) |
| Settlement Agent | Execute USDC transfers | ✅ Write (settlement) |
| Receipt Generator | Store audit records | ✅ Write (receipt) |
| Parameter | Value |
|---|---|
| Network | Base Sepolia |
| Chain ID | 84532 |
| RPC | https://sepolia.base.org |
| Explorer | https://sepolia.basescan.org |
| USDC Contract | 0x036CbD53842c5426634e7929541ec2318f3dCF7e |
| Decimals | 6 |
- ✅ Verifies AP2 signatures (ECDSA)
- ✅ Validates mandate hash, expiry, amount
- ✅ Prevents replay attacks (nonce tracking)
- ✅ Executes USDC
transferFrom - ✅ Emits
SettlementExecutedevent
- ✅ Stores payment receipts
- ✅ Provides public getters
- ✅ Enables dispute resolution
- ✅ Emits
ReceiptCreatedevent
# 1. Install dependencies
npm install
# 2. Start the frontend
npm startThis opens a beautiful web interface where you can:
- 🔐 Connect MetaMask wallet
- 🛒 Create payment intents
- ✅ Run success demos
⚠️ Test failure scenarios- 🧾 View receipts
- 📊 Monitor real-time status
See frontend/README.md for detailed frontend documentation.
# Install dependencies
npm install
# Get testnet assets
# - Base Sepolia ETH: https://www.coinbase.com/faucets/base-ethereum-goerli-faucet
# - Testnet USDC: https://faucet.circle.com/# Copy environment template
cp .env.example .env
# Edit .env and fill in:
# - PRIVATE_KEY (deployer wallet)
# - MERCHANT_PRIVATE_KEY
# - USER_PRIVATE_KEYnpm run deployOutput:
✅ PaymentProcessor deployed to: 0x...
✅ ReceiptRegistry deployed to: 0x...
Important: Copy these addresses to your .env file:
PAYMENT_PROCESSOR_ADDRESS=0x...
RECEIPT_REGISTRY_ADDRESS=0x...
Before running demos, approve USDC spending:
# Use Hardhat console or Etherscan
# Approve PaymentProcessor to spend your USDC
usdc.approve(PAYMENT_PROCESSOR_ADDRESS, amount)# Success flow
npm run demo:success
# Failure scenario (invalid signature)
npm run demo:failure{
"intent_id": "0x123...",
"chain": "Base Sepolia",
"chain_id": 84532,
"usdc_contract": "0x036CbD53842c5426634e7929541ec2318f3dCF7e",
"user": "0xUser...",
"merchant": "0xMerchant...",
"authorized_amount": "50 USDC",
"amount_raw": "50000000",
"settlement_tx": "0xTxHash...",
"processor_contract": "0xProcessor...",
"receipt_contract": "0xRegistry...",
"mandate_hash": "0xMandate...",
"authorized_signature": "0xSig...",
"status": "SUCCESS",
"timestamp": "2026-02-13T12:22:00Z"
}{
"intent_id": "0x456...",
"chain": "Base Sepolia",
"chain_id": 84532,
"status": "FAILED",
"failure_reason": "INVALID_SIGNATURE",
"timestamp": "2026-02-13T12:25:00Z"
}Credentials Provider Agent (credentials-provider.js)
- User reviews intent details
- User signs authorization message
- Signature captured and validated
- Message Construction:
keccak256(intentId, user, merchant, amount, mandateHash, expiry, nonce) - User Signs: Creates ECDSA signature
- Contract Verifies:
PaymentProcessor.executeSettlement()recovers signer - Validation: Signer must match user address
- ✅ Cryptographic Proof: ECDSA signatures cannot be forged without private key
- ✅ Nonce Tracking: Prevents replay attacks
- ✅ Mandate Binding: Amount/merchant locked in signed hash
- ✅ Expiry Validation: Time-limited authorization
- ✅ On-Chain Verification: Smart contract enforces all rules
Attack Scenarios Prevented:
- ❌ Modified amount after signature → Contract rejects (hash mismatch)
- ❌ Expired authorization → Contract rejects (timestamp check)
- ❌ Replay attack → Contract rejects (nonce consumed)
- ❌ Invalid signature → Contract rejects (signature verification fails)
# Compile contracts
npm run compile
# Run Hardhat tests
npm test
# Local Hardhat node (optional)
npx hardhat nodeAP2/
├── contracts/
│ ├── PaymentProcessor.sol # Settlement contract
│ └── ReceiptRegistry.sol # Audit trail
├── agents/
│ ├── shopping-agent.js # Intent creation
│ ├── merchant-agent.js # Mandate signing
│ ├── credentials-provider.js # AP2 authorization ⭐
│ ├── settlement-agent.js # x402 settlement
│ └── receipt-generator.js # Receipt generation
├── demo/
│ ├── demo-success.js # Success flow
│ ├── demo-failure.js # Failure scenario
│ └── receipts/ # Generated receipts
├── scripts/
│ └── deploy.js # Deployment script
├── .env.example # Configuration template
└── hardhat.config.js # Hardhat config
✅ Clean Separation: Each agent has a single responsibility
✅ Reusable Pattern: Works for any USDC payment scenario
✅ Security First: Cryptographic authorization enforcement
✅ Audit Ready: Immutable on-chain receipt trail
✅ Cloud Native: Microservice-friendly architecture
✅ Production Ready: Error handling, logging, validation
✅ Demonstrable: Both success and failure scenarios shown
# Check deployed contracts
https://sepolia.basescan.org/address/PAYMENT_PROCESSOR_ADDRESS
# View settlement transaction
https://sepolia.basescan.org/tx/SETTLEMENT_TX_HASHSettlementExecuted: Confirms payment processedReceiptCreated: Confirms audit record stored
MIT License - See LICENSE file for details
Built with ❤️ for the AP2 + x402 Hackathon