Skip to content

Comments

Convert SimplifiedTransaction[] to Transaction[] type in getAddressDe…#627

Open
Fabcien wants to merge 2 commits intoPayButton:masterfrom
Fabcien:getaddressdetails_conversion
Open

Convert SimplifiedTransaction[] to Transaction[] type in getAddressDe…#627
Fabcien wants to merge 2 commits intoPayButton:masterfrom
Fabcien:getaddressdetails_conversion

Conversation

@Fabcien
Copy link
Collaborator

@Fabcien Fabcien commented Feb 23, 2026

…tails

The API is likely to keep evolving and maintaining the types in sync is brittle as demonstrated here. Apply a proper conversion function to ensure the format is as expected.

Test Plan:
yarn test
Check payment detection still works on mobile.

Summary by CodeRabbit

  • Bug Fixes

    • API failures and malformed responses now produce safe empty results with warnings instead of errors.
  • Refactor

    • Transaction records normalized for consistent display: amounts standardized as strings, input addresses simplified to address-only lists, and message/payment metadata consolidated.
    • Added an opReturn field to transaction records to surface embedded message/payment data.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 23, 2026

📝 Walkthrough

Walkthrough

The API client now validates and parses address transaction responses, ensures the payload is an array, maps entries into normalized Transaction objects, JSON-stringifies a composed opReturn, converts amounts to strings, and reduces inputAddresses to address-only arrays before returning the list.

Changes

Cohort / File(s) Summary
API client — transaction normalization
react/lib/util/api-client.ts
Added safe HTTP/JSON handling and shape validation for address responses; introduced internal SimplifiedTransaction with Decimal fields; maps API entries into exported Transaction objects, sets opReturn (JSON-stringified), converts amount to string, and reduces inputAddresses to string[] (+69/-1).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • chedieck

Poem

🐇 I hopped through arrays, tidy and bright,

Pulled amounts to strings and trimmed addresses right,
Wrapped a little opReturn in JSON delight,
Now transactions dance in tidy moonlight,
Hooray—data hopped home tonight!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete and does not follow the required template structure with key sections like 'Related to #' and 'Description' properly filled out. Complete the description by adding issue references, expanding the 'Description' section with context, and ensuring all template sections are properly addressed.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: converting SimplifiedTransaction[] to Transaction[] in the getAddressDetails function.
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

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
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: 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 `@react/lib/util/api-client.ts`:
- Around line 39-41: The code calls apiTransaction.inputAddresses.map(...) which
will throw if apiTransaction.inputAddresses is null/undefined; update the
construction that sets inputAddresses to either
apiTransaction.inputAddresses.map(...) when present or an empty array otherwise
(e.g., use a guard or default like (apiTransaction.inputAddresses ||
[]).map(...)) so the property inputAddresses is always an array; refer to the
mapping expression that extracts input.address from
apiTransaction.inputAddresses to locate the change.
- Around line 31-33: The API returns apiTransaction.amount as a number but
Transaction.amount is typed as string, so normalize the value when building the
Transaction object: convert apiTransaction.amount to a string (e.g., via
toString or String(...)) before assigning to the Transaction.amount field (the
block that sets hash: apiTransaction.hash, amount: apiTransaction.amount,
paymentId: apiTransaction.paymentId). Ensure you handle null/undefined safely
(e.g., String(apiTransaction.amount) or apiTransaction.amount?.toString()) so
downstream consumers see a string-typed amount.
- Around line 19-46: Check the fetch response and payload before iterating:
after calling fetch (res) verify res.ok and throw or return an empty
transactions array with a clear error log if not OK; then parse JSON into
apiTransactions and ensure Array.isArray(apiTransactions) before using forEach
(otherwise handle non-array by returning [] or throwing). Also validate that
apiTransaction.inputAddresses is an array before mapping it (used in
inputAddresses mapping) and ensure opReturn/rawMessage fields are safely
accessed to avoid runtime errors when shaping each Transaction.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b9f6094 and 01fdbeb.

📒 Files selected for processing (1)
  • react/lib/util/api-client.ts

@Klakurka Klakurka self-requested a review February 23, 2026 22:49
@Klakurka Klakurka added bug Something isn't working enhancement (behind the scenes) Stuff that users won't see labels Feb 23, 2026
@Klakurka Klakurka added this to the Phase 3 milestone Feb 23, 2026
@Klakurka Klakurka requested review from chedieck and removed request for Klakurka February 23, 2026 22:49
@Fabcien Fabcien force-pushed the getaddressdetails_conversion branch from 01fdbeb to dedfc71 Compare February 24, 2026 08:00
@Fabcien
Copy link
Collaborator Author

Fabcien commented Feb 24, 2026

Added more defensive programming to avoid errors from the array methods

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

♻️ Duplicate comments (1)
react/lib/util/api-client.ts (1)

36-38: ⚠️ Potential issue | 🟡 Minor

Normalize amount to a string.
Transaction.amount is typed as string, but this still assigns the raw API value. Normalizing here prevents downstream type/format inconsistencies.

🔧 Suggested normalization
-      amount: apiTransaction.amount,
+      amount: apiTransaction.amount != null ? String(apiTransaction.amount) : '',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@react/lib/util/api-client.ts` around lines 36 - 38, The assignment is taking
apiTransaction.amount as-is even though Transaction.amount is typed string;
convert/normalize apiTransaction.amount to a string when building the
transaction object (the block assigning hash, amount, paymentId) so downstream
consumers always receive a string for Transaction.amount—e.g., coerce
apiTransaction.amount via String(...) or .toString() on the
apiTransaction.amount value before assigning to amount.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@react/lib/util/api-client.ts`:
- Around line 19-25: The current code calls res.json() without handling parse
errors so a non-JSON error body will throw before your res.ok/Array.isArray
check; wrap the JSON parsing in a try/catch (or read res.text() and safely
JSON.parse it) around the res.json() call used for apiTransactions in the fetch
block (where res and apiTransactions are defined) and on parse failure log the
response and return [] so the function reliably returns an empty array when the
body is not valid JSON.

