@tonconnect/ui 2.0.1-beta.3 → 2.0.1-beta.5

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.mjs CHANGED
@@ -1869,11 +1869,15 @@ function isNodeJs() {
1869
1869
  return typeof process !== "undefined" && process.versions != null && process.versions.node != null;
1870
1870
  }
1871
1871
  function getUserAgent() {
1872
- var _a2, _b2;
1872
+ var _a2, _b2, _c2;
1873
1873
  const results = new UAParser().getResult();
1874
1874
  const osName = (_a2 = results.os.name) == null ? void 0 : _a2.toLowerCase();
1875
+ const deviceModel = (_b2 = results.device.model) == null ? void 0 : _b2.toLowerCase();
1875
1876
  let os;
1876
1877
  switch (true) {
1878
+ case deviceModel === "ipad":
1879
+ os = "ipad";
1880
+ break;
1877
1881
  case osName === "ios":
1878
1882
  os = "ios";
1879
1883
  break;
@@ -1890,7 +1894,7 @@ function getUserAgent() {
1890
1894
  os = "windows";
1891
1895
  break;
1892
1896
  }
1893
- const browserName = (_b2 = results.browser.name) == null ? void 0 : _b2.toLowerCase();
1897
+ const browserName = (_c2 = results.browser.name) == null ? void 0 : _c2.toLowerCase();
1894
1898
  let browser;
1895
1899
  switch (true) {
1896
1900
  case browserName === "chrome":
@@ -2830,7 +2834,7 @@ function isDevice(device) {
2830
2834
  return width > maxWidth.mobile;
2831
2835
  default:
2832
2836
  case "mobile":
2833
- return width <= maxWidth.mobile || isOS("ios", "android");
2837
+ return width <= maxWidth.mobile || isOS("ios", "android", "ipad");
2834
2838
  }
2835
2839
  }
2836
2840
  function media(device) {
@@ -7044,7 +7048,7 @@ const DropdownButtonStyled = styled(AccountButtonStyled)`
7044
7048
  justify-content: center;
7045
7049
  background-color: ${(props) => props.theme.colors.background.primary};
7046
7050
  `;
7047
- const LoaderButtonStyled = styled(Button)`
7051
+ styled(Button)`
7048
7052
  min-width: 148px;
7049
7053
  height: 40px;
7050
7054
 
@@ -7056,7 +7060,7 @@ const LoaderButtonStyled = styled(Button)`
7056
7060
  align-items: center;
7057
7061
  justify-content: center;
7058
7062
  `;
7059
- const LoaderIconStyled = styled(LoaderIcon)`
7063
+ styled(LoaderIcon)`
7060
7064
  height: 18px;
7061
7065
  width: 18px;
7062
7066
  `;
@@ -7827,7 +7831,6 @@ const AccountButton = () => {
7827
7831
  const tonConnectUI = useContext(TonConnectUiContext);
7828
7832
  const [isOpened, setIsOpened] = createSignal(false);
7829
7833
  const [account, setAccount] = createSignal(connector.account);
7830
- const [restoringProcess, setRestoringProcess] = createSignal(true);
7831
7834
  let dropDownRef;
7832
7835
  const [floating, setFloating] = createSignal();
7833
7836
  const [anchor, setAnchor] = createSignal();
@@ -7843,7 +7846,6 @@ const AccountButton = () => {
7843
7846
  }
7844
7847
  return "";
7845
7848
  };
7846
- tonConnectUI.connectionRestored.then(() => setRestoringProcess(false));
7847
7849
  const unsubscribe = connector.onStatusChange((wallet) => {
7848
7850
  if (!wallet) {
7849
7851
  setIsOpened(false);
@@ -7874,143 +7876,123 @@ const AccountButton = () => {
7874
7876
  get children() {
7875
7877
  return [createComponent(Show, {
7876
7878
  get when() {
7877
- return restoringProcess();
7879
+ return !account();
7878
7880
  },
7879
7881
  get children() {
7880
- return createComponent(LoaderButtonStyled, {
7881
- disabled: true,
7882
- "data-tc-connect-button-loading": "true",
7882
+ return createComponent(AccountButtonStyled, {
7883
+ onClick: () => tonConnectUI.openModal(),
7884
+ "data-tc-connect-button": "true",
7885
+ scale: "s",
7883
7886
  get children() {
7884
- return createComponent(LoaderIconStyled, {});
7887
+ return [createComponent(TonIcon, {
7888
+ get fill() {
7889
+ return theme.colors.connectButton.foreground;
7890
+ }
7891
+ }), createComponent(Text, {
7892
+ translationKey: "button.connectWallet",
7893
+ fontSize: "15px",
7894
+ lineHeight: "18px",
7895
+ fontWeight: "590",
7896
+ get color() {
7897
+ return theme.colors.connectButton.foreground;
7898
+ },
7899
+ children: "Connect wallet"
7900
+ })];
7885
7901
  }
7886
7902
  });
7887
7903
  }
7888
7904
  }), createComponent(Show, {
7889
7905
  get when() {
7890
- return !restoringProcess();
7906
+ return account();
7891
7907
  },
7892
7908
  get children() {
7893
- return [createComponent(Show, {
7894
- get when() {
7895
- return !account();
7896
- },
7909
+ return createComponent(DropdownContainerStyled, {
7897
7910
  get children() {
7898
- return createComponent(AccountButtonStyled, {
7899
- onClick: () => tonConnectUI.openModal(),
7900
- "data-tc-connect-button": "true",
7911
+ return [createComponent(DropdownButtonStyled, {
7912
+ onClick: () => setIsOpened((v) => !v),
7913
+ ref: setAnchor,
7914
+ "data-tc-dropdown-button": "true",
7901
7915
  scale: "s",
7902
7916
  get children() {
7903
- return [createComponent(TonIcon, {
7904
- get fill() {
7905
- return theme.colors.connectButton.foreground;
7906
- }
7907
- }), createComponent(Text, {
7908
- translationKey: "button.connectWallet",
7917
+ return [createComponent(Text, {
7909
7918
  fontSize: "15px",
7910
- lineHeight: "18px",
7911
7919
  fontWeight: "590",
7912
- get color() {
7913
- return theme.colors.connectButton.foreground;
7914
- },
7915
- children: "Connect wallet"
7920
+ lineHeight: "18px",
7921
+ get children() {
7922
+ return normalizedAddress();
7923
+ }
7924
+ }), createComponent(ArrowIcon, {
7925
+ direction: "bottom"
7916
7926
  })];
7917
7927
  }
7918
- });
7919
- }
7920
- }), createComponent(Show, {
7921
- get when() {
7922
- return account();
7923
- },
7924
- get children() {
7925
- return createComponent(DropdownContainerStyled, {
7928
+ }), createComponent(Portal, {
7926
7929
  get children() {
7927
- return [createComponent(DropdownButtonStyled, {
7928
- onClick: () => setIsOpened((v) => !v),
7929
- ref: setAnchor,
7930
- "data-tc-dropdown-button": "true",
7931
- scale: "s",
7932
- get children() {
7933
- return [createComponent(Text, {
7934
- fontSize: "15px",
7935
- fontWeight: "590",
7936
- lineHeight: "18px",
7937
- get children() {
7938
- return normalizedAddress();
7939
- }
7940
- }), createComponent(ArrowIcon, {
7941
- direction: "bottom"
7942
- })];
7943
- }
7944
- }), createComponent(Portal, {
7930
+ const _el$ = untrack(() => document.importNode(_tmpl$$3, true));
7931
+ use(setFloating, _el$);
7932
+ _el$.style.setProperty("z-index", "999");
7933
+ _el$._$owner = getOwner();
7934
+ insert(_el$, createComponent(Transition, {
7935
+ onBeforeEnter: (el) => {
7936
+ animate(el, [{
7937
+ opacity: 0,
7938
+ transform: "translateY(-8px)"
7939
+ }, {
7940
+ opacity: 1,
7941
+ transform: "translateY(0)"
7942
+ }], {
7943
+ duration: 150
7944
+ });
7945
+ },
7946
+ onExit: (el, done) => {
7947
+ const a2 = animate(el, [{
7948
+ opacity: 1,
7949
+ transform: "translateY(0)"
7950
+ }, {
7951
+ opacity: 0,
7952
+ transform: "translateY(-8px)"
7953
+ }], {
7954
+ duration: 150
7955
+ });
7956
+ a2.finished.then(done);
7957
+ },
7945
7958
  get children() {
7946
- const _el$ = untrack(() => document.importNode(_tmpl$$3, true));
7947
- use(setFloating, _el$);
7948
- _el$.style.setProperty("z-index", "999");
7949
- _el$._$owner = getOwner();
7950
- insert(_el$, createComponent(Transition, {
7951
- onBeforeEnter: (el) => {
7952
- animate(el, [{
7953
- opacity: 0,
7954
- transform: "translateY(-8px)"
7955
- }, {
7956
- opacity: 1,
7957
- transform: "translateY(0)"
7958
- }], {
7959
- duration: 150
7960
- });
7961
- },
7962
- onExit: (el, done) => {
7963
- const a2 = animate(el, [{
7964
- opacity: 1,
7965
- transform: "translateY(0)"
7966
- }, {
7967
- opacity: 0,
7968
- transform: "translateY(-8px)"
7969
- }], {
7970
- duration: 150
7971
- });
7972
- a2.finished.then(done);
7959
+ return createComponent(Show, {
7960
+ get when() {
7961
+ return isOpened();
7973
7962
  },
7974
7963
  get children() {
7975
- return createComponent(Show, {
7976
- get when() {
7977
- return isOpened();
7964
+ return createComponent(DropdownStyled, {
7965
+ get hidden() {
7966
+ return !isOpened();
7978
7967
  },
7979
- get children() {
7980
- return createComponent(DropdownStyled, {
7981
- get hidden() {
7982
- return !isOpened();
7983
- },
7984
- onClose: () => setIsOpened(false),
7985
- ref(r$) {
7986
- const _ref$ = dropDownRef;
7987
- typeof _ref$ === "function" ? _ref$(r$) : dropDownRef = r$;
7988
- }
7989
- });
7968
+ onClose: () => setIsOpened(false),
7969
+ ref(r$) {
7970
+ const _ref$ = dropDownRef;
7971
+ typeof _ref$ === "function" ? _ref$(r$) : dropDownRef = r$;
7990
7972
  }
7991
7973
  });
7992
7974
  }
7993
- }), null);
7994
- insert(_el$, createComponent(NotificationsStyled, {}), null);
7995
- createRenderEffect((_p$) => {
7996
- var _a2, _b2;
7997
- const _v$ = position.strategy, _v$2 = `${(_a2 = position.y) != null ? _a2 : 0}px`, _v$3 = `${(_b2 = position.x) != null ? _b2 : 0}px`;
7998
- _v$ !== _p$._v$ && _el$.style.setProperty("position", _p$._v$ = _v$);
7999
- _v$2 !== _p$._v$2 && _el$.style.setProperty("top", _p$._v$2 = _v$2);
8000
- _v$3 !== _p$._v$3 && _el$.style.setProperty("left", _p$._v$3 = _v$3);
8001
- return _p$;
8002
- }, {
8003
- _v$: void 0,
8004
- _v$2: void 0,
8005
- _v$3: void 0
8006
7975
  });
8007
- return _el$;
8008
7976
  }
8009
- })];
7977
+ }), null);
7978
+ insert(_el$, createComponent(NotificationsStyled, {}), null);
7979
+ createRenderEffect((_p$) => {
7980
+ var _a2, _b2;
7981
+ const _v$ = position.strategy, _v$2 = `${(_a2 = position.y) != null ? _a2 : 0}px`, _v$3 = `${(_b2 = position.x) != null ? _b2 : 0}px`;
7982
+ _v$ !== _p$._v$ && _el$.style.setProperty("position", _p$._v$ = _v$);
7983
+ _v$2 !== _p$._v$2 && _el$.style.setProperty("top", _p$._v$2 = _v$2);
7984
+ _v$3 !== _p$._v$3 && _el$.style.setProperty("left", _p$._v$3 = _v$3);
7985
+ return _p$;
7986
+ }, {
7987
+ _v$: void 0,
7988
+ _v$2: void 0,
7989
+ _v$3: void 0
7990
+ });
7991
+ return _el$;
8010
7992
  }
8011
- });
7993
+ })];
8012
7994
  }
8013
- })];
7995
+ });
8014
7996
  }
8015
7997
  })];
8016
7998
  }
@@ -8369,6 +8351,27 @@ function redirectToTelegram(universalLink, options) {
8369
8351
  );
8370
8352
  openLinkBlank(linkWithStrategy);
8371
8353
  }
8354
+ } else if (isOS("ipad")) {
8355
+ if (options.returnStrategy === "back") {
8356
+ options.returnStrategy = "back";
8357
+ }
8358
+ const isChrome = isBrowser("chrome");
8359
+ const isFirefox = isBrowser("firefox");
8360
+ const useDeepLink = (isChrome || isFirefox) && !options.forceRedirect;
8361
+ if (useDeepLink) {
8362
+ const linkWithStrategy = addReturnStrategy(
8363
+ directLinkUrl.toString(),
8364
+ options.returnStrategy
8365
+ );
8366
+ const deepLink = convertToTGDeepLink(linkWithStrategy);
8367
+ openDeeplinkWithFallback(deepLink, () => openLinkBlank(linkWithStrategy));
8368
+ } else {
8369
+ const linkWithStrategy = addReturnStrategy(
8370
+ directLinkUrl.toString(),
8371
+ options.returnStrategy
8372
+ );
8373
+ openLinkBlank(linkWithStrategy);
8374
+ }
8372
8375
  } else if (isOS("macos", "windows", "linux")) {
8373
8376
  options.returnStrategy = "none";
8374
8377
  options.twaReturnUrl = void 0;
@@ -8506,6 +8509,17 @@ function redirectToWallet(universalLink, deepLink, options, setOpenMethod) {
8506
8509
  }
8507
8510
  setOpenMethod("universal-link");
8508
8511
  openLinkBlank(addReturnStrategy(universalLink, options.returnStrategy));
8512
+ } else if (isOS("ipad")) {
8513
+ if (options.returnStrategy === "back") {
8514
+ options.returnStrategy = "back";
8515
+ }
8516
+ if (isBrowser("chrome")) {
8517
+ setOpenMethod("universal-link");
8518
+ openLink(addReturnStrategy(universalLink, options.returnStrategy), "_self");
8519
+ } else {
8520
+ setOpenMethod("universal-link");
8521
+ openLinkBlank(addReturnStrategy(universalLink, options.returnStrategy));
8522
+ }
8509
8523
  } else if (isOS("macos", "windows", "linux")) {
8510
8524
  if (options.returnStrategy === "back") {
8511
8525
  if (isBrowser("safari")) {
@@ -10098,6 +10112,14 @@ const TextStyled = styled(Text)`
10098
10112
 
10099
10113
  color: ${(props) => props.theme.colors.text.secondary};
10100
10114
  `;
10115
+ const LoaderButtonStyled = styled(Button)`
10116
+ min-width: 112px;
10117
+ margin-top: 32px;
10118
+ `;
10119
+ const LoaderIconStyled = styled(LoaderIcon)`
10120
+ height: 16px;
10121
+ width: 16px;
10122
+ `;
10101
10123
  const ButtonStyled = styled(Button)`
10102
10124
  margin-top: 32px;
10103
10125
  `;
@@ -10105,6 +10127,11 @@ const ActionModal = (props) => {
10105
10127
  const dataAttrs = useDataAttributes(props);
10106
10128
  const tonConnectUI = useContext(TonConnectUiContext);
10107
10129
  const [firstClick, setFirstClick] = createSignal(true);
10130
+ const [sent, setSent] = createSignal(false);
10131
+ createEffect(() => {
10132
+ const currentAction = action();
10133
+ setSent(!!currentAction && "sent" in currentAction && currentAction.sent);
10134
+ });
10108
10135
  let universalLink;
10109
10136
  if ((tonConnectUI == null ? void 0 : tonConnectUI.wallet) && "universalLink" in tonConnectUI.wallet && (tonConnectUI.wallet.openMethod === "universal-link" || isTelegramUrl(tonConnectUI.wallet.universalLink) && isInTMA())) {
10110
10137
  universalLink = tonConnectUI.wallet.universalLink;
@@ -10150,33 +10177,53 @@ const ActionModal = (props) => {
10150
10177
  }
10151
10178
  }), createComponent(Show, {
10152
10179
  get when() {
10153
- return props.showButton !== "open-wallet";
10180
+ return !sent();
10154
10181
  },
10155
10182
  get children() {
10156
- return createComponent(ButtonStyled, {
10157
- onClick: () => props.onClose(),
10183
+ return createComponent(LoaderButtonStyled, {
10184
+ disabled: true,
10185
+ "data-tc-connect-button-loading": "true",
10158
10186
  get children() {
10159
- return createComponent(Translation, {
10160
- translationKey: "common.close",
10161
- children: "Close"
10162
- });
10187
+ return createComponent(LoaderIconStyled, {});
10163
10188
  }
10164
10189
  });
10165
10190
  }
10166
10191
  }), createComponent(Show, {
10167
10192
  get when() {
10168
- return props.showButton === "open-wallet" && universalLink;
10193
+ return sent();
10169
10194
  },
10170
10195
  get children() {
10171
- return createComponent(ButtonStyled, {
10172
- onClick: onOpenWallet,
10196
+ return [createComponent(Show, {
10197
+ get when() {
10198
+ return props.showButton !== "open-wallet";
10199
+ },
10173
10200
  get children() {
10174
- return createComponent(Translation, {
10175
- translationKey: "common.openWallet",
10176
- children: "Open wallet"
10201
+ return createComponent(ButtonStyled, {
10202
+ onClick: () => props.onClose(),
10203
+ get children() {
10204
+ return createComponent(Translation, {
10205
+ translationKey: "common.close",
10206
+ children: "Close"
10207
+ });
10208
+ }
10177
10209
  });
10178
10210
  }
10179
- });
10211
+ }), createComponent(Show, {
10212
+ get when() {
10213
+ return props.showButton === "open-wallet" && universalLink;
10214
+ },
10215
+ get children() {
10216
+ return createComponent(ButtonStyled, {
10217
+ onClick: onOpenWallet,
10218
+ get children() {
10219
+ return createComponent(Translation, {
10220
+ translationKey: "common.openWallet",
10221
+ children: "Open wallet"
10222
+ });
10223
+ }
10224
+ });
10225
+ }
10226
+ })];
10180
10227
  }
10181
10228
  })];
10182
10229
  }
@@ -10808,9 +10855,19 @@ class TonConnectUI {
10808
10855
  widgetController.setAction({
10809
10856
  name: "confirm-transaction",
10810
10857
  showNotification: notifications2.includes("before"),
10811
- openModal: modals.includes("before")
10858
+ openModal: modals.includes("before"),
10859
+ sent: false
10812
10860
  });
10813
10861
  const onRequestSent = () => {
10862
+ if (abortController.signal.aborted) {
10863
+ return;
10864
+ }
10865
+ widgetController.setAction({
10866
+ name: "confirm-transaction",
10867
+ showNotification: notifications2.includes("before"),
10868
+ openModal: modals.includes("before"),
10869
+ sent: true
10870
+ });
10814
10871
  const userOSIsIos = getUserAgent().os === "ios";
10815
10872
  const shouldSkipRedirectToWallet = skipRedirectToWallet === "ios" && userOSIsIos || skipRedirectToWallet === "always";
10816
10873
  if (this.walletInfo && "universalLink" in this.walletInfo && this.walletInfo.openMethod === "universal-link" && !shouldSkipRedirectToWallet) {
@@ -10839,7 +10896,7 @@ class TonConnectUI {
10839
10896
  const result = yield this.waitForSendTransaction(
10840
10897
  {
10841
10898
  transaction: tx,
10842
- abortSignal: abortController.signal
10899
+ signal: abortController.signal
10843
10900
  },
10844
10901
  onRequestSent
10845
10902
  );
@@ -10899,15 +10956,15 @@ class TonConnectUI {
10899
10956
  });
10900
10957
  return yield this.waitForWalletConnection({
10901
10958
  ignoreErrors: true,
10902
- abortSignal: abortController.signal
10959
+ signal: abortController.signal
10903
10960
  });
10904
10961
  });
10905
10962
  }
10906
10963
  waitForWalletConnection(options) {
10907
10964
  return __async(this, null, function* () {
10908
10965
  return new Promise((resolve, reject) => {
10909
- const { ignoreErrors = false, abortSignal = null } = options;
10910
- if (abortSignal && abortSignal.aborted) {
10966
+ const { ignoreErrors = false, signal = null } = options;
10967
+ if (signal && signal.aborted) {
10911
10968
  return reject(new TonConnectUIError("Wallet was not connected"));
10912
10969
  }
10913
10970
  const onStatusChangeHandler = (wallet) => __async(this, null, function* () {
@@ -10933,11 +10990,15 @@ class TonConnectUI {
10933
10990
  (wallet) => onStatusChangeHandler(wallet),
10934
10991
  (reason) => onErrorsHandler(reason)
10935
10992
  );
10936
- if (abortSignal) {
10937
- abortSignal.addEventListener("abort", () => {
10938
- unsubscribe();
10939
- reject(new TonConnectUIError("Wallet was not connected"));
10940
- });
10993
+ if (signal) {
10994
+ signal.addEventListener(
10995
+ "abort",
10996
+ () => {
10997
+ unsubscribe();
10998
+ reject(new TonConnectUIError("Wallet was not connected"));
10999
+ },
11000
+ { once: true }
11001
+ );
10941
11002
  }
10942
11003
  });
10943
11004
  });
@@ -10945,8 +11006,8 @@ class TonConnectUI {
10945
11006
  waitForSendTransaction(options, onRequestSent) {
10946
11007
  return __async(this, null, function* () {
10947
11008
  return new Promise((resolve, reject) => {
10948
- const { transaction, abortSignal } = options;
10949
- if (abortSignal.aborted) {
11009
+ const { transaction, signal } = options;
11010
+ if (signal.aborted) {
10950
11011
  return reject(new TonConnectUIError("Transaction was not sent"));
10951
11012
  }
10952
11013
  const onTransactionHandler = (transaction2) => __async(this, null, function* () {
@@ -10955,10 +11016,14 @@ class TonConnectUI {
10955
11016
  const onErrorsHandler = (reason) => {
10956
11017
  reject(reason);
10957
11018
  };
10958
- this.connector.sendTransaction(transaction, onRequestSent).then((result) => onTransactionHandler(result)).catch((reason) => onErrorsHandler(reason));
10959
- abortSignal.addEventListener("abort", () => {
10960
- reject(new TonConnectUIError("Transaction was not sent"));
10961
- });
11019
+ this.connector.sendTransaction(transaction, { onRequestSent, signal }).then((result) => onTransactionHandler(result)).catch((reason) => onErrorsHandler(reason));
11020
+ signal.addEventListener(
11021
+ "abort",
11022
+ () => {
11023
+ reject(new TonConnectUIError("Transaction was not sent"));
11024
+ },
11025
+ { once: true }
11026
+ );
10962
11027
  });
10963
11028
  });
10964
11029
  }