Skip to content

update readme and other nits#81

Merged
keraliss merged 1 commit into
mainfrom
update_readme
Mar 28, 2026
Merged

update readme and other nits#81
keraliss merged 1 commit into
mainfrom
update_readme

Conversation

@keraliss
Copy link
Copy Markdown
Collaborator

@keraliss keraliss commented Mar 28, 2026

Summary by CodeRabbit

  • Documentation

    • Updated README with new binary names, configuration requirements, and license information
    • Clarified setup instructions and wallet restoration guidance in usage documentation
  • Bug Fixes

    • Improved handling of invalid or missing timestamps in swap history display
    • Enhanced fallback values for swap data with unknown timestamps
  • UI/UX Improvements

    • Tor endpoint addresses now display in truncated format for better readability
    • Adjusted initial states and button labels in address generation interface

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 28, 2026

📝 Walkthrough

Walkthrough

This PR updates distribution artifact naming (TakerApp → CoinswapTaker), enhances timestamp normalization across swap-related components with new helper functions, improves Tor endpoint display formatting, adjusts initialization behavior in the receive component, refines documentation, and adds responsive CSS utilities.

Changes

Cohort / File(s) Summary
Documentation & Configuration
README.md, docs/usage.md
Updated artifact names from TakerApp-1.0.0/TakerApp to CoinswapTaker-0.2.1/coinswap-taker in examples and filenames. Changed license text to Apache 2.0 only. Clarified setup instructions regarding launch-time walkthrough and Bitcoin Core configuration requirements (added REST alongside RPC/ZMQ).
Timestamp Normalization
api1.js, src/components/swap/SwapHistory.js
Added normalizeTimestamp(value, fallback) helper to handle null, numeric (scaled by 1000 when < 1e12), and string-based timestamp inputs. Refactored swap report record processing to use file modification time as fallback and compute startedAt from multiple possible fields.
Swap History & Reporting
src/components/swap/SwapHistory.js, src/components/swap/SwapReport.js
Updated normalizeSwapReport to derive timestamps from multiple field names with fallback handling. Added descending sort by completedAt to history loading. Changed UI to display 'Unknown time'/'Unknown date' when timestamps are invalid. Updated truncateAddress logic to preserve port in host:port addresses.
Tor Address Display Formatting
src/components/market/Market.js, src/components/swap/Swap.js
Added formatTorEndpoint(address, start=14, end=16) helper to truncate long Tor hostnames while preserving ports. Updated maker table and swap summary UI to display formatted addresses with tooltip support and responsive CSS truncation styling.
Receive Component Initialization
src/components/receive/Receive.js
Removed automatic address generation on page load. Changed initial UI from "Loading..." to "No address loaded". Button now starts enabled with label "Generate Address" instead of "Generate New Address". Initialization now only refreshes recent addresses and clears status fields.
Styling
src/styles/output.css
Added new Tailwind utilities: max-w-[220px], text-ellipsis, and responsive variants md:max-w-[280px], lg:max-w-[340px] for controlling address display truncation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • unification of protocols #78: Overlapping changes to api1.js swap-report record construction and timestamp normalization helper implementation.
  • App updates #72: Related modifications to swap history UI helpers, timestamp normalization logic, and Tor-address formatting in market/swap components.
  • bug fixes #75: Concurrent updates to SwapHistory.js timestamp normalization, report processing, and history loading/display logic.

Poem

🐰 A tale of takers trading true,
Now "CoinswapTaker" shines in view!
Timestamps dance in milliseconds bright,
Tor addresses trim'd, just right,
Fresh addresses await your command—
No rushing in, we understand! ✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'update readme and other nits' is vague and generic, using non-descriptive terms like 'nits' that obscure the actual scope of changes across multiple files. Revise the title to be more specific about the main changes, such as 'Rename TakerApp to CoinswapTaker and update documentation' or focus on the primary change rather than using vague terminology.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch update_readme

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
api1.js (1)

301-318: ⚠️ Potential issue | 🟠 Major

Read startTimestamp / endTimestamp from flat reports too.

