@metamask/connect-multichain 0.4.0 → 0.5.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 (85) hide show
  1. package/CHANGELOG.md +26 -1
  2. package/dist/browser/es/connect-multichain.d.mts +26 -9
  3. package/dist/browser/es/connect-multichain.mjs +341 -78
  4. package/dist/browser/es/connect-multichain.mjs.map +1 -1
  5. package/dist/browser/es/metafile-esm.json +1 -1
  6. package/dist/browser/iife/connect-multichain.d.ts +26 -9
  7. package/dist/browser/iife/connect-multichain.js +961 -151
  8. package/dist/browser/iife/connect-multichain.js.map +1 -1
  9. package/dist/browser/iife/metafile-iife.json +1 -1
  10. package/dist/browser/umd/connect-multichain.d.ts +26 -9
  11. package/dist/browser/umd/connect-multichain.js +341 -78
  12. package/dist/browser/umd/connect-multichain.js.map +1 -1
  13. package/dist/browser/umd/metafile-cjs.json +1 -1
  14. package/dist/node/cjs/connect-multichain.d.ts +26 -9
  15. package/dist/node/cjs/connect-multichain.js +342 -79
  16. package/dist/node/cjs/connect-multichain.js.map +1 -1
  17. package/dist/node/cjs/metafile-cjs.json +1 -1
  18. package/dist/node/es/connect-multichain.d.mts +26 -9
  19. package/dist/node/es/connect-multichain.mjs +341 -78
  20. package/dist/node/es/connect-multichain.mjs.map +1 -1
  21. package/dist/node/es/metafile-esm.json +1 -1
  22. package/dist/react-native/es/connect-multichain.d.mts +26 -9
  23. package/dist/react-native/es/connect-multichain.mjs +328 -69
  24. package/dist/react-native/es/connect-multichain.mjs.map +1 -1
  25. package/dist/react-native/es/metafile-esm.json +1 -1
  26. package/dist/src/domain/multichain/index.d.ts +4 -4
  27. package/dist/src/domain/multichain/index.d.ts.map +1 -1
  28. package/dist/src/domain/multichain/index.js.map +1 -1
  29. package/dist/src/domain/multichain/types.d.ts +4 -3
  30. package/dist/src/domain/multichain/types.d.ts.map +1 -1
  31. package/dist/src/domain/ui/types.d.ts +7 -0
  32. package/dist/src/domain/ui/types.d.ts.map +1 -1
  33. package/dist/src/domain/ui/types.js.map +1 -1
  34. package/dist/src/index.browser.d.ts +1 -1
  35. package/dist/src/index.browser.d.ts.map +1 -1
  36. package/dist/src/index.browser.js +1 -1
  37. package/dist/src/index.browser.js.map +1 -1
  38. package/dist/src/index.native.d.ts +1 -1
  39. package/dist/src/index.native.d.ts.map +1 -1
  40. package/dist/src/index.native.js +2 -2
  41. package/dist/src/index.native.js.map +1 -1
  42. package/dist/src/index.node.d.ts +1 -1
  43. package/dist/src/index.node.d.ts.map +1 -1
  44. package/dist/src/index.node.js +1 -1
  45. package/dist/src/index.node.js.map +1 -1
  46. package/dist/src/multichain/index.d.ts +6 -6
  47. package/dist/src/multichain/index.d.ts.map +1 -1
  48. package/dist/src/multichain/index.js +103 -43
  49. package/dist/src/multichain/index.js.map +1 -1
  50. package/dist/src/multichain/transports/default/index.d.ts +2 -1
  51. package/dist/src/multichain/transports/default/index.d.ts.map +1 -1
  52. package/dist/src/multichain/transports/default/index.js +1 -0
  53. package/dist/src/multichain/transports/default/index.js.map +1 -1
  54. package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts +21 -0
  55. package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts.map +1 -0
  56. package/dist/src/multichain/transports/multichainApiClientWrapper/index.js +159 -0
  57. package/dist/src/multichain/transports/multichainApiClientWrapper/index.js.map +1 -0
  58. package/dist/src/multichain/transports/mwp/index.d.ts +4 -1
  59. package/dist/src/multichain/transports/mwp/index.d.ts.map +1 -1
  60. package/dist/src/multichain/transports/mwp/index.js +54 -2
  61. package/dist/src/multichain/transports/mwp/index.js.map +1 -1
  62. package/dist/src/ui/ModalFactory.d.ts +54 -0
  63. package/dist/src/ui/ModalFactory.d.ts.map +1 -0
  64. package/dist/src/ui/ModalFactory.js +171 -0
  65. package/dist/src/ui/ModalFactory.js.map +1 -0
  66. package/dist/src/ui/index.d.ts +14 -38
  67. package/dist/src/ui/index.d.ts.map +1 -1
  68. package/dist/src/ui/index.js +24 -142
  69. package/dist/src/ui/index.js.map +1 -1
  70. package/dist/src/ui/index.native.d.ts +13 -0
  71. package/dist/src/ui/index.native.d.ts.map +1 -0
  72. package/dist/src/ui/{preload.native.js → index.native.js} +12 -6
  73. package/dist/src/ui/index.native.js.map +1 -0
  74. package/dist/src/ui/modals/base/AbstractInstallModal.d.ts.map +1 -1
  75. package/dist/src/ui/modals/base/AbstractInstallModal.js +0 -4
  76. package/dist/src/ui/modals/base/AbstractInstallModal.js.map +1 -1
  77. package/dist/types/connect-multichain.d.ts +26 -9
  78. package/package.json +4 -2
  79. package/dist/src/ui/preload.native.d.ts +0 -5
  80. package/dist/src/ui/preload.native.d.ts.map +0 -1
  81. package/dist/src/ui/preload.native.js.map +0 -1
  82. package/dist/src/ui/preload.web.d.ts +0 -5
  83. package/dist/src/ui/preload.web.d.ts.map +0 -1
  84. package/dist/src/ui/preload.web.js +0 -27
  85. package/dist/src/ui/preload.web.js.map +0 -1
@@ -955,11 +955,6 @@ var init_AbstractInstallModal = __esm({
955
955
  `[UI: InstallModal-nodejs()] \u274C Error generating new QR code: ${error}`
956
956
  );
957
957
  }
958
- } else {
959
- const generateQRCode = yield this.options.generateQRCode(
960
- currentConnectionRequest
961
- );
962
- this.renderQRCode(generateQRCode, currentConnectionRequest);
963
958
  }
964
959
  }), 1e3);
965
960
  }
@@ -1446,7 +1441,8 @@ var DefaultTransport = class {
1446
1441
  getValidAccounts((_g = options == null ? void 0 : options.caipAccountIds) != null ? _g : [])
1447
1442
  );
1448
1443
  const createSessionParams = {
1449
- optionalScopes
1444
+ optionalScopes,
1445
+ sessionProperties: options == null ? void 0 : options.sessionProperties
1450
1446
  };
1451
1447
  const response = yield this.request(
1452
1448
  { method: "wallet_createSession", params: createSessionParams },
@@ -1588,6 +1584,7 @@ var MULTICHAIN_PROVIDER_STREAM_NAME = "metamask-multichain-provider";
1588
1584
  var DEFAULT_REQUEST_TIMEOUT2 = 60 * 1e3;
1589
1585
  var CONNECTION_GRACE_PERIOD = 60 * 1e3;
1590
1586
  var DEFAULT_CONNECTION_TIMEOUT = DEFAULT_REQUEST_TIMEOUT2 + CONNECTION_GRACE_PERIOD;
1587
+ var DEFAULT_RESUME_TIMEOUT = 10 * 1e3;
1591
1588
  var SESSION_STORE_KEY = "cache_wallet_getSession";
1592
1589
  var ACCOUNTS_STORE_KEY = "cache_eth_accounts";
1593
1590
  var CHAIN_STORE_KEY = "cache_eth_chainId";
@@ -1604,7 +1601,8 @@ var logger = createLogger("metamask-sdk:transport");
1604
1601
  var MWPTransport = class {
1605
1602
  constructor(dappClient, kvstore, options = {
1606
1603
  requestTimeout: DEFAULT_REQUEST_TIMEOUT2,
1607
- connectionTimeout: DEFAULT_CONNECTION_TIMEOUT
1604
+ connectionTimeout: DEFAULT_CONNECTION_TIMEOUT,
1605
+ resumeTimeout: DEFAULT_RESUME_TIMEOUT
1608
1606
  }) {
1609
1607
  this.dappClient = dappClient;
1610
1608
  this.kvstore = kvstore;
@@ -1679,6 +1677,13 @@ var MWPTransport = class {
1679
1677
  )
1680
1678
  );
1681
1679
  }
1680
+ if (message.data.method === "wallet_sessionChanged") {
1681
+ const notification = message.data;
1682
+ const response = {
1683
+ result: notification.params
1684
+ };
1685
+ this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));
1686
+ }
1682
1687
  this.notifyCallbacks(message.data);
1683
1688
  }
1684
1689
  }
