Add Swagger docs at /docs and /openapi.json with split OpenAPI spec
Made-with: Cursor
This commit is contained in:
24
backend/openapi/components/schemas/claim.yaml
Normal file
24
backend/openapi/components/schemas/claim.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
QuoteResult:
|
||||
type: object
|
||||
properties:
|
||||
quote_id:
|
||||
type: string
|
||||
payout_sats:
|
||||
type: integer
|
||||
expires_at:
|
||||
type: integer
|
||||
ConfirmResult:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
already_consumed:
|
||||
type: boolean
|
||||
payout_sats:
|
||||
type: integer
|
||||
next_eligible_at:
|
||||
type: integer
|
||||
message:
|
||||
type: string
|
||||
payment_hash:
|
||||
type: string
|
||||
12
backend/openapi/components/schemas/common.yaml
Normal file
12
backend/openapi/components/schemas/common.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
ApiError:
|
||||
type: object
|
||||
required: [code, message]
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
details:
|
||||
type: string
|
||||
next_eligible_at:
|
||||
type: integer
|
||||
64
backend/openapi/components/schemas/faucet.yaml
Normal file
64
backend/openapi/components/schemas/faucet.yaml
Normal file
@@ -0,0 +1,64 @@
|
||||
FaucetConfig:
|
||||
type: object
|
||||
properties:
|
||||
faucetEnabled:
|
||||
type: boolean
|
||||
emergencyStop:
|
||||
type: boolean
|
||||
cooldownDays:
|
||||
type: integer
|
||||
minAccountAgeDays:
|
||||
type: integer
|
||||
minActivityScore:
|
||||
type: integer
|
||||
faucetMinSats:
|
||||
type: integer
|
||||
faucetMaxSats:
|
||||
type: integer
|
||||
Stats:
|
||||
type: object
|
||||
properties:
|
||||
balanceSats:
|
||||
type: integer
|
||||
totalPaidSats:
|
||||
type: integer
|
||||
totalClaims:
|
||||
type: integer
|
||||
claimsLast24h:
|
||||
type: integer
|
||||
dailyBudgetSats:
|
||||
type: integer
|
||||
spentTodaySats:
|
||||
type: integer
|
||||
recentPayouts:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
pubkey_prefix:
|
||||
type: string
|
||||
payout_sats:
|
||||
type: integer
|
||||
claimed_at:
|
||||
type: integer
|
||||
recentDeposits:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
amount_sats:
|
||||
type: integer
|
||||
source:
|
||||
type: string
|
||||
enum: [lightning, cashu]
|
||||
created_at:
|
||||
type: integer
|
||||
DepositInfo:
|
||||
type: object
|
||||
properties:
|
||||
lightningAddress:
|
||||
type: string
|
||||
nullable: true
|
||||
lnurlp:
|
||||
type: string
|
||||
nullable: true
|
||||
9
backend/openapi/components/schemas/user.yaml
Normal file
9
backend/openapi/components/schemas/user.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
UserProfile:
|
||||
type: object
|
||||
properties:
|
||||
lightning_address:
|
||||
type: string
|
||||
nullable: true
|
||||
name:
|
||||
type: string
|
||||
nullable: true
|
||||
9
backend/openapi/components/security.yaml
Normal file
9
backend/openapi/components/security.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
NIP98:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: Nostr
|
||||
description: NIP-98 HTTP Auth (Authorization Nostr <base64(json)>)
|
||||
BearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
60
backend/openapi/index.yaml
Normal file
60
backend/openapi/index.yaml
Normal file
@@ -0,0 +1,60 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: LNFaucet API
|
||||
description: |
|
||||
Lightning Network faucet: request small amounts of sats for testing.
|
||||
Auth via NIP-98 (Nostr) or npub-only (limited).
|
||||
version: 1.0.0
|
||||
servers:
|
||||
- url: http://localhost:3001
|
||||
description: Local development
|
||||
tags:
|
||||
- name: Public
|
||||
description: No authentication required
|
||||
- name: Auth
|
||||
description: NIP-98 or npub login
|
||||
- name: Claim
|
||||
description: Request sats (rate limited)
|
||||
- name: User
|
||||
description: Profile and refresh
|
||||
paths:
|
||||
/health:
|
||||
$ref: './path-items/health.yaml'
|
||||
/config:
|
||||
$ref: './path-items/config.yaml'
|
||||
/stats:
|
||||
$ref: './path-items/stats.yaml'
|
||||
/deposit:
|
||||
$ref: './path-items/deposit.yaml'
|
||||
/deposit/redeem-cashu:
|
||||
$ref: './path-items/deposit-redeem-cashu.yaml'
|
||||
/auth/login:
|
||||
$ref: './path-items/auth-login.yaml'
|
||||
/auth/login-npub:
|
||||
$ref: './path-items/auth-login-npub.yaml'
|
||||
/auth/me:
|
||||
$ref: './path-items/auth-me.yaml'
|
||||
/claim/quote:
|
||||
$ref: './path-items/claim-quote.yaml'
|
||||
/claim/confirm:
|
||||
$ref: './path-items/claim-confirm.yaml'
|
||||
/user/refresh-profile:
|
||||
$ref: './path-items/user-refresh-profile.yaml'
|
||||
components:
|
||||
securitySchemes:
|
||||
$ref: './components/security.yaml'
|
||||
schemas:
|
||||
FaucetConfig:
|
||||
$ref: './components/schemas/faucet.yaml#/FaucetConfig'
|
||||
Stats:
|
||||
$ref: './components/schemas/faucet.yaml#/Stats'
|
||||
DepositInfo:
|
||||
$ref: './components/schemas/faucet.yaml#/DepositInfo'
|
||||
QuoteResult:
|
||||
$ref: './components/schemas/claim.yaml#/QuoteResult'
|
||||
ConfirmResult:
|
||||
$ref: './components/schemas/claim.yaml#/ConfirmResult'
|
||||
UserProfile:
|
||||
$ref: './components/schemas/user.yaml#/UserProfile'
|
||||
ApiError:
|
||||
$ref: './components/schemas/common.yaml#/ApiError'
|
||||
33
backend/openapi/path-items/auth-login-npub.yaml
Normal file
33
backend/openapi/path-items/auth-login-npub.yaml
Normal file
@@ -0,0 +1,33 @@
|
||||
post:
|
||||
tags: [Auth]
|
||||
summary: Sign in with npub only (limited)
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [npub]
|
||||
properties:
|
||||
npub:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Token and pubkey
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
pubkey:
|
||||
type: string
|
||||
method:
|
||||
type: string
|
||||
example: npub
|
||||
"400":
|
||||
description: Invalid npub
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/common.yaml#/ApiError"
|
||||
20
backend/openapi/path-items/auth-login.yaml
Normal file
20
backend/openapi/path-items/auth-login.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
post:
|
||||
tags: [Auth]
|
||||
summary: Sign in with NIP-98 (returns JWT)
|
||||
security:
|
||||
- NIP98: []
|
||||
responses:
|
||||
"200":
|
||||
description: Token and pubkey
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
pubkey:
|
||||
type: string
|
||||
method:
|
||||
type: string
|
||||
example: nip98
|
||||
23
backend/openapi/path-items/auth-me.yaml
Normal file
23
backend/openapi/path-items/auth-me.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
get:
|
||||
tags: [Auth]
|
||||
summary: Current user from Bearer token
|
||||
security:
|
||||
- BearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: Pubkey and method
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
pubkey:
|
||||
type: string
|
||||
method:
|
||||
type: string
|
||||
"401":
|
||||
description: Unauthorized or invalid token
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/common.yaml#/ApiError"
|
||||
39
backend/openapi/path-items/claim-confirm.yaml
Normal file
39
backend/openapi/path-items/claim-confirm.yaml
Normal file
@@ -0,0 +1,39 @@
|
||||
post:
|
||||
tags: [Claim]
|
||||
summary: Confirm quote and pay (rate limited)
|
||||
security:
|
||||
- BearerAuth: []
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [quote_id]
|
||||
properties:
|
||||
quote_id:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Success or already consumed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/claim.yaml#/ConfirmResult"
|
||||
"400":
|
||||
description: Invalid request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/common.yaml#/ApiError"
|
||||
"404":
|
||||
description: Quote not found or expired
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/common.yaml#/ApiError"
|
||||
"502":
|
||||
description: Lightning payment failed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/common.yaml#/ApiError"
|
||||
28
backend/openapi/path-items/claim-quote.yaml
Normal file
28
backend/openapi/path-items/claim-quote.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
post:
|
||||
tags: [Claim]
|
||||
summary: Create claim quote (rate limited)
|
||||
security:
|
||||
- BearerAuth: []
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [lightning_address]
|
||||
properties:
|
||||
lightning_address:
|
||||
type: string
|
||||
description: user@domain.tld
|
||||
responses:
|
||||
"200":
|
||||
description: Quote
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/claim.yaml#/QuoteResult"
|
||||
"403":
|
||||
description: Not eligible or budget exceeded
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/common.yaml#/ApiError"
|
||||
10
backend/openapi/path-items/config.yaml
Normal file
10
backend/openapi/path-items/config.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
get:
|
||||
tags: [Public]
|
||||
summary: Public faucet config
|
||||
responses:
|
||||
"200":
|
||||
description: Faucet configuration
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/faucet.yaml#/FaucetConfig"
|
||||
48
backend/openapi/path-items/deposit-redeem-cashu.yaml
Normal file
48
backend/openapi/path-items/deposit-redeem-cashu.yaml
Normal file
@@ -0,0 +1,48 @@
|
||||
post:
|
||||
tags: [Public]
|
||||
summary: Redeem Cashu token
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [token]
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
description: Cashu token (cashuA... or cashuB...)
|
||||
responses:
|
||||
"200":
|
||||
description: Redeem result
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
paid:
|
||||
type: boolean
|
||||
amount:
|
||||
type: integer
|
||||
invoiceAmount:
|
||||
type: integer
|
||||
netAmount:
|
||||
type: integer
|
||||
to:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
"400":
|
||||
description: Invalid token or address
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/common.yaml#/ApiError"
|
||||
"502":
|
||||
description: Redeem failed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/common.yaml#/ApiError"
|
||||
10
backend/openapi/path-items/deposit.yaml
Normal file
10
backend/openapi/path-items/deposit.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
get:
|
||||
tags: [Public]
|
||||
summary: Deposit info
|
||||
responses:
|
||||
"200":
|
||||
description: Lightning address and LNURLp
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/faucet.yaml#/DepositInfo"
|
||||
14
backend/openapi/path-items/health.yaml
Normal file
14
backend/openapi/path-items/health.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
get:
|
||||
tags: [Public]
|
||||
summary: Health check
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
example: ok
|
||||
16
backend/openapi/path-items/stats.yaml
Normal file
16
backend/openapi/path-items/stats.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
get:
|
||||
tags: [Public]
|
||||
summary: Faucet stats
|
||||
responses:
|
||||
"200":
|
||||
description: Stats (balance, paid, claims)
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/faucet.yaml#/Stats"
|
||||
"500":
|
||||
description: Internal error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/common.yaml#/ApiError"
|
||||
18
backend/openapi/path-items/user-refresh-profile.yaml
Normal file
18
backend/openapi/path-items/user-refresh-profile.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
post:
|
||||
tags: [User]
|
||||
summary: Refresh Nostr profile (kind 0)
|
||||
security:
|
||||
- BearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: lightning_address and name
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/user.yaml#/UserProfile"
|
||||
"500":
|
||||
description: Profile fetch failed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../components/schemas/common.yaml#/ApiError"
|
||||
Reference in New Issue
Block a user