<h1 align="center" style="border-bottom: none">
    <b>
        Tomo-Telegram-Wallet-Sdk
        <br>
    </b>
</h1>

<p align="center">
  <img src="https://pub-6c52100fa9ac41f681f0713eac878541.r2.dev/refferal.png" alt="" border="0">
</p>

## Feature

1. Integrating TON Chain
2. Support for Wave Wallet / TON Wallet
3. Support for Ton Keeper / metamask Mobile
4. Support for Swap and Swap Tokens

## Quick Start


### Installation

```npm
npm i tomo-tg-wallet-sdk
```

```npm
pnpm i tomo-tg-wallet-sdk
```

```tsx
<TomoProvider secret={secret} env={'main'}>
    <div>...</div>
</TomoProvider>
```

> Note: The following code must be included in the project's index.html file:


```html
<script src="https://telegram.org/js/telegram-web-app.js"></script>
```

## Examples

Example code is located in the example directory and can be started with `npm start`.

### Testing

After entering tgTestData, click the 'use test data' button, then refresh the page to use the test data.
You can then click login to perform testing.

## Documentation

### Hooks

<details>
  <summary>useChains</summary>

  In the Solana, Bitcoin (BTC), and TON chains, we need to pass in the chainId of other EVM-compatible chains respectively.
  
  ```jsx
    solana: 501;
    btc: 0;
    ton: 1100;
  ```

  ```tsx
  const { getChainId, getChain, chains, chainIds } = useChains();
```

</details>

<details>
  <summary>useBalance</summary>

  ```tsx
    const balance = useBalance({ chainId: sepolia.id });
    const balanceBtc = useBalance({ chainId: mockBtcEvmChainId});
    const balanceSol = useBalance({ chainId: mockSolEvmChainId});
    const balanceTon = useBalance({ chainId: mockTonChainId});
  ```

</details>

<details>
  <summary>useSendTransaction</summary>

1. sendEVMTransaction

```tsx
  const [inputCount, setInputCount] = useState<string>();
  const [toAddress, setToAddress] = useState<string>();
  const config = useConfig();
  const { evmAddress } = useTomoUserInfo();
  const { sendEVMTransaction } = useSendTransaction();
  const [sendEVMLoading, sendEVMLoadingFn] = useLoading();
  
  const handleSendEVMToken = () => {
    sendEVMLoadingFn(async () => {
      const res = await sendEVMTransaction({
        chainId: sepolia.id,
        fromAddress: evmAddress,
        toAddress: toAddress,
        value: parseUnits(inputCount || '0', 18),
        rpc: sepolia.rpcUrls.default.http[0],//if you don't set this param , it will use the default rpc
        config,
        tokenValue: parseUnits(inputCount || '0', 18),
        token: {
          chainId: sepolia.id,
          image: 'https://etherscan.io/images/main/empty-token.png',
          name: 'Ether',
          symbol: 'ETH',
          decimals: 18,
          address: zeroAddress,
        },
      });

    });
  };
```

2. sendSolTransaction

```tsx
  const [inputCount, setInputCount] = useState<string>();
  const [toAddress, setToAddress] = useState<string>();
  const { solAddress } = useTomoUserInfo();
  const { sendSolTransaction } = useSendTransaction();
  const [sendLoading, sendLoadingFn] = useLoading();

  const handleSendToken = () => {
    sendLoadingFn(async () => {
      const res = await sendSolTransaction({
        fromAddress: solAddress,
        toAddress: toAddress,
        value: parseUnits(inputCount || '0', solDecimals),
        // contract?: string;  // SOL SPL Token Address
        token: {
          chainId: mockSolEvmChainId,
          image: 'sol-icon.svg',
          name: 'solana',
          symbol: 'SOL',
          decimals: solDecimals,
          address: zeroAddress,
        },
      });

    });
  };
```

</details>

<details>
  <summary>useTransactions</summary>

Get transaction records


```tsx
import * as React from 'react';
import useTransactions from '../../src/hooks/useTransactions';
import { IChainId } from '../../src/state/type';
import { formatUnits } from 'viem';

const Transactions = () => {
  const { transactions } = useTransactions();

  const transactionsRender = Object.keys(transactions)
    .map(key => {
      const intKey = Number(key) as IChainId;
      return transactions[intKey];
    })
    .filter(item => !!item)
    .flat()
    // .filter(item => item.historyType === 'Swap')
    .sort((a, b) => {
      return b.time - a.time;
    });

  return (
    <div>
      <h2>History</h2>
      {transactionsRender.map((item, index) => {
        return (
          <p style={{ marginBottom: 16 }} key={item.time}>
            <p>
              <span style={{ marginRight: 16 }}>{item.chainId}</span>
              <span>{item.hash}</span>
            </p>
            <p>
              <span style={{ marginRight: 16 }}>from:{item.fromAddress}</span>
              <span>to:{item.toAddress}</span>
            </p>
            <p>
              <span>
                amount:{' '}
                {formatUnits(
                  BigInt(item.toAmount),
                  item.toSwapTokens?.decimals || 18
                )}{' '}
                {` ${item.toSwapTokens?.symbol}`}
              </span>
            </p>
          </p>
        );
      })}
    </div>
  );
};

export default Transactions;

```

</details>

<details>
  <summary>useTomo</summary>

`useTomo` is a custom React Hook for accessing the Tomo context within the Tomo application.

#### Parameters

`useTomo` does not take any parameters.

#### Return Value

This Hook returns an object containing the following properties and methods:

- `tmaid`: The Tomo application ID.
- `tmakey`: The Tomo application key.
- `env`: The environment type (dev, test, main).
- `endpoints`: The API endpoints.
- `userInfo`: The user information object.
- `onLogin`: A function to initiate the login process.
- `onLogout`: A function to log out the user.
- `telegramData`: The Telegram initialization data.
- `tMAuthLink`: The Telegram authentication link.

#### Methods

##### onLogin

`onLogin` is an asynchronous function that initiates the login process for the Tomo application.It can return a Telegram link to authenticate the user.

**Steps:**

1. Open the Telegram link to auth.
2. Return the miniapp wait for the Telegram response.

##### onLogout

`onLogout` is a function that logs out the user from the Tomo application.

</details>

<details>
  <summary>useBiometricManager</summary>

`useBiometricManager` is a custom React Hook for managing biometric authentication. It uses the `@vkruglikov/react-telegram-web-app` library to initialize and monitor the state of the biometric manager.

#### Return Value

This Hook returns an object containing the following properties and methods:

- `biometryManager`: Instance of the biometric manager.
- `requestAccess`: Requests biometric access from the user.
- `authenticate`: Handles the biometric authentication process.
- `bioAvailable`: State indicating if biometric is available.
- `bioInited`: State indicating if the biometric manager is initialized.
- `bioAccessGranted`: State indicating if biometric access is granted.

#### Methods

##### requestAccess

Requests biometric access from the user.

**Parameters:**

- `params` (Object): Request parameters.
    - `reason` (string, optional): Reason for requesting access, default is 'We will use biometry to protect your account'.
    - `callback` (Function): Callback function to handle the result.

##### authenticate

Handles the biometric authentication process.

**Parameters:**

- `params` (Object): Authentication parameters.
    - `reason` (string, optional): Reason for authentication, default is 'We need to authenticate you to continue'.
    - `callback` (Function): Callback function to handle the result.
    - `failCallback` (Function, optional): Callback function to handle failures.

</details>


<details>
  <summary>useMFAVerify</summary>

`useMFAVerify` is a custom React Hook for managing multi-factor authentication (MFA) using either biometric authentication or a password.

#### Return Value

This Hook returns an object containing the following method:

- `getMFAParams`: Retrieves MFA parameters based on the provided authentication type.

#### Methods

##### getMFAParams

Retrieves MFA parameters based on the provided authentication type.

**Parameters:**

- `params` (Object): Parameters for the MFA request.
    - `data` (any): Data to be signed.
    - `chainid` (number): Chain ID for the transaction.
- `type` (MFAType, optional): Type of MFA to use, either 'biometric' or 'password'. Default is 'biometric'.
- `password` (string, optional): Password for authentication if `type` is 'password'.
- `reason` (string, optional): Reason for requesting biometric authentication. Default is 'We need your biometric to verify your transaction'.

**Returns:**

- A Promise that resolves to an object containing the `mfa` and `signature` if the authentication is successful.
-
</details>

<details>
  <summary>usePaymentPasswd</summary>

`usePaymentPasswd` is a custom React Hook for managing payment password operations.

#### Return Value

This Hook returns an object containing the following methods:

- `setPasswd`: Sets a new payment password.
- `changePasswd`: Changes the existing payment password.
- `validatePasswd`: Validates the provided payment password.
- `checkPasswd`: Checks if a payment password exists.
- `paymentPwdExists`: State indicating if a payment password exists.

#### Methods

##### setPasswd

Sets a new payment password.

**Parameters:**

- `passwd` (string): The new password to be set.

**Returns:**

- A Promise that resolves to `true` if the password is set successfully, otherwise `false`.

##### changePasswd

Changes the existing payment password.

**Parameters:**

- `old_passwd` (string): The current password.
- `new_passwd` (string): The new password to be set.

**Returns:**

- A Promise that resolves to `true` if the password is changed successfully, otherwise `false`.

##### validatePasswd

Validates the provided payment password.

**Parameters:**

- `passwd` (string): The password to be validated.

**Returns:**

- A Promise that resolves to `true` if the password is valid, otherwise `false`.

##### checkPasswd

Checks if a payment password exists.

**Returns:**

- A Promise that resolves to `1` if a payment password exists, `0` if it does not, and `-1` if there is an error.

</details>


<details>
  <summary>useConfig</summary>

useConfig is a custom React Hook for creating and managing the configuration for the wagmi library in the Tomo application.  
Return Value
This Hook returns an object containing the following properties:
config: The configuration object for the wagmi library.

</details>

<details>
  <summary>useBuildSwapTx</summary>

`useBuildSwapTx` is a custom React Hook for building swap transactions in the Tomo application.

#### Return Value

This Hook returns an object containing the following properties and methods:

- `isBuilding`: State indicating if a transaction is currently being built.
- `error`: State indicating if there was an error during the transaction building process.
- `transaction`: The built transaction data.
- `buildSwapTx`: A method to initiate the building of a swap transaction.

#### Methods

##### buildSwapTx

Initiates the building of a swap transaction.

**Parameters:**

- `params` (Object): Parameters for building the swap transaction.
    - `fromChainid` (number): The chain ID of the source chain.
    - `toChainid` (number): The chain ID of the destination chain.
    - `fromAddress` (string): The address of the sender.
    - `toAddress` (string): The address of the recipient.
    - `amount` (string): The amount to be swapped.
    - `slippage` (number): The acceptable slippage for the swap.
    - `fromWalletAddress` (string): The wallet address of the sender.
    - `toWalletAddress` (string): The wallet address of the recipient.

**Returns:**

- A Promise that resolves to the built transaction data if the build is successful, otherwise an error message.

</details>

<details>
  <summary>useTomoUserInfo</summary>

`useTomoUserInfo` is a custom React Hook for managing and retrieving user information in the Tomo application.

#### Return Value

This Hook returns an object containing the following properties and methods:

- `userInfo`: An object containing the user's information.
- `setUserInfo`: A function to set the user's information.
- `deviceId`: The device ID.
- `evmAddress`: The user's EVM address.
- `solAddress`: The user's Solana address.
- `tonAddress`: The user's TON address.
- `tonPublicKey`: The user's TON public key.
- `btcAddress`: An object containing the user's Bitcoin addresses.
- `getRenderAddress`: A function to get the render address based on the blockchain type and options.
- `generateDeviceId`: An asynchronous function to generate a device ID.

#### Methods

##### getRenderAddress

Gets the render address based on the blockchain type and options.

**Parameters:**

- `chain` (IWeb3ChainType | undefined): The blockchain type.
- `options` (Object, optional): Options object.
    - `btcType` ('pkh' | 'sh' | 'tr' | 'wpkh'): The Bitcoin address type.

**Returns:**

- Returns the corresponding address or `undefined`.

##### generateDeviceId

An asynchronous function to generate a device ID.

**Returns:**

- Returns the generated device ID or throws an error.

</details>

<details>
  <summary>useOnRamp</summary>

`useOnRamp` is a custom React Hook for managing on-ramp operations in the Tomo application.

#### Return Value

This Hook returns an object containing the following properties and methods:

- `onContinue`: A function to continue the on-ramp process.
- `title`: The title to be displayed for the on-ramp operation.

#### Methods

##### onContinue

Continues the on-ramp process based on the provided type and rampType.

**Parameters:**

- `type` ('buy' | 'sell'): The type of on-ramp operation.
- `rampType` ('ramp' | 'mercuryo'): The ramp provider type.
- `token` (TokenInfo | undefined): The token information.

**Returns:**

- Redirects to the appropriate on-ramp URL or opens the link in the web app.

</details>

<details>
  <summary>useOnRampTokens</summary>

`useOnRampTokens` is a custom React Hook for fetching and managing on-ramp tokens in the Tomo application.

#### Return Value

This Hook returns an object containing the following properties:

- `tokens`: An array of on-ramp tokens.

</details>


### Process

Initialize the TomoProvider component by passing in the secret parameter.

### User Authentication

<details>
  <summary>1. User Authentication: Passwords and Biometrics</summary>
  
User authentication requires password verification or biometric authentication. If biometric authentication is not supported by some devices, password verification must be used.

</details>

<details>
  <summary>2. Application Opening: Verification Prompt</summary>
  
Verification should be prompted once every time the application is opened.

</details>

<details>
  <summary>3. Transaction Initiation: User Authentication</summary>
  
User authentication must succeed before transactions can be initiated.

</details>

<details>
  <summary>4. Biometric Authentication: Request Access and Prerequisites</summary>
  
Biometric authentication requires `requestAccess` before `authenticate` can proceed. The prerequisites are `bioInited` and `bioAvailable` being true.

</details>

<details>
  <summary>5. Password Verification: Payment Password Status</summary>
  
The status of `paymentPwdExists` for password verification: -1 for uninitialized (uncertain if set), 0 for not set, 1 for set.

</details>



## Contributing

## Contributors