@metamask/connect-multichain 0.5.2 → 0.6.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 (139) hide show
  1. package/CHANGELOG.md +38 -1
  2. package/README.md +415 -3
  3. package/dist/browser/es/connect-multichain.d.mts +33 -9
  4. package/dist/browser/es/connect-multichain.mjs +864 -510
  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 +33 -9
  8. package/dist/browser/iife/connect-multichain.js +24802 -24331
  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 +33 -9
  12. package/dist/browser/umd/connect-multichain.js +864 -510
  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 +33 -9
  16. package/dist/node/cjs/connect-multichain.js +693 -340
  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 +33 -9
  20. package/dist/node/es/connect-multichain.mjs +694 -339
  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 +33 -9
  24. package/dist/react-native/es/connect-multichain.mjs +857 -503
  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/logger/index.d.ts +1 -1
  28. package/dist/src/domain/logger/index.d.ts.map +1 -1
  29. package/dist/src/domain/logger/index.js.map +1 -1
  30. package/dist/src/domain/multichain/api/constants.js.map +1 -1
  31. package/dist/src/domain/multichain/api/types.d.ts +1 -1
  32. package/dist/src/domain/multichain/api/types.d.ts.map +1 -1
  33. package/dist/src/domain/multichain/index.d.ts +15 -4
  34. package/dist/src/domain/multichain/index.d.ts.map +1 -1
  35. package/dist/src/domain/multichain/index.js +14 -0
  36. package/dist/src/domain/multichain/index.js.map +1 -1
  37. package/dist/src/domain/multichain/types.d.ts +14 -0
  38. package/dist/src/domain/multichain/types.d.ts.map +1 -1
  39. package/dist/src/domain/platform/index.d.ts.map +1 -1
  40. package/dist/src/domain/platform/index.js +1 -0
  41. package/dist/src/domain/platform/index.js.map +1 -1
  42. package/dist/src/index.browser.d.ts.map +1 -1
  43. package/dist/src/index.browser.js +9 -4
  44. package/dist/src/index.browser.js.map +1 -1
  45. package/dist/src/index.native.d.ts.map +1 -1
  46. package/dist/src/index.native.js +9 -4
  47. package/dist/src/index.native.js.map +1 -1
  48. package/dist/src/index.node.d.ts.map +1 -1
  49. package/dist/src/index.node.js +8 -4
  50. package/dist/src/index.node.js.map +1 -1
  51. package/dist/src/multichain/index.d.ts +4 -3
  52. package/dist/src/multichain/index.d.ts.map +1 -1
  53. package/dist/src/multichain/index.js +181 -59
  54. package/dist/src/multichain/index.js.map +1 -1
  55. package/dist/src/multichain/rpc/handlers/rpcClient.d.ts +9 -2
  56. package/dist/src/multichain/rpc/handlers/rpcClient.d.ts.map +1 -1
  57. package/dist/src/multichain/rpc/handlers/rpcClient.js +13 -3
  58. package/dist/src/multichain/rpc/handlers/rpcClient.js.map +1 -1
  59. package/dist/src/multichain/rpc/requestRouter.d.ts +14 -1
  60. package/dist/src/multichain/rpc/requestRouter.d.ts.map +1 -1
  61. package/dist/src/multichain/rpc/requestRouter.js +27 -5
  62. package/dist/src/multichain/rpc/requestRouter.js.map +1 -1
  63. package/dist/src/multichain/transports/default/index.d.ts +5 -3
  64. package/dist/src/multichain/transports/default/index.d.ts.map +1 -1
  65. package/dist/src/multichain/transports/default/index.js +31 -28
  66. package/dist/src/multichain/transports/default/index.js.map +1 -1
  67. package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts +3 -3
  68. package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts.map +1 -1
  69. package/dist/src/multichain/transports/multichainApiClientWrapper/index.js +33 -29
  70. package/dist/src/multichain/transports/multichainApiClientWrapper/index.js.map +1 -1
  71. package/dist/src/multichain/transports/mwp/KeyManager.d.ts.map +1 -1
  72. package/dist/src/multichain/transports/mwp/KeyManager.js.map +1 -1
  73. package/dist/src/multichain/transports/mwp/index.d.ts +16 -3
  74. package/dist/src/multichain/transports/mwp/index.d.ts.map +1 -1
  75. package/dist/src/multichain/transports/mwp/index.js +157 -39
  76. package/dist/src/multichain/transports/mwp/index.js.map +1 -1
  77. package/dist/src/multichain/utils/analytics.d.ts.map +1 -1
  78. package/dist/src/multichain/utils/analytics.js +1 -0
  79. package/dist/src/multichain/utils/analytics.js.map +1 -1
  80. package/dist/src/multichain/utils/index.d.ts +48 -0
  81. package/dist/src/multichain/utils/index.d.ts.map +1 -1
  82. package/dist/src/multichain/utils/index.js +91 -6
  83. package/dist/src/multichain/utils/index.js.map +1 -1
  84. package/dist/src/polyfills/buffer-shim.js +5 -11
  85. package/dist/src/polyfills/buffer-shim.js.map +1 -1
  86. package/dist/src/store/adapters/node.d.ts +1 -1
  87. package/dist/src/store/adapters/node.d.ts.map +1 -1
  88. package/dist/src/store/adapters/node.js +11 -4
  89. package/dist/src/store/adapters/node.js.map +1 -1
  90. package/dist/src/store/adapters/rn.d.ts.map +1 -1
  91. package/dist/src/store/adapters/rn.js +1 -0
  92. package/dist/src/store/adapters/rn.js.map +1 -1
  93. package/dist/src/store/adapters/web.d.ts +5 -5
  94. package/dist/src/store/adapters/web.d.ts.map +1 -1
  95. package/dist/src/store/adapters/web.js +7 -1
  96. package/dist/src/store/adapters/web.js.map +1 -1
  97. package/dist/src/store/index.d.ts.map +1 -1
  98. package/dist/src/store/index.js +2 -0
  99. package/dist/src/store/index.js.map +1 -1
  100. package/dist/src/ui/ModalFactory.d.ts.map +1 -1
  101. package/dist/src/ui/ModalFactory.js +1 -4
  102. package/dist/src/ui/ModalFactory.js.map +1 -1
  103. package/dist/src/ui/index.d.ts.map +1 -1
  104. package/dist/src/ui/index.js +2 -0
  105. package/dist/src/ui/index.js.map +1 -1
  106. package/dist/src/ui/index.native.d.ts.map +1 -1
  107. package/dist/src/ui/index.native.js +4 -1
  108. package/dist/src/ui/index.native.js.map +1 -1
  109. package/dist/src/ui/modals/base/AbstractInstallModal.d.ts +2 -3
  110. package/dist/src/ui/modals/base/AbstractInstallModal.d.ts.map +1 -1
  111. package/dist/src/ui/modals/base/AbstractInstallModal.js +28 -12
  112. package/dist/src/ui/modals/base/AbstractInstallModal.js.map +1 -1
  113. package/dist/src/ui/modals/base/AbstractOTPModal.d.ts +2 -2
  114. package/dist/src/ui/modals/base/AbstractOTPModal.d.ts.map +1 -1
  115. package/dist/src/ui/modals/base/AbstractOTPModal.js.map +1 -1
  116. package/dist/src/ui/modals/base/utils.d.ts +12 -0
  117. package/dist/src/ui/modals/base/utils.d.ts.map +1 -1
  118. package/dist/src/ui/modals/base/utils.js +16 -5
  119. package/dist/src/ui/modals/base/utils.js.map +1 -1
  120. package/dist/src/ui/modals/node/install.d.ts.map +1 -1
  121. package/dist/src/ui/modals/node/install.js +1 -1
  122. package/dist/src/ui/modals/node/install.js.map +1 -1
  123. package/dist/src/ui/modals/node/otp.d.ts.map +1 -1
  124. package/dist/src/ui/modals/node/otp.js +6 -2
  125. package/dist/src/ui/modals/node/otp.js.map +1 -1
  126. package/dist/src/ui/modals/rn/install.d.ts.map +1 -1
  127. package/dist/src/ui/modals/rn/install.js +7 -3
  128. package/dist/src/ui/modals/rn/install.js.map +1 -1
  129. package/dist/src/ui/modals/rn/otp.d.ts.map +1 -1
  130. package/dist/src/ui/modals/rn/otp.js +6 -2
  131. package/dist/src/ui/modals/rn/otp.js.map +1 -1
  132. package/dist/src/ui/modals/web/install.d.ts.map +1 -1
  133. package/dist/src/ui/modals/web/install.js +1 -1
  134. package/dist/src/ui/modals/web/install.js.map +1 -1
  135. package/dist/src/ui/modals/web/otp.d.ts.map +1 -1
  136. package/dist/src/ui/modals/web/otp.js +6 -2
  137. package/dist/src/ui/modals/web/otp.js.map +1 -1
  138. package/dist/types/connect-multichain.d.ts +33 -9
  139. package/package.json +3 -3
@@ -420,6 +420,34 @@ var init_multichain = __esm({
420
420
  super();
421
421
  this.options = options;
422
422
  }
423
+ /**
424
+ * Merges the given options into the current instance options.
425
+ * Only the mergeable keys are updated (api.supportedNetworks, ui.*, mobile.*, transport.extensionId, debug).
426
+ * The main thing to note is that the value for `dapp` is not merged as it does not make sense for
427
+ * subsequent calls to `createMultichainClient` to have a different `dapp` value.
428
+ * Used when createMultichainClient is called with an existing singleton.
429
+ *
430
+ * @param partial - Options to merge/overwrite onto the current instance
431
+ */
432
+ mergeOptions(partial) {
433
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
434
+ const opts = this.options;
435
+ this.options = __spreadProps(__spreadValues({}, opts), {
436
+ api: __spreadProps(__spreadValues({}, opts.api), {
437
+ supportedNetworks: __spreadValues(__spreadValues({}, opts.api.supportedNetworks), (_b = (_a2 = partial.api) == null ? void 0 : _a2.supportedNetworks) != null ? _b : {})
438
+ }),
439
+ ui: __spreadProps(__spreadValues({}, opts.ui), {
440
+ headless: (_d = (_c = partial.ui) == null ? void 0 : _c.headless) != null ? _d : opts.ui.headless,
441
+ preferExtension: (_f = (_e = partial.ui) == null ? void 0 : _e.preferExtension) != null ? _f : opts.ui.preferExtension,
442
+ showInstallModal: (_h = (_g = partial.ui) == null ? void 0 : _g.showInstallModal) != null ? _h : opts.ui.showInstallModal
443
+ }),
444
+ mobile: __spreadValues(__spreadValues({}, opts.mobile), (_i = partial.mobile) != null ? _i : {}),
445
+ transport: __spreadProps(__spreadValues({}, (_j = opts.transport) != null ? _j : {}), {
446
+ extensionId: (_m = (_k = partial.transport) == null ? void 0 : _k.extensionId) != null ? _m : (_l = opts.transport) == null ? void 0 : _l.extensionId
447
+ }),
448
+ debug: (_n = partial.debug) != null ? _n : opts.debug
449
+ });
450
+ }
423
451
  };
424
452
  }
425
453
  });
@@ -605,6 +633,21 @@ var init_ui = __esm({
605
633
  });
606
634
 
607
635
  // src/multichain/utils/index.ts
636
+ function getGlobalObject() {
637
+ if (typeof globalThis !== "undefined") {
638
+ return globalThis;
639
+ }
640
+ if (typeof global !== "undefined") {
641
+ return global;
642
+ }
643
+ if (typeof self !== "undefined") {
644
+ return self;
645
+ }
646
+ if (typeof window !== "undefined") {
647
+ return window;
648
+ }
649
+ throw new Error("Unable to locate global object");
650
+ }
608
651
  function base64Encode(str) {
609
652
  if (typeof btoa !== "undefined") {
610
653
  return btoa(str);
@@ -623,8 +666,9 @@ function getDappId(dapp) {
623
666
  return (_a2 = dapp.url) != null ? _a2 : dapp.name;
624
667
  }
625
668
  function openDeeplink(options, deeplink, universalLink) {
669
+ var _a2;
626
670
  const { mobile } = options;
627
- const useDeeplink = mobile && mobile.useDeeplink !== void 0 ? mobile.useDeeplink : true;
671
+ const useDeeplink = (_a2 = mobile == null ? void 0 : mobile.useDeeplink) != null ? _a2 : true;
628
672
  if (useDeeplink) {
629
673
  if (typeof window !== "undefined") {
630
674
  window.location.href = deeplink;
@@ -637,6 +681,29 @@ function openDeeplink(options, deeplink, universalLink) {
637
681
  link.click();
638
682
  }
639
683
  }
684
+ function mergeRequestedSessionWithExisting(sessionData, scopes, caipAccountIds, sessionProperties) {
685
+ const existingCaipChainIds = Object.keys(sessionData.sessionScopes);
686
+ const existingCaipAccountIds = [];
687
+ Object.values(sessionData.sessionScopes).forEach((scopeObject) => {
688
+ if ((scopeObject == null ? void 0 : scopeObject.accounts) && Array.isArray(scopeObject.accounts)) {
689
+ scopeObject.accounts.forEach((account) => {
690
+ existingCaipAccountIds.push(account);
691
+ });
692
+ }
693
+ });
694
+ const mergedScopes = Array.from(
695
+ /* @__PURE__ */ new Set([...existingCaipChainIds, ...scopes])
696
+ );
697
+ const mergedCaipAccountIds = Array.from(
698
+ /* @__PURE__ */ new Set([...existingCaipAccountIds, ...caipAccountIds])
699
+ );
700
+ const mergedSessionProperties = __spreadValues(__spreadValues({}, sessionData.sessionProperties), sessionProperties);
701
+ return {
702
+ mergedScopes,
703
+ mergedCaipAccountIds,
704
+ mergedSessionProperties
705
+ };
706
+ }
640
707
  function getOptionalScopes(scopes) {
641
708
  return scopes.reduce(
642
709
  (prev, scope) => __spreadProps(__spreadValues({}, prev), {
@@ -665,7 +732,7 @@ function setupDappMetadata(options) {
665
732
  throw new Error("You must provide dapp url");
666
733
  }
667
734
  const BASE_64_ICON_MAX_LENGTH = 163400;
668
- const urlPattern = /^(http|https):\/\/[^\s]*$/;
735
+ const urlPattern = /^(http|https):\/\/[^\s]*$/u;
669
736
  if (options.dapp) {
670
737
  if ("iconUrl" in options.dapp) {
671
738
  if (options.dapp.iconUrl && !urlPattern.test(options.dapp.iconUrl)) {
@@ -714,9 +781,12 @@ function getValidAccounts(caipAccountIds) {
714
781
  (caipAccounts, caipAccountId) => {
715
782
  try {
716
783
  return [...caipAccounts, (0, import_utils.parseCaipAccountId)(caipAccountId)];
717
- } catch (err) {
784
+ } catch (error) {
718
785
  const stringifiedAccountId = JSON.stringify(caipAccountId);
719
- console.error(`Invalid CAIP account ID: ${stringifiedAccountId}`, err);
786
+ console.error(
787
+ `Invalid CAIP account ID: ${stringifiedAccountId}`,
788
+ error
789
+ );
720
790
  return caipAccounts;
721
791
  }
722
792
  },
@@ -772,12 +842,12 @@ function addValidAccounts(optionalScopes, validAccounts) {
772
842
  }
773
843
  return result;
774
844
  }
775
- var import_pako, import_utils, extractFavicon;
845
+ var import_utils, import_pako, extractFavicon, MAX, idCounter, getUniqueRequestId;
776
846
  var init_utils = __esm({
777
847
  "src/multichain/utils/index.ts"() {
778
848
  "use strict";
779
- import_pako = require("pako");
780
849
  import_utils = require("@metamask/utils");
850
+ import_pako = require("pako");
781
851
  init_domain();
782
852
  extractFavicon = () => {
783
853
  var _a2;
@@ -793,6 +863,12 @@ var init_utils = __esm({
793
863
  }
794
864
  return favicon;
795
865
  };
866
+ MAX = 4294967295;
867
+ idCounter = Math.floor(Math.random() * MAX);
868
+ getUniqueRequestId = () => {
869
+ idCounter = (idCounter + 1) % MAX;
870
+ return idCounter;
871
+ };
796
872
  }
797
873
  });
798
874
 
@@ -879,7 +955,9 @@ var init_domain = __esm({
879
955
 
880
956
  // src/ui/modals/base/utils.ts
881
957
  function formatRemainingTime(milliseconds) {
882
- if (milliseconds <= 0) return "EXPIRED";
958
+ if (milliseconds <= 0) {
959
+ return "EXPIRED";
960
+ }
883
961
  const seconds = Math.floor(milliseconds / 1e3);
884
962
  return `${seconds}s`;
885
963
  }
@@ -892,9 +970,8 @@ function shouldLogCountdown(remainingSeconds) {
892
970
  return remainingSeconds % 10 === 0;
893
971
  } else if (remainingSeconds <= 300) {
894
972
  return remainingSeconds % 30 === 0;
895
- } else {
896
- return remainingSeconds % 60 === 0;
897
973
  }
974
+ return remainingSeconds % 60 === 0;
898
975
  }
899
976
  var init_utils3 = __esm({
900
977
  "src/ui/modals/base/utils.ts"() {
@@ -903,18 +980,18 @@ var init_utils3 = __esm({
903
980
  });
904
981
 
905
982
  // src/ui/modals/base/AbstractInstallModal.ts
906
- var logger3, AbstractInstallModal;
983
+ var logger3, _expirationInterval, _lastLoggedCountdown, AbstractInstallModal;
907
984
  var init_AbstractInstallModal = __esm({
908
985
  "src/ui/modals/base/AbstractInstallModal.ts"() {
909
986
  "use strict";
910
- init_domain();
911
987
  init_utils3();
988
+ init_domain();
912
989
  logger3 = createLogger("metamask-sdk:ui");
913
990
  AbstractInstallModal = class extends Modal {
914
991
  constructor() {
915
992
  super(...arguments);
916
- this.expirationInterval = null;
917
- this.lastLoggedCountdown = -1;
993
+ __privateAdd(this, _expirationInterval, null);
994
+ __privateAdd(this, _lastLoggedCountdown, -1);
918
995
  }
919
996
  get link() {
920
997
  return this.data;
@@ -942,17 +1019,17 @@ var init_AbstractInstallModal = __esm({
942
1019
  startExpirationCheck(connectionRequest) {
943
1020
  this.stopExpirationCheck();
944
1021
  let currentConnectionRequest = connectionRequest;
945
- this.expirationInterval = setInterval(() => __async(this, null, function* () {
1022
+ __privateSet(this, _expirationInterval, setInterval(() => __async(this, null, function* () {
946
1023
  const { sessionRequest } = currentConnectionRequest;
947
1024
  const now = Date.now();
948
1025
  const remainingMs = sessionRequest.expiresAt - now;
949
1026
  const remainingSeconds = Math.floor(remainingMs / 1e3);
950
- if (remainingMs > 0 && shouldLogCountdown(remainingSeconds) && this.lastLoggedCountdown !== remainingSeconds) {
1027
+ if (remainingMs > 0 && shouldLogCountdown(remainingSeconds) && __privateGet(this, _lastLoggedCountdown) !== remainingSeconds) {
951
1028
  const formattedTime = formatRemainingTime(remainingMs);
952
1029
  logger3(
953
1030
  `[UI: InstallModal-nodejs()] QR code expires in: ${formattedTime} (${remainingSeconds}s)`
954
1031
  );
955
- this.lastLoggedCountdown = remainingSeconds;
1032
+ __privateSet(this, _lastLoggedCountdown, remainingSeconds);
956
1033
  }
957
1034
  if (now >= sessionRequest.expiresAt) {
958
1035
  this.stopExpirationCheck();
@@ -964,7 +1041,7 @@ var init_AbstractInstallModal = __esm({
964
1041
  const generateQRCode = yield this.options.generateQRCode(
965
1042
  currentConnectionRequest
966
1043
  );
967
- this.lastLoggedCountdown = -1;
1044
+ __privateSet(this, _lastLoggedCountdown, -1);
968
1045
  this.updateLink(generateQRCode);
969
1046
  this.updateExpiresIn(remainingSeconds);
970
1047
  this.renderQRCode(generateQRCode, currentConnectionRequest);
@@ -974,18 +1051,20 @@ var init_AbstractInstallModal = __esm({
974
1051
  );
975
1052
  }
976
1053
  }
977
- }), 1e3);
1054
+ }), 1e3));
978
1055
  }
979
1056
  stopExpirationCheck() {
980
- if (this.expirationInterval) {
981
- clearInterval(this.expirationInterval);
982
- this.expirationInterval = null;
1057
+ if (__privateGet(this, _expirationInterval)) {
1058
+ clearInterval(__privateGet(this, _expirationInterval));
1059
+ __privateSet(this, _expirationInterval, null);
983
1060
  logger3(
984
1061
  "[UI: InstallModal-nodejs()] \u{1F6D1} Stopped QR code expiration checking"
985
1062
  );
986
1063
  }
987
1064
  }
988
1065
  };
1066
+ _expirationInterval = new WeakMap();
1067
+ _lastLoggedCountdown = new WeakMap();
989
1068
  }
990
1069
  });
991
1070
 
@@ -994,8 +1073,8 @@ var import_qr, logger4, InstallModal;
994
1073
  var init_install = __esm({
995
1074
  "src/ui/modals/node/install.ts"() {
996
1075
  "use strict";
997
- init_domain();
998
1076
  import_qr = __toESM(require("@paulmillr/qr"));
1077
+ init_domain();
999
1078
  init_AbstractInstallModal();
1000
1079
  init_utils3();
1001
1080
  logger4 = createLogger("metamask-sdk:ui");
@@ -1098,7 +1177,7 @@ var node_exports2 = {};
1098
1177
  __export(node_exports2, {
1099
1178
  StoreAdapterNode: () => StoreAdapterNode
1100
1179
  });
1101
- var StoreAdapterNode;
1180
+ var _storage, StoreAdapterNode;
1102
1181
  var init_node2 = __esm({
1103
1182
  "src/store/adapters/node.ts"() {
1104
1183
  "use strict";
@@ -1107,25 +1186,26 @@ var init_node2 = __esm({
1107
1186
  constructor() {
1108
1187
  super(...arguments);
1109
1188
  this.platform = "node";
1110
- this.storage = /* @__PURE__ */ new Map();
1189
+ __privateAdd(this, _storage, /* @__PURE__ */ new Map());
1111
1190
  }
1112
1191
  get(key) {
1113
1192
  return __async(this, null, function* () {
1114
1193
  var _a2;
1115
- return (_a2 = this.storage.get(key)) != null ? _a2 : null;
1194
+ return (_a2 = __privateGet(this, _storage).get(key)) != null ? _a2 : null;
1116
1195
  });
1117
1196
  }
1118
1197
  set(key, value) {
1119
1198
  return __async(this, null, function* () {
1120
- this.storage.set(key, value);
1199
+ __privateGet(this, _storage).set(key, value);
1121
1200
  });
1122
1201
  }
1123
1202
  delete(key) {
1124
1203
  return __async(this, null, function* () {
1125
- this.storage.delete(key);
1204
+ __privateGet(this, _storage).delete(key);
1126
1205
  });
1127
1206
  }
1128
1207
  };
1208
+ _storage = new WeakMap();
1129
1209
  }
1130
1210
  });
1131
1211
 
@@ -1161,6 +1241,7 @@ __export(index_node_exports, {
1161
1241
  isSecure: () => isSecure
1162
1242
  });
1163
1243
  module.exports = __toCommonJS(index_node_exports);
1244
+ init_domain();
1164
1245
 
1165
1246
  // src/multichain/index.ts
1166
1247
  var import_analytics4 = require("@metamask/analytics");
@@ -1197,7 +1278,9 @@ var RpcClient = class {
1197
1278
  }
1198
1279
  /**
1199
1280
  * Routes the request to a configured RPC node.
1200
- * @param options - The invoke method options
1281
+ *
1282
+ * @param options - The invoke method options.
1283
+ * @returns The JSON response from the RPC node.
1201
1284
  */
1202
1285
  request(options) {
1203
1286
  return __async(this, null, function* () {
@@ -1209,7 +1292,13 @@ var RpcClient = class {
1209
1292
  id: getNextRpcId()
1210
1293
  });
1211
1294
  const rpcEndpoint = this.getRpcEndpoint(options.scope);
1212
- const rpcRequest = yield this.fetchWithTimeout(rpcEndpoint, body, "POST", this.getHeaders(rpcEndpoint), 3e4);
1295
+ const rpcRequest = yield this.fetchWithTimeout(
1296
+ rpcEndpoint,
1297
+ body,
1298
+ "POST",
1299
+ this.getHeaders(rpcEndpoint),
1300
+ 3e4
1301
+ );
1213
1302
  const response = yield this.parseResponse(rpcRequest);
1214
1303
  return response;
1215
1304
  });
@@ -1219,7 +1308,9 @@ var RpcClient = class {
1219
1308
  const supportedNetworks = (_c = (_b = (_a2 = this.config) == null ? void 0 : _a2.api) == null ? void 0 : _b.supportedNetworks) != null ? _c : {};
1220
1309
  const rpcEndpoint = supportedNetworks[scope];
1221
1310
  if (!rpcEndpoint) {
1222
- throw new MissingRpcEndpointErr(`No RPC endpoint found for scope ${scope}`);
1311
+ throw new MissingRpcEndpointErr(
1312
+ `No RPC endpoint found for scope ${scope}`
1313
+ );
1223
1314
  }
1224
1315
  return rpcEndpoint;
1225
1316
  }
@@ -1247,7 +1338,7 @@ var RpcClient = class {
1247
1338
  if (error instanceof Error && error.name === "AbortError") {
1248
1339
  throw new RPCReadonlyRequestErr(`Request timeout after ${timeout}ms`);
1249
1340
  }
1250
- throw new RPCReadonlyRequestErr(error instanceof Error ? error.message : "Unknown error");
1341
+ throw new RPCReadonlyRequestErr(error.message);
1251
1342
  }
1252
1343
  });
1253
1344
  }
@@ -1292,10 +1383,12 @@ var RequestRouter = class {
1292
1383
  * The main entry point for invoking an RPC method.
1293
1384
  * This method acts as a router, determining the correct handling strategy
1294
1385
  * for the request and delegating to the appropriate private handler.
1386
+ *
1387
+ * @param options
1295
1388
  */
1296
1389
  invokeMethod(options) {
1297
1390
  return __async(this, null, function* () {
1298
- const method = options.request.method;
1391
+ const { method } = options.request;
1299
1392
  if (RPC_HANDLED_METHODS.has(method)) {
1300
1393
  return this.handleWithRpcNode(options);
1301
1394
  }
@@ -1307,6 +1400,8 @@ var RequestRouter = class {
1307
1400
  }
1308
1401
  /**
1309
1402
  * Forwards the request directly to the wallet via the transport.
1403
+ *
1404
+ * @param options
1310
1405
  */
1311
1406
  handleWithWallet(options) {
1312
1407
  return __async(this, null, function* () {
@@ -1335,7 +1430,10 @@ var RequestRouter = class {
1335
1430
  }
1336
1431
  const response = yield request;
1337
1432
  if (response.error) {
1338
- throw new RPCInvokeMethodErr(`RPC Request failed with code ${response.error.code}: ${response.error.message}`);
1433
+ const { error } = response;
1434
+ throw new RPCInvokeMethodErr(
1435
+ `RPC Request failed with code ${error.code}: ${error.message}`
1436
+ );
1339
1437
  }
1340
1438
  return response.result;
1341
1439
  }));
@@ -1343,6 +1441,8 @@ var RequestRouter = class {
1343
1441
  }
1344
1442
  /**
1345
1443
  * Routes the request to a configured RPC node.
1444
+ *
1445
+ * @param options
1346
1446
  */
1347
1447
  handleWithRpcNode(options) {
1348
1448
  return __async(this, null, function* () {
@@ -1360,10 +1460,14 @@ var RequestRouter = class {
1360
1460
  }
1361
1461
  /**
1362
1462
  * Responds directly from the SDK's session state.
1463
+ *
1464
+ * @param options
1363
1465
  */
1364
1466
  handleWithSdkState(options) {
1365
1467
  return __async(this, null, function* () {
1366
- console.warn(`Method "${options.request.method}" is configured for SDK state handling, but this is not yet implemented. Falling back to wallet passthrough.`);
1468
+ console.warn(
1469
+ `Method "${options.request.method}" is configured for SDK state handling, but this is not yet implemented. Falling back to wallet passthrough.`
1470
+ );
1367
1471
  return this.handleWithWallet(options);
1368
1472
  });
1369
1473
  }
@@ -1383,31 +1487,50 @@ withAnalyticsTracking_fn = function(options, execute) {
1383
1487
  } else {
1384
1488
  yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options);
1385
1489
  }
1490
+ if (error instanceof RPCInvokeMethodErr) {
1491
+ throw error;
1492
+ }
1386
1493
  throw new RPCInvokeMethodErr(error.message);
1387
1494
  }
1388
1495
  });
1389
1496
  };
1390
1497
  trackWalletActionRequested_fn = function(options) {
1391
1498
  return __async(this, null, function* () {
1392
- const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1499
+ const props = yield getWalletActionAnalyticsProperties(
1500
+ this.config,
1501
+ this.config.storage,
1502
+ options
1503
+ );
1393
1504
  import_analytics2.analytics.track("mmconnect_wallet_action_requested", props);
1394
1505
  });
1395
1506
  };
1396
1507
  trackWalletActionSucceeded_fn = function(options) {
1397
1508
  return __async(this, null, function* () {
1398
- const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1509
+ const props = yield getWalletActionAnalyticsProperties(
1510
+ this.config,
1511
+ this.config.storage,
1512
+ options
1513
+ );
1399
1514
  import_analytics2.analytics.track("mmconnect_wallet_action_succeeded", props);
1400
1515
  });
1401
1516
  };
1402
1517
  trackWalletActionFailed_fn = function(options) {
1403
1518
  return __async(this, null, function* () {
1404
- const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1519
+ const props = yield getWalletActionAnalyticsProperties(
1520
+ this.config,
1521
+ this.config.storage,
1522
+ options
1523
+ );
1405
1524
  import_analytics2.analytics.track("mmconnect_wallet_action_failed", props);
1406
1525
  });
1407
1526
  };
1408
1527
  trackWalletActionRejected_fn = function(options) {
1409
1528
  return __async(this, null, function* () {
1410
- const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1529
+ const props = yield getWalletActionAnalyticsProperties(
1530
+ this.config,
1531
+ this.config.storage,
1532
+ options
1533
+ );
1411
1534
  import_analytics2.analytics.track("mmconnect_wallet_action_rejected", props);
1412
1535
  });
1413
1536
  };
@@ -1416,7 +1539,7 @@ trackWalletActionRejected_fn = function(options) {
1416
1539
  var import_multichain_api_client = require("@metamask/multichain-api-client");
1417
1540
  init_utils();
1418
1541
  var DEFAULT_REQUEST_TIMEOUT = 60 * 1e3;
1419
- var _notificationCallbacks, _transport, _defaultRequestOptions, _reqId, _pendingRequests, _handleResponseListener, _handleNotificationListener, _DefaultTransport_instances, notifyCallbacks_fn, isMetamaskProviderEvent_fn, handleResponse_fn, handleNotification_fn, setupMessageListener_fn;
1542
+ var _notificationCallbacks, _transport, _defaultRequestOptions, _pendingRequests, _handleResponseListener, _handleNotificationListener, _DefaultTransport_instances, notifyCallbacks_fn, isMetamaskProviderEvent_fn, handleResponse_fn, handleNotification_fn, setupMessageListener_fn;
1420
1543
  var DefaultTransport = class {
1421
1544
  constructor() {
1422
1545
  __privateAdd(this, _DefaultTransport_instances);
@@ -1425,8 +1548,6 @@ var DefaultTransport = class {
1425
1548
  __privateAdd(this, _defaultRequestOptions, {
1426
1549
  timeout: DEFAULT_REQUEST_TIMEOUT
1427
1550
  });
1428
- // Use timestamp-based ID to avoid conflicts across disconnect/reconnect cycles
1429
- __privateAdd(this, _reqId, Date.now());
1430
1551
  __privateAdd(this, _pendingRequests, /* @__PURE__ */ new Map());
1431
1552
  __privateAdd(this, _handleResponseListener);
1432
1553
  __privateAdd(this, _handleNotificationListener);
@@ -1434,8 +1555,7 @@ var DefaultTransport = class {
1434
1555
  sendEip1193Message(payload, options) {
1435
1556
  return __async(this, null, function* () {
1436
1557
  __privateMethod(this, _DefaultTransport_instances, setupMessageListener_fn).call(this);
1437
- __privateSet(this, _reqId, __privateGet(this, _reqId) + 1);
1438
- const requestId = `${__privateGet(this, _reqId)}`;
1558
+ const requestId = String(getUniqueRequestId());
1439
1559
  const request = __spreadValues({
1440
1560
  jsonrpc: "2.0",
1441
1561
  id: requestId
@@ -1469,7 +1589,7 @@ var DefaultTransport = class {
1469
1589
  }
1470
1590
  connect(options) {
1471
1591
  return __async(this, null, function* () {
1472
- var _a2, _b, _c, _d, _e, _f, _g;
1592
+ var _a2, _b, _c, _d, _e;
1473
1593
  __privateMethod(this, _DefaultTransport_instances, setupMessageListener_fn).call(this);
1474
1594
  yield __privateGet(this, _transport).connect();
1475
1595
  const sessionRequest = yield this.request(
@@ -1480,12 +1600,19 @@ var DefaultTransport = class {
1480
1600
  throw new Error(sessionRequest.error.message);
1481
1601
  }
1482
1602
  let walletSession = sessionRequest.result;
1603
+ const createSessionParams = {
1604
+ optionalScopes: addValidAccounts(
1605
+ getOptionalScopes((_a2 = options == null ? void 0 : options.scopes) != null ? _a2 : []),
1606
+ getValidAccounts((_b = options == null ? void 0 : options.caipAccountIds) != null ? _b : [])
1607
+ ),
1608
+ sessionProperties: options == null ? void 0 : options.sessionProperties
1609
+ };
1483
1610
  if (walletSession && options && !options.forceRequest) {
1484
1611
  const currentScopes = Object.keys(
1485
- (_a2 = walletSession == null ? void 0 : walletSession.sessionScopes) != null ? _a2 : {}
1612
+ (_c = walletSession == null ? void 0 : walletSession.sessionScopes) != null ? _c : {}
1486
1613
  );
1487
- const proposedScopes = (_b = options == null ? void 0 : options.scopes) != null ? _b : [];
1488
- const proposedCaipAccountIds = (_c = options == null ? void 0 : options.caipAccountIds) != null ? _c : [];
1614
+ const proposedScopes = (_d = options == null ? void 0 : options.scopes) != null ? _d : [];
1615
+ const proposedCaipAccountIds = (_e = options == null ? void 0 : options.caipAccountIds) != null ? _e : [];
1489
1616
  const hasSameScopesAndAccounts = isSameScopesAndAccounts(
1490
1617
  currentScopes,
1491
1618
  proposedScopes,
@@ -1493,17 +1620,6 @@ var DefaultTransport = class {
1493
1620
  proposedCaipAccountIds
1494
1621
  );
1495
1622
  if (!hasSameScopesAndAccounts) {
1496
- yield this.request(
1497
- { method: "wallet_revokeSession", params: walletSession },
1498
- __privateGet(this, _defaultRequestOptions)
1499
- );
1500
- const optionalScopes = addValidAccounts(
1501
- getOptionalScopes((_d = options == null ? void 0 : options.scopes) != null ? _d : []),
1502
- getValidAccounts((_e = options == null ? void 0 : options.caipAccountIds) != null ? _e : [])
1503
- );
1504
- const createSessionParams = {
1505
- optionalScopes
1506
- };
1507
1623
  const response = yield this.request(
1508
1624
  { method: "wallet_createSession", params: createSessionParams },
1509
1625
  __privateGet(this, _defaultRequestOptions)
@@ -1514,14 +1630,6 @@ var DefaultTransport = class {
1514
1630
  walletSession = response.result;
1515
1631
  }
1516
1632
  } else if (!walletSession || (options == null ? void 0 : options.forceRequest)) {
1517
- const optionalScopes = addValidAccounts(
1518
- getOptionalScopes((_f = options == null ? void 0 : options.scopes) != null ? _f : []),
1519
- getValidAccounts((_g = options == null ? void 0 : options.caipAccountIds) != null ? _g : [])
1520
- );
1521
- const createSessionParams = {
1522
- optionalScopes,
1523
- sessionProperties: options == null ? void 0 : options.sessionProperties
1524
- };
1525
1633
  const response = yield this.request(
1526
1634
  { method: "wallet_createSession", params: createSessionParams },
1527
1635
  __privateGet(this, _defaultRequestOptions)
@@ -1538,9 +1646,14 @@ var DefaultTransport = class {
1538
1646
  });
1539
1647
  }
1540
1648
  disconnect() {
1541
- return __async(this, null, function* () {
1649
+ return __async(this, arguments, function* (scopes = []) {
1650
+ yield this.request({ method: "wallet_revokeSession", params: { scopes } });
1651
+ const response = yield this.request({ method: "wallet_getSession" });
1652
+ const { sessionScopes } = response.result;
1653
+ if (Object.keys(sessionScopes).length > 0) {
1654
+ return;
1655
+ }
1542
1656
  __privateGet(this, _notificationCallbacks).clear();
1543
- yield this.request({ method: "wallet_revokeSession", params: {} });
1544
1657
  if (__privateGet(this, _handleResponseListener)) {
1545
1658
  window.removeEventListener("message", __privateGet(this, _handleResponseListener));
1546
1659
  __privateSet(this, _handleResponseListener, void 0);
@@ -1554,7 +1667,7 @@ var DefaultTransport = class {
1554
1667
  request.reject(new Error("Transport disconnected"));
1555
1668
  }
1556
1669
  __privateGet(this, _pendingRequests).clear();
1557
- return __privateGet(this, _transport).disconnect();
1670
+ yield __privateGet(this, _transport).disconnect();
1558
1671
  });
1559
1672
  }
1560
1673
  isConnected() {
@@ -1573,13 +1686,23 @@ var DefaultTransport = class {
1573
1686
  };
1574
1687
  }
1575
1688
  getActiveSession() {
1576
- throw new Error("getActiveSession is purposely not implemented for the DefaultTransport");
1689
+ return __async(this, null, function* () {
1690
+ throw new Error(
1691
+ "getActiveSession is purposely not implemented for the DefaultTransport"
1692
+ );
1693
+ });
1694
+ }
1695
+ getStoredPendingSessionRequest() {
1696
+ return __async(this, null, function* () {
1697
+ throw new Error(
1698
+ "getStoredPendingSessionRequest is purposely not implemented for the DefaultTransport"
1699
+ );
1700
+ });
1577
1701
  }
1578
1702
  };
1579
1703
  _notificationCallbacks = new WeakMap();
1580
1704
  _transport = new WeakMap();
1581
1705
  _defaultRequestOptions = new WeakMap();
1582
- _reqId = new WeakMap();
1583
1706
  _pendingRequests = new WeakMap();
1584
1707
  _handleResponseListener = new WeakMap();
1585
1708
  _handleNotificationListener = new WeakMap();
@@ -1647,9 +1770,170 @@ setupMessageListener_fn = function() {
1647
1770
  window.addEventListener("message", __privateGet(this, _handleNotificationListener));
1648
1771
  };
1649
1772
 
1773
+ // src/multichain/transports/multichainApiClientWrapper/index.ts
1774
+ var import_rpc_errors = require("@metamask/rpc-errors");
1775
+ init_utils();
1776
+ var _notificationCallbacks2, _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn, walletGetSession_fn, walletRevokeSession_fn, walletInvokeMethod_fn;
1777
+ var MultichainApiClientWrapperTransport = class {
1778
+ constructor(metamaskConnectMultichain) {
1779
+ this.metamaskConnectMultichain = metamaskConnectMultichain;
1780
+ __privateAdd(this, _MultichainApiClientWrapperTransport_instances);
1781
+ __privateAdd(this, _notificationCallbacks2, /* @__PURE__ */ new Set());
1782
+ }
1783
+ isTransportDefined() {
1784
+ try {
1785
+ return Boolean(this.metamaskConnectMultichain.transport);
1786
+ } catch (_error) {
1787
+ return false;
1788
+ }
1789
+ }
1790
+ clearNotificationCallbacks() {
1791
+ __privateGet(this, _notificationCallbacks2).clear();
1792
+ }
1793
+ notifyCallbacks(data) {
1794
+ __privateGet(this, _notificationCallbacks2).forEach((callback) => {
1795
+ callback(data);
1796
+ });
1797
+ }
1798
+ clearTransportNotificationListener() {
1799
+ var _a2;
1800
+ (_a2 = this.notificationListener) == null ? void 0 : _a2.call(this);
1801
+ this.notificationListener = void 0;
1802
+ }
1803
+ setupTransportNotificationListener() {
1804
+ if (!this.isTransportDefined() || this.notificationListener) {
1805
+ return;
1806
+ }
1807
+ this.notificationListener = this.metamaskConnectMultichain.transport.onNotification(
1808
+ this.notifyCallbacks.bind(this)
1809
+ );
1810
+ }
1811
+ connect() {
1812
+ return __async(this, null, function* () {
1813
+ console.log("\u{1F4DA} connect");
1814
+ yield this.metamaskConnectMultichain.emitSessionChanged();
1815
+ });
1816
+ }
1817
+ disconnect() {
1818
+ return __async(this, null, function* () {
1819
+ return Promise.resolve();
1820
+ });
1821
+ }
1822
+ isConnected() {
1823
+ return true;
1824
+ }
1825
+ request(_0) {
1826
+ return __async(this, arguments, function* (params, _options = {}) {
1827
+ const id = getUniqueRequestId();
1828
+ const requestPayload = __spreadValues({
1829
+ id,
1830
+ jsonrpc: "2.0"
1831
+ }, params);
1832
+ switch (requestPayload.method) {
1833
+ case "wallet_createSession":
1834
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn).call(this, requestPayload);
1835
+ case "wallet_getSession":
1836
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletGetSession_fn).call(this, requestPayload);
1837
+ case "wallet_revokeSession":
1838
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletRevokeSession_fn).call(this, requestPayload);
1839
+ case "wallet_invokeMethod":
1840
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletInvokeMethod_fn).call(this, requestPayload);
1841
+ default:
1842
+ throw new Error(`Unsupported method: ${requestPayload.method}`);
1843
+ }
1844
+ throw new Error(`Unknown method: ${requestPayload.method}`);
1845
+ });
1846
+ }
1847
+ onNotification(callback) {
1848
+ this.setupTransportNotificationListener();
1849
+ __privateGet(this, _notificationCallbacks2).add(callback);
1850
+ return () => {
1851
+ __privateGet(this, _notificationCallbacks2).delete(callback);
1852
+ };
1853
+ }
1854
+ };
1855
+ _notificationCallbacks2 = new WeakMap();
1856
+ _MultichainApiClientWrapperTransport_instances = new WeakSet();
1857
+ walletCreateSession_fn = function(request) {
1858
+ return __async(this, null, function* () {
1859
+ console.log("\u{1F4DA} #walletCreateSession", request);
1860
+ const createSessionParams = request.params;
1861
+ const scopes = Object.keys(__spreadValues(__spreadValues({}, createSessionParams.optionalScopes), createSessionParams.requiredScopes));
1862
+ const scopeAccounts = [];
1863
+ scopes.forEach((scope) => {
1864
+ var _a2, _b, _c, _d;
1865
+ const requiredScope = (_a2 = createSessionParams.requiredScopes) == null ? void 0 : _a2[scope];
1866
+ const optionalScope = (_b = createSessionParams.optionalScopes) == null ? void 0 : _b[scope];
1867
+ if (requiredScope) {
1868
+ scopeAccounts.push(...(_c = requiredScope.accounts) != null ? _c : []);
1869
+ }
1870
+ if (optionalScope) {
1871
+ scopeAccounts.push(...(_d = optionalScope.accounts) != null ? _d : []);
1872
+ }
1873
+ });
1874
+ const accounts = [...new Set(scopeAccounts)];
1875
+ console.log("\u{1F4DA} SDK connect");
1876
+ yield this.metamaskConnectMultichain.connect(
1877
+ scopes,
1878
+ accounts,
1879
+ createSessionParams.sessionProperties
1880
+ );
1881
+ console.log("\u{1F4DA} SDK connected");
1882
+ return this.metamaskConnectMultichain.transport.request({
1883
+ method: "wallet_getSession"
1884
+ });
1885
+ });
1886
+ };
1887
+ walletGetSession_fn = function(request) {
1888
+ return __async(this, null, function* () {
1889
+ if (!this.isTransportDefined()) {
1890
+ return {
1891
+ jsonrpc: "2.0",
1892
+ id: request.id,
1893
+ result: {
1894
+ sessionScopes: {}
1895
+ }
1896
+ };
1897
+ }
1898
+ return this.metamaskConnectMultichain.transport.request({
1899
+ method: "wallet_getSession"
1900
+ });
1901
+ });
1902
+ };
1903
+ walletRevokeSession_fn = function(request) {
1904
+ return __async(this, null, function* () {
1905
+ var _a2;
1906
+ if (!this.isTransportDefined()) {
1907
+ return { jsonrpc: "2.0", id: request.id, result: true };
1908
+ }
1909
+ const revokeSessionParams = request.params;
1910
+ const scopes = (_a2 = revokeSessionParams == null ? void 0 : revokeSessionParams.scopes) != null ? _a2 : [];
1911
+ try {
1912
+ yield this.metamaskConnectMultichain.disconnect(scopes);
1913
+ return { jsonrpc: "2.0", id: request.id, result: true };
1914
+ } catch (_error) {
1915
+ return { jsonrpc: "2.0", id: request.id, result: false };
1916
+ }
1917
+ });
1918
+ };
1919
+ walletInvokeMethod_fn = function(request) {
1920
+ return __async(this, null, function* () {
1921
+ if (!this.isTransportDefined()) {
1922
+ return { error: import_rpc_errors.providerErrors.unauthorized() };
1923
+ }
1924
+ const result = this.metamaskConnectMultichain.invokeMethod(
1925
+ request.params
1926
+ );
1927
+ return {
1928
+ result
1929
+ };
1930
+ });
1931
+ };
1932
+
1650
1933
  // src/multichain/transports/mwp/index.ts
1651
1934
  var import_mobile_wallet_protocol_core = require("@metamask/mobile-wallet-protocol-core");
1652
1935
  var import_multichain_api_client2 = require("@metamask/multichain-api-client");
1936
+ var import_rpc_errors2 = require("@metamask/rpc-errors");
1653
1937
  init_domain();
1654
1938
  init_utils();
1655
1939
 
@@ -1664,6 +1948,7 @@ var DEFAULT_RESUME_TIMEOUT = 10 * 1e3;
1664
1948
  var SESSION_STORE_KEY = "cache_wallet_getSession";
1665
1949
  var ACCOUNTS_STORE_KEY = "cache_eth_accounts";
1666
1950
  var CHAIN_STORE_KEY = "cache_eth_chainId";
1951
+ var PENDING_SESSION_REQUEST_KEY = "pending_session_request";
1667
1952
  var CACHED_METHOD_LIST = [
1668
1953
  "wallet_getSession",
1669
1954
  "wallet_createSession",
@@ -1683,10 +1968,15 @@ var MWPTransport = class {
1683
1968
  this.dappClient = dappClient;
1684
1969
  this.kvstore = kvstore;
1685
1970
  this.options = options;
1686
- this.__reqId = 0;
1687
1971
  this.__pendingRequests = /* @__PURE__ */ new Map();
1688
1972
  this.notificationCallbacks = /* @__PURE__ */ new Set();
1689
1973
  this.dappClient.on("message", this.handleMessage.bind(this));
1974
+ this.dappClient.on("session_request", (sessionRequest) => {
1975
+ this.currentSessionRequest = sessionRequest;
1976
+ this.kvstore.set(PENDING_SESSION_REQUEST_KEY, JSON.stringify(sessionRequest)).catch((err) => {
1977
+ logger("Failed to store pending session request", err);
1978
+ });
1979
+ });
1690
1980
  if (typeof window !== "undefined" && typeof window.addEventListener !== "undefined") {
1691
1981
  this.windowFocusHandler = this.onWindowFocus.bind(this);
1692
1982
  window.addEventListener("focus", this.windowFocusHandler);
@@ -1701,6 +1991,34 @@ var MWPTransport = class {
1701
1991
  get sessionRequest() {
1702
1992
  return this.currentSessionRequest;
1703
1993
  }
1994
+ /**
1995
+ * Returns the stored pending session request from the dappClient session_request event, if any.
1996
+ *
1997
+ * @returns The stored SessionRequest, or null if none or invalid.
1998
+ */
1999
+ getStoredPendingSessionRequest() {
2000
+ return __async(this, null, function* () {
2001
+ try {
2002
+ const raw = yield this.kvstore.get(PENDING_SESSION_REQUEST_KEY);
2003
+ if (!raw) {
2004
+ return null;
2005
+ }
2006
+ return JSON.parse(raw);
2007
+ } catch (e) {
2008
+ return null;
2009
+ }
2010
+ });
2011
+ }
2012
+ /**
2013
+ * Removes the stored pending session request from the KVStore.
2014
+ * This is necessary to ensure that ConnectMultichain is able to correctly
2015
+ * infer the MWP Transport connection attempt status.
2016
+ */
2017
+ removeStoredPendingSessionRequest() {
2018
+ return __async(this, null, function* () {
2019
+ yield this.kvstore.delete(PENDING_SESSION_REQUEST_KEY);
2020
+ });
2021
+ }
1704
2022
  onWindowFocus() {
1705
2023
  if (!this.isConnected()) {
1706
2024
  this.dappClient.reconnect();
@@ -1717,6 +2035,17 @@ var MWPTransport = class {
1717
2035
  request.reject(error);
1718
2036
  }
1719
2037
  }
2038
+ parseWalletError(errorPayload) {
2039
+ const errorData = errorPayload;
2040
+ if (typeof errorData.code === "number" && typeof errorData.message === "string") {
2041
+ return import_rpc_errors2.providerErrors.custom({
2042
+ code: errorData.code,
2043
+ message: errorData.message
2044
+ });
2045
+ }
2046
+ const message = errorPayload instanceof Error ? errorPayload.message : JSON.stringify(errorPayload);
2047
+ return import_rpc_errors2.rpcErrors.internal({ message });
2048
+ }
1720
2049
  handleMessage(message) {
1721
2050
  if (typeof message === "object" && message !== null) {
1722
2051
  if ("data" in message) {
@@ -1724,6 +2053,12 @@ var MWPTransport = class {
1724
2053
  if ("id" in messagePayload && typeof messagePayload.id === "string") {
1725
2054
  const request = this.pendingRequests.get(messagePayload.id);
1726
2055
  if (request) {
2056
+ clearTimeout(request.timeout);
2057
+ if ("error" in messagePayload && messagePayload.error) {
2058
+ this.pendingRequests.delete(messagePayload.id);
2059
+ request.reject(this.parseWalletError(messagePayload.error));
2060
+ return;
2061
+ }
1727
2062
  const requestWithName = __spreadProps(__spreadValues({}, messagePayload), {
1728
2063
  method: request.method === "wallet_getSession" || request.method === "wallet_createSession" ? "wallet_sessionChanged" : request.method
1729
2064
  });
@@ -1731,7 +2066,6 @@ var MWPTransport = class {
1731
2066
  method: request.method === "wallet_getSession" || request.method === "wallet_createSession" ? "wallet_sessionChanged" : request.method,
1732
2067
  params: requestWithName.result
1733
2068
  });
1734
- clearTimeout(request.timeout);
1735
2069
  this.notifyCallbacks(notification);
1736
2070
  request.resolve(requestWithName);
1737
2071
  this.pendingRequests.delete(messagePayload.id);
@@ -1821,6 +2155,7 @@ var MWPTransport = class {
1821
2155
  }
1822
2156
  walletSession = response.result;
1823
2157
  }
2158
+ yield this.removeStoredPendingSessionRequest();
1824
2159
  this.notifyCallbacks({
1825
2160
  method: "wallet_sessionChanged",
1826
2161
  params: walletSession
@@ -1836,7 +2171,7 @@ var MWPTransport = class {
1836
2171
  return __async(this, null, function* () {
1837
2172
  const request = __spreadValues({
1838
2173
  jsonrpc: "2.0",
1839
- id: `${this.__reqId++}`
2174
+ id: String(getUniqueRequestId())
1840
2175
  }, payload);
1841
2176
  const cachedWalletSession = yield this.getCachedResponse(request);
1842
2177
  if (cachedWalletSession) {
@@ -1872,6 +2207,7 @@ var MWPTransport = class {
1872
2207
  if (session) {
1873
2208
  logger("active session found", session);
1874
2209
  }
2210
+ const storedSessionRequestBeforeConnectionAttempt = yield this.getStoredPendingSessionRequest();
1875
2211
  let timeout;
1876
2212
  let initialConnectionMessageHandler;
1877
2213
  const connectionPromise = new Promise((resolve, reject) => __async(this, null, function* () {
@@ -1902,33 +2238,35 @@ var MWPTransport = class {
1902
2238
  };
1903
2239
  const request = {
1904
2240
  jsonrpc: "2.0",
1905
- id: `${this.__reqId++}`,
2241
+ id: String(getUniqueRequestId()),
1906
2242
  method: "wallet_createSession",
1907
2243
  params: sessionRequest
1908
2244
  };
1909
2245
  initialConnectionMessageHandler = (message) => __async(this, null, function* () {
1910
- if (typeof message === "object" && message !== null) {
1911
- if ("data" in message) {
1912
- const messagePayload = message.data;
1913
- if (messagePayload.method === "wallet_createSession" || messagePayload.method === "wallet_sessionChanged") {
1914
- if (messagePayload.error) {
1915
- if (initialConnectionMessageHandler) {
1916
- this.dappClient.off(
1917
- "message",
1918
- initialConnectionMessageHandler
1919
- );
1920
- }
1921
- return rejectConnection(messagePayload.error);
1922
- }
1923
- yield this.storeWalletSession(
1924
- request,
1925
- messagePayload
1926
- );
1927
- this.notifyCallbacks(messagePayload);
1928
- return resolveConnection();
1929
- }
1930
- }
2246
+ if (typeof message !== "object" || message === null) {
2247
+ return;
2248
+ }
2249
+ if (!("data" in message)) {
2250
+ return;
2251
+ }
2252
+ const messagePayload = message.data;
2253
+ const isMatchingId = messagePayload.id === request.id;
2254
+ const isMatchingMethod = messagePayload.method === "wallet_createSession" || messagePayload.method === "wallet_sessionChanged";
2255
+ if (!isMatchingId && !isMatchingMethod) {
2256
+ return;
1931
2257
  }
2258
+ if (messagePayload.error) {
2259
+ return rejectConnection(
2260
+ this.parseWalletError(messagePayload.error)
2261
+ );
2262
+ }
2263
+ yield this.storeWalletSession(
2264
+ request,
2265
+ messagePayload
2266
+ );
2267
+ yield this.removeStoredPendingSessionRequest();
2268
+ this.notifyCallbacks(messagePayload);
2269
+ return resolveConnection();
1932
2270
  });
1933
2271
  this.dappClient.on("message", initialConnectionMessageHandler);
1934
2272
  dappClient.connect({
@@ -1949,14 +2287,18 @@ var MWPTransport = class {
1949
2287
  }
1950
2288
  );
1951
2289
  }
1952
- timeout = setTimeout(() => {
1953
- reject(new import_multichain_api_client2.TransportTimeoutError());
1954
- }, this.options.connectionTimeout);
2290
+ timeout = setTimeout(
2291
+ () => {
2292
+ reject(new import_multichain_api_client2.TransportTimeoutError());
2293
+ },
2294
+ storedSessionRequestBeforeConnectionAttempt ? this.options.resumeTimeout : this.options.connectionTimeout
2295
+ );
1955
2296
  connection.then(resolve).catch(reject);
1956
2297
  }));
1957
- return connectionPromise.catch((error) => {
2298
+ return connectionPromise.catch((error) => __async(this, null, function* () {
2299
+ yield this.dappClient.disconnect();
1958
2300
  throw error;
1959
- }).finally(() => {
2301
+ })).finally(() => {
1960
2302
  if (timeout) {
1961
2303
  clearTimeout(timeout);
1962
2304
  }
@@ -1964,24 +2306,68 @@ var MWPTransport = class {
1964
2306
  this.dappClient.off("message", initialConnectionMessageHandler);
1965
2307
  initialConnectionMessageHandler = void 0;
1966
2308
  }
2309
+ this.removeStoredPendingSessionRequest();
1967
2310
  });
1968
2311
  });
1969
2312
  }
1970
2313
  /**
1971
2314
  * Disconnects from the Mobile Wallet Protocol
1972
2315
  *
2316
+ * @param [scopes] - The scopes to revoke. If not provided or empty, all scopes will be revoked.
1973
2317
  * @returns Nothing
1974
2318
  */
1975
2319
  disconnect() {
1976
- return __async(this, null, function* () {
1977
- if (typeof window !== "undefined" && typeof window.removeEventListener !== "undefined" && this.windowFocusHandler) {
1978
- window.removeEventListener("focus", this.windowFocusHandler);
1979
- this.windowFocusHandler = void 0;
1980
- }
1981
- this.kvstore.delete(SESSION_STORE_KEY);
1982
- this.kvstore.delete(ACCOUNTS_STORE_KEY);
1983
- this.kvstore.delete(CHAIN_STORE_KEY);
1984
- return this.dappClient.disconnect();
2320
+ return __async(this, arguments, function* (scopes = []) {
2321
+ var _a2, _b;
2322
+ const cachedSession = yield this.getCachedResponse({
2323
+ jsonrpc: "2.0",
2324
+ id: "0",
2325
+ method: "wallet_getSession"
2326
+ });
2327
+ const cachedSessionScopes = (_b = (_a2 = cachedSession == null ? void 0 : cachedSession.result) == null ? void 0 : _a2.sessionScopes) != null ? _b : {};
2328
+ const remainingScopes = scopes.length === 0 ? [] : Object.keys(cachedSessionScopes).filter(
2329
+ (scope) => !scopes.includes(scope)
2330
+ );
2331
+ const newSessionScopes = Object.fromEntries(
2332
+ Object.entries(cachedSessionScopes).filter(
2333
+ ([key]) => remainingScopes.includes(key)
2334
+ )
2335
+ );
2336
+ this.request({ method: "wallet_revokeSession", params: { scopes } }).catch(
2337
+ (err) => {
2338
+ console.error("error revoking session", err);
2339
+ }
2340
+ );
2341
+ const remainingScopesIncludeEip155 = remainingScopes.some(
2342
+ (scope) => scope.includes("eip155")
2343
+ );
2344
+ if (!remainingScopesIncludeEip155) {
2345
+ this.kvstore.delete(ACCOUNTS_STORE_KEY);
2346
+ this.kvstore.delete(CHAIN_STORE_KEY);
2347
+ }
2348
+ if (remainingScopes.length > 0) {
2349
+ this.kvstore.set(
2350
+ SESSION_STORE_KEY,
2351
+ JSON.stringify({
2352
+ result: {
2353
+ sessionScopes: newSessionScopes
2354
+ }
2355
+ })
2356
+ );
2357
+ } else {
2358
+ this.kvstore.delete(SESSION_STORE_KEY);
2359
+ if (typeof window !== "undefined" && typeof window.removeEventListener !== "undefined" && this.windowFocusHandler) {
2360
+ window.removeEventListener("focus", this.windowFocusHandler);
2361
+ this.windowFocusHandler = void 0;
2362
+ }
2363
+ yield this.dappClient.disconnect();
2364
+ }
2365
+ this.notifyCallbacks({
2366
+ method: "wallet_sessionChanged",
2367
+ params: {
2368
+ sessionScopes: newSessionScopes
2369
+ }
2370
+ });
1985
2371
  });
1986
2372
  }
1987
2373
  /**
@@ -2087,7 +2473,7 @@ var MWPTransport = class {
2087
2473
  return __async(this, null, function* () {
2088
2474
  const request = __spreadValues({
2089
2475
  jsonrpc: "2.0",
2090
- id: `${this.__reqId++}`
2476
+ id: String(getUniqueRequestId())
2091
2477
  }, payload);
2092
2478
  const cachedWalletSession = yield this.getCachedResponse(request);
2093
2479
  if (cachedWalletSession) {
@@ -2169,6 +2555,7 @@ var MWPTransport = class {
2169
2555
  const timeoutPromise = new Promise((_resolve, reject) => {
2170
2556
  setTimeout(() => {
2171
2557
  unsubscribe();
2558
+ this.removeStoredPendingSessionRequest();
2172
2559
  reject(new import_multichain_api_client2.TransportTimeoutError());
2173
2560
  }, this.options.resumeTimeout);
2174
2561
  });
@@ -2206,166 +2593,9 @@ var keymanager = new KeyManager();
2206
2593
 
2207
2594
  // src/multichain/index.ts
2208
2595
  init_utils();
2209
-
2210
- // src/multichain/transports/multichainApiClientWrapper/index.ts
2211
- var import_rpc_errors = require("@metamask/rpc-errors");
2212
- var MAX = 4294967295;
2213
- var idCounter = Math.floor(Math.random() * MAX);
2214
- var getUniqueId = () => {
2215
- idCounter = (idCounter + 1) % MAX;
2216
- return idCounter;
2217
- };
2218
- var _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn, walletGetSession_fn, walletRevokeSession_fn, walletInvokeMethod_fn;
2219
- var MultichainApiClientWrapperTransport = class {
2220
- constructor(metamaskConnectMultichain) {
2221
- this.metamaskConnectMultichain = metamaskConnectMultichain;
2222
- __privateAdd(this, _MultichainApiClientWrapperTransport_instances);
2223
- this.requestId = getUniqueId();
2224
- this.notificationCallbacks = /* @__PURE__ */ new Set();
2225
- }
2226
- isTransportDefined() {
2227
- try {
2228
- return Boolean(this.metamaskConnectMultichain.transport);
2229
- } catch (error) {
2230
- return false;
2231
- }
2232
- }
2233
- clearNotificationCallbacks() {
2234
- this.notificationCallbacks.clear();
2235
- }
2236
- notifyCallbacks(data) {
2237
- this.notificationCallbacks.forEach((callback) => {
2238
- callback(data);
2239
- });
2240
- }
2241
- setupNotifcationListener() {
2242
- this.metamaskConnectMultichain.transport.onNotification(
2243
- this.notifyCallbacks.bind(this)
2244
- );
2245
- }
2246
- connect() {
2247
- return __async(this, null, function* () {
2248
- console.log("\u{1F4DA} connect");
2249
- return Promise.resolve();
2250
- });
2251
- }
2252
- disconnect() {
2253
- return __async(this, null, function* () {
2254
- return Promise.resolve();
2255
- });
2256
- }
2257
- isConnected() {
2258
- return true;
2259
- }
2260
- request(_0) {
2261
- return __async(this, arguments, function* (params, _options = {}) {
2262
- const id = this.requestId++;
2263
- const requestPayload = __spreadValues({
2264
- id,
2265
- jsonrpc: "2.0"
2266
- }, params);
2267
- switch (requestPayload.method) {
2268
- case "wallet_createSession":
2269
- return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn).call(this, requestPayload);
2270
- case "wallet_getSession":
2271
- return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletGetSession_fn).call(this, requestPayload);
2272
- case "wallet_revokeSession":
2273
- return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletRevokeSession_fn).call(this, requestPayload);
2274
- case "wallet_invokeMethod":
2275
- return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletInvokeMethod_fn).call(this, requestPayload);
2276
- default:
2277
- throw new Error(`Unsupported method: ${requestPayload.method}`);
2278
- }
2279
- throw new Error(`Unknown method: ${requestPayload.method}`);
2280
- });
2281
- }
2282
- onNotification(callback) {
2283
- if (!this.isTransportDefined()) {
2284
- this.notificationCallbacks.add(callback);
2285
- return () => {
2286
- this.notificationCallbacks.delete(callback);
2287
- };
2288
- }
2289
- return this.metamaskConnectMultichain.transport.onNotification(callback);
2290
- }
2291
- };
2292
- _MultichainApiClientWrapperTransport_instances = new WeakSet();
2293
- walletCreateSession_fn = function(request) {
2294
- return __async(this, null, function* () {
2295
- console.log("\u{1F4DA} #walletCreateSession", request);
2296
- const createSessionParams = request.params;
2297
- const scopes = Object.keys(__spreadValues(__spreadValues({}, createSessionParams.optionalScopes), createSessionParams.requiredScopes));
2298
- const scopeAccounts = [];
2299
- scopes.forEach((scope) => {
2300
- var _a2, _b, _c, _d;
2301
- const requiredScope = (_a2 = createSessionParams.requiredScopes) == null ? void 0 : _a2[scope];
2302
- const optionalScope = (_b = createSessionParams.optionalScopes) == null ? void 0 : _b[scope];
2303
- if (requiredScope) {
2304
- scopeAccounts.push(...(_c = requiredScope.accounts) != null ? _c : []);
2305
- }
2306
- if (optionalScope) {
2307
- scopeAccounts.push(...(_d = optionalScope.accounts) != null ? _d : []);
2308
- }
2309
- });
2310
- const accounts = [...new Set(scopeAccounts)];
2311
- console.log("\u{1F4DA} SDK connect");
2312
- yield this.metamaskConnectMultichain.connect(
2313
- scopes,
2314
- accounts,
2315
- createSessionParams.sessionProperties
2316
- );
2317
- console.log("\u{1F4DA} SDK connected");
2318
- return this.metamaskConnectMultichain.transport.request({
2319
- method: "wallet_getSession"
2320
- });
2321
- });
2322
- };
2323
- walletGetSession_fn = function(request) {
2324
- return __async(this, null, function* () {
2325
- if (!this.isTransportDefined()) {
2326
- return {
2327
- jsonrpc: "2.0",
2328
- id: request.id,
2329
- result: {
2330
- sessionScopes: {}
2331
- }
2332
- };
2333
- }
2334
- return this.metamaskConnectMultichain.transport.request({
2335
- method: "wallet_getSession"
2336
- });
2337
- });
2338
- };
2339
- walletRevokeSession_fn = function(request) {
2340
- return __async(this, null, function* () {
2341
- if (!this.isTransportDefined()) {
2342
- return { jsonrpc: "2.0", id: request.id, result: true };
2343
- }
2344
- try {
2345
- this.metamaskConnectMultichain.disconnect();
2346
- return { jsonrpc: "2.0", id: request.id, result: true };
2347
- } catch (error) {
2348
- return { jsonrpc: "2.0", id: request.id, result: false };
2349
- }
2350
- });
2351
- };
2352
- walletInvokeMethod_fn = function(request) {
2353
- return __async(this, null, function* () {
2354
- if (!this.isTransportDefined()) {
2355
- return { error: import_rpc_errors.providerErrors.unauthorized() };
2356
- }
2357
- const result = this.metamaskConnectMultichain.invokeMethod(
2358
- request.params
2359
- );
2360
- return {
2361
- result
2362
- };
2363
- });
2364
- };
2365
-
2366
- // src/multichain/index.ts
2367
2596
  var logger2 = createLogger("metamask-sdk:core");
2368
- var _a, _provider, _providerTransportWrapper, _transport2, _dappClient, _beforeUnloadListener, _listener, _sdkInfo, _MetaMaskConnectMultichain_instances, setupAnalytics_fn, onTransportNotification_fn, getStoredTransport_fn, setupTransport_fn, init_fn, createDappClient_fn, setupMWP_fn, onBeforeUnload_fn, createBeforeUnloadListener_fn, renderInstallModalAsync_fn, showInstallModal_fn, headlessConnect_fn, setupDefaultTransport_fn, deeplinkConnect_fn, handleConnection_fn;
2597
+ var SINGLETON_KEY = "__METAMASK_CONNECT_MULTICHAIN_SINGLETON__";
2598
+ var _a, _provider, _providerTransportWrapper, _transport2, _dappClient, _beforeUnloadListener, _listener, _sdkInfo, _MetaMaskConnectMultichain_instances, setupAnalytics_fn, onTransportNotification_fn, getStoredTransport_fn, setupTransport_fn, init_fn, createDappClient_fn, setupMWP_fn, onBeforeUnload_fn, createBeforeUnloadListener_fn, renderInstallModalAsync_fn, showInstallModal_fn, headlessConnect_fn, setupDefaultTransport_fn, deeplinkConnect_fn, handleConnection_fn, getCaipSession_fn, openConnectDeeplinkIfNeeded_fn;
2369
2599
  var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends MultichainCore {
2370
2600
  constructor(options) {
2371
2601
  var _a2, _b, _c, _d, _e, _f;
@@ -2391,8 +2621,12 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2391
2621
  this._status = "pending";
2392
2622
  __privateAdd(this, _listener);
2393
2623
  __privateAdd(this, _sdkInfo, `Sdk/Javascript SdkVersion/${getVersion()} Platform/${getPlatformType()} dApp/${(_a = this.options.dapp.url) != null ? _a : this.options.dapp.name} dAppTitle/${this.options.dapp.name}`);
2394
- __privateSet(this, _providerTransportWrapper, new MultichainApiClientWrapperTransport(this));
2395
- __privateSet(this, _provider, (0, import_multichain_api_client3.getMultichainClient)({ transport: __privateGet(this, _providerTransportWrapper) }));
2624
+ __privateSet(this, _providerTransportWrapper, new MultichainApiClientWrapperTransport(
2625
+ this
2626
+ ));
2627
+ __privateSet(this, _provider, (0, import_multichain_api_client3.getMultichainClient)({
2628
+ transport: __privateGet(this, _providerTransportWrapper)
2629
+ }));
2396
2630
  }
2397
2631
  get status() {
2398
2632
  return this._status;
@@ -2426,27 +2660,54 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2426
2660
  get transportType() {
2427
2661
  return __privateGet(this, _transport2) instanceof MWPTransport ? "mwp" /* MWP */ : "browser" /* Browser */;
2428
2662
  }
2663
+ // Creates a singleton instance of MetaMaskConnectMultichain.
2664
+ // If the singleton already exists, it merges the incoming options with the
2665
+ // existing singleton options for the following keys: `api.supportedNetworks`,
2666
+ // `ui.*`, `mobile.*`, `transport.extensionId`, `debug`. Take note that the
2667
+ // value for `dapp` is not merged as it does not make sense for subsequent calls to
2668
+ // `createMultichainClient` to have a different `dapp` value.
2429
2669
  static create(options) {
2430
2670
  return __async(this, null, function* () {
2431
- var _a2;
2432
- const instance = new _MetaMaskConnectMultichain(options);
2433
- const isEnabled2 = yield isEnabled(
2434
- "metamask-sdk:core",
2435
- instance.options.storage
2436
- );
2437
- if (isEnabled2) {
2438
- enableDebug("metamask-sdk:core");
2671
+ const globalObject = getGlobalObject();
2672
+ const existing = globalObject[SINGLETON_KEY];
2673
+ if (existing) {
2674
+ const instance = yield existing;
2675
+ instance.mergeOptions(options);
2676
+ if (options.debug) {
2677
+ enableDebug("metamask-sdk:*");
2678
+ }
2679
+ return instance;
2439
2680
  }
2440
- yield __privateMethod(_a2 = instance, _MetaMaskConnectMultichain_instances, init_fn).call(_a2);
2441
- return instance;
2681
+ const instancePromise = (() => __async(null, null, function* () {
2682
+ var _a2;
2683
+ const instance = new _MetaMaskConnectMultichain(options);
2684
+ const isEnabled2 = yield isEnabled(
2685
+ "metamask-sdk:core",
2686
+ instance.options.storage
2687
+ );
2688
+ if (isEnabled2) {
2689
+ enableDebug("metamask-sdk:core");
2690
+ }
2691
+ yield __privateMethod(_a2 = instance, _MetaMaskConnectMultichain_instances, init_fn).call(_a2);
2692
+ return instance;
2693
+ }))();
2694
+ globalObject[SINGLETON_KEY] = instancePromise;
2695
+ instancePromise.catch((error) => {
2696
+ globalObject[SINGLETON_KEY] = void 0;
2697
+ console.error("Error initializing MetaMaskConnectMultichain", error);
2698
+ });
2699
+ return instancePromise;
2442
2700
  });
2443
2701
  }
2444
2702
  // TODO: make this into param object
2445
2703
  connect(scopes, caipAccountIds, sessionProperties, forceRequest) {
2446
2704
  return __async(this, null, function* () {
2447
2705
  var _a2;
2448
- if (this.status !== "connected") {
2449
- yield this.disconnect();
2706
+ if (this.status === "connecting" && this.transportType === "mwp" /* MWP */) {
2707
+ yield __privateMethod(this, _MetaMaskConnectMultichain_instances, openConnectDeeplinkIfNeeded_fn).call(this);
2708
+ throw new Error(
2709
+ "Existing connection is pending. Please check your MetaMask Mobile app to continue."
2710
+ );
2450
2711
  }
2451
2712
  const { ui } = this.options;
2452
2713
  const platformType = getPlatformType();
@@ -2476,9 +2737,21 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2476
2737
  } catch (error) {
2477
2738
  logger2("Error tracking connection_initiated event", error);
2478
2739
  }
2479
- const nonEmptySessionProperites = Object.keys(sessionProperties != null ? sessionProperties : {}).length > 0 ? sessionProperties : void 0;
2740
+ const sessionData = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, getCaipSession_fn).call(this);
2741
+ const { mergedScopes, mergedCaipAccountIds, mergedSessionProperties } = mergeRequestedSessionWithExisting(
2742
+ sessionData,
2743
+ scopes,
2744
+ caipAccountIds,
2745
+ sessionProperties
2746
+ );
2747
+ const nonEmptySessionProperties = Object.keys(mergedSessionProperties != null ? mergedSessionProperties : {}).length > 0 ? mergedSessionProperties : void 0;
2480
2748
  if (((_a2 = __privateGet(this, _transport2)) == null ? void 0 : _a2.isConnected()) && !secure) {
2481
- return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, __privateGet(this, _transport2).connect({ scopes, caipAccountIds, sessionProperties: nonEmptySessionProperites, forceRequest }).then(() => __async(this, null, function* () {
2749
+ return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, __privateGet(this, _transport2).connect({
2750
+ scopes: mergedScopes,
2751
+ caipAccountIds: mergedCaipAccountIds,
2752
+ sessionProperties: nonEmptySessionProperties,
2753
+ forceRequest
2754
+ }).then(() => __async(this, null, function* () {
2482
2755
  if (__privateGet(this, _transport2) instanceof MWPTransport) {
2483
2756
  return this.storage.setTransport("mwp" /* MWP */);
2484
2757
  }
@@ -2487,18 +2760,28 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2487
2760
  }
2488
2761
  if (platformType === "in-app-browser" /* MetaMaskMobileWebview */) {
2489
2762
  const defaultTransport = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupDefaultTransport_fn).call(this);
2490
- return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, sessionProperties: nonEmptySessionProperites, forceRequest }), scopes, transportType);
2763
+ return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, defaultTransport.connect({
2764
+ scopes: mergedScopes,
2765
+ caipAccountIds: mergedCaipAccountIds,
2766
+ sessionProperties: nonEmptySessionProperties,
2767
+ forceRequest
2768
+ }), scopes, transportType);
2491
2769
  }
2492
2770
  if (isWeb && hasExtensionInstalled && preferExtension) {
2493
2771
  const defaultTransport = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupDefaultTransport_fn).call(this);
2494
- return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, sessionProperties: nonEmptySessionProperites, forceRequest }), scopes, transportType);
2772
+ return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, defaultTransport.connect({
2773
+ scopes: mergedScopes,
2774
+ caipAccountIds: mergedCaipAccountIds,
2775
+ sessionProperties: nonEmptySessionProperties,
2776
+ forceRequest
2777
+ }), scopes, transportType);
2495
2778
  }
2496
2779
  yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupMWP_fn).call(this);
2497
2780
  const shouldShowInstallModal = hasExtensionInstalled ? showInstallModal : !preferExtension || showInstallModal;
2498
2781
  if (secure && !shouldShowInstallModal) {
2499
- return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, __privateMethod(this, _MetaMaskConnectMultichain_instances, deeplinkConnect_fn).call(this, scopes, caipAccountIds, nonEmptySessionProperites), scopes, transportType);
2782
+ return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, __privateMethod(this, _MetaMaskConnectMultichain_instances, deeplinkConnect_fn).call(this, mergedScopes, mergedCaipAccountIds, nonEmptySessionProperties), scopes, transportType);
2500
2783
  }
2501
- return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, __privateMethod(this, _MetaMaskConnectMultichain_instances, showInstallModal_fn).call(this, shouldShowInstallModal, scopes, caipAccountIds, nonEmptySessionProperites), scopes, transportType);
2784
+ return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, __privateMethod(this, _MetaMaskConnectMultichain_instances, showInstallModal_fn).call(this, shouldShowInstallModal, mergedScopes, mergedCaipAccountIds, nonEmptySessionProperties), scopes, transportType);
2502
2785
  });
2503
2786
  }
2504
2787
  emit(event, args) {
@@ -2507,18 +2790,24 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2507
2790
  super.emit(event, args);
2508
2791
  }
2509
2792
  disconnect() {
2510
- return __async(this, null, function* () {
2793
+ return __async(this, arguments, function* (scopes = []) {
2511
2794
  var _a2, _b, _c;
2512
- yield (_a2 = __privateGet(this, _listener)) == null ? void 0 : _a2.call(this);
2513
- (_b = __privateGet(this, _beforeUnloadListener)) == null ? void 0 : _b.call(this);
2514
- yield (_c = __privateGet(this, _transport2)) == null ? void 0 : _c.disconnect();
2515
- yield this.storage.removeTransport();
2516
- this.emit("stateChanged", "disconnected");
2517
- __privateSet(this, _listener, void 0);
2518
- __privateSet(this, _beforeUnloadListener, void 0);
2519
- __privateSet(this, _transport2, void 0);
2520
- __privateGet(this, _providerTransportWrapper).clearNotificationCallbacks();
2521
- __privateSet(this, _dappClient, void 0);
2795
+ const sessionData = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, getCaipSession_fn).call(this);
2796
+ const remainingScopes = scopes.length === 0 ? [] : Object.keys(sessionData.sessionScopes).filter(
2797
+ (scope) => !scopes.includes(scope)
2798
+ );
2799
+ yield (_a2 = __privateGet(this, _transport2)) == null ? void 0 : _a2.disconnect(scopes);
2800
+ if (remainingScopes.length === 0) {
2801
+ yield (_b = __privateGet(this, _listener)) == null ? void 0 : _b.call(this);
2802
+ (_c = __privateGet(this, _beforeUnloadListener)) == null ? void 0 : _c.call(this);
2803
+ yield this.storage.removeTransport();
2804
+ __privateSet(this, _listener, void 0);
2805
+ __privateSet(this, _beforeUnloadListener, void 0);
2806
+ __privateSet(this, _transport2, void 0);
2807
+ __privateGet(this, _providerTransportWrapper).clearTransportNotificationListener();
2808
+ __privateSet(this, _dappClient, void 0);
2809
+ this.status = "disconnected";
2810
+ }
2522
2811
  });
2523
2812
  }
2524
2813
  invokeMethod(request) {
@@ -2530,7 +2819,7 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2530
2819
  });
2531
2820
  }
2532
2821
  // DRY THIS WITH REQUEST ROUTER
2533
- openDeeplinkIfNeeded() {
2822
+ openSimpleDeeplinkIfNeeded() {
2534
2823
  const { ui, mobile } = this.options;
2535
2824
  const { showInstallModal = false } = ui != null ? ui : {};
2536
2825
  const secure = isSecure();
@@ -2550,6 +2839,23 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2550
2839
  }), 10);
2551
2840
  }
2552
2841
  }
2842
+ // Provides a way for ecosystem clients (EVM, Solana, etc.) to get the current CAIP session data
2843
+ // when instantiating themselves (as they would have already missed any initial sessionChanged events emitted by ConnectMultichain)
2844
+ // without having to concern themselves with the current transport connection status.
2845
+ emitSessionChanged() {
2846
+ return __async(this, null, function* () {
2847
+ var _a2;
2848
+ const emptySession = { sessionScopes: {} };
2849
+ if (this.status !== "connected" && this.status !== "connecting") {
2850
+ this.emit("wallet_sessionChanged", emptySession);
2851
+ return;
2852
+ }
2853
+ const response = yield this.transport.request({
2854
+ method: "wallet_getSession"
2855
+ });
2856
+ this.emit("wallet_sessionChanged", (_a2 = response.result) != null ? _a2 : emptySession);
2857
+ });
2858
+ }
2553
2859
  };
2554
2860
  _provider = new WeakMap();
2555
2861
  _providerTransportWrapper = new WeakMap();
@@ -2599,7 +2905,7 @@ getStoredTransport_fn = function() {
2599
2905
  if (hasExtensionInstalled) {
2600
2906
  const apiTransport = new DefaultTransport();
2601
2907
  __privateSet(this, _transport2, apiTransport);
2602
- __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2908
+ __privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
2603
2909
  __privateSet(this, _listener, apiTransport.onNotification(
2604
2910
  __privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
2605
2911
  ));
@@ -2611,7 +2917,7 @@ getStoredTransport_fn = function() {
2611
2917
  const apiTransport = new MWPTransport(dappClient, kvstore);
2612
2918
  __privateSet(this, _dappClient, dappClient);
2613
2919
  __privateSet(this, _transport2, apiTransport);
2614
- __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2920
+ __privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
2615
2921
  __privateSet(this, _listener, apiTransport.onNotification(
2616
2922
  __privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
2617
2923
  ));
@@ -2643,25 +2949,17 @@ setupTransport_fn = function() {
2643
2949
  };
2644
2950
  init_fn = function() {
2645
2951
  return __async(this, null, function* () {
2646
- var _a2;
2647
2952
  try {
2648
- if (typeof window !== "undefined" && ((_a2 = window.mmsdk) == null ? void 0 : _a2.isInitialized)) {
2649
- logger2("MetaMaskSDK: init already initialized");
2650
- } else {
2651
- yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupAnalytics_fn).call(this);
2652
- yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupTransport_fn).call(this);
2653
- try {
2654
- const baseProps = yield getBaseAnalyticsProperties(
2655
- this.options,
2656
- this.storage
2657
- );
2658
- import_analytics4.analytics.track("mmconnect_initialized", baseProps);
2659
- } catch (error) {
2660
- logger2("Error tracking initialized event", error);
2661
- }
2662
- if (typeof window !== "undefined") {
2663
- window.mmsdk = this;
2664
- }
2953
+ yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupAnalytics_fn).call(this);
2954
+ yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupTransport_fn).call(this);
2955
+ try {
2956
+ const baseProps = yield getBaseAnalyticsProperties(
2957
+ this.options,
2958
+ this.storage
2959
+ );
2960
+ import_analytics4.analytics.track("mmconnect_initialized", baseProps);
2961
+ } catch (error) {
2962
+ logger2("Error tracking initialized event", error);
2665
2963
  }
2666
2964
  } catch (error) {
2667
2965
  yield this.storage.removeTransport();
@@ -2697,7 +2995,7 @@ setupMWP_fn = function() {
2697
2995
  __privateSet(this, _dappClient, dappClient);
2698
2996
  const apiTransport = new MWPTransport(dappClient, kvstore);
2699
2997
  __privateSet(this, _transport2, apiTransport);
2700
- __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2998
+ __privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
2701
2999
  __privateSet(this, _listener, this.transport.onNotification(
2702
3000
  __privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
2703
3001
  ));
@@ -2713,15 +3011,13 @@ onBeforeUnload_fn = function() {
2713
3011
  });
2714
3012
  };
2715
3013
  createBeforeUnloadListener_fn = function() {
3014
+ const handler = __privateMethod(this, _MetaMaskConnectMultichain_instances, onBeforeUnload_fn).bind(this);
2716
3015
  if (typeof window !== "undefined" && typeof window.addEventListener !== "undefined") {
2717
- window.addEventListener("beforeunload", __privateMethod(this, _MetaMaskConnectMultichain_instances, onBeforeUnload_fn).bind(this));
3016
+ window.addEventListener("beforeunload", handler);
2718
3017
  }
2719
3018
  return () => {
2720
3019
  if (typeof window !== "undefined" && typeof window.removeEventListener !== "undefined") {
2721
- window.removeEventListener(
2722
- "beforeunload",
2723
- __privateMethod(this, _MetaMaskConnectMultichain_instances, onBeforeUnload_fn).bind(this)
2724
- );
3020
+ window.removeEventListener("beforeunload", handler);
2725
3021
  }
2726
3022
  };
2727
3023
  };
@@ -2753,7 +3049,11 @@ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds,
2753
3049
  (() => __async(this, null, function* () {
2754
3050
  var _a2;
2755
3051
  try {
2756
- yield this.transport.connect({ scopes, caipAccountIds, sessionProperties });
3052
+ yield this.transport.connect({
3053
+ scopes,
3054
+ caipAccountIds,
3055
+ sessionProperties
3056
+ });
2757
3057
  yield this.options.ui.factory.unload();
2758
3058
  (_a2 = this.options.ui.factory.modal) == null ? void 0 : _a2.unmount();
2759
3059
  this.status = "connected";
@@ -2762,13 +3062,14 @@ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds,
2762
3062
  if (error instanceof import_mobile_wallet_protocol_core2.ProtocolError) {
2763
3063
  if (error.code !== import_mobile_wallet_protocol_core2.ErrorCode.REQUEST_EXPIRED) {
2764
3064
  this.status = "disconnected";
3065
+ yield this.options.ui.factory.unload(error);
2765
3066
  reject(error);
2766
3067
  }
2767
3068
  } else {
2768
3069
  this.status = "disconnected";
2769
- reject(
2770
- error instanceof Error ? error : new Error(String(error))
2771
- );
3070
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
3071
+ yield this.options.ui.factory.unload(normalizedError);
3072
+ reject(normalizedError);
2772
3073
  }
2773
3074
  }
2774
3075
  }))().catch(() => {
@@ -2855,13 +3156,13 @@ setupDefaultTransport_fn = function() {
2855
3156
  __privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
2856
3157
  ));
2857
3158
  __privateSet(this, _transport2, transport);
2858
- __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
3159
+ __privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
2859
3160
  return transport;
2860
3161
  });
2861
3162
  };
2862
3163
  deeplinkConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
2863
3164
  return __async(this, null, function* () {
2864
- return new Promise((resolve, reject) => {
3165
+ return new Promise((resolve, reject) => __async(this, null, function* () {
2865
3166
  const dappClientMessageHandler = (payload) => {
2866
3167
  var _a2;
2867
3168
  if (typeof payload !== "object" || payload === null || !("data" in payload)) {
@@ -2882,7 +3183,7 @@ deeplinkConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
2882
3183
  let timeout;
2883
3184
  if (this.transport.isConnected()) {
2884
3185
  timeout = setTimeout(() => {
2885
- this.openDeeplinkIfNeeded();
3186
+ this.openSimpleDeeplinkIfNeeded();
2886
3187
  }, 250);
2887
3188
  } else {
2888
3189
  this.dappClient.once(
@@ -2920,7 +3221,7 @@ deeplinkConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
2920
3221
  clearTimeout(timeout);
2921
3222
  }
2922
3223
  });
2923
- });
3224
+ }));
2924
3225
  });
2925
3226
  };
2926
3227
  handleConnection_fn = function(promise, scopes, transportType) {
@@ -2965,6 +3266,53 @@ handleConnection_fn = function(promise, scopes, transportType) {
2965
3266
  }));
2966
3267
  });
2967
3268
  };
3269
+ getCaipSession_fn = function() {
3270
+ return __async(this, null, function* () {
3271
+ let sessionData = {
3272
+ sessionScopes: {},
3273
+ sessionProperties: {}
3274
+ };
3275
+ if (this.status === "connected") {
3276
+ const response = yield this.transport.request({
3277
+ method: "wallet_getSession"
3278
+ });
3279
+ if (response.result) {
3280
+ sessionData = response.result;
3281
+ }
3282
+ }
3283
+ return sessionData;
3284
+ });
3285
+ };
3286
+ openConnectDeeplinkIfNeeded_fn = function() {
3287
+ return __async(this, null, function* () {
3288
+ var _a2, _b;
3289
+ const { ui } = this.options;
3290
+ const { showInstallModal = false } = ui != null ? ui : {};
3291
+ const secure = isSecure();
3292
+ const shouldOpenDeeplink = secure && !showInstallModal;
3293
+ if (!shouldOpenDeeplink) {
3294
+ return;
3295
+ }
3296
+ const storedSessionRequest = yield (_a2 = __privateGet(this, _transport2)) == null ? void 0 : _a2.getStoredPendingSessionRequest();
3297
+ if (!storedSessionRequest) {
3298
+ return;
3299
+ }
3300
+ const connectionRequest = {
3301
+ sessionRequest: storedSessionRequest,
3302
+ metadata: {
3303
+ dapp: this.options.dapp,
3304
+ sdk: { version: getVersion(), platform: getPlatformType() }
3305
+ }
3306
+ };
3307
+ const deeplink = this.options.ui.factory.createConnectionDeeplink(connectionRequest);
3308
+ const universalLink = this.options.ui.factory.createConnectionUniversalLink(connectionRequest);
3309
+ if ((_b = this.options.mobile) == null ? void 0 : _b.preferredOpenLink) {
3310
+ this.options.mobile.preferredOpenLink(deeplink, "_self");
3311
+ } else {
3312
+ openDeeplink(this.options, deeplink, universalLink);
3313
+ }
3314
+ });
3315
+ };
2968
3316
  var MetaMaskConnectMultichain = _MetaMaskConnectMultichain;
2969
3317
 
2970
3318
  // src/store/index.ts
@@ -3213,7 +3561,9 @@ var BaseModalFactory = class {
3213
3561
  }
3214
3562
  createConnectionDeeplink(connectionRequest) {
3215
3563
  if (!connectionRequest) {
3216
- throw new Error("createConnectionDeeplink can only be called with a connection request");
3564
+ throw new Error(
3565
+ "createConnectionDeeplink can only be called with a connection request"
3566
+ );
3217
3567
  }
3218
3568
  const json = JSON.stringify(connectionRequest);
3219
3569
  const compressed = compressString(json);
@@ -3319,14 +3669,17 @@ var ModalFactory = class extends BaseModalFactory {
3319
3669
  // src/index.node.ts
3320
3670
  init_domain();
3321
3671
  var createMultichainClient = (options) => __async(null, null, function* () {
3672
+ if (options.debug) {
3673
+ enableDebug("metamask-sdk:*");
3674
+ }
3322
3675
  const uiModules = yield Promise.resolve().then(() => (init_node(), node_exports));
3323
3676
  let storage;
3324
- if (!options.storage) {
3677
+ if (options.storage) {
3678
+ storage = options.storage;
3679
+ } else {
3325
3680
  const { StoreAdapterNode: StoreAdapterNode2 } = yield Promise.resolve().then(() => (init_node2(), node_exports2));
3326
3681
  const adapter = new StoreAdapterNode2();
3327
3682
  storage = new Store(adapter);
3328
- } else {
3329
- storage = options.storage;
3330
3683
  }
3331
3684
  const factory = new ModalFactory(uiModules);
3332
3685
  return MetaMaskConnectMultichain.create(__spreadProps(__spreadValues({}, options), {