+
-
+
-
+
+
+
+
+
diff --git a/frontend-dapp/src/features/omnl-dashboard/FineractLedgerBanner.tsx b/frontend-dapp/src/features/omnl-dashboard/FineractLedgerBanner.tsx
index 8555f39..1429a12 100644
--- a/frontend-dapp/src/features/omnl-dashboard/FineractLedgerBanner.tsx
+++ b/frontend-dapp/src/features/omnl-dashboard/FineractLedgerBanner.tsx
@@ -1,99 +1,198 @@
-import type { MoneySupply } from '../central-bank/useCentralBank';
-import NasaIcon from '../../components/icons/NasaIcon';
-
-type Props = {
- moneySupply: MoneySupply | null;
- loading?: boolean;
- officeName?: string;
-};
-
-function formatAsOf(asOf?: string) {
- if (!asOf) return null;
- return asOf.slice(0, 19).replace('T', ' ') + ' UTC';
-}
-
-function BannerIcon({ variant }: { variant: 'ok' | 'warn' | 'error' | 'loading' }) {
- const map = {
- ok: { name: 'check' as const, className: 'nasa-icon--nominal' },
- warn: { name: 'alert' as const, className: 'nasa-icon--caution' },
- error: { name: 'x' as const, className: 'nasa-icon--critical' },
- loading: { name: 'loading' as const, className: 'nasa-icon--telemetry nasa-icon--spin' },
- };
- const { name, className } = map[variant];
- return
;
-}
-
-export default function FineractLedgerBanner({ moneySupply, loading, officeName }: Props) {
- if (loading && !moneySupply) {
- return (
-
-
-
-
Loading live ledger balances
-
Fetching Fineract data for Office 24
-
-
- );
- }
-
- if (!moneySupply) {
- return (
-
-
-
-
Ledger data not available
-
- The money-supply API did not respond. Check settlement middleware on port 3011.
-
-
-
- );
- }
-
- const asOf = formatAsOf(moneySupply.asOf);
- const officeLabel = officeName ?? `Office ${moneySupply.officeId ?? 24}`;
-
- if (moneySupply.fineractConnected === false) {
- return (
-
-
-
-
Fineract offline
-
- Cannot reach Fineract for {officeLabel}. Verify OMNL_FINERACT_* credentials on the
- settlement service.
-
-
-
- );
- }
-
- if (moneySupply.fineractConnected && !moneySupply.fineractLive) {
- return (
-
-
-
-
Fineract connected — opening journal pending
-
- {officeLabel} has no M1 allocation yet. Post the opening entry: Debit GL 1410 (Due from
- Head Office) · Credit GL 2100 (M1 liabilities).
- {asOf ? ` · Checked ${asOf}` : ''}
-
-
-
- );
- }
-
- return (
-
-
-
-
Live Fineract ledger · {officeLabel}
-
- M0 / M1 / M2 balances below are read from Fineract in real time.
- {asOf ? ` Last updated ${asOf}.` : ''}
-
-
-
- );
-}
+import type { MoneySupply } from '../central-bank/useCentralBank';
+
+import NasaIcon from '../../components/icons/NasaIcon';
+
+
+
+type Props = {
+
+ moneySupply: MoneySupply | null;
+
+ loading?: boolean;
+
+ officeName?: string;
+
+};
+
+
+
+function formatAsOf(asOf?: string) {
+
+ if (!asOf) return null;
+
+ return asOf.slice(0, 19).replace('T', ' ') + ' UTC';
+
+}
+
+
+
+function BannerIcon({ variant }: { variant: 'ok' | 'warn' | 'error' | 'loading' }) {
+
+ const map = {
+
+ ok: { name: 'check' as const, className: 'nasa-icon--nominal' },
+
+ warn: { name: 'alert' as const, className: 'nasa-icon--caution' },
+
+ error: { name: 'x' as const, className: 'nasa-icon--critical' },
+
+ loading: { name: 'loading' as const, className: 'nasa-icon--telemetry nasa-icon--spin' },
+
+ };
+
+ const { name, className } = map[variant];
+
+ return
;
+
+}
+
+
+
+export default function FineractLedgerBanner({ moneySupply, loading, officeName }: Props) {
+
+ if (loading && !moneySupply) {
+
+ return (
+
+
+
+
+
+
+
+
Loading live ledger balances
+
+
Fetching Fineract data for Office 24
+
+
+
+
+
+ );
+
+ }
+
+
+
+ if (!moneySupply) {
+
+ return (
+
+
+
+
+
+
+
+
Ledger data not available
+
+
+
+ The money-supply API did not respond. Check settlement middleware on port 3011.
+
+
+
+
+
+
+
+ );
+
+ }
+
+
+
+ const asOf = formatAsOf(moneySupply.asOf);
+
+ const officeLabel = officeName ?? `Office ${moneySupply.officeId ?? 24}`;
+
+
+
+ if (moneySupply.fineractConnected === false) {
+
+ return (
+
+
+
+
+
+
+
+
Fineract offline
+
+
+
+ Cannot reach Fineract for {officeLabel}. Verify OMNL_FINERACT_* credentials on the
+
+ settlement service.
+
+
+
+
+
+
+
+ );
+
+ }
+
+
+
+ if (moneySupply.fineractConnected && !moneySupply.fineractLive) {
+
+ return (
+
+
+
+
+
+
+
+
Fineract connected — opening journal pending
+
+
+
+ {officeLabel} has no M1 allocation yet. Post the opening entry: Debit GL 1410 (Due from
+
+ Head Office) · Credit GL 2100 (M1 liabilities).
+
+ {asOf ? ` · Checked ${asOf}` : ''}
+
+
+
+
+
+
+
+ );
+
+ }
+
+
+
+ return (
+
+
+
+
+
+
+
+
Live Fineract ledger · {officeLabel}
+
+
+
+ M0–M4 balances below are read from Fineract in real time.
+
+ {asOf ? ` Last updated ${asOf}.` : ''}
+
+
+
+
+
+
+
+ );
+
+}
+
diff --git a/frontend-dapp/src/features/swap/DBISSwapPanel.tsx b/frontend-dapp/src/features/swap/DBISSwapPanel.tsx
index 0de2fab..aa4a1fe 100644
--- a/frontend-dapp/src/features/swap/DBISSwapPanel.tsx
+++ b/frontend-dapp/src/features/swap/DBISSwapPanel.tsx
@@ -191,6 +191,8 @@ export default function DBISSwapPanel() {
M1: {(swap.ledger as { fundLedger?: { M1?: { circulating?: string } } }).fundLedger?.M1?.circulating ?? '—'}
M2: {(swap.ledger as { fundLedger?: { M2?: { broadMoney?: string } } }).fundLedger?.M2?.broadMoney ?? '—'}
+
M3: {(swap.ledger as { fundLedger?: { M3?: { tokenLiabilities?: string } } }).fundLedger?.M3?.tokenLiabilities ?? '—'}
+
M4: {(swap.ledger as { fundLedger?: { M4?: { nearMoney?: string } } }).fundLedger?.M4?.nearMoney ?? '—'}
{(swap.ledger as { cryptoLedger?: { balances?: Record
} }).cryptoLedger?.balances && (
Wallet balances
@@ -209,8 +211,8 @@ export default function DBISSwapPanel() {
)}
-
- GL 2200 → on-chain M2
+
+ GL 2200 → GL 2300 · on-chain M3
swap.setLoadAmount(e.target.value)} className="nasa-input mb-2 text-sm" />