@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
  }
@@ -1207,7 +1202,7 @@ __export(index_browser_exports, {
1207
1202
  StoreClient: () => StoreClient,
1208
1203
  TransportType: () => TransportType,
1209
1204
  createLogger: () => createLogger,
1210
- createMetamaskConnect: () => createMetamaskConnect,
1205
+ createMultichainClient: () => createMultichainClient,
1211
1206
  enableDebug: () => enableDebug,
1212
1207
  getInfuraRpcUrls: () => getInfuraRpcUrls,
1213
1208
  getPlatformType: () => getPlatformType,
@@ -1580,7 +1575,8 @@ var DefaultTransport = class {
1580
1575
  getValidAccounts((_g = options == null ? void 0 : options.caipAccountIds) != null ? _g : [])
1581
1576
  );
1582
1577
  const createSessionParams = {
1583
- optionalScopes
1578
+ optionalScopes,
1579
+ sessionProperties: options == null ? void 0 : options.sessionProperties
1584
1580
  };
1585
1581
  const response = yield this.request(
1586
1582
  { method: "wallet_createSession", params: createSessionParams },
@@ -1720,6 +1716,7 @@ var MULTICHAIN_PROVIDER_STREAM_NAME = "metamask-multichain-provider";
1720
1716
  var DEFAULT_REQUEST_TIMEOUT2 = 60 * 1e3;
1721
1717
  var CONNECTION_GRACE_PERIOD = 60 * 1e3;
1722
1718
  var DEFAULT_CONNECTION_TIMEOUT = DEFAULT_REQUEST_TIMEOUT2 + CONNECTION_GRACE_PERIOD;
1719
+ var DEFAULT_RESUME_TIMEOUT = 10 * 1e3;
1723
1720
  var SESSION_STORE_KEY = "cache_wallet_getSession";
1724
1721
  var ACCOUNTS_STORE_KEY = "cache_eth_accounts";
1725
1722
  var CHAIN_STORE_KEY = "cache_eth_chainId";
@@ -1736,7 +1733,8 @@ var logger = createLogger("metamask-sdk:transport");
1736
1733
  var MWPTransport = class {
1737
1734
  constructor(dappClient, kvstore, options = {
1738
1735
  requestTimeout: DEFAULT_REQUEST_TIMEOUT2,
1739
- connectionTimeout: DEFAULT_CONNECTION_TIMEOUT
1736
+ connectionTimeout: DEFAULT_CONNECTION_TIMEOUT,
1737
+ resumeTimeout: DEFAULT_RESUME_TIMEOUT
1740
1738
  }) {
1741
1739
  this.dappClient = dappClient;
1742
1740
  this.kvstore = kvstore;
@@ -1811,6 +1809,13 @@ var MWPTransport = class {
1811
1809
  )
1812
1810
  );
1813
1811
  }
1812
+ if (message.data.method === "wallet_sessionChanged") {
1813
+ const notification = message.data;
1814
+ const response = {
1815
+ result: notification.params
1816
+ };
1817
+ this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));
1818
+ }
1814
1819
  this.notifyCallbacks(message.data);
1815
1820
  }
1816
1821
  }
