UNPKG

@ecash/lib

Version:

Library for eCash transaction building

253 lines 8.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Address = exports.DEFAULT_PREFIX = exports.toLegacyAddress = exports.ECASH_PREFIXES_TESTNET = void 0; // 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. const hex_1 = require("../io/hex"); const ecashaddrjs_1 = require("ecashaddrjs"); const legacyaddr_1 = require("./legacyaddr"); const script_1 = require("../script"); exports.ECASH_PREFIXES_TESTNET = ['ectest', 'ecregtest']; /** * Converts an ecash address in cashaddr format to legacy format * Throws if user attempts to convert a legacy address to a legacy address * Separated as its own function here for * * 1 - simpler unit testing * 2 - exported for users looking to convert string cashaddr to string legacy addr * without using the Address class */ const toLegacyAddress = (cashaddress) => { try { // No-op if user is trying to convert legacy to legacy (0, legacyaddr_1.decodeLegacyAddress)(cashaddress); return cashaddress; } catch { // Do nothing with this error since we expect it every time for the function's intended use case // Proceed to convert to legacy } const { prefix, type, hash } = (0, ecashaddrjs_1.decodeCashAddress)(cashaddress); const isTestnet = exports.ECASH_PREFIXES_TESTNET.includes(prefix); // Get correct version byte for legacy format let versionByte; switch (type) { case 'p2pkh': versionByte = isTestnet ? legacyaddr_1.LEGACY_VERSION_BYTES.legacy.testnet.p2pkh : legacyaddr_1.LEGACY_VERSION_BYTES.legacy.mainnet.p2pkh; break; case 'p2sh': versionByte = isTestnet ? legacyaddr_1.LEGACY_VERSION_BYTES.legacy.testnet.p2sh : legacyaddr_1.LEGACY_VERSION_BYTES.legacy.mainnet.p2sh; break; default: throw new Error('Unsupported address type: ' + type); } // Convert hash to Uint8Array const hashArray = (0, hex_1.fromHex)(hash); // Create a new Uint8Array to hold the data const uint8Array = new Uint8Array(1 + hashArray.length); // Set the version byte uint8Array[0] = versionByte; // Set the hash uint8Array.set(hashArray, 1); // Encode to base58check return (0, legacyaddr_1.encodeBase58Check)(uint8Array); }; exports.toLegacyAddress = toLegacyAddress; exports.DEFAULT_PREFIX = 'ecash'; /** * Address * Stores properties of supported crypto addresses * in standard typed structure. Provides methods for * easy access of address data in dev-friendly formats. * Provides methods for instantiating by type, encoding, * script, prefix, and address string of arbitrary encoding. * * Simplifies conversion between cashaddr prefixes and * address encoding types. * * Address is an ecash-first class. Legacy BTC format * is supported to simplify conversion to and from * ecash addresses. * * Address may be extended to support other crypto * address formats. */ class Address { constructor(params) { this.toString = () => { return this.address; }; this.legacy = () => new Address({ type: this.type, hash: this.hash, address: (0, exports.toLegacyAddress)(this.address), encoding: 'legacy', }); /** * Create an Address with cashaddr encoding * from an existing Address */ this.cash = () => new Address({ type: this.type, hash: this.hash, address: (0, ecashaddrjs_1.encodeCashAddress)(typeof this.prefix !== 'undefined' ? this.prefix : exports.DEFAULT_PREFIX, this.type, this.hash), encoding: 'cashaddr', prefix: typeof this.prefix !== 'undefined' ? this.prefix : exports.DEFAULT_PREFIX, }); /** * Create address with specified prefix * from an existing cashaddr-encoding Address */ this.withPrefix = (prefix) => { if (this.encoding === 'legacy') { // Take no action for legacy address types throw new Error('withPrefix does not support legacy address types'); } if (this.prefix === prefix) { // Take no action if prefix is not changing return this; } return new Address({ type: this.type, hash: this.hash, prefix, address: (0, ecashaddrjs_1.encodeCashAddress)(prefix, this.type, this.hash), encoding: 'cashaddr', }); }; this.toScript = () => { return new script_1.Script((0, hex_1.fromHex)((0, ecashaddrjs_1.getOutputScriptFromTypeAndHash)(this.type, this.hash))); }; this.toScriptHex = () => { return (0, ecashaddrjs_1.getOutputScriptFromTypeAndHash)(this.type, this.hash); }; const { hash, type, address, encoding } = params; this.hash = hash; this.type = type; this.address = address; this.encoding = encoding; if (typeof params.prefix !== 'undefined') { this.prefix = params.prefix; } } } exports.Address = Address; /** * Create a new p2pkh Address from hash * cashaddr encoding, ecash: prefix */ Address.p2pkh = (hash) => new Address({ type: 'p2pkh', hash: hash instanceof Uint8Array ? (0, hex_1.toHex)(hash) : hash, prefix: exports.DEFAULT_PREFIX, address: (0, ecashaddrjs_1.encodeCashAddress)(exports.DEFAULT_PREFIX, 'p2pkh', hash), encoding: 'cashaddr', }); /** * Create a new p2sh Address from hash * cashaddr encoding * ecash: prefix */ Address.p2sh = (hash) => new Address({ type: 'p2sh', hash: hash instanceof Uint8Array ? (0, hex_1.toHex)(hash) : hash, prefix: exports.DEFAULT_PREFIX, address: (0, ecashaddrjs_1.encodeCashAddress)(exports.DEFAULT_PREFIX, 'p2sh', hash), encoding: 'cashaddr', }); /** * Create a new Address from a given address string * address must be valid legacy or cashaddr address */ Address.parse = (address) => { if ((0, ecashaddrjs_1.isValidCashAddress)(address)) { const { type, hash, prefix } = (0, ecashaddrjs_1.decodeCashAddress)(address); return new Address({ type, hash, prefix, encoding: 'cashaddr', address, }); } try { const { type, hash } = (0, legacyaddr_1.decodeLegacyAddress)(address); return new Address({ type, hash, encoding: 'legacy', address, }); } catch { throw new Error('Invalid cashaddr or legacy address'); } }; /** * Create a new Address from a cashaddr * prefix, type, and hash from creating cashaddr */ Address.fromCashAddress = (address) => { const { type, hash, prefix } = (0, ecashaddrjs_1.decodeCashAddress)(address); return new Address({ type, hash, address, encoding: 'cashaddr', prefix, }); }; /** * Create a new Address from legacy address * No prefix for Address created from legacy address * type and hash from legacy address */ Address.fromLegacyAddress = (legacy) => { // Determine addr params from legacy address const { type, hash } = (0, legacyaddr_1.decodeLegacyAddress)(legacy); return new Address({ type, hash, address: legacy, encoding: 'legacy', }); }; /** * Create a new Address from an outputScript as Script * type and hash from outputScript * cashaddr encoding * ecash: prefix */ Address.fromScript = (script) => { const scriptHex = (0, hex_1.toHex)(script.bytecode); return Address.fromScriptHex(scriptHex); }; /** * Create a new Address from an outputScript as hex string * type and hash from outputScript * cashaddr encoding * ecash: prefix */ Address.fromScriptHex = (scriptHex) => { const { type, hash } = (0, ecashaddrjs_1.getTypeAndHashFromOutputScript)(scriptHex); // Default cashaddr encoding with default prefix const address = (0, ecashaddrjs_1.encodeCashAddress)(exports.DEFAULT_PREFIX, type, hash); const prefix = exports.DEFAULT_PREFIX; return new Address({ type, hash, prefix, address, encoding: 'cashaddr', }); }; //# sourceMappingURL=address.js.map