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
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,18 @@ invofi/
│ │ ├── invoices/ InvoiceCard, InvoiceForm, InvoiceTable,
│ │ │ OfferList
│ │ ├── layout/ Navbar (dark mode + a11y), Footer
│ │ ├── marketplace/ MarketplaceCard, PositionListingCard, etc.
│ │ ├── portfolio/ LivePortfolioProvider, ConnectionStatus,
│ │ │ RepaymentProgress (live dashboard, issue #221)
│ │ └── ui/ shadcn/ui — button, dialog, table,
│ │ badge, card, input, tabs, toast...
│ ├── hooks/ useInvoices, useOffers, useMarketplace,
│ │ useLocalStorage, useDebounce, useMediaQuery
│ └── lib/
│ ├── contract.ts Soroban contract call helpers (3 contracts)
│ ├── live/ Live portfolio engine (issue #221): WebSocket
│ │ + Soroban-event polling transports, per-position
│ │ throttle, yield/APY math, USD pricing, reducer
│ ├── approved-wallets.ts Approved-wallet allowlist (extension point)
│ ├── walletkit.ts stellar-wallets-kit init + active-wallet signing
│ ├── horizon.ts Stellar Horizon API helpers
Expand Down Expand Up @@ -475,6 +481,8 @@ create policy "Own profile" on user_profiles for all using (id = auth.uid());
| `NEXT_PUBLIC_STELLAR_NETWORK` | `testnet` |
| `NEXT_PUBLIC_RPC_URL` | `https://soroban-testnet.stellar.org` |
| `NEXT_PUBLIC_HORIZON_URL` | `https://horizon-testnet.stellar.org` |
| `NEXT_PUBLIC_WS_URL` | *(optional)* WebSocket relay for the live portfolio dashboard — omit to use the polling fallback |
| `NEXT_PUBLIC_XLM_USD_PRICE` | *(optional)* Fallback XLM/USD price for live USD position values |

---

Expand Down Expand Up @@ -539,6 +547,7 @@ Both identities are auto-funded via Friendbot on testnet. See
- [x] Architecture Decision Records — ADR index in both repos
- [x] Deployer-bound initialization — `__constructor` on all contracts, no front-runnable `initialize()` (issue #75)
- [x] Compliance posture documented — KYC/SEP-12 roadmap, jurisdictions, securities-by-design
- [x] Live portfolio dashboard — WebSocket streaming (position/yield/repayment) with reconnection + polling fallback (issue #221)
- [ ] Mainnet deployment
- [ ] Oracle-based invoice verification and risk scoring
- [ ] Multi-signature treasury and escrow
Expand Down
4 changes: 4 additions & 0 deletions docs/08-environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ All environment variables for the InvoFi frontend are prefixed with `NEXT_PUBLIC
| `NEXT_PUBLIC_RPC_URL` | Yes | See below | Soroban RPC endpoint (differs by network) |
| `NEXT_PUBLIC_HORIZON_URL` | Yes | See below | Stellar Horizon REST API (differs by network) |
| `NEXT_PUBLIC_USDC_ISSUER` | No | `GBBD47IF...` | USDC issuer address. Required to display USDC balances. |
| `NEXT_PUBLIC_WS_URL` | No | `wss://relay.invofi.dev` | WebSocket relay for the live portfolio dashboard (issue #221). When empty or unreachable the dashboard degrades to Soroban event-stream + Supabase polling. |
| `NEXT_PUBLIC_XLM_USD_PRICE` | No | `0.15` | XLM/USD fallback price used for live USD position values when the live price feed (CoinGecko) is unreachable. |

\* Legacy fallback: if the three `*_CONTRACT_ID` variables are unset, the app
uses the single `NEXT_PUBLIC_CONTRACT_ID` and routes every call to that one
Expand Down Expand Up @@ -79,3 +81,5 @@ To use different values for Preview and Production deployments, set the environm
| `RPC_URL` | `lib/contract.ts` — Soroban RPC for simulating and sending transactions |
| `HORIZON_URL` | `lib/horizon.ts` — reads account balances and transaction history |
| `USDC_ISSUER` | `lib/horizon.ts` — identifies the USDC asset when reading balances |
| `WS_URL` | `lib/live/*` — live portfolio dashboard WebSocket relay; falls back to polling |
| `XLM_USD_PRICE` | `lib/live/prices.ts` — fallback XLM/USD price for live USD position values |
28 changes: 28 additions & 0 deletions invofi/apps/frontend/.env.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copy to .env.local and fill in your values. See docs/08-environment-variables.md.

# ── Supabase (required) ─────────────────────────────────────────────────────
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=

# ── Stellar network ──────────────────────────────────────────────────────────
NEXT_PUBLIC_STELLAR_NETWORK=testnet
NEXT_PUBLIC_RPC_URL=https://soroban-testnet.stellar.org
NEXT_PUBLIC_HORIZON_URL=https://horizon-testnet.stellar.org
NEXT_PUBLIC_USDC_ISSUER=GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5

# ── Protocol contracts (required) ────────────────────────────────────────────
NEXT_PUBLIC_REGISTRY_CONTRACT_ID=
NEXT_PUBLIC_FINANCING_CONTRACT_ID=
NEXT_PUBLIC_REPAYMENT_CONTRACT_ID=

# ── Position tokens (optional; default shown) ────────────────────────────────
NEXT_PUBLIC_POSITION_TOKEN_ASSET=POS:GBDDLOWR6YUEEYUKFKS6ISTCLBQKDPUXAOVJMNJYAACT6UYQGEKYEVZR

# ── Live portfolio dashboard (optional) ──────────────────────────────────────
# WebSocket relay URL for the live portfolio dashboard (issue #221). When
# empty or unreachable the dashboard degrades to the Soroban event-stream +
# Supabase polling fallback.
NEXT_PUBLIC_WS_URL=

# XLM/USD fallback price used when the live price feed is unreachable.
NEXT_PUBLIC_XLM_USD_PRICE=
7 changes: 6 additions & 1 deletion invofi/apps/frontend/src/app/portfolio/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import type { Metadata } from 'next';
import { LivePortfolioProvider } from '@/components/portfolio/LivePortfolioProvider';

export const metadata: Metadata = {
title: 'Portfolio',
description: 'Track your active investments, earned yield, and repayment history across all financed invoices.',
};

export default function PortfolioLayout({ children }: { children: React.ReactNode }) {
return <>{children}</>;
return (
<LivePortfolioProvider>
{children}
</LivePortfolioProvider>
);
}
Loading