// UBP sub-page: Storage Hosting node. // User pledges disk space → earns UBR via pin / retrieve / proof-of-storage rewards. // Editorial-instrument hybrid (paper top, dark monitoring strip). function StorageHostingDapp() { // 24h utilization sparkline values (each is "% of pledged capacity used") const util24 = [42, 44, 46, 48, 51, 53, 56, 58, 61, 63, 64, 66, 67, 69, 71, 72, 73, 73, 72, 71, 70, 69, 68, 68]; const earn30d = [3.8, 4.1, 3.9, 4.4, 4.7, 4.5, 4.8, 5.1, 4.9, 5.3, 5.6, 5.4, 5.8, 6.1, 5.9, 6.2, 6.5, 6.4, 6.7, 7.0, 6.8, 7.2, 7.5, 7.3, 7.8, 8.1, 7.9, 8.4, 8.7, 9.1]; // Pledged disks const disks = [ { name: 'attic-nvme-01', kind: 'NVMe', pledged: 2.0, used: 1.42, region: 'Home · UK-S', class: 'HOT', yield: 4.20, status: 'ACTIVE', tone: 'ok' }, { name: 'attic-hdd-04', kind: 'HDD', pledged: 8.0, used: 5.10, region: 'Home · UK-S', class: 'WARM', yield: 6.80, status: 'ACTIVE', tone: 'ok' }, { name: 'colo-r2-12', kind: 'HDD', pledged: 22.0, used: 17.4, region: 'Colo · DE-FRA', class: 'WARM', yield: 18.40, status: 'PROVING', tone: 'accent' }, { name: 'archive-tape', kind: 'Tape', pledged: 96.0, used: 84.2, region: 'Cold · US-E', class: 'COLD', yield: 12.10, status: 'ACTIVE', tone: 'ok' }, { name: 'edge-pi5-bath', kind: 'SSD', pledged: 0.5, used: 0.18, region: 'Home · UK-S', class: 'HOT', yield: 0.42, status: 'IDLE', tone: 'warn' }, ]; // Pinned datasets (live) const pins = [ { cid: 'Qmf8…2c3a', name: 'murine-cortex-2P-cohort1', size: 482, repl: '14×', dur: '184d', class: 'WARM', earn: 24.10, on: 'colo-r2-12' }, { cid: 'QmZ7…91fe', name: 'glia-pruning-rawimg-v3', size: 128, repl: '8×', dur: '96d', class: 'WARM', earn: 18.20, on: 'colo-r2-12' }, { cid: 'QmA1…d804', name: 'astro-ablation-electrophys', size: 64, repl: '12×', dur: '54d', class: 'WARM', earn: 5.40, on: 'attic-hdd-04' }, { cid: 'QmK9…0b78', name: 'open-spike-sort-bench', size: 14, repl: '24×', dur: '218d', class: 'HOT', earn: 4.80, on: 'attic-nvme-01' }, { cid: 'QmH4…aa18', name: 'preprint-figures-archive', size: 8, repl: '14×', dur: '342d', class: 'COLD', earn: 1.40, on: 'archive-tape' }, { cid: 'QmN0…8c44', name: 'rnaseq-2026q1', size: 210, repl: '8×', dur: '32d', class: 'WARM', earn: 9.80, on: 'colo-r2-12' }, ]; const recent = [ ['+0.420', 'Storage proof · sector 0x18ac…', '17:04', 'PROOF', 'accent'], ['+0.180', 'Retrieval · QmZ7…91fe · 412 MB', '17:01', 'RETRIEVE', 'ok'], ['+1.840', 'Pin reward epoch 4,219', '16:50', 'PIN', 'ok'], ['+0.060', 'Retrieval · QmK9…0b78 · 28 MB', '16:48', 'RETRIEVE', 'ok'], ['+0.120', 'Storage proof · sector 0x21f3…', '16:42', 'PROOF', 'accent'], ['+2.140', 'New pin accepted · QmN0…8c44', '16:32', 'NEW PIN', 'info'], ['−0.040', 'Bandwidth gas', '16:28', 'COST', 'warn'], ['+0.220', 'Retrieval · Qmf8…2c3a · 1.2 GB', '16:21', 'RETRIEVE', 'ok'], ]; const totalPledged = disks.reduce((a, d) => a + d.pledged, 0); const totalUsed = disks.reduce((a, d) => a + d.used, 0); // Sparkline for the dark instrument strip const SparkBig = ({ values, color }) => { const w = 240, h = 40; const max = Math.max(...values), min = Math.min(...values); const dx = w / (values.length - 1); const norm = v => h - ((v - min) / (max - min || 1)) * (h - 4) - 2; const path = values.map((v, i) => `${i === 0 ? 'M' : 'L'}${i * dx},${norm(v)}`).join(' '); return ( ); }; const Cell = ({ v, w, mono = true, color, end }) => ( {v} ); return ( : null}> UBP · Storage hostingDePIN · UB-CHAIN>} title="Earn UBR by hosting science data" sub="Pledge storage from any disk you own. The chain replicates papers, datasets, and notebooks across your space and pays you per byte-day, retrieval, and successful storage proof." actions={<> Browse pin demand Node settings Pledge a new disk >} /> {/* DARK INSTRUMENT STRIP — earnings + capacity */} EARNING NOW 0.82 UBR / HOUR · ↑6.4% 30D EARNINGS 184.2 UBR · 4 EPOCHS PLEDGED · USED {totalUsed.toFixed(1)} / {totalPledged.toFixed(0)} TB PROOFS · 24H 2,184 0 FAIL · 99.99% UPTIME 30D EARNINGS · UBR 04 APRNOW {/* LEFT — pledged disks + pinned datasets */} {/* Pledged disks */} {disks.map((d, i) => ( {d.name}>} w="160px" mono={false} /> {d.used} TB{Math.round((d.used / d.pledged) * 100)}% {d.class} {d.status} ))} TOTAL · {totalPledged.toFixed(1)} TB pledged · {totalUsed.toFixed(1)} TB used · 4 active disks + ADD DISK {/* Pin demand */} {pins.map((p, i) => ( {p.name} }, { v: `${p.size} GB`, w: '70px' }, { v: p.repl, w: '54px', style: { color: UB.ink3 } }, { v: {p.class}, w: '74px' }, { v: {p.on}, w: '120px' }, { v: +{p.earn.toFixed(2)}, w: '78px', style: { textAlign: 'right' } }, ]} /> ))} {/* Reward feed */} {recent.map((r, i) => ( {r[0]} UBR {r[1]} {r[2]} {r[3]} ))} {/* RIGHT — pledge wizard, economics, proof health */} {/* Pledge wizard */} {/* Step 1 — capacity */} STEP 01 · CAPACITY 4.0 TB pledged {/* Slider */} 0.5 TB4.0 / 20 TB20 TB {/* Step 2 — class */} STEP 02 · STORAGE CLASS {[ ['HOT', 'NVMe / SSD', '×3.2', false], ['WARM', 'HDD · always-on', '×1.0', true], ['COLD', 'Tape / archive', '×0.4', false], ].map(c => ( {c[0]} {c[1]} {c[2]} ))} {/* Step 3 — bond */} STEP 03 · COLLATERAL BOND Lock 12 UBR / TB as bond. Slashed only if you fail storage proofs. Returns when you decommission. 48 UBR · wallet 12,840 UBR {/* Estimator */} EST. EARNINGS · 4 TB · WARM 2.40 UBR / DAY 72 UBR / MO 5.4% EFF. APY Run healthcheck Pledge & bond {/* Economics */} Three reward streams settle every epoch (≈6h). Slashing applies if you miss a proof window. {[ ['PIN', 'Per byte-day stored · paid by dataset DAO', '×1.0', UB.ok], ['RETRIEVE', 'Per GB served on demand', '×2.4', UB.ok], ['PROOF', 'Per successful storage-proof challenge', '×1.0', UB.accent], ['SLASH', 'Failed proof window > 6h', '×0.8 bond', UB.bad || '#b6362a'], ].map((r, i, arr) => ( {r[0]} {r[1]} {r[2]} ))} {/* Proof health */} {util24.map((v, i) => ( ))} 00:00UTILIZATION %NOW · 68% {/* Network role */} You currently hold 0.018% of UB-Chain's total pledged storage. Demand for warm research data exceeds supply by +18.4% — pledging more disk now compounds yield until the next epoch rebalance. ); } window.StorageHostingDapp = StorageHostingDapp;