UNPKG

@ledgerhq/live-common

Version:
717 lines • 28 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.verifyAmountsAndRejectSwap = exports.verifyAmountsAndAcceptSwapForDifferentSeed = exports.verifyAmountsAndAcceptSwap = exports.getDelegateEvents = exports.signDelegationTransaction = exports.signSendNFTTransaction = exports.signSendTransaction = exports.expectValidAddressDevice = exports.getDeviceLabels = exports.providePublicKey = exports.goToSettings = exports.activateContractData = exports.activateExpertMode = exports.activateLedgerSync = exports.removeMemberLedgerSync = exports.waitForTimeOut = exports.takeScreenshot = exports.containsSubstringInEvent = exports.pressRightButton = exports.pressUntilTextFound = exports.pressBoth = exports.waitFor = exports.stopSpeculos = exports.startSpeculos = exports.specs = exports.getSpeculosModel = exports.setExchangeDependencies = void 0; const invariant_1 = __importDefault(require("invariant")); const logs_1 = require("@ledgerhq/logs"); const speculos_1 = require("../load/speculos"); const speculosCI_1 = require("./speculosCI"); const devices_1 = require("@ledgerhq/devices"); const axios_1 = __importDefault(require("axios")); const live_env_1 = require("@ledgerhq/live-env"); const currencies_1 = require("../currencies"); const DeviceLabels_1 = require("./enum/DeviceLabels"); const Account_1 = require("./enum/Account"); const Device_1 = require("./enum/Device"); const Currency_1 = require("./enum/Currency"); const expect_1 = __importDefault(require("expect")); const bitcoin_1 = require("./families/bitcoin"); const evm_1 = require("./families/evm"); const polkadot_1 = require("./families/polkadot"); const algorand_1 = require("./families/algorand"); const tron_1 = require("./families/tron"); const stellar_1 = require("./families/stellar"); const cardano_1 = require("./families/cardano"); const xrp_1 = require("./families/xrp"); const aptos_1 = require("./families/aptos"); const hedera_1 = require("./families/hedera"); const near_1 = require("./families/near"); const cosmos_1 = require("./families/cosmos"); const kaspa_1 = require("./families/kaspa"); const solana_1 = require("./families/solana"); const tezos_1 = require("./families/tezos"); const celo_1 = require("./families/celo"); const multiversX_1 = require("./families/multiversX"); const osmosis_1 = require("./families/osmosis"); const deviceLabelsData_1 = require("./data/deviceLabelsData"); const sui_1 = require("./families/sui"); const isSpeculosRemote = process.env.REMOTE_SPECULOS === "true"; function setExchangeDependencies(dependencies) { const map = new Map(); for (const dep of dependencies) { if (!map.has(dep.name)) { map.set(dep.name, dep); } } exports.specs["Exchange"].dependencies = Array.from(map.values()); } exports.setExchangeDependencies = setExchangeDependencies; function getSpeculosModel() { const speculosDevice = process.env.SPECULOS_DEVICE; switch (speculosDevice) { case Device_1.Device.LNS: return devices_1.DeviceModelId.nanoS; case Device_1.Device.LNX: return devices_1.DeviceModelId.nanoX; case Device_1.Device.LNSP: default: return devices_1.DeviceModelId.nanoSP; } } exports.getSpeculosModel = getSpeculosModel; exports.specs = { Bitcoin: { currency: (0, currencies_1.getCryptoCurrencyById)("bitcoin"), appQuery: { model: getSpeculosModel(), appName: "Bitcoin", }, dependency: "", }, Aptos: { currency: (0, currencies_1.getCryptoCurrencyById)("aptos"), appQuery: { model: getSpeculosModel(), appName: "Aptos", }, dependency: "", }, Exchange: { appQuery: { model: getSpeculosModel(), appName: "Exchange", }, dependencies: [], }, LedgerSync: { appQuery: { model: getSpeculosModel(), appName: "Ledger Sync", }, dependency: "", }, Dogecoin: { currency: (0, currencies_1.getCryptoCurrencyById)("dogecoin"), appQuery: { model: getSpeculosModel(), appName: "Dogecoin", }, dependency: "", }, Ethereum: { currency: (0, currencies_1.getCryptoCurrencyById)("ethereum"), appQuery: { model: getSpeculosModel(), appName: "Ethereum", }, dependency: "", }, Ethereum_Holesky: { currency: (0, currencies_1.getCryptoCurrencyById)("ethereum_holesky"), appQuery: { model: getSpeculosModel(), appName: "Ethereum", }, dependency: "", }, Ethereum_Sepolia: { currency: (0, currencies_1.getCryptoCurrencyById)("ethereum_sepolia"), appQuery: { model: getSpeculosModel(), appName: "Ethereum", }, dependency: "", }, Ethereum_Classic: { currency: (0, currencies_1.getCryptoCurrencyById)("ethereum_classic"), appQuery: { model: getSpeculosModel(), appName: "Ethereum Classic", }, dependency: "Ethereum", }, Bitcoin_Testnet: { currency: (0, currencies_1.getCryptoCurrencyById)("bitcoin_testnet"), appQuery: { model: getSpeculosModel(), appName: "Bitcoin Test", }, dependency: "", }, Solana: { currency: (0, currencies_1.getCryptoCurrencyById)("solana"), appQuery: { model: getSpeculosModel(), appName: "Solana", }, dependency: "", }, Cardano: { currency: (0, currencies_1.getCryptoCurrencyById)("cardano"), appQuery: { model: getSpeculosModel(), appName: "CardanoADA", }, dependency: "", }, Polkadot: { currency: (0, currencies_1.getCryptoCurrencyById)("polkadot"), appQuery: { model: getSpeculosModel(), appName: "Polkadot", }, dependency: "", }, Tron: { currency: (0, currencies_1.getCryptoCurrencyById)("tron"), appQuery: { model: getSpeculosModel(), appName: "Tron", }, dependency: "", }, XRP: { currency: (0, currencies_1.getCryptoCurrencyById)("ripple"), appQuery: { model: getSpeculosModel(), appName: "XRP", }, dependency: "", }, Stellar: { currency: (0, currencies_1.getCryptoCurrencyById)("stellar"), appQuery: { model: getSpeculosModel(), appName: "Stellar", }, dependency: "", }, Bitcoin_Cash: { currency: (0, currencies_1.getCryptoCurrencyById)("bitcoin_cash"), appQuery: { model: getSpeculosModel(), appName: "Bitcoin Cash", }, dependency: "", }, Algorand: { currency: (0, currencies_1.getCryptoCurrencyById)("algorand"), appQuery: { model: getSpeculosModel(), appName: "Algorand", }, dependency: "", }, Cosmos: { currency: (0, currencies_1.getCryptoCurrencyById)("cosmos"), appQuery: { model: getSpeculosModel(), appName: "Cosmos", }, dependency: "", }, Tezos: { currency: (0, currencies_1.getCryptoCurrencyById)("tezos"), appQuery: { model: getSpeculosModel(), appName: "TezosWallet", }, dependency: "", }, Polygon: { currency: (0, currencies_1.getCryptoCurrencyById)("polygon"), appQuery: { model: getSpeculosModel(), appName: "Ethereum", }, dependency: "", }, BNB_Chain: { currency: (0, currencies_1.getCryptoCurrencyById)("bsc"), appQuery: { model: getSpeculosModel(), appName: "Ethereum", }, dependency: "", }, Ton: { currency: (0, currencies_1.getCryptoCurrencyById)("ton"), appQuery: { model: getSpeculosModel(), appName: "TON", }, dependency: "", }, Near: { currency: (0, currencies_1.getCryptoCurrencyById)("near"), appQuery: { model: getSpeculosModel(), appName: "NEAR", }, dependency: "", }, Multivers_X: { currency: (0, currencies_1.getCryptoCurrencyById)("elrond"), appQuery: { model: getSpeculosModel(), appName: "MultiversX", }, dependency: "", }, Osmosis: { currency: (0, currencies_1.getCryptoCurrencyById)("osmo"), appQuery: { model: getSpeculosModel(), appName: "Cosmos", }, dependency: "", }, Injective: { currency: (0, currencies_1.getCryptoCurrencyById)("injective"), appQuery: { model: getSpeculosModel(), appName: "Cosmos", }, dependency: "", }, Celo: { currency: (0, currencies_1.getCryptoCurrencyById)("celo"), appQuery: { model: getSpeculosModel(), appName: "Celo", }, dependency: "", }, Litecoin: { currency: (0, currencies_1.getCryptoCurrencyById)("litecoin"), appQuery: { model: getSpeculosModel(), appName: "Litecoin", }, dependency: "", }, Kaspa: { currency: (0, currencies_1.getCryptoCurrencyById)("kaspa"), appQuery: { model: getSpeculosModel(), appName: "Kaspa", }, dependency: "", }, Hedera: { currency: (0, currencies_1.getCryptoCurrencyById)("hedera"), appQuery: { model: getSpeculosModel(), appName: "Hedera", }, dependency: "", }, Sui: { currency: (0, currencies_1.getCryptoCurrencyById)("sui"), appQuery: { model: getSpeculosModel(), appName: "Sui", }, dependency: "", }, }; async function startSpeculos(testName, spec) { (0, logs_1.log)("engine", `test ${testName}`); const { SEED, COINAPPS } = process.env; const seed = SEED; (0, invariant_1.default)(seed, "SEED is not set"); const coinapps = COINAPPS; (0, invariant_1.default)(coinapps, "COINAPPS is not set"); let appCandidates; if (!appCandidates) { appCandidates = await (0, speculos_1.listAppCandidates)(coinapps); } const { appQuery, dependency, onSpeculosDeviceCreated } = spec; const appCandidate = (0, speculos_1.findLatestAppCandidate)(appCandidates, appQuery); const { model } = appQuery; const { dependencies } = spec; const newAppQuery = dependencies?.map(dep => { return (0, speculos_1.findLatestAppCandidate)(appCandidates, { model, appName: dep.name, firmware: appCandidate?.firmware, }); }); const appVersionMap = new Map(newAppQuery?.map(app => [app?.appName, app?.appVersion])); dependencies?.forEach(dependency => { dependency.appVersion = appVersionMap.get(dependency.name) || "1.0.0"; }); if (!appCandidate) { console.warn("no app found for " + testName); console.warn(appQuery); console.warn(JSON.stringify(appCandidates, undefined, 2)); } (0, invariant_1.default)(appCandidate, "%s: no app found. Are you sure your COINAPPS is up to date?", testName, coinapps); (0, logs_1.log)("engine", `test ${testName} will use ${appCandidate.appName} ${appCandidate.appVersion} on ${appCandidate.model} ${appCandidate.firmware}`); const deviceParams = { ...appCandidate, appName: spec.currency ? spec.currency.managerAppName : spec.appQuery.appName, seed, dependency, dependencies, coinapps, onSpeculosDeviceCreated, }; try { return isSpeculosRemote ? await (0, speculosCI_1.createSpeculosDeviceCI)(deviceParams) : await (0, speculos_1.createSpeculosDevice)(deviceParams).then(device => { (0, invariant_1.default)(device.ports.apiPort, "[E2E] Speculos apiPort is not defined"); return { id: device.id, port: device.ports.apiPort }; }); } catch (e) { console.error(e); (0, logs_1.log)("engine", `test ${testName} failed with ${String(e)}`); } } exports.startSpeculos = startSpeculos; async function stopSpeculos(deviceId) { if (deviceId) { (0, logs_1.log)("engine", `test ${deviceId} finished`); isSpeculosRemote ? await (0, speculosCI_1.releaseSpeculosDeviceCI)(deviceId) : await (0, speculos_1.releaseSpeculosDevice)(deviceId); } } exports.stopSpeculos = stopSpeculos; function getSpeculosAddress() { const speculosAddress = process.env.SPECULOS_ADDRESS; return speculosAddress || "http://127.0.0.1"; } async function retryAxiosRequest(requestFn, maxRetries = 5, baseDelay = 1000, retryableStatusCodes = [500, 502, 503, 504]) { let lastError; for (let attempt = 0; attempt <= maxRetries; attempt++) { try { return await requestFn(); } catch (error) { lastError = error; const isRetryable = axios_1.default.isAxiosError(error) && error.response && retryableStatusCodes.includes(error.response.status); const isNetworkError = axios_1.default.isAxiosError(error) && !error.response; if ((isRetryable || isNetworkError) && attempt < maxRetries) { const delay = baseDelay * (attempt + 1); console.warn(`Axios request failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${delay}ms...`, { status: axios_1.default.isAxiosError(error) ? error.response?.status : "network error", message: error.message, }); await new Promise(resolve => setTimeout(resolve, delay)); continue; } throw lastError; } } throw lastError; } async function waitFor(text, maxAttempts = 60) { const port = (0, live_env_1.getEnv)("SPECULOS_API_PORT"); let texts = ""; for (let attempt = 0; attempt < maxAttempts; attempt++) { texts = await fetchCurrentScreenTexts(port); if (texts.toLowerCase().includes(text.toLowerCase())) { return texts; } await waitForTimeOut(500); } throw new Error(`Text "${text}" not found on device screen after ${maxAttempts} attempts. Last screen text: "${texts}"`); } exports.waitFor = waitFor; async function pressBoth() { const speculosApiPort = (0, live_env_1.getEnv)("SPECULOS_API_PORT"); const speculosAddress = getSpeculosAddress(); await retryAxiosRequest(() => axios_1.default.post(`${speculosAddress}:${speculosApiPort}/button/both`, { action: "press-and-release", })); } exports.pressBoth = pressBoth; async function pressUntilTextFound(targetText, strictMatch = false) { const maxAttempts = 18; const speculosApiPort = (0, live_env_1.getEnv)("SPECULOS_API_PORT"); for (let attempts = 0; attempts < maxAttempts; attempts++) { const texts = await fetchCurrentScreenTexts(speculosApiPort); if (strictMatch ? texts === targetText : texts.includes(targetText)) { return await fetchAllEvents(speculosApiPort); } await pressRightButton(); await waitForTimeOut(200); } throw new Error(`ElementNotFoundException: Element with text "${targetText}" not found on speculos screen`); } exports.pressUntilTextFound = pressUntilTextFound; async function fetchCurrentScreenTexts(speculosApiPort) { const speculosAddress = getSpeculosAddress(); const response = await retryAxiosRequest(() => axios_1.default.get(`${speculosAddress}:${speculosApiPort}/events?stream=false&currentscreenonly=true`)); return response.data.events.map(event => event.text).join(" "); } async function fetchAllEvents(speculosApiPort) { const speculosAddress = getSpeculosAddress(); const response = await retryAxiosRequest(() => axios_1.default.get(`${speculosAddress}:${speculosApiPort}/events?stream=false&currentscreenonly=false`)); return response.data.events.map(event => event.text); } async function pressRightButton() { const speculosApiPort = (0, live_env_1.getEnv)("SPECULOS_API_PORT"); const speculosAddress = getSpeculosAddress(); await retryAxiosRequest(() => axios_1.default.post(`${speculosAddress}:${speculosApiPort}/button/right`, { action: "press-and-release", })); } exports.pressRightButton = pressRightButton; function containsSubstringInEvent(targetString, events) { const concatenatedEvents = events.join(""); let result = concatenatedEvents.includes(targetString); if (!result) { const regexPattern = targetString.split("").join(".*?"); const regex = new RegExp(regexPattern, "s"); result = regex.test(concatenatedEvents); } return result; } exports.containsSubstringInEvent = containsSubstringInEvent; async function takeScreenshot(port) { const speculosAddress = getSpeculosAddress(); const speculosApiPort = port ?? (0, live_env_1.getEnv)("SPECULOS_API_PORT"); try { const response = await retryAxiosRequest(() => axios_1.default.get(`${speculosAddress}:${speculosApiPort}/screenshot`, { responseType: "arraybuffer", })); return response.data; } catch (error) { console.error("Error downloading speculos screenshot:", error); } } exports.takeScreenshot = takeScreenshot; async function waitForTimeOut(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } exports.waitForTimeOut = waitForTimeOut; async function removeMemberLedgerSync() { await waitFor(DeviceLabels_1.DeviceLabels.CONNECT_TO); await pressUntilTextFound(DeviceLabels_1.DeviceLabels.CONNECT, true); await pressBoth(); await waitFor(DeviceLabels_1.DeviceLabels.REMOVE_FROM_LEDGER_SYNC); await pressUntilTextFound(DeviceLabels_1.DeviceLabels.REMOVE, true); await pressBoth(); await waitFor(DeviceLabels_1.DeviceLabels.TURN_ON_SYNC); await pressUntilTextFound(DeviceLabels_1.DeviceLabels.LEDGER_LIVE_WILL_BE); await pressUntilTextFound(DeviceLabels_1.DeviceLabels.TURN_ON_SYNC2); await pressBoth(); } exports.removeMemberLedgerSync = removeMemberLedgerSync; async function activateLedgerSync() { await waitFor(DeviceLabels_1.DeviceLabels.CONNECT_TO); await pressUntilTextFound(DeviceLabels_1.DeviceLabels.CONNECT, true); await pressBoth(); await waitFor(DeviceLabels_1.DeviceLabels.TURN_ON_SYNC); await pressUntilTextFound(DeviceLabels_1.DeviceLabels.LEDGER_LIVE_WILL_BE); await pressUntilTextFound(DeviceLabels_1.DeviceLabels.TURN_ON_SYNC2); await pressBoth(); } exports.activateLedgerSync = activateLedgerSync; async function activateExpertMode() { await pressUntilTextFound(DeviceLabels_1.DeviceLabels.EXPERT_MODE); await pressBoth(); } exports.activateExpertMode = activateExpertMode; async function activateContractData() { await pressUntilTextFound(DeviceLabels_1.DeviceLabels.SETTINGS); await pressBoth(); await waitFor(DeviceLabels_1.DeviceLabels.CONTRACT_DATA); await pressBoth(); } exports.activateContractData = activateContractData; async function goToSettings() { await pressUntilTextFound(DeviceLabels_1.DeviceLabels.SETTINGS); await pressBoth(); } exports.goToSettings = goToSettings; async function providePublicKey() { await pressRightButton(); } exports.providePublicKey = providePublicKey; function getDeviceLabels(appInfo) { const deviceModel = getSpeculosModel(); const deviceConfig = deviceLabelsData_1.DEVICE_LABELS_CONFIG[deviceModel] ?? deviceLabelsData_1.DEVICE_LABELS_CONFIG.default; if (!deviceConfig) { throw new Error(`No device configuration found for ${deviceModel}`); } const receiveVerifyLabel = deviceConfig.receiveVerify[appInfo.name] ?? deviceConfig.receiveVerify.default; const receiveConfirmLabel = deviceConfig.receiveConfirm[appInfo.name] ?? deviceConfig.receiveConfirm.default; const delegateVerifyLabel = deviceConfig.delegateVerify[appInfo.name] ?? deviceConfig.delegateVerify.default; const delegateConfirmLabel = deviceConfig.delegateConfirm[appInfo.name] ?? deviceConfig.delegateConfirm.default; return { receiveVerifyLabel, receiveConfirmLabel, delegateVerifyLabel, delegateConfirmLabel }; } exports.getDeviceLabels = getDeviceLabels; async function expectValidAddressDevice(account, addressDisplayed) { if (account.currency === Currency_1.Currency.SUI_USDC) { providePublicKey(); } const { receiveVerifyLabel, receiveConfirmLabel } = getDeviceLabels(account.currency.speculosApp); await waitFor(receiveVerifyLabel); const events = await pressUntilTextFound(receiveConfirmLabel); const isAddressCorrect = containsSubstringInEvent(addressDisplayed, events); (0, expect_1.default)(isAddressCorrect).toBeTruthy(); await pressBoth(); } exports.expectValidAddressDevice = expectValidAddressDevice; async function signSendTransaction(tx) { const currencyName = tx.accountToDebit.currency; switch (currencyName) { case Currency_1.Currency.sepETH: case Currency_1.Currency.POL: case Currency_1.Currency.ETH: await (0, evm_1.sendEVM)(tx); break; case Currency_1.Currency.BTC: await (0, bitcoin_1.sendBTC)(tx); break; case Currency_1.Currency.ETH_USDT: await (0, evm_1.sendEVM)(tx); break; case Currency_1.Currency.DOGE: case Currency_1.Currency.BCH: await (0, bitcoin_1.sendBTCBasedCoin)(tx); break; case Currency_1.Currency.DOT: await (0, polkadot_1.sendPolkadot)(tx); break; case Currency_1.Currency.ALGO: await (0, algorand_1.sendAlgorand)(tx); break; case Currency_1.Currency.SOL: case Currency_1.Currency.SOL_GIGA: await (0, solana_1.sendSolana)(tx); break; case Currency_1.Currency.TRX: await (0, tron_1.sendTron)(tx); break; case Currency_1.Currency.XLM: await (0, stellar_1.sendStellar)(tx); break; case Currency_1.Currency.ATOM: await (0, cosmos_1.sendCosmos)(tx); break; case Currency_1.Currency.ADA: await (0, cardano_1.sendCardano)(tx); break; case Currency_1.Currency.XRP: await (0, xrp_1.sendXRP)(tx); break; case Currency_1.Currency.APT: await (0, aptos_1.sendAptos)(); break; case Currency_1.Currency.KAS: await (0, kaspa_1.sendKaspa)(); break; case Currency_1.Currency.HBAR: await (0, hedera_1.sendHedera)(); break; case Currency_1.Currency.SUI: await (0, sui_1.sendSui)(); break; case Currency_1.Currency.SUI_USDC: await (0, sui_1.sendSui)(); break; default: throw new Error(`Unsupported currency: ${currencyName.ticker}`); } } exports.signSendTransaction = signSendTransaction; async function signSendNFTTransaction(tx) { const currencyName = tx.accountToDebit.currency; if (currencyName === Currency_1.Currency.ETH) { await (0, evm_1.sendEvmNFT)(tx); } else { throw new Error(`Unsupported currency: ${currencyName.ticker}`); } } exports.signSendNFTTransaction = signSendNFTTransaction; async function signDelegationTransaction(delegatingAccount) { const currencyName = delegatingAccount.account.currency.name; switch (currencyName) { case Account_1.Account.SOL_1.currency.name: await (0, solana_1.delegateSolana)(delegatingAccount); break; case Account_1.Account.NEAR_1.currency.name: await (0, near_1.delegateNear)(delegatingAccount); break; case Account_1.Account.ATOM_1.currency.name: case Account_1.Account.INJ_1.currency.name: await (0, cosmos_1.delegateCosmos)(delegatingAccount); break; case Account_1.Account.OSMO_1.currency.name: await (0, osmosis_1.delegateOsmosis)(delegatingAccount); break; case Account_1.Account.MULTIVERS_X_1.currency.name: await (0, multiversX_1.delegateMultiversX)(delegatingAccount); break; case Account_1.Account.ADA_1.currency.name: await (0, cardano_1.delegateCardano)(); break; case Account_1.Account.XTZ_1.currency.name: await (0, tezos_1.delegateTezos)(delegatingAccount); break; case Account_1.Account.CELO_1.currency.name: await (0, celo_1.delegateCelo)(delegatingAccount); break; case Account_1.Account.APTOS_1.currency.name: await (0, aptos_1.delegateAptos)(delegatingAccount); break; default: throw new Error(`Unsupported currency: ${currencyName}`); } } exports.signDelegationTransaction = signDelegationTransaction; async function getDelegateEvents(delegatingAccount) { const { delegateVerifyLabel, delegateConfirmLabel } = getDeviceLabels(delegatingAccount.account.currency.speculosApp); await waitFor(delegateVerifyLabel); return await pressUntilTextFound(delegateConfirmLabel); } exports.getDelegateEvents = getDelegateEvents; async function verifyAmountsAndAcceptSwap(swap, amount) { await waitFor(DeviceLabels_1.DeviceLabels.REVIEW_TRANSACTION); const events = getSpeculosModel() === devices_1.DeviceModelId.nanoS ? await pressUntilTextFound(DeviceLabels_1.DeviceLabels.ACCEPT_AND_SEND) : await pressUntilTextFound(DeviceLabels_1.DeviceLabels.SIGN_TRANSACTION); verifySwapData(swap, events, amount); await pressBoth(); } exports.verifyAmountsAndAcceptSwap = verifyAmountsAndAcceptSwap; async function verifyAmountsAndAcceptSwapForDifferentSeed(swap, amount) { await waitFor(DeviceLabels_1.DeviceLabels.REVIEW_TRANSACTION); const events = await pressUntilTextFound(DeviceLabels_1.DeviceLabels.SIGN_TRANSACTION); verifySwapData(swap, events, amount); await pressBoth(); } exports.verifyAmountsAndAcceptSwapForDifferentSeed = verifyAmountsAndAcceptSwapForDifferentSeed; async function verifyAmountsAndRejectSwap(swap, amount) { await waitFor(DeviceLabels_1.DeviceLabels.REVIEW_TRANSACTION); const events = await pressUntilTextFound(DeviceLabels_1.DeviceLabels.REJECT); verifySwapData(swap, events, amount); await pressBoth(); } exports.verifyAmountsAndRejectSwap = verifyAmountsAndRejectSwap; function verifySwapData(swap, events, amount) { const swapPair = `swap ${swap.getAccountToDebit.currency.ticker} to ${swap.getAccountToCredit.currency.ticker}`; if (getSpeculosModel() !== devices_1.DeviceModelId.nanoS) { expectDeviceScreenContains(swapPair, events, "Swap pair not found on the device screen"); } expectDeviceScreenContains(amount, events, `Amount ${amount} not found on the device screen`); } function expectDeviceScreenContains(substring, events, message) { const found = containsSubstringInEvent(substring, events); if (!found) { throw new Error(`${message}. Expected events to contain "${substring}". Got: ${JSON.stringify(events)}`); } } //# sourceMappingURL=speculos.js.map