Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 StepFi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
284 changes: 156 additions & 128 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,186 +1,214 @@
<div align="center">

![React Native](https://img.shields.io/badge/React%20Native-20232A?style=for-the-badge&logo=react&logoColor=61DAFB)
![Expo](https://img.shields.io/badge/Expo-000020?style=for-the-badge&logo=expo&logoColor=white)
![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)
![Stellar](https://img.shields.io/badge/Stellar-7D00FF?style=for-the-badge&logo=stellar&logoColor=white)
<img src="./assets/icon.png" alt="StepFi" width="96" height="96" />

[![Open Source](https://img.shields.io/badge/Open%20Source-Yes-green?style=flat-square)](https://opensource.org/)
[![MIT License](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)](./LICENSE)
[![CI](https://github.com/StepFi-app/StepFi-App/actions/workflows/ci.yml/badge.svg)](https://github.com/StepFi-app/StepFi-App/actions/workflows/ci.yml)
# StepFi-App

# StepFi App
**Reputation-based, step-by-step credit (BNPL) for students, interns, and small vendors — settled on Stellar.**

**Step into your future. Credit without banks. Progress without limits.**
The official StepFi mobile client, built with Expo + React Native.

React Native mobile app for the StepFi learner BNPL protocol on Stellar
[![CI](https://github.com/StepFi-app/StepFi-App/actions/workflows/ci.yml/badge.svg)](https://github.com/StepFi-app/StepFi-App/actions/workflows/ci.yml)
[![Expo](https://img.shields.io/badge/Expo-54-000020?logo=expo&logoColor=white)](https://expo.dev)
[![React Native](https://img.shields.io/badge/React%20Native-0.81-61DAFB?logo=react&logoColor=white)](https://reactnative.dev)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org)
[![Stellar](https://img.shields.io/badge/Stellar-Soroban-7D00FF?logo=stellar&logoColor=white)](https://stellar.org)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](./LICENSE)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](#-contributing)

[Features](#-features) • [Tech Stack](#-tech-stack) • [Quick Start](#-quick-start) • [Screens](#-screens) • [Contributing](#-contributing)
[Quick Start](#-quick-start) · [Architecture](#-where-it-fits) · [Features](#-features) · [Testing](#-testing) · [Roadmap](#-roadmap) · [StepFi org](https://github.com/StepFi-app)

</div>

---

## 📖 About

StepFi App is the mobile frontend for the StepFi protocol — a React Native application built with Expo that lets learners, interns, and early-career developers access financing for laptops, courses, and dev tools, and repay in small installments on the Stellar network.

---
## 📖 What is StepFi?

## ✨ Features
StepFi lets learners and interns borrow small amounts against an **on-chain reputation score** instead of collateral, repay in scheduled installments, and build a credit history — while sponsors fund a shared liquidity pool and vendors get paid directly. All credit logic, repayment, and reputation live in Soroban smart contracts on **Stellar**; this repo is the **mobile app** users hold in their hands.

- 🔐 **Wallet Authentication** — Connect your Stellar wallet (Lobstr, xBull via WalletConnect)
- 💻 **Loan Application** — Apply for financing in a simple step-by-step wizard
- 📦 **Installment Tracker** — View your repayment schedule and make payments
- ⭐ **Reputation Dashboard** — Track your on-chain credit score and history
- 🏪 **Vendor Browse** — Explore verified learning vendors by category
- 💧 **Sponsor Pool** — Companies and mentors can fund learner pools
- 🔔 **Payment Reminders** — Never miss an installment
- 🌍 **Built for Africa** — Designed for emerging market learners
- 🎓 **Learners** connect a wallet, see their credit limit and APR (both derived from reputation), request a loan, and repay on a schedule.
- 💚 **Sponsors** back the liquidity pool that funds loans.
- 🏪 **Vendors** are paid on loan disbursement and tracked in an on-chain registry.

---
> **This repo is the learner client.** Sponsor and vendor experiences live in [StepFi-Web](https://github.com/StepFi-app/StepFi-Web); this app focuses on the learner journey.

## 🛠 Tech Stack

| Category | Technology |
|---|---|
| **Framework** | React Native 0.81 + Expo 54 |
| **Language** | TypeScript 5.9 |
| **Navigation** | Expo Router (file-based) |
| **Styling** | NativeWind (Tailwind CSS for RN) |
| **State** | Zustand |
| **API Client** | Axios with JWT interceptors |
| **Wallet** | WalletConnect v2 (Lobstr, xBull) |
| **Animations** | React Native Reanimated 4 |
| **Storage** | Expo SecureStore (JWT tokens) |
| **Icons** | Lucide React Native |
## 🗺️ Where it fits

---
StepFi-App is one of six repositories in the StepFi protocol. It talks to **StepFi-API** over REST (wallet-signature JWT), signs transactions through the user's **wallet**, and ultimately drives the **StepFi-Contracts** deployed on Stellar.

## 📁 Project Structure
<div align="center">

```
StepFi-App/
├── app/ # Expo Router screens (file-based routing)
│ ├── (auth)/ # Auth screens (sign-in, register)
│ ├── (tabs)/ # Main tab screens
│ │ ├── pay.tsx # Borrower dashboard
│ │ ├── invest.tsx # Sponsor/LP dashboard
│ │ └── settings.tsx # User settings
│ └── _layout.tsx # Root layout with auth guard
├── components/
│ ├── pages/ # Full page components
│ ├── shared/ # Reusable components
│ └── ui/ # Base UI components
├── hooks/ # Custom React hooks
├── services/ # API service layer (Axios)
├── stores/ # Zustand global state
├── constants/ # Colors, config, theme
└── docs/ # Documentation
```
<img src="./assets/architecture.svg" alt="StepFi system architecture — StepFi-App highlighted" width="900" />

---
</div>

## 🚀 Quick Start

### Prerequisites

- Node.js 20 LTS
- Expo CLI
- iOS Simulator or Android Emulator (or Expo Go app)
| Tool | Version | Notes |
|------|---------|-------|
| Node.js | ≥ 20 | Matches CI |
| npm | ≥ 10 | Uses `--legacy-peer-deps` (Expo 54 peer graph) |
| Expo CLI | bundled | Invoked via `npx expo` |
| Xcode / Android Studio | latest | Only for native simulators/devices |
| A Stellar wallet | — | [Freighter](https://www.freighter.app) (web) or [Lobstr](https://lobstr.co) (mobile, via WalletConnect) |

### Installation
### Install & run

```bash
# Clone the repository
git clone https://github.com/StepFi-app/StepFi-App.git
cd StepFi-App
npm install --legacy-peer-deps

# start the dev server (choose a target from the Expo menu)
npm start
npm run android # Android device/emulator
npm run ios # iOS simulator
npm run web # browser
```

# Install dependencies
npm install
### Configuration

# Copy environment file
cp .env.example .env
Create a `.env` (loaded by Expo as `EXPO_PUBLIC_*` at build time):

| Variable | Purpose |
|----------|---------|
| `EXPO_PUBLIC_API_URL` | Base URL of [StepFi-API](https://github.com/StepFi-app/StepFi-API) |
| `EXPO_PUBLIC_WALLETCONNECT_PROJECT_ID` | WalletConnect Cloud project ID (Lobstr / mobile) |
| `EXPO_PUBLIC_SENTRY_DSN` | Sentry DSN (optional — Sentry is skipped if unset) |

> No secrets are bundled. `EXPO_PUBLIC_*` values are public by design; never put private keys here.

## 🧭 App structure

# Add your API base URL
# EXPO_PUBLIC_API_URL=http://localhost:4000/api/v1
```
app/ # expo-router routes (file-based)
├── (auth)/ # onboarding, role-select, sign-in, register
├── (tabs)/ # Home · Loans · Simulate · Calendar · Score · Settings
├── _layout.tsx # root: auth guard, biometric gate, idle-lock, Sentry, netinfo
└── index.tsx # entry redirect
components/ # shared UI (wallet, reputation, cards…)
hooks/ # useWallet, invest/, reputation/ (+ pure, tested utils)
services/ # api, auth, wallet, loans, reputation, notifications, sentry
stores/ # Zustand: auth, user, wallet, loans
src/
├── security/ # biometric.service, security.store, lockout
├── offline/ # queue, sync, TTL cache, connectivity store
├── transactions/ # transaction-signer.service
└── locales/ # i18n (en · fr · pt)
```

### Running the App
## 🧱 Tech stack

| Layer | Choice |
|-------|--------|
| Framework | Expo `~54` · React Native `0.81` · React `19` |
| Routing | `expo-router` (file-based) |
| Language | TypeScript `~5.9` |
| State | Zustand `5` |
| Styling | NativeWind + Tailwind `3.4` |
| Wallets | `@stellar/freighter-api` · `@walletconnect/sign-client` |
| Animation | `react-native-reanimated` `4` · `react-native-svg` |
| Storage | `expo-secure-store` (secrets) · AsyncStorage (offline queue) |
| Networking | `axios` |
| i18n | `i18next` + `react-i18next` + `expo-localization` |
| Observability | `@sentry/react-native` |

```bash
# Start Expo dev server
npx expo start
## ✨ Features

| Feature | Status | Where |
|---------|--------|-------|
| Wallet connect — Freighter (web) + Lobstr (WalletConnect) | ✅ | [`services/wallet.service.ts`](services/wallet.service.ts), [`hooks/useWallet.ts`](hooks/useWallet.ts) |
| Biometric + PIN app lock | ✅ | [`src/security/biometric.service.ts`](src/security/biometric.service.ts) |
| Persisted lockout & idle auto-lock | ✅ | [`src/security/security.store.ts`](src/security/security.store.ts), [`app/_layout.tsx`](app/_layout.tsx) |
| Reputation score + animated ring | ✅ | [`app/(tabs)/reputation.tsx`](app/(tabs)/reputation.tsx), [`components/reputation/`](components/reputation) |
| Loans list & repayment | ✅ | [`app/(tabs)/loans.tsx`](app/(tabs)/loans.tsx), [`services/loans.service.ts`](services/loans.service.ts) |
| Loan simulator | ✅ | [`app/(tabs)/simulate.tsx`](app/(tabs)/simulate.tsx) |
| Repayment calendar + reminders | ✅ | [`app/(tabs)/calendar.tsx`](app/(tabs)/calendar.tsx), [`services/notifications.service.ts`](services/notifications.service.ts) |
| Offline queue, sync & cache | ✅ | [`src/offline/`](src/offline) |
| Localization (English · Français · Português) | ✅ | [`src/locales/`](src/locales) |
| Transaction signing | ✅ | [`src/transactions/transaction-signer.service.ts`](src/transactions/transaction-signer.service.ts) |
| Real wallet-signature JWT auth | 🚧 | [#35](https://github.com/StepFi-app/StepFi-App/issues/35) — mock tokens today; blocked on a wallet message-signing primitive |
| Editable profile · notification preferences | 🗺️ | planned |

### 🔐 Wallets & signing

Two wallets are supported through one interface ([`services/wallet.service.ts`](services/wallet.service.ts)):

- **Freighter** (`@stellar/freighter-api`) for web — `requestAccess`, `signTransaction`.
- **Lobstr** over **WalletConnect** for mobile — the `stellar:pubnet` namespace negotiates `stellar_signXDR` / `stellar_signAndSubmitTransaction`.

# Run on iOS
npx expo run:ios
> **Auth note:** StepFi-API's `/auth/verify` expects a signed *message*; mobile wallets over WalletConnect currently sign *XDR* only. Until a `signMessage` primitive lands, registration issues placeholder tokens — tracked in [#35](https://github.com/StepFi-app/StepFi-App/issues/35).

# Run on Android
npx expo run:android
### 🛡️ Security

# Run in web browser (basic support)
npx expo start --web
- Biometric unlock via `expo-local-authentication` with a **PIN fallback**; the PIN is salted and SHA-256 hashed with `expo-crypto` — never stored in plaintext.
- Failed-attempt **lockout** and `isLocked` are persisted (SecureStore on native, `localStorage` on web) so relaunching the app cannot bypass the gate; state resets on sign-out.
- **Idle auto-lock** after 5 minutes and on app resume ([`app/_layout.tsx`](app/_layout.tsx)).

## 🧪 Testing

Business logic is extracted into pure, unit-tested helpers.

```bash
npm run typecheck # tsc --noEmit
npm run lint # eslint + prettier --check
npm test # jest
```

---
| Suite | Tests | File |
|-------|-------|------|
| Invest math | 6 | [`hooks/invest/use-invest.test.ts`](hooks/invest/use-invest.test.ts) |
| Vouch guard | 5 | [`hooks/reputation/vouch-utils.test.ts`](hooks/reputation/vouch-utils.test.ts) |
| Lockout / backoff | 6 | [`src/security/lockout.test.ts`](src/security/lockout.test.ts) |
| Transaction signer | 9 | [`src/transactions/__tests__/transaction-signer.service.test.ts`](src/transactions/__tests__/transaction-signer.service.test.ts) |
| **Total** | **26** | |

## 📱 Screens

| Screen | Status | Description |
|---|---|---|
| Onboarding | 🚧 In Progress | Welcome → Connect Wallet → Build Score → Apply |
| Sign In | 🚧 In Progress | Wallet connection via WalletConnect |
| Register | 🚧 In Progress | Create learner profile |
| Pay Dashboard | 🚧 In Progress | Active loans, next payment, credit score |
| Loan Wizard | 📋 Planned | Step-by-step loan application |
| Loan Detail | 📋 Planned | Installment timeline and payment history |
| Vendor Browse | 📋 Planned | Categories: Education, Electronics, Courses |
| Reputation Detail | 📋 Planned | Score breakdown and improvement tips |
| Invest Dashboard | 🚧 In Progress | Sponsor/LP pool overview |
| Settings | 🚧 In Progress | Profile, notifications, theme |
| Wallet Setup | 📋 Planned | First-time Stellar wallet guide |
## 🔄 CI/CD

---
Every push and PR runs [`.github/workflows/ci.yml`](.github/workflows/ci.yml) (Node 20), a **required check on `main`**:

## 🚢 Release Process
- **web-build** — `npx expo export --platform web` (uploads the `dist/` artifact).
- **quality** — `lint` + `typecheck` + `test`.

1. Ensure all changes are merged to `main`.
2. From `main`, run `npm version patch` (or `minor`/`major`) to bump the version and create a tag:
```bash
git checkout main
git pull
npm version patch # creates v0.x.x locally
git push --tags
```
3. Pushing a `v*` tag triggers the [EAS Production Build](.github/workflows/eas-build.yml) workflow:
- Builds the Android APK via EAS Build (`production` profile)
- Creates a GitHub Release with auto-generated release notes
- Attaches the APK as a downloadable release asset
4. Monitor the build at [Actions → EAS Production Build](https://github.com/StepFi-app/StepFi-App/actions/workflows/eas-build.yml).
Tagging `v*` triggers [`eas-build.yml`](.github/workflows/eas-build.yml): an EAS production Android build that is attached as an APK to a GitHub Release.

> **Note:** The workflow requires the `EXPO_TOKEN` repository secret. Set it in **Settings → Secrets and variables → Actions → New repository secret** using a token from your [Expo access tokens settings](https://expo.dev/accounts/settings/access-tokens).
## 🛣️ Roadmap

---
| Milestone | Status |
|-----------|--------|
| Wallet connect (Freighter + Lobstr) | ✅ |
| Biometric + PIN lock with persisted lockout | ✅ |
| Offline queue & sync, TTL cache | ✅ |
| Localization (en · fr · pt) | ✅ |
| Reputation, loans, simulator, calendar reminders | ✅ |
| Enforced CI gate (web export + lint + typecheck + test) | ✅ |
| Real wallet-signature JWT auth (message signing) | 🚧 |
| Live wiring to StepFi-Contracts on testnet | 🚧 |
| Editable profile · notification preferences | 🗺️ |

## 🤝 Contributing

We welcome React Native and Expo developers of all levels! See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup, code style, and the PR process.
1. Branch off `main` (`feat/…`, `fix/…`, `docs/…`, `chore/…`).
2. Keep the gate green locally: `npm run typecheck && npm run lint && npm test && npx expo export --platform web`.
3. Open a PR using the template; PRs into `main` must pass the required checks.

Check the [Roadmap](./ROADMAP.md) for open tasks and good first issues.
See [`docs/contributing.md`](docs/contributing.md) for the full guide.

---

## 📄 License
## 🌐 The StepFi protocol

MIT License — see [LICENSE](./LICENSE) for details.
| Repo | Role |
|------|------|
| **StepFi-App** (this repo) | Learner & sponsor mobile client |
| [StepFi-Contracts](https://github.com/StepFi-app/StepFi-Contracts) | Soroban smart contracts (credit, reputation, liquidity) |
| [StepFi-API](https://github.com/StepFi-app/StepFi-API) | Backend: auth/JWT, orchestration, jobs |
| [StepFi-Web](https://github.com/StepFi-app/StepFi-Web) | Marketing site & web dashboard |
| [StepFi-Docs](https://github.com/StepFi-app/StepFi-Docs) | Protocol documentation |

---
## 📄 License

<div align="center">
Released under the [MIT License](./LICENSE).

**Built with ❤️ for learners everywhere**

[![Stellar](https://img.shields.io/badge/Powered%20by-Stellar-7D00FF?style=flat-square)](https://www.stellar.org/)
[![Open Source](https://img.shields.io/badge/Open%20Source-Yes-green?style=flat-square)](https://opensource.org/)

</div>
Loading
Loading