@broxus/tvm-connect
Version:
Nekoton-compatible wallets connector.
122 lines (121 loc) • 5.31 kB
JavaScript
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);