diff --git a/config/settlement-middleware.v1.json b/config/settlement-middleware.v1.json index cfb3e39..624e8f7 100644 --- a/config/settlement-middleware.v1.json +++ b/config/settlement-middleware.v1.json @@ -30,6 +30,9 @@ "glM0": "1050", "glM1": "2100", "glM2": "2200", + "glM3": "2300", + "glM4NearMoney": "1000", + "glM4Contingent": "1410", "glSettlement": "1000" }, "production": { diff --git a/frontend-dapp/src/features/central-bank/CentralBankDashboard.tsx b/frontend-dapp/src/features/central-bank/CentralBankDashboard.tsx index 889210d..2ccde1a 100644 --- a/frontend-dapp/src/features/central-bank/CentralBankDashboard.tsx +++ b/frontend-dapp/src/features/central-bank/CentralBankDashboard.tsx @@ -32,7 +32,15 @@ export default function CentralBankDashboard() { externalId?: string; - settlement?: { moneyLayers?: string[]; glM0?: string; glM1?: string; glM2?: string }; + settlement?: { + moneyLayers?: string[]; + glM0?: string; + glM1?: string; + glM2?: string; + glM3?: string; + glM4NearMoney?: string; + glM4Contingent?: string; + }; } | null; @@ -118,7 +126,7 @@ export default function CentralBankDashboard() { -
+
@@ -126,6 +134,10 @@ export default function CentralBankDashboard() { + + + +
@@ -208,7 +220,7 @@ export default function CentralBankDashboard() {
- {(office?.settlement?.moneyLayers ?? ['M0', 'M1', 'M2']).map((layer) => ( + {(office?.settlement?.moneyLayers ?? ['M0', 'M1', 'M2', 'M3', 'M4']).map((layer) => ( {layer} @@ -224,6 +236,10 @@ export default function CentralBankDashboard() {
M2 broad
GL {office?.settlement?.glM2 ?? '2200'}
+
M3 token liability
GL {office?.settlement?.glM3 ?? '2300'}
+ +
M4 near money
GL {office?.settlement?.glM4NearMoney ?? '1000'} + {office?.settlement?.glM4Contingent ?? '1410'}
+
Inter-office (HO)
GL 1410
diff --git a/frontend-dapp/src/features/central-bank/useCentralBank.ts b/frontend-dapp/src/features/central-bank/useCentralBank.ts index 0fcfaee..a034c91 100644 --- a/frontend-dapp/src/features/central-bank/useCentralBank.ts +++ b/frontend-dapp/src/features/central-bank/useCentralBank.ts @@ -10,6 +10,8 @@ export type MoneySupply = { M0?: { gl1050?: string; backingRatio?: number }; M1?: { circulating?: string; gl2100?: string }; M2?: { broadMoney?: string; gl2200?: string; metaFiatPending?: string }; + M3?: { tokenLiabilities?: string; gl2300?: string }; + M4?: { nearMoney?: string; gl1000?: string; glContingent?: string; inFlightSwift?: string }; }; async function fetchJson(url: string): Promise { diff --git a/frontend-dapp/src/features/office24/Office24Dashboard.tsx b/frontend-dapp/src/features/office24/Office24Dashboard.tsx index 80e4fe9..5804c2a 100644 --- a/frontend-dapp/src/features/office24/Office24Dashboard.tsx +++ b/frontend-dapp/src/features/office24/Office24Dashboard.tsx @@ -116,15 +116,19 @@ export default function Office24Dashboard() { -
+
- + - + + + + +
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" />