UNPKG

@broxus/tvm-connect

Version:

TypeScript SDK for connecting to Nekoton-compatible wallets using a unified interface.

594 lines (573 loc) 23.8 kB
import { Permissions, Provider, ProviderRpcClient, AddNetwork, Address, AssetType, Network, ProviderEvents, Subscription, ProviderProperties, FullContractState, Subscriber } from 'everscale-inpage-provider'; import { AbstractStore, Silentable, TvmNetworkConfig, NativeCurrency, Forceable } from '@broxus/js-core'; import { IReactionDisposer } from 'mobx'; type Account = Permissions['accountInteraction']; declare enum ConnectionType { NEKOTON_WALLET = "NEKOTON_WALLET", NEKOTON_ADAPTER = "NEKOTON_ADAPTER", EXTERNAL_APP = "EXTERNAL_APP" } interface RecentConnectionMeta { chainId?: string; disconnected?: boolean; providerId: string; type?: ConnectionType; } type TvmWalletAvailablePlatforms = 'ios' | 'android' | 'chromeExtension' | 'firefoxExtension'; type TvmWalletPlatformLinks = Partial<Record<TvmWalletAvailablePlatforms, string>>; type PopupType = 'drawer'; interface TvmWalletProviderInfo { description?: string; hasScanner?: boolean; icon?: string; icons?: { dark?: string; light?: string; }; links?: TvmWalletPlatformLinks & { homepage?: string; universalLink?: string; }; name: string; } interface TvmWalletProviderConfig { connector: NekotonConnector; id: string; info?: TvmWalletProviderInfo; isRecent?: boolean; minVersion?: string; } declare enum TvmWalletRdnsList { SPARX_WALLET = "com.sparxwallet", SPARX_WALLET_MOBILE = "com.broxus.sparx.app", EVER_WALLET = "net.everwallet", EVER_WALLET_MOBILE = "com.broxus.crystal.app", VENOM_WALLET = "com.venomwallet", VENOM_WALLET_MOBILE = "com.venom.wallet" } declare enum TvmProviderEvent { REQUEST_PROVIDER = "tvm:requestProvider", ANNOUNCE_PROVIDER = "tvm:announceProvider" } interface TvmAnnounceProviderEvent extends CustomEvent { detail: TvmProviderDetail; type: TvmProviderEvent.ANNOUNCE_PROVIDER; } interface TvmProviderDetail { info: TvmProviderInfo; provider: Provider; } interface TvmProviderInfo { name: string; rdns?: string; } interface NekotonConnectorInitCtorParams { autoInit?: boolean; fallbackAttempts?: number; } interface NekotonConnectorCtorParams { fallbackProviderFactory?: () => Promise<ProviderRpcClient> | ProviderRpcClient; info?: TvmWalletProviderInfo; onDisconnect?: (err: any) => Promise<void> | void; onPreconnect?: (connector: NekotonConnector) => Promise<void> | void; } interface NekotonConnectorData { account?: Account; chainId?: number; version?: string; } interface NekotonConnectorState { isConnecting?: boolean; isDisconnecting?: boolean; isInitialized?: boolean; isInitializing?: boolean; } interface ConnectOptions { onConnect?: (connector: NekotonConnector) => Promise<void> | void; } interface DisconnectOptions { force?: boolean; onDisconnect?: (connector: NekotonConnector) => Promise<void> | void; } declare abstract class NekotonConnector extends AbstractStore<NekotonConnectorData, NekotonConnectorState> { protected readonly params?: Readonly<NekotonConnectorCtorParams> | undefined; abstract readonly type: ConnectionType; provider?: ProviderRpcClient; protected constructor(params?: Readonly<NekotonConnectorCtorParams> | undefined); abstract init(): Promise<ProviderRpcClient | undefined>; connect(networkIdOParams?: number | AddNetwork, options?: ConnectOptions): Promise<void>; disconnect(options?: DisconnectOptions): Promise<void>; addAsset(address: Address | string, type?: AssetType): Promise<boolean>; addNetwork(network: AddNetwork, switchNetwork?: boolean): Promise<Network | null>; switchNetwork(networkIdOParams: number | AddNetwork): Promise<Network | null>; get account(): NekotonConnectorData['account']; get chainId(): NekotonConnectorData['chainId']; get version(): NekotonConnectorData['version']; get isConnecting(): NekotonConnectorState['isConnecting']; get isDisconnecting(): NekotonConnectorState['isDisconnecting']; get isInitialized(): NekotonConnectorState['isInitialized']; get isInitializing(): NekotonConnectorState['isInitializing']; get info(): TvmWalletProviderInfo | undefined; protected runSubscriptions(options?: Silentable): Promise<void>; protected stopSubscriptions(options?: Silentable): Promise<void>; protected preConnect(): Promise<void>; protected handlePermissionsChanged(event: ProviderEvents['permissionsChanged']): Promise<void>; protected handleNetworkChanged(event: ProviderEvents['networkChanged']): Promise<void>; protected handleDisconnected(err: ProviderEvents['disconnected']): Promise<void>; protected _networkChangeSubscription: Subscription<'networkChanged'> | undefined; protected _permissionsSubscription: Subscription<'permissionsChanged'> | undefined; protected _disconnectSubscription: Subscription<'disconnected'> | undefined; } interface EverWalletCtorParams extends NekotonConnectorCtorParams, NekotonConnectorInitCtorParams { } interface EveProviderFallbackParams { fallbackAttempts?: number; } declare function everProviderFallback(params?: EveProviderFallbackParams): (client?: Provider) => Promise<Provider>; declare class EverWallet extends NekotonConnector { protected readonly params?: Readonly<EverWalletCtorParams> | undefined; readonly type = ConnectionType.NEKOTON_WALLET; constructor(params?: Readonly<EverWalletCtorParams> | undefined); init(): Promise<ProviderRpcClient | undefined>; } interface OxyWalletCtorParams extends NekotonConnectorCtorParams, NekotonConnectorInitCtorParams { } interface OxyProviderFallbackParams { fallbackAttempts?: number; } declare function oxyChatProviderFallback(params?: OxyProviderFallbackParams): (client?: Provider) => Promise<Provider>; declare class OxyChatWallet extends NekotonConnector { protected readonly params?: Readonly<OxyWalletCtorParams> | undefined; readonly type = ConnectionType.EXTERNAL_APP; constructor(params?: Readonly<OxyWalletCtorParams> | undefined); init(): Promise<ProviderRpcClient | undefined>; } interface SparXWalletCtorParams extends NekotonConnectorCtorParams, NekotonConnectorInitCtorParams { } interface SparXProviderFallbackParams { fallbackAttempts?: number; } declare function sparxProviderFallback(params?: SparXProviderFallbackParams): (client?: Provider) => Promise<Provider>; declare class SparXWallet extends NekotonConnector { protected readonly params?: Readonly<SparXWalletCtorParams> | undefined; readonly type = ConnectionType.NEKOTON_WALLET; constructor(params?: Readonly<SparXWalletCtorParams> | undefined); init(): Promise<ProviderRpcClient | undefined>; } interface VenomWalletCtorParams extends NekotonConnectorCtorParams, NekotonConnectorInitCtorParams { } interface VenomProviderFallbackParams { fallbackAttempts?: number; } declare function venomProviderFallback(params?: VenomProviderFallbackParams): (client?: Provider) => Promise<Provider>; declare class VenomWallet extends NekotonConnector { protected readonly params?: Readonly<VenomWalletCtorParams> | undefined; readonly type = ConnectionType.NEKOTON_WALLET; constructor(params?: Readonly<VenomWalletCtorParams> | undefined); init(): Promise<ProviderRpcClient | undefined>; } declare const TVM_RECENT_CONNECTION = "TVM_RECENT_CONNECTION"; declare const CONTAINER_ID = "tvm-connect-root"; declare function createProviderConfig(Ctor: new (...args: any[]) => NekotonConnector, params?: NekotonConnectorCtorParams & NekotonConnectorInitCtorParams): TvmWalletProviderConfig; declare function getPredefinedNetworks(): TvmNetworkConfig[]; declare function getPredefinedProviderId(meta?: RecentConnectionMeta | undefined): string; interface PredefinedConfigOptions { getProviderInfo?: (providerId: string, info: TvmWalletProviderInfo) => TvmWalletProviderInfo; onPreconnect?: (connector: NekotonConnector) => Promise<void> | void; } declare function getPredefinedProviders(options?: PredefinedConfigOptions): TvmWalletProviderConfig[]; declare const everscaleMainnet: TvmNetworkConfig; declare const venomMainnet: TvmNetworkConfig; declare const tychoTestnet: TvmNetworkConfig; declare const tonMainnet: TvmNetworkConfig; declare const humoMainnet: TvmNetworkConfig; declare const tonTestnet: TvmNetworkConfig; declare const mShariaMainnet: TvmNetworkConfig; declare const vanLang: TvmNetworkConfig; declare const SparXWalletProviderInfo: TvmWalletProviderInfo; declare const EverWalletProviderInfo: TvmWalletProviderInfo; declare const VenomWalletProviderInfo: TvmWalletProviderInfo; declare const OxyChatWalletProviderInfo: TvmWalletProviderInfo; interface TvmConnectServiceCtorParams { /** * **Whether to allow unsupported networks.** * * That means if the connector will change the network * to the unsupported one - service will react for this * and will try to connect to the unsupported network * for update account state. * * @default true */ allowUnsupportedNetworks?: boolean; /** * **Whether to initialize the connection automatically.** * * @example * ```typescript * const service = new TvmConnectService({ * autoInit: false, * providerId: 'SparXWallet', * providers: [...] * }) * const sparx = await service.init() * * await service.connect() * ``` * @default true */ autoInit?: boolean; /** * **Standalone connection parameters (no permissions required).** * * @example * ```typescript * import { StandaloneClientAdapter, TvmChains } from '@broxus/js-core' * import { TvmConnectService } from '@broxus/tvm-connect/sdk' * import { ProviderRpcClient, StaticProviderAdapter } from 'everscale-inpage-provider' * * const service = new TvmConnectService({ * connectionParams: { * // Use factory to recreate connection when network has been changed * factory: (network) => new ProviderRpcClient({ * provider: new StandaloneClientAdapter({ * connection: network ? network.connectionProperties || { * data: { endpoint: network.rpcUrl }, * id: Number(network.chainId), * type: 'proto', * } : 'mainnetJrpc', * }), * }), * // ... or use your own connection directly from external source * provider: new StaticProviderAdapter(...), * }, * defaultNetworkId: TvmChains.EverscaleMainnet, * networks: [...], * providerId: 'SparXWallet', * providers: [...], * }) * * await service.connect() * ``` * * @param {(network?: TvmNetworkConfig) => ProviderRpcClient} factory - Factory function to * create a new RPC client * @param {ProviderProperties['provider']} provider - Custom external Provider properties * @param {'jrpc' | 'proto'} type - Connection type */ connectionParams?: { factory?: (network?: TvmNetworkConfig) => ProviderRpcClient; provider?: ProviderProperties['provider']; }; /** * **Default network chain id.** * * Should be provided if you want to define the default network for the service. * * `networks` parameter should be provided to use this feature. * * @default TvmChains.EverscaleMainnet */ defaultNetworkId?: number; /** * **The list of supported networks.** * * Should be provided if you want to use the more service features. */ 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. * * @example * ```typescript * import { SparXWallet, TvmConnectService } from '@broxus/tvm-connect/sdk' * * const sparxWallet: TvmWalletProviderConfig = { * connector: new SparXWallet(), * id: 'SparXWallet', * info: { * description: 'Your universal tool for TVM', * icon: '/assets/icons/SparXWallet.svg', // your own icon * links: { * android: 'https://play.google.com/store/apps/details?id=com.broxus.sparx.app', * chromeExtension: * 'https://chromewebstore.google.com/detail/sparx-wallet/aijecocmefcagpmbpjcfjjbcclfmobgf', * homepage: 'https://sparxwallet.com/', ios: * 'https://apps.apple.com/us/app/sparx-tvm-wallet/id6670219321', name: 'SparX Wallet', * }, * }, * } * * const service = new TvmConnectService({ * defaultNetworkId: TvmChains.EverscaleMainnet, * networks: [...], * providerId: 'SparXWallet', * providers: [sparxWallet], * }) * * await service.connect() * ``` */ providers?: Readonly<TvmWalletProviderConfig[]>; /** * **Storage key for recent connection meta.** * * If you want to use the recent connection meta feature, you should provide a storage key * for it. * * @default 'tvm-connect:recent-connection-meta' * @example * ```typescript * const service = new TvmConnectService({ * recentMetaStorageKey: '@{dAppName}/tvmRecentConnectionMeta', * }) * ``` * * @see getRecentConnectionMeta * @see storeRecentConnectionMeta */ recentMetaStorageKey?: string; } interface TvmConnectServiceData { contractState?: FullContractState; networks: Readonly<TvmNetworkConfig[]>; providers?: Readonly<TvmWalletProviderConfig[]>; } interface TvmConnectServiceState { chainId?: number; isSyncing?: boolean; providerId?: string; } declare class TvmConnectService extends AbstractStore<TvmConnectServiceData, TvmConnectServiceState> { protected readonly params?: Readonly<TvmConnectServiceCtorParams> | undefined; readonly name = "TvmWalletService"; constructor(params?: Readonly<TvmConnectServiceCtorParams> | undefined); /** * Returns an instance of the current connector that provides an interface * to interact with associated provider in the usage environment. * @returns {NekotonConnector|undefined} */ get connector(): NekotonConnector | undefined; /** * Initialize the wallet connection manually * @returns {Promise<ProviderRpcClient | undefined>} */ init(): Promise<ProviderRpcClient | undefined>; /** * Manually connect to the wallet * @returns {Promise<void>} */ connect(networkIdOParams?: number | AddNetwork, options?: ConnectOptions): Promise<void>; /** * Manually disconnect from the wallet * @param {DisconnectOptions} [options] * @returns {Promise<void>} */ disconnect(options?: DisconnectOptions): Promise<void>; /** * Add custom token asset to the TVM Wallet * @param {Address | string} address * @param {AssetType} [type] */ addAsset(address: Address | string, type?: AssetType): Promise<boolean | undefined>; /** * Add new network to the wallet. * Supported since version `0.3.40` of the `everscale-inpage-provider` * @param {AddNetwork} network * @param {boolean} switchNetwork * @returns {Promise<Network | null>} */ addNetwork(network: AddNetwork, switchNetwork?: boolean): Promise<Network | null>; /** * Switch to network by the given networkId or network params. * Supported since version `0.3.40` of the `everscale-inpage-provider` * @param {number | AddNetwork} networkIdOParams * @returns {Promise<Network | null>} */ switchNetwork(networkIdOParams: number | AddNetwork): Promise<Network | null>; /** * Change current account in the wallet. * @returns {Promise<void>} */ changeAccount(): Promise<void>; /** * An independent RPC connection that allows you to receive data from the blockchain without * being able to send transactions. * * This connection does not require `accountInteraction` permissions. * @returns {ProviderRpcClient} */ get connection(): ProviderRpcClient; /** * A Provider that requires a `basic` and `accountInteraction` permissions for the ability to * send transactions. * @returns {ProviderRpcClient|undefined} */ get provider(): ProviderRpcClient | undefined; /** * Returns computed wallet contract state * @returns {TvmConnectServiceData["contractState"]} */ get contract(): TvmConnectServiceData['contractState']; /** * The list of the supported networks * @returns {TvmConnectServiceData["networks"]} */ get networks(): TvmConnectServiceData['networks']; /** * The list of the supported providers * @returns {TvmConnectServiceData["providers"]} */ get providers(): TvmConnectServiceData['providers']; /** * Returns current network chain id * @returns {TvmConnectServiceState["chainId"]} */ get chainId(): TvmConnectServiceState['chainId']; /** * Returns `true` if wallet contract is updating * @returns {TvmConnectServiceState["isSyncing"]} */ get isSyncing(): TvmConnectServiceState['isSyncing']; /** * A unique identifier of the connected wallet (provider) * @returns {TvmConnectServiceState["providerId"]} */ get providerId(): TvmConnectServiceState['providerId']; /** * Returns computed wallet address value * @returns {Address|undefined} */ get address(): Address | undefined; /** * Returns computed wallet normalized balance value * @returns {FullContractState["balance"]} */ get balance(): FullContractState['balance']; /** * Returns network native currency * @returns {NativeCurrency<Address>} */ get currency(): Readonly<NativeCurrency<Address>>; /** * Whether provider is available. * * That means extension is installed and activated, else `false` * @returns {boolean} */ get hasProvider(): boolean; /** * Returns `true` if wallet is connected * @returns {boolean} */ get isConnected(): boolean; /** * Returns `true` if installed wallet has outdated version */ get isOutdated(): boolean; /** * Returns `true` if connection to RPC is initialized and connected * @returns {boolean} */ get isReady(): boolean; /** * Checks for supported network * @returns {boolean} */ get isUnsupportedNetwork(): boolean; /** * Returns current network configuration * @returns {TvmNetworkConfig|undefined} */ get network(): TvmNetworkConfig | undefined; /** * Returns details about current connected provider * @returns {TvmWalletProviderInfo | undefined} */ get providerInfo(): TvmWalletProviderInfo | undefined; /** * Returns computed account * @returns {NekotonConnector["account"]} */ get account(): NekotonConnector['account']; /** * Returns `true` if wallet is connecting * @returns {NekotonConnector["isConnecting"]} */ get isConnecting(): NekotonConnector['isConnecting']; /** * Returns `true` if wallet is disconnecting * @returns {NekotonConnector["isDisconnecting"]} */ get isDisconnecting(): NekotonConnector['isDisconnecting']; /** * Returns `true` if wallet is initialized * @returns {NekotonConnector["isInitialized"]} */ get isInitialized(): NekotonConnector['isInitialized']; /** * Returns `true` if wallet is initializing * @returns {NekotonConnector["isInitializing"]} */ get isInitializing(): NekotonConnector['isInitializing']; /** * Synchronizes the contract state of the current account. * * If `force` is not set, it will only sync if not already syncing. * * @param {Forceable} [options] - Options to control the sync behavior. * @returns {Promise<void>} */ protected syncContractState(options?: Forceable): Promise<void>; /** * Initializes the reactive logic for synchronizing the state of the contract and network. * Sets up disposers for reacting to address changes and network chain ID updates. * * @return {Promise<void>} */ protected _init(): Promise<void>; /** * Subscribe to current account address contract state updates * and update the local data while updates is coming. * @returns {Promise<void>} * @protected */ protected _watch(): Promise<void>; /** * Unsubscribe from current account address contract state updates. * * @returns {Promise<void>} * @protected */ protected _unwatch(): Promise<void>; protected _accountDisposer: IReactionDisposer | undefined; protected _contractSubscriber: Subscriber | undefined; protected _networkDisposer: IReactionDisposer | undefined; } interface UniversalLinkParams { apn: string; ibi: string; isi: string; link?: string; } declare function createUniversalLink(basePath: string, params: UniversalLinkParams): any; declare function isSparXWalletBrowser(ua: string): boolean; declare function isEverWalletBrowser(ua: string): boolean; declare function isVenomWalletBrowser(ua: string): boolean; declare function isOxyChatWalletBrowser(ua: string): boolean; declare function isNekotonWebview(ua: string): boolean; declare function getTvmProviderPlatformLink(links: TvmWalletPlatformLinks): [TvmWalletAvailablePlatforms, string | undefined] | undefined; declare function isRecentConnectionMeta(value: any): value is RecentConnectionMeta; declare function storeRecentConnectionMeta(meta: RecentConnectionMeta | undefined, storageKey?: string): void; declare function getRecentConnectionMeta(storageKey?: string): RecentConnectionMeta | undefined; declare function toChainParams(networkConfig: TvmNetworkConfig): AddNetwork; export { type Account, CONTAINER_ID, type ConnectOptions, ConnectionType, type DisconnectOptions, EverWallet, EverWalletProviderInfo, NekotonConnector, type NekotonConnectorCtorParams, type NekotonConnectorData, type NekotonConnectorInitCtorParams, type NekotonConnectorState, OxyChatWallet, OxyChatWalletProviderInfo, type OxyWalletCtorParams, type PopupType, type PredefinedConfigOptions, type RecentConnectionMeta, SparXWallet, SparXWalletProviderInfo, TVM_RECENT_CONNECTION, type TvmAnnounceProviderEvent, TvmConnectService, type TvmConnectServiceCtorParams, type TvmConnectServiceData, type TvmConnectServiceState, type TvmProviderDetail, TvmProviderEvent, type TvmProviderInfo, type TvmWalletAvailablePlatforms, type TvmWalletPlatformLinks, type TvmWalletProviderConfig, type TvmWalletProviderInfo, TvmWalletRdnsList, type UniversalLinkParams, VenomWallet, type VenomWalletCtorParams, VenomWalletProviderInfo, createProviderConfig, createUniversalLink, everProviderFallback, everscaleMainnet, getPredefinedNetworks, getPredefinedProviderId, getPredefinedProviders, getRecentConnectionMeta, getTvmProviderPlatformLink, humoMainnet, isEverWalletBrowser, isNekotonWebview, isOxyChatWalletBrowser, isRecentConnectionMeta, isSparXWalletBrowser, isVenomWalletBrowser, mShariaMainnet, oxyChatProviderFallback, sparxProviderFallback, storeRecentConnectionMeta, toChainParams, tonMainnet, tonTestnet, tychoTestnet, vanLang, venomMainnet, venomProviderFallback };