Skip to content

chore: merge main into ousdt - #855

Draft
hyper-gonk[bot] wants to merge 192 commits into
ousdtfrom
main-to-ousdt
Draft

chore: merge main into ousdt#855
hyper-gonk[bot] wants to merge 192 commits into
ousdtfrom
main-to-ousdt

Conversation

@hyper-gonk

@hyper-gonk hyper-gonk Bot commented Dec 15, 2025

Copy link
Copy Markdown
Contributor

⚠️ This PR has merge conflicts that need to be resolved manually.

This PR was automatically created to merge changes from main into ousdt.

CJ42 and others added 30 commits August 26, 2025 18:43
…estination chain that is not a smart contract (#714)

# Context

When users bridge tokens between chains (e.g. from Base to Ethereum)
using a smart contract wallet, they might enter their own wallet address
as the recipient on the destination chain.

But if that smart wallet is only deployed on the source chain (e.g. Base
✅) and not on the destination chain (e.g. Ethereum ❌), there's no
contract on the destination side to control the funds.

This can result in the user loosing its bridged tokens, as they cannot
be accessed on the destination chain in this scenario, **since the smart
contract wallet is not deployed on the destination chain**.



# ☑️ How does this PR mitigates this issue?

This PR prevents accidental loss by checking the bytecode at the
recipient address on the destination chain, if a smart contract wallet
is connected to the UI and the same recipient address is used.

# 🔄 Flow

1. User connects a smart contract wallet to the dApp.
2. They select the source/destination chain, token, and enter an amount
to bridge.
2. They enter their own wallet address as the recipient.

Then the app checks:

- ✅ Is the connected wallet a smart contract? _Yes_
- ✅ Is the recipient address the same? _Yes_
- ❌ Is there any bytecode at that address on the destination chain? Is
it a smart contract at that address on the destination chain? _No_

> If so, the "Continue" button is disabled and a warning message is
shown.
> The user can tick a checkbox to proceed only if they are sure they can
control the recipient address on the destination chain.

<img width="1328" height="1564" alt="image"
src="https://github.com/user-attachments/assets/ff9d710e-f1bd-4a14-abaf-9831c1485986"
/>

# Demo


https://github.com/user-attachments/assets/562da9bb-64e9-4601-b48b-5784811fc70b



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Recipient warning banner for Ethereum→Ethereum transfers with
explanatory text and a confirmation checkbox that gates submission.
* Submit button disabled until the user confirms control of the
recipient address.
* On-chain contract checks and friendly chain names with clear error
feedback; wallet disconnect hides the banner and resets confirmation.

* **Bug Fixes**
* Reduces accidental transfers by blocking submission until recipient
ownership is confirmed.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: default <b00ste.lyx@gmail.com>
Upgrade hyperlane packages
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- New Features
- Added Radix wallet support; users can now connect and interact using
Radix wallets.
  - Wallet connect modal now includes a Radix option.
- Added a public Radix manifest for improved wallet discovery and
compatibility.

- Chores
- Upgraded Hyperlane dependencies to the latest major version for
compatibility and stability.
- Added Radix SDK/toolkit dependencies to enable the new wallet
integration.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Troy Kessler <troy.kessler99@gmail.com>
- Fixed an issue where the checks for multi-collateral warp route was
not accounting for `HypNative` standards
- Bump hyperlane packages

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Enhanced support for HypNative tokens without a collateral address,
improving validation, matching, and deduplication across chains.
* **Bug Fixes**
* More accurate handling of multi-collateral tokens to reduce false
negatives and duplicates for HypNative scenarios.
* **Tests**
* Expanded coverage for HypNative origin/destination cases and
non-HypNative failure paths.
* **Chores**
  * Bumped Hyperlane dependencies to 18.2.0 (SDK, utils, widgets).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
bumping to match nexus version
chore: update registry to v23.2.0
Fixes critical vulnerabilities in vitest and transitive dependencies
(sha.js, cipher-base, elliptic, pbkdf2, form-data). All tests pass.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated development and runtime dependencies, including pinning and
patching select transitive packages to improve compatibility and
security. These changes enhance build stability without affecting
user-facing behavior.
* **Tests**
* Upgraded the testing framework to the latest patch release, improving
reliability and performance of the test suite.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Upgraded key third-party dependencies to the latest major release
(v19.1.0) to align with upstream ecosystem updates.
* Brings improved compatibility, stability, and potential security and
performance enhancements from upstream packages.
* No user-facing behavior changes are expected; existing features should
continue to work as before.
* Minimal testing impact anticipated—basic smoke tests recommended to
confirm end-to-end functionality remains intact.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This PR implements custom event tracking using vercel analytics as a
first approach to track user interactions in the website.

- Include a flag `enableTrackingEvents` in the configurations which will
enable/disable custom even trackings depending on the branch
- Add `EVENT_NAME` and `EventProperties` which includes the custom event
name and the fields that will be added
- Include functions to track custom events
- Current events being tracked
  - Chain Selection
  - Token Selection
  - Transaction Submission
  - Transaction Submission Failed
  - Wallet Connection Initiated
  - Wallet Connected

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Added analytics for wallet connection initiation and connected wallets
(deduplicated).
* Added analytics for chain selection, token selection, transaction
submission, and transaction failures.
* Transaction submission events include transaction hash, chain info,
amount and wallet details.
* New config flag enableTrackingEvents (default: false) to toggle
analytics.

* **Bug Fixes**
* Submit button click now consistently triggers connection analytics
when a wallet connection is initiated.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Update analytics event to be more consistent so that it represents
actions
- Include sessionId from the app instead, remove one property from tx
failed
- Include custom Page Viewed event
This PR is taken from
#746,
removing only the piece related to tokenFeeQuote and getting lowest fee
route

- Adds FeeSectionButton and TransferFeeModal that displays the amount of
transfer fee the user has to pay
- Update useFeeQuotes to reflect the changes related to fees
- Update hyperlane packages

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a fee section button and a modal showing detailed local and
interchain fee breakdowns.
* Added utilities to compute and consolidate transfer fees and to select
the optimal transfer token.

* **Updates**
* Updated Hyperlane registry, SDK, utils, and widgets to newer versions.
  * Added a documentation link for fee estimation.
* Review/details view updated to conditionally surface fee information
and improved fee-fetching behavior (optional highest-collateral token
search).

* **Tests**
  * Added comprehensive tests covering fee aggregation and edge cases.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
fixes
[ENG-2200](https://linear.app/hyperlane-xyz/issue/ENG-2200/warp-template-ui-should-show-fees-also-in-usd-terms)

- Fetches token prices in USD from the CoinGecko API
- Shows token price multiplied by the amount
- Attach `coinGeckoId` when warpCore is when built to each token that
has no `coinGeckoId` (synthetic tokens mostly)


<img width="548" height="350" alt="image"
src="https://github.com/user-attachments/assets/af5b843c-c505-4631-8bab-99e741429630"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Token transfers now show approximate USD prices below the amount input
(en-US, two decimals). Prices appear only when the converted total is at
least $0.01.
* Pricing updates automatically every 60 seconds and loads without
refetching on window focus.

* **Improvements**
* Price availability is more consistent across routes by filling missing
price identifiers from related tokens when possible.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This PR closes
[ENG-1979](https://linear.app/hyperlane-xyz/issue/ENG-1979/ui-should-support-arbitrary-quotetransferremote-fees),
[ENG-2078](https://linear.app/hyperlane-xyz/issue/ENG-2078/ui-should-show-user-fees-before-telling-validating)
and
[ENG-2079](https://linear.app/hyperlane-xyz/issue/ENG-2079/ui-should-pick-route-with-lowest-fee
)

With the inclusion of `tokenFeeQuote`, the UI needs to account for this
new fee field
- Creates a `FeeSectionButton` that shows total fees, this section will
show before validation and clicking it will show a detail modal
- Now searches for route with lowest fee (tokenFeeQuote) instead of
highest collateral value in destination
- Introduce a few utils function to help with fee managing

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a "Token Fee" line to the transfer fee breakdown when
applicable.

* **Improvements**
  * Fee values now show 8 decimal places for clearer pricing.
  * Transfer routing now prefers lower-cost routes to reduce fees.
* Smarter fee estimation and validation: debounced amounts, sender-aware
lookups, fee-aware max-transfer calculations, and minor layout spacing
refinements.

* **Chores**
  * Updated internal dependencies.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Fixed an issue where it would return the originToken if no token with
fees was found instead of tokens that have enough collateral to bridge

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved fallback token selection logic for transfers when no
fee-enabled routes are available. The system now prioritizes selecting
from available token balances instead of defaulting to the original
token.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Upgrade packages to 19.9.0
This was already done for warp route data but not chain metadata
chore: update registry to 23.6.0
This PR update TokenListModal to:

- Search by token `collateralAddressOrDenom`
- Include both `addressOrDenom` and `collateralAddressOrDenom` to
unsupported token list search
…stead (#816)

- Fixes an issue where `dedupeTokens` would merge tokens from m0
standards because they have the same `addressOrDenom` for all routes,
adding `symbol` to `dedupeTokens` fixes this
- Now URL query params use symbol instead of `addressOrDenom`, some
duplications will be expected but not for production instances since
there is a defined `warpRouteWhiteList`
Using the current version of the `dedupeToken` causes
`WarpCore.findToken()` to fail because it returns two results from the
`gasAddressOrDenom` returned from the adapter, this temporary fix the
issue by separating m0 tokens `dedupeToken` id as I figured out the
issue

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Fixed token deduplication so M0 Portal Lite tokens are distinguished
from other token types (uses token symbol plus chain to avoid collisions
when address/denom overlaps).

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
…824)

## Summary

This PR makes the `create-merge-prs` workflow more robust and migrates
to using Hyper Gonk GitHub App authentication (matching the pattern in
hyperlane-monorepo).

### Changes

**Gonk Migration:**
- Replace `GITHUB_TOKEN` with Hyper Gonk GitHub App authentication
- Uses `HYPER_GONK_APP_ID` and `HYPER_GONK_PRIVATE_KEY` secrets
- Git commits now show as Hyper Gonk bot instead of
`github-actions[bot]`

**Merge Conflict Handling:**
- Check if merge is actually needed before attempting (skip if branch is
up-to-date)
- Gracefully handle merge conflicts by aborting and reporting
- Output clear warnings/errors when conflicts occur

**Additional Robustness:**
- Add `workflow_dispatch` for manual triggering
- Add concurrency control to prevent race conditions
- Add explicit `permissions` declaration (`contents: write`,
`pull-requests: write`)
- Upgrade `actions/checkout` from v3 to v5
- Better logging messages throughout

### Prerequisites

Ensure the following are configured:
- Hyper Gonk GitHub App is installed on this repository
- `HYPER_GONK_APP_ID` secret is set
- `HYPER_GONK_PRIVATE_KEY` secret is set

## Test plan

- [ ] Verify secrets are configured in the repository
- [ ] Manually trigger the workflow via Actions tab
- [ ] Verify workflow runs successfully for branches that need updates
- [ ] Verify workflow skips branches already up-to-date

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added manual workflow trigger capability for merge PR creation.
  * Implemented automatic merge conflict detection and handling.

* **Chores**
  * Enhanced security with improved token management.
  * Optimized PR creation logic for better branch merge workflows.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude <noreply@anthropic.com>
## Summary
- Adds a weekly workflow that automatically updates Hyperlane
dependencies (sdk, utils, registry, widgets)
- Uses Hyper Gonk GitHub App for authentication to ensure CI workflows
are triggered on PRs

## Details
The workflow runs every Monday at 9 AM UTC and can also be triggered
manually. It:
1. Fetches latest versions from npm
2. Updates package.json
3. Runs yarn install
4. Creates/updates a PR with the changes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
  * Enabled automated weekly updates for core dependencies.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Automated Dependency Update

This PR updates the Hyperlane dependencies to their latest versions.

**Updated versions:**
- `@hyperlane-xyz/sdk`: `19.11.0`
- `@hyperlane-xyz/utils`: `19.11.0`
- `@hyperlane-xyz/registry`: `23.7.0`
- `@hyperlane-xyz/widgets`: `19.11.0`

**Changes include:**
- Updated `package.json` with latest Hyperlane package versions
- Updated `yarn.lock` via `yarn install`

---
🤖 This PR was automatically generated by the [update-hyperlane-deps
workflow](.github/workflows/update-hyperlane-deps.yml)

Co-authored-by: hyper-gonk[bot] <246310972+hyper-gonk[bot]@users.noreply.github.com>
## Summary
Fixes the authentication order in the `create-merge-prs.yaml` workflow
so that gonk token is used correctly for pushes.

**Problem:** The workflow was checking out the repo before generating
the gonk token, so the remote URL was configured with the default
`GITHUB_TOKEN` instead of gonk credentials.

**Solution:**
- Move token generation **before** checkout
- Add `token:` parameter to checkout step
- Add user ID lookup for proper email format (consistent with other
workflows)

This should fix the issue Jason identified in #829 where the workflow
wasn't using gonk credentials correctly.

---
🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Optimized internal CI/CD workflow for pull request automation,
improving authentication handling and Git configuration management.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
hyper-gonk Bot and others added 12 commits June 19, 2026 16:07
## Summary
- Hides the "Add token to Wallet" button for `HypNative` token standards
- `HypNative` contracts extend `ERC4626Upgradeable` (via
`LpCollateralRouter`) but never call `__ERC20_init`, so `symbol()`
returns `""`
- When `wallet_watchAsset` is called, viem validates the passed symbol
against the on-chain `symbol()` — the mismatch (`"NES" !== ""`) throws
an `Invalid parameters` error
- Hiding the button is also semantically correct: native gas tokens are
already in the user's wallet; the `HypNative` contract is only a bridge
wrapper

## Test plan
- [x] Open the bridge with
`?origin=nesa&originToken=NES&destination=bsc&destinationToken=NES`
- [x] Confirm "Add token to Wallet" button is no longer shown for the
origin NESA NES token
- [x] Confirm "Add token to Wallet" still works for non-native synthetic
tokens (e.g. BSC NES)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
- Add Aleo (Shield wallet) warp route support: `aleotestnet` chain
config, warp route entry, and wallet adapter integration
(`AleoWalletContext`) via `@provablehq/aleo-wallet-adaptor-*` and
`@hyperlane-xyz/aleo-sdk`
- Make the Aleo network the Shield wallet connects to configurable via
`NEXT_PUBLIC_ALEO_NETWORK` (defaults to `mainnet`), instead of it being
hardcoded — set to `testnet` for this app's `aleotestnet` warp route
- Upgrade `@hyperlane-xyz/*` deps from locally-linked monorepo tarballs
to the latest published npm releases
(`widgets`/`sdk`/`utils`/`aleo-sdk`/`cosmos-sdk`/`radix-sdk`/`sealevel-sdk`
→ `36.0.0`, `deploy-sdk`/`provider-sdk` → `7.0.0`, `starknet-sdk` →
`28.1.2`, `tron-sdk` → `23.1.2`), removing the `.monorepo-tarballs` /
`pnpm.overrides` linking setup entirely

## Test plan
- [x] `pnpm typecheck` passes
- [x] `pnpm lint` passes (no new errors, pre-existing warnings only)
- [x] `pnpm test` passes (252/252)
- [x] Manually verify Shield wallet connect flow against `aleotestnet`
with `NEXT_PUBLIC_ALEO_NETWORK=testnet`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
## Summary
Port of #1166 (which was merged to `nexus`, not `main`) — the diff from
that branch to `main` is large, so this is a clean re-apply of only the
relevant change.

- `NEXT_PUBLIC_RPC_OVERRIDES` was appended to the **end** of the EVM
`rpcUrls` list. viem's `fallback()` transport uses `rank=false`, so it
always tries `rpcUrls[0]` (the public primary, e.g. `base.drpc.org`)
first and only reaches the override after the primary exhausts retries —
meaning a configured keyed/premium endpoint was effectively never used.
- Prepend the override for all protocols so a keyed premium endpoint is
the **primary** RPC, with the registry's public URLs kept as fallback
(EVM fallback transport).

## Context
Fixes the recurring HTTP 429 rate-limit errors NESA hit on the base leg
of NES transfers (public `base.drpc.org` was rate-limiting). Already
merged to `nexus` as #1166; this brings the same fix to `main`.

## Test plan
- [ ] `pnpm typecheck`
- [ ] `pnpm lint`

🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
- The warp UI "Fatal Error Occurred" error page linked to the Hyperlane
**Discord**, which no longer exists.
- Repoints the support link to the Hyperlane **Help Center**
(`links.support` → https://help.hyperlane.xyz/) and updates the copy to
"For support, visit the Hyperlane Help Center".
- After this change `links.discord` is no longer referenced anywhere in
`src/` (only its now-dead definition remains in `src/consts/links.ts`).

Reported by a customer who hit the error page (via a separate
WalletConnect QR crash, tracked/fixed separately).

## Test plan
- [ ] Trigger the ErrorBoundary and confirm the support link points to
https://help.hyperlane.xyz/ and reads "Hyperlane Help Center"
## Summary
Opening the WalletConnect QR modal on Nexus crashed with **"Fatal Error
Occurred / invalid border=0"**, tripping the app error boundary. Root
cause is a transitive dependency floating forward:

- RainbowKit `2.2.10` renders the WC QR via `cuer@0.0.3`, whose
`create()` calls `encodeQR(value, 'raw', { border: 0, ... })` — border
hardcoded to `0`.
- `cuer` depends on `qr` with a loose `"~0"` range. Upstream `qr@0.6.0`
(published 2026-04-28) **added** `if (border <= 0) throw new
Error(\`invalid border=${border}\`)`. `qr@0.5.5` only validated the
border *type* and accepted `0`.
- A routine lockfile regen (`chore: merge main into nexus #1163`,
2026-07-17) bumped the lockfile's `qr` from `0.5.5` → `0.6.0`, baking
the incompatibility into the deployed build.

This pins `qr` to `0.5.5` via the `pnpm-workspace.yaml` override.
Dependency-only change; no app code touched.

## Verification
Ran `cuer`'s exact QR-encode path against both versions:
- `qr@0.6.0`: `encodeQR(..., { border: 0 })` → **THREW: invalid
border=0** (reproduces the customer crash)
- `qr@0.5.5` (pinned): `encodeQR(..., { border: 0 })` → **OK, 37-row
grid**
- `cuer.create(...)` end-to-end with pinned qr → **OK, 33×33 grid**

## Test plan
- [ ] On a preview build, open the wallet modal and select
WalletConnect; confirm the QR renders and no error boundary appears.

Co-authored-by: Jason Guo <33064781+Xaroz@users.noreply.github.com>
…-aleo-lazy

perf: reduce initial bundle size after Aleo lazy loading
## Summary

- update `@hyperlane-xyz/sdk`, `@hyperlane-xyz/utils`, and
`@hyperlane-xyz/widgets` from `39.0.0` to `39.1.0`
- consume the released Radix browser-runtime lazy loading and Starknet
runtime/deployment-artifact split
- keep the Radix toolkit and gateway client stable across React renders
- keep Starknet provider and chain configuration stable, while using
narrow public SDK and registry imports
- tighten route bundle budgets so the reduction cannot regress silently

## Runtime changes

Radix provider construction now loads its browser implementation only
when the SDK provider is used. The private-key signer remains outside
the normal browser path. The UI also avoids recreating
`RadixDappToolkit` and `GatewayApiClient` on every render, preventing
duplicate listeners and wallet-state resets.

Starknet runtime consumers now receive only the ABI and class-hash data
required by adapters. Full Sierra/CASM deployment artifacts remain
available to deployment tooling but are no longer included in the
browser runtime. The UI preserves the same registry-derived fallback
chain and wallet connectors while stabilizing the provider
configuration.

## Bundle benchmarks

Clean Turbopack production builds, comparing `main` with Hyperlane
packages `39.0.0` against this branch with `39.1.0`:

| Route | Previous raw | New raw | Raw reduction | Previous gzip | New
gzip | Gzip reduction |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| `/` | 126.22 MiB | 45.64 MiB | 63.8% | 23.62 MiB | 7.71 MiB | 67.4% |
| `/embed` | 128.04 MiB | 47.45 MiB | 62.9% | 23.95 MiB | 8.05 MiB |
66.4% |
| `/blocked` | 100.86 MiB | 27.70 MiB | 72.5% | 18.05 MiB | 5.02 MiB |
72.2% |

The route budgets now cap `/` at 47 MiB raw / 8.2 MiB gzip, `/embed` at
49 MiB / 8.6 MiB, and `/blocked` at 29 MiB / 5.4 MiB.

## Validation completed

- formatting
- linting (no errors; three existing `no-console` warnings)
- TypeScript typecheck
- 254 unit tests
- production build and bundle-budget check
- all 76 Chromium production E2E tests, including Radix and Starknet
auto-connect and wallet-modal flows
## Summary

- Increase the root route raw bundle budget from 47 MiB to 50 MiB.
- Keep the 8.2 MiB gzip budget unchanged.

## Context

This accommodates customized deployments such as Nexus while preserving
the compressed-size regression guard.
## Summary

Adds an engine-owned Transfer experience backed by the Universal Router
Engine. The UI uses the engine as the source of truth for chains,
tokens, routes, quotes, approvals, executable tx payloads, fees, and
available bridge-only routes, while applying client-side validation and
security gates before anything reaches a wallet.

## What Changed

### Transfer UX
- Adds a single Transfer form on `/` for same-chain swaps, bridge-only
transfers, and cross-chain swap routes.
- Uses engine-driven source/destination token cards, route selection,
slippage controls, fee breakdowns, approval/revoke/send flow, and a
unified transfer details modal.
- Supports deep-link/default-token behavior with engine token identity.
- Uses `/available-routes` when opening token modals only for
bridge-only opposite-side tokens, with dedupe against the regular token
list.

### Engine API Integration
- Adds `src/features/api/` router client, Zod schemas, React Query
hooks, and shared route tx helpers.
- Consumes engine `/chains`, `/tokens`, `/quote`, and
`/available-routes` responses.
- Supports engine approval payloads, quote expiry, slippage bps,
commitment salt, CCS/reveal-message flow, tx/txs payloads, and route
execution metadata.
- Uses registry validation for bridge-only route trust checks.

### Multi-VM Balances And Execution
- Adds shared multi-VM balance readers for EVM, Tron, Sealevel/Solana,
Starknet, Cosmos, Radix, and Aleo where supported.
- Handles collateral-token balance reads from engine token metadata.
- Adds native/IGP/gas validation, including EVM gas estimation and
Starknet execution fee estimation where available.
- Supports EVM/Tron and Sealevel execution payloads from the engine,
including SVM metaswap support.

### Message Tracking And History
- Adds unified transaction history/state for engine transfers.
- Decodes EVM/Tron dispatch logs, handles CCS reveal message ids, and
labels bridge/swap message ids correctly.
- Adds GraphQL origin-tx backfill and mailbox delivery polling for
non-EVM / delayed destination tx discovery.
- Keeps delivery watching in the background and avoids repeated status
updates for the same delivery target.

### Security Gates
- Adds route-security validation for engine quote responses before
signing.
- Validates bridge-only routes against registry warp routes with
packaged registry fallback.
- Validates route chain path, route tx targets, SDK warp tx metadata,
SVM router/asset accounts, approval kind/token/spender/amount,
native-route approval absence, and runtime API schemas.
- Fails closed on bad/missing security context with a dedicated `Route
data unavailable` state.
- Adds recipient safety checks: EVM smart-contract recipient warning and
destination zero-native-balance confirmation.

### Refactor / Cleanup
- Organizes reusable token, chain, balance, message, and route-security
logic into feature-level folders.
- Adds Zustand state/migration support for engine transfer history.
- Updates docs/customization references for the engine-owned flow.
- Removes stale local warp-route whitelist/default route config usage
from the active transfer path.

### Tests / E2E
- Adds/updates unit tests for API schemas/client, route security,
registry warp route validation, balances, message parsing/delivery,
store migration, quote validation, transfer execution helpers, and token
utilities.
- Updates e2e coverage for page load, token/chain selection, balances,
approvals, invalid routes, tx payload security, destination-router
guards, same-symbol dedupe, wallet modals, and embed/sidebar
regressions.

## Engine / Registry Notes

- The UI currently validates EVM/Tron-like universal-router tx targets
against `srcChain.universalRouter` from engine chain discovery.
- SVM program id pinning is deferred until trusted per-chain
`universalRouter` data exists in registry/package fallback. Only chains
with a real swap/universal-router mechanism should expose that optional
field.
- Full step-by-step token continuity across swap plus bridge still needs
richer engine route step token-in/token-out data.

## Current Review State

- Route-security follow-up PR was merged into this branch.
- Claude and Copilot reviewed the route-security head clean; Copilot
reported 14/14 files reviewed with no new comments.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Troy Kessler <43882936+troykessler@users.noreply.github.com>
…ype-analytics

feat: classify submitted Nexus transactions as bridge or swap

@paulbalaji paulbalaji left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

integration review at exact head dc5f29e3. the automated merge committed unresolved conflict markers across 32 files, including workflows, dependencies, runtime code, config, and assets. this is not a usable sync yet; resolve against the current main architecture while preserving only ousdt-specific config/branding, then run the full branch CI.

Comment thread .github/workflows/ci.yml Outdated
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v6
with:
<<<<<<< HEAD

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Blocking: this is one of unresolved conflict regions committed across 32 files. Because the workflow itself is conflicted, the PR is not exercising its build/typecheck/test suite. Resolve the full merge first; do not treat the green third-party statuses as validation of this head.

hyper-gonk Bot and others added 17 commits August 13, 2026 11:15
## Automated Dependency Update

This PR updates the Hyperlane dependencies to their latest versions.

**Updated versions:**
- `@hyperlane-xyz/sdk`: `41.0.0`
- `@hyperlane-xyz/utils`: `41.0.0`
- `@hyperlane-xyz/registry`: `25.4.0`
- `@hyperlane-xyz/widgets`: `41.0.0`

**Changes include:**
- Updated `package.json` with latest Hyperlane package versions
- Updated `pnpm-lock.yaml` via `pnpm install`

---
🤖 This PR was automatically generated by the [update-hyperlane-deps
workflow](.github/workflows/update-hyperlane-deps.yml)

Co-authored-by: hyper-gonk[bot] <246310972+hyper-gonk[bot]@users.noreply.github.com>
…n-token

fix: stop destination prefill after user interaction
## Summary

- derive Sealevel synthetic Token-2022 mints from Warp router program
IDs before reading balances
- use the SDK Sealevel token adapter for single-token balance validation
while preserving batched UI reads
- show the selected destination token for terminal cross-chain route
nodes, fixing Aleo → Solana ALEO routes displaying SOL
- add focused regression coverage for both issues
…allet-when-recipient-empty

fix: prompt destination wallet connect when recipient is empty
## Summary

- Resolve wallet readiness against the selected chain address.
- Keep the connect action available when a Cosmos wallet is connected to
another chain only.
- Add regression coverage for the partially connected Cosmos case.

Follow-up to #1199 and [this review
comment](#1199 (comment)).
## Summary

- upgrade policy-eligible dependencies, including Hyperlane packages 41,
TypeScript 7, pnpm 11.20, oxlint 1.77, oxfmt 0.62, Vitest 4, Next.js
16.2, React 19.2, and Sentry 10
- retain Node.js 24 because it is the newest runtime currently supported
by Vercel
- upgrade checkout, setup-node, cache, and pnpm setup actions to current
majors; contain Oxfmt 0.62 output to two files
- adapt Next.js, CosmosKit, Solana wallet, and Vitest integration points
for the upgraded APIs
- restore build-time TypeScript validation and fold the standalone CI
setup into the build gate
- update the Aleo WASM patch and pnpm build-script allowlist; pin
Coinbase CDP before its optional x402 imports inflate browser bundles
- raise only the `/embed` raw bundle budget from 49 MiB to 50 MiB; gzip
budget remains unchanged

Most of the diff is generated lockfile churn: `pnpm-lock.yaml` accounts
for 9,578 of 9,909 changed lines.

## Bundle validation

Exact-head production build:

| Route | Bundle size | Budget |
| --- | ---: | ---: |
| `/` | 15.06 MiB raw / 3.89 MiB gzip | 50.00 MiB / 8.20 MiB |
| `/embed` | 16.39 MiB raw / 4.22 MiB gzip | 50.00 MiB / 8.60 MiB |
| `/blocked` | 10.85 MiB raw / 2.92 MiB gzip | 29.00 MiB / 5.40 MiB |

## TypeScript 7 performance

Three alternating local runs on Node 24 used the original
dependency-upgrade head and dependency graph, changing only TypeScript
6.0.2 versus 7.0.2:

| Step | TS6 median | TS7 median | Change |
| --- | ---: | ---: | ---: |
| `tsc --noEmit` | 4.29s | 1.22s | 71% faster |

Raw typecheck runs were TS6 `6.69/4.29/3.58s` and TS7 `1.50/1.22/0.78s`.
Next/Turbopack compilation bypasses the TypeScript compiler, so its
noisy build timings are not attributed to TS7. With build-time
validation restored, the TypeScript stage took 1.18s locally and 2.1s in
exact-head CI. On the previous PR head, GitHub's standalone typecheck
took 2s but its full checkout/install/cache job took 91s. That head's CI
reduced the branch-protection compatibility job to 3s, saving 88
runner-seconds while keeping validation in the required build.

## Validation

- `pnpm install --frozen-lockfile`
- `pnpm format`
- `pnpm typecheck`
- `pnpm lint` (two pre-existing `no-console` warnings)
- `pnpm test` (44 files, 304 tests)
- `NEXT_PUBLIC_WALLET_CONNECT_ID=test pnpm build`
- `pnpm check:bundle`
- `E2E_USE_PROD=1 NEXT_PUBLIC_WALLET_CONNECT_ID=test pnpm
test:e2e:wallet:smoke` (5 tests)
- `git diff --check`

After syncing current `main`, exact-head local validation passed with
Hyperlane 41, including the production build and 5-test
production-backed wallet smoke suite.

## Compatibility holds

Chakra UI, CosmJS, Starknet React, wagmi, Zod, Zustand, Tailwind, and
bignumber.js remain on their latest compatible majors because current
application or wallet dependencies do not support the newer majors. The
deprecated Drift Snap and Backpack adapters remain because their
installed releases are still the latest available and are actively used.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Large dependency surface (wallets, Next, Sentry, TS 7) plus restored
build-time typechecking and always-on CI builds increase regression
risk; changes are mostly tooling and integration rather than core
transfer logic.
> 
> **Overview**
> **Dependency and toolchain refresh** across the app and lockfile:
TypeScript **7**, Next **16.2**, React **19.2**, Sentry **10**, Vitest
**4**, pnpm **11.20**, oxlint/oxfmt bumps, and wide wallet/UI package
updates (CosmosKit, Solana adapters, RainbowKit, wagmi/viem, Hyperlane
**41** / registry **25.4**, etc.). **Oxlint** drops the `camelcase`
rule; **Vitest** runs with `--run` and excludes `.next/**`.
> 
> **Build and CI behavior changes:** `next.config.js` removes
`typescript.ignoreBuildErrors` and enables
**`experimental.useTypeScriptCli`** so production builds typecheck
again. The **`build` job always runs `pnpm build`** (no skip on `.next`
cache hit). The standalone **`typecheck` job** is reduced to a stub that
**`needs: build`** for branch-protection compatibility. GitHub Actions
move to current majors (`checkout@v7`, `setup-node@v7`, `cache@v6`,
`pnpm/action-setup@v6`).
> 
> **Runtime integration:** The **@provablehq/wasm** patch only
auto-inits WASM in browser/worker contexts (avoids SSR/Node eager init).
Solana wallet setup switches to **named adapter imports** from
`@solana/wallet-adapter-wallets` (per upgraded package layout).
> 
> **Bundle gate:** `/embed` raw budget in `check-bundle-size.mjs` is
**50 MiB** (gzip unchanged).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
91893f2. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## Summary

- Constrain recipient addresses to the confirmation modal width.
- Allow character-level wrapping for long, unbroken addresses such as
Aleo accounts.
- Keep the full address visible and selectable before the user confirms
a fresh recipient.

## Root cause

The address paragraph was a centered flex child with its default
intrinsic minimum width. Long Aleo addresses contain no natural break
points, so the element overflowed both sides of the modal and hid the
beginning of the address.

## Verification

- `pnpm typecheck`
- `pnpm test` — 304 tests passed
- `pnpm exec oxfmt --check
src/features/wallet/RecipientConfirmationModal.tsx`
- `pnpm lint` — 0 errors; 2 existing E2E mock warnings
## Summary

- accept locally trusted wrapped-native tokens at Universal Router swap
boundaries around native Warp Routes
- preserve native-sentinel, registry-router, and non-native token
validation
- add regression coverage for trusted and untrusted wrappers, execution
mode, bridge asset, and router binding

## Checks

- `pnpm test`
- `pnpm lint`
- `pnpm typecheck`
- `pnpm build`
## Summary

- Resolve vault collateral underlying tokens during registry
initialization.
- Validate bridge assets and SDK approvals against the resolved
underlying token.
- Live-estimate nested EVM SDK transactions only for vault collateral
origin standards.
- Preserve existing behavior for non-vault SDK routes and direct
transactions.

Depends on hyperlane-xyz/universal-router-engine#94.
## Summary

- avoid double-counting IGP already embedded in the route input amount
- validate only separately funded IGP plus source-network transaction
fees
- use each max route's engine-calculated source transaction fee for
validation and fee display
- estimate source fees for manually entered amounts through the SDK
multi-protocol provider
- wait while quote-time allowance checks are pending; if a read fails,
reserve the two-transaction classic ERC20 worst case and re-check
exactly before any broadcast
- require explicit `fee.igpIncludedInAmountIn` metadata
- share the prepared transaction between fee estimation and wallet
execution, including the configured Solana provider
- preserve approval, Starknet, ERC20, synthetic, swap, and
multi-transaction handling

## Max flow

1. Clicking **Max** cancels any ordinary quote in flight and calls `POST
/v1/quote/max` once.
2. The UI fills the returned amount and seeds the ordinary quote cache
with the same executable max response, avoiding a second `/quote` call
caused by the input update.
3. While the request and filled amount remain unchanged, that response
stays authoritative until `expiresAt`: neither `/quote` nor `/quote/max`
is refreshed, and the input is not rewritten.
4. At expiry, the UI calls ordinary `/quote` for the fixed input and
resumes its normal 25-second refresh cadence. If current fees no longer
fit the balance, validation blocks the transfer and the user can press
**Max** again.
5. Editing the amount, token pair, recipient, or slippage exits the
preserved Max intent and uses ordinary quoting.
6. Send uses the same execution path for normal and max quotes. It
performs fresh exact approval/revoke checks and aborts before
broadcasting if those checks cannot resolve.

## Dependencies

- hyperlane-xyz/universal-router-engine#87 provides explicit IGP funding
metadata
- hyperlane-xyz/universal-router-engine#92 provides maximum quotes and
per-route source transaction fees
- SDK 42.0.0 includes balance-independent fee estimation from
hyperlane-xyz/hyperlane-monorepo#9313, the Solana message-fee fix from
hyperlane-xyz/hyperlane-monorepo#9270, and the EIP-1559 fee fix from
hyperlane-xyz/hyperlane-monorepo#9279
- ordinary Ethereum and Tron fees use the SDK estimate directly; local
EVM-like pricing remains only for conservative approval/revoke gas
budgets
- Starknet max quotes currently use the full source-token balance with a
zero source-fee placeholder until unsigned server-side estimation is
available
## Summary

- validate plain XERC20 quote assets and approvals against registry
`collateralAddressOrDenom`
- lazily resolve EVM XERC20 lockbox spend tokens through the SDK adapter
using the trusted registry router; cache the result across quotes
- keep Warp router validation separate, preserve strict SDK
approval-token checks, and fail closed when required token metadata is
unavailable
- leave Tron lockboxes fail-closed until a trusted Tron `wrappedToken()`
resolver is available

Companion engine fix:
hyperlane-xyz/universal-router-engine#96

## Validation

- `pnpm test` — 343 tests passed
- focused quote, resolver, and route-security regressions — 135 tests
passed
- `pnpm lint`
- `pnpm typecheck`
- `pnpm build`
- touched-file lint and format checks passed
# Conflicts:
#	.github/workflows/ci.yml
#	.github/workflows/create-merge-prs.yaml
#	.github/workflows/update-hyperlane-deps.yml
#	.prettierignore
#	next-env.d.ts
#	package.json
#	pnpm-lock.yaml
#	public/android-chrome-192x192.png
#	public/android-chrome-512x512.png
#	public/apple-touch-icon.png
#	public/backgrounds/main.svg
#	public/favicon-16x16.png
#	public/favicon-32x32.png
#	public/favicon.png
#	public/logo.png
#	public/mstile-150x150.png
#	src/components/banner/RecipientWarningBanner.tsx
#	src/components/buttons/ConnectAwareSubmitButton.tsx
#	src/components/errors/ErrorBoundary.tsx
#	src/components/layout/AppLayout.tsx
#	src/components/nav/FloatingButtonStrip.tsx
#	src/components/nav/Footer.tsx
#	src/components/nav/Header.tsx
#	src/components/tip/TipCard.tsx
#	src/consts/app.ts
#	src/consts/config.ts
#	src/consts/links.ts
#	src/consts/warpRouteWhitelist.ts
#	src/features/analytics/types.ts
#	src/features/analytics/useWalletConnectionTracking.tsx
#	src/features/analytics/utils.ts
#	src/features/chains/ChainSelectField.tsx
#	src/features/chains/ChainSelectModal.tsx
#	src/features/chains/metadata.ts
#	src/features/store.ts
#	src/features/tokens/TokenListModal.tsx
#	src/features/tokens/TokenSelectField.tsx
#	src/features/tokens/hooks.ts
#	src/features/tokens/types.ts
#	src/features/tokens/useTokenPrice.tsx
#	src/features/tokens/utils.test.ts
#	src/features/tokens/utils.ts
#	src/features/transfer/TransferTokenCard.tsx
#	src/features/transfer/TransferTokenForm.tsx
#	src/features/transfer/maxAmount.ts
#	src/features/transfer/useFeeQuotes.ts
#	src/features/transfer/useTokenTransfer.ts
#	src/features/transfer/utils.ts
#	src/features/wallet/context/RadixWalletContext.tsx
#	src/features/warpCore/warpCoreConfig.ts
#	src/images/logos/app-logo.svg
#	src/images/logos/app-name.svg
#	src/images/logos/app-title.svg
#	src/pages/_app.tsx
#	src/pages/index.tsx
#	tailwind.config.js
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.