@metamask/connect-multichain 0.5.3 → 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 (60) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/README.md +9 -3
  3. package/dist/browser/es/connect-multichain.d.mts +27 -4
  4. package/dist/browser/es/connect-multichain.mjs +603 -333
  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 +27 -4
  8. package/dist/browser/iife/connect-multichain.js +3363 -2993
  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 +27 -4
  12. package/dist/browser/umd/connect-multichain.js +603 -333
  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 +27 -4
  16. package/dist/node/cjs/connect-multichain.js +421 -151
  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 +27 -4
  20. package/dist/node/es/connect-multichain.mjs +421 -151
  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 +27 -4
  24. package/dist/react-native/es/connect-multichain.mjs +596 -326
  25. package/dist/react-native/es/connect-multichain.mjs.map +1 -1
  26. package/dist/react-native/es/metafile-esm.json +1 -1
  27. package/dist/src/domain/multichain/index.d.ts +15 -4
  28. package/dist/src/domain/multichain/index.d.ts.map +1 -1
  29. package/dist/src/domain/multichain/index.js +14 -0
  30. package/dist/src/domain/multichain/index.js.map +1 -1
  31. package/dist/src/domain/multichain/types.d.ts +12 -0
  32. package/dist/src/domain/multichain/types.d.ts.map +1 -1
  33. package/dist/src/multichain/index.d.ts +3 -2
  34. package/dist/src/multichain/index.d.ts.map +1 -1
  35. package/dist/src/multichain/index.js +158 -61
  36. package/dist/src/multichain/index.js.map +1 -1
  37. package/dist/src/multichain/transports/default/index.d.ts +3 -1
  38. package/dist/src/multichain/transports/default/index.d.ts.map +1 -1
  39. package/dist/src/multichain/transports/default/index.js +17 -11
  40. package/dist/src/multichain/transports/default/index.js.map +1 -1
  41. package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts +3 -1
  42. package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts.map +1 -1
  43. package/dist/src/multichain/transports/multichainApiClientWrapper/index.js +28 -31
  44. package/dist/src/multichain/transports/multichainApiClientWrapper/index.js.map +1 -1
  45. package/dist/src/multichain/transports/mwp/index.d.ts +15 -2
  46. package/dist/src/multichain/transports/mwp/index.d.ts.map +1 -1
  47. package/dist/src/multichain/transports/mwp/index.js +155 -38
  48. package/dist/src/multichain/transports/mwp/index.js.map +1 -1
  49. package/dist/src/multichain/utils/index.d.ts +23 -0
  50. package/dist/src/multichain/utils/index.d.ts.map +1 -1
  51. package/dist/src/multichain/utils/index.js +57 -4
  52. package/dist/src/multichain/utils/index.js.map +1 -1
  53. package/dist/src/polyfills/buffer-shim.js +4 -14
  54. package/dist/src/polyfills/buffer-shim.js.map +1 -1
  55. package/dist/src/store/adapters/web.d.ts +1 -1
  56. package/dist/src/store/adapters/web.d.ts.map +1 -1
  57. package/dist/src/store/adapters/web.js +1 -1
  58. package/dist/src/store/adapters/web.js.map +1 -1
  59. package/dist/types/connect-multichain.d.ts +27 -4
  60. package/package.json +1 -1
@@ -34,14 +34,6 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
34
34
  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);
