Skip to main content

Service Challenge Integration

Practical guide to integrating MatMul service challenges for API rate limiting, spam prevention, and AI endpoint gating.

This guide walks through integrating BTX MatMul service challenges into your application. Service challenges let you require computational proof-of-work from clients before admitting requests — useful for API rate limiting, signup spam prevention, and AI inference endpoint gating.

For the RPC reference, see Service Challenge RPCs.


Architecture

The service challenge flow involves three participants: your application server, a BTX node, and the client.

┌──────────┐    1. Issue challenge     ┌──────────┐
│          │ ──────────────────────── ▶ │          │
│  Your    │    (getmatmulservice       │  BTX     │
│  App     │     challenge)             │  Node    │
│  Server  │                            │  :19334  │
│          │ ◀ ──────────────────────── │          │
│          │    challenge envelope       │          │
└────┬─────┘                            └────┬─────┘
     │                                       │
     │  2. Send envelope to client           │
     ▼                                       │
┌──────────┐                                 │
│  Client  │    3. Solve MatMul puzzle       │
│          │       (local computation)       │
└────┬─────┘                                 │
     │                                       │
     │  4. Return proof (nonce + digest)     │
     ▼                                       │
┌──────────┐    5. Redeem proof         ┌────┴─────┐
│  Your    │ ──────────────────────── ▶ │  BTX     │
│  App     │    (redeemmatmulservice    │  Node    │
│  Server  │     proof)                 │          │
│          │ ◀ ──────────────────────── │          │
│          │    valid/redeemed/reason    │          │
└──────────┘                            └──────────┘

Key properties of this flow:

  • Each challenge is one-shot — once redeemed, replay returns already_redeemed
  • Challenges are domain-bound to a purpose, resource, and subject
  • Work is anchored to current chain state, so pre-computation is time-limited
  • Verification is cheap relative to the solve cost

The Core Flow

Step 1: Issue a Challenge

Call getmatmulservicechallenge with bindings for your use case:

curl --silent --user "$BTX_RPC_USER:$BTX_RPC_PASSWORD" \
  --data-binary '{
    "jsonrpc":"1.0",
    "id":"issue",
    "method":"getmatmulservicechallenge",
    "params":["rate_limit","signup:/v1/messages","user:[email protected]",2,300,0.25,0.75]
  }' \
  -H 'content-type: text/plain;' \
  http://127.0.0.1:19334/

The parameters are:

PositionNameDescription
1purposeChallenge domain: rate_limit, api_gate, ai_inference_gate
2resourceThe protected resource, e.g. signup:/v1/messages
3subjectThe requester identity, e.g. user:[email protected] or ip:203.0.113.5
4target_solve_time_sTarget solve time in seconds (difficulty calibration)
5expiry_sChallenge validity window in seconds
6min_difficulty_factorMinimum difficulty relative to network (0.0-1.0)
7max_difficulty_factorMaximum difficulty relative to network (0.0-1.0)

The response contains a challenge envelope with:

  • challenge_id — unique identifier for replay protection
  • issued_at / expires_at — validity window
  • header_context — chain-anchored header for deterministic seeds
  • target — difficulty target the client must meet
  • MatMul seeds derived from the challenge_id

Step 2: Client Solves the Challenge

Send the challenge envelope to the client. The client performs the MatMul computation locally — multiplying matrices, hashing the result, and searching for a nonce whose digest meets the target. The output is a nonce64_hex and digest_hex.

Step 3: Redeem the Proof

When the client returns the proof, call redeemmatmulserviceproof:

curl --silent --user "$BTX_RPC_USER:$BTX_RPC_PASSWORD" \
  --data-binary '{
    "jsonrpc":"1.0",
    "id":"redeem",
    "method":"redeemmatmulserviceproof",
    "params":[CHALLENGE_ENVELOPE,"0000000000000001","DIGEST_HEX"]
  }' \
  -H 'content-type: text/plain;' \
  http://127.0.0.1:19334/

Accept the request only when all three conditions hold:

  • valid = true
  • reason = "ok"
  • redeemed = true

Integration Patterns

Signup and Comment Spam Prevention

Require proof-of-work before accepting form submissions. This raises the cost of automated spam without blocking legitimate users.

BindingRecommended Value
purposerate_limit
resourcesignup:/v1/messages or comment:/v1/posts/:id
subjectuser:<id> or ip:<bucket>
expiry60-300 seconds
target_solve_time_s1-3 seconds (high enough to price abuse, low enough for UX)