@@ -1820,6 +1825,7 @@ var MWPTransport = class {
1820
1825
  return __async(this, null, function* () {
1821
1826
  var _a2, _b, _c, _d, _e, _f, _g;
1822
1827
  try {
1828
+ yield this.waitForWalletSessionIfNotCached();
1823
1829
  const sessionRequest = yield this.request({
1824
1830
  method: "wallet_getSession"
1825
1831
  });
@@ -1924,7 +1930,7 @@ var MWPTransport = class {
1924
1930
  }
1925
1931
  let timeout;
1926
1932
  let initialConnectionMessageHandler;
1927
- const connectionPromise = new Promise((resolve, reject) => {
1933
+ const connectionPromise = new Promise((resolve, reject) => __async(this, null, function* () {
1928
1934
  let connection;
1929
1935
  if (session) {
1930
1936
  connection = new Promise((resumeResolve, resumeReject) => {
@@ -1947,7 +1953,8 @@ var MWPTransport = class {
1947
1953
  getValidAccounts((_b = options == null ? void 0 : options.caipAccountIds) != null ? _b : [])
1948
1954
  );
1949
1955
  const sessionRequest = {
1950
- optionalScopes
1956
+ optionalScopes,
1957
+ sessionProperties: options == null ? void 0 : options.sessionProperties
1951
1958
  };
1952
1959
  const request = {
1953
1960
  jsonrpc: "2.0",
@@ -2002,7 +2009,7 @@ var MWPTransport = class {
2002
2009
  reject(new import_multichain_api_client2.TransportTimeoutError());
2003
2010
  }, this.options.connectionTimeout);
2004
2011
  connection.then(resolve).catch(reject);
2005
- });
2012
+ }));
2006
2013
  return connectionPromise.catch((error) => {
2007
2014
  throw error;
2008
2015
  }).finally(() => {
@@ -2187,6 +2194,43 @@ var MWPTransport = class {
2187
2194
  }
2188
2195
  });
2189
2196
  }
2197
+ // This method checks if an existing CAIP session response is cached or waits for one
2198
+ // to be received from the wallet if not cached. This is necessary because there is an edge
2199
+ // case during the initial connection flow where after the user has accepted the permission approval
2200
+ // and returned back to the dapp from the wallet, the dapp page may have gotten unloaded and refreshed.
2201
+ // When it is unloaded and refreshed, it will try to resume the session by making a request for wallet_getSession
2202
+ // which should resolve from cache, but because a race condition makes it possible for the response from the wallet
2203
+ // for the initial wallet_createSession connection request to not have been handled and cached yet. This results
2204
+ // in the wallet_getSession request never resolving unless we wait for it explicitly as done in this method.
2205
+ waitForWalletSessionIfNotCached() {
2206
+ return __async(this, null, function* () {
2207
+ const cachedWalletGetSessionResponse = yield this.kvstore.get(SESSION_STORE_KEY);
2208
+ if (cachedWalletGetSessionResponse) {
2209
+ return;
2210
+ }
2211
+ let unsubscribe;
2212
+ const responsePromise = new Promise((resolve) => {
2213
+ unsubscribe = this.onNotification((message) => {
2214
+ if (typeof message === "object" && message !== null) {
2215
+ if ("data" in message) {
2216
+ const messagePayload = message.data;
2217
+ if (messagePayload.method === "wallet_getSession" || messagePayload.method === "wallet_sessionChanged") {
2218
+ unsubscribe();
2219
+ resolve();
2220
+ }
2221
+ }
2222
+ }
2223
+ });
2224
+ });
2225
+ const timeoutPromise = new Promise((_resolve, reject) => {
2226
+ setTimeout(() => {
2227
+ unsubscribe();
2228
+ reject(new import_multichain_api_client2.TransportTimeoutError());
2229
+ }, this.options.resumeTimeout);
2230
+ });
2231
+ return Promise.race([responsePromise, timeoutPromise]);
2232
+ });
2233
+ }
2190
2234
  };
2191
2235
 
2192
2236
  // src/multichain/transports/mwp/KeyManager.ts
@@ -2218,8 +2262,166 @@ var keymanager = new KeyManager();
2218
2262
 
2219
2263
  // src/multichain/index.ts
2220
2264
  init_utils();
2265
+
2266
+ // src/multichain/transports/multichainApiClientWrapper/index.ts
2267
+ var import_rpc_errors = require("@metamask/rpc-errors");
2268
+ var MAX = 4294967295;
2269
+ var idCounter = Math.floor(Math.random() * MAX);
2270
+ var getUniqueId = () => {
2271
+ idCounter = (idCounter + 1) % MAX;
2272
+ return idCounter;
2273
+ };
2274
+ var _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn, walletGetSession_fn, walletRevokeSession_fn, walletInvokeMethod_fn;
2275
+ var MultichainApiClientWrapperTransport = class {
2276
+ constructor(multichainSDK) {
2277
+ this.multichainSDK = multichainSDK;
2278
+ __privateAdd(this, _MultichainApiClientWrapperTransport_instances);
2279
+ this.requestId = getUniqueId();
2280
+ this.notificationCallbacks = /* @__PURE__ */ new Set();
2281
+ }
2282
+ isTransportDefined() {
2283
+ try {
2284
+ return Boolean(this.multichainSDK.transport);
2285
+ } catch (error) {
2286
+ return false;
2287
+ }
2288
+ }
2289
+ clearNotificationCallbacks() {
2290
+ this.notificationCallbacks.clear();
2291
+ }
2292
+ notifyCallbacks(data) {
2293
+ this.notificationCallbacks.forEach((callback) => {
2294
+ callback(data);
2295
+ });
2296
+ }
2297
+ setupNotifcationListener() {
2298
+ this.multichainSDK.transport.onNotification(
2299
+ this.notifyCallbacks.bind(this)
2300
+ );
2301
+ }
2302
+ connect() {
2303
+ return __async(this, null, function* () {
2304
+ console.log("\u{1F4DA} connect");
2305
+ return Promise.resolve();
2306
+ });
2307
+ }
2308
+ disconnect() {
2309
+ return __async(this, null, function* () {
2310
+ return Promise.resolve();
2311
+ });
2312
+ }
2313
+ isConnected() {
2314
+ return true;
2315
+ }
2316
+ request(_0) {
2317
+ return __async(this, arguments, function* (params, _options = {}) {
2318
+ const id = this.requestId++;
2319
+ const requestPayload = __spreadValues({
2320
+ id,
2321
+ jsonrpc: "2.0"
2322
+ }, params);
2323
+ switch (requestPayload.method) {
2324
+ case "wallet_createSession":
2325
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletCreateSession_fn).call(this, requestPayload);
2326
+ case "wallet_getSession":
2327
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletGetSession_fn).call(this, requestPayload);
2328
+ case "wallet_revokeSession":
2329
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletRevokeSession_fn).call(this, requestPayload);
2330
+ case "wallet_invokeMethod":
2331
+ return __privateMethod(this, _MultichainApiClientWrapperTransport_instances, walletInvokeMethod_fn).call(this, requestPayload);
2332
+ default:
2333
+ throw new Error(`Unsupported method: ${requestPayload.method}`);
2334
+ }
2335
+ throw new Error(`Unknown method: ${requestPayload.method}`);
2336
+ });
2337
+ }
2338
+ onNotification(callback) {
2339
+ if (!this.isTransportDefined()) {
2340
+ this.notificationCallbacks.add(callback);
2341
+ return () => {
2342
+ this.notificationCallbacks.delete(callback);
2343
+ };
2344
+ }
2345
+ return this.multichainSDK.transport.onNotification(callback);
2346
+ }
2347
+ };
2348
+ _MultichainApiClientWrapperTransport_instances = new WeakSet();
2349
+ walletCreateSession_fn = function(request) {
2350
+ return __async(this, null, function* () {
2351
+ console.log("\u{1F4DA} #walletCreateSession", request);
2352
+ const createSessionParams = request.params;
2353
+ const scopes = Object.keys(__spreadValues(__spreadValues({}, createSessionParams.optionalScopes), createSessionParams.requiredScopes));
2354
+ const scopeAccounts = [];
2355
+ scopes.forEach((scope) => {
2356
+ var _a2, _b, _c, _d;
2357
+ const requiredScope = (_a2 = createSessionParams.requiredScopes) == null ? void 0 : _a2[scope];
2358
+ const optionalScope = (_b = createSessionParams.optionalScopes) == null ? void 0 : _b[scope];
2359
+ if (requiredScope) {
2360
+ scopeAccounts.push(...(_c = requiredScope.accounts) != null ? _c : []);
2361
+ }
2362
+ if (optionalScope) {
2363
+ scopeAccounts.push(...(_d = optionalScope.accounts) != null ? _d : []);
2364
+ }
2365
+ });
2366
+ const accounts = [...new Set(scopeAccounts)];
2367
+ console.log("\u{1F4DA} SDK connect");
2368
+ yield this.multichainSDK.connect(
2369
+ scopes,
2370
+ accounts,
2371
+ createSessionParams.sessionProperties
2372
+ );
2373
+ console.log("\u{1F4DA} SDK connected");
2374
+ return this.multichainSDK.transport.request({
2375
+ method: "wallet_getSession"
2376
+ });
2377
+ });
2378
+ };
2379
+ walletGetSession_fn = function(request) {
2380
+ return __async(this, null, function* () {
2381
+ if (!this.isTransportDefined()) {
2382
+ return {
2383
+ jsonrpc: "2.0",
2384
+ id: request.id,
2385
+ result: {
2386
+ sessionScopes: {}
2387
+ }
2388
+ };
2389
+ }
2390
+ return this.multichainSDK.transport.request({
2391
+ method: "wallet_getSession"
2392
+ });
2393
+ });
2394
+ };
2395
+ walletRevokeSession_fn = function(request) {
2396
+ return __async(this, null, function* () {
2397
+ if (!this.isTransportDefined()) {
2398
+ return { jsonrpc: "2.0", id: request.id, result: true };
2399
+ }
2400
+ try {
2401
+ this.multichainSDK.disconnect();
2402
+ return { jsonrpc: "2.0", id: request.id, result: true };
2403
+ } catch (error) {
2404
+ return { jsonrpc: "2.0", id: request.id, result: false };
2405
+ }
2406
+ });
2407
+ };
2408
+ walletInvokeMethod_fn = function(request) {
2409
+ return __async(this, null, function* () {
2410
+ if (!this.isTransportDefined()) {
2411
+ return { error: import_rpc_errors.providerErrors.unauthorized() };
2412
+ }
2413
+ const result = this.multichainSDK.invokeMethod(
2414
+ request.params
2415
+ );
2416
+ return {
2417
+ result
2418
+ };
2419
+ });
2420
+ };
2421
+
2422
+ // src/multichain/index.ts
2221
2423
  var logger2 = createLogger("metamask-sdk:core");
2222
- 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;
2424
+ 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;
2223
2425
  var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2224
2426
  constructor(options) {
2225
2427
  var _a2, _b, _c, _d, _e, _f;
@@ -2238,32 +2440,28 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2238
2440
  super(allOptions);
2239
2441
  __privateAdd(this, _MultichainSDK_instances);
2240
2442
  __privateAdd(this, _provider);
2443
+ __privateAdd(this, _providerTransportWrapper);
2241
2444
  __privateAdd(this, _transport2);
2242
2445
  __privateAdd(this, _dappClient);
2243
2446
  __privateAdd(this, _beforeUnloadListener);
2244
- this._state = "pending";
2447
+ this._status = "pending";
2245
2448
  __privateAdd(this, _listener);
2246
2449
  __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}`);
2450
+ __privateSet(this, _providerTransportWrapper, new MultichainApiClientWrapperTransport(this));
2451
+ __privateSet(this, _provider, (0, import_multichain_api_client3.getMultichainClient)({ transport: __privateGet(this, _providerTransportWrapper) }));
2247
2452
  }
2248
- get state() {
2249
- return this._state;
2453
+ get status() {
2454
+ return this._status;
2250
2455
  }
2251
- set state(value) {
2456
+ set status(value) {
2252
2457
  var _a2, _b;
2253
- this._state = value;
2458
+ this._status = value;
2254
2459
  (_b = (_a2 = this.options.transport) == null ? void 0 : _a2.onNotification) == null ? void 0 : _b.call(_a2, {
2255
2460
  method: "stateChanged",
2256
2461
  params: value
2257
2462
  });
2258
2463
  }
2259
2464
  get provider() {
2260
- if (!__privateGet(this, _provider) && __privateGet(this, _transport2)) {
2261
- __privateSet(this, _provider, (0, import_multichain_api_client3.getMultichainClient)({ transport: __privateGet(this, _transport2) }));
2262
- return __privateGet(this, _provider);
2263
- }
2264
- if (!__privateGet(this, _provider)) {
2265
- throw new Error("Provider not initialized, establish connection first");
2266
- }
2267
2465
  return __privateGet(this, _provider);
2268
2466
  }
2269
2467
  get transport() {
@@ -2299,10 +2497,11 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2299
2497
  return instance;
2300
2498
  });
2301
2499
  }
2302
- connect(scopes, caipAccountIds, forceRequest) {
2500
+ // TODO: make this into param object
2501
+ connect(scopes, caipAccountIds, sessionProperties, forceRequest) {
2303
2502
  return __async(this, null, function* () {
2304
2503
  var _a2;
2305
- if (this.state !== "connected") {
2504
+ if (this.status !== "connected") {
2306
2505
  yield this.disconnect();
2307
2506
  }
2308
2507
  const { ui } = this.options;
@@ -2334,7 +2533,7 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2334
2533
  logger2("Error tracking connection_initiated event", error);
2335
2534
  }
2336
2535
  if (((_a2 = __privateGet(this, _transport2)) == null ? void 0 : _a2.isConnected()) && !secure) {
2337
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateGet(this, _transport2).connect({ scopes, caipAccountIds, forceRequest }).then(() => __async(this, null, function* () {
2536
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateGet(this, _transport2).connect({ scopes, caipAccountIds, sessionProperties, forceRequest }).then(() => __async(this, null, function* () {
2338
2537
  if (__privateGet(this, _transport2) instanceof MWPTransport) {
2339
2538
  return this.storage.setTransport("mwp" /* MWP */);
2340
2539
  }
@@ -2343,18 +2542,18 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2343
2542
  }
2344
2543
  if (platformType === "in-app-browser" /* MetaMaskMobileWebview */) {
2345
2544
  const defaultTransport = yield __privateMethod(this, _MultichainSDK_instances, setupDefaultTransport_fn).call(this);
2346
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, forceRequest }), scopes, transportType);
2545
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, sessionProperties, forceRequest }), scopes, transportType);
2347
2546
  }
2348
2547
  if (isWeb && hasExtensionInstalled && preferExtension) {
2349
2548
  const defaultTransport = yield __privateMethod(this, _MultichainSDK_instances, setupDefaultTransport_fn).call(this);
2350
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, forceRequest }), scopes, transportType);
2549
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, defaultTransport.connect({ scopes, caipAccountIds, sessionProperties, forceRequest }), scopes, transportType);
2351
2550
  }
2352
2551
  yield __privateMethod(this, _MultichainSDK_instances, setupMWP_fn).call(this);
2353
2552
  const shouldShowInstallModal = hasExtensionInstalled ? showInstallModal : !preferExtension || showInstallModal;
2354
2553
  if (secure && !shouldShowInstallModal) {
2355
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, deeplinkConnect_fn).call(this, scopes, caipAccountIds), scopes, transportType);
2554
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, deeplinkConnect_fn).call(this, scopes, caipAccountIds, sessionProperties), scopes, transportType);
2356
2555
  }
2357
- return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, showInstallModal_fn).call(this, shouldShowInstallModal, scopes, caipAccountIds), scopes, transportType);
2556
+ return __privateMethod(this, _MultichainSDK_instances, handleConnection_fn).call(this, __privateMethod(this, _MultichainSDK_instances, showInstallModal_fn).call(this, shouldShowInstallModal, scopes, caipAccountIds, sessionProperties), scopes, transportType);
2358
2557
  });
2359
2558
  }
2360
2559
  emit(event, args) {
@@ -2373,15 +2572,13 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2373
2572
  __privateSet(this, _listener, void 0);
2374
2573
  __privateSet(this, _beforeUnloadListener, void 0);
2375
2574
  __privateSet(this, _transport2, void 0);
2376
- __privateSet(this, _provider, void 0);
2575
+ __privateGet(this, _providerTransportWrapper).clearNotificationCallbacks();
2377
2576
  __privateSet(this, _dappClient, void 0);
2378
2577
  });
2379
2578
  }
2380
2579
  invokeMethod(request) {
2381
2580
  return __async(this, null, function* () {
2382
- var _a2;
2383
2581
  const { transport, options } = this;
2384
- (_a2 = __privateGet(this, _provider)) != null ? _a2 : __privateSet(this, _provider, (0, import_multichain_api_client3.getMultichainClient)({ transport }));
2385
2582
  const rpcClient = new RpcClient(options, __privateGet(this, _sdkInfo));
2386
2583
  const requestRouter = new RequestRouter(transport, rpcClient, options);
2387
2584
  return requestRouter.invokeMethod(request);
@@ -2410,6 +2607,7 @@ var _MultichainSDK = class _MultichainSDK extends MultichainCore {
2410
2607
  }
2411
2608
  };
2412
2609
  _provider = new WeakMap();
2610
+ _providerTransportWrapper = new WeakMap();
2413
2611
  _transport2 = new WeakMap();
2414
2612
  _dappClient = new WeakMap();
2415
2613
  _beforeUnloadListener = new WeakMap();
@@ -2456,6 +2654,7 @@ getStoredTransport_fn = function() {
2456
2654
  if (hasExtensionInstalled) {
2457
2655
  const apiTransport = new DefaultTransport();
2458
2656
  __privateSet(this, _transport2, apiTransport);
2657
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2459
2658
  __privateSet(this, _listener, apiTransport.onNotification(
2460
2659
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2461
2660
  ));
@@ -2467,6 +2666,7 @@ getStoredTransport_fn = function() {
2467
2666
  const apiTransport = new MWPTransport(dappClient, kvstore);
2468
2667
  __privateSet(this, _dappClient, dappClient);
2469
2668
  __privateSet(this, _transport2, apiTransport);
2669
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2470
2670
  __privateSet(this, _listener, apiTransport.onNotification(
2471
2671
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2472
2672
  ));
@@ -2482,17 +2682,17 @@ setupTransport_fn = function() {
2482
2682
  const transport = yield __privateMethod(this, _MultichainSDK_instances, getStoredTransport_fn).call(this);
2483
2683
  if (transport) {
2484
2684
  if (!this.transport.isConnected()) {
2485
- this.state = "connecting";
2685
+ this.status = "connecting";
2486
2686
  yield this.transport.connect();
2487
2687
  }
2488
- this.state = "connected";
2688
+ this.status = "connected";
2489
2689
  if (this.transport instanceof MWPTransport) {
2490
2690
  yield this.storage.setTransport("mwp" /* MWP */);
2491
2691
  } else {
2492
2692
  yield this.storage.setTransport("browser" /* Browser */);
2493
2693
  }
2494
2694
  } else {
2495
- this.state = "loaded";
2695
+ this.status = "loaded";
2496
2696
  }
2497
2697
  });
2498
2698
  };
@@ -2520,7 +2720,7 @@ init_fn = function() {
2520
2720
  }
2521
2721
  } catch (error) {
2522
2722
  yield this.storage.removeTransport();
2523
- this.state = "pending";
2723
+ this.status = "pending";
2524
2724
  logger2("MetaMaskSDK error during initialization", error);
2525
2725
  }
2526
2726
  });
@@ -2552,6 +2752,7 @@ setupMWP_fn = function() {
2552
2752
  __privateSet(this, _dappClient, dappClient);
2553
2753
  const apiTransport = new MWPTransport(dappClient, kvstore);
2554
2754
  __privateSet(this, _transport2, apiTransport);
2755
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2555
2756
  __privateSet(this, _listener, this.transport.onNotification(
2556
2757
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2557
2758
  ));
@@ -2579,7 +2780,7 @@ createBeforeUnloadListener_fn = function() {
2579
2780
  }
2580
2781
  };
2581
2782
  };
2582
- renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds) {
2783
+ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds, sessionProperties) {
2583
2784
  return __async(this, null, function* () {
2584
2785
  return new Promise((resolve, reject) => {
2585
2786
  this.options.ui.factory.renderInstallModal(
@@ -2607,19 +2808,19 @@ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds)
2607
2808
  (() => __async(this, null, function* () {
2608
2809
  var _a2;
2609
2810
  try {
2610
- yield this.transport.connect({ scopes, caipAccountIds });
2811
+ yield this.transport.connect({ scopes, caipAccountIds, sessionProperties });
2611
2812
  yield this.options.ui.factory.unload();
2612
2813
  (_a2 = this.options.ui.factory.modal) == null ? void 0 : _a2.unmount();
2613
- this.state = "connected";
2814
+ this.status = "connected";
2614
2815
  yield this.storage.setTransport("mwp" /* MWP */);
2615
2816
  } catch (error) {
2616
2817
  if (error instanceof import_mobile_wallet_protocol_core2.ProtocolError) {
2617
2818
  if (error.code !== import_mobile_wallet_protocol_core2.ErrorCode.REQUEST_EXPIRED) {
2618
- this.state = "disconnected";
2819
+ this.status = "disconnected";
2619
2820
  reject(error);
2620
2821
  }
2621
2822
  } else {
2622
- this.state = "disconnected";
2823
+ this.status = "disconnected";
2623
2824
  reject(
2624
2825
  error instanceof Error ? error : new Error(String(error))
2625
2826
  );
@@ -2637,33 +2838,83 @@ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds)
2637
2838
  yield this.storage.setTransport("mwp" /* MWP */);
2638
2839
  resolve();
2639
2840
  }
2640
- })
2841
+ }),
2842
+ (uri) => {
2843
+ this.emit("display_uri", uri);
2844
+ }
2641
2845
  ).catch((error) => {
2642
2846
  reject(error instanceof Error ? error : new Error(String(error)));
2643
2847
  });
2644
2848
  });
2645
2849
  });
2646
2850
  };
2647
- showInstallModal_fn = function(desktopPreferred, scopes, caipAccountIds) {
2851
+ showInstallModal_fn = function(desktopPreferred, scopes, caipAccountIds, sessionProperties) {
2648
2852
  return __async(this, null, function* () {
2649
2853
  var _a2;
2650
2854
  (_a2 = __privateGet(this, _beforeUnloadListener)) != null ? _a2 : __privateSet(this, _beforeUnloadListener, __privateMethod(this, _MultichainSDK_instances, createBeforeUnloadListener_fn).call(this));
2651
- yield __privateMethod(this, _MultichainSDK_instances, renderInstallModalAsync_fn).call(this, desktopPreferred, scopes, caipAccountIds);
2855
+ if (this.options.ui.headless) {
2856
+ yield __privateMethod(this, _MultichainSDK_instances, headlessConnect_fn).call(this, scopes, caipAccountIds, sessionProperties);
2857
+ } else {
2858
+ yield __privateMethod(this, _MultichainSDK_instances, renderInstallModalAsync_fn).call(this, desktopPreferred, scopes, caipAccountIds, sessionProperties);
2859
+ }
2860
+ });
2861
+ };
2862
+ headlessConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
2863
+ return __async(this, null, function* () {
2864
+ return new Promise((resolve, reject) => {
2865
+ if (this.dappClient.state === "CONNECTED" || this.dappClient.state === "CONNECTING") {
2866
+ this.dappClient.disconnect().catch(() => {
2867
+ });
2868
+ }
2869
+ this.dappClient.on(
2870
+ "session_request",
2871
+ (sessionRequest) => {
2872
+ const connectionRequest = {
2873
+ sessionRequest,
2874
+ metadata: {
2875
+ dapp: this.options.dapp,
2876
+ sdk: {
2877
+ version: getVersion(),
2878
+ platform: getPlatformType()
2879
+ }
2880
+ }
2881
+ };
2882
+ const deeplink = this.options.ui.factory.createConnectionDeeplink(connectionRequest);
2883
+ this.emit("display_uri", deeplink);
2884
+ }
2885
+ );
2886
+ this.transport.connect({ scopes, caipAccountIds, sessionProperties }).then(() => __async(this, null, function* () {
2887
+ this.status = "connected";
2888
+ yield this.storage.setTransport("mwp" /* MWP */);
2889
+ resolve();
2890
+ })).catch((error) => __async(this, null, function* () {
2891
+ if (error instanceof import_mobile_wallet_protocol_core2.ProtocolError) {
2892
+ this.status = "disconnected";
2893
+ yield this.storage.removeTransport();
2894
+ reject(error);
2895
+ } else {
2896
+ this.status = "disconnected";
2897
+ yield this.storage.removeTransport();
2898
+ reject(error instanceof Error ? error : new Error(String(error)));
2899
+ }
2900
+ }));
2901
+ });
2652
2902
  });
2653
2903
  };
2654
2904
  setupDefaultTransport_fn = function() {
2655
2905
  return __async(this, null, function* () {
2656
- this.state = "connecting";
2906
+ this.status = "connecting";
2657
2907
  yield this.storage.setTransport("browser" /* Browser */);
2658
2908
  const transport = new DefaultTransport();
2659
2909
  __privateSet(this, _listener, transport.onNotification(
2660
2910
  __privateMethod(this, _MultichainSDK_instances, onTransportNotification_fn).bind(this)
2661
2911
  ));
2662
2912
  __privateSet(this, _transport2, transport);
2913
+ __privateGet(this, _providerTransportWrapper).setupNotifcationListener();
2663
2914
  return transport;
2664
2915
  });
2665
2916
  };
2666
- deeplinkConnect_fn = function(scopes, caipAccountIds) {
2917
+ deeplinkConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
2667
2918
  return __async(this, null, function* () {
2668
2919
  return new Promise((resolve, reject) => {
2669
2920
  const dappClientMessageHandler = (payload) => {
@@ -2706,6 +2957,7 @@ deeplinkConnect_fn = function(scopes, caipAccountIds) {
2706
2957
  const universalLink = this.options.ui.factory.createConnectionUniversalLink(
2707
2958
  connectionRequest
2708
2959
  );
2960
+ this.emit("display_uri", deeplink);
2709
2961
  if ((_a2 = this.options.mobile) == null ? void 0 : _a2.preferredOpenLink) {
2710
2962
  this.options.mobile.preferredOpenLink(deeplink, "_self");
2711
2963
  } else {
@@ -2714,7 +2966,7 @@ deeplinkConnect_fn = function(scopes, caipAccountIds) {
2714
2966
  }
2715
2967
  );
2716
2968
  }
2717
- return this.transport.connect({ scopes, caipAccountIds }).then(resolve).catch((error) => __async(this, null, function* () {
2969
+ return this.transport.connect({ scopes, caipAccountIds, sessionProperties }).then(resolve).catch((error) => __async(this, null, function* () {
2718
2970
  yield this.storage.removeTransport();
2719
2971
  this.dappClient.off("message", dappClientMessageHandler);
2720
2972
  reject(error instanceof Error ? error : new Error(String(error)));
@@ -2728,9 +2980,9 @@ deeplinkConnect_fn = function(scopes, caipAccountIds) {
2728
2980
  };
2729
2981
  handleConnection_fn = function(promise, scopes, transportType) {
2730
2982
  return __async(this, null, function* () {
2731
- this.state = "connecting";
2983
+ this.status = "connecting";
2732
2984
  return promise.then(() => __async(this, null, function* () {
2733
- this.state = "connected";
2985
+ this.status = "connected";
2734
2986
  try {
2735
2987
  const baseProps = yield getBaseAnalyticsProperties(
2736
2988
  this.options,
@@ -2745,7 +2997,7 @@ handleConnection_fn = function(promise, scopes, transportType) {
2745
2997
  }
2746
2998
  return void 0;
2747
2999
  })).catch((error) => __async(this, null, function* () {
2748
- this.state = "disconnected";
3000
+ this.status = "disconnected";
2749
3001
  try {
2750
3002
  const baseProps = yield getBaseAnalyticsProperties(
2751
3003
  this.options,
@@ -2949,28 +3201,11 @@ var Store = class extends StoreClient {
2949
3201
  }
2950
3202
  };
2951
3203
 
2952
- // src/ui/index.ts
3204
+ // src/ui/ModalFactory.ts
2953
3205
  var import_onboarding = __toESM(require("@metamask/onboarding"));
2954
3206
  init_domain();
2955
3207
  init_utils();
2956
-
2957
- // src/ui/preload.web.ts
2958
- function preload() {
2959
- return __async(this, null, function* () {
2960
- if (typeof document === "undefined") {
2961
- return;
2962
- }
2963
- try {
2964
- const { defineCustomElements } = yield import("@metamask/multichain-ui/loader");
2965
- yield defineCustomElements();
2966
- } catch (error) {
2967
- console.error("Failed to load customElements:", error);
2968
- }
2969
- });
2970
- }
2971
-
2972
- // src/ui/index.ts
2973
- var ModalFactory = class {
3208
+ var BaseModalFactory = class {
2974
3209
  /**
2975
3210
  * Creates a new modal factory instance.
2976
3211
  *
@@ -3059,15 +3294,17 @@ var ModalFactory = class {
3059
3294
  onStartDesktopOnboarding() {
3060
3295
  new import_onboarding.default().startOnboarding();
3061
3296
  }
3062
- renderInstallModal(showInstallModal, createConnectionRequest, successCallback) {
3297
+ renderInstallModal(showInstallModal, createConnectionRequest, successCallback, onDisplayUri) {
3063
3298
  return __async(this, null, function* () {
3064
- var _a2;
3299
+ var _a2, _b;
3065
3300
  (_a2 = this.modal) == null ? void 0 : _a2.unmount();
3066
- yield preload();
3301
+ yield this.preload();
3067
3302
  this.successCallback = successCallback;
3303
+ this.displayUriCallback = onDisplayUri;
3068
3304
  const parentElement = this.getMountedContainer();
3069
3305
  const connectionRequest = yield createConnectionRequest();
3070
3306
  const qrCodeLink = this.createConnectionDeeplink(connectionRequest);
3307
+ (_b = this.displayUriCallback) == null ? void 0 : _b.call(this, qrCodeLink);
3071
3308
  const modal = new this.options.InstallModal({
3072
3309
  expiresIn: (connectionRequest.sessionRequest.expiresAt - Date.now()) / 1e3,
3073
3310
  connectionRequest,
@@ -3076,11 +3313,15 @@ var ModalFactory = class {
3076
3313
  link: qrCodeLink,
3077
3314
  sdkVersion: getVersion(),
3078
3315
  generateQRCode: (request) => __async(this, null, function* () {
3079
- return this.createConnectionDeeplink(request);
3316
+ var _a3;
3317
+ const newLink = this.createConnectionDeeplink(request);
3318
+ (_a3 = this.displayUriCallback) == null ? void 0 : _a3.call(this, newLink);
3319
+ return newLink;
3080
3320
  }),
3081
3321
  onClose: this.onCloseModal.bind(this),
3082
3322
  startDesktopOnboarding: this.onStartDesktopOnboarding.bind(this),
3083
- createConnectionRequest
3323
+ createConnectionRequest,
3324
+ onDisplayUri: this.displayUriCallback
3084
3325
  });
3085
3326
  this.modal = modal;
3086
3327
  modal.mount();
@@ -3090,7 +3331,7 @@ var ModalFactory = class {
3090
3331
  return __async(this, null, function* () {
3091
3332
  var _a2;
3092
3333
  (_a2 = this.modal) == null ? void 0 : _a2.unmount();
3093
- yield preload();
3334
+ yield this.preload();
3094
3335
  this.successCallback = successCallback;
3095
3336
  const container = this.getMountedContainer();
3096
3337
  const otpCode = yield createOTPCode();
@@ -3108,9 +3349,31 @@ var ModalFactory = class {
3108
3349
  }
3109
3350
  };
3110
3351
 
3352
+ // src/ui/index.ts
3353
+ function preload() {
3354
+ return __async(this, null, function* () {
3355
+ if (typeof document === "undefined") {
3356
+ return;
3357
+ }
3358
+ try {
3359
+ const { defineCustomElements } = yield import("@metamask/multichain-ui/loader");
3360
+ yield defineCustomElements();
3361
+ } catch (error) {
3362
+ console.error("Failed to load customElements:", error);
3363
+ }
3364
+ });
3365
+ }
3366
+ var ModalFactory = class extends BaseModalFactory {
3367
+ preload() {
3368
+ return __async(this, null, function* () {
3369
+ return preload();
3370
+ });
3371
+ }
3372
+ };
3373
+
3111
3374
  // src/index.browser.ts
3112
3375
  init_domain();
3113
- var createMetamaskConnect = (options) => __async(null, null, function* () {
3376
+ var createMultichainClient = (options) => __async(null, null, function* () {
3114
3377
  const uiModules = yield Promise.resolve().then(() => (init_web(), web_exports));
3115
3378
  let storage;
3116
3379
  if (!options.storage) {