@tonconnect/ui 0.0.14 → 0.0.16

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.d.ts CHANGED
@@ -111,6 +111,12 @@ declare type WalletsListConfigurationImplicit = {
111
111
  includeWalletsOrder?: 'start' | 'end';
112
112
  };
113
113
 
114
+ /**
115
+ * Specifies return strategy for the deeplink when user signs/declines the request.
116
+ * [See details]{@link https://github.com/ton-connect/docs/blob/main/bridge.md#universal-link}.
117
+ */
118
+ declare type ReturnStrategy = 'back' | 'none' | `${string}://${string}`;
119
+
114
120
  interface ActionConfiguration {
115
121
  /**
116
122
  * Configure action modals behavior.
@@ -122,6 +128,11 @@ interface ActionConfiguration {
122
128
  * @default 'all'
123
129
  */
124
130
  notifications?: ('before' | 'success' | 'error')[] | 'all';
131
+ /**
132
+ * Specifies return strategy for the deeplink when user signs/declines the request.
133
+ * @default 'back'
134
+ */
135
+ returnStrategy?: ReturnStrategy;
125
136
  }
126
137
 
127
138
  interface TonConnectUiOptions {
@@ -144,7 +155,7 @@ interface TonConnectUiOptions {
144
155
  */
145
156
  walletsList?: WalletsListConfiguration;
146
157
  /**
147
- * Configuration for action-period (e.g. sendTransaction) UI elements: modals and notifications.
158
+ * Configuration for action-period (e.g. sendTransaction) UI elements: modals and notifications and wallet behaviour (return strategy).
148
159
  */
149
160
  actionsConfiguration?: ActionConfiguration;
150
161
  }
@@ -265,4 +276,4 @@ declare class TonConnectUIError extends TonConnectError {
265
276
  constructor(...args: ConstructorParameters<typeof Error>);
266
277
  }
267
278
 
268
- export { ActionConfiguration, BorderRadius, Color, ColorsSet, ConnectedWallet, Locales, PartialColorsSet, THEME, Theme, TonConnectUI, TonConnectUIError, TonConnectUiCreateOptions, TonConnectUiCreateOptionsBase, TonConnectUiOptions, TonConnectUiOptionsWithConnector, TonConnectUiOptionsWithManifest, UIPreferences, UIWallet, WalletInfoRemoteWithOpenMethod, WalletInfoWithOpenMethod, WalletOpenMethod, WalletsListConfiguration, WalletsListConfigurationExplicit, WalletsListConfigurationImplicit, TonConnectUI as default };
279
+ export { ActionConfiguration, BorderRadius, Color, ColorsSet, ConnectedWallet, Locales, PartialColorsSet, ReturnStrategy, THEME, Theme, TonConnectUI, TonConnectUIError, TonConnectUiCreateOptions, TonConnectUiCreateOptionsBase, TonConnectUiOptions, TonConnectUiOptionsWithConnector, TonConnectUiOptionsWithManifest, UIPreferences, UIWallet, WalletInfoRemoteWithOpenMethod, WalletInfoWithOpenMethod, WalletOpenMethod, WalletsListConfiguration, WalletsListConfigurationExplicit, WalletsListConfigurationImplicit, TonConnectUI as default };
package/lib/index.js CHANGED
@@ -3076,10 +3076,12 @@ class BridgeProvider {
3076
3076
  this.storage = storage;
3077
3077
  this.walletConnectionSource = walletConnectionSource;
3078
3078
  this.type = "http";
3079
+ this.standardUniversalLink = "https://connect.ton.org";
3079
3080
  this.pendingRequests = /* @__PURE__ */ new Map();
3080
3081
  this.nextRequestId = 0;
3081
3082
  this.session = null;
3082
3083
  this.bridge = null;
3084
+ this.pendingBridges = [];
3083
3085
  this.listeners = [];
3084
3086
  this.connectionStorage = new BridgeConnectionStorage(storage);
3085
3087
  }
@@ -3091,21 +3093,32 @@ class BridgeProvider {
3091
3093
  });
