@metamask/connect-multichain 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/dist/browser/es/connect-multichain.d.mts +67 -13
  3. package/dist/browser/es/connect-multichain.mjs +895 -384
  4. package/dist/browser/es/connect-multichain.mjs.map +1 -1
  5. package/dist/browser/es/metafile-esm.json +1 -1
  6. package/dist/browser/iife/connect-multichain.d.ts +67 -13
  7. package/dist/browser/iife/connect-multichain.js +21636 -14459
  8. package/dist/browser/iife/connect-multichain.js.map +1 -1
  9. package/dist/browser/iife/metafile-iife.json +1 -1
  10. package/dist/browser/umd/connect-multichain.d.ts +67 -13
  11. package/dist/browser/umd/connect-multichain.js +893 -382
  12. package/dist/browser/umd/connect-multichain.js.map +1 -1
  13. package/dist/browser/umd/metafile-cjs.json +1 -1
  14. package/dist/node/cjs/connect-multichain.d.ts +67 -13
  15. package/dist/node/cjs/connect-multichain.js +898 -385
  16. package/dist/node/cjs/connect-multichain.js.map +1 -1
  17. package/dist/node/cjs/metafile-cjs.json +1 -1
  18. package/dist/node/es/connect-multichain.d.mts +67 -13
  19. package/dist/node/es/connect-multichain.mjs +898 -387
  20. package/dist/node/es/connect-multichain.mjs.map +1 -1
  21. package/dist/node/es/metafile-esm.json +1 -1
  22. package/dist/react-native/es/connect-multichain.d.mts +67 -13
  23. package/dist/react-native/es/connect-multichain.mjs +897 -386
  24. package/dist/react-native/es/connect-multichain.mjs.map +1 -1
  25. package/dist/react-native/es/metafile-esm.json +1 -1
  26. package/dist/src/domain/events/index.d.ts +26 -0
  27. package/dist/src/domain/events/index.d.ts.map +1 -1
  28. package/dist/src/domain/events/index.js +35 -0
  29. package/dist/src/domain/events/index.js.map +1 -1
  30. package/dist/src/domain/multichain/index.d.ts +7 -5
  31. package/dist/src/domain/multichain/index.d.ts.map +1 -1
  32. package/dist/src/domain/multichain/index.js +2 -2
  33. package/dist/src/domain/multichain/index.js.map +1 -1
  34. package/dist/src/domain/multichain/types.d.ts +9 -7
  35. package/dist/src/domain/multichain/types.d.ts.map +1 -1
  36. package/dist/src/domain/platform/index.js +3 -3
  37. package/dist/src/domain/platform/index.js.map +1 -1
  38. package/dist/src/domain/ui/factory.d.ts +1 -1
  39. package/dist/src/domain/ui/factory.d.ts.map +1 -1
  40. package/dist/src/domain/utils/index.d.ts +1 -0
  41. package/dist/src/domain/utils/index.d.ts.map +1 -1
  42. package/dist/src/domain/utils/index.js +1 -0
  43. package/dist/src/domain/utils/index.js.map +1 -1
  44. package/dist/src/multichain/index.d.ts +5 -2
  45. package/dist/src/multichain/index.d.ts.map +1 -1
  46. package/dist/src/multichain/index.js +124 -38
  47. package/dist/src/multichain/index.js.map +1 -1
  48. package/dist/src/multichain/rpc/handlers/rpcClient.d.ts +2 -1
  49. package/dist/src/multichain/rpc/handlers/rpcClient.d.ts.map +1 -1
  50. package/dist/src/multichain/rpc/handlers/rpcClient.js +16 -17
  51. package/dist/src/multichain/rpc/handlers/rpcClient.js.map +1 -1
  52. package/dist/src/multichain/rpc/requestRouter.d.ts +1 -0
  53. package/dist/src/multichain/rpc/requestRouter.d.ts.map +1 -1
  54. package/dist/src/multichain/rpc/requestRouter.js +71 -15
  55. package/dist/src/multichain/rpc/requestRouter.js.map +1 -1
  56. package/dist/src/multichain/transports/constants.d.ts +3 -0
  57. package/dist/src/multichain/transports/constants.d.ts.map +1 -0
  58. package/dist/src/multichain/transports/constants.js +3 -0
  59. package/dist/src/multichain/transports/constants.js.map +1 -0
  60. package/dist/src/multichain/transports/default/index.d.ts +4 -0
  61. package/dist/src/multichain/transports/default/index.d.ts.map +1 -1
  62. package/dist/src/multichain/transports/default/index.js +137 -13
  63. package/dist/src/multichain/transports/default/index.js.map +1 -1
  64. package/dist/src/multichain/transports/mwp/index.d.ts +10 -1
  65. package/dist/src/multichain/transports/mwp/index.d.ts.map +1 -1
  66. package/dist/src/multichain/transports/mwp/index.js +138 -10
  67. package/dist/src/multichain/transports/mwp/index.js.map +1 -1
  68. package/dist/src/multichain/utils/analytics.d.ts +39 -0
  69. package/dist/src/multichain/utils/analytics.d.ts.map +1 -0
  70. package/dist/src/multichain/utils/analytics.js +83 -0
  71. package/dist/src/multichain/utils/analytics.js.map +1 -0
  72. package/dist/src/multichain/utils/index.d.ts +0 -1
  73. package/dist/src/multichain/utils/index.d.ts.map +1 -1
  74. package/dist/src/multichain/utils/index.js +1 -16
  75. package/dist/src/multichain/utils/index.js.map +1 -1
  76. package/dist/src/ui/index.d.ts +1 -1
  77. package/dist/src/ui/index.d.ts.map +1 -1
  78. package/dist/src/ui/index.js +35 -19
  79. package/dist/src/ui/index.js.map +1 -1
  80. package/dist/src/ui/modals/web/install.js +1 -1
  81. package/dist/src/ui/modals/web/install.js.map +1 -1
  82. package/dist/types/connect-multichain.d.ts +67 -13
  83. package/package.json +12 -9
