UNPKG

@tronweb3/tronwallet-adapter-bybit

Version:

Wallet adapter for Bybit Wallet extension and Bybit Wallet app.

353 lines 17.5 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { Adapter, AdapterState, isInBrowser, WalletReadyState, WalletSignMessageError, WalletNotFoundError, WalletDisconnectedError, WalletConnectionError, WalletSignTransactionError, WalletGetNetworkError, } from '@tronweb3/tronwallet-abstract-adapter'; import { getNetworkInfoByTronWeb } from '@tronweb3/tronwallet-adapter-tronlink'; import { openBybitWallet, supportBybitWallet } from './utils.js'; export const BybitWalletAdapterName = 'Bybit Wallet'; export class BybitWalletAdapter extends Adapter { constructor(config = {}) { super(); this.name = BybitWalletAdapterName; this.url = 'https://bybit.com/web3'; this.icon = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODgiIGhlaWdodD0iODgiIHZpZXdCb3g9IjAgMCA4OCA4OCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgMTguN0MwIDguMzcyMjcgOC4zNzIyOCAwIDE4LjcgMEg2OS4zQzc5LjYyNzcgMCA4OCA4LjM3MjI4IDg4IDE4LjdWNjkuM0M4OCA3OS42Mjc3IDc5LjYyNzcgODggNjkuMyA4OEgxOC43QzguMzcyMjcgODggMCA3OS42Mjc3IDAgNjkuM1YxOC43WiIgZmlsbD0iIzQwNDM0NyIvPgo8cGF0aCBkPSJNNy41NzYxNyAyNi44MDY3QzYuNzg1MTYgMjQuMDc4NyA4LjQ3NzUgMjEuMjUzMSAxMS4yNTU5IDIwLjY2M0w1Ny42MDg3IDEwLjgxNzNDNTkuODA5IDEwLjM1IDYyLjA0NDMgMTEuNDQ0MyA2My4wMjQ3IDEzLjQ2ODlMODMuODQ0MyA1Ni40NjU3TDI1LjE3NzYgODcuNTEwMUw3LjU3NjE3IDI2LjgwNjdaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfMzEyXzE3NTM0KSIvPgo8cGF0aCBkPSJNOC4xODI0MiAzMC4xNjE4QzcuMzUwNDkgMjcuMjgzOCA5LjI3OTI1IDI0LjM0MTMgMTIuMjUwMiAyMy45NTU5TDczLjY4NjUgMTUuOTg4MUM3Ni4yMzkxIDE1LjY1NzEgNzguNjExMSAxNy4zNjE4IDc5LjExMTEgMTkuODg2N0w4OC4wMDAzIDY0Ljc3NzFMMjQuNjg5MiA4Ny4yNjY1TDguMTgyNDIgMzAuMTYxOFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0wIDM0LjIyMjJDMCAyOC44MjIxIDQuMzc3NjYgMjQuNDQ0NSA5Ljc3Nzc4IDI0LjQ0NDVINjguNDQ0NEM3OS4yNDQ3IDI0LjQ0NDUgODggMzMuMTk5OCA4OCA0NFY2OC40NDQ1Qzg4IDc5LjI0NDcgNzkuMjQ0NyA4OCA2OC40NDQ0IDg4SDE5LjU1NTZDOC43NTUzMiA4OCAwIDc5LjI0NDcgMCA2OC40NDQ1VjM0LjIyMjJaIiBmaWxsPSJibGFjayIvPgo8cGF0aCBkPSJNNTguMjIwMSA2MS4xOTU5VjQyLjg3NTVINjEuNzkzN1Y2MS4xOTU5SDU4LjIyMDFaIiBmaWxsPSIjRjdBNjAwIi8+CjxwYXRoIGQ9Ik0xNy40Mzk1IDY2LjY2MzdIOS43Nzc5NVY0OC4zNDM0SDE3LjEzMTNDMjAuNzA0OSA0OC4zNDM0IDIyLjc4NzQgNTAuMzUwNSAyMi43ODc0IDUzLjQ4OTNDMjIuNzg3NCA1NS41MjE1IDIxLjQ1MDQgNTYuODM0NSAyMC41MjU3IDU3LjI3MjFDMjEuNjMxNSA1Ny43ODY5IDIzLjA0NTYgNTguOTQzOCAyMy4wNDU2IDYxLjM4ODVDMjMuMDQ1NiA2NC44MTA4IDIwLjcwNDkgNjYuNjYzNyAxNy40Mzk1IDY2LjY2MzdaTTE2Ljg0ODEgNTEuNTM0M0gxMy4zNTE2VjU1Ljc1NDhIMTYuODQ4MUMxOC4zNjQyIDU1Ljc1NDggMTkuMjEzOCA1NC45MDY0IDE5LjIxMzggNTMuNjQ1NUMxOS4yMTM4IDUyLjM4MjYgMTguMzY2MiA1MS41MzQzIDE2Ljg0ODEgNTEuNTM0M1pNMTcuMDc5MyA1OC45NzA4SDEzLjM1MTZWNjMuNDcyOEgxNy4wNzkzQzE4LjY5OTQgNjMuNDcyOCAxOS40NyA2Mi40NDMyIDE5LjQ3IDYxLjIwOTJDMTkuNDcyIDU5Ljk3MzMgMTguNjk5NCA1OC45NzA4IDE3LjA3OTMgNTguOTcwOFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0zMi44OTI1IDU5LjE1MDFWNjYuNjYzN0gyOS4zNDM5VjU5LjE1MDFMMjMuODQxOSA0OC4zNDM0SDI3LjcyMzhMMzEuMTQzMiA1NS43Mjc4TDM0LjUxMDcgNDguMzQzNEgzOC4zOTI2TDMyLjg5MjUgNTkuMTUwMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik00OC41NjMzIDY2LjY2MzdINDAuOTAxN1Y0OC4zNDM0SDQ4LjI1NTFDNTEuODI4NyA0OC4zNDM0IDUzLjkxMTIgNTAuMzUwNSA1My45MTEyIDUzLjQ4OTNDNTMuOTExMiA1NS41MjE1IDUyLjU3NDIgNTYuODM0NSA1MS42NDk1IDU3LjI3MjFDNTIuNzU1MyA1Ny43ODY5IDU0LjE2OTMgNTguOTQzOCA1NC4xNjkzIDYxLjM4ODVDNTQuMTY3NCA2NC44MTA4IDUxLjgyNjggNjYuNjYzNyA0OC41NjMzIDY2LjY2MzdaTTQ3Ljk3MTkgNTEuNTM0M0g0NC40NzUzVjU1Ljc1NDhINDcuOTcxOUM0OS40ODggNTUuNzU0OCA1MC4zMzc2IDU0LjkwNjQgNTAuMzM3NiA1My42NDU1QzUwLjMzNTcgNTIuMzgyNiA0OS40ODggNTEuNTM0MyA0Ny45NzE5IDUxLjUzNDNaTTQ4LjIwMzEgNTguOTcwOEg0NC40NzUzVjYzLjQ3MjhINDguMjAzMUM0OS44MjMyIDYzLjQ3MjggNTAuNTkzOCA2Mi40NDMyIDUwLjU5MzggNjEuMjA5MkM1MC41OTM4IDU5Ljk3MzQgNDkuODIxMyA1OC45NzA4IDQ4LjIwMzEgNTguOTcwOFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik03My40MzkgNTEuNTM0M1Y2Ni42NjM3SDY5Ljg2NTRWNTEuNTM0M0g2NS4wODM5VjQ4LjM0MzRINzguMjIyNFY1MS41MzQzSDczLjQzOVoiIGZpbGw9IndoaXRlIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfMzEyXzE3NTM0IiB4MT0iNy4zMzMwOCIgeTE9IjI1LjU5NCIgeDI9Ijg0LjYzODEiIHkyPSIyMS43MjE2IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkQ3NDgiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRjdBNjAwIi8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg=='; this._readyState = isInBrowser() ? WalletReadyState.Loading : WalletReadyState.NotFound; this._state = AdapterState.Loading; this.messageHandler = (e) => { var _a, _b, _c; const message = (_a = e.data) === null || _a === void 0 ? void 0 : _a.message; if (!message) { return; } if (message.action === 'accountsChanged') { setTimeout(() => { var _a; const preAddr = this.address || ''; if ((_a = this._wallet) === null || _a === void 0 ? void 0 : _a.ready) { const address = message.data.address; this.setAddress(address); this.setState(AdapterState.Connected); } else { this.setAddress(null); this.setState(AdapterState.Disconnect); } const address = this.address || ''; if (address !== preAddr) { this.emit('accountsChanged', this.address || '', preAddr); } if (!preAddr && this.address) { this.emit('connect', this.address); } else if (preAddr && !this.address) { this.emit('disconnect'); } }, 200); } else if (message.action === 'connect') { const isCurConnected = this.connected; const preAddress = this.address || ''; const address = ((_c = (_b = this._wallet.tronWeb) === null || _b === void 0 ? void 0 : _b.defaultAddress) === null || _c === void 0 ? void 0 : _c.base58) || ''; this.setAddress(address); this.setState(AdapterState.Connected); if (!isCurConnected) { this.emit('connect', address); } else if (address !== preAddress) { this.emit('accountsChanged', this.address || '', preAddress); } } else if (message.action === 'disconnect') { this.setAddress(null); this.setState(AdapterState.Disconnect); this.emit('disconnect'); } }; this._checkPromise = null; this._updateWallet = () => { var _a, _b; let state = this.state; let address = this.address; if (supportBybitWallet()) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this._wallet = window.bybitWallet.tronLink; this._listenEvent(); address = ((_b = (_a = this._wallet.tronWeb) === null || _a === void 0 ? void 0 : _a.defaultAddress) === null || _b === void 0 ? void 0 : _b.base58) || null; state = this._wallet.ready ? AdapterState.Connected : AdapterState.Disconnect; } else { this._wallet = null; address = null; state = AdapterState.NotFound; } this.setAddress(address); this.setState(state); }; const { checkTimeout = 2 * 1000, openUrlWhenWalletNotFound = true, openAppWithDeeplink = true } = config; if (typeof checkTimeout !== 'number') { throw new Error('[BybitWalletAdapter] config.checkTimeout should be a number'); } this.config = { checkTimeout, openAppWithDeeplink, openUrlWhenWalletNotFound, }; this._connecting = false; this._wallet = null; this._address = null; if (!isInBrowser()) { this._readyState = WalletReadyState.NotFound; this.setState(AdapterState.NotFound); return; } if (supportBybitWallet()) { this._readyState = WalletReadyState.Found; this._updateWallet(); } else { this._checkWallet().then(() => { if (this.connected) { this.emit('connect', this.address || ''); } }); } } get address() { return this._address; } get state() { return this._state; } get readyState() { return this._readyState; } get connecting() { return this._connecting; } /** * Get network information used by BybitWallet. * @returns {Network} Current network information. */ network() { return __awaiter(this, void 0, void 0, function* () { try { yield this._checkWallet(); if (this.state !== AdapterState.Connected) throw new WalletDisconnectedError(); const wallet = this._wallet; if (!wallet || !wallet.tronWeb) throw new WalletDisconnectedError(); try { return yield getNetworkInfoByTronWeb(wallet.tronWeb); } catch (e) { throw new WalletGetNetworkError(e === null || e === void 0 ? void 0 : e.message, e); } } catch (e) { this.emit('error', e); throw e; } }); } connect() { return __awaiter(this, void 0, void 0, function* () { var _a; try { this.checkIfOpenBybitWallet(); if (this.connected || this.connecting) return; yield this._checkWallet(); if (this.state === AdapterState.NotFound) { if (this.config.openUrlWhenWalletNotFound !== false && isInBrowser()) { window.open(this.url, '_blank'); } throw new WalletNotFoundError(); } if (!this._wallet) return; this._connecting = true; const wallet = this._wallet; try { const res = yield wallet.request({ method: 'tron_requestAccounts' }); if (!res) { throw new WalletConnectionError('Request connect error.'); } if (res.code === 4000) { throw new WalletConnectionError('The same DApp has already initiated a request to connect to BybitWallet, and the pop-up window has not been closed.'); } if (res.code === 4001) { throw new WalletConnectionError('The user rejected connection.'); } } catch (error) { throw new WalletConnectionError(error === null || error === void 0 ? void 0 : error.message, error); } const address = ((_a = wallet.tronWeb.defaultAddress) === null || _a === void 0 ? void 0 : _a.base58) || ''; this.setAddress(address); this.setState(AdapterState.Connected); this._listenEvent(); this.connected && this.emit('connect', this.address || ''); } catch (error) { this.emit('error', error); throw error; } finally { this._connecting = false; } }); } disconnect() { return __awaiter(this, void 0, void 0, function* () { this._stopListenEvent(); if (this.state !== AdapterState.Connected) { return; } this.setAddress(null); this.setState(AdapterState.Disconnect); this.emit('disconnect'); }); } signTransaction(transaction, privateKey) { return __awaiter(this, void 0, void 0, function* () { try { const wallet = yield this.checkAndGetWallet(); try { return yield wallet.tronWeb.trx.sign(transaction, privateKey); } catch (error) { if (error instanceof Error) { throw new WalletSignTransactionError(error.message, error); } else { throw new WalletSignTransactionError(error, new Error(error)); } } } catch (error) { this.emit('error', error); throw error; } }); } multiSign(transaction, privateKey, permissionId) { return __awaiter(this, void 0, void 0, function* () { try { const wallet = yield this.checkAndGetWallet(); try { return yield wallet.tronWeb.trx.multiSign(transaction, privateKey, permissionId); } catch (error) { if (error instanceof Error) { throw new WalletSignTransactionError(error.message, error); } else { throw new WalletSignTransactionError(error, new Error(error)); } } } catch (error) { this.emit('error', error); throw error; } }); } signMessage(message, privateKey) { return __awaiter(this, void 0, void 0, function* () { try { const wallet = yield this.checkAndGetWallet(); try { return yield wallet.tronWeb.trx.signMessageV2(message, privateKey); } catch (error) { if (error instanceof Error) { throw new WalletSignMessageError(error.message, error); } else { throw new WalletSignMessageError(error, new Error(error)); } } } catch (error) { this.emit('error', error); throw error; } }); } checkAndGetWallet() { return __awaiter(this, void 0, void 0, function* () { this.checkIfOpenBybitWallet(); yield this._checkWallet(); if (this.state !== AdapterState.Connected) throw new WalletDisconnectedError(); const wallet = this._wallet; if (!wallet || !wallet.tronWeb) throw new WalletDisconnectedError(); return wallet; }); } _listenEvent() { this._stopListenEvent(); window.addEventListener('message', this.messageHandler); } _stopListenEvent() { window.removeEventListener('message', this.messageHandler); } checkIfOpenBybitWallet() { if (this.config.openAppWithDeeplink === false) { return; } if (openBybitWallet()) { throw new WalletNotFoundError(); } } /** * check if wallet exists by interval, the promise only resolve when wallet detected or timeout * @returns if BybitWallet exists */ _checkWallet() { if (this.readyState === WalletReadyState.Found) { return Promise.resolve(true); } if (this._checkPromise) { return this._checkPromise; } const interval = 100; const maxTimes = Math.floor(this.config.checkTimeout / interval); let times = 0, timer; this._checkPromise = new Promise((resolve) => { const check = () => { times++; const isSupport = supportBybitWallet(); if (isSupport || times > maxTimes) { timer && clearInterval(timer); this._readyState = isSupport ? WalletReadyState.Found : WalletReadyState.NotFound; this._updateWallet(); this.emit('readyStateChanged', this.readyState); resolve(isSupport); } }; timer = setInterval(check, interval); check(); }); return this._checkPromise; } setAddress(address) { this._address = address; } setState(state) { const preState = this.state; if (state !== preState) { this._state = state; this.emit('stateChanged', state); } } } //# sourceMappingURL=adapter.js.map