@tonconnect/ui-react 0.0.6 → 0.0.8

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/README.md CHANGED
@@ -144,3 +144,50 @@ export const Settings = () => {
144
144
  );
145
145
  };
146
146
  ```
147
+
148
+
149
+ ## Add connect request parameters (ton_proof)
150
+ Pass `getConnectParameters` async function to the `TonConnectUIProvider`. This callback will be called after `connectWallet` method call or `Connect Button` click before wallets list render.
151
+
152
+ In other words, if `getConnectParameters` is passed, there will be a following steps:
153
+ 1. User clicks to the 'Connect Wallet' button, or `connectWallet` method is called
154
+ 2. Wallets modal opens
155
+ 3. Loader renders in the center of the modal
156
+ 4. TonConnectUI calls `getConnectParameters` and waits while it resolves
157
+ 5. Wallets list renders in the center of the modal
158
+
159
+ Note that there is no any caching for `getConnectParameters` -- every time wallets modal opens there will be the 5 steps above.
160
+
161
+ If you have to make a http-request to your backend it this case, it is better to do it after app initialization (if possible) and return (probably completed) promise from the `getConnectParameters` to reduce loading time for the user.
162
+
163
+ ```tsx
164
+ const tonProofPayloadPromise = getTonProofFromYourBackend(); // will be executed during app initialization
165
+ // don't forget to manage to refetch payload from your backend if needed
166
+ <TonConnectUIProvider
167
+ manifestUrl="https://<YOUR_APP_URL>/tonconnect-manifest.json"
168
+ getConnectParameters={async () => {
169
+ const tonProof = await tonProofPayloadPromise; // will be executed every time when wallets modal is opened. It is recommended to make an http-request in advance
170
+ return {
171
+ tonProof
172
+ };
173
+ }}
174
+ >
175
+ { /* Your app */ }
176
+ </TonConnectUIProvider>
177
+ ```
178
+
179
+ You can find `ton_proof` result in the `wallet` object when wallet will be connected:
180
+
181
+ ```ts
182
+ import {useTonConnectUI} from "@tonconnect/ui-react";
183
+
184
+ const [tonConnectUI] = useTonConnectUI();
185
+
186
+ useEffect(() =>
187
+ tonConnectUI.onStatusChange(wallet => {
188
+ if (wallet.connectItems?.tonProof && 'proof' in wallet.connectItems.tonProof) {
189
+ checkProofInYourBackend(wallet.connectItems.tonProof.proof, wallet.account);
190
+ }
191
+ }), []);
192
+ ```
193
+
@@ -1,5 +1,5 @@
1
1
  import { ActionConfiguration, Locales, Theme, TonConnectUI, UIPreferences, WalletsListConfiguration } from '@tonconnect/ui';
2
- import { ITonConnect } from '@tonconnect/sdk';
2
+ import type { ConnectAdditionalRequest, ITonConnect } from '@tonconnect/sdk';
3
3
  export declare const TonConnectUIContext: import("react").Context<TonConnectUI | null>;
4
4
  export declare type TonConnectUIProviderProps = {
5
5
  children: JSX.Element;
@@ -51,9 +51,17 @@ export interface TonConnectUIProviderPropsBase {
51
51
  */
52
52
  actionsConfiguration?: ActionConfiguration;
53
53
  /**
54
- * @deprecated Don't use it
54
+ * Redefine wallets list source URL. Must be a link to a json file with [following structure]{@link https://github.com/ton-connect/wallets-list}
55
+ * @default https://raw.githubusercontent.com/ton-connect/wallets-list/main/wallets.json
56
+ * @
55
57
  */
56
58
  walletsListSource?: string;
59
+ /**
60
+ * Use it to customize ConnectRequest and add `tonProof` payload.
61
+ * The function will be called after wallets modal opens, and wallets selection will be blocked until it's resolved.
62
+ * If you have to make a http-request to your backend, it is better to do it after app initialization (if possible) and return (probably completed) promise to reduce loading time for the user.
63
+ */
64
+ getConnectParameters?: () => Promise<ConnectAdditionalRequest>;
57
65
  }
58
66
  declare const _default: import("react").NamedExoticComponent<TonConnectUIProviderProps>;
59
67
  export default _default;
@@ -1,2 +1,2 @@
1
- export { default as TonConnectButton } from './TonConnectButton';
2
- export { default as TonConnectUIProvider } from './TonConnectUIProvider';
1
+ export { default as TonConnectButton, type TonConnectButtonProps } from './TonConnectButton';
2
+ export { default as TonConnectUIProvider, type TonConnectUIProviderProps, type TonConnectUIProviderPropsBase, type TonConnectUIProviderPropsWithConnector, type TonConnectUIProviderPropsWithManifest, TonConnectUIContext } from './TonConnectUIProvider';
package/lib/index.d.ts CHANGED
@@ -1,4 +1,2 @@
1
- export * from './components';
2
- export * from './errors';
3
- export * from './hooks';
1
+ export * from './library';
4
2
  export * from '@tonconnect/ui';
package/lib/index.js CHANGED
@@ -4744,11 +4744,16 @@ class TonConnect {
4744
4744
  TonConnect.walletsList = new WalletsListManager();
4745
4745
  TonConnect.isWalletInjected = (walletJSKey) => InjectedProvider.isWalletInjected(walletJSKey);
4746
4746
  TonConnect.isInsideWalletBrowser = (walletJSKey) => InjectedProvider.isInsideWalletBrowser(walletJSKey);
4747
- function toUserFriendlyAddress$1(hexAddress) {
4747
+ const bounceableTag$1 = 17;
4748
+ const testOnlyTag$1 = 128;
4749
+ function toUserFriendlyAddress$1(hexAddress, testOnly = false) {
4748
4750
  const { wc, hex } = parseHexAddress$1(hexAddress);
4749
- const bounceableTag = 17;
4751
+ let tag = bounceableTag$1;
4752
+ if (testOnly) {
4753
+ tag |= testOnlyTag$1;
4754
+ }
4750
4755
  const addr = new Int8Array(34);
4751
- addr[0] = bounceableTag;
4756
+ addr[0] = tag;
4752
4757
  addr[1] = wc;
4753
4758
  addr.set(hex, 2);
4754
4759
  const addressWithChecksum = new Uint8Array(36);
@@ -8062,7 +8067,7 @@ const AccountButtonDropdown = (props) => {
8062
8067
  const connector = useContext(ConnectorContext);
8063
8068
  const [isCopiedShown, setIsCopiedShown] = createSignal(false);
8064
8069
  const onCopy = () => __async(void 0, null, function* () {
8065
- const userFriendlyAddress = toUserFriendlyAddress$1(tonConnectUi.account.address);
8070
+ const userFriendlyAddress = toUserFriendlyAddress$1(tonConnectUi.account.address, tonConnectUi.account.chain === CHAIN$1.TESTNET);
8066
8071
  yield copyToClipboard(userFriendlyAddress);
8067
8072
  setIsCopiedShown(true);
8068
8073
  setTimeout(() => setIsCopiedShown(false), 1e3);
@@ -9137,7 +9142,7 @@ const AccountButton = () => {
9137
9142
  const connector = useContext(ConnectorContext);
9138
9143
  const tonConnectUI2 = useContext(TonConnectUiContext);
9139
9144
  const [isOpened, setIsOpened] = createSignal(false);
9140
- const [address, setAddress] = createSignal("");
9145
+ const [account, setAccount] = createSignal(null);
9141
9146
  let dropDownRef;
9142
9147
  const [floating, setFloating] = createSignal();
9143
9148
  const [anchor, setAnchor] = createSignal();
@@ -9146,8 +9151,9 @@ const AccountButton = () => {
9146
9151
  placement: "bottom-end"
9147
9152
  });
9148
9153
  const normalizedAddress = () => {
9149
- if (address()) {
9150
- const userFriendlyAddress = toUserFriendlyAddress$1(address());
9154
+ const acc = account();
9155
+ if (acc) {
9156
+ const userFriendlyAddress = toUserFriendlyAddress$1(acc.address, acc.chain === CHAIN$1.TESTNET);
9151
9157
  return userFriendlyAddress.slice(0, 4) + "..." + userFriendlyAddress.slice(-4);
9152
9158
  }
9153
9159
  return "";
@@ -9155,13 +9161,13 @@ const AccountButton = () => {
9155
9161
  const unsubscribe = connector.onStatusChange((wallet) => {
9156
9162
  if (!wallet) {
9157
9163
  setIsOpened(false);
9158
- setAddress("");
9164
+ setAccount(null);
9159
9165
  return;
9160
9166
  }
9161
- setAddress(wallet.account.address);
9167
+ setAccount(wallet.account);
9162
9168
  });
9163
9169
  const onClick = (e2) => {
9164
- if (!address() || !isOpened()) {
9170
+ if (!account() || !isOpened()) {
9165
9171
  return;
9166
9172
  }
9167
9173
  const clickToButton = anchor().contains(e2.target);
@@ -9179,7 +9185,7 @@ const AccountButton = () => {
9179
9185
  });
9180
9186
  return [createComponent(Show, {
9181
9187
  get when() {
9182
- return !address();
9188
+ return !account();
9183
9189
  },
9184
9190
  get children() {
9185
9191
  return createComponent(AccountButtonStyled, {
@@ -9205,7 +9211,7 @@ const AccountButton = () => {
9205
9211
  }
9206
9212
  }), createComponent(Show, {
9207
9213
  get when() {
9208
- return address();
9214
+ return account();
9209
9215
  },
9210
9216
  get children() {
9211
9217
  return createComponent(DropdownContainerStyled, {
@@ -9309,6 +9315,11 @@ const QrCodeStyled = styled.div`
9309
9315
  display: flex;
