Files
AtreidesAssetsFree/client/ui/fiat.js
T
2026-10-29 11:57:29 +01:00

143 lines
5.4 KiB
JavaScript

// Generated, do not edit. sha256:90b33d041c8c7e24dc16bdda9708154576175dfedc5c9ea7860984b38b588f03
import { listAssets } from '../data/assets.js';
import { upsertPriceHistory, getPricePoint, getPriceAt } from '../data/price-history.js';
import { onchainAsset } from '../data/tx-links.js';
import { liveSpotFor, ensurePriceHistoryFor, hasDailyGridFor, historicalPointForVia, primarySourceKey, lastSpotSource, basePriceOf, rateOn } from '../price/providers.js';
import { priceAtMoment } from '../data/market.js';
import { baseCurrency } from '../app-settings.js';
import { getProvider, listProviders } from '../data/providers.js';
import { provenanceOfRow, originFrom, liveOrigin } from '../../shared/price-provenance.js';
import { fmtBase, fmtMoney, isBaseAsset, priceFromBase } from './format.js';
const spot = new Map();
const hist = new Map();
const defaultTarget = async () => onchainAsset();
const mainValue = (amountSub, asset) => amountSub / Math.pow(10, asset.decimals ?? 8);
const histKey = (assetId, dateKey) => `${assetId}:${dateKey}`;
const unixAtMidnight = dateKey => Math.floor(Date.parse(`${dateKey}T00:00:00Z`) / 1000);
export async function loadFiat(assets = null) {
const targets = assets || [await defaultTarget()];
for (const asset of targets) {
if (!asset) continue;
try {
const s = await liveSpotFor(asset);
spot.set(asset.id, s || { price: null });
} catch { }
}
return spot;
}
export function fiatValue(amountSub, asset) {
if (isBaseAsset(asset)) return '';
const s = asset && spot.get(asset.id);
if (!s) return '';
const price = basePriceOf(s);
if (price == null) return '';
return fmtMoney(mainValue(amountSub, asset) * price, baseCurrency());
}
export async function loadHistorical(items) {
if (!namen.size) await laadNamen();
const byAsset = new Map();
for (const it of items) {
if (!it || !it.assetId || !it.dateKey) continue;
if (!byAsset.has(it.assetId)) byAsset.set(it.assetId, new Set());
byAsset.get(it.assetId).add(it.dateKey);
}
for (const [assetId, keys] of byAsset) {
const asset = (await listAssets()).find(a => a.id === assetId);
if (asset) await loadHistoricalForAsset(asset, keys);
}
}
async function loadHistoricalForAsset(asset, keys) {
const gridSrc = await primarySourceKey(asset, 'daily_history');
const pointSrc = await primarySourceKey(asset, 'history_point');
const readSrc = gridSrc || pointSrc;
const hasGrid = await hasDailyGridFor(asset);
const punten = await Promise.all([...keys].map(k => getPricePoint(asset.id, k)));
if (hasGrid && punten.some(p => !p)) {
try { await ensurePriceHistoryFor(asset); } catch { }
}
for (const key of keys) {
const hk = histKey(asset.id, key);
if (hist.has(hk)) continue;
const stored = await getPriceAt(asset.id, unixAtMidnight(key), readSrc);
if (stored) { hist.set(hk, stored.fiatPrice); histRij.set(hk, stored); continue; }
if (!hasGrid) {
try {
const p = await historicalPointForVia(asset, key);
if (p) {
await upsertPriceHistory(asset.id, [p], pointSrc, 'day');
hist.set(hk, p.price);
const bron = await getProvider(pointSrc).catch(() => null);
histRij.set(hk, { fiatPrice: p.price, providerId: bron ? bron.id : null, resolution: 'day',
observedAt: `${key}T00:00:00Z`, createdAt: new Date().toISOString() });
}
else hist.set(hk, null);
} catch { hist.set(hk, null); }
} else {
hist.set(hk, null);
}
}
}
export function fiatHistorical(amountSub, asset, dateKey) {
if (!asset) return '';
const price = hist.get(histKey(asset.id, dateKey));
if (price == null) return '';
return fmtBase(mainValue(amountSub, asset) * price);
}
const histRij = new Map();
let namen = new Map();
let manualId = null;
async function laadNamen() {
try {
const providers = await listProviders();
namen = new Map(providers.map(p => [p.id, p.name]));
const m = providers.find(p => p.key === 'manual');
manualId = m ? m.id : null;
} catch { }
}
export function fiatHistoricalOrigin(asset, dateKey) {
if (!asset || isBaseAsset(asset)) return null;
const rij = histRij.get(histKey(asset.id, dateKey));
return rij ? originFrom(provenanceOfRow(rij, { day: dateKey, manualProviderId: manualId }), namen) : null;
}
export function fiatValueOrigin(asset) {
if (!asset || isBaseAsset(asset)) return null;
const s = spot.get(asset.id);
const prijs = basePriceOf(s);
return prijs != null ? liveOrigin(prijs, lastSpotSource(asset)) : null;
}
export async function spotOnDate(asset, dateKey) {
if (!asset || !dateKey) return null;
try { await loadHistorical([{ assetId: asset.id, dateKey }]); } catch { }
const pt = await getPricePoint(asset.id, dateKey);
return pt && pt.fiatPrice != null ? priceFromBase(pt.fiatPrice, asset) : null;
}
export async function spotAtMoment(asset, atIso) {
if (!asset || !atIso) return null;
try {
const r = await priceAtMoment(asset.id, atIso);
if (r.status !== 'ok') return null;
const rate = await rateOn(r.currency, String(atIso).slice(0, 10));
if (rate == null) return null;
return { price: priceFromBase(r.price * rate, asset), at: r.at, source: r.source };
} catch {
return null;
}
}
export function fiatAtPrice(amountSub, decimals, pricePerUnit) {
if (pricePerUnit == null) return '';
return fmtBase((amountSub / Math.pow(10, decimals ?? 8)) * pricePerUnit);
}