UNPKG

@trezor/connect

Version:

High-level javascript interface for Trezor hardware wallet.

236 lines (235 loc) 6.95 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 } : {}) }); } onBackendDisconnected(pendingSubscriptions = false) { this.postMessage((0, events_1.createBlockchainMessage)(events_1.BLOCKCHAIN.ERROR, { coin: this.coinInfo, identity: this.identity, error: constants_1.ERRORS.ERROR_CODES.Backend_Disconnected, code: 'Backend_Disconnected' })); 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', () => { const pendingSubscriptions = this.link.listenerCount('block') || this.link.listenerCount('notification') || this.link.listenerCount('fiatRates'); this.link.dispose(); this.onBackendDisconnected(!!pendingSubscriptions); }); 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) { const data = typeof tx === 'string' ? { hex: tx } : tx; return this.link.pushTransaction(data); } disconnect() { this.link.removeAllListeners(); this.link.disconnect().then(() => this.link.dispose()); this.onBackendDisconnected(); } } exports.Blockchain = Blockchain; //# sourceMappingURL=Blockchain.js.map