@@ -53,6 +53,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
53
53
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
54
54
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
55
55
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
56
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
56
57
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
57
58
  var __async = (__this, __arguments, generator) => {
58
59
  return new Promise((resolve, reject) => {
@@ -197,6 +198,41 @@ var init_events = __esm({
197
198
  off(eventName, handler) {
198
199
  __privateGet(this, _emitter).off(eventName, handler);
199
200
  }
201
+ /**
202
+ * Removes a specific event handler for the specified event.
203
+ * Added for compatibility as some libraries use this method name.
204
+ *
205
+ * @template TEventName - The name of the event to remove the handler from (must be a key of TEvents)
206
+ * @param eventName - The name of the event to remove the handler from
207
+ * @param handler - The specific handler function to remove
208
+ */
209
+ removeListener(eventName, handler) {
210
+ __privateGet(this, _emitter).off(eventName, handler);
211
+ }
212
+ /**
213
+ * Registers an event handler for the specified event that will only be called once.
214
+ *
215
+ * @template TEventName - The name of the event to listen for (must be a key of TEvents)
216
+ * @param eventName - The name of the event to listen for
217
+ * @param handler - The function to call when the event is emitted (only once)
218
+ * @returns A function to remove the listener
219
+ */
220
+ once(eventName, handler) {
221
+ __privateGet(this, _emitter).once(eventName, handler);
222
+ return () => {
223
+ this.off(eventName, handler);
224
+ };
225
+ }
226
+ /**
227
+ * Returns the number of listeners registered for the specified event.
228
+ *
229
+ * @template TEventName - The name of the event to count listeners for (must be a key of TEvents)
230
+ * @param eventName - The name of the event to count listeners for
231
+ * @returns The number of listeners registered for the event
232
+ */
233
+ listenerCount(eventName) {
234
+ return __privateGet(this, _emitter).listenerCount(eventName);
235
+ }
200
236
  };
201
237
  _emitter = new WeakMap();
202
238
  }
@@ -361,7 +397,7 @@ function getTransportType(type) {
361
397
  case "browser":
362
398
  return "browser" /* Browser */;
363
399
  case "mwp":
364
- return "mwp" /* MPW */;
400
+ return "mwp" /* MWP */;
365
401
  default:
366
402
  return "unknown" /* UNKNOWN */;
367
403
  }
@@ -375,7 +411,7 @@ var init_multichain = __esm({
375
411
  init_infura();
376
412
  TransportType = /* @__PURE__ */ ((TransportType2) => {
377
413
  TransportType2["Browser"] = "browser";
378
- TransportType2["MPW"] = "mwp";
414
+ TransportType2["MWP"] = "mwp";
379
415
  TransportType2["UNKNOWN"] = "unknown";
380
416
  return TransportType2;
381
417
  })(TransportType || {});
@@ -417,7 +453,7 @@ function isMetaMaskMobileWebView() {
417
453
  }
418
454
  function isMobile() {
419
455
  var _a, _b;
420
- const browser = (0, import_bowser.parse)(window.navigator.userAgent);
456
+ const browser = import_bowser.default.parse(window.navigator.userAgent);
421
457
  return ((_a = browser == null ? void 0 : browser.platform) == null ? void 0 : _a.type) === "mobile" || ((_b = browser == null ? void 0 : browser.platform) == null ? void 0 : _b.type) === "tablet";
422
458
  }
423
459
  function getPlatformType() {
@@ -455,7 +491,7 @@ var import_bowser, PlatformType, detectionPromise;
455
491
  var init_platform = __esm({
456
492
  "src/domain/platform/index.ts"() {
457
493
  "use strict";
458
- import_bowser = require("bowser");
494
+ import_bowser = __toESM(require("bowser"));
459
495
  PlatformType = /* @__PURE__ */ ((PlatformType2) => {
460
496
  PlatformType2["NonBrowser"] = "nodejs";
461
497
  PlatformType2["MetaMaskMobileWebview"] = "in-app-browser";
@@ -483,8 +519,8 @@ var init_platform = __esm({
483
519
  window.removeEventListener("eip6963:announceProvider", handler);
484
520
  const hasMetaMask = providers.some(
485
521
  (provider) => {
486
- var _a;
487
- return ((_a = provider == null ? void 0 : provider.info) == null ? void 0 : _a.rdns) === "io.metamask";
522
+ var _a, _b;
523
+ return (_b = (_a = provider == null ? void 0 : provider.info) == null ? void 0 : _a.rdns) == null ? void 0 : _b.startsWith("io.metamask");
488
524
  }
489
525
  );
490
526
  resolve(hasMetaMask);
@@ -568,13 +604,262 @@ var init_ui = __esm({
568
604
  }
569
605
  });
570
606
 
607
+ // src/multichain/utils/index.ts
608
+ function base64Encode(str) {
609
+ if (typeof btoa !== "undefined") {
610
+ return btoa(str);
611
+ } else if (typeof Buffer !== "undefined") {
612
+ return Buffer.from(str).toString("base64");
613
+ }
614
+ throw new Error("No base64 encoding method available");
615
+ }
616
+ function compressString(str) {
617
+ const compressed = (0, import_pako.deflate)(str);
618
+ const binaryString = String.fromCharCode.apply(null, Array.from(compressed));
619
+ return base64Encode(binaryString);
620
+ }
621
+ function getDappId(dapp) {
622
+ var _a, _b;
623
+ if (typeof window === "undefined" || typeof window.location === "undefined") {
624
+ return (_b = (_a = dapp == null ? void 0 : dapp.name) != null ? _a : dapp == null ? void 0 : dapp.url) != null ? _b : "N/A";
625
+ }
626
+ return window.location.hostname;
627
+ }
628
+ function openDeeplink(options, deeplink, universalLink) {
629
+ const { mobile } = options;
630
+ const useDeeplink = mobile && mobile.useDeeplink !== void 0 ? mobile.useDeeplink : true;
631
+ if (useDeeplink) {
632
+ if (typeof window !== "undefined") {
633
+ window.location.href = deeplink;
634
+ }
635
+ } else if (typeof document !== "undefined") {
636
+ const link = document.createElement("a");
637
+ link.href = universalLink;
638
+ link.target = "_self";
639
+ link.rel = "noreferrer noopener";
640
+ link.click();
641
+ }
642
+ }
643
+ function getOptionalScopes(scopes) {
644
+ return scopes.reduce(
645
+ (prev, scope) => __spreadProps(__spreadValues({}, prev), {
646
+ [scope]: {
647
+ methods: [],
648
+ notifications: [],
649
+ accounts: []
650
+ }
651
+ }),
652
+ {}
653
+ );
654
+ }
655
+ function setupDappMetadata(options) {
656
+ var _a;
657
+ const platform = getPlatformType();
658
+ const isBrowser = platform === "web-desktop" /* DesktopWeb */ || platform === "web-mobile" /* MobileWeb */ || platform === "in-app-browser" /* MetaMaskMobileWebview */;
659
+ if (!((_a = options.dapp) == null ? void 0 : _a.url)) {
660
+ if (isBrowser) {
661
+ options.dapp = __spreadProps(__spreadValues({}, options.dapp), {
662
+ url: `${window.location.protocol}//${window.location.host}`
663
+ });
664
+ } else {
665
+ throw new Error("You must provide dapp url");
666
+ }
667
+ }
668
+ const BASE_64_ICON_MAX_LENGTH = 163400;
669
+ const urlPattern = /^(http|https):\/\/[^\s]*$/;
670
+ if (options.dapp) {
671
+ if ("iconUrl" in options.dapp) {
672
+ if (options.dapp.iconUrl && !urlPattern.test(options.dapp.iconUrl)) {
673
+ console.warn(
674
+ "Invalid dappMetadata.iconUrl: URL must start with http:// or https://"
675
+ );
676
+ options.dapp.iconUrl = void 0;
677
+ }
678
+ }
679
+ if ("base64Icon" in options.dapp) {
680
+ if (options.dapp.base64Icon && options.dapp.base64Icon.length > BASE_64_ICON_MAX_LENGTH) {
681
+ console.warn(
682
+ "Invalid dappMetadata.base64Icon: Base64-encoded icon string length must be less than 163400 characters"
683
+ );
684
+ options.dapp.base64Icon = void 0;
685
+ }
686
+ }
687
+ if (options.dapp.url && !urlPattern.test(options.dapp.url)) {
688
+ console.warn(
689
+ "Invalid dappMetadata.url: URL must start with http:// or https://"
690
+ );
691
+ }
692
+ const favicon = extractFavicon();
693
+ if (favicon && !("iconUrl" in options.dapp) && !("base64Icon" in options.dapp)) {
694
+ const faviconUrl = `${window.location.protocol}//${window.location.host}${favicon}`;
695
+ options.dapp.iconUrl = faviconUrl;
696
+ }
697
+ }
698
+ return options;
699
+ }
700
+ function isSameScopesAndAccounts(currentScopes, proposedScopes, walletSession, proposedCaipAccountIds) {
701
+ const isSameScopes = currentScopes.every((scope) => proposedScopes.includes(scope)) && proposedScopes.every((scope) => currentScopes.includes(scope));
702
+ if (!isSameScopes) {
703
+ return false;
704
+ }
705
+ const existingAccountIds = Object.values(
706
+ walletSession.sessionScopes
707
+ ).filter(({ accounts }) => Boolean(accounts)).flatMap(({ accounts }) => accounts != null ? accounts : []);
708
+ const allProposedAccountsIncluded = proposedCaipAccountIds.every(
709
+ (proposedAccountId) => existingAccountIds.includes(proposedAccountId)
710
+ );
711
+ return allProposedAccountsIncluded;
712
+ }
713
+ function getValidAccounts(caipAccountIds) {
714
+ return caipAccountIds.reduce(
715
+ (caipAccounts, caipAccountId) => {
716
+ try {
717
+ return [...caipAccounts, (0, import_utils.parseCaipAccountId)(caipAccountId)];
718
+ } catch (err) {
719
+ const stringifiedAccountId = JSON.stringify(caipAccountId);
720
+ console.error(`Invalid CAIP account ID: ${stringifiedAccountId}`, err);
721
+ return caipAccounts;
722
+ }
723
+ },
724
+ []
725
+ );
726
+ }
727
+ function addValidAccounts(optionalScopes, validAccounts) {
728
+ var _a;
729
+ if (!optionalScopes || !(validAccounts == null ? void 0 : validAccounts.length)) {
730
+ return optionalScopes;
731
+ }
732
+ const result = Object.fromEntries(
733
+ Object.entries(optionalScopes).map(([scope, scopeData]) => {
734
+ var _a2, _b, _c;
735
+ return [
736
+ scope,
737
+ {
738
+ methods: [...(_a2 = scopeData == null ? void 0 : scopeData.methods) != null ? _a2 : []],
739
+ notifications: [...(_b = scopeData == null ? void 0 : scopeData.notifications) != null ? _b : []],
740
+ accounts: [...(_c = scopeData == null ? void 0 : scopeData.accounts) != null ? _c : []]
741
+ }
742
+ ];
743
+ })
744
+ );
745
+ const accountsByChain = /* @__PURE__ */ new Map();
746
+ for (const account of validAccounts) {
747
+ const chainKey = `${account.chain.namespace}:${account.chain.reference}`;
748
+ const accountId = `${account.chainId}:${account.address}`;
749
+ if (!accountsByChain.has(chainKey)) {
750
+ accountsByChain.set(chainKey, []);
751
+ }
752
+ (_a = accountsByChain.get(chainKey)) == null ? void 0 : _a.push(accountId);
753
+ }
754
+ for (const [scopeKey, scopeData] of Object.entries(result)) {
755
+ if (!(scopeData == null ? void 0 : scopeData.accounts)) {
756
+ continue;
757
+ }
758
+ try {
759
+ const scope = scopeKey;
760
+ const scopeDetails = (0, import_utils.parseCaipChainId)(scope);
761
+ const chainKey = `${scopeDetails.namespace}:${scopeDetails.reference}`;
762
+ const matchingAccounts = accountsByChain.get(chainKey);
763
+ if (matchingAccounts) {
764
+ const existingAccounts = new Set(scopeData.accounts);
765
+ const newAccounts = matchingAccounts.filter(
766
+ (account) => !existingAccounts.has(account)
767
+ );
768
+ scopeData.accounts.push(...newAccounts);
769
+ }
770
+ } catch (error) {
771
+ console.error(`Invalid scope format: ${scopeKey}`, error);
772
+ }
773
+ }
774
+ return result;
775
+ }
776
+ var import_pako, import_utils, extractFavicon;
777
+ var init_utils = __esm({
778
+ "src/multichain/utils/index.ts"() {
779
+ "use strict";
780
+ import_pako = require("pako");
781
+ import_utils = require("@metamask/utils");
782
+ init_domain();
783
+ extractFavicon = () => {
784
+ var _a;
785
+ if (typeof document === "undefined") {
786
+ return void 0;
787
+ }
788
+ let favicon;
789
+ const nodeList = document.getElementsByTagName("link");
790
+ for (let i = 0; i < nodeList.length; i++) {
791
+ if (nodeList[i].getAttribute("rel") === "icon" || nodeList[i].getAttribute("rel") === "shortcut icon") {
792
+ favicon = (_a = nodeList[i].getAttribute("href")) != null ? _a : void 0;
793
+ }
794
+ }
795
+ return favicon;
796
+ };
797
+ }
798
+ });
799
+
800
+ // src/multichain/utils/analytics.ts
801
+ function isRejectionError(error) {
802
+ var _a, _b;
803
+ if (typeof error !== "object" || error === null) {
804
+ return false;
805
+ }
806
+ const errorObj = error;
807
+ const errorCode = errorObj.code;
808
+ const errorMessage = (_b = (_a = errorObj.message) == null ? void 0 : _a.toLowerCase()) != null ? _b : "";
809
+ return errorCode === 4001 || // User rejected request (common EIP-1193 code)
810
+ errorCode === 4100 || // Unauthorized (common rejection code)
811
+ errorMessage.includes("reject") || errorMessage.includes("denied") || errorMessage.includes("cancel") || errorMessage.includes("user");
812
+ }
813
+ function getBaseAnalyticsProperties(options, storage) {
814
+ return __async(this, null, function* () {
815
+ var _a, _b;
816
+ const version = getVersion();
817
+ const dappId = getDappId(options.dapp);
818
+ const platform = getPlatformType();
819
+ const anonId = yield storage.getAnonId();
820
+ const integrationType = (_b = (_a = options.analytics) == null ? void 0 : _a.integrationType) != null ? _b : "unknown" /* UNKNOWN */;
821
+ return {
822
+ mmconnect_version: version,
823
+ dapp_id: dappId,
824
+ platform,
825
+ integration_type: integrationType,
826
+ anon_id: anonId
827
+ };
828
+ });
829
+ }
830
+ function getWalletActionAnalyticsProperties(options, storage, invokeOptions) {
831
+ return __async(this, null, function* () {
832
+ var _a, _b;
833
+ const version = getVersion();
834
+ const dappId = getDappId(options.dapp);
835
+ const anonId = yield storage.getAnonId();
836
+ const integrationType = (_b = (_a = options.analytics) == null ? void 0 : _a.integrationType) != null ? _b : "unknown";
837
+ return {
838
+ mmconnect_version: version,
839
+ dapp_id: dappId,
840
+ method: invokeOptions.request.method,
841
+ integration_type: integrationType,
842
+ caip_chain_id: invokeOptions.scope,
843
+ anon_id: anonId
844
+ };
845
+ });
846
+ }
847
+ var init_analytics = __esm({
848
+ "src/multichain/utils/analytics.ts"() {
849
+ "use strict";
850
+ init_utils();
851
+ init_domain();
852
+ }
853
+ });
854
+
571
855
  // src/domain/utils/index.ts
572
856
  function getVersion() {
573
857
  return "0.0.0";
574
858
  }
575
- var init_utils = __esm({
859
+ var init_utils2 = __esm({
576
860
  "src/domain/utils/index.ts"() {
577
861
  "use strict";
862
+ init_analytics();
578
863
  }
579
864
  });
580
865
 
@@ -589,7 +874,7 @@ var init_domain = __esm({
589
874
  init_platform();
590
875
  init_store();
591
876
  init_ui();
592
- init_utils();
877
+ init_utils2();
593
878
  }
594
879
  });
595
880
 
@@ -612,7 +897,7 @@ function shouldLogCountdown(remainingSeconds) {
612
897
  return remainingSeconds % 60 === 0;
613
898
  }
614
899
  }
615
- var init_utils2 = __esm({
900
+ var init_utils3 = __esm({
616
901
  "src/ui/modals/base/utils.ts"() {
617
902
  "use strict";
618
903
  }
@@ -624,7 +909,7 @@ var init_AbstractInstallModal = __esm({
624
909
  "src/ui/modals/base/AbstractInstallModal.ts"() {
625
910
  "use strict";
626
911
  init_domain();
627
- init_utils2();
912
+ init_utils3();
628
913
  logger3 = createLogger("metamask-sdk:ui");
629
914
  AbstractInstallModal = class extends Modal {
630
915
  constructor() {
@@ -725,7 +1010,7 @@ var init_install = __esm({
725
1010
  const modal = document.createElement(
726
1011
  "mm-install-modal"
727
1012
  );
728
- modal.preferDesktop = options.preferDesktop;
1013
+ modal.showInstallModal = options.showInstallModal;
729
1014
  modal.sdkVersion = options.sdkVersion;
730
1015
  modal.addEventListener("close", (ev) => {
731
1016
  const { detail } = ev;
@@ -892,271 +1177,70 @@ var init_web2 = __esm({
892
1177
  const store = tx.objectStore(storeName);
893
1178
  const request = store.delete(key);
894
1179
  request.onerror = () => reject(new Error("Failed to delete value from IndexedDB."));
895
- request.onsuccess = () => resolve();
896
- } catch (error) {
897
- reject(error);
898
- }
899
- });
900
- });
901
- }
902
- };
903
- _StoreAdapterWeb.stores = ["sdk-kv-store", "key-value-pairs"];
904
- _StoreAdapterWeb.DB_NAME = "mmsdk";
905
- StoreAdapterWeb = _StoreAdapterWeb;
906
- }
907
- });
908
-
909
- // src/index.browser.ts
910
- var index_browser_exports = {};
911
- __export(index_browser_exports, {
912
- EventEmitter: () => EventEmitter,
913
- Modal: () => Modal,
914
- MultichainCore: () => MultichainCore,
915
- PlatformType: () => PlatformType,
916
- RPCHttpErr: () => RPCHttpErr,
917
- RPCInvokeMethodErr: () => RPCInvokeMethodErr,
918
- RPCReadonlyRequestErr: () => RPCReadonlyRequestErr,
919
- RPCReadonlyResponseErr: () => RPCReadonlyResponseErr,
920
- RPC_HANDLED_METHODS: () => RPC_HANDLED_METHODS,
921
- SDK_HANDLED_METHODS: () => SDK_HANDLED_METHODS,
922
- StoreAdapter: () => StoreAdapter,
923
- StoreClient: () => StoreClient,
924
- TransportType: () => TransportType,
925
- createLogger: () => createLogger,
926
- createMetamaskConnect: () => createMetamaskConnect,
927
- enableDebug: () => enableDebug,
928
- getInfuraRpcUrls: () => getInfuraRpcUrls,
929
- getPlatformType: () => getPlatformType,
930
- getTransportType: () => getTransportType,
931
- getVersion: () => getVersion,
932
- hasExtension: () => hasExtension,
933
- infuraRpcUrls: () => infuraRpcUrls,
934
- isEnabled: () => isEnabled,
935
- isMetamaskExtensionInstalled: () => isMetamaskExtensionInstalled,
936
- isSecure: () => isSecure
937
- });
938
- module.exports = __toCommonJS(index_browser_exports);
939
-
940
- // src/multichain/index.ts
941
- var import_analytics = require("@metamask/analytics");
942
- var import_mobile_wallet_protocol_core2 = require("@metamask/mobile-wallet-protocol-core");
943
- var import_mobile_wallet_protocol_dapp_client = require("@metamask/mobile-wallet-protocol-dapp-client");
944
- var import_multichain_api_client3 = require("@metamask/multichain-api-client");
945
-
946
- // src/config/index.ts
947
- var MWP_RELAY_URL = "wss://mm-sdk-relay.api.cx.metamask.io/connection/websocket";
948
- var METAMASK_CONNECT_BASE_URL = "https://metamask.app.link/connect";
949
- var METAMASK_DEEPLINK_BASE = "metamask://connect";
950
-
951
- // src/multichain/index.ts
952
- init_domain();
953
- init_logger();
954
- init_multichain();
955
- init_platform();
956
-
957
- // src/multichain/rpc/requestRouter.ts
958
- init_domain();
959
-
960
- // src/multichain/utils/index.ts
961
- var import_pako = require("pako");
962
- var import_utils = require("@metamask/utils");
963
- init_domain();
964
- function base64Encode(str) {
965
- if (typeof btoa !== "undefined") {
966
- return btoa(str);
967
- } else if (typeof Buffer !== "undefined") {
968
- return Buffer.from(str).toString("base64");
969
- }
970
- throw new Error("No base64 encoding method available");
971
- }
972
- function compressString(str) {
973
- const compressed = (0, import_pako.deflate)(str);
974
- const binaryString = String.fromCharCode.apply(null, Array.from(compressed));
975
- return base64Encode(binaryString);
976
- }
977
- function getDappId(dapp) {
978
- var _a, _b;
979
- if (typeof window === "undefined" || typeof window.location === "undefined") {
980
- return (_b = (_a = dapp == null ? void 0 : dapp.name) != null ? _a : dapp == null ? void 0 : dapp.url) != null ? _b : "N/A";
981
- }
982
- return window.location.hostname;
983
- }
984
- function openDeeplink(options, deeplink, universalLink) {
985
- const { mobile } = options;
986
- const useDeeplink = mobile && mobile.useDeeplink !== void 0 ? mobile.useDeeplink : true;
987
- if (useDeeplink) {
988
- if (typeof window !== "undefined") {
989
- window.location.href = deeplink;
990
- }
991
- } else if (typeof document !== "undefined") {
992
- const link = document.createElement("a");
993
- link.href = universalLink;
994
- link.target = "_self";
995
- link.rel = "noreferrer noopener";
996
- link.click();
997
- }
998
- }
999
- function getOptionalScopes(scopes) {
1000
- return scopes.reduce(
1001
- (prev, scope) => __spreadProps(__spreadValues({}, prev), {
1002
- [scope]: {
1003
- methods: [],
1004
- notifications: [],
1005
- accounts: []
1006
- }
1007
- }),
1008
- {}
1009
- );
1010
- }
1011
- var extractFavicon = () => {
1012
- var _a;
1013
- if (typeof document === "undefined") {
1014
- return void 0;
1015
- }
1016
- let favicon;
1017
- const nodeList = document.getElementsByTagName("link");
1018
- for (let i = 0; i < nodeList.length; i++) {
1019
- if (nodeList[i].getAttribute("rel") === "icon" || nodeList[i].getAttribute("rel") === "shortcut icon") {
1020
- favicon = (_a = nodeList[i].getAttribute("href")) != null ? _a : void 0;
1021
- }
1022
- }
1023
- return favicon;
1024
- };
1025
- function setupInfuraProvider(options) {
1026
- var _a, _b;
1027
- const infuraAPIKey = (_a = options.api) == null ? void 0 : _a.infuraAPIKey;
1028
- if (!infuraAPIKey) {
1029
- return options;
1030
- }
1031
- const urlsWithToken = getInfuraRpcUrls(infuraAPIKey);
1032
- if ((_b = options.api) == null ? void 0 : _b.readonlyRPCMap) {
1033
- options.api.readonlyRPCMap = __spreadValues(__spreadValues({}, options.api.readonlyRPCMap), urlsWithToken);
1034
- } else if (options.api) {
1035
- options.api.readonlyRPCMap = urlsWithToken;
1036
- }
1037
- return options;
1038
- }
1039
- function setupDappMetadata(options) {
1040
- var _a;
1041
- const platform = getPlatformType();
1042
- const isBrowser = platform === "web-desktop" /* DesktopWeb */ || platform === "web-mobile" /* MobileWeb */ || platform === "in-app-browser" /* MetaMaskMobileWebview */;
1043
- if (!((_a = options.dapp) == null ? void 0 : _a.url)) {
1044
- if (isBrowser) {
1045
- options.dapp = __spreadProps(__spreadValues({}, options.dapp), {
1046
- url: `${window.location.protocol}//${window.location.host}`
1047
- });
1048
- } else {
1049
- throw new Error("You must provide dapp url");
1050
- }
1051
- }
1052
- const BASE_64_ICON_MAX_LENGTH = 163400;
1053
- const urlPattern = /^(http|https):\/\/[^\s]*$/;
1054
- if (options.dapp) {
1055
- if ("iconUrl" in options.dapp) {
1056
- if (options.dapp.iconUrl && !urlPattern.test(options.dapp.iconUrl)) {
1057
- console.warn(
1058
- "Invalid dappMetadata.iconUrl: URL must start with http:// or https://"
1059
- );
1060
- options.dapp.iconUrl = void 0;
1061
- }
1062
- }
1063
- if ("base64Icon" in options.dapp) {
1064
- if (options.dapp.base64Icon && options.dapp.base64Icon.length > BASE_64_ICON_MAX_LENGTH) {
1065
- console.warn(
1066
- "Invalid dappMetadata.base64Icon: Base64-encoded icon string length must be less than 163400 characters"
1067
- );
1068
- options.dapp.base64Icon = void 0;
1069
- }
1070
- }
1071
- if (options.dapp.url && !urlPattern.test(options.dapp.url)) {
1072
- console.warn(
1073
- "Invalid dappMetadata.url: URL must start with http:// or https://"
1074
- );
1075
- }
1076
- const favicon = extractFavicon();
1077
- if (favicon && !("iconUrl" in options.dapp) && !("base64Icon" in options.dapp)) {
1078
- const faviconUrl = `${window.location.protocol}//${window.location.host}${favicon}`;
1079
- options.dapp.iconUrl = faviconUrl;
1080
- }
1081
- }
1082
- return options;
1083
- }
1084
- function isSameScopesAndAccounts(currentScopes, proposedScopes, walletSession, proposedCaipAccountIds) {
1085
- const isSameScopes = currentScopes.every((scope) => proposedScopes.includes(scope)) && proposedScopes.every((scope) => currentScopes.includes(scope));
1086
- if (!isSameScopes) {
1087
- return false;
1088
- }
1089
- const existingAccountIds = Object.values(
1090
- walletSession.sessionScopes
1091
- ).filter(({ accounts }) => Boolean(accounts)).flatMap(({ accounts }) => accounts != null ? accounts : []);
1092
- const allProposedAccountsIncluded = proposedCaipAccountIds.every(
1093
- (proposedAccountId) => existingAccountIds.includes(proposedAccountId)
1094
- );
1095
- return allProposedAccountsIncluded;
1096
- }
1097
- function getValidAccounts(caipAccountIds) {
1098
- return caipAccountIds.reduce(
1099
- (caipAccounts, caipAccountId) => {
1100
- try {
1101
- return [...caipAccounts, (0, import_utils.parseCaipAccountId)(caipAccountId)];
1102
- } catch (err) {
1103
- const stringifiedAccountId = JSON.stringify(caipAccountId);
1104
- console.error(`Invalid CAIP account ID: ${stringifiedAccountId}`, err);
1105
- return caipAccounts;
1106
- }
1107
- },
1108
- []
1109
- );
1110
- }
1111
- function addValidAccounts(optionalScopes, validAccounts) {
1112
- var _a;
1113
- if (!optionalScopes || !(validAccounts == null ? void 0 : validAccounts.length)) {
1114
- return optionalScopes;
1115
- }
1116
- const result = Object.fromEntries(
1117
- Object.entries(optionalScopes).map(([scope, scopeData]) => {
1118
- var _a2, _b, _c;
1119
- return [
1120
- scope,
1121
- {
1122
- methods: [...(_a2 = scopeData == null ? void 0 : scopeData.methods) != null ? _a2 : []],
1123
- notifications: [...(_b = scopeData == null ? void 0 : scopeData.notifications) != null ? _b : []],
1124
- accounts: [...(_c = scopeData == null ? void 0 : scopeData.accounts) != null ? _c : []]
1125
- }
1126
- ];
1127
- })
1128
- );
1129
- const accountsByChain = /* @__PURE__ */ new Map();
1130
- for (const account of validAccounts) {
1131
- const chainKey = `${account.chain.namespace}:${account.chain.reference}`;
1132
- const accountId = `${account.chainId}:${account.address}`;
1133
- if (!accountsByChain.has(chainKey)) {
1134
- accountsByChain.set(chainKey, []);
1135
- }
1136
- (_a = accountsByChain.get(chainKey)) == null ? void 0 : _a.push(accountId);
1137
- }
1138
- for (const [scopeKey, scopeData] of Object.entries(result)) {
1139
- if (!(scopeData == null ? void 0 : scopeData.accounts)) {
1140
- continue;
1141
- }
1142
- try {
1143
- const scope = scopeKey;
1144
- const scopeDetails = (0, import_utils.parseCaipChainId)(scope);
1145
- const chainKey = `${scopeDetails.namespace}:${scopeDetails.reference}`;
1146
- const matchingAccounts = accountsByChain.get(chainKey);
1147
- if (matchingAccounts) {
1148
- const existingAccounts = new Set(scopeData.accounts);
1149
- const newAccounts = matchingAccounts.filter(
1150
- (account) => !existingAccounts.has(account)
1151
- );
1152
- scopeData.accounts.push(...newAccounts);
1180
+ request.onsuccess = () => resolve();
1181
+ } catch (error) {
1182
+ reject(error);
1183
+ }
1184
+ });
1185
+ });
1153
1186
  }
1154
- } catch (error) {
1155
- console.error(`Invalid scope format: ${scopeKey}`, error);
1156
- }
1187
+ };
1188
+ _StoreAdapterWeb.stores = ["sdk-kv-store", "key-value-pairs"];
1189
+ _StoreAdapterWeb.DB_NAME = "mmsdk";
1190
+ StoreAdapterWeb = _StoreAdapterWeb;
1157
1191
  }
1158
- return result;
1159
- }
1192
+ });
1193
+
1194
+ // src/index.browser.ts
1195
+ var index_browser_exports = {};
1196
+ __export(index_browser_exports, {
1197
+ EventEmitter: () => EventEmitter,
1198
+ Modal: () => Modal,
1199
+ MultichainCore: () => MultichainCore,
1200
+ PlatformType: () => PlatformType,
1201
+ RPCHttpErr: () => RPCHttpErr,
1202
+ RPCInvokeMethodErr: () => RPCInvokeMethodErr,
1203
+ RPCReadonlyRequestErr: () => RPCReadonlyRequestErr,
1204
+ RPCReadonlyResponseErr: () => RPCReadonlyResponseErr,
1205
+ RPC_HANDLED_METHODS: () => RPC_HANDLED_METHODS,
1206
+ SDK_HANDLED_METHODS: () => SDK_HANDLED_METHODS,
1207
+ StoreAdapter: () => StoreAdapter,
1208
+ StoreClient: () => StoreClient,
1209
+ TransportType: () => TransportType,
1210
+ createLogger: () => createLogger,
1211
+ createMetamaskConnect: () => createMetamaskConnect,
1212
+ enableDebug: () => enableDebug,
1213
+ getInfuraRpcUrls: () => getInfuraRpcUrls,
1214
+ getPlatformType: () => getPlatformType,
1215
+ getTransportType: () => getTransportType,
1216
+ getVersion: () => getVersion,
1217
+ getWalletActionAnalyticsProperties: () => getWalletActionAnalyticsProperties,
1218
+ hasExtension: () => hasExtension,
1219
+ infuraRpcUrls: () => infuraRpcUrls,
1220
+ isEnabled: () => isEnabled,
1221
+ isMetamaskExtensionInstalled: () => isMetamaskExtensionInstalled,
1222
+ isRejectionError: () => isRejectionError,
1223
+ isSecure: () => isSecure
1224
+ });
1225
+ module.exports = __toCommonJS(index_browser_exports);
1226
+
1227
+ // src/multichain/index.ts
1228
+ var import_analytics4 = require("@metamask/analytics");
1229
+ var import_mobile_wallet_protocol_core2 = require("@metamask/mobile-wallet-protocol-core");
1230
+ var import_mobile_wallet_protocol_dapp_client = require("@metamask/mobile-wallet-protocol-dapp-client");
1231
+ var import_multichain_api_client3 = require("@metamask/multichain-api-client");
1232
+
1233
+ // src/config/index.ts
1234
+ var MWP_RELAY_URL = "wss://mm-sdk-relay.api.cx.metamask.io/connection/websocket";
1235
+ var METAMASK_CONNECT_BASE_URL = "https://metamask.app.link/connect";
1236
+ var METAMASK_DEEPLINK_BASE = "metamask://connect";
1237
+
1238
+ // src/multichain/index.ts
1239
+ init_domain();
1240
+ init_analytics();
1241
+ init_logger();
1242
+ init_multichain();
1243
+ init_platform();
1160
1244
 
1161
1245
  // src/multichain/rpc/handlers/rpcClient.ts
1162
1246
  var import_cross_fetch = __toESM(require("cross-fetch"));
@@ -1175,6 +1259,7 @@ var RpcClient = class {
1175
1259
  }
1176
1260
  /**
1177
1261
  * Routes the request to a configured RPC node.
1262
+ * @param options - The invoke method options
1178
1263
  */
1179
1264
  request(options) {
1180
1265
  return __async(this, null, function* () {
@@ -1186,46 +1271,45 @@ var RpcClient = class {
1186
1271
  id: getNextRpcId()
1187
1272
  });
1188
1273
  const rpcEndpoint = this.getRpcEndpoint(options.scope);
1189
- const rpcRequest = yield this.fetch(rpcEndpoint, body, "POST", this.getHeaders(rpcEndpoint));
1274
+ const rpcRequest = yield this.fetchWithTimeout(rpcEndpoint, body, "POST", this.getHeaders(rpcEndpoint), 3e4);
1190
1275
  const response = yield this.parseResponse(rpcRequest);
1191
1276
  return response;
1192
1277
  });
1193
1278
  }
1194
1279
  getRpcEndpoint(scope) {
1195
- var _a, _b, _c, _d, _e;
1196
- let infuraAPIKey = (_b = (_a = this.config) == null ? void 0 : _a.api) == null ? void 0 : _b.infuraAPIKey;
1197
- let readonlyRPCMap = (_e = (_d = (_c = this.config) == null ? void 0 : _c.api) == null ? void 0 : _d.readonlyRPCMap) != null ? _e : {};
1198
- if (infuraAPIKey) {
1199
- const urlsWithToken = getInfuraRpcUrls(infuraAPIKey);
1200
- if (readonlyRPCMap) {
1201
- readonlyRPCMap = __spreadValues(__spreadValues({}, urlsWithToken), readonlyRPCMap);
1202
- } else {
1203
- readonlyRPCMap = urlsWithToken;
1204
- }
1205
- }
1206
- const rpcEndpoint = readonlyRPCMap[scope];
1280
+ var _a, _b, _c;
1281
+ const supportedNetworks = (_c = (_b = (_a = this.config) == null ? void 0 : _a.api) == null ? void 0 : _b.supportedNetworks) != null ? _c : {};
1282
+ const rpcEndpoint = supportedNetworks[scope];
1207
1283
  if (!rpcEndpoint) {
1208
1284
  throw new MissingRpcEndpointErr(`No RPC endpoint found for scope ${scope}`);
1209
1285
  }
1210
1286
  return rpcEndpoint;
1211
1287
  }
1212
- fetch(endpoint, body, method, headers) {
1288
+ fetchWithTimeout(endpoint, body, method, headers, timeout) {
1213
1289
  return __async(this, null, function* () {
1290
+ const controller = new AbortController();
1291
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
1214
1292
  try {
1215
1293
  const response = yield (0, import_cross_fetch.default)(endpoint, {
1216
1294
  method,
1217
1295
  headers,
1218
- body
1296
+ body,
1297
+ signal: controller.signal
1219
1298
  });
1299
+ clearTimeout(timeoutId);
1220
1300
  if (!response.ok) {
1221
1301
  throw new RPCHttpErr(endpoint, method, response.status);
1222
1302
  }
1223
1303
  return response;
1224
1304
  } catch (error) {
1305
+ clearTimeout(timeoutId);
1225
1306
  if (error instanceof RPCHttpErr) {
1226
1307
  throw error;
1227
1308
  }
1228
- throw new RPCReadonlyRequestErr(error.message);
1309
+ if (error instanceof Error && error.name === "AbortError") {
1310
+ throw new RPCReadonlyRequestErr(`Request timeout after ${timeout}ms`);
1311
+ }
1312
+ throw new RPCReadonlyRequestErr(error instanceof Error ? error.message : "Unknown error");
1229
1313
  }
1230
1314
  });
1231
1315
  }
@@ -1254,11 +1338,17 @@ var RpcClient = class {
1254
1338
  };
1255
1339
 
1256
1340
  // src/multichain/rpc/requestRouter.ts
1341
+ var import_analytics2 = require("@metamask/analytics");
1342
+ init_domain();
1343
+ init_utils();
1344
+ init_analytics();
1345
+ var _RequestRouter_instances, withAnalyticsTracking_fn, trackWalletActionRequested_fn, trackWalletActionSucceeded_fn, trackWalletActionFailed_fn, trackWalletActionRejected_fn;
1257
1346
  var RequestRouter = class {
1258
1347
  constructor(transport, rpcClient, config) {
1259
1348
  this.transport = transport;
1260
1349
  this.rpcClient = rpcClient;
1261
1350
  this.config = config;
1351
+ __privateAdd(this, _RequestRouter_instances);
1262
1352
  }
1263
1353
  /**
1264
1354
  * The main entry point for invoking an RPC method.
@@ -1282,15 +1372,15 @@ var RequestRouter = class {
1282
1372
  */
1283
1373
  handleWithWallet(options) {
1284
1374
  return __async(this, null, function* () {
1285
- try {
1375
+ return __privateMethod(this, _RequestRouter_instances, withAnalyticsTracking_fn).call(this, options, () => __async(this, null, function* () {
1286
1376
  const request = this.transport.request({
1287
1377
  method: "wallet_invokeMethod",
1288
1378
  params: options
1289
1379
  });
1290
1380
  const { ui, mobile } = this.config;
1291
- const { preferDesktop = false } = ui != null ? ui : {};
1381
+ const { showInstallModal = false } = ui != null ? ui : {};
1292
1382
  const secure = isSecure();
1293
- const shouldOpenDeeplink = secure && !preferDesktop;
1383
+ const shouldOpenDeeplink = secure && !showInstallModal;
1294
1384
  if (shouldOpenDeeplink) {
1295
1385
  setTimeout(() => {
1296
1386
  if (mobile == null ? void 0 : mobile.preferredOpenLink) {
@@ -1305,9 +1395,7 @@ var RequestRouter = class {
1305
1395
  throw new RPCInvokeMethodErr(`RPC Request failed with code ${response.error.code}: ${response.error.message}`);
1306
1396
  }
1307
1397
  return response.result;
1308
- } catch (error) {
1309
- throw new RPCInvokeMethodErr(error.message);
1310
- }
1398
+ }));
1311
1399
  });
1312
1400
  }
1313
1401
  /**
@@ -1315,14 +1403,16 @@ var RequestRouter = class {
1315
1403
  */
1316
1404
  handleWithRpcNode(options) {
1317
1405
  return __async(this, null, function* () {
1318
- try {
1319
- return yield this.rpcClient.request(options);
1320
- } catch (error) {
1321
- if (error instanceof MissingRpcEndpointErr) {
1322
- return this.handleWithWallet(options);
1406
+ return __privateMethod(this, _RequestRouter_instances, withAnalyticsTracking_fn).call(this, options, () => __async(this, null, function* () {
1407
+ try {
1408
+ return yield this.rpcClient.request(options);
1409
+ } catch (error) {
1410
+ if (error instanceof MissingRpcEndpointErr) {
1411
+ return this.handleWithWallet(options);
1412
+ }
1413
+ throw error;
1323
1414
  }
1324
- throw error;
1325
- }
1415
+ }));
1326
1416
  });
1327
1417
  }
1328
1418
  /**
@@ -1335,11 +1425,62 @@ var RequestRouter = class {
1335
1425
  });
1336
1426
  }
1337
1427
  };
1428
+ _RequestRouter_instances = new WeakSet();
1429
+ withAnalyticsTracking_fn = function(options, execute) {
1430
+ return __async(this, null, function* () {
1431
+ var _a, _b, _c;
1432
+ if ((_a = this.config.analytics) == null ? void 0 : _a.enabled) {
1433
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRequested_fn).call(this, options);
1434
+ }
1435
+ try {
1436
+ const result = yield execute();
1437
+ if ((_b = this.config.analytics) == null ? void 0 : _b.enabled) {
1438
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionSucceeded_fn).call(this, options);
1439
+ }
1440
+ return result;
1441
+ } catch (error) {
1442
+ if ((_c = this.config.analytics) == null ? void 0 : _c.enabled) {
1443
+ const isRejection = isRejectionError(error);
1444
+ if (isRejection) {
1445
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRejected_fn).call(this, options);
1446
+ } else {
1447
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options);
1448
+ }
1449
+ }
1450
+ throw new RPCInvokeMethodErr(error.message);
1451
+ }
1452
+ });
1453
+ };
1454
+ trackWalletActionRequested_fn = function(options) {
1455
+ return __async(this, null, function* () {
1456
+ const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1457
+ import_analytics2.analytics.track("mmconnect_wallet_action_requested", props);
1458
+ });
1459
+ };
1460
+ trackWalletActionSucceeded_fn = function(options) {
1461
+ return __async(this, null, function* () {
1462
+ const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1463
+ import_analytics2.analytics.track("mmconnect_wallet_action_succeeded", props);
1464
+ });
1465
+ };
1466
+ trackWalletActionFailed_fn = function(options) {
1467
+ return __async(this, null, function* () {
1468
+ const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1469
+ import_analytics2.analytics.track("mmconnect_wallet_action_failed", props);
1470
+ });
1471
+ };
1472
+ trackWalletActionRejected_fn = function(options) {
1473
+ return __async(this, null, function* () {
1474
+ const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1475
+ import_analytics2.analytics.track("mmconnect_wallet_action_rejected", props);
1476
+ });
1477
+ };
1338
1478
 
1339
1479
  // src/multichain/transports/default/index.ts
1340
1480
  var import_multichain_api_client = require("@metamask/multichain-api-client");
1481
+ init_utils();
1341
1482
  var DEFAULT_REQUEST_TIMEOUT = 60 * 1e3;
1342
- var _notificationCallbacks, _transport, _defaultRequestOptions, _DefaultTransport_instances, notifyCallbacks_fn;
1483
+ var _notificationCallbacks, _transport, _defaultRequestOptions, _reqId, _pendingRequests, _handleResponseListener, _handleNotificationListener, _DefaultTransport_instances, notifyCallbacks_fn, isMetamaskProviderEvent_fn, handleResponse_fn, handleNotification_fn, setupMessageListener_fn;
1343
1484
  var DefaultTransport = class {
1344
1485
  constructor() {
1345
1486
  __privateAdd(this, _DefaultTransport_instances);
@@ -1348,10 +1489,52 @@ var DefaultTransport = class {
1348
1489
  __privateAdd(this, _defaultRequestOptions, {
1349
1490
  timeout: DEFAULT_REQUEST_TIMEOUT
1350
1491
  });
1492
+ // Use timestamp-based ID to avoid conflicts across disconnect/reconnect cycles
1493
+ __privateAdd(this, _reqId, Date.now());
1494
+ __privateAdd(this, _pendingRequests, /* @__PURE__ */ new Map());
1495
+ __privateAdd(this, _handleResponseListener);
1496
+ __privateAdd(this, _handleNotificationListener);
1497
+ }
1498
+ sendEip1193Message(payload, options) {
1499
+ return __async(this, null, function* () {
1500
+ __privateMethod(this, _DefaultTransport_instances, setupMessageListener_fn).call(this);
1501
+ __privateSet(this, _reqId, __privateGet(this, _reqId) + 1);
1502
+ const requestId = `${__privateGet(this, _reqId)}`;
1503
+ const request = __spreadValues({
1504
+ jsonrpc: "2.0",
1505
+ id: requestId
1506
+ }, payload);
1507
+ return new Promise((resolve, reject) => {
1508
+ var _a;
1509
+ const timeout = setTimeout(() => {
1510
+ __privateGet(this, _pendingRequests).delete(requestId);
1511
+ reject(new Error("Request timeout"));
1512
+ }, (_a = options == null ? void 0 : options.timeout) != null ? _a : __privateGet(this, _defaultRequestOptions).timeout);
1513
+ __privateGet(this, _pendingRequests).set(requestId, {
1514
+ resolve: (response) => {
1515
+ resolve(response);
1516
+ },
1517
+ reject,
1518
+ timeout
1519
+ });
1520
+ window.postMessage(
1521
+ {
1522
+ target: "metamask-contentscript",
1523
+ data: {
1524
+ name: "metamask-provider",
1525
+ data: request
1526
+ }
1527
+ },
1528
+ // eslint-disable-next-line no-restricted-globals
1529
+ location.origin
1530
+ );
1531
+ });
1532
+ });
1351
1533
  }
1352
1534
  connect(options) {
1353
1535
  return __async(this, null, function* () {
1354
1536
  var _a, _b, _c, _d, _e, _f, _g;
1537
+ __privateMethod(this, _DefaultTransport_instances, setupMessageListener_fn).call(this);
1355
1538
  yield __privateGet(this, _transport).connect();
1356
1539
  const sessionRequest = yield this.request(
1357
1540
  { method: "wallet_getSession" },
@@ -1361,7 +1544,7 @@ var DefaultTransport = class {
1361
1544
  throw new Error(sessionRequest.error.message);
1362
1545
  }
1363
1546
  let walletSession = sessionRequest.result;
1364
- if (walletSession && options) {
1547
+ if (walletSession && options && !options.forceRequest) {
1365
1548
  const currentScopes = Object.keys(
1366
1549
  (_a = walletSession == null ? void 0 : walletSession.sessionScopes) != null ? _a : {}
1367
1550
  );
@@ -1382,9 +1565,11 @@ var DefaultTransport = class {
1382
1565
  getOptionalScopes((_d = options == null ? void 0 : options.scopes) != null ? _d : []),
1383
1566
  getValidAccounts((_e = options == null ? void 0 : options.caipAccountIds) != null ? _e : [])
1384
1567
  );
1385
- const sessionRequest2 = { optionalScopes };
1568
+ const createSessionParams = {
1569
+ optionalScopes
1570
+ };
1386
1571
  const response = yield this.request(
1387
- { method: "wallet_createSession", params: sessionRequest2 },
1572
+ { method: "wallet_createSession", params: createSessionParams },
1388
1573
  __privateGet(this, _defaultRequestOptions)
1389
1574
  );
1390
1575
  if (response.error) {
@@ -1392,14 +1577,16 @@ var DefaultTransport = class {
1392
1577
  }
1393
1578
  walletSession = response.result;
1394
1579
  }
1395
- } else if (!walletSession) {
1580
+ } else if (!walletSession || (options == null ? void 0 : options.forceRequest)) {
1396
1581
  const optionalScopes = addValidAccounts(
1397
1582
  getOptionalScopes((_f = options == null ? void 0 : options.scopes) != null ? _f : []),
1398
1583
  getValidAccounts((_g = options == null ? void 0 : options.caipAccountIds) != null ? _g : [])
1399
1584
  );
1400
- const sessionRequest2 = { optionalScopes };
1585
+ const createSessionParams = {
1586
+ optionalScopes
1587
+ };
1401
1588
  const response = yield this.request(
1402
- { method: "wallet_createSession", params: sessionRequest2 },
1589
+ { method: "wallet_createSession", params: createSessionParams },
1403
1590
  __privateGet(this, _defaultRequestOptions)
1404
1591
  );
1405
1592
  if (response.error) {
@@ -1416,6 +1603,16 @@ var DefaultTransport = class {
1416
1603
  disconnect() {
1417
1604
  return __async(this, null, function* () {
1418
1605
  __privateGet(this, _notificationCallbacks).clear();
1606
+ yield this.request({ method: "wallet_revokeSession", params: {} });
1607
+ if (__privateGet(this, _handleResponseListener)) {
1608
+ window.removeEventListener("message", __privateGet(this, _handleResponseListener));
1609
+ __privateSet(this, _handleResponseListener, void 0);
1610
+ }
1611
+ for (const [, request] of __privateGet(this, _pendingRequests)) {
1612
+ clearTimeout(request.timeout);
1613
+ request.reject(new Error("Transport disconnected"));
1614
+ }
1615
+ __privateGet(this, _pendingRequests).clear();
1419
1616
  return __privateGet(this, _transport).disconnect();
1420
1617
  });
1421
1618
  }
@@ -1438,31 +1635,99 @@ var DefaultTransport = class {
1438
1635
  _notificationCallbacks = new WeakMap();
1439
1636
  _transport = new WeakMap();
1440
1637
  _defaultRequestOptions = new WeakMap();
1638
+ _reqId = new WeakMap();
1639
+ _pendingRequests = new WeakMap();
1640
+ _handleResponseListener = new WeakMap();
1641
+ _handleNotificationListener = new WeakMap();
1441
1642
  _DefaultTransport_instances = new WeakSet();
1442
1643
  notifyCallbacks_fn = function(data) {
1443
- for (const cb of __privateGet(this, _notificationCallbacks)) {
1644
+ for (const callback of __privateGet(this, _notificationCallbacks)) {
1444
1645
  try {
1445
- cb(data);
1446
- } catch (err) {
1447
- console.log("[WindowPostMessageTransport] notifyCallbacks error:", err);
1646
+ callback(data);
1647
+ } catch (error) {
1648
+ console.log(
1649
+ "[WindowPostMessageTransport] notifyCallbacks error:",
1650
+ error
1651
+ );
1652
+ }
1653
+ }
1654
+ };
1655
+ isMetamaskProviderEvent_fn = function(event) {
1656
+ var _a, _b;
1657
+ return ((_b = (_a = event == null ? void 0 : event.data) == null ? void 0 : _a.data) == null ? void 0 : _b.name) === "metamask-provider" && // eslint-disable-next-line no-restricted-globals
1658
+ event.origin === location.origin;
1659
+ };
1660
+ handleResponse_fn = function(event) {
1661
+ var _a, _b;
1662
+ if (!__privateMethod(this, _DefaultTransport_instances, isMetamaskProviderEvent_fn).call(this, event)) {
1663
+ return;
1664
+ }
1665
+ const responseData = (_b = (_a = event == null ? void 0 : event.data) == null ? void 0 : _a.data) == null ? void 0 : _b.data;
1666
+ if (typeof responseData === "object" && responseData !== null && "method" in responseData) {
1667
+ return;
1668
+ }
1669
+ if (typeof responseData === "object" && responseData !== null && "id" in responseData && ("result" in responseData || "error" in responseData)) {
1670
+ const responseId = String(responseData.id);
1671
+ const pendingRequest = __privateGet(this, _pendingRequests).get(responseId);
1672
+ if (pendingRequest) {
1673
+ clearTimeout(pendingRequest.timeout);
1674
+ __privateGet(this, _pendingRequests).delete(responseId);
1675
+ const response = responseData;
1676
+ if ("error" in response && response.error) {
1677
+ pendingRequest.reject(
1678
+ new Error(response.error.message || "Request failed")
1679
+ );
1680
+ } else {
1681
+ pendingRequest.resolve(response);
1682
+ }
1448
1683
  }
1449
1684
  }
1450
1685
  };
1686
+ handleNotification_fn = function(event) {
1687
+ var _a, _b;
1688
+ if (!__privateMethod(this, _DefaultTransport_instances, isMetamaskProviderEvent_fn).call(this, event)) {
1689
+ return;
1690
+ }
1691
+ const responseData = (_b = (_a = event == null ? void 0 : event.data) == null ? void 0 : _a.data) == null ? void 0 : _b.data;
1692
+ if (typeof responseData === "object" && responseData.method === "metamask_chainChanged" || responseData.method === "metamask_accountsChanged") {
1693
+ __privateMethod(this, _DefaultTransport_instances, notifyCallbacks_fn).call(this, responseData);
1694
+ }
1695
+ };
1696
+ setupMessageListener_fn = function() {
1697
+ if (__privateGet(this, _handleResponseListener)) {
1698
+ return;
1699
+ }
1700
+ __privateSet(this, _handleResponseListener, __privateMethod(this, _DefaultTransport_instances, handleResponse_fn).bind(this));
1701
+ __privateSet(this, _handleNotificationListener, __privateMethod(this, _DefaultTransport_instances, handleNotification_fn).bind(this));
1702
+ window.addEventListener("message", __privateGet(this, _handleResponseListener));
1703
+ window.addEventListener("message", __privateGet(this, _handleNotificationListener));
1704
+ };
1451
1705
 
1452
1706
  // src/multichain/transports/mwp/index.ts
1453
1707
  var import_mobile_wallet_protocol_core = require("@metamask/mobile-wallet-protocol-core");
1454
1708
  var import_multichain_api_client2 = require("@metamask/multichain-api-client");
1455
1709
  init_domain();
1710
+ init_utils();
1711
+
1712
+ // src/multichain/transports/constants.ts
1713
+ var MULTICHAIN_PROVIDER_STREAM_NAME = "metamask-multichain-provider";
1714
+
1715
+ // src/multichain/transports/mwp/index.ts
1456
1716
  var DEFAULT_REQUEST_TIMEOUT2 = 60 * 1e3;
1457
1717
  var CONNECTION_GRACE_PERIOD = 60 * 1e3;
1458
1718
  var DEFAULT_CONNECTION_TIMEOUT = DEFAULT_REQUEST_TIMEOUT2 + CONNECTION_GRACE_PERIOD;
1459
1719
  var SESSION_STORE_KEY = "cache_wallet_getSession";
1720
+ var ACCOUNTS_STORE_KEY = "cache_eth_accounts";
1721
+ var CHAIN_STORE_KEY = "cache_eth_chainId";
1460
1722
  var CACHED_METHOD_LIST = [
1461
1723
  "wallet_getSession",
1462
1724
  "wallet_createSession",
1463
1725
  "wallet_sessionChanged"
1464
1726
  ];
1465
- var CACHED_RESET_METHOD_LIST = ["wallet_revokeSession"];
1727
+ var CACHED_RESET_METHOD_LIST = [
1728
+ "wallet_revokeSession",
1729
+ "wallet_revokePermissions"
1730
+ ];
1466
1731
  var logger = createLogger("metamask-sdk:transport");
1467
1732
  var MWPTransport = class {
1468
1733
  constructor(dappClient, kvstore, options = {
@@ -1526,6 +1791,22 @@ var MWPTransport = class {
1526
1791
  this.pendingRequests.delete(messagePayload.id);
1527
1792
  }
1528
1793
  } else {
1794
+ if (message.data.method === "metamask_chainChanged") {
1795
+ this.kvstore.set(
1796
+ CHAIN_STORE_KEY,
1797
+ JSON.stringify(
1798
+ message.data.params.chainId
1799
+ )
1800
+ );
1801
+ }
1802
+ if (message.data.method === "metamask_accountsChanged") {
1803
+ this.kvstore.set(
1804
+ ACCOUNTS_STORE_KEY,
1805
+ JSON.stringify(
1806
+ message.data.params
1807
+ )
1808
+ );
1809
+ }
1529
1810
  this.notifyCallbacks(message.data);
1530
1811
  }
1531
1812
  }
@@ -1596,6 +1877,40 @@ var MWPTransport = class {
1596
1877
  }
1597
1878
  });
1598
1879
  }
1880
+ // TODO: Rename this
1881
+ sendEip1193Message(payload, options) {
1882
+ return __async(this, null, function* () {
1883
+ const request = __spreadValues({
1884
+ jsonrpc: "2.0",
1885
+ id: `${this.__reqId++}`
1886
+ }, payload);
1887
+ const cachedWalletSession = yield this.getCachedResponse(request);
1888
+ if (cachedWalletSession) {
1889
+ this.notifyCallbacks(cachedWalletSession);
1890
+ return cachedWalletSession;
1891
+ }
1892
+ return new Promise((resolve, reject) => {
1893
+ var _a;
1894
+ const timeout = setTimeout(() => {
1895
+ this.rejectRequest(request.id, new import_multichain_api_client2.TransportTimeoutError());
1896
+ }, (_a = options == null ? void 0 : options.timeout) != null ? _a : this.options.requestTimeout);
1897
+ this.pendingRequests.set(request.id, {
1898
+ request,
1899
+ method: request.method,
1900
+ resolve: (response) => __async(this, null, function* () {
1901
+ yield this.storeWalletSession(request, response);
1902
+ return resolve(response);
1903
+ }),
1904
+ reject,
1905
+ timeout
1906
+ });
1907
+ this.dappClient.sendRequest({
1908
+ name: "metamask-provider",
1909
+ data: request
1910
+ }).catch(reject);
1911
+ });
1912
+ });
1913
+ }
1599
1914
  connect(options) {
1600
1915
  return __async(this, null, function* () {
1601
1916
  const { dappClient, kvstore } = this;
@@ -1649,17 +1964,23 @@ var MWPTransport = class {
1649
1964
  if (messagePayload.error) {
1650
1965
  return rejectConnection(messagePayload.error);
1651
1966
  }
1652
- this.notifyCallbacks(message.data);
1653
1967
  yield this.storeWalletSession(
1654
1968
  request,
1655
1969
  messagePayload
1656
1970
  );
1971
+ this.notifyCallbacks(messagePayload);
1657
1972
  return resolveConnection();
1658
1973
  }
1659
1974
  }
1660
1975
  }
1661
1976
  }));
1662
- dappClient.connect({ mode: "trusted", initialPayload: request }).catch(rejectConnection);
1977
+ dappClient.connect({
1978
+ mode: "trusted",
1979
+ initialPayload: {
1980
+ name: MULTICHAIN_PROVIDER_STREAM_NAME,
1981
+ data: request
1982
+ }
1983
+ }).catch(rejectConnection);
1663
1984
  }
1664
1985
  );
1665
1986
  }
@@ -1686,6 +2007,9 @@ var MWPTransport = class {
1686
2007
  window.removeEventListener("focus", this.windowFocusHandler);
1687
2008
  this.windowFocusHandler = void 0;
1688
2009
  }
2010
+ this.kvstore.delete(SESSION_STORE_KEY);
2011
+ this.kvstore.delete(ACCOUNTS_STORE_KEY);
2012
+ this.kvstore.delete(CHAIN_STORE_KEY);
1689
2013
  return this.dappClient.disconnect();
1690
2014
  });
1691
2015
  }
@@ -1697,7 +2021,39 @@ var MWPTransport = class {
1697
2021
  isConnected() {
1698
2022
  return this.dappClient.state === "CONNECTED";
1699
2023
  }
1700
- fetchCachedWalletSession(request) {
2024
+ /**
2025
+ * Attempts to re-establish a connection via DappClient
2026
+ *
2027
+ * @returns Nothing
2028
+ */
2029
+ // TODO: We should re-evaluate adding this to the WebSocketTransport layer from `@metamask/mobile-wallet-protocol-core`
2030
+ // ticket: https://consensyssoftware.atlassian.net/browse/WAPI-862
2031
+ attemptResumeSession() {
2032
+ return __async(this, null, function* () {
2033
+ try {
2034
+ yield this.dappClient.reconnect();
2035
+ yield new Promise((resolve, reject) => {
2036
+ const timeout = setTimeout(() => {
2037
+ reject(new Error("Resume timeout"));
2038
+ }, 2e3);
2039
+ if (this.isConnected()) {
2040
+ clearTimeout(timeout);
2041
+ resolve();
2042
+ } else {
2043
+ this.dappClient.once("connected", () => {
2044
+ clearTimeout(timeout);
2045
+ resolve();
2046
+ });
2047
+ }
2048
+ });
2049
+ } catch (error) {
2050
+ return Promise.reject(
2051
+ new Error(`Failed to resume session: ${error.message}`)
2052
+ );
2053
+ }
2054
+ });
2055
+ }
2056
+ getCachedResponse(request) {
1701
2057
  return __async(this, null, function* () {
1702
2058
  var _a;
1703
2059
  if (request.method === "wallet_getSession") {
@@ -1708,6 +2064,27 @@ var MWPTransport = class {
1708
2064
  id: request.id,
1709
2065
  jsonrpc: "2.0",
1710
2066
  result: (_a = walletSession.params) != null ? _a : walletSession.result,
2067
+ // "what?... why walletSession.params?.."
2068
+ method: request.method
2069
+ };
2070
+ }
2071
+ } else if (request.method === "eth_accounts") {
2072
+ const ethAccounts = yield this.kvstore.get(ACCOUNTS_STORE_KEY);
2073
+ if (ethAccounts) {
2074
+ return {
2075
+ id: request.id,
2076
+ jsonrpc: "2.0",
2077
+ result: JSON.parse(ethAccounts),
2078
+ method: request.method
2079
+ };
2080
+ }
2081
+ } else if (request.method === "eth_chainId") {
2082
+ const ethChainId = yield this.kvstore.get(CHAIN_STORE_KEY);
2083
+ if (ethChainId) {
2084
+ return {
2085
+ id: request.id,
2086
+ jsonrpc: "2.0",
2087
+ result: JSON.parse(ethChainId),
1711
2088
  method: request.method
1712
2089
  };
1713
2090
  }
@@ -1718,8 +2095,17 @@ var MWPTransport = class {
1718
2095
  return __async(this, null, function* () {
1719
2096
  if (CACHED_METHOD_LIST.includes(request.method)) {
1720
2097
  yield this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));
2098
+ } else if (request.method === "eth_accounts") {
2099
+ yield this.kvstore.set(
2100
+ ACCOUNTS_STORE_KEY,
2101
+ JSON.stringify(response.result)
2102
+ );
2103
+ } else if (request.method === "eth_chainId") {
2104
+ yield this.kvstore.set(CHAIN_STORE_KEY, JSON.stringify(response.result));
1721
2105
  } else if (CACHED_RESET_METHOD_LIST.includes(request.method)) {
1722
2106
  yield this.kvstore.delete(SESSION_STORE_KEY);
2107
+ yield this.kvstore.delete(ACCOUNTS_STORE_KEY);
2108
+ yield this.kvstore.delete(CHAIN_STORE_KEY);
1723
2109
  }
1724
2110
  });
1725
2111
  }
@@ -1729,11 +2115,14 @@ var MWPTransport = class {
1729
2115
  jsonrpc: "2.0",
1730
2116
  id: `${this.__reqId++}`
1731
2117
  }, payload);
1732
- const cachedWalletSession = yield this.fetchCachedWalletSession(request);
2118
+ const cachedWalletSession = yield this.getCachedResponse(request);
1733
2119
  if (cachedWalletSession) {
1734
2120
  this.notifyCallbacks(cachedWalletSession);
1735
2121
  return cachedWalletSession;
1736
2122
  }
2123
+ if (!this.isConnected()) {
2124
+ yield this.attemptResumeSession();
2125
+ }
1737
2126
  return new Promise((resolve, reject) => {
1738
2127
  var _a;
1739
2128
  const timeout = setTimeout(() => {
@@ -1743,15 +2132,16 @@ var MWPTransport = class {
1743
2132
  request,
1744
2133
  method: request.method,
1745
2134
  resolve: (response) => __async(this, null, function* () {
1746
- if (CACHED_METHOD_LIST.includes(request.method)) {
1747
- yield this.storeWalletSession(request, response);
1748
- }
2135
+ yield this.storeWalletSession(request, response);
1749
2136
  return resolve(response);
1750
2137
  }),
1751
2138
  reject,
1752
2139
  timeout
1753
2140
  });
1754
- this.dappClient.sendRequest(request).catch(reject);
2141
+ this.dappClient.sendRequest({
2142
+ name: MULTICHAIN_PROVIDER_STREAM_NAME,
2143
+ data: request
2144
+ }).catch(reject);
1755
2145
  });
1756
2146
  });
1757
2147
  }
@@ -1791,21 +2181,22 @@ var KeyManager = class {
1791
2181
  var keymanager = new KeyManager();
1792
2182
 
1793
2183
  // src/multichain/index.ts
2184
+ init_utils();
1794
2185
  var logger2 = createLogger("metamask-sdk:core");
1795
2186
  var MultichainSDK = class _MultichainSDK extends MultichainCore {
1796
2187
  constructor(options) {
1797
- var _a, _b, _c, _d, _e, _f;
1798
- const withInfuraRPCMethods = setupInfuraProvider(options);
1799
- const withDappMetadata = setupDappMetadata(withInfuraRPCMethods);
2188
+ var _a, _b, _c, _d, _e, _f, _g;
2189
+ const withDappMetadata = setupDappMetadata(options);
2190
+ const integrationType = ((_a = options.analytics) == null ? void 0 : _a.enabled) ? options.analytics.integrationType : "direct";
1800
2191
  const allOptions = __spreadProps(__spreadValues({}, withDappMetadata), {
1801
2192
  ui: __spreadProps(__spreadValues({}, withDappMetadata.ui), {
1802
- preferExtension: (_a = withDappMetadata.ui.preferExtension) != null ? _a : true,
1803
- preferDesktop: (_b = withDappMetadata.ui.preferDesktop) != null ? _b : false,
1804
- headless: (_c = withDappMetadata.ui.headless) != null ? _c : false
2193
+ preferExtension: (_b = withDappMetadata.ui.preferExtension) != null ? _b : true,
2194
+ showInstallModal: (_c = withDappMetadata.ui.showInstallModal) != null ? _c : false,
2195
+ headless: (_d = withDappMetadata.ui.headless) != null ? _d : false
1805
2196
  }),
1806
- analytics: __spreadProps(__spreadValues({}, (_d = options.analytics) != null ? _d : {}), {
1807
- enabled: (_f = (_e = options.analytics) == null ? void 0 : _e.enabled) != null ? _f : true,
1808
- integrationType: "unknown"
2197
+ analytics: __spreadProps(__spreadValues({}, (_e = options.analytics) != null ? _e : {}), {
2198
+ enabled: (_g = (_f = options.analytics) == null ? void 0 : _f.enabled) != null ? _g : true,
2199
+ integrationType
1809
2200
  })
1810
2201
  });
1811
2202
  super(allOptions);
@@ -1826,6 +2217,10 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
1826
2217
  });
1827
2218
  }
1828
2219
  get provider() {
2220
+ if (!this.__provider && this.__transport) {
2221
+ this.__provider = (0, import_multichain_api_client3.getMultichainClient)({ transport: this.__transport });
2222
+ return this.__provider;
2223
+ }
1829
2224
  if (!this.__provider) {
1830
2225
  throw new Error("Provider not initialized, establish connection first");
1831
2226
  }
@@ -1846,6 +2241,9 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
1846
2241
  get storage() {
1847
2242
  return this.options.storage;
1848
2243
  }
2244
+ get transportType() {
2245
+ return this.__transport instanceof MWPTransport ? "mwp" /* MWP */ : "browser" /* Browser */;
2246
+ }
1849
2247
  get sdkInfo() {
1850
2248
  var _a;
1851
2249
  return `Sdk/Javascript SdkVersion/${getVersion()} Platform/${getPlatformType()} dApp/${(_a = this.options.dapp.url) != null ? _a : this.options.dapp.name} dAppTitle/${this.options.dapp.name}`;
@@ -1882,12 +2280,12 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
1882
2280
  const { integrationType } = (_b = this.options.analytics) != null ? _b : {
1883
2281
  integrationType: ""
1884
2282
  };
1885
- import_analytics.analytics.setGlobalProperty("sdk_version", version);
1886
- import_analytics.analytics.setGlobalProperty("dapp_id", dappId);
1887
- import_analytics.analytics.setGlobalProperty("anon_id", anonId);
1888
- import_analytics.analytics.setGlobalProperty("platform", platform);
1889
- import_analytics.analytics.setGlobalProperty("integration_type", integrationType);
1890
- import_analytics.analytics.enable();
2283
+ import_analytics4.analytics.setGlobalProperty("mmconnect_version", version);
2284
+ import_analytics4.analytics.setGlobalProperty("dapp_id", dappId);
2285
+ import_analytics4.analytics.setGlobalProperty("anon_id", anonId);
2286
+ import_analytics4.analytics.setGlobalProperty("platform", platform);
2287
+ import_analytics4.analytics.setGlobalProperty("integration_type", integrationType);
2288
+ import_analytics4.analytics.enable();
1891
2289
  });
1892
2290
  }
1893
2291
  onTransportNotification(payload) {
@@ -1900,13 +2298,11 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
1900
2298
  }
1901
2299
  getStoredTransport() {
1902
2300
  return __async(this, null, function* () {
1903
- const { ui } = this.options;
1904
- const { preferExtension = true } = ui;
1905
2301
  const transportType = yield this.storage.getTransport();
1906
2302
  const hasExtensionInstalled = yield hasExtension();
1907
2303
  if (transportType) {
1908
2304
  if (transportType === "browser" /* Browser */) {
1909
- if (hasExtensionInstalled && preferExtension) {
2305
+ if (hasExtensionInstalled) {
1910
2306
  const apiTransport = new DefaultTransport();
1911
2307
  this.__transport = apiTransport;
1912
2308
  this.listener = apiTransport.onNotification(
@@ -1914,7 +2310,7 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
1914
2310
  );
1915
2311
  return apiTransport;
1916
2312
  }
1917
- } else if (transportType === "mwp" /* MPW */) {
2313
+ } else if (transportType === "mwp" /* MWP */) {
1918
2314
  const { adapter: kvstore } = this.options.storage;
1919
2315
  const dappClient = yield this.createDappClient();
1920
2316
  const apiTransport = new MWPTransport(dappClient, kvstore);
@@ -1940,7 +2336,7 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
1940
2336
  }
1941
2337
  this.state = "connected";
1942
2338
  if (this.transport instanceof MWPTransport) {
1943
- yield this.storage.setTransport("mwp" /* MPW */);
2339
+ yield this.storage.setTransport("mwp" /* MWP */);
1944
2340
  } else {
1945
2341
  yield this.storage.setTransport("browser" /* Browser */);
1946
2342
  }
@@ -1951,14 +2347,24 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
1951
2347
  }
1952
2348
  init() {
1953
2349
  return __async(this, null, function* () {
1954
- var _a;
2350
+ var _a, _b;
1955
2351
  try {
1956
2352
  if (typeof window !== "undefined" && ((_a = window.mmsdk) == null ? void 0 : _a.isInitialized)) {
1957
2353
  logger2("MetaMaskSDK: init already initialized");
1958
2354
  } else {
1959
2355
  yield this.setupAnalytics();
1960
2356
  yield this.setupTransport();
1961
- import_analytics.analytics.track("sdk_initialized", {});
2357
+ if ((_b = this.options.analytics) == null ? void 0 : _b.enabled) {
2358
+ try {
2359
+ const baseProps = yield getBaseAnalyticsProperties(
2360
+ this.options,
2361
+ this.storage
2362
+ );
2363
+ import_analytics4.analytics.track("mmconnect_initialized", baseProps);
2364
+ } catch (error) {
2365
+ logger2("Error tracking initialized event", error);
2366
+ }
2367
+ }
1962
2368
  if (typeof window !== "undefined") {
1963
2369
  window.mmsdk = this;
1964
2370
  }
@@ -2000,7 +2406,7 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2000
2406
  this.listener = this.transport.onNotification(
2001
2407
  this.onTransportNotification.bind(this)
2002
2408
  );
2003
- yield this.storage.setTransport("mwp" /* MPW */);
2409
+ yield this.storage.setTransport("mwp" /* MWP */);
2004
2410
  });
2005
2411
  }
2006
2412
  onBeforeUnload() {
@@ -2056,7 +2462,7 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2056
2462
  this.options.ui.factory.unload();
2057
2463
  (_a2 = this.options.ui.factory.modal) == null ? void 0 : _a2.unmount();
2058
2464
  this.state = "connected";
2059
- return this.storage.setTransport("mwp" /* MPW */);
2465
+ return this.storage.setTransport("mwp" /* MWP */);
2060
2466
  }).catch((error) => {
2061
2467
  if (error instanceof import_mobile_wallet_protocol_core2.ProtocolError) {
2062
2468
  if (error.code !== import_mobile_wallet_protocol_core2.ErrorCode.REQUEST_EXPIRED) {
@@ -2072,7 +2478,7 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2072
2478
  }),
2073
2479
  (error) => __async(this, null, function* () {
2074
2480
  if (!error) {
2075
- yield this.storage.setTransport("mwp" /* MPW */);
2481
+ yield this.storage.setTransport("mwp" /* MWP */);
2076
2482
  resolve();
2077
2483
  } else {
2078
2484
  yield this.storage.removeTransport();
@@ -2160,52 +2566,128 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2160
2566
  }));
2161
2567
  });
2162
2568
  }
2163
- handleConnection(promise) {
2569
+ handleConnection(promise, scopes, transportType) {
2164
2570
  return __async(this, null, function* () {
2165
2571
  this.state = "connecting";
2166
- return promise.then(() => {
2572
+ return promise.then(() => __async(this, null, function* () {
2573
+ var _a;
2167
2574
  this.state = "connected";
2168
- }).catch((error) => {
2575
+ if ((_a = this.options.analytics) == null ? void 0 : _a.enabled) {
2576
+ try {
2577
+ const baseProps = yield getBaseAnalyticsProperties(
2578
+ this.options,
2579
+ this.storage
2580
+ );
2581
+ import_analytics4.analytics.track("mmconnect_connection_established", __spreadProps(__spreadValues({}, baseProps), {
2582
+ transport_type: transportType,
2583
+ user_permissioned_chains: scopes
2584
+ }));
2585
+ } catch (error) {
2586
+ logger2("Error tracking connection_established event", error);
2587
+ }
2588
+ }
2589
+ })).catch((error) => __async(this, null, function* () {
2590
+ var _a;
2169
2591
  this.state = "disconnected";
2592
+ if ((_a = this.options.analytics) == null ? void 0 : _a.enabled) {
2593
+ try {
2594
+ const baseProps = yield getBaseAnalyticsProperties(
2595
+ this.options,
2596
+ this.storage
2597
+ );
2598
+ const isRejection = isRejectionError(error);
2599
+ if (isRejection) {
2600
+ import_analytics4.analytics.track("mmconnect_connection_rejected", __spreadProps(__spreadValues({}, baseProps), {
2601
+ transport_type: transportType
2602
+ }));
2603
+ } else {
2604
+ import_analytics4.analytics.track("mmconnect_connection_failed", __spreadProps(__spreadValues({}, baseProps), {
2605
+ transport_type: transportType
2606
+ }));
2607
+ }
2608
+ } catch (e) {
2609
+ logger2("Error tracking connection failed/rejected event", error);
2610
+ }
2611
+ }
2170
2612
  return Promise.reject(error);
2171
- });
2613
+ }));
2172
2614
  });
2173
2615
  }
2174
- connect(scopes, caipAccountIds) {
2616
+ connect(scopes, caipAccountIds, forceRequest) {
2175
2617
  return __async(this, null, function* () {
2176
- var _a;
2618
+ var _a, _b;
2177
2619
  const { ui } = this.options;
2178
2620
  const platformType = getPlatformType();
2179
2621
  const isWeb = platformType === "in-app-browser" /* MetaMaskMobileWebview */ || platformType === "web-desktop" /* DesktopWeb */;
2180
- const { preferExtension = true, preferDesktop = false } = ui;
2622
+ const { preferExtension = true, showInstallModal = false } = ui;
2181
2623
  const secure = isSecure();
2182
2624
  const hasExtensionInstalled = yield hasExtension();
2183
- if (((_a = this.__transport) == null ? void 0 : _a.isConnected()) && !secure) {
2625
+ let transportType;
2626
+ if (platformType === "in-app-browser" /* MetaMaskMobileWebview */ || isWeb && hasExtensionInstalled && preferExtension) {
2627
+ transportType = "browser" /* Browser */;
2628
+ } else {
2629
+ transportType = "mwp" /* MWP */;
2630
+ }
2631
+ if ((_a = this.options.analytics) == null ? void 0 : _a.enabled) {
2632
+ try {
2633
+ const baseProps = yield getBaseAnalyticsProperties(
2634
+ this.options,
2635
+ this.storage
2636
+ );
2637
+ const dappConfiguredChains = Object.keys(
2638
+ this.options.api.supportedNetworks
2639
+ );
2640
+ import_analytics4.analytics.track("mmconnect_connection_initiated", __spreadProps(__spreadValues({}, baseProps), {
2641
+ transport_type: transportType,
2642
+ dapp_configured_chains: dappConfiguredChains,
2643
+ dapp_requested_chains: scopes
2644
+ }));
2645
+ } catch (error) {
2646
+ logger2("Error tracking connection_initiated event", error);
2647
+ }
2648
+ }
2649
+ if (((_b = this.__transport) == null ? void 0 : _b.isConnected()) && !secure) {
2184
2650
  return this.handleConnection(
2185
- this.__transport.connect({ scopes, caipAccountIds }).then(() => {
2651
+ this.__transport.connect({ scopes, caipAccountIds, forceRequest }).then(() => {
2186
2652
  if (this.__transport instanceof MWPTransport) {
2187
- return this.storage.setTransport("mwp" /* MPW */);
2653
+ return this.storage.setTransport("mwp" /* MWP */);
2188
2654
  } else {
2189
2655
  return this.storage.setTransport("browser" /* Browser */);
2190
2656
  }
2191
- })
2657
+ }),
2658
+ scopes,
2659
+ transportType
2660
+ );
2661
+ }
2662
+ if (platformType === "in-app-browser" /* MetaMaskMobileWebview */) {
2663
+ const defaultTransport = yield this.setupDefaultTransport();
2664
+ return this.handleConnection(
2665
+ defaultTransport.connect({ scopes, caipAccountIds, forceRequest }),
2666
+ scopes,
2667
+ transportType
2192
2668
  );
2193
2669
  }
2194
2670
  if (isWeb && hasExtensionInstalled && preferExtension) {
2195
2671
  const defaultTransport = yield this.setupDefaultTransport();
2196
2672
  return this.handleConnection(
2197
- defaultTransport.connect({ scopes, caipAccountIds })
2673
+ defaultTransport.connect({ scopes, caipAccountIds, forceRequest }),
2674
+ scopes,
2675
+ transportType
2198
2676
  );
2199
2677
  }
2200
2678
  yield this.setupMWP();
2201
- const isDesktopPreferred = hasExtensionInstalled ? preferDesktop : !preferExtension || preferDesktop;
2202
- if (secure && !isDesktopPreferred) {
2679
+ const shouldShowInstallModal = hasExtensionInstalled ? showInstallModal : !preferExtension || showInstallModal;
2680
+ if (secure && !shouldShowInstallModal) {
2203
2681
  return this.handleConnection(
2204
- this.deeplinkConnect(scopes, caipAccountIds)
2682
+ this.deeplinkConnect(scopes, caipAccountIds),
2683
+ scopes,
2684
+ transportType
2205
2685
  );
2206
2686
  }
2207
2687
  return this.handleConnection(
2208
- this.showInstallModal(isDesktopPreferred, scopes, caipAccountIds)
2688
+ this.showInstallModal(shouldShowInstallModal, scopes, caipAccountIds),
2689
+ scopes,
2690
+ transportType
2209
2691
  );
2210
2692
  });
2211
2693
  }
@@ -2240,6 +2722,26 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2240
2722
  return requestRouter.invokeMethod(request);
2241
2723
  });
2242
2724
  }
2725
+ // DRY THIS WITH REQUEST ROUTER
2726
+ openDeeplinkIfNeeded() {
2727
+ const { ui, mobile } = this.options;
2728
+ const { showInstallModal = false } = ui != null ? ui : {};
2729
+ const secure = isSecure();
2730
+ const shouldOpenDeeplink = secure && !showInstallModal;
2731
+ if (shouldOpenDeeplink) {
2732
+ setTimeout(() => {
2733
+ if (mobile == null ? void 0 : mobile.preferredOpenLink) {
2734
+ mobile.preferredOpenLink(METAMASK_DEEPLINK_BASE, "_self");
2735
+ } else {
2736
+ openDeeplink(
2737
+ this.options,
2738
+ METAMASK_DEEPLINK_BASE,
2739
+ METAMASK_CONNECT_BASE_URL
2740
+ );
2741
+ }
2742
+ }, 10);
2743
+ }
2744
+ }
2243
2745
  };
2244
2746
 
2245
2747
  // src/store/index.ts
@@ -2438,25 +2940,34 @@ function preloadQR() {
2438
2940
  }
2439
2941
 
2440
2942
  // src/ui/index.ts
2943
+ init_utils();
2441
2944
  var __instance;
2442
2945
  function preload() {
2443
2946
  return __async(this, null, function* () {
2444
- __instance != null ? __instance : __instance = yield import(
2445
- // Use a non-literal specifier to avoid Vite static analysis of deep imports
2446
- // and gracefully handle absence of the Stencil loader in this package build.
2447
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2448
- // @ts-ignore
2449
- "@metamask/multichain-ui".concat("/dist/loader/index.js")
2450
- // Prefer ESM loader in browsers
2451
- ).then((loader) => __async(null, null, function* () {
2452
- if (typeof (loader == null ? void 0 : loader.defineCustomElements) === "function") {
2453
- loader.defineCustomElements();
2454
- }
2455
- return Promise.resolve(loader);
2456
- })).catch((error) => __async(null, null, function* () {
2457
- console.error(`Gracefully Failed to load modal customElements:`, error);
2458
- return Promise.resolve(void 0);
2459
- }));
2947
+ if (false) {
2948
+ __instance != null ? __instance : __instance = yield null.then((loader) => __async(null, null, function* () {
2949
+ if (typeof (loader == null ? void 0 : loader.defineCustomElements) === "function") {
2950
+ loader.defineCustomElements();
2951
+ }
2952
+ return Promise.resolve(loader);
2953
+ })).catch((error) => __async(null, null, function* () {
2954
+ console.error(`Gracefully Failed to load modal customElements:`, error);
2955
+ return Promise.resolve(void 0);
2956
+ }));
2957
+ } else {
2958
+ const dynamicImport = (0, eval)("import");
2959
+ __instance != null ? __instance : __instance = yield dynamicImport(
2960
+ "@metamask/multichain-ui/dist/loader/index.js"
2961
+ ).then((loader) => __async(null, null, function* () {
2962
+ if (typeof (loader == null ? void 0 : loader.defineCustomElements) === "function") {
2963
+ loader.defineCustomElements();
2964
+ }
2965
+ return Promise.resolve(loader);
2966
+ })).catch((error) => __async(null, null, function* () {
2967
+ console.error(`Gracefully Failed to load modal customElements:`, error);
2968
+ return Promise.resolve(void 0);
2969
+ }));
2970
+ }
2460
2971
  });
2461
2972
  }
2462
2973
  var ModalFactory = class {
@@ -2548,7 +3059,7 @@ var ModalFactory = class {
2548
3059
  onStartDesktopOnboarding() {
2549
3060
  new import_onboarding.default().startOnboarding();
2550
3061
  }
2551
- renderInstallModal(preferDesktop, createConnectionRequest, successCallback) {
3062
+ renderInstallModal(showInstallModal, createConnectionRequest, successCallback) {
2552
3063
  return __async(this, null, function* () {
2553
3064
  var _a;
2554
3065
  (_a = this.modal) == null ? void 0 : _a.unmount();
@@ -2561,7 +3072,7 @@ var ModalFactory = class {
2561
3072
  expiresIn: (connectionRequest.sessionRequest.expiresAt - Date.now()) / 1e3,
2562
3073
  connectionRequest,
2563
3074
  parentElement,
2564
- preferDesktop,
3075
+ showInstallModal,
2565
3076
  link: qrCodeLink,
2566
3077
  sdkVersion: getVersion(),
2567
3078
  generateQRCode: (request) => __async(this, null, function* () {