@@ -1688,6 +1693,7 @@ var MWPTransport = class {
1688
1693
  return __async(this, null, function* () {
1689
1694
  var _a2, _b, _c, _d, _e, _f, _g;
1690
1695
  try {
1696
+ yield this.waitForWalletSessionIfNotCached();
1691
1697
  const sessionRequest = yield this.request({
1692
1698
  method: "wallet_getSession"
1693
1699
  });
@@ -1792,7 +1798,7 @@ var MWPTransport = class {
1792
1798
  }
1793
1799
  let timeout;
1794
1800
  let initialConnectionMessageHandler;
1795
- const connectionPromise = new Promise((resolve, reject) => {
1801
+ const connectionPromise = new Promise((resolve, reject) => __async(this, null, function* () {
1796
1802
  let connection;
1797
1803
  if (session) {
1798
1804
  connection = new Promise((resumeResolve, resumeReject) => {
@@ -1815,7 +1821,8 @@ var MWPTransport = class {
1815
1821
  getValidAccounts((_b = options == null ? void 0 : options.caipAccountIds) != null ? _b : [])
1816
1822
  );
1817
1823
  const sessionRequest = {
1818
- optionalScopes
1824
+ optionalScopes,
1825
+ sessionProperties: options == null ? void 0 : options.sessionProperties
1819
1826
  };
1820
1827
  const request = {
1821
1828
  jsonrpc: "2.0",
@@ -1870,7 +1877,7 @@ var MWPTransport = class {
1870
1877
  reject(new TransportTimeoutError());
1871
1878
  }, this.options.connectionTimeout);
1872
1879
  connection.then(resolve).catch(reject);
1873
- });
1880
+ }));
1874
1881
  return connectionPromise.catch((error) => {
1875
1882
  throw error;
1876
1883
  }).finally(() => {
@@ -2055,6 +2062,43 @@ var MWPTransport = class {
2055
2062
  }
2056
2063
  });
2057
2064
  }
2065
+ // This method checks if an existing CAIP session response is cached or waits for one
2066
+ // to be received from the wallet if not cached. This is necessary because there is an edge
2067
+ // case during the initial connection flow where after the user has accepted the permission approval
2068
+ // and returned back to the dapp from the wallet, the dapp page may have gotten unloaded and refreshed.
2069
+ // When it is unloaded and refreshed, it will try to resume the session by making a request for wallet_getSession
2070
+ // which should resolve from cache, but because a race condition makes it possible for the response from the wallet
2071
+ // for the initial wallet_createSession connection request to not have been handled and cached yet. This results
2072
+ // in the wallet_getSession request never resolving unless we wait for it explicitly as done in this method.
2073
+ waitForWalletSessionIfNotCached() {
2074
+ return __async(this, null, function* () {
2075
+ const cachedWalletGetSessionResponse = yield this.kvstore.get(SESSION_STORE_KEY);
2076
+ if (cachedWalletGetSessionResponse) {
2077
+ return;
2078
+ }
2079
+ let unsubscribe;
2080
+ const responsePromise = new Promise((resolve) => {
2081
+ unsubscribe = this.onNotification((message) => {
2082
+ if (typeof message === "object" && message !== null) {
2083
+ if ("data" in message) {
2084
+ const messagePayload = message.data;
2085
+ if (messagePayload.method === "wallet_getSession" || messagePayload.method === "wallet_sessionChanged") {
2086
+ unsubscribe();
2087
+ resolve();
2088
+ }
2089
+ }
2090
+ }
2091
+ });
2092
+ });
2093
+ const timeoutPromise = new Promise((_resolve, reject) => {
2094
+ setTimeout(() => {
2095
+ unsubscribe();
2096
+ reject(new TransportTimeoutError());
2097
+ }, this.options.resumeTimeout);
2098
+ });
2099
+ return Promise.race([responsePromise, timeoutPromise]);
2100
+ });
2101
+ }
2058
2102
  };
2059
2103
 
2060
2104
  // src/multichain/transports/mwp/KeyManager.ts
@@ -2086,8 +2130,166 @@ var keymanager = new KeyManager();
2086
2130
 
2087
2131
  // src/multichain/index.ts
2088
2132
  init_utils();
2133
+
2134
+ // src/multichain/transports/multichainApiClientWrapper/index.ts
2135
+ import { providerErrors } from "@metamask/rpc-errors";
2136
+ var MAX = 4294967295;
2137
+ var idCounter = Math.floor(Math.random() * MAX);
2138
+ var getUniqueId = () => {
2139
+ idCounter = (idCounter + 1) % MAX;
2140
+ return idCounter;
2141
+ };
2142
+ var _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn, walletGetSession_fn, walletRevokeSession_fn, walletInvokeMethod_fn;
2143
+ var MultichainApiClientWrapperTransport = class {
2144
+ constructor(multichainSDK) {
2145
+ this.multichainSDK = multichainSDK;
2146
+ __privateAdd(this, _MultichainApiClientWrapperTransport_instances);
2147
+ this.requestId = getUniqueId();
2148
+ this.notificationCallbacks = /* @__PURE__ */ new Set();
2149
+ }
2150
+ isTransportDefined() {
2151
+ try {
2152
+ return Boolean(this.multichainSDK.transport);
2153
+ } catch (error) {
2154
+ return false;
2155
+ }
2156
+ }
2157
+ clearNotificationCallbacks() {
2158
+ this.notificationCallbacks.clear();
2159
+ }
2160
+ notifyCallbacks(data) {
2161
+ this.notificationCallbacks.forEach((callback) => {
2162
+ callback(data);
2163
+ });
2164
+ }
2165
+ setupNotifcationListener() {
2166
+ this.multichainSDK.transport.onNotification(
2167
+ this.notifyCallbacks.bind(this)
2168
+ );
2169
+ }
2170
+ connect() {
2171
+ return __async(this, null, function* () {
2172
+ console.log("\u{1F4DA} connect");
2173
+ return Promise.resolve();
2174
+ });
2175
+ }
2176
+ disconnect() {
2177
+ return __async(this, null, function* () {
2178
+ return Promise.resolve();
2179
+ });
2180
+ }
2181
+ isConnected() {
2182
+ return true;
2183
+ }
2184
+ request(_0) {
2185
+ return __async(this, arguments, function* (params, _options = {}) {
2186
+ const id = this.requestId++;
2187
+ const requestPayload = __spreadValues({
2188
+ id,
2189
+ jsonrpc: "2.0"
2190
+ }, params);
2191
+ switch (requestPayload.method) {
2192
+ case "wallet_createSession":
2193
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn).call(this, requestPayload);
2194
+ case "wallet_getSession":
2195
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletGetSession_fn).call(this, requestPayload);
2196
+ case "wallet_revokeSession":
2197
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletRevokeSession_fn).call(this, requestPayload);
2198
+ case "wallet_invokeMethod":
2199
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletInvokeMethod_fn).call(this, requestPayload);
2200
+ default:
2201
+ throw new Error(`Unsupported method: ${requestPayload.method}`);
2202
+ }
2203
+ throw new Error(`Unknown method: ${requestPayload.method}`);
2204
+ });
2205
+ }
2206
+ onNotification(callback) {
2207
+ if (!this.isTransportDefined()) {
2208
+ this.notificationCallbacks.add(callback);
2209
+ return () => {
2210
+ this.notificationCallbacks.delete(callback);
2211
+ };
2212
+ }
2213
+ return this.multichainSDK.transport.onNotification(callback);
2214
+ }
2215
+ };
2216
+ _MultichainApiClientWrapperTransport_instances = new WeakSet();
2217
+ walletCreateSession_fn = function(request) {
2218
+ return __async(this, null, function* () {
2219
+ console.log("\u{1F4DA} #walletCreateSession", request);
2220
+ const createSessionParams = request.params;
2221
+ const scopes = Object.keys(__spreadValues(__spreadValues({}, createSessionParams.optionalScopes), createSessionParams.requiredScopes));
2222
+ const scopeAccounts = [];
2223
+ scopes.forEach((scope) => {
2224
+ var _a2, _b, _c, _d;
2225
+ const requiredScope = (_a2 = createSessionParams.requiredScopes) == null ? void 0 : _a2[scope];
2226
+ const optionalScope = (_b = createSessionParams.optionalScopes) == null ? void 0 : _b[scope];
2227
+ if (requiredScope) {
2228
+ scopeAccounts.push(...(_c = requiredScope.accounts) != null ? _c : []);
2229
+ }
2230
+ if (optionalScope) {
2231
+ scopeAccounts.push(...(_d = optionalScope.accounts) != null ? _d : []);
2232
+ }
2233
+ });
2234
+ const accounts = [...new Set(scopeAccounts)];
2235
+ console.log("\u{1F4DA} SDK connect");
2236
+ yield this.multichainSDK.connect(
2237
+ scopes,
2238
+ accounts,
2239
+ createSessionParams.sessionProperties
2240
+ );
2241
+ console.log("\u{1F4DA} SDK connected");
2242
+ return this.multichainSDK.transport.request({
2243
+ method: "wallet_getSession"
2244
+ });
2245
+ });
2246
+ };
2247
+ walletGetSession_fn = function(request) {
2248
+ return __async(this, null, function* () {
2249
+ if (!this.isTransportDefined()) {
2250
+ return {
2251
+ jsonrpc: "2.0",
2252
+ id: request.id,
2253
+ result: {
2254
+ sessionScopes: {}
2255
+ }
2256
+ };
2257
+ }
2258
+ return this.multichainSDK.transport.request({
2259
+ method: "wallet_getSession"
2260
+ });
2261
+ });
2262
+ };
2263
+ walletRevokeSession_fn = function(request) {
2264
+ return __async(this, null, function* () {
2265
+ if (!this.isTransportDefined()) {
2266
+ return { jsonrpc: "2.0", id: request.id, result: true };
2267
+ }
2268
+ try {
2269
+ this.multichainSDK.disconnect();
2270
+ return { jsonrpc: "2.0", id: request.id, result: true };
2271
+ } catch (error) {
2272
+ return { jsonrpc: "2.0", id: request.id, result: false };
2273
+ }
2274
+ });
2275
+ };
2276
+ walletInvokeMethod_fn = function(request) {
2277
+ return __async(this, null, function* () {
2278
+ if (!this.isTransportDefined()) {
2279
+ return { error: providerErrors.unauthorized() };
2280
+ }
2281
+ const result = this.multichainSDK.invokeMethod(
2282
+ request.params
2283
+ );
2284
+ return {
2285
+ result
2286
+ };
2287
+ });
2288
+ };
2289
+
2290
+ // src/multichain/index.ts
2089
2291
  var logger2 = createLogger("metamask-sdk:core");
2090
- var _a, _provider, _transport2, _dappClient, _beforeUnloadListener, _listener, _sdkInfo, _MultichainSDK_instances, setupAnalytics_fn, onTransportNotification_fn, getStoredTransport_fn, setupTransport_fn, init_fn, createDappClient_fn, setupMWP_fn, onBeforeUnload_fn, createBeforeUnloadListener_fn, renderInstallModalAsync_fn, showInstallModal_fn, setupDefaultTransport_fn, deeplinkConnect_fn, handleConnection_fn;
2292
+ var _a, _provider, _providerTransportWrapper, _transport2, _dappClient, _beforeUnloadListener, _listener, _sdkInfo, _MultichainSDK_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;
2091
2293
  var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2092
2294
  constructor(options) {
2093
2295
  var _a2, _b, _c, _d, _e, _f;
@@ -2106,32 +2308,28 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2106
2308
  super(allOptions);
2107
2309
  __privateAdd(this, _MultichainSDK_instances);
2108
2310
  __privateAdd(this, _provider);
2311
+ __privateAdd(this, _providerTransportWrapper);
2109
2312
  __privateAdd(this, _transport2);
2110
2313
  __privateAdd(this, _dappClient);
2111
2314
  __privateAdd(this, _beforeUnloadListener);
2112
- this._state = "pending";
2315
+ this._status = "pending";
2113
2316
  __privateAdd(this, _listener);
2114
2317
  __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}`);
2318
+ __privateSet(this, _providerTransportWrapper, new MultichainApiClientWrapperTransport(this));
2319
+ __privateSet(this, _provider, getMultichainClient({ transport: __privateGet(this, _providerTransportWrapper) }));
2115
2320
  }
2116
- get state() {
2117
- return this._state;
2321
+ get status() {
2322
+ return this._status;
2118
2323
  }
2119
- set state(value) {
2324
+ set status(value) {
2120
2325
  var _a2, _b;
2121
- this._state = value;
2326
+ this._status = value;
2122
2327
  (_b = (_a2 = this.options.transport) == null ? void 0 : _a2.onNotification) == null ? void 0 : _b.call(_a2, {
2123
2328
  method: "stateChanged",
2124
2329
  params: value
2125
2330
  });
2126
2331
  }
2127
2332
  get provider() {
2128
- if (!__privateGet(this, _provider) && __privateGet(this, _transport2)) {
2129
- __privateSet(this, _provider, getMultichainClient({ transport: __privateGet(this, _transport2) }));
2130
- return __privateGet(this, _provider);
2131
- }
2132
- if (!__privateGet(this, _provider)) {
2133
- throw new Error("Provider not initialized, establish connection first");
2134
- }
2135
2333
  return __privateGet(this, _provider);
2136
2334
  }
2137
2335
  get transport() {
@@ -2167,10 +2365,11 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2167
2365
  return instance;
2168
2366
  });
2169
2367
  }
2170
- connect(scopes, caipAccountIds, forceRequest) {
2368
+ // TODO: make this into param object
2369
+ connect(scopes, caipAccountIds, sessionProperties, forceRequest) {
2171
2370
  return __async(this, null, function* () {
2172
2371
  var _a2;
2173
- if (this.state !== "connected") {
2372
+ if (this.status !== "connected") {
2174
2373
  yield this.disconnect();
2175
2374
  }
2176
2375
  const { ui } = this.options;
@@ -2202,7 +2401,7 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2202
2401
  logger2("Error tracking connection_initiated event", error);
2203
2402
  }
2204
2403
  if (((_a2 = __privateGet(this, _transport2)) == null ? void 0 : _a2.isConnected()) && !secure) {
2205
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateGet(this, _transport2).connect({ scopes, caipAccountIds, forceRequest }).then(() => __async(this, null, function* () {
2404
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateGet(this, _transport2).connect({ scopes, caipAccountIds, sessionProperties, forceRequest }).then(() => __async(this, null, function* () {
2206
2405
  if (__privateGet(this, _transport2) instanceof MWPTransport) {
2207
2406
  return this.storage.setTransport("mwp" /* MWP */);
2208
2407
  }
@@ -2211,18 +2410,18 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2211
2410
  }
2212
2411
  if (platformType === "in-app-browser" /* MetaMaskMobileWebview */) {
2213
2412
  const defaultTransport = yield __privateMethod(this, _MultichainSDK_instances, setupDefaultTransport_fn).call(this);
2214
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, forceRequest }), scopes, transportType);
2413
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, sessionProperties, forceRequest }), scopes, transportType);
2215
2414
  }
2216
2415
  if (isWeb && hasExtensionInstalled && preferExtension) {
2217
2416
  const defaultTransport = yield __privateMethod(this, _MultichainSDK_instances, setupDefaultTransport_fn).call(this);
2218
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, forceRequest }), scopes, transportType);
2417
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, sessionProperties, forceRequest }), scopes, transportType);
2219
2418
  }
2220
2419
  yield __privateMethod(this, _MultichainSDK_instances, setupMWP_fn).call(this);
2221
2420
  const shouldShowInstallModal = hasExtensionInstalled ? showInstallModal : !preferExtension || showInstallModal;
2222
2421
  if (secure && !shouldShowInstallModal) {
2223
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, deeplinkConnect_fn).call(this, scopes, caipAccountIds), scopes, transportType);
2422
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, deeplinkConnect_fn).call(this, scopes, caipAccountIds, sessionProperties), scopes, transportType);
2224
2423
  }
2225
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, showInstallModal_fn).call(this, shouldShowInstallModal, scopes, caipAccountIds), scopes, transportType);
2424
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, showInstallModal_fn).call(this, shouldShowInstallModal, scopes, caipAccountIds, sessionProperties), scopes, transportType);
2226
2425
  });
2227
2426
  }
2228
2427
  emit(event, args) {
@@ -2241,15 +2440,13 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2241
2440
  __privateSet(this, _listener, void 0);
2242
2441
  __privateSet(this, _beforeUnloadListener, void 0);
2243
2442
  __privateSet(this, _transport2, void 0);
2244
- __privateSet(this, _provider, void 0);
2443
+ __privateGet(this, _providerTransportWrapper).clearNotificationCallbacks();
2245
2444
  __privateSet(this, _dappClient, void 0);
2246
2445
  });
2247
2446
  }
2248
2447
  invokeMethod(request) {
2249
2448
  return __async(this, null, function* () {
2250
- var _a2;
2251
2449
  const { transport, options } = this;
2252
- (_a2 = __privateGet(this, _provider)) != null ? _a2 : __privateSet(this, _provider, getMultichainClient({ transport }));
2253
2450
  const rpcClient = new RpcClient(options, __privateGet(this, _sdkInfo));
2254
2451
  const requestRouter = new RequestRouter(transport, rpcClient, options);
2255
2452
  return requestRouter.invokeMethod(request);
@@ -2278,6 +2475,7 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2278
2475
  }
2279
2476
  };
2280
2477
  _provider = new WeakMap();
2478
+ _providerTransportWrapper = new WeakMap();
2281
2479
  _transport2 = new WeakMap();
2282
2480
  _dappClient = new WeakMap();
2283
2481
  _beforeUnloadListener = new WeakMap();
@@ -2324,6 +2522,7 @@ getStoredTransport_fn = function() {
2324
2522
  if (hasExtensionInstalled) {
2325
2523
  const apiTransport = new DefaultTransport();
2326
2524
  __privateSet(this, _transport2, apiTransport);
2525
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2327
2526
  __privateSet(this, _listener, apiTransport.onNotification(
2328
2527
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2329
2528
  ));
@@ -2335,6 +2534,7 @@ getStoredTransport_fn = function() {
2335
2534
  const apiTransport = new MWPTransport(dappClient, kvstore);
2336
2535
  __privateSet(this, _dappClient, dappClient);
2337
2536
  __privateSet(this, _transport2, apiTransport);
2537
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2338
2538
  __privateSet(this, _listener, apiTransport.onNotification(
2339
2539
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2340
2540
  ));
@@ -2350,17 +2550,17 @@ setupTransport_fn = function() {
2350
2550
  const transport = yield __privateMethod(this, _MultichainSDK_instances, getStoredTransport_fn).call(this);
2351
2551
  if (transport) {
2352
2552
  if (!this.transport.isConnected()) {
2353
- this.state = "connecting";
2553
+ this.status = "connecting";
2354
2554
  yield this.transport.connect();
2355
2555
  }
2356
- this.state = "connected";
2556
+ this.status = "connected";
2357
2557
  if (this.transport instanceof MWPTransport) {
2358
2558
  yield this.storage.setTransport("mwp" /* MWP */);
2359
2559
  } else {
2360
2560
  yield this.storage.setTransport("browser" /* Browser */);
2361
2561
  }
2362
2562
  } else {
2363
- this.state = "loaded";
2563
+ this.status = "loaded";
2364
2564
  }
2365
2565
  });
2366
2566
  };
@@ -2388,7 +2588,7 @@ init_fn = function() {
2388
2588
  }
2389
2589
  } catch (error) {
2390
2590
  yield this.storage.removeTransport();
2391
- this.state = "pending";
2591
+ this.status = "pending";
2392
2592
  logger2("MetaMaskSDK error during initialization", error);
2393
2593
  }
2394
2594
  });
@@ -2420,6 +2620,7 @@ setupMWP_fn = function() {
2420
2620
  __privateSet(this, _dappClient, dappClient);
2421
2621
  const apiTransport = new MWPTransport(dappClient, kvstore);
2422
2622
  __privateSet(this, _transport2, apiTransport);
2623
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2423
2624
  __privateSet(this, _listener, this.transport.onNotification(
2424
2625
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2425
2626
  ));
@@ -2447,7 +2648,7 @@ createBeforeUnloadListener_fn = function() {
2447
2648
  }
2448
2649
  };
2449
2650
  };
2450
- renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds) {
2651
+ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds, sessionProperties) {
2451
2652
  return __async(this, null, function* () {
2452
2653
  return new Promise((resolve, reject) => {
2453
2654
  this.options.ui.factory.renderInstallModal(
@@ -2475,19 +2676,19 @@ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds)
2475
2676
  (() => __async(this, null, function* () {
2476
2677
  var _a2;
2477
2678
  try {
2478
- yield this.transport.connect({ scopes, caipAccountIds });
2679
+ yield this.transport.connect({ scopes, caipAccountIds, sessionProperties });
2479
2680
  yield this.options.ui.factory.unload();
2480
2681
  (_a2 = this.options.ui.factory.modal) == null ? void 0 : _a2.unmount();
2481
- this.state = "connected";
2682
+ this.status = "connected";
2482
2683
  yield this.storage.setTransport("mwp" /* MWP */);
2483
2684
  } catch (error) {
2484
2685
  if (error instanceof ProtocolError) {
2485
2686
  if (error.code !== ErrorCode.REQUEST_EXPIRED) {
2486
- this.state = "disconnected";
2687
+ this.status = "disconnected";
2487
2688
  reject(error);
2488
2689
  }
2489
2690
  } else {
2490
- this.state = "disconnected";
2691
+ this.status = "disconnected";
2491
2692
  reject(
2492
2693
  error instanceof Error ? error : new Error(String(error))
2493
2694
  );
@@ -2505,33 +2706,83 @@ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds)
2505
2706
  yield this.storage.setTransport("mwp" /* MWP */);
2506
2707
  resolve();
2507
2708
  }
2508
- })
2709
+ }),
2710
+ (uri) => {
2711
+ this.emit("display_uri", uri);
2712
+ }
2509
2713
  ).catch((error) => {
2510
2714
  reject(error instanceof Error ? error : new Error(String(error)));
2511
2715
  });
2512
2716
  });
2513
2717
  });
2514
2718
  };
2515
- showInstallModal_fn = function(desktopPreferred, scopes, caipAccountIds) {
2719
+ showInstallModal_fn = function(desktopPreferred, scopes, caipAccountIds, sessionProperties) {
2516
2720
  return __async(this, null, function* () {
2517
2721
  var _a2;
2518
2722
  (_a2 = __privateGet(this, _beforeUnloadListener)) != null ? _a2 : __privateSet(this, _beforeUnloadListener, __privateMethod(this, _MultichainSDK_instances, createBeforeUnloadListener_fn).call(this));
2519
- yield __privateMethod(this, _MultichainSDK_instances, renderInstallModalAsync_fn).call(this, desktopPreferred, scopes, caipAccountIds);
2723
+ if (this.options.ui.headless) {
2724
+ yield __privateMethod(this, _MultichainSDK_instances, headlessConnect_fn).call(this, scopes, caipAccountIds, sessionProperties);
2725
+ } else {
2726
+ yield __privateMethod(this, _MultichainSDK_instances, renderInstallModalAsync_fn).call(this, desktopPreferred, scopes, caipAccountIds, sessionProperties);
2727
+ }
2728
+ });
2729
+ };
2730
+ headlessConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
2731
+ return __async(this, null, function* () {
2732
+ return new Promise((resolve, reject) => {
2733
+ if (this.dappClient.state === "CONNECTED" || this.dappClient.state === "CONNECTING") {
2734
+ this.dappClient.disconnect().catch(() => {
2735
+ });
2736
+ }
2737
+ this.dappClient.on(
2738
+ "session_request",
2739
+ (sessionRequest) => {
2740
+ const connectionRequest = {
2741
+ sessionRequest,
2742
+ metadata: {
2743
+ dapp: this.options.dapp,
2744
+ sdk: {
2745
+ version: getVersion(),
2746
+ platform: getPlatformType()
2747
+ }
2748
+ }
2749
+ };
2750
+ const deeplink = this.options.ui.factory.createConnectionDeeplink(connectionRequest);
2751
+ this.emit("display_uri", deeplink);
2752
+ }
2753
+ );
2754
+ this.transport.connect({ scopes, caipAccountIds, sessionProperties }).then(() => __async(this, null, function* () {
2755
+ this.status = "connected";
2756
+ yield this.storage.setTransport("mwp" /* MWP */);
2757
+ resolve();
2758
+ })).catch((error) => __async(this, null, function* () {
2759
+ if (error instanceof ProtocolError) {
2760
+ this.status = "disconnected";
2761
+ yield this.storage.removeTransport();
2762
+ reject(error);
2763
+ } else {
2764
+ this.status = "disconnected";
2765
+ yield this.storage.removeTransport();
2766
+ reject(error instanceof Error ? error : new Error(String(error)));
2767
+ }
2768
+ }));
2769
+ });
2520
2770
  });
2521
2771
  };
2522
2772
  setupDefaultTransport_fn = function() {
2523
2773
  return __async(this, null, function* () {
2524
- this.state = "connecting";
2774
+ this.status = "connecting";
2525
2775
  yield this.storage.setTransport("browser" /* Browser */);
2526
2776
  const transport = new DefaultTransport();
2527
2777
  __privateSet(this, _listener, transport.onNotification(
2528
2778
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2529
2779
  ));
2530
2780
  __privateSet(this, _transport2, transport);
2781
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2531
2782
  return transport;
2532
2783
  });
2533
2784
  };
2534
- deeplinkConnect_fn = function(scopes, caipAccountIds) {
2785
+ deeplinkConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
2535
2786
  return __async(this, null, function* () {
2536
2787
  return new Promise((resolve, reject) => {
2537
2788
  const dappClientMessageHandler = (payload) => {
@@ -2574,6 +2825,7 @@ deeplinkConnect_fn = function(scopes, caipAccountIds) {
2574
2825
  const universalLink = this.options.ui.factory.createConnectionUniversalLink(
2575
2826
  connectionRequest
2576
2827
  );
2828
+ this.emit("display_uri", deeplink);
2577
2829
  if ((_a2 = this.options.mobile) == null ? void 0 : _a2.preferredOpenLink) {
2578
2830
  this.options.mobile.preferredOpenLink(deeplink, "_self");
2579
2831
  } else {
@@ -2582,7 +2834,7 @@ deeplinkConnect_fn = function(scopes, caipAccountIds) {
2582
2834
  }
2583
2835
  );
2584
2836
  }
2585
- return this.transport.connect({ scopes, caipAccountIds }).then(resolve).catch((error) => __async(this, null, function* () {
2837
+ return this.transport.connect({ scopes, caipAccountIds, sessionProperties }).then(resolve).catch((error) => __async(this, null, function* () {
2586
2838
  yield this.storage.removeTransport();
2587
2839
  this.dappClient.off("message", dappClientMessageHandler);
2588
2840
  reject(error instanceof Error ? error : new Error(String(error)));
@@ -2596,9 +2848,9 @@ deeplinkConnect_fn = function(scopes, caipAccountIds) {
2596
2848
  };
2597
2849
  handleConnection_fn = function(promise, scopes, transportType) {
2598
2850
  return __async(this, null, function* () {
2599
- this.state = "connecting";
2851
+ this.status = "connecting";
2600
2852
  return promise.then(() => __async(this, null, function* () {
2601
- this.state = "connected";
2853
+ this.status = "connected";
2602
2854
  try {
2603
2855
  const baseProps = yield getBaseAnalyticsProperties(
2604
2856
  this.options,
@@ -2613,7 +2865,7 @@ handleConnection_fn = function(promise, scopes, transportType) {
2613
2865
  }
2614
2866
  return void 0;
2615
2867
  })).catch((error) => __async(this, null, function* () {
2616
- this.state = "disconnected";
2868
+ this.status = "disconnected";
2617
2869
  try {
2618
2870
  const baseProps = yield getBaseAnalyticsProperties(
2619
2871
  this.options,
@@ -2817,19 +3069,11 @@ var Store = class extends StoreClient {
2817
3069
  }
2818
3070
  };
2819
3071
 
2820
- // src/ui/index.ts
3072
+ // src/ui/ModalFactory.ts
2821
3073
  import MetaMaskOnboarding from "@metamask/onboarding";
2822
3074
  init_domain();
2823
3075
  init_utils();
2824
-
2825
- // src/ui/preload.native.ts
2826
- function preload() {
2827
- return __async(this, null, function* () {
2828
- });
2829
- }
2830
-
2831
- // src/ui/index.ts
2832
- var ModalFactory = class {
3076
+ var BaseModalFactory = class {
2833
3077
  /**
2834
3078
  * Creates a new modal factory instance.
2835
3079
  *
@@ -2918,15 +3162,17 @@ var ModalFactory = class {
2918
3162
  onStartDesktopOnboarding() {
2919
3163
  new MetaMaskOnboarding().startOnboarding();
2920
3164
  }
2921
- renderInstallModal(showInstallModal, createConnectionRequest, successCallback) {
3165
+ renderInstallModal(showInstallModal, createConnectionRequest, successCallback, onDisplayUri) {
2922
3166
  return __async(this, null, function* () {
2923
- var _a2;
3167
+ var _a2, _b;
2924
3168
  (_a2 = this.modal) == null ? void 0 : _a2.unmount();
2925
- yield preload();
3169
+ yield this.preload();
2926
3170
  this.successCallback = successCallback;
3171
+ this.displayUriCallback = onDisplayUri;
2927
3172
  const parentElement = this.getMountedContainer();
2928
3173
  const connectionRequest = yield createConnectionRequest();
2929
3174
  const qrCodeLink = this.createConnectionDeeplink(connectionRequest);
3175
+ (_b = this.displayUriCallback) == null ? void 0 : _b.call(this, qrCodeLink);
2930
3176
  const modal = new this.options.InstallModal({
2931
3177
  expiresIn: (connectionRequest.sessionRequest.expiresAt - Date.now()) / 1e3,
2932
3178
  connectionRequest,
@@ -2935,11 +3181,15 @@ var ModalFactory = class {
2935
3181
  link: qrCodeLink,
2936
3182
  sdkVersion: getVersion(),
2937
3183
  generateQRCode: (request) => __async(this, null, function* () {
2938
- return this.createConnectionDeeplink(request);
3184
+ var _a3;
3185
+ const newLink = this.createConnectionDeeplink(request);
3186
+ (_a3 = this.displayUriCallback) == null ? void 0 : _a3.call(this, newLink);
3187
+ return newLink;
2939
3188
  }),
2940
3189
  onClose: this.onCloseModal.bind(this),
2941
3190
  startDesktopOnboarding: this.onStartDesktopOnboarding.bind(this),
2942
- createConnectionRequest
3191
+ createConnectionRequest,
3192
+ onDisplayUri: this.displayUriCallback
2943
3193
  });
2944
3194
  this.modal = modal;
2945
3195
  modal.mount();
@@ -2949,7 +3199,7 @@ var ModalFactory = class {
2949
3199
  return __async(this, null, function* () {
2950
3200
  var _a2;
2951
3201
  (_a2 = this.modal) == null ? void 0 : _a2.unmount();
2952
- yield preload();
3202
+ yield this.preload();
2953
3203
  this.successCallback = successCallback;
2954
3204
  const container = this.getMountedContainer();
2955
3205
  const otpCode = yield createOTPCode();
@@ -2967,9 +3217,18 @@ var ModalFactory = class {
2967
3217
  }
2968
3218
  };
2969
3219
 
3220
+ // src/ui/index.native.ts
3221
+ var ModalFactory = class extends BaseModalFactory {
3222
+ // No-op for React Native - web components are not applicable
3223
+ preload() {
3224
+ return __async(this, null, function* () {
3225
+ });
3226
+ }
3227
+ };
3228
+
2970
3229
  // src/index.native.ts
2971
3230
  init_domain();
2972
- var createMetamaskConnect = (options) => __async(null, null, function* () {
3231
+ var createMultichainClient = (options) => __async(null, null, function* () {
2973
3232
  const uiModules = yield Promise.resolve().then(() => (init_rn(), rn_exports));
2974
3233
  let storage;
2975
3234
  if (!options.storage) {
@@ -3002,7 +3261,7 @@ export {
3002
3261
  StoreClient,
3003
3262
  TransportType,
3004
3263
  createLogger,
3005
- createMetamaskConnect,
3264
+ createMultichainClient,
3006
3265
  enableDebug,
3007
3266
  getInfuraRpcUrls,
3008
3267
  getPlatformType,