@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
@@ -973,11 +973,6 @@ var init_AbstractInstallModal = __esm({
973
973
  `[UI: InstallModal-nodejs()] \u274C Error generating new QR code: ${error}`
974
974
  );
975
975
  }
976
- } else {
977
- const generateQRCode = yield this.options.generateQRCode(
978
- currentConnectionRequest
979
- );
980
- this.renderQRCode(generateQRCode, currentConnectionRequest);
981
976
  }
982
977
  }), 1e3);
983
978
  }
@@ -1151,7 +1146,7 @@ __export(index_node_exports, {
1151
1146
  StoreClient: () => StoreClient,
1152
1147
  TransportType: () => TransportType,
1153
1148
  createLogger: () => createLogger,
1154
- createMetamaskConnect: () => createMetamaskConnect,
1149
+ createMultichainClient: () => createMultichainClient,
1155
1150
  enableDebug: () => enableDebug,
1156
1151
  getInfuraRpcUrls: () => getInfuraRpcUrls,
1157
1152
  getPlatformType: () => getPlatformType,
@@ -1524,7 +1519,8 @@ var DefaultTransport = class {
1524
1519
  getValidAccounts((_g = options == null ? void 0 : options.caipAccountIds) != null ? _g : [])
1525
1520
  );
1526
1521
  const createSessionParams = {
1527
- optionalScopes
1522
+ optionalScopes,
1523
+ sessionProperties: options == null ? void 0 : options.sessionProperties
1528
1524
  };
1529
1525
  const response = yield this.request(
1530
1526
  { method: "wallet_createSession", params: createSessionParams },
@@ -1664,6 +1660,7 @@ var MULTICHAIN_PROVIDER_STREAM_NAME = "metamask-multichain-provider";
1664
1660
  var DEFAULT_REQUEST_TIMEOUT2 = 60 * 1e3;
1665
1661
  var CONNECTION_GRACE_PERIOD = 60 * 1e3;
1666
1662
  var DEFAULT_CONNECTION_TIMEOUT = DEFAULT_REQUEST_TIMEOUT2 + CONNECTION_GRACE_PERIOD;
1663
+ var DEFAULT_RESUME_TIMEOUT = 10 * 1e3;
1667
1664
  var SESSION_STORE_KEY = "cache_wallet_getSession";
1668
1665
  var ACCOUNTS_STORE_KEY = "cache_eth_accounts";
1669
1666
  var CHAIN_STORE_KEY = "cache_eth_chainId";
@@ -1680,7 +1677,8 @@ var logger = createLogger("metamask-sdk:transport");
1680
1677
  var MWPTransport = class {
1681
1678
  constructor(dappClient, kvstore, options = {
1682
1679
  requestTimeout: DEFAULT_REQUEST_TIMEOUT2,
1683
- connectionTimeout: DEFAULT_CONNECTION_TIMEOUT
1680
+ connectionTimeout: DEFAULT_CONNECTION_TIMEOUT,
1681
+ resumeTimeout: DEFAULT_RESUME_TIMEOUT
1684
1682
  }) {
1685
1683
  this.dappClient = dappClient;
1686
1684
  this.kvstore = kvstore;
@@ -1755,6 +1753,13 @@ var MWPTransport = class {
1755
1753
  )
1756
1754
  );
1757
1755
  }
1756
+ if (message.data.method === "wallet_sessionChanged") {
1757
+ const notification = message.data;
1758
+ const response = {
1759
+ result: notification.params
1760
+ };
1761
+ this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));
1762
+ }
1758
1763
  this.notifyCallbacks(message.data);
1759
1764
  }
1760
1765
  }
