"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.verifyAmountsAndAcceptSwap = exports.signDelegationTransaction = exports.signSendNFTTransaction = exports.signSendTransaction = exports.expectValidAddressDevice = 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("../e2e/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 near_1 = require("./families/near");
const cosmos_1 = require("./families/cosmos");
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 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: "",
    },
    Binance_Smart_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: "",
    },
};
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 {
        const device = 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 };
            });
        return device;
    }
    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;
async function waitFor(text, maxAttempts = 10) {
    const speculosApiPort = (0, live_env_1.getEnv)("SPECULOS_API_PORT");
    const speculosAddress = process.env.SPECULOS_ADDRESS || "http://127.0.0.1";
    let attempts = 0;
    let textFound = false;
    while (attempts < maxAttempts && !textFound) {
        const response = await axios_1.default.get(`${speculosAddress}:${speculosApiPort}/events?stream=false&currentscreenonly=true`);
        const responseData = response.data;
        const texts = responseData.events.map(event => event.text);
        if (texts?.[0]?.includes(text)) {
            textFound = true;
            return texts;
        }
        attempts++;
        await waitForTimeOut(500);
    }
    return [];
}
exports.waitFor = waitFor;
async function pressBoth() {
    const speculosApiPort = (0, live_env_1.getEnv)("SPECULOS_API_PORT");
    const speculosAddress = process.env.SPECULOS_ADDRESS || "http://127.0.0.1";
    await axios_1.default.post(`${speculosAddress}:${speculosApiPort}/button/both`, {
        action: "press-and-release",
    });
}
exports.pressBoth = pressBoth;
async function pressUntilTextFound(targetText, maxAttempts = 15) {
    const speculosApiPort = (0, live_env_1.getEnv)("SPECULOS_API_PORT");
    for (let attempts = 0; attempts < maxAttempts; attempts++) {
        const texts = await fetchCurrentScreenTexts(speculosApiPort);
        if (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 = process.env.SPECULOS_ADDRESS || "http://127.0.0.1";
    const response = await 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 = process.env.SPECULOS_ADDRESS || "http://127.0.0.1";
    const response = await 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 = process.env.SPECULOS_ADDRESS || "http://127.0.0.1";
    await 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 = process.env.SPECULOS_ADDRESS || "http://127.0.0.1";
    const speculosApiPort = port ?? (0, live_env_1.getEnv)("SPECULOS_API_PORT");
    try {
        const response = await 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_WITH);
    await pressUntilTextFound(DeviceLabels_1.DeviceLabels.MAKE_SURE_TO_USE);
    await pressUntilTextFound(DeviceLabels_1.DeviceLabels.CONNECT_WITH);
    await pressBoth();
    await waitFor(DeviceLabels_1.DeviceLabels.REMOVE_PHONE_OR_COMPUTER);
    await pressUntilTextFound(DeviceLabels_1.DeviceLabels.AFTER_REMOVING);
    await pressUntilTextFound(DeviceLabels_1.DeviceLabels.REMOVE_PHONE_OR_COMPUTER);
    await pressBoth();
    await waitFor(DeviceLabels_1.DeviceLabels.TURN_ON_SYNC);
    await pressUntilTextFound(DeviceLabels_1.DeviceLabels.YOUR_CRYPTO_ACCOUNTS);
    await pressUntilTextFound(DeviceLabels_1.DeviceLabels.TURN_ON_SYNC);
    await pressBoth();
}
exports.removeMemberLedgerSync = removeMemberLedgerSync;
async function activateLedgerSync() {
    await waitFor(DeviceLabels_1.DeviceLabels.CONNECT_WITH);
    await pressUntilTextFound(DeviceLabels_1.DeviceLabels.MAKE_SURE_TO_USE);
    await pressUntilTextFound(DeviceLabels_1.DeviceLabels.CONNECT_WITH);
    await pressBoth();
    await waitFor(DeviceLabels_1.DeviceLabels.TURN_ON_SYNC);
    await pressUntilTextFound(DeviceLabels_1.DeviceLabels.YOUR_CRYPTO_ACCOUNTS);
    await pressUntilTextFound(DeviceLabels_1.DeviceLabels.TURN_ON_SYNC);
    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 expectValidAddressDevice(account, addressDisplayed) {
    let deviceLabels;
    switch (account.currency) {
        case Currency_1.Currency.SOL:
            deviceLabels = [DeviceLabels_1.DeviceLabels.PUBKEY, DeviceLabels_1.DeviceLabels.APPROVE, DeviceLabels_1.DeviceLabels.REJECT];
            break;
        case Currency_1.Currency.DOT:
        case Currency_1.Currency.ATOM:
            deviceLabels = [DeviceLabels_1.DeviceLabels.ADDRESS, DeviceLabels_1.DeviceLabels.CAPS_APPROVE, DeviceLabels_1.DeviceLabels.CAPS_REJECT];
            break;
        case Currency_1.Currency.BTC:
            deviceLabels = [DeviceLabels_1.DeviceLabels.ADDRESS, DeviceLabels_1.DeviceLabels.CONFIRM, DeviceLabels_1.DeviceLabels.CANCEL];
            break;
        default:
            deviceLabels = [DeviceLabels_1.DeviceLabels.ADDRESS, DeviceLabels_1.DeviceLabels.APPROVE, DeviceLabels_1.DeviceLabels.REJECT];
            break;
    }
    await waitFor(deviceLabels[0]);
    const events = await pressUntilTextFound(deviceLabels[1]);
    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.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;
        default:
            throw new Error(`Unsupported currency: ${currencyName.ticker}`);
    }
}
exports.signSendTransaction = signSendTransaction;
async function signSendNFTTransaction(tx) {
    const currencyName = tx.accountToDebit.currency;
    switch (currencyName) {
        case Currency_1.Currency.ETH:
            await (0, evm_1.sendEvmNFT)(tx);
            break;
        default:
            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)();
            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:
        case Account_1.Account.OSMO_1.currency.name:
            await (0, cosmos_1.delegateCosmos)(delegatingAccount);
            break;
        case Account_1.Account.MULTIVERS_X_1.currency.name:
            await (0, multiversX_1.delegateMultiversX)();
            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)();
            break;
        case Account_1.Account.CELO_1.currency.name:
            await (0, celo_1.delegateCelo)(delegatingAccount);
            break;
        default:
            throw new Error(`Unsupported currency: ${currencyName}`);
    }
}
exports.signDelegationTransaction = signDelegationTransaction;
async function verifyAmountsAndAcceptSwap(swap, amount) {
    const events = await pressUntilTextFound(DeviceLabels_1.DeviceLabels.ACCEPT);
    await verifySwapData(swap, events, amount);
    await pressBoth();
}
exports.verifyAmountsAndAcceptSwap = verifyAmountsAndAcceptSwap;
async function verifyAmountsAndRejectSwap(swap, amount) {
    const events = await pressUntilTextFound(DeviceLabels_1.DeviceLabels.REJECT);
    await verifySwapData(swap, events, amount);
    await pressBoth();
}
exports.verifyAmountsAndRejectSwap = verifyAmountsAndRejectSwap;
async function verifySwapData(swap, events, amount) {
    const sendAmountScreen = containsSubstringInEvent(amount, events);
    (0, expect_1.default)(sendAmountScreen).toBeTruthy();
    verifySwapGetAmountScreen(swap, events);
    verifySwapFeesAmountScreen(swap, events);
}
function verifySwapGetAmountScreen(swap, events) {
    const parsedAmountToReceive = extractNumberFromString(swap.amountToReceive);
    swap.amountToReceive =
        parsedAmountToReceive.length < 19
            ? parsedAmountToReceive
            : parsedAmountToReceive.substring(0, 18);
    const receivedGetAmount = containsSubstringInEvent(`${swap.amountToReceive}`, events);
    (0, expect_1.default)(receivedGetAmount).toBeTruthy();
}
function verifySwapFeesAmountScreen(swap, events) {
    const parsedFeesAmount = extractNumberFromString(swap.feesAmount);
    swap.feesAmount =
        parsedFeesAmount.length < 19 ? parsedFeesAmount : parsedFeesAmount.substring(0, 18);
    const receivedFeesAmount = containsSubstringInEvent(swap.feesAmount, events);
    (0, expect_1.default)(receivedFeesAmount).toBeTruthy();
}
const extractNumberFromString = (input) => {
    const match = input?.match(/[\d.]+/);
    return match ? match[0] : "";
};
//# sourceMappingURL=speculos.js.map