@metamask/connect-multichain 0.13.0 → 0.15.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 (51) hide show
  1. package/CHANGELOG.md +24 -1
  2. package/README.md +20 -19
  3. package/dist/browser/es/connect-multichain.d.mts +62 -6
  4. package/dist/browser/es/connect-multichain.mjs +286 -124
  5. package/dist/browser/es/connect-multichain.mjs.map +1 -1
  6. package/dist/browser/es/metafile-esm.json +1 -1
  7. package/dist/browser/iife/connect-multichain.d.ts +62 -6
  8. package/dist/browser/iife/connect-multichain.js +304 -124
  9. package/dist/browser/iife/connect-multichain.js.map +1 -1
  10. package/dist/browser/iife/metafile-iife.json +1 -1
  11. package/dist/browser/umd/connect-multichain.d.ts +62 -6
  12. package/dist/browser/umd/connect-multichain.js +286 -124
  13. package/dist/browser/umd/connect-multichain.js.map +1 -1
  14. package/dist/browser/umd/metafile-cjs.json +1 -1
  15. package/dist/node/cjs/connect-multichain.d.ts +62 -6
  16. package/dist/node/cjs/connect-multichain.js +287 -124
  17. package/dist/node/cjs/connect-multichain.js.map +1 -1
  18. package/dist/node/cjs/metafile-cjs.json +1 -1
  19. package/dist/node/es/connect-multichain.d.mts +62 -6
  20. package/dist/node/es/connect-multichain.mjs +286 -124
  21. package/dist/node/es/connect-multichain.mjs.map +1 -1
  22. package/dist/node/es/metafile-esm.json +1 -1
  23. package/dist/react-native/es/connect-multichain.d.mts +62 -6
  24. package/dist/react-native/es/connect-multichain.mjs +286 -124
  25. package/dist/react-native/es/connect-multichain.mjs.map +1 -1
  26. package/dist/react-native/es/metafile-esm.json +1 -1
  27. package/dist/src/domain/multichain/index.d.ts +1 -1
  28. package/dist/src/domain/multichain/index.d.ts.map +1 -1
  29. package/dist/src/domain/multichain/index.js +7 -3
  30. package/dist/src/domain/multichain/index.js.map +1 -1
  31. package/dist/src/domain/multichain/types.d.ts +15 -3
  32. package/dist/src/domain/multichain/types.d.ts.map +1 -1
  33. package/dist/src/domain/utils/index.d.ts +2 -1
  34. package/dist/src/domain/utils/index.d.ts.map +1 -1
  35. package/dist/src/domain/utils/index.js +1 -1
  36. package/dist/src/domain/utils/index.js.map +1 -1
  37. package/dist/src/multichain/index.d.ts.map +1 -1
  38. package/dist/src/multichain/index.js +109 -63
  39. package/dist/src/multichain/index.js.map +1 -1
  40. package/dist/src/multichain/rpc/requestRouter.d.ts.map +1 -1
  41. package/dist/src/multichain/rpc/requestRouter.js +27 -9
  42. package/dist/src/multichain/rpc/requestRouter.js.map +1 -1
  43. package/dist/src/multichain/transports/mwp/index.d.ts.map +1 -1
  44. package/dist/src/multichain/transports/mwp/index.js +17 -5
  45. package/dist/src/multichain/transports/mwp/index.js.map +1 -1
  46. package/dist/src/multichain/utils/analytics.d.ts +82 -1
  47. package/dist/src/multichain/utils/analytics.d.ts.map +1 -1
  48. package/dist/src/multichain/utils/analytics.js +252 -17
  49. package/dist/src/multichain/utils/analytics.js.map +1 -1
  50. package/dist/types/connect-multichain.d.ts +62 -6
  51. package/package.json +2 -2
