@broxus/tvm-connect
TypeScript icon, indicating that this package has built-in type declarations

2.13.0 • Public • Published

TVM Connect

Create a connection to Nekoton-based wallets and dApps

Usage

Installation

To apply this component, install it with npm using following command:

npm install @broxus/tvm-connect

or using yarn:

yarn add @broxus/tvm-connect

Requirements

In general it works great with our UIkit package. If you use this package you don't need to worry about the details.

Minimum requirements

If you are only going to use stores, you should install a few required packages

npm i everscale-inpage-provider mobx

or using yarn:

yarn add everscale-inpage-provider mobx

Full requirements

If you would like to use stores and included react components, you need to install a few more packages

npm i everscale-inpage-providermobx mobx-react-lite react-intl

or using yarn:

yarn add everscale-inpage-provider mobx-react-lite react-intl

TvmWalletService

The Wallet Service is a key part of this module. It accepts a number of settings and parameters when created and has a convenient interface for working with a connected wallet. It works with wallets whose providers and standalone RPC connections are based on everscale-inpage-provider and everscale-standalone-client.

import { TvmChains } from '@broxus/js-core'
import { EverWallet, SparXWallet, TvmWalletProviderConfig, TvmWalletService, VenomWallet } from '@broxus/tvm-connect'

const sparxWallet: TvmWalletProviderConfig = {
    connector: new SparXWallet(), // autoInit: false to prevent auto initialization. Optional
    id: 'SparXWallet',
    info: {
        description: 'Your universal tool for TVM',
        icon: '/assets/icons/SparXWallet.svg',
        links: {
            android: 'https://play.google.com/store/apps/details?id=com.broxus.sparx.app',
            homepage: 'https://sparxwallet.com/',
            ios: 'https://apps.apple.com/us/app/sparx-tvm-wallet/id6670219321',
        },
        name: 'SparX Wallet',
    },
}
const everWallet: TvmWalletProviderConfig = {
    connector: new EverWallet({ autoInit: false }), // autoInit: false to prevent auto initialization. Optional
    id: 'EverWallet',
    info: {
        description: 'Premier wallet for the Everscale',
        icon: '/assets/icons/EverWallet.svg',
        links: {
            android: 'https://play.google.com/store/apps/details?id=com.broxus.crystal.app',
            chromeExtension: 'https://chrome.google.com/webstore/detail/ever-wallet/cgeeodpfagjceefieflmdfphplkenlfk',
            firefoxExtension: 'https://addons.mozilla.org/en-GB/firefox/addon/ever-wallet/',
            homepage: 'https://everwallet.net/',
            ios: 'https://apps.apple.com/us/app/ever-wallet-everscale/id1581310780',
        },
        name: 'Ever Wallet',
    },
}
const venomWallet: TvmWalletProviderConfig = {
    connector: new VenomWallet(),
    id: 'VenomWallet',
    info: {
        description: 'Safe, reliable, and 100% yours',
        icon: '/assets/icons/VenomWallet.svg',
        links: {
            android: 'https://play.google.com/store/apps/details?id=com.venom.wallet',
            chromeExtension: 'https://chrome.google.com/webstore/detail/venom-wallet/ojggmchlghnjlapmfbnjholfjkiidbch',
            homepage: 'https://venomwallet.com/',
            ios: 'https://apps.apple.com/app/venom-blockchain-wallet/id1622970889',
        },
        name: 'Venom Wallet',
    },
}

