Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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