From e8b6d7fb36d63972fa856dd064f63c9c0937ce74 Mon Sep 17 00:00:00 2001 From: mathi Date: Wed, 22 Sep 2021 14:38:54 +0200 Subject: [PATCH] added toEcashAddress() & ecashtoCashAddress() for ecash format support --- package-lock.json | 64 ++++++++++++++++++++-------------------- package.json | 2 +- src/address.js | 75 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 107 insertions(+), 34 deletions(-) diff --git a/package-lock.json b/package-lock.json index c3c298c..436136d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "bip66": "^1.1.5", "bitcoinjs-message": "^2.0.0", "bs58": "^4.0.1", - "cashaddrjs": "^0.3.3", + "ecashaddrjs": "^1.0.7", "ini": "^1.3.8", "randombytes": "^2.0.6", "safe-buffer": "^5.1.2", @@ -2099,14 +2099,6 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "node_modules/cashaddrjs": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/cashaddrjs/-/cashaddrjs-0.3.12.tgz", - "integrity": "sha512-GdjCYMVwd86HXcFcxyEZQLPLFv8a/u0ccYPsO0PpnUW26LhZzHX9l9QA+DjaeUah7tnebwPs33NWDbbUy8iVYQ==", - "dependencies": { - "big-integer": "1.6.36" - } - }, "node_modules/cashaddrjs-slp": { "version": "0.2.12", "resolved": "https://registry.npmjs.org/cashaddrjs-slp/-/cashaddrjs-slp-0.2.12.tgz", @@ -2115,14 +2107,6 @@ "big-integer": "^1.6.34" } }, - "node_modules/cashaddrjs/node_modules/big-integer": { - "version": "1.6.36", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz", - "integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==", - "engines": { - "node": ">=0.6" - } - }, "node_modules/chai": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.0.tgz", @@ -2873,6 +2857,22 @@ "readable-stream": "^2.0.2" } }, + "node_modules/ecashaddrjs": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/ecashaddrjs/-/ecashaddrjs-1.0.7.tgz", + "integrity": "sha512-KsvHYLlYtLr/GBkEPiwwQDIDBzqRx61qC34n1puHKOjVE4Uwg3syHccjFCqNynLa6T6xI0Rd7ByCRUJcuJcoIw==", + "dependencies": { + "big-integer": "1.6.36" + } + }, + "node_modules/ecashaddrjs/node_modules/big-integer": { + "version": "1.6.36", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz", + "integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==", + "engines": { + "node": ">=0.6" + } + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -17837,21 +17837,6 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "cashaddrjs": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/cashaddrjs/-/cashaddrjs-0.3.12.tgz", - "integrity": "sha512-GdjCYMVwd86HXcFcxyEZQLPLFv8a/u0ccYPsO0PpnUW26LhZzHX9l9QA+DjaeUah7tnebwPs33NWDbbUy8iVYQ==", - "requires": { - "big-integer": "1.6.36" - }, - "dependencies": { - "big-integer": { - "version": "1.6.36", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz", - "integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==" - } - } - }, "cashaddrjs-slp": { "version": "0.2.12", "resolved": "https://registry.npmjs.org/cashaddrjs-slp/-/cashaddrjs-slp-0.2.12.tgz", @@ -18483,6 +18468,21 @@ "readable-stream": "^2.0.2" } }, + "ecashaddrjs": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/ecashaddrjs/-/ecashaddrjs-1.0.7.tgz", + "integrity": "sha512-KsvHYLlYtLr/GBkEPiwwQDIDBzqRx61qC34n1puHKOjVE4Uwg3syHccjFCqNynLa6T6xI0Rd7ByCRUJcuJcoIw==", + "requires": { + "big-integer": "1.6.36" + }, + "dependencies": { + "big-integer": { + "version": "1.6.36", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz", + "integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==" + } + } + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", diff --git a/package.json b/package.json index 90af705..6363209 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "bip66": "^1.1.5", "bitcoinjs-message": "^2.0.0", "bs58": "^4.0.1", - "cashaddrjs": "^0.3.3", + "ecashaddrjs": "^1.0.7", "ini": "^1.3.8", "randombytes": "^2.0.6", "safe-buffer": "^5.1.2", diff --git a/src/address.js b/src/address.js index 7aaea03..b6e8f74 100644 --- a/src/address.js +++ b/src/address.js @@ -1,6 +1,6 @@ // const axios = require("axios") const Bitcoin = require('@psf/bitcoincashjs-lib') -const cashaddr = require('cashaddrjs') +const cashaddr = require('ecashaddrjs') const coininfo = require('@psf/coininfo') class Address { @@ -129,6 +129,63 @@ class Address { return cashAddress.split(':')[1] } + /** + * @api Address.toEcashAddress() toEcashAddress() + * @apiName toEcashAddress + * @apiGroup Address + * @apiDescription Convert legacy to cashAddress format + * + * @apiExample Example usage: + * // mainnet + * bchjs.Address.toEcashAddress('bitcoincash:qq50d800hgunr8u4trz3uuppspk3mds0dy9978plt2') + * // ecash:qq50d800hgunr8u4trz3uuppspk3mds0dyug2v69da + * + * // mainnet no prefix + * bchjs.Address.toEcashAddress('bitcoincash:qq50d800hgunr8u4trz3uuppspk3mds0dy9978plt2', false) + * // qq50d800hgunr8u4trz3uuppspk3mds0dyug2v69da + * + */ + toEcashAddress (address, prefix = true) { + const decoded = this._decode(address) + + const ecashAddress = cashaddr.encode( + 'ecash', + decoded.type, + decoded.hash + ) + + if (prefix) return ecashAddress + return ecashAddress.split(':')[1] + } + + /** + * @api Address.ecashtoCashAddress() ecashtoCashAddress() + * @apiName ecashtoCashAddress + * @apiGroup Address + * @apiDescription Convert legacy to cashAddress format + * + * @apiExample Example usage: + * // mainnet + * bchjs.Address.ecashtoCashAddress('ecash:qq50d800hgunr8u4trz3uuppspk3mds0dyug2v69da') + * // bitcoincash:qq50d800hgunr8u4trz3uuppspk3mds0dy9978plt2 + * + * // mainnet no prefix + * bchjs.Address.ecashtoCashAddress('ecash:qq50d800hgunr8u4trz3uuppspk3mds0dyug2v69da', false) + * // qq50d800hgunr8u4trz3uuppspk3mds0dy9978plt2 + */ + ecashtoCashAddress (address, prefix = true) { + const decoded = this._decodeEcashAddress(address) + + const cashAddress = cashaddr.encode( + 'bitcoincash', + decoded.type, + decoded.hash + ) + + if (prefix) return cashAddress + return cashAddress.split(':')[1] + } + // Converts any address format to hash160 toHash160 (address) { const legacyAddress = this.toLegacyAddress(address) @@ -271,6 +328,22 @@ class Address { throw new Error(`Invalid format : ${address}`) } + _decodeEcashAddress (address) { + if (address.indexOf(':') !== -1) { + const decoded = cashaddr.decode(address) + decoded.format = 'cashaddr' + return decoded + } + + try { + const decoded = cashaddr.decode(`ecash:${address}`) + decoded.format = 'cashaddr' + return decoded + } catch (error) {} + + throw new Error(`Invalid format : ${address}`) + } + /** * @api Address.isLegacyAddress() isLegacyAddress() * @apiName isLegacyAddress