Versie 0.2.0
This commit is contained in:
commit
e77d8fd373
495 files changed
+81026
No files matched your search
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user