@metamask/connect-multichain 0.12.1 → 0.14.0

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/dist/browser/es/connect-multichain.d.mts +46 -2
  3. package/dist/browser/es/connect-multichain.mjs +1733 -1566
  4. package/dist/browser/es/connect-multichain.mjs.map +1 -1
  5. package/dist/browser/es/metafile-esm.json +1 -1
  6. package/dist/browser/iife/connect-multichain.d.ts +46 -2
  7. package/dist/browser/iife/connect-multichain.js +6279 -5413
  8. package/dist/browser/iife/connect-multichain.js.map +1 -1
  9. package/dist/browser/iife/metafile-iife.json +1 -1
  10. package/dist/browser/umd/connect-multichain.d.ts +46 -2
  11. package/dist/browser/umd/connect-multichain.js +1761 -1589
  12. package/dist/browser/umd/connect-multichain.js.map +1 -1
  13. package/dist/browser/umd/metafile-cjs.json +1 -1
  14. package/dist/node/cjs/connect-multichain.d.ts +46 -2
  15. package/dist/node/cjs/connect-multichain.js +892 -719
  16. package/dist/node/cjs/connect-multichain.js.map +1 -1
  17. package/dist/node/cjs/metafile-cjs.json +1 -1
  18. package/dist/node/es/connect-multichain.d.mts +46 -2
  19. package/dist/node/es/connect-multichain.mjs +890 -723
  20. package/dist/node/es/connect-multichain.mjs.map +1 -1
  21. package/dist/node/es/metafile-esm.json +1 -1
  22. package/dist/react-native/es/connect-multichain.d.mts +46 -2
  23. package/dist/react-native/es/connect-multichain.mjs +890 -723
  24. package/dist/react-native/es/connect-multichain.mjs.map +1 -1
  25. package/dist/react-native/es/metafile-esm.json +1 -1
  26. package/dist/src/domain/multichain/index.d.ts +1 -1
  27. package/dist/src/domain/multichain/index.d.ts.map +1 -1
  28. package/dist/src/domain/utils/index.d.ts +2 -1
  29. package/dist/src/domain/utils/index.d.ts.map +1 -1
  30. package/dist/src/domain/utils/index.js +1 -1
  31. package/dist/src/domain/utils/index.js.map +1 -1
  32. package/dist/src/multichain/index.d.ts +2 -2
  33. package/dist/src/multichain/index.d.ts.map +1 -1
  34. package/dist/src/multichain/index.js +39 -25
  35. package/dist/src/multichain/index.js.map +1 -1
  36. package/dist/src/multichain/rpc/requestRouter.d.ts.map +1 -1
  37. package/dist/src/multichain/rpc/requestRouter.js +4 -4
  38. package/dist/src/multichain/rpc/requestRouter.js.map +1 -1
  39. package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts +1 -0
  40. package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts.map +1 -1
  41. package/dist/src/multichain/transports/multichainApiClientWrapper/index.js +10 -10
  42. package/dist/src/multichain/transports/multichainApiClientWrapper/index.js.map +1 -1
  43. package/dist/src/multichain/transports/mwp/KeyManager.d.ts +12 -9
  44. package/dist/src/multichain/transports/mwp/KeyManager.d.ts.map +1 -1
  45. package/dist/src/multichain/transports/mwp/KeyManager.js +38 -25
  46. package/dist/src/multichain/transports/mwp/KeyManager.js.map +1 -1
  47. package/dist/src/multichain/transports/mwp/index.d.ts.map +1 -1
  48. package/dist/src/multichain/transports/mwp/index.js +18 -6
  49. package/dist/src/multichain/transports/mwp/index.js.map +1 -1
  50. package/dist/src/multichain/utils/analytics.d.ts +82 -1
  51. package/dist/src/multichain/utils/analytics.d.ts.map +1 -1
  52. package/dist/src/multichain/utils/analytics.js +252 -17
  53. package/dist/src/multichain/utils/analytics.js.map +1 -1
  54. package/dist/types/connect-multichain.d.ts +46 -2
  55. package/package.json +2 -2
@@ -700,17 +700,94 @@ var init_ui = __esm({
700
700
  });
701
701
 
702
702
  // src/multichain/utils/analytics.ts
703
+ function sanitiseErrorMessage(message) {
704
+ if (!message) {
705
+ return void 0;
706
+ }
707
+ let sanitised = message;
708
+ for (const { pattern, replacement } of SANITISE_PATTERNS) {
709
+ sanitised = sanitised.replace(pattern, replacement);
710
+ }
711
+ if (sanitised.length > ERROR_MESSAGE_SAMPLE_MAX_LENGTH) {
712
+ sanitised = `${sanitised.slice(0, ERROR_MESSAGE_SAMPLE_MAX_LENGTH - 1)}\u2026`;
713
+ }
714
+ return sanitised;
715
+ }
716
+ function getUnwrappedErrorDetails(error) {
717
+ var _a3, _b, _c, _d;
718
+ if (typeof error !== "object" || error === null) {
719
+ return { code: void 0, message: "" };
720
+ }
721
+ if (error instanceof RPCInvokeMethodErr) {
722
+ return {
723
+ code: (_a3 = error.rpcCode) != null ? _a3 : error.code,
724
+ message: (_c = (_b = error.rpcMessage) != null ? _b : error.message) != null ? _c : ""
725
+ };
726
+ }
727
+ const errorObj = error;
728
+ return {
729
+ code: errorObj.code,
730
+ message: (_d = errorObj.message) != null ? _d : ""
731
+ };
732
+ }
703
733
  function isRejectionError(error) {
704
- var _a3, _b;
705
734
  if (typeof error !== "object" || error === null) {
706
735
  return false;
707
736
  }
737
+ const { code, message } = getUnwrappedErrorDetails(error);
738
+ const errorMessage = message.toLowerCase();
739
+ return code === 4001 || errorMessage.includes("reject") || errorMessage.includes("denied") || errorMessage.includes("cancel") || // Narrow "user …" matches — bare "user" is too greedy (catches Account
740
+ // Abstraction errors like "user operation reverted").
741
+ errorMessage.includes("user rejected") || errorMessage.includes("user denied") || errorMessage.includes("user cancelled") || errorMessage.includes("user canceled");
742
+ }
743
+ function classifyFailureReason(error) {
744
+ var _a3, _b;
745
+ if (typeof error !== "object" || error === null) {
746
+ return "unknown";
747
+ }
708
748
  const errorObj = error;
709
- const errorCode = errorObj.code;
710
- const errorMessage = (_b = (_a3 = errorObj.message) == null ? void 0 : _a3.toLowerCase()) != null ? _b : "";
711
- return errorCode === 4001 || // User rejected request (common EIP-1193 code)
712
- errorCode === 4100 || // Unauthorized (common rejection code)
713
- errorMessage.includes("reject") || errorMessage.includes("denied") || errorMessage.includes("cancel") || errorMessage.includes("user");
749
+ const errorName = (_a3 = errorObj.name) != null ? _a3 : "";
750
+ const errorMessageRaw = (_b = errorObj.message) != null ? _b : "";
751
+ const errorMessage = errorMessageRaw.toLowerCase();
752
+ const { code } = getUnwrappedErrorDetails(error);
753
+ if (typeof code === "number") {
754
+ if (code === -32601) {
755
+ return "wallet_method_unsupported";
756
+ }
757
+ if (code === -32602) {
758
+ return "wallet_invalid_params";
759
+ }
760
+ if (code === -32603) {
761
+ return "wallet_internal_error";
762
+ }
763
+ if (code <= -32e3 && code >= -32099) {
764
+ return "wallet_internal_error";
765
+ }
766
+ if (code === 4100) {
767
+ return "wallet_unauthorized";
768
+ }
769
+ if (code === 4200) {
770
+ return "wallet_method_unsupported";
771
+ }
772
+ if (code === 4902) {
773
+ return "unrecognized_chain";
774
+ }
775
+ }
776
+ if (errorName === "TransportTimeoutError" || errorMessageRaw === "Request timeout" || errorMessage.includes("timed out") || errorMessage.includes("timeout")) {
777
+ return "transport_timeout";
778
+ }
779
+ if (errorName === "TransportError" || errorMessage.includes("not connected") || errorMessage.includes("transport disconnect") || errorMessage.includes("connection lost") || errorMessage.includes("socket closed")) {
780
+ return "transport_disconnect";
781
+ }
782
+ return "unknown";
783
+ }
784
+ function extractErrorDiagnostics(error) {
785
+ const failureReason = classifyFailureReason(error);
786
+ const { code, message } = getUnwrappedErrorDetails(error);
787
+ const messageSample = sanitiseErrorMessage(message);
788
+ return __spreadValues(__spreadValues({
789
+ failure_reason: failureReason
790
+ }, typeof code === "number" ? { error_code: code } : {}), messageSample ? { error_message_sample: messageSample } : {});
714
791
  }
715
792
  function getBaseAnalyticsProperties(options, storage) {
716
793
  return __async(this, null, function* () {
@@ -726,26 +803,61 @@ function getBaseAnalyticsProperties(options, storage) {
726
803
  };
727
804
  });
728
805
  }