@@ -1764,6 +1769,7 @@ var MWPTransport = class {
1764
1769
  return __async(this, null, function* () {
1765
1770
  var _a2, _b, _c, _d, _e, _f, _g;
1766
1771
  try {
1772
+ yield this.waitForWalletSessionIfNotCached();
1767
1773
  const sessionRequest = yield this.request({
1768
1774
  method: "wallet_getSession"
1769
1775
  });
@@ -1868,7 +1874,7 @@ var MWPTransport = class {
1868
1874
  }
1869
1875
  let timeout;
1870
1876
  let initialConnectionMessageHandler;
1871
- const connectionPromise = new Promise((resolve, reject) => {
1877
+ const connectionPromise = new Promise((resolve, reject) => __async(this, null, function* () {
1872
1878
  let connection;
1873
1879
  if (session) {
1874
1880
  connection = new Promise((resumeResolve, resumeReject) => {
@@ -1891,7 +1897,8 @@ var MWPTransport = class {
1891
1897
  getValidAccounts((_b = options == null ? void 0 : options.caipAccountIds) != null ? _b : [])
1892
1898
  );
1893
1899
  const sessionRequest = {
1894
- optionalScopes
1900
+ optionalScopes,
1901
+ sessionProperties: options == null ? void 0 : options.sessionProperties
1895
1902
  };
1896
1903
  const request = {
1897
1904
  jsonrpc: "2.0",
@@ -1946,7 +1953,7 @@ var MWPTransport = class {
1946
1953
  reject(new import_multichain_api_client2.TransportTimeoutError());
1947
1954
  }, this.options.connectionTimeout);
1948
1955
  connection.then(resolve).catch(reject);
1949
- });
1956
+ }));
1950
1957
  return connectionPromise.catch((error) => {
1951
1958
  throw error;
1952
1959
  }).finally(() => {
@@ -2131,6 +2138,43 @@ var MWPTransport = class {
2131
2138
  }
2132
2139
  });
2133
2140
  }
2141
+ // This method checks if an existing CAIP session response is cached or waits for one
2142
+ // to be received from the wallet if not cached. This is necessary because there is an edge
2143
+ // case during the initial connection flow where after the user has accepted the permission approval
2144
+ // and returned back to the dapp from the wallet, the dapp page may have gotten unloaded and refreshed.
2145
+ // When it is unloaded and refreshed, it will try to resume the session by making a request for wallet_getSession
2146
+ // which should resolve from cache, but because a race condition makes it possible for the response from the wallet
2147
+ // for the initial wallet_createSession connection request to not have been handled and cached yet. This results
2148
+ // in the wallet_getSession request never resolving unless we wait for it explicitly as done in this method.
2149
+ waitForWalletSessionIfNotCached() {
2150
+ return __async(this, null, function* () {
2151
+ const cachedWalletGetSessionResponse = yield this.kvstore.get(SESSION_STORE_KEY);
2152
+ if (cachedWalletGetSessionResponse) {
2153
+ return;
2154
+ }
2155
+ let unsubscribe;
2156
+ const responsePromise = new Promise((resolve) => {
2157
+ unsubscribe = this.onNotification((message) => {
2158
+ if (typeof message === "object" && message !== null) {
2159
+ if ("data" in message) {
2160
+ const messagePayload = message.data;
2161
+ if (messagePayload.method === "wallet_getSession" || messagePayload.method === "wallet_sessionChanged") {
2162
+ unsubscribe();
2163
+ resolve();
2164
+ }
2165
+ }
2166
+ }
2167
+ });
2168
+ });
2169
+ const timeoutPromise = new Promise((_resolve, reject) => {
2170
+ setTimeout(() => {
2171
+ unsubscribe();
2172
+ reject(new import_multichain_api_client2.TransportTimeoutError());
2173
+ }, this.options.resumeTimeout);
2174
+ });
2175
+ return Promise.race([responsePromise, timeoutPromise]);
2176
+ });
2177
+ }
2134
2178
  };
2135
2179
 
2136
2180
  // src/multichain/transports/mwp/KeyManager.ts
@@ -2162,8 +2206,166 @@ var keymanager = new KeyManager();
2162
2206
 
2163
2207
  // src/multichain/index.ts
2164
2208
  init_utils();
2209
+
2210
+ // src/multichain/transports/multichainApiClientWrapper/index.ts
2211
+ var import_rpc_errors = require("@metamask/rpc-errors");
2212
+ var MAX = 4294967295;
2213
+ var idCounter = Math.floor(Math.random() * MAX);
2214
+ var getUniqueId = () => {
2215
+ idCounter = (idCounter + 1) % MAX;
2216
+ return idCounter;
2217
+ };
2218
+ var _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn, walletGetSession_fn, walletRevokeSession_fn, walletInvokeMethod_fn;
2219
+ var MultichainApiClientWrapperTransport = class {
2220
+ constructor(multichainSDK) {
2221
+ this.multichainSDK = multichainSDK;
2222
+ __privateAdd(this, _MultichainApiClientWrapperTransport_instances);
2223
+ this.requestId = getUniqueId();
2224
+ this.notificationCallbacks = /* @__PURE__ */ new Set();
2225
+ }
2226
+ isTransportDefined() {
2227
+ try {
2228
+ return Boolean(this.multichainSDK.transport);
2229
+ } catch (error) {
2230
+ return false;
2231
+ }
2232
+ }
2233
+ clearNotificationCallbacks() {
2234
+ this.notificationCallbacks.clear();
2235
+ }
2236
+ notifyCallbacks(data) {
2237
+ this.notificationCallbacks.forEach((callback) => {
2238
+ callback(data);
2239
+ });
2240
+ }
2241
+ setupNotifcationListener() {
2242
+ this.multichainSDK.transport.onNotification(
2243
+ this.notifyCallbacks.bind(this)
2244
+ );
2245
+ }
2246
+ connect() {
2247
+ return __async(this, null, function* () {
2248
+ console.log("\u{1F4DA} connect");
2249
+ return Promise.resolve();
2250
+ });
2251
+ }
2252
+ disconnect() {
2253
+ return __async(this, null, function* () {
2254
+ return Promise.resolve();
2255
+ });
2256
+ }
2257
+ isConnected() {
2258
+ return true;
2259
+ }
2260
+ request(_0) {
2261
+ return __async(this, arguments, function* (params, _options = {}) {
2262
+ const id = this.requestId++;
2263
+ const requestPayload = __spreadValues({
2264
+ id,
2265
+ jsonrpc: "2.0"
2266
+ }, params);
2267
+ switch (requestPayload.method) {
2268
+ case "wallet_createSession":
2269
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn).call(this, requestPayload);
2270
+ case "wallet_getSession":
2271
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletGetSession_fn).call(this, requestPayload);
2272
+ case "wallet_revokeSession":
2273
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletRevokeSession_fn).call(this, requestPayload);
2274
+ case "wallet_invokeMethod":
2275
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletInvokeMethod_fn).call(this, requestPayload);
2276
+ default:
2277
+ throw new Error(`Unsupported method: ${requestPayload.method}`);
2278
+ }
2279
+ throw new Error(`Unknown method: ${requestPayload.method}`);
2280
+ });
2281
+ }
2282
+ onNotification(callback) {
2283
+ if (!this.isTransportDefined()) {
2284
+ this.notificationCallbacks.add(callback);
2285
+ return () => {
2286
+ this.notificationCallbacks.delete(callback);
2287
+ };
2288
+ }
2289
+ return this.multichainSDK.transport.onNotification(callback);
2290
+ }
2291
+ };
2292
+ _MultichainApiClientWrapperTransport_instances = new WeakSet();
2293
+ walletCreateSession_fn = function(request) {
2294
+ return __async(this, null, function* () {
2295
+ console.log("\u{1F4DA} #walletCreateSession", request);
2296
+ const createSessionParams = request.params;
2297
+ const scopes = Object.keys(__spreadValues(__spreadValues({}, createSessionParams.optionalScopes), createSessionParams.requiredScopes));
2298
+ const scopeAccounts = [];
2299
+ scopes.forEach((scope) => {
2300
+ var _a2, _b, _c, _d;
2301
+ const requiredScope = (_a2 = createSessionParams.requiredScopes) == null ? void 0 : _a2[scope];
2302
+ const optionalScope = (_b = createSessionParams.optionalScopes) == null ? void 0 : _b[scope];
2303
+ if (requiredScope) {
2304
+ scopeAccounts.push(...(_c = requiredScope.accounts) != null ? _c : []);
2305
+ }
2306
+ if (optionalScope) {
2307
+ scopeAccounts.push(...(_d = optionalScope.accounts) != null ? _d : []);
2308
+ }
2309
+ });
2310
+ const accounts = [...new Set(scopeAccounts)];
2311
+ console.log("\u{1F4DA} SDK connect");
2312
+ yield this.multichainSDK.connect(
2313
+ scopes,
2314
+ accounts,
2315
+ createSessionParams.sessionProperties
2316
+ );
2317
+ console.log("\u{1F4DA} SDK connected");
2318
+ return this.multichainSDK.transport.request({
2319
+ method: "wallet_getSession"
2320
+ });
2321
+ });
2322
+ };
2323
+ walletGetSession_fn = function(request) {
2324
+ return __async(this, null, function* () {
2325
+ if (!this.isTransportDefined()) {
2326
+ return {
2327
+ jsonrpc: "2.0",
2328
+ id: request.id,
2329
+ result: {
2330
+ sessionScopes: {}
2331
+ }
2332
+ };
2333
+ }
2334
+ return this.multichainSDK.transport.request({
2335
+ method: "wallet_getSession"
2336
+ });
2337
+ });
2338
+ };
2339
+ walletRevokeSession_fn = function(request) {
2340
+ return __async(this, null, function* () {
2341
+ if (!this.isTransportDefined()) {
2342
+ return { jsonrpc: "2.0", id: request.id, result: true };
2343
+ }
2344
+ try {
2345
+ this.multichainSDK.disconnect();
2346
+ return { jsonrpc: "2.0", id: request.id, result: true };
2347
+ } catch (error) {
2348
+ return { jsonrpc: "2.0", id: request.id, result: false };
2349
+ }
2350
+ });
2351
+ };
2352
+ walletInvokeMethod_fn = function(request) {
2353
+ return __async(this, null, function* () {
2354
+ if (!this.isTransportDefined()) {
2355
+ return { error: import_rpc_errors.providerErrors.unauthorized() };
2356
+ }
2357
+ const result = this.multichainSDK.invokeMethod(
2358
+ request.params
2359
+ );
2360
+ return {
2361
+ result
2362
+ };
2363
+ });
2364
+ };
2365
+
2366
+ // src/multichain/index.ts
2165
2367
  var logger2 = createLogger("metamask-sdk:core");
2166
- 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;
2368
+ 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;
2167
2369
  var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2168
2370
  constructor(options) {
2169
2371
  var _a2, _b, _c, _d, _e, _f;
@@ -2182,32 +2384,28 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2182
2384
  super(allOptions);
2183
2385
  __privateAdd(this, _MultichainSDK_instances);
2184
2386
  __privateAdd(this, _provider);
2387
+ __privateAdd(this, _providerTransportWrapper);
2185
2388
  __privateAdd(this, _transport2);
2186
2389
  __privateAdd(this, _dappClient);
2187
2390
  __privateAdd(this, _beforeUnloadListener);
2188
- this._state = "pending";
2391
+ this._status = "pending";
2189
2392
  __privateAdd(this, _listener);
2190
2393
  __privateAdd(this, _sdkInfo, `Sdk/Javascript SdkVersion/${getVersion()} Platform/${getPlatformType()} dApp/${(_a = this.options.dapp.url) != null ? _a : this.options.dapp.name} dAppTitle/${this.options.dapp.name}`);
2394
+ __privateSet(this, _providerTransportWrapper, new MultichainApiClientWrapperTransport(this));
2395
+ __privateSet(this, _provider, (0, import_multichain_api_client3.getMultichainClient)({ transport: __privateGet(this, _providerTransportWrapper) }));
2191
2396
  }
2192
- get state() {
2193
- return this._state;
2397
+ get status() {
2398
+ return this._status;
2194
2399
  }
2195
- set state(value) {
2400
+ set status(value) {
2196
2401
  var _a2, _b;
2197
- this._state = value;
2402
+ this._status = value;
2198
2403
  (_b = (_a2 = this.options.transport) == null ? void 0 : _a2.onNotification) == null ? void 0 : _b.call(_a2, {
2199
2404
  method: "stateChanged",
2200
2405
  params: value
2201
2406
  });
2202
2407
  }
2203
2408
  get provider() {
2204
- if (!__privateGet(this, _provider) && __privateGet(this, _transport2)) {
2205
- __privateSet(this, _provider, (0, import_multichain_api_client3.getMultichainClient)({ transport: __privateGet(this, _transport2) }));
2206
- return __privateGet(this, _provider);
2207
- }
2208
- if (!__privateGet(this, _provider)) {
2209
- throw new Error("Provider not initialized, establish connection first");
2210
- }
2211
2409
  return __privateGet(this, _provider);
2212
2410
  }
2213
2411
  get transport() {
@@ -2243,10 +2441,11 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2243
2441
  return instance;
2244
2442
  });
2245
2443
  }
2246
- connect(scopes, caipAccountIds, forceRequest) {
2444
+ // TODO: make this into param object
2445
+ connect(scopes, caipAccountIds, sessionProperties, forceRequest) {
2247
2446
  return __async(this, null, function* () {
2248
2447
  var _a2;
2249
- if (this.state !== "connected") {
2448
+ if (this.status !== "connected") {
2250
2449
  yield this.disconnect();
2251
2450
  }
2252
2451
  const { ui } = this.options;
@@ -2278,7 +2477,7 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2278
2477
  logger2("Error tracking connection_initiated event", error);
2279
2478
  }
2280
2479
  if (((_a2 = __privateGet(this, _transport2)) == null ? void 0 : _a2.isConnected()) && !secure) {
2281
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateGet(this, _transport2).connect({ scopes, caipAccountIds, forceRequest }).then(() => __async(this, null, function* () {
2480
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateGet(this, _transport2).connect({ scopes, caipAccountIds, sessionProperties, forceRequest }).then(() => __async(this, null, function* () {
2282
2481
  if (__privateGet(this, _transport2) instanceof MWPTransport) {
2283
2482
  return this.storage.setTransport("mwp" /* MWP */);
2284
2483
  }
@@ -2287,18 +2486,18 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2287
2486
  }
2288
2487
  if (platformType === "in-app-browser" /* MetaMaskMobileWebview */) {
2289
2488
  const defaultTransport = yield __privateMethod(this, _MultichainSDK_instances, setupDefaultTransport_fn).call(this);
2290
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, forceRequest }), scopes, transportType);
2489
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, sessionProperties, forceRequest }), scopes, transportType);
2291
2490
  }
2292
2491
  if (isWeb && hasExtensionInstalled && preferExtension) {
2293
2492
  const defaultTransport = yield __privateMethod(this, _MultichainSDK_instances, setupDefaultTransport_fn).call(this);
2294
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, forceRequest }), scopes, transportType);
2493
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, sessionProperties, forceRequest }), scopes, transportType);
2295
2494
  }
