372 lines
11 KiB
JavaScript
372 lines
11 KiB
JavaScript
|
|
function setStartupMessage(message, type = "") {
|
|||
|
|
if (!startupMessage) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
startupMessage.textContent = message;
|
|||
|
|
startupMessage.classList.toggle("error", type === "error");
|
|||
|
|
startupMessage.classList.toggle("success", type === "success");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function setLoadMessage(message, type = "") {
|
|||
|
|
if (!loadMessage) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
loadMessage.textContent = message;
|
|||
|
|
loadMessage.classList.toggle("error", type === "error");
|
|||
|
|
loadMessage.classList.toggle("success", type === "success");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function setWalletSwitchMessage(message, type = "") {
|
|||
|
|
if (!walletSwitchMessage) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
walletSwitchMessage.textContent = message;
|
|||
|
|
walletSwitchMessage.classList.toggle("error", type === "error");
|
|||
|
|
walletSwitchMessage.classList.toggle("success", type === "success");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function setImportMessage(message, type = "") {
|
|||
|
|
if (!importMessage) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
importMessage.textContent = message;
|
|||
|
|
importMessage.classList.toggle("error", type === "error");
|
|||
|
|
importMessage.classList.toggle("success", type === "success");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function setImportImageMessage(message, type = "") {
|
|||
|
|
if (!importImageMessage) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
importImageMessage.textContent = message;
|
|||
|
|
importImageMessage.classList.toggle("error", type === "error");
|
|||
|
|
importImageMessage.classList.toggle("success", type === "success");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function updateActiveWallet(wallet) {
|
|||
|
|
balanceRefreshRequestId += 1;
|
|||
|
|
registrationRequestId += 1;
|
|||
|
|
balanceRefreshInFlight = false;
|
|||
|
|
registrationCheckInFlight = false;
|
|||
|
|
stopBalanceRefresh();
|
|||
|
|
stopBackgroundTransactionSync();
|
|||
|
|
stopLatestDashboardTransactionsPolling();
|
|||
|
|
stopHistoryRefresh();
|
|||
|
|
clearHistoryRows();
|
|||
|
|
if (typeof resetTransactionForms === "function") {
|
|||
|
|
resetTransactionForms();
|
|||
|
|
}
|
|||
|
|
if (currentView === "send" && typeof showTransactionList === "function") {
|
|||
|
|
setActiveTransactionType("Transfer");
|
|||
|
|
showTransactionList();
|
|||
|
|
}
|
|||
|
|
if (typeof resetMarketingCampaignPage === "function") {
|
|||
|
|
resetMarketingCampaignPage();
|
|||
|
|
}
|
|||
|
|
if (typeof resetAddressBookPage === "function") {
|
|||
|
|
resetAddressBookPage();
|
|||
|
|
}
|
|||
|
|
if (typeof resetAssetsPage === "function") {
|
|||
|
|
resetAssetsPage();
|
|||
|
|
}
|
|||
|
|
if (typeof resetNftsPage === "function") {
|
|||
|
|
resetNftsPage();
|
|||
|
|
}
|
|||
|
|
if (typeof resetLoansPage === "function") {
|
|||
|
|
resetLoansPage();
|
|||
|
|
}
|
|||
|
|
resetLatestDashboardTransactionsMemory();
|
|||
|
|
dashboardLastBalanceStatus = "";
|
|||
|
|
resetBalances(`0 ${activeBaseCoin()}`, "Checking balances for this wallet.");
|
|||
|
|
|
|||
|
|
activeWalletPath = wallet.wallet_path || "";
|
|||
|
|
const shortAddress = wallet.short_address;
|
|||
|
|
const vanityAddress = wallet.vanity_address || "N/A";
|
|||
|
|
const walletName = wallet.wallet_name || shortenAddress(shortAddress);
|
|||
|
|
walletLoaded = true;
|
|||
|
|
activeWalletAddressHex = (wallet.short_address_hex || "").toLowerCase();
|
|||
|
|
activeWalletAddressShort = (wallet.short_address || "").toLowerCase();
|
|||
|
|
setWalletImageMarks(wallet.private_key_image);
|
|||
|
|
|
|||
|
|
document.querySelectorAll("[data-active-address]").forEach((item) => {
|
|||
|
|
item.textContent = shortAddress;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.querySelectorAll("[data-active-vanity]").forEach((item) => {
|
|||
|
|
item.textContent = vanityAddress;
|
|||
|
|
});
|
|||
|
|
document.querySelectorAll("[data-copy-vanity]").forEach((button) => {
|
|||
|
|
button.disabled = vanityAddress === "N/A";
|
|||
|
|
button.textContent = "Copy";
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.querySelectorAll("[data-active-wallet-short]").forEach((item) => {
|
|||
|
|
item.textContent = shortenAddress(shortAddress).replace(".cltc", "");
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
registrationRegistered = false;
|
|||
|
|
setRegistrationState("checking");
|
|||
|
|
checkWalletRegistrationOnce();
|
|||
|
|
resetAutoLockTimer();
|
|||
|
|
populateTopWalletList();
|
|||
|
|
updateHistoryRefreshState();
|
|||
|
|
if (typeof refreshAddressBookVanitiesOnce === "function") {
|
|||
|
|
refreshAddressBookVanitiesOnce();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function setActiveNetwork(network) {
|
|||
|
|
activeNetwork = network;
|
|||
|
|
const label = network === "mainnet" ? "Mainnet" : "Testnet";
|
|||
|
|
|
|||
|
|
networkButtons.forEach((button) => {
|
|||
|
|
button.classList.toggle("active", button.dataset.networkToggle === network);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
networkLabels.forEach((item) => {
|
|||
|
|
item.textContent = label;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
resetBalances(walletLoaded ? `0 ${activeBaseCoin()}` : "Load wallet");
|
|||
|
|
updateBalanceRefreshState();
|
|||
|
|
updateHistoryRefreshState();
|
|||
|
|
resetNetworkInfoDisplays();
|
|||
|
|
updateNetworkInfoRefreshState();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function clearActiveWallet() {
|
|||
|
|
balanceRefreshRequestId += 1;
|
|||
|
|
registrationRequestId += 1;
|
|||
|
|
balanceRefreshInFlight = false;
|
|||
|
|
walletLoaded = false;
|
|||
|
|
resetAutoLockTimer();
|
|||
|
|
activeWalletAddressHex = "";
|
|||
|
|
activeWalletAddressShort = "";
|
|||
|
|
latestKnownBlockHeight = 0;
|
|||
|
|
registrationRegistered = false;
|
|||
|
|
registrationCheckInFlight = false;
|
|||
|
|
stopBalanceRefresh();
|
|||
|
|
stopNetworkInfoRefresh();
|
|||
|
|
stopNodeInfoRefresh();
|
|||
|
|
stopHistoryRefresh();
|
|||
|
|
if (typeof resetTransactionForms === "function") {
|
|||
|
|
resetTransactionForms();
|
|||
|
|
}
|
|||
|
|
if (typeof resetIssueTokenSession === "function") {
|
|||
|
|
resetIssueTokenSession();
|
|||
|
|
}
|
|||
|
|
if (typeof resetCreateNftSession === "function") {
|
|||
|
|
resetCreateNftSession();
|
|||
|
|
}
|
|||
|
|
if (typeof resetSwapOfferSession === "function") {
|
|||
|
|
resetSwapOfferSession();
|
|||
|
|
}
|
|||
|
|
if (typeof resetLoanOfferSession === "function") {
|
|||
|
|
resetLoanOfferSession();
|
|||
|
|
}
|
|||
|
|
if (typeof resetLoanPaymentSession === "function") {
|
|||
|
|
resetLoanPaymentSession();
|
|||
|
|
}
|
|||
|
|
if (typeof resetCollateralClaimSession === "function") {
|
|||
|
|
resetCollateralClaimSession();
|
|||
|
|
}
|
|||
|
|
if (typeof resetBurnSession === "function") {
|
|||
|
|
resetBurnSession();
|
|||
|
|
}
|
|||
|
|
if (typeof resetMarketingSession === "function") {
|
|||
|
|
resetMarketingSession();
|
|||
|
|
}
|
|||
|
|
if (typeof resetVanityAddressSession === "function") {
|
|||
|
|
resetVanityAddressSession();
|
|||
|
|
}
|
|||
|
|
if (typeof resetMarketingCampaignPage === "function") {
|
|||
|
|
resetMarketingCampaignPage();
|
|||
|
|
}
|
|||
|
|
if (typeof resetAddressBookPage === "function") {
|
|||
|
|
resetAddressBookPage();
|
|||
|
|
}
|
|||
|
|
if (typeof resetAssetsPage === "function") {
|
|||
|
|
resetAssetsPage();
|
|||
|
|
}
|
|||
|
|
if (typeof resetNftsPage === "function") {
|
|||
|
|
resetNftsPage();
|
|||
|
|
}
|
|||
|
|
if (typeof resetLoansPage === "function") {
|
|||
|
|
resetLoansPage();
|
|||
|
|
}
|
|||
|
|
clearHistoryRows();
|
|||
|
|
setWalletImageMarks("");
|
|||
|
|
refreshReceivePage();
|
|||
|
|
resetBalances();
|
|||
|
|
resetNetworkInfoDisplays();
|
|||
|
|
setRegistrationState("unregistered");
|
|||
|
|
setRecentTransactionsForWalletState("none");
|
|||
|
|
setHistoryState("Load a wallet to view transaction history.");
|
|||
|
|
|
|||
|
|
document.querySelectorAll("[data-active-address]").forEach((item) => {
|
|||
|
|
item.textContent = "No wallet loaded";
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.querySelectorAll("[data-active-vanity]").forEach((item) => {
|
|||
|
|
item.textContent = "N/A";
|
|||
|
|
});
|
|||
|
|
document.querySelectorAll("[data-copy-vanity]").forEach((button) => {
|
|||
|
|
button.disabled = true;
|
|||
|
|
button.textContent = "Copy";
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.querySelectorAll("[data-active-wallet-short]").forEach((item) => {
|
|||
|
|
item.textContent = "No wallet";
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const walletLabel = document.querySelector("[data-active-wallet-label]");
|
|||
|
|
if (walletLabel) {
|
|||
|
|
walletLabel.innerHTML = "No wallet <span>v</span>";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
refreshReceivePage();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function lockWalletSession() {
|
|||
|
|
clearWalletClipboard();
|
|||
|
|
walletNameInput && (walletNameInput.value = "");
|
|||
|
|
walletKeyInput && (walletKeyInput.value = "");
|
|||
|
|
walletKeyConfirmInput && (walletKeyConfirmInput.value = "");
|
|||
|
|
loadWalletKeyInput && (loadWalletKeyInput.value = "");
|
|||
|
|
importWalletNameInput && (importWalletNameInput.value = "");
|
|||
|
|
importPrivateKeyInput && (importPrivateKeyInput.value = "");
|
|||
|
|
importWalletKeyInput && (importWalletKeyInput.value = "");
|
|||
|
|
importWalletKeyConfirmInput && (importWalletKeyConfirmInput.value = "");
|
|||
|
|
importImageWalletNameInput && (importImageWalletNameInput.value = "");
|
|||
|
|
importImagePathInput && (importImagePathInput.value = "");
|
|||
|
|
importImageWalletKeyInput && (importImageWalletKeyInput.value = "");
|
|||
|
|
importImageWalletKeyConfirmInput && (importImageWalletKeyConfirmInput.value = "");
|
|||
|
|
createWalletForm?.classList.add("hidden");
|
|||
|
|
loadWalletForm?.classList.add("hidden");
|
|||
|
|
importKeyForm?.classList.add("hidden");
|
|||
|
|
importImageForm?.classList.add("hidden");
|
|||
|
|
setStartupMessage("");
|
|||
|
|
setLoadMessage("");
|
|||
|
|
setImportMessage("");
|
|||
|
|
setImportImageMessage("");
|
|||
|
|
toggleNodeModal(false);
|
|||
|
|
closeWalletSwitchModal({ restoreSelection: false });
|
|||
|
|
clearActiveWallet();
|
|||
|
|
setActiveView("dashboard");
|
|||
|
|
document.body.classList.remove("wallet-open");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function refreshWalletList() {
|
|||
|
|
const invoke = window.__TAURI__?.core?.invoke;
|
|||
|
|
if (!invoke || !walletListSelect) {
|
|||
|
|
setLoadMessage("Wallet loading requires the desktop app build.", "error");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setLoadMessage("Checking saved wallets...");
|
|||
|
|
try {
|
|||
|
|
const wallets = await invoke("list_wallets", { network: activeNetwork });
|
|||
|
|
walletListSelect.innerHTML = "";
|
|||
|
|
if (!wallets.length) {
|
|||
|
|
const option = document.createElement("option");
|
|||
|
|
option.value = "";
|
|||
|
|
option.textContent = "No wallets found";
|
|||
|
|
walletListSelect.appendChild(option);
|
|||
|
|
setLoadMessage("No app-managed wallets found. You can load an external wallet path.");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
wallets.forEach((wallet) => {
|
|||
|
|
const option = document.createElement("option");
|
|||
|
|
option.value = wallet.wallet_path;
|
|||
|
|
option.textContent = wallet.wallet_name;
|
|||
|
|
walletListSelect.appendChild(option);
|
|||
|
|
});
|
|||
|
|
setLoadMessage("Choose a saved wallet or enter an external wallet path.");
|
|||
|
|
} catch (error) {
|
|||
|
|
setLoadMessage(String(error), "error");
|
|||
|
|
}
|
|||
|
|
await populateTopWalletList();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function loadWalletByPath(walletPath, walletKey) {
|
|||
|
|
const invoke = window.__TAURI__?.core?.invoke;
|
|||
|
|
if (!invoke) {
|
|||
|
|
throw new Error("Wallet loading requires the desktop app build.");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return invoke("load_wallet", { walletPath, walletKey });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function restoreActiveWalletSelection() {
|
|||
|
|
if (topWalletListSelect) {
|
|||
|
|
topWalletListSelect.value = activeWalletPath || "";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function closeWalletSwitchModal({ restoreSelection = true } = {}) {
|
|||
|
|
walletSwitchModal?.classList.add("hidden");
|
|||
|
|
pendingWalletSwitch = null;
|
|||
|
|
if (walletSwitchSubmit) {
|
|||
|
|
walletSwitchSubmit.disabled = false;
|
|||
|
|
}
|
|||
|
|
if (walletSwitchKeyInput) {
|
|||
|
|
walletSwitchKeyInput.value = "";
|
|||
|
|
}
|
|||
|
|
setWalletSwitchMessage("");
|
|||
|
|
if (restoreSelection) {
|
|||
|
|
restoreActiveWalletSelection();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function openWalletSwitchModal(walletPath) {
|
|||
|
|
if (!walletPath || walletPath === activeWalletPath) {
|
|||
|
|
restoreActiveWalletSelection();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const selectedOption = topWalletListSelect?.selectedOptions?.[0];
|
|||
|
|
pendingWalletSwitch = {
|
|||
|
|
walletPath,
|
|||
|
|
walletName: selectedOption?.textContent?.trim() || "selected wallet"
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (walletSwitchName) {
|
|||
|
|
walletSwitchName.textContent = `Unlock ${pendingWalletSwitch.walletName}`;
|
|||
|
|
}
|
|||
|
|
setWalletSwitchMessage("");
|
|||
|
|
if (walletSwitchKeyInput) {
|
|||
|
|
walletSwitchKeyInput.value = "";
|
|||
|
|
}
|
|||
|
|
walletSwitchModal?.classList.remove("hidden");
|
|||
|
|
setTimeout(() => walletSwitchKeyInput?.focus(), 0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function selectWalletOption(wallet) {
|
|||
|
|
if (!walletListSelect || !wallet) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const existing = Array.from(walletListSelect.options).find((option) => option.value === wallet.wallet_path);
|
|||
|
|
if (existing) {
|
|||
|
|
existing.selected = true;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const placeholder = Array.from(walletListSelect.options).find((option) => !option.value);
|
|||
|
|
if (placeholder) {
|
|||
|
|
placeholder.remove();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const option = document.createElement("option");
|
|||
|
|
option.value = wallet.wallet_path;
|
|||
|
|
option.textContent = wallet.wallet_name;
|
|||
|
|
option.selected = true;
|
|||
|
|
walletListSelect.appendChild(option);
|
|||
|
|
}
|