feat(ui): Ghibli/Miyazaki reskin + Obsidian docs vault + project audit
UI: warm daylight design system (Tailwind v4 @theme palette, gh-* component classes, watercolor grain, Zen Maru Gothic + Klee One fonts), animated SSR-safe GhibliBackground (drifting clouds, meadow hills, soot sprites), and a full reskin of navbar, connect button, dapp page, loan cards, settings modal, and readme. Fixes the bg-white-on-dark loan-card inconsistency. Web3/business logic untouched. Docs: converted docs/ into an Obsidian vault (frontmatter, [[wikilinks]], callouts, Home MOC, folders Architecture/Operations/Audits) and added a full-project audit note (Project Audit 2026-06). Redacted a real leaked Schedy key value from the security audit example (rotate it at Schedy). Also commits the previously-untracked server layer: app/api (cron + tasks routes) and lib (redis, ssrf-guard, task-store). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
211
docs/Architecture/API Reference.md
Normal file
211
docs/Architecture/API Reference.md
Normal file
@@ -0,0 +1,211 @@
|
||||
---
|
||||
title: API Reference
|
||||
tags: [mortgagefi, api, reference]
|
||||
type: reference
|
||||
status: stable
|
||||
updated: 2026-06-14
|
||||
---
|
||||
|
||||
# API Reference
|
||||
|
||||
## nftcache API
|
||||
|
||||
Base URL: `http://localhost:8090` (or `/nftcache` when proxied)
|
||||
|
||||
### Authentication
|
||||
|
||||
> [!info]
|
||||
> If `NFTCACHE_API_KEY` is configured, include it in the `X-API-Key` header for all requests.
|
||||
|
||||
---
|
||||
|
||||
### GET /nfts
|
||||
|
||||
Returns token IDs owned by a specific wallet for a given NFT contract.
|
||||
|
||||
**Query Parameters:**
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `network` | string | Yes | Network key: `eth`, `arb`, `base` |
|
||||
| `nft_contract` | string | Yes | Contract address or config slug (e.g., `cbbtc`) |
|
||||
| `user_wallet` | string | Yes | Owner wallet address |
|
||||
|
||||
**Response (200):**
|
||||
```json
|
||||
{
|
||||
"token_ids": ["1", "5", "42"],
|
||||
"source": "cache"
|
||||
}
|
||||
```
|
||||
|
||||
**Sources:**
|
||||
- `cache` — Returned from BadgerDB cache
|
||||
- `refreshed` — Fetched live from RPC and cached
|
||||
|
||||
**Errors:**
|
||||
- `400` — Missing required parameters
|
||||
- `401` — Invalid or missing API key
|
||||
- `502` — RPC fetch error (rate limit, node unavailable)
|
||||
|
||||
---
|
||||
|
||||
### POST /nfts/refresh
|
||||
|
||||
Force a full refresh of the contract ownership cache.
|
||||
|
||||
**Query Parameters:**
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `network` | string | Yes | Network key |
|
||||
| `nft_contract` | string | Yes | Contract address or slug |
|
||||
|
||||
**Response:**
|
||||
- `204 No Content` — Success
|
||||
- `401` — Unauthorized
|
||||
- `502` — RPC error
|
||||
|
||||
---
|
||||
|
||||
### POST /nfts/invalidate
|
||||
|
||||
Delete a contract's cache entry.
|
||||
|
||||
**Query Parameters:**
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `network` | string | Yes | Network key |
|
||||
| `nft_contract` | string | Yes | Contract address |
|
||||
|
||||
**Response:**
|
||||
- `204 No Content` — Success
|
||||
- `401` — Unauthorized
|
||||
|
||||
---
|
||||
|
||||
## Schedy API
|
||||
|
||||
Base URL: `http://localhost:8080` (or `/schedy` when proxied)
|
||||
|
||||
### Authentication
|
||||
|
||||
> [!info]
|
||||
> If `SCHEDY_API_KEY` is configured, include it in the `X-API-Key` header for all requests.
|
||||
|
||||
---
|
||||
|
||||
### POST /tasks
|
||||
|
||||
Create a new scheduled task.
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"url": "https://ntfy.sh/mytopic",
|
||||
"headers": {
|
||||
"Content-Type": "text/plain",
|
||||
"X-Email": "user@example.com"
|
||||
},
|
||||
"payload": "Your position is approaching liquidation",
|
||||
"execute_at": "2026-05-10T12:00:00Z",
|
||||
"retries": 3,
|
||||
"retry_interval": 2000
|
||||
}
|
||||
```
|
||||
|
||||
**Fields:**
|
||||
| Field | Type | Required | Default | Description |
|
||||
|-------|------|----------|---------|-------------|
|
||||
| `url` | string | Yes | — | Webhook target URL |
|
||||
| `headers` | object | No | `{}` | HTTP headers to send |
|
||||
| `payload` | any | No | `null` | Request body (string or JSON) |
|
||||
| `execute_at` | string | Yes | — | ISO 8601 / RFC3339 timestamp |
|
||||
| `retries` | int | No | `0` | Max retry attempts on failure |
|
||||
| `retry_interval` | int | No | `2000` | Milliseconds between retries |
|
||||
|
||||
**Response (201):**
|
||||
```json
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"url": "https://ntfy.sh/mytopic",
|
||||
"execute_at": "2026-05-10T12:00:00Z",
|
||||
"headers": { "Content-Type": "text/plain" },
|
||||
"payload": "Your position is approaching liquidation",
|
||||
"retries": 3,
|
||||
"retry_interval": 2000
|
||||
}
|
||||
```
|
||||
|
||||
**Errors:**
|
||||
- `400` — Invalid body or timestamp
|
||||
- `400` — Timestamp is in the past
|
||||
- `401` — Missing API key
|
||||
- `403` — Invalid API key
|
||||
|
||||
---
|
||||
|
||||
### GET /tasks
|
||||
|
||||
List all scheduled tasks.
|
||||
|
||||
**Response (200):**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"url": "https://ntfy.sh/mytopic",
|
||||
"execute_at": "2026-05-10T12:00:00Z",
|
||||
"headers": {},
|
||||
"payload": "...",
|
||||
"retries": 3,
|
||||
"retry_interval": 2000
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### DELETE /tasks/{id}
|
||||
|
||||
Delete a scheduled task by ID.
|
||||
|
||||
**Response:**
|
||||
- `204 No Content` — Success
|
||||
- `404` — Task not found
|
||||
- `401` / `403` — Auth error
|
||||
|
||||
---
|
||||
|
||||
## ntfy API (Proxied)
|
||||
|
||||
Base URL: `http://localhost/ntfy` (when behind nginx)
|
||||
|
||||
### POST /{topic}
|
||||
|
||||
Publish a message to a topic.
|
||||
|
||||
**Request Headers:**
|
||||
| Header | Description |
|
||||
|--------|-------------|
|
||||
| `Content-Type: text/plain` | Message body is plain text |
|
||||
| `X-Email: user@example.com` | Forward message via email |
|
||||
| `X-Priority: 5` | Message priority (1-5) |
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
curl -X POST -H 'Content-Type: text/plain' -H 'X-Email: user@example.com' \
|
||||
http://localhost/ntfy/mytopic \
|
||||
-d 'Your position is approaching liquidation'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
- `200 OK` — Message published
|
||||
|
||||
### Web UI
|
||||
|
||||
Access `http://localhost/ntfy/` to use the ntfy web interface for subscribing to topics.
|
||||
|
||||
## Related
|
||||
|
||||
- [[Home]]
|
||||
- [[Architecture]]
|
||||
- [[Deployment]]
|
||||
Reference in New Issue
Block a user