@bitgo-beta/sdk-hmac 1.0.1-beta.102 → 1.0.1-beta.1021

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,49 @@
1
+ import { type BinaryLike, type KeyObject } from 'crypto';
2
+ export type HashableData = string | Buffer | Uint8Array | ArrayBuffer;
3
+ /**
4
+ * Calculate SHA256 hash of data and return as lowercase hex string.
5
+ * Used for body hash calculation in v4 authentication.
6
+ *
7
+ * Accepts string, Buffer, Uint8Array, and ArrayBuffer for compatibility
8
+ * with both Node.js and browser environments.
9
+ *
10
+ * Note: ArrayBuffer is converted to Uint8Array internally since Node.js crypto
11
+ * requires TypedArray or DataView, not plain ArrayBuffer.
12
+ *
13
+ * @param data - The data to hash
14
+ * @returns Lowercase hex string of SHA256 hash
15
+ */
16
+ export declare function sha256Hex(data: HashableData): string;
17
+ /**
18
+ * Calculate HMAC-SHA256 and return as lowercase hex string.
19
+ * This is the core cryptographic primitive shared by v2/v3/v4 authentication.
20
+ *
21
+ * @param key - The secret key for HMAC
22
+ * @param message - The message to authenticate
23
+ * @returns Lowercase hex string of HMAC-SHA256
24
+ */
25
+ export declare function createHmacWithSha256(key: string | BinaryLike | KeyObject, message: string | BinaryLike): string;
26
+ /**
27
+ * Normalize HTTP method to uppercase.
28
+ * Handles legacy 'del' → 'DELETE' conversion for backward compatibility.
29
+ *
30
+ * @param method - HTTP method (case-insensitive)
31
+ * @returns Uppercase HTTP method
32
+ */
33
+ export declare function normalizeMethod(method: string): string;
34
+ /**
35
+ * Extract path with query string from a URL.
36
+ * Handles both absolute URLs and relative paths.
37
+ *
38
+ * @param urlPath - Full URL or relative path
39
+ * @returns Path with query string (e.g., '/api/v2/wallet?foo=bar')
40
+ */
41
+ export declare function extractPathWithQuery(urlPath: string): string;
42
+ /**
43
+ * Get current timestamp in seconds (Unix epoch).
44
+ * Used for v4 authentication which uses seconds instead of milliseconds.
45
+ *
46
+ * @returns Current Unix timestamp in seconds
47
+ */
48
+ export declare function getTimestampSec(): number;
49
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEjF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,CAAC;AAEtE;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAKpD;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAE/G;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAa5D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sha256Hex = sha256Hex;
4
+ exports.createHmacWithSha256 = createHmacWithSha256;
5
+ exports.normalizeMethod = normalizeMethod;
6
+ exports.extractPathWithQuery = extractPathWithQuery;
7
+ exports.getTimestampSec = getTimestampSec;
8
+ const crypto_1 = require("crypto");
9
+ /**
10
+ * Calculate SHA256 hash of data and return as lowercase hex string.
11
+ * Used for body hash calculation in v4 authentication.
12
+ *
13
+ * Accepts string, Buffer, Uint8Array, and ArrayBuffer for compatibility
14
+ * with both Node.js and browser environments.
15
+ *
16
+ * Note: ArrayBuffer is converted to Uint8Array internally since Node.js crypto
17
+ * requires TypedArray or DataView, not plain ArrayBuffer.
18
+ *
19
+ * @param data - The data to hash
20
+ * @returns Lowercase hex string of SHA256 hash
21
+ */
22
+ function sha256Hex(data) {
23
+ const normalizedData = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
24
+ return (0, crypto_1.createHash)('sha256')
25
+ .update(normalizedData)
26
+ .digest('hex');
27
+ }
28
+ /**
29
+ * Calculate HMAC-SHA256 and return as lowercase hex string.
30
+ * This is the core cryptographic primitive shared by v2/v3/v4 authentication.
31
+ *
32
+ * @param key - The secret key for HMAC
33
+ * @param message - The message to authenticate
34
+ * @returns Lowercase hex string of HMAC-SHA256
35
+ */
36
+ function createHmacWithSha256(key, message) {
37
+ return (0, crypto_1.createHmac)('sha256', key).update(message).digest('hex');
38
+ }
39
+ /**
40
+ * Normalize HTTP method to uppercase.
41
+ * Handles legacy 'del' → 'DELETE' conversion for backward compatibility.
42
+ *
43
+ * @param method - HTTP method (case-insensitive)
44
+ * @returns Uppercase HTTP method
45
+ */
46
+ function normalizeMethod(method) {
47
+ const lowerMethod = method.toLowerCase();
48
+ if (lowerMethod === 'del') {
49
+ return 'DELETE';
50
+ }
51
+ return method.toUpperCase();
52
+ }
53
+ /**
54
+ * Extract path with query string from a URL.
55
+ * Handles both absolute URLs and relative paths.
56
+ *
57
+ * @param urlPath - Full URL or relative path
58
+ * @returns Path with query string (e.g., '/api/v2/wallet?foo=bar')
59
+ */
60
+ function extractPathWithQuery(urlPath) {
61
+ try {
62
+ // Try parsing as absolute URL first
63
+ const url = new URL(urlPath);
64
+ return url.pathname + url.search;
65
+ }
66
+ catch {
67
+ try {
68
+ const url = new URL(urlPath, 'http://localhost');
69
+ return url.pathname + url.search;
70
+ }
71
+ catch {
72
+ return urlPath;
73
+ }
74
+ }
75
+ }
76
+ /**
77
+ * Get current timestamp in seconds (Unix epoch).
78
+ * Used for v4 authentication which uses seconds instead of milliseconds.
79
+ *
80
+ * @returns Current Unix timestamp in seconds
81
+ */
82
+ function getTimestampSec() {
83
+ return Math.floor(Date.now() / 1000);
84
+ }
85
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBaUJBLDhCQUtDO0FBVUQsb0RBRUM7QUFTRCwwQ0FNQztBQVNELG9EQWFDO0FBUUQsMENBRUM7QUFqRkQsbUNBQWlGO0FBSWpGOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILFNBQWdCLFNBQVMsQ0FBQyxJQUFrQjtJQUMxQyxNQUFNLGNBQWMsR0FBRyxJQUFJLFlBQVksV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ2pGLE9BQU8sSUFBQSxtQkFBVSxFQUFDLFFBQVEsQ0FBQztTQUN4QixNQUFNLENBQUMsY0FBNEIsQ0FBQztTQUNwQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbkIsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxTQUFnQixvQkFBb0IsQ0FBQyxHQUFvQyxFQUFFLE9BQTRCO0lBQ3JHLE9BQU8sSUFBQSxtQkFBVSxFQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ2pFLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixlQUFlLENBQUMsTUFBYztJQUM1QyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDekMsSUFBSSxXQUFXLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDMUIsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBQzlCLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixvQkFBb0IsQ0FBQyxPQUFlO0lBQ2xELElBQUksQ0FBQztRQUNILG9DQUFvQztRQUNwQyxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM3QixPQUFPLEdBQUcsQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztJQUNuQyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsSUFBSSxDQUFDO1lBQ0gsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxFQUFFLGtCQUFrQixDQUFDLENBQUM7WUFDakQsT0FBTyxHQUFHLENBQUMsUUFBUSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7UUFDbkMsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sT0FBTyxDQUFDO1FBQ2pCLENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBZ0IsZUFBZTtJQUM3QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQ3ZDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVIYXNoLCBjcmVhdGVIbWFjLCB0eXBlIEJpbmFyeUxpa2UsIHR5cGUgS2V5T2JqZWN0IH0gZnJvbSAnY3J5cHRvJztcblxuZXhwb3J0IHR5cGUgSGFzaGFibGVEYXRhID0gc3RyaW5nIHwgQnVmZmVyIHwgVWludDhBcnJheSB8IEFycmF5QnVmZmVyO1xuXG4vKipcbiAqIENhbGN1bGF0ZSBTSEEyNTYgaGFzaCBvZiBkYXRhIGFuZCByZXR1cm4gYXMgbG93ZXJjYXNlIGhleCBzdHJpbmcuXG4gKiBVc2VkIGZvciBib2R5IGhhc2ggY2FsY3VsYXRpb24gaW4gdjQgYXV0aGVudGljYXRpb24uXG4gKlxuICogQWNjZXB0cyBzdHJpbmcsIEJ1ZmZlciwgVWludDhBcnJheSwgYW5kIEFycmF5QnVmZmVyIGZvciBjb21wYXRpYmlsaXR5XG4gKiB3aXRoIGJvdGggTm9kZS5qcyBhbmQgYnJvd3NlciBlbnZpcm9ubWVudHMuXG4gKlxuICogTm90ZTogQXJyYXlCdWZmZXIgaXMgY29udmVydGVkIHRvIFVpbnQ4QXJyYXkgaW50ZXJuYWxseSBzaW5jZSBOb2RlLmpzIGNyeXB0b1xuICogcmVxdWlyZXMgVHlwZWRBcnJheSBvciBEYXRhVmlldywgbm90IHBsYWluIEFycmF5QnVmZmVyLlxuICpcbiAqIEBwYXJhbSBkYXRhIC0gVGhlIGRhdGEgdG8gaGFzaFxuICogQHJldHVybnMgTG93ZXJjYXNlIGhleCBzdHJpbmcgb2YgU0hBMjU2IGhhc2hcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNoYTI1NkhleChkYXRhOiBIYXNoYWJsZURhdGEpOiBzdHJpbmcge1xuICBjb25zdCBub3JtYWxpemVkRGF0YSA9IGRhdGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciA/IG5ldyBVaW50OEFycmF5KGRhdGEpIDogZGF0YTtcbiAgcmV0dXJuIGNyZWF0ZUhhc2goJ3NoYTI1NicpXG4gICAgLnVwZGF0ZShub3JtYWxpemVkRGF0YSBhcyBCaW5hcnlMaWtlKVxuICAgIC5kaWdlc3QoJ2hleCcpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBITUFDLVNIQTI1NiBhbmQgcmV0dXJuIGFzIGxvd2VyY2FzZSBoZXggc3RyaW5nLlxuICogVGhpcyBpcyB0aGUgY29yZSBjcnlwdG9ncmFwaGljIHByaW1pdGl2ZSBzaGFyZWQgYnkgdjIvdjMvdjQgYXV0aGVudGljYXRpb24uXG4gKlxuICogQHBhcmFtIGtleSAtIFRoZSBzZWNyZXQga2V5IGZvciBITUFDXG4gKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGF1dGhlbnRpY2F0ZVxuICogQHJldHVybnMgTG93ZXJjYXNlIGhleCBzdHJpbmcgb2YgSE1BQy1TSEEyNTZcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUhtYWNXaXRoU2hhMjU2KGtleTogc3RyaW5nIHwgQmluYXJ5TGlrZSB8IEtleU9iamVjdCwgbWVzc2FnZTogc3RyaW5nIHwgQmluYXJ5TGlrZSk6IHN0cmluZyB7XG4gIHJldHVybiBjcmVhdGVIbWFjKCdzaGEyNTYnLCBrZXkpLnVwZGF0ZShtZXNzYWdlKS5kaWdlc3QoJ2hleCcpO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSBIVFRQIG1ldGhvZCB0byB1cHBlcmNhc2UuXG4gKiBIYW5kbGVzIGxlZ2FjeSAnZGVsJyDihpIgJ0RFTEVURScgY29udmVyc2lvbiBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eS5cbiAqXG4gKiBAcGFyYW0gbWV0aG9kIC0gSFRUUCBtZXRob2QgKGNhc2UtaW5zZW5zaXRpdmUpXG4gKiBAcmV0dXJucyBVcHBlcmNhc2UgSFRUUCBtZXRob2RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZU1ldGhvZChtZXRob2Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGxvd2VyTWV0aG9kID0gbWV0aG9kLnRvTG93ZXJDYXNlKCk7XG4gIGlmIChsb3dlck1ldGhvZCA9PT0gJ2RlbCcpIHtcbiAgICByZXR1cm4gJ0RFTEVURSc7XG4gIH1cbiAgcmV0dXJuIG1ldGhvZC50b1VwcGVyQ2FzZSgpO1xufVxuXG4vKipcbiAqIEV4dHJhY3QgcGF0aCB3aXRoIHF1ZXJ5IHN0cmluZyBmcm9tIGEgVVJMLlxuICogSGFuZGxlcyBib3RoIGFic29sdXRlIFVSTHMgYW5kIHJlbGF0aXZlIHBhdGhzLlxuICpcbiAqIEBwYXJhbSB1cmxQYXRoIC0gRnVsbCBVUkwgb3IgcmVsYXRpdmUgcGF0aFxuICogQHJldHVybnMgUGF0aCB3aXRoIHF1ZXJ5IHN0cmluZyAoZS5nLiwgJy9hcGkvdjIvd2FsbGV0P2Zvbz1iYXInKVxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFBhdGhXaXRoUXVlcnkodXJsUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgdHJ5IHtcbiAgICAvLyBUcnkgcGFyc2luZyBhcyBhYnNvbHV0ZSBVUkwgZmlyc3RcbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHVybFBhdGgpO1xuICAgIHJldHVybiB1cmwucGF0aG5hbWUgKyB1cmwuc2VhcmNoO1xuICB9IGNhdGNoIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdXJsID0gbmV3IFVSTCh1cmxQYXRoLCAnaHR0cDovL2xvY2FsaG9zdCcpO1xuICAgICAgcmV0dXJuIHVybC5wYXRobmFtZSArIHVybC5zZWFyY2g7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gdXJsUGF0aDtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgY3VycmVudCB0aW1lc3RhbXAgaW4gc2Vjb25kcyAoVW5peCBlcG9jaCkuXG4gKiBVc2VkIGZvciB2NCBhdXRoZW50aWNhdGlvbiB3aGljaCB1c2VzIHNlY29uZHMgaW5zdGVhZCBvZiBtaWxsaXNlY29uZHMuXG4gKlxuICogQHJldHVybnMgQ3VycmVudCBVbml4IHRpbWVzdGFtcCBpbiBzZWNvbmRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUaW1lc3RhbXBTZWMoKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApO1xufVxuIl19
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Browser-native HMAC auth strategy using the Web Crypto API.
3
+ *
4
+ * All browser API usage (crypto.subtle) is inside method bodies,
5
+ * so the module can be safely imported in any environment -- it only requires
6
+ * browser globals when methods are actually called.
7
+ */
8
+ import type { AuthVersion, IHmacAuthStrategy, ITokenStore, CalculateRequestHeadersWebCryptoOptions, RequestHeaders, VerifyResponseOptions, VerifyResponseInfo } from './types';
9
+ export interface WebCryptoHmacStrategyOptions {
10
+ tokenStore?: ITokenStore;
11
+ authVersion?: AuthVersion;
12
+ }
13
+ /**
14
+ * HMAC auth strategy using the browser's Web Crypto API (crypto.subtle).
15
+ *
16
+ * Usable both as an `IHmacAuthStrategy` for BitGoAPI and as a standalone
17
+ * utility for signing/verifying requests made with the browser `fetch()` API.
18
+ *
19
+ * Token lifecycle:
20
+ * - Call `setToken(rawToken)` after authentication to import the token as a
21
+ * non-extractable CryptoKey and persist it to the configured ITokenStore.
22
+ * - Call `restoreToken()` on page load to recover a previously stored token.
23
+ * - Call `clearToken()` on logout.
24
+ */
25
+ export declare class WebCryptoHmacStrategy implements IHmacAuthStrategy {
26
+ private cryptoKey;
27
+ private tokenHashHex;
28
+ private tokenStore;
29
+ private authVersion;
30
+ constructor(options?: WebCryptoHmacStrategyOptions);
31
+ /**
32
+ * Import a raw bearer token: derives a non-extractable CryptoKey for HMAC
33
+ * signing, computes the SHA-256 token hash, and persists the
34
+ * {@link CryptoSigning} material (NOT the raw token) to the token store.
35
+ */
36
+ setToken(rawToken: string): Promise<void>;
37
+ clearToken(): Promise<void>;
38
+ /**
39
+ * Attempt to restore signing material from the token store (e.g. IndexedDB).
40
+ * The stored {@link CryptoSigning} already contains the non-extractable
41
+ * CryptoKey and token hash — no raw token is involved.
42
+ * Returns true if signing material was successfully restored.
43
+ */
44
+ restoreToken(): Promise<boolean>;
45
+ hasToken(): boolean;
46
+ isAuthenticated(): boolean;
47
+ calculateRequestHeaders(params: CalculateRequestHeadersWebCryptoOptions): Promise<RequestHeaders>;
48
+ verifyResponse(params: VerifyResponseOptions): Promise<VerifyResponseInfo>;
49
+ calculateHMAC(key: string, message: string): Promise<string>;
50
+ /**
51
+ * Returns a flat headers dict ready to spread into a `fetch()` init object.
52
+ *
53
+ * Example:
54
+ * ```
55
+ * const headers = await strategy.getAuthHeaders({ url, method: 'GET' });
56
+ * const response = await fetch(url, { headers });
57
+ * ```
58
+ */
59
+ getAuthHeaders(params: {
60
+ url: string;
61
+ method: string;
62
+ body?: string;
63
+ }): Promise<Record<string, string>>;
64
+ /**
65
+ * Verify a browser Fetch `Response` object's HMAC.
66
+ *
67
+ * Clones the response to read the body text without consuming it.
68
+ */
69
+ verifyFetchResponse(params: {
70
+ url: string;
71
+ method: string;
72
+ response: Response;
73
+ }): Promise<VerifyResponseInfo>;
74
+ }
75
+ //# sourceMappingURL=webCryptoStrategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webCryptoStrategy.d.ts","sourceRoot":"","sources":["../../src/webCryptoStrategy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,uCAAuC,EACvC,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAiDjB,MAAM,WAAW,4BAA4B;IAC3C,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,qBAAsB,YAAW,iBAAiB;IAC7D,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,WAAW,CAAc;gBAErB,OAAO,CAAC,EAAE,4BAA4B;IAOlD;;;;OAIG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAMjC;;;;;OAKG;IACG,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAUtC,QAAQ,IAAI,OAAO;IAInB,eAAe,IAAI,OAAO;IAMpB,uBAAuB,CAAC,MAAM,EAAE,uCAAuC,GAAG,OAAO,CAAC,cAAc,CAAC;IAgBjG,cAAc,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA8B1E,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOlE;;;;;;;;OAQG;IACG,cAAc,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAe7G;;;;OAIG;IACG,mBAAmB,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAcpH"}
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebCryptoHmacStrategy = void 0;
4
+ const hmac_1 = require("./hmac");
5
+ const indexedDbTokenStore_1 = require("./indexedDbTokenStore");
6
+ function arrayBufToHex(buffer) {
7
+ const bytes = new Uint8Array(buffer);
8
+ const hexParts = new Array(bytes.length);
9
+ for (let i = 0; i < bytes.length; i++) {
10
+ hexParts[i] = bytes[i].toString(16).padStart(2, '0');
11
+ }
12
+ return hexParts.join('');
13
+ }
14
+ async function webCryptoHmacSign(key, data) {
15
+ const encoded = new TextEncoder().encode(data);
16
+ const sig = await crypto.subtle.sign('HMAC', key, encoded);
17
+ return arrayBufToHex(sig);
18
+ }
19
+ async function webCryptoImportHmacKey(rawKey) {
20
+ const encoded = new TextEncoder().encode(rawKey);
21
+ return crypto.subtle.importKey('raw', encoded, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
22
+ }
23
+ /**
24
+ * Constant-time string comparison to prevent timing side-channel attacks.
25
+ * Browser-compatible polyfill for Node's `crypto.timingSafeEqual`.
26
+ */
27
+ function timingSafeStringEqual(a, b) {
28
+ const aBytes = new TextEncoder().encode(a);
29
+ const bBytes = new TextEncoder().encode(b);
30
+ if (aBytes.length !== bBytes.length)
31
+ return false;
32
+ let result = 0;
33
+ for (let i = 0; i < aBytes.length; i++) {
34
+ result |= aBytes[i] ^ bBytes[i];
35
+ }
36
+ return result === 0;
37
+ }
38
+ async function webCryptoSha256Hex(data) {
39
+ const encoded = new TextEncoder().encode(data);
40
+ const hash = await crypto.subtle.digest('SHA-256', encoded);
41
+ return arrayBufToHex(hash);
42
+ }
43
+ /**
44
+ * HMAC auth strategy using the browser's Web Crypto API (crypto.subtle).
45
+ *
46
+ * Usable both as an `IHmacAuthStrategy` for BitGoAPI and as a standalone
47
+ * utility for signing/verifying requests made with the browser `fetch()` API.
48
+ *
49
+ * Token lifecycle:
50
+ * - Call `setToken(rawToken)` after authentication to import the token as a
51
+ * non-extractable CryptoKey and persist it to the configured ITokenStore.
52
+ * - Call `restoreToken()` on page load to recover a previously stored token.
53
+ * - Call `clearToken()` on logout.
54
+ */
55
+ class WebCryptoHmacStrategy {
56
+ constructor(options) {
57
+ this.cryptoKey = null;
58
+ this.tokenHashHex = null;
59
+ this.tokenStore = options?.tokenStore ?? new indexedDbTokenStore_1.IndexedDbTokenStore();
60
+ this.authVersion = options?.authVersion ?? 2;
61
+ }
62
+ // --- Token lifecycle ---------------------------------------------------
63
+ /**
64
+ * Import a raw bearer token: derives a non-extractable CryptoKey for HMAC
65
+ * signing, computes the SHA-256 token hash, and persists the
66
+ * {@link CryptoSigning} material (NOT the raw token) to the token store.
67
+ */
68
+ async setToken(rawToken) {
69
+ this.cryptoKey = await webCryptoImportHmacKey(rawToken);
70
+ this.tokenHashHex = await webCryptoSha256Hex(rawToken);
71
+ await this.tokenStore.save({ cryptoKey: this.cryptoKey, tokenHash: this.tokenHashHex });
72
+ }
73
+ async clearToken() {
74
+ this.cryptoKey = null;
75
+ this.tokenHashHex = null;
76
+ await this.tokenStore.remove();
77
+ }
78
+ /**
79
+ * Attempt to restore signing material from the token store (e.g. IndexedDB).
80
+ * The stored {@link CryptoSigning} already contains the non-extractable
81
+ * CryptoKey and token hash — no raw token is involved.
82
+ * Returns true if signing material was successfully restored.
83
+ */
84
+ async restoreToken() {
85
+ const signing = await this.tokenStore.load();
86
+ if (signing) {
87
+ this.cryptoKey = signing.cryptoKey;
88
+ this.tokenHashHex = signing.tokenHash;
89
+ return true;
90
+ }
91
+ return false;
92
+ }
93
+ hasToken() {
94
+ return this.cryptoKey !== null && this.tokenHashHex !== null;
95
+ }
96
+ isAuthenticated() {
97
+ return this.hasToken();
98
+ }
99
+ // --- IHmacAuthStrategy implementation -----------------------------------
100
+ async calculateRequestHeaders(params) {
101
+ if (!this.cryptoKey || !this.tokenHashHex) {
102
+ throw new Error('No token available. Call setToken() or restoreToken() first.');
103
+ }
104
+ const timestamp = Date.now();
105
+ const subject = (0, hmac_1.calculateHMACSubject)({
106
+ urlPath: params.url,
107
+ text: params.text,
108
+ timestamp,
109
+ method: params.method,
110
+ authVersion: params.authVersion,
111
+ });
112
+ const hmac = await webCryptoHmacSign(this.cryptoKey, subject);
113
+ return { hmac, timestamp, tokenHash: this.tokenHashHex };
114
+ }
115
+ async verifyResponse(params) {
116
+ if (!this.cryptoKey) {
117
+ throw new Error('No token available. Call setToken() or restoreToken() first.');
118
+ }
119
+ const subject = (0, hmac_1.calculateHMACSubject)({
120
+ urlPath: params.url,
121
+ text: params.text,
122
+ timestamp: params.timestamp,
123
+ method: params.method,
124
+ statusCode: params.statusCode,
125
+ authVersion: params.authVersion,
126
+ });
127
+ const expectedHmac = await webCryptoHmacSign(this.cryptoKey, subject);
128
+ const now = Date.now();
129
+ const backwardValidityWindow = 1000 * 60 * 5;
130
+ const forwardValidityWindow = 1000 * 60;
131
+ const isInResponseValidityWindow = params.timestamp >= now - backwardValidityWindow && params.timestamp <= now + forwardValidityWindow;
132
+ return {
133
+ isValid: timingSafeStringEqual(expectedHmac, params.hmac),
134
+ expectedHmac,
135
+ signatureSubject: subject,
136
+ isInResponseValidityWindow,
137
+ verificationTime: now,
138
+ };
139
+ }
140
+ async calculateHMAC(key, message) {
141
+ const cryptoKey = await webCryptoImportHmacKey(key);
142
+ return webCryptoHmacSign(cryptoKey, message);
143
+ }
144
+ // --- Convenience methods for standalone fetch() usage -------------------
145
+ /**
146
+ * Returns a flat headers dict ready to spread into a `fetch()` init object.
147
+ *
148
+ * Example:
149
+ * ```
150
+ * const headers = await strategy.getAuthHeaders({ url, method: 'GET' });
151
+ * const response = await fetch(url, { headers });
152
+ * ```
153
+ */
154
+ async getAuthHeaders(params) {
155
+ const requestHeaders = await this.calculateRequestHeaders({
156
+ url: params.url,
157
+ method: params.method,
158
+ text: params.body ?? '',
159
+ authVersion: this.authVersion,
160
+ });
161
+ return {
162
+ 'Auth-Timestamp': requestHeaders.timestamp.toString(),
163
+ Authorization: 'Bearer ' + requestHeaders.tokenHash,
164
+ HMAC: requestHeaders.hmac,
165
+ 'BitGo-Auth-Version': this.authVersion === 3 ? '3.0' : '2.0',
166
+ };
167
+ }
168
+ /**
169
+ * Verify a browser Fetch `Response` object's HMAC.
170
+ *
171
+ * Clones the response to read the body text without consuming it.
172
+ */
173
+ async verifyFetchResponse(params) {
174
+ const cloned = params.response.clone();
175
+ const text = await cloned.text();
176
+ return this.verifyResponse({
177
+ url: params.url,
178
+ token: '',
179
+ method: params.method,
180
+ text,
181
+ hmac: params.response.headers.get('hmac') ?? '',
182
+ statusCode: params.response.status,
183
+ timestamp: parseInt(params.response.headers.get('timestamp') ?? '0', 10),
184
+ authVersion: this.authVersion,
185
+ });
186
+ }
187
+ }
188
+ exports.WebCryptoHmacStrategy = WebCryptoHmacStrategy;
189
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViQ3J5cHRvU3RyYXRlZ3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd2ViQ3J5cHRvU3RyYXRlZ3kudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBZ0JBLGlDQUE4QztBQUM5QywrREFBNEQ7QUFFNUQsU0FBUyxhQUFhLENBQUMsTUFBbUI7SUFDeEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDckMsTUFBTSxRQUFRLEdBQWEsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ25ELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDdEMsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBQ0QsT0FBTyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzNCLENBQUM7QUFFRCxLQUFLLFVBQVUsaUJBQWlCLENBQUMsR0FBYyxFQUFFLElBQVk7SUFDM0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDL0MsTUFBTSxHQUFHLEdBQUcsTUFBTSxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzNELE9BQU8sYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLENBQUM7QUFFRCxLQUFLLFVBQVUsc0JBQXNCLENBQUMsTUFBYztJQUNsRCxNQUFNLE9BQU8sR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENB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LEdBQUcsRUFBRSxFQUFFLENBQUM7WUFDeEUsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO1NBQzlCLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQXhKRCxzREF3SkMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEJyb3dzZXItbmF0aXZlIEhNQUMgYXV0aCBzdHJhdGVneSB1c2luZyB0aGUgV2ViIENyeXB0byBBUEkuXG4gKlxuICogQWxsIGJyb3dzZXIgQVBJIHVzYWdlIChjcnlwdG8uc3VidGxlKSBpcyBpbnNpZGUgbWV0aG9kIGJvZGllcyxcbiAqIHNvIHRoZSBtb2R1bGUgY2FuIGJlIHNhZmVseSBpbXBvcnRlZCBpbiBhbnkgZW52aXJvbm1lbnQgLS0gaXQgb25seSByZXF1aXJlc1xuICogYnJvd3NlciBnbG9iYWxzIHdoZW4gbWV0aG9kcyBhcmUgYWN0dWFsbHkgY2FsbGVkLlxuICovXG5pbXBvcnQgdHlwZSB7XG4gIEF1dGhWZXJzaW9uLFxuICBJSG1hY0F1dGhTdHJhdGVneSxcbiAgSVRva2VuU3RvcmUsXG4gIENhbGN1bGF0ZVJlcXVlc3RIZWFkZXJzV2ViQ3J5cHRvT3B0aW9ucyxcbiAgUmVxdWVzdEhlYWRlcnMsXG4gIFZlcmlmeVJlc3BvbnNlT3B0aW9ucyxcbiAgVmVyaWZ5UmVzcG9uc2VJbmZvLFxufSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IGNhbGN1bGF0ZUhNQUNTdWJqZWN0IH0gZnJvbSAnLi9obWFjJztcbmltcG9ydCB7IEluZGV4ZWREYlRva2VuU3RvcmUgfSBmcm9tICcuL2luZGV4ZWREYlRva2VuU3RvcmUnO1xuXG5mdW5jdGlvbiBhcnJheUJ1ZlRvSGV4KGJ1ZmZlcjogQXJyYXlCdWZmZXIpOiBzdHJpbmcge1xuICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG4gIGNvbnN0IGhleFBhcnRzOiBzdHJpbmdbXSA9IG5ldyBBcnJheShieXRlcy5sZW5ndGgpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgaGV4UGFydHNbaV0gPSBieXRlc1tpXS50b1N0cmluZygxNikucGFkU3RhcnQoMiwgJzAnKTtcbiAgfVxuICByZXR1cm4gaGV4UGFydHMuam9pbignJyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHdlYkNyeXB0b0htYWNTaWduKGtleTogQ3J5cHRvS2V5LCBkYXRhOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBlbmNvZGVkID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGRhdGEpO1xuICBjb25zdCBzaWcgPSBhd2FpdCBjcnlwdG8uc3VidGxlLnNpZ24oJ0hNQUMnLCBrZXksIGVuY29kZWQpO1xuICByZXR1cm4gYXJyYXlCdWZUb0hleChzaWcpO1xufVxuXG5hc3luYyBmdW5jdGlvbiB3ZWJDcnlwdG9JbXBvcnRIbWFjS2V5KHJhd0tleTogc3RyaW5nKTogUHJvbWlzZTxDcnlwdG9LZXk+IHtcbiAgY29uc3QgZW5jb2RlZCA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShyYXdLZXkpO1xuICByZXR1cm4gY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoJ3JhdycsIGVuY29kZWQsIHsgbmFtZTogJ0hNQUMnLCBoYXNoOiAnU0hBLTI1NicgfSwgZmFsc2UsIFsnc2lnbiddKTtcbn1cblxuLyoqXG4gKiBDb25zdGFudC10aW1lIHN0cmluZyBjb21wYXJpc29uIHRvIHByZXZlbnQgdGltaW5nIHNpZGUtY2hhbm5lbCBhdHRhY2tzLlxuICogQnJvd3Nlci1jb21wYXRpYmxlIHBvbHlmaWxsIGZvciBOb2RlJ3MgYGNyeXB0by50aW1pbmdTYWZlRXF1YWxgLlxuICovXG5mdW5jdGlvbiB0aW1pbmdTYWZlU3RyaW5nRXF1YWwoYTogc3RyaW5nLCBiOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgYUJ5dGVzID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGEpO1xuICBjb25zdCBiQnl0ZXMgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoYik7XG4gIGlmIChhQnl0ZXMubGVuZ3RoICE9PSBiQnl0ZXMubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gIGxldCByZXN1bHQgPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGFCeXRlcy5sZW5ndGg7IGkrKykge1xuICAgIHJlc3VsdCB8PSBhQnl0ZXNbaV0gXiBiQnl0ZXNbaV07XG4gIH1cbiAgcmV0dXJuIHJlc3VsdCA9PT0gMDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gd2ViQ3J5cHRvU2hhMjU2SGV4KGRhdGE6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGVuY29kZWQgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZGF0YSk7XG4gIGNvbnN0IGhhc2ggPSBhd2FpdCBjcnlwdG8uc3VidGxlLmRpZ2VzdCgnU0hBLTI1NicsIGVuY29kZWQpO1xuICByZXR1cm4gYXJyYXlCdWZUb0hleChoYXNoKTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBXZWJDcnlwdG8gSE1BQyBTdHJhdGVneVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmV4cG9ydCBpbnRlcmZhY2UgV2ViQ3J5cHRvSG1hY1N0cmF0ZWd5T3B0aW9ucyB7XG4gIHRva2VuU3RvcmU/OiBJVG9rZW5TdG9yZTtcbiAgYXV0aFZlcnNpb24/OiBBdXRoVmVyc2lvbjtcbn1cblxuLyoqXG4gKiBITUFDIGF1dGggc3RyYXRlZ3kgdXNpbmcgdGhlIGJyb3dzZXIncyBXZWIgQ3J5cHRvIEFQSSAoY3J5cHRvLnN1YnRsZSkuXG4gKlxuICogVXNhYmxlIGJvdGggYXMgYW4gYElIbWFjQXV0aFN0cmF0ZWd5YCBmb3IgQml0R29BUEkgYW5kIGFzIGEgc3RhbmRhbG9uZVxuICogdXRpbGl0eSBmb3Igc2lnbmluZy92ZXJpZnlpbmcgcmVxdWVzdHMgbWFkZSB3aXRoIHRoZSBicm93c2VyIGBmZXRjaCgpYCBBUEkuXG4gKlxuICogVG9rZW4gbGlmZWN5Y2xlOlxuICogIC0gQ2FsbCBgc2V0VG9rZW4ocmF3VG9rZW4pYCBhZnRlciBhdXRoZW50aWNhdGlvbiB0byBpbXBvcnQgdGhlIHRva2VuIGFzIGFcbiAqICAgIG5vbi1leHRyYWN0YWJsZSBDcnlwdG9LZXkgYW5kIHBlcnNpc3QgaXQgdG8gdGhlIGNvbmZpZ3VyZWQgSVRva2VuU3RvcmUuXG4gKiAgLSBDYWxsIGByZXN0b3JlVG9rZW4oKWAgb24gcGFnZSBsb2FkIHRvIHJlY292ZXIgYSBwcmV2aW91c2x5IHN0b3JlZCB0b2tlbi5cbiAqICAtIENhbGwgYGNsZWFyVG9rZW4oKWAgb24gbG9nb3V0LlxuICovXG5leHBvcnQgY2xhc3MgV2ViQ3J5cHRvSG1hY1N0cmF0ZWd5IGltcGxlbWVudHMgSUhtYWNBdXRoU3RyYXRlZ3kge1xuICBwcml2YXRlIGNyeXB0b0tleTogQ3J5cHRvS2V5IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgdG9rZW5IYXNoSGV4OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSB0b2tlblN0b3JlOiBJVG9rZW5TdG9yZTtcbiAgcHJpdmF0ZSBhdXRoVmVyc2lvbjogQXV0aFZlcnNpb247XG5cbiAgY29uc3RydWN0b3Iob3B0aW9ucz86IFdlYkNyeXB0b0htYWNTdHJhdGVneU9wdGlvbnMpIHtcbiAgICB0aGlzLnRva2VuU3RvcmUgPSBvcHRpb25zPy50b2tlblN0b3JlID8/IG5ldyBJbmRleGVkRGJUb2tlblN0b3JlKCk7XG4gICAgdGhpcy5hdXRoVmVyc2lvbiA9IG9wdGlvbnM/LmF1dGhWZXJzaW9uID8/IDI7XG4gIH1cblxuICAvLyAtLS0gVG9rZW4gbGlmZWN5Y2xlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8qKlxuICAgKiBJbXBvcnQgYSByYXcgYmVhcmVyIHRva2VuOiBkZXJpdmVzIGEgbm9uLWV4dHJhY3RhYmxlIENyeXB0b0tleSBmb3IgSE1BQ1xuICAgKiBzaWduaW5nLCBjb21wdXRlcyB0aGUgU0hBLTI1NiB0b2tlbiBoYXNoLCBhbmQgcGVyc2lzdHMgdGhlXG4gICAqIHtAbGluayBDcnlwdG9TaWduaW5nfSBtYXRlcmlhbCAoTk9UIHRoZSByYXcgdG9rZW4pIHRvIHRoZSB0b2tlbiBzdG9yZS5cbiAgICovXG4gIGFzeW5jIHNldFRva2VuKHJhd1Rva2VuOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmNyeXB0b0tleSA9IGF3YWl0IHdlYkNyeXB0b0ltcG9ydEhtYWNLZXkocmF3VG9rZW4pO1xuICAgIHRoaXMudG9rZW5IYXNoSGV4ID0gYXdhaXQgd2ViQ3J5cHRvU2hhMjU2SGV4KHJhd1Rva2VuKTtcbiAgICBhd2FpdCB0aGlzLnRva2VuU3RvcmUuc2F2ZSh7IGNyeXB0b0tleTogdGhpcy5jcnlwdG9LZXksIHRva2VuSGFzaDogdGhpcy50b2tlbkhhc2hIZXggfSk7XG4gIH1cblxuICBhc3luYyBjbGVhclRva2VuKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuY3J5cHRvS2V5ID0gbnVsbDtcbiAgICB0aGlzLnRva2VuSGFzaEhleCA9IG51bGw7XG4gICAgYXdhaXQgdGhpcy50b2tlblN0b3JlLnJlbW92ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGVtcHQgdG8gcmVzdG9yZSBzaWduaW5nIG1hdGVyaWFsIGZyb20gdGhlIHRva2VuIHN0b3JlIChlLmcuIEluZGV4ZWREQikuXG4gICAqIFRoZSBzdG9yZWQge0BsaW5rIENyeXB0b1NpZ25pbmd9IGFscmVhZHkgY29udGFpbnMgdGhlIG5vbi1leHRyYWN0YWJsZVxuICAgKiBDcnlwdG9LZXkgYW5kIHRva2VuIGhhc2gg4oCUIG5vIHJhdyB0b2tlbiBpcyBpbnZvbHZlZC5cbiAgICogUmV0dXJucyB0cnVlIGlmIHNpZ25pbmcgbWF0ZXJpYWwgd2FzIHN1Y2Nlc3NmdWxseSByZXN0b3JlZC5cbiAgICovXG4gIGFzeW5jIHJlc3RvcmVUb2tlbigpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBzaWduaW5nID0gYXdhaXQgdGhpcy50b2tlblN0b3JlLmxvYWQoKTtcbiAgICBpZiAoc2lnbmluZykge1xuICAgICAgdGhpcy5jcnlwdG9LZXkgPSBzaWduaW5nLmNyeXB0b0tleTtcbiAgICAgIHRoaXMudG9rZW5IYXNoSGV4ID0gc2lnbmluZy50b2tlbkhhc2g7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaGFzVG9rZW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY3J5cHRvS2V5ICE9PSBudWxsICYmIHRoaXMudG9rZW5IYXNoSGV4ICE9PSBudWxsO1xuICB9XG5cbiAgaXNBdXRoZW50aWNhdGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmhhc1Rva2VuKCk7XG4gIH1cblxuICAvLyAtLS0gSUhtYWNBdXRoU3RyYXRlZ3kgaW1wbGVtZW50YXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBhc3luYyBjYWxjdWxhdGVSZXF1ZXN0SGVhZGVycyhwYXJhbXM6IENhbGN1bGF0ZVJlcXVlc3RIZWFkZXJzV2ViQ3J5cHRvT3B0aW9ucyk6IFByb21pc2U8UmVxdWVzdEhlYWRlcnM+IHtcbiAgICBpZiAoIXRoaXMuY3J5cHRvS2V5IHx8ICF0aGlzLnRva2VuSGFzaEhleCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyB0b2tlbiBhdmFpbGFibGUuIENhbGwgc2V0VG9rZW4oKSBvciByZXN0b3JlVG9rZW4oKSBmaXJzdC4nKTtcbiAgICB9XG4gICAgY29uc3QgdGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBzdWJqZWN0ID0gY2FsY3VsYXRlSE1BQ1N1YmplY3Qoe1xuICAgICAgdXJsUGF0aDogcGFyYW1zLnVybCxcbiAgICAgIHRleHQ6IHBhcmFtcy50ZXh0LFxuICAgICAgdGltZXN0YW1wLFxuICAgICAgbWV0aG9kOiBwYXJhbXMubWV0aG9kLFxuICAgICAgYXV0aFZlcnNpb246IHBhcmFtcy5hdXRoVmVyc2lvbixcbiAgICB9KTtcbiAgICBjb25zdCBobWFjID0gYXdhaXQgd2ViQ3J5cHRvSG1hY1NpZ24odGhpcy5jcnlwdG9LZXksIHN1YmplY3QpO1xuICAgIHJldHVybiB7IGhtYWMsIHRpbWVzdGFtcCwgdG9rZW5IYXNoOiB0aGlzLnRva2VuSGFzaEhleCB9O1xuICB9XG5cbiAgYXN5bmMgdmVyaWZ5UmVzcG9uc2UocGFyYW1zOiBWZXJpZnlSZXNwb25zZU9wdGlvbnMpOiBQcm9taXNlPFZlcmlmeVJlc3BvbnNlSW5mbz4ge1xuICAgIGlmICghdGhpcy5jcnlwdG9LZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gdG9rZW4gYXZhaWxhYmxlLiBDYWxsIHNldFRva2VuKCkgb3IgcmVzdG9yZVRva2VuKCkgZmlyc3QuJyk7XG4gICAgfVxuICAgIGNvbnN0IHN1YmplY3QgPSBjYWxjdWxhdGVITUFDU3ViamVjdCh7XG4gICAgICB1cmxQYXRoOiBwYXJhbXMudXJsLFxuICAgICAgdGV4dDogcGFyYW1zLnRleHQsXG4gICAgICB0aW1lc3RhbXA6IHBhcmFtcy50aW1lc3RhbXAsXG4gICAgICBtZXRob2Q6IHBhcmFtcy5tZXRob2QsXG4gICAgICBzdGF0dXNDb2RlOiBwYXJhbXMuc3RhdHVzQ29kZSxcbiAgICAgIGF1dGhWZXJzaW9uOiBwYXJhbXMuYXV0aFZlcnNpb24sXG4gICAgfSk7XG5cbiAgICBjb25zdCBleHBlY3RlZEhtYWMgPSBhd2FpdCB3ZWJDcnlwdG9IbWFjU2lnbih0aGlzLmNyeXB0b0tleSwgc3ViamVjdCk7XG5cbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IGJhY2t3YXJkVmFsaWRpdHlXaW5kb3cgPSAxMDAwICogNjAgKiA1O1xuICAgIGNvbnN0IGZvcndhcmRWYWxpZGl0eVdpbmRvdyA9IDEwMDAgKiA2MDtcbiAgICBjb25zdCBpc0luUmVzcG9uc2VWYWxpZGl0eVdpbmRvdyA9XG4gICAgICBwYXJhbXMudGltZXN0YW1wID49IG5vdyAtIGJhY2t3YXJkVmFsaWRpdHlXaW5kb3cgJiYgcGFyYW1zLnRpbWVzdGFtcCA8PSBub3cgKyBmb3J3YXJkVmFsaWRpdHlXaW5kb3c7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaXNWYWxpZDogdGltaW5nU2FmZVN0cmluZ0VxdWFsKGV4cGVjdGVkSG1hYywgcGFyYW1zLmhtYWMpLFxuICAgICAgZXhwZWN0ZWRIbWFjLFxuICAgICAgc2lnbmF0dXJlU3ViamVjdDogc3ViamVjdCBhcyBWZXJpZnlSZXNwb25zZUluZm9bJ3NpZ25hdHVyZVN1YmplY3QnXSxcbiAgICAgIGlzSW5SZXNwb25zZVZhbGlkaXR5V2luZG93LFxuICAgICAgdmVyaWZpY2F0aW9uVGltZTogbm93LFxuICAgIH07XG4gIH1cblxuICBhc3luYyBjYWxjdWxhdGVITUFDKGtleTogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IGNyeXB0b0tleSA9IGF3YWl0IHdlYkNyeXB0b0ltcG9ydEhtYWNLZXkoa2V5KTtcbiAgICByZXR1cm4gd2ViQ3J5cHRvSG1hY1NpZ24oY3J5cHRvS2V5LCBtZXNzYWdlKTtcbiAgfVxuXG4gIC8vIC0tLSBDb252ZW5pZW5jZSBtZXRob2RzIGZvciBzdGFuZGFsb25lIGZldGNoKCkgdXNhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgZmxhdCBoZWFkZXJzIGRpY3QgcmVhZHkgdG8gc3ByZWFkIGludG8gYSBgZmV0Y2goKWAgaW5pdCBvYmplY3QuXG4gICAqXG4gICAqIEV4YW1wbGU6XG4gICAqIGBgYFxuICAgKiBjb25zdCBoZWFkZXJzID0gYXdhaXQgc3RyYXRlZ3kuZ2V0QXV0aEhlYWRlcnMoeyB1cmwsIG1ldGhvZDogJ0dFVCcgfSk7XG4gICAqIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsLCB7IGhlYWRlcnMgfSk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZ2V0QXV0aEhlYWRlcnMocGFyYW1zOiB7IHVybDogc3RyaW5nOyBtZXRob2Q6IHN0cmluZzsgYm9keT86IHN0cmluZyB9KTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PiB7XG4gICAgY29uc3QgcmVxdWVzdEhlYWRlcnMgPSBhd2FpdCB0aGlzLmNhbGN1bGF0ZVJlcXVlc3RIZWFkZXJzKHtcbiAgICAgIHVybDogcGFyYW1zLnVybCxcbiAgICAgIG1ldGhvZDogcGFyYW1zLm1ldGhvZCBhcyBDYWxjdWxhdGVSZXF1ZXN0SGVhZGVyc1dlYkNyeXB0b09wdGlvbnNbJ21ldGhvZCddLFxuICAgICAgdGV4dDogcGFyYW1zLmJvZHkgPz8gJycsXG4gICAgICBhdXRoVmVyc2lvbjogdGhpcy5hdXRoVmVyc2lvbixcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgJ0F1dGgtVGltZXN0YW1wJzogcmVxdWVzdEhlYWRlcnMudGltZXN0YW1wLnRvU3RyaW5nKCksXG4gICAgICBBdXRob3JpemF0aW9uOiAnQmVhcmVyICcgKyByZXF1ZXN0SGVhZGVycy50b2tlbkhhc2gsXG4gICAgICBITUFDOiByZXF1ZXN0SGVhZGVycy5obWFjLFxuICAgICAgJ0JpdEdvLUF1dGgtVmVyc2lvbic6IHRoaXMuYXV0aFZlcnNpb24gPT09IDMgPyAnMy4wJyA6ICcyLjAnLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZ5IGEgYnJvd3NlciBGZXRjaCBgUmVzcG9uc2VgIG9iamVjdCdzIEhNQUMuXG4gICAqXG4gICAqIENsb25lcyB0aGUgcmVzcG9uc2UgdG8gcmVhZCB0aGUgYm9keSB0ZXh0IHdpdGhvdXQgY29uc3VtaW5nIGl0LlxuICAgKi9cbiAgYXN5bmMgdmVyaWZ5RmV0Y2hSZXNwb25zZShwYXJhbXM6IHsgdXJsOiBzdHJpbmc7IG1ldGhvZDogc3RyaW5nOyByZXNwb25zZTogUmVzcG9uc2UgfSk6IFByb21pc2U8VmVyaWZ5UmVzcG9uc2VJbmZvPiB7XG4gICAgY29uc3QgY2xvbmVkID0gcGFyYW1zLnJlc3BvbnNlLmNsb25lKCk7XG4gICAgY29uc3QgdGV4dCA9IGF3YWl0IGNsb25lZC50ZXh0KCk7XG4gICAgcmV0dXJuIHRoaXMudmVyaWZ5UmVzcG9uc2Uoe1xuICAgICAgdXJsOiBwYXJhbXMudXJsLFxuICAgICAgdG9rZW46ICcnLFxuICAgICAgbWV0aG9kOiBwYXJhbXMubWV0aG9kIGFzIFZlcmlmeVJlc3BvbnNlT3B0aW9uc1snbWV0aG9kJ10sXG4gICAgICB0ZXh0LFxuICAgICAgaG1hYzogcGFyYW1zLnJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdobWFjJykgPz8gJycsXG4gICAgICBzdGF0dXNDb2RlOiBwYXJhbXMucmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgdGltZXN0YW1wOiBwYXJzZUludChwYXJhbXMucmVzcG9uc2UuaGVhZGVycy5nZXQoJ3RpbWVzdGFtcCcpID8/ICcwJywgMTApLFxuICAgICAgYXV0aFZlcnNpb246IHRoaXMuYXV0aFZlcnNpb24sXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
package/package.json CHANGED
@@ -1,13 +1,30 @@
1
1
  {
2
2
  "name": "@bitgo-beta/sdk-hmac",
3
- "version": "1.0.1-beta.102",
3
+ "version": "1.0.1-beta.1021",
4
4
  "description": "HMAC module for the BitGo SDK",
5
5
  "main": "./dist/src/index.js",
6
6
  "types": "./dist/src/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/src/index.d.ts",
10
+ "default": "./dist/src/index.js"
11
+ },
12
+ "./browser": {
13
+ "types": "./dist/src/browser.d.ts",
14
+ "default": "./dist/src/browser.js"
15
+ }
16
+ },
17
+ "typesVersions": {
18
+ "*": {
19
+ "browser": [
20
+ "./dist/src/browser.d.ts"
21
+ ]
22
+ }
23
+ },
7
24
  "scripts": {
8
25
  "build": "yarn tsc --build --incremental --verbose .",
9
26
  "fmt": "prettier --write .",
10
- "check-fmt": "prettier --check .",
27
+ "check-fmt": "prettier --check '**/*.{ts,js,json}'",
11
28
  "clean": "rm -r ./dist",
12
29
  "lint": "eslint --quiet .",
13
30
  "test": "npm run coverage",
@@ -16,7 +33,7 @@
16
33
  "prepare": "npm run build"
17
34
  },
18
35
  "dependencies": {
19
- "@bitgo-beta/sjcl": "1.0.2-beta.974"
36
+ "@bitgo-beta/sjcl": "1.0.2-beta.1893"
20
37
  },
21
38
  "devDependencies": {
22
39
  "chai": "^4.3.6",
@@ -46,5 +63,5 @@
46
63
  ".ts"
47
64
  ]
48
65
  },
49
- "gitHead": "a8223d20b478c43d0486e270ce6b84b2eb15a944"
66
+ "gitHead": "be29a647eac8a4aba15ab8e4fd5ceeb6d438630c"
50
67
  }