nestedReport is already normalized to rawReport.report ?? rawReport, but this lookup still hardcodes rawReport.report?.startTimestamp/endTimestamp. Flat report files that only carry those aliases at the top level will fall back to mtimeMs/null, which then skews history ordering and duration in SwapHistory.js.

🛠️ Suggested fix
   const rawCompletedAt =
-    rawReport.completedAt ||
-    rawReport.completed_at ||
-    rawReport.report?.completedAt ||
-    rawReport.report?.completed_at ||
-    rawReport.report?.endTimestamp ||
-    rawReport.report?.end_timestamp ||
+    rawReport.completedAt ??
+    rawReport.completed_at ??
+    rawReport.endTimestamp ??
+    rawReport.end_timestamp ??
+    nestedReport.completedAt ??
+    nestedReport.completed_at ??
+    nestedReport.endTimestamp ??
+    nestedReport.end_timestamp ??
     null;
   const completedAt = normalizeTimestamp(rawCompletedAt, fileStats.mtimeMs);
   const startedAt = normalizeTimestamp(
-    rawReport.startedAt ||
-      rawReport.started_at ||
-      rawReport.report?.startedAt ||
-      rawReport.report?.started_at ||
-      rawReport.report?.startTimestamp ||
-      rawReport.report?.start_timestamp,
+    rawReport.startedAt ??
+      rawReport.started_at ??
+      rawReport.startTimestamp ??
+      rawReport.start_timestamp ??
+      nestedReport.startedAt ??
+      nestedReport.started_at ??
+      nestedReport.startTimestamp ??
+      nestedReport.start_timestamp,
     null
   );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api1.js` around lines 301 - 318, The timestamp lookup for completedAt and
startedAt misses flat-report aliases startTimestamp/endTimestamp at the top
level; update the rawCompletedAt and startedAt expressions used by
normalizeTimestamp to also check rawReport.startTimestamp and
rawReport.endTimestamp (and their snake_case forms if needed) in addition to
rawReport.report?.startTimestamp/endTimestamp so both nested and flat reports
resolve correctly; ensure you still fall back to fileStats.mtimeMs for
completedAt and null for startedAt and keep references to normalizeTimestamp,
rawReport, completedAt, startedAt, and fileStats.mtimeMs.
src/components/market/Market.js (1)

773-780: ⚠️ Potential issue | 🔴 Critical

Escape maker addresses before injecting them into HTML.

maker.address is network-derived offerbook data, but it's interpolated raw into title="..." and the inline onclick. A malformed address containing quotes or markup can break out of the attribute/script context inside the Electron renderer. Set the text/title with DOM APIs and bind the click handler with addEventListener/data-* instead of string interpolation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/market/Market.js` around lines 773 - 780, The maker.address is
injected unsafely into HTML attributes and an inline onclick; update the
rendering in Market.js to stop string-interpolating maker.address into title and
onclick. Instead create the DOM nodes with document.createElement (or your
existing renderer utilities), set the tooltip via element.title =
formatTorEndpoint(maker.address) and the visible text via element.textContent,
store the raw address in a data attribute (e.g., dataset.address) or closure,
and attach the click behavior with element.addEventListener('click', () =>
viewFidelityBond(maker.address)); replace the inline onclick/attribute usage so
quotes/markup in maker.address cannot break the renderer.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@README.md`:
- Around line 123-124: Add blank lines immediately before and after the "Using
the AppImage" heading and each surrounding fenced code block so the heading and
code fences are separated by empty lines; update the README's "Using the
AppImage" section (the "Using the AppImage" heading and its opening/closing ```
blocks) and the other similar fenced blocks in that area (the blocks flagged
around the following section) to satisfy markdownlint MD022/MD031.
- Around line 143-145: The README's AppImage extraction instructions still tell
users to run ./TakerApp which mismatches the renamed unpacked binary; update the
steps after "./dist/CoinswapTaker-0.2.1.AppImage --appimage-extract" to either
rename the extracted binary to "coinswap-taker" (matching the rest of the doc)
or directly instruct running "./coinswap-taker" instead of "./TakerApp" so the
command and references (./TakerApp, coinswap-taker) are consistent.

In `@src/components/market/Market.js`:
- Around line 39-53: The formatTorEndpoint helper in Market.js is duplicated in
Swap.js—extract it into a single shared util named formatTorEndpoint (exported
as a named function) and replace the local implementations in both Market.js and
Swap.js with imports of that shared function; ensure the new util exports
formatTorEndpoint, update both components to import { formatTorEndpoint }, and
run the app to confirm behavior is unchanged.

In `@src/components/receive/Receive.js`:
- Around line 43-45: The Receive component currently passes fresh receive
addresses to the external generateQR() service (called where the "Generate
Address" button handler updates elements with classes
generate-text/generate-loading and in the flows around the other generate
calls), which leaks addresses off-box; replace those calls to generateQR() so
the new address is not sent to any third-party URL and instead render the QR
locally in this component using a client-side QR renderer (e.g., a local qrcode
library) when the button with id "generate-new" is clicked and in the other
flows that call generateQR(); update the handlers that toggle elements with
classes "generate-text" and "generate-loading" to call a local
renderQRCode(address) function (or inline local rendering) and remove any
construction of external URLs or calls to generateQR() so addresses are never
transmitted externally.

In `@src/components/swap/Swap.js`:
- Around line 681-687: The tooltip is currently set to selectedMakersText
(abbreviated output from formatTorEndpoint) so hovering doesn't reveal full Tor
addresses; update the code that sets selectedMakersEl.title to use the full
addresses instead (e.g., map getTopCandidateMakers() to maker.address and join
with ', ' or create a selectedMakersFull variable) while keeping
selectedMakersText for the displayed/abbreviated content; reference symbols:
selectedMakersText, selectedMakersEl, getTopCandidateMakers, formatTorEndpoint.

---

Outside diff comments:
In `@api1.js`:
- Around line 301-318: The timestamp lookup for completedAt and startedAt misses
flat-report aliases startTimestamp/endTimestamp at the top level; update the
rawCompletedAt and startedAt expressions used by normalizeTimestamp to also
check rawReport.startTimestamp and rawReport.endTimestamp (and their snake_case
forms if needed) in addition to rawReport.report?.startTimestamp/endTimestamp so
both nested and flat reports resolve correctly; ensure you still fall back to
fileStats.mtimeMs for completedAt and null for startedAt and keep references to
normalizeTimestamp, rawReport, completedAt, startedAt, and fileStats.mtimeMs.

In `@src/components/market/Market.js`:
- Around line 773-780: The maker.address is injected unsafely into HTML
attributes and an inline onclick; update the rendering in Market.js to stop
string-interpolating maker.address into title and onclick. Instead create the
DOM nodes with document.createElement (or your existing renderer utilities), set
the tooltip via element.title = formatTorEndpoint(maker.address) and the visible
text via element.textContent, store the raw address in a data attribute (e.g.,
dataset.address) or closure, and attach the click behavior with
element.addEventListener('click', () => viewFidelityBond(maker.address));
replace the inline onclick/attribute usage so quotes/markup in maker.address
cannot break the renderer.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1f751e7d-93c5-4f88-8b89-eeaf80dcc22e

📥 Commits

Reviewing files that changed from the base of the PR and between 0b3709a and 9c99269.

📒 Files selected for processing (9)
  • README.md
  • api1.js
  • docs/usage.md
  • src/components/market/Market.js
  • src/components/receive/Receive.js
  • src/components/swap/Swap.js
  • src/components/swap/SwapHistory.js
  • src/components/swap/SwapReport.js
  • src/styles/output.css

Comment thread README.md
Comment on lines 123 to 124
### Using the AppImage
```bash
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 123 - 124, Add blank lines immediately before and
after the "Using the AppImage" heading and each surrounding fenced code block so
the heading and code fences are separated by empty lines; update the README's
"Using the AppImage" section (the "Using the AppImage" heading and its
opening/closing ``` blocks) and the other similar fenced blocks in that area
(the blocks flagged around the following section) to satisfy markdownlint
MD022/MD031.

