Seamless crypto payments with automatic wallet creation and gasless rewards
Crypify is a production-ready e-commerce platform that demonstrates the power of Coinbase Developer Platform (CDP) by combining Embedded Wallets for user payments with Server Wallets for gasless reward distribution.
Traditional e-commerce platforms struggle with crypto adoption because:
- Users need to manage complex wallets and private keys
- High gas fees discourage small transactions
- Reward distribution requires manual processes
- No seamless integration between fiat and crypto ecosystems
Crypify eliminates these barriers by:
- Zero-friction onboarding: Email OTP authentication creates wallets automatically (CDP Embedded Wallets)
- Gasless rewards: Server-side distribution eliminates gas costs for users (CDP Server Wallets)
- Instant liquidity: Users can spend rewards immediately without additional setup
- Email-based recovery: No seed phrases to remember - wallet access tied to email
Monorepo structure with microservices deployment on Google Cloud Run:
crypify/
web/ # Next.js 14 frontend with CDP Embedded Wallets
api/ # Express backend with CDP Server Wallets
specs/ # Technical documentation
βββββββββββββββ
β User β
β (Browser) β
ββββββββ¬βββββββ
β
β 1. Browse products
βΌ
βββββββββββββββββββββββ
β Web Service β
β (Next.js + CDP) β
β β
β β’ Product catalog β
β β’ Email OTP auth β
β β’ USDC payment UI β
β β’ Embedded Wallets β
ββββββββ¬βββββββββββββββ
β
β 2. Payment notification
βΌ
βββββββββββββββββββββββ
β API Service β
β (Express + CDP) β
β β
β β’ Payment tracking β
β β’ Reward calculationβ
β β’ Email with claim β
β β’ Server Wallets β
ββββββββ¬βββββββββββββββ
β
β 3. Gasless reward transfer
βΌ
βββββββββββββββββββββββ
β Coinbase CDP β
β β
β β’ Wallet management β
β β’ USDC transfers β
β β’ Base Sepolia β
βββββββββββββββββββββββ
We leverage two distinct CDP wallet systems working in harmony:
// Frontend: Email OTP authentication
const { signInWithEmail } = useSignInWithEmail();
await signInWithEmail(email);
// CDP automatically manages wallet lifecycle
// userId = email β persistent wallet addressWhy?
- Users own their private keys (non-custodial)
- Zero setup friction (no MetaMask required)
- Email-based recovery (familiar UX)
- Perfect for payment flows
// Backend: Merchant wallet management
const merchant = await Wallet.fetch(process.env.MERCHANT_WALLET_ID);
// Gasless reward distribution
await merchant.createTransfer({
amount: rewardAmount,
assetId: USDC_CONTRACT,
destination: userAddress,
gasless: true // π― User pays zero gas
});Why?
- Automated backend operations
- Gasless transfers (better UX)
- Centralized fund management
- Perfect for reward distribution
No database required for claim validation:
// Generate tamper-proof claim token
const token = makeClaimToken({
email,
userAddress,
rewardUsd,
expiresAt: Date.now() + 24 * 3600 * 1000
});
// Email: https://crypify.app/claim?token=eyJ...Security features:
- HMAC-SHA256 signature prevents tampering
- Time-based expiration (24 hours)
- Stateless validation (no DB lookup)
- Replay-resistant (one-time use tracked via frontend)
Next.js NEXT_PUBLIC_* variables require special handling in Docker:
# Build stage - Accept build arguments
ARG NEXT_PUBLIC_CDP_PROJECT_ID
ARG NEXT_PUBLIC_API_BASE_URL
# Inject into build environment
ENV NEXT_PUBLIC_CDP_PROJECT_ID=$NEXT_PUBLIC_CDP_PROJECT_ID
ENV NEXT_PUBLIC_API_BASE_URL=$NEXT_PUBLIC_API_BASE_URL
# Build with embedded variables
RUN pnpm buildWhy this matters:
- Next.js bundles
NEXT_PUBLIC_*at build time, not runtime - Runtime env vars don't work for client-side code
- Our solution: GitHub Actions β Secret Manager β Docker build args
- ποΈ E-commerce shop with crypto payments (USDC on Base Sepolia)
- πΌ Automatic wallet creation via Email OTP (no MetaMask needed)
- π° 10% cashback rewards distributed gaslessly
- π§ Email notifications with tamper-proof claim links
- π Zero-knowledge architecture - no user data stored
- β‘ Instant settlement - blockchain-native transactions
- Framework: Next.js 14 (App Router)
- Wallet SDK:
@coinbase/cdp-hooks(Embedded Wallets) - Blockchain: viem + wagmi (Base Sepolia)
- Deployment: Google Cloud Run (containerized)
- Runtime: Node.js 20 + Express
- Wallet SDK:
@coinbase/coinbase-sdk(Server Wallets) - Email: SendGrid (transactional emails)
- Deployment: Google Cloud Run + Secret Manager
- CI/CD: GitHub Actions (automated deployment)
- Container Registry: Google Artifact Registry
- Secrets: Google Secret Manager
- Monitoring: Cloud Run metrics
- Node.js 20+
- pnpm 9.0.0+
- Coinbase Developer Platform account
- SendGrid API key
- Google Cloud account (for deployment)
- Clone repository
git clone https://github.com/rtree/crypify.git
cd crypify- Install dependencies
pnpm install- Configure API
cd api
cp .env.example .env
# Edit .env with your credentials:
# - CDP_API_KEY, CDP_API_SECRET
# - SENDGRID_API_KEY, FROM_EMAIL
# - MERCHANT_WALLET_ADDRESS, CLAIM_SECRET
pnpm dev # Runs on http://localhost:8080- Configure Web
cd web
cp .env.local.example .env.local
# Edit .env.local:
# - NEXT_PUBLIC_CDP_PROJECT_ID (from CDP Portal)
# - NEXT_PUBLIC_API_BASE_URL=http://localhost:8080
pnpm dev # Runs on http://localhost:3000- Visit http://localhost:3000
Deployment is fully automated via GitHub Actions when pushing to main branch.
-
Create Google Cloud Project
- Enable Cloud Run, Artifact Registry, Secret Manager APIs
- Create service account with required permissions
-
Configure GitHub Secrets
GCP_PROJECT_ID: Your GCP project IDGCP_SA_KEY: Service account JSON key
-
Populate Secret Manager
# CDP credentials
echo -n "YOUR_API_KEY" | gcloud secrets create CDP_API_KEY --data-file=-
echo -n "YOUR_API_SECRET" | gcloud secrets create CDP_API_SECRET --data-file=-
echo -n "YOUR_PROJECT_ID" | gcloud secrets create CDP_PROJECT_ID --data-file=-
# Email
echo -n "YOUR_SENDGRID_KEY" | gcloud secrets create SENDGRID_API_KEY --data-file=-
echo -n "noreply@crypify.app" | gcloud secrets create FROM_EMAIL --data-file=-
# Application
echo -n "YOUR_MERCHANT_ADDRESS" | gcloud secrets create MERCHANT_WALLET_ADDRESS --data-file=-
echo -n "$(openssl rand -hex 32)" | gcloud secrets create CLAIM_SECRET --data-file=-- Deploy
git push origin mainGitHub Actions will:
- Build Docker images with embedded environment variables
- Push to Artifact Registry
- Deploy to Cloud Run (asia-northeast1)
- Configure secrets and environment variables
- Browse Products β User visits
/shopand selects a product - Email OTP Login β CDP Embedded Wallet created automatically
- Pay with USDC β User approves transaction (Embedded Wallet signature)
- Backend Processing β API calculates 10% reward and sends email
- Claim Reward β User clicks email link β Gasless USDC transfer from Server Wallet
- View Wallet β User can check balance and transaction history
- SHA-256 signature with 256-bit secret
- Payload includes:
{email, userAddress, rewardUsd, expiresAt} - 24-hour expiration window
- Stateless validation (no database required)
- Source: Merchant Server Wallet (CDP-managed)
- Network: Base Sepolia (testnet)
- Asset: USDC only
- Maximum: Wallet balance limit
- Secrets stored in Secret Manager (not environment variables)
- Stateless containers (auto-scaling, no session persistence)
- HTTPS-only (automatic TLS certificates)
- IAM-based access control
crypify/
βββ .github/workflows/
β βββ deploy-web.yml # Web deployment pipeline
β βββ deploy-api.yml # API deployment pipeline
βββ api/
β βββ src/
β β βββ routes/
β β β βββ claim.ts # Reward claim endpoint
β β β βββ fundWallet.ts # Gas funding endpoint
β β β βββ merchant.ts # Merchant address endpoint
β β β βββ pay.ts # Payment notification
β β β βββ purchase.ts # Purchase creation
β β βββ services/
β β β βββ email.ts # SendGrid integration
β β βββ lib/
β β β βββ cdp.ts # CDP SDK initialization
β β β βββ claimToken.ts # HMAC token utilities
β β βββ types.ts # TypeScript definitions
β β βββ index.ts # Express app
β βββ Dockerfile # Multi-stage production build
β βββ package.json
βββ web/
β βββ app/
β β βββ shop/ # Product catalog
β β β βββ page.tsx
β β βββ thanks/ # Payment page
β β β βββ page.tsx
β β β βββ PayWithCrypto.tsx # Embedded Wallet UI
β β βββ claim/ # Reward claim page
β β β βββ page.tsx
β β β βββ ClaimWithAuth.tsx
β β βββ wallet/ # Wallet dashboard
β β β βββ page.tsx
β β βββ CDPProvider.tsx # CDP hooks provider
β β βββ layout.tsx
β β βββ globals.css
β βββ lib/
β β βββ api.ts # API client utilities
β βββ public/
β β βββ shop/ # Static shop assets
β βββ Dockerfile # Next.js production build
β βββ next.config.js
β βββ package.json
βββ specs/
β βββ MVP_FINALDESIGN.md # Architecture documentation
β βββ DEPLOYMENT.md # Deployment guide
β βββ PROCEDURE.md # Development procedures
βββ pnpm-workspace.yaml # Monorepo configuration
βββ README.md
- β Embedded Wallets with Email OTP
- β Server Wallets for gasless transfers
- β HMAC-signed claim links
- β Production deployment on Cloud Run
- β Automated CI/CD with GitHub Actions
- CDP OnRamp integration (fiat β crypto)
- Multi-chain support (Ethereum, Polygon, Arbitrum)
- Firestore for claim deduplication
- Advanced analytics dashboard
- Mobile app (React Native)
- NFT rewards for loyal customers
MIT License - see LICENSE file for details
Contributions welcome! Please read our contributing guidelines and submit pull requests.
- Documentation: See
/specsdirectory - Issues: GitHub Issues
- CDP Docs: https://docs.cdp.coinbase.com
Built with β€οΈ using Coinbase Developer Platform