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>
367 lines
8.1 KiB
Markdown
367 lines
8.1 KiB
Markdown
---
|
|
title: Development
|
|
tags: [mortgagefi, ops, development]
|
|
type: operations
|
|
status: stable
|
|
updated: 2026-06-14
|
|
---
|
|
|
|
# Development
|
|
|
|
## Repository Structure
|
|
|
|
```
|
|
mortgageFi/
|
|
├── mortgagefi-frontend/ # Next.js DApp
|
|
│ ├── app/ # App Router pages
|
|
│ │ ├── dapp/page.tsx # Main DApp interface
|
|
│ │ ├── dapp/position/... # Deep-link position pages
|
|
│ │ ├── layout.tsx # Root layout with Web3Provider
|
|
│ │ └── page.tsx # Landing page
|
|
│ ├── components/ # React components
|
|
│ │ ├── ConnectButton.tsx
|
|
│ │ ├── Navbar.tsx
|
|
│ │ └── SettingsModal.tsx # Notification settings
|
|
│ ├── providers/
|
|
│ │ └── Web3Provider.tsx # Wagmi + QueryClient setup
|
|
│ ├── utils/
|
|
│ │ ├── scheduler.ts # Schedy API client
|
|
│ │ ├── useLocalStorage.ts # localStorage hook
|
|
│ │ ├── format.ts # Number formatting
|
|
│ │ └── cronhost.ts # Legacy cronhost support
|
|
│ ├── config/
|
|
│ │ └── web3.ts # Wagmi chain config
|
|
│ ├── types/
|
|
│ │ └── notifications.ts # TypeScript types
|
|
│ ├── ABIs/
|
|
│ │ └── mortgagefiusdccbbtcupgraded.json
|
|
│ └── submodules/
|
|
│ └── schedy/ # Go scheduler (Git submodule)
|
|
├── nftcache/ # Go NFT ownership cache
|
|
│ ├── cmd/nftcache/main.go
|
|
│ └── internal/
|
|
│ ├── config/config.go # YAML contract config
|
|
│ ├── fetcher/
|
|
│ │ ├── rpc.go # RPC scanning with rate limits
|
|
│ │ └── alchemy.go # Alchemy API fallback
|
|
│ └── store/store.go # BadgerDB persistence
|
|
├── config/
|
|
│ └── contracts.yaml # Contract address mappings
|
|
├── nginx/
|
|
│ └── nginx.conf # Reverse proxy config
|
|
├── docker-compose.yml # Full stack orchestration
|
|
├── .env / .env.local # Environment variables
|
|
├── ALERT_CHANGES.md # Alert feature changelog
|
|
└── MIGRATION_NOTES.md # Dependency upgrade notes
|
|
```
|
|
|
|
---
|
|
|
|
## Frontend Development
|
|
|
|
### Setup
|
|
|
|
```bash
|
|
cd mortgagefi-frontend
|
|
npm install
|
|
```
|
|
|
|
### Run Dev Server
|
|
|
|
```bash
|
|
npm run dev
|
|
# Opens on http://localhost:3000
|
|
```
|
|
|
|
> [!info]
|
|
> Turbopack is enabled by default for faster builds.
|
|
|
|
### Build for Production
|
|
|
|
```bash
|
|
npm run build
|
|
npm start
|
|
```
|
|
|
|
### Lint
|
|
|
|
```bash
|
|
npm run lint
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
Create `mortgagefi-frontend/.env.local`:
|
|
|
|
```bash
|
|
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your-project-id
|
|
NEXT_PUBLIC_RPC_BASE=https://base.llamarpc.com
|
|
```
|
|
|
|
> [!note]
|
|
> See `.env` in the repo root for the full variable list.
|
|
|
|
---
|
|
|
|
## Backend Development
|
|
|
|
### nftcache
|
|
|
|
```bash
|
|
cd nftcache
|
|
|
|
# Run
|
|
go run ./cmd/nftcache
|
|
|
|
# Build
|
|
go build -o nftcache ./cmd/nftcache
|
|
./nftcache
|
|
|
|
# With custom env
|
|
NFTCACHE_API_KEY=test NFTCACHE_TTL=1h go run ./cmd/nftcache
|
|
```
|
|
|
|
**Test the API:**
|
|
```bash
|
|
# After starting, test with:
|
|
curl "http://localhost:8090/nfts?network=base&nft_contract=cbbtc&user_wallet=0x..."
|
|
```
|
|
|
|
### schedy
|
|
|
|
```bash
|
|
cd mortgagefi-frontend/submodules/schedy
|
|
|
|
# Run
|
|
go run ./cmd/schedy
|
|
|
|
# Build
|
|
go build -o schedy ./cmd/schedy
|
|
./schedy -port 8080
|
|
```
|
|
|
|
**Test the API:**
|
|
```bash
|
|
# Create a task
|
|
curl -X POST http://localhost:8080/tasks \
|
|
-H "Content-Type: application/json" \
|
|
-H "X-API-Key: test" \
|
|
-d '{
|
|
"url": "https://httpbin.org/post",
|
|
"execute_at": "2026-12-31T23:59:59Z",
|
|
"payload": "test"
|
|
}'
|
|
|
|
# List tasks
|
|
curl http://localhost:8080/tasks -H "X-API-Key: test"
|
|
```
|
|
|
|
---
|
|
|
|
## Full Stack Local Development
|
|
|
|
Run all services together with Docker Compose:
|
|
|
|
```bash
|
|
# From repo root
|
|
docker compose up -d
|
|
|
|
# Watch logs
|
|
docker compose logs -f
|
|
|
|
# Restart a single service
|
|
docker compose restart frontend
|
|
docker compose restart nftcache
|
|
|
|
# Rebuild after code changes
|
|
docker compose up -d --build frontend
|
|
docker compose up -d --build nftcache
|
|
```
|
|
|
|
The nginx proxy exposes everything on `http://localhost`:
|
|
- `/` — Next.js frontend
|
|
- `/ntfy/` — ntfy web UI and API
|
|
- `/schedy/` — Schedy API
|
|
- `/nftcache/` — nftcache API
|
|
|
|
---
|
|
|
|
## Adding a New Chain/Preset
|
|
|
|
### 1. Update Frontend (`mortgagefi-frontend/app/dapp/page.tsx`)
|
|
|
|
Add chain defaults:
|
|
```typescript
|
|
const DEFAULTS = {
|
|
[base.id]: { nft: '0x...', debt: '0x...' },
|
|
[arbitrum.id]: { nft: '0x...', debt: '0x...' },
|
|
[newChain.id]: { nft: '0x...', debt: '0x...' },
|
|
};
|
|
```
|
|
|
|
Add presets:
|
|
```typescript
|
|
const PRESETS = {
|
|
[newChain.id]: [
|
|
{ key: 'PAIR-QUOTE', label: 'PAIR-QUOTE', nft: '0x...', debt: '0x...' },
|
|
],
|
|
};
|
|
```
|
|
|
|
### 2. Update Web3 Config (`mortgagefi-frontend/config/web3.ts`)
|
|
|
|
```typescript
|
|
import { newChain } from 'wagmi/chains';
|
|
|
|
export const config = createConfig({
|
|
chains: [base, arbitrum, newChain],
|
|
transports: {
|
|
[newChain.id]: http('https://newchain.rpc.com'),
|
|
},
|
|
});
|
|
```
|
|
|
|
### 3. Update nftcache (`config/contracts.yaml`)
|
|
|
|
```yaml
|
|
contracts:
|
|
mypreset:
|
|
network: newchain
|
|
address: "0x..."
|
|
max_token_id: "10000"
|
|
```
|
|
|
|
### 4. Add RPC to nftcache environment
|
|
|
|
```bash
|
|
NEWCHAIN_RPC_URL=https://newchain.rpc.com
|
|
```
|
|
|
|
Update `nftcache/cmd/nftcache/main.go` to read the new env var.
|
|
|
|
---
|
|
|
|
## Testing Notifications End-to-End
|
|
|
|
### 1. Configure Settings in UI
|
|
|
|
Open the DApp, click Settings (gear icon):
|
|
- **Provider:** ntfy
|
|
- **Server:** `/ntfy` (or your ntfy URL)
|
|
- **Topic:** `mortgagefi-test`
|
|
- **Email:** your email address
|
|
- **Scheduler:** Schedy
|
|
- **Schedy URL:** `/schedy`
|
|
- **Schedy API Key:** your key
|
|
|
|
### 2. Send Test Alert
|
|
|
|
Click "Send test alert" in Settings.
|
|
|
|
### 3. Verify
|
|
|
|
Check:
|
|
- ntfy web UI at `http://localhost/ntfy/` — message should appear
|
|
- Your email inbox — message should arrive within seconds (or 2 minutes for Schedy tests)
|
|
|
|
### 4. Manual Test via cURL
|
|
|
|
```bash
|
|
# Direct ntfy test
|
|
curl -X POST http://localhost/ntfy/mortgagefi-test \
|
|
-H "Content-Type: text/plain" \
|
|
-H "X-Email: you@example.com" \
|
|
-d "Manual test"
|
|
|
|
# Schedy + ntfy test
|
|
curl -X POST http://localhost/schedy/tasks \
|
|
-H "Content-Type: application/json" \
|
|
-H "X-API-Key: your-key" \
|
|
-d '{
|
|
"url": "http://localhost/ntfy/mortgagefi-test",
|
|
"headers": {"Content-Type":"text/plain","X-Email":"you@example.com"},
|
|
"payload": "Scheduled test",
|
|
"execute_at": "'$(date -u -v+2M +%Y-%m-%dT%H:%M:%SZ)'"
|
|
}'
|
|
```
|
|
|
|
---
|
|
|
|
## Common Issues
|
|
|
|
### 429 Rate Limit Errors
|
|
|
|
> [!warning] RPC returns "Too Many Requests" during NFT scanning.
|
|
|
|
**Solutions:**
|
|
- Use a private RPC endpoint (Infura, Alchemy, QuickNode)
|
|
- Reduce `NFTCACHE_TTL` to reduce background refresh frequency
|
|
- Enable nftcache in frontend settings to offload scanning
|
|
|
|
### Wallet Connection Fails
|
|
|
|
> [!warning] WalletConnect modal doesn't appear.
|
|
|
|
**Solutions:**
|
|
- Verify `NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID` is set
|
|
- Check that the project ID is valid at https://cloud.walletconnect.com
|
|
|
|
### Schedy Tasks Not Executing
|
|
|
|
> [!warning] Scheduled alerts never fire.
|
|
|
|
**Debugging:**
|
|
```bash
|
|
# List pending tasks
|
|
curl http://localhost/schedy/tasks -H "X-API-Key: your-key"
|
|
|
|
# Check schedy logs
|
|
docker compose logs -f schedy
|
|
```
|
|
|
|
**Common causes:**
|
|
- Schedy container clock drift (ensure NTP is enabled)
|
|
- Task deleted before execution (check auto-reschedule logic)
|
|
- ntfy URL unreachable from Schedy container
|
|
|
|
### CORS Errors
|
|
|
|
> [!warning] Browser blocks API calls to Schedy or nftcache.
|
|
|
|
**Solution:**
|
|
Ensure `CORS_ALLOW_ORIGIN` matches your frontend URL exactly, including protocol:
|
|
```bash
|
|
CORS_ALLOW_ORIGIN=https://mortgagefi.example.com
|
|
```
|
|
|
|
---
|
|
|
|
## Git Submodules
|
|
|
|
The `schedy` project is included as a Git submodule:
|
|
|
|
```bash
|
|
# Initialize on fresh clone
|
|
git submodule update --init --recursive
|
|
|
|
# Pull latest submodule changes
|
|
git submodule update --remote
|
|
|
|
# Commit submodule pin
|
|
cd mortgagefi-frontend/submodules/schedy
|
|
git checkout main
|
|
git pull
|
|
cd ../../..
|
|
git add mortgagefi-frontend/submodules/schedy
|
|
git commit -m "Update schedy submodule"
|
|
```
|
|
|
|
---
|
|
|
|
## Related
|
|
|
|
- [[Home]]
|
|
- [[Architecture]]
|
|
- [[API Reference]]
|
|
- [[Deployment]]
|