Repository navigation
contracts view: copy encoded params, empty state, active/inactive sections - #645
Conversation
|
Warning Review limit reached
More reviews will be available in 20 minutes and 50 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThe ChangesContract display and grouping refactor
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Deploying tmp-boltz-upstream-mainnet-arkade-wallet with
|
| Latest commit: |
60ee259
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://2d7c9fb6.tmp-boltz-upstream-mainnet-arkade-wallet.pages.dev |
| Branch Preview URL: | https://feat-contracts-copy-params.tmp-boltz-upstream-mainnet-arkade-wallet.pages.dev |
Deploying wallet-bitcoin with
|
| Latest commit: |
60ee259
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://c2847b44.wallet-bitcoin.pages.dev |
| Branch Preview URL: | https://feat-contracts-copy-params.wallet-bitcoin.pages.dev |
Deploying wallet-mutinynet with
|
| Latest commit: |
60ee259
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://3c1d5e7b.arkade-wallet.pages.dev |
| Branch Preview URL: | https://feat-contracts-copy-params.arkade-wallet.pages.dev |
ghost
left a comment
There was a problem hiding this comment.
Code Review — contracts view: copy encoded params, empty state, active/inactive sections
Scope: Single-file UI change (src/screens/Settings/Contracts.tsx). Not protocol-critical — no VTXO, signing, forfeit, or exit path logic touched.
Verdict: Clean, low-risk UI improvement. Two actionable items before merge.
🔴 Must fix
1. encodeArkContract called unguarded in render — can crash the screen
src/screens/Settings/Contracts.tsx:68
<CopyRow label='parameters' value={encodeArkContract(contract)} />If encodeArkContract throws on a contract with unexpected/malformed data (e.g. a contract created by an older SDK version missing a field), the entire Contracts screen white-screens with an unhandled React error. This is the only screen where users can inspect their contracts — losing it is bad UX.
Wrap it:
const encoded = (() => {
try { return encodeArkContract(contract) } catch { return '' }
})()
// ... then conditionally render:
{encoded && <CopyRow label='parameters' value={encoded} />}Or compute it in a useMemo with a try-catch inside ContractCard.
2. Tests are stale — will break on this PR
src/test/screens/settings/contracts.test.tsx
The mock contracts lack createdAt (now rendered via prettyAgo) and label. More critically, encodeArkContract is imported as a real SDK function but will be called on incomplete mock data — this will either throw or produce garbage.
Needs:
- Add
createdAt: 1717000000(and optionallylabel) to mock contracts - Mock or spy
encodeArkContractfrom@arkade-os/sdkto avoid coupling test to SDK internals - Add a test case for the empty state (
contracts.length === 0→ renders "No contracts found.") - Existing assertions for
screen.getByText('default')/screen.getByText('vhtlc')should still pass since the text nodes remain, but verify after adding the missing fields
🟡 Nits (non-blocking)
3. encodeArkContract recomputed on every render
src/screens/Settings/Contracts.tsx:68
encodeArkContract likely involves string encoding work. On a settings screen with a handful of contracts this is fine, but wrapping it in useMemo would be the defensive play — especially if this component ever gets reused in a more render-heavy context.
4. key={c.script} as React key — pre-existing but worth noting
src/screens/Settings/Contracts.tsx:79
If two contracts can share the same script (same contract type, different addresses), React will silently drop one. c.address would be a safer unique key, or a composite ${c.address}:${c.script}.
✅ What's good
import type { Contract }→import { Contract, encodeArkContract }— correct, need the runtime value nowprettyAgo(contract.createdAt)—prettyAgogracefully handles falsy (if (!timestamp) return '') and auto-detects ms vs s timestamps. Solid.contract.label ? ... : null— correctly handles the optionallabelfield- Active/inactive split logic is clean:
=== 'active'/!== 'active'is exhaustive Sectionreturningnullwhen empty prevents rendering empty headers- Replacing inline
cardStylewith<Shadow border>is a good consistency win
LGTM with the error handling fix and test updates. 🫡
—Arkana
ghost
left a comment
There was a problem hiding this comment.
Code Review — contracts view: copy encoded params, empty state, active/inactive sections
Scope: Single-file UI change (src/screens/Settings/Contracts.tsx). Not protocol-critical — no VTXO, signing, forfeit, or exit path logic touched.
Verdict: Clean, low-risk UI improvement. Two actionable items before merge.
🔴 Must fix
1. encodeArkContract called unguarded in render — can crash the screen
src/screens/Settings/Contracts.tsx:68
<CopyRow label='parameters' value={encodeArkContract(contract)} />If encodeArkContract throws on a contract with unexpected/malformed data (e.g. a contract created by an older SDK version missing a field), the entire Contracts screen white-screens with an unhandled React error. This is the only screen where users can inspect their contracts — losing it is bad UX.
Wrap it:
const encoded = (() => {
try { return encodeArkContract(contract) } catch { return '' }
})()
// ... then conditionally render:
{encoded && <CopyRow label='parameters' value={encoded} />}Or compute it in a useMemo with a try-catch inside ContractCard.
2. Tests are stale — will break on this PR
src/test/screens/settings/contracts.test.tsx
The mock contracts lack createdAt (now rendered via prettyAgo) and label. More critically, encodeArkContract is imported as a real SDK function but will be called on incomplete mock data — this will either throw or produce garbage.
Needs:
- Add
createdAt: 1717000000(and optionallylabel) to mock contracts - Mock or spy
encodeArkContractfrom@arkade-os/sdkto avoid coupling test to SDK internals - Add a test case for the empty state (
contracts.length === 0→ renders "No contracts found.") - Existing assertions for
screen.getByText('default')/screen.getByText('vhtlc')should still pass since the text nodes remain, but verify after adding the missing fields
🟡 Nits (non-blocking)
3. encodeArkContract recomputed on every render
src/screens/Settings/Contracts.tsx:68
encodeArkContract likely involves string encoding work. On a settings screen with a handful of contracts this is fine, but wrapping it in useMemo would be the defensive play — especially if this component ever gets reused in a more render-heavy context.
4. key={c.script} as React key — pre-existing but worth noting
src/screens/Settings/Contracts.tsx:79
If two contracts can share the same script (same contract type, different addresses), React will silently drop one. c.address would be a safer unique key, or a composite ${c.address}:${c.script}.
✅ What's good
import type { Contract }→import { Contract, encodeArkContract }— correct, need the runtime value nowprettyAgo(contract.createdAt)—prettyAgogracefully handles falsy (if (!timestamp) return '') and auto-detects ms vs s timestamps. Solid.contract.label ? ... : null— correctly handles the optionallabelfield- Active/inactive split logic is clean:
=== 'active'/!== 'active'is exhaustive Sectionreturningnullwhen empty prevents rendering empty headers- Replacing inline
cardStylewith<Shadow border>is a good consistency win
LGTM with the error handling fix and test updates. 🫡
—Arkana
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/screens/Settings/Contracts.tsx (1)
113-114: 💤 Low valueConsider using a single pass to partition contracts (optional micro-optimization).
The current implementation filters the contracts array twice (once for active, once for inactive). While this is clear and readable, you could partition in a single pass if preferred:
♻️ Single-pass partition approach
- const active = contracts.filter((c) => c.state === 'active') - const inactive = contracts.filter((c) => c.state !== 'active') + const [active, inactive] = contracts.reduce<[Contract[], Contract[]]>( + ([act, inact], c) => (c.state === 'active' ? [[...act, c], inact] : [act, [...inact, c]]), + [[], []] + )However, given that contract lists are typically small, the current approach is clearer and the performance difference is negligible.
🤖 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/Settings/Contracts.tsx` around lines 113 - 114, The current code computes active and inactive by filtering contracts twice (const active = contracts.filter((c) => c.state === 'active') and const inactive = contracts.filter((c) => c.state !== 'active')), so replace that with a single-pass partition over contracts (e.g., a simple for loop or Array.prototype.reduce) that builds active and inactive arrays in one traversal; update any references to active and inactive to use the new variables and keep the same semantics (state === 'active' goes to active, everything else goes to inactive).
🤖 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/Settings/Contracts.tsx`:
- Line 63: The UI currently calls prettyAgo(contract.createdAt) and will render
an empty string when contract.createdAt is missing; update the rendering in the
Contracts component (where contract.createdAt is used) to show a fallback such
as contract.createdAt ? prettyAgo(contract.createdAt) : 'Unknown' (i.e., guard
the call to prettyAgo with a truthy check on Contract.createdAt and render
'Unknown' when absent) so tests and missing dates display a clear value.
---
Nitpick comments:
In `@src/screens/Settings/Contracts.tsx`:
- Around line 113-114: The current code computes active and inactive by
filtering contracts twice (const active = contracts.filter((c) => c.state ===
'active') and const inactive = contracts.filter((c) => c.state !== 'active')),
so replace that with a single-pass partition over contracts (e.g., a simple for
loop or Array.prototype.reduce) that builds active and inactive arrays in one
traversal; update any references to active and inactive to use the new variables
and keep the same semantics (state === 'active' goes to active, everything else
goes to inactive).
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3880bc8e-b0ec-46e2-8671-911e8e31865a
📒 Files selected for processing (1)
src/screens/Settings/Contracts.tsx
|
Is this a dev gated feature? Curious if not if it aligns with new redesign of @sahilc0 |
|
@tiero it's dev-gated. The main issue was to expose the contract params but since I was there I decided to revamp a bit the UI. Not a blocker from my side. |
…ard key Wrap encodeArkContract in try/catch via useMemo and render the parameters row only when encoding succeeds, so a contract with missing/malformed params can no longer white-screen the Contracts screen. Show 'Unknown' instead of an empty string when createdAt is absent. Use contract.address as the React key. Update tests with createdAt/params and add an empty-state case.
ghost
left a comment
There was a problem hiding this comment.
Re-review after 60ee259f — all three issues from my previous review are resolved:
- ✅
encodeArkContractwrapped inuseMemo+try/catch— malformed contracts no longer white-screen - ✅
createdAtfallback to'Unknown'when absent - ✅ React key changed to
c.address(unique per contract) - ✅ Tests updated with
params/createdAtfields + empty-state test added
Clean UI-only change. No protocol-critical paths touched. LGTM.
—Arkana
|
@sahilc0 we need to have this on the new design. |
…tions (#645) * show encoded contract params and allow copying * show encoded contract params and allow copying * improve contracts view: empty state, active/inactive sections, label and createdAt * address review: guard encodeArkContract, createdAt fallback, unique card key Wrap encodeArkContract in try/catch via useMemo and render the parameters row only when encoding succeeds, so a contract with missing/malformed params can no longer white-screen the Contracts screen. Show 'Unknown' instead of an empty string when createdAt is absent. Use contract.address as the React key. Update tests with createdAt/params and add an empty-state case.
* feat(wallet): redesign bitcoin home Port the scoped home redesign foundation and bitcoin-only wallet home from the draft branch. Adds shared motion and haptics helpers, redesigned home header/hero/actions/assets/upsells/activity preview, hides bottom navigation for home-launched wallet flows, and wires scan/swap interactions without pulling in passkeys or prototype asset accounts. * fix(wallet): use real assets on redesigned home * fix(wallet): polish settings and activity follow-ups Remove the bottom nav from the redesigned wallet flow and align the settings screens with the draft redesign, including the Arkade Mint entry under General. Refresh the full Activity page before showing an empty state, keep the home activity preview hidden when empty, and use the shared secondary/drawer styling for the swap coming-soon sheet. * chore(deps): update pnpm lockfile * test(e2e): follow redesigned navigation Update Playwright helpers and specs to navigate through the redesigned home header, settings entry points, and Boltz deep link instead of the removed bottom nav. * test(e2e): align home and settings assertions Use the settings header text rendered by the shared Header component and assert the redesigned zero-balance home through stable test ids. * test(e2e): navigate app screens without reload * tests fixes * Guard BigInt coercion to prevent render-time crashes * fix polling leak * lint * Add a fallback for --pill-navbar-footer-clearance in settings padding * Remove overriding aria-label on settings rows. * fix(settings): address Arkade Mint review feedback * fix tests * fix test * feat(wallet): add bitcoin detail page (#630) * feat(wallet): add bitcoin detail page Add a bitcoin-only wallet detail screen opened from the home asset row, with the Liveline price chart, current price, percentage badge, holdings, wallet actions, and bitcoin-filtered recent activity. Share the existing swap coming-soon drawer between home and the detail page, and cover the bitcoin row navigation with a wallet screen regression test. * fix(wallet): harden bitcoin chart loading Remove the invalid fiat conversion path from the bitcoin detail chart, use CoinGecko max data for non-USD all-time charts, cache chart responses per fiat/range, fetch Coinbase all-time chunks sequentially, and guard the holdings balance before BigInt conversion. * fix(wallet): pause bitcoin chart while hovering * fix tests * fix test * use graph worker * default chart period one week * remove console.log * new marketData file * fixes --------- Co-authored-by: Sahil Chaturvedi <sahilc0@users.noreply.github.com> Co-authored-by: João Bordalo <bordalix@users.noreply.github.com> * feat(wallet): align recent activity with prototype (#628) * chore(dev): support mnemonic wallet auto-init Allow local dev auto-init to use VITE_DEV_MNEMONIC in addition to VITE_DEV_NSEC, so demo wallets can be restored from the current seed phrase without using the broken legacy default key. * feat(wallet): align recent activity with prototype Update the home recent activity list, full activity view, and transaction receipt details to match the prototype visuals while keeping the shared Activity header from PR 627. Add swap/account asset rendering, receipt-style detail rows, and measured virtual rows for taller activity entries. * fix(wallet): address activity review feedback Guard the round waiting screen when no info logs exist, cancel delayed polling on unmount, preserve the safer settlement status flow, remove incomplete BRL fiat support, and share token ticker mapping helpers across activity and asset views. * fix send max with fiat ' + tests --------- Co-authored-by: Sahil Chaturvedi <sahilc0@users.noreply.github.com> Co-authored-by: João Bordalo <bordalix@users.noreply.github.com> * feat(send): align send form with redesign prototype (#629) Port the draft send-flow field shell, asset selector, amount max control, and button safety polish on top of PR 627. Add dev mnemonic auto-init support so local wallets can boot from mnemonic-based seeds without falling back to stale nsec state. Co-authored-by: Sahil Chaturvedi <sahilc0@users.noreply.github.com> Co-authored-by: João Bordalo <bordalix@users.noreply.github.com> * feat(wallet): align recent activity with prototype (#628) * chore(dev): support mnemonic wallet auto-init Allow local dev auto-init to use VITE_DEV_MNEMONIC in addition to VITE_DEV_NSEC, so demo wallets can be restored from the current seed phrase without using the broken legacy default key. * feat(wallet): align recent activity with prototype Update the home recent activity list, full activity view, and transaction receipt details to match the prototype visuals while keeping the shared Activity header from PR 627. Add swap/account asset rendering, receipt-style detail rows, and measured virtual rows for taller activity entries. * fix(wallet): address activity review feedback Guard the round waiting screen when no info logs exist, cancel delayed polling on unmount, preserve the safer settlement status flow, remove incomplete BRL fiat support, and share token ticker mapping helpers across activity and asset views. * fix send max with fiat ' + tests --------- Co-authored-by: Sahil Chaturvedi <sahilc0@users.noreply.github.com> Co-authored-by: João Bordalo <bordalix@users.noreply.github.com> * fix tests * fix navigation * remove border from video container in scan * change toggle bg color when selected to purple * fix(wallet): address home redesign review feedback * fix flacky test * fix flacky test * contracts view: copy encoded params, empty state, active/inactive sections (#645) * show encoded contract params and allow copying * show encoded contract params and allow copying * improve contracts view: empty state, active/inactive sections, label and createdAt * address review: guard encodeArkContract, createdAt fallback, unique card key Wrap encodeArkContract in try/catch via useMemo and render the parameters row only when encoding succeeds, so a contract with missing/malformed params can no longer white-screen the Contracts screen. Show 'Unknown' instead of an empty string when createdAt is absent. Use contract.address as the React key. Update tests with createdAt/params and add an empty-state case. * fix buttons overflow in input * fix other value when bip21 has amount * remove excessive bottom padding on content-shell * less sensible pull-to-refresh * fix typescript build errors (tsc -b) (#646) * fix typescript build errors (tsc -b) * arkana fixes * build fixes * remove console.log * validate asset mint amount is not too large * validate asset mint amount * validate mint values * fixes * refactor mint form * remove console.log * fix e2e tests * feat(settings): move advanced tools into settings (#652) * feat(settings): move advanced tools into settings Remove the root Apps surface and keep developer-focused tools under Settings > Advanced. Add Boltz and Arkade Mint entries there, rename the main settings group to Display, and update navigation tab ownership so these flows return through settings instead of an apps tab. Also refresh bun.lock to match the dependency versions declared on the PR 627 base and update affected settings/e2e tests. * re-order menu options * fix e2e tests * fix test --------- Co-authored-by: Sahil Chaturvedi <sahilc0@users.noreply.github.com> Co-authored-by: João Bordalo <bordalix@users.noreply.github.com> * feat(settings): support bitcoin currency units (#653) * feat(settings): support bitcoin currency units Add BTC as a selectable currency and replace display preferences with bitcoin unit options for BTC, sats, and BIP-177 notation. Format wallet totals, transactions, send/receive flows, portfolio rows, and the Bitcoin detail view with the selected bitcoin unit while keeping the detail market price in fiat. Convert fiat-like asset balances into selected-currency totals and add focused coverage for CHF asset conversion, settings options, formatting, and Bitcoin detail display. * fix e2e test * Several fixes --------- Co-authored-by: Sahil Chaturvedi <sahilc0@users.noreply.github.com> Co-authored-by: João Bordalo <bordalix@users.noreply.github.com> * fallback to btc currency if price feed fails * add useEffect missing dependencies to InputAmount * fix e2e test * arkana fixes * Fix Settings / Display * change Fiats type to Currencies change Settings menu option names * fix(wallet): address arkana wallet review * fix other value when clicking send max * update regtest link * update price chart proxy url * fix build errors * style(settings): polish contracts screen (#664) Redesign the dev-mode contracts screen with a full-width summary, clearer contract cards, copyable code fields, and subtle motion feedback. Update the contracts screen tests to cover the new summary and metadata layout. Co-authored-by: Sahil Chaturvedi <sahilc0@users.noreply.github.com> * feat(settings): add currency icons (#663) Add reusable leading content support to the settings Select component and use it on the currency picker so each option shows a circular bitcoin or country currency mark. Extend TokenLogo with the remaining fiat currency marks used by settings, add selector icon styling, and update the fiat settings tests to distinguish row icons from the selected-state checkmark. Co-authored-by: Sahil Chaturvedi <sahilc0@users.noreply.github.com> * Fixes * Remove onboarding button (#678) * remove 'complete boarding' button * Upgrade ts-sdk 0.4.36 - boltz-swap 0.3.41 (#676) * prevent double keys in local storage (#677) * prevent double keys in local storage * fix circular dependency * add tests * fix SVGs * remove "Complete boarding button" --------- Co-authored-by: pietro909 <2094604+pietro909@users.noreply.github.com> * Clean qrcode (#681) * remove 'complete boarding' button * fix SVGs * remove "Complete boarding button" * clean qr code ui * remove console.log * clean Reminder (#683) * clean Reminder * fix color * fix duplicate init with devMnemonic * fix test * update regtest commit * mini fixes * fix test * fix test * persist value; fix toggle currency (#705) * fix bitcoin balance in btc page * fix server url input * add error messages inline * fix tests * fix import * fix secondary value when not useFiat * fix flash of unlock screen (#710) * bug fix in privacyAmount * remove dead code * click on asset card to view asset * add test for clicking asset card in homepage * fixes in input amount * lnurl fix * add unit tests * bug fix * fix test * remove currencyDisplay from config (#713) * remove currencyDisplay from config * rabbit fixes * fix test * remove option from upsellsSection * only show btc and registered assets on homepage * fix import path * rename config.fiat to config.currency * fix test --------- Co-authored-by: Sahil Chaturvedi <sahilc0@users.noreply.github.com> Co-authored-by: João Bordalo <bordalix@users.noreply.github.com> Co-authored-by: pietro909 <2094604+pietro909@users.noreply.github.com>
Summary
encodeArkContractcall to render the URI-likearkcontract=…string and let users copy itcardStylediv withShadow border(consistent with the rest of the codebase)contract.label(when set) andcreatedAtas relative time on each cardScreenshot
Summary by CodeRabbit