UNPKG

@dfinity/agent

Version:

JavaScript and TypeScript library to interact with the Internet Computer

83 lines 3.05 kB
import { lebEncode, compare } from '@dfinity/candid'; import { HashValueErrorCode, InputError } from "./errors.js"; import { uint8FromBufLike } from "./utils/buffer.js"; import { concatBytes } from '@noble/hashes/utils'; import { sha256 } from '@noble/hashes/sha2'; /** * * @param value unknown value * @returns Uint8Array */ export function hashValue(value) { if (typeof value === 'string') { return hashString(value); } else if (typeof value === 'number') { return sha256(lebEncode(value)); } else if (value instanceof Uint8Array || ArrayBuffer.isView(value)) { return sha256(uint8FromBufLike(value)); } else if (Array.isArray(value)) { const vals = value.map(hashValue); return sha256(concatBytes(...vals)); } else if (value && typeof value === 'object' && value._isPrincipal) { return sha256(value.toUint8Array()); } else if (typeof value === 'object' && value !== null && typeof value.toHash === 'function') { return hashValue(value.toHash()); // TODO This should be move to a specific async method as the webauthn flow required // the flow to be synchronous to ensure Safari touch id works. // } else if (value instanceof Promise) { // return value.then(x => hashValue(x)); } else if (typeof value === 'object') { return hashOfMap(value); } else if (typeof value === 'bigint') { // Do this check much later than the other bigint check because this one is much less // type-safe. // So we want to try all the high-assurance type guards before this 'probable' one. return sha256(lebEncode(value)); } throw InputError.fromCode(new HashValueErrorCode(value)); } const hashString = (value) => { const encoded = new TextEncoder().encode(value); return sha256(encoded); }; /** * Get the RequestId of the provided ic-ref request. * RequestId is the result of the representation-independent-hash function. * https://sdk.dfinity.org/docs/interface-spec/index.html#hash-of-map * @param request - ic-ref request to hash into RequestId */ export function requestIdOf(request) { return hashOfMap(request); } /** * Hash a map into a Uint8Array using the representation-independent-hash function. * https://sdk.dfinity.org/docs/interface-spec/index.html#hash-of-map * @param map - Any non-nested object * @returns Uint8Array */ export function hashOfMap(map) { const hashed = Object.entries(map) .filter(([, value]) => value !== undefined) .map(([key, value]) => { const hashedKey = hashString(key); const hashedValue = hashValue(value); return [hashedKey, hashedValue]; }); const traversed = hashed; const sorted = traversed.sort(([k1], [k2]) => { return compare(k1, k2); }); const concatenated = concatBytes(...sorted.map(x => concatBytes(...x))); const result = sha256(concatenated); return result; } //# sourceMappingURL=request_id.js.map