All files / src/crypto/base58 index.ts

96.29% Statements 26/27
0% Branches 0/1
100% Functions 2/2
96.15% Lines 25/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 4742x 42x           42x 48x 48x 48x   48x 48x 48x 48x   48x   48x 48x 48x   48x           42x 40x     40x 40x 40x 40x 160x         40x 40x 40x    
import { encodeB58, decodeB58 } from 'micro-stacks/common';
import { hashSha256 } from 'micro-stacks/crypto-sha';
import type { BitcoinNetworkVersion } from './networks';
 
// original:
// @see: https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/address.js#L30
// Thank you @hstove :~)
export function base58checkEncode(hash: Uint8Array, version: BitcoinNetworkVersion) {
  const versionBuffer = new Uint8Array([version]);
  const data = new Uint8Array(25);
  const payload = new Uint8Array(21);
 
  payload[0] = version;
  payload.set(hash, 1);
  const sha1 = hashSha256(payload);
  const sha2 = hashSha256(sha1);
 
  const checksum = sha2.slice(0, 4);
 
  data.set(versionBuffer, 0);
  data.set(hash, 1);
  data.set(checksum, hash.length + 1);
 
  return encodeB58(data);
}
 
/**
 * Decode a b58 address into its version and hash160.
 */
export function base58checkDecode(address: string): { hash: Uint8Array; version: number } {
  const buffer = decodeB58(address);
 
  // checksum validation
  const checksum = buffer.slice(-4);
  const hash1 = hashSha256(buffer.slice(0, -4));
  const hash2 = hashSha256(hash1);
  for (let i = 0; i < 4; i++) {
    Iif (hash2[i] !== checksum[i]) {
      throw new Error('base58 address has invalid checksum');
    }
  }
 
  const prefix = buffer[0];
  const data = buffer.slice(1, -4);
  return { hash: data, version: prefix };
}