Skip to content

Feature/recent escrow events#51

Open
bitstarkbridge wants to merge 5 commits intoTrustless-Work:mainfrom
bitstarkbridge:feature/recent-escrow-events
Open

Feature/recent escrow events#51
bitstarkbridge wants to merge 5 commits intoTrustless-Work:mainfrom
bitstarkbridge:feature/recent-escrow-events

Conversation

@bitstarkbridge
Copy link

@bitstarkbridge bitstarkbridge commented Jan 22, 2026

#43 close

Summary by CodeRabbit

  • New Features

    • Network switching in escrow details and network-aware transaction/detail views
    • Recent contract events panel with loading, empty and error states
    • Retry and “switch network” actions surfaced on error messages
  • Bug Fixes

    • Stronger contract ID validation with clearer user-facing errors
    • More robust handling when ledger entries are missing
  • Improvements

    • Centralized RPC proxy endpoint and updated mainnet RPC URL
    • Network-aware example contracts in welcome state

✏️ Tip: You can customize this high-level summary in your review settings.

- Implement useRecentEvents hook to fetch Soroban contract events via Stellar RPC
- Add Recent Contract Events section in Transaction History view
- Display events with type, ledger, ID, topics, and value (base64)
- Handle loading, error, and empty states
- Include disclosure about 7-day RPC limitation
- Events ordered most recent first
@vercel
Copy link
Contributor

vercel bot commented Jan 22, 2026

@bitstarkbridge is attempting to deploy a commit to the Trustless Work Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Jan 22, 2026

📝 Walkthrough

Walkthrough

Adds a POST RPC proxy route and threads network selection across data-fetching utilities and UI, introduces a new useRecentEvents hook, updates escrow components for network-aware behavior and error handling, and adjusts network configuration and RPC call targets.

Changes

