const VANITY_ADDRESS_FEE_ATOMIC = 500000000n; function setVanityMessage(message, type = "") { setScopedTransactionMessage("Vanity Address", vanityMessage, message, type); } function vanityNetworkSuffix() { return activeBaseCoin().toLowerCase() || "cltc"; } function normalizedVanityName() { return String(vanityNameInput?.value || "").trim().toLowerCase(); } function vanityPreviewValue() { const name = normalizedVanityName(); return name ? `${name}.${vanityNetworkSuffix()}` : "--"; } function displayVanityAddress(vanityAddress) { const value = String(vanityAddress || "").trim(); const separator = value.lastIndexOf("."); if (separator < 1) { return value || "N/A"; } const payload = value.slice(0, separator).trimStart(); const suffix = value.slice(separator + 1); return payload ? `${payload}.${suffix}` : "N/A"; } function applyActiveVanityDisplay(vanityAddress) { const display = displayVanityAddress(vanityAddress); document.querySelectorAll("[data-active-vanity]").forEach((item) => { item.textContent = display; }); document.querySelectorAll("[data-copy-vanity]").forEach((button) => { button.disabled = display === "N/A"; button.textContent = "Copy"; }); } function applyActiveVanityDisplayFromTransaction(transaction) { const vanityAddress = transaction?.vanity_address; const owner = transaction?.address; const active = activeWalletAddressShort || activeWalletAddressHex || ""; if (vanityAddress && owner && String(owner).trim().toLowerCase() === active.toLowerCase()) { applyActiveVanityDisplay(vanityAddress); } } function updateVanityDerivedFields() { if (vanityFeeInput) { vanityFeeInput.value = atomicToDecimal(VANITY_ADDRESS_FEE_ATOMIC); } if (vanityOwner) { vanityOwner.textContent = activeWalletAddressShort || activeWalletAddressHex || "--"; } if (vanityPreview) { vanityPreview.textContent = vanityPreviewValue(); } if (vanityFeeLabel) { vanityFeeLabel.textContent = `${atomicToDecimal(VANITY_ADDRESS_FEE_ATOMIC)} ${activeBaseCoin()}`; } } function validateVanityForm() { if (!walletLoaded) { return "Load a wallet before creating a vanity address."; } if (!registrationRegistered) { return "Address registration is required before creating a vanity address."; } const name = String(vanityNameInput?.value || "").trim(); if (!name) { return "Vanity name is required."; } if (name.length > 20) { return "Vanity name cannot exceed 20 letters."; } if (!/^[A-Za-z]+$/.test(name)) { return "Vanity name can only contain letters."; } if (baseCoinBalanceAtomic() < VANITY_ADDRESS_FEE_ATOMIC) { return `Vanity address registration requires ${atomicToDecimal(VANITY_ADDRESS_FEE_ATOMIC)} ${activeBaseCoin()} for the fee.`; } return ""; } function validateVanityAvailabilityCheck() { if (!walletLoaded) { return "Load a wallet before checking a vanity address."; } if (!activeBroadcastNode()) { return "Select a broadcast node before checking a vanity address."; } const name = String(vanityNameInput?.value || "").trim(); if (!name) { return "Vanity name is required."; } if (name.length > 20) { return "Vanity name cannot exceed 20 letters."; } if (!/^[A-Za-z]+$/.test(name)) { return "Vanity name can only contain letters."; } return ""; } function vanityPayload() { return { vanityName: String(vanityNameInput.value || "").trim(), txfee: String(VANITY_ADDRESS_FEE_ATOMIC) }; } function clearVanityForm() { if (vanityNameInput) { vanityNameInput.value = ""; } updateVanityDerivedFields(); } function setVanityButtonsDisabled(disabled) { document.querySelector("[data-vanity-save]")?.toggleAttribute("disabled", disabled); document.querySelector("[data-vanity-broadcast]")?.toggleAttribute("disabled", disabled); document.querySelector("[data-vanity-check]")?.toggleAttribute("disabled", disabled); } async function checkVanityAvailability() { const validationError = validateVanityAvailabilityCheck(); if (validationError) { setVanityMessage(validationError, "error"); return; } const invoke = window.__TAURI__?.core?.invoke; if (!invoke) { setVanityMessage("Wallet bridge is not available.", "error"); return; } setVanityButtonsDisabled(true); try { setVanityMessage("Checking vanity address availability..."); const result = await invoke("check_vanity_address_availability", { broadcastNode: activeBroadcastNode(), vanityName: String(vanityNameInput.value || "").trim() }); if (result?.available) { setVanityMessage(`${result.vanity_address} is available.`, "success"); } else { setVanityMessage(`${result?.vanity_address || vanityPreviewValue()} is already registered.`, "error"); } } catch (error) { setVanityMessage(String(error), "error"); } finally { setVanityButtonsDisabled(false); } } async function handleVanityAction(action) { const validationError = validateVanityForm(); if (validationError) { setVanityMessage(validationError, "error"); return; } const invoke = window.__TAURI__?.core?.invoke; if (!invoke) { setVanityMessage("Wallet bridge is not available.", "error"); return; } const walletKey = await requestSigningWalletKey(); if (guiRuntimeSettings.require_key_before_signing !== false && !walletKey) { setVanityMessage("Signing cancelled."); return; } setVanityButtonsDisabled(true); try { if (action === "save") { setVanityMessage("Saving vanity address transaction..."); const review = await invoke("save_vanity_address_transaction", { ...vanityPayload(), walletKey }); clearVanityForm(); setVanityMessage(`Vanity address transaction saved: ${review.file_name}`, "success"); if (typeof refreshUnbroadcastTransactions === "function") { refreshUnbroadcastTransactions(); } } else { const broadcastNode = activeBroadcastNode(); if (!broadcastNode) { throw new Error("Select a broadcast node before broadcasting."); } setVanityMessage("Broadcasting vanity address transaction..."); const result = await invoke("broadcast_vanity_address_transaction", { ...vanityPayload(), broadcastNode, walletKey }); applyActiveVanityDisplay(vanityPreviewValue()); clearVanityForm(); setVanityMessage(result.response || "Vanity address transaction broadcast.", "success"); } } catch (error) { setVanityMessage(String(error), "error"); } finally { setVanityButtonsDisabled(false); } } function prepareVanityAddressForm() { updateVanityDerivedFields(); setVanityMessage(""); } function resetVanityAddressSession() { clearVanityForm(); setVanityMessage(""); } vanityNameInput?.addEventListener("input", () => { setVanityMessage(""); updateVanityDerivedFields(); }); document .querySelector("[data-vanity-save]") ?.addEventListener("click", () => handleVanityAction("save")); document .querySelector("[data-vanity-broadcast]") ?.addEventListener("click", () => handleVanityAction("broadcast")); document .querySelector("[data-vanity-check]") ?.addEventListener("click", checkVanityAvailability);