"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseSequenceFromLogSui = exports.parseSequenceFromLogAptos = exports.parseSequenceFromLogNear = exports.parseSequenceFromLogAlgorand = exports.parseSequencesFromLogSolana = exports.parseSequenceFromLogSolana = exports.parseSequenceFromLogInjective = exports.parseSequencesFromLogTerra = exports.parseSequenceFromLogXpla = exports.parseSequenceFromLogTerra = exports.parseSequencesFromLogEth = exports.parseSequenceFromLogEth = void 0;
const ethers_1 = require("ethers");
const ethers_contracts_1 = require("../ethers-contracts");
function parseSequenceFromLogEth(receipt, bridgeAddress) {
    // TODO: dangerous!(?)
    const bridgeLog = receipt.logs.filter((l) => {
        return l.address === bridgeAddress;
    })[0];
    const { args: { sequence }, } = ethers_contracts_1.Implementation__factory.createInterface().parseLog(bridgeLog);
    return sequence.toString();
}
exports.parseSequenceFromLogEth = parseSequenceFromLogEth;
function parseSequencesFromLogEth(receipt, bridgeAddress) {
    // TODO: dangerous!(?)
    const bridgeLogs = receipt.logs.filter((l) => {
        return l.address === bridgeAddress;
    });
    return bridgeLogs.map((bridgeLog) => {
        const { args: { sequence }, } = ethers_contracts_1.Implementation__factory.createInterface().parseLog(bridgeLog);
        return sequence.toString();
    });
}
exports.parseSequencesFromLogEth = parseSequencesFromLogEth;
function parseSequenceFromLogTerra(info) {
    // Scan for the Sequence attribute in all the outputs of the transaction.
    // TODO: Make this not horrible.
    let sequence = "";
    const jsonLog = JSON.parse(info.raw_log);
    jsonLog.map((row) => {
        row.events.map((event) => {
            event.attributes.map((attribute) => {
                if (attribute.key === "message.sequence") {
                    sequence = attribute.value;
                }
            });
        });
    });
    return sequence.toString();
}
exports.parseSequenceFromLogTerra = parseSequenceFromLogTerra;
function parseSequenceFromLogXpla(info) {
    // Scan for the Sequence attribute in all the outputs of the transaction.
    // TODO: Make this not horrible.
    let sequence = "";
    const jsonLog = JSON.parse(info.raw_log);
    jsonLog.map((row) => {
        row.events.map((event) => {
            event.attributes.map((attribute) => {
                if (attribute.key === "message.sequence") {
                    sequence = attribute.value;
                }
            });
        });
    });
    return sequence.toString();
}
exports.parseSequenceFromLogXpla = parseSequenceFromLogXpla;
function parseSequencesFromLogTerra(info) {
    // Scan for the Sequence attribute in all the outputs of the transaction.
    // TODO: Make this not horrible.
    const sequences = [];
    const jsonLog = JSON.parse(info.raw_log);
    jsonLog.map((row) => {
        row.events.map((event) => {
            event.attributes.map((attribute) => {
                if (attribute.key === "message.sequence") {
                    sequences.push(attribute.value.toString());
                }
            });
        });
    });
    return sequences;
}
exports.parseSequencesFromLogTerra = parseSequencesFromLogTerra;
function parseSequenceFromLogInjective(info) {
    // Scan for the Sequence attribute in all the outputs of the transaction.
    let sequence = "";
    const jsonLog = JSON.parse(info.rawLog);
    jsonLog.map((row) => {
        row.events.map((event) => {
            event.attributes.map((attribute) => {
                if (attribute.key === "message.sequence") {
                    sequence = attribute.value;
                }
            });
        });
    });
    return sequence.toString();
}
exports.parseSequenceFromLogInjective = parseSequenceFromLogInjective;
const SOLANA_SEQ_LOG = "Program log: Sequence: ";
function parseSequenceFromLogSolana(info) {
    var _a, _b, _c, _d;
    // TODO: better parsing, safer
    const sequence = (_d = (_c = (_b = (_a = info.meta) === null || _a === void 0 ? void 0 : _a.logMessages) === null || _b === void 0 ? void 0 : _b.filter((msg) => msg.startsWith(SOLANA_SEQ_LOG))) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.replace(SOLANA_SEQ_LOG, "");
    if (!sequence) {
        throw new Error("sequence not found");
    }
    return sequence.toString();
}
exports.parseSequenceFromLogSolana = parseSequenceFromLogSolana;
function parseSequencesFromLogSolana(info) {
    var _a, _b;
    // TODO: better parsing, safer
    return (_b = (_a = info.meta) === null || _a === void 0 ? void 0 : _a.logMessages) === null || _b === void 0 ? void 0 : _b.filter((msg) => msg.startsWith(SOLANA_SEQ_LOG)).map((msg) => msg.replace(SOLANA_SEQ_LOG, ""));
}
exports.parseSequencesFromLogSolana = parseSequencesFromLogSolana;
function parseSequenceFromLogAlgorand(result) {
    let sequence = "";
    if (result["inner-txns"]) {
        const innerTxns = result["inner-txns"];
        class iTxn {
        }
        innerTxns.forEach((txn) => {
            if (txn.logs) {
                sequence = ethers_1.BigNumber.from(txn.logs[0].slice(0, 8)).toString();
            }
        });
    }
    return sequence;
}
exports.parseSequenceFromLogAlgorand = parseSequenceFromLogAlgorand;
const NEAR_EVENT_PREFIX = "EVENT_JSON:";
function parseSequenceFromLogNear(outcome) {
    for (const o of outcome.receipts_outcome) {
        for (const l of o.outcome.logs) {
            if (l.startsWith(NEAR_EVENT_PREFIX)) {
                const body = JSON.parse(l.slice(NEAR_EVENT_PREFIX.length));
                if (body.standard === "wormhole" && body.event === "publish") {
                    return body.seq.toString();
                }
            }
        }
    }
    return null;
}
exports.parseSequenceFromLogNear = parseSequenceFromLogNear;
/**
 * Given a transaction result, return the first WormholeMessage event sequence
 * @param coreBridgeAddress Wormhole Core bridge address
 * @param result the result of client.waitForTransactionWithResult(txHash)
 * @returns sequence
 */
function parseSequenceFromLogAptos(coreBridgeAddress, result) {
    if (result.success) {
        const event = result.events.find((e) => e.type === `${coreBridgeAddress}::state::WormholeMessage`);
        return (event === null || event === void 0 ? void 0 : event.data.sequence) || null;
    }
    return null;
}
exports.parseSequenceFromLogAptos = parseSequenceFromLogAptos;
function parseSequenceFromLogSui(coreBridgePackageId, response) {
    var _a, _b;
    const event = (_a = response.events) === null || _a === void 0 ? void 0 : _a.find((e) => e.type === `${coreBridgePackageId}::publish_message::WormholeMessage`);
    return ((_b = event === null || event === void 0 ? void 0 : event.parsedJson) === null || _b === void 0 ? void 0 : _b.sequence) || null;
}
exports.parseSequenceFromLogSui = parseSequenceFromLogSui;
