- Frontend Setup - Created a Next.js + Tailwind CSS frontend in
escrow-frontend/ - Contract Utility Functions - Added
app/lib/contract.tswith Soroban RPC integration - Wallet Integration - Built
app/context/WalletContext.tsxusing Freighter browser extension API - Navbar Component - Implemented
app/components/Navbar.tsxwith wallet connect/disconnect and links to Dashboard/Create Job - Home Page - Updated
app/page.tsxwith landing content and call-to-action - Create Job Page - Added
app/create/page.tsxwith form to create jobs with milestones - MilestoneCard Component - Created
app/components/MilestoneCard.tsxwith status badges and action buttons - Job Dashboard Page - Built
app/dashboard/page.tsxwith mock job data and milestone interaction - Dev Server - Successfully running on http://localhost:3001 with all routes compiled!
- Contract Deployment - Deployed milestone escrow contract to Stellar Testnet!
- Contract ID:
CDD5WKK3WT3QVKXMXTJNDIXE4T73FK6GGXDSD6UTJAH6YYZU52SQ4MUH - Explorer: https://stellar.expert/explorer/testnet/contract/CDD5WKK3WT3QVKXMXTJNDIXE4T73FK6GGXDSD6UTJAH6YYZU52SQ4MUH
- Contract ID:
- Backend Setup - Created an Express + TypeScript backend in
escrow-backend/ - API Endpoints - Added endpoints to get job state, build transactions, and submit signed transactions
- Pushed to GitHub - Backend repo is live at https://github.com/Goldii-locks/escrow-backend
- Contract: Added event emission to all functions
- Backend: Added vec type handling for build-tx endpoint
- Frontend: Wired Create Job form to backend
- All changes pushed to GitHub!
- Contract: Added CONTRIBUTING.md file with contributor guidelines
- Frontend: Added loading skeleton to dashboard for better UX
- Backend: Added GET /api/jobs/by-wallet/:address endpoint (closes issue #1)
- Fix: Fixed type error in dashboard useState
- All changes pushed to GitHub!
- Contract: Added 10+ edge case tests (closes issue #3) - now total 15 tests!
- Tests for invalid milestone index, wrong status, unauthorized access, etc.
- Frontend: Added CONTRIBUTING.md; wired dashboard to fetch real job data via backend
- Backend: Added CONTRIBUTING.md; updated job endpoints to parse contract response; added Jest integration test setup (closes issue #3)
- All changes committed and pushed!
- Contract: Added
released_amountfield to Milestone struct; addedapprove_partialfunction; updated all existing functions to handle partial releases; added comprehensive tests - All tests passed! (19 total tests)
- Committed and pushed!
- Contract: Added
delivered_at: u64to Milestone struct; addedauto_release_seconds: u64to Job struct; updatedinitialize()signature to acceptauto_release_seconds; updatedmark_delivered()to setdelivered_at; addedclaim_auto_release()public function; addedtime_until_auto_release()public function; addedDeadlineNotPassederror variant; fixed all token client calls to use &Address; added 5+ new tests (total tests 32) - All tests passed! ✅
- Frontend: Updated Create Job form to:
- Add "Response Deadline (days)" input
- Pass correct args to
initialize()(admin, client, freelancer, arbiter, token, auto_release_seconds, milestone_amounts) - Fixed BigInt compatibility issue
- Backend: Updated build-tx endpoint to handle
u64type (for auto_release_seconds) - All repos committed and pushed!
Milesto/
├── escrow-contract/ # Soroban smart contract
│ ├── Cargo.toml
│ ├── Cargo.lock
│ ├── .gitignore
│ ├── README.md
│ ├── CONTRIBUTING.md
│ ├── context.md
│ └── contracts/
│ └── milestone-escrow/
│ ├── Cargo.toml
│ ├── src/
│ │ ├── lib.rs
│ │ └── test.rs
│ └── test_snapshots/
├── escrow-frontend/ # Next.js frontend
│ ├── package.json
│ ├── package-lock.json
│ ├── tsconfig.json
│ ├── next.config.ts
│ ├── tailwind.config.ts
│ ├── postcss.config.mjs
│ ├── .gitignore
│ ├── .env.local
│ ├── .env.local.example
│ ├── README.md
│ ├── CONTRIBUTING.md
│ ├── app/
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ ├── globals.css
│ │ ├── lib/
│ │ │ └── contract.ts
│ │ ├── context/
│ │ │ └── WalletContext.tsx
│ │ ├── components/
│ │ │ ├── Navbar.tsx
│ │ │ ├── MilestoneCard.tsx
│ │ │ └── LoadingSkeleton.tsx
│ │ ├── create/
│ │ │ └── page.tsx
│ │ └── dashboard/
│ │ └── page.tsx
│ └── public/
└── escrow-backend/ # Express backend
├── package.json
├── package-lock.json
├── tsconfig.json
├── jest.config.ts
├── .gitignore
├── .env.example
├── .env
├── README.md
├── CONTRIBUTING.md
├── __tests__/
│ └── jobs.test.ts
└── src/
├── index.ts
└── routes/
└── jobs.ts
- Issue #4 (Closed): Added GET /api/jobs/:contractId/whitelist endpoint to fetch whitelisted tokens with graceful NotInitialized error handling
- Issue #5 (Closed): Updated build-tx endpoint to support admin whitelist management actions (add_whitelisted_token / remove_whitelisted_token) with validation
- Issue #6 (Closed): Added POST /api/jobs/:contractId/milestones/:index/partial-release endpoint to build approve_partial transactions
- Issue #7 (Closed): Added GET /api/jobs/:contractId/milestones/:index/time-remaining endpoint to fetch time left for auto-release
- Issue #8 (Closed): Added POST /api/jobs/:contractId/milestones/:index/claim-auto-release endpoint to build claim_auto_release transactions
- Event Indexer Service (New Feature!):
- Added SQLite database integration (better-sqlite3 dependency)
- Implemented db.ts with schema initialization, last_ledger tracking, event insertion (with UNIQUE constraint to avoid duplicates), and address-filtered querying
- Implemented poller.ts that periodically fetches events from Soroban RPC, processes them, and stores in database
- Updated index.ts to initialize indexer schema and start polling on server start
- Added comprehensive tests for indexer database functionality
- All 4 tests passed!
- All TypeScript checks passed! npm run build is clean!
- All issues closed with manual comments (no auto-close keywords!)
- CI is green! All commits pushed to GitHub!
Milesto/
├── escrow-contract/ # Soroban smart contract
│ ├── Cargo.toml
│ ├── Cargo.lock
│ ├── .gitignore
│ ├── README.md
│ ├── CONTRIBUTING.md
│ ├── context.md
│ └── contracts/
│ └── milestone-escrow/
│ ├── Cargo.toml
│ ├── src/
│ │ ├── lib.rs
│ │ └── test.rs
│ └── test_snapshots/
├── escrow-frontend/ # Next.js frontend
│ ├── package.json
│ ├── package-lock.json
│ ├── tsconfig.json
│ ├── next.config.ts
│ ├── tailwind.config.ts
│ ├── postcss.config.mjs
│ ├── .gitignore
│ ├── .env.local
│ ├── .env.local.example
│ ├── README.md
│ ├── CONTRIBUTING.md
│ ├── app/
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ ├── globals.css
│ │ ├── lib/
│ │ │ └── contract.ts
│ │ ├── context/
│ │ │ └── WalletContext.tsx
│ │ ├── components/
│ │ │ ├── Navbar.tsx
│ │ │ ├── MilestoneCard.tsx
│ │ │ └── LoadingSkeleton.tsx
│ │ ├── create/
│ │ │ └── page.tsx
│ │ └── dashboard/
│ │ └── page.tsx
│ └── public/
└── escrow-backend/ # Express backend
├── package.json
├── package-lock.json
├── tsconfig.json
├── jest.config.ts
├── .gitignore
├── .env.example
├── .env
├── README.md
├── CONTRIBUTING.md
├── __tests__/
│ ├── jobs.test.ts
│ └── indexer.test.ts
└── src/
├── index.ts
├── indexer/
│ ├── db.ts
│ └── poller.ts
└── routes/
└── jobs.ts
- Wire up other contract functions (fund, deliver, approve, dispute, resolve) to frontend
- Add support for multiple jobs in contract
- Add more comprehensive integration tests for backend
- Audit contract for security issues
- Close issue #1 once CI confirms green on the by-wallet upgrade
Goal: Replace the stub RPC-based GET /api/jobs/by-wallet/:address with a fast, SQLite-backed implementation that reads from the local event indexer.
src/indexer/db.ts — Added getJobsByWallet(address, page, limit):
- Queries
eventstable for rows wheredata_json LIKE %address% - Parses
data_jsonas JSON and checks role fields strictly (client,freelancer,arbiter) — protects against false-positive LIKE matches on other string fields - Groups events by
contract_idusing aMap— one distinct job per contract - Each job summary captures:
contract_id,role,milestone_count,latest_event_type,latest_ledger,latest_timestamp - Applies
page/limitpagination (1-based, safe clamping) - Returns
{ jobs, total, page, limit } - Also exported
JobSummaryandPaginatedJobsTypeScript interfaces
src/routes/jobs.ts — Replaced old by-wallet handler:
- Removed live RPC call (
simulateTransactionon a hardcoded single contract) - Now calls
getJobsByWallet(address, page, limit)directly from SQLite — sub-millisecond reads - Validates
?pageand?limitquery params with clear 400 errors - Response shape:
{ success: true, jobs: [...], total, page, limit }
__tests__/by-wallet.test.ts — 15 new tests:
- Returns empty when no events for address
- Role detection: client ✅ freelancer ✅ arbiter ✅
- Grouping: multiple events for same contract → single job entry
- Multi-contract: distinct jobs across C1/C2/C3
- False-positive guard: address in
tokenfield is NOT returned - Pagination: page 1 of 2, page 2 of 2, last partial page, page beyond total
- HTTP integration (supertest): response shape, empty address, pagination params, job field types
npx tsc --noEmit→ ✅ Zero errorsnpm test→ ✅ 19/19 tests pass (3 suites: indexer, jobs, by-wallet)npm run build→ ✅ Clean- Commit:
9bd8508—feat: wire indexer into by-wallet endpoint with pagination and role detection - Pushed to GitHub, CI running
Milesto/
├── escrow-contract/ # Soroban smart contract
│ ├── Cargo.toml
│ ├── Cargo.lock
│ ├── .gitignore
│ ├── README.md
│ ├── CONTRIBUTING.md
│ ├── context.md
│ └── contracts/
│ └── milestone-escrow/
│ ├── Cargo.toml
│ ├── src/
│ │ ├── lib.rs
│ │ └── test.rs
│ └── test_snapshots/
├── escrow-frontend/ # Next.js frontend
│ ├── package.json
│ ├── package-lock.json
│ ├── tsconfig.json
│ ├── next.config.ts
│ ├── tailwind.config.ts
│ ├── postcss.config.mjs
│ ├── .gitignore
│ ├── .env.local
│ ├── .env.local.example
│ ├── README.md
│ ├── CONTRIBUTING.md
│ ├── app/
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ ├── globals.css
│ │ ├── lib/
│ │ │ └── contract.ts
│ │ ├── context/
│ │ │ └── WalletContext.tsx
│ │ ├── components/
│ │ │ ├── Navbar.tsx
│ │ │ ├── MilestoneCard.tsx
│ │ │ └── LoadingSkeleton.tsx
│ │ ├── create/
│ │ │ └── page.tsx
│ │ └── dashboard/
│ │ └── page.tsx
│ └── public/
└── escrow-backend/ # Express backend
├── package.json
├── package-lock.json
├── tsconfig.json
├── jest.config.ts
├── .gitignore
├── .env.example
├── .env
├── README.md
├── CONTRIBUTING.md
├── __tests__/
│ ├── jobs.test.ts
│ ├── indexer.test.ts
│ └── by-wallet.test.ts ← NEW
└── src/
├── index.ts
├── indexer/
│ ├── db.ts ← getJobsByWallet() + interfaces added
│ └── poller.ts
└── routes/
└── jobs.ts ← by-wallet endpoint rebuilt
- Confirm CI green on
9bd8508, then close issue #1 with proper comment - Wire remaining contract functions (fund, deliver, approve, dispute, resolve) to frontend
- Add support for multiple jobs in contract
- Audit contract for security issues
- Deploy and sync generated issues to GitHub using the
sync.jsscript
Goal: Break the next major phases of Milesto down into 10 distinct phrases, each comprising 100 independent, well-labelled issues (1,000 issues total) to facilitate parallel development with collaborators, including a tool to preview and sync them.
milesto-roadmap/generate.js:
- Programmatic Node.js generator.
- Splits development into 10 phrases across core domains: contract safety, advanced features, API security, indexer performance, wallet integrations, component libraries, admin/arbitrator portals, financial math, notification triggers, and monitoring/telemetry.
- Compiles exactly 100 independent issues per phrase, each referencing the target repository, validation check, implementation steps, testing guidelines, and difficulty labels.
- Outputs structured JSON issue templates into local directories under
milesto-roadmap/issues/.
milesto-roadmap/sync.js:
- Interactive CLI import utility.
- Supports Dry-Run Mode (logs exact
ghCLI commands to execute) and Live Mode (creates issues via local authenticatedghCLI credentials). - Automatically parses and resolves the owner/repo mapping for the target packages (
escrow-contract,escrow-backend,escrow-frontend) by checking git remote urls.
- Ran
node generate.js→ successfully generated 10 folders, each containing exactly 100 issue JSON configurations (1,000 total). - Tested
echo "1" | node sync.js→ successfully verified dry-run CLI command formatting and github remote mapping resolver.
Milesto/
├── milesto-roadmap/ # NEW: Project Roadmap & Issues Manager
│ ├── generate.js # Generates the 1000 issue templates
│ ├── sync.js # Interactive sync tool (dry-run & live)
│ └── issues/ # Generated issues structured by phrase
│ ├── phrase_01_soroban_contract_safety_gas_optimization/
│ ├── phrase_02_advanced_escrow_features/
... └── phrase_10_performance_monitoring_diagnostics/
├── escrow-contract/ # Soroban smart contract
│ ├── Cargo.toml
│ ├── Cargo.lock
│ ├── context.md
│ └── contracts/
│ └── milestone-escrow/
├── escrow-frontend/ # Next.js frontend
│ ├── package.json
│ └── app/
└── escrow-backend/ # Express backend
├── package.json
└── src/