// Base58Check encode/decode for Tron addresses (0x41 || H160 || sha256d[:4]). // Bitcoin-style base58 alphabet; the caller supplies the raw 21-byte payload // (version byte first) so this module knows nothing about Tron itself. const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; const INDEX = new Int8Array(128).fill(-1); for (let i = 0; i < ALPHABET.length; i++) INDEX[ALPHABET.charCodeAt(i)] = i; module.exports = function makeBase58Check({ sha256 }) { function encodeBase58(bytes) { let zeros = 0; while (zeros < bytes.length && bytes[zeros] === 0) zeros++; // Convert base-256 → base-58 by repeated division. const b58 = new Uint8Array(Math.ceil(bytes.length * 138 / 100 + 1)); let length = 0; for (let i = zeros; i < bytes.length; i++) { let carry = bytes[i]; let j = 0; for (let k = b58.length - 1; (carry !== 0 || j < length) && k >= 0; k--, j++) { carry += (b58[k] << 8) >>> 0; b58[k] = carry % 58; carry = (carry / 58) | 0; } length = j; } // Skip leading zero-bytes in the base58 buffer, then prepend '1' per leading zero-byte in input. let it = b58.length - length; while (it < b58.length && b58[it] === 0) it++; let out = ""; for (let i = 0; i < zeros; i++) out += ALPHABET[0]; for (; it < b58.length; it++) out += ALPHABET[b58[it]]; return out; } function decodeBase58(str) { if (typeof str !== "string" || str.length === 0) throw new Error("base58: empty input"); let zeros = 0; while (zeros < str.length && str[zeros] === ALPHABET[0]) zeros++; const out = new Uint8Array(Math.ceil(str.length * 733 / 1000 + 1)); let length = 0; for (let i = zeros; i < str.length; i++) { const c = str.charCodeAt(i); const val = c < 128 ? INDEX[c] : -1; if (val < 0) throw new Error("base58: bad character " + JSON.stringify(str[i])); let carry = val; let j = 0; for (let k = out.length - 1; (carry !== 0 || j < length) && k >= 0; k--, j++) { carry += 58 * out[k]; out[k] = carry & 0xff; carry >>>= 8; } length = j; } let it = out.length - length; while (it < out.length && out[it] === 0) it++; const total = zeros + (out.length - it); const decoded = new Uint8Array(total); for (let i = 0; i < zeros; i++) decoded[i] = 0; let p = zeros; while (it < out.length) decoded[p++] = out[it++]; return decoded; } function encodeCheck(payload) { const bytes = payload instanceof Uint8Array ? payload : Uint8Array.from(payload); const check = sha256(sha256(bytes)).slice(0, 4); const full = new Uint8Array(bytes.length + 4); full.set(bytes, 0); full.set(check, bytes.length); return encodeBase58(full); } function decodeCheck(str) { const full = decodeBase58(str); if (full.length < 5) throw new Error("base58check: too short"); const payload = full.slice(0, full.length - 4); const check = full.slice(full.length - 4); const want = sha256(sha256(payload)).slice(0, 4); for (let i = 0; i < 4; i++) if (check[i] !== want[i]) throw new Error("base58check: bad checksum"); return payload; } return { encodeBase58, decodeBase58, encodeCheck, decodeCheck }; };