diff --git a/web/ecashaddrjs/README.md b/web/ecashaddrjs/README.md --- a/web/ecashaddrjs/README.md +++ b/web/ecashaddrjs/README.md @@ -36,6 +36,29 @@ // 'ecash:qpadrekpz6gjd8w0zfedmtqyld0r2j4qmuthccqd8d' ``` +### Working with chronik-client in Node.js + +[chronik](https://www.npmjs.com/package/chronik-client) is the reference indexer for eCash. It queries the blockchain using address hash160 and type parameters. + +The `type` and `hash` parameters can be returned in a format ready for chronik by calling `cashaddr.decode(address, true)` + +```javascript +const ecashaddr = require('ecashaddrjs'); +const { ChronikClient } = require('chronik-client'); +const chronik = new ChronikClient('https://chronik.be.cash/xec'); +const chronikQueryAddress = 'ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035'; +const { prefix, type, hash } = ecashaddr.decode(chronikQueryAddress, true); +console.log(prefix); // 'ecash' +console.log(type); // 'p2pkh' (instead of 'P2PKH', returned without the 'true' flag) +console.log(hash); // '95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d' (instead of Uint8Array [ 149, 241, ..., 29 ], returned without the 'true' flag) +console.log(ecashaddr.encode('ecash', type, hash)); // encode supports chronik output inputs +// 'ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035' +// use chronik client to get a page of address tx history +const history = await chronik + .script(type, hash) + .history(/*page=*/ 0, /*page_size=*/ 10); +``` + ### React ```javascript @@ -105,3 +128,4 @@ 1.1.1 - Updated README to point to Bitcoin ABC monorepo 1.1.2 - Updated `repository` field in `package.json` to Bitcoin ABC monorepo 1.1.3 - Support string input and output for `hash` +1.2.0 - Support lowercase input and output of address types diff --git a/web/ecashaddrjs/package-lock.json b/web/ecashaddrjs/package-lock.json --- a/web/ecashaddrjs/package-lock.json +++ b/web/ecashaddrjs/package-lock.json @@ -1,12 +1,12 @@ { "name": "ecashaddrjs", - "version": "1.1.3", + "version": "1.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ecashaddrjs", - "version": "1.1.3", + "version": "1.2.0", "license": "MIT", "dependencies": { "big-integer": "1.6.36" diff --git a/web/ecashaddrjs/package.json b/web/ecashaddrjs/package.json --- a/web/ecashaddrjs/package.json +++ b/web/ecashaddrjs/package.json @@ -1,6 +1,6 @@ { "name": "ecashaddrjs", - "version": "1.1.3", + "version": "1.2.0", "description": "eCash cashaddr address format support for Node.js and web browsers.", "main": "src/cashaddr.js", "browser": "dist/cashaddrjs.min.js", diff --git a/web/ecashaddrjs/src/cashaddr.js b/web/ecashaddrjs/src/cashaddr.js --- a/web/ecashaddrjs/src/cashaddr.js +++ b/web/ecashaddrjs/src/cashaddr.js @@ -68,7 +68,7 @@ * @returns {object} * @throws {ValidationError} */ -function decode(address, returnHashAsString = false) { +function decode(address, chronikReady = false) { validate( typeof address === 'string' && hasSingleCase(address), 'Invalid address: ' + address + '.', @@ -117,8 +117,8 @@ var type = getType(versionByte); return { prefix: prefix, - type: type, - hash: returnHashAsString ? uint8arraytoString(hash) : hash, + type: chronikReady ? type.toLowerCase() : type, + hash: chronikReady ? uint8arraytoString(hash) : hash, }; } @@ -204,8 +204,10 @@ */ function getTypeBits(type) { switch (type) { + case 'p2pkh': case 'P2PKH': return 0; + case 'p2sh': case 'P2SH': return 8; default: @@ -430,5 +432,6 @@ module.exports = { encode: encode, decode: decode, + uint8arraytoString: uint8arraytoString, ValidationError: ValidationError, }; diff --git a/web/ecashaddrjs/test/cashaddr.js b/web/ecashaddrjs/test/cashaddr.js --- a/web/ecashaddrjs/test/cashaddr.js +++ b/web/ecashaddrjs/test/cashaddr.js @@ -301,6 +301,51 @@ } }); + it('should encode and decode all types and networks if type input is lowercase', () => { + for (const type of ADDRESS_TYPES) { + for (const network of NETWORKS) { + const hash = getRandomHash(20); + const address = cashaddr.encode( + network, + type.toLowerCase(), + hash, + ); + const { + prefix, + type: actualType, + hash: actualHash, + } = cashaddr.decode(address); + assert.equal(prefix, network); + assert.equal(actualType, type); + assert.deepEqual(actualHash, hash); + } + } + }); + + it('should encode and decode all types and networks if type input is lowercase and desired return data is formatted for chronik', () => { + for (const type of ADDRESS_TYPES) { + for (const network of NETWORKS) { + const hash = getRandomHash(20); + const address = cashaddr.encode( + network, + type.toLowerCase(), + hash, + ); + const { + prefix, + type: actualType, + hash: actualHash, + } = cashaddr.decode(address, true); + assert.equal(prefix, network); + assert.equal(actualType, type.toLowerCase()); + assert.deepEqual( + actualHash, + cashaddr.uint8arraytoString(hash), + ); + } + } + }); + it('should encode and decode many random hashes', () => { const NUM_TESTS = 1000; for (let i = 0; i < NUM_TESTS; ++i) {