// Kaspa-style address encoder (copied from tools/observer/observer.mjs). Devnet prefix is igneumdev. const CHARSET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'; function polymod(values) { let c = 1n; for (const d of values) { const c0 = c >> 35n; c = ((c & 0x07ffffffffn) << 5n) ^ BigInt(d); if (c0 & 0x01n) c ^= 0x98f2bc8e61n; if (c0 & 0x02n) c ^= 0x79b76d99e2n; if (c0 & 0x04n) c ^= 0xf33e5fb3c4n; if (c0 & 0x08n) c ^= 0xae2eabe2a8n; if (c0 & 0x10n) c ^= 0x1e4f43e470n; } return c ^ 1n; } function conv8to5(bytes) { const out = []; let buff = 0, bits = 0; for (const b of bytes) { buff = ((buff << 8) | b) & 0xffff; bits += 8; while (bits >= 5) { bits -= 5; out.push((buff >> bits) & 31); buff &= (1 << bits) - 1; } } if (bits > 0) out.push((buff << (5 - bits)) & 31); return out; } export function encodeAddress(prefix, version, payload) { const five = conv8to5([version, ...payload]); const pre = [...prefix].map(ch => ch.charCodeAt(0) & 0x1f); const sum = polymod([...pre, 0, ...five, 0, 0, 0, 0, 0, 0, 0, 0]); const sumBytes = []; for (let i = 4; i >= 0; i--) sumBytes.push(Number((sum >> BigInt(i * 8)) & 0xffn)); return `${prefix}:${[...five, ...conv8to5(sumBytes)].map(v => CHARSET[v]).join('')}`; } /// A deterministic devnet pay address for a miner label (32-byte payload from the label). export function devAddress(label = 'harness') { const payload = Array.from({ length: 32 }, (_, i) => (label.charCodeAt(i % label.length) * (i + 1)) & 0xff); return encodeAddress('igneumdev', 0, payload); }