3092
3094
  }
3093
3095
  connect(message) {
3094
- var _a;
3095
- (_a = this.bridge) === null || _a === void 0 ? void 0 : _a.close();
3096
+ this.closeBridges();
3096
3097
  const sessionCrypto = new SessionCrypto();
3098
+ let walletConnectionSource = {
3099
+ universalLink: this.standardUniversalLink,
3100
+ bridgeUrl: ""
3101
+ };
3102
+ if (Array.isArray(this.walletConnectionSource)) {
3103
+ this.pendingBridges = this.walletConnectionSource.map((source) => new BridgeGateway(this.storage, source, sessionCrypto.sessionId, this.gatewayListener.bind(this), this.gatewayErrorsListener.bind(this)));
3104
+ this.pendingBridges.forEach((bridge) => bridge.registerSession());
3105
+ } else {
3106
+ walletConnectionSource = this.walletConnectionSource;
3107
+ this.bridge = new BridgeGateway(this.storage, this.walletConnectionSource.bridgeUrl, sessionCrypto.sessionId, this.gatewayListener.bind(this), this.gatewayErrorsListener.bind(this));
3108
+ this.bridge.registerSession();
3109
+ }
3097
3110
  this.session = {
3098
3111
  sessionCrypto,
3099
- walletConnectionSource: this.walletConnectionSource
3112
+ walletConnectionSource
3100
3113
  };
3101
- this.bridge = new BridgeGateway(this.storage, this.walletConnectionSource.bridgeUrl, sessionCrypto.sessionId, this.gatewayListener.bind(this), this.gatewayErrorsListener.bind(this));
3102
- this.bridge.registerSession();
3103
- return this.generateUniversalLink(message);
3114
+ return this.generateUniversalLink(walletConnectionSource.universalLink, message);
3104
3115
  }