@@ -472,7 +472,7 @@ var init_multichain = __esm({
472
472
  }
473
473
  /**
474
474
  * Merges the given options into the current instance options.
475
- * Only the mergeable keys are updated (api.supportedNetworks, versions, ui.*, mobile.*, transport.extensionId, debug).
475
+ * Only the mergeable keys are updated (api.supportedNetworks, analytics, versions, ui.*, mobile.*, transport.extensionId, debug).
476
476
  * The main thing to note is that the value for `dapp` is not merged as it does not make sense for
477
477
  * subsequent calls to `createMultichainClient` to have a different `dapp` value.
478
478
  * Used when createMultichainClient is called with an existing singleton.
@@ -480,23 +480,28 @@ var init_multichain = __esm({
480
480
  * @param partial - Options to merge/overwrite onto the current instance
481
481
  */
482
482
  mergeOptions(partial) {
483
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
483
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
484
484
  const opts = this.options;
485
+ const analytics3 = __spreadValues(__spreadValues({}, opts.analytics), (_a2 = partial.analytics) != null ? _a2 : {});
486
+ if (((_b = opts.analytics) == null ? void 0 : _b.enabled) === false) {
487
+ analytics3.enabled = false;
488
+ }
485
489
  this.options = __spreadProps(__spreadValues({}, opts), {
486
490
  api: __spreadProps(__spreadValues({}, opts.api), {
487
- supportedNetworks: __spreadValues(__spreadValues({}, opts.api.supportedNetworks), (_b = (_a2 = partial.api) == null ? void 0 : _a2.supportedNetworks) != null ? _b : {})
491
+ supportedNetworks: __spreadValues(__spreadValues({}, opts.api.supportedNetworks), (_d = (_c = partial.api) == null ? void 0 : _c.supportedNetworks) != null ? _d : {})
488
492
  }),
489
- versions: __spreadValues(__spreadValues({}, opts.versions), (_c = partial.versions) != null ? _c : {}),
493
+ versions: __spreadValues(__spreadValues({}, opts.versions), (_e = partial.versions) != null ? _e : {}),
494
+ analytics: __spreadValues({}, analytics3),
490
495
  ui: __spreadProps(__spreadValues({}, opts.ui), {
491
- headless: (_e = (_d = partial.ui) == null ? void 0 : _d.headless) != null ? _e : opts.ui.headless,
492
- preferExtension: (_g = (_f = partial.ui) == null ? void 0 : _f.preferExtension) != null ? _g : opts.ui.preferExtension,
493
- showInstallModal: (_i = (_h = partial.ui) == null ? void 0 : _h.showInstallModal) != null ? _i : opts.ui.showInstallModal
496
+ headless: (_g = (_f = partial.ui) == null ? void 0 : _f.headless) != null ? _g : opts.ui.headless,
497
+ preferExtension: (_i = (_h = partial.ui) == null ? void 0 : _h.preferExtension) != null ? _i : opts.ui.preferExtension,
498
+ showInstallModal: (_k = (_j = partial.ui) == null ? void 0 : _j.showInstallModal) != null ? _k : opts.ui.showInstallModal
494
499
  }),
495
- mobile: __spreadValues(__spreadValues({}, opts.mobile), (_j = partial.mobile) != null ? _j : {}),
496
- transport: __spreadProps(__spreadValues({}, (_k = opts.transport) != null ? _k : {}), {
497
- extensionId: (_n = (_l = partial.transport) == null ? void 0 : _l.extensionId) != null ? _n : (_m = opts.transport) == null ? void 0 : _m.extensionId
500
+ mobile: __spreadValues(__spreadValues({}, opts.mobile), (_l = partial.mobile) != null ? _l : {}),
501
+ transport: __spreadProps(__spreadValues({}, (_m = opts.transport) != null ? _m : {}), {
502
+ extensionId: (_p = (_n = partial.transport) == null ? void 0 : _n.extensionId) != null ? _p : (_o = opts.transport) == null ? void 0 : _o.extensionId
498
503
  }),
499
- debug: (_o = partial.debug) != null ? _o : opts.debug
504
+ debug: (_q = partial.debug) != null ? _q : opts.debug
500
505
  });
501
506
  }
502
507
  };
@@ -949,17 +954,94 @@ var init_utils = __esm({
949
954
  });
950
955
 
951
956
  // src/multichain/utils/analytics.ts
957
+ function sanitiseErrorMessage(message) {
958
+ if (!message) {
959
+ return void 0;
960
+ }
961
+ let sanitised = message;
962
+ for (const { pattern, replacement } of SANITISE_PATTERNS) {
963
+ sanitised = sanitised.replace(pattern, replacement);
964
+ }
965
+ if (sanitised.length > ERROR_MESSAGE_SAMPLE_MAX_LENGTH) {
966
+ sanitised = `${sanitised.slice(0, ERROR_MESSAGE_SAMPLE_MAX_LENGTH - 1)}\u2026`;
967
+ }
968
+ return sanitised;
969
+ }
970
+ function getUnwrappedErrorDetails(error) {
971
+ var _a2, _b, _c, _d;
972
+ if (typeof error !== "object" || error === null) {
973
+ return { code: void 0, message: "" };
974
+ }
975
+ if (error instanceof RPCInvokeMethodErr) {
976
+ return {
977
+ code: (_a2 = error.rpcCode) != null ? _a2 : error.code,
978
+ message: (_c = (_b = error.rpcMessage) != null ? _b : error.message) != null ? _c : ""
979
+ };
980
+ }
981
+ const errorObj = error;
982
+ return {
983
+ code: errorObj.code,
984
+ message: (_d = errorObj.message) != null ? _d : ""
985
+ };
986
+ }
952
987
  function isRejectionError(error) {
953
- var _a2, _b;
954
988
  if (typeof error !== "object" || error === null) {
955
989
  return false;
956
990
  }
991
+ const { code, message } = getUnwrappedErrorDetails(error);
992
+ const errorMessage = message.toLowerCase();
993
+ return code === 4001 || errorMessage.includes("reject") || errorMessage.includes("denied") || errorMessage.includes("cancel") || // Narrow "user …" matches — bare "user" is too greedy (catches Account
994
+ // Abstraction errors like "user operation reverted").
995
+ errorMessage.includes("user rejected") || errorMessage.includes("user denied") || errorMessage.includes("user cancelled") || errorMessage.includes("user canceled");
996
+ }
997
+ function classifyFailureReason(error) {
998
+ var _a2, _b;
999
+ if (typeof error !== "object" || error === null) {
1000
+ return "unknown";
1001
+ }
957
1002
  const errorObj = error;
958
- const errorCode = errorObj.code;
959
- const errorMessage = (_b = (_a2 = errorObj.message) == null ? void 0 : _a2.toLowerCase()) != null ? _b : "";
960
- return errorCode === 4001 || // User rejected request (common EIP-1193 code)
961
- errorCode === 4100 || // Unauthorized (common rejection code)
962
- errorMessage.includes("reject") || errorMessage.includes("denied") || errorMessage.includes("cancel") || errorMessage.includes("user");
1003
+ const errorName = (_a2 = errorObj.name) != null ? _a2 : "";
1004
+ const errorMessageRaw = (_b = errorObj.message) != null ? _b : "";
1005
+ const errorMessage = errorMessageRaw.toLowerCase();
1006
+ const { code } = getUnwrappedErrorDetails(error);
1007
+ if (typeof code === "number") {
1008
+ if (code === -32601) {
1009
+ return "wallet_method_unsupported";
1010
+ }
1011
+ if (code === -32602) {
1012
+ return "wallet_invalid_params";
1013
+ }
1014
+ if (code === -32603) {
1015
+ return "wallet_internal_error";
1016
+ }
1017
+ if (code <= -32e3 && code >= -32099) {
1018
+ return "wallet_internal_error";
1019
+ }
1020
+ if (code === 4100) {
1021
+ return "wallet_unauthorized";
1022
+ }
1023
+ if (code === 4200) {
1024
+ return "wallet_method_unsupported";
1025
+ }
1026
+ if (code === 4902) {
1027
+ return "unrecognized_chain";
1028
+ }
1029
+ }
1030
+ if (errorName === "TransportTimeoutError" || errorMessageRaw === "Request timeout" || errorMessage.includes("timed out") || errorMessage.includes("timeout")) {
1031
+ return "transport_timeout";
1032
+ }
1033
+ if (errorName === "TransportError" || errorMessage.includes("not connected") || errorMessage.includes("transport disconnect") || errorMessage.includes("connection lost") || errorMessage.includes("socket closed")) {
1034
+ return "transport_disconnect";
1035
+ }
1036
+ return "unknown";
1037
+ }
1038
+ function extractErrorDiagnostics(error) {
1039
+ const failureReason = classifyFailureReason(error);
1040
+ const { code, message } = getUnwrappedErrorDetails(error);
1041
+ const messageSample = sanitiseErrorMessage(message);
1042
+ return __spreadValues(__spreadValues({
1043
+ failure_reason: failureReason
1044
+ }, typeof code === "number" ? { error_code: code } : {}), messageSample ? { error_message_sample: messageSample } : {});
963
1045
  }
964
1046
  function getBaseAnalyticsProperties(options, storage) {
965
1047
  return __async(this, null, function* () {
@@ -975,26 +1057,61 @@ function getBaseAnalyticsProperties(options, storage) {
975
1057
  };
976
1058
  });
977
1059
  }
978
- function getWalletActionAnalyticsProperties(options, storage, invokeOptions, transportType) {
1060
+ function getWalletActionAnalyticsProperties(options, storage, invokeOptions, transportType, extra) {
979
1061
  return __async(this, null, function* () {
980
1062
  var _a2;
981
1063
  const dappId = getDappId(options.dapp);
982
1064
  const anonId = yield storage.getAnonId();
983
- return {
1065
+ return __spreadValues(__spreadValues(__spreadValues({
984
1066
  mmconnect_versions: (_a2 = options.versions) != null ? _a2 : {},
985
1067
  dapp_id: dappId,
986
1068
  method: invokeOptions.request.method,
987
1069
  caip_chain_id: invokeOptions.scope,
988
1070
  anon_id: anonId,
989
1071
  transport_type: transportType
990
- };
1072
+ }, (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 } : {});
991
1073
  });
992
1074
  }
1075
+ var ERROR_MESSAGE_SAMPLE_MAX_LENGTH, SANITISE_PATTERNS;
993
1076
  var init_analytics = __esm({
994
1077
  "src/multichain/utils/analytics.ts"() {
995
1078
  "use strict";
996
1079
  init_utils();
997
1080
  init_domain();
1081
+ ERROR_MESSAGE_SAMPLE_MAX_LENGTH = 200;
1082
+ SANITISE_PATTERNS = [
1083
+ // EVM-style 20-byte hex addresses (e.g. `0x` + 40 hex chars).
1084
+ { pattern: /0x[a-fA-F0-9]{40}/gu, replacement: "<addr>" },
1085
+ // Other long hex blobs: tx hashes, signatures, raw byte strings, large
1086
+ // hex amounts. 16+ hex chars catches 32-byte hashes/signatures without
1087
+ // snagging EVM method selectors (8 chars) or short hex codes.
1088
+ { pattern: /(?:0x)?[a-fA-F0-9]{16,}/gu, replacement: "<hex>" },
1089
+ // URLs of any scheme up to the first whitespace / quote / closing paren.
1090
+ // Catches RPC endpoints, dapp deeplinks, query strings with secrets.
1091
+ { pattern: /https?:\/\/[^\s"')]+/gu, replacement: "<url>" },
1092
+ // Bech32 addresses: short HRP (1-10 lowercase chars) + `1` separator +
1093
+ // ≥38 chars of Bech32 data alphabet `[ac-hj-np-z02-9]` (excludes the
1094
+ // look-alike chars `b`, `i`, `o`, `1`). Covers Bitcoin SegWit
1095
+ // (`bc1…`/`tb1…`) and Cosmos-SDK chains (`cosmos1…`, `osmo1…`,
1096
+ // `juno1…`, `inj1…`, etc.) without enumerating every HRP. Runs before
1097
+ // the Base58 pattern below — see header comment for why.
1098
+ {
1099
+ pattern: /\b[a-z]{1,10}1[ac-hj-np-z02-9]{38,}\b/gu,
1100
+ replacement: "<addr>"
1101
+ },
1102
+ // Base58 tokens (32+ chars, Base58 alphabet `[1-9A-HJ-NP-Za-km-z]`).
1103
+ // Covers Solana pubkeys (32-44 chars), Solana tx signatures (~88 chars),
1104
+ // and Bitcoin Base58 addresses ≥32 chars. The 32-char floor and `\b`
1105
+ // word boundary keep English words and shorter alphanumerics safe.
1106
+ {
1107
+ pattern: /\b[1-9A-HJ-NP-Za-km-z]{32,}\b/gu,
1108
+ replacement: "<addr>"
1109
+ },
1110
+ // Long decimal numbers — token amounts, gas units, timestamps, lamports.
1111
+ // 10+ digits catches typical chain quantities without affecting JSON-RPC
1112
+ // codes (-32601, 4001, etc.) or short numeric IDs.
1113
+ { pattern: /\d{10,}/gu, replacement: "<num>" }
1114
+ ];
998
1115
  }
999
1116
  });
1000
1117
 
@@ -1386,13 +1503,24 @@ var init_mwp = __esm({
1386
1503
  return resolveConnection();
1387
1504
  });
1388
1505
  this.dappClient.on("message", initialConnectionMessageHandler);
1506
+ const platformType = getPlatformType();
1507
+ const isQRCodeFlow = [
1508
+ "web-desktop" /* DesktopWeb */,
1509
+ "nodejs" /* NonBrowser */
1510
+ ].includes(platformType);
1511
+ const initialPayload = {
1512
+ name: MULTICHAIN_PROVIDER_STREAM_NAME,
1513
+ data: request
1514
+ };
1389
1515
  dappClient.connect({
1390
1516
  mode: "trusted",
1391
- initialPayload: {
1392
- name: MULTICHAIN_PROVIDER_STREAM_NAME,
1393
- data: request
1517
+ initialPayload: isQRCodeFlow ? void 0 : initialPayload
1518
+ }).then(() => __async(this, null, function* () {
1519
+ if (isQRCodeFlow) {
1520
+ return dappClient.sendRequest(initialPayload);
1394
1521
  }
1395
- }).catch((error) => {
1522
+ return void 0;
1523
+ })).catch((error) => {
1396
1524
  if (initialConnectionMessageHandler) {
1397
1525
  this.dappClient.off(
1398
1526
  "message",
@@ -2113,6 +2241,17 @@ import { analytics } from "@metamask/analytics";
2113
2241
  init_domain();
2114
2242
  init_utils();
2115
2243
  init_analytics();
2244
+ function toRPCInvokeMethodErr(error) {
2245
+ var _a2;
2246
+ if (error instanceof RPCInvokeMethodErr) {
2247
+ return error;
2248
+ }
2249
+ const castError = error;
2250
+ return new RPCInvokeMethodErr(
2251
+ (_a2 = castError.message) != null ? _a2 : "Unknown error",
2252
+ castError.code
2253
+ );
2254
+ }
2116
2255
  var _RequestRouter_instances, withAnalyticsTracking_fn, trackWalletActionRequested_fn, trackWalletActionSucceeded_fn, trackWalletActionFailed_fn, trackWalletActionRejected_fn;
2117
2256
  var RequestRouter = class {
2118
2257
  constructor(transport, rpcClient, config, transportType) {
@@ -2219,6 +2358,13 @@ _RequestRouter_instances = new WeakSet();
2219
2358
  withAnalyticsTracking_fn = function(options, execute) {
2220
2359
  return __async(this, null, function* () {
2221
2360
  var _a2;
2361
+ if (((_a2 = this.config.analytics) == null ? void 0 : _a2.enabled) === false) {
2362
+ try {
2363
+ return yield execute();
2364
+ } catch (error) {
2365
+ throw toRPCInvokeMethodErr(error);
2366
+ }
2367
+ }
2222
2368
  yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRequested_fn).call(this, options);
2223
2369
  try {
2224
2370
  const result = yield execute();
@@ -2229,16 +2375,9 @@ withAnalyticsTracking_fn = function(options, execute) {
2229
2375
  if (isRejection) {
2230
2376
  yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRejected_fn).call(this, options);
2231
2377
  } else {
2232
- yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options);
2233
- }
2234
- if (error instanceof RPCInvokeMethodErr) {
2235
- throw error;
2378
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options, error);
2236
2379
  }
2237
- const castError = error;
2238
- throw new RPCInvokeMethodErr(
2239
- (_a2 = castError.message) != null ? _a2 : "Unknown error",
2240
- castError.code
2241
- );
2380
+ throw toRPCInvokeMethodErr(error);
2242
2381
  }
2243
2382
  });
2244
2383
  };
@@ -2264,13 +2403,14 @@ trackWalletActionSucceeded_fn = function(options) {
2264
2403
  analytics.track("mmconnect_wallet_action_succeeded", props);
2265
2404
  });
2266
2405
  };
2267
- trackWalletActionFailed_fn = function(options) {
2406
+ trackWalletActionFailed_fn = function(options, error) {
2268
2407
  return __async(this, null, function* () {
2269
2408
  const props = yield getWalletActionAnalyticsProperties(
2270
2409
  this.config,
2271
2410
  this.config.storage,
2272
2411
  options,
2273
- this.transportType
2412
+ this.transportType,
2413
+ extractErrorDiagnostics(error)
2274
2414
  );
2275
2415
  analytics.track("mmconnect_wallet_action_failed", props);
2276
2416
  });
@@ -2698,26 +2838,65 @@ walletInvokeMethod_fn = function(request) {
2698
2838
  init_utils();
2699
2839
  var logger2 = createLogger("metamask-sdk:core");
2700
2840
  var SINGLETON_KEY = "__METAMASK_CONNECT_MULTICHAIN_SINGLETON__";
2841
+ function normalizeAnalyticsOptions(analyticsOptions) {
2842
+ var _a2;
2843
+ return __spreadProps(__spreadValues({}, analyticsOptions != null ? analyticsOptions : {}), {
2844
+ enabled: (_a2 = analyticsOptions == null ? void 0 : analyticsOptions.enabled) != null ? _a2 : true,
2845
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
2846
+ integrationType: (analyticsOptions == null ? void 0 : analyticsOptions.integrationType) || "direct"
2847
+ });
2848
+ }
2849
+ function isAnalyticsEnabled(options) {
2850
+ var _a2;
2851
+ return ((_a2 = options.analytics) == null ? void 0 : _a2.enabled) !== false;
2852
+ }
2853
+ function setupAnalyticsGlobals(options, storage, setAnonId) {
2854
+ return __async(this, null, function* () {
2855
+ var _a2, _b;
2856
+ if (!isAnalyticsEnabled(options)) {
2857
+ setAnonId == null ? void 0 : setAnonId(void 0);
2858
+ analytics2.disable();
2859
+ return;
2860
+ }
2861
+ const platform = getPlatformType();
2862
+ const isBrowser = platform === "in-app-browser" /* MetaMaskMobileWebview */ || platform === "web-desktop" /* DesktopWeb */ || platform === "web-mobile" /* MobileWeb */;
2863
+ const isReactNative2 = platform === "react-native" /* ReactNative */;
2864
+ if (!isBrowser && !isReactNative2) {
2865
+ return;
2866
+ }
2867
+ const dappId = getDappId(options.dapp);
2868
+ const anonId = yield storage.getAnonId();
2869
+ setAnonId == null ? void 0 : setAnonId(anonId);
2870
+ const { integrationType } = (_a2 = options.analytics) != null ? _a2 : {
2871
+ integrationType: ""
2872
+ };
2873
+ analytics2.setGlobalProperty("mmconnect_versions", (_b = options.versions) != null ? _b : {});
2874
+ analytics2.setGlobalProperty("dapp_id", dappId);
2875
+ analytics2.setGlobalProperty("anon_id", anonId);
2876
+ analytics2.setGlobalProperty("platform", platform);
2877
+ if (integrationType) {
2878
+ analytics2.setGlobalProperty("integration_types", [integrationType]);
2879
+ }
2880
+ analytics2.enable();
2881
+ });
2882
+ }
2701
2883
  var _a, _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;
2702
2884
  var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends MultichainCore {
2703
2885
  constructor(options) {
2704
- var _a2, _b, _c, _d, _e, _f;
2886
+ var _a2, _b, _c, _d;
2705
2887
  const withDappMetadata = setupDappMetadata(options);
2706
- const integrationType = ((_a2 = options.analytics) == null ? void 0 : _a2.integrationType) || "direct";
2707
2888
  const allOptions = __spreadProps(__spreadValues({}, withDappMetadata), {
2708
2889
  ui: __spreadProps(__spreadValues({}, withDappMetadata.ui), {
2709
- preferExtension: (_b = withDappMetadata.ui.preferExtension) != null ? _b : true,
2710
- showInstallModal: (_c = withDappMetadata.ui.showInstallModal) != null ? _c : false,
2711
- headless: (_d = withDappMetadata.ui.headless) != null ? _d : false
2712
- }),
2713
- analytics: __spreadProps(__spreadValues({}, (_e = options.analytics) != null ? _e : {}), {
2714
- integrationType
2890
+ preferExtension: (_a2 = withDappMetadata.ui.preferExtension) != null ? _a2 : true,
2891
+ showInstallModal: (_b = withDappMetadata.ui.showInstallModal) != null ? _b : false,
2892
+ headless: (_c = withDappMetadata.ui.headless) != null ? _c : false
2715
2893
  }),
2894
+ analytics: normalizeAnalyticsOptions(options.analytics),
2716
2895
  versions: __spreadValues({
2717
2896
  // typeof guard needed: Metro (React Native) bundles TS source directly,
2718
2897
  // bypassing the tsup build that substitutes __PACKAGE_VERSION__.
2719
- "connect-multichain": false ? "unknown" : "0.13.0"
2720
- }, (_f = options.versions) != null ? _f : {})
2898
+ "connect-multichain": false ? "unknown" : "0.15.0"
2899
+ }, (_d = options.versions) != null ? _d : {})
2721
2900
  });
2722
2901
  super(allOptions);
2723
2902
  __privateAdd(this, _MetaMaskConnectMultichain_instances);
@@ -2773,25 +2952,22 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2773
2952
  // Creates a singleton instance of MetaMaskConnectMultichain.
2774
2953
  // If the singleton already exists, it merges the incoming options with the
2775
2954
  // existing singleton options for the following keys: `api.supportedNetworks`,
2776
- // `versions`, `ui.*`, `mobile.*`, `transport.extensionId`, `debug`. Take note
2777
- // that the value for `dapp` is not merged as it does not make sense for
2778
- // subsequent calls to `createMultichainClient` to have a different `dapp` value.
2955
+ // `analytics`, `versions`, `ui.*`, `mobile.*`, `transport.extensionId`,
2956
+ // `debug`. Take note that the value for `dapp` is not merged as it does not
2957
+ // make sense for subsequent calls to `createMultichainClient` to have a
2958
+ // different `dapp` value.
2779
2959
  static create(options) {
2780
2960
  return __async(this, null, function* () {
2781
- var _a2, _b;
2961
+ var _a2;
2782
2962
  const globalObject = getGlobalObject();
2783
2963
  const existing = globalObject[SINGLETON_KEY];
2784
2964
  if (existing) {
2785
2965
  const instance = yield existing;
2786
2966
  instance.mergeOptions(options);
2787
- analytics2.setGlobalProperty(
2788
- "mmconnect_versions",
2789
- (_a2 = instance.options.versions) != null ? _a2 : {}
2790
- );
2791
- if ((_b = options.analytics) == null ? void 0 : _b.integrationType) {
2792
- analytics2.setGlobalProperty("integration_types", [
2793
- options.analytics.integrationType
2794
- ]);
2967
+ if (instance instanceof _MetaMaskConnectMultichain) {
2968
+ yield __privateMethod(_a2 = instance, _MetaMaskConnectMultichain_instances, setupAnalytics_fn).call(_a2);
2969
+ } else {
2970
+ yield setupAnalyticsGlobals(instance.options, instance.storage);
2795
2971
  }
2796
2972
  if (options.debug) {
2797
2973
  enableDebug("metamask-sdk:*");
@@ -2841,21 +3017,23 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2841
3017
  } else {
2842
3018
  transportType = "mwp" /* MWP */;
2843
3019
  }
2844
- try {
2845
- const baseProps = yield getBaseAnalyticsProperties(
2846
- this.options,
2847
- this.storage
2848
- );
2849
- const dappConfiguredChains = Object.keys(
2850
- this.options.api.supportedNetworks
2851
- );
2852
- analytics2.track("mmconnect_connection_initiated", __spreadProps(__spreadValues({}, baseProps), {
2853
- transport_type: transportType,
2854
- dapp_configured_chains: dappConfiguredChains,
2855
- dapp_requested_chains: scopes
2856
- }));
2857
- } catch (error) {
2858
- logger2("Error tracking connection_initiated event", error);
3020
+ if (isAnalyticsEnabled(this.options)) {
3021
+ try {
3022
+ const baseProps = yield getBaseAnalyticsProperties(
3023
+ this.options,
3024
+ this.storage
3025
+ );
3026
+ const dappConfiguredChains = Object.keys(
3027
+ this.options.api.supportedNetworks
3028
+ );
3029
+ analytics2.track("mmconnect_connection_initiated", __spreadProps(__spreadValues({}, baseProps), {
3030
+ transport_type: transportType,
3031
+ dapp_configured_chains: dappConfiguredChains,
3032
+ dapp_requested_chains: scopes
3033
+ }));
3034
+ } catch (error) {
3035
+ logger2("Error tracking connection_initiated event", error);
3036
+ }
2859
3037
  }
2860
3038
  const sessionData = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, getCaipSession_fn).call(this);
2861
3039
  const { mergedScopes, mergedCaipAccountIds, mergedSessionProperties } = mergeRequestedSessionWithExisting(
@@ -2998,30 +3176,9 @@ _sdkInfo = new WeakMap();
2998
3176
  _MetaMaskConnectMultichain_instances = new WeakSet();
2999
3177
  setupAnalytics_fn = function() {
3000
3178
  return __async(this, null, function* () {
3001
- var _a2, _b;
3002
- const platform = getPlatformType();
3003
- const isBrowser = platform === "in-app-browser" /* MetaMaskMobileWebview */ || platform === "web-desktop" /* DesktopWeb */ || platform === "web-mobile" /* MobileWeb */;
3004
- const isReactNative2 = platform === "react-native" /* ReactNative */;
3005
- if (!isBrowser && !isReactNative2) {
3006
- return;
3007
- }
3008
- const dappId = getDappId(this.options.dapp);
3009
- const anonId = yield this.storage.getAnonId();
3010
- __privateSet(this, _anonId, anonId);
3011
- const { integrationType } = (_a2 = this.options.analytics) != null ? _a2 : {
3012
- integrationType: ""
3013
- };
3014
- analytics2.setGlobalProperty(
3015
- "mmconnect_versions",
3016
- (_b = this.options.versions) != null ? _b : {}
3017
- );
3018
- analytics2.setGlobalProperty("dapp_id", dappId);
3019
- analytics2.setGlobalProperty("anon_id", anonId);
3020
- analytics2.setGlobalProperty("platform", platform);
3021
- if (integrationType) {
3022
- analytics2.setGlobalProperty("integration_types", [integrationType]);
3023
- }
3024
- analytics2.enable();
3179
+ yield setupAnalyticsGlobals(this.options, this.storage, (anonId) => {
3180
+ __privateSet(this, _anonId, anonId);
3181
+ });
3025
3182
  });
3026
3183
  };
3027
3184
  onTransportNotification_fn = function(payload) {
@@ -3110,7 +3267,7 @@ buildConnectionMetadata_fn = function() {
3110
3267
  dapp: this.options.dapp,
3111
3268
  sdk: { version: getVersion(), platform: getPlatformType() }
3112
3269
  };
3113
- if (__privateGet(this, _anonId)) {
3270
+ if (isAnalyticsEnabled(this.options) && __privateGet(this, _anonId)) {
3114
3271
  metadata.analytics = { remote_session_id: __privateGet(this, _anonId) };
3115
3272
  }
3116
3273
  return metadata;
@@ -3392,38 +3549,42 @@ handleConnection_fn = function(promise, scopes, transportType) {
3392
3549
  this.status = "connecting";
3393
3550
  return promise.then(() => __async(this, null, function* () {
3394
3551
  this.status = "connected";
3395
- try {
3396
- const baseProps = yield getBaseAnalyticsProperties(
3397
- this.options,
3398
- this.storage
3399
- );
3400
- analytics2.track("mmconnect_connection_established", __spreadProps(__spreadValues({}, baseProps), {
3401
- transport_type: transportType,
3402
- user_permissioned_chains: scopes
3403
- }));
3404
- } catch (error) {
3405
- logger2("Error tracking connection_established event", error);
3552
+ if (isAnalyticsEnabled(this.options)) {
3553
+ try {
3554
+ const baseProps = yield getBaseAnalyticsProperties(
3555
+ this.options,
3556
+ this.storage
3557
+ );
3558
+ analytics2.track("mmconnect_connection_established", __spreadProps(__spreadValues({}, baseProps), {
3559
+ transport_type: transportType,
3560
+ user_permissioned_chains: scopes
3561
+ }));
3562
+ } catch (error) {
3563
+ logger2("Error tracking connection_established event", error);
3564
+ }
3406
3565
  }
3407
3566
  return void 0;
3408
3567
  })).catch((error) => __async(this, null, function* () {
3409
3568
  this.status = "disconnected";
3410
- try {
3411
- const baseProps = yield getBaseAnalyticsProperties(
3412
- this.options,
3413
- this.storage
3414
- );
3415
- const isRejection = isRejectionError(error);
3416
- if (isRejection) {
3417
- analytics2.track("mmconnect_connection_rejected", __spreadProps(__spreadValues({}, baseProps), {
3418
- transport_type: transportType
3419
- }));
3420
- } else {
3421
- analytics2.track("mmconnect_connection_failed", __spreadProps(__spreadValues({}, baseProps), {
3422
- transport_type: transportType
3423
- }));
3569
+ if (isAnalyticsEnabled(this.options)) {
3570
+ try {
3571
+ const baseProps = yield getBaseAnalyticsProperties(
3572
+ this.options,
3573
+ this.storage
3574
+ );
3575
+ const isRejection = isRejectionError(error);
3576
+ if (isRejection) {
3577
+ analytics2.track("mmconnect_connection_rejected", __spreadProps(__spreadValues({}, baseProps), {
3578
+ transport_type: transportType
3579
+ }));
3580
+ } else {
3581
+ analytics2.track("mmconnect_connection_failed", __spreadValues(__spreadProps(__spreadValues({}, baseProps), {
3582
+ transport_type: transportType
3583
+ }), extractErrorDiagnostics(error)));
3584
+ }
3585
+ } catch (e) {
3586
+ logger2("Error tracking connection failed/rejected event", error);
3424
3587
  }
3425
- } catch (e) {
3426
- logger2("Error tracking connection failed/rejected event", error);
3427
3588
  }
3428
3589
  throw error;
3429
3590
  }));
@@ -3865,6 +4026,7 @@ export {
3865
4026
  StoreAdapter,
3866
4027
  StoreClient,
3867
4028
  TransportType,
4029
+ classifyFailureReason,
3868
4030
  createLogger,
3869
4031
  createMultichainClient,
3870
4032
  enableDebug,