<template id="tx-table">
    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles.css') }}">
    <style>
        .tx-table {
            display: table;
        }
        tx-row {
            display: contents;
        }
        .pagination-container {
            text-align: center;
            width: 100%;
        }
        .pagination-next, .pagination-back {
            cursor: pointer;
        }
        input::-webkit-outer-spin-button,
        input::-webkit-inner-spin-button {
            -webkit-appearance: none;
            margin: 0;
        }

        /* Firefox */
        input[type=number] {
            -moz-appearance: textfield;
        }

        .pagination-idx {
            min-width: 50px;
            max-width: 50px;
            width: 50px;
            margin: 7px 7px 7px 3px;
            text-align: center;
            height: 35px;
        }
        .search {
            /* float: right; */
            margin: auto;
            width: 100%;
            max-width: 350px;
        }
        .search-container {
            width: 100%;
            display: flex;
            margin-bottom: 0.5em;
        }
        .up-arrow {
            width: 0;
            height: 0;
            border: solid 5px transparent;
            background: transparent;
            border-bottom: solid 7px #fff;
            border-top-width: 0;
            cursor: pointer;
            float: right;
            margin-right: 50px;
            margin-top: 5px;
        }

        .down-arrow {
            width: 0;
            height: 0;
            border: solid 5px transparent;
            background: transparent;
            border-top: solid 7px #fff;
            border-bottom-width: 0;
            margin-top:1px;
            cursor: pointer;
            float: right;
            margin-right: 50px;
            margin-top: 5px;
        }
        
        .export-container {
            max-width: 50%;
            margin: 20px auto;
            border: 1px solid #fff;
            padding: 20px;
            text-align: center;
            border-radius: 7px;
        }
        .export {
            max-width: 200px;
            margin: auto;
        }
        .selected-rows-action-box {
            float: right;
        }
        .selected-rows-action-box .btn {
            width: 200px;
            margin: 5px;
            height: 38px;
        }
    </style>
    <nav class="row">
        <button
            type="button"
            class="txlist-view-btn btn radio left">
            History
        </button>
        <button
            type="button"
            class="utxo-view-btn btn radio right">
            UTXO
        </button>
    </nav>
    <div class="pagination-container">
        <a class="pagination-back pagination-arrow pagination-disabled">&#8249;</a>
        Page <input class="pagination-idx" type="number" step="1" min="1" value="1"></input><span class="pagination-counter"></span>
        <a class="pagination-next pagination-arrow pagination-disabled">&#8250;</a>
        <br>
    </div>
    <div class="search-container">
        <!--Left part of the toolbar-->
        <div style="flex: 1;">
            {% include "includes/page-limit-select.html" %}
        </div>
        <!--Middle part of the toolbar-->
        <input class="search" type="text" placeholder="Search..." />
        <!--Placeholder for right part of the toolbar-->
        <div style="flex: 1;"></div>
    </div>
    <div class="selected-rows-action-box row hidden">
        <form class="freeze-tx-form" method="POST">
            <input type="hidden" class="csrf-token" name="csrf_token" value="{{ csrf_token() }}"/>
            <button type="button" class="btn freeze-tx-btn">
                <tool-tip title="Freezing UTXOs">
                    Freezing a UTXO will make Specter disallow spending it.<br><br>
                    This is useful especially for dealing with dust attack, where you don't want to accidentally spend the dust received.
                </tool-tip>&nbsp;&nbsp;
                Un/Freeze UTXOs
            </button>
        </form>
        <form class="compose-tx-form" method="POST">
            <input type="hidden" class="csrf-token" name="csrf_token" value="{{ csrf_token() }}"/>
            <button type="button" class="btn compose-tx-btn">Create new transaction</button>
        </form>
    </div>
    <div class="export-container hidden">
        <h1>Export transactions to CSV</h1>
        <div class="{% if not specter.price_check or not (specter.alt_rate and specter.alt_symbol) %}hidden{% endif %}">
        Fetch historical price data:
        <label class="switch">
        <input type="checkbox" class="export-prices">
        <span class="slider"></span>
        </label><br><br>
        <div class="note">
            If enabled, specter will try to fetch historical prices for each transaction date from the configured price provider.
            <br><b>This has privacy implications!</b>
        </div><br>
        </div>
        <a class="export btn" download>Export</a>
    </div>
    <table class="tx-table">
        <thead>
            <tr>
                <th value="category" class="category-header"><div class="category-arrow"></div></th>
                <th value="txid" class="optional txid-header">TxID<div class="txid-arrow"></div></th>
                <th value="label" class="optional label-header">Label<div class="label-arrow"></div></th>
                <th value="amount" class="amount-header">Amount<div class="amount-arrow"></div></th>
                <th value="time" class="time-header">Time<div class="time-arrow up-arrow"></div></th>
                <th value="confirmations" class="confirmations-header">Confirmations<div class="confirmations-arrow"></div></th>
                <th value="blockhash" class="optional hidden blockhash-header">
                    {% include "includes/merkletooltip.html" %}
                    Block Hash
                </th>
                <th style="width: 50px; padding: 10px;"><button type="button" class="export-btn btn" style="width: 50px;">Export</button></th>
            </tr>
    </thead>
    <tr class="empty">
        <td></td>
        <td>Fetching transactions...</td>
        <td class="optional"></td>
        <td class="optional"></td>
        <td></td>
        <td></td>
        <td class="optional hidden blockhash-empty"></td>
        <td></td>
    </tr>
    <tr class="summary-row hidden">
        <td></td>
        <td class="summary-tx-count"></td>
        <td class="optional"></td>
        <td class="summary-amount"></td>
        <td class="optional"></td>
        <td></td>
        <td class="optional hidden blockhash-summary"></td>
        <td></td>
    </tr>
	<tbody class="tx-tbody">
	</tbody>
    </table>