Issue the challenge on form render or just before submission. Redeem on final submit, not on initial page load.

API Rate Limiting

Gate public API endpoints behind proof-of-work instead of (or alongside) API key quotas.

BindingRecommended Value
purposeapi_gate
resourcePOST:/v1/inference or GET:/v1/search
subjectapi_key:<id> or tenant:<id>

Use shorter expiries and redeem on request receipt so stale pre-computation is less useful.

AI Inference Endpoint Gating

Protect expensive AI model endpoints by requiring useful work before inference is admitted. This is effective for free-tier throttling, anonymous endpoint hardening, and protecting multimodal routes.

BindingRecommended Value
purposeai_inference_gate
resourcemodel:gpt-x|route:/v1/generate|tier:free
subjecttenant:abc123

Scale puzzle cost by endpoint sensitivity, user trust level, or tenant risk score using getmatmulchallengeprofile to calibrate difficulty for a specific target solve time.


Batch Redemption

High-throughput gateways should use redeemmatmulserviceproofs to redeem multiple proofs in a single RPC round trip:

curl --silent --user "$BTX_RPC_USER:$BTX_RPC_PASSWORD" \
  --data-binary '{
    "jsonrpc":"1.0",
    "id":"redeem-batch",
    "method":"redeemmatmulserviceproofs",
    "params":[[
      {
        "challenge": "CHALLENGE_A",
        "nonce64_hex": "0000000000000001",
        "digest_hex": "DIGEST_A"
      },
      {
        "challenge": "CHALLENGE_B",
        "nonce64_hex": "0000000000000002",
        "digest_hex": "DIGEST_B"
      }
    ]]
  }' \
  -H 'content-type: text/plain;' \
  http://127.0.0.1:19334/

Batch semantics:

  • Processing order is preserved
  • The operation is sequential, not all-or-nothing
  • Duplicate or already-redeemed proofs return already_redeemed
  • Unknown cross-node challenges return unknown_challenge

The response includes count, valid, invalid, by_reason, and ordered per-item results.


Difficulty Calibration

Use getmatmulchallengeprofile to get a challenge shape for a custom solve-time target. This lets you dynamically price work based on:

  • Endpoint sensitivity (a public comments form vs. a free-tier AI image endpoint)
  • User trust level (verified accounts get easier puzzles)
  • Tenant risk score
  • Live network conditions (via getdifficultyhealth)

Example: a public comments endpoint might target 1 second of solve time, while a free-tier AI image generation route might target 4 seconds.


Deployment Considerations

Single-Node Deployment

The simplest deployment runs issuance and redemption on the same BTX node:

  • Issue with getmatmulservicechallenge
  • Redeem on the same node with redeemmatmulserviceproof
  • Challenge state lives in the node's local process memory
  • Capacity: 10,000 active issued challenges per node

This is production-ready for most use cases.

Multi-Node Deployment

The issued-challenge store is currently local process memory only. This means:

  • Daemon restarts clear outstanding challenge state
  • Cross-node redemption is rejected as unknown_challenge
  • Horizontally scaled frontends need sticky routing to ensure redemption hits the issuing node

For production multi-node deployments, route requests with session affinity or deploy a shared challenge store layer in front of multiple BTX nodes.


Verify vs. Redeem

BTX provides two verification paths:

RPCReplay Safe?Use When
verifymatmulserviceproofNoDiagnostics, offline checking, debugging
redeemmatmulserviceproofYesProduction admission control

Always use redeem for real admission control. Stateless verify alone does not prevent replay.


What BTX Does and Does Not Prove

BTX proves that useful matrix-multiplication work was performed against a BTX-defined challenge and that the resulting digest met the required target.

BTX does not prove that:

  • A specific AI model produced a specific output
  • A claimed inference trace was faithful
  • An application request should be authorized for business reasons

For semantic proof-of-inference, pair BTX admission control with a verifiable inference layer such as Jolt Atlas, EZKL, or RISC Zero.


Comparison with Other Defenses

MechanismProves WorkCheap to VerifyReusable for AI InfraGood for Spam
BTX service challengeYesYesYesYes
Hashcash-style hash puzzleYesYesNoYes
CAPTCHANoN/ANoSometimes
API key / auth onlyNoYesN/AWeak
Verifiable inference layerExecution onlyExpensiveSometimesIndirectly