all files / src/ base58.js

85.71% Statements 36/42
65% Branches 13/20
100% Functions 4/4
81.25% Lines 26/32
1 branch Ignored     
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65          1×           1× 8× 7× 7× 7× 7×   7×   7×       7× 2×     5×   5×       5×       5×     1× 5× 5× 5×     1× 5×       5×       5× 20×         5×    
import {default as bs58} from "./vendor/bs58";
import isUndefined from "lodash/isUndefined";
import isNull from "lodash/isNull";
import {hash} from "./hashing";
 
const versionBytes = {
  "accountId": 0x00, // decimal 0
  "none":      0x01, // decimal 1
  "seed":      0x21, // decimal 33
};
 
export function decodeBase58Check(versionByteName, encoded) {
  let decoded     = bs58.decode(encoded);
  let versionByte = decoded[0];
  let payload     = decoded.slice(0, decoded.length - 4);
  let data        = payload.slice(1);
  let checksum    = decoded.slice(decoded.length - 4);
 
  let expectedVersion = versionBytes[versionByteName];
 
  Iif (isUndefined(expectedVersion)) {
    throw new Error(`${versionByteName} is not a valid version byte name.  expected one of "accountId", "seed", or "none"`);
  }
 
  if (versionByte !== expectedVersion) {
    throw new Error(`invalid version byte.  expected ${expectedVersion}, got ${versionByte}`);
  }
 
  let expectedChecksum = calculateChecksum(payload);
 
  Iif (!verifyChecksum(expectedChecksum, checksum)) {
    throw new Error(`invalid checksum`);
  }
 
  Iif (versionByteName === 'accountId' && decoded.length !== 37) {
    throw new Error(`Decoded address length is invalid. Expected 37, got ${decoded.length}`);
  }
 
  return new Buffer(data);
}
 
function calculateChecksum(payload) {
  let inner = hash(payload);
  let outer = hash(inner);
  return outer.slice(0,4);
}
 
function verifyChecksum(expected, actual) {
  Iif (expected.length !== actual.length) {
    return false;
  }
 
  Iif (expected.length === 0) {
    return true;
  }
 
  for(let i = 0; i < expected.length; i++) {
    Iif (expected[i] !== actual[i]) {
      return false;
    }
  }
 
  return true;
}