Skip to content

feat: view latest transactions#133

Merged
MicBun merged 1 commit intomainfrom
viewLatestTransaction
Oct 26, 2025
Merged

feat: view latest transactions#133
MicBun merged 1 commit intomainfrom
viewLatestTransaction

Conversation

@MicBun
Copy link
Copy Markdown
Member

@MicBun MicBun commented Oct 24, 2025

resolves: #132

Summary by CodeRabbit

  • New Features

    • Added example demonstrating how to retrieve recent transactions using NodeTNClient
  • Performance Improvements

    • Optimized transaction fetching with batch querying instead of individual block queries
    • Enhanced error handling with fallback values for missing transaction data

@MicBun MicBun requested a review from outerlook October 24, 2025 17:59
@MicBun MicBun self-assigned this Oct 24, 2025
@MicBun MicBun added the enhancement New feature or request label Oct 24, 2025
@holdex
Copy link
Copy Markdown

holdex bot commented Oct 24, 2025

Time Submission Status

Member Status Time Action Last Update
MicBun ✅ Submitted 4h Update time Oct 24, 2025, 6:48 PM
@outerlook ❌ Missing - ⚠️ Submit time -

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Oct 24, 2025

Walkthrough

The PR optimizes getLastTransactions() by replacing per-block RPC calls with a single indexer range query, reducing latency and network overhead. Additionally, it introduces an example script demonstrating how to use NodeTNClient to fetch the last transactions with timing measurements.

Changes

Cohort / File(s) Summary
Example Project
examples/get_last_transactions/index.ts, examples/get_last_transactions/package.json
New example script demonstrating NodeTNClient usage to fetch last transactions with execution time logging and error handling. Package manifest includes TSX-based start script.
Core Implementation
src/client/getLastTransactions.ts
Replaces per-block RPC calls with single indexer range query; adds block height validation; consolidates results with mapping step; introduces fallback values for missing transactions (sender, hash, stampMs); normalizes indexer response shape to LastTransaction structure.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Indexer
    participant RPC as RPC Node
    
    Note over Client,RPC: ❌ Old Approach (N+1 calls)
    Client->>Indexer: Get transactions (N blocks)
    Indexer-->>Client: Transactions with block_height
    loop Per Transaction
        Client->>RPC: Get block timestamp
        RPC-->>Client: timestamp
    end
    
    Note over Client,RPC: ✅ New Approach (Single query)
    Client->>Indexer: Get transactions range query<br/>(includes stamp_ms)
    Indexer-->>Client: All transactions with<br/>block_height, hash, sender, stamp_ms
    Client->>Client: Map & normalize response
    Note right of Client: Fallback handling for<br/>missing fields
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • outerlook

Poem

🐰 Hops through the blocks, no more delays,
One query instead of N RPC ways,
The indexer stamps each transaction bright,
Latency drops—80 milliseconds less to flight!
Examples sprout, showing the path so clear. 🌱

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ 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: view latest transactions" is concise and directly related to the primary change in this pull request. It clearly summarizes the main objective: improving transaction viewing through the implementation of getLastTransactions with optimized performance. The title is specific enough to convey the feature addition without excessive verbosity.
Linked Issues Check ✅ Passed The code changes directly address the core requirements from issue #132 [#132]. The implementation in src/client/getLastTransactions.ts replaces per-block RPC calls with a single range query to the indexer and uses the stamp_ms field from the indexer response instead of making separate RPC calls for timestamps, which eliminates unnecessary network overhead. The example files demonstrate the feature's usage, and the changes include validation for block heights and proper error handling. While performance metrics (latency <100ms) and test verification require runtime/CI validation rather than static code review, the coding requirements to implement the stamp_ms solution and eliminate RPC calls are clearly met.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch viewLatestTransaction

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.

@MicBun MicBun requested review from outerlook and removed request for outerlook October 24, 2025 18:04
Copy link
Copy Markdown
Contributor

@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: 0

🧹 Nitpick comments (8)
examples/get_last_transactions/package.json (1)

1-11: Make the example self-contained and non-publishable.

Without local deps, npm run start can fail; also guard against accidental publish. If the workspace doesn’t hoist these, add:

 {
+  "private": true,
   "scripts": {
     "start": "tsx index.ts"
   },
   "name": "get_last_transactions",
   "version": "1.0.0",
   "description": "",
-  "main": "index.ts",
+  "main": "index.ts",
   "author": "",
-  "license": "ISC"
+  "license": "ISC",
+  "type": "module",
+  "devDependencies": {
+    "tsx": "^4"
+  },
+  "dependencies": {
+    "ethers": "^6"
+  }
 }

If the monorepo already provides tsx/ethers, feel free to swap to workspace ranges instead (e.g., "workspace:^"). Please confirm the repo setup.

examples/get_last_transactions/index.ts (2)

4-14: Parametrize secrets and endpoints; avoid committing keys.

Use env vars for the demo key/endpoint/chain to prevent accidental misuse and ease local testing.

-import { Wallet } from "ethers";
+import { Wallet } from "ethers";

-const wallet = new Wallet("0000000000000000000000000000000000000000000000000000000000000001");
+// Demo only. Prefer supplying DEMO_PRIV_KEY via env. Never commit real keys.
+const PRIV_KEY = process.env.DEMO_PRIV_KEY ?? "0000000000000000000000000000000000000000000000000000000000000001";
+const wallet = new Wallet(PRIV_KEY);

 const client = new NodeTNClient({
-    endpoint: "https://gateway.mainnet.truf.network",
+    endpoint: process.env.TRUF_GATEWAY ?? "https://gateway.mainnet.truf.network",
     signerInfo: {
         address: wallet.address,
         signer: wallet,
     },
-    chainId: "tn-v2.1",
+    chainId: process.env.TRUF_CHAIN_ID ?? "tn-v2.1",
     timeout: 30000,
 });

Please confirm ethers v6 is in use (the example uses ESM import style).


27-30: Type-safe error handling in catch.

error may be unknown; guard before accessing .message.

-    } catch (error) {
-        console.error("❌ Error:", error.message);
-        console.error(error);
-    }
+    } catch (err) {
+        if (err instanceof Error) {
+            console.error("❌ Error:", err.message);
+            console.error(err.stack ?? err);
+        } else {
+            console.error("❌ Error:", err);
+        }
+    }
src/client/getLastTransactions.ts (5)

5-5: Allow overriding the indexer base.

Hardcoding makes staging/tests harder. Consider env/config override.

-const INDEXER_BASE = "https://indexer.infra.truf.network";
+const INDEXER_BASE = process.env.TRUF_INDEXER_BASE ?? "https://indexer.infra.truf.network";

If config already exposes this elsewhere, wire it through instead.


24-37: Verify created_at is a block height, not a timestamp.

You treat created_at as a block height; the name suggests time. If it’s actually a timestamp, the range query becomes invalid.

  • Confirm the SQL action main.get_last_transactions returns block heights in created_at. If not, switch to the correct field or adjust the query alias (e.g., SELECT block_height AS created_at), or rename the local var to avoid confusion.

  • Consider typing rows with an explicit block_height field to align semantics and reduce casting.


39-51: Add timeout and ensure Node fetch availability.

  • Node <18 lacks global fetch. If you support Node 16, import a ponyfill (undici/cross-fetch) or surface a fetch dependency.
  • Add an AbortController timeout to prevent request hangs and to help meet the <100ms target in failure cases.
-    const resp = await fetch(txUrl);
+    // Abort after 8s (tune or make configurable if needed)
+    const ac = new AbortController();
+    const timeoutId = setTimeout(() => ac.abort(), 8000);
+    let resp: Response;
+    try {
+        resp = await fetch(txUrl, { signal: ac.signal });
+    } finally {
+        clearTimeout(timeoutId);
+    }
     if (!resp.ok) {
-        throw new Error(`Indexer fetch failed: ${resp.status}`);
+        const text = await resp.text().catch(() => "");
+        throw new Error(`Indexer fetch failed: ${resp.status} ${resp.statusText} ${text}`.trim());
     }

Please confirm the minimum Node version supported by this package.


39-46: Range query could be heavy for sparse heights.

If maxBlock - minBlock is large (e.g., multiple thousands), this may return many irrelevant txs and hurt latency. A guarded fallback (multi-query by specific block heights or an API that accepts a list) would keep performance predictable.

Example guard:

  • If max - min > 2000, either:
    • Split the range into chunks, or
    • Query per unique height (still zero RPC calls) with small concurrency.

Does the indexer expose a “blocks=1,2,3” style filter? If yes, that’s ideal here.


66-82: First-transaction-per-block semantics: clarify intent.

For timestamps this is fine (per-block), but sender/hash will be from an arbitrary tx in that block (first in returned order). If consumers assume these correspond 1:1 to the SQL method row, this may change behavior.

  • Confirm no downstream relies on exact tx identity for a given method.

  • Consider documenting this in the return type or include a note field, or omit sender/hash when deduping by block (breaking change) to avoid misinterpretation.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 93e7768 and d00651e.

📒 Files selected for processing (3)
  • examples/get_last_transactions/index.ts (1 hunks)
  • examples/get_last_transactions/package.json (1 hunks)
  • src/client/getLastTransactions.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (3)
examples/get_last_transactions/index.ts (1)

16-26: Example flow looks good.

Clear timing and pretty-printed output; good for validating the latency objective.

src/client/getLastTransactions.ts (2)

84-106: Mapping and fallbacks look solid.

Stable order preserved; sensible fallbacks for missing blocks; stampMs sourced from stamp_ms per acceptance criteria. Nice.


1-106: Based on the script execution results, I've verified the review comment's two key assertions:

  1. "No RPC method is invoked for timestamps within getLastTransactions" — Confirmed. The script output shows only the indexer endpoint (/v0/chain/transactions) is accessed via fetch() at line 43. No RPC timestamp patterns were detected.

  2. "stampMs is populated from indexer data" — Confirmed. The output shows stamp_ms references only in the indexer response handling (lines 79 and 104: stampMs: tx.stamp_ms ?? 0).

The implementation correctly eliminates RPC timestamp calls and uses the indexer's stamp_ms field as intended. The review's suggestion to add lightweight tests to prevent regressions is a reasonable best practice, but the code itself is functionally correct and meets core objectives.


Verified: Implementation correctly uses indexer timestamps, not RPC calls.

The change successfully eliminates RPC timestamp calls and uses indexer stamp_ms data as intended. To prevent regressions, consider adding a lightweight test that:

  • Verifies the indexer endpoint is called (not RPC methods)
  • Confirms stampMs is populated from the response data

Tests would help lock in these design decisions for future maintenance.

@MicBun MicBun merged commit cca416d into main Oct 26, 2025
4 of 7 checks passed
@MicBun MicBun deleted the viewLatestTransaction branch October 26, 2025 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Problem: Transaction API Makes Excessive RPC Calls for Timestamps

2 participants