UNPKG

@funded-labs/dab-js

Version:
83 lines (82 loc) 3.17 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAccountId = void 0; const crypto_js_1 = __importDefault(require("crypto-js")); const buffer_crc32_1 = __importDefault(require("buffer-crc32")); const ACCOUNT_DOMAIN_SEPERATOR = '\x0Aaccount-id'; const SUB_ACCOUNT_ZERO = Buffer.alloc(32); const byteArrayToWordArray = (byteArray) => { const wordArray = []; let i; for (i = 0; i < byteArray.length; i += 1) { wordArray[(i / 4) | 0] |= byteArray[i] << (24 - 8 * i); } // eslint-disable-next-line const result = crypto_js_1.default.lib.WordArray.create(wordArray, byteArray.length); return result; }; const wordToByteArray = (word, length) => { const byteArray = []; const xFF = 0xff; if (length > 0) byteArray.push(word >>> 24); if (length > 1) byteArray.push((word >>> 16) & xFF); if (length > 2) byteArray.push((word >>> 8) & xFF); if (length > 3) byteArray.push(word & xFF); return byteArray; }; const wordArrayToByteArray = (wordArray, length) => { if (wordArray.hasOwnProperty('sigBytes') && wordArray.hasOwnProperty('words')) { length = wordArray.sigBytes; wordArray = wordArray.words; } let result = []; let bytes; let i = 0; while (length > 0) { bytes = wordToByteArray(wordArray[i], Math.min(4, length)); length -= bytes.length; result = [...result, bytes]; i++; } return [].concat.apply([], result); }; const intToHex = (val) => val < 0 ? (Number(val) >>> 0).toString(16) : Number(val).toString(16); // We generate a CRC32 checksum, and trnasform it into a hexString const generateChecksum = (hash) => { const crc = buffer_crc32_1.default.unsigned(Buffer.from(hash)); const hex = intToHex(crc); return hex.padStart(8, '0'); }; /* Used dfinity/keysmith/account/account.go as a base for the ID generation */ const getAccountId = (principal, subAccount) => { const sha = crypto_js_1.default.algo.SHA224.create(); sha.update(ACCOUNT_DOMAIN_SEPERATOR); // Internally parsed with UTF-8, like go does sha.update(byteArrayToWordArray(principal.toUint8Array())); const subBuffer = Buffer.from(SUB_ACCOUNT_ZERO); if (subAccount) { subBuffer.writeUInt32BE(subAccount); } sha.update(byteArrayToWordArray(subBuffer)); const hash = sha.finalize(); /// While this is backed by an array of length 28, it's canonical representation /// is a hex string of length 64. The first 8 characters are the CRC-32 encoded /// hash of the following 56 characters of hex. Both, upper and lower case /// characters are valid in the input string and can even be mixed. /// [ic/rs/rosetta-api/ledger_canister/src/account_identifier.rs] const byteArray = wordArrayToByteArray(hash, 28); const checksum = generateChecksum(byteArray); const val = checksum + hash.toString(); return val; }; exports.getAccountId = getAccountId; exports.default = {};