UNPKG

@broxus/tvm-connect

Version:

Nekoton-compatible wallets connector.

122 lines (121 loc) 5.31 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; import { debounce, debug, error, isBrowser, throwException, timeoutPromise } from '@broxus/js-utils'; import { ProviderRpcClient, StaticProviderAdapter } from 'everscale-inpage-provider'; import { action, makeObservable, runInAction } from 'mobx'; import { NekotonConnector } from '../core'; import { ConnectionType, TvmProviderEvent, TvmWalletRdnsList } from '../types'; // eslint-disable-next-line max-len export const venomRpcFallback = (opts) => async (client) => new Promise((resolve, reject) => { if (client) { resolve(client); } else { const fallbackAttempts = opts?.fallbackAttempts ?? 5; let attempts = 0; const tryToResolve = debounce(() => { if (attempts >= fallbackAttempts) { reject(new Error(`Max attempts (${fallbackAttempts}) is reached.`)); return; } if (isBrowser() && window.__venom) { debug('Venom Wallet provider was found with fallback', window.__venom); resolve(window.__venom); return; } attempts += 1; tryToResolve(); }, 1000); tryToResolve(); } }); const rdnsList = [TvmWalletRdnsList.VENOM_WALLET.toString(), TvmWalletRdnsList.VENOM_WALLET_MOBILE.toString()]; export class VenomWallet extends NekotonConnector { params; name = 'VenomWallet'; type = ConnectionType.NEKOTON_WALLET; constructor(params) { super(params); this.params = params; makeObservable(this); if (params?.autoInit ?? true) { this.init().catch(error); } } async init() { let provider; const onAnnouncement = async (event) => { const { name, rdns } = event.detail.info; if (name === 'Venom Wallet' || (rdns && rdnsList.includes(rdns))) { window.removeEventListener(TvmProviderEvent.ANNOUNCE_PROVIDER, onAnnouncement); provider = new ProviderRpcClient({ provider: new StaticProviderAdapter(event.detail.provider), }); debug('Venom Wallet provider event was captured', event); } }; try { this.setState('isInitializing', true); if (isBrowser()) { window.addEventListener(TvmProviderEvent.ANNOUNCE_PROVIDER, onAnnouncement); window.dispatchEvent(new Event(TvmProviderEvent.REQUEST_PROVIDER)); } if (!provider) { if (this.params?.fallbackProviderFactory) { provider = await this.params.fallbackProviderFactory(); } else { const fallback = await this.params?.options?.provider ?? await venomRpcFallback({ fallbackAttempts: this.params?.fallbackAttempts, })(); if (!fallback) { throwException('No provider found'); } provider = new ProviderRpcClient({ provider: fallback, }); } } const hasProvider = await provider.hasProvider(); if (!hasProvider) { throwException('No provider found'); } runInAction(() => { this.provider = provider; if (isBrowser()) { window.removeEventListener(TvmProviderEvent.ANNOUNCE_PROVIDER, onAnnouncement); } }); const state = await timeoutPromise(provider.getProviderState(), 2000); if (!state.permissions.accountInteraction) { throwException('No permissions returned'); } this.setData({ account: state.permissions.accountInteraction, chainId: state.networkId, version: state.version, }); this.setState({ isInitialized: true, isInitializing: false }); await this.runSubscriptions(); } catch (e) { debug('Venom Wallet could not be pre-connected', e); this.setState({ isInitialized: false, isInitializing: false }); await this.stopSubscriptions(); } return this.provider; } } __decorate([ action.bound, __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], VenomWallet.prototype, "init", null);