Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/release'
Browse files Browse the repository at this point in the history
  • Loading branch information
thekiba committed Oct 25, 2023
2 parents 12e21c0 + 9d86c73 commit 955cbf7
Show file tree
Hide file tree
Showing 25 changed files with 880 additions and 125 deletions.
41 changes: 23 additions & 18 deletions packages/sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ Make sure that manifest is available to GET by its URL.

If your manifest placed not in the root of your app, you can specify its path:
```ts
const connector = new TonConnect({ manifestUrl: 'https://myApp.com/assets/tonconnect-manifest.json' });
const connector = new TonConnect({
manifestUrl: 'https://myApp.com/assets/tonconnect-manifest.json'
});
```

## Subscribe to the connection status changes
Expand Down Expand Up @@ -273,29 +275,32 @@ To authorize user in your backend with TonConnect you can use following schema:
1. Fetch auth payload from your backend. It might be any random value. Backend must save information that this payload was sent to the client to check payload correctness later.
2. Connect to the wallet when user clicks to the connection button:
```ts
connector.connect(walletConnectionSource, { tonProof: "<your-fetched-payload>" });
connector.connect(
walletConnectionSource,
{ tonProof: "<your-fetched-payload>" }
);
```
Note that you can use `tonProof` only with `connector.connect()` method. This feature is not available in `connector.restoreConnection()`.

3. Read a signed result after user approves connection:
```ts
connector.onStatusChange(wallet => {
if (!wallet) {
return;
}

const tonProof = wallet.connectItems?.tonProof;

if (tonProof) {
if ('proof' in tonProof) {
// send proof to your backend
// e.g. myBackendCheckProof(tonProof.proof, wallet.account);
return;
}

console.error(tonProof.error);
}
});
if (!wallet) {
return;
}

const tonProof = wallet.connectItems?.tonProof;

if (tonProof) {
if ('proof' in tonProof) {
// send proof to your backend
// e.g. myBackendCheckProof(tonProof.proof, wallet.account);
return;
}

console.error(tonProof.error);
}
});
```
4. Send proof and user's account data to your backend. Backend should check the proof correctness and check that payload inside the proof was generated before. After all checks backend should return an auth token to the client. Notice that `Account` contains the `walletStateInit` property which can be helpful for your backend to get user's public key if user's wallet contract doesn't support corresponding get method.
5. Client saves the auth token in the `localStorage` and use it to access to auth-required endpoints. Client should delete the token when user disconnects the wallet.
Expand Down
13 changes: 13 additions & 0 deletions packages/ui-react/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog @tonconnect/ui-react

# [2.0.0-beta.4](https://github.com/ton-connect/sdk/compare/ui-react-2.0.0-beta.3...ui-react-2.0.0-beta.4) (2023-10-25)



# [2.0.0-beta.3](https://github.com/ton-connect/sdk/compare/ui-react-2.0.0-beta.2...ui-react-2.0.0-beta.3) (2023-10-20)


### Features

