@trezor/connect
Version:
High-level javascript interface for Trezor hardware wallet.
182 lines • 6.35 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.eventEmitter = void 0;
const tslib_1 = require("tslib");
const events_1 = tslib_1.__importDefault(require("events"));
const utils_1 = require("@trezor/utils");
const constants_1 = require("./constants");
const core_1 = require("./core");
const connectSettings_1 = require("./data/connectSettings");
const events_2 = require("./events");
const factory_1 = require("./factory");
const debug_1 = require("./utils/debug");
exports.eventEmitter = new events_1.default();
const _log = (0, debug_1.initLog)('@trezor/connect');
let _settings = (0, connectSettings_1.parseConnectSettings)();
const coreManager = (0, core_1.initCoreState)();
const messagePromises = (0, utils_1.createDeferredManager)({ initialId: 1 });
const manifest = (data) => {
_settings = (0, connectSettings_1.parseConnectSettings)({
..._settings,
manifest: data,
});
};
const dispose = () => {
exports.eventEmitter.removeAllListeners();
_settings = (0, connectSettings_1.parseConnectSettings)();
coreManager.dispose();
};
const onCoreEvent = (message) => {
const { event, type, payload } = message;
if (type === events_2.UI.REQUEST_UI_WINDOW) {
coreManager.get()?.handleMessage({ type: events_2.POPUP.HANDSHAKE });
return;
}
if (type === events_2.POPUP.CANCEL_POPUP_REQUEST)
return;
_log.debug('handleMessage', message.type);
switch (event) {
case events_2.RESPONSE_EVENT: {
const { id = 0, success, device } = message;
const resolved = messagePromises.resolve(id, { id, success, payload, device });
if (!resolved)
_log.warn(`Unknown message id ${id}`);
break;
}
case events_2.DEVICE_EVENT:
exports.eventEmitter.emit(event, message);
exports.eventEmitter.emit(type, payload);
break;
case events_2.TRANSPORT_EVENT:
exports.eventEmitter.emit(event, message);
exports.eventEmitter.emit(type, payload);
break;
case events_2.BLOCKCHAIN_EVENT:
exports.eventEmitter.emit(event, message);
exports.eventEmitter.emit(type, payload);
break;
case events_2.UI_EVENT:
exports.eventEmitter.emit(event, message);
exports.eventEmitter.emit(type, payload);
break;
default:
_log.warn('Undefined message', event, message);
}
};
const initSettings = (settings = {}) => {
_settings = (0, connectSettings_1.parseConnectSettings)({ ..._settings, ...settings, popup: false });
if (!_settings.manifest) {
throw constants_1.ERRORS.TypedError('Init_ManifestMissing');
}
if (!_settings.transports?.length) {
_settings.transports = ['BridgeTransport'];
}
};
const init = async (settings = {}) => {
if (coreManager.get() || coreManager.getPending()) {
throw constants_1.ERRORS.TypedError('Init_AlreadyInitialized');
}
initSettings(settings);
if (!_settings.lazyLoad) {
await coreManager.getOrInit(_settings, onCoreEvent);
}
};
const initCore = () => {
initSettings({ lazyLoad: false });
return coreManager.getOrInit(_settings, onCoreEvent);
};
const call = async (params) => {
let core;
try {
core = coreManager.get() ?? (await coreManager.getPending()) ?? (await initCore());
}
catch (error) {
return (0, events_2.createErrorMessage)(error);
}
try {
const { promiseId, promise } = messagePromises.create();
core.handleMessage({
type: events_2.IFRAME.CALL,
payload: params,
id: promiseId,
});
const response = await promise;
return response ?? (0, events_2.createErrorMessage)(constants_1.ERRORS.TypedError('Method_NoResponse'));
}
catch (error) {
_log.error('call', error);
return (0, events_2.createErrorMessage)(error);
}
};
const setTransports = (payload) => {
const core = coreManager.get();
if (!core) {
throw constants_1.ERRORS.TypedError('Init_NotInitialized');
}
core.handleMessage({ type: events_2.TRANSPORT.SET_TRANSPORTS, payload });
};
const uiResponse = (response) => {
const core = coreManager.get();
if (!core) {
throw constants_1.ERRORS.TypedError('Init_NotInitialized');
}
core.handleMessage(response);
};
const requestLogin = async (params) => {
if (typeof params.callback === 'function') {
const { callback } = params;
const core = coreManager.get();
const loginChallengeListener = async (event) => {
const { data } = event;
if (data && data.type === events_2.UI.LOGIN_CHALLENGE_REQUEST) {
try {
const payload = await callback();
core?.handleMessage({
type: events_2.UI.LOGIN_CHALLENGE_RESPONSE,
payload,
});
}
catch (error) {
core?.handleMessage({
type: events_2.UI.LOGIN_CHALLENGE_RESPONSE,
payload: error.message,
});
}
}
};
core?.on(events_2.CORE_EVENT, loginChallengeListener);
const response = await call({
method: 'requestLogin',
...params,
asyncChallenge: true,
callback: null,
});
core?.removeListener(events_2.CORE_EVENT, loginChallengeListener);
return response;
}
return call({ method: 'requestLogin', ...params });
};
const cancel = (error) => {
const core = coreManager.get();
if (!core) {
throw constants_1.ERRORS.TypedError('Runtime', 'postMessage: _core not found');
}
core.handleMessage({
type: events_2.POPUP.CLOSED,
payload: error ? { error } : null,
});
};
const TrezorConnect = (0, factory_1.factory)({
eventEmitter: exports.eventEmitter,
manifest,
init,
call,
setTransports,
requestLogin,
uiResponse,
cancel,
dispose,
}, {});
exports.default = TrezorConnect;
tslib_1.__exportStar(require("./exports"), exports);
//# sourceMappingURL=index.js.map