Source document: ../LUMENBAZAAR_FULL_PROJECT_DOCUMENTATION.md
Repo role: the public web application for resource discovery, seller onboarding, payment testing, settlement inspection, operator visibility, and reviewer evidence.
Primary stack:
- Next.js
- TypeScript
- Tailwind CSS
- shadcn/ui or equivalent component system
- TanStack Query
- Zod
- Stellar Wallets Kit
- Freighter support
Core pages:
//explore/resources/[resourceId]/seller/seller/new-resource/seller/resources/seller/payments/playground/transactions/operators/operators/health/operators/conformance/docs/settings
Implementation rules:
- Keep each phase small enough for one focused pull request.
- Use backend OpenAPI or generated schemas as the source of truth when available.
- Do not claim official Stellar, SDF, or SCF endorsement.
- Build testnet flows first.
- Show machine-readable errors clearly.
- Keep wallet and payment logic non-custodial.
Parts:
- Scaffold the Next.js TypeScript application.
- Add Tailwind CSS and the selected component system.
- Add
README.md,LICENSE,CONTRIBUTING.md,SECURITY.md, and.editorconfig. - Add
.gitignore, PR template, issue template, and GitHub Actions CI.
Completion check:
- Fresh clone can install dependencies, run lint, and start the dev server.
Parts:
- Create the global layout.
- Add top navigation for dashboard, explore, seller, playground, transactions, operators, docs, and settings.
- Add responsive container rules.
- Add shared loading, empty, and error surfaces.
Completion check:
- Every planned route renders a placeholder page without layout shifts.
Parts:
- Define frontend environment variables.
- Add network configuration for
stellar:testnetandstellar:pubnet. - Add facilitator API base URL configuration.
- Add feature flags for mainnet,
uptosessions, and MCP tool inspection.
Completion check:
- Invalid or missing required configuration fails with a clear local error.
Parts:
- Add a generated or hand-authored API client from backend schemas.
- Add Zod validators for API responses until generated schemas exist.
- Configure TanStack Query providers.
- Add request correlation IDs and structured error parsing.
Completion check:
- Health, networks, resources, payments, and conformance client calls are typed.
Parts:
- Add testnet resource fixtures.
- Add payment requirement fixtures.
- Add settlement receipt fixtures.
- Add conformance run fixtures.
Completion check:
- UI pages can be developed before the backend is live.
Parts:
- Show indexed resource count.
- Show active seller count.
- Show settled payment count.
- Show settlement volume by network.
- Show supported networks, API uptime, and latest conformance result.
Completion check:
- Dashboard renders real data when available and fixture data in local demo mode.
Parts:
- Build
/explore. - Add search input.
- Add results region.
- Add sort selector.
- Add pagination or cursor handling.
Completion check:
- Users can submit a search and see resource results.
Parts:
- Add network filter.
- Add asset filter.
- Add resource type filter.
- Add seller verification filter.
- Add price range filter.
- Add extension filter for Bazaar and MCP metadata.
Completion check:
- Filter state is reflected in the URL and backend query parameters.
Parts:
- Build
ResourceCard. - Show name, seller domain, type, network, asset, amount, and verification status.
- Show metadata quality and recent settlement status where available.
- Handle partial search results.
Completion check:
- Resource cards are scan-friendly on desktop and mobile.
Parts:
- Build
/resources/[resourceId]. - Show resource name, description, seller domain, endpoint URL, and route template.
- Show network,
payTo, asset, amount, and current status. - Show public settlement history when available.
Completion check:
- A buyer can inspect the full payment terms before calling a resource.
Parts:
- Build
ResourceSchemaViewer. - Render input schema.
- Render output schema.
- Add schema validation status.
- Add copy buttons for JSON examples.
Completion check:
- Schema displays are deterministic and readable for HTTP APIs and MCP tools.
Parts:
- Build
PaymentRequirementViewer. - Show x402 scheme, network, asset, amount, recipient, expiry, and extensions.
- Show machine-readable failure reasons.
- Add copyable JSON payload view.
Completion check:
- Developers can inspect the exact 402 terms without reading raw network logs.
Parts:
- Integrate Stellar Wallets Kit.
- Add Freighter support.
- Add wallet status component.
- Add network mismatch handling.
- Add disconnect behavior.
Completion check:
- Testnet wallet connection works without storing private keys.
Parts:
- Build
/seller. - Show seller identity status.
- Show domain verification status.
- Show resource count.
- Show recent payment attempts.
Completion check:
- A seller can see whether they are ready to publish paid resources.
Parts:
- Build
SellerDomainVerifier. - Request backend verification challenge.
- Show DNS or well-known file instructions returned by the backend.
- Submit verification request.
- Display success and stable failure codes.
Completion check:
- Domain verification flow can be completed against backend test fixtures.
Parts:
- Build
/seller/new-resource. - Add resource name, description, type, endpoint URL, and route template steps.
- Validate route template syntax.
- Store draft state locally until submission.
Completion check:
- A seller can create a valid resource draft without payment settings.
Parts:
- Add network selector.
- Add accepted asset selector.
- Add amount input.
- Add
payToaddress input. - Add Stellar address validation.
Completion check:
- Invalid asset, amount, network, and recipient values are rejected before submission.
Parts:
- Build
MetadataBuilder. - Add input schema editor.
- Add output schema editor.
- Add MCP metadata section for tool resources.
- Add preview of Bazaar metadata.
Completion check:
- Seller can generate metadata that matches backend validation expectations.
Parts:
- Generate Express middleware snippet.
- Generate Fastify middleware snippet.
- Generate Next.js route helper snippet.
- Insert selected resource metadata into snippets.
Completion check:
- Snippets use
@lumenbazaar/seller-sdkpackage names and testnet defaults.
Parts:
- Call
/v1/discovery/validate. - Show validation warnings and blocking errors.
- Submit resource to
/v1/resources. - Trigger cataloging when valid.
Completion check:
- Invalid metadata cannot be published from the UI.
Parts:
- Build
/seller/resources. ✓ - Add table of seller resources. ✓
- Add status, network, asset, amount, and last indexed time. ✓
- Add edit, disable, and detail links. ✓
Completion check:
- Seller can manage published and draft resources. ✓
Parts:
- Build
/seller/payments. ✓ - Show payment attempts for the seller. ✓
- Show verification status, settlement status, amount, asset, and failure reason. ✓
- Link settled payments to receipts and transaction hashes. ✓
Completion check:
- Seller can reconcile recent payment activity. ✓
Parts:
- Build
/playground. ✓ - Let user select a resource. ✓
- Generate a sample request from the input schema. ✓
- Trigger or simulate initial 402 response. ✓
Completion check:
- Developer can see the payment requirement generated for a chosen resource. ✓
Parts:
- Add authorization simulation path. ✓
- Add wallet-backed authorization path where backend support exists. ✓
- Submit payment payload to
/v1/verify. ✓ - Show accepted and rejected verification states. ✓
Completion check:
- Testnet verification results are visible and machine-readable. ✓
Parts:
- Retry paid request after verification. ✓
- Submit settlement through the backend. ✓
- Show receipt ID, transaction hash, ledger, amount, asset, and seller. ✓
- Show failure codes for settlement failures. ✓
Completion check:
- A full testnet payment simulation can be run from the UI. ✓
Parts:
- Build
/transactions. (done) - Add filters for network, status, asset, seller, and date. (done)
- Show payment attempts and settlements. (done)
- Link transaction hashes to the configured Stellar explorer. (done)
Completion check:
- Operators and reviewers can inspect successful and failed payments. (done)
Parts:
- Build
/operators. (done) - Show API status, supported networks, and configured assets. (done)
- Show queue depth and settlement latency. (done)
- Show RPC and Horizon health. (done)
Completion check:
- Operator can quickly identify degraded backend dependencies. (done)
Parts:
- Build
/operators/health. (done) - Render
OperatorHealthTable. (done) - Add service-level status rows for API, worker, search, Redis, Postgres, RPC, and Horizon. (done)
- Show last check time and recent failure reason. (done)
Completion check:
- Health checks are readable without exposing secrets. (done)
Parts:
- Build
/operators/conformance. (done) - Show latest conformance run. (done)
- Show
/supported,/verify, and/settlepass or fail status. (done) - Show exact scheme and future
uptoscheme coverage. (done)
Completion check:
- Reviewers can see conformance status without reading CI logs. (done)
Parts:
- Build
McpToolInspector. (done) - Show MCP server metadata. (done)
- Render tool schemas for
search_paid_resources,inspect_resource, andcall_paid_resource. (done) - Show budget controls and deterministic error examples. (done)
Completion check:
- Agent developers can inspect MCP tool contracts from the UI. (done)
Parts:
- Build
/settings. (done) - Add network selection. (done)
- Add facilitator URL override for local development. (done)
- Add wallet preferences. (done)
- Add local demo mode toggle. (done)
Completion check:
- Developers can switch between local, testnet, staging, and mainnet-compatible settings. (done)
Parts:
- Build
/docs. (done) - Link to seller, buyer, agent, operator, API, contract, and security docs. (done)
- Link each page to the canonical docs repo path. (done)
Completion check:
- Frontend routes never become the canonical documentation source. (done)
Parts:
- Normalize API errors into stable UI states. (done)
- Add empty states for no resources, no payments, and unavailable conformance runs. (done)
- Add retry actions where safe. (done)
- Avoid logging payment payloads or sensitive wallet data. (done)
Completion check:
- Failure states are clear to humans and still preserve machine-readable codes. (done)
Parts:
- Add keyboard navigation checks. (done)
- Add labels for form controls. (done)
- Add responsive tests for mobile and desktop. (done)
- Fix overflow and truncation for addresses, hashes, and schema content. (done)
Completion check:
- Primary seller, buyer, operator, and playground flows work on mobile and desktop. (done)
Parts:
- Add component unit tests. (done)
- Add form validation tests. (done)
- Add API client tests. (done)
- Add wallet mock tests. (done)
- Add Playwright flows for explore, resource detail, seller onboarding, playground, and transactions. (done)
Completion check:
- CI runs lint, typecheck, unit tests, and Playwright smoke tests. (done)
Parts:
- Configure deployed frontend environment. (done)
- Connect to testnet backend. (done)
- Verify resource search, seller onboarding, playground, transactions, operator health, and conformance pages. (done)
- Document known limitations. (done)
Completion check:
- Testnet UI is usable by sellers, buyers, agents, operators, and reviewers. (done)
Parts:
- Enable mainnet only after backend mainnet acceptance criteria are met.
- Add explicit mainnet labels and warnings.
- Verify production asset configuration.
- Confirm the UI still exposes settlement details.
Completion check:
- Mainnet UI does not hide network, asset, amount, recipient, or transaction details.
Parts:
- Add changelog process.
- Track frontend issues from Drips.
- Keep API schemas synchronized.
- Add regression tests for each fixed UI bug.
Completion check:
- The frontend can evolve without drifting from backend, docs, and contract behavior.
Receipt evidence verification ensures that a settlement receipt presented to the user matches the original payment terms they approved. This prevents scenarios where a malicious or faulty backend could swap payment details mid-transaction.
- Non-Sensitive Storage: Persist only the approved payment terms (identifiers, amounts, networks) in sessionStorage—never store signatures, private keys, or complete signed payloads.
- Field-by-Field Validation: Compare each critical payment term independently against the receipt.
- Explicit Indeterminate State: Any mismatch immediately triggers an explicit "indeterminate" security state—confirmation is impossible if evidence disagrees.
- User Visibility: Display validation errors prominently as security warnings so users can investigate mismatches.
The system persists all seven critical payment terms in the recovery record:
| Term | Stored In | Compared At | Purpose |
|---|---|---|---|
| Network | recovery.network |
Receipt validation | Ensures payment on correct blockchain |
| Asset Code | recovery.assetCode |
Receipt validation | Ensures correct token is paid |
| Asset Issuer | recovery.assetIssuer |
Receipt validation | Identifies token issuer address |
| Amount | recovery.amount |
Receipt validation | Confirms correct payment amount |
| Recipient (payTo) | recovery.payTo |
Recovery record | Ensures funds go to intended seller |
| Payment Attempt ID | recovery.paymentAttemptId |
Settlement & receipt validation | Tracks payment through backend |
| Correlation ID | recovery.correlationId |
Settlement & receipt validation | Correlates verify → settle → receipt flow |
const recoverySchema = z.object({
amount: z.string().regex(/^[1-9]\d*$/), // Atomic amount (stroops)
assetCode: z.string().min(1), // Asset code (e.g., "USDC")
assetIssuer: z.string().min(1), // Asset issuer address or contract ID
correlationId: z.string().min(1), // Verification → settlement correlation
network: z.literal("stellar:testnet"), // Network identifier
paymentAttemptId: z.string().min(1), // Unique payment identifier
payTo: z.string().min(1), // Intended recipient address
receiptId: z.string().min(1).optional(), // Set after settlement submission
resourceId: z.string().min(1), // Resource being paid for
stage: z.enum(["verified", "submitted"]), // Payment stage
transactionHash: z.string().min(1).optional(), // Set after successful settlement
updatedAt: z.string().datetime() // Last update timestamp
});Recovery records are stored in sessionStorage under keys like lumenbazaar:payment-recovery:${resourceId}. The storage is cleared:
- After successful settlement confirmation
- On explicit settlement failures
- On browser close (session scope)
validateReceiptEvidence(receipt, recovery) performs field-by-field comparison:
Receipt Identifier Validation:
├─ receipt.id matches recovery.receiptId
├─ receipt.paymentAttemptId matches recovery.paymentAttemptId
└─ receipt.correlationId matches recovery.correlationId
Network Validation:
└─ receipt.network matches recovery.network
Payment Terms Validation:
├─ receipt.amount matches recovery.amount
├─ receipt.assetCode matches recovery.assetCode
└─ receipt.assetIssuer matches recovery.assetIssuer
Recipient Validation:
└─ receipt.sellerId is present and represents intended recipient
Resource Validation:
└─ receipt.resourceId matches recovery.resourceId (if present)
Transaction Lineage Validation:
└─ receipt.transactionHash matches recovery.transactionHash (if present)
Each mismatch generates an explicit error message:
- "Amount mismatch: expected 500000, got 600000"
- "Asset code mismatch: expected USDC, got USDT"
- "Network mismatch: expected stellar:testnet, got stellar:public"
When outcomeFromReceipt() is called:
-
Validation Phase: Run
validateReceiptEvidence()first- If errors detected: return
{ state: "indeterminate", validationErrors: [...] } - Prevents confirmation state if any evidence disagrees
- If errors detected: return
-
Status Phase: Check receipt status only after validation passes
status === "failed"→{ state: "rejected" }status === "pending"→{ state: "pending" }status === "finalized"+ ledger →{ state: "confirmed" }
When outcome.validationErrors is present, an amber warning alert displays:
{hasValidationErrors && (
<div role="alert" className="bg-amber-50 border-amber-200">
<h3>Receipt evidence validation warnings</h3>
<ul>
{outcome.validationErrors.map(error => (
<li key={error}>{error}</li>
))}
</ul>
</div>
)}Enhanced receipt details display:
- Receipt ID: Full ID with text wrapping
- Receipt Status: pending | finalized | failed
- Ledger: Ledger number or "Pending"
- Amount: Payment amount
- Asset: Asset code
- Network: Network identifier
Comprehensive test suite in paid-flow.test.ts with 8 focused tests:
- ✅ Amount mismatch → indeterminate
- ✅ Asset code mismatch → indeterminate
- ✅ Asset issuer mismatch → indeterminate
- ✅ Network mismatch → indeterminate
- ✅ Resource ID mismatch → indeterminate
- ✅ Payment attempt ID mismatch → indeterminate
- ✅ Correlation ID mismatch → indeterminate
- ✅ Transaction hash mismatch → indeterminate
Each test:
- Mutates a single field independently
- Verifies indeterminate state is returned
- Confirms detailed error message is present
- Uses helper functions for consistent setup
- No Signature Storage: Authorization payloads are never persisted
- No Private Key Storage: Wallet operations are delegated to Freighter
- No Complete Payloads: Recovery stores only identifiers and terms
- Testnet Only: Currently limited to
stellar:testnet - Fail Closed: Any validation error blocks confirmation
Error messages are specific but don't expose backend internals:
✅ User-Facing:
- "Amount mismatch: expected 500000, got 600000"
- "Network mismatch: expected stellar:testnet, got stellar:public"
❌ Avoid Exposing:
- Full request/response bodies
- API endpoint URLs
- Backend version or service names
- Stack traces or SQL queries
Recovery records use sessionStorage (supported in all modern browsers):
- Desktop: Chrome, Firefox, Safari, Edge
- Mobile: Chrome, Safari (iOS 5+)
- Falls back gracefully to
nullin SSR contexts
- Asset code derivation requires optional
resourceAssetCode/resourceAssetIssuerparameters inExecutePaidFlowInput—default to generic values if not provided payTocomparison is implicit (checked only forsellerIdpresence in receipt)- Only one unresolved payment attempt per resource (sessionStorage key scoped to resourceId)
- No recovery across browser sessions (sessionStorage cleared on close)
- Cross-Session Recovery: Persist recovery metadata with encryption (localStorage + vault)
- Mainnet Support: Extend network validation beyond testnet
- Signature Verification: Include challenge fingerprint validation for replay detection
- Audit Logging: Store anonymized validation events for fraud detection
- Batch Validation: Handle multiple concurrent payment attempts