2296
2495
  yield __privateMethod(this, _MultichainSDK_instances, setupMWP_fn).call(this);
2297
2496
  const shouldShowInstallModal = hasExtensionInstalled ? showInstallModal : !preferExtension || showInstallModal;
2298
2497
  if (secure && !shouldShowInstallModal) {
2299
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, deeplinkConnect_fn).call(this, scopes, caipAccountIds), scopes, transportType);
2498
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, deeplinkConnect_fn).call(this, scopes, caipAccountIds, sessionProperties), scopes, transportType);
2300
2499
  }
2301
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, showInstallModal_fn).call(this, shouldShowInstallModal, scopes, caipAccountIds), scopes, transportType);
2500
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, showInstallModal_fn).call(this, shouldShowInstallModal, scopes, caipAccountIds, sessionProperties), scopes, transportType);
2302
2501
  });
2303
2502
  }
2304
2503
  emit(event, args) {
@@ -2317,15 +2516,13 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2317
2516
  __privateSet(this, _listener, void 0);
2318
2517
  __privateSet(this, _beforeUnloadListener, void 0);
2319
2518
  __privateSet(this, _transport2, void 0);
2320
- __privateSet(this, _provider, void 0);
2519
+ __privateGet(this, _providerTransportWrapper).clearNotificationCallbacks();
2321
2520
  __privateSet(this, _dappClient, void 0);
2322
2521
  });