3105
3116
  restoreConnection() {
3106
- var _a;
3107
3117
  return __awaiter$4(this, void 0, void 0, function* () {
3108
- (_a = this.bridge) === null || _a === void 0 ? void 0 : _a.close();
3118
+ if (Array.isArray(this.walletConnectionSource)) {
3119
+ throw new TonConnectError("Internal error. Connection source is array while WalletConnectionSourceHTTP was expected.");
3120
+ }
3121
+ this.closeBridges();
3109
3122
  const storedConnection = yield this.connectionStorage.getHttpConnection();
3110
3123
  if (!storedConnection) {
3111
3124
  return;
@@ -3129,15 +3142,13 @@ class BridgeProvider {
3129
3142
  });
3130
3143
  }
3131
3144
  closeConnection() {
3132
- var _a;
3133
- (_a = this.bridge) === null || _a === void 0 ? void 0 : _a.close();
3145
+ this.closeBridges();
3134
3146
  this.listeners = [];
3135
3147
  this.session = null;
3136
3148
  this.bridge = null;
3137
3149
  }
3138
3150
  disconnect() {
3139
- var _a;
3140
- (_a = this.bridge) === null || _a === void 0 ? void 0 : _a.close();
3151
+ this.closeBridges();
3141
3152
  this.listeners = [];
3142
3153
  return this.removeBridgeAndSession();
3143
3154
  }
@@ -3145,6 +3156,18 @@ class BridgeProvider {
3145
3156
  this.listeners.push(callback);
3146
3157
  return () => this.listeners = this.listeners.filter((listener) => listener !== callback);
3147
3158
  }
3159
+ pendingGatewaysListener(gateway, bridgeIncomingMessage) {
3160
+ return __awaiter$4(this, void 0, void 0, function* () {
3161
+ if (!this.pendingBridges.includes(gateway)) {
3162
+ gateway.close();
3163
+ return;
3164
+ }
3165
+ this.closeBridges();
3166
+ this.session.walletConnectionSource.bridgeUrl = gateway.bridgeUrl;
3167
+ this.bridge = gateway;
3168
+ return this.gatewayListener(bridgeIncomingMessage);
3169
+ });
3170
+ }
3148
3171
  gatewayListener(bridgeIncomingMessage) {
3149
3172
  return __awaiter$4(this, void 0, void 0, function* () {
3150
3173
  const walletMessage = JSON.parse(this.session.sessionCrypto.decrypt(Base64.decode(bridgeIncomingMessage.message).toUint8Array(), hexToByteArray(bridgeIncomingMessage.from)));
@@ -3191,13 +3214,19 @@ class BridgeProvider {
3191
3214
  yield this.connectionStorage.removeConnection();
3192
3215
  });
3193
3216
  }
3194
- generateUniversalLink(message) {
3195
- const url = new URL(this.walletConnectionSource.universalLink);
3217
+ generateUniversalLink(universalLink, message) {
3218
+ const url = new URL(universalLink);
3196
3219
  url.searchParams.append("v", PROTOCOL_VERSION.toString());
3197
3220
  url.searchParams.append("id", this.session.sessionCrypto.sessionId);
3198
3221
  url.searchParams.append("r", JSON.stringify(message));
3199
3222
  return url.toString();
3200
3223
  }
3224
+ closeBridges(except) {
3225
+ var _a;
3226
+ (_a = this.bridge) === null || _a === void 0 ? void 0 : _a.close();
3227
+ this.pendingBridges.filter((item) => item !== except).forEach((bridge) => bridge.close());
3228
+ this.pendingBridges = [];
3229
+ }
3201
3230
  }
3202
3231
  function getWindow$1() {
3203
3232
  if (typeof window === "undefined") {
@@ -3681,7 +3710,7 @@ class TonConnect {
3681
3710
  }
3682
3711
  createProvider(wallet) {
3683
3712
  let provider;
3684
- if (isWalletConnectionSourceJS(wallet)) {
3713
+ if (!Array.isArray(wallet) && isWalletConnectionSourceJS(wallet)) {
3685
3714
  provider = new InjectedProvider(this.dappSettings.storage, wallet.jsBridgeKey);
3686
3715
  } else {
3687
3716
  provider = new BridgeProvider(this.dappSettings.storage, wallet);
@@ -4876,6 +4905,10 @@ function render(code, element, init, options = {}) {
4876
4905
  };
4877
4906
  }
4878
4907
  function template$1(html, check, isSVG) {
4908
+ if (typeof window === 'undefined') {
4909
+ return null;
4910
+ }
4911
+
4879
4912
  const t2 = document.createElement("template");
4880
4913
  t2.innerHTML = html;
4881
4914
  let node = t2.content.firstChild;
@@ -10158,6 +10191,20 @@ function subscribeToThemeChange(callback) {
10158
10191
  window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", handler);
10159
10192
  return () => window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", handler);
10160
10193
  }
10194
+ function addQueryParameter(url, key, value) {
10195
+ const parsed = new URL(url);
10196
+ parsed.searchParams.append(key, value);
10197
+ return parsed.toString();
10198
+ }
10199
+ function addReturnStrategy(url, returnStrategy) {
10200
+ return addQueryParameter(url, "ret", returnStrategy);
10201
+ }
10202
+ const [appState, setAppState] = createStore({
10203
+ buttonRootId: null,
10204
+ language: "en",
10205
+ returnStrategy: "back",
10206
+ walletsList: {}
10207
+ });
10161
10208
  const QrCodeModal = (props) => {
10162
10209
  const connector = useContext(ConnectorContext);
10163
10210
  const universalLink = connector.connect({
@@ -10208,7 +10255,7 @@ const QrCodeModal = (props) => {
10208
10255
  setLastSelectedWalletInfo(__spreadProps(__spreadValues({}, props.wallet), {
10209
10256
  openMethod: "universal-link"
10210
10257
  }));
10211
- openLink(universalLink);
10258
+ openLink(addReturnStrategy(universalLink, appState.returnStrategy));
10212
10259
  },
10213
10260
  get children() {
10214
10261
  return createComponent(Translation, {
@@ -10448,11 +10495,6 @@ const LoaderContainerStyled = styled.div`
10448
10495
  align-items: center;
10449
10496
  }
10450
10497
  `;
10451
- const [appState, setAppState] = createStore({
10452
- buttonRootId: null,
10453
- language: "en",
10454
- walletsList: {}
10455
- });
10456
10498
  function uiWalletToWalletInfo(uiWallet) {
10457
10499
  if ("jsBridgeKey" in uiWallet) {
10458
10500
  return __spreadProps(__spreadValues({}, uiWallet), {
@@ -10556,14 +10598,14 @@ const WalletsModal = () => {
10556
10598
  setSelectedWalletInfo(walletInfo);
10557
10599
  return;
10558
10600
  }
10559
- openLink(walletInfo.aboutUrl, "_blank");
10601
+ openLinkBlank(walletInfo.aboutUrl);
10560
10602
  };
10561
10603
  const onSelectIfMobile = (walletInfo) => {
10562
10604
  const universalLink = connector.connect({
10563
10605
  universalLink: walletInfo.universalLink,
10564
10606
  bridgeUrl: walletInfo.bridgeUrl
10565
10607
  }, additionalRequest());
10566
- openLink(universalLink);
10608
+ openLink(addReturnStrategy(universalLink, appState.returnStrategy));
10567
10609
  };
10568
10610
  const onSelectIfInjected = (walletInfo) => {
10569
10611
  connector.connect({
@@ -10855,7 +10897,7 @@ class WalletInfoStorage {
10855
10897
  constructor() {
10856
10898
  __publicField(this, "localStorage");
10857
10899
  __publicField(this, "storageKey", "ton-connect-ui_wallet-info");
10858
- if (!localStorage) {
10900
+ if (typeof localStorage === "undefined") {
10859
10901
  throw new TonConnectUIError(
10860
10902
  "window.localStorage is undefined. localStorage is required for TonConnectUI"
10861
10903
  );
@@ -10953,8 +10995,11 @@ class TonConnectUI {
10953
10995
  setBorderRadius(options.uiPreferences.borderRadius);
10954
10996
  }
10955
10997
  setAppState((state) => {
10998
+ var _a2;
10956
10999
  const merged = mergeOptions(
10957
- __spreadValues(__spreadValues({}, options.language && { language: options.language }), !!options.walletsList && { walletsList: options.walletsList }),
11000
+ __spreadValues(__spreadValues(__spreadValues({}, options.language && { language: options.language }), !!((_a2 = options.actionsConfiguration) == null ? void 0 : _a2.returnStrategy) && {
11001
+ returnStrategy: options.actionsConfiguration.returnStrategy
11002
+ }), !!options.walletsList && { walletsList: options.walletsList }),
10958
11003
  unwrap(state)
10959
11004
  );
10960
11005
  if (options.buttonRootId !== void 0) {
@@ -11014,10 +11059,10 @@ class TonConnectUI {
11014
11059
  if (!this.connected || !this.walletInfo) {
11015
11060
  throw new TonConnectUIError("Connect wallet to send a transaction.");
11016
11061
  }
11062
+ const { notifications: notifications2, modals, returnStrategy } = this.getModalsAndNotificationsConfiguration(options);
11017
11063
  if ("universalLink" in this.walletInfo && this.walletInfo.openMethod === "universal-link") {
11018
- openLink(this.walletInfo.universalLink);
11064
+ openLink(addReturnStrategy(this.walletInfo.universalLink, returnStrategy));
11019
11065
  }
11020
- const { notifications: notifications2, modals } = this.getModalsAndNotificationsConfiguration(options);
11021
11066
  widgetController.setAction({
11022
11067
  name: "confirm-transaction",
11023
11068
  showNotification: notifications2.includes("before"),
@@ -11116,7 +11161,8 @@ class TonConnectUI {
11116
11161
  }
11117
11162
  return {
11118
11163
  notifications: notifications2,
11119
- modals
11164
+ modals,
11165
+ returnStrategy: (options == null ? void 0 : options.returnStrategy) || "back"
11120
11166
  };
11121
11167
  }
11122
11168
  }