feat: add stealth address#18
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
components/one/payment-card.tsx (1)
1339-1361: 🧹 Nitpick | 🔵 Trivial | 💤 Low valueStale dependency:
isValidReceiveris in deps but not used in callback body.The guard at lines 1251-1252 checks
isStealthReceiverandresolvedReceiverdirectly rather than usingisValidReceiver. SinceisValidReceiveris derived from those values, this is functionally correct but the dependency is misleading. Consider either:
- Remove
isValidReceiverfrom deps (it's derived from values already in deps)- Use
isValidReceiverin the guard:if (!isValidReceiver) return;Option 2 is cleaner and more explicit:
Suggested fix
const handleSend = useCallback(async () => { if (!publicKey || !signTransaction || !connected) return; - if (isResolvingRecipient) return; - if (!isStealthReceiver && !resolvedReceiver) return; + if (isResolvingRecipient || !isValidReceiver) return; if (!rawAmount || rawAmount === "0") return;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/one/payment-card.tsx` around lines 1339 - 1361, The dependency list includes isValidReceiver but the effect body checks isStealthReceiver and resolvedReceiver directly; update the effect callback so it uses isValidReceiver in the guard (e.g., replace the current checks with if (!isValidReceiver) return;) and keep isValidReceiver in the dependency array, ensuring the effect's logic references the derived value rather than the underlying pieces (symbols to change: isValidReceiver, isStealthReceiver, resolvedReceiver inside the useEffect callback and the dependency array near the closing bracket).components/one/trade-hub.tsx (1)
179-230: 🧹 Nitpick | 🔵 TrivialAlign
hquery param usage withHandleCardbehavior
trade-hub.tsxtreats the presence of thehquery param as a signal to activate thehandletab (hasHandleSelection = Boolean(searchParams.get("h"))), butHandleCardnever readssearchParams.get("h")and instead initializeshandlefromgetStoredStealthHandle(owner).
Ifhis meant for deep-linking a specific handle, parsesearchParams.get("h")inHandleCardand use it to pre-populate the input; otherwise remove/rename this “unused” query-param detection to avoid implying the value is consumed.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/one/trade-hub.tsx` around lines 179 - 230, trade-hub.tsx currently treats the presence of the "h" query param (hasHandleSelection = Boolean(searchParams.get("h"))) as selecting the handle tab but HandleCard ignores that param and instead uses getStoredStealthHandle(owner); fix by wiring the "h" deep-link into HandleCard: read searchParams.get("h") (or accept it as a prop from trade-hub) and, in HandleCard's initialization logic (where it currently calls getStoredStealthHandle(owner)), prefer the parsed "h" value to pre-populate the input/selection (falling back to getStoredStealthHandle(owner) when "h" is absent); alternatively, if "h" is not intended as a deep-link, remove/rename the Boolean(searchParams.get("h")) check in trade-hub (updateTabUrl/hasHandleSelection) to stop implying consumption — reference symbols: hasHandleSelection, searchParams.get("h"), HandleCard, getStoredStealthHandle(owner), and updateTabUrl.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/api/payments/send/route.ts`:
- Around line 78-89: Wrap the call to request.json() in a try/catch and return
an HTTP 400 response for malformed JSON instead of letting it bubble to the
generic 502; specifically, around the code that assigns body and destructures
signedTransaction, blockhash, lastValidBlockHeight, sendTo (and the similar
block later around the other request.json() usage), catch a SyntaxError (or any
parse error) and return a Response with status 400 and a short error message
indicating invalid JSON payload so clients receive a proper client error.
In `@app/api/payments/stealth-pool/route.ts`:
- Around line 76-82: The auth header check using authHeader?.startsWith("Bearer
") is case-sensitive and should accept any casing of the scheme; update the
logic in route.ts where authHeader is read (variable authHeader) and the
startsWith check to perform a case-insensitive match (e.g., test the scheme
portion with toLowerCase() === "bearer" or use a case-insensitive regex like
/^bearer\s+/i), then extract the token after the scheme safely (split on
whitespace and use the second element) and return the same 401 response if the
scheme is not "bearer" or the token is missing.
In `@lib/payment-transactions.ts`:
- Around line 138-147: The POST fetches to "/api/payments/send" (the call that
sends serializeSignedPaymentTransaction(signedTransaction) and
unsignedTransaction fields) need a client-side timeout to avoid hanging; wrap
each fetch in an AbortController with a setTimeout that calls controller.abort()
after a configurable timeout (e.g. 10s), pass controller.signal to fetch, and
clear the timeout on success; also handle the abort by catching the thrown
DOMException/AbortError and surface a clear error (or return a timeout-specific
error) so callers of this payment flow can recover.
In `@lib/stealth-handles.ts`:
- Around line 25-27: The setter setStoredStealthHandle currently writes directly
to localStorage and can throw in restricted environments; update it to mirror
the getter’s safety guards by checking for a window/localStorage environment
(e.g., typeof window !== 'undefined' and window.localStorage) and wrapping the
write in a try/catch, using STORAGE_PREFIX to build the key and swallowing or
logging errors instead of allowing exceptions to propagate from
localStorage.setItem.
In `@README.md`:
- Line 34: Update the README line describing `PAYMENTS_EPHEMERAL_RPC_URL` and
`EPHEMERAL_RPC_URL` to expand the "ER" acronym for clarity—replace or augment
"ER" with "Ephemeral RPC" (or "Ephemeral RPC (ER)") so the sentence reads
something like: "`PAYMENTS_EPHEMERAL_RPC_URL` or `EPHEMERAL_RPC_URL`: ephemeral
RPC (ER) used when signed transactions must be submitted to Ephemeral RPC."
Reference the environment variable names `PAYMENTS_EPHEMERAL_RPC_URL` and
`EPHEMERAL_RPC_URL` when making the change.
- Line 34: Update the README description for the PAYMENTS_EPHEMERAL_RPC_URL and
EPHEMERAL_RPC_URL entries to state that Bearer authentication is required when
submitting signed transactions to the ephemeral RPC; explicitly note that
requests must include an Authorization: Bearer <token> header (or equivalent)
and mention that users must obtain/configure a valid token when setting those
environment variables so the endpoint will accept submissions.
- Around line 51-52: Remove the unintended trailing blank line after the
sentence describing the Handle tab so the paragraph ends immediately after
"private stealth-transfer route."; locate the sentence containing "Handle tab"
and ".block" and delete the empty line following it to clean up the README
formatting.
---
Outside diff comments:
In `@components/one/payment-card.tsx`:
- Around line 1339-1361: The dependency list includes isValidReceiver but the
effect body checks isStealthReceiver and resolvedReceiver directly; update the
effect callback so it uses isValidReceiver in the guard (e.g., replace the
current checks with if (!isValidReceiver) return;) and keep isValidReceiver in
the dependency array, ensuring the effect's logic references the derived value
rather than the underlying pieces (symbols to change: isValidReceiver,
isStealthReceiver, resolvedReceiver inside the useEffect callback and the
dependency array near the closing bracket).
In `@components/one/trade-hub.tsx`:
- Around line 179-230: trade-hub.tsx currently treats the presence of the "h"
query param (hasHandleSelection = Boolean(searchParams.get("h"))) as selecting
the handle tab but HandleCard ignores that param and instead uses
getStoredStealthHandle(owner); fix by wiring the "h" deep-link into HandleCard:
read searchParams.get("h") (or accept it as a prop from trade-hub) and, in
HandleCard's initialization logic (where it currently calls
getStoredStealthHandle(owner)), prefer the parsed "h" value to pre-populate the
input/selection (falling back to getStoredStealthHandle(owner) when "h" is
absent); alternatively, if "h" is not intended as a deep-link, remove/rename the
Boolean(searchParams.get("h")) check in trade-hub
(updateTabUrl/hasHandleSelection) to stop implying consumption — reference
symbols: hasHandleSelection, searchParams.get("h"), HandleCard,
getStoredStealthHandle(owner), and updateTabUrl.
🪄 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: 7c3a5f0a-cd29-4850-95db-292ec60713a7
📒 Files selected for processing (13)
README.mdapp/api/payments/send/route.tsapp/api/payments/stealth-pool/route.tsapp/api/payments/transfer-queue/ensure-crank/route.tsapp/api/payments/transfer-stealth/route.tscomponents/one/handle-card.tsxcomponents/one/payment-card.tsxcomponents/one/swap-card.tsxcomponents/one/trade-hub.tsxlib/payment-transactions.tslib/payments.tslib/solana-rpc.tslib/stealth-handles.ts

Summary by CodeRabbit
New Features
Documentation