2323
2522
  }
2324
2523
  invokeMethod(request) {
2325
2524
  return __async(this, null, function* () {
2326
- var _a2;
2327
2525
  const { transport, options } = this;
2328
- (_a2 = __privateGet(this, _provider)) != null ? _a2 : __privateSet(this, _provider, (0, import_multichain_api_client3.getMultichainClient)({ transport }));
2329
2526
  const rpcClient = new RpcClient(options, __privateGet(this, _sdkInfo));
2330
2527
  const requestRouter = new RequestRouter(transport, rpcClient, options);
2331
2528
  return requestRouter.invokeMethod(request);
@@ -2354,6 +2551,7 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2354
2551
  }
2355
2552
  };
2356
2553
  _provider = new WeakMap();
2554
+ _providerTransportWrapper = new WeakMap();
2357
2555
  _transport2 = new WeakMap();
2358
2556
  _dappClient = new WeakMap();
2359
2557
  _beforeUnloadListener = new WeakMap();
@@ -2400,6 +2598,7 @@ getStoredTransport_fn = function() {
2400
2598
  if (hasExtensionInstalled) {
2401
2599
  const apiTransport = new DefaultTransport();
2402
2600
  __privateSet(this, _transport2, apiTransport);
2601
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2403
2602
  __privateSet(this, _listener, apiTransport.onNotification(
2404
2603
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2405
2604
  ));
@@ -2411,6 +2610,7 @@ getStoredTransport_fn = function() {
2411
2610
  const apiTransport = new MWPTransport(dappClient, kvstore);
2412
2611
  __privateSet(this, _dappClient, dappClient);
2413
2612
  __privateSet(this, _transport2, apiTransport);
2613
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2414
2614
  __privateSet(this, _listener, apiTransport.onNotification(
2415
2615
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2416
2616
  ));
@@ -2426,17 +2626,17 @@ setupTransport_fn = function() {
2426
2626
  const transport = yield __privateMethod(this, _MultichainSDK_instances, getStoredTransport_fn).call(this);
2427
2627
  if (transport) {
2428
2628
  if (!this.transport.isConnected()) {
2429
- this.state = "connecting";
2629
+ this.status = "connecting";
2430
2630
  yield this.transport.connect();
2431
2631
  }
2432
- this.state = "connected";
2632
+ this.status = "connected";
2433
2633
  if (this.transport instanceof MWPTransport) {
2434
2634
  yield this.storage.setTransport("mwp" /* MWP */);
2435
2635
  } else {
2436
2636
  yield this.storage.setTransport("browser" /* Browser */);
2437
2637
  }
2438
2638
  } else {
2439
- this.state = "loaded";
2639
+ this.status = "loaded";
2440
2640
  }
2441
2641
  });
2442
2642
  };
@@ -2464,7 +2664,7 @@ init_fn = function() {
2464
2664
  }
2465
2665
  } catch (error) {
2466
2666
  yield this.storage.removeTransport();
2467
- this.state = "pending";
2667
+ this.status = "pending";
2468
2668
  logger2("MetaMaskSDK error during initialization", error);
2469
2669
  }
2470
2670
  });