---

Duplicate comments:
In `@react/lib/util/api-client.ts`:
- Around line 36-38: The assignment is taking apiTransaction.amount as-is even
though Transaction.amount is typed string; convert/normalize
apiTransaction.amount to a string when building the transaction object (the
block assigning hash, amount, paymentId) so downstream consumers always receive
a string for Transaction.amount—e.g., coerce apiTransaction.amount via
String(...) or .toString() on the apiTransaction.amount value before assigning
to amount.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01fdbeb and dedfc71.

📒 Files selected for processing (1)
  • react/lib/util/api-client.ts

…tails

The API is likely to keep evolving and maintaining the types in sync is brittle as demonstrated here. Apply a proper conversion function to ensure the format is as expected.

Test Plan:
yarn test
Check payment detection still works on mobile.
@Fabcien Fabcien force-pushed the getaddressdetails_conversion branch from dedfc71 to 521d325 Compare February 24, 2026 08:19
Copy link
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.

♻️ Duplicate comments (1)
react/lib/util/api-client.ts (1)

47-50: ⚠️ Potential issue | 🟡 Minor

Normalize amount to string to match Transaction.

Transaction.amount is typed as string, but Line 49 assigns the raw API value. Convert to string here to prevent downstream type/format inconsistencies.

🔧 Suggested normalization
-      amount: apiTransaction.amount,
+      amount: String(apiTransaction.amount),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@react/lib/util/api-client.ts` around lines 47 - 50, The Transaction object
construction assigns apiTransaction.amount directly but Transaction.amount is
typed as string; update the mapping where the transaction constant is created
(the transaction variable that uses apiTransaction) to normalize the amount to a
string (e.g., via String(apiTransaction.amount) or .toString()) so the created
Transaction conforms to the Transaction type and prevents downstream format/type
issues.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@react/lib/util/api-client.ts`:
- Around line 47-50: The Transaction object construction assigns
apiTransaction.amount directly but Transaction.amount is typed as string; update
the mapping where the transaction constant is created (the transaction variable
that uses apiTransaction) to normalize the amount to a string (e.g., via
String(apiTransaction.amount) or .toString()) so the created Transaction
conforms to the Transaction type and prevents downstream format/type issues.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dedfc71 and 521d325.

📒 Files selected for processing (1)
  • react/lib/util/api-client.ts

Copy link
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.

🧹 Nitpick comments (1)
react/lib/util/api-client.ts (1)

65-85: Wrap amount in Decimal() to normalize precision handling.

SimplifiedTransaction declares amount: Decimal, but res.json() yields primitive numbers. Instantiating Decimal here aligns runtime behavior with the type and ensures arbitrary-precision decimal handling rather than JavaScript number precision, which is especially important for financial values.

Suggested fix
-      amount: apiTransaction.amount.toString(),
+      amount: new Decimal(apiTransaction.amount).toString(),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@react/lib/util/api-client.ts` around lines 65 - 85, The transaction mapping
uses apiTransaction.amount as a JS number but the declared type is Decimal;
update the mapping in the block that builds each Transaction (inside the
apiTransactions.forEach) to wrap the incoming amount with Decimal(), e.g., set
the Transaction.amount to Decimal(apiTransaction.amount).toString() or otherwise
normalize to a Decimal representation before storing, ensuring you
import/require Decimal and handle cases where apiTransaction.amount may already
be a Decimal or null.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@react/lib/util/api-client.ts`:
- Around line 65-85: The transaction mapping uses apiTransaction.amount as a JS
number but the declared type is Decimal; update the mapping in the block that
builds each Transaction (inside the apiTransactions.forEach) to wrap the
incoming amount with Decimal(), e.g., set the Transaction.amount to
Decimal(apiTransaction.amount).toString() or otherwise normalize to a Decimal
representation before storing, ensuring you import/require Decimal and handle
cases where apiTransaction.amount may already be a Decimal or null.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 521d325 and e18dfeb.

📒 Files selected for processing (1)
  • react/lib/util/api-client.ts

import { CURRENCY_TYPES_MAP, DECIMALS } from './constants';
import Decimal from 'decimal.js';

interface SimplifiedTransaction {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What's the point ? This is an API call so the type can't be enforced. This is guaranteed to go out of sync sooner or later. The whole point of this PR is to enforce the returned type when the input type is subject to change, so this type adds a false sense of type safety which is worst than no type imo

Copy link
Collaborator

Choose a reason for hiding this comment

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

I added mostly because I saw (via code rabbit ai) that a type was being wrongly casted from Decimal to string: not a huge deal of course, but for me it's more about keeping the contract between client and server explicit.

I also don't think is a big deal keeping both in sync, logistically speaking, since we control both the client and the server. Besides that, changing the server api's response would most likely require a change in this file (or at least reviewing it), so having them tied together looks like a good thing to me, but maybe I am not seeing it right.

In any case, I don't think this is significant enough to be worth discussing it too much, so if you prefer, you can just revert my commit (but probably keep the amount.toString() part)

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

Labels

bug Something isn't working enhancement (behind the scenes) Stuff that users won't see

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants