@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
  }
@@ -1482,7 +1477,8 @@ var DefaultTransport = class {
1482
1477
  getValidAccounts((_g = options == null ? void 0 : options.caipAccountIds) != null ? _g : [])
1483
1478
  );
1484
1479
  const createSessionParams = {
1485
- optionalScopes
1480
+ optionalScopes,
1481
+ sessionProperties: options == null ? void 0 : options.sessionProperties
1486
1482
  };
1487
1483
  const response = yield this.request(
1488
1484
  { method: "wallet_createSession", params: createSessionParams },
@@ -1624,6 +1620,7 @@ var MULTICHAIN_PROVIDER_STREAM_NAME = "metamask-multichain-provider";
1624
1620
  var DEFAULT_REQUEST_TIMEOUT2 = 60 * 1e3;
1625
1621
  var CONNECTION_GRACE_PERIOD = 60 * 1e3;
1626
1622
  var DEFAULT_CONNECTION_TIMEOUT = DEFAULT_REQUEST_TIMEOUT2 + CONNECTION_GRACE_PERIOD;
1623
+ var DEFAULT_RESUME_TIMEOUT = 10 * 1e3;
1627
1624
  var SESSION_STORE_KEY = "cache_wallet_getSession";
1628
1625
  var ACCOUNTS_STORE_KEY = "cache_eth_accounts";
1629
1626
  var CHAIN_STORE_KEY = "cache_eth_chainId";
@@ -1640,7 +1637,8 @@ var logger = createLogger("metamask-sdk:transport");
1640
1637
  var MWPTransport = class {
1641
1638
  constructor(dappClient, kvstore, options = {
1642
1639
  requestTimeout: DEFAULT_REQUEST_TIMEOUT2,
1643
- connectionTimeout: DEFAULT_CONNECTION_TIMEOUT
1640
+ connectionTimeout: DEFAULT_CONNECTION_TIMEOUT,
1641
+ resumeTimeout: DEFAULT_RESUME_TIMEOUT
1644
1642
  }) {
1645
1643
  this.dappClient = dappClient;
1646
1644
  this.kvstore = kvstore;
@@ -1715,6 +1713,13 @@ var MWPTransport = class {
1715
1713
  )
1716
1714
  );
1717
1715
  }
1716
+ if (message.data.method === "wallet_sessionChanged") {
1717
+ const notification = message.data;
1718
+ const response = {
1719
+ result: notification.params
1720
+ };
1721
+ this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));
1722
+ }
1718
1723
  this.notifyCallbacks(message.data);
1719
1724
  }
1720
1725
  }
