// ============================================================================ // Principia White Paper — Chart library (part 2: flow, economics, structure) // ============================================================================ // ════════════════════════════════════════════════════════════════════════ // FIG — From 5 intermediaries to zero (settlement flow comparison) // ════════════════════════════════════════════════════════════════════════ function IntermediaryFlow() { const [ref, seen] = useReveal(); const today = ['Sender', 'Originating bank', 'Correspondent', 'Correspondent', 'Beneficiary bank', 'Recipient']; const ours = ['Sender', 'Digital Bank — direct settlement', 'Recipient']; const Node = ({ label, tone, i, n }) => (
{label}
); const Arrow = ({ i, danger }) => (
); return (
Today · 5–7 parties $15–35 per hop · any bank can exit
{today.map((t, i) => ( {i < today.length - 1 && } ))}
Our model · 2 parties €0.002 per instant payment · cannot be de-risked
{ours.map((t, i) => ( {i < ours.length - 1 && } ))}
); } // ════════════════════════════════════════════════════════════════════════ // FIG — Partner economics: net margin per $200 transfer (+105%) // ════════════════════════════════════════════════════════════════════════ function MarginCompare() { const [ref, seen] = useReveal(); const mobile = useIsMobile(640); const H = mobile ? 200 : 300, MAX = 16; const cols = [ { title: 'Today', tone: C_DANGER, segs: [ { label: 'Net margin', value: 4.0, color: C_INK, net: true, display: '$4.00' }, { label: 'Compliance + ops', value: 4.0, color: 'rgba(91,107,133,0.45)', display: '–$4.00' }, { label: 'Intermediary fees', value: 8.0, color: C_DANGER2, display: '–$8.00' }, ], }, { title: 'On our rails', tone: C_SUCCESS, segs: [ { label: 'Net margin', value: 8.2, color: C_SUCCESS, net: true, display: '$8.20' }, { label: 'Payout (mobile money)', value: 4.0, color: 'rgba(91,107,133,0.45)', display: '–$4.00' }, { label: 'Our fee (1.90%)', value: 3.8, color: C_ACCENT, display: '–$3.80' }, ], }, ]; const netToday = useCountUp(4, seen, { decimals: 2 }); const netOurs = useCountUp(8.2, seen, { decimals: 2 }); return (
{cols.map((col, ci) => (
{col.segs.map((s, si) => (
))}
{col.segs.slice().reverse().map((s, si) => (
{s.label} {s.display}
))}
{col.title}
${ci === 0 ? netToday : netOurs}
net margin · per $200 transfer
))}
+105%
net margin improvement. Same price to the customer. Same volume — four layers of intermediaries removed.
); } // ════════════════════════════════════════════════════════════════════════ // FIG — Competitive matrix (capabilities × providers) // ════════════════════════════════════════════════════════════════════════ function CompetitiveMatrix() { const [ref, seen] = useReveal(0.12); const mobile = useIsMobile(640); const caps = [ 'Direct ECB (TARGET2 / TIPS)', 'Direct BoE (FPS / CHAPS)', 'Nordic direct (SEK / DKK / NOK)', 'MC / Visa principal membership', 'Own POS acquiring stack', 'Sub-Saharan Africa corridor', 'Zero intermediary dependency', ]; // 2 = full, 1 = partial, 0 = none const providers = [ { name: 'Banking Circle', vals: [2, 0, 1, 0, 0, 0, 0], score: '2 / 7' }, { name: 'ClearBank', vals: [0, 2, 0, 0, 0, 0, 0], score: '1 / 7' }, { name: 'Modulr', vals: [0, 0, 0, 2, 0, 0, 0], score: '1 / 7' }, { name: 'Digital Bank', vals: [2, 2, 2, 2, 2, 2, 2], score: '7 / 7', us: true }, ]; const Dot = ({ v, us, delay }) => { const color = v === 2 ? (us ? '#fff' : C_INK) : v === 1 ? C_ACCENT : 'transparent'; return ( {v === 1 ? ( ) : v === 2 ? ( ) : ( )} ); }; if (mobile) { const StatusIcon = ({ v }) => v === 2 ? : v === 1 ? ½ : ; return (
{providers.map((p) => (
{p.name}
{p.score}
{caps.map((cap, ri) => (
{cap}
))}
))}
Full ½ Partial None
); } return (
{/* header */}
{providers.map((p) => (
{p.name}
))} {/* rows */} {caps.map((cap, ri) => (
{cap}
{providers.map((p) => (
))}
))} {/* score */}
Score
{providers.map((p) => (
{p.score}
))}
Full Partial None
); } // ════════════════════════════════════════════════════════════════════════ // FIG — Five currencies, five central banks, direct (hub diagram) // ════════════════════════════════════════════════════════════════════════ function CentralBanksDiagram() { const [ref, seen] = useReveal(); const banks = [ { cur: 'EUR', bank: 'ECB', rail: 'TARGET2 / TIPS' }, { cur: 'GBP', bank: 'Bank of England', rail: 'FPS / CHAPS' }, { cur: 'SEK', bank: 'Riksbanken', rail: 'RIX' }, { cur: 'DKK', bank: 'Nationalbanken', rail: 'TARGET DKK' }, { cur: 'NOK', bank: 'Norges Bank', rail: 'NBO' }, ]; return (
One licence
Lithuanian specialised bank
{[50, 150, 250, 350, 450].map((x, i) => ( ))}
{banks.map((b, i) => (
{b.cur}
{b.bank}
{b.rail}
))}
No correspondent bank required for any major European currency
); } // ════════════════════════════════════════════════════════════════════════ // FIG — Settlement rails table (currency lanes) // ════════════════════════════════════════════════════════════════════════ function CurrencyRails() { const [ref, seen] = useReveal(0.15); const mobile = useIsMobile(640); const rows = [ { cur: 'EUR', rail: 'TARGET2 / TIPS', cost: '€0.002', speed: '<10 sec', entity: 'Lithuanian specialised bank — direct ECB' }, { cur: 'GBP', rail: 'FPS / CHAPS', cost: '£0.487', speed: '<2 sec', entity: 'PRA branch — Year 2 (CHAPS direct)' }, { cur: 'SEK', rail: 'RIX-INST', cost: '~SEK 0.02', speed: '<10 sec', entity: 'Direct — Riksbanken (Apr 2025, TIPS-based)' }, { cur: 'DKK', rail: 'TARGET DKK', cost: '~DKK 0.015', speed: '<10 sec', entity: 'Direct — ECB TIPS infrastructure' }, { cur: 'NOK', rail: 'NBO', cost: 'Fixed fee', speed: 'Same-day', entity: 'Direct — Norges Bank (NBO INST H1 2028)' }, ]; if (mobile) { return (
{rows.map((r, i) => (
{r.cur}
{r.speed}
{r.rail}
Cost / txn
{r.cost}
{r.entity}
))}
); } return (
Cur.
Rail
Cost / txn
Speed
Settlement entity
{rows.map((r, i) => (
{r.cur}
{r.rail}
{r.cost}
{r.speed}
{r.entity}
))}
); } // ════════════════════════════════════════════════════════════════════════ // FIG — Partner onboarding timeline (Day 1 → 7) // ════════════════════════════════════════════════════════════════════════ function OnboardingTimeline() { const [ref, seen] = useReveal(); const steps = [ { day: '1–3', t: 'Onboarding & due diligence', d: 'EDD, AML/CTF policy & procedures, external audit document. KYC/KYB. Sanctions screening. Risk assessment.' }, { day: '3–4', t: 'Account setup', d: 'Segregated safeguarding account. API credentials. Sandbox access.' }, { day: '4–5', t: 'Integration', d: 'Iframe drop-in or API integration. Test transactions in sandbox.' }, { day: '5–7', t: 'Go-live', d: 'Production switch. First live transaction. Settlement cycle begins.' }, ]; return (
{steps.map((s, i) => (
{i + 1}
Day {s.day}
{s.t}
{s.d}
))}
); } // ════════════════════════════════════════════════════════════════════════ // FIG — Platform architecture (layered stack) // ════════════════════════════════════════════════════════════════════════ function ArchitectureStack() { const [ref, seen] = useReveal(0.12); const layers = [ { name: 'Regulatory', items: [ ['EU', 'Lithuanian specialised bank', 'EEA passporting · SEPA direct · MC/Visa principal'], ['UK', 'PRA branch', 'BoE settlement · FPS/CHAPS · Year 2'], ['Nordics', 'Direct clearing', 'Riksbanken · Nationalbanken · Norges Bank'], ] }, { name: 'Infrastructure', items: [ ['Core banking', 'Mambu', 'Cloud SaaS · ledger · FX engine'], ['Payments', 'SWIFT + TIPS', 'Own BIC · HSM + PKI · direct participant'], ['Cards', 'MC/Visa principal', 'Own BIN · issuing + acquiring'], ['Risk', 'Onfido / Sumsub', 'KYC/AML · Chainalysis · Dow Jones screening'], ] }, { name: 'Partner', items: [ ['API', 'REST / GraphQL', 'OpenAPI 3.0 · OAuth 2.0 · webhooks'], ['Gateway', 'Hosted iframe + SDK', 'PCI-compliant · 48-hour go-live'], ['Portal', 'Dashboard', 'Transactions · settlements · reconciliation'], ] }, ]; return (
{layers.map((layer, li) => (
Layer {li + 1}
{layer.name}
{layer.items.map((it, ii) => (
{it[0]}
{it[1]}
{it[2]}
))}
))}
); } Object.assign(window, { IntermediaryFlow, MarginCompare, CompetitiveMatrix, CentralBanksDiagram, CurrencyRails, OnboardingTimeline, ArchitectureStack, });