Cohort / File(s) Summary
RPC Proxy
src/app/api/rpc/route.ts
New Next.js App Router POST endpoint that validates network ('testnet'
Network config
src/lib/network-config.ts
Updated NETWORK_CONFIGS.mainnet.rpcUrl to https://soroban-mainnet.stellar.org; removed getStellarLabUrl and deleted default-network body.
Event hook
src/hooks/useRecentEvents.ts
New hook exposing events, loading, error, and refetch; fetches latest ledger and contract events via the /api/rpc proxy, maps and sorts events.
Escrow data & validation
src/hooks/useEscrowData.ts
Added isValidContractId validation (56-char base32), pre-fetch validation that sets contextual errors and clears data on invalid / no-data results.
Transaction & ledger utils
src/utils/transactionFetcher.ts, src/utils/ledgerkeycontract.ts
Added network parameter to fetch functions; replaced direct RPC URLs with /api/rpc proxy calls including network in request body; ledger lookup now returns empty EscrowMap on missing entry.
Escrow UI (details + modal)
src/components/escrow/EscrowDetails.tsx, src/components/escrow/TransactionDetailModal.tsx
Integrated useRecentEvents; added network switching (via useNetwork().setNetwork) and URL updates; threaded network to transaction fetches and passed network prop into TransactionDetailModal.
Escrow UI (errors, welcome, content)
src/components/escrow/error-display.tsx, src/components/escrow/escrow-content.tsx, src/components/escrow/welcome-state.tsx
ErrorDisplay now accepts onSwitchNetwork and onRetry, parses multi-line errors, suggests network switch buttons; WelcomeState accepts network and selects example IDs per network; escrow-content passes current network through views.
Theme toggle
src/components/ui/theme-toggle.tsx
Removed client-side synchronous theme state/read/write logic and related DOM mutations; component simplified (internal state logic largely removed).

Sequence Diagram(s)

sequenceDiagram
    participant Component as EscrowDetails
    participant Hook as useRecentEvents
    participant Proxy as /api/rpc (proxy)
    participant StellarRPC as Stellar RPC

    Component->>Hook: call useRecentEvents(contractId, network)
    activate Hook
    Hook->>Proxy: POST { method: "getLatestLedger", network }
    activate Proxy
    Proxy->>StellarRPC: getLatestLedger()
    StellarRPC-->>Proxy: { endLedger }
    Proxy-->>Hook: { endLedger }
    deactivate Proxy

    Note over Hook: compute startLedger (~7 days prior)

    Hook->>Proxy: POST { method: "getEvents", params: { contractId, startLedger, endLedger }, network }
    activate Proxy
    Proxy->>StellarRPC: getEvents(filters)
    StellarRPC-->>Proxy: events[]
    Proxy-->>Hook: events[]
    deactivate Proxy

    Hook-->>Component: { events, loading, error, refetch }
    deactivate Hook
Loading
sequenceDiagram
    participant User as User
    participant Component as EscrowDetails
    participant Hook as useEscrowData
    participant Proxy as /api/rpc (proxy)

    User->>Component: open contractId view
    Component->>Hook: useEscrowData(contractId, network)
    activate Hook
    Hook->>Hook: validate contractId (56-char base32)
    alt invalid
        Hook-->>Component: set error (invalid id)
    else valid
        Hook->>Proxy: POST { method: "getLedgerKeyContractCode", params:{contractId}, network }
        activate Proxy
        Proxy->>StellarRPC: getLedgerKeyContractCode(...)
        StellarRPC-->>Proxy: data or empty
        Proxy-->>Hook: data / []
        deactivate Proxy
        alt data found
            Hook-->>Component: set data
        else no data
            Hook-->>Component: set contextual error (suggest network)
        end
    end
    deactivate Hook

    alt error shown
        Component->>Component: render ErrorDisplay(error, onSwitchNetwork, onRetry)
        User->>Component: click "Switch to Testnet/Mainnet"
        Component-->>Hook: setNetwork(network) + refresh flows
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • techrebelgit

Poem

🐰
I hopped to wire networks anew,
Proxy in paw and events in view,
Ledgers I chased, seven days bright,
Switched with a button, everything right,
Hop, fetch, repeat — rejoice in the new hue!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feature/recent escrow events' directly aligns with the main objective of the PR, which implements a new feature to display recent contract events in the escrow viewer.

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

✨ Finishing touches
  • 📝 Generate docstrings

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

@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

Caution

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

⚠️ Outside diff range comments (2)
src/components/escrow/TransactionDetailModal.tsx (1)

159-174: Inconsistent network usage in explorer links.

Line 163 uses process.env.NEXT_PUBLIC_STELLAR_NETWORK || 'testnet' for the explorer URL, while line 171 hardcodes 'testnet'. Both should use the network prop passed to this component for consistency.

🔧 Proposed fix
                       <Button
                         variant="ghost"
                         size="sm"
                         className="h-8 w-8 p-0"
-                        onClick={() => window.open(`https://stellar.expert/explorer/${process.env.NEXT_PUBLIC_STELLAR_NETWORK || 'testnet'}/tx/${details.txHash}`, "_blank")}
+                        onClick={() => copyToClipboard(details.txHash)}
                       >
                         <Copy className="h-4 w-4" />
                       </Button>
                       <Button
                         variant="ghost"
                         size="sm"
                         className="h-8 w-8 p-0"
-                        onClick={() => window.open(`https://stellar.expert/explorer/testnet/tx/${details.txHash}`, "_blank")}
+                        onClick={() => window.open(`https://stellar.expert/explorer/${network}/tx/${details.txHash}`, "_blank")}
                       >
                         <ExternalLink className="h-4 w-4" />
                       </Button>

Note: The first button also appears to open an external link instead of copying—it should call copyToClipboard(details.txHash) based on the Copy icon.

src/components/escrow/EscrowDetails.tsx (1)

196-221: Remove or disable debug logging before merge.

The DEBUG = true flag with multiple console.log statements should be removed or disabled for production. Consider using a proper logging utility with environment-based log levels instead.

🔧 Proposed fix
-// === DEBUG LOGGING (EscrowDetails) ===
-const DEBUG = true;
-
-useEffect(() => {
-  if (!DEBUG) return;
-  console.log("[DBG][EscrowDetails] network:", currentNetwork);
-  console.log("[DBG][EscrowDetails] contractId:", contractId);
-}, [currentNetwork, contractId]);
-
-useEffect(() => {
-  if (!DEBUG) return;
-  console.log("[DBG][EscrowDetails] raw escrow map:", raw);
-}, [raw]);
-
-useEffect(() => {
-  if (!DEBUG) return;
-  console.log("[DBG][EscrowDetails] organized data:", organized);
-}, [organized]);
-
-useEffect(() => {
-  if (!DEBUG) return;
-  console.log("[DBG][EscrowDetails] token live balance:", {
-    ledgerBalance,
-    decimals,
-    mismatch,
-  });
-}, [ledgerBalance, decimals, mismatch]);
🤖 Fix all issues with AI agents
In `@src/components/escrow/error-display.tsx`:
- Around line 17-25: The network-switch detection in error-display.ts currently
looks for "Try switching to" (via parts.find -> switchSuggestion) so the switch
button never appears because useEscrowData.ts errors don't contain that phrase;
update the detection in error-display.ts to also match the actual messages
(e.g., check parts for substrings like "different network", "not be deployed",
or "contract exists on a different network") and map those matches to
targetNetwork ('testnet' | 'mainnet') accordingly, or alternatively add matching
"Try switching to testnet"/"Try switching to mainnet" suggestions in
useEscrowData.ts so the existing parts.find logic can succeed.

In `@src/hooks/useRecentEvents.ts`:
- Around line 91-105: The mappedEvents mapping in useRecentEvents.ts can set
topics to undefined when event.topic is missing; update the mapping in the
mappedEvents creation (the arrow mapping over eventsData.result?.events) to
ensure topics is always a string[] by replacing event.topic with a safe fallback
(e.g., event.topic ?? [] or Array.isArray(event.topic) ? event.topic : []) so
that ContractEvent.topics is never undefined.
- Around line 51-52: Check and handle malformed RPC responses before accessing
nested fields: after awaiting latestLedgerResponse.json() verify
latestLedgerResponse.ok and that latestLedgerData and latestLedgerData.result
exist and that latestLedgerData.result.sequence is a valid number; if any check
fails, handle gracefully (return early, set endLedger to null/undefined, or
throw a descriptive error) instead of directly using
latestLedgerData.result.sequence. Update the logic around latestLedgerResponse,
latestLedgerData and endLedger in useRecentEvents.ts to include these null/ok
checks and a clear fallback path.
🧹 Nitpick comments (2)
src/hooks/useRecentEvents.ts (1)

54-56: Consider documenting the ledger calculation.

The ~5 seconds per ledger assumption is reasonable for Stellar, but this value can vary. A brief inline comment noting this is an approximation would help future maintainers.

src/components/escrow/error-display.tsx (1)

38-45: Consider using a stable key instead of index.

Using index as a React key works here since the error list is static and won't reorder, but a stable key derived from content would be slightly better.

-                  {parts.slice(1).map((line, index) => (
-                    <li key={index}>{line}</li>
+                  {parts.slice(1).map((line) => (
+                    <li key={line}>{line}</li>
                   ))}

Copy link

@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

Caution

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

⚠️ Outside diff range comments (2)
src/lib/network-config.ts (1)

29-31: Return a default network value (or remove the export).

This function currently returns undefined, violating the declared return type and breaking callers at runtime/compile time.

🛠️ Proposed fix
 export function getDefaultNetwork(): NetworkType {
-  
+  return 'testnet';
 } 
src/components/escrow/EscrowDetails.tsx (1)

13-13: Build break: getStellarLabUrl is no longer exported.

getStellarLabUrl was removed from src/lib/network-config.ts, so this import/usage will fail. Either restore the helper or replace it with the new URL-building approach.

Also applies to: 294-296

🤖 Fix all issues with AI agents
In `@src/components/ui/theme-toggle.tsx`:
- Around line 6-18: The ThemeToggle component is missing state and theme-apply
logic: declare state like isDark and setIsDark (via useState) and a mounted flag
(via useState/useEffect) inside ThemeToggle, restore the first useEffect to
initialize isDark from persisted preference (e.g., localStorage or
window.matchMedia) and set mounted=true, implement the second useEffect to
add/remove the theme class on document.documentElement based on isDark and
mounted, and update the toggle handler to call setIsDark and persist the new
preference; use the symbols ThemeToggle, isDark, setIsDark, mounted, toggle, and
the two useEffect blocks to place these fixes.
🧹 Nitpick comments (1)
src/components/escrow/EscrowDetails.tsx (1)

33-36: Consider deferring recent-events RPC until the panel is shown.

useRecentEvents runs on every page load, even when the Recent Contract Events panel is hidden, adding extra RPC calls. Consider adding an enabled flag or gating by showOnlyTransactions to reduce load.

Also applies to: 82-87, 382-458

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