UNPKG

@trezor/transport

Version:

Low level library facilitating protocol buffers based communication with Trezor devices

71 lines 3.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.sendThpMessage = void 0; const protocol_1 = require("@trezor/protocol"); const utils_1 = require("@trezor/utils"); const readWithExpectedHeaders_1 = require("../utils/readWithExpectedHeaders"); const result_1 = require("../utils/result"); const send_1 = require("../utils/send"); const ATTEMPTS_LIMIT = 10; const THP_ACK_DEADLINE = 3000; const sendThpMessage = async ({ thpState, skipAck, chunks, apiWrite, apiRead, signal, logger, }) => { if (!thpState) { return (0, result_1.error)({ error: 'ThpStateMissing' }); } const expectedResponses = protocol_1.thp.getExpectedResponses(chunks[0]); const isAckExpected = protocol_1.thp.isAckExpected(chunks[0]); if (skipAck || !isAckExpected || expectedResponses.length === 0) { const sendResult = await (0, send_1.sendChunks)(chunks, apiWrite); if (!sendResult.success) { return sendResult; } thpState.setExpectedResponses(expectedResponses); return sendResult; } thpState.setExpectedResponses([0x20]); let attempt = 0; const apiReadWithExpectedHeaders = (0, readWithExpectedHeaders_1.readWithExpectedHeaders)(apiRead, { signal }); try { const result = await (0, utils_1.scheduleAction)(async (attemptSignal) => { logger?.debug(`sendThpMessage attempt ${attempt} start`); const sendResult = await (0, send_1.sendChunks)(chunks, apiWrite); logger?.debug(`sendThpMessage success: ${sendResult.success}`); if (!sendResult.success) { return sendResult; } logger?.debug(`sendThpMessage read ThpAck`); return (0, utils_1.scheduleAction)(() => apiReadWithExpectedHeaders(protocol_1.thp.getExpectedHeaders(thpState)), { signal: attemptSignal, deadline: Date.now() + THP_ACK_DEADLINE, }); }, { signal, attempts: ATTEMPTS_LIMIT, attemptFailureHandler: error => { if (error.message !== 'Aborted by deadline') { logger?.error(`sendThpMessage error ${error.message}`); return error; } attempt++; logger?.debug(`sendThpMessage retransmission ${attempt} start`); }, }); if (!result.success) { return result; } const decodedResult = protocol_1.thp.decodeSendAck(protocol_1.v2.decode(result.payload)); if (decodedResult.type === 'ThpError') { const { code, message } = decodedResult.message; return (0, result_1.error)({ error: code, message }); } logger?.debug('sendThpMessage done'); thpState.setExpectedResponses(expectedResponses); return (0, result_1.success)(undefined); } catch (err) { logger?.error(`sendThpMessage error ${err.message}`); return (0, result_1.error)({ error: err.code, message: err.message }); } }; exports.sendThpMessage = sendThpMessage; //# sourceMappingURL=send.js.map