From 0d77546ce15071d9198d3a7d407a6b80cd3c9361 Mon Sep 17 00:00:00 2001 From: keraliss Date: Sat, 2 May 2026 20:34:05 +0530 Subject: [PATCH] add tabs for settings --- frontend/app/routes/makerDetails/settings.tsx | 928 +++++++++--------- 1 file changed, 486 insertions(+), 442 deletions(-) diff --git a/frontend/app/routes/makerDetails/settings.tsx b/frontend/app/routes/makerDetails/settings.tsx index 7705466..1a1f314 100644 --- a/frontend/app/routes/makerDetails/settings.tsx +++ b/frontend/app/routes/makerDetails/settings.tsx @@ -82,6 +82,9 @@ export default function Settings({ id, onSaved }: Props) { const [fidelityTimelock, setFidelityTimelock] = useState(15000); // ── UI state ────────────────────────────────────────────────────────────── + const [activeTab, setActiveTab] = useState<"bitcoin" | "network" | "swap">( + "bitcoin", + ); const [showRpcPassword, setShowRpcPassword] = useState(false); const [showTorAuth, setShowTorAuth] = useState(false); const [saving, setSaving] = useState(false); @@ -223,6 +226,12 @@ export default function Settings({ id, onSaved }: Props) { } } + const tabs = [ + { id: "bitcoin" as const, label: "Bitcoin Core" }, + { id: "network" as const, label: "Network & Tor" }, + { id: "swap" as const, label: "Swap & Fees" }, + ]; + return (
{loadError && ( @@ -231,480 +240,515 @@ export default function Settings({ id, onSaved }: Props) {
)} - {/* ── Bitcoin Core RPC ──────────────────────────────────────────────── */} -
-

Bitcoin Core RPC

-
-
- - setRpc(e.target.value)} - placeholder="127.0.0.1:18443" - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono text-sm" - /> -

- 8332 mainnet · 18332 testnet · 18443 regtest · 38332 signet -

-
-
- - setRpcUser(e.target.value)} - placeholder="Leave blank to keep current" - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100" - /> -
-
- -
- setRpcPassword(e.target.value)} - placeholder="Leave blank to keep current" - className="w-full px-4 py-2.5 pr-12 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100" - /> - -
-

- Username and password must be provided together -

-
-
- - setDataDir(e.target.value)} - placeholder="~/.coinswap/maker" - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono text-sm" - /> -
-
-
+ {/* ── Tabs ─────────────────────────────────────────────────────────── */} +
+ {tabs.map((tab) => ( + + ))} +
+ + {/* ── Bitcoin Core tab ─────────────────────────────────────────────── */} + {activeTab === "bitcoin" && ( + <> +
+

Bitcoin Core RPC

+
+
+ + setRpc(e.target.value)} + placeholder="127.0.0.1:18443" + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono text-sm" + /> +

+ 8332 mainnet · 18332 testnet · 18443 regtest · 38332 signet +

+
-
Unified Protocol
-
- Unified maker server + + setRpcUser(e.target.value)} + placeholder="Leave blank to keep current" + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100" + /> +
+
+ +
+ setRpcPassword(e.target.value)} + placeholder="Leave blank to keep current" + className="w-full px-4 py-2.5 pr-12 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100" + /> + +
+

+ Username and password must be provided together +

+
+
+ + setDataDir(e.target.value)} + placeholder="~/.coinswap/maker" + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono text-sm" + /> +
+
+
+
+
+ Unified Protocol +
+
+ Unified maker server +
+
+
+ Always on +
-
Always on
-
-
- {/* ── Test Connection ───────────────────────────────────────────────── */} -
-
-

Test Connection

-
-
-
-
-
-
- Connection Status -
- - {rpcStatus === null - ? "Unknown" - : rpcStatus.connected - ? "Connected" - : "Disconnected"} - +
+
+

Test Connection

-
- {( - [ - [ - "Bitcoin Version", - rpcStatus?.version !== undefined - ? String(rpcStatus.version) - : "--", - ], - ["Network", rpcStatus?.network ?? "--"], - [ - "Block Height", - rpcStatus?.block_height !== undefined - ? rpcStatus.block_height.toLocaleString() - : "--", - ], - [ - "Sync Progress", - rpcStatus?.sync_progress !== undefined - ? `${(rpcStatus.sync_progress * 100).toFixed(2)}%` - : "--", - ], - ] as [string, string][] - ).map(([label, val]) => ( -
- {label} +
+
+
+
+
+ + Connection Status + +
- {val} + {rpcStatus === null + ? "Unknown" + : rpcStatus.connected + ? "Connected" + : "Disconnected"}
- ))} +
+ {( + [ + [ + "Bitcoin Version", + rpcStatus?.version !== undefined + ? String(rpcStatus.version) + : "--", + ], + ["Network", rpcStatus?.network ?? "--"], + [ + "Block Height", + rpcStatus?.block_height !== undefined + ? rpcStatus.block_height.toLocaleString() + : "--", + ], + [ + "Sync Progress", + rpcStatus?.sync_progress !== undefined + ? `${(rpcStatus.sync_progress * 100).toFixed(2)}%` + : "--", + ], + ] as [string, string][] + ).map(([label, val]) => ( +
+ {label} + + {val} + +
+ ))} +
+
+
+

+ Tests connectivity to the configured Bitcoin Core RPC endpoint + and returns node info. +

+ {rpcTestError && ( +

{rpcTestError}

+ )} + +
-
-

- Tests connectivity to the configured Bitcoin Core RPC endpoint and - returns node info. + +

+

ZMQ Configuration

+
+
+
+ + setZmq(e.target.value)} + placeholder="tcp://127.0.0.1:28332" + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono text-sm" + /> +

