@trezor/connect
Version:
High-level javascript interface for Trezor hardware wallet.
99 lines (98 loc) • 3.53 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.uploadFirmware = void 0;
const transport_1 = require("@trezor/transport");
const constants_1 = require("../../constants");
const events_1 = require("../../events");
const postConfirmationMessage = (device, updateFlowType) => {
const freshInstall = device.features.firmware_present === false;
if (freshInstall || updateFlowType === 'reboot_and_upgrade') return;
device.emit(events_1.DEVICE.BUTTON, {
device,
payload: {
code: 'ButtonRequest_FirmwareUpdate'
}
});
};
const postProgressMessage = (device, progress, postMessage) => {
postMessage((0, events_1.createUiMessage)(events_1.UI.FIRMWARE_PROGRESS, {
device: device.toMessageObject(),
operation: 'flashing',
progress
}));
};
const FIRMWARE_ERASE_TIMEOUT_MILLISECONDS = 15_000;
const uploadFirmware = async ({
typedCall,
postMessage,
device,
firmwareUploadRequest: {
payload
},
updateFlowType
}) => {
if (device.features.major_version === 1) {
postConfirmationMessage(device, updateFlowType);
const timeoutId = setTimeout(() => {
postMessage((0, events_1.createUiMessage)(events_1.UI.FIRMWARE_PROGRESS_UNEXPECTED_DELAY, {}));
}, FIRMWARE_ERASE_TIMEOUT_MILLISECONDS);
await typedCall('FirmwareErase', 'Success', {});
clearTimeout(timeoutId);
postProgressMessage(device, 0, postMessage);
let i = 0;
const progressTimer = setInterval(() => {
i++;
postProgressMessage(device, Math.min(i * 2, 99), postMessage);
}, 300);
const message = await typedCall('FirmwareUpload', 'Success', {
payload
}).finally(() => {
clearInterval(progressTimer);
});
postProgressMessage(device, 100, postMessage);
return message;
}
if (device.features.major_version === 2) {
postConfirmationMessage(device, updateFlowType);
const length = payload.byteLength;
let progress = 0;
let response = await typedCall('FirmwareErase', ['FirmwareRequest', 'Success'], {
length
});
postMessage((0, events_1.createUiMessage)(events_1.UI.FIRMWARE_PROGRESS, {
device: device.toMessageObject(),
operation: 'start-flashing',
progress
}));
while (response.type !== 'Success') {
const start = response.message.offset;
const end = response.message.offset + response.message.length;
const chunk = payload.slice(start, end);
const progressStart = Math.round(start / length * 100);
const progressEnd = Math.round(end / length * 100);
const progressDiff = progressEnd - progressStart;
device.transport.on(transport_1.TRANSPORT.SEND_MESSAGE_PROGRESS, p => {
const newProgress = progressStart + Math.floor(progressDiff * p);
if (start > 0 && newProgress > progress) {
progress = newProgress;
postProgressMessage(device, progress, postMessage);
}
});
if (start > 0) {
postProgressMessage(device, progressStart, postMessage);
}
response = await typedCall('FirmwareUpload', ['FirmwareRequest', 'Success'], {
payload: chunk
}).finally(() => {
device.transport.removeAllListeners(transport_1.TRANSPORT.SEND_MESSAGE_PROGRESS);
});
}
postProgressMessage(device, 100, postMessage);
return response.message;
}
throw constants_1.ERRORS.TypedError('Runtime', 'uploadFirmware: unknown major_version');
};
exports.uploadFirmware = uploadFirmware;
//# sourceMappingURL=uploadFirmware.js.map