Skip to content

refactor: earn flow + remove xstate/store - #551

Open
petar-omni wants to merge 178 commits into
mainfrom
feat/earn-effect-atom-poc
Open

refactor: earn flow + remove xstate/store#551
petar-omni wants to merge 178 commits into
mainfrom
feat/earn-effect-atom-poc

Conversation

@petar-omni

@petar-omni petar-omni commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Note

High Risk
Large new DeFi borrow path with wallet signing, transaction submission, and LTV validation touches money-moving flows; earn routing/state refactor could regress staking if mis-wired.

Overview
Adds a feature-flagged borrow experience in the dashboard (form → review → steps → complete, plus borrow position management), backed by a new borrow module: Effect Schema domain models, OpenAPI-generated BorrowApi client, and @effect/atom-react atoms for markets/positions, form state, action execution (sign/submit/confirm), and post-tx cache refresh.

Earn flow cleanup: drops EarnPageStateUsageBoundaryProvider / @xstate/store, removes common/get-token-balances.ts and getInitialToken from stake types, and tightens validator handling via a composite Validator.key (address + optional subnet) used in select-validator and position balance keys.

Tooling/config: OpenAPI generator gains BorrowApi (full httpclient + spec prep), optional CLI spec selection, VITE_BORROW_API_URL / VITE_FORCE_BORROW, and root pnpm.patchedDependencies removed; adds skeleton line/circle loaders for borrow UI loading states.

Reviewed by Cursor Bugbot for commit 6cf3187. Configure here.

@changeset-bot

changeset-bot Bot commented Jun 26, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 86f03c8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f2d2a83c-e736-49e8-b48f-3041b4042c82

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/earn-effect-atom-poc

Comment @coderabbitai help to get the list of available commands.

@aws-amplify-eu-central-1

Copy link
Copy Markdown

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-551.d2ribjy8evqo6h.amplifyapp.com

@aws-amplify-eu-central-1

Copy link
Copy Markdown

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-551.df4xyoi0xyeak.amplifyapp.com

Key validators by address and subnet so selection keeps distinct validator options.

Scope balance and init token options to the selected dashboard category.
@petar-omni
petar-omni marked this pull request as ready for review July 7, 2026 12:22
Philippoes
Philippoes previously approved these changes Jul 7, 2026

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

Stale comment

Philippoes
Philippoes previously approved these changes Jul 7, 2026

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

Stale comment

Risk: high. Not approving: this large earn/borrow refactor exceeds the low-risk approval threshold, Cursor Security Agent left an unresolved medium-severity finding, and required checks did not finish on the latest commit (Bugbot cancelled; Security Agent still running). Assigned jdomingos and dnehl for human review.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@cursor
cursor Bot requested a review from jdomingos July 7, 2026 12:31

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

Stale comment

Risk: high. Not approving: this large earn/borrow refactor exceeds the low-risk approval threshold, and Cursor Security Agent has an unresolved medium-severity tabnabbing finding on complete.tsx. jdomingos and dnehl are already assigned for human review.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

dnehl
dnehl previously approved these changes Jul 7, 2026

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

Played around with the flow - looks good.

  • no console errors
  • no "strange" multiple backend calls
  • duration looks good

@dnehl
dnehl self-requested a review July 7, 2026 14:11
Split earn intent and view atoms so route and wallet state changes update the resolved view.

Keep dispatch separate from view reads and add wallet resolution handling.

Cover dashboard tab selection and patch Effect parent tracking.
Use the native TypeScript 7 compiler across the widget and examples.
Keep TypeScript 6 API compatibility for Next.js tooling.

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

Stale comment

Risk: high. Not approving: this large earn/borrow refactor exceeds the low-risk approval threshold, and Cursor Security Agent has an unresolved medium-severity tabnabbing finding on complete.tsx. jdomingos and dnehl are already assigned for human review.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

Replace legacy context, query, and state-machine integrations with Effect services and
atom-backed wallet, API, and workflow state.

Split Vitest projects and add AST rules to validate the new architecture.
@petar-omni
petar-omni force-pushed the feat/earn-effect-atom-poc branch from 16d2bb4 to 67eb76f Compare July 15, 2026 08:42
Show collapsed source details for non-validator positions so protocol
yields have the same disclosure as validator-backed ones. Keep an
untouched zero unstake amount neutral until the user edits or submits.

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

Stale comment

Risk: high. Left a non-blocking comment and did not approve: this earn-flow refactor exceeds the low-risk threshold, and Cursor Security Agent still has unresolved high and medium findings that need human review. Reviewers were already assigned, so none were added.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

