Skip to content

[v0.39.0] Sync master with release - #889

Merged
tuliomir merged 11 commits into
masterfrom
release-sync
Jun 17, 2026
Merged

[v0.39.0] Sync master with release#889
tuliomir merged 11 commits into
masterfrom
release-sync

Conversation

@tuliomir

@tuliomir tuliomir commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Sync release back into master after the v0.39.0 stable release. Must be merged with a merge commit, not squash.

Summary by CodeRabbit

  • New Features

    • Transaction history now automatically refreshes when cache becomes invalid.
  • Bug Fixes

    • Improved error messages in send confirmation for transaction failures.
    • Fixed send button state management during PIN authentication.
  • Improvements

    • Settings address mode menu visibility enhanced.
  • Chores

    • Version bumped to 0.39.0.
    • Updated translations for Danish, Portuguese, and Russian locales.

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Version bumped to 0.39.0 across all platform manifests. The send flow is refactored: fee/UTXO calculation is removed from SendAmountInput and transaction pre-building with a PHASE state machine, error mapping, and UTXO cleanup is added to SendConfirmScreen. Token version is propagated through import sagas and token persistence strips wallet metadata. MainScreen gains invalidation-triggered history refetch. AmountTextInput layout is fixed and localization catalogs are regenerated.

Changes

v0.39.0 Feature Changes

Layer / File(s) Summary
Send flow: move fee/UTXO build from SendAmountInput to SendConfirmScreen
src/screens/SendAmountInput.js, src/screens/SendConfirmScreen.js
SendAmountInput drops hathorLib import, wallet state, fee/UTXO effect, and fee-related navigation params. SendConfirmScreen gains PHASE state machine, mount-time prepare-tx build, mapTxError, UTXO cleanup on unmount, focus-listener isSending reset, signAndSendTx, executeSend, and FeedbackModal-driven phase rendering.
Token version: propagation through import and persist sagas
src/sagas/tokenImport.js, src/sagas/tokens.js
fetchTokenDetails adds version to returned token objects; all downstream saga payloads carry version. persistTokensForCurrentNetwork uses new stripTokenMetadata helper saving only uid/name/symbol/version instead of full wallet objects.
MainScreen: refetch history on INVALIDATED status
src/screens/MainScreen.js
componentDidUpdate detects TOKEN_DOWNLOAD_STATUS.INVALIDATED and dispatches getHistory; the loading view also renders for INVALIDATED.
AmountTextInput layout fix for CreateTokenConfirm
src/components/AmountTextInput.js, src/screens/CreateTokenConfirm.js
AmountTextInput comment is expanded to document parent-controlled width requirement; CreateTokenConfirm applies alignSelf: 'stretch' to prevent font-scaling collapse feedback loop.
Settings: address mode guard corrected
src/screens/Settings.js
Condition rendering the "Address Mode" ListMenu in Advanced Settings is switched from reownEnabled to singleAddressEnabled.
Locale catalog regeneration
locale/texts.pot, locale/da/texts.po, locale/pt-br/texts.po, locale/ru-ru/texts.po
All .po/.pot files update #: source references for the modified screens; the send flow section replaces fee-calculation msgids with new insufficiency/failure/building strings; pt-br obsolete entries are updated accordingly.
Version bump to 0.39.0
package.json, android/app/build.gradle, ios/HathorMobile.xcodeproj/project.pbxproj
package.json version, Android versionCode/versionName, and iOS MARKETING_VERSION (Debug + Release) are updated to 0.39.0.

Sequence Diagram

sequenceDiagram
  participant User
  participant SendAmountInput
  participant SendConfirmScreen
  participant WalletLib
  participant PinScreen
  participant FeedbackModal

  User->>SendAmountInput: enter address, amount, token
  SendAmountInput->>SendConfirmScreen: navigate(address, amount, token)
  SendConfirmScreen->>WalletLib: prepare-tx on mount
  alt build fails
    WalletLib-->>SendConfirmScreen: error
    SendConfirmScreen->>FeedbackModal: show PHASE.ERROR + mapTxError(err)
    FeedbackModal-->>User: dismiss → navigateBack
  else build succeeds
    WalletLib-->>SendConfirmScreen: sendTx instance
    SendConfirmScreen->>FeedbackModal: show PHASE.READY (tx summary)
    User->>SendConfirmScreen: press Send (isSending=true)
    SendConfirmScreen->>PinScreen: navigate
    PinScreen-->>SendConfirmScreen: focus return → isSending reset
    SendConfirmScreen->>WalletLib: signAndSendTx(pin)
    WalletLib-->>FeedbackModal: success or mapped error
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • HathorNetwork/hathor-wallet-mobile#876: Updates the same src/sagas/tokenImport.js to include token version and refactors SendAmountInput/SendConfirmScreen with the prepared-transaction and intermediate loading/error UI pattern.
  • HathorNetwork/hathor-wallet-mobile#881: Directly related — introduces the stripTokenMetadata snapshot filtering in src/sagas/tokens.js to remove balance from stored token configs, the same change merged here.
  • HathorNetwork/hathor-wallet-mobile#878: Touches the same SendConfirmScreen mapTxError/send-state handling, Settings address-mode gating, and MainScreen invalidated tx-history refetch behavior.