</template>

<script type="text/javascript">
    /**
     * Custom element for showing a table of transactions.
     * Can be configured to show:
     *  - The transaction history of a wallet (set attribute `type` to "txlist" and `wallet` to the wallet's alias)
     *  - The UTXO list of a wallet (set attribute `type` to "utxo" and `wallet` to the wallet's alias)
     *  - The transaction history of all the user's wallets (set attribute `type` to "txlist" and `wallet` to null)
     *  - The UTXO list of all the user's wallets (set attribute `type` to "utxo" and `wallet` to null)
     * The uses Specter's API to fetch transactions every time the user changes its parameters.
     * These parameters are configured using components included in this table element:
     *  - Tabs for switching between History (`type="txlist"`) and UTXO (`type="utxo"`) list types
     *  - Sorting transactions by any column (ascending or descending)
     *  - Search bar to filter transactions using free text search
     *  - Configuring limit for transactions displayed per page
     *  - Pagination, jumping between pages and showing the total pages count
     *  - Export - export the full (unfiltered) list from which the table is drawing its data as CSV (optionally with price history)
     * 
     * The table also supports:
     *  - Showing amounts in either BTC or sats (set attribute `btc-unit` to either "btc" or "sat")
     *  - Showing prices next to the amounts (set attribute `price` to the BTC price and symbol to the symbol of the currency you're pricing at)
     *  - Showing validated blockhash column (set attribute `blockhash` to either "true" or "false")
    */
    class TxTableElement extends HTMLElement {
        constructor() {
            super();
            // Create a shadow root
            var shadow = this.attachShadow({mode: 'open'});
            var style = document.getElementById('tx-table').content;
            var clone = style.cloneNode(true);
            this.el = clone.querySelector(".tx-table");
            this.tbody = clone.querySelector(".tx-tbody");

            // Empty row element
            this.emptyRow = clone.querySelector(".empty");

            // Blockhash header and empty column
            this.blockhashHeader = clone.querySelector(".blockhash-header");
            this.blockhashEmpty = clone.querySelector(".blockhash-empty");
            this.blockhashSummary = clone.querySelector(".blockhash-summary");

            // Tabs (History/ UTXO)
            this.txlistViewBtn = clone.querySelector(".txlist-view-btn");
            this.utxoViewBtn = clone.querySelector(".utxo-view-btn");

            // Pagination
            this.paginationNext = clone.querySelector(".pagination-next");
            this.paginationBack = clone.querySelector(".pagination-back");
            this.paginationContainer = clone.querySelector(".pagination-container");
            this.paginationCounter = clone.querySelector(".pagination-counter");
            this.paginationIdxInput = clone.querySelector(".pagination-idx");
            this.pageLimitSelect = clone.querySelector(".page-limit-select");

            // Search bar element
            this.searchInput = clone.querySelector(".search");

            // Sorting headers and arrows
            this.categoryHeader = clone.querySelector(".category-header");
            this.txidHeader = clone.querySelector(".txid-header");
            this.labelHeader = clone.querySelector(".label-header");
            this.amountHeader = clone.querySelector(".amount-header");
            this.timeHeader = clone.querySelector(".time-header");
            this.confirmationsHeader = clone.querySelector(".confirmations-header");
            this.categoryArrow = clone.querySelector(".category-arrow");
            this.txidArrow = clone.querySelector(".txid-arrow");
            this.labelArrow = clone.querySelector(".label-arrow");
            this.amountArrow = clone.querySelector(".amount-arrow");
            this.timeArrow = clone.querySelector(".time-arrow");
            this.confirmationsArrow = clone.querySelector(".confirmations-arrow");

            // Summary row
            this.summaryRow = clone.querySelector(".summary-row");
            this.summaryTxCount = clone.querySelector(".summary-tx-count");
            this.summaryAmount = clone.querySelector(".summary-amount");

            // Export button
            this.exportBtn = clone.querySelector(".export-btn");
            this.exportContainer = clone.querySelector(".export-container");
            this.export = clone.querySelector(".export");
            this.exportPricesSwitch = clone.querySelector(".export-prices");

            // Selected rows
            this.selectedRowsActionBox = clone.querySelector(".selected-rows-action-box");
            this.composeTxForm = clone.querySelector(".compose-tx-form");
            this.composeTxBtn = clone.querySelector(".compose-tx-btn");
            this.freezeTxForm = clone.querySelector(".freeze-tx-form");
            this.freezeTxBtn = clone.querySelector(".freeze-tx-btn");
            this.selectedRows = [];
            
			this.txlistViewBtn.onclick = () => {
				if (!this.txlistViewBtn.classList.contains("checked")) {
					this.utxoViewBtn.classList.remove("checked");
					this.txlistViewBtn.classList.add("checked");
					this.setAttribute("type","txlist");
				}
			}

			this.utxoViewBtn.onclick = () => {
				if (!this.utxoViewBtn.classList.contains("checked")) {
					this.txlistViewBtn.classList.remove("checked");
					this.utxoViewBtn.classList.add("checked");
					this.setAttribute("type","utxo");
				}
            }
            
            // Init call id to avoid fetch returning after another one triggered
            this.callId = 0


            // Initialize default sort, search, limit and page parameters
            this.idx = 0;
            this.limit = 50;
            this.search = "";
            this.sortby = "time";
            this.sortdir = "desc";
            this.pageCount = 1;
            
            // Next page action
            this.paginationNext.onclick = () => {
                this.idx++;
                fetchTxItems(this);
            }

            // Previous page action
            this.paginationBack.onclick = () => {
                this.idx--;
                fetchTxItems(this);
            }

            // Listen to changes in page number selection input
            this.paginationIdxInput.onchange = () => {
                let newIdx = parseInt(this.paginationIdxInput.value);
                if (isNaN(newIdx) || (newIdx < 1 || newIdx > this.pageCount)) {
                    this.paginationIdxInput.value = this.idx + 1;
                    return;
                }
                this.idx = newIdx - 1;
                fetchTxItems(this);
            }

            // Listen to changes in search bar
            this.searchInput.onchange = () => {
                this.search = this.searchInput.value;
                this.export.href = this.export.href.split('?')[0] + `?exportPrices=${this.exportPricesSwitch.checked}&search=${this.search}&sortby=${this.sortby}&sortdir=${this.sortdir}`;
                fetchTxItems(this);
            }

            // Listen to changes in page limit
            this.pageLimitSelect.onchange = () => {
                this.limit = this.pageLimitSelect.value;
                fetchTxItems(this);
            }

            // Setup sorting functionality for each column of the table header
            let sortHeaders = [
                this.categoryHeader,
                this.txidHeader,
                this.labelHeader,
                this.amountHeader,
                this.timeHeader,
                this.confirmationsHeader
            ];

            for (let header of sortHeaders) {
                header.onclick = () => {
                    if (header.classList.toString().indexOf(this.sortby) != -1) {
                        // flip direction
                        this.el.querySelector(`.${this.sortby}-arrow`).classList.remove(this.sortdir == 'asc' ? 'down-arrow' : 'up-arrow');
                        this.el.querySelector(`.${this.sortby}-arrow`).classList.add(this.sortdir == 'asc' ? 'up-arrow' : 'down-arrow');
                        this.sortdir = this.sortdir == 'asc' ? 'desc' : 'asc';
                        this.export.href = this.export.href.split('?')[0] + `?exportPrices=${this.exportPricesSwitch.checked}&search=${this.search}&sortby=${this.sortby}&sortdir=${this.sortdir}`;
                    } else {
                        sortHeaders.forEach(el => {
                            let existingArrow = el.querySelector(`.${this.sortby}-arrow`)
                            if (existingArrow) {
                                existingArrow.classList.remove('up-arrow');
                                existingArrow.classList.remove('down-arrow');
                            }
                        });
                        this.sortby = header.getAttribute('value');
                        this.el.querySelector(`.${this.sortby}-arrow`).classList.add(this.sortdir == 'asc' ? 'down-arrow' : 'up-arrow');
                        this.export.href = this.export.href.split('?')[0] + `?exportPrices=${this.exportPricesSwitch.checked}&search=${this.search}&sortby=${this.sortby}&sortdir=${this.sortdir}`;
                    }
                    fetchTxItems(this);
                }
            }

            // Export data
            this.exportBtn.onclick = () => {
                if (this.exportBtn.innerText == 'Done') {
                    this.exportContainer.classList.add('hidden');
                    this.exportBtn.innerText = 'Export';
                } else {
                    this.exportContainer.classList.remove('hidden');
                    this.exportBtn.innerText = 'Done';
                }
            }

            this.export.onclick = () => {
                this.exportContainer.classList.add('hidden');
                this.exportBtn.innerText = 'Export';
            }
            
            // Export prices switch toggle
            this.exportPricesSwitch.onchange = () => {
                this.export.href = this.export.href.split('?')[0] + `?exportPrices=${this.exportPricesSwitch.checked}&search=${this.search}&sortby=${this.sortby}&sortdir=${this.sortdir}`;
            }

            this.composeTxBtn.onclick = () => {
                for (let tx of this.selectedRows) {
                    this.composeTxForm.innerHTML += `
                        <input type="checkbox" checked class="hidden" name="coinselect" value="${tx.txid}, ${tx.vout}">
                    `
                }
                this.composeTxForm.action = `{{ url_for('wallets_endpoint.send_new', wallet_alias='WALLET_ALIAS') }}`.replace("WALLET_ALIAS", this.wallet);
                this.composeTxForm.submit();
            }

            this.freezeTxBtn.onclick = () => {
                for (let tx of this.selectedRows) {
                    this.freezeTxForm.innerHTML += `
                        <input type="checkbox" checked class="hidden" name="selected_utxo" value="${tx.txid}:${tx.vout}">
                    `
                }
                this.freezeTxForm.innerHTML += `<input type="hidden" name="action" value="freezeutxo"/>`
                this.freezeTxForm.action = `{{ url_for('wallets_endpoint.history', wallet_alias='WALLET_ALIAS') }}`.replace("WALLET_ALIAS", this.wallet);
                this.freezeTxForm.submit();
            }

            // Attach the created element to the shadow dom
            shadow.appendChild(clone);
        }

        static get observedAttributes() {
            return ['blockhash', 'btc-unit', 'price', 'symbol', 'type', 'wallet'];
        }

        /**
         * Listens to changes on the following attributes:
         * - blockhash: Should show blockhash column. Either "true" or "false"
         * - btc-unit: Bitcoin unit to display amounts with. Either "btc" or "sat"
         * - price: BTC price for price calculations
         * - symbol: Currency symbol for price calculations
         * - type: Transactions list type to load. Either "txlist" or "utxo"
         * - wallet: The wallet alias (null to get all wallets combined)
        */
        attributeChangedCallback(attrName, oldValue, newValue) {
            if (this.getAttribute('blockhash') == 'true' && this.getAttribute('type') == "txlist" && this.getAttribute('wallet')) {
                    this.blockhashHeader.classList.remove('hidden');
                    this.blockhashEmpty.classList.remove('hidden');
                    this.blockhashSummary.classList.remove('hidden');
            } else {
                this.blockhashHeader.classList.add('hidden');
                this.blockhashEmpty.classList.add('hidden');
                this.blockhashSummary.classList.add('hidden');
            }
            if (
                this.blockhash != this.getAttribute('blockhash') ||
                this.btcUnit != this.getAttribute('btc-unit') ||
                this.price != this.getAttribute('price') ||
                this.symbol != this.getAttribute('symbol') ||
                this.listType != this.getAttribute('type') ||
                this.wallet != this.getAttribute('wallet')
            ) {
                this.blockhash = this.getAttribute('blockhash');
                this.btcUnit = this.getAttribute('btc-unit');
                this.price = this.getAttribute('price');
                this.symbol = this.getAttribute('symbol');
                this.listType = this.getAttribute('type');
                this.wallet = this.getAttribute('wallet');
                if (!this.listType) {
                    return
                }
                fetchTxItems(this);
            }
        }

    }

    /**
     * Fetches txlist from the Specter API and loads the result into TxRowElement
     * @param self - The TxTableElement itself.
    */
    async function fetchTxItems(self) {
        self.callId++;
        // Clean up from existing transaction list
        self.summaryRow.classList.add('hidden');
        self.emptyRow.children[1].innerText = "Fetching transactions...";
        self.emptyRow.classList.remove('hidden');
        self.tbody.querySelectorAll('tx-row').forEach((row) => {row.remove()});
        if (!self.listType) {
            self.emptyRow.children[1].innerText = "Failed to fetch transactions...";
            return
        }

        if (self.listType == "txlist") {
            self.txlistViewBtn.classList.add("checked");
        } else {
            self.utxoViewBtn.classList.add("checked");
        }

        // Select the correct URL based on the list type and selected wallet
        let url;
        switch (self.listType) {
            case "txlist":
                if (self.wallet) {
                    self.export.href = `{{ url_for('wallets_endpoint.tx_history_csv', wallet_alias='WALLET_ALIAS') }}`.replace("WALLET_ALIAS", self.wallet);
                    url = `{{ url_for('wallets_endpoint.txlist', wallet_alias='WALLET_ALIAS') }}`.replace("WALLET_ALIAS", self.wallet);
                } else {
                    self.export.href = `{{ url_for('wallets_endpoint.wallet_overview_txs_csv') }}`;
                    url = `{{ url_for('wallets_endpoint.wallets_overview_txlist') }}`;
                }
                break;
            case "utxo":
                if (self.wallet) {
                    self.export.href = `{{ url_for('wallets_endpoint.utxo_csv', wallet_alias='WALLET_ALIAS') }}`.replace("WALLET_ALIAS", self.wallet);
                    url = `{{ url_for('wallets_endpoint.utxo_list', wallet_alias='WALLET_ALIAS') }}`.replace("WALLET_ALIAS", self.wallet);
                } else {
                    self.export.href = `{{ url_for('wallets_endpoint.wallet_overview_utxo_csv') }}`;
                    url = `{{ url_for('wallets_endpoint.wallets_overview_utxo_list') }}`;
                }
                break
            default:
                self.export.href = ``
                self.emptyRow.children[1].innerText = "Failed to fetch transactions...";
                return
        }

        if (self.export.href != '') {
            self.export.href += `?exportPrices=${self.exportPricesSwitch.checked}&search=${self.search}&sortby=${self.sortby}&sortdir=${self.sortdir}`;
        }

        // Prepare form data with all relevant parameters
        var formData = new FormData();
        formData.append('idx', self.idx);
        formData.append('limit', self.limit);
        formData.append('search', self.search);
        formData.append('sortby', self.sortby);
        formData.append('sortdir', self.sortdir);
        formData.append('csrf_token', '{{ csrf_token() }}');
        try {
            let callId = self.callId;
            const response = await fetch(
                url,
                {
                    method: 'POST',
                    body: formData
                }
            );
            if (callId != self.callId) {
                return;
            }
            if(response.status != 200){
                showError(await response.text());
                return;
            }
            const jsonResponse = await response.json();
            let showBlockhash = !self.blockhashHeader.classList.contains('hidden');
            
            if ("txlist" in jsonResponse) {
                // Populate the table with TXRowElement objects using the fetched txlist
                if (jsonResponse.txlist) {
                    let txlist = JSON.parse(jsonResponse.txlist);
                    let summaryTxCount = 0;
                    let summaryAmount = 0;
                    let summaryPrice = 0;
                    for (let tx of txlist) {
                        let txRow = `
                        <tx-row
                            data-btc-unit="${self.btcUnit ? self.btcUnit : 'btc'}"
                            data-price="${self.price ? self.price : 0}"
                            data-symbol="${self.symbol ? self.symbol : ''}"
                            data-tx='${JSON.stringify(tx).replace(/[\(]/g, "&lpar;").replace(/[\)]/g, "&rpar;").replace(/[\/]/g, "&sol;").replace(/[\']/g, "&apos;")}'
                            data-wallet="${(self.wallet ? self.wallet : tx.wallet_alias)}"
                            data-show-blockhash="${showBlockhash}"
                            data-mode="${self.getAttribute('type') + (self.wallet ? "" : "-overview")}">
                            </tx-row>
                        `
                        self.tbody.innerHTML += txRow;
                        summaryTxCount++;
                        summaryAmount += parseFloat(self.tbody.children[self.tbody.children.length - 1].shadowRoot.querySelector('.amount').innerText.replace(',', ''));
                        summaryPrice += parseFloat(self.tbody.children[self.tbody.children.length - 1].shadowRoot.querySelector('.amount-price').innerText.replace(`(${self.symbol}`, '').replace(')', '').replace(',', ''));
                    }

                    if (summaryTxCount > 0 && self.search) {
                        self.summaryTxCount.innerText = `Transactions count: ${summaryTxCount}`;
                        self.summaryAmount.innerHTML = `Total amount: ${numberWithCommas(summaryAmount.toFixed(8))}`;
                        if (summaryPrice) {
                            self.summaryAmount.innerHTML += ` <span class="note">(${self.symbol}${numberWithCommas(summaryPrice.toFixed(2))})</span>`
                        }
                        self.summaryRow.classList.remove('hidden');
                    }
                    // Pagination
                    self.pageCount = jsonResponse.pageCount;
                    // Show empty row if no transaction found
                    if (self.pageCount == 0 || txlist.length == 0) {
                        self.emptyRow.classList.remove('hidden');
                        self.emptyRow.children[1].innerText = "No transactions found...";
                        self.pageCount = 1;
                    } else {
                        self.emptyRow.classList.add('hidden');
                    }

                    // If index is greater than the pages count fetch again for the last page
                    if (self.idx >= self.pageCount) {
                        self.idx = self.pageCount - 1;
                        fetchTxItems(self)
                    }

                    self.paginationIdxInput.value = self.idx + 1;

                    // If there are multiple pages show the pagination bar
                    if (self.pageCount > 1) {
                        self.paginationContainer.classList.remove('hidden');
                        self.paginationCounter.innerText = `of ${self.pageCount}`;
                        self.paginationIdxInput.max = self.pageCount;
                    } else {
                        self.paginationContainer.classList.add('hidden');
                    }

                    // Disable pagination back button if on the first page
                    if (self.idx == 0) {
                        self.paginationBack.classList.add('pagination-disabled');
                    } else {
                        self.paginationBack.classList.remove('pagination-disabled');
                    }

                    // Disable pagination next button if on the last page
                    if (self.idx + 1 == self.pageCount) {
                        self.paginationNext.classList.add('pagination-disabled');
                    } else {
                        self.paginationNext.classList.remove('pagination-disabled');
                    }

                    self.selectedRows = [];
                    self.selectedRowsActionBox.classList.add('hidden');

                    for (let txRow of self.shadowRoot.querySelectorAll('tx-row')) {
                        txRow.addEventListener('txRowSelected', e=>{
                            let selectedRow = e.target;
                            if (e.detail.selected) {
                                self.selectedRows.push({
                                    txid: e.detail.txid,
                                    vout: e.detail.vout,
                                    amount: e.detail.amount.toFixed(8)
                                });
                            } else {
                                self.selectedRows = self.selectedRows.filter(row => !(row.txid === e.detail.txid && row.vout === e.detail.vout))
                            }
                            if (self.selectedRows.length == 0) {
                                self.selectedRowsActionBox.classList.add('hidden');
                            } else {
                                self.selectedRowsActionBox.classList.remove('hidden');
                            }
						});
                    }
                }
                return
            };
            showError('Failed to fetch transactions list.')
        } catch(e) {
            console.log("Caught error: ", e);
            showError(`Failed to fetch transactions list: ${e}`);
        }
    }

    /**
     * Shows a <tx-data> element popup for specified txid.
     * @param btcUnit - Bitcoin unit to display amounts with. Either "btc" or "sat"
     * @param price - BTC price for price calculations
     * @param symbol - Currency symbol for price calculations
     * @param txid - ID of the transaction to show.
     * @param wallet - The wallet alias of the wallet the transaction is associated with.
    */
    function showTxData(btcUnit, price, symbol, txid, wallet) {
        if (wallet) {
            let txDataPopup = document.getElementById('tx-popup');
            txDataPopup.innerHTML = `
            <tx-data
            data-btc-unit="${btcUnit ? btcUnit : 'btc'}"
            data-price="${price ? price : 0}"
            data-symbol="${symbol ? symbol : ''}"
            data-txid="${txid}"
            data-tx-wallet="${wallet}">
            </tx-data>`;
            showPageOverlay('tx-popup');
        } else {
            copyText(txid, `Copied transaction: ${ txid }`);
        }
    }

    /**
     * Triggered when a tx-row is marked as selected/ unselected .
     * 
    */
    function txRowToggled(txRow) {
        // if ()
    }

    customElements.define('tx-table', TxTableElement);
</script>
