From 9abe657a0afdfb339e104e3b52a940d99dc992d6 Mon Sep 17 00:00:00 2001 From: vinhbhn Date: Sat, 3 Jul 2021 10:21:54 +0700 Subject: [PATCH 1/4] Add support for RUNE (ThorChain) --- README.md | 1 + src/__tests__/index.test.ts | 8 ++++++++ src/index.ts | 1 + 3 files changed, 10 insertions(+) diff --git a/README.md b/README.md index d1d838b4..63eed3ad 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,7 @@ This library currently supports the following cryptocurrencies and address forma - QTUM (base58check) - RDD (base58check P2PKH and P2SH) - RSK (checksummed-hex) + - RUNE (bech32) - RVN (base58check P2PKH and P2SH) - SC (blake2b checksum) - SERO (base58, no check) diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index e4fd8cfd..a7e222b5 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -851,6 +851,14 @@ const vectors: Array = [ { text: '112qB3YaH5bZkCnKA5uRH7tBtGNv2Y5B4smv1jsmvGUzgKT71QpE', hex: '00f11444921875e2ef7435513a1d1f1b0fa49e3242956a24383912ec5d4f194077' }, ], }, + { + name: 'RUNE', + coinType: 931, + passingVectors: [ + { text: 'thor196yf4pq80hjrmz7nnh0ar0ypqg02r0w4dq4mzu', hex: '2e889a84077de43d8bd39ddfd1bc81021ea1bdd5' }, + { text: 'thor1yv0mrrygnjs03zsrwrgqz4sa36evfw2a049l5p', hex: '231fb18c889ca0f88a0370d001561d8eb2c4b95d' }, + ], + }, { name: 'BCD', coinType: 999, diff --git a/src/index.ts b/src/index.ts index 23ea214d..ed90bc44 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1379,6 +1379,7 @@ export const formats: IFormat[] = [ eosioChain('HIVE', 825, 'STM'), hexChecksumChain('TOMO', 889), getConfig('HNT', 904, hntAddresEncoder, hntAddressDecoder), + bech32Chain('RUNE', 931, 'thor'), bitcoinChain('BCD', 999, 'bcd', [[0x00]], [[0x05]]), hexChecksumChain('TT', 1001), bech32Chain('ONE', 1023, 'one'), From 7a9ece0fd33072905d5d51f7c8a3531e5db93372 Mon Sep 17 00:00:00 2001 From: vinhbhn Date: Sun, 4 Jul 2021 21:52:17 +0700 Subject: [PATCH 2/4] Add support for STX (Blockstack) address --- README.md | 1 + package-lock.json | 25 +++++ package.json | 1 + src/__tests__/index.test.ts | 10 +- src/blockstack/stx-c32.ts | 186 ++++++++++++++++++++++++++++++++++++ src/index.ts | 2 + 6 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 src/blockstack/stx-c32.ts diff --git a/README.md b/README.md index 63eed3ad..dfa421e5 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,7 @@ This library currently supports the following cryptocurrencies and address forma - SRM (base58, no check) - STEEM (base58 + ripemd160-checksum) - STRAT (base58check P2PKH and P2SH) + - STX (crockford base32 P2PKH and P2SH + ripemd160-checksum) - SYS (base58check P2PKH and P2SH, and bech32 segwit) - TFUEL (checksummed-hex) - THETA (base58check) diff --git a/package-lock.json b/package-lock.json index 190e01d3..ef7471d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5262,6 +5262,31 @@ "sha.js": "^2.4.8" } }, + "cross-sha256": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cross-sha256/-/cross-sha256-1.1.2.tgz", + "integrity": "sha512-ZMGqJvPZQY/hmFvTJyM4LGVZIvEqD58GrCWA28goaDdo6wGzjgxWKEDxVfahkNCF/ryxBNfHe3Ql/BMSwPPbcg==", + "requires": { + "@types/node": "^8.0.0", + "buffer": "^5.6.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + } + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", diff --git a/package.json b/package.json index c773c9fc..7dc2931f 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "blakejs": "^1.1.0", "bn.js": "^4.11.8", "bs58": "^4.0.1", + "cross-sha256": "^1.1.2", "crypto-addr-codec": "^0.1.7", "js-sha512": "^0.8.0", "nano-base32": "^1.0.1", diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index a7e222b5..49b0df26 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -4,7 +4,7 @@ import { IFormat, formats, formatsByName, formatsByCoinType } from '../index'; interface TestVector { name: string; coinType: number; - passingVectors: Array<{ text: string; hex: string; canonical?: string }>; + passingVectors: Array<{ text: string; hex: string; canonical?: string; }>; } // Ordered by coinType @@ -979,6 +979,14 @@ const vectors: Array = [ { text: 'hs1qd42hrldu5yqee58se4uj6xctm7nk28r70e84vx', hex: '6d5571fdbca1019cd0f0cd792d1b0bdfa7651c7e' }, ], }, + { + name: 'STX', + coinType: 5757, + passingVectors: [ + { text: 'SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7', hex: 'a46ff88886c2ef9762d970b4d2c63678835bd39d71b4ba47' }, + { text: 'SM2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0G', hex: 'a46ff88886c2ef9762d970b4d2c63678835bd39df7d47410' }, + ], + }, { name: 'GO', coinType: 6060, diff --git a/src/blockstack/stx-c32.ts b/src/blockstack/stx-c32.ts new file mode 100644 index 00000000..bcca0fdc --- /dev/null +++ b/src/blockstack/stx-c32.ts @@ -0,0 +1,186 @@ +// https://en.wikipedia.org/wiki/Base32#Crockford's_Base32 +import { hashSha256 } from 'cross-sha256'; +export const C32_ALPHABET = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; +const hex = '0123456789abcdef'; + +function c32checksum(dataHex: string): string { + const dataHash = hashSha256(hashSha256(Buffer.from(dataHex, 'hex'))); + const checksum = dataHash.slice(0, 4).toString('hex'); + return checksum; +} + +export function c32checkEncode(data: Buffer): string { + let dataHex = data.toString('hex'); + let hash160hex = dataHex.substring(0, dataHex.length - 8); + if (!hash160hex.match(/^[0-9a-fA-F]{40}$/)) { + throw new Error('Invalid argument: not a hash160 hex string'); + } + + hash160hex = hash160hex.toLowerCase(); + if (hash160hex.length % 2 !== 0) { + hash160hex = `0${hash160hex}`; + } + + // p2pkh: 'P' + // p2sh: 'M' + let version = { p2pkh: 22, p2sh: 20 }; + + let checksumHex = dataHex.slice(-8); + let c32str = ''; + let prefix = ''; + + if (checksumHex == c32checksum(`${version.p2pkh.toString(16)}${hash160hex}`)) { + prefix = 'P'; + c32str = c32encode(`${hash160hex}${checksumHex}`); + } else if ((checksumHex == c32checksum(`${version.p2sh.toString(16)}${hash160hex}`))) { + prefix = 'M'; + c32str = c32encode(`${hash160hex}${checksumHex}`); + } + + return `S${prefix}${c32str}`; +} + +function c32encode(inputHex: string): string { + // must be hex + if (!inputHex.match(/^[0-9a-fA-F]*$/)) { + throw new Error('Not a hex-encoded string'); + } + + if (inputHex.length % 2 !== 0) { + inputHex = `0${inputHex}`; + } + + inputHex = inputHex.toLowerCase(); + + let res = []; + let carry = 0; + for (let i = inputHex.length - 1; i >= 0; i--) { + if (carry < 4) { + const currentCode = hex.indexOf(inputHex[i]) >> carry; + let nextCode = 0; + if (i !== 0) { + nextCode = hex.indexOf(inputHex[i - 1]); + } + // carry = 0, nextBits is 1, carry = 1, nextBits is 2 + const nextBits = 1 + carry; + const nextLowBits = nextCode % (1 << nextBits) << (5 - nextBits); + const curC32Digit = C32_ALPHABET[currentCode + nextLowBits]; + carry = nextBits; + res.unshift(curC32Digit); + } else { + carry = 0; + } + } + + let C32leadingZeros = 0; + for (let i = 0; i < res.length; i++) { + if (res[i] !== '0') { + break; + } else { + C32leadingZeros++; + } + } + + res = res.slice(C32leadingZeros); + + const zeroPrefix = Buffer.from(inputHex, 'hex') + .toString() + .match(/^\u0000*/); + const numLeadingZeroBytesInHex = zeroPrefix ? zeroPrefix[0].length : 0; + + for (let i = 0; i < numLeadingZeroBytesInHex; i++) { + res.unshift(C32_ALPHABET[0]); + } + + return res.join(''); +} + +function c32normalize(c32input: string): string { + // must be upper-case + // replace all O's with 0's + // replace all I's and L's with 1's + return c32input.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1'); +} + +export function c32checkDecode(data: string): Buffer { + if (data.length <= 5) { + throw new Error('Invalid c32 address: invalid length'); + } + if (data[0] != 'S') { + throw new Error('Invalid c32 address: must start with "S"'); + } + + let c32data = c32normalize(data.slice(1)); + const versionChar = c32data[0]; + const version = C32_ALPHABET.indexOf(versionChar); + + let versionHex = version.toString(16); + if (versionHex.length === 1) { + versionHex = `0${versionHex}`; + } + + let dataHex = c32decode(c32data.slice(1)); + const checksum = dataHex.slice(-8); + + if (c32checksum(`${versionHex}${dataHex.substring(0, dataHex.length - 8)}`) !== checksum) { + throw new Error('Invalid c32check string: checksum mismatch'); + } + + return Buffer.from(dataHex, 'hex'); +} + +function c32decode(c32input: string): string { + c32input = c32normalize(c32input); + + // must result in a c32 string + if (!c32input.match(`^[${C32_ALPHABET}]*$`)) { + throw new Error('Not a c32-encoded string'); + } + + const zeroPrefix = c32input.match(`^${C32_ALPHABET[0]}*`); + const numLeadingZeroBytes = zeroPrefix ? zeroPrefix[0].length : 0; + + let res = []; + let carry = 0; + let carryBits = 0; + for (let i = c32input.length - 1; i >= 0; i--) { + if (carryBits === 4) { + res.unshift(hex[carry]); + carryBits = 0; + carry = 0; + } + const currentCode = C32_ALPHABET.indexOf(c32input[i]) << carryBits; + const currentValue = currentCode + carry; + const currentHexDigit = hex[currentValue % 16]; + carryBits += 1; + carry = currentValue >> 4; + if (carry > 1 << carryBits) { + throw new Error('Panic error in decoding.'); + } + res.unshift(currentHexDigit); + } + // one last carry + res.unshift(hex[carry]); + + if (res.length % 2 === 1) { + res.unshift('0'); + } + + let hexLeadingZeros = 0; + for (let i = 0; i < res.length; i++) { + if (res[i] !== '0') { + break; + } else { + hexLeadingZeros++; + } + } + + res = res.slice(hexLeadingZeros - (hexLeadingZeros % 2)); + + let hexStr = res.join(''); + for (let i = 0; i < numLeadingZeroBytes; i++) { + hexStr = `00${hexStr}`; + } + + return hexStr; +} diff --git a/src/index.ts b/src/index.ts index ed90bc44..d9ced9d7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -30,6 +30,7 @@ import { import { sha512_256 } from 'js-sha512'; import { decode as nanoBase32Decode, encode as nanoBase32Encode } from 'nano-base32'; import { Keccak, SHA3 } from 'sha3'; +import { c32checkDecode, c32checkEncode } from './blockstack/stx-c32'; import { filAddrDecoder, filAddrEncoder } from './filecoin/index'; import { ChainID, isValidAddress } from './flow/index'; import { groestl_2 } from './groestl-hash-js/index'; @@ -1404,6 +1405,7 @@ export const formats: IFormat[] = [ }, getConfig('IOTA', 4218, bs58Encode, bs58Decode), getConfig('HNS', 5353, hnsAddressEncoder, hnsAddressDecoder), + getConfig('STX',5757, c32checkEncode, c32checkDecode), hexChecksumChain('GO', 6060), getConfig('NULS', 8964, nulsAddressEncoder, nulsAddressDecoder), bech32Chain('AVAX', 9000, 'avax'), From 1a8e1ec251266348efc7fb14d4f094ed4f47fcff Mon Sep 17 00:00:00 2001 From: vinhbhn Date: Sun, 4 Jul 2021 22:49:14 +0700 Subject: [PATCH 3/4] tslint --- README.md | 1 - src/__tests__/index.test.ts | 8 -------- src/blockstack/stx-c32.ts | 23 +++++++++++++++-------- src/index.ts | 1 - 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index dfa421e5..7e96e6e5 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,6 @@ This library currently supports the following cryptocurrencies and address forma - QTUM (base58check) - RDD (base58check P2PKH and P2SH) - RSK (checksummed-hex) - - RUNE (bech32) - RVN (base58check P2PKH and P2SH) - SC (blake2b checksum) - SERO (base58, no check) diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index 49b0df26..6eeae2dc 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -851,14 +851,6 @@ const vectors: Array = [ { text: '112qB3YaH5bZkCnKA5uRH7tBtGNv2Y5B4smv1jsmvGUzgKT71QpE', hex: '00f11444921875e2ef7435513a1d1f1b0fa49e3242956a24383912ec5d4f194077' }, ], }, - { - name: 'RUNE', - coinType: 931, - passingVectors: [ - { text: 'thor196yf4pq80hjrmz7nnh0ar0ypqg02r0w4dq4mzu', hex: '2e889a84077de43d8bd39ddfd1bc81021ea1bdd5' }, - { text: 'thor1yv0mrrygnjs03zsrwrgqz4sa36evfw2a049l5p', hex: '231fb18c889ca0f88a0370d001561d8eb2c4b95d' }, - ], - }, { name: 'BCD', coinType: 999, diff --git a/src/blockstack/stx-c32.ts b/src/blockstack/stx-c32.ts index bcca0fdc..1229c7c6 100644 --- a/src/blockstack/stx-c32.ts +++ b/src/blockstack/stx-c32.ts @@ -10,7 +10,7 @@ function c32checksum(dataHex: string): string { } export function c32checkEncode(data: Buffer): string { - let dataHex = data.toString('hex'); + const dataHex = data.toString('hex'); let hash160hex = dataHex.substring(0, dataHex.length - 8); if (!hash160hex.match(/^[0-9a-fA-F]{40}$/)) { throw new Error('Invalid argument: not a hash160 hex string'); @@ -23,16 +23,16 @@ export function c32checkEncode(data: Buffer): string { // p2pkh: 'P' // p2sh: 'M' - let version = { p2pkh: 22, p2sh: 20 }; + const version = { p2pkh: 22, p2sh: 20 }; - let checksumHex = dataHex.slice(-8); + const checksumHex = dataHex.slice(-8); let c32str = ''; let prefix = ''; - if (checksumHex == c32checksum(`${version.p2pkh.toString(16)}${hash160hex}`)) { + if (checksumHex === c32checksum(`${version.p2pkh.toString(16)}${hash160hex}`)) { prefix = 'P'; c32str = c32encode(`${hash160hex}${checksumHex}`); - } else if ((checksumHex == c32checksum(`${version.p2sh.toString(16)}${hash160hex}`))) { + } else if ((checksumHex === c32checksum(`${version.p2sh.toString(16)}${hash160hex}`))) { prefix = 'M'; c32str = c32encode(`${hash160hex}${checksumHex}`); } @@ -56,6 +56,7 @@ function c32encode(inputHex: string): string { let carry = 0; for (let i = inputHex.length - 1; i >= 0; i--) { if (carry < 4) { + // tslint:disable-next-line:no-bitwise const currentCode = hex.indexOf(inputHex[i]) >> carry; let nextCode = 0; if (i !== 0) { @@ -63,6 +64,7 @@ function c32encode(inputHex: string): string { } // carry = 0, nextBits is 1, carry = 1, nextBits is 2 const nextBits = 1 + carry; + // tslint:disable-next-line:no-bitwise const nextLowBits = nextCode % (1 << nextBits) << (5 - nextBits); const curC32Digit = C32_ALPHABET[currentCode + nextLowBits]; carry = nextBits; @@ -73,6 +75,7 @@ function c32encode(inputHex: string): string { } let C32leadingZeros = 0; + // tslint:disable-next-line:prefer-for-of for (let i = 0; i < res.length; i++) { if (res[i] !== '0') { break; @@ -106,11 +109,11 @@ export function c32checkDecode(data: string): Buffer { if (data.length <= 5) { throw new Error('Invalid c32 address: invalid length'); } - if (data[0] != 'S') { + if (data[0] !== 'S') { throw new Error('Invalid c32 address: must start with "S"'); } - let c32data = c32normalize(data.slice(1)); + const c32data = c32normalize(data.slice(1)); const versionChar = c32data[0]; const version = C32_ALPHABET.indexOf(versionChar); @@ -119,7 +122,7 @@ export function c32checkDecode(data: string): Buffer { versionHex = `0${versionHex}`; } - let dataHex = c32decode(c32data.slice(1)); + const dataHex = c32decode(c32data.slice(1)); const checksum = dataHex.slice(-8); if (c32checksum(`${versionHex}${dataHex.substring(0, dataHex.length - 8)}`) !== checksum) { @@ -149,11 +152,14 @@ function c32decode(c32input: string): string { carryBits = 0; carry = 0; } + // tslint:disable-next-line:no-bitwise const currentCode = C32_ALPHABET.indexOf(c32input[i]) << carryBits; const currentValue = currentCode + carry; const currentHexDigit = hex[currentValue % 16]; carryBits += 1; + // tslint:disable-next-line:no-bitwise carry = currentValue >> 4; + // tslint:disable-next-line:no-bitwise if (carry > 1 << carryBits) { throw new Error('Panic error in decoding.'); } @@ -167,6 +173,7 @@ function c32decode(c32input: string): string { } let hexLeadingZeros = 0; + // tslint:disable-next-line:prefer-for-of for (let i = 0; i < res.length; i++) { if (res[i] !== '0') { break; diff --git a/src/index.ts b/src/index.ts index d9ced9d7..6b4266e6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1380,7 +1380,6 @@ export const formats: IFormat[] = [ eosioChain('HIVE', 825, 'STM'), hexChecksumChain('TOMO', 889), getConfig('HNT', 904, hntAddresEncoder, hntAddressDecoder), - bech32Chain('RUNE', 931, 'thor'), bitcoinChain('BCD', 999, 'bcd', [[0x00]], [[0x05]]), hexChecksumChain('TT', 1001), bech32Chain('ONE', 1023, 'one'), From f5ba4734f7688aa8824ffd08ec0ab07fa47a93ad Mon Sep 17 00:00:00 2001 From: vinhbhn Date: Tue, 31 Aug 2021 22:25:55 +0700 Subject: [PATCH 4/4] chore: reduce size --- package-lock.json | 30 +++++------------------------- package.json | 2 +- src/blockstack/stx-c32.ts | 6 +++++- src/index.ts | 2 +- 4 files changed, 12 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index 420e6581..13b413aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5262,31 +5262,6 @@ "sha.js": "^2.4.8" } }, - "cross-sha256": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cross-sha256/-/cross-sha256-1.1.2.tgz", - "integrity": "sha512-ZMGqJvPZQY/hmFvTJyM4LGVZIvEqD58GrCWA28goaDdo6wGzjgxWKEDxVfahkNCF/ryxBNfHe3Ql/BMSwPPbcg==", - "requires": { - "@types/node": "^8.0.0", - "buffer": "^5.6.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -8845,6 +8820,11 @@ "resolved": "https://registry.npmjs.org/js-crc/-/js-crc-0.2.0.tgz", "integrity": "sha1-9yxcdhgXa/91zIEqHO2949jraDk=" }, + "js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, "js-sha512": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", diff --git a/package.json b/package.json index 8747e090..1e79d039 100644 --- a/package.json +++ b/package.json @@ -45,9 +45,9 @@ "blakejs": "^1.1.0", "bn.js": "^4.11.8", "bs58": "^4.0.1", - "cross-sha256": "^1.1.2", "crypto-addr-codec": "^0.1.7", "js-crc": "^0.2.0", + "js-sha256": "^0.9.0", "js-sha512": "^0.8.0", "nano-base32": "^1.0.1", "ripemd160": "^2.0.2", diff --git a/src/blockstack/stx-c32.ts b/src/blockstack/stx-c32.ts index 1229c7c6..bc949950 100644 --- a/src/blockstack/stx-c32.ts +++ b/src/blockstack/stx-c32.ts @@ -1,8 +1,12 @@ // https://en.wikipedia.org/wiki/Base32#Crockford's_Base32 -import { hashSha256 } from 'cross-sha256'; +import { sha256 } from 'js-sha256'; export const C32_ALPHABET = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; const hex = '0123456789abcdef'; +function hashSha256(data: Buffer): Buffer { + return Buffer.from(sha256.update(data).digest()) +} + function c32checksum(dataHex: string): string { const dataHash = hashSha256(hashSha256(Buffer.from(dataHex, 'hex'))); const checksum = dataHash.slice(0, 4).toString('hex'); diff --git a/src/index.ts b/src/index.ts index 78e58041..ab7c2962 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1483,7 +1483,7 @@ export const formats: IFormat[] = [ }, getConfig('IOTA', 4218, bs58Encode, bs58Decode), getConfig('HNS', 5353, hnsAddressEncoder, hnsAddressDecoder), - getConfig('STX',5757, c32checkEncode, c32checkDecode), + getConfig('STX', 5757, c32checkEncode, c32checkDecode), hexChecksumChain('GO', 6060), getConfig('NULS', 8964, nulsAddressEncoder, nulsAddressDecoder), bech32Chain('AVAX', 9000, 'avax'),