Skip to content

feat: proxy getTokenDetails to fullnode thin_wallet/token API#372

Merged
andreabadesso merged 3 commits intomasterfrom
feat/proxy-get-token-details
Mar 3, 2026
Merged

feat: proxy getTokenDetails to fullnode thin_wallet/token API#372
andreabadesso merged 3 commits intomasterfrom
feat/proxy-get-token-details

Conversation

@andreabadesso
Copy link
Copy Markdown
Collaborator

@andreabadesso andreabadesso commented Mar 2, 2026

Instead of querying the database for token info, supply, transactions and authorities, proxy the request to the fullnode's thin_wallet/token endpoint and map the response to preserve the existing API contract.

Motivation

The getTokenDetails endpoint was querying multiple database tables (token info, total supply, total transactions, mint/melt authority UTXOs) to assemble the response. By proxying directly to the fullnode, we get real-time token data while keeping the same response format so existing wallets are unaffected.

Acceptance Criteria

  • The GET /wallet/tokens/{token_id}/details endpoint proxies to the fullnode's thin_wallet/token?id={token_id} API
  • The response format is preserved exactly as before (success, details.tokenInfo, details.totalSupply, details.totalTransactions, details.authorities.mint, details.authorities.melt)
  • Input validation (64-char hex token_id) still works as before

Checklist

  • If you are requesting a merge into master, confirm this code is production-ready and can be included in future releases as soon as it gets merged
  • Make sure either the unit tests and/or the QA tests are capable of testing the new features
  • Make sure you do not include new dependencies in the project unless strictly necessary and do not include dev-dependencies as production ones. More dependencies increase the possibility of one of them being hijacked and affecting us.

Summary by CodeRabbit

  • Refactor

    • Token details are now fetched directly from the blockchain node (fullnode), providing tokenInfo and authority flags (mint/melt).
  • Bug Fixes

    • Short/invalid token IDs now return a 400 validation response.
    • More consistent “token not found” behavior from the node proxy.
  • Tests

    • Updated tests to mock and validate fullnode-backed token details and authority behavior.

Instead of querying the database for token info, supply, transactions
and authorities, proxy the request to the fullnode's thin_wallet/token
endpoint and map the response to preserve the existing API contract.
@andreabadesso andreabadesso self-assigned this Mar 2, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 2, 2026

📝 Walkthrough

Walkthrough

Token details endpoint now proxies to the fullnode via fullnode.getTokenDetails(tokenId) instead of DB lookups; DB connection is closed in a finally block. Tests were updated to mock fullnode.getTokenDetails and to cover success and validation paths.

Changes

Cohort / File(s) Summary
Fullnode API Extension
packages/wallet-service/src/fullnode.ts
Adds getTokenDetails(tokenId: string) which GETs thin_wallet/token?id=... and returns response.data; exposed on the fullnode client API.
Token Details Endpoint Migration
packages/wallet-service/src/api/tokens.ts
Replaces multiple DB getters with a single fullnode.getTokenDetails() call, removes TokenInfo export/DB-specific logic, renames walletId_walletId, ensures DB connection closed in finally (await closeDbConnection(mysql)), and uses JSON.stringify for response body.
Test Updates
packages/wallet-service/tests/api.test.ts
Replaces heavy DB/state setup with mocked fullnode.getTokenDetails() responses (two token cases), adds spies and restores them, and adds validation test for short token_id. Asserts new response fields (tokenInfo, totalSupply, totalTransactions, authorities).

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant Wallet as WalletService
    participant Fullnode as Fullnode
    participant Thin as ThinWalletAPI
    participant DB as DB

    Client->>Wallet: GET /wallet/tokens/:token_id/details
    Wallet->>Fullnode: getTokenDetails(token_id)
    Fullnode->>Thin: GET thin_wallet/token?id=token_id
    Thin-->>Fullnode: 200 { data: token details }
    Fullnode-->>Wallet: token details
    Wallet->>DB: closeDbConnection(mysql)
    Wallet-->>Client: 200 { success:true, details: {...} }
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped from rows of tables to nodes so bright,
Now token tales arrive on a single flight.
One call to the fullnode, swift and neat,
I nibble on code and tap my feet. 🥕

🚥 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 accurately summarizes the main change: proxying getTokenDetails to the fullnode thin_wallet/token API, which is the core objective of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/proxy-get-token-details

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

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

Inline comments:
In `@packages/wallet-service/src/api/tokens.ts`:
- Around line 68-90: Wrap the call to fullnode.getTokenDetails in a
try/catch/finally so closeDbConnection(mysql) is always invoked in the finally
block, and validate the response before returning success: check that data
exists and contains expected fields (e.g., data.name, data.symbol, data.total);
if the fullnode response is falsy or missing required fields or threw, return a
non-200 statusCode with success: false and an explanatory message instead of
returning success: true. Specifically update the code around
fullnode.getTokenDetails and closeDbConnection to ensure errors are caught,
logged/propagated, and DB closure always runs.

In `@packages/wallet-service/tests/api.test.ts`:
- Around line 1530-1563: The test fails to assert that the second proxied call
forwarded the correct token id, risking false positives; after calling
getTokenDetails with event made by makeGatewayEventWithAuthorizer (using
TX_IDS[1]) add an assertion that mockFullnodeResponse was called with TX_IDS[1]
(similar to the earlier
expect(mockFullnodeResponse).toHaveBeenCalledWith(TX_IDS[0])), referencing the
mockFullnodeResponse mock, the getTokenDetails invocation, and TX_IDS[1] to
ensure the forwarded argument is validated.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e942e0 and b36ee56.

