Files
wownero.org-website/js/donations.test.cjs
T
jwinterm 40ed2fa221 feat(donations): live fund balances from wownero.org's own nodes
The page asked mempool.space, Blockscout and PublicNode for three of the
five balances from each visitor's browser, and showed nothing for WOW and
XMR. wownero.org now reads every balance once a minute, from its own
Wownero, Bitcoin and Ethereum nodes and PublicNode for Solana, and
publishes /donations/balances.json. The page reads only that.

WOW gains a live balance from a view-only wallet and its view key is
published so anyone can verify incoming donations; XMR follows once its
view key is. A source that cannot be read shows its last value marked as
such, or says it is unavailable; it is never shown as zero.
2026-10-04 19:59:15 -04:00

36 lines
1.9 KiB
JavaScript

'use strict';
const { test } = require('node:test');
const assert = require('node:assert/strict');
const { amount, describe } = require('./donations.js');
test('server amounts keep their precision and lose only trailing zeros', () => {
assert.equal(amount('1.000000000000000001'), '1.000000000000000001');
assert.equal(amount('0.00027878'), '0.00027878');
assert.equal(amount('5.637709531'), '5.637709531');
assert.equal(amount('0.000000000000000000'), '0');
assert.equal(amount('12'), '12');
for (const invalid of [null, undefined, '', '1.5e3', 'NaN', 1.5, '1.']) {
assert.throws(() => amount(invalid));
}
});
test('a source that cannot be read is never shown as zero', () => {
const never = describe('ETH', { status: 'unavailable', error: 'OSError: no route', source: 'x' });
assert.equal(never.balance, 'Balance unavailable.');
const stale = describe('ETH', { status: 'stale', balance: '0.5', checked_at: '2026-10-05T00:00:00Z', source: 'x' });
assert.match(stale.balance, /^0\.5 ETH \(last read .+unreachable\)$/);
assert.equal(describe('XMR', undefined).balance, 'Not monitored yet.');
});
test('a view-only wallet says what its balance does and does not show', () => {
const base = { status: 'ok', balance: '10', total_received: '10', incoming_transfers: 2,
wallet_height: 100, chain_height: 100, checked_at: '2026-10-05T00:00:00Z', source: 'our node' };
const unsynced = describe('WOW', base).details.join(' ');
assert.match(unsynced, /Received in total: 10 WOW over 2 incoming transfers/);
assert.match(unsynced, /incoming funds only/);
const synced = describe('WOW', { ...base, key_images_synced_at: '2026-10-05T00:00:00Z' }).details.join(' ');
assert.match(synced, /Spending is reflected as of/);
const scanning = describe('WOW', { ...base, scanning: true, wallet_height: 40 }).details.join(' ');
assert.match(scanning, /still scanning the chain \(60 blocks to go\)/);
});