@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
@@ -493,7 +493,7 @@ var init_multichain = __esm({
493
493
  }
494
494
  /**
495
495
  * Merges the given options into the current instance options.
496
- * Only the mergeable keys are updated (api.supportedNetworks, versions, ui.*, mobile.*, transport.extensionId, debug).
496
+ * Only the mergeable keys are updated (api.supportedNetworks, analytics, versions, ui.*, mobile.*, transport.extensionId, debug).
497
497
  * The main thing to note is that the value for `dapp` is not merged as it does not make sense for
498
498
  * subsequent calls to `createMultichainClient` to have a different `dapp` value.
499
499
  * Used when createMultichainClient is called with an existing singleton.
@@ -501,23 +501,28 @@ var init_multichain = __esm({
501
501
  * @param partial - Options to merge/overwrite onto the current instance
502
502
  */
503
503
  mergeOptions(partial) {
504
- var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
504
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
505
505
  const opts = this.options;
506
+ const analytics3 = __spreadValues(__spreadValues({}, opts.analytics), (_a3 = partial.analytics) != null ? _a3 : {});
507
+ if (((_b = opts.analytics) == null ? void 0 : _b.enabled) === false) {
508
+ analytics3.enabled = false;
509
+ }
506
510
  this.options = __spreadProps(__spreadValues({}, opts), {
507
511
  api: __spreadProps(__spreadValues({}, opts.api), {
508
- supportedNetworks: __spreadValues(__spreadValues({}, opts.api.supportedNetworks), (_b = (_a3 = partial.api) == null ? void 0 : _a3.supportedNetworks) != null ? _b : {})
512
+ supportedNetworks: __spreadValues(__spreadValues({}, opts.api.supportedNetworks), (_d = (_c = partial.api) == null ? void 0 : _c.supportedNetworks) != null ? _d : {})
509
513
  }),
510
- versions: __spreadValues(__spreadValues({}, opts.versions), (_c = partial.versions) != null ? _c : {}),
514
+ versions: __spreadValues(__spreadValues({}, opts.versions), (_e = partial.versions) != null ? _e : {}),
515
+ analytics: __spreadValues({}, analytics3),
511
516
  ui: __spreadProps(__spreadValues({}, opts.ui), {
512
- headless: (_e = (_d = partial.ui) == null ? void 0 : _d.headless) != null ? _e : opts.ui.headless,
513
- preferExtension: (_g = (_f = partial.ui) == null ? void 0 : _f.preferExtension) != null ? _g : opts.ui.preferExtension,
514
- showInstallModal: (_i = (_h = partial.ui) == null ? void 0 : _h.showInstallModal) != null ? _i : opts.ui.showInstallModal
517
+ headless: (_g = (_f = partial.ui) == null ? void 0 : _f.headless) != null ? _g : opts.ui.headless,
518
+ preferExtension: (_i = (_h = partial.ui) == null ? void 0 : _h.preferExtension) != null ? _i : opts.ui.preferExtension,
519
+ showInstallModal: (_k = (_j = partial.ui) == null ? void 0 : _j.showInstallModal) != null ? _k : opts.ui.showInstallModal
515
520
  }),
516
- mobile: __spreadValues(__spreadValues({}, opts.mobile), (_j = partial.mobile) != null ? _j : {}),
517
- transport: __spreadProps(__spreadValues({}, (_k = opts.transport) != null ? _k : {}), {
518
- extensionId: (_n = (_l = partial.transport) == null ? void 0 : _l.extensionId) != null ? _n : (_m = opts.transport) == null ? void 0 : _m.extensionId
521
+ mobile: __spreadValues(__spreadValues({}, opts.mobile), (_l = partial.mobile) != null ? _l : {}),
522
+ transport: __spreadProps(__spreadValues({}, (_m = opts.transport) != null ? _m : {}), {
523
+ extensionId: (_p = (_n = partial.transport) == null ? void 0 : _n.extensionId) != null ? _p : (_o = opts.transport) == null ? void 0 : _o.extensionId
519
524
  }),
520
- debug: (_o = partial.debug) != null ? _o : opts.debug
525
+ debug: (_q = partial.debug) != null ? _q : opts.debug
521
526
  });
522
527
  }
523
528
  };
@@ -700,17 +705,94 @@ var init_ui = __esm({
700
705
  });
701
706
 
702
707
  // src/multichain/utils/analytics.ts
708
+ function sanitiseErrorMessage(message) {
709
+ if (!message) {
710
+ return void 0;
711
+ }
712
+ let sanitised = message;
713
+ for (const { pattern, replacement } of SANITISE_PATTERNS) {
714
+ sanitised = sanitised.replace(pattern, replacement);
715
+ }
716
+ if (sanitised.length > ERROR_MESSAGE_SAMPLE_MAX_LENGTH) {
717
+ sanitised = `${sanitised.slice(0, ERROR_MESSAGE_SAMPLE_MAX_LENGTH - 1)}\u2026`;
718
+ }
719
+ return sanitised;
720
+ }
721
+ function getUnwrappedErrorDetails(error) {
722
+ var _a3, _b, _c, _d;
723
+ if (typeof error !== "object" || error === null) {
724
+ return { code: void 0, message: "" };
725
+ }
726
+ if (error instanceof RPCInvokeMethodErr) {
727
+ return {
728
+ code: (_a3 = error.rpcCode) != null ? _a3 : error.code,
729
+ message: (_c = (_b = error.rpcMessage) != null ? _b : error.message) != null ? _c : ""
730
+ };
731
+ }
732
+ const errorObj = error;
733
+ return {
734
+ code: errorObj.code,
735
+ message: (_d = errorObj.message) != null ? _d : ""
736
+ };
737
+ }
703
738
  function isRejectionError(error) {
704
- var _a3, _b;
705
739
  if (typeof error !== "object" || error === null) {
706
740
  return false;
707
741
  }
742
+ const { code, message } = getUnwrappedErrorDetails(error);
743
+ const errorMessage = message.toLowerCase();
744
+ return code === 4001 || errorMessage.includes("reject") || errorMessage.includes("denied") || errorMessage.includes("cancel") || // Narrow "user …" matches — bare "user" is too greedy (catches Account
745
+ // Abstraction errors like "user operation reverted").
746
+ errorMessage.includes("user rejected") || errorMessage.includes("user denied") || errorMessage.includes("user cancelled") || errorMessage.includes("user canceled");
747
+ }
748
+ function classifyFailureReason(error) {
749
+ var _a3, _b;
750
+ if (typeof error !== "object" || error === null) {
751
+ return "unknown";
752
+ }
708
753
  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");
754
+ const errorName = (_a3 = errorObj.name) != null ? _a3 : "";
755
+ const errorMessageRaw = (_b = errorObj.message) != null ? _b : "";
756
+ const errorMessage = errorMessageRaw.toLowerCase();
757
+ const { code } = getUnwrappedErrorDetails(error);
758
+ if (typeof code === "number") {
759
+ if (code === -32601) {
760
+ return "wallet_method_unsupported";
761
+ }
762
+ if (code === -32602) {
763
+ return "wallet_invalid_params";
764
+ }
765
+ if (code === -32603) {
766
+ return "wallet_internal_error";
767
+ }
768
+ if (code <= -32e3 && code >= -32099) {
769
+ return "wallet_internal_error";
770
+ }
771
+ if (code === 4100) {
772
+ return "wallet_unauthorized";
773
+ }
774
+ if (code === 4200) {
775
+ return "wallet_method_unsupported";
776
+ }
777
+ if (code === 4902) {
778
+ return "unrecognized_chain";
779
+ }
780
+ }
781
+ if (errorName === "TransportTimeoutError" || errorMessageRaw === "Request timeout" || errorMessage.includes("timed out") || errorMessage.includes("timeout")) {
782
+ return "transport_timeout";
783
+ }
784
+ if (errorName === "TransportError" || errorMessage.includes("not connected") || errorMessage.includes("transport disconnect") || errorMessage.includes("connection lost") || errorMessage.includes("socket closed")) {
785
+ return "transport_disconnect";
786
+ }
787
+ return "unknown";
788
+ }
789
+ function extractErrorDiagnostics(error) {
790
+ const failureReason = classifyFailureReason(error);
791
+ const { code, message } = getUnwrappedErrorDetails(error);
792
+ const messageSample = sanitiseErrorMessage(message);
793
+ return __spreadValues(__spreadValues({
794
+ failure_reason: failureReason
795
+ }, typeof code === "number" ? { error_code: code } : {}), messageSample ? { error_message_sample: messageSample } : {});
714
796
  }
715
797
  function getBaseAnalyticsProperties(options, storage) {
716
798
  return __async(this, null, function* () {
@@ -726,26 +808,61 @@ function getBaseAnalyticsProperties(options, storage) {
726
808
  };
727
809
  });
728
810
  }
729
- function getWalletActionAnalyticsProperties(options, storage, invokeOptions, transportType) {
811
+ function getWalletActionAnalyticsProperties(options, storage, invokeOptions, transportType, extra) {
730
812
  return __async(this, null, function* () {
731
813
  var _a3;
732
814
  const dappId = getDappId(options.dapp);
733
815
  const anonId = yield storage.getAnonId();
734
- return {
816
+ return __spreadValues(__spreadValues(__spreadValues({
735
817
  mmconnect_versions: (_a3 = options.versions) != null ? _a3 : {},
736
818
  dapp_id: dappId,
737
819
  method: invokeOptions.request.method,
738
820
  caip_chain_id: invokeOptions.scope,
739
821
  anon_id: anonId,
740
822
  transport_type: transportType
741
- };
823
+ }, (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
824
  });
743
825
  }
826
+ var ERROR_MESSAGE_SAMPLE_MAX_LENGTH, SANITISE_PATTERNS;
744
827
  var init_analytics = __esm({
745
828
  "src/multichain/utils/analytics.ts"() {
746
829
  "use strict";
747
830
  init_utils2();
748
831
  init_domain();
832
+ ERROR_MESSAGE_SAMPLE_MAX_LENGTH = 200;
833
+ SANITISE_PATTERNS = [
834
+ // EVM-style 20-byte hex addresses (e.g. `0x` + 40 hex chars).
835
+ { pattern: /0x[a-fA-F0-9]{40}/gu, replacement: "<addr>" },
836
+ // Other long hex blobs: tx hashes, signatures, raw byte strings, large
837
+ // hex amounts. 16+ hex chars catches 32-byte hashes/signatures without
838
+ // snagging EVM method selectors (8 chars) or short hex codes.
839
+ { pattern: /(?:0x)?[a-fA-F0-9]{16,}/gu, replacement: "<hex>" },
840
+ // URLs of any scheme up to the first whitespace / quote / closing paren.
841
+ // Catches RPC endpoints, dapp deeplinks, query strings with secrets.
842
+ { pattern: /https?:\/\/[^\s"')]+/gu, replacement: "<url>" },
843
+ // Bech32 addresses: short HRP (1-10 lowercase chars) + `1` separator +
844
+ // ≥38 chars of Bech32 data alphabet `[ac-hj-np-z02-9]` (excludes the
845
+ // look-alike chars `b`, `i`, `o`, `1`). Covers Bitcoin SegWit
846
+ // (`bc1…`/`tb1…`) and Cosmos-SDK chains (`cosmos1…`, `osmo1…`,
847
+ // `juno1…`, `inj1…`, etc.) without enumerating every HRP. Runs before
848
+ // the Base58 pattern below — see header comment for why.
849
+ {
850
+ pattern: /\b[a-z]{1,10}1[ac-hj-np-z02-9]{38,}\b/gu,
851
+ replacement: "<addr>"
852
+ },
853
+ // Base58 tokens (32+ chars, Base58 alphabet `[1-9A-HJ-NP-Za-km-z]`).
854
+ // Covers Solana pubkeys (32-44 chars), Solana tx signatures (~88 chars),
855
+ // and Bitcoin Base58 addresses ≥32 chars. The 32-char floor and `\b`
856
+ // word boundary keep English words and shorter alphanumerics safe.
857
+ {
858
+ pattern: /\b[1-9A-HJ-NP-Za-km-z]{32,}\b/gu,
859
+ replacement: "<addr>"
860
+ },
861
+ // Long decimal numbers — token amounts, gas units, timestamps, lamports.
862
+ // 10+ digits catches typical chain quantities without affecting JSON-RPC
863
+ // codes (-32601, 4001, etc.) or short numeric IDs.
864
+ { pattern: /\d{10,}/gu, replacement: "<num>" }
865
+ ];
749
866
  }
750
867
  });
751
868
 
@@ -1402,13 +1519,24 @@ var init_mwp = __esm({
1402
1519
  return resolveConnection();
1403
1520
  });
1404
1521
  this.dappClient.on("message", initialConnectionMessageHandler);
1522
+ const platformType = getPlatformType();
1523
+ const isQRCodeFlow = [
1524
+ "web-desktop" /* DesktopWeb */,
1525
+ "nodejs" /* NonBrowser */
1526
+ ].includes(platformType);
1527
+ const initialPayload = {
1528
+ name: MULTICHAIN_PROVIDER_STREAM_NAME,
1529
+ data: request
1530
+ };
1405
1531
  dappClient.connect({
1406
1532
  mode: "trusted",
1407
- initialPayload: {
1408
- name: MULTICHAIN_PROVIDER_STREAM_NAME,
1409
- data: request
1533
+ initialPayload: isQRCodeFlow ? void 0 : initialPayload
1534
+ }).then(() => __async(this, null, function* () {
1535
+ if (isQRCodeFlow) {
1536
+ return dappClient.sendRequest(initialPayload);
1410
1537
  }
1411
- }).catch((error) => {
1538
+ return void 0;
1539
+ })).catch((error) => {
1412
1540
  if (initialConnectionMessageHandler) {
1413
1541
  this.dappClient.off(
1414
1542
  "message",
@@ -2068,6 +2196,7 @@ __export(index_browser_exports, {
2068
2196
  StoreAdapter: () => StoreAdapter,
2069
2197
  StoreClient: () => StoreClient,
2070
2198
  TransportType: () => TransportType,
2199
+ classifyFailureReason: () => classifyFailureReason,
2071
2200
  createLogger: () => createLogger,
2072
2201
  createMultichainClient: () => createMultichainClient,
2073
2202
  enableDebug: () => enableDebug,
@@ -2221,6 +2350,17 @@ var import_analytics2 = require("@metamask/analytics");
2221
2350
  init_domain();
2222
2351
  init_utils2();
2223
2352
  init_analytics();
2353
+ function toRPCInvokeMethodErr(error) {
2354
+ var _a3;
2355
+ if (error instanceof RPCInvokeMethodErr) {
2356
+ return error;
2357
+ }
2358
+ const castError = error;
2359
+ return new RPCInvokeMethodErr(
2360
+ (_a3 = castError.message) != null ? _a3 : "Unknown error",
2361
+ castError.code
2362
+ );
2363
+ }
2224
2364
  var _RequestRouter_instances, withAnalyticsTracking_fn, trackWalletActionRequested_fn, trackWalletActionSucceeded_fn, trackWalletActionFailed_fn, trackWalletActionRejected_fn;
2225
2365
  var RequestRouter = class {
2226
2366
  constructor(transport, rpcClient, config, transportType) {
@@ -2327,6 +2467,13 @@ _RequestRouter_instances = new WeakSet();
2327
2467
  withAnalyticsTracking_fn = function(options, execute) {
2328
2468
  return __async(this, null, function* () {
2329
2469
  var _a3;
2470
+ if (((_a3 = this.config.analytics) == null ? void 0 : _a3.enabled) === false) {
2471
+ try {
2472
+ return yield execute();
2473
+ } catch (error) {
2474
+ throw toRPCInvokeMethodErr(error);
2475
+ }
2476
+ }
2330
2477
  yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRequested_fn).call(this, options);
2331
2478
  try {
2332
2479
  const result = yield execute();
@@ -2337,16 +2484,9 @@ withAnalyticsTracking_fn = function(options, execute) {
2337
2484
  if (isRejection) {
2338
2485
  yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRejected_fn).call(this, options);
2339
2486
  } else {
2340
- yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options);
2341
- }
2342
- if (error instanceof RPCInvokeMethodErr) {
2343
- throw error;
2487
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options, error);
2344
2488
  }
2345
- const castError = error;
2346
- throw new RPCInvokeMethodErr(
2347
- (_a3 = castError.message) != null ? _a3 : "Unknown error",
2348
- castError.code
2349
- );
2489
+ throw toRPCInvokeMethodErr(error);
2350
2490
  }
2351
2491
  });
2352
2492
  };
@@ -2372,13 +2512,14 @@ trackWalletActionSucceeded_fn = function(options) {
2372
2512
  import_analytics2.analytics.track("mmconnect_wallet_action_succeeded", props);
2373
2513
  });
2374
2514
  };
2375
- trackWalletActionFailed_fn = function(options) {
2515
+ trackWalletActionFailed_fn = function(options, error) {
2376
2516
  return __async(this, null, function* () {
2377
2517
  const props = yield getWalletActionAnalyticsProperties(
2378
2518
  this.config,
2379
2519
  this.config.storage,
2380
2520
  options,
2381
- this.transportType
2521
+ this.transportType,
2522
+ extractErrorDiagnostics(error)
2382
2523
  );
2383
2524
  import_analytics2.analytics.track("mmconnect_wallet_action_failed", props);
2384
2525
  });
@@ -2804,26 +2945,65 @@ walletInvokeMethod_fn = function(request) {
2804
2945
  init_utils2();
2805
2946
  var logger2 = createLogger("metamask-sdk:core");
2806
2947
  var SINGLETON_KEY = "__METAMASK_CONNECT_MULTICHAIN_SINGLETON__";
2948
+ function normalizeAnalyticsOptions(analyticsOptions) {
2949
+ var _a3;
2950
+ return __spreadProps(__spreadValues({}, analyticsOptions != null ? analyticsOptions : {}), {
2951
+ enabled: (_a3 = analyticsOptions == null ? void 0 : analyticsOptions.enabled) != null ? _a3 : true,
2952
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
2953
+ integrationType: (analyticsOptions == null ? void 0 : analyticsOptions.integrationType) || "direct"
2954
+ });
2955
+ }
2956
+ function isAnalyticsEnabled(options) {
2957
+ var _a3;
2958
+ return ((_a3 = options.analytics) == null ? void 0 : _a3.enabled) !== false;
2959
+ }
2960
+ function setupAnalyticsGlobals(options, storage, setAnonId) {
2961
+ return __async(this, null, function* () {
2962
+ var _a3, _b;
2963
+ if (!isAnalyticsEnabled(options)) {
2964
+ setAnonId == null ? void 0 : setAnonId(void 0);
2965
+ import_analytics4.analytics.disable();
2966
+ return;
2967
+ }
2968
+ const platform = getPlatformType();
2969
+ const isBrowser = platform === "in-app-browser" /* MetaMaskMobileWebview */ || platform === "web-desktop" /* DesktopWeb */ || platform === "web-mobile" /* MobileWeb */;
2970
+ const isReactNative2 = platform === "react-native" /* ReactNative */;
2971
+ if (!isBrowser && !isReactNative2) {
2972
+ return;
2973
+ }
2974
+ const dappId = getDappId(options.dapp);
2975
+ const anonId = yield storage.getAnonId();
2976
+ setAnonId == null ? void 0 : setAnonId(anonId);
2977
+ const { integrationType } = (_a3 = options.analytics) != null ? _a3 : {
2978
+ integrationType: ""
2979
+ };
2980
+ import_analytics4.analytics.setGlobalProperty("mmconnect_versions", (_b = options.versions) != null ? _b : {});
2981
+ import_analytics4.analytics.setGlobalProperty("dapp_id", dappId);
2982
+ import_analytics4.analytics.setGlobalProperty("anon_id", anonId);
2983
+ import_analytics4.analytics.setGlobalProperty("platform", platform);
2984
+ if (integrationType) {
2985
+ import_analytics4.analytics.setGlobalProperty("integration_types", [integrationType]);
2986
+ }
2987
+ import_analytics4.analytics.enable();
2988
+ });
2989
+ }
2807
2990
  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;
2808
2991
  var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends MultichainCore {
2809
2992
  constructor(options) {
2810
- var _a3, _b, _c, _d, _e, _f;
2993
+ var _a3, _b, _c, _d;
2811
2994
  const withDappMetadata = setupDappMetadata(options);
2812
- const integrationType = ((_a3 = options.analytics) == null ? void 0 : _a3.integrationType) || "direct";
2813
2995
  const allOptions = __spreadProps(__spreadValues({}, withDappMetadata), {
2814
2996
  ui: __spreadProps(__spreadValues({}, withDappMetadata.ui), {
2815
- preferExtension: (_b = withDappMetadata.ui.preferExtension) != null ? _b : true,
2816
- showInstallModal: (_c = withDappMetadata.ui.showInstallModal) != null ? _c : false,
2817
- headless: (_d = withDappMetadata.ui.headless) != null ? _d : false
2818
- }),
2819
- analytics: __spreadProps(__spreadValues({}, (_e = options.analytics) != null ? _e : {}), {
2820
- integrationType
2997
+ preferExtension: (_a3 = withDappMetadata.ui.preferExtension) != null ? _a3 : true,
2998
+ showInstallModal: (_b = withDappMetadata.ui.showInstallModal) != null ? _b : false,
2999
+ headless: (_c = withDappMetadata.ui.headless) != null ? _c : false
2821
3000
  }),
3001
+ analytics: normalizeAnalyticsOptions(options.analytics),
2822
3002
  versions: __spreadValues({
2823
3003
  // typeof guard needed: Metro (React Native) bundles TS source directly,
2824
3004
  // bypassing the tsup build that substitutes __PACKAGE_VERSION__.
2825
- "connect-multichain": false ? "unknown" : "0.13.0"
2826
- }, (_f = options.versions) != null ? _f : {})
3005
+ "connect-multichain": false ? "unknown" : "0.15.0"
3006
+ }, (_d = options.versions) != null ? _d : {})
2827
3007
  });
2828
3008
  super(allOptions);
2829
3009
  __privateAdd(this, _MetaMaskConnectMultichain_instances);
@@ -2879,25 +3059,22 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2879
3059
  // Creates a singleton instance of MetaMaskConnectMultichain.
2880
3060
  // If the singleton already exists, it merges the incoming options with the
2881
3061
  // existing singleton options for the following keys: `api.supportedNetworks`,
2882
- // `versions`, `ui.*`, `mobile.*`, `transport.extensionId`, `debug`. Take note
2883
- // that the value for `dapp` is not merged as it does not make sense for
2884
- // subsequent calls to `createMultichainClient` to have a different `dapp` value.
3062
+ // `analytics`, `versions`, `ui.*`, `mobile.*`, `transport.extensionId`,
3063
+ // `debug`. Take note that the value for `dapp` is not merged as it does not
3064
+ // make sense for subsequent calls to `createMultichainClient` to have a
3065
+ // different `dapp` value.
2885
3066
  static create(options) {
2886
3067
  return __async(this, null, function* () {
2887
- var _a3, _b;
3068
+ var _a3;
2888
3069
  const globalObject = getGlobalObject();
2889
3070
  const existing = globalObject[SINGLETON_KEY];
2890
3071
  if (existing) {
2891
3072
  const instance = yield existing;
2892
3073
  instance.mergeOptions(options);
2893
- import_analytics4.analytics.setGlobalProperty(
2894
- "mmconnect_versions",
2895
- (_a3 = instance.options.versions) != null ? _a3 : {}
2896
- );
2897
- if ((_b = options.analytics) == null ? void 0 : _b.integrationType) {
2898
- import_analytics4.analytics.setGlobalProperty("integration_types", [
2899
- options.analytics.integrationType
2900
- ]);
3074
+ if (instance instanceof _MetaMaskConnectMultichain) {
3075
+ yield __privateMethod(_a3 = instance, _MetaMaskConnectMultichain_instances, setupAnalytics_fn).call(_a3);
3076
+ } else {
3077
+ yield setupAnalyticsGlobals(instance.options, instance.storage);
2901
3078
  }
2902
3079
  if (options.debug) {
2903
3080
  enableDebug("metamask-sdk:*");
@@ -2947,21 +3124,23 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2947
3124
  } else {
2948
3125
  transportType = "mwp" /* MWP */;
2949
3126
  }
2950
- try {
2951
- const baseProps = yield getBaseAnalyticsProperties(
2952
- this.options,
2953
- this.storage
2954
- );
2955
- const dappConfiguredChains = Object.keys(
2956
- this.options.api.supportedNetworks
2957
- );
2958
- import_analytics4.analytics.track("mmconnect_connection_initiated", __spreadProps(__spreadValues({}, baseProps), {
2959
- transport_type: transportType,
2960
- dapp_configured_chains: dappConfiguredChains,
2961
- dapp_requested_chains: scopes
2962
- }));
2963
- } catch (error) {
2964
- logger2("Error tracking connection_initiated event", error);
3127
+ if (isAnalyticsEnabled(this.options)) {
3128
+ try {
3129
+ const baseProps = yield getBaseAnalyticsProperties(
3130
+ this.options,
3131
+ this.storage
3132
+ );
3133
+ const dappConfiguredChains = Object.keys(
3134
+ this.options.api.supportedNetworks
3135
+ );
3136
+ import_analytics4.analytics.track("mmconnect_connection_initiated", __spreadProps(__spreadValues({}, baseProps), {
3137
+ transport_type: transportType,
3138
+ dapp_configured_chains: dappConfiguredChains,
3139
+ dapp_requested_chains: scopes
3140
+ }));
3141
+ } catch (error) {
3142
+ logger2("Error tracking connection_initiated event", error);
3143
+ }
2965
3144
  }
2966
3145
  const sessionData = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, getCaipSession_fn).call(this);
2967
3146
  const { mergedScopes, mergedCaipAccountIds, mergedSessionProperties } = mergeRequestedSessionWithExisting(
@@ -3104,30 +3283,9 @@ _sdkInfo = new WeakMap();
3104
3283
  _MetaMaskConnectMultichain_instances = new WeakSet();
3105
3284
  setupAnalytics_fn = function() {
3106
3285
  return __async(this, null, function* () {
3107
- var _a3, _b;
3108
- const platform = getPlatformType();
3109
- const isBrowser = platform === "in-app-browser" /* MetaMaskMobileWebview */ || platform === "web-desktop" /* DesktopWeb */ || platform === "web-mobile" /* MobileWeb */;
3110
- const isReactNative2 = platform === "react-native" /* ReactNative */;
3111
- if (!isBrowser && !isReactNative2) {
3112
- return;
3113
- }
3114
- const dappId = getDappId(this.options.dapp);
3115
- const anonId = yield this.storage.getAnonId();
3116
- __privateSet(this, _anonId, anonId);
3117
- const { integrationType } = (_a3 = this.options.analytics) != null ? _a3 : {
3118
- integrationType: ""
3119
- };
3120
- import_analytics4.analytics.setGlobalProperty(
3121
- "mmconnect_versions",
3122
- (_b = this.options.versions) != null ? _b : {}
3123
- );
3124
- import_analytics4.analytics.setGlobalProperty("dapp_id", dappId);
3125
- import_analytics4.analytics.setGlobalProperty("anon_id", anonId);
3126
- import_analytics4.analytics.setGlobalProperty("platform", platform);
3127
- if (integrationType) {
3128
- import_analytics4.analytics.setGlobalProperty("integration_types", [integrationType]);
3129
- }
3130
- import_analytics4.analytics.enable();
3286
+ yield setupAnalyticsGlobals(this.options, this.storage, (anonId) => {
3287
+ __privateSet(this, _anonId, anonId);
3288
+ });
3131
3289
  });
3132
3290
  };
3133
3291
  onTransportNotification_fn = function(payload) {
@@ -3216,7 +3374,7 @@ buildConnectionMetadata_fn = function() {
3216
3374
  dapp: this.options.dapp,
3217
3375
  sdk: { version: getVersion(), platform: getPlatformType() }
3218
3376
  };
3219
- if (__privateGet(this, _anonId)) {
3377
+ if (isAnalyticsEnabled(this.options) && __privateGet(this, _anonId)) {
3220
3378
  metadata.analytics = { remote_session_id: __privateGet(this, _anonId) };
3221
3379
  }
3222
3380
  return metadata;
@@ -3498,38 +3656,42 @@ handleConnection_fn = function(promise, scopes, transportType) {
3498
3656
  this.status = "connecting";
3499
3657
  return promise.then(() => __async(this, null, function* () {
3500
3658
  this.status = "connected";
3501
- try {
3502
- const baseProps = yield getBaseAnalyticsProperties(
3503
- this.options,
3504
- this.storage
3505
- );
3506
- import_analytics4.analytics.track("mmconnect_connection_established", __spreadProps(__spreadValues({}, baseProps), {
3507
- transport_type: transportType,
3508
- user_permissioned_chains: scopes
3509
- }));
3510
- } catch (error) {
3511
- logger2("Error tracking connection_established event", error);
3659
+ if (isAnalyticsEnabled(this.options)) {
3660
+ try {
3661
+ const baseProps = yield getBaseAnalyticsProperties(
3662
+ this.options,
3663
+ this.storage
3664
+ );
3665
+ import_analytics4.analytics.track("mmconnect_connection_established", __spreadProps(__spreadValues({}, baseProps), {
3666
+ transport_type: transportType,
3667
+ user_permissioned_chains: scopes
3668
+ }));
3669
+ } catch (error) {
3670
+ logger2("Error tracking connection_established event", error);
3671
+ }
3512
3672
  }
3513
3673
  return void 0;
3514
3674
  })).catch((error) => __async(this, null, function* () {
3515
3675
  this.status = "disconnected";
3516
- try {
3517
- const baseProps = yield getBaseAnalyticsProperties(
3518
- this.options,
3519
- this.storage
3520
- );
3521
- const isRejection = isRejectionError(error);
3522
- if (isRejection) {
3523
- import_analytics4.analytics.track("mmconnect_connection_rejected", __spreadProps(__spreadValues({}, baseProps), {
3524
- transport_type: transportType
3525
- }));
3526
- } else {
3527
- import_analytics4.analytics.track("mmconnect_connection_failed", __spreadProps(__spreadValues({}, baseProps), {
3528
- transport_type: transportType
3529
- }));
3676
+ if (isAnalyticsEnabled(this.options)) {
3677
+ try {
3678
+ const baseProps = yield getBaseAnalyticsProperties(
3679
+ this.options,
3680
+ this.storage
3681
+ );
3682
+ const isRejection = isRejectionError(error);
3683
+ if (isRejection) {
3684
+ import_analytics4.analytics.track("mmconnect_connection_rejected", __spreadProps(__spreadValues({}, baseProps), {
3685
+ transport_type: transportType
3686
+ }));
3687
+ } else {
3688
+ import_analytics4.analytics.track("mmconnect_connection_failed", __spreadValues(__spreadProps(__spreadValues({}, baseProps), {
3689
+ transport_type: transportType
3690
+ }), extractErrorDiagnostics(error)));
3691
+ }
3692
+ } catch (e) {
3693
+ logger2("Error tracking connection failed/rejected event", error);
3530
3694
  }
3531
- } catch (e) {
3532
- logger2("Error tracking connection failed/rejected event", error);
3533
3695
  }
3534
3696
  throw error;
3535
3697
  }));