Suggested labels

enhancement

Suggested reviewers

  • pedroferreira1

🐇 Hoppity hop, the version grows,
From .38 to .39 the codebase flows!
Fees now build where confirm screens glow,
Token versions travel wherever they go.
The rabbit cheers — each phase in a row! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title '[v0.39.0] Sync master with release' clearly and accurately describes the main purpose of this PR: syncing the release branch into master after the v0.39.0 release, which aligns with the file-level changes (version bumps and related bug fixes) and documented objectives.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release-sync

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.

@tuliomir tuliomir moved this from Todo to In Progress (Done) in Hathor Network Jun 17, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/sagas/tokenImport.js (1)

62-62: 💤 Low value

Minor: Fallback lacks explicit version field.

The fallback path returns { uid, name, symbol } without version, causing details.version to be undefined at lines 105, 140, and 178. This works correctly since stripTokenMetadata in tokens.js omits undefined fields, but adding version: undefined here would make the contract explicit.

💡 Optional: make version explicit
-  return { uid, name: uid.slice(0, 8), symbol: '???' };
+  return { uid, name: uid.slice(0, 8), symbol: '???', version: undefined };
🤖 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 `@src/sagas/tokenImport.js` at line 62, The fallback return statement in the
tokenImport.js file returns an object with uid, name, and symbol fields but
omits the version field. Add version: undefined to the returned object at the
return statement (the one returning { uid, name: uid.slice(0, 8), symbol: '???'
}) to make the contract explicit and clarify that the version field is
intentionally undefined in this fallback path.
locale/pt-br/texts.po (1)

1013-1023: 💤 Low value

Minor punctuation inconsistency in translation.

Line 1023 translation "Falha ao processar a transação" is missing the trailing period that exists in the English source "Failed to process transaction." This is a minor inconsistency with other translations that include punctuation.

📝 Optional fix
 #: src/screens/SendConfirmScreen.js:59
 msgid "Failed to process transaction."
-msgstr "Falha ao processar a transação"
+msgstr "Falha ao processar a transação."
🤖 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 `@locale/pt-br/texts.po` around lines 1013 - 1023, The Portuguese Brazilian
translation for the message "Failed to process transaction." (corresponding to
src/screens/SendConfirmScreen.js:59) is missing a trailing period. Update the
translation "Falha ao processar a transação" to include a period at the end to
match the punctuation of the English source and maintain consistency with the
other translations in the same section that include proper punctuation.
🤖 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 `@src/screens/SendConfirmScreen.js`:
- Around line 88-89: Replace the hardcoded native token symbol sourcing from
hathorLib.constants.DEFAULT_NATIVE_TOKEN_CONFIG.symbol with the server-provided
symbol from serverInfo.native_token.symbol in the SendConfirmScreen component.
Update the nativeSymbol constant assignment at line 88 to use
serverInfo.native_token.symbol instead, and apply the same fix to the other
occurrences around lines 360-362 to ensure all user-facing references to the
native token symbol use the actual network metadata rather than default
configuration values.
- Around line 96-117: The catch block handling errors from
sendTransaction.run('prepare-tx') does not release locked UTXOs before exiting
the error path, leaving them in a locked state for subsequent transactions. Add
a UTXO cleanup call to the catch block by invoking await
sendTransaction.releaseUtxos() wrapped in a try-catch block (matching the
pattern already implemented in the cancellation handler at lines 107-109),
before the setBuildError and setPhase calls, to ensure resources are properly
released even when an error occurs.

---

Nitpick comments:
In `@locale/pt-br/texts.po`:
- Around line 1013-1023: The Portuguese Brazilian translation for the message
"Failed to process transaction." (corresponding to
src/screens/SendConfirmScreen.js:59) is missing a trailing period. Update the
translation "Falha ao processar a transação" to include a period at the end to
match the punctuation of the English source and maintain consistency with the
other translations in the same section that include proper punctuation.

In `@src/sagas/tokenImport.js`:
- Line 62: The fallback return statement in the tokenImport.js file returns an
object with uid, name, and symbol fields but omits the version field. Add
version: undefined to the returned object at the return statement (the one
returning { uid, name: uid.slice(0, 8), symbol: '???' }) to make the contract
explicit and clarify that the version field is intentionally undefined in this
fallback path.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: d2b3db1f-dda7-4a76-8fdb-4a758180bf82

📥 Commits

Reviewing files that changed from the base of the PR and between 99c9215 and 3c01bd6.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (15)
  • android/app/build.gradle
  • ios/HathorMobile.xcodeproj/project.pbxproj
  • locale/da/texts.po
  • locale/pt-br/texts.po
  • locale/ru-ru/texts.po
  • locale/texts.pot
  • package.json
  • src/components/AmountTextInput.js
  • src/sagas/tokenImport.js
  • src/sagas/tokens.js
  • src/screens/CreateTokenConfirm.js
  • src/screens/MainScreen.js
  • src/screens/SendAmountInput.js
  • src/screens/SendConfirmScreen.js
  • src/screens/Settings.js

Comment on lines 88 to 89
const nativeSymbol = hathorLib.constants.DEFAULT_NATIVE_TOKEN_CONFIG.symbol;

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 | ⚡ Quick win

Use server-provided native token symbol in the Total line.

nativeSymbol is sourced from DEFAULT_NATIVE_TOKEN_CONFIG, which can diverge from the connected network metadata and show the wrong symbol in user-facing text.

Proposed fix
-  const nativeSymbol = hathorLib.constants.DEFAULT_NATIVE_TOKEN_CONFIG.symbol;
+  const nativeSymbol = useSelector((state) => state.serverInfo?.native_token?.symbol)
+    ?? hathorLib.constants.DEFAULT_NATIVE_TOKEN_CONFIG.symbol;

Based on learnings: do not hardcode native token symbol in user-facing UI; use serverInfo.native_token.symbol.

Also applies to: 360-362

🤖 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 `@src/screens/SendConfirmScreen.js` around lines 88 - 89, Replace the hardcoded
native token symbol sourcing from
hathorLib.constants.DEFAULT_NATIVE_TOKEN_CONFIG.symbol with the server-provided
symbol from serverInfo.native_token.symbol in the SendConfirmScreen component.
Update the nativeSymbol constant assignment at line 88 to use
serverInfo.native_token.symbol instead, and apply the same fix to the other
occurrences around lines 360-362 to ensure all user-facing references to the
native token symbol use the actual network metadata rather than default
configuration values.

Source: Learnings

Comment on lines +96 to +117
(async () => {
try {
const outputs = [{ address, value: amount, token: token.uid }];
const sendTransaction = useWalletService
? new hathorLib.SendTransactionWalletService(wallet, { outputs })
: new hathorLib.SendTransaction({ storage: wallet.storage, outputs });

await sendTransaction.run('prepare-tx');

if (cancelled) {
try { await sendTransaction.releaseUtxos(); } catch (e) { console.error(e); }
return;
}

setSendTx(sendTransaction);
setPhase(PHASE.READY);
} catch (err) {
if (cancelled) return;
console.error(err);
setBuildError({ message: mapTxError(err) });
setPhase(PHASE.ERROR);
}

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 | 🟠 Major

🧩 Analysis chain

🌐 Web query:

In @hathor/wallet-lib v3.1.1, if SendTransaction.run('prepare-tx') throws, can selected UTXOs remain reserved and require an explicit releaseUtxos() call?

💡 Result:

In @hathor/wallet-lib v3.1.1, if a process such as SendTransaction.run('prepare-tx') fails, it is possible for selected UTXOs to remain in a reserved or "selected" state within the wallet's internal storage [1]. The library architecture often requires explicit handling to ensure these UTXOs are returned to the available pool if a transaction proposal or preparation step is aborted [2][3][4]. Because the library maintains internal tracking of UTXOs being used in current transactions to prevent double-spending, an unhandled exception during the preparation phase may prevent the automatic release of these locks [1]. Developers should implement robust error handling—typically within a try/catch block—to call the appropriate release or cleanup method if the transaction process fails to complete successfully [2]. If the application does not explicitly release these UTXOs, they may remain effectively locked, preventing them from being used in subsequent transactions until the wallet state is synchronized or the UTXOs are manually released [3][5].

Citations:


Add UTXO cleanup to error handler.

The catch block at lines 110–117 discards the sendTransaction instance without calling releaseUtxos(). If run('prepare-tx') throws, selected UTXOs remain locked in the wallet's internal state and cannot be used in subsequent transactions. Call releaseUtxos() before exiting the error path, matching the cleanup already present in the cancellation handler at lines 107–109.

🧰 Tools
🪛 ast-grep (0.43.0)

[warning] 109-109: Avoid using the initial state variable in setState
Context: setSendTx(sendTransaction)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)

🤖 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 `@src/screens/SendConfirmScreen.js` around lines 96 - 117, The catch block
handling errors from sendTransaction.run('prepare-tx') does not release locked
UTXOs before exiting the error path, leaving them in a locked state for
subsequent transactions. Add a UTXO cleanup call to the catch block by invoking
await sendTransaction.releaseUtxos() wrapped in a try-catch block (matching the
pattern already implemented in the cancellation handler at lines 107-109),
before the setBuildError and setPhase calls, to ensure resources are properly
released even when an error occurs.

@github-project-automation github-project-automation Bot moved this from In Progress (Done) to In Review (WIP) in Hathor Network Jun 17, 2026
@tuliomir
tuliomir merged commit ec769be into master Jun 17, 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 Jun 17, 2026
@tuliomir
tuliomir deleted the release-sync branch June 17, 2026 15:14
@tuliomir tuliomir moved this from Waiting to be deployed to Done in Hathor Network Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants