Skip to content

Add Monero#1027

Open
peachbits wants to merge 11 commits into
masterfrom
matthew/monero
Open

Add Monero#1027
peachbits wants to merge 11 commits into
masterfrom
matthew/monero

Conversation

@peachbits

@peachbits peachbits commented Feb 17, 2026

Copy link
Copy Markdown
Contributor

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

none

Note

High Risk
Large new wallet engine touching private keys, native bridge, LWS login/API keys, and send/broadcast paths; depends on beta edge-core-js and react-native-monero-lwsf.

Overview
Adds Monero (XMR) as a first-class Edge currency plugin, wired through react-native-monero-lwsf and new rn-monero entry points that bridge MoneroLwsfModule events into the JS engine.

The new MoneroEngine / MoneroTools stack covers wallet lifecycle (LWS vs monerod backends), birthday-height recovery, block/balance/history sync with a weighted progress tracker, paginated tx backfill, spend/broadcast, and optional Nym privacy routing for fetches. User settings cover custom LWS/monerod servers and network privacy; per-wallet settings choose the sync backend. Edge LWS login uses a guarded edgeApiKey only against the configured Edge server.

ZanoSyncTracker is generalized to shared WeightedSyncTracker in src/common/ and Zano is switched to it. edge-core-js is bumped to 2.42.1-beta.0; CLI/tests pass walletSettings alongside userSettings.

Reviewed by Cursor Bugbot for commit 44de95b. Bugbot is set up for automated code reviews on this repo. Configure here.


@peachbits peachbits force-pushed the matthew/monero branch 2 times, most recently from f3d8f17 to 666e692 Compare February 17, 2026 23:35
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts Outdated

@swansontec swansontec left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks pretty solid.

Comment thread src/monero/moneroTypes.ts
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/moneroTypes.ts Outdated

