Skip to content

feat(store): USDC-on-Base checkout for KeepKey wallet#132

Merged
sktbrd merged 2 commits into
mainfrom
feat/store-checkout-usdc
Jul 16, 2026
Merged

feat(store): USDC-on-Base checkout for KeepKey wallet#132
sktbrd merged 2 commits into
mainfrom
feat/store-checkout-usdc

Conversation

@sktbrd

@sktbrd sktbrd commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Builds the customer-facing checkout — the missing left side of the KeepKey flow, so a wallet can actually be purchased on gnars.com.
  • Real payment (USDC on Base) is gated to live mode; in sandbox the flow skips payment and places a free KK-TEST-001 order, so the full UX is testable now with no money.
  • Recipient is a dedicated store wallet (NEXT_PUBLIC_STORE_CHECKOUT_ADDRESS), not the treasury.

Flow

/store/[slug]Buy now/store/[slug]/checkout (form) → POST /api/store/checkout → (live: verify USDC tx) → createDropshipOrder → confirmation with status polled via GET /api/store/orders?externalOrderId=….

Changes

  • src/app/[locale]/store/[slug]/checkout/page.tsx — checkout route.
  • src/components/store/CheckoutFlow.tsx — form + payment + confirmation/status polling.
  • src/hooks/use-usdc-payment.ts — USDC transfer on Base (thirdweb, honors EOA/SA view mode).
  • src/app/api/store/checkout/route.ts — payment gate → fulfillment order.
  • src/services/store-payment.ts — on-chain payment verification (+ tests).
  • src/lib/store/fulfillment.ts — checkout eligibility (KK-HW-001 only; tees stay "coming soon") (+ tests).
  • src/lib/schemas/checkout.ts, src/lib/config.ts (STORE_CHECKOUT), CTA wiring in ProductDetail.tsx.
  • i18n EN + PT-BR; env.example; docs (store-checkout.md, keepkey-fulfillment.md, INDEX.md).

Security notes

  • Client supplies only the tx hash; amount/recipient/token are re-read from chain (verifyUsdcPayment). No client-reported payment is trusted.
  • Live externalOrderId = gnars-<txHash> + KeepKey dedup → one payment cannot place two orders.

Test plan

  • pnpm test — 115 passing (13 new: payment verification + eligibility)
  • pnpm lint + prettier clean, no tsc src errors
  • Sandbox e2e: Buy now → form → order → poll (received)
  • Tee correctly rejected: API 400 unsupported_product, page 404, CTA disabled
  • Before live: set NEXT_PUBLIC_STORE_CHECKOUT_ADDRESS + flip KEEPKEY_DROPSHIP_MODE=live, then do one real order

Generated with Claude Code

Build the customer-facing checkout so a KeepKey can actually be purchased —
the missing left side of the fulfillment flow.

- /store/[slug]/checkout: shipping form → payment → order → confirmation with
  live status polling (GET /api/store/orders?externalOrderId=…).
- POST /api/store/checkout is the payment gate. Sandbox mode skips payment and
  places a free KK-TEST-001 order (full UX testable now); live mode requires a
  USDC-on-Base txHash, re-verified server-side (recipient, token, amount ≥ price,
  confirmations, success) before forwarding to KeepKey.
- externalOrderId is derived from the payment tx hash → one payment can only
  ever place one order (KeepKey dedupes on externalOrderId).
- Checkout eligibility gated to DROPSHIP_CATALOG_SKUS (KK-HW-001 only). The tees
  carry a keepkey provider but are print-on-demand elsewhere → stay "coming soon"
  on the CTA, page, and API.
- Payment via useUsdcPayment() (thirdweb, honors EOA/SA view mode). Recipient is
  a dedicated store wallet: NEXT_PUBLIC_STORE_CHECKOUT_ADDRESS.
- i18n EN + PT-BR; tests for payment verification + eligibility (115 passing).
- Docs: store-checkout.md marked Phase 1 built; keepkey-fulfillment.md + INDEX updated.

Verified in sandbox end-to-end: Buy now → form → order → poll; tee correctly
rejected (API 400, page 404, CTA disabled); wallet regression green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
gnars-shadcn Ignored Ignored Jul 16, 2026 5:43pm
hackertestdao Ignored Ignored Jul 16, 2026 5:43pm

Hardcode the dedicated store wallet (0x8Bf5941d27176242745B716251943Ae4892a3C26)
as STORE_CHECKOUT.recipient, matching the treasury pattern (env override wins).
Public address, safe to commit; KeepKey tokens/secrets stay in env. Only used in
live mode — sandbox skips payment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sktbrd
sktbrd merged commit 46df50c into main Jul 16, 2026
4 checks passed
@sktbrd
sktbrd deleted the feat/store-checkout-usdc branch July 16, 2026 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant