Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dgb-tollgate

DigiDollar paywall proxy for MCP servers — plus an autonomous paying client.

v0.1 is the paywall proxy (src/server.js): it returns HTTP 402 with a DigiDollar invoice and issues bearer tokens after payment. v0.2 is the paying client (src/client.js): a stdio MCP server an AI agent connects to; it detects 402, pays DigiDollar automatically (within spend caps), obtains a token, and mirrors upstream tools — no human in the loop.

TESTNET ONLY — not audited

This is v0.1 research / demo software. Default REQUIRE_TESTNET=true refuses to run against a non-test chain. Do not use on mainnet with real funds. There is no security audit. Expect breaking changes. You run this at your own risk.

Flow (v0.1 tollgate proxy)

Agent                         dgb-tollgate                      Your node / upstream
  |                                |                                   |
  |-- MCP request (no token) ----->|                                   |
  |<- 402 + fresh DD invoice ------|                                   |
  |                                |-- getdigidollaraddress ---------->|
  |                                |                                   |
  |-- pay DigiDollar to payTo --------------------------------------> chain
  |                                |                                   |
  |-- POST /token { invoiceId } -->|                                   |
  |                                |-- listdigidollarutxos (own node) ->|
  |<- { token } -------------------|(only if address balance ≥ price)  |
  |                                |                                   |
  |-- MCP + Authorization: Bearer >|                                   |
  |                                |-- reverse-proxy ----------------->| upstream MCP
  |<- upstream response -----------|<- streamed response --------------|

Flow (v0.2 autonomous loop)

Claude / agent                paying client (stdio)           tollgate (v0.1)        upstream MCP
  |                                |                              |                        |
  |-- MCP stdio ------------------>|                              |                        |
  |                                |-- HTTP MCP (no token) ------>|                        |
  |                                |<- 402 + DD invoice ----------|                        |
  |                                |-- senddigidollar (wallet) ---> node                   |
  |                                |-- POST /token -------------->|                        |
  |                                |<- bearer token ---------------|                        |
  |                                |-- HTTP MCP + Bearer -------->|-- proxy ------------->|
  |<- tool result ------------------|<- upstream response ----------|<-----------------------|

The paying client caches the bearer token until expiry. It only pays again when there is no valid token. Spend caps (DD_MAX_PAYMENT_USD, DD_MAX_DAILY_USD) are enforced before any senddigidollar call.

  1. Unpaid request → HTTP 402 with a fresh DigiDollar address and invoice id.
  2. Agent pays that address in DigiDollar (minimum $1.00 — consensus floor).
  3. POST /token with { "invoiceId" } → tollgate checks its own node (listdigidollarutxos at the invoice address). Client txids are never trusted.
  4. On success, a short-lived HMAC-SHA256 bearer token is issued.
  5. Requests with a valid Bearer token are reverse-proxied to UPSTREAM_MCP_URL (method, headers, body; streamed response).

Quick start

npm install

# Configure (placeholders only in the repo — use your own secrets locally)
cp .env.example .env   # then edit; do not commit .env

# Terminal A — example upstream MCP (one tool: echo)
npm run upstream

# Terminal B — tollgate (loads env from your shell / dotenv of your choice)
export $(grep -v '^#' .env | xargs)   # or use your preferred env loader
npm start

# Terminal C — v0.1 walkthrough (payment step is manual)
npm run demo

# Or: v0.2 autonomous loop (payment is automatic)
npm run paid-demo

Paying client (v0.2)

Point your MCP host at the stdio server (bin: dgb-tollgate-client):

{
  "mcpServers": {
    "dgb-tollgate-client": {
      "command": "node",
      "args": ["/path/to/dgb-tollgate/src/client.js"],
      "env": {
        "TOLLGATE_URL": "http://127.0.0.1:8080/mcp",
        "TOLLGATE_TOKEN_URL": "http://127.0.0.1:8080/token",
        "DGB_RPC_URL": "http://127.0.0.1:14023",
        "DGB_RPC_USER": "rpcuser",
        "DGB_RPC_PASSWORD": "…",
        "DGB_WALLET": "wallet-name",
        "DD_MAX_PAYMENT_USD": "5",
        "DD_MAX_DAILY_USD": "25"
      }
    }
  }
}

Or: npm run client (with the same env vars exported in your shell).

Config

Tollgate server (v0.1)

Variable Required Default Description
UPSTREAM_MCP_URL yes — Streamable-HTTP MCP endpoint to protect
PRICE_USD yes — Price per token; must be ≥ 1.00
TOKEN_TTL_SECONDS no 3600 Bearer token lifetime after payment
TOLLGATE_SECRET yes — HMAC signing secret (≥ 16 chars)
DGB_RPC_URL yes — DigiByte Core RPC URL
DGB_RPC_USER yes — RPC username
DGB_RPC_PASSWORD yes — RPC password
DGB_WALLET yes — Wallet name (fresh DD addresses)
REQUIRE_TESTNET no true Exit unless node chain is test
PORT no 8080 Tollgate listen port
INVOICE_TTL_SECONDS no 900 How long an unpaid invoice is valid
MIN_CONFIRMATIONS no 1 Confirmations required for payment
MAX_OUTSTANDING_INVOICES no 1000 Cap on unsettled invoices; excess requests get HTTP 429

Startup rejects PRICE_USD < 1.00 because DigiDollar cannot create outputs below $1.00.

Paying client (v0.2)

Variable Required Default Description
TOLLGATE_URL yes — Paywalled Streamable-HTTP MCP endpoint
TOLLGATE_TOKEN_URL yes — Tollgate POST /token URL
DGB_RPC_URL yes — DigiByte Core RPC (wallet that pays)
DGB_RPC_USER yes — RPC username
DGB_RPC_PASSWORD yes — RPC password
DGB_WALLET yes — Wallet name used for senddigidollar
DD_MAX_PAYMENT_USD no 5 Per-payment spend cap
DD_MAX_DAILY_USD no 25 Rolling 24h spend cap
REQUIRE_TESTNET no true Exit unless node chain is test
PAY_POLL_TIMEOUT_MS no 90000 Max wait for /token after payment
PAY_POLL_INTERVAL_MS no 3000 Poll interval for /token

Security model (do not weaken)

  • Payment is verified only by querying your DigiByte node for DigiDollar UTXOs at the invoice address. A client-supplied txid is never proof.
  • Fresh DigiDollar address per invoice so “paid?” = address balance lookup.
  • Bearer tokens are HMAC-SHA256 over { invoiceId, exp }; verification uses a constant-time compare.
  • Secrets and tokens are never logged.
  • Testnet guard is on by default.
  • The paying client enforces spend caps before payment (allowance, not custody).
  • senddigidollar always receives integer cents (never decimal dollars).

API surface

Method Path Auth Behavior
POST /token none Body { invoiceId } → verify payment → { token, tokenType, expiresAt, invoiceId }
* any other Bearer Valid token → proxy to upstream; else 402 + new invoice

Example 402 body

{
  "x402Version": 1,
  "error": "Payment Required",
  "accepts": [
    {
      "scheme": "exact",
      "network": "digibyte-testnet",
      "asset": "DigiDollar",
      "payTo": "<fresh-dd-address>",
      "amountUsd": 1,
      "amountCents": 100,
      "invoiceId": "<uuid>",
      "expiresAt": "2026-01-01T00:15:00.000Z"
    }
  ],
  "hint": "Pay the DigiDollar amount to payTo, then POST /token ..."
}

Layout

src/server.js          v0.1 tollgate proxy (Express)
src/client.js          v0.2 paying MCP client (stdio)
src/payer.js           DigiDollar payment + spend-cap policy
example/upstream-mcp.js   Minimal Streamable-HTTP MCP (tool: echo)
example/demo.sh           v0.1: manual payment walkthrough
example/paid-agent-demo.sh   v0.2: fully autonomous payment demo
reference/           Proven modules from dgb-x402 (source of security model)

Non-goals (v0.1 / v0.2)

  • Per-tool pricing (all-or-nothing per token)
  • Digi-ID identity gating
  • Batch / metered settlement
  • stdio→HTTP bridging (upstream must already be HTTP)
  • Multi-tenant dashboards or durable persistence

License

MIT

About

DigiDollar paywall for MCP servers + an autonomous paying client. An agent hits a 402, pays in DigiDollar within spend caps, and gets the tool — no human in the loop. Testnet-proven.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages