Versie 0.2.0

This commit is contained in:
Atreides Assets committed 2026-10-29 11:57:29 +01:00
commit e77d8fd373
495 files changed
+81026

No files matched your search

+74
View File
@@ -0,0 +1,74 @@
// Generated, do not edit. sha256:e9ea9293b00980ab0270b38c345d130a439421cd662f57bea63c105e66a1587f
import { CONFIG } from '../../shared/config.js';
import { activeConnection } from '../data/connections.js';
import { t } from '../i18n/index.js';
export async function explorerBase() {
return (await activeConnection('btc_explorer')).url;
}
const HTTP_TIMEOUT_MS = 12000;
const HTTP_RETRIES = 1;
const HTTP_BACKOFF_MS = 800;
export async function fetchJson(url, label, options = {}) {
let laatste;
for (let poging = 0; poging <= HTTP_RETRIES; poging++) {
if (poging) await new Promise(r => setTimeout(r, HTTP_BACKOFF_MS * poging));
const ctrl = new AbortController();
const timer = setTimeout(() => ctrl.abort(), HTTP_TIMEOUT_MS);
try {
const res = await fetch(url, { ...options, signal: ctrl.signal });
if (res.ok) return await res.json();
laatste = new Error(t('integrations.price.callFailed', { label, status: res.status }));
if (res.status < 500 && res.status !== 429) throw laatste;
} catch (e) {
if (e === laatste) throw e;
laatste = e.name === 'AbortError'
? new Error(t('integrations.price.callTimeout', { label, s: HTTP_TIMEOUT_MS / 1000 }))
: e;
} finally {
clearTimeout(timer);
}
}
throw laatste;
}
export async function addressInfo(addr) {
const base = await explorerBase();
const d = await fetchJson(`${base}/api/address/${addr}`, t('integrations.price.labelAddress', { adres: addr }));
const balance_sats = d.chain_stats.funded_txo_sum - d.chain_stats.spent_txo_sum;
const tx_count = d.chain_stats.tx_count + d.mempool_stats.tx_count;
return { balance_sats, tx_count };
}
const PAGE = 25;
const MAX_PAGES = 200;
const lastConfirmedTxid = batch => {
for (let i = batch.length - 1; i >= 0; i--) {
if (batch[i].status && batch[i].status.confirmed) return batch[i].txid;
}
return null;
};
export async function addressTxs(addr) {
const base = await explorerBase();
const all = await fetchJson(`${base}/api/address/${addr}/txs`, t('integrations.price.labelAddressTxs', { adres: addr }));
let cursor = lastConfirmedTxid(all);
let pages = 0;
while (cursor && pages < MAX_PAGES) {
await new Promise(r => setTimeout(r, 150));
let batch;
try {
batch = await fetchJson(`${base}/api/address/${addr}/txs/chain/${cursor}`, t('integrations.price.labelAddressTxsPage'));
} catch (e) {
console.warn(`[addressTxs] pagination stopped for ${addr}: ${e.message}`);
break;
}
if (!batch.length) break;
all.push(...batch);
if (batch.length < PAGE) break;
cursor = batch[batch.length - 1].txid;
pages++;
}
return all;
}