-
Notifications
You must be signed in to change notification settings - Fork 7
update readme and other nits #81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -39,7 +39,7 @@ Unlike traditional Bitcoin transactions that create an on-chain trail, coinswaps | |||||||||||||
|
|
||||||||||||||
| The Taker app requires the following components to operate: | ||||||||||||||
|
|
||||||||||||||
| 1. **Bitcoin Core (Mutinynet)** - A fully synced Mutinynet node with proper RPC and ZMQ configuration | ||||||||||||||
| 1. **Bitcoin Core (Mutinynet)** - A fully synced Mutinynet node with proper RPC, REST, and ZMQ configuration | ||||||||||||||
| - See the [Bitcoin Core setup guide](https://github.com/citadel-tech/coinswap/blob/master/docs/bitcoind.md) for detailed instructions | ||||||||||||||
|
|
||||||||||||||
| 2. **Tor** - Required for anonymous maker discovery and privacy | ||||||||||||||
|
|
@@ -117,30 +117,30 @@ npm run dist | |||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| This creates production-ready packages in the `dist/` directory: | ||||||||||||||
| - `TakerApp-1.0.0.AppImage` - Portable executable for all Linux distributions | ||||||||||||||
| - `taker-app_1.0.0_amd64.snap` - Optional snap package | ||||||||||||||
| - `CoinswapTaker-0.2.1.AppImage` - Portable executable for Linux distributions | ||||||||||||||
| - `coinswaptaker_0.2.1_amd64.snap` - Optional snap package | ||||||||||||||
|
|
||||||||||||||
| ### Using the AppImage | ||||||||||||||
| ```bash | ||||||||||||||
| # Make executable (one-time) | ||||||||||||||
| chmod +x dist/TakerApp-1.0.0.AppImage | ||||||||||||||
| chmod +x dist/CoinswapTaker-0.2.1.AppImage | ||||||||||||||
|
|
||||||||||||||
| # Run directly | ||||||||||||||
| ./dist/TakerApp-1.0.0.AppImage | ||||||||||||||
| ./dist/CoinswapTaker-0.2.1.AppImage | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| **Optional desktop integration:** | ||||||||||||||
| ```bash | ||||||||||||||
| # Integrate with application menu | ||||||||||||||
| ./dist/TakerApp-1.0.0.AppImage --appimage-integrate | ||||||||||||||
| ./dist/CoinswapTaker-0.2.1.AppImage --appimage-integrate | ||||||||||||||
|
|
||||||||||||||
| # Remove integration | ||||||||||||||
| ./dist/TakerApp-1.0.0.AppImage --appimage-unintegrate | ||||||||||||||
| ./dist/CoinswapTaker-0.2.1.AppImage --appimage-unintegrate | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| **Extract and inspect:** | ||||||||||||||
| ```bash | ||||||||||||||
| ./dist/TakerApp-1.0.0.AppImage --appimage-extract | ||||||||||||||
| ./dist/CoinswapTaker-0.2.1.AppImage --appimage-extract | ||||||||||||||
| cd squashfs-root | ||||||||||||||
| ./TakerApp | ||||||||||||||
|
Comment on lines
+143
to
145
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix the extracted AppImage launch command. After 📝 Suggested doc fix ./dist/CoinswapTaker-0.2.1.AppImage --appimage-extract
cd squashfs-root
-./TakerApp
+./coinswap-taker📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| ``` | ||||||||||||||
|
|
@@ -186,8 +186,8 @@ which fusermount | |||||||||||||
| sudo apt install fuse libfuse2 | ||||||||||||||
|
|
||||||||||||||
| # Or extract and run directly | ||||||||||||||
| ./TakerApp-1.0.0.AppImage --appimage-extract | ||||||||||||||
| ./squashfs-root/TakerApp | ||||||||||||||
| ./CoinswapTaker-0.2.1.AppImage --appimage-extract | ||||||||||||||
| ./squashfs-root/coinswap-taker | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| **Error: Cannot find module 'coinswap-napi'** | ||||||||||||||
|
|
@@ -228,7 +228,7 @@ Report security issues on our [Discord](https://discord.gg/Wz42hVmrrK) or email | |||||||||||||
|
|
||||||||||||||
| ## License | ||||||||||||||
|
|
||||||||||||||
| Dual-licensed under MIT or Apache 2.0 at your option. | ||||||||||||||
| Licensed under Apache 2.0. See [LICENSE](LICENSE). | ||||||||||||||
|
|
||||||||||||||
| ## Community | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -238,4 +238,4 @@ Dual-licensed under MIT or Apache 2.0 at your option. | |||||||||||||
|
|
||||||||||||||
| --- | ||||||||||||||
|
|
||||||||||||||
| **⚠️ Warning**: Experimental software under active development. Mainnet use is **NOT recommended**. | ||||||||||||||
| **⚠️ Warning**: Experimental software under active development. Mainnet use is **NOT recommended**. | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,6 +36,22 @@ export function Market(container) { | |
| } | ||
| } | ||
|
|
||
| function formatTorEndpoint(address, start = 14, end = 16) { | ||
| if (!address || typeof address !== 'string') return 'unknown'; | ||
|
|
||
| const separatorIndex = address.lastIndexOf(':'); | ||
| if (separatorIndex === -1) return address; | ||
|
|
||
| const host = address.slice(0, separatorIndex); | ||
| const port = address.slice(separatorIndex + 1); | ||
|
|
||
| if (host.length <= start + end + 3) { | ||
| return `${host}:${port}`; | ||
| } | ||
|
|
||
| return `${host.slice(0, start)}...${host.slice(-end)}:${port}`; | ||
| } | ||
|
Comment on lines
+39
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Extract This helper is now identical to the one in 🤖 Prompt for AI Agents |
||
|
|
||
| // Check sync state every second | ||
| function startSyncStateMonitor() { | ||
| if (syncCheckInterval) return; | ||
|
|
@@ -754,7 +770,7 @@ export function Market(container) { | |
| ${protocolBadge.icon} ${protocolBadge.label} | ||
| </span> | ||
| </div> | ||
| <div class="text-gray-300 font-mono text-sm truncate" title="${maker.address}">${maker.address.substring(0, 18)}...</div> | ||
| <div class="text-gray-300 font-mono text-sm truncate" title="${maker.address}">${formatTorEndpoint(maker.address)}</div> | ||
| <div class="text-green-400">${maker.baseFee}</div> | ||
| <div class="text-blue-400">${maker.volumeFee}%</div> | ||
| <div class="text-cyan-400">${maker.timeFee}%</div> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,9 +17,9 @@ export function ReceiveComponent(container) { | |
| <!-- QR Code --> | ||
| <div class="bg-white p-4 rounded-lg mb-6 flex items-center justify-center"> | ||
| <div id="qr-container" class="flex items-center justify-center" style="min-height: 256px; min-width: 256px;"> | ||
| <div id="qr-loading" class="text-center"> | ||
| <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-400 mx-auto mb-2"></div> | ||
| <p class="text-sm text-gray-500">Generating address...</p> | ||
| <div id="qr-loading" class="text-center text-gray-500"> | ||
| <p class="text-sm">No address loaded</p> | ||
| <p class="text-xs mt-2">Click the button below to generate a receive address.</p> | ||
| </div> | ||
| </div> | ||
| </div> | ||
|
|
@@ -28,7 +28,7 @@ export function ReceiveComponent(container) { | |
| <div class="mb-6"> | ||
| <div class="bg-[#0f1419] border border-gray-700 rounded-lg p-4 flex items-center justify-between"> | ||
| <span id="current-address" class="font-mono text-sm text-white break-all flex-1 mr-4"> | ||
| Loading... | ||
| No address loaded | ||
| </span> | ||
| <button id="copy-address" disabled class="bg-[#FF6B35] hover:bg-[#ff7d4d] disabled:bg-gray-600 disabled:cursor-not-allowed text-white px-4 py-2 rounded text-sm font-semibold text-lg transition-colors whitespace-nowrap"> | ||
| Copy | ||
|
|
@@ -40,8 +40,8 @@ export function ReceiveComponent(container) { | |
| </div> | ||
|
|
||
| <!-- Generate New Address Button --> | ||
| <button id="generate-new" disabled class="w-full bg-[#242d3d] hover:bg-[#2d3748] disabled:bg-gray-700 disabled:cursor-not-allowed text-white font-semibold text-lg py-3 rounded-lg transition-colors border border-gray-700"> | ||
| <span class="generate-text">Generate New Address</span> | ||
| <button id="generate-new" class="w-full bg-[#242d3d] hover:bg-[#2d3748] disabled:bg-gray-700 disabled:cursor-not-allowed text-white font-semibold text-lg py-3 rounded-lg transition-colors border border-gray-700"> | ||
| <span class="generate-text">Generate Address</span> | ||
| <span class="generate-loading hidden"> | ||
|
Comment on lines
+43
to
45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't leak fresh receive addresses to a third-party QR service. Manual generation is now the primary receive path, and this flow still hands the new address to Also applies to: 402-405, 419-424 🤖 Prompt for AI Agents |
||
| <span class="inline-block animate-spin mr-2">⟳</span> | ||
| Generating... | ||
|
|
@@ -399,9 +399,9 @@ export function ReceiveComponent(container) { | |
|
|
||
| // Show loading in QR container | ||
| qrContainer.innerHTML = ` | ||
| <div class="text-center"> | ||
| <div class="text-center"> | ||
| <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-400 mx-auto mb-2"></div> | ||
| <p class="text-sm text-gray-500">Generating...</p> | ||
| <p class="text-sm text-gray-500">Generating address...</p> | ||
| </div> | ||
| `; | ||
|
|
||
|
|
@@ -457,17 +457,10 @@ export function ReceiveComponent(container) { | |
| } | ||
| } | ||
|
|
||
| // Initialize - always generate a new address on page load | ||
| async function initialize() { | ||
| try { | ||
| // Always generate a new address | ||
| await generateNewAddress(); | ||
|
|
||
| // Update recent addresses list | ||
| await updateRecentAddresses(); | ||
|
|
||
| // Enable generate button | ||
| generateButton.disabled = false; | ||
| updateAddressStatus(null); | ||
| } catch (error) { | ||
| console.error('❌ Initialization failed:', error); | ||
| currentAddressEl.textContent = 'Failed to initialize'; | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -50,6 +50,22 @@ function saveSwapDataToCache(utxos, makers, balance) { | |||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| function formatTorEndpoint(address, start = 14, end = 16) { | ||||||||||||||||||||||||||||||||||||||||
| if (!address || typeof address !== 'string') return 'unknown'; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const separatorIndex = address.lastIndexOf(':'); | ||||||||||||||||||||||||||||||||||||||||
| if (separatorIndex === -1) return address; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const host = address.slice(0, separatorIndex); | ||||||||||||||||||||||||||||||||||||||||
| const port = address.slice(separatorIndex + 1); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if (host.length <= start + end + 3) { | ||||||||||||||||||||||||||||||||||||||||
| return `${host}:${port}`; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| return `${host.slice(0, start)}...${host.slice(-end)}:${port}`; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| export async function SwapComponent(container) { | ||||||||||||||||||||||||||||||||||||||||
| const existingContent = container.querySelector('#swap-content'); | ||||||||||||||||||||||||||||||||||||||||
| if (existingContent) { | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -662,10 +678,13 @@ export async function SwapComponent(container) { | |||||||||||||||||||||||||||||||||||||||
| details.hops + ' hop' + (details.hops !== 1 ? 's' : ''); | ||||||||||||||||||||||||||||||||||||||||
| content.querySelector('#estimated-time').textContent = | ||||||||||||||||||||||||||||||||||||||||
| formatEstimatedTime(details.timeSeconds); | ||||||||||||||||||||||||||||||||||||||||
| content.querySelector('#selected-makers-display').textContent = | ||||||||||||||||||||||||||||||||||||||||
| const selectedMakersText = | ||||||||||||||||||||||||||||||||||||||||
| getTopCandidateMakers() | ||||||||||||||||||||||||||||||||||||||||
| .map((maker) => maker.address) | ||||||||||||||||||||||||||||||||||||||||
| .map((maker) => formatTorEndpoint(maker.address)) | ||||||||||||||||||||||||||||||||||||||||
| .join(', ') || 'None selected'; | ||||||||||||||||||||||||||||||||||||||||
| const selectedMakersEl = content.querySelector('#selected-makers-display'); | ||||||||||||||||||||||||||||||||||||||||
| selectedMakersEl.textContent = selectedMakersText; | ||||||||||||||||||||||||||||||||||||||||
| selectedMakersEl.title = selectedMakersText; | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+681
to
+687
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tooltip shows abbreviated value instead of full addresses. Setting 🔧 Proposed fix to show full addresses in tooltip const selectedMakersText =
getTopCandidateMakers()
.map((maker) => formatTorEndpoint(maker.address))
.join(', ') || 'None selected';
+ const fullAddressesText =
+ getTopCandidateMakers()
+ .map((maker) => maker.address)
+ .join(', ') || 'None selected';
const selectedMakersEl = content.querySelector('#selected-makers-display');
selectedMakersEl.textContent = selectedMakersText;
- selectedMakersEl.title = selectedMakersText;
+ selectedMakersEl.title = fullAddressesText;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||
| content.querySelector('#maker-fee-percent').textContent = | ||||||||||||||||||||||||||||||||||||||||
| details.makerFeePercent + '%'; | ||||||||||||||||||||||||||||||||||||||||
| content.querySelector('#maker-fee-sats').textContent = | ||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1104,7 +1123,7 @@ export async function SwapComponent(container) { | |||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||
| <div class="flex justify-between mb-2 gap-3"> | ||||||||||||||||||||||||||||||||||||||||
| <span class="text-sm text-gray-400">Top Maker Candidates</span> | ||||||||||||||||||||||||||||||||||||||||
| <span id="selected-makers-display" class="text-sm text-cyan-400 text-right break-all">None selected</span> | ||||||||||||||||||||||||||||||||||||||||
| <span id="selected-makers-display" class="text-sm text-cyan-400 text-right whitespace-nowrap overflow-hidden text-ellipsis block max-w-[220px] md:max-w-[280px] lg:max-w-[340px]" title="None selected">None selected</span> | ||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||
| <div class="flex justify-between mb-2"> | ||||||||||||||||||||||||||||||||||||||||
| <span class="text-sm text-gray-400">Hops</span> | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add blank lines around this heading and the fenced blocks.
markdownlint is still flagging MD022/MD031 in this section, so the README will keep warning until the heading and each code fence are separated by blank lines.
Also applies to: 133-143
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 123-123: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 124-124: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
🤖 Prompt for AI Agents