@tonconnect/ui 2.3.1-beta.0 → 2.4.0-beta.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.
package/lib/index.cjs CHANGED
@@ -1718,6 +1718,7 @@ function logWarning(...args) {
1718
1718
  }
1719
1719
  }
1720
1720
  function openLink(href, target = "_self") {
1721
+ setLastOpenedLink({ link: href });
1721
1722
  logDebug("openLink", href, target);
1722
1723
  window.open(href, target, "noopener noreferrer");
1723
1724
  }
@@ -1963,6 +1964,13 @@ const setLastSelectedWalletInfo = (walletInfo) => {
1963
1964
  _setLastSelectedWalletInfo(walletInfo);
1964
1965
  };
1965
1966
  const [action, setAction] = createSignal(null);
1967
+ const [lastVisibleWalletsInfo, setLastVisibleWalletsInfo] = createSignal({
1968
+ walletsMenu: "explicit_wallet",
1969
+ wallets: []
1970
+ });
1971
+ const [lastOpenedLink, setLastOpenedLink] = createSignal({
1972
+ link: ""
1973
+ });
1966
1974
  const common$1 = { "close": "Close", "openWallet": "Open wallet", "copyLink": "Copy Link", "linkCopied": "Link Copied", "copied": "Copied", "yourWallet": "Your Wallet", "retry": "Retry", "get": "GET", "mobile": "Mobile", "browserExtension": "Browser Extension", "desktop": "Desktop" };
1967
1975
  const button$1 = { "connectWallet": "Connect Wallet", "dropdown": { "copy": "Copy address", "copied": "Address copied!", "disconnect": "Disconnect" } };
1968
1976
  const notifications$1 = { "confirm": { "header": "Open {{ name }} to confirm the transaction." }, "transactionSent": { "header": "Transaction sent", "text": "Your transaction will be processed in a few seconds." }, "transactionCanceled": { "header": "Transaction canceled", "text": "There will be no changes to your account." }, "dataSigned": { "header": "Data signed" }, "signDataCanceled": { "header": "Sign data canceled" } };
@@ -2437,6 +2445,27 @@ if (!webAppVersion) {
2437
2445
  const window2 = getWindow$1();
2438
2446
  webAppVersion = (_g = (_f = (_e = window2 == null ? void 0 : window2.Telegram) == null ? void 0 : _e.WebApp) == null ? void 0 : _f.version) != null ? _g : "6.0";
2439
2447
  }
2448
+ const initDataRaw = initParams == null ? void 0 : initParams.tgWebAppData;
2449
+ let telegramUser = void 0;
2450
+ try {
2451
+ if (initDataRaw) {
2452
+ let initData = urlParseQueryString(initDataRaw);
2453
+ let userRaw = initData.user;
2454
+ if (userRaw) {
2455
+ let user = JSON.parse(userRaw);
2456
+ if (typeof user.id === "number" && typeof user.is_premium === "boolean") {
2457
+ telegramUser = {
2458
+ id: user.id,
2459
+ isPremium: user.is_premium
2460
+ };
2461
+ }
2462
+ }
2463
+ }
2464
+ } catch (e2) {
2465
+ }
2466
+ function getTgUser() {
2467
+ return telegramUser;
2468
+ }
2440
2469
  function isTmaPlatform(...platforms) {
2441
2470
  return platforms.includes(tmaPlatform);
2442
2471
  }
@@ -2468,6 +2497,7 @@ function sendOpenTelegramLink(link, fallback) {
2468
2497
  }
2469
2498
  const pathFull = url.pathname + url.search;
2470
2499
  if (isIframe() || versionAtLeast("6.1")) {
2500
+ setLastOpenedLink({ link: pathFull, type: "tg_link" });
2471
2501
  postEvent("web_app_open_tg_link", { path_full: pathFull });
2472
2502
  } else {
2473
2503
  openLinkBlank("https://t.me" + pathFull);
@@ -8712,6 +8742,10 @@ const AllWalletsListModal = (props) => {
8712
8742
  };
8713
8743
  const walletsList = () => isMobile() ? props.walletsList.filter(supportsMobile) : props.walletsList;
8714
8744
  const supportedWallets = () => walletsList().filter((wallet) => wallet.isSupportRequiredFeatures);
8745
+ setLastVisibleWalletsInfo({
8746
+ walletsMenu: "other_wallets",
8747
+ wallets: supportedWallets()
8748
+ });
8715
8749
  const unsupportedWallets = () => walletsList().filter((wallet) => !wallet.isSupportRequiredFeatures);
8716
8750
  return createComponent(DesktopSelectWalletModalStyled, {
8717
8751
  "data-tc-wallets-modal-list": "true",
@@ -9246,28 +9280,48 @@ function redirectToWallet(universalLink, deepLink, options, setOpenMethod) {
9246
9280
  }
9247
9281
  }
9248
9282
  }
9249
- function addSessionIdToUniversalLink(universalLink, sessionId) {
9250
- if (!sessionId) {
9251
- return universalLink;
9252
- }
9283
+ function enrichUniversalLink(universalLink, params) {
9284
+ var _a2, _b2;
9253
9285
  if (!sdk.isTelegramUrl(universalLink)) {
9254
- const newUrl2 = addQueryParameter(universalLink, "id", sessionId);
9255
- return newUrl2;
9286
+ return addQueryParametersIfNotPresented(universalLink, {
9287
+ id: params.sessionId,
9288
+ trace_id: params.traceId
9289
+ });
9256
9290
  }
9257
9291
  const directLink = convertToTGDirectLink(universalLink);
9258
9292
  const directLinkUrl = new URL(directLink);
9259
- if (!directLinkUrl.searchParams.has("startapp")) {
9260
- directLinkUrl.searchParams.append("startapp", "tonconnect");
9261
- }
9262
- const newUrl = addQueryParameter(directLinkUrl.toString(), "id", sessionId);
9263
- const lastParam = newUrl.slice(newUrl.lastIndexOf("&") + 1);
9264
- return newUrl.slice(0, newUrl.lastIndexOf("&")) + "-v__2-" + sdk.encodeTelegramUrlParameters(lastParam);
9293
+ const previousStartApp = sdk.decodeTelegramUrlParameters(
9294
+ (_a2 = directLinkUrl.searchParams.get("startapp")) != null ? _a2 : ""
9295
+ );
9296
+ let searchParams = buildSearchParams(previousStartApp);
9297
+ const sessionId = (_b2 = params.sessionId) != null ? _b2 : searchParams.get("id");
9298
+ const traceId = params.traceId;
9299
+ const orderedKeys = ["tonconnect", "v", "id", "trace_id"];
9300
+ const unorderedParams = searchParams.entries().filter(([key]) => !orderedKeys.includes(key));
9301
+ const startApp = buildQueryParams(__spreadProps(__spreadValues({
9302
+ tonconnect: "",
9303
+ v: "2",
9304
+ id: sessionId
9305
+ }, Object.fromEntries(unorderedParams)), {
9306
+ trace_id: traceId
9307
+ })).replace("=&", "&");
9308
+ directLinkUrl.searchParams.set("startapp", sdk.encodeTelegramUrlParameters(startApp));
9309
+ return directLinkUrl.toString();
9265
9310
  }
9266
9311
  function addQueryParameter(url, key, value) {
9267
9312
  const parsed = new URL(url);
9268
9313
  parsed.searchParams.append(key, value);
9269
9314
  return parsed.toString();
9270
9315
  }
9316
+ function addQueryParametersIfNotPresented(url, params) {
9317
+ const parsed = new URL(url);
9318
+ for (const [key, value] of Object.entries(params)) {
9319
+ if (value !== void 0 && value !== null) {
9320
+ parsed.searchParams.set(key, value);
9321
+ }
9322
+ }
9323
+ return parsed.toString();
9324
+ }
9271
9325
  function convertToTGDirectLink(universalLink) {
9272
9326
  const url = new URL(universalLink);
9273
9327
  if (url.searchParams.has("attach")) {
@@ -9276,6 +9330,20 @@ function convertToTGDirectLink(universalLink) {
9276
9330
  }
9277
9331
  return url.toString();
9278
9332
  }
9333
+ function buildSearchParams(search = "") {
9334
+ const url = new URL("https://example.com");
9335
+ url.search = search;
9336
+ return url.searchParams;
9337
+ }
9338
+ function buildQueryParams(params) {
9339
+ const searchParams = buildSearchParams();
9340
+ for (const [key, value] of Object.entries(params)) {
9341
+ if (value !== void 0 && value !== null) {
9342
+ searchParams.append(key, value);
9343
+ }
9344
+ }
9345
+ return searchParams.toString();
9346
+ }
9279
9347
  function convertToTGDeepLink(directLink) {
9280
9348
  const parsed = new URL(directLink);
9281
9349
  const [, domain, appname] = parsed.pathname.split("/");
@@ -9304,11 +9372,14 @@ const DesktopConnectionModal = (props) => {
9304
9372
  });
9305
9373
  onCleanup(unsubscribe);
9306
9374
  const generateUniversalLink = () => {
9375
+ var _a2;
9307
9376
  try {
9308
9377
  const universalLink2 = connector.connect({
9309
9378
  universalLink: props.wallet.universalLink,
9310
9379
  bridgeUrl: props.wallet.bridgeUrl
9311
- }, props.additionalRequest);
9380
+ }, props.additionalRequest, {
9381
+ traceId: (_a2 = props.walletsModalState) == null ? void 0 : _a2.traceId
9382
+ });
9312
9383
  setUniversalLink(universalLink2);
9313
9384
  } catch (e2) {
9314
9385
  }
@@ -9362,13 +9433,16 @@ const DesktopConnectionModal = (props) => {
9362
9433
  });
9363
9434
  };
9364
9435
  const onClickExtension = () => {
9436
+ var _a2;
9365
9437
  setConnectionErrored(null);
9366
9438
  setMode("extension");
9367
9439
  if (sdk.isWalletInfoCurrentlyInjected(props.wallet)) {
9368
9440
  setLastSelectedWalletInfo(props.wallet);
9369
9441
  connector.connect({
9370
9442
  jsBridgeKey: props.wallet.jsBridgeKey
9371
- }, props.additionalRequest);
9443
+ }, props.additionalRequest, {
9444
+ traceId: (_a2 = props.walletsModalState) == null ? void 0 : _a2.traceId
9445
+ });
9372
9446
  }
9373
9447
  };
9374
9448
  if (supportsMobile(props.wallet)) {
@@ -10080,10 +10154,15 @@ const MobileConnectionModal = (props) => {
10080
10154
  }, () => {
10081
10155
  setConnectionErrored(null);
10082
10156
  });