Connecting ticks were wiping the owner pair, so flow sessions and
wallet-scoped routes bounced after unstake/enter. Keep the pair until
disconnect, leave committed start navigation uninterruptible, and treat
the scope guard as a published Wallet State.
@petar-omni
petar-omni force-pushed the feat/earn-effect-atom-poc branch from 3b58f30 to 0b0a3d5 Compare August 27, 2026 11:06

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

Risk: high. Left a non-blocking comment and did not approve: this earn-flow refactor exceeds the low-risk threshold, and Cursor Security Agent still has unresolved high and medium findings that need human review. Reviewers were already assigned, so none were added.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

Move feed, action lookup, and details into Activity so Classic Flow only
executes continuable WAITING_FOR_NEXT actions. Completed and failed details
no longer open a Flow Session.
@petar-omni
petar-omni force-pushed the feat/earn-effect-atom-poc branch from 446701d to 34e6d6f Compare August 31, 2026 13:17
Treat Stellar mainnet as a wallet network whose passphrase is its protocol
identity. Add Freighter, Albedo, xBull, LOBSTR, and WalletConnect connections
through Stellar Wallets Kit.

Validate saved wallet sessions before restoring them and route XDR signing
through the shared wallet driver.
Stop surfacing English API reason and server prose in the modal. Render
known Error Copy with interpolated details and omit reason as a value.
Move mise to Node 24.20.0, npm 11.19.1, and pnpm 11.24.0 so local and CI
tooling match current releases.
@petar-omni
petar-omni force-pushed the feat/earn-effect-atom-poc branch from 34e6d6f to 4b751ed Compare August 31, 2026 13:31
…ariant

Activity feed and select modal each painted their own selected background.
Route both through ListItem's active variant so the highlight stays consistent.
Exit amount editability incorrectly required amount.required (or ERC4626),
so yields that advertise an optional amount locked the field at full balance.
Gate on amount presence and non-force-max instead.
Selecting a visible activity row already has the enriched item in the
feed. Prefer that row so the details pane skips the loading flash, and
only fetch by id when the action is missing from the loaded list.
Classic submit discarded explorerUrl and the complete page only read
router state, so links often never appeared after a finished action.
Keep submit explorer links in workflow meta and read them from live
workflow state on the complete screen.
Document that Total staked and Average APY stay at zero when a position
has a token amount but no amountUsd, or when the Yield is missing from
the lookup map. Drop unused isERC4626 helper.
Treat borrow AsyncResult waiting as a background refresh, not a first
load, so Manage summary and positions keep current data instead of
flashing the full-page spinner.
Warm Manage list/summary and Activity All after the landing tab's
primary resource is ready so those tabs paint from cache on navigate.
Reorganize app/routes into model/state/react/ui and mount route
effects (including prefetch) via useApplicationRouteEffects.
useLocation in App required Router context that jsdom mounts do not
provide, so prefetch from the router pathname stream instead.
Return Effect programs from it.effect and it.live instead of calling
Effect.runPromise in tests. Add a fixture-aware @effect/vitest wrapper
and an ast-grep rule that forbids Effect.run* in the widget test tree
except at documented non-Effect boundaries.
Collapse wagmi connect return casts into one helper, and type transaction
type labels through i18n keys plus a fallback instead of never escapes.
Replace per-test Wallet, Tracking, and Navigation stubs with reusable
helpers so classic-flow tests can mutate wallet state without as-never
service shapes.
Replace the typescript catalog dependency with @typescript/native so the
example typechecks with tsgo instead of tsc.
Classic-flow and transaction-workflow tests each assembled layers by
hand and copied wallet-state objects. Shared kits plus wallet-state
fixtures so those suites compose the same doubles and mutate real
wallet state.
Wire @effect/tsgo and the Effect language service into widget
typechecking, replace unknown Effect and AsyncResult errors with
tagged domain errors, and add ast-grep rules to prevent regressions.
AddressRow left labels sat above the address and copy icon because
the row flex container defaulted to stretch while only the right side
centered its content. Align items in the row and match label styling
to DetailRow.
Project ExternalProviderError customMessage through WalletSigningError so
message-signing failures show the host wallet prompt, matching broadcast
errors.
Route EIP-712 Borrow payloads through typed-data signing and preserve host errors.

Keep Borrow nonces optional without weakening classic transaction decoding.
Reject invalid count fields instead of substituting signing values.
Trim the repo tree by replacing the vendored Effect subtree with a
submodule pinned to catalog effect@4.0.0-rc.112. Consumers init via
`git submodule update --init .repos/effect`.
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