lotus-sdk
Version:
Central repository for several classes of tools for integrating with, and building for, the Lotusia ecosystem
83 lines (82 loc) • 2.64 kB
JavaScript
import { sha256 } from '@noble/hashes/sha256';
const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
const ALPHABET_MAP = {};
for (let i = 0; i < ALPHABET.length; i++) {
ALPHABET_MAP[ALPHABET[i]] = i;
}
export class Base58Check {
static encode(buf) {
if (!Buffer.isBuffer(buf)) {
throw new Error('Input must be a Buffer');
}
const checksum = this.checksum(buf);
const payload = Buffer.concat([buf, checksum]);
return this.base58Encode(payload);
}
static decode(str) {
if (typeof str !== 'string') {
throw new Error('Input must be a string');
}
const buf = this.base58Decode(str);
if (buf.length < 4) {
throw new Error('Input string too short');
}
const data = buf.subarray(0, -4);
const checksum = buf.subarray(-4);
if (!this.validChecksum(data, checksum)) {
throw new Error('Invalid checksum');
}
return data;
}
static checksum(data) {
const hash1 = sha256(data);
const hash2 = sha256(hash1);
return Buffer.from(hash2).subarray(0, 4);
}
static validChecksum(data, checksum) {
const calculatedChecksum = this.checksum(data);
return calculatedChecksum.equals(checksum);
}
static base58Encode(buf) {
if (buf.length === 0)
return '';
let num = 0n;
for (let i = 0; i < buf.length; i++) {
num = num * 256n + BigInt(buf[i]);
}
let result = '';
while (num > 0n) {
result = ALPHABET[Number(num % 58n)] + result;
num = num / 58n;
}
for (let i = 0; i < buf.length && buf[i] === 0; i++) {
result = '1' + result;
}
return result;
}
static base58Decode(str) {
if (str.length === 0)
return Buffer.alloc(0);
let num = 0n;
let leadingZeros = 0;
for (let i = 0; i < str.length; i++) {
const char = str[i];
if (ALPHABET_MAP[char] === undefined) {
throw new Error(`Invalid character: ${char}`);
}
num = num * 58n + BigInt(ALPHABET_MAP[char]);
}
for (let i = 0; i < str.length && str[i] === '1'; i++) {
leadingZeros++;
}
const bytes = [];
while (num > 0n) {
bytes.unshift(Number(num % 256n));
num = num / 256n;
}
for (let i = 0; i < leadingZeros; i++) {
bytes.unshift(0);
}
return Buffer.from(bytes);
}
}