@dynamic-labs-wallet/forward-mpc-client 0.10.0 → 0.10.1

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.
package/dist/index.d.cts CHANGED
@@ -3,7 +3,7 @@ import { BaseWebSocketMessage, TraceContext, HashAlgorithm, encryptKeyshare } fr
3
3
  export { BaseWebSocketMessage, ErrorResponse, HandshakeV1RequestMessage, HandshakeV1ResponseMessage, SignMessageV1RequestMessage, SignMessageV1ResponseMessage, WebSocketError, WebSocketErrorType } from '@dynamic-labs-wallet/forward-mpc-shared';
4
4
  import { SigningAlgorithm } from '@dynamic-labs-wallet/primitives';
5
5
  export { SigningAlgorithm } from '@dynamic-labs-wallet/primitives';
6
- export { A as AttestationErrorCode, C as ClientError, a as ClientSessionEstablishFailedError, b as ClientUnsupportedAlgorithmError, E as ErrorCode, F as ForwardMPCError, c as ForwardMPCErrorType, d as ForwardMpcErrorClassification, e as ForwardMpcErrorType, S as SessionAttestationError, f as SessionDisposedError, g as SessionError, h as SessionHandshakeError, i as SessionHandshakeInvalidResponseError, j as SessionMessageParseError, k as SessionRemoteError, l as SessionRequestTimeoutError, m as SessionServerError, T as TransportConnectionError, n as TransportConnectionTimeoutError, o as TransportError, p as TransportNotConnectedError, q as classifyForwardMpcError, r as isAttestationError, s as isForwardMpcError } from './utils-pzTJsc5g.cjs';
6
+ export { A as AttestationErrorCode, C as ClientError, a as ClientSessionEstablishFailedError, b as ClientUnsupportedAlgorithmError, E as ErrorCode, F as ForwardMPCError, c as ForwardMPCErrorType, d as ForwardMpcErrorClassification, e as ForwardMpcErrorType, S as SessionAttestationError, f as SessionDisposedError, g as SessionError, h as SessionHandshakeError, i as SessionHandshakeInvalidResponseError, j as SessionMessageParseError, k as SessionRemoteError, l as SessionRequestTimeoutError, m as SessionServerError, T as TransportConnectionError, n as TransportConnectionTimeoutError, o as TransportError, p as TransportNotConnectedError, q as classifyForwardMpcError, r as isAttestationError, s as isForwardMpcError } from './utils-D77Qzra4.cjs';
7
7
 
