"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const bn_js_1 = require("bn.js");
const cross_fetch_1 = __importDefault(require("cross-fetch"));
const ENDPOINT = 'https://api.interlay.io/gateway-graphql/v1/graphql';
const ENDPOINT2 = 'https://api.interlay.io/graphql/graphql';
const ACALA_SOVEREIGN_ACCOUNT = 'wdA7Cx6DfdaYx39ac5RtRD1H8kDdT74Nmi8tB7vKh2z9RPzQg';
const MOONBEAM_SOVEREIGN_ACCOUNT = 'wdA7Cx6DgS4mg7dHqMwoKyjqR8kH7gW7G6ymTeLywQAHJJVNy';
const xcmTransferQuery = JSON.stringify({
    query: `{
        substrate_extrinsic(where: {substrate_events: {section: {_eq: "xcmpQueue"}, method: {_eq: "Success"}}, blockNumber: {_gt: "975127"}}) {
        id
        method
        name
        section
        blockNumber
        substrate_events {
          method
          name
          section
          params
        }
    }
    }`
});
function query(query, endpoint) {
    return __awaiter(this, void 0, void 0, function* () {
        const response = yield cross_fetch_1.default(endpoint, {
            method: 'post',
            body: query,
            headers: {
                'Content-Type': 'application/json',
            },
        });
        const json = yield response.json();
        return json.data;
    });
}
const redeemRequests = JSON.stringify({
    query: `{
        redeems(where: {request: {height: {absolute_gt: 975127}}}) {
          id
          status
          userParachainAddress
          request {
            requestedAmountBacking
            height {
              absolute
            }
          }
        }
    }`
});
function main() {
    return __awaiter(this, void 0, void 0, function* () {
        const xcm = (yield query(xcmTransferQuery, ENDPOINT)).substrate_extrinsic;
        const redeems = (yield query(redeemRequests, ENDPOINT2)).redeems;
        let accounts = new Map();
        let totalWrappedDeposited = new bn_js_1.BN(0);
        let totalWrappedWithdrawn = new bn_js_1.BN(0);
        let totalWrappedWithdrawnAcala = new bn_js_1.BN(0);
        let totalWrappedWithdrawnMoonbeam = new bn_js_1.BN(0);
        let totalGovDeposited = new bn_js_1.BN(0);
        let totalGovWithdrawn = new bn_js_1.BN(0);
        // get a list of all accounts the deposited iBTC to Interlay
        // and log total amount as well as amount from Acala and Moonbeam
        let latestBlock = 0;
        // let countMoonbeam = 0;
        xcm.forEach((extrinsic) => {
            const events = extrinsic.substrate_events;
            let withdrawnFrom = "";
            let depositedTo;
            if (latestBlock < extrinsic.blockNumber) {
                latestBlock = extrinsic.blockNumber;
            }
            ;
            events.forEach((event) => {
                if (event.section === "tokens") {
                    const method = event.method;
                    // param0 is the token
                    const token = event.params[0].value.token;
                    // param1 is the account
                    const account = event.params[1].value;
                    // param2 is the amount either as a number of hex encoded
                    let amount = new bn_js_1.BN(event.params[2].value);
                    // console.log(`${method} ${amount} ${token} from/to ${account}`);
                    if (method === "Withdrawn") {
                        withdrawnFrom = account;
                        if (token === "INTR") {
                            totalGovWithdrawn = totalGovWithdrawn.add(amount);
                        }
                        else if (token === "IBTC") {
                            totalWrappedWithdrawn = totalWrappedWithdrawn.add(amount);
                            if (withdrawnFrom === ACALA_SOVEREIGN_ACCOUNT) {
                                totalWrappedWithdrawnAcala = totalWrappedWithdrawnAcala.add(amount);
                            }
                            else if (withdrawnFrom === MOONBEAM_SOVEREIGN_ACCOUNT) {
                                console.log(`${amount} IBTC at ${extrinsic.blockNumber}`);
                                // countMoonbeam += 1;
                                totalWrappedWithdrawnMoonbeam = totalWrappedWithdrawnMoonbeam.add(amount);
                            }
                        }
                    }
                    else if (method === "Deposited") {
                        depositedTo = account;
                        if (token === "INTR") {
                            totalGovDeposited = totalGovDeposited.add(amount);
                        }
                        else if (token === "IBTC") {
                            totalWrappedDeposited = totalWrappedDeposited.add(amount);
                            const deposited = accounts.get(account);
                            if (deposited) {
                                deposited.total = deposited.total.add(amount);
                                let currentAmount = deposited.amountFrom.get(withdrawnFrom);
                                if (currentAmount) {
                                    const newAmount = currentAmount.add(amount);
                                    deposited.amountFrom.set(withdrawnFrom, newAmount);
                                }
                                else {
                                    deposited.amountFrom.set(withdrawnFrom, amount);
                                }
                                accounts.set(account, deposited);
                            }
                            else {
                                const amountFrom = new Map();
                                amountFrom.set(withdrawnFrom, amount);
                                accounts.set(account, {
                                    total: amount,
                                    amountFrom: amountFrom
                                });
                            }
                        }
                    }
                }
            });
        });
        // console.log(countMoonbeam);
        const redeemsFromXcmUsers = [];
        const redeemsFromAcalaUsers = [];
        const redeemsFromMoonbeamUsers = [];
        let totalWrappedRedeemedFromXcm = new bn_js_1.BN(0);
        let totalWrappedRedeemedAcala = new bn_js_1.BN(0);
        let maxAcalaRedeems = new bn_js_1.BN(0);
        console.log(redeems);
        redeems.forEach((redeem) => {
            var _a, _b, _c;
            const account = redeem.userParachainAddress;
            if (accounts.has(account)) {
                redeemsFromXcmUsers.push(redeem);
                const amount = new bn_js_1.BN(redeem.request.requestedAmountBacking);
                totalWrappedRedeemedFromXcm = totalWrappedRedeemedFromXcm.add(amount);
                if ((_a = accounts.get(account)) === null || _a === void 0 ? void 0 : _a.amountFrom.has(ACALA_SOVEREIGN_ACCOUNT)) {
                    maxAcalaRedeems = maxAcalaRedeems.add(amount);
                }
                if ((_b = accounts.get(account)) === null || _b === void 0 ? void 0 : _b.amountFrom.has(ACALA_SOVEREIGN_ACCOUNT)) {
                    redeemsFromAcalaUsers.push(redeem);
                    totalWrappedRedeemedAcala = totalWrappedRedeemedAcala.add(amount);
                }
                if ((_c = accounts.get(account)) === null || _c === void 0 ? void 0 : _c.amountFrom.has(MOONBEAM_SOVEREIGN_ACCOUNT)) {
                    redeemsFromMoonbeamUsers.push(redeem);
                }
            }
        });
        console.log(`Latest XCM transfer ${latestBlock}`);
        console.log(`Total INTR Deposited: ${totalGovDeposited}`);
        console.log(`Total INTR Withdrawn: ${totalGovWithdrawn}`);
        console.log(`Total IBTC Deposited: ${totalWrappedDeposited}`);
        console.log(`Total IBTC Withdrawn: ${totalWrappedWithdrawn}`);
        console.log(`Total IBTC Withdrawn Acala: ${totalWrappedWithdrawnAcala}`);
        console.log(`Total IBTC Withdrawn Moonbeam: ${totalWrappedWithdrawnMoonbeam}`);
        console.log(`Total redeemed from XCM users ${totalWrappedRedeemedFromXcm}`);
        console.log(`Max possible redeemed from Acala users ${maxAcalaRedeems}`);
        console.log(`Redeems from users bridging from Moonbeam ${redeemsFromMoonbeamUsers.length}`);
        console.log(`Redeems from users bridging from Acala ${JSON.stringify(redeemsFromAcalaUsers)}`);
        console.log(`Total IBTC redeemed from users bridging from Acala ${totalWrappedRedeemedAcala}`);
    });
}
main().catch((err) => {
    console.log("Error thrown by script:");
    console.log(err);
});
//# sourceMappingURL=analyze-xcm-transfers.js.map