@@ -1724,6 +1729,7 @@ var MWPTransport = class {
1724
1729
  return __async(this, null, function* () {
1725
1730
  var _a2, _b, _c, _d, _e, _f, _g;
1726
1731
  try {
1732
+ yield this.waitForWalletSessionIfNotCached();
1727
1733
  const sessionRequest = yield this.request({
1728
1734
  method: "wallet_getSession"
1729
1735
  });
@@ -1828,7 +1834,7 @@ var MWPTransport = class {
1828
1834
  }
1829
1835
  let timeout;
1830
1836
  let initialConnectionMessageHandler;
1831
- const connectionPromise = new Promise((resolve, reject) => {
1837
+ const connectionPromise = new Promise((resolve, reject) => __async(this, null, function* () {
1832
1838
  let connection;
1833
1839
  if (session) {
1834
1840
  connection = new Promise((resumeResolve, resumeReject) => {
@@ -1851,7 +1857,8 @@ var MWPTransport = class {
1851
1857
  getValidAccounts((_b = options == null ? void 0 : options.caipAccountIds) != null ? _b : [])
1852
1858
  );
1853
1859
  const sessionRequest = {
1854
- optionalScopes
1860
+ optionalScopes,
1861
+ sessionProperties: options == null ? void 0 : options.sessionProperties
1855
1862
  };
1856
1863
  const request = {
1857
1864
  jsonrpc: "2.0",
@@ -1906,7 +1913,7 @@ var MWPTransport = class {
1906
1913
  reject(new TransportTimeoutError());
1907
1914
  }, this.options.connectionTimeout);
1908
1915
  connection.then(resolve).catch(reject);
1909
- });
1916
+ }));
1910
1917
  return connectionPromise.catch((error) => {
1911
1918
  throw error;
1912
1919
  }).finally(() => {
@@ -2091,6 +2098,43 @@ var MWPTransport = class {
2091
2098
  }
2092
2099
  });
2093
2100
  }
2101
+ // This method checks if an existing CAIP session response is cached or waits for one
2102
+ // to be received from the wallet if not cached. This is necessary because there is an edge
2103
+ // case during the initial connection flow where after the user has accepted the permission approval
2104
+ // and returned back to the dapp from the wallet, the dapp page may have gotten unloaded and refreshed.
2105
+ // When it is unloaded and refreshed, it will try to resume the session by making a request for wallet_getSession
2106
+ // which should resolve from cache, but because a race condition makes it possible for the response from the wallet
2107
+ // for the initial wallet_createSession connection request to not have been handled and cached yet. This results
2108
+ // in the wallet_getSession request never resolving unless we wait for it explicitly as done in this method.
2109
+ waitForWalletSessionIfNotCached() {
2110
+ return __async(this, null, function* () {
2111
+ const cachedWalletGetSessionResponse = yield this.kvstore.get(SESSION_STORE_KEY);
2112
+ if (cachedWalletGetSessionResponse) {
2113
+ return;
2114
+ }
2115
+ let unsubscribe;
2116
+ const responsePromise = new Promise((resolve) => {
2117
+ unsubscribe = this.onNotification((message) => {
2118
+ if (typeof message === "object" && message !== null) {
2119
+ if ("data" in message) {
2120
+ const messagePayload = message.data;
2121
+ if (messagePayload.method === "wallet_getSession" || messagePayload.method === "wallet_sessionChanged") {
2122
+ unsubscribe();
2123
+ resolve();
2124
+ }
2125
+ }
2126
+ }
2127
+ });
2128
+ });
2129
+ const timeoutPromise = new Promise((_resolve, reject) => {
2130
+ setTimeout(() => {
2131
+ unsubscribe();
2132
+ reject(new TransportTimeoutError());
2133
+ }, this.options.resumeTimeout);
2134
+ });
2135
+ return Promise.race([responsePromise, timeoutPromise]);
2136
+ });
2137
+ }
2094
2138
  };
2095
2139
 
2096
2140
  // src/multichain/transports/mwp/KeyManager.ts
@@ -2122,8 +2166,166 @@ var keymanager = new KeyManager();
2122
2166
 
2123
2167
  // src/multichain/index.ts
2124
2168
  init_utils();
2169
+
2170
+ // src/multichain/transports/multichainApiClientWrapper/index.ts
2171
+ import { providerErrors } from "@metamask/rpc-errors";
2172
+ var MAX = 4294967295;
2173
+ var idCounter = Math.floor(Math.random() * MAX);
2174
+ var getUniqueId = () => {
2175
+ idCounter = (idCounter + 1) % MAX;
2176
+ return idCounter;
2177
+ };
2178
+ var _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn, walletGetSession_fn, walletRevokeSession_fn, walletInvokeMethod_fn;
2179
+ var MultichainApiClientWrapperTransport = class {
2180
+ constructor(multichainSDK) {
2181
+ this.multichainSDK = multichainSDK;
2182
+ __privateAdd(this, _MultichainApiClientWrapperTransport_instances);
2183
+ this.requestId = getUniqueId();
2184
+ this.notificationCallbacks = /* @__PURE__ */ new Set();
2185
+ }
2186
+ isTransportDefined() {
2187
+ try {
2188
+ return Boolean(this.multichainSDK.transport);
2189
+ } catch (error) {
2190
+ return false;
2191
+ }
2192
+ }
2193
+ clearNotificationCallbacks() {
2194
+ this.notificationCallbacks.clear();
2195
+ }
2196
+ notifyCallbacks(data) {
2197
+ this.notificationCallbacks.forEach((callback) => {
2198
+ callback(data);
2199
+ });
2200
+ }
2201
+ setupNotifcationListener() {
2202
+ this.multichainSDK.transport.onNotification(
2203
+ this.notifyCallbacks.bind(this)
2204
+ );
2205
+ }
2206
+ connect() {
2207
+ return __async(this, null, function* () {
2208
+ console.log("\u{1F4DA} connect");
2209
+ return Promise.resolve();
2210
+ });
2211
+ }
2212
+ disconnect() {
2213
+ return __async(this, null, function* () {
2214
+ return Promise.resolve();
2215
+ });
2216
+ }
2217
+ isConnected() {
2218
+ return true;
2219
+ }
2220
+ request(_0) {
2221
+ return __async(this, arguments, function* (params, _options = {}) {
2222
+ const id = this.requestId++;
2223
+ const requestPayload = __spreadValues({
2224
+ id,
2225
+ jsonrpc: "2.0"
2226
+ }, params);
2227
+ switch (requestPayload.method) {
2228
+ case "wallet_createSession":
2229
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn).call(this, requestPayload);
2230
+ case "wallet_getSession":
2231
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletGetSession_fn).call(this, requestPayload);
2232
+ case "wallet_revokeSession":
2233
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletRevokeSession_fn).call(this, requestPayload);
2234
+ case "wallet_invokeMethod":
2235
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletInvokeMethod_fn).call(this, requestPayload);
2236
+ default:
2237
+ throw new Error(`Unsupported method: ${requestPayload.method}`);
2238
+ }
2239
+ throw new Error(`Unknown method: ${requestPayload.method}`);
2240
+ });
2241
+ }
2242
+ onNotification(callback) {
2243
+ if (!this.isTransportDefined()) {
2244
+ this.notificationCallbacks.add(callback);
2245
+ return () => {
2246
+ this.notificationCallbacks.delete(callback);
2247
+ };
2248
+ }
2249
+ return this.multichainSDK.transport.onNotification(callback);
2250
+ }
2251
+ };
2252
+ _MultichainApiClientWrapperTransport_instances = new WeakSet();
2253
+ walletCreateSession_fn = function(request) {
2254
+ return __async(this, null, function* () {
2255
+ console.log("\u{1F4DA} #walletCreateSession", request);
2256
+ const createSessionParams = request.params;
2257
+ const scopes = Object.keys(__spreadValues(__spreadValues({}, createSessionParams.optionalScopes), createSessionParams.requiredScopes));
2258
+ const scopeAccounts = [];
2259
+ scopes.forEach((scope) => {
2260
+ var _a2, _b, _c, _d;
2261
+ const requiredScope = (_a2 = createSessionParams.requiredScopes) == null ? void 0 : _a2[scope];
2262
+ const optionalScope = (_b = createSessionParams.optionalScopes) == null ? void 0 : _b[scope];
2263
+ if (requiredScope) {
2264
+ scopeAccounts.push(...(_c = requiredScope.accounts) != null ? _c : []);
2265
+ }
2266
+ if (optionalScope) {
2267
+ scopeAccounts.push(...(_d = optionalScope.accounts) != null ? _d : []);
2268
+ }
2269
+ });
2270
+ const accounts = [...new Set(scopeAccounts)];
2271
+ console.log("\u{1F4DA} SDK connect");
2272
+ yield this.multichainSDK.connect(
2273
+ scopes,
2274
+ accounts,
2275
+ createSessionParams.sessionProperties
2276
+ );
2277
+ console.log("\u{1F4DA} SDK connected");
2278
+ return this.multichainSDK.transport.request({
2279
+ method: "wallet_getSession"
2280
+ });
2281
+ });
2282
+ };
2283
+ walletGetSession_fn = function(request) {
2284
+ return __async(this, null, function* () {
2285
+ if (!this.isTransportDefined()) {
2286
+ return {
2287
+ jsonrpc: "2.0",
2288
+ id: request.id,
2289
+ result: {
2290
+ sessionScopes: {}
2291
+ }
2292
+ };
2293
+ }
2294
+ return this.multichainSDK.transport.request({
2295
+ method: "wallet_getSession"
2296
+ });
2297
+ });
2298
+ };
2299
+ walletRevokeSession_fn = function(request) {
2300
+ return __async(this, null, function* () {
2301
+ if (!this.isTransportDefined()) {
2302
+ return { jsonrpc: "2.0", id: request.id, result: true };
2303
+ }
2304
+ try {
2305
+ this.multichainSDK.disconnect();
2306
+ return { jsonrpc: "2.0", id: request.id, result: true };
2307
+ } catch (error) {
2308
+ return { jsonrpc: "2.0", id: request.id, result: false };
2309
+ }
2310
+ });
2311
+ };
2312
+ walletInvokeMethod_fn = function(request) {
2313
+ return __async(this, null, function* () {
2314
+ if (!this.isTransportDefined()) {
2315
+ return { error: providerErrors.unauthorized() };
2316
+ }
2317
+ const result = this.multichainSDK.invokeMethod(
2318
+ request.params
2319
+ );
2320
+ return {
2321
+ result
2322
+ };
2323
+ });
2324
+ };
2325
+
2326
+ // src/multichain/index.ts
2125
2327
  var logger2 = createLogger("metamask-sdk:core");
2126
- 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;
2328
+ 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;
2127
2329
  var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2128
2330
  constructor(options) {
2129
2331
  var _a2, _b, _c, _d, _e, _f;
@@ -2142,32 +2344,28 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2142
2344
  super(allOptions);
2143
2345
  __privateAdd(this, _MultichainSDK_instances);
2144
2346
  __privateAdd(this, _provider);
2347
+ __privateAdd(this, _providerTransportWrapper);
2145
2348
  __privateAdd(this, _transport2);
2146
2349
  __privateAdd(this, _dappClient);
2147
2350
  __privateAdd(this, _beforeUnloadListener);
2148
- this._state = "pending";
2351
+ this._status = "pending";
2149
2352
  __privateAdd(this, _listener);
2150
2353
  __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}`);
2354
+ __privateSet(this, _providerTransportWrapper, new MultichainApiClientWrapperTransport(this));
2355
+ __privateSet(this, _provider, getMultichainClient({ transport: __privateGet(this, _providerTransportWrapper) }));
2151
2356
  }
2152
- get state() {
2153
- return this._state;
2357
+ get status() {
2358
+ return this._status;
2154
2359
  }
2155
- set state(value) {
2360
+ set status(value) {
2156
2361
  var _a2, _b;
2157
- this._state = value;
2362
+ this._status = value;
2158
2363
  (_b = (_a2 = this.options.transport) == null ? void 0 : _a2.onNotification) == null ? void 0 : _b.call(_a2, {
2159
2364
  method: "stateChanged",
2160
2365
  params: value
2161
2366
  });
2162
2367
  }
2163
2368
  get provider() {
2164
- if (!__privateGet(this, _provider) && __privateGet(this, _transport2)) {
2165
- __privateSet(this, _provider, getMultichainClient({ transport: __privateGet(this, _transport2) }));
2166
- return __privateGet(this, _provider);
2167
- }
2168
- if (!__privateGet(this, _provider)) {
2169
- throw new Error("Provider not initialized, establish connection first");
2170
- }
2171
2369
  return __privateGet(this, _provider);
2172
2370
  }
2173
2371
  get transport() {
@@ -2203,10 +2401,11 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2203
2401
  return instance;
2204
2402
  });
2205
2403
  }
2206
- connect(scopes, caipAccountIds, forceRequest) {
2404
+ // TODO: make this into param object
2405
+ connect(scopes, caipAccountIds, sessionProperties, forceRequest) {
2207
2406
  return __async(this, null, function* () {
2208
2407
  var _a2;
2209
- if (this.state !== "connected") {
2408
+ if (this.status !== "connected") {
2210
2409
  yield this.disconnect();
2211
2410
  }
2212
2411
  const { ui } = this.options;
@@ -2238,7 +2437,7 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2238
2437
  logger2("Error tracking connection_initiated event", error);
2239
2438
  }
2240
2439
  if (((_a2 = __privateGet(this, _transport2)) == null ? void 0 : _a2.isConnected()) && !secure) {
2241
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateGet(this, _transport2).connect({ scopes, caipAccountIds, forceRequest }).then(() => __async(this, null, function* () {
2440
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateGet(this, _transport2).connect({ scopes, caipAccountIds, sessionProperties, forceRequest }).then(() => __async(this, null, function* () {
2242
2441
  if (__privateGet(this, _transport2) instanceof MWPTransport) {
2243
2442
  return this.storage.setTransport("mwp" /* MWP */);
2244
2443
  }
@@ -2247,18 +2446,18 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2247
2446
  }
2248
2447
  if (platformType === "in-app-browser" /* MetaMaskMobileWebview */) {
2249
2448
  const defaultTransport = yield __privateMethod(this, _MultichainSDK_instances, setupDefaultTransport_fn).call(this);
2250
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, forceRequest }), scopes, transportType);
2449
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, sessionProperties, forceRequest }), scopes, transportType);
2251
2450
  }
2252
2451
  if (isWeb && hasExtensionInstalled && preferExtension) {
2253
2452
  const defaultTransport = yield __privateMethod(this, _MultichainSDK_instances, setupDefaultTransport_fn).call(this);
2254
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, forceRequest }), scopes, transportType);
2453
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, sessionProperties, forceRequest }), scopes, transportType);
2255
2454
  }
2256
2455
  yield __privateMethod(this, _MultichainSDK_instances, setupMWP_fn).call(this);
2257
2456
  const shouldShowInstallModal = hasExtensionInstalled ? showInstallModal : !preferExtension || showInstallModal;
2258
2457
  if (secure && !shouldShowInstallModal) {
2259
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, deeplinkConnect_fn).call(this, scopes, caipAccountIds), scopes, transportType);
2458
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, deeplinkConnect_fn).call(this, scopes, caipAccountIds, sessionProperties), scopes, transportType);
2260
2459
  }
2261
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, showInstallModal_fn).call(this, shouldShowInstallModal, scopes, caipAccountIds), scopes, transportType);
2460
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, showInstallModal_fn).call(this, shouldShowInstallModal, scopes, caipAccountIds, sessionProperties), scopes, transportType);
2262
2461
  });
2263
2462
  }
2264
2463
  emit(event, args) {
@@ -2277,15 +2476,13 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2277
2476
  __privateSet(this, _listener, void 0);
2278
2477
  __privateSet(this, _beforeUnloadListener, void 0);
2279
2478
  __privateSet(this, _transport2, void 0);
2280
- __privateSet(this, _provider, void 0);
2479
+ __privateGet(this, _providerTransportWrapper).clearNotificationCallbacks();
2281
2480
  __privateSet(this, _dappClient, void 0);
2282
2481
  });
2283
2482
  }
2284
2483
  invokeMethod(request) {
2285
2484
  return __async(this, null, function* () {
2286
- var _a2;
2287
2485
  const { transport, options } = this;
2288
- (_a2 = __privateGet(this, _provider)) != null ? _a2 : __privateSet(this, _provider, getMultichainClient({ transport }));
2289
2486
  const rpcClient = new RpcClient(options, __privateGet(this, _sdkInfo));
2290
2487
  const requestRouter = new RequestRouter(transport, rpcClient, options);
2291
2488
  return requestRouter.invokeMethod(request);
@@ -2314,6 +2511,7 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2314
2511
  }
2315
2512
  };
2316
2513
  _provider = new WeakMap();
2514
+ _providerTransportWrapper = new WeakMap();
2317
2515
  _transport2 = new WeakMap();
2318
2516
  _dappClient = new WeakMap();
2319
2517
  _beforeUnloadListener = new WeakMap();
@@ -2360,6 +2558,7 @@ getStoredTransport_fn = function() {
2360
2558
  if (hasExtensionInstalled) {
2361
2559
  const apiTransport = new DefaultTransport();
2362
2560
  __privateSet(this, _transport2, apiTransport);
2561
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2363
2562
  __privateSet(this, _listener, apiTransport.onNotification(
2364
2563
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2365
2564
  ));
@@ -2371,6 +2570,7 @@ getStoredTransport_fn = function() {
2371
2570
  const apiTransport = new MWPTransport(dappClient, kvstore);
2372
2571
  __privateSet(this, _dappClient, dappClient);
2373
2572
  __privateSet(this, _transport2, apiTransport);
2573
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2374
2574
  __privateSet(this, _listener, apiTransport.onNotification(
2375
2575
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2376
2576
  ));
@@ -2386,17 +2586,17 @@ setupTransport_fn = function() {
2386
2586
  const transport = yield __privateMethod(this, _MultichainSDK_instances, getStoredTransport_fn).call(this);
2387
2587
  if (transport) {
2388
2588
  if (!this.transport.isConnected()) {
2389
- this.state = "connecting";
2589
+ this.status = "connecting";
2390
2590
  yield this.transport.connect();
2391
2591
  }
2392
- this.state = "connected";
2592
+ this.status = "connected";
2393
2593
  if (this.transport instanceof MWPTransport) {
2394
2594
  yield this.storage.setTransport("mwp" /* MWP */);
2395
2595
  } else {
2396
2596
  yield this.storage.setTransport("browser" /* Browser */);
2397
2597
  }
2398
2598
  } else {
2399
- this.state = "loaded";
2599
+ this.status = "loaded";
2400
2600
  }
2401
2601
  });
2402
2602
  };
@@ -2424,7 +2624,7 @@ init_fn = function() {
2424
2624
  }
2425
2625
  } catch (error) {
2426
2626
  yield this.storage.removeTransport();
2427
- this.state = "pending";
2627
+ this.status = "pending";
2428
2628
  logger2("MetaMaskSDK error during initialization", error);
2429
2629
  }
2430
2630
  });
@@ -2456,6 +2656,7 @@ setupMWP_fn = function() {
2456
2656
  __privateSet(this, _dappClient, dappClient);
2457
2657
  const apiTransport = new MWPTransport(dappClient, kvstore);
2458
2658
  __privateSet(this, _transport2, apiTransport);
2659
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2459
2660
  __privateSet(this, _listener, this.transport.onNotification(
2460
2661
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2461
2662
  ));
@@ -2483,7 +2684,7 @@ createBeforeUnloadListener_fn = function() {
2483
2684
  }
2484
2685
  };
2485
2686
  };
2486
- renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds) {
2687
+ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds, sessionProperties) {
2487
2688
  return __async(this, null, function* () {
2488
2689
  return new Promise((resolve, reject) => {
2489
2690
  this.options.ui.factory.renderInstallModal(
@@ -2511,19 +2712,19 @@ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds)
2511
2712
  (() => __async(this, null, function* () {
2512
2713
  var _a2;
2513
2714
  try {
2514
- yield this.transport.connect({ scopes, caipAccountIds });
2715
+ yield this.transport.connect({ scopes, caipAccountIds, sessionProperties });
2515
2716
  yield this.options.ui.factory.unload();
2516
2717
  (_a2 = this.options.ui.factory.modal) == null ? void 0 : _a2.unmount();
2517
- this.state = "connected";
2718
+ this.status = "connected";
2518
2719
  yield this.storage.setTransport("mwp" /* MWP */);
2519
2720
  } catch (error) {
2520
2721
  if (error instanceof ProtocolError) {
2521
2722
  if (error.code !== ErrorCode.REQUEST_EXPIRED) {
2522
- this.state = "disconnected";
2723
+ this.status = "disconnected";
2523
2724
  reject(error);
2524
2725
  }
2525
2726
  } else {
2526
- this.state = "disconnected";
2727
+ this.status = "disconnected";
2527
2728
  reject(
2528
2729
  error instanceof Error ? error : new Error(String(error))
2529
2730
  );
@@ -2541,33 +2742,83 @@ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds)
2541
2742
  yield this.storage.setTransport("mwp" /* MWP */);
2542
2743
  resolve();
2543
2744
  }
2544
- })
2745
+ }),
2746
+ (uri) => {
2747
+ this.emit("display_uri", uri);
2748
+ }
2545
2749
  ).catch((error) => {
2546
2750
  reject(error instanceof Error ? error : new Error(String(error)));
2547
2751
  });
2548
2752
  });
2549
2753
  });
2550
2754
  };
2551
- showInstallModal_fn = function(desktopPreferred, scopes, caipAccountIds) {
2755
+ showInstallModal_fn = function(desktopPreferred, scopes, caipAccountIds, sessionProperties) {
2552
2756
  return __async(this, null, function* () {
2553
2757
  var _a2;
2554
2758
  (_a2 = __privateGet(this, _beforeUnloadListener)) != null ? _a2 : __privateSet(this, _beforeUnloadListener, __privateMethod(this, _MultichainSDK_instances, createBeforeUnloadListener_fn).call(this));
2555
- yield __privateMethod(this, _MultichainSDK_instances, renderInstallModalAsync_fn).call(this, desktopPreferred, scopes, caipAccountIds);
2759
+ if (this.options.ui.headless) {
2760
+ yield __privateMethod(this, _MultichainSDK_instances, headlessConnect_fn).call(this, scopes, caipAccountIds, sessionProperties);
2761
+ } else {
2762
+ yield __privateMethod(this, _MultichainSDK_instances, renderInstallModalAsync_fn).call(this, desktopPreferred, scopes, caipAccountIds, sessionProperties);
2763
+ }
2764
+ });
2765
+ };
2766
+ headlessConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
2767
+ return __async(this, null, function* () {
2768
+ return new Promise((resolve, reject) => {
2769
+ if (this.dappClient.state === "CONNECTED" || this.dappClient.state === "CONNECTING") {
2770
+ this.dappClient.disconnect().catch(() => {
2771
+ });
2772
+ }
2773
+ this.dappClient.on(
2774
+ "session_request",
2775
+ (sessionRequest) => {
2776
+ const connectionRequest = {
2777
+ sessionRequest,
2778
+ metadata: {
2779
+ dapp: this.options.dapp,
2780
+ sdk: {
2781
+ version: getVersion(),
2782
+ platform: getPlatformType()
2783
+ }
2784
+ }
2785
+ };
2786
+ const deeplink = this.options.ui.factory.createConnectionDeeplink(connectionRequest);
2787
+ this.emit("display_uri", deeplink);
2788
+ }
2789
+ );
2790
+ this.transport.connect({ scopes, caipAccountIds, sessionProperties }).then(() => __async(this, null, function* () {
2791
+ this.status = "connected";
2792
+ yield this.storage.setTransport("mwp" /* MWP */);
2793
+ resolve();
2794
+ })).catch((error) => __async(this, null, function* () {
2795
+ if (error instanceof ProtocolError) {
2796
+ this.status = "disconnected";
2797
+ yield this.storage.removeTransport();
2798
+ reject(error);
2799
+ } else {
2800
+ this.status = "disconnected";
2801
+ yield this.storage.removeTransport();
2802
+ reject(error instanceof Error ? error : new Error(String(error)));
2803
+ }
2804
+ }));
2805
+ });
2556
2806
  });
2557
2807
  };
2558
2808
  setupDefaultTransport_fn = function() {
2559
2809
  return __async(this, null, function* () {
2560
- this.state = "connecting";
2810
+ this.status = "connecting";
2561
2811
  yield this.storage.setTransport("browser" /* Browser */);
2562
2812
  const transport = new DefaultTransport();
2563
2813
  __privateSet(this, _listener, transport.onNotification(
2564
2814
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2565
2815
  ));
2566
2816
  __privateSet(this, _transport2, transport);
2817
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2567
2818
  return transport;
2568
2819
  });
2569
2820
  };
2570
- deeplinkConnect_fn = function(scopes, caipAccountIds) {
2821
+ deeplinkConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
2571
2822
  return __async(this, null, function* () {
2572
2823
  return new Promise((resolve, reject) => {
2573
2824
  const dappClientMessageHandler = (payload) => {
@@ -2610,6 +2861,7 @@ deeplinkConnect_fn = function(scopes, caipAccountIds) {
2610
2861
  const universalLink = this.options.ui.factory.createConnectionUniversalLink(
2611
2862
  connectionRequest
2612
2863
  );
2864
+ this.emit("display_uri", deeplink);
2613
2865
  if ((_a2 = this.options.mobile) == null ? void 0 : _a2.preferredOpenLink) {
2614
2866
  this.options.mobile.preferredOpenLink(deeplink, "_self");
2615
2867
  } else {
@@ -2618,7 +2870,7 @@ deeplinkConnect_fn = function(scopes, caipAccountIds) {
2618
2870
  }
2619
2871
  );
2620
2872
  }
2621
- return this.transport.connect({ scopes, caipAccountIds }).then(resolve).catch((error) => __async(this, null, function* () {
2873
+ return this.transport.connect({ scopes, caipAccountIds, sessionProperties }).then(resolve).catch((error) => __async(this, null, function* () {
2622
2874
  yield this.storage.removeTransport();
2623
2875
  this.dappClient.off("message", dappClientMessageHandler);
2624
2876
  reject(error instanceof Error ? error : new Error(String(error)));
@@ -2632,9 +2884,9 @@ deeplinkConnect_fn = function(scopes, caipAccountIds) {
2632
2884
  };
2633
2885
  handleConnection_fn = function(promise, scopes, transportType) {
2634
2886
  return __async(this, null, function* () {
2635
- this.state = "connecting";
2887
+ this.status = "connecting";
2636
2888
  return promise.then(() => __async(this, null, function* () {
2637
- this.state = "connected";
2889
+ this.status = "connected";
2638
2890
  try {
2639
2891
  const baseProps = yield getBaseAnalyticsProperties(
2640
2892
  this.options,
@@ -2649,7 +2901,7 @@ handleConnection_fn = function(promise, scopes, transportType) {
2649
2901
  }
2650
2902
  return void 0;
2651
2903
  })).catch((error) => __async(this, null, function* () {
2652
- this.state = "disconnected";
2904
+ this.status = "disconnected";
2653
2905
  try {
2654
2906
  const baseProps = yield getBaseAnalyticsProperties(
2655
2907
  this.options,
@@ -2853,28 +3105,11 @@ var Store = class extends StoreClient {
2853
3105
  }
2854
3106
  };
2855
3107
 
2856
- // src/ui/index.ts
3108
+ // src/ui/ModalFactory.ts
2857
3109
  import MetaMaskOnboarding from "@metamask/onboarding";
2858
3110
  init_domain();
2859
3111
  init_utils();
2860
-
2861
- // src/ui/preload.web.ts
2862
- function preload() {
2863
- return __async(this, null, function* () {
2864
- if (typeof document === "undefined") {
2865
- return;
2866
- }
2867
- try {
2868
- const { defineCustomElements } = yield import("@metamask/multichain-ui/loader");
2869
- yield defineCustomElements();
2870
- } catch (error) {
2871
- console.error("Failed to load customElements:", error);
2872
- }
2873
- });
2874
- }
2875
-
2876
- // src/ui/index.ts
2877
- var ModalFactory = class {
3112
+ var BaseModalFactory = class {
2878
3113
  /**
2879
3114
  * Creates a new modal factory instance.
2880
3115
  *
@@ -2963,15 +3198,17 @@ var ModalFactory = class {
2963
3198
  onStartDesktopOnboarding() {
2964
3199
  new MetaMaskOnboarding().startOnboarding();
2965
3200
  }
2966
- renderInstallModal(showInstallModal, createConnectionRequest, successCallback) {
3201
+ renderInstallModal(showInstallModal, createConnectionRequest, successCallback, onDisplayUri) {
2967
3202
  return __async(this, null, function* () {
2968
- var _a2;
3203
+ var _a2, _b;
2969
3204
  (_a2 = this.modal) == null ? void 0 : _a2.unmount();
2970
- yield preload();
3205
+ yield this.preload();
2971
3206
  this.successCallback = successCallback;
3207
+ this.displayUriCallback = onDisplayUri;
2972
3208
  const parentElement = this.getMountedContainer();
2973
3209
  const connectionRequest = yield createConnectionRequest();
2974
3210
  const qrCodeLink = this.createConnectionDeeplink(connectionRequest);
3211
+ (_b = this.displayUriCallback) == null ? void 0 : _b.call(this, qrCodeLink);
2975
3212
  const modal = new this.options.InstallModal({
2976
3213
  expiresIn: (connectionRequest.sessionRequest.expiresAt - Date.now()) / 1e3,
2977
3214
  connectionRequest,
@@ -2980,11 +3217,15 @@ var ModalFactory = class {
2980
3217
  link: qrCodeLink,
2981
3218
  sdkVersion: getVersion(),
2982
3219
  generateQRCode: (request) => __async(this, null, function* () {
2983
- return this.createConnectionDeeplink(request);
3220
+ var _a3;
3221
+ const newLink = this.createConnectionDeeplink(request);
3222
+ (_a3 = this.displayUriCallback) == null ? void 0 : _a3.call(this, newLink);
3223
+ return newLink;
2984
3224
  }),
2985
3225
  onClose: this.onCloseModal.bind(this),
2986
3226
  startDesktopOnboarding: this.onStartDesktopOnboarding.bind(this),
2987
- createConnectionRequest
3227
+ createConnectionRequest,
3228
+ onDisplayUri: this.displayUriCallback
2988
3229
  });
2989
3230
  this.modal = modal;
2990
3231
  modal.mount();
@@ -2994,7 +3235,7 @@ var ModalFactory = class {
2994
3235
  return __async(this, null, function* () {
2995
3236
  var _a2;
2996
3237
  (_a2 = this.modal) == null ? void 0 : _a2.unmount();
2997
- yield preload();
3238
+ yield this.preload();
2998
3239
  this.successCallback = successCallback;
2999
3240
  const container = this.getMountedContainer();
3000
3241
  const otpCode = yield createOTPCode();
@@ -3012,9 +3253,31 @@ var ModalFactory = class {
3012
3253
  }
3013
3254
  };
3014
3255
 
3256
+ // src/ui/index.ts
3257
+ function preload() {
3258
+ return __async(this, null, function* () {
3259
+ if (typeof document === "undefined") {
3260
+ return;
3261
+ }
3262
+ try {
3263
+ const { defineCustomElements } = yield import("@metamask/multichain-ui/loader");
3264
+ yield defineCustomElements();
3265
+ } catch (error) {
3266
+ console.error("Failed to load customElements:", error);
3267
+ }
3268
+ });
3269
+ }
3270
+ var ModalFactory = class extends BaseModalFactory {
3271
+ preload() {
3272
+ return __async(this, null, function* () {
3273
+ return preload();
3274
+ });
3275
+ }
3276
+ };
3277
+
3015
3278
  // src/index.node.ts
3016
3279
  init_domain();
3017
- var createMetamaskConnect = (options) => __async(null, null, function* () {
3280
+ var createMultichainClient = (options) => __async(null, null, function* () {
3018
3281
  const uiModules = yield Promise.resolve().then(() => (init_node(), node_exports));
3019
3282
  let storage;
3020
3283
  if (!options.storage) {
@@ -3047,7 +3310,7 @@ export {
3047
3310
  StoreClient,
3048
3311
  TransportType,
3049
3312
  createLogger,
3050
- createMetamaskConnect,
3313
+ createMultichainClient,
3051
3314
  enableDebug,
3052
3315
  getInfuraRpcUrls,
3053
3316
  getPlatformType,