Comment thread README.md
Comment on lines +143 to 145
./dist/CoinswapTaker-0.2.1.AppImage --appimage-extract
cd squashfs-root
./TakerApp
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix the extracted AppImage launch command.

After --appimage-extract, this section still tells users to run ./TakerApp, but the rest of the README has already renamed the unpacked binary to coinswap-taker. Following these steps will fail on the extracted image.

📝 Suggested doc fix
 ./dist/CoinswapTaker-0.2.1.AppImage --appimage-extract
 cd squashfs-root
-./TakerApp
+./coinswap-taker
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
./dist/CoinswapTaker-0.2.1.AppImage --appimage-extract
cd squashfs-root
./TakerApp
./dist/CoinswapTaker-0.2.1.AppImage --appimage-extract
cd squashfs-root
./coinswap-taker
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 143 - 145, The README's AppImage extraction
instructions still tell users to run ./TakerApp which mismatches the renamed
unpacked binary; update the steps after "./dist/CoinswapTaker-0.2.1.AppImage
--appimage-extract" to either rename the extracted binary to "coinswap-taker"
(matching the rest of the doc) or directly instruct running "./coinswap-taker"
instead of "./TakerApp" so the command and references (./TakerApp,
coinswap-taker) are consistent.

Comment on lines +39 to +53
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}`;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Extract formatTorEndpoint() into a shared util.

This helper is now identical to the one in src/components/swap/Swap.js, so any truncation tweak has to be kept in sync in two places. Pull it into a shared formatter before the two implementations drift.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/market/Market.js` around lines 39 - 53, The formatTorEndpoint
helper in Market.js is duplicated in Swap.js—extract it into a single shared
util named formatTorEndpoint (exported as a named function) and replace the
local implementations in both Market.js and Swap.js with imports of that shared
function; ensure the new util exports formatTorEndpoint, update both components
to import { formatTorEndpoint }, and run the app to confirm behavior is
unchanged.

Comment on lines +43 to 45
<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">
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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 generateQR(). generateQR() builds an external QR URL, so every fresh receive address is disclosed off-box before the user even copies it. Render the QR locally instead.

Also applies to: 402-405, 419-424

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/receive/Receive.js` around lines 43 - 45, The Receive
component currently passes fresh receive addresses to the external generateQR()
service (called where the "Generate Address" button handler updates elements
with classes generate-text/generate-loading and in the flows around the other
generate calls), which leaks addresses off-box; replace those calls to
generateQR() so the new address is not sent to any third-party URL and instead
render the QR locally in this component using a client-side QR renderer (e.g., a
local qrcode library) when the button with id "generate-new" is clicked and in
the other flows that call generateQR(); update the handlers that toggle elements
with classes "generate-text" and "generate-loading" to call a local
renderQRCode(address) function (or inline local rendering) and remove any
construction of external URLs or calls to generateQR() so addresses are never
transmitted externally.

Comment on lines +681 to +687
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;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Tooltip shows abbreviated value instead of full addresses.

Setting title to selectedMakersText (the abbreviated text) means the tooltip provides no additional information when hovering. The typical UX pattern is to show the full value in the tooltip when text is truncated, allowing users to see complete Tor addresses on hover.

🔧 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

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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;
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 = fullAddressesText;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/swap/Swap.js` around lines 681 - 687, The tooltip is currently
set to selectedMakersText (abbreviated output from formatTorEndpoint) so
hovering doesn't reveal full Tor addresses; update the code that sets
selectedMakersEl.title to use the full addresses instead (e.g., map
getTopCandidateMakers() to maker.address and join with ', ' or create a
selectedMakersFull variable) while keeping selectedMakersText for the
displayed/abbreviated content; reference symbols: selectedMakersText,
selectedMakersEl, getTopCandidateMakers, formatTorEndpoint.

@keraliss keraliss merged commit 7f6be70 into main Mar 28, 2026
1 check passed
@coderabbitai coderabbitai Bot mentioned this pull request May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant