Contractless-GUI-Wallet/frontend/js/vanity_address_form.js

242 lines
7.1 KiB
JavaScript
Raw Normal View History

2026-07-01 16:01:30 +00:00
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);