@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 _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
483
+ var _a3, _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), (_a3 = partial.analytics) != null ? _a3 : {});
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 = (_a3 = partial.api) == null ? void 0 : _a3.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
  };
@@ -679,17 +684,94 @@ var init_ui = __esm({
679
684
  });
680
685
 
681
686
  // src/multichain/utils/analytics.ts
687
+ function sanitiseErrorMessage(message) {
688
+ if (!message) {
689
+ return void 0;
690
+ }
691
+ let sanitised = message;
692
+ for (const { pattern, replacement } of SANITISE_PATTERNS) {
693
+ sanitised = sanitised.replace(pattern, replacement);
694
+ }
695
+ if (sanitised.length > ERROR_MESSAGE_SAMPLE_MAX_LENGTH) {
696
+ sanitised = `${sanitised.slice(0, ERROR_MESSAGE_SAMPLE_MAX_LENGTH - 1)}\u2026`;
697
+ }
698
+ return sanitised;
699
+ }
700
+ function getUnwrappedErrorDetails(error) {
701
+ var _a3, _b, _c, _d;
702
+ if (typeof error !== "object" || error === null) {
703
+ return { code: void 0, message: "" };
704
+ }
705
+ if (error instanceof RPCInvokeMethodErr) {
706
+ return {
707
+ code: (_a3 = error.rpcCode) != null ? _a3 : error.code,
708
+ message: (_c = (_b = error.rpcMessage) != null ? _b : error.message) != null ? _c : ""
709
+ };
710
+ }
711
+ const errorObj = error;
712
+ return {
713
+ code: errorObj.code,
714
+ message: (_d = errorObj.message) != null ? _d : ""
715
+ };
716
+ }
682
717
  function isRejectionError(error) {
683
- var _a3, _b;
684
718
  if (typeof error !== "object" || error === null) {
685
719
  return false;
686
720
  }
721
+ const { code, message } = getUnwrappedErrorDetails(error);
722
+ const errorMessage = message.toLowerCase();
723
+ return code === 4001 || errorMessage.includes("reject") || errorMessage.includes("denied") || errorMessage.includes("cancel") || // Narrow "user …" matches — bare "user" is too greedy (catches Account
724
+ // Abstraction errors like "user operation reverted").
725
+ errorMessage.includes("user rejected") || errorMessage.includes("user denied") || errorMessage.includes("user cancelled") || errorMessage.includes("user canceled");
726
+ }
727
+ function classifyFailureReason(error) {
728
+ var _a3, _b;
729
+ if (typeof error !== "object" || error === null) {
730
+ return "unknown";
731
+ }
687
732
  const errorObj = error;
688
- const errorCode = errorObj.code;
689
- const errorMessage = (_b = (_a3 = errorObj.message) == null ? void 0 : _a3.toLowerCase()) != null ? _b : "";
690
- return errorCode === 4001 || // User rejected request (common EIP-1193 code)
691
- errorCode === 4100 || // Unauthorized (common rejection code)
692
- errorMessage.includes("reject") || errorMessage.includes("denied") || errorMessage.includes("cancel") || errorMessage.includes("user");
733
+ const errorName = (_a3 = errorObj.name) != null ? _a3 : "";
734
+ const errorMessageRaw = (_b = errorObj.message) != null ? _b : "";
735
+ const errorMessage = errorMessageRaw.toLowerCase();
736
+ const { code } = getUnwrappedErrorDetails(error);
737
+ if (typeof code === "number") {
738
+ if (code === -32601) {
739
+ return "wallet_method_unsupported";
740
+ }
741
+ if (code === -32602) {
742
+ return "wallet_invalid_params";
743
+ }
744
+ if (code === -32603) {
745
+ return "wallet_internal_error";
746
+ }
747
+ if (code <= -32e3 && code >= -32099) {
748
+ return "wallet_internal_error";
749
+ }
750
+ if (code === 4100) {
751
+ return "wallet_unauthorized";
752
+ }
753
+ if (code === 4200) {
754
+ return "wallet_method_unsupported";
755
+ }
756
+ if (code === 4902) {
757
+ return "unrecognized_chain";
758
+ }
759
+ }
760
+ if (errorName === "TransportTimeoutError" || errorMessageRaw === "Request timeout" || errorMessage.includes("timed out") || errorMessage.includes("timeout")) {
761
+ return "transport_timeout";
762
+ }
763
+ if (errorName === "TransportError" || errorMessage.includes("not connected") || errorMessage.includes("transport disconnect") || errorMessage.includes("connection lost") || errorMessage.includes("socket closed")) {
764
+ return "transport_disconnect";
765
+ }
766
+ return "unknown";
767
+ }
768
+ function extractErrorDiagnostics(error) {
769
+ const failureReason = classifyFailureReason(error);
770
+ const { code, message } = getUnwrappedErrorDetails(error);
771
+ const messageSample = sanitiseErrorMessage(message);
772
+ return __spreadValues(__spreadValues({
773
+ failure_reason: failureReason
774
+ }, typeof code === "number" ? { error_code: code } : {}), messageSample ? { error_message_sample: messageSample } : {});
693
775
  }
