All files / src utils.ts

93.94% Statements 31/33
73.68% Branches 14/19
100% Functions 8/8
93.75% Lines 30/32

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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109      4x               18x                     13x                 3x                   1x     1x                       7x 7x 7x 7x 56x 56x 56x     7x                   3x 3x   3x 3x       3x 3x 3x   3x                   42x 42x 42x 42x 31x   42x 42x 42x      
import bsv from 'bsv';
import {PathPrefix} from "./interface";
 
export const Utils = {
  /**
   * Helper function for encoding strings to hex
   *
   * @param string
   * @returns {string}
   */
  hexEncode(string: string) {
    return '0x' + Buffer.from(string).toString('hex');
  },
 
  /**
   * Helper function for encoding strings to hex
   *
   * @param hexString string
   * @param encoding BufferEncoding
   * @returns {string}
   */
  hexDecode(hexString: string, encoding: BufferEncoding = 'utf8') {
    return Buffer.from(hexString.replace('0x', ''), 'hex').toString(encoding);
  },
 
  /**
   * Helper function to generate a random nonce
   *
   * @returns {string}
   */
  getRandomString(length = 32) {
    return bsv.crypto.Random.getRandomBuffer(length).toString('hex');
  },
 
  /**
   * Test whether the given string is hex
   *
   * @param value any
   * @returns {boolean}
   */
  isHex(value: any) {
    Iif (typeof value !== 'string') {
      return false;
    }
    return /^[0-9a-fA-F]+$/.test(value);
  },
 
  /**
   * Get a signing path from a hex number
   *
   * @param hexString {string}
   * @param hardened {boolean} Whether to return a hardened path
   * @returns {string}
   */
  getSigningPathFromHex(hexString: string, hardened = true) {
    // "m/0/0/1"
    let signingPath = 'm';
    const signingHex = hexString.match(/.{1,8}/g);
    const maxNumber = 2147483648 - 1; // 0x80000000
    signingHex?.forEach((hexNumber) => {
      let number = Number('0x' + hexNumber);
      if (number > maxNumber) number -= maxNumber;
      signingPath += `/${number}${(hardened ? "'" : '')}`;
    });
 
    return signingPath;
  },
 
  /**
   * Increment that second to last part from the given part, set the last part to 0
   *
   * @param path string
   * @returns {*}
   */
  getNextIdentityPath(path: string): PathPrefix {
    const pathValues = path.split('/');
    const secondToLastPart = pathValues[pathValues.length - 2];
 
    let hardened = false;
    Iif (secondToLastPart.match('\'')) {
      hardened = true;
    }
 
    const nextPath = (Number(secondToLastPart.replace(/[^0-9]/g, '')) + 1).toString();
    pathValues[pathValues.length - 2] = nextPath + (hardened ? '\'' : '');
    pathValues[pathValues.length - 1] = '0' + (hardened ? '\'' : '');
 
    return pathValues.join('/') as PathPrefix;
  },
 
  /**
   * Increment that last part of the given path
   *
   * @param path string
   * @returns {*}
   */
  getNextPath(path: string) {
    const pathValues = path.split('/');
    const lastPart = pathValues[pathValues.length - 1];
    let hardened = false;
    if (lastPart.match('\'')) {
      hardened = true;
    }
    const nextPath = (Number(lastPart.replace(/[^0-9]/g, '')) + 1).toString();
    pathValues[pathValues.length - 1] = nextPath + (hardened ? '\'' : '');
    return pathValues.join('/');
  },
};