Menu

Explorer & Settings

Tempo Explorer Submit Project
Back to all projects
X

xcf-concordium-facilitator

by rgraulus · Updated May 20, 2026

The x402 Concordium Facilitator (XCF) implements a rail-agnostic x402 facilitator (UFX) plus a Concordium Rail Plugin (CRP) that verifies finalized PLT transfers (no token contracts), enforces exact-amount matching, and issues JWS-signed receipts with JWKS rotation.

0
Stars
0
Forks
TypeScript
Language
Oct 31, 2025
Created

In the AI payments ecosystem

xcf-concordium-facilitator is an early-stage TypeScript project in the AI payments / x402 ecosystem. It currently has 0 GitHub stars and 0 forks.

README.md View on GitHub →

x402 Concordium-aware Facilitator (XCF)

🧱 Architecture (layered)

XCF Layered Architecture

XCF consists of two layers:

  • UFX (Universal Facilitator for x402) – rail-agnostic core that exposes the x402-friendly API, enforces idempotency/expiry, signs verifiable receipts (JWS), and emits webhooks/metrics.
  • CRP (Concordium Rail Plugin) – rail-specific adapter that talks to a Concordium gRPC v2 node, reads finalized blocks, parses PLT (protocol-level token) transfers, and matches exact payments.

PoC scope: No custody; no on-chain contracts. Finality-only, exact amount matching, signed receipts, and minimal merchant integration (webhook + polling).


✨ Demo outcome

A payer scans a QR (or taps NFC), sends the exact PLT amount to the pay_to address, and the terminal shows a green check as soon as XCF issues a signed receipt.


📐 Hard guarantees

  • Finality-only: match only transactions in last-finalized blocks (no mempool/pending).
  • Exact tuple match: { tokenId, to, amountMinor }, where amountMinor = toMinorUnits(amount, decimals); no slippage.
  • Idempotency: same nonce + identical payload ⇒ same outcome; same nonce + different payload ⇒ 422.
  • Verifiable receipts: compact JWS with kid; JWKS published at /.well-known/jwks.json.
  • Auth everywhere: all facilitator endpoints require auth; CORS allow-list enforced.

🧭 Milestones (status)

M1 – UFX API skeleton

  • Node/TypeScript + Fastify service
  • Basic health endpoints:
    • GET /healthz
    • GET /v1/crp/health

M2 – CRP wiring (gRPC v2)

  • Concordium testnet gRPC wiring via src/crp/grpc.ts
  • Consensus & account reads:
    • GET /v1/crp/consensus
    • GET /v1/crp/account/:address
  • Basic CRP payments search stub
  • Local smoke tests:
    • npm run smoke:crp
    • npm run smoke:plt (initial stub)

M3 – PLT stream ingest & CRP payments search

  • Database migration for PLT stream ingest:
    • db/migrations/002_m3_stream.sql
  • PLT decimals & parsing:
    • src/crp/decimals-registry.ts
    • src/crp/parser.ts
  • Stream worker & stream control:
    • src/crp/stream.ts
    • src/crp/stream-worker.ts
  • Postgres stores:
    • src/store/plt.pg.ts – PLT events
    • src/store/match.pg.ts – matched payments
  • CRP routes:
    • GET /v1/crp/payments/search
      • Filters: merchantId, status, limit (and default unfiltered listing)
  • Demo tooling:
    • scripts/migrate-002-m3-stream.js – apply M3 migration
    • scripts/debug-*.js – consensus, PLT events, seeding demo challenges
    • scripts/smoke-idempotency.sh – create/idempotent/409 conflict flow for JWS receipts

Status: M3 is implemented and merged into main.

M4 – Exact match & webhook for CRP payments

M4 adds two helper routes under /v1/crp for working with PLT-based payment challenges:

  • GET /v1/crp/payments/search
    Search challenges/payments by tuple filters (existing route).

  • POST /v1/crp/payments/match
    Pure read-only exact tuple match. Validates the full tuple:
    merchantId, nonce, network, asset{type, tokenId, decimals}, amount, payTo.
    Returns either reason: "exact_match" with a single row, or reason: "no_match".

  • POST /v1/crp/payments/fulfill
    Uses the same exact-tuple match as /payments/match, but is intended as the gateway “fulfill” entrypoint. On success it can also POST a JSON payload to a merchant-specific webhook.

All Facilitators projects →