+ Used for both zmqpubrawblock and zmqpubrawtx +

+
+
+

+ Note: Both zmqpubrawblock and zmqpubrawtx + must use the same endpoint. +

+
+
+
+

+ bitcoin.conf snippet +

+
+ zmqpubrawblock={zmq || "tcp://127.0.0.1:28332"} +
+ zmqpubrawtx={zmq || "tcp://127.0.0.1:28332"} +
+ +
+
+
+ + )} + + {/* ── Network & Tor tab ─────────────────────────────────────────────── */} + {activeTab === "network" && ( + <> +
+

Network Ports

+

+ Each maker must use unique ports to avoid clashes when running + multiple makers on the same machine.

- {rpcTestError && ( -

{rpcTestError}

- )} - +
+
+ + setNetworkPort(Number(e.target.value))} + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" + /> +

+ Port for coinswap client connections (default 6102) +

+
+
+ + setRpcPort(Number(e.target.value))} + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" + /> +

+ Port for maker-cli operations (default 6103) +

+
+
-
-
- {/* ── ZMQ ──────────────────────────────────────────────────────────── */} -
-

ZMQ Configuration

-
-
+
+

Tor Configuration

+
+
+ +
+ setTorAuth(e.target.value)} + placeholder="Leave blank to keep current" + className="w-full px-4 py-2.5 pr-12 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100" + /> + +
+

+ Authentication password for Tor control port +

+
+
+ + setSocksPort(Number(e.target.value))} + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" + /> +

+ SOCKS5 proxy port for Tor (default 9050) +

+
+
+ + setControlPort(Number(e.target.value))} + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" + /> +

+ Control port for Tor interface (default 9051) +

+
+
+
+ + )} + + {/* ── Swap & Fees tab ───────────────────────────────────────────────── */} + {activeTab === "swap" && ( +
+

+ Swap & Fidelity Configuration +

+
-
+
+ setZmq(e.target.value)} - placeholder="tcp://127.0.0.1:28332" - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono text-sm" + type="number" + min={0} + step={1} + value={requiredConfirms} + onChange={(e) => setRequiredConfirms(Number(e.target.value))} + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" />

- Used for both zmqpubrawblock and zmqpubrawtx + Enter a whole number of funding confirmations required before + progressing a swap

-
-

- Note: Both zmqpubrawblock and zmqpubrawtx must - use the same endpoint. +

+ + setBaseFee(Number(e.target.value))} + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" + /> +
+
+ + + setAmountRelativeFeePct(Number(e.target.value)) + } + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" + /> +

+ Enter a decimal from 0 to 1. Example: `0.025` = `2.5%`

-
-
-

- bitcoin.conf snippet -

-
- zmqpubrawblock={zmq || "tcp://127.0.0.1:28332"} -
- zmqpubrawtx={zmq || "tcp://127.0.0.1:28332"} +
+ + setTimeRelativeFeePct(Number(e.target.value))} + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" + /> +

+ Enter a decimal from 0 to 1. Example: `0.001` = `0.1%` +

- -
-
-
- - {/* ── Network Ports ─────────────────────────────────────────────────── */} -
-

Network Ports

-

- Each maker must use unique ports to avoid clashes when running - multiple makers on the same machine. -

-
-
- - setNetworkPort(Number(e.target.value))} - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" - /> -

- Port for coinswap client connections (default 6102) -

-
-
- - setRpcPort(Number(e.target.value))} - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" - /> -

- Port for maker-cli operations (default 6103) -

-
-
-
- - {/* ── Tor ──────────────────────────────────────────────────────────── */} -
-

Tor Configuration

-
-
- -
+
+ setTorAuth(e.target.value)} - placeholder="Leave blank to keep current" - className="w-full px-4 py-2.5 pr-12 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100" + type="number" + min={1} + value={fidelityAmount} + placeholder="10000" + onChange={(e) => setFidelityAmount(Number(e.target.value))} + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" /> -
+
+ + setFidelityTimelock(Number(e.target.value))} + className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" + /> +

+ Must be between 12960 and 25920 blocks +

-

- Authentication password for Tor control port -

-
-
- - setSocksPort(Number(e.target.value))} - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" - /> -

- SOCKS5 proxy port for Tor (default 9050) -

-
-
- - setControlPort(Number(e.target.value))} - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" - /> -

- Control port for Tor interface (default 9051) -

-
-
-
- - {/* ── Swap & Fidelity ───────────────────────────────────────────────── */} -
-

- Swap & Fidelity Configuration -

-
-
- - setMinSwapAmount(Number(e.target.value))} - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" - /> -
-
- - setRequiredConfirms(Number(e.target.value))} - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" - /> -

- Enter a whole number of funding confirmations required before - progressing a swap -

-
-
- - setBaseFee(Number(e.target.value))} - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" - /> -
-
- - setAmountRelativeFeePct(Number(e.target.value))} - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" - /> -

- Enter a decimal from 0 to 1. Example: `0.025` = `2.5%` -

-
-
- - setTimeRelativeFeePct(Number(e.target.value))} - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" - /> -

- Enter a decimal from 0 to 1. Example: `0.001` = `0.1%` -

-
-
- - setFidelityAmount(Number(e.target.value))} - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" - /> -
-
- - setFidelityTimelock(Number(e.target.value))} - className="w-full px-4 py-2.5 bg-gray-800 border border-gray-700 rounded-lg focus:border-orange-500 focus:outline-none focus:shadow-[0_0_0_3px_rgba(249,115,22,0.15)] transition-shadow duration-200 text-gray-100 font-mono" - /> -

- Must be between 12960 and 25920 blocks -

-
+ )} {/* ── Save ─────────────────────────────────────────────────────────── */} {saveResult && (