35
35
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
36
36
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
37
- var __privateWrapper = (obj, member, setter, getter) => ({
38
- set _(value) {
39
- __privateSet(obj, member, value, setter);
40
- },
41
- get _() {
42
- return __privateGet(obj, member, getter);
43
- }
44
- });
45
37
  var __async = (__this, __arguments, generator) => {
46
38
  return new Promise((resolve, reject) => {
47
39
  var fulfilled = (value) => {
@@ -407,6 +399,34 @@ var init_multichain = __esm({
407
399
  super();
408
400
  this.options = options;
409
401
  }
402
+ /**
403
+ * Merges the given options into the current instance options.
404
+ * Only the mergeable keys are updated (api.supportedNetworks, ui.*, mobile.*, transport.extensionId, debug).
405
+ * The main thing to note is that the value for `dapp` is not merged as it does not make sense for
406
+ * subsequent calls to `createMultichainClient` to have a different `dapp` value.
407
+ * Used when createMultichainClient is called with an existing singleton.
408
+ *
409
+ * @param partial - Options to merge/overwrite onto the current instance
410
+ */
411
+ mergeOptions(partial) {
412
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
413
+ const opts = this.options;
414
+ this.options = __spreadProps(__spreadValues({}, opts), {
415
+ api: __spreadProps(__spreadValues({}, opts.api), {
416
+ supportedNetworks: __spreadValues(__spreadValues({}, opts.api.supportedNetworks), (_b = (_a2 = partial.api) == null ? void 0 : _a2.supportedNetworks) != null ? _b : {})
417
+ }),
418
+ ui: __spreadProps(__spreadValues({}, opts.ui), {
419
+ headless: (_d = (_c = partial.ui) == null ? void 0 : _c.headless) != null ? _d : opts.ui.headless,
420
+ preferExtension: (_f = (_e = partial.ui) == null ? void 0 : _e.preferExtension) != null ? _f : opts.ui.preferExtension,
421
+ showInstallModal: (_h = (_g = partial.ui) == null ? void 0 : _g.showInstallModal) != null ? _h : opts.ui.showInstallModal
422
+ }),
423
+ mobile: __spreadValues(__spreadValues({}, opts.mobile), (_i = partial.mobile) != null ? _i : {}),
424
+ transport: __spreadProps(__spreadValues({}, (_j = opts.transport) != null ? _j : {}), {
425
+ extensionId: (_m = (_k = partial.transport) == null ? void 0 : _k.extensionId) != null ? _m : (_l = opts.transport) == null ? void 0 : _l.extensionId
426
+ }),
427
+ debug: (_n = partial.debug) != null ? _n : opts.debug
428
+ });
429
+ }
410
430
  };
411
431
  }
412
432
  });
@@ -597,6 +617,21 @@ import {
597
617
  parseCaipChainId
598
618
  } from "@metamask/utils";
599
619
  import { deflate } from "pako";
620
+ function getGlobalObject() {
621
+ if (typeof globalThis !== "undefined") {
622
+ return globalThis;
623
+ }
624
+ if (typeof global !== "undefined") {
625
+ return global;
626
+ }
627
+ if (typeof self !== "undefined") {
628
+ return self;
629
+ }
630
+ if (typeof window !== "undefined") {
631
+ return window;
632
+ }
633
+ throw new Error("Unable to locate global object");
634
+ }
600
635
  function base64Encode(str) {
601
636
  if (typeof btoa !== "undefined") {
602
637
  return btoa(str);
@@ -630,6 +665,29 @@ function openDeeplink(options, deeplink, universalLink) {
630
665
  link.click();
631
666
  }
632
667
  }
668
+ function mergeRequestedSessionWithExisting(sessionData, scopes, caipAccountIds, sessionProperties) {
669
+ const existingCaipChainIds = Object.keys(sessionData.sessionScopes);
670
+ const existingCaipAccountIds = [];
671
+ Object.values(sessionData.sessionScopes).forEach((scopeObject) => {
672
+ if ((scopeObject == null ? void 0 : scopeObject.accounts) && Array.isArray(scopeObject.accounts)) {
673
+ scopeObject.accounts.forEach((account) => {
674
+ existingCaipAccountIds.push(account);
675
+ });
676
+ }
677
+ });
678
+ const mergedScopes = Array.from(
679
+ /* @__PURE__ */ new Set([...existingCaipChainIds, ...scopes])
680
+ );
681
+ const mergedCaipAccountIds = Array.from(
682
+ /* @__PURE__ */ new Set([...existingCaipAccountIds, ...caipAccountIds])
683
+ );
684
+ const mergedSessionProperties = __spreadValues(__spreadValues({}, sessionData.sessionProperties), sessionProperties);
685
+ return {
686
+ mergedScopes,
687
+ mergedCaipAccountIds,
688
+ mergedSessionProperties
689
+ };
690
+ }
633
691
  function getOptionalScopes(scopes) {
634
692
  return scopes.reduce(
635
693
  (prev, scope) => __spreadProps(__spreadValues({}, prev), {
@@ -768,7 +826,7 @@ function addValidAccounts(optionalScopes, validAccounts) {
768
826
  }
769
827
  return result;
770
828
  }
771
- var extractFavicon;
829
+ var extractFavicon, MAX, idCounter, getUniqueRequestId;
772
830
  var init_utils = __esm({
773
831
  "src/multichain/utils/index.ts"() {
774
832
  "use strict";
@@ -787,6 +845,12 @@ var init_utils = __esm({
787
845
  }
788
846
  return favicon;
789
847
  };
848
+ MAX = 4294967295;
849
+ idCounter = Math.floor(Math.random() * MAX);
850
+ getUniqueRequestId = () => {
851
+ idCounter = (idCounter + 1) % MAX;
852
+ return idCounter;
853
+ };
790
854
  }
791
855
  });
792
856
 
@@ -1435,7 +1499,7 @@ import {
1435
1499
  getDefaultTransport
1436
1500
  } from "@metamask/multichain-api-client";
1437
1501
  var DEFAULT_REQUEST_TIMEOUT = 60 * 1e3;
1438
- var _notificationCallbacks, _transport, _defaultRequestOptions, _reqId, _pendingRequests, _handleResponseListener, _handleNotificationListener, _DefaultTransport_instances, notifyCallbacks_fn, isMetamaskProviderEvent_fn, handleResponse_fn, handleNotification_fn, setupMessageListener_fn;
1502
+ var _notificationCallbacks, _transport, _defaultRequestOptions, _pendingRequests, _handleResponseListener, _handleNotificationListener, _DefaultTransport_instances, notifyCallbacks_fn, isMetamaskProviderEvent_fn, handleResponse_fn, handleNotification_fn, setupMessageListener_fn;
1439
1503
  var DefaultTransport = class {
1440
1504
  constructor() {
1441
1505
  __privateAdd(this, _DefaultTransport_instances);
@@ -1444,8 +1508,6 @@ var DefaultTransport = class {
1444
1508
  __privateAdd(this, _defaultRequestOptions, {
1445
1509
  timeout: DEFAULT_REQUEST_TIMEOUT
1446
1510
  });
1447
- // Use timestamp-based ID to avoid conflicts across disconnect/reconnect cycles
1448
- __privateAdd(this, _reqId, Date.now());
1449
1511
  __privateAdd(this, _pendingRequests, /* @__PURE__ */ new Map());
1450
1512
  __privateAdd(this, _handleResponseListener);
1451
1513
  __privateAdd(this, _handleNotificationListener);
@@ -1453,8 +1515,7 @@ var DefaultTransport = class {
1453
1515
  sendEip1193Message(payload, options) {
1454
1516
  return __async(this, null, function* () {
1455
1517
  __privateMethod(this, _DefaultTransport_instances, setupMessageListener_fn).call(this);
1456
- __privateSet(this, _reqId, __privateGet(this, _reqId) + 1);
1457
- const requestId = `${__privateGet(this, _reqId)}`;
1518
+ const requestId = String(getUniqueRequestId());
1458
1519
  const request = __spreadValues({
1459
1520
  jsonrpc: "2.0",
1460
1521
  id: requestId
@@ -1519,10 +1580,6 @@ var DefaultTransport = class {
1519
1580
  proposedCaipAccountIds
1520
1581
  );
1521
1582
  if (!hasSameScopesAndAccounts) {
1522
- yield this.request(
1523
- { method: "wallet_revokeSession", params: walletSession },
1524
- __privateGet(this, _defaultRequestOptions)
1525
- );
1526
1583
  const response = yield this.request(
1527
1584
  { method: "wallet_createSession", params: createSessionParams },
1528
1585
  __privateGet(this, _defaultRequestOptions)
@@ -1549,9 +1606,14 @@ var DefaultTransport = class {
1549
1606
  });
1550
1607
  }
1551
1608
  disconnect() {
1552
- return __async(this, null, function* () {
1609
+ return __async(this, arguments, function* (scopes = []) {
1610
+ yield this.request({ method: "wallet_revokeSession", params: { scopes } });
1611
+ const response = yield this.request({ method: "wallet_getSession" });
1612
+ const { sessionScopes } = response.result;
1613
+ if (Object.keys(sessionScopes).length > 0) {
1614
+ return;
1615
+ }
1553
1616
  __privateGet(this, _notificationCallbacks).clear();
1554
- yield this.request({ method: "wallet_revokeSession", params: {} });
1555
1617
  if (__privateGet(this, _handleResponseListener)) {
1556
1618
  window.removeEventListener("message", __privateGet(this, _handleResponseListener));
1557
1619
  __privateSet(this, _handleResponseListener, void 0);
@@ -1565,7 +1627,7 @@ var DefaultTransport = class {
1565
1627
  request.reject(new Error("Transport disconnected"));
1566
1628
  }
1567
1629
  __privateGet(this, _pendingRequests).clear();
1568
- return __privateGet(this, _transport).disconnect();
1630
+ yield __privateGet(this, _transport).disconnect();
1569
1631
  });
1570
1632
  }
1571
1633
  isConnected() {
@@ -1590,11 +1652,17 @@ var DefaultTransport = class {
1590
1652
  );
1591
1653
  });
1592
1654
  }
1655
+ getStoredPendingSessionRequest() {
1656
+ return __async(this, null, function* () {
1657
+ throw new Error(
1658
+ "getStoredPendingSessionRequest is purposely not implemented for the DefaultTransport"
1659
+ );
1660
+ });
1661
+ }
1593
1662
  };
1594
1663
  _notificationCallbacks = new WeakMap();
1595
1664
  _transport = new WeakMap();
1596
1665
  _defaultRequestOptions = new WeakMap();
1597
- _reqId = new WeakMap();
1598
1666
  _pendingRequests = new WeakMap();
1599
1667
  _handleResponseListener = new WeakMap();
1600
1668
  _handleNotificationListener = new WeakMap();
@@ -1663,19 +1731,13 @@ setupMessageListener_fn = function() {
1663
1731
  };
1664
1732
 
1665
1733
  // src/multichain/transports/multichainApiClientWrapper/index.ts
1734
+ init_utils();
1666
1735
  import { providerErrors } from "@metamask/rpc-errors";
1667
- var MAX = 4294967295;
1668
- var idCounter = Math.floor(Math.random() * MAX);
1669
- var getUniqueId = () => {
1670
- idCounter = (idCounter + 1) % MAX;
1671
- return idCounter;
1672
- };
1673
- var _requestId, _notificationCallbacks2, _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn, walletGetSession_fn, walletRevokeSession_fn, walletInvokeMethod_fn;
1736
+ var _notificationCallbacks2, _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn, walletGetSession_fn, walletRevokeSession_fn, walletInvokeMethod_fn;
1674
1737
  var MultichainApiClientWrapperTransport = class {
1675
1738
  constructor(metamaskConnectMultichain) {
1676
1739
  this.metamaskConnectMultichain = metamaskConnectMultichain;
1677
1740
  __privateAdd(this, _MultichainApiClientWrapperTransport_instances);
1678
- __privateAdd(this, _requestId, getUniqueId());
1679
1741
  __privateAdd(this, _notificationCallbacks2, /* @__PURE__ */ new Set());
1680
1742
  }
1681
1743
  isTransportDefined() {
@@ -1693,15 +1755,23 @@ var MultichainApiClientWrapperTransport = class {
1693
1755
  callback(data);
1694
1756
  });
1695
1757
  }
1696
- setupNotifcationListener() {
1697
- this.metamaskConnectMultichain.transport.onNotification(
1758
+ clearTransportNotificationListener() {
1759
+ var _a2;
1760
+ (_a2 = this.notificationListener) == null ? void 0 : _a2.call(this);
1761
+ this.notificationListener = void 0;
1762
+ }
1763
+ setupTransportNotificationListener() {
1764
+ if (!this.isTransportDefined() || this.notificationListener) {
1765
+ return;
1766
+ }
1767
+ this.notificationListener = this.metamaskConnectMultichain.transport.onNotification(
1698
1768
  this.notifyCallbacks.bind(this)
1699
1769
  );
1700
1770
  }
1701
1771
  connect() {
1702
1772
  return __async(this, null, function* () {
1703
1773
  console.log("\u{1F4DA} connect");
1704
- return Promise.resolve();
1774
+ yield this.metamaskConnectMultichain.emitSessionChanged();
1705
1775
  });
1706
1776
  }
1707
1777
  disconnect() {
@@ -1714,7 +1784,7 @@ var MultichainApiClientWrapperTransport = class {
1714
1784
  }
1715
1785
  request(_0) {
1716
1786
  return __async(this, arguments, function* (params, _options = {}) {
1717
- const id = __privateWrapper(this, _requestId)._++;
1787
+ const id = getUniqueRequestId();
1718
1788
  const requestPayload = __spreadValues({
1719
1789
  id,
1720
1790
  jsonrpc: "2.0"
@@ -1735,16 +1805,13 @@ var MultichainApiClientWrapperTransport = class {
1735
1805
  });
1736
1806
  }
1737
1807
  onNotification(callback) {
1738
- if (!this.isTransportDefined()) {
1739
- __privateGet(this, _notificationCallbacks2).add(callback);
1740
- return () => {
1741
- __privateGet(this, _notificationCallbacks2).delete(callback);
1742
- };
1743
- }
1744
- return this.metamaskConnectMultichain.transport.onNotification(callback);
1808
+ this.setupTransportNotificationListener();
1809
+ __privateGet(this, _notificationCallbacks2).add(callback);
1810
+ return () => {
1811
+ __privateGet(this, _notificationCallbacks2).delete(callback);
1812
+ };
1745
1813
  }
1746
1814
  };
1747
- _requestId = new WeakMap();
1748
1815
  _notificationCallbacks2 = new WeakMap();
1749
1816
  _MultichainApiClientWrapperTransport_instances = new WeakSet();
1750
1817
  walletCreateSession_fn = function(request) {
@@ -1795,11 +1862,14 @@ walletGetSession_fn = function(request) {
1795
1862
  };
1796
1863
  walletRevokeSession_fn = function(request) {
1797
1864
  return __async(this, null, function* () {
1865
+ var _a2;
1798
1866
  if (!this.isTransportDefined()) {
1799
1867
  return { jsonrpc: "2.0", id: request.id, result: true };
1800
1868
  }
1869
+ const revokeSessionParams = request.params;
1870
+ const scopes = (_a2 = revokeSessionParams == null ? void 0 : revokeSessionParams.scopes) != null ? _a2 : [];
1801
1871
  try {
1802
- this.metamaskConnectMultichain.disconnect();
1872
+ yield this.metamaskConnectMultichain.disconnect(scopes);
1803
1873
  return { jsonrpc: "2.0", id: request.id, result: true };
1804
1874
  } catch (_error) {
1805
1875
  return { jsonrpc: "2.0", id: request.id, result: false };
@@ -1827,6 +1897,7 @@ import { SessionStore } from "@metamask/mobile-wallet-protocol-core";
1827
1897
  import {
1828
1898
  TransportTimeoutError
1829
1899
  } from "@metamask/multichain-api-client";
1900
+ import { providerErrors as providerErrors2, rpcErrors } from "@metamask/rpc-errors";
1830
1901
 
1831
1902
  // src/multichain/transports/constants.ts
1832
1903
  var MULTICHAIN_PROVIDER_STREAM_NAME = "metamask-multichain-provider";
@@ -1839,6 +1910,7 @@ var DEFAULT_RESUME_TIMEOUT = 10 * 1e3;
1839
1910
  var SESSION_STORE_KEY = "cache_wallet_getSession";
1840
1911
  var ACCOUNTS_STORE_KEY = "cache_eth_accounts";
1841
1912
  var CHAIN_STORE_KEY = "cache_eth_chainId";
1913
+ var PENDING_SESSION_REQUEST_KEY = "pending_session_request";
1842
1914
  var CACHED_METHOD_LIST = [
1843
1915
  "wallet_getSession",
1844
1916
  "wallet_createSession",
@@ -1858,10 +1930,15 @@ var MWPTransport = class {
1858
1930
  this.dappClient = dappClient;
1859
1931
  this.kvstore = kvstore;
1860
1932
  this.options = options;
1861
- this.__reqId = 0;
1862
1933
  this.__pendingRequests = /* @__PURE__ */ new Map();
1863
1934
  this.notificationCallbacks = /* @__PURE__ */ new Set();
1864
1935
  this.dappClient.on("message", this.handleMessage.bind(this));
1936
+ this.dappClient.on("session_request", (sessionRequest) => {
1937
+ this.currentSessionRequest = sessionRequest;
1938
+ this.kvstore.set(PENDING_SESSION_REQUEST_KEY, JSON.stringify(sessionRequest)).catch((err) => {
1939
+ logger("Failed to store pending session request", err);
1940
+ });
1941
+ });
1865
1942
  if (typeof window !== "undefined" && typeof window.addEventListener !== "undefined") {
1866
1943
  this.windowFocusHandler = this.onWindowFocus.bind(this);
1867
1944
  window.addEventListener("focus", this.windowFocusHandler);
@@ -1876,6 +1953,34 @@ var MWPTransport = class {
1876
1953
  get sessionRequest() {
1877
1954
  return this.currentSessionRequest;
1878
1955
  }
1956
+ /**
1957
+ * Returns the stored pending session request from the dappClient session_request event, if any.
1958
+ *
1959
+ * @returns The stored SessionRequest, or null if none or invalid.
1960
+ */
1961
+ getStoredPendingSessionRequest() {
1962
+ return __async(this, null, function* () {
1963
+ try {
1964
+ const raw = yield this.kvstore.get(PENDING_SESSION_REQUEST_KEY);
1965
+ if (!raw) {
1966
+ return null;
1967
+ }
1968
+ return JSON.parse(raw);
1969
+ } catch (e) {
1970
+ return null;
1971
+ }
1972
+ });
1973
+ }
1974
+ /**
1975
+ * Removes the stored pending session request from the KVStore.
1976
+ * This is necessary to ensure that ConnectMultichain is able to correctly
1977
+ * infer the MWP Transport connection attempt status.
1978
+ */
1979
+ removeStoredPendingSessionRequest() {
1980
+ return __async(this, null, function* () {
1981
+ yield this.kvstore.delete(PENDING_SESSION_REQUEST_KEY);
1982
+ });
1983
+ }
1879
1984
  onWindowFocus() {
1880
1985
  if (!this.isConnected()) {
1881
1986
  this.dappClient.reconnect();
@@ -1892,6 +1997,17 @@ var MWPTransport = class {
1892
1997
  request.reject(error);
1893
1998
  }
1894
1999
  }
2000
+ parseWalletError(errorPayload) {
2001
+ const errorData = errorPayload;
2002
+ if (typeof errorData.code === "number" && typeof errorData.message === "string") {
2003
+ return providerErrors2.custom({
2004
+ code: errorData.code,
2005
+ message: errorData.message
2006
+ });
2007
+ }
2008
+ const message = errorPayload instanceof Error ? errorPayload.message : JSON.stringify(errorPayload);
2009
+ return rpcErrors.internal({ message });
2010
+ }
1895
2011
  handleMessage(message) {
1896
2012
  if (typeof message === "object" && message !== null) {
1897
2013
  if ("data" in message) {
@@ -1899,6 +2015,12 @@ var MWPTransport = class {
1899
2015
  if ("id" in messagePayload && typeof messagePayload.id === "string") {
1900
2016
  const request = this.pendingRequests.get(messagePayload.id);
1901
2017
  if (request) {
2018
+ clearTimeout(request.timeout);
2019
+ if ("error" in messagePayload && messagePayload.error) {
2020
+ this.pendingRequests.delete(messagePayload.id);
2021
+ request.reject(this.parseWalletError(messagePayload.error));
2022
+ return;
2023
+ }
1902
2024
  const requestWithName = __spreadProps(__spreadValues({}, messagePayload), {
1903
2025
  method: request.method === "wallet_getSession" || request.method === "wallet_createSession" ? "wallet_sessionChanged" : request.method
1904
2026
  });
@@ -1906,7 +2028,6 @@ var MWPTransport = class {
1906
2028
  method: request.method === "wallet_getSession" || request.method === "wallet_createSession" ? "wallet_sessionChanged" : request.method,
1907
2029
  params: requestWithName.result
1908
2030
  });
1909
- clearTimeout(request.timeout);
1910
2031
  this.notifyCallbacks(notification);
1911
2032
  request.resolve(requestWithName);
1912
2033
  this.pendingRequests.delete(messagePayload.id);
@@ -1996,6 +2117,7 @@ var MWPTransport = class {
1996
2117
  }
1997
2118
  walletSession = response.result;
1998
2119
  }
2120
+ yield this.removeStoredPendingSessionRequest();
1999
2121
  this.notifyCallbacks({
2000
2122
  method: "wallet_sessionChanged",
2001
2123
  params: walletSession
@@ -2011,7 +2133,7 @@ var MWPTransport = class {
2011
2133
  return __async(this, null, function* () {
2012
2134
  const request = __spreadValues({
2013
2135
  jsonrpc: "2.0",
2014
- id: `${this.__reqId++}`
2136
+ id: String(getUniqueRequestId())
2015
2137
  }, payload);
2016
2138
  const cachedWalletSession = yield this.getCachedResponse(request);
2017
2139
  if (cachedWalletSession) {
@@ -2047,6 +2169,7 @@ var MWPTransport = class {
2047
2169
  if (session) {
2048
2170
  logger("active session found", session);
2049
2171
  }
2172
+ const storedSessionRequestBeforeConnectionAttempt = yield this.getStoredPendingSessionRequest();
2050
2173
  let timeout;
2051
2174
  let initialConnectionMessageHandler;
2052
2175
  const connectionPromise = new Promise((resolve, reject) => __async(this, null, function* () {
@@ -2077,33 +2200,35 @@ var MWPTransport = class {
2077
2200
  };
2078
2201
  const request = {
2079
2202
  jsonrpc: "2.0",
2080
- id: `${this.__reqId++}`,
2203
+ id: String(getUniqueRequestId()),
2081
2204
  method: "wallet_createSession",
2082
2205
  params: sessionRequest
2083
2206
  };
2084
2207
  initialConnectionMessageHandler = (message) => __async(this, null, function* () {
2085
- if (typeof message === "object" && message !== null) {
2086
- if ("data" in message) {
2087
- const messagePayload = message.data;
2088
- if (messagePayload.method === "wallet_createSession" || messagePayload.method === "wallet_sessionChanged") {
2089
- if (messagePayload.error) {
2090
- if (initialConnectionMessageHandler) {
2091
- this.dappClient.off(
2092
- "message",
2093
- initialConnectionMessageHandler
2094
- );
2095
- }
2096
- return rejectConnection(messagePayload.error);
2097
- }
2098
- yield this.storeWalletSession(
2099
- request,
2100
- messagePayload
2101
- );
2102
- this.notifyCallbacks(messagePayload);
2103
- return resolveConnection();
2104
- }
2105
- }
2208
+ if (typeof message !== "object" || message === null) {
2209
+ return;
2210
+ }
2211
+ if (!("data" in message)) {
2212
+ return;
2213
+ }
2214
+ const messagePayload = message.data;
2215
+ const isMatchingId = messagePayload.id === request.id;
2216
+ const isMatchingMethod = messagePayload.method === "wallet_createSession" || messagePayload.method === "wallet_sessionChanged";
2217
+ if (!isMatchingId && !isMatchingMethod) {
2218
+ return;
2106
2219
  }
2220
+ if (messagePayload.error) {
2221
+ return rejectConnection(
2222
+ this.parseWalletError(messagePayload.error)
2223
+ );
2224
+ }
2225
+ yield this.storeWalletSession(
2226
+ request,
2227
+ messagePayload
2228
+ );
2229
+ yield this.removeStoredPendingSessionRequest();
2230
+ this.notifyCallbacks(messagePayload);
2231
+ return resolveConnection();
2107
2232
  });
2108
2233
  this.dappClient.on("message", initialConnectionMessageHandler);
2109
2234
  dappClient.connect({
@@ -2124,14 +2249,18 @@ var MWPTransport = class {
2124
2249
  }
2125
2250
  );
2126
2251
  }
2127
- timeout = setTimeout(() => {
2128
- reject(new TransportTimeoutError());
2129
- }, this.options.connectionTimeout);
2252
+ timeout = setTimeout(
2253
+ () => {
2254
+ reject(new TransportTimeoutError());
2255
+ },
2256
+ storedSessionRequestBeforeConnectionAttempt ? this.options.resumeTimeout : this.options.connectionTimeout
2257
+ );
2130
2258
  connection.then(resolve).catch(reject);
2131
2259
  }));
2132
- return connectionPromise.catch((error) => {
2260
+ return connectionPromise.catch((error) => __async(this, null, function* () {
2261
+ yield this.dappClient.disconnect();
2133
2262
  throw error;
2134
- }).finally(() => {
2263
+ })).finally(() => {
2135
2264
  if (timeout) {
2136
2265
  clearTimeout(timeout);
2137
2266
  }
@@ -2139,24 +2268,68 @@ var MWPTransport = class {
2139
2268
  this.dappClient.off("message", initialConnectionMessageHandler);
2140
2269
  initialConnectionMessageHandler = void 0;
2141
2270
  }
2271
+ this.removeStoredPendingSessionRequest();
2142
2272
  });
2143
2273
  });
2144
2274
  }
2145
2275
  /**
2146
2276
  * Disconnects from the Mobile Wallet Protocol
2147
2277
  *
2278
+ * @param [scopes] - The scopes to revoke. If not provided or empty, all scopes will be revoked.
2148
2279
  * @returns Nothing
2149
2280
  */
2150
2281
  disconnect() {
2151
- return __async(this, null, function* () {
2152
- if (typeof window !== "undefined" && typeof window.removeEventListener !== "undefined" && this.windowFocusHandler) {
2153
- window.removeEventListener("focus", this.windowFocusHandler);
2154
- this.windowFocusHandler = void 0;
2155
- }
2156
- this.kvstore.delete(SESSION_STORE_KEY);
2157
- this.kvstore.delete(ACCOUNTS_STORE_KEY);
2158
- this.kvstore.delete(CHAIN_STORE_KEY);
2159
- return this.dappClient.disconnect();
2282
+ return __async(this, arguments, function* (scopes = []) {
2283
+ var _a2, _b;
2284
+ const cachedSession = yield this.getCachedResponse({
2285
+ jsonrpc: "2.0",
2286
+ id: "0",
2287
+ method: "wallet_getSession"
2288
+ });
2289
+ const cachedSessionScopes = (_b = (_a2 = cachedSession == null ? void 0 : cachedSession.result) == null ? void 0 : _a2.sessionScopes) != null ? _b : {};
2290
+ const remainingScopes = scopes.length === 0 ? [] : Object.keys(cachedSessionScopes).filter(
2291
+ (scope) => !scopes.includes(scope)
2292
+ );
2293
+ const newSessionScopes = Object.fromEntries(
2294
+ Object.entries(cachedSessionScopes).filter(
2295
+ ([key]) => remainingScopes.includes(key)
2296
+ )
2297
+ );
2298
+ this.request({ method: "wallet_revokeSession", params: { scopes } }).catch(
2299
+ (err) => {
2300
+ console.error("error revoking session", err);
2301
+ }
2302
+ );
2303
+ const remainingScopesIncludeEip155 = remainingScopes.some(
2304
+ (scope) => scope.includes("eip155")
2305
+ );
2306
+ if (!remainingScopesIncludeEip155) {
2307
+ this.kvstore.delete(ACCOUNTS_STORE_KEY);
2308
+ this.kvstore.delete(CHAIN_STORE_KEY);
2309
+ }
2310
+ if (remainingScopes.length > 0) {
2311
+ this.kvstore.set(
2312
+ SESSION_STORE_KEY,
2313
+ JSON.stringify({
2314
+ result: {
2315
+ sessionScopes: newSessionScopes
2316
+ }
2317
+ })
2318
+ );
2319
+ } else {
2320
+ this.kvstore.delete(SESSION_STORE_KEY);
2321
+ if (typeof window !== "undefined" && typeof window.removeEventListener !== "undefined" && this.windowFocusHandler) {
2322
+ window.removeEventListener("focus", this.windowFocusHandler);
2323
+ this.windowFocusHandler = void 0;
2324
+ }
2325
+ yield this.dappClient.disconnect();
2326
+ }
2327
+ this.notifyCallbacks({
2328
+ method: "wallet_sessionChanged",
2329
+ params: {
2330
+ sessionScopes: newSessionScopes
2331
+ }
2332
+ });
2160
2333
  });
2161
2334
  }
2162
2335
  /**
@@ -2262,7 +2435,7 @@ var MWPTransport = class {
2262
2435
  return __async(this, null, function* () {
2263
2436
  const request = __spreadValues({
2264
2437
  jsonrpc: "2.0",
2265
- id: `${this.__reqId++}`
2438
+ id: String(getUniqueRequestId())
2266
2439
  }, payload);
2267
2440
  const cachedWalletSession = yield this.getCachedResponse(request);
2268
2441
  if (cachedWalletSession) {
@@ -2344,6 +2517,7 @@ var MWPTransport = class {
2344
2517
  const timeoutPromise = new Promise((_resolve, reject) => {
2345
2518
  setTimeout(() => {
2346
2519
  unsubscribe();
2520
+ this.removeStoredPendingSessionRequest();
2347
2521
  reject(new TransportTimeoutError());
2348
2522
  }, this.options.resumeTimeout);
2349
2523
  });
@@ -2382,7 +2556,8 @@ var keymanager = new KeyManager();
2382
2556
  // src/multichain/index.ts
2383
2557
  init_utils();
2384
2558
  var logger2 = createLogger("metamask-sdk:core");
2385
- 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;
2559
+ var SINGLETON_KEY = "__METAMASK_CONNECT_MULTICHAIN_SINGLETON__";
2560
+ 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;
2386
2561
  var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends MultichainCore {
2387
2562
  constructor(options) {
2388
2563
  var _a2, _b, _c, _d, _e, _f;
@@ -2447,27 +2622,54 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2447
2622
  get transportType() {
2448
2623
  return __privateGet(this, _transport2) instanceof MWPTransport ? "mwp" /* MWP */ : "browser" /* Browser */;
2449
2624
  }
2625
+ // Creates a singleton instance of MetaMaskConnectMultichain.
2626
+ // If the singleton already exists, it merges the incoming options with the
2627
+ // existing singleton options for the following keys: `api.supportedNetworks`,
2628
+ // `ui.*`, `mobile.*`, `transport.extensionId`, `debug`. Take note that the
2629
+ // value for `dapp` is not merged as it does not make sense for subsequent calls to
2630
+ // `createMultichainClient` to have a different `dapp` value.
2450
2631
  static create(options) {
2451
2632
  return __async(this, null, function* () {
2452
- var _a2;
2453
- const instance = new _MetaMaskConnectMultichain(options);
2454
- const isEnabled2 = yield isEnabled(
2455
- "metamask-sdk:core",
2456
- instance.options.storage
2457
- );
2458
- if (isEnabled2) {
2459
- enableDebug("metamask-sdk:core");
2633
+ const globalObject = getGlobalObject();
2634
+ const existing = globalObject[SINGLETON_KEY];
2635
+ if (existing) {
2636
+ const instance = yield existing;
2637
+ instance.mergeOptions(options);
2638
+ if (options.debug) {
2639
+ enableDebug("metamask-sdk:*");
2640
+ }
2641
+ return instance;
2460
2642
  }
2461
- yield __privateMethod(_a2 = instance, _MetaMaskConnectMultichain_instances, init_fn).call(_a2);
2462
- return instance;
2643
+ const instancePromise = (() => __async(null, null, function* () {
2644
+ var _a2;
2645
+ const instance = new _MetaMaskConnectMultichain(options);
2646
+ const isEnabled2 = yield isEnabled(
2647
+ "metamask-sdk:core",
2648
+ instance.options.storage
2649
+ );
2650
+ if (isEnabled2) {
2651
+ enableDebug("metamask-sdk:core");
2652
+ }
2653
+ yield __privateMethod(_a2 = instance, _MetaMaskConnectMultichain_instances, init_fn).call(_a2);
2654
+ return instance;
2655
+ }))();
2656
+ globalObject[SINGLETON_KEY] = instancePromise;
2657
+ instancePromise.catch((error) => {
2658
+ globalObject[SINGLETON_KEY] = void 0;
2659
+ console.error("Error initializing MetaMaskConnectMultichain", error);
2660
+ });
2661
+ return instancePromise;
2463
2662
  });
2464
2663
  }
2465
2664
  // TODO: make this into param object
2466
2665
  connect(scopes, caipAccountIds, sessionProperties, forceRequest) {
2467
2666
  return __async(this, null, function* () {
2468
2667
  var _a2;
2469
- if (this.status !== "connected") {
2470
- yield this.disconnect();
2668
+ if (this.status === "connecting" && this.transportType === "mwp" /* MWP */) {
2669
+ yield __privateMethod(this, _MetaMaskConnectMultichain_instances, openConnectDeeplinkIfNeeded_fn).call(this);
2670
+ throw new Error(
2671
+ "Existing connection is pending. Please check your MetaMask Mobile app to continue."
2672
+ );
2471
2673
  }
2472
2674
  const { ui } = this.options;
2473
2675
  const platformType = getPlatformType();
@@ -2497,12 +2699,19 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2497
2699
  } catch (error) {
2498
2700
  logger2("Error tracking connection_initiated event", error);
2499
2701
  }
2500
- const nonEmptySessionProperites = Object.keys(sessionProperties != null ? sessionProperties : {}).length > 0 ? sessionProperties : void 0;
2702
+ const sessionData = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, getCaipSession_fn).call(this);
2703
+ const { mergedScopes, mergedCaipAccountIds, mergedSessionProperties } = mergeRequestedSessionWithExisting(
2704
+ sessionData,
2705
+ scopes,
2706
+ caipAccountIds,
2707
+ sessionProperties
2708
+ );
2709
+ const nonEmptySessionProperties = Object.keys(mergedSessionProperties != null ? mergedSessionProperties : {}).length > 0 ? mergedSessionProperties : void 0;
2501
2710
  if (((_a2 = __privateGet(this, _transport2)) == null ? void 0 : _a2.isConnected()) && !secure) {
2502
2711
  return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, __privateGet(this, _transport2).connect({
2503
- scopes,
2504
- caipAccountIds,
2505
- sessionProperties: nonEmptySessionProperites,
2712
+ scopes: mergedScopes,
2713
+ caipAccountIds: mergedCaipAccountIds,
2714
+ sessionProperties: nonEmptySessionProperties,
2506
2715
  forceRequest
2507
2716
  }).then(() => __async(this, null, function* () {
2508
2717
  if (__privateGet(this, _transport2) instanceof MWPTransport) {
@@ -2514,27 +2723,27 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2514
2723
  if (platformType === "in-app-browser" /* MetaMaskMobileWebview */) {
2515
2724
  const defaultTransport = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupDefaultTransport_fn).call(this);
2516
2725
  return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, defaultTransport.connect({
2517
- scopes,
2518
- caipAccountIds,
2519
- sessionProperties: nonEmptySessionProperites,
2726
+ scopes: mergedScopes,
2727
+ caipAccountIds: mergedCaipAccountIds,
2728
+ sessionProperties: nonEmptySessionProperties,
2520
2729
  forceRequest
2521
2730
  }), scopes, transportType);
2522
2731
  }
2523
2732
  if (isWeb && hasExtensionInstalled && preferExtension) {
2524
2733
  const defaultTransport = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupDefaultTransport_fn).call(this);
2525
2734
  return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, defaultTransport.connect({
2526
- scopes,
2527
- caipAccountIds,
2528
- sessionProperties: nonEmptySessionProperites,
2735
+ scopes: mergedScopes,
2736
+ caipAccountIds: mergedCaipAccountIds,
2737
+ sessionProperties: nonEmptySessionProperties,
2529
2738
  forceRequest
2530
2739
  }), scopes, transportType);
2531
2740
  }
2532
2741
  yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupMWP_fn).call(this);
2533
2742
  const shouldShowInstallModal = hasExtensionInstalled ? showInstallModal : !preferExtension || showInstallModal;
2534
2743
  if (secure && !shouldShowInstallModal) {
2535
- return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, __privateMethod(this, _MetaMaskConnectMultichain_instances, deeplinkConnect_fn).call(this, scopes, caipAccountIds, nonEmptySessionProperites), scopes, transportType);
2744
+ return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, __privateMethod(this, _MetaMaskConnectMultichain_instances, deeplinkConnect_fn).call(this, mergedScopes, mergedCaipAccountIds, nonEmptySessionProperties), scopes, transportType);
2536
2745
  }
2537
- return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, __privateMethod(this, _MetaMaskConnectMultichain_instances, showInstallModal_fn).call(this, shouldShowInstallModal, scopes, caipAccountIds, nonEmptySessionProperites), scopes, transportType);
2746
+ return __privateMethod(this, _MetaMaskConnectMultichain_instances, handleConnection_fn).call(this, __privateMethod(this, _MetaMaskConnectMultichain_instances, showInstallModal_fn).call(this, shouldShowInstallModal, mergedScopes, mergedCaipAccountIds, nonEmptySessionProperties), scopes, transportType);
2538
2747
  });
2539
2748
  }
2540
2749
  emit(event, args) {
@@ -2543,18 +2752,24 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2543
2752
  super.emit(event, args);
2544
2753
  }
2545
2754
  disconnect() {
2546
- return __async(this, null, function* () {
2755
+ return __async(this, arguments, function* (scopes = []) {
2547
2756
  var _a2, _b, _c;
2548
- yield (_a2 = __privateGet(this, _listener)) == null ? void 0 : _a2.call(this);
2549
- (_b = __privateGet(this, _beforeUnloadListener)) == null ? void 0 : _b.call(this);
2550
- yield (_c = __privateGet(this, _transport2)) == null ? void 0 : _c.disconnect();
2551
- yield this.storage.removeTransport();
2552
- this.emit("stateChanged", "disconnected");
2553
- __privateSet(this, _listener, void 0);
2554
- __privateSet(this, _beforeUnloadListener, void 0);
2555
- __privateSet(this, _transport2, void 0);
2556
- __privateGet(this, _providerTransportWrapper).clearNotificationCallbacks();
2557
- __privateSet(this, _dappClient, void 0);
2757
+ const sessionData = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, getCaipSession_fn).call(this);
2758
+ const remainingScopes = scopes.length === 0 ? [] : Object.keys(sessionData.sessionScopes).filter(
2759
+ (scope) => !scopes.includes(scope)
2760
+ );
2761
+ yield (_a2 = __privateGet(this, _transport2)) == null ? void 0 : _a2.disconnect(scopes);
2762
+ if (remainingScopes.length === 0) {
2763
+ yield (_b = __privateGet(this, _listener)) == null ? void 0 : _b.call(this);
2764
+ (_c = __privateGet(this, _beforeUnloadListener)) == null ? void 0 : _c.call(this);
2765
+ yield this.storage.removeTransport();
2766
+ __privateSet(this, _listener, void 0);
2767
+ __privateSet(this, _beforeUnloadListener, void 0);
2768
+ __privateSet(this, _transport2, void 0);
2769
+ __privateGet(this, _providerTransportWrapper).clearTransportNotificationListener();
2770
+ __privateSet(this, _dappClient, void 0);
2771
+ this.status = "disconnected";
2772
+ }
2558
2773
  });
2559
2774
  }
2560
2775
  invokeMethod(request) {
@@ -2566,7 +2781,7 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2566
2781
  });
2567
2782
  }
2568
2783
  // DRY THIS WITH REQUEST ROUTER
2569
- openDeeplinkIfNeeded() {
2784
+ openSimpleDeeplinkIfNeeded() {
2570
2785
  const { ui, mobile } = this.options;
2571
2786
  const { showInstallModal = false } = ui != null ? ui : {};
2572
2787
  const secure = isSecure();
@@ -2586,6 +2801,23 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
2586
2801
  }), 10);
2587
2802
  }
2588
2803
  }
2804
+ // Provides a way for ecosystem clients (EVM, Solana, etc.) to get the current CAIP session data
2805
+ // when instantiating themselves (as they would have already missed any initial sessionChanged events emitted by ConnectMultichain)
2806
+ // without having to concern themselves with the current transport connection status.
2807
+ emitSessionChanged() {
2808
+ return __async(this, null, function* () {
2809
+ var _a2;
2810
+ const emptySession = { sessionScopes: {} };
2811
+ if (this.status !== "connected" && this.status !== "connecting") {
2812
+ this.emit("wallet_sessionChanged", emptySession);
2813
+ return;
2814
+ }
2815
+ const response = yield this.transport.request({
2816
+ method: "wallet_getSession"
2817
+ });
2818
+ this.emit("wallet_sessionChanged", (_a2 = response.result) != null ? _a2 : emptySession);
2819
+ });
2820
+ }
2589
2821
  };
2590
2822
  _provider = new WeakMap();
2591
2823
  _providerTransportWrapper = new WeakMap();
@@ -2635,7 +2867,7 @@ getStoredTransport_fn = function() {
2635
2867
  if (hasExtensionInstalled) {
2636
2868
  const apiTransport = new DefaultTransport();
2637
2869
  __privateSet(this, _transport2, apiTransport);
2638
- __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2870
+ __privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
2639
2871
  __privateSet(this, _listener, apiTransport.onNotification(
2640
2872
  __privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
2641
2873
  ));
@@ -2647,7 +2879,7 @@ getStoredTransport_fn = function() {
2647
2879
  const apiTransport = new MWPTransport(dappClient, kvstore);
2648
2880
  __privateSet(this, _dappClient, dappClient);
2649
2881
  __privateSet(this, _transport2, apiTransport);
2650
- __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2882
+ __privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
2651
2883
  __privateSet(this, _listener, apiTransport.onNotification(
2652
2884
  __privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
2653
2885
  ));
@@ -2679,25 +2911,17 @@ setupTransport_fn = function() {
2679
2911
  };
2680
2912
  init_fn = function() {
2681
2913
  return __async(this, null, function* () {
2682
- var _a2;
2683
2914
  try {
2684
- if (typeof window !== "undefined" && ((_a2 = window.mmsdk) == null ? void 0 : _a2.isInitialized)) {
2685
- logger2("MetaMaskSDK: init already initialized");
2686
- } else {
2687
- yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupAnalytics_fn).call(this);
2688
- yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupTransport_fn).call(this);
2689
- try {
2690
- const baseProps = yield getBaseAnalyticsProperties(
2691
- this.options,
2692
- this.storage
2693
- );
2694
- analytics2.track("mmconnect_initialized", baseProps);
2695
- } catch (error) {
2696
- logger2("Error tracking initialized event", error);
2697
- }
2698
- if (typeof window !== "undefined") {
2699
- window.mmsdk = this;
2700
- }
2915
+ yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupAnalytics_fn).call(this);
2916
+ yield __privateMethod(this, _MetaMaskConnectMultichain_instances, setupTransport_fn).call(this);
2917
+ try {
2918
+ const baseProps = yield getBaseAnalyticsProperties(
2919
+ this.options,
2920
+ this.storage
2921
+ );
2922
+ analytics2.track("mmconnect_initialized", baseProps);
2923
+ } catch (error) {
2924
+ logger2("Error tracking initialized event", error);
2701
2925
  }
2702
2926
  } catch (error) {
2703
2927
  yield this.storage.removeTransport();
@@ -2733,7 +2957,7 @@ setupMWP_fn = function() {
2733
2957
  __privateSet(this, _dappClient, dappClient);
2734
2958
  const apiTransport = new MWPTransport(dappClient, kvstore);
2735
2959
  __privateSet(this, _transport2, apiTransport);
2736
- __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2960
+ __privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
2737
2961
  __privateSet(this, _listener, this.transport.onNotification(
2738
2962
  __privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
2739
2963
  ));
@@ -2749,15 +2973,13 @@ onBeforeUnload_fn = function() {
2749
2973
  });
2750
2974
  };
2751
2975
  createBeforeUnloadListener_fn = function() {
2976
+ const handler = __privateMethod(this, _MetaMaskConnectMultichain_instances, onBeforeUnload_fn).bind(this);
2752
2977
  if (typeof window !== "undefined" && typeof window.addEventListener !== "undefined") {
2753
- window.addEventListener("beforeunload", __privateMethod(this, _MetaMaskConnectMultichain_instances, onBeforeUnload_fn).bind(this));
2978
+ window.addEventListener("beforeunload", handler);
2754
2979
  }
2755
2980
  return () => {
2756
2981
  if (typeof window !== "undefined" && typeof window.removeEventListener !== "undefined") {
2757
- window.removeEventListener(
2758
- "beforeunload",
2759
- __privateMethod(this, _MetaMaskConnectMultichain_instances, onBeforeUnload_fn).bind(this)
2760
- );
2982
+ window.removeEventListener("beforeunload", handler);
2761
2983
  }
2762
2984
  };
2763
2985
  };
@@ -2802,13 +3024,14 @@ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds,
2802
3024
  if (error instanceof ProtocolError) {
2803
3025
  if (error.code !== ErrorCode.REQUEST_EXPIRED) {
2804
3026
  this.status = "disconnected";
3027
+ yield this.options.ui.factory.unload(error);
2805
3028
  reject(error);
2806
3029
  }
2807
3030
  } else {
2808
3031
  this.status = "disconnected";
2809
- reject(
2810
- error instanceof Error ? error : new Error(String(error))
2811
- );
3032
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
3033
+ yield this.options.ui.factory.unload(normalizedError);
3034
+ reject(normalizedError);
2812
3035
  }
2813
3036
  }
2814
3037
  }))().catch(() => {
@@ -2895,7 +3118,7 @@ setupDefaultTransport_fn = function() {
2895
3118
  __privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
2896
3119
  ));
2897
3120
  __privateSet(this, _transport2, transport);
2898
- __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
3121
+ __privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
2899
3122
  return transport;
2900
3123
  });
2901
3124
  };
@@ -2922,7 +3145,7 @@ deeplinkConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
2922
3145
  let timeout;
2923
3146
  if (this.transport.isConnected()) {
2924
3147
  timeout = setTimeout(() => {
2925
- this.openDeeplinkIfNeeded();
3148
+ this.openSimpleDeeplinkIfNeeded();
2926
3149
  }, 250);
2927
3150
  } else {
2928
3151
  this.dappClient.once(
@@ -3005,6 +3228,53 @@ handleConnection_fn = function(promise, scopes, transportType) {
3005
3228
  }));
3006
3229
  });
3007
3230
  };
3231
+ getCaipSession_fn = function() {
3232
+ return __async(this, null, function* () {
3233
+ let sessionData = {
3234
+ sessionScopes: {},
3235
+ sessionProperties: {}
3236
+ };
3237
+ if (this.status === "connected") {
3238
+ const response = yield this.transport.request({
3239
+ method: "wallet_getSession"
3240
+ });
3241
+ if (response.result) {
3242
+ sessionData = response.result;
3243
+ }
3244
+ }
3245
+ return sessionData;
3246
+ });
3247
+ };
3248
+ openConnectDeeplinkIfNeeded_fn = function() {
3249
+ return __async(this, null, function* () {
3250
+ var _a2, _b;
3251
+ const { ui } = this.options;
3252
+ const { showInstallModal = false } = ui != null ? ui : {};
3253
+ const secure = isSecure();
3254
+ const shouldOpenDeeplink = secure && !showInstallModal;
3255
+ if (!shouldOpenDeeplink) {
3256
+ return;
3257
+ }
3258
+ const storedSessionRequest = yield (_a2 = __privateGet(this, _transport2)) == null ? void 0 : _a2.getStoredPendingSessionRequest();
3259
+ if (!storedSessionRequest) {
3260
+ return;
3261
+ }
3262
+ const connectionRequest = {
3263
+ sessionRequest: storedSessionRequest,
3264
+ metadata: {
3265
+ dapp: this.options.dapp,
3266
+ sdk: { version: getVersion(), platform: getPlatformType() }
3267
+ }
3268
+ };
3269
+ const deeplink = this.options.ui.factory.createConnectionDeeplink(connectionRequest);
3270
+ const universalLink = this.options.ui.factory.createConnectionUniversalLink(connectionRequest);
3271
+ if ((_b = this.options.mobile) == null ? void 0 : _b.preferredOpenLink) {
3272
+ this.options.mobile.preferredOpenLink(deeplink, "_self");
3273
+ } else {
3274
+ openDeeplink(this.options, deeplink, universalLink);
3275
+ }
3276
+ });
3277
+ };
3008
3278
  var MetaMaskConnectMultichain = _MetaMaskConnectMultichain;
3009
3279
 
3010
3280
  // src/store/index.ts