@trezor/connect
Version:
High-level javascript interface for Trezor hardware wallet.
125 lines • 4.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BackendManager = void 0;
const constants_1 = require("../constants");
const Blockchain_1 = require("./Blockchain");
const DataManager_1 = require("../data/DataManager");
const events_1 = require("../events");
const DEFAULT_IDENTITY = 'default';
class BackendManager {
instances = {};
reconnect = {};
custom = {};
preferred = {};
get(shortcut, identity = DEFAULT_IDENTITY) {
return this.instances[`${shortcut}/${identity}`] ?? null;
}
async getOrConnect({ coinInfo, postMessage, identity }) {
const coinIdentity = `${coinInfo.shortcut}/${identity ?? DEFAULT_IDENTITY}`;
let backend = this.instances[coinIdentity];
if (!backend) {
backend = new Blockchain_1.Blockchain({
coinInfo: this.patchCoinInfo(coinInfo),
identity,
debug: DataManager_1.DataManager.getSettings('debug'),
proxy: DataManager_1.DataManager.getSettings('proxy'),
postMessage,
onDisconnected: pendingSubscriptions => {
const reconnectAttempts = pendingSubscriptions ? 0 : undefined;
this.onDisconnect({ coinInfo, postMessage, identity }, reconnectAttempts);
},
});
this.setInstance(coinIdentity, backend);
}
const reconnect = this.clearReconnect(coinIdentity);
try {
const info = await backend.init();
this.setPreferred(coinInfo.shortcut, info.url);
return backend;
}
catch (error) {
this.onDisconnect({ coinInfo, postMessage, identity }, reconnect?.attempts);
throw error;
}
}
dispose() {
Object.keys(this.reconnect)
.filter(this.getReconnectFilter())
.forEach(this.clearReconnect, this);
Object.values(this.instances).forEach(i => i.disconnect());
}
reconnectAll(coin) {
const backends = Object.values(this.instances).filter(backend => !coin || coin.shortcut === backend.coinInfo.shortcut);
backends.forEach(i => i.disconnect());
return Promise.all(backends.map(this.getOrConnect, this));
}
isSupported(coinInfo) {
const info = this.custom[coinInfo.shortcut] || coinInfo.blockchainLink;
if (!info) {
throw constants_1.ERRORS.TypedError('Backend_NotSupported');
}
}
setCustom(shortcut, blockchainLink) {
this.setPreferred(shortcut, undefined);
if (blockchainLink) {
this.custom[shortcut] = blockchainLink;
}
else {
delete this.custom[shortcut];
}
}
setInstance(coinIdentity, instance) {
if (!instance)
delete this.instances[coinIdentity];
else
this.instances[coinIdentity] = instance;
}
setPreferred(shortcut, url) {
if (!url)
delete this.preferred[shortcut];
else
this.preferred[shortcut] = url;
}
onDisconnect({ coinInfo, postMessage, identity }, reconnectAttempt) {
const coinIdentity = `${coinInfo.shortcut}/${identity ?? DEFAULT_IDENTITY}`;
this.setInstance(coinIdentity, undefined);
if (reconnectAttempt === undefined || reconnectAttempt === 4) {
this.setPreferred(coinInfo.shortcut, undefined);
}
if (reconnectAttempt === undefined) {
return;
}
const timeout = Math.min(2500 * reconnectAttempt, 20000);
const time = Date.now() + timeout;
const handle = setTimeout(() => {
this.getOrConnect({ coinInfo, postMessage, identity }).catch(() => { });
}, timeout);
clearTimeout(this.reconnect[coinIdentity]?.handle);
this.reconnect[coinIdentity] = { attempts: reconnectAttempt + 1, handle };
postMessage((0, events_1.createBlockchainMessage)(events_1.BLOCKCHAIN.RECONNECTING, { coin: coinInfo, identity, time }));
}
clearReconnect(coinIdentity) {
const reconnect = this.reconnect[coinIdentity];
clearTimeout(reconnect?.handle);
delete this.reconnect[coinIdentity];
return reconnect;
}
patchCoinInfo(coinInfo) {
const custom = this.custom[coinInfo.shortcut];
const preferred = this.preferred[coinInfo.shortcut];
const url = preferred ? [preferred] : (custom?.url ?? coinInfo.blockchainLink?.url);
return {
...coinInfo,
blockchainLink: {
...coinInfo.blockchainLink,
...custom,
url,
},
};
}
getReconnectFilter(coinInfo) {
return (key) => !coinInfo || key.startsWith(`${coinInfo.shortcut}/`);
}
}
exports.BackendManager = BackendManager;
//# sourceMappingURL=BackendManager.js.map