9310
9316
  align-items: center;
9311
9317
  justify-content: center;
9318
+
9319
+ > svg {
9320
+ height: 276px;
9321
+ width: 276px;
9322
+ }
9312
9323
  }
9313
9324
 
9314
9325
  rect {
@@ -11082,7 +11093,7 @@ const QrCodeModal = (props) => {
11082
11093
  const universalLink = connector.connect({
11083
11094
  universalLink: props.wallet.universalLink,
11084
11095
  bridgeUrl: props.wallet.bridgeUrl
11085
- });
11096
+ }, props.additionalRequest);
11086
11097
  return createComponent(QrCodeModalStyled, {
11087
11098
  get id() {
11088
11099
  return props.id;
@@ -11145,7 +11156,7 @@ const QrCodeModal = (props) => {
11145
11156
  return createComponent(ActionButtonStyled, {
11146
11157
  onClick: () => connector.connect({
11147
11158
  jsBridgeKey: props.wallet.jsBridgeKey
11148
- }),
11159
+ }, props.additionalRequest),
11149
11160
  get children() {
11150
11161
  return createComponent(Translation, {
11151
11162
  translationKey: "walletModal.qrCodeModal.openExtension",
@@ -11415,6 +11426,22 @@ const WalletsModal = () => {
11415
11426
  const connector = useContext(ConnectorContext);
11416
11427
  const tonConnectUI2 = useContext(TonConnectUiContext);
11417
11428
  const [fetchedWalletsList] = createResource(() => tonConnectUI2.getWallets());
11429
+ const [fetchedAdditionalRequest, {
11430
+ refetch
11431
+ }] = createResource((_, {
11432
+ refetching
11433
+ }) => {
11434
+ var _a;
11435
+ if (refetching) {
11436
+ return (_a = appState.getConnectParameters) == null ? void 0 : _a.call(appState);
11437
+ }
11438
+ return void 0;
11439
+ });
11440
+ createEffect(on(walletsModalOpen, () => {
11441
+ if (walletsModalOpen() && fetchedAdditionalRequest.state !== "refreshing") {
11442
+ refetch();
11443
+ }
11444
+ }));
11418
11445
  const [selectedWalletInfo, setSelectedWalletInfo] = createSignal(null);
11419
11446
  const walletsList = createMemo(() => {
11420
11447
  if (fetchedWalletsList.state !== "ready") {
@@ -11422,6 +11449,13 @@ const WalletsModal = () => {
11422
11449
  }
11423
11450
  return applyWalletsListConfiguration(fetchedWalletsList(), appState.walletsList);
11424
11451
  });
11452
+ const additionalRequestLoading = () => fetchedAdditionalRequest.state !== "ready" && fetchedAdditionalRequest.state !== "errored";
11453
+ const additionalRequest = createMemo(() => {
11454
+ if (fetchedAdditionalRequest.state !== "ready") {
11455
+ return void 0;
11456
+ }
11457
+ return fetchedAdditionalRequest();
11458
+ });
11425
11459
  const onClose = () => {
11426
11460
  setWalletsModalOpen(false);
11427
11461
  setSelectedWalletInfo(null);
@@ -11444,13 +11478,13 @@ const WalletsModal = () => {
11444
11478
  const universalLink = connector.connect({
11445
11479
  universalLink: walletInfo.universalLink,
11446
11480
  bridgeUrl: walletInfo.bridgeUrl
11447
- });
11481
+ }, additionalRequest());
11448
11482
  openLink(universalLink);
11449
11483
  };
11450
11484
  const onSelectIfInjected = (walletInfo) => {
11451
11485
  connector.connect({
11452
11486
  jsBridgeKey: walletInfo.jsBridgeKey
11453
- });
11487
+ }, additionalRequest());
11454
11488
  };
11455
11489
  const unsubscribe = connector.onStatusChange((wallet) => {
11456
11490
  if (wallet) {
@@ -11467,7 +11501,7 @@ const WalletsModal = () => {
11467
11501
  get children() {
11468
11502
  return [createComponent(Show, {
11469
11503
  get when() {
11470
- return !walletsList();
11504
+ return !walletsList() || additionalRequestLoading();
11471
11505
  },
11472
11506
  get children() {
11473
11507
  return [createComponent(H1Styled$1, {
@@ -11481,7 +11515,7 @@ const WalletsModal = () => {
11481
11515
  }
11482
11516
  }), createComponent(Show, {
11483
11517
  get when() {
11484
- return walletsList();
11518
+ return createMemo(() => !!walletsList())() && !additionalRequestLoading();
11485
11519
  },
11486
11520
  get children() {
11487
11521
  return [createComponent(Show, {
@@ -11505,6 +11539,9 @@ const WalletsModal = () => {
11505
11539
  keyed: false,
11506
11540
  get children() {
11507
11541
  return createComponent(QrCodeModal, {
11542
+ get additionalRequest() {
11543
+ return additionalRequest();
11544
+ },
11508
11545
  get wallet() {
11509
11546
  return selectedWalletInfo();
11510
11547
  },
@@ -11785,7 +11822,10 @@ class TonConnectUI {
11785
11822
  });
11786
11823
  }
11787
11824
  this.uiOptions = mergeOptions(options, { uiPreferences: { theme: "SYSTEM" } });
11788
- setAppState({ connector: this.connector });
11825
+ setAppState({
11826
+ connector: this.connector,
11827
+ getConnectParameters: options == null ? void 0 : options.getConnectParameters
11828
+ });
11789
11829
  widgetController.renderApp(rootId, this);
11790
11830
  }
11791
11831
  static getWallets() {
@@ -14822,11 +14862,16 @@ globalThis && globalThis.__rest || function(s2, e2) {
14822
14862
  }
14823
14863
  return t2;
14824
14864
  };
14825
- function toUserFriendlyAddress(hexAddress) {
14865
+ const bounceableTag = 17;
14866
+ const testOnlyTag = 128;
14867
+ function toUserFriendlyAddress(hexAddress, testOnly = false) {
14826
14868
  const { wc, hex } = parseHexAddress(hexAddress);
14827
- const bounceableTag = 17;
14869
+ let tag = bounceableTag;
14870
+ if (testOnly) {
14871
+ tag |= testOnlyTag;
14872
+ }
14828
14873
  const addr = new Int8Array(34);
14829
- addr[0] = bounceableTag;
14874
+ addr[0] = tag;
14830
14875
  addr[1] = wc;
14831
14876
  addr.set(hex, 2);
14832
14877
  const addressWithChecksum = new Uint8Array(36);
@@ -14906,7 +14951,7 @@ function hexToBytes(hex) {
14906
14951
  function useTonAddress(userFriendly = true) {
14907
14952
  const wallet = useTonWallet();
14908
14953
  if (wallet) {
14909
- return userFriendly ? toUserFriendlyAddress(wallet.account.address) : wallet.account.address;
14954
+ return userFriendly ? toUserFriendlyAddress(wallet.account.address, wallet.account.chain === CHAIN.TESTNET) : wallet.account.address;
14910
14955
  } else {
14911
14956
  return "";
14912
14957
  }
@@ -14916,6 +14961,7 @@ export {
14916
14961
  TonConnectButton$1 as TonConnectButton,
14917
14962
  TonConnectProviderNotSetError,
14918
14963
  TonConnectUI,
14964
+ TonConnectUIContext,
14919
14965
  TonConnectUIError,
14920
14966
  TonConnectUIProvider$1 as TonConnectUIProvider,
14921
14967
  TonConnectUIReactError,