Files
mortgagefi-helper/docs/Operations/Development.md
Siavash Sameni 6ae581ab2e 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>
2026-06-14 08:13:53 +04:00

8.1 KiB

title, tags, type, status, updated
title tags type status updated
Development
mortgagefi
ops
development
operations stable 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

cd mortgagefi-frontend
npm install

Run Dev Server

npm run dev
# Opens on http://localhost:3000

[!info] Turbopack is enabled by default for faster builds.

Build for Production

npm run build
npm start

Lint

npm run lint

Environment Variables

Create mortgagefi-frontend/.env.local:

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

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:

# After starting, test with:
curl "http://localhost:8090/nfts?network=base&nft_contract=cbbtc&user_wallet=0x..."

schedy

cd mortgagefi-frontend/submodules/schedy

# Run
go run ./cmd/schedy

# Build
go build -o schedy ./cmd/schedy
./schedy -port 8080

Test the API:

# 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:

# 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:

const DEFAULTS = {
  [base.id]: { nft: '0x...', debt: '0x...' },
  [arbitrum.id]: { nft: '0x...', debt: '0x...' },
  [newChain.id]: { nft: '0x...', debt: '0x...' },
};

Add presets:

const PRESETS = {
  [newChain.id]: [
    { key: 'PAIR-QUOTE', label: 'PAIR-QUOTE', nft: '0x...', debt: '0x...' },
  ],
};

2. Update Web3 Config (mortgagefi-frontend/config/web3.ts)

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)

contracts:
  mypreset:
    network: newchain
    address: "0x..."
    max_token_id: "10000"

4. Add RPC to nftcache environment

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

# 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:

Schedy Tasks Not Executing

[!warning] Scheduled alerts never fire.

Debugging:

# 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:

CORS_ALLOW_ORIGIN=https://mortgagefi.example.com

Git Submodules

The schedy project is included as a Git submodule:

# 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"