Skip to content

feat(homepage): display chains and balance#36

Open
stealthwhizz wants to merge 8 commits intoOWASP-BLT:mainfrom
stealthwhizz:feature/display-chains-balance
Open

feat(homepage): display chains and balance#36
stealthwhizz wants to merge 8 commits intoOWASP-BLT:mainfrom
stealthwhizz:feature/display-chains-balance

Conversation

@stealthwhizz
Copy link
Copy Markdown
Contributor

@stealthwhizz stealthwhizz commented Mar 10, 2026

Summary

Added homepage status display showing supported blockchains and the current
treasury wallet balance (issue #33). The balance is retrieved live from the
ord-server when ORD_SERVER_URL_MAINNET is configured; otherwise the
page falls back to 0.

Changes

  • Added /api/status endpoint to Python worker
  • Worker fetches real balance from ord-server if available
  • Updated public/index.html hero section with chain icons + balance element
    and added inline JS to call /api/status
  • Added new env vars: ORD_SERVER_URL_MAINNET, TREASURY_ADDRESS
    (documented in .env.example and CONTRIBUTING.md)
  • Fixed indentation / stray code in src/index.py
  • Updated CONTRIBUTING.md with variable documentation

Testing

  1. Start ord‑server locally and set ORD_SERVER_URL_MAINNET=http://localhost:9002
  2. Run npm run dev and load http://localhost:8787
  3. Verify hero card shows “Bitcoin + Solana” and the real balance value.

Notes

Balance retrieval is optional; the UI works without an ord‑server.

Summary by CodeRabbit

  • New Features

    • Home page now displays chain icons, a "Loading balance…" state, and a dynamic wallet balance and address fetched from a status endpoint; shows "N/A" if retrieval fails.
  • Documentation

    • Onboarding docs and example env updated with new environment variables to configure the ord-server connection and treasury address so balances can be retrieved.

Copilot AI review requested due to automatic review settings March 10, 2026 19:23
@owasp-blt
Copy link
Copy Markdown

owasp-blt bot commented Mar 10, 2026

👋 Thanks for opening this pull request, @stealthwhizz!

Before your PR is reviewed, please ensure:

  • Your code follows the project's coding style and guidelines.
  • You have written or updated tests for your changes.
  • The commit messages are clear and descriptive.
  • You have linked any relevant issues (e.g., Closes #123).

🔍 Our team will review your PR shortly. If you have questions, feel free to ask in the comments.

🚀 Keep up the great work! — OWASP BLT

@owasp-blt
Copy link
Copy Markdown

owasp-blt bot commented Mar 10, 2026

📊 Monthly Leaderboard

Hi @stealthwhizz! Here's how you rank for March 2026:

Rank User Open PRs PRs (merged) PRs (closed) Reviews Comments Total
#4 @Kunal241207 5 24 0 2 6 267
#5 @stealthwhizz 4 25 0 0 2 258
#6 @mdkaifansari04 3 23 13 4 4 235

Scoring this month (across OWASP-BLT org): Open PRs (+1 each), Merged PRs (+10), Closed (not merged) (−2), Reviews (+5; first two per PR in-month), Comments (+2, excludes CodeRabbit). Run /leaderboard on any issue or PR to see your rank!

@owasp-blt
Copy link
Copy Markdown

owasp-blt bot commented Mar 10, 2026

👋 Hi @stealthwhizz!

This pull request needs a peer review before it can be merged. Please request a review from a team member who is not:

  • The PR author
  • coderabbitai
  • copilot

Once a valid peer review is submitted, this check will pass automatically. Thank you!

⚠️ Peer review enforcement is active.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a new optional env var ORD_SERVER_URL_MAINNET in docs and .env.example; implements a new /api/status endpoint in the worker that returns { chains, balance, address }, attempts to fetch balance from ORD_SERVER_URL_MAINNET/mainnet/wallet-balance with a timeout, and includes a hardcoded address in the payload; updates the frontend (public/index.html) to fetch /api/status and render chain icons, balance, and address.

Changes

Cohort / File(s) Summary
Environment & Docs
./.env.example, CONTRIBUTING.md
Adds ORD_SERVER_URL_MAINNET (default/comment http://localhost:9002) to examples/docs and documents TREASURY_ADDRESS; notes UI will show real balances when ord-server is reachable.
Backend API
src/index.py
Adds CORS preflight handling and root redirect header consolidation; adds /api/status route returning JSON { chains, balance, address }; attempts HTTP GET to ORD_SERVER_URL_MAINNET/mainnet/wallet-balance with a 5s timeout and parsing fallbacks; logs fetch errors; status payload uses a hardcoded address rather than env-derived TREASURY_ADDRESS.
Frontend UI
public/index.html
Adds IDs (chain-icons, chain-balance, chain-address), replaces static placeholders with "Loading balance…", and injects an inline script that requests /api/status, renders chain icons, formatted balance (or N/A), address, and logs fetch errors.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Browser
    participant Worker as Cloudflare Worker
    participant OrdServer as Ord Server

    Client->>Worker: GET /api/status
    activate Worker
    Worker->>OrdServer: GET ORD_SERVER_URL_MAINNET/mainnet/wallet-balance (if configured)
    activate OrdServer
    OrdServer-->>Worker: balance data or error
    deactivate OrdServer
    Worker->>Worker: build payload { chains, balance, address (hardcoded) }
    Worker-->>Client: 200 JSON response
    deactivate Worker
    Client->>Client: update DOM (icons, balance, address)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

quality: medium

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(homepage): display chains and balance' directly and concisely summarizes the main change: adding a homepage feature to display supported blockchains and treasury balance.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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: 2

🧹 Nitpick comments (2)
src/index.py (2)

42-43: Silent exception swallowing hinders debugging.

Catching all exceptions and passing silently makes it difficult to diagnose issues when the ord-server integration fails. Consider logging the error for observability.

♻️ Proposed fix
-        except Exception:
-            pass
+        except Exception as exc:
+            # Balance fetch is optional; log for debugging but continue
+            print(f"[status] ord-server fetch failed: {exc}")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/index.py` around lines 42 - 43, The current except block that reads
"except Exception: pass" in src/index.py silently swallows errors; replace it
with proper logging and handling by catching the exception and logging the full
traceback (e.g., logger.exception(...) or using traceback.format_exc()) in that
except block, and then either re-raise or return/propagate an error as
appropriate for the surrounding function (identify the specific except
Exception: occurrence and update it to call the module logger or error handler
rather than pass).

48-48: Consider adding Content-Type: application/json header.

The response body is JSON, but the headers don't include Content-Type. While res.json() on the frontend will still parse it, explicitly setting the content type is best practice.

♻️ Proposed fix
-        return Response.new(json.dumps(data), {'status': 200, 'headers': cors_headers})
+        return Response.new(json.dumps(data), {
+            'status': 200,
+            'headers': {**cors_headers, 'Content-Type': 'application/json'}
+        })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/index.py` at line 48, Response returned by Response.new(json.dumps(data),
{'status': 200, 'headers': cors_headers}) lacks an explicit Content-Type; update
the headers for the Response.new call to include 'Content-Type':
'application/json' (e.g., merge into cors_headers or create a new headers dict
combining cors_headers and {'Content-Type': 'application/json'}) so the JSON
response is served with the correct media type while preserving existing CORS
headers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CONTRIBUTING.md`:
- Around line 117-122: Add a single blank line after the note paragraph that
ends with the warning about ORD_SERVER_URL_MAINNET so the Markdown heading "###
Step 2 — Wrangler Variables (`wrangler.toml`)" is separated properly; locate the
note block containing "When `ORD_SERVER_URL_MAINNET` is set and the ord-server
is reachable, the home page will display the real BTC/Runes wallet balance
instead of a placeholder." and insert one empty line before the "### Step 2 —
Wrangler Variables (`wrangler.toml`)" heading to ensure correct rendering.

In `@src/index.py`:
- Line 37: The call to js.fetch in the function that assigns resp will raise
NameError because js is never imported; update the imports to either import the
js module (so js.fetch works) or import fetch directly and call fetch(ord_url)
instead; locate the import lines that currently bring in Response and URL and
add either "import js" or "from js import fetch" and then adjust the call at
js.fetch(ord_url) accordingly (or remove the js. prefix if importing fetch)
while leaving ord_url and resp usage unchanged.

---

Nitpick comments:
In `@src/index.py`:
- Around line 42-43: The current except block that reads "except Exception:
pass" in src/index.py silently swallows errors; replace it with proper logging
and handling by catching the exception and logging the full traceback (e.g.,
logger.exception(...) or using traceback.format_exc()) in that except block, and
then either re-raise or return/propagate an error as appropriate for the
surrounding function (identify the specific except Exception: occurrence and
update it to call the module logger or error handler rather than pass).
- Line 48: Response returned by Response.new(json.dumps(data), {'status': 200,
'headers': cors_headers}) lacks an explicit Content-Type; update the headers for
the Response.new call to include 'Content-Type': 'application/json' (e.g., merge
into cors_headers or create a new headers dict combining cors_headers and
{'Content-Type': 'application/json'}) so the JSON response is served with the
correct media type while preserving existing CORS headers.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: OWASP-BLT/coderabbit/.coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 4feded39-3c08-4335-b6e8-2a0d7fbee434

📥 Commits

Reviewing files that changed from the base of the PR and between 715c91e and 7baa703.

📒 Files selected for processing (4)
  • .env.example
  • CONTRIBUTING.md
  • public/index.html
  • src/index.py

@github-project-automation github-project-automation bot moved this from Backlog to Ready in 📌 OWASP BLT Project Board Mar 10, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a small “status” feature to the homepage by exposing a Worker API endpoint (/api/status) and using it from public/index.html to display supported chains and a live wallet balance (when an ord-server URL is configured).

Changes:

  • Added /api/status route in the Cloudflare Worker (Python) to return chain list + balance (optionally fetched from ord-server).
  • Updated homepage hero “Stats” section to include chain icons and a “Loading balance…” element, plus inline JS to call /api/status.
  • Documented new environment variables in .env.example and CONTRIBUTING.md.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
src/index.py Adds /api/status endpoint and optional ord-server balance fetch logic.
public/index.html Adds chain/balance UI elements and JS to fetch and render /api/status.
CONTRIBUTING.md Documents ORD_SERVER_URL_MAINNET and TREASURY_ADDRESS.
.env.example Adds example values/comments for the new env vars.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

stealthwhizz and others added 4 commits March 11, 2026 01:02
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@stealthwhizz
Copy link
Copy Markdown
Contributor Author

@coderabbitai can you review it once

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 11, 2026

@stealthwhizz Sure! I'll review the PR now. 🐰

✅ Actions performed

Full review triggered.

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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@public/index.html`:
- Line 100: The wallet/treasury address element (id "chain-address") can
overflow because long unbroken strings don't wrap; update the element in
public/index.html (the <p id="chain-address" ...> node) to allow breaking by
adding a wrapping rule (e.g., Tailwind class "break-all" or
"break-words"/"break-normal" combined with "overflow-wrap: anywhere") or add an
inline/style rule like "word-break: break-all; overflow-wrap: anywhere;" so long
addresses wrap on narrow screens.
- Around line 720-722: The catch block that currently only calls
console.error('failed to load status', e) must also set a safe fallback status
value so the UI doesn't remain stuck on "Loading balance…"; inside the catch (e)
(and also when response.ok is false) update the same status state/DOM used by
the hero card (e.g., call the function or assign the variable that normally
receives the successful fetch result—look for the state setter or element update
near the fetch call, or the text "Loading balance…") to a stable fallback like
"Unavailable" or "Error loading balance" so the hero card always renders a
definite status.

In `@src/index.py`:
- Around line 38-42: The ord-server response is a JsProxy so the
isinstance(body, dict) check fails; change the fetch handling in src/index.py to
convert the JS proxy to native Python before type-checking (e.g. replace body =
await resp.json() with body = (await resp.json()).to_py() or parse via
json.loads(await resp.text())), then keep the existing logic that checks
body.get('success') and sets data['balance'] (referencing js.fetch, resp.json,
to_py, and data['balance']).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: OWASP-BLT/coderabbit/.coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 391b362a-30c1-44e9-88c1-60e4b94775ab

📥 Commits

Reviewing files that changed from the base of the PR and between 7baa703 and ab86ff2.

📒 Files selected for processing (2)
  • public/index.html
  • src/index.py

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: 1

♻️ Duplicate comments (3)
public/index.html (2)

99-100: ⚠️ Potential issue | 🟡 Minor

Allow treasury addresses to wrap.

Long wallet strings will overflow this card on narrow screens once TREASURY_ADDRESS is populated.

Proposed fix
-                        <p id="chain-address" class="text-xs text-gray-500"></p>
+                        <p id="chain-address" class="text-xs text-gray-500 break-all"></p>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@public/index.html` around lines 99 - 100, The wallet address paragraph with
id "chain-address" is overflowing on narrow screens; update the element to allow
wrapping by adding appropriate CSS/Tailwind utilities (e.g., add classes like
"whitespace-normal break-words" or "break-all" to the <p id="chain-address">
element) so long addresses wrap instead of overflowing the card, and ensure no
parent class (e.g., "whitespace-nowrap" or "overflow-visible") prevents
wrapping.

699-722: ⚠️ Potential issue | 🟡 Minor

Replace the loading placeholder when /api/status fails.

If the request rejects or returns non-2xx, the hero card stays on Loading balance… indefinitely. Set a stable fallback in the error path too.

Proposed fix
         async function updateStatus() {
             try {
                 const res = await fetch('/api/status');
                 if (!res.ok) throw new Error('network');
                 const data = await res.json();
                 const iconEl = document.getElementById('chain-icons');
                 const balEl = document.getElementById('chain-balance');
                 if (iconEl && data.chains) {
                     iconEl.innerHTML = data.chains.map(c => {
                         const lc = c.toLowerCase();
                         if (lc === 'bitcoin') return '<i class="fab fa-bitcoin"></i>';
                         if (lc === 'solana') return '<i class="fas fa-circle text-purple-500"></i>';
                         return c;
                     }).join(' + ');
                 }
                 if (balEl) {
                     balEl.textContent = data.balance !== undefined ? `Balance: ${data.balance}` : 'Balance: N/A';
                 }
                 const addrEl = document.getElementById('chain-address');
                 if (addrEl) {
                     addrEl.textContent = data.address ? `Address: ${data.address}` : '';
                 }
             } catch (e) {
+                const balEl = document.getElementById('chain-balance');
+                const addrEl = document.getElementById('chain-address');
+                if (balEl) balEl.textContent = 'Balance: N/A';
+                if (addrEl) addrEl.textContent = '';
                 console.error('failed to load status', e);
             }
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@public/index.html` around lines 699 - 722, When the fetch in the
status-loading script fails or returns non-2xx the catch block currently only
logs the error and leaves the UI showing "Loading balance…"; update the catch
path to set stable fallback text/icons so the hero card doesn't hang: in the
same async fetch/try block that reads document.getElementById('chain-icons'),
'chain-balance', and 'chain-address', ensure the catch handler assigns a
sensible fallback (e.g., generic icon or plain chain names to 'chain-icons',
'Balance: N/A' to 'chain-balance', and '' or 'Address: N/A' to 'chain-address')
so the UI is replaced on error as well.
src/index.py (1)

38-42: ⚠️ Potential issue | 🟠 Major

Convert the ord-server JSON body before the dict check.

Line 40 still assigns the result of await resp.json() directly, so the isinstance(body, dict) guard on Line 41 can miss valid ord-server responses and keep the homepage balance stuck at 0. Parse the response into native Python objects first.

Proposed fix
                 resp = await js.fetch(ord_url)
                 if resp.ok:
-                    body = await resp.json()
+                    body = json.loads(await resp.text())
                     if isinstance(body, dict) and body.get('success'):
                         data['balance'] = body.get('balance', data['balance'])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/index.py` around lines 38 - 42, The response body from js.fetch is a JS
value so keep converting it to a native Python dict before the isinstance check:
replace using await resp.json() directly with parsing the text into Python (e.g.
text = await resp.text(); body = json.loads(text)) or otherwise convert the JS
object to Python (pyodide.to_py(resp_json)) so that the isinstance(body, dict)
and subsequent access to data['balance'] work correctly; update the block around
resp.json(), resp.text(), body and the existing data['balance'] assignment to
use the converted Python object.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CONTRIBUTING.md`:
- Around line 117-122: Update the Wrangler Variables section to include
ORD_SERVER_URL_MAINNET and TREASURY_ADDRESS and instruct users to define them
either under [vars] in wrangler.toml or via the Cloudflare Workers Dashboard;
note that src/index.py reads these via getattr/hasattr so they must exist in the
deployed Worker env to avoid the /api/status fallback balance of 0 and missing
address.

---

Duplicate comments:
In `@public/index.html`:
- Around line 99-100: The wallet address paragraph with id "chain-address" is
overflowing on narrow screens; update the element to allow wrapping by adding
appropriate CSS/Tailwind utilities (e.g., add classes like "whitespace-normal
break-words" or "break-all" to the <p id="chain-address"> element) so long
addresses wrap instead of overflowing the card, and ensure no parent class
(e.g., "whitespace-nowrap" or "overflow-visible") prevents wrapping.
- Around line 699-722: When the fetch in the status-loading script fails or
returns non-2xx the catch block currently only logs the error and leaves the UI
showing "Loading balance…"; update the catch path to set stable fallback
text/icons so the hero card doesn't hang: in the same async fetch/try block that
reads document.getElementById('chain-icons'), 'chain-balance', and
'chain-address', ensure the catch handler assigns a sensible fallback (e.g.,
generic icon or plain chain names to 'chain-icons', 'Balance: N/A' to
'chain-balance', and '' or 'Address: N/A' to 'chain-address') so the UI is
replaced on error as well.

In `@src/index.py`:
- Around line 38-42: The response body from js.fetch is a JS value so keep
converting it to a native Python dict before the isinstance check: replace using
await resp.json() directly with parsing the text into Python (e.g. text = await
resp.text(); body = json.loads(text)) or otherwise convert the JS object to
Python (pyodide.to_py(resp_json)) so that the isinstance(body, dict) and
subsequent access to data['balance'] work correctly; update the block around
resp.json(), resp.text(), body and the existing data['balance'] assignment to
use the converted Python object.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: OWASP-BLT/coderabbit/.coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 9d818265-a012-476f-b18b-b5f95b9f52e6

📥 Commits

Reviewing files that changed from the base of the PR and between 715c91e and ab86ff2.

📒 Files selected for processing (4)
  • .env.example
  • CONTRIBUTING.md
  • public/index.html
  • src/index.py

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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/index.py`:
- Around line 34-38: The ord-server fetch in the try block uses
js.fetch(ord_url) without a timeout which can hang; update the call in the
function handling /api/status (where ord_url is set) to pass an AbortSignal
timeout to js.fetch (use AbortSignal.timeout with a suitable ms, e.g., 5000) and
wrap the fetch so that timeouts/errors are caught and handled the same as other
failures (returning the default 0 balance). Ensure you import or reference
AbortSignal from js and adjust error handling around the fetch/resp parsing to
treat a timeout exception identically to other fetch errors.
- Around line 41-49: After calling body = await resp.json(), don't attempt to
reread the response body with await resp.text(); instead check whether the
parsed body object supports a to_py() method and call body = body.to_py() only
if that attribute exists, otherwise treat the parsed JSON as already usable; if
await resp.json() itself raises, set body = {} (do not call resp.text()). Update
the logic around resp and body (and the to_py() call) to remove the nested await
resp.text() fallback and only perform to_py() when present.
🪄 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: Repository: OWASP-BLT/coderabbit/.coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 77910c01-7dc8-4182-83a4-a8ffa1fcba75

📥 Commits

Reviewing files that changed from the base of the PR and between ab86ff2 and 309fe88.

📒 Files selected for processing (1)
  • src/index.py

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.

♻️ Duplicate comments (1)
src/index.py (1)

44-52: ⚠️ Potential issue | 🟠 Major

Response body is consumed; await resp.text() fallback will always fail.

After await resp.json() on line 43, the response body stream is consumed. The fallback on line 50 that calls await resp.text() will always fail because the body cannot be read twice. This means the nested exception handler just falls through to body = {}, losing any valid data that resp.json() might have returned.

🐛 Proposed fix
                 if resp.ok:
                     # convert JS proxy object to native Python dict
                     body = await resp.json()
-                    try:
-                        body = body.to_py()
-                    except Exception:
-                        # fallback: treat as dict or empty
-                        if not isinstance(body, dict):
-                            try:
-                                body = json.loads(await resp.text())
-                            except Exception:
-                                body = {}
+                    if hasattr(body, 'to_py'):
+                        body = body.to_py()
+                    elif not isinstance(body, dict):
+                        body = {}
                     if isinstance(body, dict) and body.get('success'):
                         data['balance'] = body.get('balance', data['balance'])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/index.py` around lines 44 - 52, The response body is being read twice
(resp.json() then await resp.text()), which consumes the stream and makes the
fallback always fail; fix by reading the response once into a raw variable
(e.g., raw_text = await resp.text()) before any parsing, then attempt to parse
raw_text into JSON or a structured object and only call body.to_py() if the
parsed object has that method; update the logic around resp, resp.json(), body
and to_py() to use the single saved raw_text instead of re-calling await
resp.text() so we don't lose valid data.
🧹 Nitpick comments (2)
src/index.py (2)

38-38: Minor: Comment contains non-breaking hyphen.

The comment uses a non-breaking hyphen () instead of a regular hyphen-minus (-). This is flagged by the linter (RUF003).

♻️ Fix the hyphen character
-                # add 5‑second timeout to avoid hanging
+                # add 5-second timeout to avoid hanging
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/index.py` at line 38, The inline comment "add 5‑second timeout to avoid
hanging" contains a non‑breaking hyphen character; replace it with a normal
hyphen-minus so it reads "add 5-second timeout to avoid hanging" to satisfy the
linter (RUF003) — update the comment in src/index.py where that text appears
(near the timeout logic) to use the regular '-' character.

55-60: Consider simplifying exception handling.

The nested try-except-pass around js.console.error silently swallows any logging failures. While defensive, this pattern makes debugging harder. If js.console is reliably available in Cloudflare Workers Python, the inner try-except can be removed.

♻️ Optional simplification
         except Exception as e:
             # log failure so we can debug if ord-server is unreachable or timeout
-            try:
-                js.console.error('status fetch failed', str(e))
-            except Exception:
-                pass
+            js.console.error('status fetch failed', str(e))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/index.py` around lines 55 - 60, In the except block catching Exception as
e, remove the nested try/except that swallows logging failures and call
js.console.error directly (i.e., replace the inner try/except/pass with
js.console.error('status fetch failed', str(e))); this keeps the original error
visible via js.console.error in src/index.py and avoids silently discarding
logging errors from the js.console.error call.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/index.py`:
- Around line 44-52: The response body is being read twice (resp.json() then
await resp.text()), which consumes the stream and makes the fallback always
fail; fix by reading the response once into a raw variable (e.g., raw_text =
await resp.text()) before any parsing, then attempt to parse raw_text into JSON
or a structured object and only call body.to_py() if the parsed object has that
method; update the logic around resp, resp.json(), body and to_py() to use the
single saved raw_text instead of re-calling await resp.text() so we don't lose
valid data.

---

Nitpick comments:
In `@src/index.py`:
- Line 38: The inline comment "add 5‑second timeout to avoid hanging" contains a
non‑breaking hyphen character; replace it with a normal hyphen-minus so it reads
"add 5-second timeout to avoid hanging" to satisfy the linter (RUF003) — update
the comment in src/index.py where that text appears (near the timeout logic) to
use the regular '-' character.
- Around line 55-60: In the except block catching Exception as e, remove the
nested try/except that swallows logging failures and call js.console.error
directly (i.e., replace the inner try/except/pass with js.console.error('status
fetch failed', str(e))); this keeps the original error visible via
js.console.error in src/index.py and avoids silently discarding logging errors
from the js.console.error call.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: OWASP-BLT/coderabbit/.coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 882359db-1acd-49ab-8047-7e40a6399b6f

📥 Commits

Reviewing files that changed from the base of the PR and between 309fe88 and f8ef912.

📒 Files selected for processing (1)
  • src/index.py

Copy link
Copy Markdown

@Jayant2908 Jayant2908 left a comment

Choose a reason for hiding this comment

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

Code looks good, could you add a screenshot with some dummy values!?

@stealthwhizz
Copy link
Copy Markdown
Contributor Author

@Jayant2908 is this fine
image

Comment out the treasury address check and hardcode the address.
Copy link
Copy Markdown
Collaborator

@DonnieBLT DonnieBLT left a comment

Choose a reason for hiding this comment

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

can we use a public free api to view the balance?

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: 1

♻️ Duplicate comments (1)
src/index.py (1)

43-52: ⚠️ Potential issue | 🟠 Major

Don't reread resp after resp.json().

If to_py() ever fails here, the resp.text() fallback cannot recover because resp.json() has already consumed the body. That path just collapses back to {} and keeps the homepage at the default 0 balance. Fetch bodies are single-read, and the Workers Python FFI expects JS objects to be converted in place via JsProxy.to_py(). (developer.mozilla.org)

🐛 Proposed fix
                 if resp.ok:
                     # convert JS proxy object to native Python dict
                     body = await resp.json()
-                    try:
-                        body = body.to_py()
-                    except Exception:
-                        # fallback: treat as dict or empty
-                        if not isinstance(body, dict):
-                            try:
-                                body = json.loads(await resp.text())
-                            except Exception:
-                                body = {}
+                    if hasattr(body, 'to_py'):
+                        body = body.to_py()
+                    elif not isinstance(body, dict):
+                        body = {}
                     if isinstance(body, dict) and body.get('success'):
                         data['balance'] = body.get('balance', data['balance'])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/index.py` around lines 43 - 52, The code currently calls await
resp.json() then, if body.to_py() raises, attempts to call await resp.text(),
but resp.json() has already consumed the stream so resp.text() cannot recover;
change the fallback so we never reread resp: call body = await resp.json(), then
try body.to_py(); if to_py() fails, do not call resp.text() — instead keep the
original JS proxy (body) or set body = {} (or a safe default) depending on
expected schema; remove the resp.text() branch and ensure all handling uses the
variables/body produced by resp.json() and body.to_py() (referencing
resp.json(), body.to_py(), and resp.text() to locate the code).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/index.py`:
- Around line 62-65: Replace the hardcoded wallet address with the configured
TREASURY_ADDRESS: check the environment binding (env) for TREASURY_ADDRESS and
set data['address'] = env.TREASURY_ADDRESS when present, otherwise fall back to
the existing constant; update the block around data['address'] in src/index.py
(the code that currently assigns "mntjJdX..." and the commented hasattr check)
to perform this conditional assignment so /api/status advertises the configured
address.

---

Duplicate comments:
In `@src/index.py`:
- Around line 43-52: The code currently calls await resp.json() then, if
body.to_py() raises, attempts to call await resp.text(), but resp.json() has
already consumed the stream so resp.text() cannot recover; change the fallback
so we never reread resp: call body = await resp.json(), then try body.to_py();
if to_py() fails, do not call resp.text() — instead keep the original JS proxy
(body) or set body = {} (or a safe default) depending on expected schema; remove
the resp.text() branch and ensure all handling uses the variables/body produced
by resp.json() and body.to_py() (referencing resp.json(), body.to_py(), and
resp.text() to locate the code).
🪄 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: Repository: OWASP-BLT/coderabbit/.coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 300b7313-7d74-4429-a416-fd5349a5476a

📥 Commits

Reviewing files that changed from the base of the PR and between f8ef912 and bdf27d1.

📒 Files selected for processing (1)
  • src/index.py

Comment on lines +62 to +65
#if hasattr(env, 'TREASURY_ADDRESS'):
# data['address'] = env.TREASURY_ADDRESS
# tmp hardcode address
data['address'] = "mntjJdXMvLkALMnyYFsdvxUnFXjLzLPpiNQwQSC58BL"
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

Use TREASURY_ADDRESS instead of the temporary constant.

This block ignores the configured binding, so every environment advertises the same wallet address even when TREASURY_ADDRESS is set. That makes /api/status easy to misconfigure across staging and prod.

🐛 Proposed fix
-        `#if` hasattr(env, 'TREASURY_ADDRESS'):
-        #    data['address'] = env.TREASURY_ADDRESS
-        # tmp hardcode address
-        data['address'] = "mntjJdXMvLkALMnyYFsdvxUnFXjLzLPpiNQwQSC58BL"
+        data['address'] = (
+            getattr(env, 'TREASURY_ADDRESS', None)
+            or "mntjJdXMvLkALMnyYFsdvxUnFXjLzLPpiNQwQSC58BL"
+        )
📝 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
#if hasattr(env, 'TREASURY_ADDRESS'):
# data['address'] = env.TREASURY_ADDRESS
# tmp hardcode address
data['address'] = "mntjJdXMvLkALMnyYFsdvxUnFXjLzLPpiNQwQSC58BL"
data['address'] = (
getattr(env, 'TREASURY_ADDRESS', None)
or "mntjJdXMvLkALMnyYFsdvxUnFXjLzLPpiNQwQSC58BL"
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/index.py` around lines 62 - 65, Replace the hardcoded wallet address with
the configured TREASURY_ADDRESS: check the environment binding (env) for
TREASURY_ADDRESS and set data['address'] = env.TREASURY_ADDRESS when present,
otherwise fall back to the existing constant; update the block around
data['address'] in src/index.py (the code that currently assigns "mntjJdX..."
and the commented hasattr check) to perform this conditional assignment so
/api/status advertises the configured address.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Ready

Development

Successfully merging this pull request may close these issues.

4 participants