A tutorial demo showing how to combine Circle Programmable Wallets with ACK-Pay verifiable payment receipts to create auditable, cryptographically signed proof of USDC payments on Base blockchain.
ACK-Pay is an open protocol for generating verifiable payment receipts as W3C Verifiable Credentials. When a payment is made, the payer (or a trusted payment service) issues a signed credential that proves:
- Who paid (payer DID)
- Who was paid (payee DID)
- How much (amount + currency)
- Where (blockchain + transaction hash)
- When (ISO 8601 timestamp)
These receipts are tamper-proof (Ed25519 signed), machine-readable (JSON-LD), and independently verifiable without contacting the original payment processor.
Circle Programmable Wallets let you create and manage blockchain wallets via API. In developer-controlled mode, your server holds the keys and can:
- Create wallet sets and individual wallets
- Send USDC transfers programmatically
- Query balances and transaction status
- Operate on multiple chains (Ethereum, Base, Polygon, Arbitrum, etc.)
sequenceDiagram
participant App as Your Application
participant Circle as Circle Wallets API
participant Chain as Base Blockchain
participant ACK as ACK-Pay Receipt Engine
App->>Circle: 1. Create wallet set
Circle-->>App: Wallet set ID
App->>Circle: 2. Create payer + payee wallets
Circle-->>App: Wallet addresses
App->>Circle: 3. Initiate USDC transfer
Circle->>Chain: Submit transaction
Chain-->>Circle: Transaction hash
Circle-->>App: Transfer confirmation
App->>ACK: 4. Generate payment receipt (VC)
Note over ACK: Signs with Ed25519<br/>Embeds tx hash, DIDs,<br/>amount, chain info
ACK-->>App: Signed Verifiable Credential
App->>ACK: 5. Verify receipt
Note over ACK: Check signature,<br/>expiry, issuer DID
ACK-->>App: Verification result
graph TB
subgraph "Circle Wallets Layer"
WS[Wallet Set] --> PW[Payer Wallet<br/>Base USDC]
WS --> RW[Payee Wallet<br/>Base USDC]
end
subgraph "Payment Flow"
PW -->|USDC Transfer| TX[On-Chain Transaction]
TX -->|tx hash| RE[Receipt Engine]
end
subgraph "ACK-Pay Receipt Layer"
RE -->|Sign with Ed25519| VC[Verifiable Credential]
VC -->|JSON-LD| SCHEMA[Payment Receipt Schema]
VC -->|Verify| VER[Receipt Verifier]
end
style WS fill:#00D395,color:#fff
style PW fill:#00D395,color:#fff
style RW fill:#00D395,color:#fff
style TX fill:#3B82F6,color:#fff
style VC fill:#8B5CF6,color:#fff
style VER fill:#8B5CF6,color:#fff
- Node.js 18+
- A Circle Developer Account with API key
- Basic understanding of USDC and blockchain transactions
git clone https://github.com/your-org/ack-circle-payments-demo.git
cd ack-circle-payments-demo
npm installcp .env.example .env
# Edit .env with your Circle API credentialsnpm run buildnpm run demoThis will:
- Create a Circle wallet set
- Create payer and payee wallets on Base (testnet)
- Simulate a USDC transfer between them
- Generate an ACK-Pay verifiable payment receipt
- Verify the receipt's signature, expiry, and issuer
# Just create a wallet
npm run wallet
# Just verify a receipt
npm run verifyack-circle-payments-demo/
src/
circle-wallet.ts # Circle wallet creation and management
ack-pay-receipt.ts # ACK-Pay receipt generation (W3C VC)
verify-receipt.ts # Receipt verification logic
demo.ts # End-to-end demo tying it all together
schemas/
payment-receipt.json # JSON-LD schema for payment receipt VC
.env.example # Required environment variables
package.json
tsconfig.json
| Variable | Description |
|---|---|
CIRCLE_API_KEY |
Your Circle developer API key |
CIRCLE_ENTITY_SECRET |
Your Circle entity secret (hex-encoded) |
CIRCLE_BASE_URL |
Circle API base URL (default: https://api.circle.com) |
CHAIN_ID |
Target chain — BASE-SEPOLIA for testnet, BASE for mainnet |
A VC is a tamper-evident credential that conforms to the W3C VC Data Model. In ACK-Pay, each payment receipt is a VC containing:
{
"@context": ["https://www.w3.org/2018/credentials/v1"],
"type": ["VerifiableCredential", "PaymentReceipt"],
"issuer": "did:key:z6Mkh...",
"credentialSubject": {
"payer": "did:key:z6Mkp...",
"payee": "did:key:z6Mkr...",
"amount": "25.00",
"currency": "USDC",
"chain": "BASE-SEPOLIA",
"transactionHash": "0xabc..."
}
}Each party is identified by a did:key identifier derived from their Ed25519 public key. This allows receipt verification without a centralized registry.
Receipts are signed using Ed25519, providing fast, compact, and secure digital signatures. The signature is embedded in the VC proof field.
Sebastian Borjas — Founder & CEO, Lucilla Inc.
Pioneering pay-per-visit advertising on-chain — the first platform where businesses pay USDC rewards only when customers physically show up, verified by wearable sensors and GPS, settled transparently on-chain. No impressions, no clicks, no fraud. Real foot traffic, real payments, real proof.
Lucilla combines Circle Programmable Wallets, USDC on Base/Arc, ERC-8004 agent reputation, and W3C Verifiable Credentials to build the trust infrastructure for location-verified agentic commerce.
- Website: lucilla.app
- Email: s.borjas@lucilla.ca
- X: @sb_lucilla
- GitHub: @superbigroach
MIT