PaymentOracle β Verifiable Multi-Rail Payment Receipts
PaymentOracle β ES256K-signed receipts for x402 payments on USDC+EURC (Base) and XRP+RLUSD (XRPL).
Ask AI about PaymentOracle β Verifiable Multi-Rail Payment Receipts
Powered by Claude Β· Grounded in docs
I know everything about PaymentOracle β Verifiable Multi-Rail Payment Receipts. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
PaymentOracle
Verifiable multi-rail payment receipts for autonomous agents.
PaymentOracle issues ES256K-signed, externally verifiable receipts for x402 payments across four payment rails. One signing key, one schema, one verify snippet β regardless of which chain settled the underlying transfer.
What this is
PaymentOracle is a small REST + MCP service that:
- Quotes payment intents for tool calls on a chosen rail
- Verifies on-chain transactions against those intents (no custody, read-only RPC)
- Issues ES256K-signed receipts that any third party can verify offline
Each receipt is a small JSON object that says: this exact tool call, on this exact rail, at this exact time, was paid for by this exact transaction. The signing key's public half is published at /.well-known/payment-oracle.json so receipts can be re-verified without trusting the issuer.
The four rails
| Rail | Asset | Chain | Type | Status |
|---|---|---|---|---|
base-usdc-x402 | USDC | Base mainnet (8453) | ERC-20 | live |
xrpl-xrp | XRP | XRPL mainnet | chain-native | live |
xrpl-rlusd | RLUSD | XRPL mainnet | issued asset (IOU) | beta |
base-eurc | EURC | Base mainnet (8453) | ERC-20 | beta |
Three architectures (EVM Transfer events / XRPL native / XRPL IOU), one receipt schema (oraclenet.payment.receipt.v1), one signing key (tooloracle-paymentoracle-es256k-1).
Live endpoints
- Service descriptor: https://tooloracle.io/.well-known/payment-oracle.json
- Latest signed proof: https://tooloracle.io/payments/proof/latest
- MCP endpoint (streamable HTTP): https://tooloracle.io/payments/mcp/
- Landing page: https://tooloracle.io/payment-oracle/
- Deep-dive: https://tooloracle.io/blog/paymentoracle-multi-rail-verifiable-receipts
Live receipts
Every receipt this service has issued is publicly fetchable:
| Rail | Receipt id | Amount | Tx |
|---|---|---|---|
base-usdc-x402 | r_a603fc71β¦ | 1.0 USDC | Base 8453 |
xrpl-xrp | r_9c941c43β¦ | 0.01 XRP | XRPL |
xrpl-rlusd | r_bb5960a6β¦ | 1.0 RLUSD | XRPL |
base-eurc | r_f48be831β¦ | 1.272801 EURC | Base 8453 |
Repository layout
paymentoracle/
βββ service/ REST service (server.js, port 6510 internal)
βββ mcp/ MCP wrapper (server.py, port 6520 internal)
βββ milestones/ Snapshot tarballs from each release phase
βββ docs/ Architecture + verify reference
βββ LICENSE
βββ SECURITY.md
βββ README.md (this file)
Quick start β verify a receipt
# pip install cryptography
import json, hashlib, base64, urllib.request
from cryptography.hazmat.primitives.asymmetric import ec, utils
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
def canon(o): return json.dumps(o, sort_keys=True, separators=(',', ':'), ensure_ascii=False)
# 1. fetch JWK and a live receipt
po = json.load(urllib.request.urlopen("https://tooloracle.io/.well-known/payment-oracle.json"))
rcp = json.load(urllib.request.urlopen("https://tooloracle.io/payments/receipt/r_f48be831573596ad3ebba1e04dc45311"))
jwk = po["receipts"]["public_jwk"]
r = rcp["receipt"]
# 2. recompute the receipt hash
body = {k: v for k, v in r.items() if k not in ("receipt_hash", "signature")}
assert "sha256:" + hashlib.sha256(canon(body).encode()).hexdigest() == r["receipt_hash"]
# 3. verify ES256K signature
sig = base64.urlsafe_b64decode(r["signature"]["sig"] + "==")
x = int.from_bytes(base64.urlsafe_b64decode(jwk["x"] + "=="), "big")
y = int.from_bytes(base64.urlsafe_b64decode(jwk["y"] + "=="), "big")
pub = ec.EllipticCurvePublicNumbers(x, y, ec.SECP256K1()).public_key(default_backend())
so = dict(r); so["signature"] = {"alg": r["signature"]["alg"], "kid": r["signature"]["kid"]}
der = utils.encode_dss_signature(int.from_bytes(sig[:32], "big"), int.from_bytes(sig[32:], "big"))
pub.verify(der, canon(so).encode(), ec.ECDSA(hashes.SHA256()))
print("verified")
Quick start β call from an MCP client
curl -s -X POST https://tooloracle.io/payments/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
The MCP wrapper exposes 6 tools (all free / credits=0):
quote_paymentβ open intent for a tool call on a chosen railverify_paymentβ verify on-chain tx, get verification idissue_receiptβ issue ES256K-signed receipt for verified paymentget_receiptβ fetch any issued receipt by idget_proof_latestβ most recent signed payment proofhealth_checkβ service status, version, supported rails, signing kid
Architecture
See docs/ARCHITECTURE.md for the three verification architectures (EVM, XRPL native, XRPL IOU) and how the receipt schema unifies them.
Building locally
This repository contains the source of two services that run on tooloracle.io. The services share a host but listen on different ports:
service/server.jsβ Node.js REST service, port 6510 internalmcp/server.pyβ Python MCP wrapper, port 6520 internal
Both services depend on a runtime environment that is not in this repository:
- The ES256K signing key (per-deployment, kept at host mode 0600)
- The XRPL receiving wallet seed (per-deployment)
- A SQLite database for intent/verification/receipt state
- The Whitelabel MCP base class (the wrapper inherits from this)
If you want to run your own PaymentOracle, the source here is a reference implementation. Production-grade operation requires the full whitelabel platform.
Security
Vulnerability reports go to security@feedoracle.io. See SECURITY.md for details.
License
MIT β Β© 2026 FeedOracle Technologies (Murat Keskin).
