diff --git a/bin/server.js b/bin/server.js index 73bc9bf..2c652f5 100644 --- a/bin/server.js +++ b/bin/server.js @@ -252,6 +252,19 @@ class Server { res.sendFile(docsPath) }) + // AI-friendly discovery endpoints + app.get('/llms.txt', (req, res) => { + const llmsPath = join(__dirname, '..', 'public', 'llms.txt') + res.setHeader('Content-Type', 'text/plain') + res.sendFile(llmsPath) + }) + + app.get('/openapi.json', (req, res) => { + const openapiPath = join(__dirname, '..', 'public', 'openapi.json') + res.setHeader('Content-Type', 'application/json') + res.sendFile(openapiPath) + }) + // MIDDLEWARE END console.log(`Running server in environment: ${this.config.env}`) diff --git a/public/llms.txt b/public/llms.txt new file mode 100644 index 0000000..0d4c3d3 --- /dev/null +++ b/public/llms.txt @@ -0,0 +1,74 @@ +# psf-bch-api - Bitcoin Cash Blockchain API + +> A comprehensive REST API for Bitcoin Cash blockchain data, with x402 micropayment support. + +## Overview + +psf-bch-api provides REST API access to Bitcoin Cash (BCH) blockchain infrastructure. It aggregates data from multiple sources (full node, Fulcrum indexer, SLP token indexer) into a unified API interface. + +**Payment Model:** x402 micropayments (~$0.001/call via USDC on Base, or BCH on x402-bch) + +**Base URL:** https://x402.fullstack.cash/v6 + +## API Endpoints + +### Fulcrum (Address/UTXO Operations) +- `GET /v6/fulcrum/balance/:address` - Get BCH balance for an address +- `POST /v6/fulcrum/balance` - Bulk balance lookup (array of addresses) +- `GET /v6/fulcrum/utxos/:address` - Get UTXOs for an address +- `POST /v6/fulcrum/utxos` - Bulk UTXO lookup +- `GET /v6/fulcrum/tx/data/:txid` - Get transaction details +- `POST /v6/fulcrum/tx/data` - Bulk transaction lookup +- `POST /v6/fulcrum/tx/broadcast` - Broadcast raw transaction +- `GET /v6/fulcrum/transactions/:address` - Get transaction history for address +- `POST /v6/fulcrum/transactions` - Bulk transaction history lookup + +### Full Node (Blockchain Data) +- `GET /v6/full-node/blockchain/getBestBlockHash` - Get best block hash +- `GET /v6/full-node/blockchain/getBlockchainInfo` - Get blockchain info +- `GET /v6/full-node/blockchain/getBlockCount` - Get current block height +- `GET /v6/full-node/blockchain/getBlockHash/:height` - Get block hash by height +- `POST /v6/full-node/blockchain/getBlock` - Get block data +- `GET /v6/full-node/blockchain/getBlockHeader/:hash` - Get block header +- `GET /v6/full-node/blockchain/getDifficulty` - Get network difficulty +- `GET /v6/full-node/blockchain/getMempoolInfo` - Get mempool info +- `GET /v6/full-node/blockchain/getRawMempool` - Get raw mempool + +### Raw Transactions +- `GET /v6/full-node/rawtransactions/getRawTransaction/:txid` - Get raw transaction +- `POST /v6/full-node/rawtransactions/getRawTransaction` - Bulk raw transaction lookup +- `GET /v6/full-node/rawtransactions/decodeRawTransaction/:hex` - Decode raw transaction +- `GET /v6/full-node/rawtransactions/sendRawTransaction/:hex` - Broadcast raw transaction + +### SLP Tokens (Simple Ledger Protocol) +- `GET /v6/slp/status` - Get SLP indexer status +- `POST /v6/slp/address` - Get SLP tokens at address +- `POST /v6/slp/txid` - Get SLP transaction data +- `POST /v6/slp/token` - Get SLP token stats +- `POST /v6/slp/token/data` - Get full SLP token data + +### Price +- `GET /v6/price/bchusd` - Get BCH/USD price +- `GET /v6/price/psffpp` - Get PSFFPP write price + +### Encryption +- `GET /v6/encryption/publickey/:address` - Get public key for address + +## Payment + +This API uses the x402 payment protocol. Requests require: +- Payment header with signed authorization +- Cost: ~$0.001 USD per call (USDC on Base) + +For more information on x402: +- Documentation: https://docs.cdp.coinbase.com/x402/ +- Protocol: https://www.x402.org/ + +## OpenAPI Specification + +Full API specification available at: `/openapi.json` + +## Support + +- GitHub: https://github.com/Permissionless-Software-Foundation/psf-bch-api +- FullStack.cash: https://fullstack.cash diff --git a/public/openapi.json b/public/openapi.json new file mode 100644 index 0000000..fb7fa14 --- /dev/null +++ b/public/openapi.json @@ -0,0 +1,493 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "psf-bch-api", + "description": "Bitcoin Cash Blockchain API with x402 micropayment support. Provides access to BCH blockchain data, UTXOs, transactions, and SLP tokens via REST endpoints.", + "version": "7.0.0", + "contact": { + "name": "FullStack.cash", + "url": "https://fullstack.cash" + } + }, + "servers": [ + { + "url": "https://x402.fullstack.cash/v6", + "description": "Production (x402 payments - USDC on Base)" + }, + { + "url": "https://x402-bch.fullstack.cash/v6", + "description": "Production (x402 payments - BCH)" + }, + { + "url": "https://bch.fullstack.cash/v6", + "description": "Development (free, rate-limited)" + } + ], + "paths": { + "/health": { + "get": { + "summary": "Health Check", + "description": "Returns service health status", + "responses": { + "200": { + "description": "Service is healthy", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "status": { "type": "string", "example": "ok" }, + "service": { "type": "string" }, + "version": { "type": "string" } + } + } + } + } + } + } + } + }, + "/fulcrum/balance/{address}": { + "get": { + "summary": "Get Balance", + "description": "Get Bitcoin Cash balance for a single address", + "parameters": [ + { + "name": "address", + "in": "path", + "required": true, + "schema": { "type": "string" }, + "description": "Bitcoin Cash address" + } + ], + "responses": { + "200": { + "description": "Balance information", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "balance": { "type": "number" }, + "balanceConfirmed": { "type": "number" }, + "balanceUnconfirmed": { "type": "number" } + } + } + } + } + }, + "402": { + "description": "Payment required - x402 header missing" + } + } + } + }, + "/fulcrum/utxos/{address}": { + "get": { + "summary": "Get UTXOs", + "description": "Get unspent transaction outputs for an address", + "parameters": [ + { + "name": "address", + "in": "path", + "required": true, + "schema": { "type": "string" }, + "description": "Bitcoin Cash address" + } + ], + "responses": { + "200": { + "description": "Array of UTXOs", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "txid": { "type": "string" }, + "vout": { "type": "integer" }, + "satoshis": { "type": "integer" }, + "height": { "type": "integer" }, + "confirmations": { "type": "integer" } + } + } + } + } + } + } + } + } + }, + "/fulcrum/tx/data/{txid}": { + "get": { + "summary": "Get Transaction Details", + "description": "Get detailed information about a transaction", + "parameters": [ + { + "name": "txid", + "in": "path", + "required": true, + "schema": { "type": "string" }, + "description": "Transaction ID" + } + ], + "responses": { + "200": { + "description": "Transaction details", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "txid": { "type": "string" }, + "version": { "type": "integer" }, + "locktime": { "type": "integer" }, + "vin": { "type": "array" }, + "vout": { "type": "array" }, + "confirmations": { "type": "integer" }, + "time": { "type": "integer" }, + "blocktime": { "type": "integer" }, + "blockhash": { "type": "string" }, + "blockheight": { "type": "integer" }, + "size": { "type": "integer" }, + "valueIn": { "type": "number" }, + "valueOut": { "type": "number" } + } + } + } + } + } + } + } + }, + "/fulcrum/tx/broadcast": { + "post": { + "summary": "Broadcast Transaction", + "description": "Broadcast a raw transaction to the BCH network", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "hex": { "type": "string", "description": "Raw transaction hex" } + }, + "required": ["hex"] + } + } + } + }, + "responses": { + "200": { + "description": "Transaction broadcast result", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "txid": { "type": "string" }, + "message": { "type": "string" } + } + } + } + } + } + } + } + }, + "/full-node/blockchain/getBlockchainInfo": { + "get": { + "summary": "Get Blockchain Info", + "description": "Get general blockchain information including chain, blocks, difficulty", + "responses": { + "200": { + "description": "Blockchain info", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "chain": { "type": "string" }, + "blocks": { "type": "integer" }, + "headers": { "type": "integer" }, + "bestblockhash": { "type": "string" }, + "difficulty": { "type": "number" }, + "mediantime": { "type": "integer" }, + "verificationprogress": { "type": "number" }, + "chainwork": { "type": "string" } + } + } + } + } + } + } + } + }, + "/full-node/blockchain/getBlockCount": { + "get": { + "summary": "Get Block Count", + "description": "Get current block height", + "responses": { + "200": { + "description": "Current block count", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "blockcount": { "type": "integer" } + } + } + } + } + } + } + } + }, + "/full-node/blockchain/getBlockHash/{height}": { + "get": { + "summary": "Get Block Hash", + "description": "Get block hash by height", + "parameters": [ + { + "name": "height", + "in": "path", + "required": true, + "schema": { "type": "integer" }, + "description": "Block height" + } + ], + "responses": { + "200": { + "description": "Block hash", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "hash": { "type": "string" } + } + } + } + } + } + } + } + }, + "/full-node/rawtransactions/getRawTransaction/{txid}": { + "get": { + "summary": "Get Raw Transaction", + "description": "Get raw transaction hex by TXID", + "parameters": [ + { + "name": "txid", + "in": "path", + "required": true, + "schema": { "type": "string" }, + "description": "Transaction ID" + } + ], + "responses": { + "200": { + "description": "Raw transaction", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "hex": { "type": "string" }, + "txid": { "type": "string" }, + "version": { "type": "integer" }, + "locktime": { "type": "integer" }, + "vin": { "type": "array" }, + "vout": { "type": "array" } + } + } + } + } + } + } + } + }, + "/full-node/rawtransactions/sendRawTransaction/{hex}": { + "get": { + "summary": "Send Raw Transaction", + "description": "Broadcast a raw transaction", + "parameters": [ + { + "name": "hex", + "in": "path", + "required": true, + "schema": { "type": "string" }, + "description": "Raw transaction hex" + } + ], + "responses": { + "200": { + "description": "Broadcast result", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "txid": { "type": "string" } + } + } + } + } + } + } + } + }, + "/slp/status": { + "get": { + "summary": "SLP Status", + "description": "Get SLP token indexer status", + "responses": { + "200": { + "description": "SLP indexer status", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "status": { "type": "string" }, + "blockHeight": { "type": "integer" } + } + } + } + } + } + } + } + }, + "/slp/address": { + "post": { + "summary": "Get SLP Address Data", + "description": "Get SLP token balances for an address", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "address": { "type": "string", "description": "SLP address" } + }, + "required": ["address"] + } + } + } + }, + "responses": { + "200": { + "description": "SLP token balances", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "balances": { + "type": "array", + "items": { + "type": "object", + "properties": { + "tokenId": { "type": "string" }, + "ticker": { "type": "string" }, + "name": { "type": "string" }, + "balance": { "type": "string" } + } + } + } + } + } + } + } + } + } + } + }, + "/slp/token": { + "post": { + "summary": "Get Token Stats", + "description": "Get statistics for a specific SLP token", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "tokenId": { "type": "string", "description": "Token ID" } + }, + "required": ["tokenId"] + } + } + } + }, + "responses": { + "200": { + "description": "Token statistics" + } + } + } + }, + "/price/bchusd": { + "get": { + "summary": "Get BCH Price", + "description": "Get current BCH/USD price", + "responses": { + "200": { + "description": "BCH price in USD", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "price": { "type": "number" } + } + } + } + } + } + } + } + }, + "/encryption/publickey/{address}": { + "get": { + "summary": "Get Public Key", + "description": "Get public key for a Bitcoin Cash address", + "parameters": [ + { + "name": "address", + "in": "path", + "required": true, + "schema": { "type": "string" } + } + ], + "responses": { + "200": { + "description": "Public key data" + } + } + } + } + }, + "components": { + "securitySchemes": { + "x402": { + "type": "apiKey", + "in": "header", + "name": "X-PAYMENT", + "description": "x402 payment header with signed authorization" + } + } + }, + "security": [ + { + "x402": [] + } + ] +}