694
776
  function getBaseAnalyticsProperties(options, storage) {
695
777
  return __async(this, null, function* () {
@@ -705,26 +787,61 @@ function getBaseAnalyticsProperties(options, storage) {
705
787
  };
706
788
  });
707
789
  }
708
- function getWalletActionAnalyticsProperties(options, storage, invokeOptions, transportType) {
790
+ function getWalletActionAnalyticsProperties(options, storage, invokeOptions, transportType, extra) {
709
791
  return __async(this, null, function* () {
710
792
  var _a3;
711
793
  const dappId = getDappId(options.dapp);
712
794
  const anonId = yield storage.getAnonId();
713
- return {
795
+ return __spreadValues(__spreadValues(__spreadValues({
714
796
  mmconnect_versions: (_a3 = options.versions) != null ? _a3 : {},
715
797
  dapp_id: dappId,
716
798
  method: invokeOptions.request.method,
717
799
  caip_chain_id: invokeOptions.scope,
718
800
  anon_id: anonId,
719
801
  transport_type: transportType
720
- };
802
+ }, (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 } : {});
721
803
  });
722
804
  }
805
+ var ERROR_MESSAGE_SAMPLE_MAX_LENGTH, SANITISE_PATTERNS;
723
806
  var init_analytics = __esm({
724
807
  "src/multichain/utils/analytics.ts"() {
725
808
  "use strict";
726
809
  init_utils2();
727
810
  init_domain();
811
+ ERROR_MESSAGE_SAMPLE_MAX_LENGTH = 200;
812
+ SANITISE_PATTERNS = [
813
+ // EVM-style 20-byte hex addresses (e.g. `0x` + 40 hex chars).
814
+ { pattern: /0x[a-fA-F0-9]{40}/gu, replacement: "<addr>" },
815
+ // Other long hex blobs: tx hashes, signatures, raw byte strings, large
816
+ // hex amounts. 16+ hex chars catches 32-byte hashes/signatures without
817
+ // snagging EVM method selectors (8 chars) or short hex codes.
818
+ { pattern: /(?:0x)?[a-fA-F0-9]{16,}/gu, replacement: "<hex>" },
819
+ // URLs of any scheme up to the first whitespace / quote / closing paren.
820
+ // Catches RPC endpoints, dapp deeplinks, query strings with secrets.
821
+ { pattern: /https?:\/\/[^\s"')]+/gu, replacement: "<url>" },
822
+ // Bech32 addresses: short HRP (1-10 lowercase chars) + `1` separator +
823
+ // ≥38 chars of Bech32 data alphabet `[ac-hj-np-z02-9]` (excludes the
824
+ // look-alike chars `b`, `i`, `o`, `1`). Covers Bitcoin SegWit
825
+ // (`bc1…`/`tb1…`) and Cosmos-SDK chains (`cosmos1…`, `osmo1…`,
826
+ // `juno1…`, `inj1…`, etc.) without enumerating every HRP. Runs before
827
+ // the Base58 pattern below — see header comment for why.
828
+ {
829
+ pattern: /\b[a-z]{1,10}1[ac-hj-np-z02-9]{38,}\b/gu,
830
+ replacement: "<addr>"
831
+ },
832
+ // Base58 tokens (32+ chars, Base58 alphabet `[1-9A-HJ-NP-Za-km-z]`).
833
+ // Covers Solana pubkeys (32-44 chars), Solana tx signatures (~88 chars),
834
+ // and Bitcoin Base58 addresses ≥32 chars. The 32-char floor and `\b`
835
+ // word boundary keep English words and shorter alphanumerics safe.
836
+ {
837
+ pattern: /\b[1-9A-HJ-NP-Za-km-z]{32,}\b/gu,
838
+ replacement: "<addr>"
839
+ },
840
+ // Long decimal numbers — token amounts, gas units, timestamps, lamports.
841
+ // 10+ digits catches typical chain quantities without affecting JSON-RPC
842
+ // codes (-32601, 4001, etc.) or short numeric IDs.
843
+ { pattern: /\d{10,}/gu, replacement: "<num>" }
844
+ ];
728
845
  }
729
846
  });
730
847
 
@@ -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",
@@ -2174,6 +2302,17 @@ import { analytics } from "@metamask/analytics";
2174
2302
  init_domain();
2175
2303
  init_utils2();
2176
2304
  init_analytics();
2305
+ function toRPCInvokeMethodErr(error) {
2306
+ var _a3;
2307
+ if (error instanceof RPCInvokeMethodErr) {
2308
+ return error;
2309
+ }
2310
+ const castError = error;
2311
+ return new RPCInvokeMethodErr(
2312
+ (_a3 = castError.message) != null ? _a3 : "Unknown error",
2313
+ castError.code
2314
+ );
2315
+ }
2177
2316
  var _RequestRouter_instances, withAnalyticsTracking_fn, trackWalletActionRequested_fn, trackWalletActionSucceeded_fn, trackWalletActionFailed_fn, trackWalletActionRejected_fn;
2178
2317
  var RequestRouter = class {
2179
2318
  constructor(transport, rpcClient, config, transportType) {
@@ -2280,6 +2419,13 @@ _RequestRouter_instances = new WeakSet();
2280
2419
  withAnalyticsTracking_fn = function(options, execute) {
2281
2420
  return __async(this, null, function* () {
2282
2421
  var _a3;
2422
+ if (((_a3 = this.config.analytics) == null ? void 0 : _a3.enabled) === false) {
2423
+ try {
2424
+ return yield execute();
2425
+ } catch (error) {
2426
+ throw toRPCInvokeMethodErr(error);
2427
+ }
2428
+ }
2283
2429
  yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRequested_fn).call(this, options);
2284
2430
  try {
2285
2431
  const result = yield execute();
@@ -2290,16 +2436,9 @@ withAnalyticsTracking_fn = function(options, execute) {
2290
2436
  if (isRejection) {
2291
2437
  yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRejected_fn).call(this, options);
2292
2438
  } else {
2293
- yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options);
2294
- }
2295
- if (error instanceof RPCInvokeMethodErr) {
2296
- throw error;
2439
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options, error);
2297
2440
  }
2298
- const castError = error;
2299
- throw new RPCInvokeMethodErr(
2300
- (_a3 = castError.message) != null ? _a3 : "Unknown error",
2301
- castError.code
2302
- );
2441
+ throw toRPCInvokeMethodErr(error);
2303
2442
  }
2304
2443
  });
2305
2444
  };
@@ -2325,13 +2464,14 @@ trackWalletActionSucceeded_fn = function(options) {
2325
2464
  analytics.track("mmconnect_wallet_action_succeeded", props);
2326
2465
  });
2327
2466
  };
2328
- trackWalletActionFailed_fn = function(options) {
2467
+ trackWalletActionFailed_fn = function(options, error) {
2329
2468
  return __async(this, null, function* () {
2330
2469
  const props = yield getWalletActionAnalyticsProperties(
2331
2470
  this.config,
2332
2471
  this.config.storage,
2333
2472
  options,
2334
- this.transportType
2473
+ this.transportType,
2474
+ extractErrorDiagnostics(error)
2335
2475
  );
2336
2476
  analytics.track("mmconnect_wallet_action_failed", props);
2337
2477
  });
@@ -2759,26 +2899,65 @@ walletInvokeMethod_fn = function(request) {
2759
2899
  init_utils2();
2760
2900
  var logger2 = createLogger("metamask-sdk:core");
2761
2901
  var SINGLETON_KEY = "__METAMASK_CONNECT_MULTICHAIN_SINGLETON__";
2902
+ function normalizeAnalyticsOptions(analyticsOptions) {
2903
+ var _a3;
2904
+ return __spreadProps(__spreadValues({}, analyticsOptions != null ? analyticsOptions : {}), {
2905
+ enabled: (_a3 = analyticsOptions == null ? void 0 : analyticsOptions.enabled) != null ? _a3 : true,
2906
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
2907
+ integrationType: (analyticsOptions == null ? void 0 : analyticsOptions.integrationType) || "direct"
2908
+ });
2909
+ }
2910
+ function isAnalyticsEnabled(options) {
2911
+ var _a3;
2912
+ return ((_a3 = options.analytics) == null ? void 0 : _a3.enabled) !== false;
2913
+ }
2914
+ function setupAnalyticsGlobals(options, storage, setAnonId) {
2915
+ return __async(this, null, function* () {
2916
+ var _a3, _b;
2917
+ if (!isAnalyticsEnabled(options)) {
2918
+ setAnonId == null ? void 0 : setAnonId(void 0);
2919
+ analytics2.disable();
2920
+ return;
2921
+ }
2922
+ const platform = getPlatformType();
2923
+ const isBrowser = platform === "in-app-browser" /* MetaMaskMobileWebview */ || platform === "web-desktop" /* DesktopWeb */ || platform === "web-mobile" /* MobileWeb */;
2924
+ const isReactNative2 = platform === "react-native" /* ReactNative */;
2925
+ if (!isBrowser && !isReactNative2) {
2926
+ return;
2927
+ }
2928
+ const dappId = getDappId(options.dapp);
2929
+ const anonId = yield storage.getAnonId();
2930
+ setAnonId == null ? void 0 : setAnonId(anonId);
2931
+ const { integrationType } = (_a3 = options.analytics) != null ? _a3 : {
2932
+ integrationType: ""
2933
+ };
2934
+ analytics2.setGlobalProperty("mmconnect_versions", (_b = options.versions) != null ? _b : {});
2935
+ analytics2.setGlobalProperty("dapp_id", dappId);
2936
+ analytics2.setGlobalProperty("anon_id", anonId);
2937
+ analytics2.setGlobalProperty("platform", platform);
2938
+ if (integrationType) {
2939
+ analytics2.setGlobalProperty("integration_types", [integrationType]);
2940
+ }
2941
+ analytics2.enable();
2942
+ });
2943
+ }
2762
2944
  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;
2763
2945
  var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends MultichainCore {
2764
2946
  constructor(options) {
2765
- var _a3, _b, _c, _d, _e, _f;
2947
+ var _a3, _b, _c, _d;
2766
2948
  const withDappMetadata = setupDappMetadata(options);
2767
- const integrationType = ((_a3 = options.analytics) == null ? void 0 : _a3.integrationType) || "direct";
2768
2949
  const allOptions = __spreadProps(__spreadValues({}, withDappMetadata), {
2769
2950
  ui: __spreadProps(__spreadValues({}, withDappMetadata.ui), {
2770
- preferExtension: (_b = withDappMetadata.ui.preferExtension) != null ? _b : true,
2771
- showInstallModal: (_c = withDappMetadata.ui.showInstallModal) != null ? _c : false,
2772
- headless: (_d = withDappMetadata.ui.headless) != null ? _d : false
2773
- }),
2774
- analytics: __spreadProps(__spreadValues({}, (_e = options.analytics) != null ? _e : {}), {
2775
- integrationType
2951
+ preferExtension: (_a3 = withDappMetadata.ui.preferExtension) != null ? _a3 : true,
2952
+ showInstallModal: (_b = withDappMetadata.ui.showInstallModal) != null ? _b : false,
2953
+ headless: (_c = withDappMetadata.ui.headless) != null ? _c : false
2776
2954
  }),
2955
+ analytics: normalizeAnalyticsOptions(options.analytics),
2777
2956
  versions: __spreadValues({
2778
2957
  // typeof guard needed: Metro (React Native) bundles TS source directly,
2779
2958
  // bypassing the tsup build that substitutes __PACKAGE_VERSION__.
2780
- "connect-multichain": false ? "unknown" : "0.13.0"
2781
- }, (_f = options.versions) != null ? _f : {})
2959
+ "connect-multichain": false ? "unknown" : "0.15.0"
2960
+ }, (_d = options.versions) != null ? _d : {})
2782
2961
  });
2783
2962
  super(allOptions);
2784
2963
  __privateAdd(this, _MetaMaskConnectMultichain_instances);
@@ -2834,25 +3013,22 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2834
3013
  // Creates a singleton instance of MetaMaskConnectMultichain.
2835
3014
  // If the singleton already exists, it merges the incoming options with the
2836
3015
  // existing singleton options for the following keys: `api.supportedNetworks`,
2837
- // `versions`, `ui.*`, `mobile.*`, `transport.extensionId`, `debug`. Take note
2838
- // that the value for `dapp` is not merged as it does not make sense for
2839
- // subsequent calls to `createMultichainClient` to have a different `dapp` value.
3016
+ // `analytics`, `versions`, `ui.*`, `mobile.*`, `transport.extensionId`,
3017
+ // `debug`. Take note that the value for `dapp` is not merged as it does not
3018
+ // make sense for subsequent calls to `createMultichainClient` to have a
3019
+ // different `dapp` value.
2840
3020
  static create(options) {
2841
3021
  return __async(this, null, function* () {
2842
- var _a3, _b;
3022
+ var _a3;
2843
3023
  const globalObject = getGlobalObject();
2844
3024
  const existing = globalObject[SINGLETON_KEY];
2845
3025
  if (existing) {
2846
3026
  const instance = yield existing;
2847
3027
  instance.mergeOptions(options);
2848
- analytics2.setGlobalProperty(
2849
- "mmconnect_versions",
2850
- (_a3 = instance.options.versions) != null ? _a3 : {}
2851
- );
2852
- if ((_b = options.analytics) == null ? void 0 : _b.integrationType) {
2853
- analytics2.setGlobalProperty("integration_types", [
2854
- options.analytics.integrationType
2855
- ]);
3028
+ if (instance instanceof _MetaMaskConnectMultichain) {
3029
+ yield __privateMethod(_a3 = instance, _MetaMaskConnectMultichain_instances, setupAnalytics_fn).call(_a3);
3030
+ } else {
3031
+ yield setupAnalyticsGlobals(instance.options, instance.storage);
2856
3032
  }
2857
3033
  if (options.debug) {
2858
3034
  enableDebug("metamask-sdk:*");
@@ -2902,21 +3078,23 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2902
3078
  } else {
2903
3079
  transportType = "mwp" /* MWP */;
2904
3080
  }
2905
- try {
2906
- const baseProps = yield getBaseAnalyticsProperties(
2907
- this.options,
2908
- this.storage
2909
- );
2910
- const dappConfiguredChains = Object.keys(
2911
- this.options.api.supportedNetworks
2912
- );
2913
- analytics2.track("mmconnect_connection_initiated", __spreadProps(__spreadValues({}, baseProps), {
2914
- transport_type: transportType,
2915
- dapp_configured_chains: dappConfiguredChains,
2916
- dapp_requested_chains: scopes
2917
- }));
2918
- } catch (error) {
2919
- logger2("Error tracking connection_initiated event", error);
3081
+ if (isAnalyticsEnabled(this.options)) {
3082
+ try {
3083
+ const baseProps = yield getBaseAnalyticsProperties(
3084
+ this.options,
3085
+ this.storage
3086
+ );
3087
+ const dappConfiguredChains = Object.keys(
3088
+ this.options.api.supportedNetworks
3089
+ );
3090
+ analytics2.track("mmconnect_connection_initiated", __spreadProps(__spreadValues({}, baseProps), {
3091
+ transport_type: transportType,
3092
+ dapp_configured_chains: dappConfiguredChains,
3093
+ dapp_requested_chains: scopes
3094
+ }));
3095
+ } catch (error) {
3096
+ logger2("Error tracking connection_initiated event", error);
3097
+ }
2920
3098
  }
2921
3099
  const sessionData = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, getCaipSession_fn).call(this);
2922
3100
  const { mergedScopes, mergedCaipAccountIds, mergedSessionProperties } = mergeRequestedSessionWithExisting(
@@ -3059,30 +3237,9 @@ _sdkInfo = new WeakMap();
3059
3237
  _MetaMaskConnectMultichain_instances = new WeakSet();
3060
3238
  setupAnalytics_fn = function() {
3061
3239
  return __async(this, null, function* () {
3062
- var _a3, _b;
3063
- const platform = getPlatformType();
3064
- const isBrowser = platform === "in-app-browser" /* MetaMaskMobileWebview */ || platform === "web-desktop" /* DesktopWeb */ || platform === "web-mobile" /* MobileWeb */;
3065
- const isReactNative2 = platform === "react-native" /* ReactNative */;
3066
- if (!isBrowser && !isReactNative2) {
3067
- return;
3068
- }
3069
- const dappId = getDappId(this.options.dapp);
3070
- const anonId = yield this.storage.getAnonId();
3071
- __privateSet(this, _anonId, anonId);
3072
- const { integrationType } = (_a3 = this.options.analytics) != null ? _a3 : {
3073
- integrationType: ""
3074
- };
3075
- analytics2.setGlobalProperty(
3076
- "mmconnect_versions",
3077
- (_b = this.options.versions) != null ? _b : {}
3078
- );
3079
- analytics2.setGlobalProperty("dapp_id", dappId);
3080
- analytics2.setGlobalProperty("anon_id", anonId);
3081
- analytics2.setGlobalProperty("platform", platform);
3082
- if (integrationType) {
3083
- analytics2.setGlobalProperty("integration_types", [integrationType]);
3084
- }
3085
- analytics2.enable();
3240
+ yield setupAnalyticsGlobals(this.options, this.storage, (anonId) => {
3241
+ __privateSet(this, _anonId, anonId);
3242
+ });
3086
3243
  });
3087
3244
  };
3088
3245
  onTransportNotification_fn = function(payload) {
@@ -3171,7 +3328,7 @@ buildConnectionMetadata_fn = function() {
3171
3328
  dapp: this.options.dapp,
3172
3329
  sdk: { version: getVersion(), platform: getPlatformType() }
3173
3330
  };
3174
- if (__privateGet(this, _anonId)) {
3331
+ if (isAnalyticsEnabled(this.options) && __privateGet(this, _anonId)) {
3175
3332
  metadata.analytics = { remote_session_id: __privateGet(this, _anonId) };
3176
3333
  }
3177
3334
  return metadata;
@@ -3453,38 +3610,42 @@ handleConnection_fn = function(promise, scopes, transportType) {
3453
3610
  this.status = "connecting";
3454
3611
  return promise.then(() => __async(this, null, function* () {
3455
3612
  this.status = "connected";
3456
- try {
3457
- const baseProps = yield getBaseAnalyticsProperties(
3458
- this.options,
3459
- this.storage
3460
- );
3461
- analytics2.track("mmconnect_connection_established", __spreadProps(__spreadValues({}, baseProps), {
3462
- transport_type: transportType,
3463
- user_permissioned_chains: scopes
3464
- }));
3465
- } catch (error) {
3466
- logger2("Error tracking connection_established event", error);
3613
+ if (isAnalyticsEnabled(this.options)) {
3614
+ try {
3615
+ const baseProps = yield getBaseAnalyticsProperties(
3616
+ this.options,
3617
+ this.storage
3618
+ );
3619
+ analytics2.track("mmconnect_connection_established", __spreadProps(__spreadValues({}, baseProps), {
3620
+ transport_type: transportType,
3621
+ user_permissioned_chains: scopes
3622
+ }));
3623
+ } catch (error) {
3624
+ logger2("Error tracking connection_established event", error);
3625
+ }
3467
3626
  }
3468
3627
  return void 0;
3469
3628
  })).catch((error) => __async(this, null, function* () {
3470
3629
  this.status = "disconnected";
3471
- try {
3472
- const baseProps = yield getBaseAnalyticsProperties(
3473
- this.options,
3474
- this.storage
3475
- );
3476
- const isRejection = isRejectionError(error);
3477
- if (isRejection) {
3478
- analytics2.track("mmconnect_connection_rejected", __spreadProps(__spreadValues({}, baseProps), {
3479
- transport_type: transportType
3480
- }));
3481
- } else {
3482
- analytics2.track("mmconnect_connection_failed", __spreadProps(__spreadValues({}, baseProps), {
3483
- transport_type: transportType
3484
- }));
3630
+ if (isAnalyticsEnabled(this.options)) {
3631
+ try {
3632
+ const baseProps = yield getBaseAnalyticsProperties(
3633
+ this.options,
3634
+ this.storage
3635
+ );
3636
+ const isRejection = isRejectionError(error);
3637
+ if (isRejection) {
3638
+ analytics2.track("mmconnect_connection_rejected", __spreadProps(__spreadValues({}, baseProps), {
3639
+ transport_type: transportType
3640
+ }));
3641
+ } else {
3642
+ analytics2.track("mmconnect_connection_failed", __spreadValues(__spreadProps(__spreadValues({}, baseProps), {
3643
+ transport_type: transportType
3644
+ }), extractErrorDiagnostics(error)));
3645
+ }
3646
+ } catch (e) {
3647
+ logger2("Error tracking connection failed/rejected event", error);
3485
3648
  }
3486
- } catch (e) {
3487
- logger2("Error tracking connection failed/rejected event", error);
3488
3649
  }
3489
3650
  throw error;
3490
3651
  }));
@@ -3926,6 +4087,7 @@ export {
3926
4087
  StoreAdapter,
3927
4088
  StoreClient,
3928
4089
  TransportType,
4090
+ classifyFailureReason,
3929
4091
  createLogger,
3930
4092
  createMultichainClient,
3931
4093
  enableDebug,