const walletService = new TvmWalletService({
    autoInit: false,
    defaultNetworkId: TvmChains.EverscaleMainnet, // 42
    networks: [
        {
            chainId: TvmChains.EverscaleMainnet.toString(),
            currency: {
                decimals: 9,
                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.toString()}`, // <type>-<chainId>
            name: 'Everscale',
            rpcUrl: 'https://jrpc.everwallet.net',
            shortName: 'Everscale',
            type: 'tvm',
        },
    ],
    providerId: 'EverWallet', // TvmWalletProviderConfig['id']
    providers: [sparxWallet, everWallet, venomWallet],
})

await everWallet.connector.init()
const provider = await walletService.init()
await walletService.connect()

This is library/framework agnostic component. So, you can use it anywhere.

Using with React

First at all, you should wrap entire your app with TvmWalletServiceProvider to share TvmWalletService through all your app components.

import { TvmConnector, TvmWalletServiceProvider } from '@broxus/tvm-connect'
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { IntlProvider } from 'react-intl'

function App(): JSX.Element {
    return (
        <IntlProvider>
            <TvmWalletServiceProvider>
                ...
                <TvmConnector />
                ...
            </TvmWalletServiceProvider>
        </IntlProvider>
    )
}

ReactDOM.render(<App />, document.body)

Custom service

You may use TvmWalletService to create your own service with provider and connection.

import { TvmWalletService } from '@broxus/tvm-connect'

let service: TvmWalletService

export function useTvmConnect(): TvmWalletService {
    if (service === undefined) {
        service = new TvmWalletService({
            defaultNetworkId: number, // (optional) use TvmChains enum to provide a network id
            networks: TvmNetworkConfig[], // (optional) supported networks configurations
            providerId: string, // (optional) TvmWalletProviderConfig['id'] provide option to define a default connector
            providers: TvmWalletProviderConfig[], // (optional) providers config
        })
    }
    return service
}

// Pass custom wallet to service provider
function App(): JSX.Element {
    const wallet = useTvmConnect()
    return (
        <IntlProvider>
            <TvmWalletServiceProvider wallet={wallet}>
            ...
                <TvmConnector />
            ...
            </TvmWalletServiceProvider>
        </IntlProvider>
    )
}

Network configuration

Below you can see a models of the network configuration, native currency and explorer config.

interface NativeCurrency<T = any> {
    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 TvmWalletService.

interface TvmWalletProviderConfig {
    connector: NekotonConnector
    info: {
        description?: string
        icon?: string
        links?: TvmProviderPlatformLinks & { homepage?: string, universalLink?: string }
        name: string
    }
    id: string
    isRecent?: boolean
    minVersion?: string
}

export type TvmProviderAvailablePlatforms = 'ios' | 'android' | 'chromeExtension' | 'firefoxExtension'

export type TvmProviderPlatformLinks = Partial<Record<TvmProviderAvailablePlatforms, string>>

Helpful utils

You can use isEverWalletBrowser or isVenomWalletBrowser to check environment.

  • isSparXWalletBrowser - checks if your dApp is opened in mobile SparX Wallet WebView
  • isEverWalletBrowser - checks if your dApp is opened in mobile Ever Wallet WebView
  • isVenomWalletBrowser - checks if your dApp is opened in mobile Venom Wallet WebView

This will help you determine which connectors to use for mobile applications and for all other cases

import { TvmChains } from '@broxus/js-core'
import { TvmWalletService, useRecentConnectionMeta } from '@broxus/tvm-connect'
import { AddressLiteral } from 'everscale-inpage-provider'

const providers: TvmWalletProviderConfig[] = []

const networks: TvmNetworkConfig[] = [
    {
        chainId: TvmChains.EverscaleMainnet.toString(),
        currency: {
            decimals: 9,
            icon: '/assets/icons/EVER.svg',
            name: 'EVER',
            symbol: 'EVER',
            wrappedCurrencyAddress: new AddressLiteral('0:a49cd4e158a9a15555e624759e2e4e766d22600b7800d891e46f9291f044a93d'),
        },
        explorer: {
            accountsSubPath: 'accounts',
            baseUrl: 'https://everscan.io',
            title: 'EVER Scan',
            transactionsSubPath: 'transactions',
        },
        icon: '/assets/icons/EVER.svg',
        id: `tvm-${TvmChains.EverscaleMainnet}`,
        name: 'Everscale',
        rpcUrl: 'https://jrpc.everwallet.net',
        shortName: 'Everscale',
        type: 'tvm',
    },
    {
        chainId: TvmChains.VenomMainnet.toString(),
        currency: {
            decimals: 9,
            icon: '/assets/icons/VENOM.svg',
            name: 'VENOM',
            symbol: 'VENOM',
            wrappedCurrencyAddress: new AddressLiteral('0:77d36848bb159fa485628bc38dc37eadb74befa514395e09910f601b841f749e'),
        },
        explorer: {
            accountsSubPath: 'accounts',
            baseUrl: 'https://venomscan.com',
            title: 'VenomScan',
            transactionsSubPath: 'transactions',
        },
        icon: '/assets/icons/VENOM.svg',
        id: `tvm-${TvmChains.VenomMainnet}`,
        name: 'Venom Mainnet',
        rpcUrl: 'https://jrpc.venom.foundation',
        shortName: 'Venom',
        type: 'tvm',
    },
]

try {
    const ua = getUserAgent()
    const isSparXWallet = isSparXWalletBrowser(ua)
    const isEverWallet = isEverWalletBrowser(ua)
    const isVenomWallet = isVenomWalletBrowser(ua)
    if (isSparXWallet) {
        providers.push(sparxWallet)
        defaultProviderId = sparxWallet.id
        predefinedNetworkId = TvmChains.EverscaleMainnet
    }
    else if (isEverWallet) {
        providers.push(everWallet)
        defaultProviderId = everWallet.id
        predefinedNetworkId = TvmChains.EverscaleMainnet
    }
    else if (isVenomWallet) {
        providers.push(venomWallet)
        defaultProviderId = venomWallet.id
        predefinedNetworkId = TvmChains.VenomMainnet
    }
    else {
        providers.push({
            ...sparxWallet,
            minVersion: '0.4.0',
        }, {
            ...everWallet,
            minVersion: '0.4.0',
        }, {
            ...venomWallet,
            minVersion: '0.3.173',
        })
    }
}
catch (e) {}

let service: TvmWalletService

export function useTvmWallet(): TvmWalletService {
    const [recentMeta] = useRecentConnectionMeta()
    if (service === undefined) {
        const networkId = recentMeta?.chainId ? Number(recentMeta.chainId) : TvmChains.EverscaleMainnet
        service = new TvmWalletService({
            defaultNetworkId: predefinedNetworkId ?? networkId,
            networks,
            providerId: recentMeta?.disconnected ? defaultProviderId : recentMeta?.providerId ?? defaultProviderId,
            providers,
        })
    }
    return service
}

Styling

If you are using our UIkit package it will it automatically adapts to your interface colors.

Otherwise, you can import standalone CSS

import '@broxus/tvm-connect/uikit.min.css' // include all required styles from UIkit
import '@broxus/tvm-connect/style.min.css' // include all required styles from TVM Connect

Below you can find all supported CSS variables and their defaults

/* Connector */
--tvm-connect-dropdown-trigger-horizontal-padding: var(--global-small-gutter, 8px);
--tvm-connect-dropdown-trigger-vertical-padding: 0;
--tvm-connect-dropdown-background: var(--dropdown-background, #fff);
--tvm-connect-dropdown-border-radius: var(--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(--dropdown-color, #333);
--tvm-connect-dropdown-link-color: var(--dropdown-color, #0af);

/* Providers list buttons */
--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(--global-primary-border, transparent);

/* Modal */
--tvm-connect-modal-content-background: var(--modal-content-background, #fff);
--tvm-connect-modal-content-border-radius: 12px;
--tvm-connect-modal-content-box-shadow: 0 8px 32px 0 rgb(63 74 111 / 12%), 0 1px 4px 0 rgb(63 74 111 / 8%);
--tvm-connect-modal-content-color: var(--base-body-color, #383838);
--tvm-connect-modal-content-padding-horizontal: 18px;
--tvm-connect-modal-content-padding-vertical: var(--tvm-connect-modal-content-padding-horizontal);
--tvm-connect-modal-header-padding-horizontal: 0;
--tvm-connect-modal-header-padding-vertical: var(--tvm-connect-modal-content-padding-vertical);
--tvm-connect-modal-title-color: var(--base-heading-color, #383838);
--tvm-connect-modal-title-font-size: var(--modal-title-font-size, 18px);
--tvm-connect-modal-title-font-weight: 500;
--tvm-connect-modal-title-line-height: var(--modal-title-line-height, 22px);
--tvm-connect-modal-body-padding-horizontal: 0;
--tvm-connect-modal-body-padding-vertical: var(--tvm-connect-modal-content-padding-vertical);
--tvm-connect-modal-footer-padding-horizontal: 0;
--tvm-connect-modal-footer-padding-vertical: var(--tvm-connect-modal-content-padding-vertical);

/* Drawer */
--tvm-connect-drawer-content-background: var(--drawer-content-background, #fff);
--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(--base-body-color, #383838);
--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(--base-heading-color, #383838);
--tvm-connect-drawer-title-font-size: var(--drawer-title-font-size, 24px);
--tvm-connect-drawer-title-font-weight: 500;
--tvm-connect-drawer-title-line-height: var(--drawer-title-line-height, 28px);
--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);

/* Connection approve popup stage */
--tvm-connect-connection-request-button-border-width: 2px;
--tvm-connect-connection-request-button-border-style: solid;
--tvm-connect-connection-request-button-border: transparent;
--tvm-connect-connection-request-button-hover-border: var(--global-border, transparent);

Package Sidebar

Install

npm i @broxus/tvm-connect

Weekly Downloads

215

Version

2.13.0

License

MIT

Unpacked Size

749 kB

Total Files

113

Last publish

Collaborators

  • rexagon
  • pavlovdog_
  • geronimo
  • 30mb1
  • odrin
  • pavel337