Skip to content

Ticoworld/spindle

Repository files navigation

Spindle

Spindle is an API-first Fiber payment gateway for agent backends on CKB.

What it does

Spindle puts a narrow gateway layer in front of agent payment execution:

  • authenticates callers with API keys
  • enforces route-level scopes
  • checks spend policy before execution
  • creates Fiber invoices
  • executes allowed payments on owned Fiber testnet nodes
  • handles retries and duplicate execution honestly
  • records audit history
  • exposes tenant-scoped query APIs for invoices, payments, audit rows, and API keys

Why it exists

Agent backends should not move directly from app logic to payment execution. Without a gateway layer, ownership boundaries get blurred, spend rules are easy to bypass, and denial or failure states are easy to hide.

Spindle sits between agent logic and Fiber so each request has explicit auth, policy, execution, and audit outcomes. The point is not to look like a broad infrastructure platform. The point is to make automated payment requests controlled and auditable.

Current MVP capabilities

The current repo supports:

  • API-key authentication with active, inactive, malformed, and invalid key handling
  • API-key lifecycle with create and revoke flows
  • route-level scopes for invoice, payment, audit, and key routes
  • policy checks for approved addresses, max-per-action, and rolling 24-hour spend
  • invoice creation through Fiber testnet
  • payment execution against owned Fiber testnet nodes
  • payment status lookup by owned payment hash
  • tenant-scoped invoice, payment, audit, and key reads
  • audit logging for success, denial, failure, blocked, idempotent, and status-check paths
  • idempotent retry handling for already-settled invoices
  • duplicate in-flight execution blocking
  • stale processing recovery during payment-status checks

See also:

Current boundaries and non-claims

This repository does not claim:

  • mainnet settlement
  • proof verification or on-chain anchoring
  • live telemetry or an operations console
  • a published SDK
  • production SLA or uptime guarantees
  • full RBAC or session-based auth
  • webhook delivery or external reconciliation tooling
  • a broader infrastructure platform beyond the gateway described here

Why Fiber / CKB matters

Fiber is the actual payment rail used by the repo. That makes Spindle relevant to CKB in a direct way: it is not a generic policy engine with an ecosystem label attached after the fact.

The honest value is the gateway shape around Fiber:

  • policy before execution
  • tenant ownership before reads and writes
  • truthful handling of denial, failure, blocked, processing, and settled states
  • audit and query surfaces after execution

Real API surface

Health

GET /api/health

Returns application, database, and Fiber configuration status for the current environment.

Invoices

POST /api/v1/invoices

Creates an invoice through Fiber and persists an owned invoice record.

Request body:

{
  "amount": "1",
  "assetSymbol": "USDT",
  "description": "Agent payout",
  "externalReference": "optional"
}

GET /api/v1/invoices

Lists invoices for the authenticated agent. Supports status and limit.

GET /api/v1/invoices/[invoiceId]

Returns one owned invoice by stable ID.

Payments

POST /api/v1/payments

Executes payment for an owned invoice string.

Request body:

{
  "invoice": "fibt1..."
}

Behavior includes:

  • policy evaluation before execution
  • idempotent success for already-paid invoices
  • 409 blocking for duplicate in-flight execution
  • status updates written back to the owned invoice

GET /api/v1/payments/[paymentHash]

Returns normalized invoice status and Fiber status for an owned payment hash.

Audit

GET /api/v1/audit

Lists tenant-scoped audit rows. Supports invoiceId, paymentHash, actionType, and limit.

API keys

GET /api/v1/keys

Lists API keys owned by the authenticated agent.

POST /api/v1/keys

Creates a new scoped API key.

{
  "name": "Read-only payment key",
  "scopes": ["payments:read"]
}

DELETE /api/v1/keys/[keyId]

Revokes an owned API key.

Local setup

Prerequisites:

  • Postgres reachable through DATABASE_URL
  • Fiber testnet node reachable through FIBER_NODE_URL
  • optional FIBER_API_KEY if the node requires it

Recommended local flow:

npm install
npm run db:setup
npm run dev

If port 3000 is busy:

npm run dev -- --port 3041

Repo notes

  • The seeded local fixture creates the test API key spnd_test_abcdef123.
  • That key is a local test fixture, not a production secret.
  • Reviewer-facing seeded scenarios live in the app under /scenarios and are labeled as seeded support material rather than live runtime evidence.

Hosted Postgres MVP setup

The repo is ready for a hosted Postgres database through Prisma. For the current MVP, Neon is the simplest fit because Spindle only needs Postgres plus a connection string, not Supabase auth, storage, realtime, or dashboard features.

Set these variables in .env locally and in the demo host:

# Runtime app connection. Use a pooled hosted Postgres URL when available.
DATABASE_URL="postgresql://USER:PASSWORD@HOST/DATABASE?sslmode=require"

# Prisma CLI migration connection. Use the direct/non-pooled URL.
# If omitted, Prisma falls back to DATABASE_URL.
DIRECT_URL="postgresql://USER:PASSWORD@DIRECT_HOST/DATABASE?sslmode=require"

FIBER_NODE_URL="http://localhost:8227"
FIBER_API_KEY=""
SPINDLE_ENABLE_LEGACY_API_KEY_FALLBACK="false"

Run the hosted database setup from this repo:

npm install
npm run db:migrate
npm run db:generate
npm run db:seed
npm run build

The demo seed creates:

  • agent test-agent-id
  • managed API key secret spnd_test_abcdef123
  • active policy with daily spend limit 300, max per action 500, and two approved addresses
  • one paid USDT invoice for policy history

Public MVP deployment

The simplest public deployment is the full Next.js app on Vercel when FIBER_NODE_URL points to a Fiber RPC endpoint that Vercel can reach. The app does not need a separate frontend/backend split for Postgres or Prisma.

If FIBER_NODE_URL is local, such as http://127.0.0.1:8229, the public UI can still run on Vercel, but live invoice creation and payment execution must run on a backend host that can reach that Fiber node.

Minimum production env vars:

DATABASE_URL="postgresql://..."
DIRECT_URL="postgresql://..."
FIBER_NODE_URL="https://public-or-private-fiber-rpc.example"
FIBER_API_KEY=""
SPINDLE_ENABLE_LEGACY_API_KEY_FALLBACK="false"

Vercel deployment commands:

npm run build
vercel --prod

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors