UNPKG

@trezor/connect

Version:

High-level javascript interface for Trezor hardware wallet.

220 lines 7.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Blockchain = void 0; const tslib_1 = require("tslib"); const blockchain_link_1 = tslib_1.__importDefault(require("@trezor/blockchain-link")); const constants_1 = require("../constants"); const events_1 = require("../events"); const workers_1 = require("../workers/workers"); const getWorker = (type) => { switch (type) { case 'blockbook': return workers_1.BlockbookWorker; case 'ripple': return workers_1.RippleWorker; case 'blockfrost': return workers_1.BlockfrostWorker; case 'electrum': return workers_1.ElectrumWorker; case 'solana': return workers_1.SolanaWorker; case 'stellar': return workers_1.StellarWorker; default: return null; } }; const getNormalizedTrezorShortcut = (shortcut) => { if (shortcut === 'tXRP') { return 'XRP'; } return shortcut; }; class Blockchain { link; serverInfo; identity; coinInfo; postMessage; onDisconnected; initPromise; constructor(options) { this.identity = options.identity; this.coinInfo = options.coinInfo; this.postMessage = options.postMessage; this.onDisconnected = options.onDisconnected; const { blockchainLink } = options.coinInfo; if (!blockchainLink) { throw constants_1.ERRORS.TypedError('Backend_NotSupported'); } const worker = getWorker(blockchainLink.type); if (!worker) { throw constants_1.ERRORS.TypedError('Backend_WorkerMissing', `BlockchainLink worker not found ${blockchainLink.type}`); } const server = blockchainLink.url; this.link = new blockchain_link_1.default({ name: this.coinInfo.shortcut, worker, server, debug: options.debug, proxy: options.proxy, ...(this.coinInfo.type === 'ethereum' ? { throttleBlockEvent: 10 * 1000 } : {}), ...(['ripple', 'stellar'].includes(blockchainLink.type) ? { throttleBlockEvent: 60 * 1000 } : {}), }); } onError(error) { const pendingSubscriptions = this.link.listenerCount('block') || this.link.listenerCount('notification') || this.link.listenerCount('fiatRates'); this.link.dispose(); this.postMessage((0, events_1.createBlockchainMessage)(events_1.BLOCKCHAIN.ERROR, { coin: this.coinInfo, identity: this.identity, error: error.message, code: error.code, })); this.onDisconnected?.(!!pendingSubscriptions); } async initLink() { let info; try { await this.link.connect(); info = await this.link.getInfo(); } catch (error) { throw constants_1.ERRORS.TypedError('Backend_Error', error.message); } this.serverInfo = info; const trezorNetworkShortcut = getNormalizedTrezorShortcut(this.coinInfo.shortcut); const backendNetworkShortcut = this.serverInfo.network; if (backendNetworkShortcut.toLowerCase() !== trezorNetworkShortcut.toLowerCase()) { throw constants_1.ERRORS.TypedError('Backend_Invalid'); } this.link.on('disconnected', () => { this.onError(constants_1.ERRORS.TypedError('Backend_Disconnected')); }); return info; } init() { if (!this.initPromise) { this.initPromise = this.initLink() .then(info => { this.postMessage((0, events_1.createBlockchainMessage)(events_1.BLOCKCHAIN.CONNECT, { coin: this.coinInfo, identity: this.identity, ...info, })); this.initPromise = Promise.resolve(info); return info; }) .catch(error => { this.postMessage((0, events_1.createBlockchainMessage)(events_1.BLOCKCHAIN.ERROR, { coin: this.coinInfo, identity: this.identity, error: error.message, code: error.code, })); this.initPromise = Promise.reject(error); this.link.dispose(); return this.initPromise; }); } return this.initPromise; } getTransactions(txs) { return Promise.all(txs.map(id => this.link.getTransaction(id))); } getTransactionHexes(txids) { return Promise.all(txids.map(id => this.link.getTransactionHex(id))); } getCurrentFiatRates(params) { return this.link.getCurrentFiatRates(params); } getFiatRatesForTimestamps(params) { return this.link.getFiatRatesForTimestamps(params); } getAccountBalanceHistory(params) { return this.link.getAccountBalanceHistory(params); } getNetworkInfo() { return this.link.getInfo(); } getAccountInfo(request) { return this.link.getAccountInfo(request); } getAccountUtxo(descriptor) { return this.link.getAccountUtxo(descriptor); } rpcCall(params) { return this.link.rpcCall(params); } estimateFee(request) { return this.link.estimateFee(request); } subscribeBlocks() { if (this.link.listenerCount('block') === 0) { this.link.on('block', block => { this.postMessage((0, events_1.createBlockchainMessage)(events_1.BLOCKCHAIN.BLOCK, { coin: this.coinInfo, ...block, })); }); } return this.link.subscribe({ type: 'block' }); } subscribeAccounts(accounts) { if (this.link.listenerCount('notification') === 0) { this.link.on('notification', notification => { this.postMessage((0, events_1.createBlockchainMessage)(events_1.BLOCKCHAIN.NOTIFICATION, { coin: this.coinInfo, notification, })); }); } return this.link.subscribe({ type: 'accounts', accounts, }); } subscribeFiatRates(_currency) { if (this.link.listenerCount('fiatRates') === 0) { this.link.on('fiatRates', ({ rates }) => { this.postMessage((0, events_1.createBlockchainMessage)(events_1.BLOCKCHAIN.FIAT_RATES_UPDATE, { coin: this.coinInfo, rates, })); }); } return this.link.subscribe({ type: 'fiatRates', }); } unsubscribeBlocks() { this.link.removeAllListeners('block'); return this.link.unsubscribe({ type: 'block' }); } unsubscribeAccounts(accounts) { return this.link.unsubscribe({ type: 'accounts', accounts }); } unsubscribeFiatRates() { this.link.removeAllListeners('fiatRates'); return this.link.unsubscribe({ type: 'fiatRates' }); } async unsubscribeAll() { this.link.removeAllListeners('notification'); await this.unsubscribeFiatRates(); return this.unsubscribeBlocks(); } pushTransaction(tx) { return this.link.pushTransaction(tx); } disconnect() { this.link.removeAllListeners(); this.link.disconnect(); this.onError(constants_1.ERRORS.TypedError('Backend_Disconnected')); } } exports.Blockchain = Blockchain; //# sourceMappingURL=Blockchain.js.map