@paullinator paullinator left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Additional Findings

  • critical package.json: devDependency edge-core-js pinned to beta version '2.42.1-beta.0'. Beta dependencies should not ship to production. The master branch uses '^2.42.0' (stable).
    • Upgrade to a stable edge-core-js release (>=2.42.1) or revert to '^2.42.0' before merging. If the beta has required API changes (walletSettings), wait for its stable release.
  • critical package.json: devDependency react-native-monero-lwsf is '0.1.0-beta.0' while peerDependency declares 'v0.1.0'. The 'v' prefix in the peerDependency semver string is non-standard and may cause npm/yarn resolution warnings. The dev version (beta) does not satisfy the peer version (stable).
    • Remove the 'v' prefix from the peerDependency version. Align both devDependency and peerDependency to the same stable release before merging.
  • warning: PR has 14 commits including 4 unsquashed 'fixup!' commits and a typo ('new wallet's to save'). PR description says 'none' and the CHANGELOG checkbox is unchecked. This is a significant feature addition that warrants a proper description and CHANGELOG entry.
    • Squash fixup commits, add a meaningful PR description, and add a CHANGELOG entry for Monero support.
  • suggestion: No Monero fixtures in test/plugin/ or test/engine/ test suites. The 1423 lines of new code (MoneroEngine, MoneroTools, moneroTypes) have zero dedicated test coverage. Key logic (processTransaction, queryTransactionsAsc/Desc, resolveBirthdayHeight, makeSpend, translateFee) is untested.
    • Add Monero fixtures to the plugin and engine test suites. If the native CppBridge cannot run in Node.js, create a mock. At minimum test processTransaction, translateFee, and the cleaner types which have no native dependency.

Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroTools.ts
Comment thread src/monero/moneroTypes.ts
Comment thread src/monero/MoneroEngine.ts
Comment thread src/common/WeightedSyncTracker.ts
Comment thread src/monero/MoneroEngine.ts

@eddy-edge eddy-edge 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.

Requesting changes after full review. Architecture is strong and many comments were addressed, but there are still blockers around type-safety/dependency hygiene plus a few correctness/perf issues.

Comment thread src/monero/moneroTypes.ts Outdated

@eddy-edge eddy-edge 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.

Requesting changes after full review. Architecture is strong and many comments were addressed, but there are still blockers around type-safety/dependency hygiene plus a few correctness/perf issues.

Comment thread src/monero/MoneroEngine.ts Outdated

@eddy-edge eddy-edge 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.

Requesting changes after full review. Architecture is strong and many comments were addressed, but there are still blockers around type-safety/dependency hygiene plus a few correctness/perf issues.

Comment thread src/monero/MoneroEngine.ts

@eddy-edge eddy-edge 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.

Requesting changes after full review. Architecture is strong and many comments were addressed, but there are still blockers around type-safety/dependency hygiene plus a few correctness/perf issues.

Comment thread src/monero/MoneroEngine.ts

@eddy-edge eddy-edge 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.

Additional blocking dependency/version notes from full review: please align Monero package semver between dev/peer deps (including removing v prefix), avoid exact beta pin for edge-core-js unless intentional, and add a CHANGELOG entry before merge.

Comment thread package.json
Comment thread package.json

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for all 3 issues found in the latest run.

  • ✅ Fixed: Sync progress ratio can go negative after reorg
    • I clamped the computed sync block ratio to the [0, 1] range before passing it to the weighted sync tracker.
  • ✅ Fixed: Hardcoded currency code instead of using currencyInfo
    • I replaced the hardcoded 'XMR' in processed transactions with this.currencyInfo.currencyCode to align with engine conventions.
  • ✅ Fixed: Wallet event log exposes potentially sensitive data
    • I removed event.data from wallet event logging so only the event name is logged.

Create PR

Or push these changes by commenting:

@cursor push 6e67221e80
Preview (6e67221e80)
diff --git a/src/monero/MoneroEngine.ts b/src/monero/MoneroEngine.ts
--- a/src/monero/MoneroEngine.ts
+++ b/src/monero/MoneroEngine.ts
@@ -162,7 +162,7 @@
             event => {
               if (event.walletId !== base64UrlWalletId) return
               if (event.eventName !== 'pendingTransactionReceived') return
-              this.log(`Wallet event: ${event.eventName} data=${event.data}`)
+              this.log(`Wallet event: ${event.eventName}`)
               this.queryTransactions(base64UrlWalletId).catch(err =>
                 this.log.error(
                   `Event-triggered queryTransactions error: ${String(err)}`
@@ -344,8 +344,9 @@
         return 20000
       } else {
         const range = status.networkHeight - this.syncStartHeight
-        const ratio =
+        const rawRatio =
           range > 0 ? (status.syncedHeight - this.syncStartHeight) / range : 0
+        const ratio = Math.max(0, Math.min(1, rawRatio))
 
         this.syncTracker.updateBlockRatio(
           ratio,
@@ -524,7 +525,7 @@
 
     const edgeTransaction: EdgeTransaction = {
       blockHeight,
-      currencyCode: 'XMR',
+      currencyCode: this.currencyInfo.currencyCode,
       date: tx.timestamp,
       isSend: !isReceive,
       memos,

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroEngine.ts Outdated
@peachbits peachbits force-pushed the matthew/monero branch 2 times, most recently from 5888d25 to 9d42eef Compare March 13, 2026 23:13
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread package.json

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 6 total unresolved issues (including 5 from previous reviews).

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Birthday height zero bypasses fallback guard
    • Updated resolveBirthdayHeight to only short-circuit for positive stored heights so a saved value of 0 now falls through to the fallback guard path instead of opening from genesis.

Create PR

Or push these changes by commenting:

@cursor push 42c46b7b76
Preview (42c46b7b76)
diff --git a/src/monero/MoneroEngine.ts b/src/monero/MoneroEngine.ts
--- a/src/monero/MoneroEngine.ts
+++ b/src/monero/MoneroEngine.ts
@@ -216,7 +216,7 @@
     edgeLwsServer: string,
     loginResult?: LoginResponse
   ): Promise<number> {
-    if (height != null) return height
+    if (height != null && height > 0) return height
 
     // For Edge LWS, the login response may already have it
     if (loginResult?.start_height != null) {

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/moneroTypes.ts
Comment thread src/common/network.ts Outdated
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/common/network.ts Outdated
Comment thread src/common/network.ts Outdated
Comment thread src/common/network.ts
Comment thread src/monero/MoneroEngine.ts Outdated
Comment thread src/monero/MoneroTools.ts
Comment thread src/monero/MoneroTools.ts
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/moneroInfo.ts
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts
Comment thread src/monero/MoneroEngine.ts
this.log.error(
`Event-triggered queryTransactions error: ${String(err)}`
)
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Concurrent transaction queries race

Medium Severity

pendingTransactionReceived fires queryTransactions without coordinating with the syncNetwork path that also awaits the same method. Overlapping runs can interleave updates to otherData (processedTransactionCount, mostRecentTxid) and duplicate or skip ingestion while history backfill is in progress.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5496aa0. Configure here.

Squashed fix-ups responding to review on the Monero engine/tools:
- resolveBirthdayHeight: use the user's enabled LWS for recovery; reject
  zero heights from both the stored value and the LWS login response
- history sync: report 100% only once the ascending backfill completes;
  fast-poll while backfilling; empty wallets complete immediately
- clamp the block-sync ratio so a reorg cannot feed a negative value
- settings-change queue no longer poisons on a failed kill/start
- scope the Edge API key to the Edge LWS only, never custom servers
- make loginToLwsServer/getAddressInfo private
- misc: poll-interval constants, log levels, parseUri error logging,
  doc comments, translateFee priorities, package peer range

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

There are 3 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 44de95b. Configure here.

}

this.otherData.processedTransactionCount =
startPage * pageSize + txPage.transactions.length

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Backfill skips txs after crash

Medium Severity

During ascending history backfill, queryTransactionsAsc skips every transaction before mostRecentTxid without processing them. mostRecentTxid is updated after each processed tx, but processedTransactionCount is only bumped once at the end of the page. If persistence fails between those updates, mostRecentTxid can move ahead of the count-implied position and transactions in that gap are never ingested.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 44de95b. Configure here.

: defaults.moneroLightwalletServer
: this.currentSettings.enableCustomMonerod
? this.currentSettings.monerodServer
: defaults.monerodServer

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Empty custom server URL used

Medium Severity

When enableCustomServers or enableCustomMonerod is true, the engine uses moneroLightwalletServer or monerodServer directly. Those fields come from asMaybe(asString, …) and can be an empty string, which still passes truthy custom-mode checks. Wallet open, LWS login, and birthday recovery then target an invalid base URL instead of falling back to defaults.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by learned rule: Guard asOptional(asString) results against empty strings

Reviewed by Cursor Bugbot for commit 44de95b. Configure here.

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.

4 participants