@@ -2496,6 +2696,7 @@ setupMWP_fn = function() {
2496
2696
  __privateSet(this, _dappClient, dappClient);
2497
2697
  const apiTransport = new MWPTransport(dappClient, kvstore);
2498
2698
  __privateSet(this, _transport2, apiTransport);
2699
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2499
2700
  __privateSet(this, _listener, this.transport.onNotification(
2500
2701
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2501
2702
  ));
@@ -2523,7 +2724,7 @@ createBeforeUnloadListener_fn = function() {
2523
2724
  }
2524
2725
  };
2525
2726
  };
2526
- renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds) {
2727
+ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds, sessionProperties) {
2527
2728
  return __async(this, null, function* () {
2528
2729
  return new Promise((resolve, reject) => {
2529
2730
  this.options.ui.factory.renderInstallModal(
@@ -2551,19 +2752,19 @@ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds)
2551
2752
  (() => __async(this, null, function* () {
2552
2753
  var _a2;
2553
2754
  try {
2554
- yield this.transport.connect({ scopes, caipAccountIds });
2755
+ yield this.transport.connect({ scopes, caipAccountIds, sessionProperties });
2555
2756
  yield this.options.ui.factory.unload();
2556
2757
  (_a2 = this.options.ui.factory.modal) == null ? void 0 : _a2.unmount();
2557
- this.state = "connected";
2758
+ this.status = "connected";
2558
2759
  yield this.storage.setTransport("mwp" /* MWP */);
2559
2760
  } catch (error) {
2560
2761
  if (error instanceof import_mobile_wallet_protocol_core2.ProtocolError) {
2561
2762
  if (error.code !== import_mobile_wallet_protocol_core2.ErrorCode.REQUEST_EXPIRED) {
2562
- this.state = "disconnected";
2763
+ this.status = "disconnected";
2563
2764
  reject(error);
2564
2765
  }
2565
2766
  } else {
2566
- this.state = "disconnected";
2767
+ this.status = "disconnected";
2567
2768
  reject(
2568
2769
  error instanceof Error ? error : new Error(String(error))
2569
2770
  );
@@ -2581,33 +2782,83 @@ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds)
2581
2782
  yield this.storage.setTransport("mwp" /* MWP */);
2582
2783
  resolve();
2583
2784
  }
2584
- })
2785
+ }),
2786
+ (uri) => {
2787
+ this.emit("display_uri", uri);
2788
+ }
2585
2789
  ).catch((error) => {
2586
2790
  reject(error instanceof Error ? error : new Error(String(error)));
2587
2791
  });
2588
2792
  });
2589
2793
  });
2590
2794
  };
2591
- showInstallModal_fn = function(desktopPreferred, scopes, caipAccountIds) {
2795
+ showInstallModal_fn = function(desktopPreferred, scopes, caipAccountIds, sessionProperties) {
2592
2796
  return __async(this, null, function* () {
2593
2797
  var _a2;
2594
2798
  (_a2 = __privateGet(this, _beforeUnloadListener)) != null ? _a2 : __privateSet(this, _beforeUnloadListener, __privateMethod(this, _MultichainSDK_instances, createBeforeUnloadListener_fn).call(this));
2595
- yield __privateMethod(this, _MultichainSDK_instances, renderInstallModalAsync_fn).call(this, desktopPreferred, scopes, caipAccountIds);
2799
+ if (this.options.ui.headless) {
2800
+ yield __privateMethod(this, _MultichainSDK_instances, headlessConnect_fn).call(this, scopes, caipAccountIds, sessionProperties);
2801
+ } else {
2802
+ yield __privateMethod(this, _MultichainSDK_instances, renderInstallModalAsync_fn).call(this, desktopPreferred, scopes, caipAccountIds, sessionProperties);
2803
+ }
2804
+ });
2805
+ };
2806
+ headlessConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
2807
+ return __async(this, null, function* () {
2808
+ return new Promise((resolve, reject) => {
2809
+ if (this.dappClient.state === "CONNECTED" || this.dappClient.state === "CONNECTING") {
2810
+ this.dappClient.disconnect().catch(() => {
2811
+ });
2812
+ }
2813
+ this.dappClient.on(
2814
+ "session_request",
2815
+ (sessionRequest) => {
2816
+ const connectionRequest = {
2817
+ sessionRequest,
2818
+ metadata: {
2819
+ dapp: this.options.dapp,
2820
+ sdk: {
2821
+ version: getVersion(),
2822
+ platform: getPlatformType()
2823
+ }
2824
+ }
2825
+ };
2826
+ const deeplink = this.options.ui.factory.createConnectionDeeplink(connectionRequest);
2827
+ this.emit("display_uri", deeplink);
2828
+ }
2829
+ );
2830
+ this.transport.connect({ scopes, caipAccountIds, sessionProperties }).then(() => __async(this, null, function* () {
2831
+ this.status = "connected";
2832
+ yield this.storage.setTransport("mwp" /* MWP */);
2833
+ resolve();
2834
+ })).catch((error) => __async(this, null, function* () {
2835
+ if (error instanceof import_mobile_wallet_protocol_core2.ProtocolError) {
2836
+ this.status = "disconnected";
2837
+ yield this.storage.removeTransport();
2838
+ reject(error);
2839
+ } else {
2840
+ this.status = "disconnected";
2841
+ yield this.storage.removeTransport();
2842
+ reject(error instanceof Error ? error : new Error(String(error)));
2843
+ }
2844
+ }));
2845
+ });
2596
2846
  });
2597
2847
  };
2598
2848
  setupDefaultTransport_fn = function() {
2599
2849
  return __async(this, null, function* () {
2600
- this.state = "connecting";
2850
+ this.status = "connecting";
2601
2851
  yield this.storage.setTransport("browser" /* Browser */);
2602
2852
  const transport = new DefaultTransport();
2603
2853
  __privateSet(this, _listener, transport.onNotification(
2604
2854
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2605
2855
  ));
2606
2856
  __privateSet(this, _transport2, transport);
2857
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2607
2858
  return transport;
2608
2859
  });
2609
2860
  };
2610
- deeplinkConnect_fn = function(scopes, caipAccountIds) {
2861
+ deeplinkConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
2611
2862
  return __async(this, null, function* () {
2612
2863
  return new Promise((resolve, reject) => {
2613
2864
  const dappClientMessageHandler = (payload) => {
@@ -2650,6 +2901,7 @@ deeplinkConnect_fn = function(scopes, caipAccountIds) {
2650
2901
  const universalLink = this.options.ui.factory.createConnectionUniversalLink(
2651
2902
  connectionRequest
2652
2903
  );
2904
+ this.emit("display_uri", deeplink);
2653
2905
  if ((_a2 = this.options.mobile) == null ? void 0 : _a2.preferredOpenLink) {
2654
2906
  this.options.mobile.preferredOpenLink(deeplink, "_self");
2655
2907
  } else {
@@ -2658,7 +2910,7 @@ deeplinkConnect_fn = function(scopes, caipAccountIds) {
2658
2910
  }
2659
2911
  );
2660
2912
  }
2661
- return this.transport.connect({ scopes, caipAccountIds }).then(resolve).catch((error) => __async(this, null, function* () {
2913
+ return this.transport.connect({ scopes, caipAccountIds, sessionProperties }).then(resolve).catch((error) => __async(this, null, function* () {
2662
2914
  yield this.storage.removeTransport();
2663
2915
  this.dappClient.off("message", dappClientMessageHandler);
2664
2916
  reject(error instanceof Error ? error : new Error(String(error)));
@@ -2672,9 +2924,9 @@ deeplinkConnect_fn = function(scopes, caipAccountIds) {
2672
2924
  };
2673
2925
  handleConnection_fn = function(promise, scopes, transportType) {
2674
2926
  return __async(this, null, function* () {
2675
- this.state = "connecting";
2927
+ this.status = "connecting";
2676
2928
  return promise.then(() => __async(this, null, function* () {
2677
- this.state = "connected";
2929
+ this.status = "connected";
2678
2930
  try {
2679
2931
  const baseProps = yield getBaseAnalyticsProperties(
2680
2932
  this.options,
@@ -2689,7 +2941,7 @@ handleConnection_fn = function(promise, scopes, transportType) {
2689
2941
  }
2690
2942
  return void 0;
2691
2943
  })).catch((error) => __async(this, null, function* () {
2692
- this.state = "disconnected";
2944
+ this.status = "disconnected";
2693
2945
  try {
2694
2946
  const baseProps = yield getBaseAnalyticsProperties(
2695
2947
  this.options,
@@ -2893,28 +3145,11 @@ var Store = class extends StoreClient {
2893
3145
  }
2894
3146
  };
2895
3147
 
2896
- // src/ui/index.ts
3148
+ // src/ui/ModalFactory.ts
2897
3149
  var import_onboarding = __toESM(require("@metamask/onboarding"));
2898
3150
  init_domain();
2899
3151
  init_utils();
2900
-
2901
- // src/ui/preload.web.ts
2902
- function preload() {
2903
- return __async(this, null, function* () {
2904
- if (typeof document === "undefined") {
2905
- return;
2906
- }
2907
- try {
2908
- const { defineCustomElements } = yield import("@metamask/multichain-ui/loader");
2909
- yield defineCustomElements();
2910
- } catch (error) {
2911
- console.error("Failed to load customElements:", error);
2912
- }
2913
- });
2914
- }
2915
-
2916
- // src/ui/index.ts
2917
- var ModalFactory = class {
3152
+ var BaseModalFactory = class {
2918
3153
  /**
2919
3154
  * Creates a new modal factory instance.
2920
3155
  *
@@ -3003,15 +3238,17 @@ var ModalFactory = class {
3003
3238
  onStartDesktopOnboarding() {
3004
3239
  new import_onboarding.default().startOnboarding();
3005
3240
  }
3006
- renderInstallModal(showInstallModal, createConnectionRequest, successCallback) {
3241
+ renderInstallModal(showInstallModal, createConnectionRequest, successCallback, onDisplayUri) {
3007
3242
  return __async(this, null, function* () {
3008
- var _a2;
3243
+ var _a2, _b;
3009
3244
  (_a2 = this.modal) == null ? void 0 : _a2.unmount();
3010
- yield preload();
3245
+ yield this.preload();
3011
3246
  this.successCallback = successCallback;
3247
+ this.displayUriCallback = onDisplayUri;
3012
3248
  const parentElement = this.getMountedContainer();
3013
3249
  const connectionRequest = yield createConnectionRequest();
3014
3250
  const qrCodeLink = this.createConnectionDeeplink(connectionRequest);
3251
+ (_b = this.displayUriCallback) == null ? void 0 : _b.call(this, qrCodeLink);
3015
3252
  const modal = new this.options.InstallModal({
3016
3253
  expiresIn: (connectionRequest.sessionRequest.expiresAt - Date.now()) / 1e3,
3017
3254
  connectionRequest,
@@ -3020,11 +3257,15 @@ var ModalFactory = class {
3020
3257
  link: qrCodeLink,
3021
3258
  sdkVersion: getVersion(),
3022
3259
  generateQRCode: (request) => __async(this, null, function* () {
3023
- return this.createConnectionDeeplink(request);
3260
+ var _a3;
3261
+ const newLink = this.createConnectionDeeplink(request);
3262
+ (_a3 = this.displayUriCallback) == null ? void 0 : _a3.call(this, newLink);
3263
+ return newLink;
3024
3264
  }),
3025
3265
  onClose: this.onCloseModal.bind(this),
3026
3266
  startDesktopOnboarding: this.onStartDesktopOnboarding.bind(this),
3027
- createConnectionRequest
3267
+ createConnectionRequest,
3268
+ onDisplayUri: this.displayUriCallback
3028
3269
  });
3029
3270
  this.modal = modal;
3030
3271
  modal.mount();
@@ -3034,7 +3275,7 @@ var ModalFactory = class {
3034
3275
  return __async(this, null, function* () {
3035
3276
  var _a2;
3036
3277
  (_a2 = this.modal) == null ? void 0 : _a2.unmount();
3037
- yield preload();
3278
+ yield this.preload();
3038
3279
  this.successCallback = successCallback;
3039
3280
  const container = this.getMountedContainer();
3040
3281
  const otpCode = yield createOTPCode();
@@ -3052,9 +3293,31 @@ var ModalFactory = class {
3052
3293
  }
3053
3294
  };
3054
3295
 
3296
+ // src/ui/index.ts
3297
+ function preload() {
3298
+ return __async(this, null, function* () {
3299
+ if (typeof document === "undefined") {
3300
+ return;
3301
+ }
3302
+ try {
3303
+ const { defineCustomElements } = yield import("@metamask/multichain-ui/loader");
3304
+ yield defineCustomElements();
3305
+ } catch (error) {
3306
+ console.error("Failed to load customElements:", error);
3307
+ }
3308
+ });
3309
+ }
3310
+ var ModalFactory = class extends BaseModalFactory {
3311
+ preload() {
3312
+ return __async(this, null, function* () {
3313
+ return preload();
3314
+ });
3315
+ }
3316
+ };
3317
+
3055
3318
  // src/index.node.ts
3056
3319
  init_domain();
3057
- var createMetamaskConnect = (options) => __async(null, null, function* () {
3320
+ var createMultichainClient = (options) => __async(null, null, function* () {
3058
3321
  const uiModules = yield Promise.resolve().then(() => (init_node(), node_exports));
3059
3322
  let storage;
3060
3323
  if (!options.storage) {
@@ -3088,7 +3351,7 @@ var createMetamaskConnect = (options) => __async(null, null, function* () {
3088
3351
  StoreClient,
3089
3352
  TransportType,
3090
3353
  createLogger,
3091
- createMetamaskConnect,
3354
+ createMultichainClient,
3092
3355
  enableDebug,
3093
3356
  getInfuraRpcUrls,
3094
3357
  getPlatformType,