10083
- const universalLink = createMemo(() => connector.connect({
10084
- universalLink: props.wallet.universalLink,
10085
- bridgeUrl: props.wallet.bridgeUrl
10086
- }, props.additionalRequest));
10157
+ const universalLink = createMemo(() => {
10158
+ var _a2;
10159
+ return connector.connect({
10160
+ universalLink: props.wallet.universalLink,
10161
+ bridgeUrl: props.wallet.bridgeUrl
10162
+ }, props.additionalRequest, {
10163
+ traceId: (_a2 = props.walletModalState) == null ? void 0 : _a2.traceId
10164
+ });
10165
+ });
10087
10166
  const onClickTelegram = () => {
10088
10167
  const alwaysForceRedirect = true;
10089
10168
  setLastSelectedWalletInfo(__spreadProps(__spreadValues({}, props.wallet), {
@@ -10627,7 +10706,9 @@ const MobileUniversalModal = (props) => {
10627
10706
  }, null);
10628
10707
  const getUniversalLink = () => {
10629
10708
  if (!universalLink()) {
10630
- setUniversalLink(connector.connect(walletsBridges(), props.additionalRequest));
10709
+ setUniversalLink(connector.connect(walletsBridges(), props.additionalRequest, {
10710
+ traceId: props.walletModalState.traceId
10711
+ }));
10631
10712
  }
10632
10713
  return universalLink();
10633
10714
  };
@@ -10664,7 +10745,9 @@ const MobileUniversalModal = (props) => {
10664
10745
  const walletLink = connector.connect({
10665
10746
  bridgeUrl: atWallet.bridgeUrl,
10666
10747
  universalLink: atWallet.universalLink
10667
- }, props.additionalRequest);
10748
+ }, props.additionalRequest, {
10749
+ traceId: props.walletModalState.traceId
10750
+ });
10668
10751
  const forceRedirect = !firstClick();
10669
10752
  setFirstClick(false);
10670
10753
  redirectToTelegram(walletLink, {
@@ -10687,6 +10770,10 @@ const MobileUniversalModal = (props) => {
10687
10770
  };
10688
10771
  const supportedWallets = createMemo(() => walletsList().filter((wallet) => wallet.isSupportRequiredFeatures), null);
10689
10772
  const visibleWallets = createMemo(() => supportedWallets().slice(0, 3), null);
10773
+ setLastVisibleWalletsInfo({
10774
+ walletsMenu: "main_screen",
10775
+ wallets: atWalletSupportFeatures() ? [props.walletsList.find((wallet) => wallet.appName === AT_WALLET_APP_NAME), ...visibleWallets()] : visibleWallets()
10776
+ });
10690
10777
  const fourWalletsItem = createMemo(() => walletsList().filter((wallet) => !visibleWallets().find((w) => w.appName === wallet.appName)).slice(0, 4), null);
10691
10778
  return (() => {
10692
10779
  var _el$ = _tmpl$2();
@@ -10917,9 +11004,15 @@ const DesktopUniversalModal = (props) => {
10917
11004
  setLastSelectedWalletInfo({
10918
11005
  openMethod: "qrcode"
10919
11006
  });
10920
- const request = createMemo(() => connector.connect(walletsBridges(), props.additionalRequest));
11007
+ const request = createMemo(() => connector.connect(walletsBridges(), props.additionalRequest, {
11008
+ traceId: props.walletModalState.traceId
11009
+ }));
10921
11010
  const supportedWallets = createMemo(() => props.walletsList.filter((wallet) => wallet.isSupportRequiredFeatures), null);
10922
11011
  const visibleWallets = createMemo(() => supportedWallets().slice(0, 3), null);
11012
+ setLastVisibleWalletsInfo({
11013
+ walletsMenu: "main_screen",
11014
+ wallets: visibleWallets()
11015
+ });
10923
11016
  const fourWalletsItem = createMemo(() => props.walletsList.filter((wallet) => !visibleWallets().find((w) => w.appName === wallet.appName)).slice(0, 4), null);
10924
11017
  return createComponent(DesktopUniversalModalStyled, {
10925
11018
  onClick: () => setPopupOpened(false),
@@ -11514,6 +11607,9 @@ const WalletsModal = () => {
11514
11607
  get component() {
11515
11608
  return isMobile() ? MobileConnectionModal : DesktopConnectionModal;
11516
11609
  },
11610
+ get walletsModalState() {
11611
+ return walletsModalState();
11612
+ },
11517
11613
  get wallet() {
11518
11614
  return selectedWalletInfo();
11519
11615
  },
@@ -11536,6 +11632,9 @@ const WalletsModal = () => {
11536
11632
  return isMobile() ? MobileUniversalModal : DesktopUniversalModal;
11537
11633
  },
11538
11634
  onSelect: setSelectedWalletInfo,
11635
+ get walletModalState() {
11636
+ return walletsModalState();
11637
+ },
11539
11638
  get walletsList() {
11540
11639
  return walletsList();
11541
11640
  },
@@ -11626,7 +11725,10 @@ const ActionModal = (props) => {
11626
11725
  const returnStrategy = "returnStrategy" in currentAction ? currentAction.returnStrategy : appState.returnStrategy;
11627
11726
  const forceRedirect = !firstClick();
11628
11727
  setFirstClick(false);
11629
- const linkWithSessionId = addSessionIdToUniversalLink(universalLink, currentAction.sessionId);
11728
+ const linkWithSessionId = enrichUniversalLink(universalLink, {
11729
+ sessionId: currentAction.sessionId,
11730
+ traceId: currentAction.traceId
11731
+ });
11630
11732
  if (sdk.isTelegramUrl(universalLink)) {
11631
11733
  redirectToTelegram(linkWithSessionId, {
11632
11734
  returnStrategy,
@@ -12035,9 +12137,13 @@ const App = (props) => {
12035
12137
  });
12036
12138
  };
12037
12139
  const widgetController = {
12038
- openWalletsModal: () => void setTimeout(() => setWalletsModalState({
12039
- status: "opened",
12040
- closeReason: null
12140
+ openWalletsModal: (options) => void setTimeout(() => setWalletsModalState((prev) => {
12141
+ var _a2;
12142
+ return {
12143
+ status: "opened",
12144
+ traceId: (_a2 = options == null ? void 0 : options.traceId) != null ? _a2 : prev == null ? void 0 : prev.traceId,
12145
+ closeReason: null
12146
+ };
12041
12147
  })),
12042
12148
  closeWalletsModal: (reason) => void setTimeout(() => setWalletsModalState({
12043
12149
  status: "closed",
@@ -12054,8 +12160,9 @@ const widgetController = {
12054
12160
  status: "closed",
12055
12161
  closeReason: reason
12056
12162
  })),
12057
- openWalletNotSupportFeatureModal: (cause) => void setTimeout(() => setWalletsModalState({
12163
+ openWalletNotSupportFeatureModal: (cause, options) => void setTimeout(() => setWalletsModalState({
12058
12164
  status: "opened",
12165
+ traceId: options.traceId,
12059
12166
  closeReason: null,
12060
12167
  type: "wallet-not-support-feature",
12061
12168
  requiredFeature: cause.requiredFeature
@@ -12063,6 +12170,7 @@ const widgetController = {
12063
12170
  setAction: (action2) => void setTimeout(() => setAction(action2)),
12064
12171
  clearAction: () => void setTimeout(() => setAction(null)),
12065
12172
  getSelectedWalletInfo: () => lastSelectedWalletInfo(),
12173
+ getLastVisibleWallets: () => lastVisibleWalletsInfo(),
12066
12174
  removeSelectedWalletInfo: () => setLastSelectedWalletInfo(null),
12067
12175
  renderApp: (root, tonConnectUI) => render(() => createComponent(App, {
12068
12176
  tonConnectUI
@@ -12080,19 +12188,67 @@ class WalletsModalManager {
12080
12188
  this.state = state;
12081
12189
  this.consumers.forEach((consumer) => consumer(state));
12082
12190
  });
12191
+ createEffect(
12192
+ on(lastSelectedWalletInfo, (selectedWallet, previousWallet) => __async(this, null, function* () {
12193
+ try {
12194
+ const { wallets, walletsMenu } = widgetController.getLastVisibleWallets();
12195
+ if (selectedWallet && "appName" in selectedWallet) {
12196
+ if (previousWallet && "appName" in previousWallet && previousWallet.appName === selectedWallet.appName) {
12197
+ return;
12198
+ }
12199
+ const clientId = yield this.connector.getSessionId();
12200
+ this.tracker.trackSelectedWallet(
12201
+ wallets.map((wallet) => wallet.name),
12202
+ selectedWallet,
12203
+ walletsMenu,
12204
+ "",
12205
+ void 0,
12206
+ clientId,
12207
+ this.state.traceId
12208
+ );
12209
+ }
12210
+ } catch (error) {
12211
+ logError(error);
12212
+ }
12213
+ }))
12214
+ );
12215
+ createEffect(
12216
+ on(lastOpenedLink, (openedLink) => __async(this, null, function* () {
12217
+ try {
12218
+ const { wallets, walletsMenu } = widgetController.getLastVisibleWallets();
12219
+ if (sdk.isConnectUrl(openedLink.link)) {
12220
+ const selectedWallet = lastSelectedWalletInfo();
12221
+ const clientId = yield this.connector.getSessionId();
12222
+ this.tracker.trackSelectedWallet(
12223
+ wallets.map((wallet) => wallet.name),
12224
+ selectedWallet && "appName" in selectedWallet ? selectedWallet : null,
12225
+ walletsMenu,
12226
+ openedLink.link,
12227
+ openedLink.type,
12228
+ clientId,
12229
+ this.state.traceId
12230
+ );
12231
+ }
12232
+ } catch (error) {
12233
+ logError(error);
12234
+ }
12235
+ }))
12236
+ );
12083
12237
  }
12084
12238
  /**
12085
12239
  * Opens the modal window.
12086
12240
  */
12087
- open() {
12241
+ open(options) {
12088
12242
  return __async(this, null, function* () {
12243
+ var _a2;
12244
+ const traceId = (_a2 = options == null ? void 0 : options.traceId) != null ? _a2 : sdk.UUIDv7();
12089
12245
  this.tracker.trackConnectionStarted();
12090
12246
  const walletsList = yield this.connector.getWallets();
12091
12247
  const embeddedWallet = walletsList.find(sdk.isWalletInfoCurrentlyEmbedded);
12092
12248
  if (embeddedWallet) {
12093
- return this.connectEmbeddedWallet(embeddedWallet);
12249
+ return this.connectEmbeddedWallet(embeddedWallet, { traceId });
12094
12250
  } else {
12095
- return this.openWalletsModal();
12251
+ return this.openWalletsModal({ traceId });
12096
12252
  }
12097
12253
  });
12098
12254
  }
@@ -12120,10 +12276,12 @@ class WalletsModalManager {
12120
12276
  * @param embeddedWallet - Information about the embedded wallet to connect to.
12121
12277
  * @internal
12122
12278
  */
12123
- connectEmbeddedWallet(embeddedWallet) {
12279
+ connectEmbeddedWallet(embeddedWallet, options) {
12124
12280
  const connect = (parameters) => {
12125
12281
  setLastSelectedWalletInfo(embeddedWallet);
12126
- this.connector.connect({ jsBridgeKey: embeddedWallet.jsBridgeKey }, parameters);
12282
+ this.connector.connect({ jsBridgeKey: embeddedWallet.jsBridgeKey }, parameters, {
12283
+ traceId: options.traceId
12284
+ });
12127
12285
  };
12128
12286
  const additionalRequest = appState.connectRequestParameters;
12129
12287
  if ((additionalRequest == null ? void 0 : additionalRequest.state) === "loading") {
@@ -12136,12 +12294,12 @@ class WalletsModalManager {
12136
12294
  * Opens the modal window to connect to an external wallet, and waits when modal window is opened.
12137
12295
  * @internal
12138
12296
  */
12139
- openWalletsModal() {
12297
+ openWalletsModal(options) {
12140
12298
  return __async(this, null, function* () {
12141
12299
  if (isInTMA()) {
12142
12300
  sendExpand();
12143
12301
  }
12144
- widgetController.openWalletsModal();
12302
+ widgetController.openWalletsModal({ traceId: options.traceId });
12145
12303
  return new Promise((resolve) => {
12146
12304
  const unsubscribe = this.onStateChange((state) => {
12147
12305
  const { status } = state;
@@ -12274,10 +12432,9 @@ class SingleWalletModalManager {
12274
12432
  }
12275
12433
  class TonConnectUITracker {
12276
12434
  constructor(options) {
12277
- var _a2;
12278
12435
  this.eventPrefix = "ton-connect-ui-";
12279
12436
  this.tonConnectSdkVersion = null;
12280
- this.eventDispatcher = (_a2 = options == null ? void 0 : options.eventDispatcher) != null ? _a2 : new sdk.BrowserEventDispatcher();
12437
+ this.eventDispatcher = options == null ? void 0 : options.eventDispatcher;
12281
12438
  this.tonConnectUiVersion = options.tonConnectUiVersion;
12282
12439
  this.init().catch();
12283
12440
  }
@@ -12353,6 +12510,29 @@ class TonConnectUITracker {
12353
12510
  } catch (e2) {
12354
12511
  }
12355
12512
  }
12513
+ /**
12514
+ * Track wallet opened event.
12515
+ * @param args
12516
+ */
12517
+ trackWalletModalOpened(...args) {
12518
+ try {
12519
+ const event = sdk.createWalletModalOpenedEvent(this.version, ...args);
12520
+ this.dispatchUserActionEvent(event);
12521
+ } catch (e2) {
12522
+ }
12523
+ }
12524
+ /**
12525
+ * Track wallet selected event.
12526
+ * @param args
12527
+ */
12528
+ trackSelectedWallet(...args) {
12529
+ try {
12530
+ const event = sdk.createSelectedWalletEvent(this.version, ...args);
12531
+ this.dispatchUserActionEvent(event);
12532
+ } catch (e2) {
12533
+ logError(e2);
12534
+ }
12535
+ }
12356
12536
  /**
12357
12537
  * Track connection init event.
12358
12538
  * @param args
@@ -12497,22 +12677,48 @@ class TonConnectUITracker {
12497
12677
  }
12498
12678
  }
12499
12679
  }
12500
- const tonConnectUiVersion = "2.3.1-beta.0";
12680
+ const tonConnectUiVersion = "2.4.0-beta.0";
12681
+ class TonConnectEnvironment {
12682
+ constructor() {
12683
+ this.userAgent = getUserAgent();
12684
+ }
12685
+ getLocale() {
12686
+ var _a2;
12687
+ return ((_a2 = navigator.languages) == null ? void 0 : _a2[0]) || navigator.language || "";
12688
+ }
12689
+ getBrowser() {
12690
+ var _a2;
12691
+ return (_a2 = this.userAgent.browser) != null ? _a2 : "";
12692
+ }
12693
+ getPlatform() {
12694
+ var _a2;
12695
+ return (_a2 = this.userAgent.os) != null ? _a2 : "";
12696
+ }
12697
+ getTelegramUser() {
12698
+ return getTgUser();
12699
+ }
12700
+ getClientEnvironment() {
12701
+ return isInTMA() ? "miniapp" : "web";
12702
+ }
12703
+ }
12501
12704
  class TonConnectUI {
12502
12705
  // TODO: `actionsConfiguration.twaReturnUrl` is used only in `connectWallet` method, but it's not used in `sendTransaction` method, NEED TO FIX IT
12503
12706
  constructor(options) {
12707
+ var _a2;
12504
12708
  this.walletInfoStorage = new WalletInfoStorage();
12505
12709
  this.preferredWalletStorage = new PreferredWalletStorage();
12506
12710
  this.walletInfo = null;
12507
12711
  this.systemThemeChangeUnsubscribe = null;
12508
12712
  this.connectionRestored = Promise.resolve(false);
12713
+ let eventDispatcher = (_a2 = options == null ? void 0 : options.eventDispatcher) != null ? _a2 : new sdk.BrowserEventDispatcher();
12509
12714
  if (options && "connector" in options && options.connector) {
12510
12715
  this.connector = options.connector;
12511
12716
  } else if (options && "manifestUrl" in options && options.manifestUrl) {
12512
12717
  this.connector = new sdk.TonConnect({
12513
12718
  manifestUrl: options.manifestUrl,
12514
- eventDispatcher: options.eventDispatcher,
12515
- walletsRequiredFeatures: options.walletsRequiredFeatures
12719
+ eventDispatcher,
12720
+ walletsRequiredFeatures: options.walletsRequiredFeatures,
12721
+ environment: new TonConnectEnvironment()
12516
12722
  });
12517
12723
  } else {
12518
12724
  throw new TonConnectUIError(
@@ -12520,7 +12726,7 @@ class TonConnectUI {
12520
12726
  );
12521
12727
  }
12522
12728
  this.tracker = new TonConnectUITracker({
12523
- eventDispatcher: options == null ? void 0 : options.eventDispatcher,
12729
+ eventDispatcher,
12524
12730
  tonConnectUiVersion
12525
12731
  });
12526
12732
  this.modal = new WalletsModalManager({
@@ -12688,9 +12894,18 @@ class TonConnectUI {
12688
12894
  /**
12689
12895
  * Opens the modal window, returns a promise that resolves after the modal window is opened.
12690
12896
  */
12691
- openModal() {
12897
+ openModal(options) {
12692
12898
  return __async(this, null, function* () {
12693
- return this.modal.open();
12899
+ var _a2;
12900
+ const traceId = (_a2 = options == null ? void 0 : options.traceId) != null ? _a2 : sdk.UUIDv7();
12901
+ yield this.modal.open({ traceId });
12902
+ const sessionId = yield this.getSessionId();
12903
+ const visibleWallets = widgetController.getLastVisibleWallets();
12904
+ this.tracker.trackWalletModalOpened(
12905
+ visibleWallets.wallets.map((wallet) => wallet.name),
12906
+ sessionId,
12907
+ options == null ? void 0 : options.traceId
12908
+ );
12694
12909
  });
12695
12910
  }
12696
12911
  /**
@@ -12747,26 +12962,30 @@ class TonConnectUI {
12747
12962
  * @return Connected wallet.
12748
12963
  * @throws TonConnectUIError if connection was aborted.
12749
12964
  */
12750
- connectWallet() {
12965
+ connectWallet(options) {
12751
12966
  return __async(this, null, function* () {
12967
+ var _a2;
12968
+ const traceId = (_a2 = options == null ? void 0 : options.traceId) != null ? _a2 : sdk.UUIDv7();
12752
12969
  const walletsList = yield this.getWallets();
12753
12970
  const embeddedWallet = walletsList.find(sdk.isWalletInfoCurrentlyEmbedded);
12754
12971
  if (embeddedWallet) {
12755
- return yield this.connectEmbeddedWallet(embeddedWallet);
12972
+ return yield this.connectEmbeddedWallet(embeddedWallet, { traceId });
12756
12973
  } else {
12757
- return yield this.connectExternalWallet();
12974
+ return yield this.connectExternalWallet({ traceId });
12758
12975
  }
12759
12976
  });
12760
12977
  }
12761
12978
  /**
12762
12979
  * Disconnect wallet and clean localstorage.
12763
12980
  */
12764
- disconnect() {
12981
+ disconnect(options) {
12982
+ var _a2;
12983
+ const traceId = (_a2 = options == null ? void 0 : options.traceId) != null ? _a2 : sdk.UUIDv7();
12765
12984
  this.tracker.trackDisconnection(this.wallet, "dapp");
12766
12985
  widgetController.clearAction();
12767
12986
  widgetController.removeSelectedWalletInfo();
12768
12987
  this.walletInfoStorage.removeWalletInfo();
12769
- return this.connector.disconnect();
12988
+ return this.connector.disconnect({ traceId });
12770
12989
  }
12771
12990
  /**
12772
12991
  * Opens the modal window and handles the transaction sending.
@@ -12775,6 +12994,8 @@ class TonConnectUI {
12775
12994
  */
12776
12995
  sendTransaction(tx, options) {
12777
12996
  return __async(this, null, function* () {
12997
+ var _a2;
12998
+ const traceId = (_a2 = options == null ? void 0 : options.traceId) != null ? _a2 : sdk.UUIDv7();
12778
12999
  this.tracker.trackTransactionSentForSignature(this.wallet, tx);
12779
13000
  if (!this.connected) {
12780
13001
  this.tracker.trackTransactionSigningFailed(this.wallet, tx, "Wallet was not connected");
@@ -12790,11 +13011,12 @@ class TonConnectUI {
12790
13011
  showNotification: notifications2.includes("before"),
12791
13012
  openModal: modals.includes("before"),
12792
13013
  sent: false,
12793
- sessionId: sessionId || void 0
13014
+ sessionId: sessionId || void 0,
13015
+ traceId
12794
13016
  });
12795
13017
  const abortController = new AbortController();
12796
13018
  const onRequestSent = () => {
12797
- var _a2;
13019
+ var _a3;
12798
13020
  if (abortController.signal.aborted) {
12799
13021
  return;
12800
13022
  }
@@ -12803,12 +13025,14 @@ class TonConnectUI {
12803
13025
  showNotification: notifications2.includes("before"),
12804
13026
  openModal: modals.includes("before"),
12805
13027
  sent: true,
12806
- sessionId: sessionId || void 0
13028
+ sessionId: sessionId || void 0,
13029
+ traceId
12807
13030
  });
12808
13031
  this.redirectAfterRequestSent({
12809
13032
  returnStrategy,
12810
13033
  twaReturnUrl,
12811
- sessionId: sessionId || void 0
13034
+ sessionId: sessionId || void 0,
13035
+ traceId
12812
13036
  });
12813
13037
  let firstClick = true;
12814
13038
  const redirectToWallet2 = () => __async(this, null, function* () {
@@ -12821,10 +13045,11 @@ class TonConnectUI {
12821
13045
  returnStrategy,
12822
13046
  twaReturnUrl,
12823
13047
  forceRedirect,
12824
- sessionId: sessionId || void 0
13048
+ sessionId: sessionId || void 0,
13049
+ traceId
12825
13050
  });
12826
13051
  });
12827
- (_a2 = options == null ? void 0 : options.onRequestSent) == null ? void 0 : _a2.call(options, redirectToWallet2);
13052
+ (_a3 = options == null ? void 0 : options.onRequestSent) == null ? void 0 : _a3.call(options, redirectToWallet2);
12828
13053
  };
12829
13054
  const unsubscribe = this.onTransactionModalStateChange((action2) => {
12830
13055
  if (action2 == null ? void 0 : action2.openModal) {
@@ -12839,7 +13064,8 @@ class TonConnectUI {
12839
13064
  const result = yield this.waitForSendTransaction(
12840
13065
  {
12841
13066
  transaction: tx,
12842
- signal: abortController.signal
13067
+ signal: abortController.signal,
13068
+ traceId
12843
13069
  },
12844
13070
  onRequestSent
12845
13071
  );
@@ -12847,19 +13073,21 @@ class TonConnectUI {
12847
13073
  widgetController.setAction({
12848
13074
  name: "transaction-sent",
12849
13075
  showNotification: notifications2.includes("success"),
12850
- openModal: modals.includes("success")
13076
+ openModal: modals.includes("success"),
13077
+ traceId
12851
13078
  });
12852
13079
  return result;
12853
13080
  } catch (e2) {
12854
13081
  if (e2 instanceof sdk.WalletNotSupportFeatureError) {
12855
13082
  widgetController.clearAction();
12856
- widgetController.openWalletNotSupportFeatureModal(e2.cause);
13083
+ widgetController.openWalletNotSupportFeatureModal(e2.cause, { traceId });
12857
13084
  throw e2;
12858
13085
  }
12859
13086
  widgetController.setAction({
12860
13087
  name: "transaction-canceled",
12861
13088
  showNotification: notifications2.includes("error"),
12862
- openModal: modals.includes("error")
13089
+ openModal: modals.includes("error"),
13090
+ traceId
12863
13091
  });
12864
13092
  if (e2 instanceof sdk.TonConnectError) {
12865
13093
  throw e2;
@@ -12878,6 +13106,8 @@ class TonConnectUI {
12878
13106
  */
12879
13107
  signData(data, options) {
12880
13108
  return __async(this, null, function* () {
13109
+ var _a2;
13110
+ const traceId = (_a2 = options == null ? void 0 : options.traceId) != null ? _a2 : sdk.UUIDv7();
12881
13111
  this.tracker.trackDataSentForSignature(this.wallet, data);
12882
13112
  if (!this.connected) {
12883
13113
  this.tracker.trackDataSigningFailed(this.wallet, data, "Wallet was not connected");
@@ -12893,11 +13123,12 @@ class TonConnectUI {
12893
13123
  showNotification: notifications2.includes("before"),
12894
13124
  openModal: modals.includes("before"),
12895
13125
  signed: false,
12896
- sessionId: sessionId || void 0
13126
+ sessionId: sessionId || void 0,
13127
+ traceId
12897
13128
  });
12898
13129
  const abortController = new AbortController();
12899
13130
  const onRequestSent = () => {
12900
- var _a2;
13131
+ var _a3;
12901
13132
  if (abortController.signal.aborted) {
12902
13133
  return;
12903
13134
  }
@@ -12906,12 +13137,14 @@ class TonConnectUI {
12906
13137
  showNotification: notifications2.includes("before"),
12907
13138
  openModal: modals.includes("before"),
12908
13139
  signed: true,
12909
- sessionId: sessionId || void 0
13140
+ sessionId: sessionId || void 0,
13141
+ traceId
12910
13142
  });
12911
13143
  this.redirectAfterRequestSent({
12912
13144
  returnStrategy,
12913
13145
  twaReturnUrl,
12914
- sessionId: sessionId || void 0
13146
+ sessionId: sessionId || void 0,
13147
+ traceId
12915
13148
  });
12916
13149
  let firstClick = true;
12917
13150
  const redirectToWallet2 = () => {
@@ -12924,10 +13157,11 @@ class TonConnectUI {
12924
13157
  returnStrategy,
12925
13158
  twaReturnUrl,
12926
13159
  forceRedirect,
12927
- sessionId: sessionId || void 0
13160
+ sessionId: sessionId || void 0,
13161
+ traceId
12928
13162
  });
12929
13163
  };
12930
- (_a2 = options == null ? void 0 : options.onRequestSent) == null ? void 0 : _a2.call(options, redirectToWallet2);
13164
+ (_a3 = options == null ? void 0 : options.onRequestSent) == null ? void 0 : _a3.call(options, redirectToWallet2);
12931
13165
  };
12932
13166
  const unsubscribe = this.onTransactionModalStateChange((action2) => {
12933
13167
  if (action2 == null ? void 0 : action2.openModal) {
@@ -12942,7 +13176,8 @@ class TonConnectUI {
12942
13176
  const result = yield this.waitForSignData(
12943
13177
  {
12944
13178
  data,
12945
- signal: new AbortController().signal
13179
+ signal: new AbortController().signal,
13180
+ traceId
12946
13181
  },
12947
13182
  onRequestSent
12948
13183
  );
@@ -12950,19 +13185,21 @@ class TonConnectUI {
12950
13185
  widgetController.setAction({
12951
13186
  name: "data-signed",
12952
13187
  showNotification: notifications2.includes("success"),
12953
- openModal: modals.includes("success")
13188
+ openModal: modals.includes("success"),
13189
+ traceId
12954
13190
  });
12955
13191
  return result;
12956
13192
  } catch (e2) {
12957
13193
  if (e2 instanceof sdk.WalletNotSupportFeatureError) {
12958
13194
  widgetController.clearAction();
12959
- widgetController.openWalletNotSupportFeatureModal(e2.cause);
13195
+ widgetController.openWalletNotSupportFeatureModal(e2.cause, { traceId });
12960
13196
  throw e2;
12961
13197
  }
12962
13198
  widgetController.setAction({
12963
13199
  name: "sign-data-canceled",
12964
13200
  showNotification: notifications2.includes("error"),
12965
- openModal: modals.includes("error")
13201
+ openModal: modals.includes("error"),
13202
+ traceId
12966
13203
  });
12967
13204
  if (e2 instanceof sdk.TonConnectError) {
12968
13205
  throw e2;
@@ -12982,9 +13219,6 @@ class TonConnectUI {
12982
13219
  getSessionId() {
12983
13220
  return __async(this, null, function* () {
12984
13221
  var _a2, _b2;
12985
- if (!this.connected) {
12986
- return null;
12987
- }
12988
13222
  try {
12989
13223
  const storage = (_a2 = this.connector.dappSettings) == null ? void 0 : _a2.storage;
12990
13224
  if (storage) {
@@ -13011,13 +13245,14 @@ class TonConnectUI {
13011
13245
  returnStrategy,
13012
13246
  twaReturnUrl,
13013
13247
  forceRedirect,
13014
- sessionId
13248
+ sessionId,
13249
+ traceId
13015
13250
  }) {
13016
13251
  if (this.walletInfo && "universalLink" in this.walletInfo && (this.walletInfo.openMethod === "universal-link" || this.walletInfo.openMethod === "custom-deeplink")) {
13017
- const linkWithSessionId = addSessionIdToUniversalLink(
13018
- this.walletInfo.universalLink,
13019
- sessionId
13020
- );
13252
+ const linkWithSessionId = enrichUniversalLink(this.walletInfo.universalLink, {
13253
+ sessionId,
13254
+ traceId
13255
+ });
13021
13256
  if (sdk.isTelegramUrl(this.walletInfo.universalLink)) {
13022
13257
  redirectToTelegram(linkWithSessionId, {
13023
13258
  returnStrategy,
@@ -13045,11 +13280,13 @@ class TonConnectUI {
13045
13280
  * @throws Error if the connection process fails.
13046
13281
  * @internal
13047
13282
  */
13048
- connectEmbeddedWallet(embeddedWallet) {
13283
+ connectEmbeddedWallet(embeddedWallet, options) {
13049
13284
  return __async(this, null, function* () {
13050
13285
  const connect = (parameters) => {
13051
13286
  setLastSelectedWalletInfo(embeddedWallet);
13052
- this.connector.connect({ jsBridgeKey: embeddedWallet.jsBridgeKey }, parameters);
13287
+ this.connector.connect({ jsBridgeKey: embeddedWallet.jsBridgeKey }, parameters, {
13288
+ traceId: options.traceId
13289
+ });
13053
13290
  };
13054
13291
  const additionalRequest = appState.connectRequestParameters;
13055
13292
  if ((additionalRequest == null ? void 0 : additionalRequest.state) === "loading") {
@@ -13058,7 +13295,8 @@ class TonConnectUI {
13058
13295
  connect(additionalRequest == null ? void 0 : additionalRequest.value);
13059
13296
  }
13060
13297
  return yield this.waitForWalletConnection({
13061
- ignoreErrors: false
13298
+ ignoreErrors: false,
13299
+ traceId: options.traceId
13062
13300
  });
13063
13301
  });
13064
13302
  }
@@ -13069,10 +13307,10 @@ class TonConnectUI {
13069
13307
  * @throws Error if the user cancels the connection process or if the connection process fails.
13070
13308
  * @internal
13071
13309
  */
13072
- connectExternalWallet() {
13310
+ connectExternalWallet(options) {
13073
13311
  return __async(this, null, function* () {
13074
13312
  const abortController = new AbortController();
13075
- widgetController.openWalletsModal();
13313
+ widgetController.openWalletsModal({ traceId: options.traceId });
13076
13314
  const unsubscribe = this.onModalStateChange((state) => {
13077
13315
  const { status, closeReason } = state;
13078
13316
  if (status === "opened") {
@@ -13085,7 +13323,8 @@ class TonConnectUI {
13085
13323
  });
13086
13324
  return yield this.waitForWalletConnection({
13087
13325
  ignoreErrors: true,
13088
- signal: abortController.signal
13326
+ signal: abortController.signal,
13327
+ traceId: options.traceId
13089
13328
  });
13090
13329
  });
13091
13330
  }
@@ -13183,7 +13422,11 @@ class TonConnectUI {
13183
13422
  reject(new TonConnectUIError("Transaction was not sent"));
13184
13423
  };
13185
13424
  signal.addEventListener("abort", onCanceledHandler, { once: true });
13186
- this.connector.sendTransaction(transaction, { onRequestSent, signal }).then((result) => {
13425
+ this.connector.sendTransaction(transaction, {
13426
+ onRequestSent,
13427
+ signal,
13428
+ traceId: options.traceId
13429
+ }).then((result) => {
13187
13430
  signal.removeEventListener("abort", onCanceledHandler);
13188
13431
  return onTransactionHandler(result);
13189
13432
  }).catch((reason) => {