8
8
  /**
9
9
  * Result of attestation document verification
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { BaseWebSocketMessage, TraceContext, HashAlgorithm, encryptKeyshare } fr
3
3
  export { BaseWebSocketMessage, ErrorResponse, HandshakeV1RequestMessage, HandshakeV1ResponseMessage, SignMessageV1RequestMessage, SignMessageV1ResponseMessage, WebSocketError, WebSocketErrorType } from '@dynamic-labs-wallet/forward-mpc-shared';
4
4
  import { SigningAlgorithm } from '@dynamic-labs-wallet/primitives';
5
5
  export { SigningAlgorithm } from '@dynamic-labs-wallet/primitives';
6
- export { A as AttestationErrorCode, C as ClientError, a as ClientSessionEstablishFailedError, b as ClientUnsupportedAlgorithmError, E as ErrorCode, F as ForwardMPCError, c as ForwardMPCErrorType, d as ForwardMpcErrorClassification, e as ForwardMpcErrorType, S as SessionAttestationError, f as SessionDisposedError, g as SessionError, h as SessionHandshakeError, i as SessionHandshakeInvalidResponseError, j as SessionMessageParseError, k as SessionRemoteError, l as SessionRequestTimeoutError, m as SessionServerError, T as TransportConnectionError, n as TransportConnectionTimeoutError, o as TransportError, p as TransportNotConnectedError, q as classifyForwardMpcError, r as isAttestationError, s as isForwardMpcError } from './utils-pzTJsc5g.js';
6
+ export { A as AttestationErrorCode, C as ClientError, a as ClientSessionEstablishFailedError, b as ClientUnsupportedAlgorithmError, E as ErrorCode, F as ForwardMPCError, c as ForwardMPCErrorType, d as ForwardMpcErrorClassification, e as ForwardMpcErrorType, S as SessionAttestationError, f as SessionDisposedError, g as SessionError, h as SessionHandshakeError, i as SessionHandshakeInvalidResponseError, j as SessionMessageParseError, k as SessionRemoteError, l as SessionRequestTimeoutError, m as SessionServerError, T as TransportConnectionError, n as TransportConnectionTimeoutError, o as TransportError, p as TransportNotConnectedError, q as classifyForwardMpcError, r as isAttestationError, s as isForwardMpcError } from './utils-D77Qzra4.js';
7
7
 
8
8
  /**
9
9
  * Result of attestation document verification
package/dist/index.js CHANGED
@@ -16,6 +16,96 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
16
16
  var ATTESTATION_CONSTANTS = {
17
17
  // Maximum age of attestation document in milliseconds
18
18
  MAX_ATTESTATION_AGE: 5 * 60 * 1e3};
19
+
20
+ // src/attestation/attestationDocReader.ts
21
+ var PCRS_LABEL_AND_MAP_HEADER = new Uint8Array([
22
+ 100,
23
+ 112,
24
+ 99,
25
+ 114,
26
+ 115,
27
+ 176
28
+ ]);
29
+ var BSTR_48_PREFIX = new Uint8Array([
30
+ 88,
31
+ 48
32
+ ]);
33
+ var PCR_VALUE_BYTES = 48;
34
+ var PCR_ENTRIES = 16;
35
+ var TRACKED_PCRS = /* @__PURE__ */ new Set([
36
+ 0,
37
+ 1,
38
+ 2,
39
+ 8
40
+ ]);
41
+ function decodeBase64ToBytes(base64) {
42
+ if (typeof atob !== "undefined") {
43
+ const binary = atob(base64);
44
+ const out = new Uint8Array(binary.length);
45
+ for (let i = 0; i < binary.length; i++) {
46
+ out[i] = binary.codePointAt(i) ?? 0;
47
+ }
48
+ return out;
49
+ }
50
+ return new Uint8Array(Buffer.from(base64, "base64"));
51
+ }
52
+ __name(decodeBase64ToBytes, "decodeBase64ToBytes");
53
+ function bytesToHex(bytes) {
54
+ let out = "";
55
+ for (const b of bytes) {
56
+ out += b.toString(16).padStart(2, "0");
57
+ }
58
+ return out;
59
+ }
60
+ __name(bytesToHex, "bytesToHex");
61
+ function findMarker(haystack, needle) {
62
+ outer: for (let i = 0; i <= haystack.length - needle.length; i++) {
63
+ for (let j = 0; j < needle.length; j++) {
64
+ if (haystack[i + j] !== needle[j]) continue outer;
65
+ }
66
+ return i;
67
+ }
68
+ return -1;
69
+ }
70
+ __name(findMarker, "findMarker");
71
+ function extractPcrsFromAttestationDoc(attestationDocBase64) {
72
+ const pcrs = {};
73
+ if (!attestationDocBase64) return pcrs;
74
+ try {
75
+ const bytes = decodeBase64ToBytes(attestationDocBase64);
76
+ const markerIdx = findMarker(bytes, PCRS_LABEL_AND_MAP_HEADER);
77
+ if (markerIdx < 0) return pcrs;
78
+ let pos = markerIdx + PCRS_LABEL_AND_MAP_HEADER.length;
79
+ for (let i = 0; i < PCR_ENTRIES; i++) {
80
+ if (pos + 1 + BSTR_48_PREFIX.length + PCR_VALUE_BYTES > bytes.length) {
81
+ break;
82
+ }
83
+ const key = bytes[pos++];
84
+ if (bytes[pos] !== BSTR_48_PREFIX[0] || bytes[pos + 1] !== BSTR_48_PREFIX[1]) {
85
+ break;
86
+ }
87
+ pos += BSTR_48_PREFIX.length;
88
+ const value = bytes.subarray(pos, pos + PCR_VALUE_BYTES);
89
+ pos += PCR_VALUE_BYTES;
90
+ if (TRACKED_PCRS.has(key)) {
91
+ pcrs[key] = bytesToHex(value);
92
+ }
93
+ }
94
+ } catch {
95
+ }
96
+ return pcrs;
97
+ }
98
+ __name(extractPcrsFromAttestationDoc, "extractPcrsFromAttestationDoc");
99
+ function formatPcrMismatchDetail(expectedPcr8, receivedPcrs) {
100
+ const receivedParts = [];
101
+ if (receivedPcrs[8] !== void 0) receivedParts.push(`pcr8=${receivedPcrs[8]}`);
102
+ if (receivedPcrs[0] !== void 0) receivedParts.push(`pcr0=${receivedPcrs[0]}`);
103
+ if (receivedPcrs[1] !== void 0) receivedParts.push(`pcr1=${receivedPcrs[1]}`);
104
+ if (receivedPcrs[2] !== void 0) receivedParts.push(`pcr2=${receivedPcrs[2]}`);
105
+ const received = receivedParts.length > 0 ? receivedParts.join(", ") : "unavailable";
106
+ return `expected pcr8=${expectedPcr8}; received ${received}`;
107
+ }
108
+ __name(formatPcrMismatchDetail, "formatPcrMismatchDetail");
19
109
  var NitroAttestationVerifier = class {
20
110
  static {
21
111
  __name(this, "NitroAttestationVerifier");
@@ -85,10 +175,12 @@ var NitroAttestationVerifier = class {
85
175
  expectedPcrs
86
176
  ]);
87
177
  if (!isValid) {
178
+ const receivedPcrs = extractPcrsFromAttestationDoc(attestationDocBase64);
179
+ const detail = formatPcrMismatchDetail(this.config.expectedPcr8, receivedPcrs);
88
180
  return {
89
181
  valid: false,
90
182
  errors: [
91
- "Attestation document PCR verification failed"
183
+ `Attestation document PCR verification failed (${detail})`
92
184
  ],
93
185
  timestamp: Date.now()
94
186
  };
@@ -799,6 +891,21 @@ var ClientSessionEstablishFailedError = class extends ClientError {
799
891
  super("Failed to establish session", ErrorCode.SESSION_ESTABLISH_FAILED, context);
800
892
  }
801
893
  };
894
+ var FORWARD_MPC_ERROR_NAMES = /* @__PURE__ */ new Set([
895
+ "TransportConnectionError",
896
+ "TransportConnectionTimeoutError",
897
+ "TransportNotConnectedError",
898
+ "SessionHandshakeError",
899
+ "SessionHandshakeInvalidResponseError",
900
+ "SessionAttestationError",
901
+ "SessionRequestTimeoutError",
902
+ "SessionDisposedError",
903
+ "SessionServerError",
904
+ "SessionMessageParseError",
905
+ "SessionRemoteError",
906
+ "ClientUnsupportedAlgorithmError",
907
+ "ClientSessionEstablishFailedError"
908
+ ]);
802
909
 
803
910
  // src/client-v2/transport.ts
804
911
  var ForwardMPCTransport = class extends EventEmitter2 {
@@ -1426,8 +1533,22 @@ var ForwardMPCClientSingleton = class extends ForwardMPCClientV2 {
1426
1533
  };
1427
1534
 
1428
1535
  // src/client-v2/error-classification.ts
1536
+ function matchesForwardMpcErrorClass(error, ctor, name) {
1537
+ if (error instanceof ctor) {
1538
+ return true;
1539
+ }
1540
+ return error instanceof Error && error.name === name && typeof error.code === "string";
1541
+ }
1542
+ __name(matchesForwardMpcErrorClass, "matchesForwardMpcErrorClass");
1543
+ function matchesAnyForwardMpcError(error) {
1544
+ if (error instanceof ForwardMPCError) {
1545
+ return true;
1546
+ }
1547
+ return error instanceof Error && FORWARD_MPC_ERROR_NAMES.has(error.name) && typeof error.code === "string";
1548
+ }
1549
+ __name(matchesAnyForwardMpcError, "matchesAnyForwardMpcError");
1429
1550
  function classifyForwardMpcError(error) {
1430
- if (error instanceof SessionAttestationError) {
1551
+ if (matchesForwardMpcErrorClass(error, SessionAttestationError, "SessionAttestationError")) {
1431
1552
  return {
1432
1553
  errorType: "ATTESTATION_FAILURE",
1433
1554
  errorCode: error.code,
@@ -1437,22 +1558,22 @@ function classifyForwardMpcError(error) {
1437
1558
  shouldFallback: true
1438
1559
  };
1439
1560
  }
1440
- if (error instanceof SessionRequestTimeoutError) {
1561
+ if (matchesForwardMpcErrorClass(error, SessionRequestTimeoutError, "SessionRequestTimeoutError")) {
1441
1562
  return {
1442
1563
  errorType: "FORWARD_MPC_TIMEOUT",
1443
1564
  errorCode: error.code,
1444
1565
  errorMessage: error.message,
1445
1566
  sessionEstablished: true,
1446
- shouldFallback: false
1567
+ shouldFallback: true
1447
1568
  };
1448
1569
  }
1449
- if (error instanceof ForwardMPCError) {
1570
+ if (matchesAnyForwardMpcError(error)) {
1450
1571
  return {
1451
1572
  errorType: "FORWARD_MPC_ERROR",
1452
1573
  errorCode: error.code,
1453
1574
  errorMessage: error.message,
1454
1575
  sessionEstablished: true,
1455
- shouldFallback: false
1576
+ shouldFallback: true
1456
1577
  };
1457
1578
  }
1458
1579
  return {
@@ -1460,16 +1581,16 @@ function classifyForwardMpcError(error) {
1460
1581
  errorCode: void 0,
1461
1582
  errorMessage: error instanceof Error ? error.message : String(error),
1462
1583
  sessionEstablished: false,
1463
- shouldFallback: false
1584
+ shouldFallback: true
1464
1585
  };
1465
1586
  }
1466
1587
  __name(classifyForwardMpcError, "classifyForwardMpcError");
1467
1588
  function isForwardMpcError(error) {
1468
- return error instanceof ForwardMPCError;
1589
+ return matchesAnyForwardMpcError(error);
1469
1590
  }
1470
1591
  __name(isForwardMpcError, "isForwardMpcError");
1471
1592
  function isAttestationError(error) {
1472
- return error instanceof SessionAttestationError;
1593
+ return matchesForwardMpcErrorClass(error, SessionAttestationError, "SessionAttestationError");
1473
1594
  }
1474
1595
  __name(isAttestationError, "isAttestationError");
1475
1596