@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
170 lines • 6.5 kB
JavaScript
import expect from "expect";
import { pressUntilTextFound, containsSubstringInEvent, waitFor } from "../speculos";
import { getSpeculosModel, isTouchDevice } from "../speculosAppVersion";
import { pressAndRelease, longPressAndRelease, swipeRight, } from "../deviceInteraction/TouchDeviceSimulator";
import { DeviceLabels } from "../enum/DeviceLabels";
import { DeviceModelId } from "@ledgerhq/types-devices";
import { withDeviceController } from "../deviceInteraction/DeviceController";
function validateTransactionData(tx, events) {
if (!tx.accountToCredit.address) {
throw new Error("Recipient address is not set");
}
const isAddressCorrect = containsSubstringInEvent(tx.accountToCredit.address, events);
expect(isAddressCorrect).toBeTruthy();
const isAmountCorrect = containsSubstringInEvent(tx.amount, events);
expect(isAmountCorrect).toBeTruthy();
}
async function sendCardanoTouchDevices(tx) {
await waitFor(DeviceLabels.REVIEW_TRANSACTION);
const events = await pressUntilTextFound(DeviceLabels.AMOUNT);
validateTransactionData(tx, events);
await pressAndRelease(DeviceLabels.TAP_TO_CONTINUE);
await waitFor(DeviceLabels.FEES);
await pressAndRelease(DeviceLabels.TAP_TO_CONTINUE);
await waitFor(DeviceLabels.SIGN_TRANSACTION);
await longPressAndRelease(DeviceLabels.HOLD_TO_SIGN, 3);
}
export const sendCardanoNanoS = withDeviceController(({ getButtonsController }) => async (_tx) => {
const buttons = getButtonsController();
await waitFor(DeviceLabels.NEW_ORDINARY);
await buttons.right();
await waitFor(DeviceLabels.SEND_TO_ADDRESS);
await buttons.both();
await pressUntilTextFound(DeviceLabels.SEND);
await buttons.both();
await waitFor(DeviceLabels.TRANSACTION_FEE);
await buttons.both();
await waitFor(DeviceLabels.CONFIRM);
await buttons.right();
});
export const sendCardanoButtonDevice = withDeviceController(({ getButtonsController }) => async (tx) => {
const buttons = getButtonsController();
await waitFor(DeviceLabels.NEW_ORDINARY);
await buttons.both();
await pressUntilTextFound(DeviceLabels.SEND_TO_ADDRESS_2);
await buttons.both();
const events = await pressUntilTextFound(DeviceLabels.SEND);
validateTransactionData(tx, events);
await buttons.both();
await waitFor(DeviceLabels.TRANSACTION_FEE);
await buttons.both();
await waitFor(DeviceLabels.CONFIRM);
await buttons.both();
});
export async function sendCardano(tx) {
const speculosModel = getSpeculosModel();
if (isTouchDevice()) {
return sendCardanoTouchDevices(tx);
}
if (speculosModel === DeviceModelId.nanoS) {
return sendCardanoNanoS(tx);
}
return sendCardanoButtonDevice(tx);
}
const TOUCH_DELEGATE_STEPS = [
[],
[],
[],
[],
[],
[],
[],
[],
[],
];
const DELEGATE_STEPS_CONFIG = {
[]: TOUCH_DELEGATE_STEPS,
[]: TOUCH_DELEGATE_STEPS,
[]: TOUCH_DELEGATE_STEPS,
[]: [
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
],
default: [
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
],
};
function getConfirmButtonCoords() {
const speculosModel = getSpeculosModel();
switch (speculosModel) {
case DeviceModelId.stax:
return { x: 152, y: 532 };
case DeviceModelId.apex:
return { x: 114, y: 305 };
case DeviceModelId.europa:
default:
return { x: 186, y: 446 };
}
}
async function delegateTouchDevicesAction(label) {
const CONFIRM_BUTTON_COORDS = getConfirmButtonCoords();
await waitFor(label);
switch (label) {
case DeviceLabels.TAP_TO_CONTINUE:
await pressAndRelease(DeviceLabels.TAP_TO_CONTINUE);
break;
case DeviceLabels.CONFIRM:
await pressAndRelease(DeviceLabels.CONFIRM, CONFIRM_BUTTON_COORDS.x, CONFIRM_BUTTON_COORDS.y);
break;
case DeviceLabels.HOLD_TO_SIGN:
await longPressAndRelease(DeviceLabels.HOLD_TO_SIGN, 3);
break;
default:
await swipeRight();
break;
}
}
export const delegateNanoAction = withDeviceController(({ getButtonsController }) => async (label, action) => {
const buttons = getButtonsController();
await waitFor(label);
if (action === "both") {
await buttons.both();
}
else {
await buttons.right();
}
});
async function executeDelegateStep(label, action) {
try {
if (isTouchDevice()) {
await delegateTouchDevicesAction(label);
}
else {
await delegateNanoAction(label, action);
}
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
console.error(`Error while waiting for "${label}":`, message);
throw error;
}
}
export async function delegateCardano() {
const speculosModel = getSpeculosModel();
const steps = isTouchDevice() && DELEGATE_STEPS_CONFIG[speculosModel]
? DELEGATE_STEPS_CONFIG[speculosModel]
: speculosModel === DeviceModelId.nanoS
? DELEGATE_STEPS_CONFIG[DeviceModelId.nanoS]
: DELEGATE_STEPS_CONFIG.default;
for (const [label, action] of steps) {
await executeDelegateStep(label, action);
}
}
//# sourceMappingURL=cardano.js.map