* **ui-react:** add useTonConnectModal() hook for modal management ([d1e2381](https://github.com/ton-connect/sdk/commit/d1e238154694d142bae67b21bfc81deb30647d49))



# [2.0.0-beta.2](https://github.com/ton-connect/sdk/compare/ui-react-2.0.0-beta.1...ui-react-2.0.0-beta.2) (2023-09-15)


Expand Down
20 changes: 20 additions & 0 deletions packages/ui-react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,26 @@ export const Wallet = () => {
};
```

### useTonConnectModal

Use this hook to access the functions for opening and closing the modal window. The hook returns an object with the current modal state and methods to open and close the modal.

```tsx
import { useTonConnectModal } from '@tonconnect/ui-react';

export const ModalControl = () => {
const { state, open, close } = useTonConnectModal();

return (
<div>
<div>Modal state: {state?.status}</div>
<button onClick={open}>Open modal</button>
<button onClick={close}>Close modal</button>
</div>
);
};
```

### useTonConnectUI
Use it to get access to the `TonConnectUI` instance and UI options updating function.

Expand Down
4 changes: 2 additions & 2 deletions packages/ui-react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tonconnect/ui-react",
"version": "2.0.0-beta.2",
"version": "2.0.0-beta.4",
"scripts": {
"dev": "vite",
"build": "tsc && vite build"
Expand Down Expand Up @@ -52,7 +52,7 @@
"vite-plugin-dts": "^1.7.1"
},
"dependencies": {
"@tonconnect/ui": "^2.0.0-beta.2"
"@tonconnect/ui": "^2.0.0-beta.4"
},
"peerDependencies": {
"react": ">=17.0.0",
Expand Down
1 change: 1 addition & 0 deletions packages/ui-react/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { useTonAddress } from './useTonAddress';
export { useTonConnectModal } from './useTonConnectModal';
export { useTonConnectUI } from './useTonConnectUI';
export { useTonWallet } from './useTonWallet';
export { useIsConnectionRestored } from './useIsConnectionRestored';
2 changes: 1 addition & 1 deletion packages/ui-react/src/hooks/useTonAddress.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useTonWallet } from './useTonWallet';
import { CHAIN, toUserFriendlyAddress } from '@tonconnect/ui';
import { useTonWallet } from './useTonWallet';

/**
* Use it to get user's current ton wallet address. If wallet is not connected hook will return empty string.
Expand Down
33 changes: 33 additions & 0 deletions packages/ui-react/src/hooks/useTonConnectModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { WalletsModal, WalletsModalState } from '@tonconnect/ui';
import { useTonConnectUI } from './useTonConnectUI';
import { useEffect, useState } from 'react';

/**
* Use it to get access to the open/close modal functions.
*/
export function useTonConnectModal(): Omit<WalletsModal, 'onStateChange'> {
const [tonConnectUI] = useTonConnectUI();
const [state, setState] = useState(tonConnectUI?.modal.state || null);

useEffect(() => {
if (tonConnectUI) {
return tonConnectUI.onModalStateChange((value: WalletsModalState) => {
setState(value);
});
}
}, [tonConnectUI]);

return {
state,
open: () => {
if (tonConnectUI) {
return tonConnectUI.modal.open();
}
},
close: () => {
if (tonConnectUI) {
tonConnectUI.modal.close();
}
}
};
}
6 changes: 3 additions & 3 deletions packages/ui-react/src/hooks/useTonWallet.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useTonConnectUI } from './useTonConnectUI';
import { useEffect, useState } from 'react';
import { WalletInfoWithOpenMethod, Wallet } from '@tonconnect/ui';
import { WalletInfoWithOpenMethod, Wallet, ConnectedWallet } from '@tonconnect/ui';
import { useTonConnectUI } from './useTonConnectUI';

/**
* Use it to get user's current ton wallet. If wallet is not connected hook will return null.
Expand All @@ -13,7 +13,7 @@ export function useTonWallet(): Wallet | (Wallet & WalletInfoWithOpenMethod) | n

useEffect(() => {
if (tonConnectUI) {
return tonConnectUI.onStatusChange(value => {
return tonConnectUI.onStatusChange((value: ConnectedWallet | null) => {
setWallet(value);
});
}
Expand Down
27 changes: 27 additions & 0 deletions packages/ui/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
# Changelog @tonconnect/ui

# [2.0.0-beta.4](https://github.com/ton-connect/sdk/compare/ui-2.0.0-beta.3...ui-2.0.0-beta.4) (2023-10-25)



# [2.0.0-beta.3](https://github.com/ton-connect/sdk/compare/ui-2.0.0-beta.2...ui-2.0.0-beta.3) (2023-10-20)


### Bug Fixes

* **ui:** implement back button handler for modal popup on Android devices ([ff83611](https://github.com/ton-connect/sdk/commit/ff8361138dac5efb1086ab5791e0700e67190491)), closes [#70](https://github.com/ton-connect/sdk/issues/70)
* **ui:** prevent reappearing of success tooltip on re-render ([17bbc9a](https://github.com/ton-connect/sdk/commit/17bbc9a66eb01aad10dcc9bd91ba25696c652ba8))
* **ui:** resolve illegal constructor error in safari ([512678f](https://github.com/ton-connect/sdk/commit/512678ff25ae877a7a2f608e8d8c06fda5dcbd21)), closes [#87](https://github.com/ton-connect/sdk/issues/87)
* **ui:** resolve premature promise resolution and unhandled popup closing scenarios ([5e7b825](https://github.com/ton-connect/sdk/commit/5e7b825b809856f6bd3dff969464beeb9d372a08)), closes [#67](https://github.com/ton-connect/sdk/issues/67) [#68](https://github.com/ton-connect/sdk/issues/68)


### Features

* **ui:** introduce modal, fix promise handling, and refactor internal classes ([ac803aa](https://github.com/ton-connect/sdk/commit/ac803aa7bec56f6358071a906879d814eb485c8d))
* **ui:** refactor wallet modal interfaces and expose them publicly ([5618a0a](https://github.com/ton-connect/sdk/commit/5618a0ae945b2aad50cb994d4cad8371f029bf65))


### BREAKING CHANGES

* **ui:** The method tonConnectUI.connectWallet() is now deprecated and will be removed in subsequent versions. Use tonConnectUI.openModal() instead.



# [2.0.0-beta.2](https://github.com/ton-connect/sdk/compare/ui-2.0.0-beta.1...ui-2.0.0-beta.2) (2023-09-15)


Expand Down
79 changes: 68 additions & 11 deletions packages/ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,38 +103,95 @@ or
const walletsList = await TonConnectUI.getWallets();
```

## Call connect
## Open connect modal
"TonConnect UI connect button" (which is added at `buttonRootId`) automatically handles clicks and calls connect.
But you are still able to open "connect modal" programmatically, e.g. after click on your custom connect button.

```ts
const connectedWallet = await tonConnectUI.connectWallet();
await tonConnectUI.openModal();
```

If there is an error while wallet connecting, `TonConnectUIError` or `TonConnectError` will be thrown depends on situation.
This method opens the modal window and returns a promise that resolves after the modal window is opened.

If there is an error while modal opening, `TonConnectUIError` or `TonConnectError` will be thrown depends on situation.

## Close connect modal

```ts
tonConnectUI.closeModal();
```

This method closes the modal window.

## Get current modal state

This getter returns the current state of the modal window. The state will be an object with `status` and `closeReason` properties. The `status` can be either 'opened' or 'closed'. If the modal is closed, you can check the `closeReason` to find out the reason of closing.

```ts
const currentModalState = tonConnectUI.modalState;
```

## Subscribe to the modal window state changes
To subscribe to the changes of the modal window state, you can use the `onModalStateChange` method. It returns a function which has to be called to unsubscribe.

```js
const unsubscribeModal = tonConnectUI.onModalStateChange(
(state: WalletsModalState) => {
// update state/reactive variables to show updates in the ui
// state.status will be 'opened' or 'closed'
// if state.status is 'closed', you can check state.closeReason to find out the reason
}
);
```

Call `unsubscribeModal()` later to save resources when you don't need to listen for updates anymore.

## Wallets Modal Control

The `tonConnectUI` provides methods for managing the modal window, such as `openModal()`, `closeModal()` and other, which are designed for ease of use and cover most use cases.

```typescript
const { modal } = tonConnectUI;

// Open and close the modal
await modal.open();
modal.close();

// Get the current modal state
const currentState = modal.state;

// Subscribe and unsubscribe to modal state changes
const unsubscribe = modal.onStateChange(state => { /* ... */ });
unsubscribe();
```

While `tonConnectUI` internally delegates these calls to the `modal`, it is recommended to use the `tonConnectUI` methods for a more straightforward and consistent experience. The `modal` is exposed in case you need direct access to the modal window's state and behavior, but this should generally be avoided unless necessary.

## Get current connected Wallet and WalletInfo
You can use special getters to read current connection state. Note that this getter only represents current value, so they are not reactive.
To react and handle wallet changes use `onStatusChange` mathod.
To react and handle wallet changes use `onStatusChange` method.

```ts
const currentWallet = tonConnectUI.wallet;
const currentWalletInfo = tonConnectUI.walletInfo;
const currentAccount = tonConnectUI.account;
const currentIsConnectedStatus = tonConnectUI.connected;
const currentWallet = tonConnectUI.wallet;
const currentWalletInfo = tonConnectUI.walletInfo;
const currentAccount = tonConnectUI.account;
const currentIsConnectedStatus = tonConnectUI.connected;
```

## Subscribe to the connection status changes
```js

To subscribe to the changes of the connection status, you can use the `onStatusChange` method. It returns a function which has to be called to unsubscribe.

```ts
const unsubscribe = tonConnectUI.onStatusChange(
walletAndwalletInfo => {
// update state/reactive variables to show updates in the ui
}
);

// call `unsubscribe()` later to save resources when you don't need to listen for updates anymore.
```

Call `unsubscribe()` later to save resources when you don't need to listen for updates anymore.

## Disconnect wallet
Call to disconnect the wallet.

Expand Down
2 changes: 1 addition & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tonconnect/ui",
"version": "2.0.0-beta.2",
"version": "2.0.0-beta.4",
"scripts": {
"start": "vite --host",
"dev": "vite",
Expand Down
5 changes: 5 additions & 0 deletions packages/ui/src/app/components/modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Component, createEffect, JSXElement, Show } from 'solid-js';
import { Transition } from 'solid-transition-group';
import clickOutsideDirective from 'src/app/directives/click-outside';
import keyPressedDirective from 'src/app/directives/key-pressed';
import androidBackHandlerDirective from 'src/app/directives/android-back-handler';
import { Styleable } from 'src/app/models/styleable';
import { isDevice, media } from 'src/app/styles/media';
import {
Expand All @@ -19,8 +20,10 @@ import { disableScroll, enableScroll } from 'src/app/utils/web-api';
import { WithDataAttributes } from 'src/app/models/with-data-attributes';
import { useDataAttributes } from 'src/app/hooks/use-data-attributes';
import { TonConnectBrand } from 'src/app/components';

const clickOutside = clickOutsideDirective;
const keyPressed = keyPressedDirective;
const androidBackHandler = androidBackHandlerDirective;

export interface ModalProps extends Styleable, WithDataAttributes {
children: JSXElement;
Expand Down Expand Up @@ -90,6 +93,7 @@ export const Modal: Component<ModalProps> = props => {
css`
border-radius: ${borders[theme!.borderRadius]};
background-color: ${theme.colors.background.tint};
${media('mobile')} {
border-radius: ${borders[theme!.borderRadius]}
${borders[theme!.borderRadius]} 0 0;
Expand All @@ -98,6 +102,7 @@ export const Modal: Component<ModalProps> = props => {
)}
use:clickOutside={() => props.onClose()}
use:keyPressed={() => props.onClose()}
use:androidBackHandler={() => props.onClose()}
>
<ModalBodyStyled class={props.class}>
<CloseButtonStyled icon="close" onClick={() => props.onClose()} />
Expand Down
Loading

0 comments on commit 955cbf7

Please sign in to comment.