📒 Files selected for processing (3)
  • packages/wallet-service/src/api/tokens.ts
  • packages/wallet-service/src/fullnode.ts
  • packages/wallet-service/tests/api.test.ts

Comment thread packages/wallet-service/src/api/tokens.ts Outdated
Comment thread packages/wallet-service/tests/api.test.ts Outdated
- Wrap fullnode call in try/finally to ensure DB connection is always closed
- Check data.success before returning success response; return TOKEN_NOT_FOUND if fullnode reports failure
- Assert second proxied token id with toHaveBeenNthCalledWith
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

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

Inline comments:
In `@packages/wallet-service/src/api/tokens.ts`:
- Around line 72-75: The token-not-found branches in
packages/wallet-service/src/api/tokens.ts call closeDbAndGetError (e.g., the if
(!data?.success) branch and the similar 98-100 branch) which duplicates DB
closing because a finally block later also closes mysql; change those branches
to return the error response without closing the DB (i.e., don’t call
closeDbAndGetError — return the equivalent ApiError payload directly or call a
non-closing helper) and let the existing finally block perform the single
mysql.close; update references to closeDbAndGetError in these branches so only
the finally closes the connection.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b36ee56 and 966f69a.

📒 Files selected for processing (2)
  • packages/wallet-service/src/api/tokens.ts
  • packages/wallet-service/tests/api.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/wallet-service/tests/api.test.ts

Comment thread packages/wallet-service/src/api/tokens.ts Outdated
@andreabadesso andreabadesso moved this from Todo to In Progress (Done) in Hathor Network Mar 2, 2026
Return error response directly instead of using closeDbAndGetError,
since the finally block already handles closing the DB connection.
@andreabadesso andreabadesso added the enhancement New feature or request label Mar 2, 2026
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

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

Inline comments:
In `@packages/wallet-service/src/api/tokens.ts`:
- Around line 103-105: The get function currently opens a DB connection and
returns results but never closes it; mirror the pattern used in getTokenDetails
by adding a try/finally (or a finally block after the existing return) that
calls closeDbConnection(mysql) to always release the connection; locate the get
function in tokens.ts and ensure closeDbConnection(mysql) is invoked in a
finally block (same as in getTokenDetails) so the mysql connection is closed on
all execution paths.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 966f69a and ccd2ed1.

📒 Files selected for processing (1)
  • packages/wallet-service/src/api/tokens.ts

Comment on lines +103 to +105
} finally {
await closeDbConnection(mysql);
}
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

🧩 Analysis chain

🏁 Script executed:

cat packages/wallet-service/src/api/tokens.ts | head -120

Repository: HathorNetwork/hathor-wallet-service

Length of output: 2764


🏁 Script executed:

rg -n "closeDbConnection|closeDb" packages/wallet-service/src/api/ -C2

Repository: HathorNetwork/hathor-wallet-service

Length of output: 50391


🏁 Script executed:

rg -n "getDbConnection" packages/wallet-service/src/ -A10

Repository: HathorNetwork/hathor-wallet-service

Length of output: 47728


🏁 Script executed:

fd "connection|db" packages/wallet-service/src/ -t f | grep -E "\.(ts|js)$"

Repository: HathorNetwork/hathor-wallet-service

Length of output: 123


🏁 Script executed:

# Let me check if there are any tests or documentation about how the connection pool handles closing
rg -i "serverless.*mysql" packages/wallet-service/src/ -A2 | head -40

Repository: HathorNetwork/hathor-wallet-service

Length of output: 2861


🏁 Script executed:

# Check if closeDbConnection is called in error handlers
rg "closeDbConnection|closeDbAndGetError" packages/wallet-service/src/api/utils.ts -A3 -B3

Repository: HathorNetwork/hathor-wallet-service

Length of output: 661


Add connection closing to the get function for consistency and resource management.

The get function (lines 26-38) should close the database connection like getTokenDetails does. Currently, get performs a database query but never calls closeDbConnection(mysql), while getTokenDetails properly closes the connection in a finally block. This inconsistency can lead to connection pool exhaustion and resource leaks on warm Lambda instances where the module-level connection persists across invocations. Add a finally block after the return statement to ensure the connection is properly released.

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

In `@packages/wallet-service/src/api/tokens.ts` around lines 103 - 105, The get
function currently opens a DB connection and returns results but never closes
it; mirror the pattern used in getTokenDetails by adding a try/finally (or a
finally block after the existing return) that calls closeDbConnection(mysql) to
always release the connection; locate the get function in tokens.ts and ensure
closeDbConnection(mysql) is invoked in a finally block (same as in
getTokenDetails) so the mysql connection is closed on all execution paths.

@andreabadesso andreabadesso moved this from In Progress (Done) to In Review (WIP) in Hathor Network Mar 3, 2026
Copy link
Copy Markdown
Contributor

@raul-oliveira raul-oliveira left a comment

Choose a reason for hiding this comment

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

LGTM

@andreabadesso andreabadesso merged commit 62b3698 into master Mar 3, 2026
2 checks passed
@github-project-automation github-project-automation Bot moved this from In Review (WIP) to Waiting to be deployed in Hathor Network Mar 3, 2026
This was referenced Mar 4, 2026
@andreabadesso andreabadesso moved this from Waiting to be deployed to Done in Hathor Network Mar 5, 2026
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

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants