# How to handle connections with WalletKit on the Web platform (https://docs-orhepa2tm-ton-core-docs.vercel.app/llms/ecosystem/walletkit/web/connections/content.md)



<Callout>
  [Initialize the WalletKit](/llms/ecosystem/walletkit/web/init/content.md) and [set up at least one TON wallet](/llms/ecosystem/walletkit/web/wallets/content.md) before using examples on this page.
</Callout>

To use a wallet service for initiating blockchain transactions and signing data, dApps need to set up a connection over the bridge first. Connection is established via `connect` requests and terminated via `disconnect` requests.

## Connection flow [#connection-flow]

Standard flow looks as follows:

1. User clicks a "Connect wallet" button in the dApp, selecting the desired wallet service
2. WalletKit processes the connection URL and triggers the `onConnectRequest()` method
3. WalletKit instructs the wallet service to show a connection request preview, waiting for the user's approval
4. User approves or rejects a connection

<Callout>
  The flow can be started by scanning a QR code from a dApp in the wallet service, or by following a deep link from a dApp to the wallet service. In both cases, WalletKit will process the URL via the `handleTonConnectUrl()` method, then fire a `connect` event for the `onConnectRequest()` method to handle.
</Callout>

If the connection was approved, the dApp could proceed to send various transaction or data sign requests. If it was rejected, the dApp can repeat the flow.

If a user decides to disconnect a wallet at any point, the `disconnect` request will be issued and the `onDisconnect()` method of the WalletKit will handle it.

## Handlers [#handlers]

To work with connection-specific requests, the WalletKit offers three methods which expect processing functions as callbacks:

* The `onConnectRequest()` method processes connection requests
* The `onDisconnect()` method processes disconnection requests
* The `onRequestError()` method allows to [handle errors](/llms/ecosystem/walletkit/web/events/content.md) arising in any of the requests

### Handle `onConnectRequest` [#handle-onconnectrequest]

When a user wants to connect a TON wallet from the dApp, the dApp fires the `connect` request over the bridge. The wallet service then handles it with the `onConnectRequest` method of the WalletKit.

On the dApp side, this flow is often initiated by pressing the "Connect a wallet" button, followed by selecting the user's wallet service. Additionally, a dApp can produce a [QR code or a deep link](#qr-codes-and-deep-links), which initiate the connection flow from within the wallet service.

```ts title="TypeScript"
kit.onConnectRequest(async (event) => {
  try {
    const wallets = kit.getWallets();
    if (wallets.length === 0) {
      // Make sure to present a message to the user.
      console.log('No wallets available');
      await kit.rejectConnectRequest(event, 'No wallets available');
      return;
    }
    const dappName = event.preview.dAppInfo?.name || 'Unknown dApp';
    const dappUrl = event.preview.dAppInfo?.url || event.preview.dAppInfo?.manifestUrl || 'Unknown URL';
    // Show the connection confirmation UI to the user of the wallet service
    if (confirm(`Connect to ${dappName} from ${dappUrl}?`)) {
      // Set `walletId` on the request before approving
      event.walletId = wallets[0].getWalletId();
      await kit.approveConnectRequest(event);
      console.log('Connected to:', dappName);
    } else {
      await kit.rejectConnectRequest(event, 'User rejected');
      console.log('Connection rejected by a user');
    }
  } catch (error) {
    console.error('Connection handler error:', error);
    await kit.rejectConnectRequest(event, 'Fatal error in the connection handler');
  }
});
```

#### Wallet selection [#wallet-selection]

When there are several TON wallets added, ask the user to select one before approving the connection request.

```ts title="TypeScript"
kit.onConnectRequest(async (event) => {
  try {
    const wallets = kit.getWallets();
    if (wallets.length === 0) {
      // Make sure to present a message to the user.
      console.log('No wallets available');
      await kit.rejectConnectRequest(event, 'No wallets available');
      return;
    }
    // Selecting the 1st TON wallet by default
    let selectedWallet = { ok: true, wallet: wallets[0] };
    // Yet, asking the user to pick one if there are many
    if (wallets.length > 1) {
      // Here, uiSelectWallet() is assumed to be implemented elsewhere:
      // it takes the list of wallets and provides the user with a choice
      // to pick one from the list, then returns with the picked option
      // or a rejection if there was none.
      selectedWallet = await uiSelectWallet(wallets);
    }
    if (!selectedWallet.ok) {
      // Make sure to present a message to the user.
      console.log('No wallet selected');
      await kit.rejectConnectRequest(event, 'No wallet selected');
      return;
    }
    const dappName = event.preview.dAppInfo?.name || 'Unknown dApp';
    const dappUrl = event.preview.dAppInfo?.url || event.preview.dAppInfo?.manifestUrl || 'Unknown URL';
    // Show the connection confirmation UI to the user of the wallet service
    if (confirm(`Connect to ${dappName} from ${dappUrl}?`)) {
      // Set `walletId` on the request before approving
      event.walletId = selectedWallet.wallet.getWalletId();
      await kit.approveConnectRequest(event);
      console.log('Connected to:', dappName);
    } else {
      await kit.rejectConnectRequest(event, 'User rejected');
      console.log('Connection rejected by a user');
    }
  } catch (error) {
    console.error('Connection handler error:', error);
    await kit.rejectConnectRequest(event, 'Fatal error in the connection handler');
  }
});
```

#### QR codes and deep links [#qr-codes-and-deep-links]

The `handleTonConnectUrl()` method of the WalletKit parses a TON Connect link and creates a new [connection request event](#handle-onconnectrequest).

Usually, this link comes from a QR code generated on the dApp side, but it can also be provided within the mobile dApp as a deep link.

```ts title="TypeScript"
async function handleQrCode(content: string) {
  try {
    // On success, this will fire the onConnectRequest handler:
    await kit.handleTonConnectUrl(content);
  } catch (error) {
    console.error('Invalid QR code:', error);
    // Make sure to present an error to the user.
    throw new Error('Failed to process TON Connect QR code');
  }
}

async function handleDeepLink(url: string) {
  if (url.startsWith('tc://') || url.includes('ton-connect')) {
    try {
      // On success, this will fire the onConnectRequest handler:
      await kit.handleTonConnectUrl(url);
    } catch (error) {
      console.error('Invalid link:', error);
      // Make sure to present an error to the user.
      throw new Error('Failed to process TON Connect deep link');
    }
  }
}
```

### Handle `onDisconnect` [#handle-ondisconnect]

When a user disconnects a wallet service and its TON wallet from the dApp, the dApp fires the `disconnect` request over the bridge. The wallet service then handles it with the `onDisconnect` method of the WalletKit.

```ts title="TypeScript"
kit.onDisconnect(async (event) => {
  // Clean up any UI state related to this connection.
  console.log(`Disconnected from a dApp that used this TON wallet: ${event.walletAddress}`);
});
```

## Next steps [#next-steps]

<Columns cols="2">
  <Card title="Handle other events" icon="signature" horizontal="true" href="/ecosystem/walletkit/web/events" />
</Columns>

## See also [#see-also]

* [WalletKit overview](/llms/ecosystem/walletkit/overview/content.md)
* [TON Connect overview](/llms/ecosystem/ton-connect/overview/content.md)
