@broxus/tvm-connect
Version:
TypeScript SDK for connecting to Nekoton-compatible wallets using a unified interface.
1,044 lines (844 loc) • 37.4 kB
Markdown
# TVM Connect
This is a powerful and easy-to-use TypeScript SDK designed to simplify **connecting to crypto wallets that work with
TVM-compatible blockchains (such as TON, Hamster, Everscale and so on) via
[Nekoton](https://github.com/broxus/nekoton)**, as well as interacting with dApps (decentralized applications) that use
Nekoton to work with the blockchain. It provides a unified interface for connecting to various types of wallets, making
dApp development more efficient and convenient.
### Table of Contents
- [Usage](#usage)
- [Creation and connect](#creation-and-connect)
- [Basic usage with default behavior](#basic-usage-with-default-behavior)
- [Configuration when creating](#configuration-when-creating)
- [Connecting to a specific network](#connecting-to-a-specific-network)
- [Connecting to a specific wallet provider](#connecting-to-a-specific-wallet-provider)
- [Tracking changes](#tracking-changes)
- [Switch or Add Network](#switch-or-add-network)
- [Change account](#change-account)
- [Disconnecting](#disconnecting)
- [Advanced usage](#advanced-usage)
- [TvmConnectService](#tvmconnectservice)
- [Network configuration](#network-configuration)
- [Provider configuration](#provider-configuration)
- [React integration](#react-integration)
- [Available React components](#available-react-components)
- [React hooks](#react-hooks)
- [Basic React integration example](#basic-react-integration-example)
- [Advanced React integration](#advanced-react-integration)
- [Styling](#styling)
- [Styles import](#styles-import)
- [Standalone styles](#standalone-styles)
- [Inherited styles](#inherited-styles)
- [CSS-tokens](#css-tokens)
- [Helpful utils](#helpful-utils)
- [Migration from v2 to v3](#migration-from-v2-to-v3)
- [License](#license)
### Installation and requirements
To apply this component, install it with **npm** using following command:
```shell
npm install /tvm-connect
```
or using **yarn**:
```shell
yarn add /tvm-connect
```
## Usage
---
This section covers the basic usage of the `TvmConnect` component, which is the main entry point for connecting to
Nekoton-compatible wallets and interacting with dApps. It provides a simple and intuitive API for developers to
integrate wallet connections into their applications, manage network configurations, and handle user interactions with
wallets.
### Creation and connect
`TvmConnect` provides a simple way to connect to Nekoton-compatible wallets. By default, all supported wallets and
networks are available:
- **Wallets:** SparX Wallet, Ever Wallet, Venom Wallet
- **Networks:** TON Mainnet, Hamster Mainnet, Venom Mainnet, Everscale Mainnet, Humo Mainnet, M.Sharia, Tycho Testnet
### Basic usage with default behavior
By default, `TvmConnect` comes with built-in support for all compatible wallets and networks without requiring any
additional configuration. If you don't specify a custom set of networks or wallet providers, it will automatically use
all supported options out of the box. Additionally, it attempts to restore the previous connection from localStorage for
a seamless user experience.
```typescript
import { TvmConnect } from '/tvm-connect'
// Creating an instance with default settings
const tvmConnect = new TvmConnect()
// Connecting to a wallet
const connector = await tvmConnect.connect()
// Getting the service for API access
const service = tvmConnect.getService()
// Getting information about the connected account
console.log('Address:', service.address?.toString())
console.log('Network:', service.network?.name)
console.log('Balance:', service.balance)
```
### Configuration when creating
The `TvmConnect` constructor accepts various configuration options that allow you to customize its behavior. You can
override default networks, specify a custom wallet provider list, set the default network, and configure how connection
metadata is stored. This flexibility enables integration with specific blockchain environments and customized user
experiences.
```typescript
import { TvmChains } from '/js-core'
import {
type NekotonConnector,
SparXWallet,
createProviderConfig,
getRecentConnectionMeta,
everscaleMainnet,
tonMainnet,
} from '/tvm-connect'
import { type ProviderProperties, ProviderRpcClient } from 'everscale-inpage-provider'
const recentMetaStorageKey = '@{dAppName}/tvmRecentConnectionMeta'
const meta = getRecentConnectionMeta(recentMetaStorageKey)
const sparxWallet = createProviderConfig(SparXWallet, {
// (Optional) Number of attempts to connect to the wallet
fallbackAttempts: 5,
// (Optional) Fallback provider factory to use when the wallet is not available
fallbackProviderFactory: async () => new ProviderRpcClient({ ... }),
// (Optional) Will be called when the connection is established
onPreconnect: (connector: NekotonConnector) => {
console.log('Preconnected with', connector.name)
},
})
// Creating with custom parameters. All parameters are optional, so you can use only the ones you need.
// If you don't specify any parameters, it will use the default settings.
const tvmConnect = new TvmConnect({
// Use to override default agreements note. If set to false, the agreements note will not be displayed
agreementsNote: string | false,
// Use to override provider info (like description, icon, links etc.)
getProviderInfo: (providerId: string, info: TvmWalletProviderInfo) => TvmWalletProviderInfo,
// Use to override the default locale for the Intl
locale: 'en',
// Use to display the connection popup as a drawer instead of a modal
// This is useful for mobile devices
popupType: 'drawer',
// Disable the QR code connection option. Default is true
qrEnabled: false,
// Will be called for each provider from the providers list when the connection is established
onPreconnect(connector: NekotonConnector) {
// You can use this to perform any actions before the connection is established
console.log('Preconnected with', connector.name)
},
// Other parameters are available through the TvmConnectServiceCtorParams interface
// Whether to allow unsupported networks
allowUnsupportedNetworks: true,
// Standalone connection parameters (no permissions required)
connectionParams: {
// Use factory to recreate connection when network has been changed
factory: (network?: TvmNetworkConfig) => new ProviderRpcClient({ ... }),
// ... or use your own connection directly from external source
provider: ProviderProperties['provider']
},
// Use Hamster Mainnet as default network instead of the meta.chainId
defaultNetworkId: TvmChains.EverscaleMainnet.toString(),
// Use to override default networks list
networks: [tonMainnet, everscaleMainnet],
// Use SparX Wallet as default wallet instead of the meta.providerId
providerId: SparXWallet.name,
// Use to override default providers list
providers: [sparxWallet],
// Use to override default connection metadata storage key
recentMetaStorageKey,
})
```
### Connecting to a specific network
When you specify a network configuration in the `connect()` method parameters, `TvmConnect` will automatically trigger a
network switch in the wallet after the connection is established. This allows your dApp to ensure that the user is
connected to the required blockchain network without manual intervention.
```typescript
// Connecting with a specified network
const connector = await tvmConnect.connect({
network: everscaleMainnet,
})
```
### Connecting to a specific wallet provider
If you want to connect to a specific wallet provider, you can pass the provider configuration directly to the
`connectTo()` method. This is useful when you want to ensure that your dApp connects to a particular wallet, regardless
of the user's default wallet settings. The `connectTo()` method allows you to specify the wallet provider and the
network configuration, ensuring that the connection is established with the desired wallet.
```typescript
// Connecting with a specified provider
const connector = await tvmConnect.connectTo(sparxWallet, {
network: everscaleMainnet,
})
```
### Tracking changes
`TvmConnect` provides a convenient way to monitor changes in the connection state, such as account or network changes.
By using the `watch()` method, you can set up a callback function that will be executed whenever relevant connection
data changes. This is particularly useful for updating your UI in response to wallet actions or for triggering
application logic when the user switches networks.
Under the hood, the service returned by `tvmConnect.getService()` uses MobX with computed getters. If your project
already uses MobX, you can directly leverage these reactive properties instead of using the `watch()` method. This
allows for more fine-grained reactivity and seamless integration with your existing MobX stores.
```typescript
// Using watch() method
tvmConnect.watch((data: TvmConnectWatchData) => {
if (data.address) {
console.log('Connected to:', data.address.toString())
}
if (data.balance) {
console.log('Balance changed:', data.balance)
}
if (data.network) {
console.log('Network changed:', data.network)
}
})
// Canceling the subscription
tvmConnect.unwatch()
// Alternative: Using MobX reactivity directly
import { reaction } from 'mobx'
const service = tvmConnect.getService()
// React to address changes
reaction(
() => service.address,
address => {
if (address) {
console.log('Address changed:', address.toString())
}
},
)
// React to network changes
reaction(
() => service.chainId,
chainId => {
console.log('Network changed:', chainId)
},
)
```
### Switch or Add Network
If you need to switch to a different network or add a new one, you can use the `switchNetwork()` method. This method
allows you to change the current network while maintaining the connection to the wallet. If the specified network is not
already configured, it will be added to the list of available networks. This is useful for applications that need to
support multiple networks and allow users to switch between them seamlessly.
```typescript
import { TvmChains } from '/js-core'
import { type AddNetwork } from 'everscale-inpage-provider'
const chainParams: AddNetwork = {
name: 'Hamster Mainnet',
networkId: TvmChains.EverscaleMainnet,
connection: {
data: { endpoint: 'https://rpc.hamster.network/' },
type: 'proto',
},
}
// Switching to a different network
await tvmConnect.switchNetwork(chainParams) // or pass the network ID directly if it's already configured
// Adding a new network if it doesn't exist
await tvmConnect.addNetwork(chainParams, true) // true to switch to it immediately
```
Also, you can use `toChainParams` function to convert a network configuration to the format required by the
`switchNetwork()` method:
```typescript
import { everscaleMainnet, toChainParams } from '/tvm-connect'
const chainParams = toChainParams(everscaleMainnet)
// Now you can use chainParams with switchNetwork or addNetwork
await tvmConnect.switchNetwork(chainParams)
```
### Change account
You can also change the connected account by using the `changeAccount()` method. This method allows you to switch
between different accounts within the same wallet provider. This is particularly useful for wallets that support
multiple accounts or for applications that need to allow users to manage multiple accounts seamlessly.
```typescript
// Changing the connected account
await tvmConnect.changeAccount()
```
### Disconnecting
When your application needs to disconnect from the wallet, you can use the `disconnect()` method. This completely
terminates the connection with the wallet provider, resets all connection states, and removes active permissions. It's
good practice to call this method when users explicitly want to disconnect or when your application session ends.
```typescript
// Disconnecting from the wallet
await tvmConnect.disconnect()
```
## Advanced usage
---
This section provides a more in-depth look at the `TvmConnect` SDK, focusing on its framework-agnostic service
(`TvmConnectService`) and how to configure networks and providers. It also covers advanced usage scenarios, such as
integrating with different UI frameworks (like React) and customizing wallet connections. This allows developers to
create tailored user experiences while maintaining the core functionality of connecting to Nekoton-compatible wallets.
### TvmConnectService
The `TvmConnectService` is the core framework-agnostic SDK module that can be used in browser environments. It's
designed to be framework-independent, making it suitable for various UI frameworks and libraries (React, Vue, Angular,
etc.) or vanilla JavaScript browser applications.
This service provides a low-level API for connecting to Nekoton-compatible wallets, managing network connections, and
interacting with the blockchain. It accepts various configuration options when created and offers a comprehensive
interface for wallet interactions.
```typescript
import { StandaloneClientAdapter, type TvmNetworkConfig } from '/js-core'
import { SparXWallet, TvmConnectService, everscaleMainnet } from '/tvm-connect/sdk'
import { ProviderRpcClient } from 'everscale-inpage-provider'
const service = new TvmConnectService({
allowUnsupportedNetworks: true,
autoInit: true,
connectionParams: {
factory: (network: TvmNetworkConfig) => new ProviderRpcClient({
provider: new StandaloneClientAdapter({
connection: network ? network.connectionProperties || {
data: { endpoint: network.rpcUrl },
id: Number(network.chainId),
type: 'proto',
} : 'mainnetJrpc',
}),
}),
},
defaultNetworkId: TvmChains.EverscaleMainnet,
networks: [everscaleMainnet],
providerId: SparXWallet.name,
providers: [
{
connector: new SparXWallet({ ... }),
id: SparXWallet.name,
}
],
})
// Using the service directly
const connectWallet = async () => {
try {
await service.connect()
console.log('Connected to wallet at', service.address?.toString())
}
catch (error) {
console.error('Connection failed', error)
}
}
// Access service properties directly
if (service.isConnected) {
console.log('Current network:', service.network?.name)
console.log('Balance:', service.balance)
}
// Direct blockchain interaction without UI dependencies
const sendTransaction = async (recipient, amount) => {
const { provider, address } = service
if (!provider || !address) return
return provider.sendMessage({
amount,
bounce: true,
recipient,
sender: address,
})
}
```
While the `TvmConnect` class provides a more high-level abstraction with UI integration capabilities (like the dialog
component for wallet selection), `TvmConnectService` gives you direct access to the core wallet connection
functionality, making it ideal for:
- Custom UI implementations
- Integration with any UI framework or library
- Direct blockchain interactions in web applications
- Framework-independent browser implementations
```typescript
interface TvmConnectServiceCtorParams {
// Whether to allow unsupported networks. Default: true
allowUnsupportedNetworks?: boolean
// Whether to initialize the connection automatically. Default: true
autoInit?: boolean
// Standalone connection parameters (no permissions required)
connectionParams?: {
factory?: (network?: TvmNetworkConfig) => ProviderRpcClient // will be called every time when a network is changed
provider?: ProviderProperties['provider'] // or pass connection directly
}
// Default network chain id. Default: TvmChains.EverscaleMainnet
defaultNetworkId?: number
// The list of supported networks.
// everscaleMainnet, tonMainnet, tychoTestnet, venomMainnet networks are supported out of the box.
networks?: Readonly<TvmNetworkConfig[]>
// Provider ID for service initialization (using connectors provided in the providers parameter).
// SparXWallet, EverWallet, and VenomWallet connectors are supported out of the box.
providerId?: string
// The list of supported Providers.
// SparXWallet, EverWallet, and VenomWallet connectors are supported out of the box.
providers?: Readonly<TvmWalletProviderConfig[]>
}
```
### Network configuration
Below you can see a models of the network configuration, native currency and explorer config.
```typescript
import { DEFAULT_NATIVE_CURRENCY_DECIMALS, TvmChains, type TvmNetworkConfig } from '/js-core'
import { AddressLiteral } from 'everscale-inpage-provider'
const everscaleMainnet: TvmNetworkConfig = {
chainId: TvmChains.EverscaleMainnet.toString(),
currency: {
decimals: DEFAULT_NATIVE_CURRENCY_DECIMALS,
icon: '/assets/icons/EVER.svg',
name: 'Native currency',
symbol: 'EVER',
wrappedCurrencyAddress: new AddressLiteral(
'0:a49cd4e158a9a15555e624759e2e4e766d22600b7800d891e46f9291f044a93d',
), // WEVER
},
explorer: {
accountsSubPath: 'accounts',
baseUrl: 'https://everscan.io',
title: 'EVER Scan',
transactionsSubPath: 'transactions',
},
id: `tvm:${TvmChains.EverscaleMainnet}`, // <type>:<chainId>
name: 'Everscale',
rpcUrl: 'https://jrpc.everwallet.net',
shortName: 'Everscale',
type: 'tvm',
}
```
```typescript
import { type Address } from 'everscale-inpage-provider'
interface NativeCurrency<T = Address> {
balance?: string
decimals: number
icon?: string
name?: string
symbol: string
wrappedCurrencyAddress?: T
}
interface TvmNetworkConfig {
badge?: string
chainId: string
currency: NativeCurrency<Address>
disabled?: boolean
explorer: NetworkExplorerConfig
icon?: string
id: string
name: string
rpcUrl: string
shortName: string
tokensListUri?: string
tokenType?: string
type: 'tvm'
}
interface NetworkExplorerConfig {
accountsSubPath?: string | null
baseUrl: string
title: string
tokensSubPath?: string | null
transactionsSubPath?: string | null
}
```
### Provider configuration
To use more providers (wallets) and their connections, you can configure these providers with the `providers` option
that can be passed when instantiating the `TvmConnectService`.
```typescript
import {
createProviderConfig,
SparXWallet,
SparXWalletProviderInfo,
type TvmWalletProviderConfig,
} from '/tvm-connect/sdk'
import { ProviderRpcClient } from 'everscale-inpage-provider'
const sparxWallet: TvmWalletProviderConfig = createProviderConfig(SparXWallet, {
// Automatically initialize the wallet connection
autoInit: true,
// Number of attempts to connect to the wallet
fallbackAttempts: 5,
// Fallback provider factory to use when the wallet is not available
fallbackProviderFactory: async () => new ProviderRpcClient({ ... }),
id: SparXWallet.name,
// TvmWalletProviderInfo interface
info: SparXWalletProviderInfo,
// Will be called when the provider is disconnected
onDisconnect(err: any) {
console.error('Disconnected from SparX Wallet', err)
},
// Will be called when the connection is established
onPreconnect(connector: NekotonConnector) {
console.log('Preconnected with', connector.name)
},
})
```
```typescript
interface TvmWalletProviderConfig {
connector: NekotonConnector
info: TvmWalletProviderInfo
id: string
isRecent?: boolean
minVersion?: string
}
export type TvmWalletAvailablePlatforms = 'ios' | 'android' | 'chromeExtension' | 'firefoxExtension'
export type TvmWalletPlatformLinks = Partial<Record<TvmWalletAvailablePlatforms, string>>
interface TvmWalletProviderInfo {
description?: string
icon?: string
icons?: {
dark?: string
light?: string
}
links?: TvmWalletPlatformLinks & {
homepage?: string
universalLink?: string
}
name: string
}
```
## React integration
---
`TvmConnect` provides ready-to-use React components and hooks to simplify integration with React applications. These
components handle wallet connection UI, state management, and reactive updates when connection status changes.
> When using React integration, you should import `TvmConnect` and related components from the `/react` submodule
> instead of the root. The `/react` submodule already includes everything from the `/sdk` submodule (all classes, wallet
> connectors, networks), so you don't need to import them separately.
### Available React components
```typescript
import {
// Components
TvmConnectButton, // Button component for connecting to wallets (opens TvmConnectDialog)
TvmConnectDialog, // Modal dialog for wallet selection
TvmConnector, // Wallet account component showing connection status and balance
TvmConnectProvider, // Provider component for TvmConnectService and dialog context
// Providers
TvmConnectServiceProvider, // Provider for the TvmConnectService context
TvmConnectDialogStoreProvider, // Provider for the dialog store context
SharedParamsContext, // Context for shared parameters like agreements note and other (SharedParamsContext.Provider)
} from '/tvm-connect/react'
```
> `TvmConnectButton` will automatically open the `TvmConnectDialog` when clicked, helping users select a wallet
> provider. This dialog is managed internally and you don't need to render it separately.
### React hooks
```typescript
import {
// Context hooks for accessing services
useTvmConnectDialog, // Hook for accessing the wallet selection dialog
useTvmConnectService, // Hook for accessing the low-level service directly
useSharedParams, // Hook for accessing shared parameters like agreements note and other
// Utility hooks
useRecentConnectionMeta, // Hook for working with connection metadata storage
useOrderedConnections, // Hook for ordering wallet connectors with the most recent first
} from '/tvm-connect/react'
```
### Basic React integration example
```tsx
import {
TvmConnect,
TvmConnectButton,
TvmConnector,
TvmConnectProvider,
useTvmConnectService,
hamsterNetwork,
} from '/tvm-connect/react'
import * as React from 'react'
import { IntlProvider } from 'react-intl'
// Import necessary styles
import '/tvm-connect/uikit.min.css'
import '/tvm-connect/style.min.css'
// Creating an instance with default settings
const tvmConnect = new TvmConnect()
// Create a functional component for wallet info display
function WalletInfo() {
// Get the service to access wallet data
const service = useTvmConnectService()
if (!service?.isConnected) {
return <p>Not connected</p>
}
return (
<div>
{/* TvmConnector displays wallet info with a nicer UI */}
<TvmConnector />
{/* Or you can build your own UI using service data */}
<div>
<p>Address: {service.address?.toString()}</p>
<p>Network: {service.network?.name}</p>
<p>Balance: {service.balance}</p>
<button onClick={() => service.disconnect()}>Disconnect</button>
</div>
</div>
)
}
// Main app component
function App() {
const onConnect = (connector: NekotonConnector) => {
console.log('Connected with', connector.name)
console.log('Account address', connector.account.address.toString())
}
return (
<IntlProvider>
<TvmConnectProvider agreementsNote={<>...</>} service={tvmConnect.getService()}>
<div className="app">
<h1>My dApp</h1>
{/* Button to connect wallet */}
<TvmConnectButton network={hamsterNetwork} onConnect={onConnect}>
Connect Wallet
</TvmConnectButton>
<WalletInfo />
</div>
</TvmConnectProvider>
</IntlProvider>
)
}
export default App
```
### Advanced React integration
For more complex applications, you can use the dialog controls and service directly:
```tsx
import {
toChainParams,
useTvmConnectDialog,
useTvmConnectService,
// Networks and connectors are also available from /react
everscaleMainnet,
venomMainnet,
toChainParams,
} from '/tvm-connect/react'
import * as React from 'react'
function NetworkSwitcher() {
const service = useTvmConnectService()
const dialog = useTvmConnectDialog()
const connectToEverscale = React.useCallback(async () => {
try {
const chainParams = toChainParams(everscaleMainnet)
await service.switchNetwork(chainParams)
console.log('Switched to Everscale')
} catch (e) {
console.error('Failed to switch network', e)
}
}, [service])
const openWalletSelector = React.useCallback(() => {
dialog.connect({
network: venomMainnet,
onConnect: (connector: NekotonConnector) => {
console.log('Connected with', connector.name)
},
})
}, [dialog])
return (
<div>
<button onClick={connectToEverscale}>Switch to Everscale</button>
<button onClick={openWalletSelector}>Connect</button>
</div>
)
}
```
The React components use the same underlying `TvmConnect` service, providing a seamless integration with all the
features described in previous sections.
## Styling
---
This section describes how to apply the default styles for the `TvmConnect` components, ensuring that all components and
dialogs are styled correctly. It covers both standalone styles and inherited styles, as well as how to use CSS variables
(CSS-tokens) for customization. This allows developers to easily adapt the appearance of the `TvmConnect` components to
match their application's design while maintaining a consistent user interface.
### Styles import
To apply the default styles for the `TvmConnect` components, you need to import the appropriate CSS files. Depending on
your setup, you can choose between standalone styles or inherited styles.
#### Standalone styles
If you would like to use the standalone styles, provided by the `/tvm-connect` package and represent the
default styles for the `TvmConnect` components, you can import them as follows:
```typescript
/* index.ts */
import '/tvm-connect/uikit.min.css'
import '/tvm-connect/standalone.min.css'
```
```css
/* index.css */
'/tvm-connect/uikit.min.css';
'/tvm-connect/standalone.min.css';
```
#### Inherited styles
If you are using our [UIkit](https://www.npmjs.com/package/@broxus/react-uikit) package it will it automatically adapts
to your interface colors. So you don't need to import `/tvm-connect/uikit.min.css` separately. Just import
`/tvm-connect/inheritance.min.css` to apply the **UIkit** styles for the `TvmConnect` components.
```typescript
/* index.ts */
import '/tvm-connect/inheritance.min.css'
```
```css
/* index.css */
'/tvm-connect/inheritance.min.css';
```
### CSS-tokens
To customize the styles of the `Tvm Connect` components, you can use CSS variables (CSS-tokens). This allows you to
easily change colors, sizes, and other styles without modifying the source CSS files directly. You can override these
variables in your own CSS files or inline styles.
```css
--tvm-connect-color: var(--global-color, #383838);
--tvm-connect-emphasis-color: var(--global-emphasis-color, #333);
--tvm-connect-muted-color: var(--global-muted-color, #7698bb);
--tvm-connect-link-color: var(--global-link-color, #1e87f0);
--tvm-connect-link-hover-color: var(--global-link-hover-color, #00a6ff);
--tvm-connect-border: var(--global-border, #93b6d8);
--tvm-connect-border-radius: var(--global-border-radius, 12px);
/* Modal */
--tvm-connect-modal-width: var(--modal-width, 380px);
--tvm-connect-modal-background: var(--modal-background, #f7f9fb);
--tvm-connect-modal-border-radius: 12px;
--tvm-connect-modal-box-shadow: 0 8px 32px 0 rgb(63 74 111 / 12%), 0 1px 4px 0 rgb(63 74 111 / 8%);
--tvm-connect-modal-color: var(--tvm-connect-color);
--tvm-connect-modal-padding-horizontal: 24px;
--tvm-connect-modal-padding-vertical: var(--tvm-connect-modal-padding-horizontal);
--tvm-connect-modal-header-padding-horizontal: 0;
--tvm-connect-modal-header-padding-vertical: var(--tvm-connect-modal-padding-vertical);
--tvm-connect-modal-title-color: var(--tvm-connect-emphasis-color);
--tvm-connect-modal-title-font-size: 20px;
--tvm-connect-modal-title-font-weight: 500;
--tvm-connect-modal-title-line-height: 24px;
--tvm-connect-modal-body-padding-horizontal: 0;
--tvm-connect-modal-body-padding-vertical: var(--tvm-connect-modal-padding-vertical);
--tvm-connect-modal-footer-padding-horizontal: 0;
--tvm-connect-modal-footer-padding-vertical: var(--tvm-connect-modal-padding-vertical);
/* Drawer */
--tvm-connect-drawer-content-background: var(--drawer-content-background, #f7f9fb);
--tvm-connect-drawer-content-border-radius: 16px;
--tvm-connect-drawer-content-box-shadow: 0 8px 32px 0 rgb(63 74 111 / 12%), 0 1px 4px 0 rgb(63 74 111 / 8%);
--tvm-connect-drawer-content-color: var(--tvm-connect-color);
--tvm-connect-drawer-content-padding-horizontal: 24px;
--tvm-connect-drawer-content-padding-vertical: var(--tvm-connect-drawer-content-padding-horizontal);
--tvm-connect-drawer-header-padding-horizontal: 0;
--tvm-connect-drawer-header-padding-vertical: var(--tvm-connect-drawer-content-padding-vertical);
--tvm-connect-drawer-title-color: var(--tvm-connect-emphasis-color);
--tvm-connect-drawer-title-font-size: 22px;
--tvm-connect-drawer-title-font-weight: 500;
--tvm-connect-drawer-title-line-height: 26px;
--tvm-connect-drawer-body-padding-horizontal: 0;
--tvm-connect-drawer-body-padding-vertical: var(--tvm-connect-drawer-content-padding-vertical);
--tvm-connect-drawer-footer-padding-horizontal: 0;
--tvm-connect-drawer-footer-padding-vertical: var(--tvm-connect-drawer-content-padding-vertical);
/* Connector */
--tvm-connect-dropdown-trigger-horizontal-padding: 8px;
--tvm-connect-dropdown-trigger-vertical-padding: 0;
--tvm-connect-dropdown-background: var(--dropdown-background, #fff);
--tvm-connect-dropdown-border-radius: 5px;
--tvm-connect-dropdown-box-shadow: 0 8px 32px 0 rgb(63 74 111 / 12%), 0 1px 4px 0 rgb(63 74 111 / 8%);
--tvm-connect-dropdown-color: var(--tvm-connect-emphasis-color);
--tvm-connect-dropdown-link-color: var(--tvm-connect-muted-color, #0098ea);
--tvm-connect-dropdown-link-hover-color: var(--tvm-connect-color, #00a6ff);
/* Providers list */
--tvm-connect-provider-button-background: var(--button-default-background, #e4eaf1);
--tvm-connect-provider-button-hover-background: var(--button-default-hover-background, rgb(0 154.494955 232.2106 / 8%));
--tvm-connect-provider-button-hover-color: var(--tvm-connect-color);
--tvm-connect-provider-button-border-width: 2px;
--tvm-connect-provider-button-border-style: solid;
--tvm-connect-provider-button-border: transparent;
--tvm-connect-provider-button-hover-border: var(--button-default-hover-border, #07acff);
```
## Helpful utils
---
You can use `isSparXWalletBrowser`, `isEverWalletBrowser` or `isVenomWalletBrowser` to check the environment.
- `isSparXWalletBrowser(userAgent: string): boolean` - checks if your dApp is opened in mobile SparX Wallet WebView
- `isEverWalletBrowser(userAgent: string): boolean` - checks if your dApp is opened in mobile Ever Wallet WebView
- `isVenomWalletBrowser(userAgent: string): boolean` - checks if your dApp is opened in mobile Venom Wallet WebView
- `isNekotonWebview(userAgent: string): boolean` - checks if your dApp is opened in mobile WebView of any of the mobile
wallets above
- `getRecentConnectionMeta(storageKey?: string): TvmRecentConnectionMeta` - retrieves the last connection metadata from
localStorage
- `storeRecentConnectionMeta(meta: TvmRecentConnectionMeta, storageKey?: string): void` - saves the last connection
metadata to localStorage
- `toChainParams(networkConfig: TvmNetworkConfig): AddNetwork` - converts the network configuration to chain parameters
This will help you determine which connectors to use for mobile applications and for all other cases.
## Migration from v2 to v3
---
If you are migrating from version 2 to version 3 of the `/tvm-connect`, please refer to the
guide below for detailed instructions on how to update your codebase. The migration guide
covers breaking changes, new features, and best practices for transitioning to the latest version of the SDK. It is
essential to follow the migration steps to ensure compatibility with the new version and to take advantage of the
improvements and enhancements introduced in v3.
### SDK Changes
#### 1. Service Class Rename
**Main service class:**
```typescript
// v2 → v3
TvmWalletService → TvmConnectService
```
#### 2. New High-Level API
**v3 introduces TvmConnect class:**
```typescript
// v3 new high-level API
import { TvmConnect } from '/tvm-connect'
const tvmConnect = new TvmConnect()
const connector = await tvmConnect.connect()
```
#### 3. Utility Function Renames
**Utility function changes:**
```typescript
// v2 → v3
convertNetworkToChainParams → toChainParams
```
### React Components Changes
#### 1. Context and Provider Changes
**Context renames:**
```tsx
// v2 → v3
TvmWalletServiceContext → TvmConnectServiceContext
useTvmWalletService → useTvmConnectService
TvmWalletServiceProvider → TvmConnectServiceProvider
```
**Provider component changes:**
```tsx
// v2 → v3
TvmWalletProvidersContext → removed (replaced by TvmConnectProvider)
```
#### 2. Component Props Changes
**TvmConnectButton onConnect callback:**
```tsx
// v2: receives TvmWalletService
onConnect ? : (walletService?: TvmWalletService) => Promise<void> | void
// v3: receives NekotonConnector
onConnect ? : (connector: NekotonConnector) => Promise<void> | void
```
#### 3. New React Components in v3
**Added components:**
- `TvmConnectProvider` - comprehensive provider wrapper
- `InstallationGuide` - wallet installation guide
- `ProviderQRCode` - QR code component
- `ProvidersList` - improved providers list
#### 4. Architecture Changes
**v2 structure:**
- `TvmWalletServiceProvider` for context
- `TvmWalletProvidersContext` for providers management
**v3 structure:**
- `TvmConnectServiceProvider` for service context
- `TvmConnectProvider` as high-level provider wrapper
- `SharedParamsContext` for shared parameters
- `TvmConnectDialogStore` for dialog state management
### Migration Steps
#### SDK Migration
1. **Update service class:**
```typescript
// Replace service class name and imports
- import { TvmWalletService } from '/tvm-connect'
+ import { TvmConnectService } from '/tvm-connect'
- const service = new TvmWalletService(params)
+ const service = new TvmConnectService(params)
```
2. **Update utility function names:**
```typescript
// Replace utility function names
- import { convertNetworkToChainParams } from '/tvm-connect'
+ import { toChainParams } from '/tvm-connect'
```
3. **Optional: Use new high-level API:**
```typescript
// v3 introduces TvmConnect class for easier usage
import { TvmConnect } from '/tvm-connect'
const tvmConnect = new TvmConnect()
const connector = await tvmConnect.connect()
```
#### React Components Migration
1. **Update context and hooks:**
```tsx
// Replace context imports and usage
- import { TvmWalletServiceProvider, useTvmWalletService } from '/tvm-connect'
+ import { TvmConnectServiceProvider, useTvmConnectService } from '/tvm-connect'
- const service = useTvmWalletService()
+ const service = useTvmConnectService()
- <TvmWalletServiceProvider wallet={service}>
+ <TvmConnectServiceProvider service={service}>
```
2. **Update TvmConnectButton onConnect callback:**
```tsx
// Update callback parameter type
- onConnect={(walletService) => { /* use walletService */ }}
+ onConnect={(connector) => { /* use connector */ }}
```
3. **Remove TvmWalletProvidersContext (if used):**
```tsx
// v2: Remove this context usage
- import { TvmWalletProvidersProvider } from '/tvm-connect'
- <TvmWalletProvidersProvider>
// v3: Use TvmConnectProvider instead
+ import { TvmConnectProvider } from '/tvm-connect/react'
+ <TvmConnectProvider service={service}>
```
4. **Optional: Use new comprehensive provider:**
```tsx
// v3 provides TvmConnectProvider for better integration
import { TvmConnectProvider } from '/tvm-connect'
function App() {
return (
<TvmConnectProvider service={service} qrEnabled={false} popupType="drawer">
{/* your app */}
</TvmConnectProvider>
)
}
```