@funded-labs/dab-js
Version:
JS adapter for DAB
83 lines (82 loc) • 3.17 kB
JavaScript
;
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 = {};