@ecash/lib
Version:
Library for eCash transaction building
101 lines • 4 kB
JavaScript
;
// Copyright (c) 2024 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
Object.defineProperty(exports, "__esModule", { value: true });
exports.encodeLegacyAddress = exports.decodeLegacyAddress = exports.LEGACY_VERSION_BYTES = exports.decodeBase58Check = exports.encodeBase58Check = void 0;
const hash_1 = require("../hash");
const b58_ts_1 = require("b58-ts");
const hex_1 = require("../io/hex");
/**
* Base 58 Check
*/
const encodeBase58Check = (data) => {
const checksum = (0, hash_1.sha256d)(data);
const dataWithChecksum = new Uint8Array(data.length + 4);
dataWithChecksum.set(data, 0);
dataWithChecksum.set(checksum.subarray(0, 4), data.length);
return (0, b58_ts_1.encodeBase58)(dataWithChecksum);
};
exports.encodeBase58Check = encodeBase58Check;
const decodeBase58Check = (str) => {
const dataWithChecksum = (0, b58_ts_1.decodeBase58)(str);
const payload = dataWithChecksum.slice(0, -4);
const checksum = dataWithChecksum.slice(-4);
const expectedChecksum = (0, hash_1.sha256d)(payload);
// Ensure the two checksums are equal
if ((checksum[0] ^ expectedChecksum[0]) |
(checksum[1] ^ expectedChecksum[1]) |
(checksum[2] ^ expectedChecksum[2]) |
(checksum[3] ^ expectedChecksum[3])) {
throw new Error('Invalid checksum');
}
return payload;
};
exports.decodeBase58Check = decodeBase58Check;
// Length of a valid base58check encoding payload: 1 byte for
// the version byte plus 20 bytes for a RIPEMD - 160 hash.
const BASE_58_CHECK_PAYLOAD_LENGTH = 21;
exports.LEGACY_VERSION_BYTES = {
legacy: {
mainnet: { p2pkh: 0, p2sh: 5 },
testnet: { p2pkh: 111, p2sh: 196 },
},
};
// Modeled from https://github.com/ealmansi/bchaddrjs/blob/master/src/bchaddr.js#L193
const decodeLegacyAddress = (address) => {
try {
const payload = (0, exports.decodeBase58Check)(address);
if (payload.length !== BASE_58_CHECK_PAYLOAD_LENGTH) {
throw new Error(`Invalid legacy address: payload length must be ${BASE_58_CHECK_PAYLOAD_LENGTH}`);
}
const versionByte = payload[0];
const hash = (0, hex_1.toHex)(new Uint8Array(payload.slice(1)));
switch (versionByte) {
case exports.LEGACY_VERSION_BYTES.legacy.mainnet.p2pkh:
return {
hash,
type: 'p2pkh',
network: 'mainnet',
};
case exports.LEGACY_VERSION_BYTES.legacy.mainnet.p2sh:
return {
hash,
type: 'p2sh',
network: 'mainnet',
};
case exports.LEGACY_VERSION_BYTES.legacy.testnet.p2pkh:
return {
hash,
type: 'p2pkh',
network: 'testnet',
};
case exports.LEGACY_VERSION_BYTES.legacy.testnet.p2sh:
return {
hash,
type: 'p2sh',
network: 'testnet',
};
default: {
throw new Error(`Invalid legacy address: unrecognized version byte "${versionByte}"`);
}
}
}
catch {
throw new Error(`Invalid legacy address`);
}
};
exports.decodeLegacyAddress = decodeLegacyAddress;
/**
* Encode a legacy address given type and hash
* For now, this is a stub method that supports only BTC p2pkh and p2sh
*/
const encodeLegacyAddress = (hash, type, network = 'mainnet') => {
const versionByte = exports.LEGACY_VERSION_BYTES.legacy[network][type];
const combined = new Uint8Array(1 + hash.length);
combined[0] = versionByte;
combined.set(hash, 1);
return (0, exports.encodeBase58Check)(combined);
};
exports.encodeLegacyAddress = encodeLegacyAddress;
//# sourceMappingURL=legacyaddr.js.map