@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.cjs CHANGED
@@ -42,6 +42,96 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
42
42
  var ATTESTATION_CONSTANTS = {
43
43
  // Maximum age of attestation document in milliseconds
44
44
  MAX_ATTESTATION_AGE: 5 * 60 * 1e3};
45
+
46
+ // src/attestation/attestationDocReader.ts
47
+ var PCRS_LABEL_AND_MAP_HEADER = new Uint8Array([
48
+ 100,
49
+ 112,
50
+ 99,
51
+ 114,
52
+ 115,
53
+ 176
54
+ ]);
55
+ var BSTR_48_PREFIX = new Uint8Array([
56
+ 88,
57
+ 48
58
+ ]);
59
+ var PCR_VALUE_BYTES = 48;
60
+ var PCR_ENTRIES = 16;
61
+ var TRACKED_PCRS = /* @__PURE__ */ new Set([
62
+ 0,
63
+ 1,
64
+ 2,
65
+ 8
66
+ ]);
67
+ function decodeBase64ToBytes(base64) {
68
+ if (typeof atob !== "undefined") {
69
+ const binary = atob(base64);
70
+ const out = new Uint8Array(binary.length);
71
+ for (let i = 0; i < binary.length; i++) {
72
+ out[i] = binary.codePointAt(i) ?? 0;
73
+ }
74
+ return out;
75
+ }
76
+ return new Uint8Array(Buffer.from(base64, "base64"));
77
+ }
78
+ __name(decodeBase64ToBytes, "decodeBase64ToBytes");
79
+ function bytesToHex(bytes) {
80
+ let out = "";
81
+ for (const b of bytes) {
82
+ out += b.toString(16).padStart(2, "0");
83
+ }
84
+ return out;
85
+ }
86
+ __name(bytesToHex, "bytesToHex");
87
+ function findMarker(haystack, needle) {
88
+ outer: for (let i = 0; i <= haystack.length - needle.length; i++) {
89
+ for (let j = 0; j < needle.length; j++) {
90
+ if (haystack[i + j] !== needle[j]) continue outer;
91
+ }
92
+ return i;
93
+ }
94
+ return -1;
95
+ }
96
+ __name(findMarker, "findMarker");
97
+ function extractPcrsFromAttestationDoc(attestationDocBase64) {
98
+ const pcrs = {};
99
+ if (!attestationDocBase64) return pcrs;
100
+ try {
101
+ const bytes = decodeBase64ToBytes(attestationDocBase64);
102
+ const markerIdx = findMarker(bytes, PCRS_LABEL_AND_MAP_HEADER);
103
+ if (markerIdx < 0) return pcrs;
104
+ let pos = markerIdx + PCRS_LABEL_AND_MAP_HEADER.length;
105
+ for (let i = 0; i < PCR_ENTRIES; i++) {
106
+ if (pos + 1 + BSTR_48_PREFIX.length + PCR_VALUE_BYTES > bytes.length) {
107
+ break;
108
+ }
109
+ const key = bytes[pos++];
110
+ if (bytes[pos] !== BSTR_48_PREFIX[0] || bytes[pos + 1] !== BSTR_48_PREFIX[1]) {
111
+ break;
112
+ }
113
+ pos += BSTR_48_PREFIX.length;
114
+ const value = bytes.subarray(pos, pos + PCR_VALUE_BYTES);
115
+ pos += PCR_VALUE_BYTES;
116
+ if (TRACKED_PCRS.has(key)) {
117
+ pcrs[key] = bytesToHex(value);
118
+ }
119
+ }
120
+ } catch {
121
+ }
122
+ return pcrs;
123
+ }
124
+ __name(extractPcrsFromAttestationDoc, "extractPcrsFromAttestationDoc");
125
+ function formatPcrMismatchDetail(expectedPcr8, receivedPcrs) {
126
+ const receivedParts = [];
127
+ if (receivedPcrs[8] !== void 0) receivedParts.push(`pcr8=${receivedPcrs[8]}`);
128
+ if (receivedPcrs[0] !== void 0) receivedParts.push(`pcr0=${receivedPcrs[0]}`);
129
+ if (receivedPcrs[1] !== void 0) receivedParts.push(`pcr1=${receivedPcrs[1]}`);
130
+ if (receivedPcrs[2] !== void 0) receivedParts.push(`pcr2=${receivedPcrs[2]}`);
131
+ const received = receivedParts.length > 0 ? receivedParts.join(", ") : "unavailable";
132
+ return `expected pcr8=${expectedPcr8}; received ${received}`;
133
+ }
134
+ __name(formatPcrMismatchDetail, "formatPcrMismatchDetail");
45
135
  var NitroAttestationVerifier = class {
46
136
  static {
47
137
  __name(this, "NitroAttestationVerifier");
@@ -111,10 +201,12 @@ var NitroAttestationVerifier = class {
111
201
  expectedPcrs
112
202
  ]);
113
203
  if (!isValid) {
204
+ const receivedPcrs = extractPcrsFromAttestationDoc(attestationDocBase64);
205
+ const detail = formatPcrMismatchDetail(this.config.expectedPcr8, receivedPcrs);
114
206
  return {
115
207
  valid: false,
116
208
  errors: [
117
- "Attestation document PCR verification failed"
209
+ `Attestation document PCR verification failed (${detail})`
118
210
  ],
119
211
  timestamp: Date.now()
120
212
  };
@@ -825,6 +917,21 @@ var ClientSessionEstablishFailedError = class extends ClientError {
825
917
  super("Failed to establish session", ErrorCode.SESSION_ESTABLISH_FAILED, context);
826
918
  }
827
919
  };
920
+ var FORWARD_MPC_ERROR_NAMES = /* @__PURE__ */ new Set([
921
+ "TransportConnectionError",
922
+ "TransportConnectionTimeoutError",
923
+ "TransportNotConnectedError",
924
+ "SessionHandshakeError",
925
+ "SessionHandshakeInvalidResponseError",
926
+ "SessionAttestationError",
927
+ "SessionRequestTimeoutError",
928
+ "SessionDisposedError",
929
+ "SessionServerError",
930
+ "SessionMessageParseError",
931
+ "SessionRemoteError",
932
+ "ClientUnsupportedAlgorithmError",
933
+ "ClientSessionEstablishFailedError"
934
+ ]);
828
935
 
829
936
  // src/client-v2/transport.ts
830
937
  var ForwardMPCTransport = class extends EventEmitter2__default.default {
@@ -1452,8 +1559,22 @@ var ForwardMPCClientSingleton = class extends ForwardMPCClientV2 {
1452
1559
  };
1453
1560
 
1454
1561
  // src/client-v2/error-classification.ts
1562
+ function matchesForwardMpcErrorClass(error, ctor, name) {
1563
+ if (error instanceof ctor) {
1564
+ return true;
1565
+ }
1566
+ return error instanceof Error && error.name === name && typeof error.code === "string";
1567
+ }
1568
+ __name(matchesForwardMpcErrorClass, "matchesForwardMpcErrorClass");
1569
+ function matchesAnyForwardMpcError(error) {
1570
+ if (error instanceof ForwardMPCError) {
1571
+ return true;
1572
+ }
1573
+ return error instanceof Error && FORWARD_MPC_ERROR_NAMES.has(error.name) && typeof error.code === "string";
1574
+ }
1575
+ __name(matchesAnyForwardMpcError, "matchesAnyForwardMpcError");
1455
1576
  function classifyForwardMpcError(error) {
1456
- if (error instanceof SessionAttestationError) {
1577
+ if (matchesForwardMpcErrorClass(error, SessionAttestationError, "SessionAttestationError")) {
1457
1578
  return {
1458
1579
  errorType: "ATTESTATION_FAILURE",
1459
1580
  errorCode: error.code,
@@ -1463,22 +1584,22 @@ function classifyForwardMpcError(error) {
1463
1584
  shouldFallback: true
1464
1585
  };
1465
1586
  }
1466
- if (error instanceof SessionRequestTimeoutError) {
1587
+ if (matchesForwardMpcErrorClass(error, SessionRequestTimeoutError, "SessionRequestTimeoutError")) {
1467
1588
  return {
1468
1589
  errorType: "FORWARD_MPC_TIMEOUT",
1469
1590
  errorCode: error.code,
1470
1591
  errorMessage: error.message,
1471
1592
  sessionEstablished: true,
1472
- shouldFallback: false
1593
+ shouldFallback: true
1473
1594
  };
1474
1595
  }
1475
- if (error instanceof ForwardMPCError) {
1596
+ if (matchesAnyForwardMpcError(error)) {
1476
1597
  return {
1477
1598
  errorType: "FORWARD_MPC_ERROR",
1478
1599
  errorCode: error.code,
1479
1600
  errorMessage: error.message,
1480
1601
  sessionEstablished: true,
1481
- shouldFallback: false
1602
+ shouldFallback: true
1482
1603
  };
1483
1604
  }
1484
1605
  return {
@@ -1486,16 +1607,16 @@ function classifyForwardMpcError(error) {
1486
1607
  errorCode: void 0,
1487
1608
  errorMessage: error instanceof Error ? error.message : String(error),
1488
1609
  sessionEstablished: false,
1489
- shouldFallback: false
1610
+ shouldFallback: true
1490
1611
  };
1491
1612
  }
1492
1613
  __name(classifyForwardMpcError, "classifyForwardMpcError");
1493
1614
  function isForwardMpcError(error) {
1494
- return error instanceof ForwardMPCError;
1615
+ return matchesAnyForwardMpcError(error);
1495
1616
  }
1496
1617
  __name(isForwardMpcError, "isForwardMpcError");
1497
1618
  function isAttestationError(error) {
1498
- return error instanceof SessionAttestationError;
1619
+ return matchesForwardMpcErrorClass(error, SessionAttestationError, "SessionAttestationError");
1499
1620
  }
1500
1621
  __name(isAttestationError, "isAttestationError");
1501
1622