729
- function getWalletActionAnalyticsProperties(options, storage, invokeOptions, transportType) {
806
+ function getWalletActionAnalyticsProperties(options, storage, invokeOptions, transportType, extra) {
730
807
  return __async(this, null, function* () {
731
808
  var _a3;
732
809
  const dappId = getDappId(options.dapp);
733
810
  const anonId = yield storage.getAnonId();
734
- return {
811
+ return __spreadValues(__spreadValues(__spreadValues({
735
812
  mmconnect_versions: (_a3 = options.versions) != null ? _a3 : {},
736
813
  dapp_id: dappId,
737
814
  method: invokeOptions.request.method,
738
815
  caip_chain_id: invokeOptions.scope,
739
816
  anon_id: anonId,
740
817
  transport_type: transportType
741
- };
818
+ }, (extra == null ? void 0 : extra.failure_reason) ? { failure_reason: extra.failure_reason } : {}), typeof (extra == null ? void 0 : extra.error_code) === "number" ? { error_code: extra.error_code } : {}), (extra == null ? void 0 : extra.error_message_sample) ? { error_message_sample: extra.error_message_sample } : {});
742
819
  });
743
820
  }
821
+ var ERROR_MESSAGE_SAMPLE_MAX_LENGTH, SANITISE_PATTERNS;
744
822
  var init_analytics = __esm({
745
823
  "src/multichain/utils/analytics.ts"() {
746
824
  "use strict";
747
825
  init_utils2();
748
826
  init_domain();
827
+ ERROR_MESSAGE_SAMPLE_MAX_LENGTH = 200;
828
+ SANITISE_PATTERNS = [
829
+ // EVM-style 20-byte hex addresses (e.g. `0x` + 40 hex chars).
830
+ { pattern: /0x[a-fA-F0-9]{40}/gu, replacement: "<addr>" },
831
+ // Other long hex blobs: tx hashes, signatures, raw byte strings, large
832
+ // hex amounts. 16+ hex chars catches 32-byte hashes/signatures without
833
+ // snagging EVM method selectors (8 chars) or short hex codes.
834
+ { pattern: /(?:0x)?[a-fA-F0-9]{16,}/gu, replacement: "<hex>" },
835
+ // URLs of any scheme up to the first whitespace / quote / closing paren.
836
+ // Catches RPC endpoints, dapp deeplinks, query strings with secrets.
837
+ { pattern: /https?:\/\/[^\s"')]+/gu, replacement: "<url>" },
838
+ // Bech32 addresses: short HRP (1-10 lowercase chars) + `1` separator +
839
+ // ≥38 chars of Bech32 data alphabet `[ac-hj-np-z02-9]` (excludes the
840
+ // look-alike chars `b`, `i`, `o`, `1`). Covers Bitcoin SegWit
841
+ // (`bc1…`/`tb1…`) and Cosmos-SDK chains (`cosmos1…`, `osmo1…`,
842
+ // `juno1…`, `inj1…`, etc.) without enumerating every HRP. Runs before
843
+ // the Base58 pattern below — see header comment for why.
844
+ {
845
+ pattern: /\b[a-z]{1,10}1[ac-hj-np-z02-9]{38,}\b/gu,
846
+ replacement: "<addr>"
847
+ },
848
+ // Base58 tokens (32+ chars, Base58 alphabet `[1-9A-HJ-NP-Za-km-z]`).
849
+ // Covers Solana pubkeys (32-44 chars), Solana tx signatures (~88 chars),
850
+ // and Bitcoin Base58 addresses ≥32 chars. The 32-char floor and `\b`
851
+ // word boundary keep English words and shorter alphanumerics safe.
852
+ {
853
+ pattern: /\b[1-9A-HJ-NP-Za-km-z]{32,}\b/gu,
854
+ replacement: "<addr>"
855
+ },
856
+ // Long decimal numbers — token amounts, gas units, timestamps, lamports.
857
+ // 10+ digits catches typical chain quantities without affecting JSON-RPC
858
+ // codes (-32601, 4001, etc.) or short numeric IDs.
859
+ { pattern: /\d{10,}/gu, replacement: "<num>" }
860
+ ];
749
861
  }
750
862
  });
751
863
 
@@ -1042,1745 +1154,1782 @@ var init_utils2 = __esm({
1042
1154
  }
1043
1155
  });
1044
1156
 
1045
- // src/ui/modals/base/utils.ts
1046
- function formatRemainingTime(milliseconds) {
1047
- if (milliseconds <= 0) {
1048
- return "EXPIRED";
1049
- }
1050
- const seconds = Math.floor(milliseconds / 1e3);
1051
- return `${seconds}s`;
1052
- }
1053
- function shouldLogCountdown(remainingSeconds) {
1054
- if (remainingSeconds <= 10) {
1055
- return true;
1056
- } else if (remainingSeconds <= 30) {
1057
- return remainingSeconds % 5 === 0;
1058
- } else if (remainingSeconds <= 60) {
1059
- return remainingSeconds % 10 === 0;
1060
- } else if (remainingSeconds <= 300) {
1061
- return remainingSeconds % 30 === 0;
1062
- }
1063
- return remainingSeconds % 60 === 0;
1064
- }
1065
- var init_utils3 = __esm({
1066
- "src/ui/modals/base/utils.ts"() {
1157
+ // src/multichain/transports/constants.ts
1158
+ var MULTICHAIN_PROVIDER_STREAM_NAME;
1159
+ var init_constants2 = __esm({
1160
+ "src/multichain/transports/constants.ts"() {
1067
1161
  "use strict";
1162
+ MULTICHAIN_PROVIDER_STREAM_NAME = "metamask-multichain-provider";
1068
1163
  }
1069
1164
  });
1070
1165
 
1071
- // src/ui/modals/base/AbstractInstallModal.ts
1072
- var logger3, _expirationInterval, _lastLoggedCountdown, AbstractInstallModal;
1073
- var init_AbstractInstallModal = __esm({
1074
- "src/ui/modals/base/AbstractInstallModal.ts"() {
1166
+ // src/multichain/transports/mwp/index.ts
1167
+ var mwp_exports = {};
1168
+ __export(mwp_exports, {
1169
+ MWPTransport: () => MWPTransport
1170
+ });
1171
+ var import_multichain_api_client2, import_rpc_errors2, DEFAULT_REQUEST_TIMEOUT2, CONNECTION_GRACE_PERIOD, DEFAULT_CONNECTION_TIMEOUT, DEFAULT_RESUME_TIMEOUT, SESSION_STORE_KEY, ACCOUNTS_STORE_KEY, CHAIN_STORE_KEY, PENDING_SESSION_REQUEST_KEY, CACHED_METHOD_LIST, CACHED_RESET_METHOD_LIST, logger, MWPTransport;
1172
+ var init_mwp = __esm({
1173
+ "src/multichain/transports/mwp/index.ts"() {
1075
1174
  "use strict";
1076
- init_utils3();
1175
+ import_multichain_api_client2 = require("@metamask/multichain-api-client");
1176
+ import_rpc_errors2 = require("@metamask/rpc-errors");
1077
1177
  init_domain();
1078
- logger3 = createLogger("metamask-sdk:ui");
1079
- AbstractInstallModal = class extends Modal {
1080
- constructor() {
1081
- super(...arguments);
1082
- __privateAdd(this, _expirationInterval, null);
1083
- __privateAdd(this, _lastLoggedCountdown, -1);
1178
+ init_utils2();
1179
+ init_constants2();
1180
+ DEFAULT_REQUEST_TIMEOUT2 = 60 * 1e3;
1181
+ CONNECTION_GRACE_PERIOD = 60 * 1e3;
1182
+ DEFAULT_CONNECTION_TIMEOUT = DEFAULT_REQUEST_TIMEOUT2 + CONNECTION_GRACE_PERIOD;
1183
+ DEFAULT_RESUME_TIMEOUT = 10 * 1e3;
1184
+ SESSION_STORE_KEY = "cache_wallet_getSession";
1185
+ ACCOUNTS_STORE_KEY = "cache_eth_accounts";
1186
+ CHAIN_STORE_KEY = "cache_eth_chainId";
1187
+ PENDING_SESSION_REQUEST_KEY = "pending_session_request";
1188
+ CACHED_METHOD_LIST = [
1189
+ "wallet_getSession",
1190
+ "wallet_createSession",
1191
+ "wallet_sessionChanged"
1192
+ ];
1193
+ CACHED_RESET_METHOD_LIST = [
1194
+ "wallet_revokeSession",
1195
+ "wallet_revokePermissions"
1196
+ ];
1197
+ logger = createLogger("metamask-sdk:transport");
1198
+ MWPTransport = class {
1199
+ constructor(dappClient, kvstore, options = {
1200
+ requestTimeout: DEFAULT_REQUEST_TIMEOUT2,
1201
+ connectionTimeout: DEFAULT_CONNECTION_TIMEOUT,
1202
+ resumeTimeout: DEFAULT_RESUME_TIMEOUT
1203
+ }) {
1204
+ this.dappClient = dappClient;
1205
+ this.kvstore = kvstore;
1206
+ this.options = options;
1207
+ this.__pendingRequests = /* @__PURE__ */ new Map();
1208
+ this.notificationCallbacks = /* @__PURE__ */ new Set();
1209
+ this.dappClient.on("message", this.handleMessage.bind(this));
1210
+ this.dappClient.on("session_request", (sessionRequest) => {
1211
+ this.currentSessionRequest = sessionRequest;
1212
+ this.kvstore.set(PENDING_SESSION_REQUEST_KEY, JSON.stringify(sessionRequest)).catch((err) => {
1213
+ logger("Failed to store pending session request", err);
1214
+ });
1215
+ });
1216
+ if (typeof window !== "undefined" && typeof window.addEventListener !== "undefined") {
1217
+ this.windowFocusHandler = this.onWindowFocus.bind(this);
1218
+ window.addEventListener("focus", this.windowFocusHandler);
1219
+ }
1084
1220
  }
1085
- get link() {
1086
- return this.data;
1221
+ get pendingRequests() {
1222
+ return this.__pendingRequests;
1087
1223
  }
1088
- set link(link) {
1089
- this.data = link;
1224
+ set pendingRequests(pendingRequests) {
1225
+ this.__pendingRequests = pendingRequests;
1090
1226
  }
1091
- get connectionRequest() {
1092
- return this.options.connectionRequest;
1227
+ get sessionRequest() {
1228
+ return this.currentSessionRequest;
1093
1229
  }
1094
- set connectionRequest(connectionRequest) {
1095
- this.options.connectionRequest = connectionRequest;
1230
+ /**
1231
+ * Returns the stored pending session request from the dappClient session_request event, if any.
1232
+ *
1233
+ * @returns The stored SessionRequest, or null if none or invalid.
1234
+ */
1235
+ getStoredPendingSessionRequest() {
1236
+ return __async(this, null, function* () {
1237
+ try {
1238
+ const raw = yield this.kvstore.get(PENDING_SESSION_REQUEST_KEY);
1239
+ if (!raw) {
1240
+ return null;
1241
+ }
1242
+ return JSON.parse(raw);
1243
+ } catch (e) {
1244
+ return null;
1245
+ }
1246
+ });
1096
1247
  }
1097
- updateLink(link) {
1098
- this.link = link;
1099
- if (this.instance) {
1100
- this.instance.link = link;
1248
+ /**
1249
+ * Removes the stored pending session request from the KVStore.
1250
+ * This is necessary to ensure that ConnectMultichain is able to correctly
1251
+ * infer the MWP Transport connection attempt status.
1252
+ */
1253
+ removeStoredPendingSessionRequest() {
1254
+ return __async(this, null, function* () {
1255
+ yield this.kvstore.delete(PENDING_SESSION_REQUEST_KEY);
1256
+ });
1257
+ }
1258
+ onWindowFocus() {
1259
+ if (!this.isConnected()) {
1260
+ this.dappClient.reconnect();
1101
1261
  }
1102
1262
  }
1103
- updateExpiresIn(expiresIn) {
1104
- if (expiresIn >= 0 && this.instance) {
1105
- this.instance.expiresIn = expiresIn;
1263
+ notifyCallbacks(data) {
1264
+ this.notificationCallbacks.forEach((callback) => callback(data));
1265
+ }
1266
+ rejectRequest(id, error = new Error("Request rejected")) {
1267
+ const request = this.pendingRequests.get(id);
1268
+ if (request) {
1269
+ this.pendingRequests.delete(id);
1270
+ clearTimeout(request.timeout);
1271
+ request.reject(error);
1106
1272
  }
1107
1273
  }
1108
- startExpirationCheck(connectionRequest) {
1109
- this.stopExpirationCheck();
1110
- let currentConnectionRequest = connectionRequest;
1111
- __privateSet(this, _expirationInterval, setInterval(() => __async(this, null, function* () {
1112
- const { sessionRequest } = currentConnectionRequest;
1113
- const now = Date.now();
1114
- const remainingMs = sessionRequest.expiresAt - now;
1115
- const remainingSeconds = Math.floor(remainingMs / 1e3);
1116
- if (remainingMs > 0 && shouldLogCountdown(remainingSeconds) && __privateGet(this, _lastLoggedCountdown) !== remainingSeconds) {
1117
- const formattedTime = formatRemainingTime(remainingMs);
1118
- logger3(
1119
- `[UI: InstallModal-nodejs()] QR code expires in: ${formattedTime} (${remainingSeconds}s)`
1120
- );
1121
- __privateSet(this, _lastLoggedCountdown, remainingSeconds);
1274
+ parseWalletError(errorPayload) {
1275
+ const errorData = errorPayload;
1276
+ if (typeof errorData.code === "number" && typeof errorData.message === "string") {
1277
+ const { code, message: message2 } = errorData;
1278
+ if (code >= 1e3 && code <= 4999) {
1279
+ return import_rpc_errors2.providerErrors.custom({ code, message: message2 });
1122
1280
  }
1123
- if (now >= sessionRequest.expiresAt) {
1124
- this.stopExpirationCheck();
1125
- logger3(
1126
- "[UI: InstallModal-nodejs()] \u23F0 QR code EXPIRED! Generating new one..."
1127
- );
1128
- try {
1129
- currentConnectionRequest = yield this.options.createConnectionRequest();
1130
- const generateQRCode = yield this.options.generateQRCode(
1131
- currentConnectionRequest
1281
+ return new import_rpc_errors2.JsonRpcError(code, message2);
1282
+ }
1283
+ const message = errorPayload instanceof Error ? errorPayload.message : JSON.stringify(errorPayload);
1284
+ return import_rpc_errors2.rpcErrors.internal({ message });
1285
+ }
1286
+ handleMessage(message) {
1287
+ if (typeof message === "object" && message !== null) {
1288
+ if ("data" in message) {
1289
+ const messagePayload = message.data;
1290
+ if ("id" in messagePayload && typeof messagePayload.id === "string") {
1291
+ const request = this.pendingRequests.get(messagePayload.id);
1292
+ if (request) {
1293
+ clearTimeout(request.timeout);
1294
+ if ("error" in messagePayload && messagePayload.error) {
1295
+ this.pendingRequests.delete(messagePayload.id);
1296
+ request.reject(this.parseWalletError(messagePayload.error));
1297
+ return;
1298
+ }
1299
+ const requestWithName = __spreadProps(__spreadValues({}, messagePayload), {
1300
+ method: request.method === "wallet_getSession" || request.method === "wallet_createSession" ? "wallet_sessionChanged" : request.method
1301
+ });
1302
+ const notification = __spreadProps(__spreadValues({}, messagePayload), {
1303
+ method: request.method === "wallet_getSession" || request.method === "wallet_createSession" ? "wallet_sessionChanged" : request.method,
1304
+ params: requestWithName.result
1305
+ });
1306
+ this.notifyCallbacks(notification);
1307
+ request.resolve(requestWithName);
1308
+ this.pendingRequests.delete(messagePayload.id);
1309
+ }
1310
+ } else {
1311
+ if (message.data.method === "metamask_chainChanged") {
1312
+ this.kvstore.set(
1313
+ CHAIN_STORE_KEY,
1314
+ JSON.stringify(
1315
+ message.data.params.chainId
1316
+ )
1317
+ );
1318
+ }
1319
+ if (message.data.method === "metamask_accountsChanged") {
1320
+ this.kvstore.set(
1321
+ ACCOUNTS_STORE_KEY,
1322
+ JSON.stringify(
1323
+ message.data.params
1324
+ )
1325
+ );
1326
+ }
1327
+ if (message.data.method === "wallet_sessionChanged") {
1328
+ const notification = message.data;
1329
+ const response = {
1330
+ result: notification.params
1331
+ };
1332
+ this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));
1333
+ }
1334
+ this.notifyCallbacks(message.data);
1335
+ }
1336
+ }
1337
+ }
1338
+ }
1339
+ onResumeSuccess(resumeResolve, resumeReject, options) {
1340
+ return __async(this, null, function* () {
1341
+ var _a3, _b, _c, _d, _e, _f, _g;
1342
+ try {
1343
+ yield this.waitForWalletSessionIfNotCached();
1344
+ const sessionRequest = yield this.request({
1345
+ method: "wallet_getSession"
1346
+ });
1347
+ if (sessionRequest.error) {
1348
+ return resumeReject(new Error(sessionRequest.error.message));
1349
+ }
1350
+ let walletSession = sessionRequest.result;
1351
+ if (walletSession && options) {
1352
+ const currentScopes = Object.keys(
1353
+ (_a3 = walletSession == null ? void 0 : walletSession.sessionScopes) != null ? _a3 : {}
1132
1354
  );
1133
- __privateSet(this, _lastLoggedCountdown, -1);
1134
- this.updateLink(generateQRCode);
1135
- this.updateExpiresIn(remainingSeconds);
1136
- this.renderQRCode(generateQRCode, currentConnectionRequest);
1137
- } catch (error) {
1138
- logger3(
1139
- `[UI: InstallModal-nodejs()] \u274C Error generating new QR code: ${error}`
1355
+ const proposedScopes = (_b = options == null ? void 0 : options.scopes) != null ? _b : [];
1356
+ const proposedCaipAccountIds = (_c = options == null ? void 0 : options.caipAccountIds) != null ? _c : [];
1357
+ const hasSameScopesAndAccounts = isSameScopesAndAccounts(
1358
+ currentScopes,
1359
+ proposedScopes,
1360
+ walletSession,
1361
+ proposedCaipAccountIds
1140
1362
  );
1363
+ if (options.forceRequest || !hasSameScopesAndAccounts) {
1364
+ const optionalScopes = addValidAccounts(
1365
+ getOptionalScopes((_d = options == null ? void 0 : options.scopes) != null ? _d : []),
1366
+ getValidAccounts((_e = options == null ? void 0 : options.caipAccountIds) != null ? _e : [])
1367
+ );
1368
+ const sessionRequest2 = {
1369
+ optionalScopes
1370
+ };
1371
+ const response = yield this.request({
1372
+ method: "wallet_createSession",
1373
+ params: sessionRequest2
1374
+ });
1375
+ if (response.error) {
1376
+ return resumeReject(new Error(response.error.message));
1377
+ }
1378
+ walletSession = response.result;
1379
+ }
1380
+ } else if (!walletSession) {
1381
+ const optionalScopes = addValidAccounts(
1382
+ getOptionalScopes((_f = options == null ? void 0 : options.scopes) != null ? _f : []),
1383
+ getValidAccounts((_g = options == null ? void 0 : options.caipAccountIds) != null ? _g : [])
1384
+ );
1385
+ const sessionRequest2 = { optionalScopes };
1386
+ const response = yield this.request({
1387
+ method: "wallet_createSession",
1388
+ params: sessionRequest2
1389
+ });
1390
+ if (response.error) {
1391
+ return resumeReject(new Error(response.error.message));
1392
+ }
1393
+ walletSession = response.result;
1141
1394
  }
1395
+ yield this.removeStoredPendingSessionRequest();
1396
+ this.notifyCallbacks({
1397
+ method: "wallet_sessionChanged",
1398
+ params: walletSession
1399
+ });
1400
+ return resumeResolve();
1401
+ } catch (err) {
1402
+ return resumeReject(err);
1142
1403
  }
1143
- }), 1e3));
1144
- }
1145
- stopExpirationCheck() {
1146
- if (__privateGet(this, _expirationInterval)) {
1147
- clearInterval(__privateGet(this, _expirationInterval));
1148
- __privateSet(this, _expirationInterval, null);
1149
- logger3(
1150
- "[UI: InstallModal-nodejs()] \u{1F6D1} Stopped QR code expiration checking"
1151
- );
1152
- }
1404
+ });
1153
1405
  }
1154
- };
1155
- _expirationInterval = new WeakMap();
1156
- _lastLoggedCountdown = new WeakMap();
1157
- }
1158
- });
1159
-
1160
- // src/ui/modals/web/install.ts
1161
- var InstallModal;
1162
- var init_install = __esm({
1163
- "src/ui/modals/web/install.ts"() {
1164
- "use strict";
1165
- init_AbstractInstallModal();
1166
- InstallModal = class extends AbstractInstallModal {
1167
- renderQRCode() {
1406
+ init() {
1407
+ return __async(this, null, function* () {
1408
+ });
1168
1409
  }
1169
- mount() {
1170
- var _a3;
1171
- const { options } = this;
1172
- const modal = document.createElement(
1173
- "mm-install-modal"
1174
- );
1175
- modal.showInstallModal = options.showInstallModal;
1176
- modal.addEventListener("close", (ev) => {
1177
- const { detail } = ev;
1178
- options.onClose(detail == null ? void 0 : detail.shouldTerminate);
1410
+ // TODO: Rename this
1411
+ sendEip1193Message(payload, options) {
1412
+ return __async(this, null, function* () {
1413
+ const request = __spreadValues({
1414
+ jsonrpc: "2.0",
1415
+ id: String(getUniqueRequestId())
1416
+ }, payload);
1417
+ const cachedWalletSession = yield this.getCachedResponse(request);
1418
+ if (cachedWalletSession) {
1419
+ this.notifyCallbacks(cachedWalletSession);
1420
+ return cachedWalletSession;
1421
+ }
1422
+ return new Promise((resolve, reject) => {
1423
+ var _a3;
1424
+ const timeout = setTimeout(() => {
1425
+ this.rejectRequest(request.id, new import_multichain_api_client2.TransportTimeoutError());
1426
+ }, (_a3 = options == null ? void 0 : options.timeout) != null ? _a3 : this.options.requestTimeout);
1427
+ this.pendingRequests.set(request.id, {
1428
+ request,
1429
+ method: request.method,
1430
+ resolve: (response) => __async(this, null, function* () {
1431
+ yield this.storeWalletSession(request, response);
1432
+ return resolve(response);
1433
+ }),
1434
+ reject,
1435
+ timeout
1436
+ });
1437
+ this.dappClient.sendRequest({
1438
+ name: "metamask-provider",
1439
+ data: request
1440
+ }).catch(reject);
1441
+ });
1179
1442
  });
1180
- modal.addEventListener(
1181
- "startDesktopOnboarding",
1182
- options.startDesktopOnboarding
1183
- );
1184
- modal.link = options.link;
1185
- this.instance = modal;
1186
- (_a3 = options.parentElement) == null ? void 0 : _a3.appendChild(modal);
1187
- this.startExpirationCheck(options.connectionRequest);
1188
1443
  }
1189
- unmount() {
1190
- var _a3;
1191
- const { options, instance: modal } = this;
1192
- this.stopExpirationCheck();
1193
- if (modal && ((_a3 = options.parentElement) == null ? void 0 : _a3.contains(modal))) {
1194
- options.parentElement.removeChild(modal);
1195
- this.instance = void 0;
1196
- }
1444
+ connect(options) {
1445
+ return __async(this, null, function* () {
1446
+ const { dappClient } = this;
1447
+ const session = yield this.getActiveSession();
1448
+ if (session) {
1449
+ logger("active session found", {
1450
+ id: session.id,
1451
+ channel: session.channel,
1452
+ expiresAt: session.expiresAt
1453
+ });
1454
+ }
1455
+ const storedSessionRequestBeforeConnectionAttempt = yield this.getStoredPendingSessionRequest();
1456
+ let timeout;
1457
+ let initialConnectionMessageHandler;
1458
+ const connectionPromise = new Promise((resolve, reject) => __async(this, null, function* () {
1459
+ let connection;
1460
+ if (session) {
1461
+ connection = new Promise((resumeResolve, resumeReject) => {
1462
+ var _a3;
1463
+ if (this.dappClient.state === "CONNECTED") {
1464
+ this.onResumeSuccess(resumeResolve, resumeReject, options);
1465
+ } else {
1466
+ this.dappClient.once("connected", () => __async(this, null, function* () {
1467
+ this.onResumeSuccess(resumeResolve, resumeReject, options);
1468
+ }));
1469
+ dappClient.resume((_a3 = session == null ? void 0 : session.id) != null ? _a3 : "");
1470
+ }
1471
+ });
1472
+ } else {
1473
+ connection = new Promise(
1474
+ (resolveConnection, rejectConnection) => {
1475
+ var _a3, _b;
1476
+ const optionalScopes = addValidAccounts(
1477
+ getOptionalScopes((_a3 = options == null ? void 0 : options.scopes) != null ? _a3 : []),
1478
+ getValidAccounts((_b = options == null ? void 0 : options.caipAccountIds) != null ? _b : [])
1479
+ );
1480
+ const sessionRequest = {
1481
+ optionalScopes,
1482
+ sessionProperties: options == null ? void 0 : options.sessionProperties
1483
+ };
1484
+ const request = {
1485
+ jsonrpc: "2.0",
1486
+ id: String(getUniqueRequestId()),
1487
+ method: "wallet_createSession",
1488
+ params: sessionRequest
1489
+ };
1490
+ initialConnectionMessageHandler = (message) => __async(this, null, function* () {
1491
+ if (typeof message !== "object" || message === null) {
1492
+ return;
1493
+ }
1494
+ if (!("data" in message)) {
1495
+ return;
1496
+ }
1497
+ const messagePayload = message.data;
1498
+ const isMatchingId = messagePayload.id === request.id;
1499
+ const isMatchingMethod = messagePayload.method === "wallet_createSession" || messagePayload.method === "wallet_sessionChanged";
1500
+ if (!isMatchingId && !isMatchingMethod) {
1501
+ return;
1502
+ }
1503
+ if (messagePayload.error) {
1504
+ return rejectConnection(
1505
+ this.parseWalletError(messagePayload.error)
1506
+ );
1507
+ }
1508
+ yield this.storeWalletSession(
1509
+ request,
1510
+ messagePayload
1511
+ );
1512
+ yield this.removeStoredPendingSessionRequest();
1513
+ this.notifyCallbacks(messagePayload);
1514
+ return resolveConnection();
1515
+ });
1516
+ this.dappClient.on("message", initialConnectionMessageHandler);
1517
+ const platformType = getPlatformType();
1518
+ const isQRCodeFlow = [
1519
+ "web-desktop" /* DesktopWeb */,
1520
+ "nodejs" /* NonBrowser */
1521
+ ].includes(platformType);
1522
+ const initialPayload = {
1523
+ name: MULTICHAIN_PROVIDER_STREAM_NAME,
1524
+ data: request
1525
+ };
1526
+ dappClient.connect({
1527
+ mode: "trusted",
1528
+ initialPayload: isQRCodeFlow ? void 0 : initialPayload
1529
+ }).then(() => __async(this, null, function* () {
1530
+ if (isQRCodeFlow) {
1531
+ return dappClient.sendRequest(initialPayload);
1532
+ }
1533
+ return void 0;
1534
+ })).catch((error) => {
1535
+ if (initialConnectionMessageHandler) {
1536
+ this.dappClient.off(
1537
+ "message",
1538
+ initialConnectionMessageHandler
1539
+ );
1540
+ }
1541
+ rejectConnection(error);
1542
+ });
1543
+ }
1544
+ );
1545
+ }
1546
+ timeout = setTimeout(
1547
+ () => {
1548
+ reject(new import_multichain_api_client2.TransportTimeoutError());
1549
+ },
1550
+ storedSessionRequestBeforeConnectionAttempt ? this.options.resumeTimeout : this.options.connectionTimeout
1551
+ );
1552
+ connection.then(resolve).catch(reject);
1553
+ }));
1554
+ return connectionPromise.catch((error) => __async(this, null, function* () {
1555
+ yield this.dappClient.disconnect();
1556
+ throw error;
1557
+ })).finally(() => {
1558
+ if (timeout) {
1559
+ clearTimeout(timeout);
1560
+ }
1561
+ if (initialConnectionMessageHandler) {
1562
+ this.dappClient.off("message", initialConnectionMessageHandler);
1563
+ initialConnectionMessageHandler = void 0;
1564
+ }
1565
+ this.removeStoredPendingSessionRequest();
1566
+ });
1567
+ });
1197
1568
  }
1198
- };
1199
- }
1200
- });
1201
-
1202
- // src/ui/modals/base/AbstractOTPModal.ts
1203
- var AbstractOTPCodeModal;
1204
- var init_AbstractOTPModal = __esm({
1205
- "src/ui/modals/base/AbstractOTPModal.ts"() {
1206
- "use strict";
1207
- init_domain();
1208
- AbstractOTPCodeModal = class extends Modal {
1209
- get otpCode() {
1210
- return this.data;
1211
- }
1212
- set otpCode(code) {
1213
- this.data = code;
1214
- }
1215
- updateOTPCode(code) {
1216
- this.otpCode = code;
1217
- if (this.instance) {
1218
- this.instance.otpCode = code;
1219
- }
1220
- }
1221
- };
1222
- }
1223
- });
1224
-
1225
- // src/ui/modals/web/otp.ts
1226
- var OTPCodeModal;
1227
- var init_otp = __esm({
1228
- "src/ui/modals/web/otp.ts"() {
1229
- "use strict";
1230
- init_AbstractOTPModal();
1231
- OTPCodeModal = class extends AbstractOTPCodeModal {
1232
- mount() {
1569
+ /**
1570
+ * Disconnects from the Mobile Wallet Protocol
1571
+ *
1572
+ * @param [scopes] - The scopes to revoke. If not provided or empty, all scopes will be revoked.
1573
+ * @returns Nothing
1574
+ */
1575
+ disconnect() {
1576
+ return __async(this, arguments, function* (scopes = []) {
1577
+ var _a3, _b;
1578
+ const cachedSession = yield this.getCachedResponse({
1579
+ jsonrpc: "2.0",
1580
+ id: "0",
1581
+ method: "wallet_getSession"
1582
+ });
1583
+ const cachedSessionScopes = (_b = (_a3 = cachedSession == null ? void 0 : cachedSession.result) == null ? void 0 : _a3.sessionScopes) != null ? _b : {};
1584
+ const remainingScopes = scopes.length === 0 ? [] : Object.keys(cachedSessionScopes).filter(
1585
+ (scope) => !scopes.includes(scope)
1586
+ );
1587
+ const newSessionScopes = Object.fromEntries(
1588
+ Object.entries(cachedSessionScopes).filter(
1589
+ ([key]) => remainingScopes.includes(key)
1590
+ )
1591
+ );
1592
+ this.request({ method: "wallet_revokeSession", params: { scopes } }).catch(
1593
+ (err) => {
1594
+ console.error("error revoking session", err);
1595
+ }
1596
+ );
1597
+ const remainingScopesIncludeEip155 = remainingScopes.some(
1598
+ (scope) => scope.includes("eip155")
1599
+ );
1600
+ if (!remainingScopesIncludeEip155) {
1601
+ this.kvstore.delete(ACCOUNTS_STORE_KEY);
1602
+ this.kvstore.delete(CHAIN_STORE_KEY);
1603
+ }
1604
+ if (remainingScopes.length > 0) {
1605
+ this.kvstore.set(
1606
+ SESSION_STORE_KEY,
1607
+ JSON.stringify({
1608
+ result: {
1609
+ sessionScopes: newSessionScopes
1610
+ }
1611
+ })
1612
+ );
1613
+ } else {
1614
+ this.kvstore.delete(SESSION_STORE_KEY);
1615
+ if (typeof window !== "undefined" && typeof window.removeEventListener !== "undefined" && this.windowFocusHandler) {
1616
+ window.removeEventListener("focus", this.windowFocusHandler);
1617
+ this.windowFocusHandler = void 0;
1618
+ }
1619
+ yield this.dappClient.disconnect();
1620
+ }
1621
+ this.notifyCallbacks({
1622
+ method: "wallet_sessionChanged",
1623
+ params: {
1624
+ sessionScopes: newSessionScopes
1625
+ }
1626
+ });
1627
+ });
1233
1628
  }
1234
- unmount() {
1629
+ /**
1630
+ * Checks if the transport is connected
1631
+ *
1632
+ * @returns True if transport is connected, false otherwise
1633
+ */
1634
+ isConnected() {
1635
+ return this.dappClient.state === "CONNECTED";
1235
1636
  }
1236
- };
1237
- }
1238
- });
1239
-
1240
- // src/ui/modals/web/index.ts
1241
- var web_exports = {};
1242
- __export(web_exports, {
1243
- InstallModal: () => InstallModal,
1244
- OTPCodeModal: () => OTPCodeModal
1245
- });
1246
- var init_web = __esm({
1247
- "src/ui/modals/web/index.ts"() {
1248
- "use strict";
1249
- init_install();
1250
- init_otp();
1251
- }
1252
- });
1253
-
1254
- // src/store/adapters/web.ts
1255
- var web_exports2 = {};
1256
- __export(web_exports2, {
1257
- StoreAdapterWeb: () => StoreAdapterWeb
1258
- });
1259
- var _StoreAdapterWeb, StoreAdapterWeb;
1260
- var init_web2 = __esm({
1261
- "src/store/adapters/web.ts"() {
1262
- "use strict";
1263
- init_domain();
1264
- _StoreAdapterWeb = class _StoreAdapterWeb extends StoreAdapter {
1265
- constructor(dbNameSuffix = "-kv-store", storeName = _StoreAdapterWeb.stores[0]) {
1266
- super();
1267
- this.storeName = storeName;
1268
- this.platform = "web";
1269
- const dbName = `${_StoreAdapterWeb.DB_NAME}${dbNameSuffix}`;
1270
- this.dbPromise = new Promise((resolve, reject) => {
1637
+ /**
1638
+ * Attempts to re-establish a connection via DappClient
1639
+ *
1640
+ * @returns Nothing
1641
+ */
1642
+ // TODO: We should re-evaluate adding this to the WebSocketTransport layer from `@metamask/mobile-wallet-protocol-core`
1643
+ // ticket: https://consensyssoftware.atlassian.net/browse/WAPI-862
1644
+ attemptResumeSession() {
1645
+ return __async(this, null, function* () {
1271
1646
  try {
1272
- const request = this.internal.open(dbName, 1);
1273
- request.onerror = () => reject(new Error("Failed to open IndexedDB."));
1274
- request.onsuccess = () => resolve(request.result);
1275
- request.onupgradeneeded = () => {
1276
- const db = request.result;
1277
- for (const name of _StoreAdapterWeb.stores) {
1278
- if (!db.objectStoreNames.contains(name)) {
1279
- db.createObjectStore(name);
1280
- }
1647
+ yield this.dappClient.reconnect();
1648
+ yield new Promise((resolve, reject) => {
1649
+ const timeout = setTimeout(() => {
1650
+ reject(new Error("Resume timeout"));
1651
+ }, 2e3);
1652
+ if (this.isConnected()) {
1653
+ clearTimeout(timeout);
1654
+ resolve();
1655
+ } else {
1656
+ this.dappClient.once("connected", () => {
1657
+ clearTimeout(timeout);
1658
+ resolve();
1659
+ });
1281
1660
  }
1282
- };
1661
+ });
1283
1662
  } catch (error) {
1284
- reject(error);
1663
+ return Promise.reject(
1664
+ new Error(`Failed to resume session: ${error.message}`)
1665
+ );
1285
1666
  }
1286
1667
  });
1287
1668
  }
1288
- get internal() {
1289
- if (typeof window === "undefined" || !window.indexedDB) {
1290
- throw new Error("indexedDB is not available in this environment");
1291
- }
1292
- return window.indexedDB;
1293
- }
1294
- get(key) {
1669
+ getCachedResponse(request) {
1295
1670
  return __async(this, null, function* () {
1296
- const { storeName } = this;
1297
- const db = yield this.dbPromise;
1298
- return new Promise((resolve, reject) => {
1299
- try {
1300
- const tx = db.transaction(storeName, "readonly");
1301
- const store = tx.objectStore(storeName);
1302
- const request = store.get(key);
1303
- request.onerror = () => reject(new Error("Failed to get value from IndexedDB."));
1304
- request.onsuccess = () => {
1305
- var _a3;
1306
- return resolve((_a3 = request.result) != null ? _a3 : null);
1671
+ var _a3;
1672
+ if (request.method === "wallet_getSession") {
1673
+ const walletGetSession = yield this.kvstore.get(SESSION_STORE_KEY);
1674
+ if (walletGetSession) {
1675
+ const walletSession = JSON.parse(walletGetSession);
1676
+ return {
1677
+ id: request.id,
1678
+ jsonrpc: "2.0",
1679
+ result: (_a3 = walletSession.params) != null ? _a3 : walletSession.result,
1680
+ // "what?... why walletSession.params?.."
1681
+ method: request.method
1307
1682
  };
1308
- } catch (error) {
1309
- reject(error);
1310
1683
  }
1311
- });
1684
+ } else if (request.method === "eth_accounts") {
1685
+ const ethAccounts = yield this.kvstore.get(ACCOUNTS_STORE_KEY);
1686
+ if (ethAccounts) {
1687
+ return {
1688
+ id: request.id,
1689
+ jsonrpc: "2.0",
1690
+ result: JSON.parse(ethAccounts),
1691
+ method: request.method
1692
+ };
1693
+ }
1694
+ } else if (request.method === "eth_chainId") {
1695
+ const ethChainId = yield this.kvstore.get(CHAIN_STORE_KEY);
1696
+ if (ethChainId) {
1697
+ return {
1698
+ id: request.id,
1699
+ jsonrpc: "2.0",
1700
+ result: JSON.parse(ethChainId),
1701
+ method: request.method
1702
+ };
1703
+ }
1704
+ }
1312
1705
  });
1313
1706
  }
1314
- set(key, value) {
1707
+ storeWalletSession(request, response) {
1315
1708
  return __async(this, null, function* () {
1316
- const { storeName } = this;
1317
- const db = yield this.dbPromise;
1709
+ if (response.error) {
1710
+ return;
1711
+ }
1712
+ if (CACHED_METHOD_LIST.includes(request.method)) {
1713
+ yield this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));
1714
+ } else if (request.method === "eth_accounts") {
1715
+ yield this.kvstore.set(
1716
+ ACCOUNTS_STORE_KEY,
1717
+ JSON.stringify(response.result)
1718
+ );
1719
+ } else if (request.method === "eth_chainId") {
1720
+ yield this.kvstore.set(CHAIN_STORE_KEY, JSON.stringify(response.result));
1721
+ } else if (CACHED_RESET_METHOD_LIST.includes(request.method)) {
1722
+ yield this.kvstore.delete(SESSION_STORE_KEY);
1723
+ yield this.kvstore.delete(ACCOUNTS_STORE_KEY);
1724
+ yield this.kvstore.delete(CHAIN_STORE_KEY);
1725
+ }
1726
+ });
1727
+ }
1728
+ request(payload, options) {
1729
+ return __async(this, null, function* () {
1730
+ const request = __spreadValues({
1731
+ jsonrpc: "2.0",
1732
+ id: String(getUniqueRequestId())
1733
+ }, payload);
1734
+ const cachedWalletSession = yield this.getCachedResponse(request);
1735
+ if (cachedWalletSession) {
1736
+ this.notifyCallbacks(cachedWalletSession);
1737
+ return cachedWalletSession;
1738
+ }
1739
+ if (!this.isConnected()) {
1740
+ yield this.attemptResumeSession();
1741
+ }
1318
1742
  return new Promise((resolve, reject) => {
1319
- try {
1320
- const tx = db.transaction(storeName, "readwrite");
1321
- const store = tx.objectStore(storeName);
1322
- const request = store.put(value, key);
1323
- request.onerror = () => reject(new Error("Failed to set value in IndexedDB."));
1324
- request.onsuccess = () => resolve();
1325
- } catch (error) {
1326
- reject(error);
1327
- }
1743
+ var _a3;
1744
+ const timeout = setTimeout(() => {
1745
+ this.rejectRequest(request.id, new import_multichain_api_client2.TransportTimeoutError());
1746
+ }, (_a3 = options == null ? void 0 : options.timeout) != null ? _a3 : this.options.requestTimeout);
1747
+ this.pendingRequests.set(request.id, {
1748
+ request,
1749
+ method: request.method,
1750
+ resolve: (response) => __async(this, null, function* () {
1751
+ yield this.storeWalletSession(request, response);
1752
+ return resolve(response);
1753
+ }),
1754
+ reject,
1755
+ timeout
1756
+ });
1757
+ this.dappClient.sendRequest({
1758
+ name: MULTICHAIN_PROVIDER_STREAM_NAME,
1759
+ data: request
1760
+ }).catch(reject);
1328
1761
  });
1329
1762
  });
1330
1763
  }
1331
- delete(key) {
1764
+ onNotification(callback) {
1765
+ this.notificationCallbacks.add(callback);
1766
+ return () => {
1767
+ this.notificationCallbacks.delete(callback);
1768
+ };
1769
+ }
1770
+ getActiveSession() {
1332
1771
  return __async(this, null, function* () {
1333
- const { storeName } = this;
1334
- const db = yield this.dbPromise;
1335
- return new Promise((resolve, reject) => {
1336
- try {
1337
- const tx = db.transaction(storeName, "readwrite");
1338
- const store = tx.objectStore(storeName);
1339
- const request = store.delete(key);
1340
- request.onerror = () => reject(new Error("Failed to delete value from IndexedDB."));
1341
- request.onsuccess = () => resolve();
1342
- } catch (error) {
1343
- reject(error);
1344
- }
1772
+ const { kvstore } = this;
1773
+ const { SessionStore } = yield import("@metamask/mobile-wallet-protocol-core");
1774
+ const sessionStore = yield SessionStore.create(kvstore);
1775
+ try {
1776
+ const [activeSession] = yield sessionStore.list();
1777
+ return activeSession;
1778
+ } catch (error) {
1779
+ logger("error getting active session", error);
1780
+ return void 0;
1781
+ }
1782
+ });
1783
+ }
1784
+ // This method checks if an existing CAIP session response is cached or waits for one
1785
+ // to be received from the wallet if not cached. This is necessary because there is an edge
1786
+ // case during the initial connection flow where after the user has accepted the permission approval
1787
+ // and returned back to the dapp from the wallet, the dapp page may have gotten unloaded and refreshed.
1788
+ // When it is unloaded and refreshed, it will try to resume the session by making a request for wallet_getSession
1789
+ // which should resolve from cache, but because a race condition makes it possible for the response from the wallet
1790
+ // for the initial wallet_createSession connection request to not have been handled and cached yet. This results
1791
+ // in the wallet_getSession request never resolving unless we wait for it explicitly as done in this method.
1792
+ waitForWalletSessionIfNotCached() {
1793
+ return __async(this, null, function* () {
1794
+ const cachedWalletGetSessionResponse = yield this.kvstore.get(SESSION_STORE_KEY);
1795
+ if (cachedWalletGetSessionResponse) {
1796
+ return;
1797
+ }
1798
+ let unsubscribe;
1799
+ const responsePromise = new Promise((resolve) => {
1800
+ unsubscribe = this.onNotification((message) => {
1801
+ if (typeof message === "object" && message !== null) {
1802
+ if ("data" in message) {
1803
+ const messagePayload = message.data;
1804
+ if (messagePayload.method === "wallet_getSession" || messagePayload.method === "wallet_sessionChanged") {
1805
+ unsubscribe();
1806
+ resolve();
1807
+ }
1808
+ }
1809
+ }
1810
+ });
1345
1811
  });
1812
+ const timeoutPromise = new Promise((_resolve, reject) => {
1813
+ setTimeout(() => {
1814
+ unsubscribe();
1815
+ this.removeStoredPendingSessionRequest();
1816
+ reject(new import_multichain_api_client2.TransportTimeoutError());
1817
+ }, this.options.resumeTimeout);
1818
+ });
1819
+ return Promise.race([responsePromise, timeoutPromise]);
1346
1820
  });
1347
1821
  }
1348
1822
  };
1349
- _StoreAdapterWeb.stores = ["sdk-kv-store", "key-value-pairs"];
1350
- _StoreAdapterWeb.DB_NAME = "mmconnect";
1351
- StoreAdapterWeb = _StoreAdapterWeb;
1352
1823
  }
1353
1824
  });
1354
1825
 
1355
- // src/index.browser.ts
1356
- var index_browser_exports = {};
1357
- __export(index_browser_exports, {
1358
- EventEmitter: () => EventEmitter,
1359
- Modal: () => Modal,
1360
- MultichainCore: () => MultichainCore,
1361
- PlatformType: () => PlatformType,
1362
- RPCHttpErr: () => RPCHttpErr,
1363
- RPCInvokeMethodErr: () => RPCInvokeMethodErr,
1364
- RPCReadonlyRequestErr: () => RPCReadonlyRequestErr,
1365
- RPCReadonlyResponseErr: () => RPCReadonlyResponseErr,
1366
- RPC_HANDLED_METHODS: () => RPC_HANDLED_METHODS,
1367
- SDK_HANDLED_METHODS: () => SDK_HANDLED_METHODS,
1368
- StoreAdapter: () => StoreAdapter,
1369
- StoreClient: () => StoreClient,
1370
- TransportType: () => TransportType,
1371
- createLogger: () => createLogger,
1372
- createMultichainClient: () => createMultichainClient,
1373
- enableDebug: () => enableDebug,
1374
- getInfuraRpcUrls: () => getInfuraRpcUrls,
1375
- getPlatformType: () => getPlatformType,
1376
- getTransportType: () => getTransportType,
1377
- getVersion: () => getVersion,
1378
- getWalletActionAnalyticsProperties: () => getWalletActionAnalyticsProperties,
1379
- hasExtension: () => hasExtension,
1380
- infuraRpcUrls: () => infuraRpcUrls,
1381
- isEnabled: () => isEnabled,
1382
- isMetamaskExtensionInstalled: () => isMetamaskExtensionInstalled,
1383
- isRejectionError: () => isRejectionError,
1384
- isSecure: () => isSecure
1826
+ // src/multichain/transports/mwp/KeyManager.ts
1827
+ var KeyManager_exports = {};
1828
+ __export(KeyManager_exports, {
1829
+ createKeyManager: () => createKeyManager
1830
+ });
1831
+ function createKeyManager() {
1832
+ return __async(this, null, function* () {
1833
+ const { decrypt, encrypt, PrivateKey, PublicKey } = yield import("eciesjs");
1834
+ return {
1835
+ generateKeyPair() {
1836
+ const privateKey = new PrivateKey();
1837
+ return {
1838
+ privateKey: new Uint8Array(privateKey.secret),
1839
+ publicKey: privateKey.publicKey.toBytes(true)
1840
+ };
1841
+ },
1842
+ encrypt(plaintext, theirPublicKey) {
1843
+ return __async(this, null, function* () {
1844
+ const plaintextBuffer = Buffer.from(plaintext, "utf8");
1845
+ const encryptedBuffer = encrypt(theirPublicKey, plaintextBuffer);
1846
+ return encryptedBuffer.toString("base64");
1847
+ });
1848
+ },
1849
+ decrypt(encryptedB64, myPrivateKey) {
1850
+ return __async(this, null, function* () {
1851
+ const encryptedBuffer = Buffer.from(encryptedB64, "base64");
1852
+ const decryptedBuffer = yield decrypt(myPrivateKey, encryptedBuffer);
1853
+ return Buffer.from(decryptedBuffer).toString("utf8");
1854
+ });
1855
+ },
1856
+ validatePeerKey(key) {
1857
+ PublicKey.fromHex(Buffer.from(key).toString("hex"));
1858
+ }
1859
+ };
1860
+ });
1861
+ }
1862
+ var init_KeyManager = __esm({
1863
+ "src/multichain/transports/mwp/KeyManager.ts"() {
1864
+ "use strict";
1865
+ }
1385
1866
  });
1386
- module.exports = __toCommonJS(index_browser_exports);
1387
-
1388
- // src/polyfills/buffer-shim.ts
1389
- var import_buffer = require("buffer");
1390
- init_utils2();
1391
- var globalObj = getGlobalObject();
1392
- var _a;
1393
- (_a = globalObj.Buffer) != null ? _a : globalObj.Buffer = import_buffer.Buffer;
1394
-
1395
- // src/index.browser.ts
1396
- init_domain();
1397
-
1398
- // src/multichain/index.ts
1399
- var import_analytics4 = require("@metamask/analytics");
1400
- var import_mobile_wallet_protocol_core2 = require("@metamask/mobile-wallet-protocol-core");
1401
- var import_mobile_wallet_protocol_dapp_client = require("@metamask/mobile-wallet-protocol-dapp-client");
1402
- var import_multichain_api_client3 = require("@metamask/multichain-api-client");
1403
1867
 
1404
- // src/config/index.ts
1405
- var MWP_RELAY_URL = "wss://mm-sdk-relay.api.cx.metamask.io/connection/websocket";
1406
- var METAMASK_CONNECT_BASE_URL = "https://metamask.app.link/connect";
1407
- var METAMASK_DEEPLINK_BASE = "metamask://connect";
1408
-
1409
- // src/multichain/index.ts
1410
- init_domain();
1411
- init_analytics();
1412
- init_logger();
1413
- init_multichain();
1414
- init_platform();
1415
-
1416
- // src/multichain/rpc/handlers/rpcClient.ts
1417
- var import_cross_fetch = __toESM(require("cross-fetch"));
1418
- init_domain();
1419
- var rpcId = 1;
1420
- function getNextRpcId() {
1421
- rpcId += 1;
1422
- return rpcId;
1423
- }
1424
- var MissingRpcEndpointErr = class extends Error {
1425
- };
1426
- var RpcClient = class {
1427
- constructor(config, sdkInfo) {
1428
- this.config = config;
1429
- this.sdkInfo = sdkInfo;
1868
+ // src/ui/modals/base/utils.ts
1869
+ function formatRemainingTime(milliseconds) {
1870
+ if (milliseconds <= 0) {
1871
+ return "EXPIRED";
1430
1872
  }
1431
- /**
1432
- * Routes the request to a configured RPC node.
1433
- *
1434
- * @param options - The invoke method options.
1435
- * @returns The JSON response from the RPC node.
1436
- */
1437
- request(options) {
1438
- return __async(this, null, function* () {
1439
- const { request } = options;
1440
- const body = JSON.stringify({
1441
- jsonrpc: "2.0",
1442
- method: request.method,
1443
- params: request.params,
1444
- id: getNextRpcId()
1445
- });
1446
- const rpcEndpoint = this.getRpcEndpoint(options.scope);
1447
- const rpcRequest = yield this.fetchWithTimeout(
1448
- rpcEndpoint,
1449
- body,
1450
- "POST",
1451
- this.getHeaders(rpcEndpoint),
1452
- 3e4
1453
- );
1454
- const response = yield this.parseResponse(rpcRequest);
1455
- return response;
1456
- });
1873
+ const seconds = Math.floor(milliseconds / 1e3);
1874
+ return `${seconds}s`;
1875
+ }
1876
+ function shouldLogCountdown(remainingSeconds) {
1877
+ if (remainingSeconds <= 10) {
1878
+ return true;
1879
+ } else if (remainingSeconds <= 30) {
1880
+ return remainingSeconds % 5 === 0;
1881
+ } else if (remainingSeconds <= 60) {
1882
+ return remainingSeconds % 10 === 0;
1883
+ } else if (remainingSeconds <= 300) {
1884
+ return remainingSeconds % 30 === 0;
1457
1885
  }
1458
- getRpcEndpoint(scope) {
1459
- var _a3, _b, _c;
1460
- const supportedNetworks = (_c = (_b = (_a3 = this.config) == null ? void 0 : _a3.api) == null ? void 0 : _b.supportedNetworks) != null ? _c : {};
1461
- const rpcEndpoint = supportedNetworks[scope];
1462
- if (!rpcEndpoint) {
1463
- throw new MissingRpcEndpointErr(
1464
- `No RPC endpoint found for scope ${scope}`
1465
- );
1466
- }
1467
- return rpcEndpoint;
1886
+ return remainingSeconds % 60 === 0;
1887
+ }
1888
+ var init_utils3 = __esm({
1889
+ "src/ui/modals/base/utils.ts"() {
1890
+ "use strict";
1468
1891
  }
1469
- fetchWithTimeout(endpoint, body, method, headers, timeout) {
1470
- return __async(this, null, function* () {
1471
- const controller = new AbortController();
1472
- const timeoutId = setTimeout(() => controller.abort(), timeout);
1473
- try {
1474
- const response = yield (0, import_cross_fetch.default)(endpoint, {
1475
- method,
1476
- headers,
1477
- body,
1478
- signal: controller.signal
1479
- });
1480
- clearTimeout(timeoutId);
1481
- if (!response.ok) {
1482
- throw new RPCHttpErr(endpoint, method, response.status);
1892
+ });
1893
+
1894
+ // src/ui/modals/base/AbstractInstallModal.ts
1895
+ var logger3, _expirationInterval, _lastLoggedCountdown, AbstractInstallModal;
1896
+ var init_AbstractInstallModal = __esm({
1897
+ "src/ui/modals/base/AbstractInstallModal.ts"() {
1898
+ "use strict";
1899
+ init_utils3();
1900
+ init_domain();
1901
+ logger3 = createLogger("metamask-sdk:ui");
1902
+ AbstractInstallModal = class extends Modal {
1903
+ constructor() {
1904
+ super(...arguments);
1905
+ __privateAdd(this, _expirationInterval, null);
1906
+ __privateAdd(this, _lastLoggedCountdown, -1);
1907
+ }
1908
+ get link() {
1909
+ return this.data;
1910
+ }
1911
+ set link(link) {
1912
+ this.data = link;
1913
+ }
1914
+ get connectionRequest() {
1915
+ return this.options.connectionRequest;
1916
+ }
1917
+ set connectionRequest(connectionRequest) {
1918
+ this.options.connectionRequest = connectionRequest;
1919
+ }
1920
+ updateLink(link) {
1921
+ this.link = link;
1922
+ if (this.instance) {
1923
+ this.instance.link = link;
1483
1924
  }
1484
- return response;
1485
- } catch (error) {
1486
- clearTimeout(timeoutId);
1487
- if (error instanceof RPCHttpErr) {
1488
- throw error;
1925
+ }
1926
+ updateExpiresIn(expiresIn) {
1927
+ if (expiresIn >= 0 && this.instance) {
1928
+ this.instance.expiresIn = expiresIn;
1489
1929
  }
1490
- if (error instanceof Error && error.name === "AbortError") {
1491
- throw new RPCReadonlyRequestErr(`Request timeout after ${timeout}ms`);
1930
+ }
1931
+ startExpirationCheck(connectionRequest) {
1932
+ this.stopExpirationCheck();
1933
+ let currentConnectionRequest = connectionRequest;
1934
+ __privateSet(this, _expirationInterval, setInterval(() => __async(this, null, function* () {
1935
+ const { sessionRequest } = currentConnectionRequest;
1936
+ const now = Date.now();
1937
+ const remainingMs = sessionRequest.expiresAt - now;
1938
+ const remainingSeconds = Math.floor(remainingMs / 1e3);
1939
+ if (remainingMs > 0 && shouldLogCountdown(remainingSeconds) && __privateGet(this, _lastLoggedCountdown) !== remainingSeconds) {
1940
+ const formattedTime = formatRemainingTime(remainingMs);
1941
+ logger3(
1942
+ `[UI: InstallModal-nodejs()] QR code expires in: ${formattedTime} (${remainingSeconds}s)`
1943
+ );
1944
+ __privateSet(this, _lastLoggedCountdown, remainingSeconds);
1945
+ }
1946
+ if (now >= sessionRequest.expiresAt) {
1947
+ this.stopExpirationCheck();
1948
+ logger3(
1949
+ "[UI: InstallModal-nodejs()] \u23F0 QR code EXPIRED! Generating new one..."
1950
+ );
1951
+ try {
1952
+ currentConnectionRequest = yield this.options.createConnectionRequest();
1953
+ const generateQRCode = yield this.options.generateQRCode(
1954
+ currentConnectionRequest
1955
+ );
1956
+ __privateSet(this, _lastLoggedCountdown, -1);
1957
+ this.updateLink(generateQRCode);
1958
+ this.updateExpiresIn(remainingSeconds);
1959
+ this.renderQRCode(generateQRCode, currentConnectionRequest);
1960
+ } catch (error) {
1961
+ logger3(
1962
+ `[UI: InstallModal-nodejs()] \u274C Error generating new QR code: ${error}`
1963
+ );
1964
+ }
1965
+ }
1966
+ }), 1e3));
1967
+ }
1968
+ stopExpirationCheck() {
1969
+ if (__privateGet(this, _expirationInterval)) {
1970
+ clearInterval(__privateGet(this, _expirationInterval));
1971
+ __privateSet(this, _expirationInterval, null);
1972
+ logger3(
1973
+ "[UI: InstallModal-nodejs()] \u{1F6D1} Stopped QR code expiration checking"
1974
+ );
1492
1975
  }
1493
- throw new RPCReadonlyRequestErr(error.message);
1494
1976
  }
1495
- });
1977
+ };
1978
+ _expirationInterval = new WeakMap();
1979
+ _lastLoggedCountdown = new WeakMap();
1496
1980
  }
1497
- parseResponse(response) {
1498
- return __async(this, null, function* () {
1499
- try {
1500
- const rpcResponse = yield response.json();
1501
- return rpcResponse.result;
1502
- } catch (error) {
1503
- throw new RPCReadonlyResponseErr(error.message);
1981
+ });
1982
+
1983
+ // src/ui/modals/web/install.ts
1984
+ var InstallModal;
1985
+ var init_install = __esm({
1986
+ "src/ui/modals/web/install.ts"() {
1987
+ "use strict";
1988
+ init_AbstractInstallModal();
1989
+ InstallModal = class extends AbstractInstallModal {
1990
+ renderQRCode() {
1991
+ }
1992
+ mount() {
1993
+ var _a3;
1994
+ const { options } = this;
1995
+ const modal = document.createElement(
1996
+ "mm-install-modal"
1997
+ );
1998
+ modal.showInstallModal = options.showInstallModal;
1999
+ modal.addEventListener("close", (ev) => {
2000
+ const { detail } = ev;
2001
+ options.onClose(detail == null ? void 0 : detail.shouldTerminate);
2002
+ });
2003
+ modal.addEventListener(
2004
+ "startDesktopOnboarding",
2005
+ options.startDesktopOnboarding
2006
+ );
2007
+ modal.link = options.link;
2008
+ this.instance = modal;
2009
+ (_a3 = options.parentElement) == null ? void 0 : _a3.appendChild(modal);
2010
+ this.startExpirationCheck(options.connectionRequest);
2011
+ }
2012
+ unmount() {
2013
+ var _a3;
2014
+ const { options, instance: modal } = this;
2015
+ this.stopExpirationCheck();
2016
+ if (modal && ((_a3 = options.parentElement) == null ? void 0 : _a3.contains(modal))) {
2017
+ options.parentElement.removeChild(modal);
2018
+ this.instance = void 0;
2019
+ }
1504
2020
  }
1505
- });
1506
- }
1507
- getHeaders(rpcEndpoint) {
1508
- const defaultHeaders = {
1509
- Accept: "application/json",
1510
- "Content-Type": "application/json"
1511
2021
  };
1512
- if (rpcEndpoint.includes("infura")) {
1513
- return __spreadProps(__spreadValues({}, defaultHeaders), {
1514
- "Metamask-Sdk-Info": this.sdkInfo
1515
- });
1516
- }
1517
- return defaultHeaders;
1518
2022
  }
1519
- };
2023
+ });
1520
2024
 
1521
- // src/multichain/rpc/requestRouter.ts
1522
- var import_analytics2 = require("@metamask/analytics");
1523
- init_domain();
1524
- init_utils2();
1525
- init_analytics();
1526
- var _RequestRouter_instances, withAnalyticsTracking_fn, trackWalletActionRequested_fn, trackWalletActionSucceeded_fn, trackWalletActionFailed_fn, trackWalletActionRejected_fn;
1527
- var RequestRouter = class {
1528
- constructor(transport, rpcClient, config, transportType) {
1529
- this.transport = transport;
1530
- this.rpcClient = rpcClient;
1531
- this.config = config;
1532
- this.transportType = transportType;
1533
- __privateAdd(this, _RequestRouter_instances);
1534
- }
1535
- /**
1536
- * The main entry point for invoking an RPC method.
1537
- * This method acts as a router, determining the correct handling strategy
1538
- * for the request and delegating to the appropriate private handler.
1539
- *
1540
- * @param options
1541
- */
1542
- invokeMethod(options) {
1543
- return __async(this, null, function* () {
1544
- const { method } = options.request;
1545
- if (RPC_HANDLED_METHODS.has(method)) {
1546
- return this.handleWithRpcNode(options);
2025
+ // src/ui/modals/base/AbstractOTPModal.ts
2026
+ var AbstractOTPCodeModal;
2027
+ var init_AbstractOTPModal = __esm({
2028
+ "src/ui/modals/base/AbstractOTPModal.ts"() {
2029
+ "use strict";
2030
+ init_domain();
2031
+ AbstractOTPCodeModal = class extends Modal {
2032
+ get otpCode() {
2033
+ return this.data;
1547
2034
  }
1548
- if (SDK_HANDLED_METHODS.has(method)) {
1549
- return this.handleWithSdkState(options);
2035
+ set otpCode(code) {
2036
+ this.data = code;
1550
2037
  }
1551
- return this.handleWithWallet(options);
1552
- });
1553
- }
1554
- /**
1555
- * Forwards the request directly to the wallet via the transport.
1556
- *
1557
- * @param options
1558
- */
1559
- handleWithWallet(options) {
1560
- return __async(this, null, function* () {
1561
- return __privateMethod(this, _RequestRouter_instances, withAnalyticsTracking_fn).call(this, options, () => __async(this, null, function* () {
1562
- const request = this.transport.request({
1563
- method: "wallet_invokeMethod",
1564
- params: options
1565
- });
1566
- const { ui, mobile } = this.config;
1567
- const { showInstallModal = false } = ui != null ? ui : {};
1568
- const secure = isSecure();
1569
- const shouldOpenDeeplink = secure && !showInstallModal;
1570
- if (shouldOpenDeeplink) {
1571
- setTimeout(() => __async(this, null, function* () {
1572
- const session = yield this.transport.getActiveSession();
1573
- if (!session) {
1574
- throw new Error("No active session found");
1575
- }
1576
- const url = `${METAMASK_DEEPLINK_BASE}/mwp?id=${encodeURIComponent(session.id)}`;
1577
- if (mobile == null ? void 0 : mobile.preferredOpenLink) {
1578
- mobile.preferredOpenLink(url, "_self");
1579
- } else {
1580
- openDeeplink(this.config, url, METAMASK_CONNECT_BASE_URL);
1581
- }
1582
- }), 10);
1583
- }
1584
- const response = yield request;
1585
- if (response.error) {
1586
- const { error } = response;
1587
- throw new RPCInvokeMethodErr(
1588
- `RPC Request failed with code ${error.code}: ${error.message}`,
1589
- error.code,
1590
- error.message
1591
- );
1592
- }
1593
- return response.result;
1594
- }));
1595
- });
1596
- }
1597
- /**
1598
- * Routes the request to a configured RPC node.
1599
- *
1600
- * @param options
1601
- */
1602
- handleWithRpcNode(options) {
1603
- return __async(this, null, function* () {
1604
- try {
1605
- return yield this.rpcClient.request(options);
1606
- } catch (error) {
1607
- if (error instanceof MissingRpcEndpointErr) {
1608
- return this.handleWithWallet(options);
2038
+ updateOTPCode(code) {
2039
+ this.otpCode = code;
2040
+ if (this.instance) {
2041
+ this.instance.otpCode = code;
1609
2042
  }
1610
- throw error;
1611
2043
  }
1612
- });
1613
- }
1614
- /**
1615
- * Responds directly from the SDK's session state.
1616
- *
1617
- * @param options
1618
- */
1619
- handleWithSdkState(options) {
1620
- return __async(this, null, function* () {
1621
- console.warn(
1622
- `Method "${options.request.method}" is configured for SDK state handling, but this is not yet implemented. Falling back to wallet passthrough.`
1623
- );
1624
- return this.handleWithWallet(options);
1625
- });
2044
+ };
1626
2045
  }
1627
- };
1628
- _RequestRouter_instances = new WeakSet();
1629
- withAnalyticsTracking_fn = function(options, execute) {
1630
- return __async(this, null, function* () {
1631
- var _a3;
1632
- yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRequested_fn).call(this, options);
1633
- try {
1634
- const result = yield execute();
1635
- yield __privateMethod(this, _RequestRouter_instances, trackWalletActionSucceeded_fn).call(this, options);
1636
- return result;
1637
- } catch (error) {
1638
- const isRejection = isRejectionError(error);
1639
- if (isRejection) {
1640
- yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRejected_fn).call(this, options);
1641
- } else {
1642
- yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options);
2046
+ });
2047
+
2048
+ // src/ui/modals/web/otp.ts
2049
+ var OTPCodeModal;
2050
+ var init_otp = __esm({
2051
+ "src/ui/modals/web/otp.ts"() {
2052
+ "use strict";
2053
+ init_AbstractOTPModal();
2054
+ OTPCodeModal = class extends AbstractOTPCodeModal {
2055
+ mount() {
1643
2056
  }
1644
- if (error instanceof RPCInvokeMethodErr) {
1645
- throw error;
2057
+ unmount() {
1646
2058
  }
1647
- const castError = error;
1648
- throw new RPCInvokeMethodErr(
1649
- (_a3 = castError.message) != null ? _a3 : "Unknown error",
1650
- castError.code
1651
- );
1652
- }
1653
- });
1654
- };
1655
- trackWalletActionRequested_fn = function(options) {
1656
- return __async(this, null, function* () {
1657
- const props = yield getWalletActionAnalyticsProperties(
1658
- this.config,
1659
- this.config.storage,
1660
- options,
1661
- this.transportType
1662
- );
1663
- import_analytics2.analytics.track("mmconnect_wallet_action_requested", props);
1664
- });
1665
- };
1666
- trackWalletActionSucceeded_fn = function(options) {
1667
- return __async(this, null, function* () {
1668
- const props = yield getWalletActionAnalyticsProperties(
1669
- this.config,
1670
- this.config.storage,
1671
- options,
1672
- this.transportType
1673
- );
1674
- import_analytics2.analytics.track("mmconnect_wallet_action_succeeded", props);
1675
- });
1676
- };
1677
- trackWalletActionFailed_fn = function(options) {
1678
- return __async(this, null, function* () {
1679
- const props = yield getWalletActionAnalyticsProperties(
1680
- this.config,
1681
- this.config.storage,
1682
- options,
1683
- this.transportType
1684
- );
1685
- import_analytics2.analytics.track("mmconnect_wallet_action_failed", props);
1686
- });
1687
- };
1688
- trackWalletActionRejected_fn = function(options) {
1689
- return __async(this, null, function* () {
1690
- const props = yield getWalletActionAnalyticsProperties(
1691
- this.config,
1692
- this.config.storage,
1693
- options,
1694
- this.transportType
1695
- );
1696
- import_analytics2.analytics.track("mmconnect_wallet_action_rejected", props);
1697
- });
1698
- };
2059
+ };
2060
+ }
2061
+ });
1699
2062
 
1700
- // src/multichain/transports/default/index.ts
1701
- var import_multichain_api_client = require("@metamask/multichain-api-client");
1702
- init_utils2();
1703
- var DEFAULT_REQUEST_TIMEOUT = 60 * 1e3;
1704
- var _notificationCallbacks, _transport, _defaultRequestOptions, _pendingRequests, _handleResponseListener, _handleNotificationListener, _DefaultTransport_instances, notifyCallbacks_fn, isMetamaskProviderEvent_fn, handleResponse_fn, handleNotification_fn, setupMessageListener_fn, init_fn;
1705
- var DefaultTransport = class {
1706
- constructor() {
1707
- __privateAdd(this, _DefaultTransport_instances);
1708
- __privateAdd(this, _notificationCallbacks, /* @__PURE__ */ new Set());
1709
- __privateAdd(this, _transport, (0, import_multichain_api_client.getDefaultTransport)());
1710
- __privateAdd(this, _defaultRequestOptions, {
1711
- timeout: DEFAULT_REQUEST_TIMEOUT
1712
- });
1713
- __privateAdd(this, _pendingRequests, /* @__PURE__ */ new Map());
1714
- __privateAdd(this, _handleResponseListener);
1715
- __privateAdd(this, _handleNotificationListener);
2063
+ // src/ui/modals/web/index.ts
2064
+ var web_exports = {};
2065
+ __export(web_exports, {
2066
+ InstallModal: () => InstallModal,
2067
+ OTPCodeModal: () => OTPCodeModal
2068
+ });
2069
+ var init_web = __esm({
2070
+ "src/ui/modals/web/index.ts"() {
2071
+ "use strict";
2072
+ init_install();
2073
+ init_otp();
1716
2074
  }
1717
- sendEip1193Message(payload, options) {
1718
- return __async(this, null, function* () {
1719
- __privateMethod(this, _DefaultTransport_instances, setupMessageListener_fn).call(this);
1720
- const requestId = String(getUniqueRequestId());
1721
- const request = __spreadValues({
1722
- jsonrpc: "2.0",
1723
- id: requestId
1724
- }, payload);
1725
- return new Promise((resolve, reject) => {
1726
- var _a3;
1727
- const timeout = setTimeout(() => {
1728
- __privateGet(this, _pendingRequests).delete(requestId);
1729
- reject(new Error("Request timeout"));
1730
- }, (_a3 = options == null ? void 0 : options.timeout) != null ? _a3 : __privateGet(this, _defaultRequestOptions).timeout);
1731
- __privateGet(this, _pendingRequests).set(requestId, {
1732
- resolve: (response) => {
1733
- resolve(response);
1734
- },
1735
- reject,
1736
- timeout
2075
+ });
2076
+
2077
+ // src/store/adapters/web.ts
2078
+ var web_exports2 = {};
2079
+ __export(web_exports2, {
2080
+ StoreAdapterWeb: () => StoreAdapterWeb
2081
+ });
2082
+ var _StoreAdapterWeb, StoreAdapterWeb;
2083
+ var init_web2 = __esm({
2084
+ "src/store/adapters/web.ts"() {
2085
+ "use strict";
2086
+ init_domain();
2087
+ _StoreAdapterWeb = class _StoreAdapterWeb extends StoreAdapter {
2088
+ constructor(dbNameSuffix = "-kv-store", storeName = _StoreAdapterWeb.stores[0]) {
2089
+ super();
2090
+ this.storeName = storeName;
2091
+ this.platform = "web";
2092
+ const dbName = `${_StoreAdapterWeb.DB_NAME}${dbNameSuffix}`;
2093
+ this.dbPromise = new Promise((resolve, reject) => {
2094
+ try {
2095
+ const request = this.internal.open(dbName, 1);
2096
+ request.onerror = () => reject(new Error("Failed to open IndexedDB."));
2097
+ request.onsuccess = () => resolve(request.result);
2098
+ request.onupgradeneeded = () => {
2099
+ const db = request.result;
2100
+ for (const name of _StoreAdapterWeb.stores) {
2101
+ if (!db.objectStoreNames.contains(name)) {
2102
+ db.createObjectStore(name);
2103
+ }
2104
+ }
2105
+ };
2106
+ } catch (error) {
2107
+ reject(error);
2108
+ }
1737
2109
  });
1738
- window.postMessage(
1739
- {
1740
- target: "metamask-contentscript",
1741
- data: {
1742
- name: "metamask-provider",
1743
- data: request
1744
- }
1745
- },
1746
- // eslint-disable-next-line no-restricted-globals
1747
- location.origin
1748
- );
1749
- });
1750
- });
1751
- }
1752
- init() {
1753
- return __async(this, null, function* () {
1754
- yield __privateMethod(this, _DefaultTransport_instances, init_fn).call(this);
1755
- let walletSession = { sessionScopes: {} };
1756
- try {
1757
- const sessionRequest = yield this.request(
1758
- { method: "wallet_getSession" },
1759
- __privateGet(this, _defaultRequestOptions)
1760
- );
1761
- walletSession = sessionRequest.result;
1762
- } catch (e) {
1763
- console.error(
1764
- "Failed to get wallet session during DefaultTransport init"
1765
- );
1766
- }
1767
- __privateMethod(this, _DefaultTransport_instances, notifyCallbacks_fn).call(this, {
1768
- method: "wallet_sessionChanged",
1769
- params: walletSession
1770
- });
1771
- });
1772
- }
1773
- connect(options) {
1774
- return __async(this, null, function* () {
1775
- var _a3, _b, _c, _d, _e;
1776
- yield __privateMethod(this, _DefaultTransport_instances, init_fn).call(this);
1777
- const sessionRequest = yield this.request(
1778
- { method: "wallet_getSession" },
1779
- __privateGet(this, _defaultRequestOptions)
1780
- );
1781
- if (sessionRequest.error) {
1782
- throw new Error(sessionRequest.error.message);
1783
2110
  }
1784
- let walletSession = sessionRequest.result;
1785
- const createSessionParams = {
1786
- optionalScopes: addValidAccounts(
1787
- getOptionalScopes((_a3 = options == null ? void 0 : options.scopes) != null ? _a3 : []),
1788
- getValidAccounts((_b = options == null ? void 0 : options.caipAccountIds) != null ? _b : [])
1789
- ),
1790
- sessionProperties: options == null ? void 0 : options.sessionProperties
1791
- };
1792
- if (walletSession && options && !options.forceRequest) {
1793
- const currentScopes = Object.keys(
1794
- (_c = walletSession == null ? void 0 : walletSession.sessionScopes) != null ? _c : {}
1795
- );
1796
- const proposedScopes = (_d = options == null ? void 0 : options.scopes) != null ? _d : [];
1797
- const proposedCaipAccountIds = (_e = options == null ? void 0 : options.caipAccountIds) != null ? _e : [];
1798
- const hasSameScopesAndAccounts = isSameScopesAndAccounts(
1799
- currentScopes,
1800
- proposedScopes,
1801
- walletSession,
1802
- proposedCaipAccountIds
1803
- );
1804
- if (!hasSameScopesAndAccounts) {
1805
- const response = yield this.request(
1806
- { method: "wallet_createSession", params: createSessionParams },
1807
- __privateGet(this, _defaultRequestOptions)
1808
- );
1809
- if (response.error) {
1810
- throw new Error(response.error.message);
1811
- }
1812
- walletSession = response.result;
1813
- }
1814
- } else if (!walletSession || (options == null ? void 0 : options.forceRequest)) {
1815
- const response = yield this.request(
1816
- { method: "wallet_createSession", params: createSessionParams },
1817
- __privateGet(this, _defaultRequestOptions)
1818
- );
1819
- if (response.error) {
1820
- throw new Error(response.error.message);
2111
+ get internal() {
2112
+ if (typeof window === "undefined" || !window.indexedDB) {
2113
+ throw new Error("indexedDB is not available in this environment");
1821
2114
  }
1822
- walletSession = response.result;
2115
+ return window.indexedDB;
1823
2116
  }
1824
- __privateMethod(this, _DefaultTransport_instances, notifyCallbacks_fn).call(this, {
1825
- method: "wallet_sessionChanged",
1826
- params: walletSession
1827
- });
1828
- });
1829
- }
1830
- disconnect() {
1831
- return __async(this, arguments, function* (scopes = []) {
1832
- yield this.request({ method: "wallet_revokeSession", params: { scopes } });
1833
- });
1834
- }
1835
- isConnected() {
1836
- return __privateGet(this, _transport).isConnected();
1837
- }
1838
- request(_0) {
1839
- return __async(this, arguments, function* (request, options = __privateGet(this, _defaultRequestOptions)) {
1840
- return __privateGet(this, _transport).request(request, options);
1841
- });
1842
- }
1843
- onNotification(callback) {
1844
- __privateGet(this, _transport).onNotification(callback);
1845
- __privateGet(this, _notificationCallbacks).add(callback);
1846
- return () => {
1847
- __privateGet(this, _notificationCallbacks).delete(callback);
1848
- };
1849
- }
1850
- getActiveSession() {
1851
- return __async(this, null, function* () {
1852
- throw new Error(
1853
- "getActiveSession is purposely not implemented for the DefaultTransport"
1854
- );
1855
- });
1856
- }
1857
- getStoredPendingSessionRequest() {
1858
- return __async(this, null, function* () {
1859
- throw new Error(
1860
- "getStoredPendingSessionRequest is purposely not implemented for the DefaultTransport"
1861
- );
1862
- });
1863
- }
1864
- };
1865
- _notificationCallbacks = new WeakMap();
1866
- _transport = new WeakMap();
1867
- _defaultRequestOptions = new WeakMap();
1868
- _pendingRequests = new WeakMap();
1869
- _handleResponseListener = new WeakMap();
1870
- _handleNotificationListener = new WeakMap();
1871
- _DefaultTransport_instances = new WeakSet();
1872
- notifyCallbacks_fn = function(data) {
1873
- for (const callback of __privateGet(this, _notificationCallbacks)) {
1874
- try {
1875
- callback(data);
1876
- } catch (error) {
1877
- console.log(
1878
- "[WindowPostMessageTransport] notifyCallbacks error:",
1879
- error
1880
- );
1881
- }
1882
- }
1883
- };
1884
- isMetamaskProviderEvent_fn = function(event) {
1885
- var _a3, _b;
1886
- return ((_b = (_a3 = event == null ? void 0 : event.data) == null ? void 0 : _a3.data) == null ? void 0 : _b.name) === "metamask-provider" && // eslint-disable-next-line no-restricted-globals
1887
- event.origin === location.origin;
1888
- };
1889
- handleResponse_fn = function(event) {
1890
- var _a3, _b;
1891
- if (!__privateMethod(this, _DefaultTransport_instances, isMetamaskProviderEvent_fn).call(this, event)) {
1892
- return;
1893
- }
1894
- const responseData = (_b = (_a3 = event == null ? void 0 : event.data) == null ? void 0 : _a3.data) == null ? void 0 : _b.data;
1895
- if (typeof responseData === "object" && responseData !== null && "method" in responseData) {
1896
- return;
1897
- }
1898
- if (typeof responseData === "object" && responseData !== null && "id" in responseData && ("result" in responseData || "error" in responseData)) {
1899
- const responseId = String(responseData.id);
1900
- const pendingRequest = __privateGet(this, _pendingRequests).get(responseId);
1901
- if (pendingRequest) {
1902
- clearTimeout(pendingRequest.timeout);
1903
- __privateGet(this, _pendingRequests).delete(responseId);
1904
- const response = responseData;
1905
- if ("error" in response && response.error) {
1906
- const error = new Error(
1907
- response.error.message || "Request failed"
1908
- );
1909
- if (typeof response.error.code === "number") {
1910
- error.code = response.error.code;
1911
- }
1912
- pendingRequest.reject(error);
1913
- } else {
1914
- pendingRequest.resolve(response);
2117
+ get(key) {
2118
+ return __async(this, null, function* () {
2119
+ const { storeName } = this;
2120
+ const db = yield this.dbPromise;
2121
+ return new Promise((resolve, reject) => {
2122
+ try {
2123
+ const tx = db.transaction(storeName, "readonly");
2124
+ const store = tx.objectStore(storeName);
2125
+ const request = store.get(key);
2126
+ request.onerror = () => reject(new Error("Failed to get value from IndexedDB."));
2127
+ request.onsuccess = () => {
2128
+ var _a3;
2129
+ return resolve((_a3 = request.result) != null ? _a3 : null);
2130
+ };
2131
+ } catch (error) {
2132
+ reject(error);
2133
+ }
2134
+ });
2135
+ });
2136
+ }
2137
+ set(key, value) {
2138
+ return __async(this, null, function* () {
2139
+ const { storeName } = this;
2140
+ const db = yield this.dbPromise;
2141
+ return new Promise((resolve, reject) => {
2142
+ try {
2143
+ const tx = db.transaction(storeName, "readwrite");
2144
+ const store = tx.objectStore(storeName);
2145
+ const request = store.put(value, key);
2146
+ request.onerror = () => reject(new Error("Failed to set value in IndexedDB."));
2147
+ request.onsuccess = () => resolve();
2148
+ } catch (error) {
2149
+ reject(error);
2150
+ }
2151
+ });
2152
+ });
2153
+ }
2154
+ delete(key) {
2155
+ return __async(this, null, function* () {
2156
+ const { storeName } = this;
2157
+ const db = yield this.dbPromise;
2158
+ return new Promise((resolve, reject) => {
2159
+ try {
2160
+ const tx = db.transaction(storeName, "readwrite");
2161
+ const store = tx.objectStore(storeName);
2162
+ const request = store.delete(key);
2163
+ request.onerror = () => reject(new Error("Failed to delete value from IndexedDB."));
2164
+ request.onsuccess = () => resolve();
2165
+ } catch (error) {
2166
+ reject(error);
2167
+ }
2168
+ });
2169
+ });
1915
2170
  }
1916
- }
1917
- }
1918
- };
1919
- handleNotification_fn = function(event) {
1920
- var _a3, _b;
1921
- if (!__privateMethod(this, _DefaultTransport_instances, isMetamaskProviderEvent_fn).call(this, event)) {
1922
- return;
1923
- }
1924
- const responseData = (_b = (_a3 = event == null ? void 0 : event.data) == null ? void 0 : _a3.data) == null ? void 0 : _b.data;
1925
- if (typeof responseData === "object" && responseData !== null && "method" in responseData) {
1926
- __privateMethod(this, _DefaultTransport_instances, notifyCallbacks_fn).call(this, responseData);
1927
- }
1928
- };
1929
- setupMessageListener_fn = function() {
1930
- if (__privateGet(this, _handleResponseListener)) {
1931
- return;
2171
+ };
2172
+ _StoreAdapterWeb.stores = ["sdk-kv-store", "key-value-pairs"];
2173
+ _StoreAdapterWeb.DB_NAME = "mmconnect";
2174
+ StoreAdapterWeb = _StoreAdapterWeb;
1932
2175
  }
1933
- __privateSet(this, _handleResponseListener, __privateMethod(this, _DefaultTransport_instances, handleResponse_fn).bind(this));
1934
- __privateSet(this, _handleNotificationListener, __privateMethod(this, _DefaultTransport_instances, handleNotification_fn).bind(this));
1935
- window.addEventListener("message", __privateGet(this, _handleResponseListener));
1936
- window.addEventListener("message", __privateGet(this, _handleNotificationListener));
1937
- };
1938
- init_fn = function() {
1939
- return __async(this, null, function* () {
1940
- __privateMethod(this, _DefaultTransport_instances, setupMessageListener_fn).call(this);
1941
- if (!__privateGet(this, _transport).isConnected()) {
1942
- yield __privateGet(this, _transport).connect();
1943
- }
1944
- });
1945
- };
2176
+ });
1946
2177
 
1947
- // src/multichain/transports/multichainApiClientWrapper/index.ts
1948
- var import_rpc_errors = require("@metamask/rpc-errors");
2178
+ // src/index.browser.ts
2179
+ var index_browser_exports = {};
2180
+ __export(index_browser_exports, {
2181
+ EventEmitter: () => EventEmitter,
2182
+ Modal: () => Modal,
2183
+ MultichainCore: () => MultichainCore,
2184
+ PlatformType: () => PlatformType,
2185
+ RPCHttpErr: () => RPCHttpErr,
2186
+ RPCInvokeMethodErr: () => RPCInvokeMethodErr,
2187
+ RPCReadonlyRequestErr: () => RPCReadonlyRequestErr,
2188
+ RPCReadonlyResponseErr: () => RPCReadonlyResponseErr,
2189
+ RPC_HANDLED_METHODS: () => RPC_HANDLED_METHODS,
2190
+ SDK_HANDLED_METHODS: () => SDK_HANDLED_METHODS,
2191
+ StoreAdapter: () => StoreAdapter,
2192
+ StoreClient: () => StoreClient,
2193
+ TransportType: () => TransportType,
2194
+ classifyFailureReason: () => classifyFailureReason,
2195
+ createLogger: () => createLogger,
2196
+ createMultichainClient: () => createMultichainClient,
2197
+ enableDebug: () => enableDebug,
2198
+ getInfuraRpcUrls: () => getInfuraRpcUrls,
2199
+ getPlatformType: () => getPlatformType,
2200
+ getTransportType: () => getTransportType,
2201
+ getVersion: () => getVersion,
2202
+ getWalletActionAnalyticsProperties: () => getWalletActionAnalyticsProperties,
2203
+ hasExtension: () => hasExtension,
2204
+ infuraRpcUrls: () => infuraRpcUrls,
2205
+ isEnabled: () => isEnabled,
2206
+ isMetamaskExtensionInstalled: () => isMetamaskExtensionInstalled,
2207
+ isRejectionError: () => isRejectionError,
2208
+ isSecure: () => isSecure
2209
+ });
2210
+ module.exports = __toCommonJS(index_browser_exports);
2211
+
2212
+ // src/polyfills/buffer-shim.ts
2213
+ var import_buffer = require("buffer");
1949
2214
  init_utils2();
1950
- var _notificationCallbacks2, _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn, walletGetSession_fn, walletRevokeSession_fn, walletInvokeMethod_fn;
1951
- var MultichainApiClientWrapperTransport = class {
1952
- constructor(metamaskConnectMultichain) {
1953
- this.metamaskConnectMultichain = metamaskConnectMultichain;
1954
- __privateAdd(this, _MultichainApiClientWrapperTransport_instances);
1955
- __privateAdd(this, _notificationCallbacks2, /* @__PURE__ */ new Set());
1956
- }
1957
- isTransportDefined() {
1958
- try {
1959
- return Boolean(this.metamaskConnectMultichain.transport);
1960
- } catch (_error) {
1961
- return false;
1962
- }
1963
- }
1964
- clearNotificationCallbacks() {
1965
- __privateGet(this, _notificationCallbacks2).clear();
2215
+ var globalObj = getGlobalObject();
2216
+ var _a;
2217
+ (_a = globalObj.Buffer) != null ? _a : globalObj.Buffer = import_buffer.Buffer;
2218
+
2219
+ // src/index.browser.ts
2220
+ init_domain();
2221
+
2222
+ // src/multichain/index.ts
2223
+ var import_analytics4 = require("@metamask/analytics");
2224
+ var import_multichain_api_client3 = require("@metamask/multichain-api-client");
2225
+
2226
+ // src/config/index.ts
2227
+ var MWP_RELAY_URL = "wss://mm-sdk-relay.api.cx.metamask.io/connection/websocket";
2228
+ var METAMASK_CONNECT_BASE_URL = "https://metamask.app.link/connect";
2229
+ var METAMASK_DEEPLINK_BASE = "metamask://connect";
2230
+
2231
+ // src/multichain/index.ts
2232
+ init_domain();
2233
+ init_analytics();
2234
+ init_logger();
2235
+ init_multichain();
2236
+ init_platform();
2237
+
2238
+ // src/multichain/rpc/handlers/rpcClient.ts
2239
+ var import_cross_fetch = __toESM(require("cross-fetch"));
2240
+ init_domain();
2241
+ var rpcId = 1;
2242
+ function getNextRpcId() {
2243
+ rpcId += 1;
2244
+ return rpcId;
2245
+ }
2246
+ var MissingRpcEndpointErr = class extends Error {
2247
+ };
2248
+ var RpcClient = class {
2249
+ constructor(config, sdkInfo) {
2250
+ this.config = config;
2251
+ this.sdkInfo = sdkInfo;
1966
2252
  }
1967
- notifyCallbacks(data) {
1968
- __privateGet(this, _notificationCallbacks2).forEach((callback) => {
1969
- callback(data);
2253
+ /**
2254
+ * Routes the request to a configured RPC node.
2255
+ *
2256
+ * @param options - The invoke method options.
2257
+ * @returns The JSON response from the RPC node.
2258
+ */
2259
+ request(options) {
2260
+ return __async(this, null, function* () {
2261
+ const { request } = options;
2262
+ const body = JSON.stringify({
2263
+ jsonrpc: "2.0",
2264
+ method: request.method,
2265
+ params: request.params,
2266
+ id: getNextRpcId()
2267
+ });
2268
+ const rpcEndpoint = this.getRpcEndpoint(options.scope);
2269
+ const rpcRequest = yield this.fetchWithTimeout(
2270
+ rpcEndpoint,
2271
+ body,
2272
+ "POST",
2273
+ this.getHeaders(rpcEndpoint),
2274
+ 3e4
2275
+ );
2276
+ const response = yield this.parseResponse(rpcRequest);
2277
+ return response;
1970
2278
  });
1971
2279
  }
1972
- clearTransportNotificationListener() {
1973
- var _a3;
1974
- (_a3 = this.notificationListener) == null ? void 0 : _a3.call(this);
1975
- this.notificationListener = void 0;
1976
- }
1977
- setupTransportNotificationListener() {
1978
- if (!this.isTransportDefined() || this.notificationListener) {
1979
- return;
2280
+ getRpcEndpoint(scope) {
2281
+ var _a3, _b, _c;
2282
+ const supportedNetworks = (_c = (_b = (_a3 = this.config) == null ? void 0 : _a3.api) == null ? void 0 : _b.supportedNetworks) != null ? _c : {};
2283
+ const rpcEndpoint = supportedNetworks[scope];
2284
+ if (!rpcEndpoint) {
2285
+ throw new MissingRpcEndpointErr(
2286
+ `No RPC endpoint found for scope ${scope}`
2287
+ );
1980
2288
  }
1981
- this.notificationListener = this.metamaskConnectMultichain.transport.onNotification(
1982
- this.notifyCallbacks.bind(this)
1983
- );
1984
- }
1985
- connect() {
1986
- return __async(this, null, function* () {
1987
- console.log("\u{1F4DA} connect");
1988
- yield this.metamaskConnectMultichain.emitSessionChanged();
1989
- });
2289
+ return rpcEndpoint;
1990
2290
  }
1991
- disconnect() {
2291
+ fetchWithTimeout(endpoint, body, method, headers, timeout) {
1992
2292
  return __async(this, null, function* () {
1993
- return Promise.resolve();
1994
- });
1995
- }
1996
- isConnected() {
1997
- return true;
1998
- }
1999
- request(_0) {
2000
- return __async(this, arguments, function* (params, _options = {}) {
2001
- const id = getUniqueRequestId();
2002
- const requestPayload = __spreadValues({
2003
- id,
2004
- jsonrpc: "2.0"
2005
- }, params);
2006
- switch (requestPayload.method) {
2007
- case "wallet_createSession":
2008
- return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn).call(this, requestPayload);
2009
- case "wallet_getSession":
2010
- return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletGetSession_fn).call(this, requestPayload);
2011
- case "wallet_revokeSession":
2012
- return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletRevokeSession_fn).call(this, requestPayload);
2013
- case "wallet_invokeMethod":
2014
- return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletInvokeMethod_fn).call(this, requestPayload);
2015
- default:
2016
- throw new Error(`Unsupported method: ${requestPayload.method}`);
2017
- }
2018
- throw new Error(`Unknown method: ${requestPayload.method}`);
2019
- });
2020
- }
2021
- onNotification(callback) {
2022
- this.setupTransportNotificationListener();
2023
- __privateGet(this, _notificationCallbacks2).add(callback);
2024
- return () => {
2025
- __privateGet(this, _notificationCallbacks2).delete(callback);
2026
- };
2027
- }
2028
- };
2029
- _notificationCallbacks2 = new WeakMap();
2030
- _MultichainApiClientWrapperTransport_instances = new WeakSet();
2031
- walletCreateSession_fn = function(request) {
2032
- return __async(this, null, function* () {
2033
- const createSessionParams = request.params;
2034
- const scopes = Object.keys(__spreadValues(__spreadValues({}, createSessionParams.optionalScopes), createSessionParams.requiredScopes));
2035
- const scopeAccounts = [];
2036
- scopes.forEach((scope) => {
2037
- var _a3, _b, _c, _d;
2038
- const requiredScope = (_a3 = createSessionParams.requiredScopes) == null ? void 0 : _a3[scope];
2039
- const optionalScope = (_b = createSessionParams.optionalScopes) == null ? void 0 : _b[scope];
2040
- if (requiredScope) {
2041
- scopeAccounts.push(...(_c = requiredScope.accounts) != null ? _c : []);
2042
- }
2043
- if (optionalScope) {
2044
- scopeAccounts.push(...(_d = optionalScope.accounts) != null ? _d : []);
2293
+ const controller = new AbortController();
2294
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
2295
+ try {
2296
+ const response = yield (0, import_cross_fetch.default)(endpoint, {
2297
+ method,
2298
+ headers,
2299
+ body,
2300
+ signal: controller.signal
2301
+ });
2302
+ clearTimeout(timeoutId);
2303
+ if (!response.ok) {
2304
+ throw new RPCHttpErr(endpoint, method, response.status);
2305
+ }
2306
+ return response;
2307
+ } catch (error) {
2308
+ clearTimeout(timeoutId);
2309
+ if (error instanceof RPCHttpErr) {
2310
+ throw error;
2311
+ }
2312
+ if (error instanceof Error && error.name === "AbortError") {
2313
+ throw new RPCReadonlyRequestErr(`Request timeout after ${timeout}ms`);
2314
+ }
2315
+ throw new RPCReadonlyRequestErr(error.message);
2045
2316
  }
2046
2317
  });
2047
- const accounts = [...new Set(scopeAccounts)];
2048
- console.log("\u{1F4DA} SDK connect");
2049
- yield this.metamaskConnectMultichain.connect(
2050
- scopes,
2051
- accounts,
2052
- createSessionParams.sessionProperties
2053
- );
2054
- console.log("\u{1F4DA} SDK connected");
2055
- return this.metamaskConnectMultichain.transport.request({
2056
- method: "wallet_getSession"
2057
- });
2058
- });
2059
- };
2060
- walletGetSession_fn = function(request) {
2061
- return __async(this, null, function* () {
2062
- if (!this.isTransportDefined()) {
2063
- return {
2064
- jsonrpc: "2.0",
2065
- id: request.id,
2066
- result: {
2067
- sessionScopes: {}
2068
- }
2069
- };
2070
- }
2071
- return this.metamaskConnectMultichain.transport.request({
2072
- method: "wallet_getSession"
2318
+ }
2319
+ parseResponse(response) {
2320
+ return __async(this, null, function* () {
2321
+ try {
2322
+ const rpcResponse = yield response.json();
2323
+ return rpcResponse.result;
2324
+ } catch (error) {
2325
+ throw new RPCReadonlyResponseErr(error.message);
2326
+ }
2073
2327
  });
2074
- });
2075
- };
2076
- walletRevokeSession_fn = function(request) {
2077
- return __async(this, null, function* () {
2078
- var _a3;
2079
- if (!this.isTransportDefined()) {
2080
- return { jsonrpc: "2.0", id: request.id, result: true };
2081
- }
2082
- const revokeSessionParams = request.params;
2083
- const scopes = (_a3 = revokeSessionParams == null ? void 0 : revokeSessionParams.scopes) != null ? _a3 : [];
2084
- try {
2085
- yield this.metamaskConnectMultichain.disconnect(scopes);
2086
- return { jsonrpc: "2.0", id: request.id, result: true };
2087
- } catch (_error) {
2088
- return { jsonrpc: "2.0", id: request.id, result: false };
2089
- }
2090
- });
2091
- };
2092
- walletInvokeMethod_fn = function(request) {
2093
- return __async(this, null, function* () {
2094
- if (!this.isTransportDefined()) {
2095
- return { error: import_rpc_errors.providerErrors.unauthorized() };
2096
- }
2097
- const result = this.metamaskConnectMultichain.invokeMethod(
2098
- request.params
2099
- );
2100
- return {
2101
- result
2328
+ }
2329
+ getHeaders(rpcEndpoint) {
2330
+ const defaultHeaders = {
2331
+ Accept: "application/json",
2332
+ "Content-Type": "application/json"
2102
2333
  };
2103
- });
2334
+ if (rpcEndpoint.includes("infura")) {
2335
+ return __spreadProps(__spreadValues({}, defaultHeaders), {
2336
+ "Metamask-Sdk-Info": this.sdkInfo
2337
+ });
2338
+ }
2339
+ return defaultHeaders;
2340
+ }
2104
2341
  };
2105
2342
 
2106
- // src/multichain/transports/mwp/index.ts
2107
- var import_mobile_wallet_protocol_core = require("@metamask/mobile-wallet-protocol-core");
2108
- var import_multichain_api_client2 = require("@metamask/multichain-api-client");
2109
- var import_rpc_errors2 = require("@metamask/rpc-errors");
2343
+ // src/multichain/rpc/requestRouter.ts
2344
+ var import_analytics2 = require("@metamask/analytics");
2110
2345
  init_domain();
2111
2346
  init_utils2();
2112
-
2113
- // src/multichain/transports/constants.ts
2114
- var MULTICHAIN_PROVIDER_STREAM_NAME = "metamask-multichain-provider";
2115
-
2116
- // src/multichain/transports/mwp/index.ts
2117
- var DEFAULT_REQUEST_TIMEOUT2 = 60 * 1e3;
2118
- var CONNECTION_GRACE_PERIOD = 60 * 1e3;
2119
- var DEFAULT_CONNECTION_TIMEOUT = DEFAULT_REQUEST_TIMEOUT2 + CONNECTION_GRACE_PERIOD;
2120
- var DEFAULT_RESUME_TIMEOUT = 10 * 1e3;
2121
- var SESSION_STORE_KEY = "cache_wallet_getSession";
2122
- var ACCOUNTS_STORE_KEY = "cache_eth_accounts";
2123
- var CHAIN_STORE_KEY = "cache_eth_chainId";
2124
- var PENDING_SESSION_REQUEST_KEY = "pending_session_request";
2125
- var CACHED_METHOD_LIST = [
2126
- "wallet_getSession",
2127
- "wallet_createSession",
2128
- "wallet_sessionChanged"
2129
- ];
2130
- var CACHED_RESET_METHOD_LIST = [
2131
- "wallet_revokeSession",
2132
- "wallet_revokePermissions"
2133
- ];
2134
- var logger = createLogger("metamask-sdk:transport");
2135
- var MWPTransport = class {
2136
- constructor(dappClient, kvstore, options = {
2137
- requestTimeout: DEFAULT_REQUEST_TIMEOUT2,
2138
- connectionTimeout: DEFAULT_CONNECTION_TIMEOUT,
2139
- resumeTimeout: DEFAULT_RESUME_TIMEOUT
2140
- }) {
2141
- this.dappClient = dappClient;
2142
- this.kvstore = kvstore;
2143
- this.options = options;
2144
- this.__pendingRequests = /* @__PURE__ */ new Map();
2145
- this.notificationCallbacks = /* @__PURE__ */ new Set();
2146
- this.dappClient.on("message", this.handleMessage.bind(this));
2147
- this.dappClient.on("session_request", (sessionRequest) => {
2148
- this.currentSessionRequest = sessionRequest;
2149
- this.kvstore.set(PENDING_SESSION_REQUEST_KEY, JSON.stringify(sessionRequest)).catch((err) => {
2150
- logger("Failed to store pending session request", err);
2151
- });
2152
- });
2153
- if (typeof window !== "undefined" && typeof window.addEventListener !== "undefined") {
2154
- this.windowFocusHandler = this.onWindowFocus.bind(this);
2155
- window.addEventListener("focus", this.windowFocusHandler);
2156
- }
2157
- }
2158
- get pendingRequests() {
2159
- return this.__pendingRequests;
2160
- }
2161
- set pendingRequests(pendingRequests) {
2162
- this.__pendingRequests = pendingRequests;
2163
- }
2164
- get sessionRequest() {
2165
- return this.currentSessionRequest;
2347
+ init_analytics();
2348
+ var _RequestRouter_instances, withAnalyticsTracking_fn, trackWalletActionRequested_fn, trackWalletActionSucceeded_fn, trackWalletActionFailed_fn, trackWalletActionRejected_fn;
2349
+ var RequestRouter = class {
2350
+ constructor(transport, rpcClient, config, transportType) {
2351
+ this.transport = transport;
2352
+ this.rpcClient = rpcClient;
2353
+ this.config = config;
2354
+ this.transportType = transportType;
2355
+ __privateAdd(this, _RequestRouter_instances);
2166
2356
  }
2167
2357
  /**
2168
- * Returns the stored pending session request from the dappClient session_request event, if any.
2358
+ * The main entry point for invoking an RPC method.
2359
+ * This method acts as a router, determining the correct handling strategy
2360
+ * for the request and delegating to the appropriate private handler.
2169
2361
  *
2170
- * @returns The stored SessionRequest, or null if none or invalid.
2362
+ * @param options
2171
2363
  */
2172
- getStoredPendingSessionRequest() {
2364
+ invokeMethod(options) {
2173
2365
  return __async(this, null, function* () {
2174
- try {
2175
- const raw = yield this.kvstore.get(PENDING_SESSION_REQUEST_KEY);
2176
- if (!raw) {
2177
- return null;
2178
- }
2179
- return JSON.parse(raw);
2180
- } catch (e) {
2181
- return null;
2366
+ const { method } = options.request;
2367
+ if (RPC_HANDLED_METHODS.has(method)) {
2368
+ return this.handleWithRpcNode(options);
2369
+ }
2370
+ if (SDK_HANDLED_METHODS.has(method)) {
2371
+ return this.handleWithSdkState(options);
2182
2372
  }
2373
+ return this.handleWithWallet(options);
2183
2374
  });
2184
2375
  }
2185
2376
  /**
2186
- * Removes the stored pending session request from the KVStore.
2187
- * This is necessary to ensure that ConnectMultichain is able to correctly
2188
- * infer the MWP Transport connection attempt status.
2377
+ * Forwards the request directly to the wallet via the transport.
2378
+ *
2379
+ * @param options
2189
2380
  */
2190
- removeStoredPendingSessionRequest() {
2381
+ handleWithWallet(options) {
2191
2382
  return __async(this, null, function* () {
2192
- yield this.kvstore.delete(PENDING_SESSION_REQUEST_KEY);
2193
- });
2194
- }
2195
- onWindowFocus() {
2196
- if (!this.isConnected()) {
2197
- this.dappClient.reconnect();
2198
- }
2199
- }
2200
- notifyCallbacks(data) {
2201
- this.notificationCallbacks.forEach((callback) => callback(data));
2202
- }
2203
- rejectRequest(id, error = new Error("Request rejected")) {
2204
- const request = this.pendingRequests.get(id);
2205
- if (request) {
2206
- this.pendingRequests.delete(id);
2207
- clearTimeout(request.timeout);
2208
- request.reject(error);
2209
- }
2210
- }
2211
- parseWalletError(errorPayload) {
2212
- const errorData = errorPayload;
2213
- if (typeof errorData.code === "number" && typeof errorData.message === "string") {
2214
- const { code, message: message2 } = errorData;
2215
- if (code >= 1e3 && code <= 4999) {
2216
- return import_rpc_errors2.providerErrors.custom({ code, message: message2 });
2217
- }
2218
- return new import_rpc_errors2.JsonRpcError(code, message2);
2219
- }
2220
- const message = errorPayload instanceof Error ? errorPayload.message : JSON.stringify(errorPayload);
2221
- return import_rpc_errors2.rpcErrors.internal({ message });
2222
- }
2223
- handleMessage(message) {
2224
- if (typeof message === "object" && message !== null) {
2225
- if ("data" in message) {
2226
- const messagePayload = message.data;
2227
- if ("id" in messagePayload && typeof messagePayload.id === "string") {
2228
- const request = this.pendingRequests.get(messagePayload.id);
2229
- if (request) {
2230
- clearTimeout(request.timeout);
2231
- if ("error" in messagePayload && messagePayload.error) {
2232
- this.pendingRequests.delete(messagePayload.id);
2233
- request.reject(this.parseWalletError(messagePayload.error));
2234
- return;
2383
+ return __privateMethod(this, _RequestRouter_instances, withAnalyticsTracking_fn).call(this, options, () => __async(this, null, function* () {
2384
+ const request = this.transport.request({
2385
+ method: "wallet_invokeMethod",
2386
+ params: options
2387
+ });
2388
+ const { ui, mobile } = this.config;
2389
+ const { showInstallModal = false } = ui != null ? ui : {};
2390
+ const secure = isSecure();
2391
+ const shouldOpenDeeplink = secure && !showInstallModal;
2392
+ if (shouldOpenDeeplink) {
2393
+ setTimeout(() => __async(this, null, function* () {
2394
+ const session = yield this.transport.getActiveSession();
2395
+ if (!session) {
2396
+ throw new Error("No active session found");
2235
2397
  }
2236
- const requestWithName = __spreadProps(__spreadValues({}, messagePayload), {
2237
- method: request.method === "wallet_getSession" || request.method === "wallet_createSession" ? "wallet_sessionChanged" : request.method
2238
- });
2239
- const notification = __spreadProps(__spreadValues({}, messagePayload), {
2240
- method: request.method === "wallet_getSession" || request.method === "wallet_createSession" ? "wallet_sessionChanged" : request.method,
2241
- params: requestWithName.result
2242
- });
2243
- this.notifyCallbacks(notification);
2244
- request.resolve(requestWithName);
2245
- this.pendingRequests.delete(messagePayload.id);
2246
- }
2247
- } else {
2248
- if (message.data.method === "metamask_chainChanged") {
2249
- this.kvstore.set(
2250
- CHAIN_STORE_KEY,
2251
- JSON.stringify(
2252
- message.data.params.chainId
2253
- )
2254
- );
2255
- }
2256
- if (message.data.method === "metamask_accountsChanged") {
2257
- this.kvstore.set(
2258
- ACCOUNTS_STORE_KEY,
2259
- JSON.stringify(
2260
- message.data.params
2261
- )
2262
- );
2263
- }
2264
- if (message.data.method === "wallet_sessionChanged") {
2265
- const notification = message.data;
2266
- const response = {
2267
- result: notification.params
2268
- };
2269
- this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));
2270
- }
2271
- this.notifyCallbacks(message.data);
2398
+ const url = `${METAMASK_DEEPLINK_BASE}/mwp?id=${encodeURIComponent(session.id)}`;
2399
+ if (mobile == null ? void 0 : mobile.preferredOpenLink) {
2400
+ mobile.preferredOpenLink(url, "_self");
2401
+ } else {
2402
+ openDeeplink(this.config, url, METAMASK_CONNECT_BASE_URL);
2403
+ }
2404
+ }), 10);
2272
2405
  }
2273
- }
2274
- }
2406
+ const response = yield request;
2407
+ if (response.error) {
2408
+ const { error } = response;
2409
+ throw new RPCInvokeMethodErr(
2410
+ `RPC Request failed with code ${error.code}: ${error.message}`,
2411
+ error.code,
2412
+ error.message
2413
+ );
2414
+ }
2415
+ return response.result;
2416
+ }));
2417
+ });
2275
2418
  }
2276
- onResumeSuccess(resumeResolve, resumeReject, options) {
2419
+ /**
2420
+ * Routes the request to a configured RPC node.
2421
+ *
2422
+ * @param options
2423
+ */
2424
+ handleWithRpcNode(options) {
2277
2425
  return __async(this, null, function* () {
2278
- var _a3, _b, _c, _d, _e, _f, _g;
2279
2426
  try {
2280
- yield this.waitForWalletSessionIfNotCached();
2281
- const sessionRequest = yield this.request({
2282
- method: "wallet_getSession"
2283
- });
2284
- if (sessionRequest.error) {
2285
- return resumeReject(new Error(sessionRequest.error.message));
2286
- }
2287
- let walletSession = sessionRequest.result;
2288
- if (walletSession && options) {
2289
- const currentScopes = Object.keys(
2290
- (_a3 = walletSession == null ? void 0 : walletSession.sessionScopes) != null ? _a3 : {}
2291
- );
2292
- const proposedScopes = (_b = options == null ? void 0 : options.scopes) != null ? _b : [];
2293
- const proposedCaipAccountIds = (_c = options == null ? void 0 : options.caipAccountIds) != null ? _c : [];
2294
- const hasSameScopesAndAccounts = isSameScopesAndAccounts(
2295
- currentScopes,
2296
- proposedScopes,
2297
- walletSession,
2298
- proposedCaipAccountIds
2299
- );
2300
- if (options.forceRequest || !hasSameScopesAndAccounts) {
2301
- const optionalScopes = addValidAccounts(
2302
- getOptionalScopes((_d = options == null ? void 0 : options.scopes) != null ? _d : []),
2303
- getValidAccounts((_e = options == null ? void 0 : options.caipAccountIds) != null ? _e : [])
2304
- );
2305
- const sessionRequest2 = {
2306
- optionalScopes
2307
- };
2308
- const response = yield this.request({
2309
- method: "wallet_createSession",
2310
- params: sessionRequest2
2311
- });
2312
- if (response.error) {
2313
- return resumeReject(new Error(response.error.message));
2314
- }
2315
- walletSession = response.result;
2316
- }
2317
- } else if (!walletSession) {
2318
- const optionalScopes = addValidAccounts(
2319
- getOptionalScopes((_f = options == null ? void 0 : options.scopes) != null ? _f : []),
2320
- getValidAccounts((_g = options == null ? void 0 : options.caipAccountIds) != null ? _g : [])
2321
- );
2322
- const sessionRequest2 = { optionalScopes };
2323
- const response = yield this.request({
2324
- method: "wallet_createSession",
2325
- params: sessionRequest2
2326
- });
2327
- if (response.error) {
2328
- return resumeReject(new Error(response.error.message));
2329
- }
2330
- walletSession = response.result;
2427
+ return yield this.rpcClient.request(options);
2428
+ } catch (error) {
2429
+ if (error instanceof MissingRpcEndpointErr) {
2430
+ return this.handleWithWallet(options);
2331
2431
  }
2332
- yield this.removeStoredPendingSessionRequest();
2333
- this.notifyCallbacks({
2334
- method: "wallet_sessionChanged",
2335
- params: walletSession
2336
- });
2337
- return resumeResolve();
2338
- } catch (err) {
2339
- return resumeReject(err);
2432
+ throw error;
2340
2433
  }
2341
2434
  });
2342
2435
  }
2343
- init() {
2436
+ /**
2437
+ * Responds directly from the SDK's session state.
2438
+ *
2439
+ * @param options
2440
+ */
2441
+ handleWithSdkState(options) {
2344
2442
  return __async(this, null, function* () {
2443
+ console.warn(
2444
+ `Method "${options.request.method}" is configured for SDK state handling, but this is not yet implemented. Falling back to wallet passthrough.`
2445
+ );
2446
+ return this.handleWithWallet(options);
2447
+ });
2448
+ }
2449
+ };
2450
+ _RequestRouter_instances = new WeakSet();
2451
+ withAnalyticsTracking_fn = function(options, execute) {
2452
+ return __async(this, null, function* () {
2453
+ var _a3;
2454
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRequested_fn).call(this, options);
2455
+ try {
2456
+ const result = yield execute();
2457
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionSucceeded_fn).call(this, options);
2458
+ return result;
2459
+ } catch (error) {
2460
+ const isRejection = isRejectionError(error);
2461
+ if (isRejection) {
2462
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRejected_fn).call(this, options);
2463
+ } else {
2464
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options, error);
2465
+ }
2466
+ if (error instanceof RPCInvokeMethodErr) {
2467
+ throw error;
2468
+ }
2469
+ const castError = error;
2470
+ throw new RPCInvokeMethodErr(
2471
+ (_a3 = castError.message) != null ? _a3 : "Unknown error",
2472
+ castError.code
2473
+ );
2474
+ }
2475
+ });
2476
+ };
2477
+ trackWalletActionRequested_fn = function(options) {
2478
+ return __async(this, null, function* () {
2479
+ const props = yield getWalletActionAnalyticsProperties(
2480
+ this.config,
2481
+ this.config.storage,
2482
+ options,
2483
+ this.transportType
2484
+ );
2485
+ import_analytics2.analytics.track("mmconnect_wallet_action_requested", props);
2486
+ });
2487
+ };
2488
+ trackWalletActionSucceeded_fn = function(options) {
2489
+ return __async(this, null, function* () {
2490
+ const props = yield getWalletActionAnalyticsProperties(
2491
+ this.config,
2492
+ this.config.storage,
2493
+ options,
2494
+ this.transportType
2495
+ );
2496
+ import_analytics2.analytics.track("mmconnect_wallet_action_succeeded", props);
2497
+ });
2498
+ };
2499
+ trackWalletActionFailed_fn = function(options, error) {
2500
+ return __async(this, null, function* () {
2501
+ const props = yield getWalletActionAnalyticsProperties(
2502
+ this.config,
2503
+ this.config.storage,
2504
+ options,
2505
+ this.transportType,
2506
+ extractErrorDiagnostics(error)
2507
+ );
2508
+ import_analytics2.analytics.track("mmconnect_wallet_action_failed", props);
2509
+ });
2510
+ };
2511
+ trackWalletActionRejected_fn = function(options) {
2512
+ return __async(this, null, function* () {
2513
+ const props = yield getWalletActionAnalyticsProperties(
2514
+ this.config,
2515
+ this.config.storage,
2516
+ options,
2517
+ this.transportType
2518
+ );
2519
+ import_analytics2.analytics.track("mmconnect_wallet_action_rejected", props);
2520
+ });
2521
+ };
2522
+
2523
+ // src/multichain/transports/default/index.ts
2524
+ var import_multichain_api_client = require("@metamask/multichain-api-client");
2525
+ init_utils2();
2526
+ var DEFAULT_REQUEST_TIMEOUT = 60 * 1e3;
2527
+ var _notificationCallbacks, _transport, _defaultRequestOptions, _pendingRequests, _handleResponseListener, _handleNotificationListener, _DefaultTransport_instances, notifyCallbacks_fn, isMetamaskProviderEvent_fn, handleResponse_fn, handleNotification_fn, setupMessageListener_fn, init_fn;
2528
+ var DefaultTransport = class {
2529
+ constructor() {
2530
+ __privateAdd(this, _DefaultTransport_instances);
2531
+ __privateAdd(this, _notificationCallbacks, /* @__PURE__ */ new Set());
2532
+ __privateAdd(this, _transport, (0, import_multichain_api_client.getDefaultTransport)());
2533
+ __privateAdd(this, _defaultRequestOptions, {
2534
+ timeout: DEFAULT_REQUEST_TIMEOUT
2345
2535
  });
2536
+ __privateAdd(this, _pendingRequests, /* @__PURE__ */ new Map());
2537
+ __privateAdd(this, _handleResponseListener);
2538
+ __privateAdd(this, _handleNotificationListener);
2346
2539
  }
2347
- // TODO: Rename this
2348
2540
  sendEip1193Message(payload, options) {
2349
2541
  return __async(this, null, function* () {
2542
+ __privateMethod(this, _DefaultTransport_instances, setupMessageListener_fn).call(this);
2543
+ const requestId = String(getUniqueRequestId());
2350
2544
  const request = __spreadValues({
2351
2545
  jsonrpc: "2.0",
2352
- id: String(getUniqueRequestId())
2546
+ id: requestId
2353
2547
  }, payload);
2354
- const cachedWalletSession = yield this.getCachedResponse(request);
2355
- if (cachedWalletSession) {
2356
- this.notifyCallbacks(cachedWalletSession);
2357
- return cachedWalletSession;
2358
- }
2359
2548
  return new Promise((resolve, reject) => {
2360
2549
  var _a3;
2361
2550
  const timeout = setTimeout(() => {
2362
- this.rejectRequest(request.id, new import_multichain_api_client2.TransportTimeoutError());
2363
- }, (_a3 = options == null ? void 0 : options.timeout) != null ? _a3 : this.options.requestTimeout);
2364
- this.pendingRequests.set(request.id, {
2365
- request,
2366
- method: request.method,
2367
- resolve: (response) => __async(this, null, function* () {
2368
- yield this.storeWalletSession(request, response);
2369
- return resolve(response);
2370
- }),
2551
+ __privateGet(this, _pendingRequests).delete(requestId);
2552
+ reject(new Error("Request timeout"));
2553
+ }, (_a3 = options == null ? void 0 : options.timeout) != null ? _a3 : __privateGet(this, _defaultRequestOptions).timeout);
2554
+ __privateGet(this, _pendingRequests).set(requestId, {
2555
+ resolve: (response) => {
2556
+ resolve(response);
2557
+ },
2371
2558
  reject,
2372
2559
  timeout
2373
2560
  });
2374
- this.dappClient.sendRequest({
2375
- name: "metamask-provider",
2376
- data: request
2377
- }).catch(reject);
2561
+ window.postMessage(
2562
+ {
2563
+ target: "metamask-contentscript",
2564
+ data: {
2565
+ name: "metamask-provider",
2566
+ data: request
2567
+ }
2568
+ },
2569
+ // eslint-disable-next-line no-restricted-globals
2570
+ location.origin
2571
+ );
2572
+ });
2573
+ });
2574
+ }
2575
+ init() {
2576
+ return __async(this, null, function* () {
2577
+ yield __privateMethod(this, _DefaultTransport_instances, init_fn).call(this);
2578
+ let walletSession = { sessionScopes: {} };
2579
+ try {
2580
+ const sessionRequest = yield this.request(
2581
+ { method: "wallet_getSession" },
2582
+ __privateGet(this, _defaultRequestOptions)
2583
+ );
2584
+ walletSession = sessionRequest.result;
2585
+ } catch (e) {
2586
+ console.error(
2587
+ "Failed to get wallet session during DefaultTransport init"
2588
+ );
2589
+ }
2590
+ __privateMethod(this, _DefaultTransport_instances, notifyCallbacks_fn).call(this, {
2591
+ method: "wallet_sessionChanged",
2592
+ params: walletSession
2378
2593
  });
2379
2594
  });
2380
2595
  }
2381
2596
  connect(options) {
2382
2597
  return __async(this, null, function* () {
2383
- const { dappClient } = this;
2384
- const session = yield this.getActiveSession();
2385
- if (session) {
2386
- logger("active session found", {
2387
- id: session.id,
2388
- channel: session.channel,
2389
- expiresAt: session.expiresAt
2390
- });
2598
+ var _a3, _b, _c, _d, _e;
2599
+ yield __privateMethod(this, _DefaultTransport_instances, init_fn).call(this);
2600
+ const sessionRequest = yield this.request(
2601
+ { method: "wallet_getSession" },
2602
+ __privateGet(this, _defaultRequestOptions)
2603
+ );
2604
+ if (sessionRequest.error) {
2605
+ throw new Error(sessionRequest.error.message);
2391
2606
  }
2392
- const storedSessionRequestBeforeConnectionAttempt = yield this.getStoredPendingSessionRequest();
2393
- let timeout;
2394
- let initialConnectionMessageHandler;
2395
- const connectionPromise = new Promise((resolve, reject) => __async(this, null, function* () {
2396
- let connection;
2397
- if (session) {
2398
- connection = new Promise((resumeResolve, resumeReject) => {
2399
- var _a3;
2400
- if (this.dappClient.state === "CONNECTED") {
2401
- this.onResumeSuccess(resumeResolve, resumeReject, options);
2402
- } else {
2403
- this.dappClient.once("connected", () => __async(this, null, function* () {
2404
- this.onResumeSuccess(resumeResolve, resumeReject, options);
2405
- }));
2406
- dappClient.resume((_a3 = session == null ? void 0 : session.id) != null ? _a3 : "");
2407
- }
2408
- });
2409
- } else {
2410
- connection = new Promise(
2411
- (resolveConnection, rejectConnection) => {
2412
- var _a3, _b;
2413
- const optionalScopes = addValidAccounts(
2414
- getOptionalScopes((_a3 = options == null ? void 0 : options.scopes) != null ? _a3 : []),
2415
- getValidAccounts((_b = options == null ? void 0 : options.caipAccountIds) != null ? _b : [])
2416
- );
2417
- const sessionRequest = {
2418
- optionalScopes,
2419
- sessionProperties: options == null ? void 0 : options.sessionProperties
2420
- };
2421
- const request = {
2422
- jsonrpc: "2.0",
2423
- id: String(getUniqueRequestId()),
2424
- method: "wallet_createSession",
2425
- params: sessionRequest
2426
- };
2427
- initialConnectionMessageHandler = (message) => __async(this, null, function* () {
2428
- if (typeof message !== "object" || message === null) {
2429
- return;
2430
- }
2431
- if (!("data" in message)) {
2432
- return;
2433
- }
2434
- const messagePayload = message.data;
2435
- const isMatchingId = messagePayload.id === request.id;
2436
- const isMatchingMethod = messagePayload.method === "wallet_createSession" || messagePayload.method === "wallet_sessionChanged";
2437
- if (!isMatchingId && !isMatchingMethod) {
2438
- return;
2439
- }
2440
- if (messagePayload.error) {
2441
- return rejectConnection(
2442
- this.parseWalletError(messagePayload.error)
2443
- );
2444
- }
2445
- yield this.storeWalletSession(
2446
- request,
2447
- messagePayload
2448
- );
2449
- yield this.removeStoredPendingSessionRequest();
2450
- this.notifyCallbacks(messagePayload);
2451
- return resolveConnection();
2452
- });
2453
- this.dappClient.on("message", initialConnectionMessageHandler);
2454
- dappClient.connect({
2455
- mode: "trusted",
2456
- initialPayload: {
2457
- name: MULTICHAIN_PROVIDER_STREAM_NAME,
2458
- data: request
2459
- }
2460
- }).catch((error) => {
2461
- if (initialConnectionMessageHandler) {
2462
- this.dappClient.off(
2463
- "message",
2464
- initialConnectionMessageHandler
2465
- );
2466
- }
2467
- rejectConnection(error);
2468
- });
2469
- }
2607
+ let walletSession = sessionRequest.result;
2608
+ const createSessionParams = {
2609
+ optionalScopes: addValidAccounts(
2610
+ getOptionalScopes((_a3 = options == null ? void 0 : options.scopes) != null ? _a3 : []),
2611
+ getValidAccounts((_b = options == null ? void 0 : options.caipAccountIds) != null ? _b : [])
2612
+ ),
2613
+ sessionProperties: options == null ? void 0 : options.sessionProperties
2614
+ };
2615
+ if (walletSession && options && !options.forceRequest) {
2616
+ const currentScopes = Object.keys(
2617
+ (_c = walletSession == null ? void 0 : walletSession.sessionScopes) != null ? _c : {}
2618
+ );
2619
+ const proposedScopes = (_d = options == null ? void 0 : options.scopes) != null ? _d : [];
2620
+ const proposedCaipAccountIds = (_e = options == null ? void 0 : options.caipAccountIds) != null ? _e : [];
2621
+ const hasSameScopesAndAccounts = isSameScopesAndAccounts(
2622
+ currentScopes,
2623
+ proposedScopes,
2624
+ walletSession,
2625
+ proposedCaipAccountIds
2626
+ );
2627
+ if (!hasSameScopesAndAccounts) {
2628
+ const response = yield this.request(
2629
+ { method: "wallet_createSession", params: createSessionParams },
2630
+ __privateGet(this, _defaultRequestOptions)
2470
2631
  );
2632
+ if (response.error) {
2633
+ throw new Error(response.error.message);
2634
+ }
2635
+ walletSession = response.result;
2471
2636
  }
2472
- timeout = setTimeout(
2473
- () => {
2474
- reject(new import_multichain_api_client2.TransportTimeoutError());
2475
- },
2476
- storedSessionRequestBeforeConnectionAttempt ? this.options.resumeTimeout : this.options.connectionTimeout
2637
+ } else if (!walletSession || (options == null ? void 0 : options.forceRequest)) {
2638
+ const response = yield this.request(
2639
+ { method: "wallet_createSession", params: createSessionParams },
2640
+ __privateGet(this, _defaultRequestOptions)
2477
2641
  );
2478
- connection.then(resolve).catch(reject);
2479
- }));
2480
- return connectionPromise.catch((error) => __async(this, null, function* () {
2481
- yield this.dappClient.disconnect();
2482
- throw error;
2483
- })).finally(() => {
2484
- if (timeout) {
2485
- clearTimeout(timeout);
2486
- }
2487
- if (initialConnectionMessageHandler) {
2488
- this.dappClient.off("message", initialConnectionMessageHandler);
2489
- initialConnectionMessageHandler = void 0;
2642
+ if (response.error) {
2643
+ throw new Error(response.error.message);
2490
2644
  }
2491
- this.removeStoredPendingSessionRequest();
2645
+ walletSession = response.result;
2646
+ }
2647
+ __privateMethod(this, _DefaultTransport_instances, notifyCallbacks_fn).call(this, {
2648
+ method: "wallet_sessionChanged",
2649
+ params: walletSession
2492
2650
  });
2493
2651
  });
2494
2652
  }
2495
- /**
2496
- * Disconnects from the Mobile Wallet Protocol
2497
- *
2498
- * @param [scopes] - The scopes to revoke. If not provided or empty, all scopes will be revoked.
2499
- * @returns Nothing
2500
- */
2501
2653
  disconnect() {
2502
2654
  return __async(this, arguments, function* (scopes = []) {
2503
- var _a3, _b;
2504
- const cachedSession = yield this.getCachedResponse({
2505
- jsonrpc: "2.0",
2506
- id: "0",
2507
- method: "wallet_getSession"
2508
- });
2509
- const cachedSessionScopes = (_b = (_a3 = cachedSession == null ? void 0 : cachedSession.result) == null ? void 0 : _a3.sessionScopes) != null ? _b : {};
2510
- const remainingScopes = scopes.length === 0 ? [] : Object.keys(cachedSessionScopes).filter(
2511
- (scope) => !scopes.includes(scope)
2512
- );
2513
- const newSessionScopes = Object.fromEntries(
2514
- Object.entries(cachedSessionScopes).filter(
2515
- ([key]) => remainingScopes.includes(key)
2516
- )
2655
+ yield this.request({ method: "wallet_revokeSession", params: { scopes } });
2656
+ });
2657
+ }
2658
+ isConnected() {
2659
+ return __privateGet(this, _transport).isConnected();
2660
+ }
2661
+ request(_0) {
2662
+ return __async(this, arguments, function* (request, options = __privateGet(this, _defaultRequestOptions)) {
2663
+ return __privateGet(this, _transport).request(request, options);
2664
+ });
2665
+ }
2666
+ onNotification(callback) {
2667
+ __privateGet(this, _transport).onNotification(callback);
2668
+ __privateGet(this, _notificationCallbacks).add(callback);
2669
+ return () => {
2670
+ __privateGet(this, _notificationCallbacks).delete(callback);
2671
+ };
2672
+ }
2673
+ getActiveSession() {
2674
+ return __async(this, null, function* () {
2675
+ throw new Error(
2676
+ "getActiveSession is purposely not implemented for the DefaultTransport"
2517
2677
  );
2518
- this.request({ method: "wallet_revokeSession", params: { scopes } }).catch(
2519
- (err) => {
2520
- console.error("error revoking session", err);
2521
- }
2678
+ });
2679
+ }
2680
+ getStoredPendingSessionRequest() {
2681
+ return __async(this, null, function* () {
2682
+ throw new Error(
2683
+ "getStoredPendingSessionRequest is purposely not implemented for the DefaultTransport"
2522
2684
  );
2523
- const remainingScopesIncludeEip155 = remainingScopes.some(
2524
- (scope) => scope.includes("eip155")
2685
+ });
2686
+ }
2687
+ };
2688
+ _notificationCallbacks = new WeakMap();
2689
+ _transport = new WeakMap();
2690
+ _defaultRequestOptions = new WeakMap();
2691
+ _pendingRequests = new WeakMap();
2692
+ _handleResponseListener = new WeakMap();
2693
+ _handleNotificationListener = new WeakMap();
2694
+ _DefaultTransport_instances = new WeakSet();
2695
+ notifyCallbacks_fn = function(data) {
2696
+ for (const callback of __privateGet(this, _notificationCallbacks)) {
2697
+ try {
2698
+ callback(data);
2699
+ } catch (error) {
2700
+ console.log(
2701
+ "[WindowPostMessageTransport] notifyCallbacks error:",
2702
+ error
2525
2703
  );
2526
- if (!remainingScopesIncludeEip155) {
2527
- this.kvstore.delete(ACCOUNTS_STORE_KEY);
2528
- this.kvstore.delete(CHAIN_STORE_KEY);
2529
- }
2530
- if (remainingScopes.length > 0) {
2531
- this.kvstore.set(
2532
- SESSION_STORE_KEY,
2533
- JSON.stringify({
2534
- result: {
2535
- sessionScopes: newSessionScopes
2536
- }
2537
- })
2704
+ }
2705
+ }
2706
+ };
2707
+ isMetamaskProviderEvent_fn = function(event) {
2708
+ var _a3, _b;
2709
+ return ((_b = (_a3 = event == null ? void 0 : event.data) == null ? void 0 : _a3.data) == null ? void 0 : _b.name) === "metamask-provider" && // eslint-disable-next-line no-restricted-globals
2710
+ event.origin === location.origin;
2711
+ };
2712
+ handleResponse_fn = function(event) {
2713
+ var _a3, _b;
2714
+ if (!__privateMethod(this, _DefaultTransport_instances, isMetamaskProviderEvent_fn).call(this, event)) {
2715
+ return;
2716
+ }
2717
+ const responseData = (_b = (_a3 = event == null ? void 0 : event.data) == null ? void 0 : _a3.data) == null ? void 0 : _b.data;
2718
+ if (typeof responseData === "object" && responseData !== null && "method" in responseData) {
2719
+ return;
2720
+ }
2721
+ if (typeof responseData === "object" && responseData !== null && "id" in responseData && ("result" in responseData || "error" in responseData)) {
2722
+ const responseId = String(responseData.id);
2723
+ const pendingRequest = __privateGet(this, _pendingRequests).get(responseId);
2724
+ if (pendingRequest) {
2725
+ clearTimeout(pendingRequest.timeout);
2726
+ __privateGet(this, _pendingRequests).delete(responseId);
2727
+ const response = responseData;
2728
+ if ("error" in response && response.error) {
2729
+ const error = new Error(
2730
+ response.error.message || "Request failed"
2538
2731
  );
2539
- } else {
2540
- this.kvstore.delete(SESSION_STORE_KEY);
2541
- if (typeof window !== "undefined" && typeof window.removeEventListener !== "undefined" && this.windowFocusHandler) {
2542
- window.removeEventListener("focus", this.windowFocusHandler);
2543
- this.windowFocusHandler = void 0;
2732
+ if (typeof response.error.code === "number") {
2733
+ error.code = response.error.code;
2544
2734
  }
2545
- yield this.dappClient.disconnect();
2735
+ pendingRequest.reject(error);
2736
+ } else {
2737
+ pendingRequest.resolve(response);
2546
2738
  }
2547
- this.notifyCallbacks({
2548
- method: "wallet_sessionChanged",
2549
- params: {
2550
- sessionScopes: newSessionScopes
2551
- }
2552
- });
2553
- });
2739
+ }
2554
2740
  }
2555
- /**
2556
- * Checks if the transport is connected
2557
- *
2558
- * @returns True if transport is connected, false otherwise
2559
- */
2560
- isConnected() {
2561
- return this.dappClient.state === "CONNECTED";
2741
+ };
2742
+ handleNotification_fn = function(event) {
2743
+ var _a3, _b;
2744
+ if (!__privateMethod(this, _DefaultTransport_instances, isMetamaskProviderEvent_fn).call(this, event)) {
2745
+ return;
2562
2746
  }
2563
- /**
2564
- * Attempts to re-establish a connection via DappClient
2565
- *
2566
- * @returns Nothing
2567
- */
2568
- // TODO: We should re-evaluate adding this to the WebSocketTransport layer from `@metamask/mobile-wallet-protocol-core`
2569
- // ticket: https://consensyssoftware.atlassian.net/browse/WAPI-862
2570
- attemptResumeSession() {
2571
- return __async(this, null, function* () {
2572
- try {
2573
- yield this.dappClient.reconnect();
2574
- yield new Promise((resolve, reject) => {
2575
- const timeout = setTimeout(() => {
2576
- reject(new Error("Resume timeout"));
2577
- }, 2e3);
2578
- if (this.isConnected()) {
2579
- clearTimeout(timeout);
2580
- resolve();
2581
- } else {
2582
- this.dappClient.once("connected", () => {
2583
- clearTimeout(timeout);
2584
- resolve();
2585
- });
2586
- }
2587
- });
2588
- } catch (error) {
2589
- return Promise.reject(
2590
- new Error(`Failed to resume session: ${error.message}`)
2591
- );
2592
- }
2747
+ const responseData = (_b = (_a3 = event == null ? void 0 : event.data) == null ? void 0 : _a3.data) == null ? void 0 : _b.data;
2748
+ if (typeof responseData === "object" && responseData !== null && "method" in responseData) {
2749
+ __privateMethod(this, _DefaultTransport_instances, notifyCallbacks_fn).call(this, responseData);
2750
+ }
2751
+ };
2752
+ setupMessageListener_fn = function() {
2753
+ if (__privateGet(this, _handleResponseListener)) {
2754
+ return;
2755
+ }
2756
+ __privateSet(this, _handleResponseListener, __privateMethod(this, _DefaultTransport_instances, handleResponse_fn).bind(this));
2757
+ __privateSet(this, _handleNotificationListener, __privateMethod(this, _DefaultTransport_instances, handleNotification_fn).bind(this));
2758
+ window.addEventListener("message", __privateGet(this, _handleResponseListener));
2759
+ window.addEventListener("message", __privateGet(this, _handleNotificationListener));
2760
+ };
2761
+ init_fn = function() {
2762
+ return __async(this, null, function* () {
2763
+ __privateMethod(this, _DefaultTransport_instances, setupMessageListener_fn).call(this);
2764
+ if (!__privateGet(this, _transport).isConnected()) {
2765
+ yield __privateGet(this, _transport).connect();
2766
+ }
2767
+ });
2768
+ };
2769
+
2770
+ // src/multichain/transports/multichainApiClientWrapper/index.ts
2771
+ var import_rpc_errors = require("@metamask/rpc-errors");
2772
+ init_utils2();
2773
+ var _notificationCallbacks2, _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn, walletGetSession_fn, walletRevokeSession_fn, walletInvokeMethod_fn;
2774
+ var MultichainApiClientWrapperTransport = class {
2775
+ constructor(metamaskConnectMultichain) {
2776
+ this.metamaskConnectMultichain = metamaskConnectMultichain;
2777
+ __privateAdd(this, _MultichainApiClientWrapperTransport_instances);
2778
+ __privateAdd(this, _notificationCallbacks2, /* @__PURE__ */ new Set());
2779
+ }
2780
+ isTransportDefined() {
2781
+ try {
2782
+ return Boolean(this.metamaskConnectMultichain.transport);
2783
+ } catch (_error) {
2784
+ return false;
2785
+ }
2786
+ }
2787
+ isTransportConnected() {
2788
+ return this.isTransportDefined() && this.metamaskConnectMultichain.transport.isConnected();
2789
+ }
2790
+ clearNotificationCallbacks() {
2791
+ __privateGet(this, _notificationCallbacks2).clear();
2792
+ }
2793
+ notifyCallbacks(data) {
2794
+ __privateGet(this, _notificationCallbacks2).forEach((callback) => {
2795
+ callback(data);
2593
2796
  });
2594
2797
  }
2595
- getCachedResponse(request) {
2798
+ clearTransportNotificationListener() {
2799
+ var _a3;
2800
+ (_a3 = this.notificationListener) == null ? void 0 : _a3.call(this);
2801
+ this.notificationListener = void 0;
2802
+ }
2803
+ setupTransportNotificationListener() {
2804
+ if (!this.isTransportDefined() || this.notificationListener) {
2805
+ return;
2806
+ }
2807
+ this.notificationListener = this.metamaskConnectMultichain.transport.onNotification(
2808
+ this.notifyCallbacks.bind(this)
2809
+ );
2810
+ }
2811
+ // Purposely noop, resolves successfully. Actual connection is handled by the underlying client/transport.
2812
+ connect() {
2596
2813
  return __async(this, null, function* () {
2597
- var _a3;
2598
- if (request.method === "wallet_getSession") {
2599
- const walletGetSession = yield this.kvstore.get(SESSION_STORE_KEY);
2600
- if (walletGetSession) {
2601
- const walletSession = JSON.parse(walletGetSession);
2602
- return {
2603
- id: request.id,
2604
- jsonrpc: "2.0",
2605
- result: (_a3 = walletSession.params) != null ? _a3 : walletSession.result,
2606
- // "what?... why walletSession.params?.."
2607
- method: request.method
2608
- };
2609
- }
2610
- } else if (request.method === "eth_accounts") {
2611
- const ethAccounts = yield this.kvstore.get(ACCOUNTS_STORE_KEY);
2612
- if (ethAccounts) {
2613
- return {
2614
- id: request.id,
2615
- jsonrpc: "2.0",
2616
- result: JSON.parse(ethAccounts),
2617
- method: request.method
2618
- };
2619
- }
2620
- } else if (request.method === "eth_chainId") {
2621
- const ethChainId = yield this.kvstore.get(CHAIN_STORE_KEY);
2622
- if (ethChainId) {
2623
- return {
2624
- id: request.id,
2625
- jsonrpc: "2.0",
2626
- result: JSON.parse(ethChainId),
2627
- method: request.method
2628
- };
2629
- }
2630
- }
2814
+ return Promise.resolve();
2631
2815
  });
2632
2816
  }
2633
- storeWalletSession(request, response) {
2817
+ // Purposely noop, resolves successfully. Actual connection is handled by the underlying client/transport.
2818
+ disconnect() {
2634
2819
  return __async(this, null, function* () {
2635
- if (response.error) {
2636
- return;
2637
- }
2638
- if (CACHED_METHOD_LIST.includes(request.method)) {
2639
- yield this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));
2640
- } else if (request.method === "eth_accounts") {
2641
- yield this.kvstore.set(
2642
- ACCOUNTS_STORE_KEY,
2643
- JSON.stringify(response.result)
2644
- );
2645
- } else if (request.method === "eth_chainId") {
2646
- yield this.kvstore.set(CHAIN_STORE_KEY, JSON.stringify(response.result));
2647
- } else if (CACHED_RESET_METHOD_LIST.includes(request.method)) {
2648
- yield this.kvstore.delete(SESSION_STORE_KEY);
2649
- yield this.kvstore.delete(ACCOUNTS_STORE_KEY);
2650
- yield this.kvstore.delete(CHAIN_STORE_KEY);
2651
- }
2820
+ return Promise.resolve();
2652
2821
  });
2653
2822
  }
2654
- request(payload, options) {
2655
- return __async(this, null, function* () {
2656
- const request = __spreadValues({
2657
- jsonrpc: "2.0",
2658
- id: String(getUniqueRequestId())
2659
- }, payload);
2660
- const cachedWalletSession = yield this.getCachedResponse(request);
2661
- if (cachedWalletSession) {
2662
- this.notifyCallbacks(cachedWalletSession);
2663
- return cachedWalletSession;
2664
- }
2665
- if (!this.isConnected()) {
2666
- yield this.attemptResumeSession();
2823
+ // Purposely hardcoded to true. Actual connection is handled by the underlying client/transport.
2824
+ isConnected() {
2825
+ return true;
2826
+ }
2827
+ request(_0) {
2828
+ return __async(this, arguments, function* (params, _options = {}) {
2829
+ const id = getUniqueRequestId();
2830
+ const requestPayload = __spreadValues({
2831
+ id,
2832
+ jsonrpc: "2.0"
2833
+ }, params);
2834
+ switch (requestPayload.method) {
2835
+ case "wallet_createSession":
2836
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn).call(this, requestPayload);
2837
+ case "wallet_getSession":
2838
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletGetSession_fn).call(this, requestPayload);
2839
+ case "wallet_revokeSession":
2840
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletRevokeSession_fn).call(this, requestPayload);
2841
+ case "wallet_invokeMethod":
2842
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletInvokeMethod_fn).call(this, requestPayload);
2843
+ default:
2844
+ throw new Error(`Unsupported method: ${requestPayload.method}`);
2667
2845
  }
2668
- return new Promise((resolve, reject) => {
2669
- var _a3;
2670
- const timeout = setTimeout(() => {
2671
- this.rejectRequest(request.id, new import_multichain_api_client2.TransportTimeoutError());
2672
- }, (_a3 = options == null ? void 0 : options.timeout) != null ? _a3 : this.options.requestTimeout);
2673
- this.pendingRequests.set(request.id, {
2674
- request,
2675
- method: request.method,
2676
- resolve: (response) => __async(this, null, function* () {
2677
- yield this.storeWalletSession(request, response);
2678
- return resolve(response);
2679
- }),
2680
- reject,
2681
- timeout
2682
- });
2683
- this.dappClient.sendRequest({
2684
- name: MULTICHAIN_PROVIDER_STREAM_NAME,
2685
- data: request
2686
- }).catch(reject);
2687
- });
2688
2846
  });
2689
2847
  }
2690
2848
  onNotification(callback) {
2691
- this.notificationCallbacks.add(callback);
2849
+ this.setupTransportNotificationListener();
2850
+ __privateGet(this, _notificationCallbacks2).add(callback);
2692
2851
  return () => {
2693
- this.notificationCallbacks.delete(callback);
2852
+ __privateGet(this, _notificationCallbacks2).delete(callback);
2694
2853
  };
2695
2854
  }
2696
- getActiveSession() {
2697
- return __async(this, null, function* () {
2698
- const { kvstore } = this;
2699
- const sessionStore = yield import_mobile_wallet_protocol_core.SessionStore.create(kvstore);
2700
- try {
2701
- const [activeSession] = yield sessionStore.list();
2702
- return activeSession;
2703
- } catch (error) {
2704
- logger("error getting active session", error);
2705
- return void 0;
2855
+ };
2856
+ _notificationCallbacks2 = new WeakMap();
2857
+ _MultichainApiClientWrapperTransport_instances = new WeakSet();
2858
+ walletCreateSession_fn = function(request) {
2859
+ return __async(this, null, function* () {
2860
+ const createSessionParams = request.params;
2861
+ const scopes = Object.keys(__spreadValues(__spreadValues({}, createSessionParams.optionalScopes), createSessionParams.requiredScopes));
2862
+ const scopeAccounts = [];
2863
+ scopes.forEach((scope) => {
2864
+ var _a3, _b, _c, _d;
2865
+ const requiredScope = (_a3 = createSessionParams.requiredScopes) == null ? void 0 : _a3[scope];
2866
+ const optionalScope = (_b = createSessionParams.optionalScopes) == null ? void 0 : _b[scope];
2867
+ if (requiredScope) {
2868
+ scopeAccounts.push(...(_c = requiredScope.accounts) != null ? _c : []);
2706
2869
  }
2707
- });
2708
- }
2709
- // This method checks if an existing CAIP session response is cached or waits for one
2710
- // to be received from the wallet if not cached. This is necessary because there is an edge
2711
- // case during the initial connection flow where after the user has accepted the permission approval
2712
- // and returned back to the dapp from the wallet, the dapp page may have gotten unloaded and refreshed.
2713
- // When it is unloaded and refreshed, it will try to resume the session by making a request for wallet_getSession
2714
- // which should resolve from cache, but because a race condition makes it possible for the response from the wallet
2715
- // for the initial wallet_createSession connection request to not have been handled and cached yet. This results
2716
- // in the wallet_getSession request never resolving unless we wait for it explicitly as done in this method.
2717
- waitForWalletSessionIfNotCached() {
2718
- return __async(this, null, function* () {
2719
- const cachedWalletGetSessionResponse = yield this.kvstore.get(SESSION_STORE_KEY);
2720
- if (cachedWalletGetSessionResponse) {
2721
- return;
2870
+ if (optionalScope) {
2871
+ scopeAccounts.push(...(_d = optionalScope.accounts) != null ? _d : []);
2722
2872
  }
2723
- let unsubscribe;
2724
- const responsePromise = new Promise((resolve) => {
2725
- unsubscribe = this.onNotification((message) => {
2726
- if (typeof message === "object" && message !== null) {
2727
- if ("data" in message) {
2728
- const messagePayload = message.data;
2729
- if (messagePayload.method === "wallet_getSession" || messagePayload.method === "wallet_sessionChanged") {
2730
- unsubscribe();
2731
- resolve();
2732
- }
2733
- }
2734
- }
2735
- });
2736
- });
2737
- const timeoutPromise = new Promise((_resolve, reject) => {
2738
- setTimeout(() => {
2739
- unsubscribe();
2740
- this.removeStoredPendingSessionRequest();
2741
- reject(new import_multichain_api_client2.TransportTimeoutError());
2742
- }, this.options.resumeTimeout);
2743
- });
2744
- return Promise.race([responsePromise, timeoutPromise]);
2745
2873
  });
2746
- }
2874
+ const accounts = [...new Set(scopeAccounts)];
2875
+ yield this.metamaskConnectMultichain.connect(
2876
+ scopes,
2877
+ accounts,
2878
+ createSessionParams.sessionProperties
2879
+ );
2880
+ return this.metamaskConnectMultichain.transport.request({
2881
+ method: "wallet_getSession"
2882
+ });
2883
+ });
2747
2884
  };
2748
-
2749
- // src/multichain/transports/mwp/KeyManager.ts
2750
- var import_eciesjs = require("eciesjs");
2751
- var KeyManager = class {
2752
- generateKeyPair() {
2753
- const privateKey = new import_eciesjs.PrivateKey();
2885
+ walletGetSession_fn = function(request) {
2886
+ return __async(this, null, function* () {
2887
+ if (!this.isTransportConnected()) {
2888
+ return {
2889
+ jsonrpc: "2.0",
2890
+ id: request.id,
2891
+ result: {
2892
+ sessionScopes: {}
2893
+ }
2894
+ };
2895
+ }
2896
+ return this.metamaskConnectMultichain.transport.request({
2897
+ method: "wallet_getSession"
2898
+ });
2899
+ });
2900
+ };
2901
+ walletRevokeSession_fn = function(request) {
2902
+ return __async(this, null, function* () {
2903
+ var _a3;
2904
+ const revokeSessionParams = request.params;
2905
+ const scopes = (_a3 = revokeSessionParams == null ? void 0 : revokeSessionParams.scopes) != null ? _a3 : [];
2906
+ try {
2907
+ yield this.metamaskConnectMultichain.disconnect(scopes);
2908
+ return { jsonrpc: "2.0", id: request.id, result: true };
2909
+ } catch (_error) {
2910
+ return { jsonrpc: "2.0", id: request.id, result: false };
2911
+ }
2912
+ });
2913
+ };
2914
+ walletInvokeMethod_fn = function(request) {
2915
+ return __async(this, null, function* () {
2916
+ if (!this.isTransportConnected()) {
2917
+ return { error: import_rpc_errors.providerErrors.unauthorized() };
2918
+ }
2919
+ const result = this.metamaskConnectMultichain.invokeMethod(
2920
+ request.params
2921
+ );
2754
2922
  return {
2755
- privateKey: new Uint8Array(privateKey.secret),
2756
- publicKey: privateKey.publicKey.toBytes(true)
2923
+ result
2757
2924
  };
2758
- }
2759
- encrypt(plaintext, theirPublicKey) {
2760
- return __async(this, null, function* () {
2761
- const plaintextBuffer = Buffer.from(plaintext, "utf8");
2762
- const encryptedBuffer = (0, import_eciesjs.encrypt)(theirPublicKey, plaintextBuffer);
2763
- return encryptedBuffer.toString("base64");
2764
- });
2765
- }
2766
- decrypt(encryptedB64, myPrivateKey) {
2767
- return __async(this, null, function* () {
2768
- const encryptedBuffer = Buffer.from(encryptedB64, "base64");
2769
- const decryptedBuffer = yield (0, import_eciesjs.decrypt)(myPrivateKey, encryptedBuffer);
2770
- return Buffer.from(decryptedBuffer).toString("utf8");
2771
- });
2772
- }
2773
- validatePeerKey(key) {
2774
- import_eciesjs.PublicKey.fromHex(Buffer.from(key).toString("hex"));
2775
- }
2925
+ });
2776
2926
  };
2777
- var keymanager = new KeyManager();
2778
2927
 
2779
2928
  // src/multichain/index.ts
2780
2929
  init_utils2();
2781
2930
  var logger2 = createLogger("metamask-sdk:core");
2782
2931
  var SINGLETON_KEY = "__METAMASK_CONNECT_MULTICHAIN_SINGLETON__";
2783
- var _a2, _provider, _providerTransportWrapper, _transport2, _dappClient, _beforeUnloadListener, _listener, _anonId, _sdkInfo, _MetaMaskConnectMultichain_instances, setupAnalytics_fn, onTransportNotification_fn, getStoredTransport_fn, setupTransport_fn, buildConnectionMetadata_fn, init_fn2, createDappClient_fn, setupMWP_fn, onBeforeUnload_fn, createBeforeUnloadListener_fn, renderInstallModalAsync_fn, showInstallModal_fn, headlessConnect_fn, setupDefaultTransport_fn, deeplinkConnect_fn, handleConnection_fn, getCaipSession_fn, openConnectDeeplinkIfNeeded_fn;
2932
+ var _a2, _provider, _providerTransportWrapper, _transport2, _dappClient, _beforeUnloadListener, _transportType, _listener, _anonId, _sdkInfo, _MetaMaskConnectMultichain_instances, setupAnalytics_fn, onTransportNotification_fn, getStoredTransport_fn, setupTransport_fn, buildConnectionMetadata_fn, init_fn2, createDappClient_fn, setupMWP_fn, onBeforeUnload_fn, createBeforeUnloadListener_fn, renderInstallModalAsync_fn, showInstallModal_fn, headlessConnect_fn, setupDefaultTransport_fn, deeplinkConnect_fn, handleConnection_fn, getCaipSession_fn, openConnectDeeplinkIfNeeded_fn;
2784
2933
  var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends MultichainCore {
2785
2934
  constructor(options) {
2786
2935
  var _a3, _b, _c, _d, _e, _f;
@@ -2798,7 +2947,7 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2798
2947
  versions: __spreadValues({
2799
2948
  // typeof guard needed: Metro (React Native) bundles TS source directly,
2800
2949
  // bypassing the tsup build that substitutes __PACKAGE_VERSION__.
2801
- "connect-multichain": false ? "unknown" : "0.12.1"
2950
+ "connect-multichain": false ? "unknown" : "0.14.0"
2802
2951
  }, (_f = options.versions) != null ? _f : {})
2803
2952
  });
2804
2953
  super(allOptions);
@@ -2808,6 +2957,7 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2808
2957
  __privateAdd(this, _transport2);
2809
2958
  __privateAdd(this, _dappClient);
2810
2959
  __privateAdd(this, _beforeUnloadListener);
2960
+ __privateAdd(this, _transportType);
2811
2961
  this._status = "pending";
2812
2962
  __privateAdd(this, _listener);
2813
2963
  __privateAdd(this, _anonId);
@@ -2844,12 +2994,13 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2844
2994
  }
2845
2995
  return __privateGet(this, _dappClient);
2846
2996
  }
2997
+ get transportType() {
2998
+ var _a3;
2999
+ return (_a3 = __privateGet(this, _transportType)) != null ? _a3 : "unknown" /* UNKNOWN */;
3000
+ }
2847
3001
  get storage() {
2848
3002
  return this.options.storage;
2849
3003
  }
2850
- get transportType() {
2851
- return __privateGet(this, _transport2) instanceof MWPTransport ? "mwp" /* MWP */ : "browser" /* Browser */;
2852
- }
2853
3004
  // Creates a singleton instance of MetaMaskConnectMultichain.
2854
3005
  // If the singleton already exists, it merges the incoming options with the
2855
3006
  // existing singleton options for the following keys: `api.supportedNetworks`,
@@ -2903,7 +3054,7 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2903
3054
  connect(scopes, caipAccountIds, sessionProperties, forceRequest) {
2904
3055
  return __async(this, null, function* () {
2905
3056
  var _a3;
2906
- if (this.status === "connecting" && this.transportType === "mwp" /* MWP */) {
3057
+ if (this.status === "connecting" && __privateGet(this, _transportType) === "mwp" /* MWP */) {
2907
3058
  yield __privateMethod(this, _MetaMaskConnectMultichain_instances, openConnectDeeplinkIfNeeded_fn).call(this);
2908
3059
  throw new Error(
2909
3060
  "Existing connection is pending. Please check your MetaMask Mobile app to continue."
@@ -2952,7 +3103,7 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2952
3103
  sessionProperties: nonEmptySessionProperties,
2953
3104
  forceRequest
2954
3105
  }).then(() => __async(this, null, function* () {
2955
- if (__privateGet(this, _transport2) instanceof MWPTransport) {
3106
+ if (__privateGet(this, _transportType) === "mwp" /* MWP */) {
2956
3107
  return this.storage.setTransport("mwp" /* MWP */);
2957
3108
  }
2958
3109
  return this.storage.setTransport("browser" /* Browser */);
@@ -2999,12 +3150,13 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2999
3150
  yield (_a3 = __privateGet(this, _transport2)) == null ? void 0 : _a3.disconnect(scopes);
3000
3151
  if (remainingScopes.length === 0) {
3001
3152
  yield this.storage.removeTransport();
3002
- if (this.transportType !== "browser" /* Browser */) {
3153
+ if (__privateGet(this, _transportType) !== "browser" /* Browser */) {
3003
3154
  yield (_b = __privateGet(this, _listener)) == null ? void 0 : _b.call(this);
3004
3155
  (_c = __privateGet(this, _beforeUnloadListener)) == null ? void 0 : _c.call(this);
3005
3156
  __privateSet(this, _listener, void 0);
3006
3157
  __privateSet(this, _beforeUnloadListener, void 0);
3007
3158
  __privateSet(this, _transport2, void 0);
3159
+ __privateSet(this, _transportType, void 0);
3008
3160
  __privateGet(this, _providerTransportWrapper).clearTransportNotificationListener();
3009
3161
  __privateSet(this, _dappClient, void 0);
3010
3162
  }
@@ -3014,13 +3166,14 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
3014
3166
  }
3015
3167
  invokeMethod(request) {
3016
3168
  return __async(this, null, function* () {
3169
+ var _a3;
3017
3170
  const { transport, options } = this;
3018
3171
  const rpcClient = new RpcClient(options, __privateGet(this, _sdkInfo));
3019
3172
  const requestRouter = new RequestRouter(
3020
3173
  transport,
3021
3174
  rpcClient,
3022
3175
  options,
3023
- this.transportType
3176
+ (_a3 = __privateGet(this, _transportType)) != null ? _a3 : "unknown" /* UNKNOWN */
3024
3177
  );
3025
3178
  return requestRouter.invokeMethod(request);
3026
3179
  });
@@ -3069,6 +3222,7 @@ _providerTransportWrapper = new WeakMap();
3069
3222
  _transport2 = new WeakMap();
3070
3223
  _dappClient = new WeakMap();
3071
3224
  _beforeUnloadListener = new WeakMap();
3225
+ _transportType = new WeakMap();
3072
3226
  _listener = new WeakMap();
3073
3227
  _anonId = new WeakMap();
3074
3228
  _sdkInfo = new WeakMap();
@@ -3126,6 +3280,7 @@ getStoredTransport_fn = function() {
3126
3280
  if (hasExtensionInstalled) {
3127
3281
  const apiTransport = new DefaultTransport();
3128
3282
  __privateSet(this, _transport2, apiTransport);
3283
+ __privateSet(this, _transportType, "browser" /* Browser */);
3129
3284
  __privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
3130
3285
  __privateSet(this, _listener, apiTransport.onNotification(
3131
3286
  __privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
@@ -3135,9 +3290,11 @@ getStoredTransport_fn = function() {
3135
3290
  } else if (transportType === "mwp" /* MWP */) {
3136
3291
  const { adapter: kvstore } = this.options.storage;
3137
3292
  const dappClient = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, createDappClient_fn).call(this);
3138
- const apiTransport = new MWPTransport(dappClient, kvstore);
3293
+ const { MWPTransport: MWPTransport2 } = yield Promise.resolve().then(() => (init_mwp(), mwp_exports));
3294
+ const apiTransport = new MWPTransport2(dappClient, kvstore);
3139
3295
  __privateSet(this, _dappClient, dappClient);
3140
3296
  __privateSet(this, _transport2, apiTransport);
3297
+ __privateSet(this, _transportType, "mwp" /* MWP */);
3141
3298
  __privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
3142
3299
  __privateSet(this, _listener, apiTransport.onNotification(
3143
3300
  __privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
@@ -3159,7 +3316,7 @@ setupTransport_fn = function() {
3159
3316
  yield this.transport.connect();
3160
3317
  }
3161
3318
  this.status = "connected";
3162
- if (this.transport instanceof MWPTransport) {
3319
+ if (__privateGet(this, _transportType) === "mwp" /* MWP */) {
3163
3320
  yield this.storage.setTransport("mwp" /* MWP */);
3164
3321
  } else {
3165
3322
  yield this.storage.setTransport("browser" /* Browser */);
@@ -3203,31 +3360,43 @@ init_fn2 = function() {
3203
3360
  };
3204
3361
  createDappClient_fn = function() {
3205
3362
  return __async(this, null, function* () {
3363
+ const [mwpCore, { DappClient: DappClientClass }, { createKeyManager: createKeyManager2 }] = yield Promise.all([
3364
+ import("@metamask/mobile-wallet-protocol-core"),
3365
+ import("@metamask/mobile-wallet-protocol-dapp-client"),
3366
+ Promise.resolve().then(() => (init_KeyManager(), KeyManager_exports))
3367
+ ]);
3368
+ const keymanager = yield createKeyManager2();
3206
3369
  const { adapter: kvstore } = this.options.storage;
3207
- const sessionstore = yield import_mobile_wallet_protocol_core2.SessionStore.create(kvstore);
3370
+ const sessionstore = yield mwpCore.SessionStore.create(kvstore);
3208
3371
  const websocket = (
3209
3372
  // eslint-disable-next-line no-negated-condition
3210
3373
  typeof window !== "undefined" ? WebSocket : (yield import("ws")).WebSocket
3211
3374
  );
3212
- const transport = yield import_mobile_wallet_protocol_core2.WebSocketTransport.create({
3375
+ const transport = yield mwpCore.WebSocketTransport.create({
3213
3376
  url: MWP_RELAY_URL,
3214
3377
  kvstore,
3215
3378
  websocket
3216
3379
  });
3217
- const dappClient = new import_mobile_wallet_protocol_dapp_client.DappClient({ transport, sessionstore, keymanager });
3380
+ const dappClient = new DappClientClass({
3381
+ transport,
3382
+ sessionstore,
3383
+ keymanager
3384
+ });
3218
3385
  return dappClient;
3219
3386
  });
3220
3387
  };
3221
3388
  setupMWP_fn = function() {
3222
3389
  return __async(this, null, function* () {
3223
- if (__privateGet(this, _transport2) instanceof MWPTransport) {
3390
+ if (__privateGet(this, _transportType) === "mwp" /* MWP */) {
3224
3391
  return;
3225
3392
  }
3226
3393
  const { adapter: kvstore } = this.options.storage;
3227
3394
  const dappClient = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, createDappClient_fn).call(this);
3228
3395
  __privateSet(this, _dappClient, dappClient);
3229
- const apiTransport = new MWPTransport(dappClient, kvstore);
3396
+ const { MWPTransport: MWPTransport2 } = yield Promise.resolve().then(() => (init_mwp(), mwp_exports));
3397
+ const apiTransport = new MWPTransport2(dappClient, kvstore);
3230
3398
  __privateSet(this, _transport2, apiTransport);
3399
+ __privateSet(this, _transportType, "mwp" /* MWP */);
3231
3400
  __privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
3232
3401
  __privateSet(this, _listener, this.transport.onNotification(
3233
3402
  __privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
@@ -3286,8 +3455,9 @@ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds,
3286
3455
  this.status = "connected";
3287
3456
  yield this.storage.setTransport("mwp" /* MWP */);
3288
3457
  } catch (error) {
3289
- if (error instanceof import_mobile_wallet_protocol_core2.ProtocolError) {
3290
- if (error.code !== import_mobile_wallet_protocol_core2.ErrorCode.REQUEST_EXPIRED) {
3458
+ const { ProtocolError, ErrorCode } = yield import("@metamask/mobile-wallet-protocol-core");
3459
+ if (error instanceof ProtocolError) {
3460
+ if (error.code !== ErrorCode.REQUEST_EXPIRED) {
3291
3461
  this.status = "disconnected";
3292
3462
  yield this.options.ui.factory.unload(error);
3293
3463
  reject(error);
@@ -3355,7 +3525,8 @@ headlessConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
3355
3525
  yield this.storage.setTransport("mwp" /* MWP */);
3356
3526
  resolve();
3357
3527
  })).catch((error) => __async(this, null, function* () {
3358
- if (error instanceof import_mobile_wallet_protocol_core2.ProtocolError) {
3528
+ const { ProtocolError } = yield import("@metamask/mobile-wallet-protocol-core");
3529
+ if (error instanceof ProtocolError) {
3359
3530
  this.status = "disconnected";
3360
3531
  yield this.storage.removeTransport();
3361
3532
  reject(error);
@@ -3370,7 +3541,7 @@ headlessConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
3370
3541
  };
3371
3542
  setupDefaultTransport_fn = function() {
3372
3543
  return __async(this, arguments, function* (options = { persist: true }) {
3373
- if (__privateGet(this, _transport2) instanceof DefaultTransport) {
3544
+ if (__privateGet(this, _transportType) === "browser" /* Browser */) {
3374
3545
  return __privateGet(this, _transport2);
3375
3546
  }
3376
3547
  if (options == null ? void 0 : options.persist) {
@@ -3381,6 +3552,7 @@ setupDefaultTransport_fn = function() {
3381
3552
  __privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
3382
3553
  ));
3383
3554
  __privateSet(this, _transport2, transport);
3555
+ __privateSet(this, _transportType, "browser" /* Browser */);
3384
3556
  __privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
3385
3557
  return transport;
3386
3558
  });
@@ -3477,9 +3649,9 @@ handleConnection_fn = function(promise, scopes, transportType) {
3477
3649
  transport_type: transportType
3478
3650
  }));
3479
3651
  } else {
3480
- import_analytics4.analytics.track("mmconnect_connection_failed", __spreadProps(__spreadValues({}, baseProps), {
3652
+ import_analytics4.analytics.track("mmconnect_connection_failed", __spreadValues(__spreadProps(__spreadValues({}, baseProps), {
3481
3653
  transport_type: transportType
3482
- }));
3654
+ }), extractErrorDiagnostics(error)));
3483
3655
  }
3484
3656
  } catch (e) {
3485
3657
  logger2("Error tracking connection failed/rejected event", error);