Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
386 commits
Select commit Hold shift + click to select a range
91578b7
fix: instant/secondary username confirm is always free (revert cost r…
bfoss765 Jul 15, 2026
4d83184
fix: invite shielded sheet shows the amount to shield (0.15/0.35), no…
bfoss765 Jul 15, 2026
0b4a6b3
fix: four live-QA bugs — shield-first exit, dual-name render, tile fl…
bfoss765 Jul 15, 2026
395ea27
fix: under-avatar dual name shows the DISPLAY form, not the normalize…
bfoss765 Jul 16, 2026
7e5235e
fix: shielded username submit — calm 'still syncing' surface + live p…
bfoss765 Jul 16, 2026
6766aaf
fix: L1 username creation processing dialog now dismisses on completion
bfoss765 Jul 16, 2026
b9dd1d9
feat: L2 shielded invitations — inviter funds a pool note, receiver c…
bfoss765 Jul 16, 2026
792af85
fix: lengthen the two shielded-wait banners (registration 30s→35s, tr…
bfoss765 Jul 16, 2026
6e73471
feat: persistent 2h privacy-window advisory above the username reques…
bfoss765 Jul 16, 2026
9c56cc6
feat: Phase 5d cutover commit mechanism — engine gate, debug triggers…
bfoss765 Jul 16, 2026
f0bbe6a
fix: clear SDK wallet state on 'Reset this wallet' so the next wallet…
bfoss765 Jul 16, 2026
b3c1126
fix: self-heal Platform availability so a transient DAPI failure can'…
bfoss765 Jul 16, 2026
74d8e42
fix: reset-wallet at-risk path showed two near-identical red confirma…
bfoss765 Jul 16, 2026
584b05a
feat: Phase 5d — home balance follows the SDK L1 scan after cutover
bfoss765 Jul 16, 2026
e15c1a2
feat: Phase 5d — send authority routes through the SDK after a commit…
bfoss765 Jul 16, 2026
111c041
fix: route the main send UI's SendRequest through the SDK bridge post…
bfoss765 Jul 16, 2026
e88d73b
feat: SDK-sourced quorums — Platform proof verification survives the …
bfoss765 Jul 17, 2026
5fac54c
fix: synthesize serializable FinalCommitments in the SDK quorum bridge
bfoss765 Jul 17, 2026
475680d
fix: six DashPay/invite QA fixes from on-device testing
bfoss765 Jul 17, 2026
ee67c65
fix: route contested username completion to the More voting tile
bfoss765 Jul 17, 2026
7c2a423
fix: invite fee/confirm/decision-sheet corrections from on-device tes…
bfoss765 Jul 17, 2026
42f23d8
fix: shielded invite payment validation uses withdrawn 0.1/0.3, not p…
bfoss765 Jul 17, 2026
285341e
fix: shielded invite hung on "Loading Invite…" — share the invite Vie…
bfoss765 Jul 17, 2026
21936ee
fix: shielded invite OneLink + honest shield-stall surfacing + 90s wa…
bfoss765 Jul 17, 2026
0c3f61a
fix: restore the 40s shield-stall notice + kick pool re-eval on usern…
bfoss765 Jul 17, 2026
a78d1fa
fix: bring the shielded runtime up at app startup, not first UI visit
bfoss765 Jul 17, 2026
b3c970b
fix: failed username validations sort to the top of the criteria list
bfoss765 Jul 17, 2026
0edc980
fix: dual username completion routes to More + arms the instant welco…
bfoss765 Jul 17, 2026
817c2fa
feat: post-cutover home UI served from the SDK (no dashj mirror) + da…
bfoss765 Jul 18, 2026
ced9f48
refactor: Step A of dashj elimination — neutral cross-module facade, …
bfoss765 Jul 18, 2026
5051a68
feat: kill-list Step B (sync-state) — post-cutover BlockchainState de…
bfoss765 Jul 18, 2026
31ea436
feat: Step D prep — self-contained BIP39 and WIF utilities in common
bfoss765 Jul 18, 2026
d897ca1
feat: instant receives post-cutover — engine tx events drive the tx l…
bfoss765 Jul 18, 2026
62d3485
feat: Step B send-all — post-cutover empty-wallet sends drain via the…
bfoss765 Jul 18, 2026
a316625
fix(wif): check version byte before payload length, matching dashj or…
bfoss765 Jul 18, 2026
b780967
fix: Step B sync-state adversarial-review fixes (date freshness, roll…
bfoss765 Jul 19, 2026
56abba5
merge: B2 — SDK-fed BlockchainState post-cutover (reviewed, 2 rounds)
bfoss765 Jul 19, 2026
844abfe
merge: D-prep — self-contained BIP39/WIF utils + Step D inventory (re…
bfoss765 Jul 19, 2026
f18ce50
fix: harden B4 instant-receive — self-spend notify guard, InBlock cle…
bfoss765 Jul 19, 2026
da9d6f2
merge: B4 — instant receive via engine tx events (reviewed, 2 rounds)
bfoss765 Jul 19, 2026
9282e8b
feat: Step B7 — post-cutover wallet-data seam served from the SDK
bfoss765 Jul 19, 2026
620b00e
feat: Step B1 — SDK-only tx detail sheet via the transaction_decode b…
bfoss765 Jul 19, 2026
11d1096
fix: send-all fix round — locked-output drain guard, atomic CrowdNode…
bfoss765 Jul 19, 2026
a37d5ec
merge: B3 — SDK send-all with fail-closed locked-output guard (review…
bfoss765 Jul 19, 2026
ea69737
fix: harden B1 tx-detail path against native-lib LinkageError + corre…
bfoss765 Jul 19, 2026
4757017
fix: B7 seam adversarial-review fixes — seam output locks, pending/lo…
bfoss765 Jul 19, 2026
d3723e7
merge: B7 — seam-level SDK routing for wallet-data reads (reviewed, 2…
bfoss765 Jul 19, 2026
1977dfb
fix: send-all drain guard unions the seam output-lock registry
bfoss765 Jul 19, 2026
14ffa37
merge: B1 — transaction_decode JNI + SDK-only tx detail sheet (review…
bfoss765 Jul 19, 2026
2adf70f
feat(dash-dex): finish buy swap flow (#1504)
HashEngineering Jul 20, 2026
6690173
fix: tax category stuck on "Loading" in tx detail sheet
bfoss765 Jul 20, 2026
b6eab62
fix(shielded): SDK-only wallet funding gate that opens on caught-up, …
bfoss765 Jul 20, 2026
ea37835
fix: persist tax category and memo for SDK-only transactions
bfoss765 Jul 20, 2026
99ca44d
feat(cutover): automatic SDK-primary cutover (per-wallet, fail-safe)
bfoss765 Jul 20, 2026
1bbb003
Merge origin/feat/dash-dex (Dash DEX / SwapKit) into Kotlin-SDK migra…
bfoss765 Jul 20, 2026
a6527be
fix(cutover): review fixes — non-blocking fresh commit, live-gate doc…
bfoss765 Jul 20, 2026
88a9d15
Merge branch 'claude/autocommit' into claude/build-11.10.1
bfoss765 Jul 20, 2026
090ab14
Merge branch 'claude/fix-txmeta' into claude/build-11.10.1
bfoss765 Jul 20, 2026
21df06c
feat(about+settings): dynamic L1-engine ownership on About; remove mi…
bfoss765 Jul 20, 2026
b1720f8
feat(cutover): commit SDK-primary within ~20-30s once parity holds
bfoss765 Jul 20, 2026
5550cc0
merge: cutover flip in ~20-30s (faster parity sampling, 3-match anti-…
bfoss765 Jul 20, 2026
31a370d
merge: reactive About L1-engine indicator + remove 3 migration debug …
bfoss765 Jul 20, 2026
89caf16
fix(l1-shadow): self-heal a persistent parity mismatch with a one-tim…
bfoss765 Jul 20, 2026
4225753
build: adopt SDK 0.1.0-b2-SNAPSHOT (vendored #649 out-of-order spend …
bfoss765 Jul 20, 2026
6caa6aa
feat(dash-dex): swap tracking, maya screen redesign, and review fixes…
HashEngineering Jul 21, 2026
3640ceb
chore: ktlint
HashEngineering Jul 21, 2026
287777e
Merge pull request #1516 from dashpay/feat/dash-dex
HashEngineering Jul 21, 2026
7e75c47
fix: crash and ANR fixes and review fixes (#1509)
HashEngineering Jul 21, 2026
a6b7b2f
fix: v11.9.0 and related fixes (#1514)
HashEngineering Jul 21, 2026
526fe78
chore: update GitHub actions and fastlane (#1494)
HashEngineering Jul 21, 2026
b6d29b2
feat: support dark mode (#1480)
HashEngineering Jul 27, 2026
d4c0495
fix: many Dash DEX sell-swap fixes (#1519)
HashEngineering Jul 29, 2026
b6f6f21
feat(cutover): contacts-on-SDK, note-confirm fixes, mixed-funds promp…
bfoss765 Jul 30, 2026
f73bf13
Merge remote-tracking branch 'origin/master' into feat/merge-kotlin-s…
HashEngineering Jul 30, 2026
22f9ff5
fix(ci): repair ktlint violations and the uphold unit-test org.json c…
HashEngineering Jul 31, 2026
88a7d75
feat(cutover): post-cutover completeness — spendable contact funds, i…
bfoss765 Jul 31, 2026
93c68c3
Merge remote-tracking branch 'origin/feat/kotlin-sdk-phase1' into fea…
HashEngineering Jul 31, 2026
dabaaac
feat(cutover): make the first-launch SDK sync window honest to the user
bfoss765 Aug 2, 2026
9fec7ec
fix(cutover): chainlock feed, honest idle detection, meaningful parit…
bfoss765 Aug 2, 2026
620f180
fix(cutover): stop wallet.reset() destroying history, overlay the UTX…
bfoss765 Aug 2, 2026
ff3e623
refactor(cutover): make the L1 engine choice invisible above the seam
bfoss765 Aug 2, 2026
6170a4e
feat(cutover): version-gate the one-time upgrade sync explainer to pr…
bfoss765 Aug 3, 2026
eccd9e7
fix(cutover): route self-sends via the SDK bridge, stop misdiagnosing…
bfoss765 Aug 3, 2026
4978b29
fix(contacts): CBOR crash on own-identity refresh aborted contact syn…
bfoss765 Aug 3, 2026
ef2c94f
feat(display): group historical CoinJoin mixing txs on the home scree…
bfoss765 Aug 3, 2026
bf58042
Merge remote-tracking branch 'origin/feat/kotlin-sdk-phase1' into fea…
HashEngineering Aug 3, 2026
992dca4
Merge pull request #1525 from dashpay/feat/merge-kotlin-sdk-master
bfoss765 Aug 3, 2026
290c742
build: resolve the Kotlin SDK from GitHub Packages in CI
bfoss765 Aug 3, 2026
970be36
fix(anr): stop touching the dashj wallet on the main thread at 1 Hz d…
bfoss765 Aug 3, 2026
37c973d
fix(invites): stop telling contested-invite claimers they may only pi…
bfoss765 Aug 3, 2026
17c4504
fix(funding): honest spendability — IS/CL context as lock evidence, a…
bfoss765 Aug 3, 2026
fe04cc1
feat(tools): SDK-backed Network Monitor
bfoss765 Aug 3, 2026
fbd3091
Merge mixing-tx group display (#1533) into the consolidated line
bfoss765 Aug 3, 2026
55b44c7
fix(tests): stop the settling-gate poll from hanging the whole unit-t…
bfoss765 Aug 3, 2026
57f4eaf
feat(invites): the identity gets the invite's full value, not the use…
bfoss765 Aug 3, 2026
aa9bee0
feat(cutover): route BIP70/BIP270 direct pay through the SDK deferred…
HashEngineering Jul 31, 2026
f51eaa3
feat(cutover): source the BIP70 refund address from the SDK address pool
HashEngineering Jul 31, 2026
6333c7d
feat(cutover): BIP70 fee preview via SDK build-at-preview; no dashj i…
HashEngineering Jul 31, 2026
a7491c2
docs(testing): add the local BIP70 test server used to verify the SDK…
HashEngineering Aug 1, 2026
282d7e5
fix(cutover): post-rebase alignment with the typed fail-closed except…
HashEngineering Aug 3, 2026
e8c6d75
build: pin the Kotlin SDK to 0.1.0-v41int13-SNAPSHOT
bfoss765 Aug 3, 2026
a4a2bde
fix(invites): detect an already-claimed shielded invite by its typed …
bfoss765 Aug 3, 2026
0f01e38
fix(cutover): bound the post-cutover display pipeline — O(delta) per …
bfoss765 Aug 3, 2026
6d1b6ae
fix(startup): survive large-wallet startup — no consistency mega-dump…
bfoss765 Aug 3, 2026
24b70aa
fix(cutover): close the BIP70 double-submission race (review finding)
HashEngineering Aug 3, 2026
e4f34bd
refactor(bip70)!: delete the dashj BIP70 implementation - SDK route u…
HashEngineering Aug 3, 2026
437cf5f
feat(bip70): rebuild the timeout rescue on the SDK's InstantSend-lock…
HashEngineering Aug 3, 2026
c374245
Merge BIP70/BIP270 on the SDK deferred surface (#1531)
bfoss765 Aug 3, 2026
92a7415
fix(invites): claim only ever requests an ALLOWED exit denomination
bfoss765 Aug 3, 2026
f0c40e9
fix(bip70): key the timeout rescue on network OBSERVATION, not IS-loc…
HashEngineering Aug 3, 2026
1378b04
feat(invites): the claim's overage ends up on the identity, not the c…
bfoss765 Aug 3, 2026
c01a46d
feat(sdk): v41int14 AAR + typed core-send error classification
bfoss765 Aug 4, 2026
1eaa1f0
Merge branch 'pr1534' into feat/kotlin-sdk-phase1
bfoss765 Aug 4, 2026
374e6b9
fix(invites): align the UI/affordability layer with the v13 mint deno…
bfoss765 Aug 4, 2026
41fac4f
fix(invites): SDK DPNS routing for EVERY username branch + crash-free…
bfoss765 Aug 4, 2026
eb997d1
fix(startup): launch-path hardening — the app is its own crash-diagno…
bfoss765 Aug 4, 2026
a2d0672
fix(invites): the primary stage registers the PRIMARY — kill the wrap…
bfoss765 Aug 4, 2026
c194348
fix(startup): pre-parse wallet size guard + Error-free key-backup rec…
bfoss765 Aug 4, 2026
459052e
fix(invites): completed-claim overage RECONCILE — retro-fit the S22's…
bfoss765 Aug 4, 2026
db33167
fix(startup): a degraded launch that OPENED counts as survived
bfoss765 Aug 4, 2026
932d18e
fix(invites): pin overage-record-before-link-clear ordering; WARN whe…
bfoss765 Aug 4, 2026
31b8b52
fix(username): land on Home when a usable instant username exists
bfoss765 Aug 4, 2026
87b3e48
fix(invites): settle-aware overage give-up + v2 outcome markers — un-…
bfoss765 Aug 4, 2026
9868147
fix(startup): defer DashPay friend-chain lookahead off the wallet loa…
bfoss765 Aug 4, 2026
8a3d551
fix(startup): a completed launch killed later is NOT a launch failure…
bfoss765 Aug 4, 2026
3f4cfd7
fix(perf): stop the mainnet session-death spiral — ANR flood, wallet-…
bfoss765 Aug 4, 2026
f9b0a1d
chore: bump SDK to v41int15 (watermark persistence fix)
bfoss765 Aug 4, 2026
8385b02
chore: bump SDK to v41int16 (lossless watermark persistence channel)
bfoss765 Aug 5, 2026
d1e34df
fix: unshield tx stuck on "Received" — don't negative-cache a not-yet…
bfoss765 Aug 5, 2026
a87e56a
feat: remove redundant username-creation progress dialog
bfoss765 Aug 5, 2026
4e71b37
feat: copy the SDK's native log:: output into wallet.log so reports c…
bfoss765 Aug 5, 2026
d106c89
fix(perf): derive the DashPay friend-chain lookahead ONCE, not every …
bfoss765 Aug 5, 2026
a97bc6b
feat(diagnostics): record WHY the previous process died, in the suppo…
bfoss765 Aug 5, 2026
99cf78c
fix(dashpay): stop the coreHeight backfill rewinding the SPV scan eve…
bfoss765 Aug 5, 2026
dab3315
feat(shielded-invites): fund the invite as two notes via shieldedTran…
bfoss765 Aug 5, 2026
d9c8f39
fix(dashpay): latch the backfill watch via a persisted ARMED marker, …
bfoss765 Aug 5, 2026
92ac90d
feat(diagnostics): route the SDK's Rust tracing output to a reportabl…
bfoss765 Aug 5, 2026
61a0f93
feat(diagnostics): per-minute MEM line in wallet.log while the blockc…
bfoss765 Aug 5, 2026
92b1a3e
fix(diagnostics): force a native-log drain after the DashPay provisio…
bfoss765 Aug 5, 2026
e81b347
fix(invites): account for the shielded transfer fee in invite afforda…
bfoss765 Aug 5, 2026
adae720
docs(shielded): correct retired-denomination comments; de-hardcode dr…
bfoss765 Aug 5, 2026
34b5582
chore: bump SDK to v41int18 (segment eviction + dead-merge removal + …
bfoss765 Aug 5, 2026
774375b
chore(usernames): round shield-at-least guidance to 0.035 / 0.26
bfoss765 Aug 5, 2026
93ed8d1
fix(diagnostics): sweep the SPV crate's tracing log into support reports
bfoss765 Aug 6, 2026
c666e2a
fix(dashpay): wrong-contact payments, empty contact history, replayed…
bfoss765 Aug 7, 2026
8476ae7
fix(dashpay): poll for the armed backfill rewind so the gate can latc…
bfoss765 Aug 7, 2026
6380f82
fix(dashpay): conclude the no-rewind case so a wallet needing no back…
bfoss765 Aug 7, 2026
f687165
fix(migration): suppress the mixed-funds prompt until its main-thread…
bfoss765 Aug 7, 2026
f1d1072
fix(cutover): refuse the dashj cache rebuild that would erase all his…
bfoss765 Aug 8, 2026
f0c2da6
fix(cutover): re-base the display-cache completeness check on the SDK
bfoss765 Aug 8, 2026
c3cb222
fix(dashpay): drain the deferred contact account builds on every launch
bfoss765 Aug 8, 2026
12ddf3c
fix(cutover): log every published balance, and stop persisting a shor…
bfoss765 Aug 8, 2026
fbf38e1
fix(migration): take the mixed-funds destination address off the main…
bfoss765 Aug 8, 2026
587a862
fix(dashpay): report the contact-build drain on every pass, empty or not
bfoss765 Aug 8, 2026
f71888f
fix(cutover): wait for the SDK record count the completeness check needs
bfoss765 Aug 8, 2026
37953e6
fix(preflight): stop reading a pre-block receive as a funding shortfall
bfoss765 Aug 8, 2026
6601565
fix(dashpay): stop offering "Join DashPay" while the wallet is still …
bfoss765 Aug 8, 2026
e4898da
fix(dashpay): greet the user by the name they registered, not the DPN…
bfoss765 Aug 8, 2026
ba1d393
fix(restore): honor the wallet birth date the user picks when restoring
bfoss765 Aug 8, 2026
7bfa26d
fix(dashpay): never assume "nothing to backfill" while a rewind is owed
bfoss765 Aug 8, 2026
7290a03
fix(dashpay): re-derive the notification badge from the contact data …
bfoss765 Aug 8, 2026
5ac5ffd
fix(reset): destroy the wallet only after the UI has let go of it
bfoss765 Aug 8, 2026
9cbe9a2
fix(home): re-take the empty-view decision when the identity record c…
bfoss765 Aug 8, 2026
658fb70
fix(cutover): persist engine IS-lock events where readers can see them
bfoss765 Aug 9, 2026
77a07cd
build(sdk): bump to v41int19 and move the drain shim to the atomic po…
bfoss765 Aug 9, 2026
df43cfa
feat(send): pool funding across accounts — one transaction for any send
bfoss765 Aug 9, 2026
e8747cf
fix(ui): never run dashj's wallet-saving freshReceiveAddress on the m…
bfoss765 Aug 9, 2026
44f7e8f
fix(cutover): classify wallet-internal transactions as INTERNAL, orde…
bfoss765 Aug 9, 2026
15090f9
chore(strings): name the network in the sync-failure banner
bfoss765 Aug 9, 2026
14e230f
fix(cutover): let the balance-persist gate settle on a STUCK contact-…
bfoss765 Aug 9, 2026
08c5cf7
fix(sync): hold the network-failure banner on a masternode-list-starv…
bfoss765 Aug 9, 2026
7d8f0c6
fix(invite): terminate the confirm/authorize cycle in a classified error
bfoss765 Aug 9, 2026
146a7cd
fix(cutover): one truth for the SDK balance figure — native ledger, n…
bfoss765 Aug 9, 2026
4e855d9
fix(cutover): reattribute provably-wrong stored SDK records; foreign …
bfoss765 Aug 9, 2026
af2390a
chore(sdk): bump the Kotlin SDK to 0.1.0-v41int20-SNAPSHOT
bfoss765 Aug 9, 2026
3e621e2
fix: contact's watch-only spends no longer poison receive rows
bfoss765 Aug 10, 2026
8a1e641
fix(security): stop logging SecurityGuard preference values
bfoss765 Aug 10, 2026
f85dbee
fix(dashpay): make the contact-sync single-flight guard recoverable
bfoss765 Aug 10, 2026
13373e0
fix(dashpay): never fail or stall the post-send contact-request recon…
bfoss765 Aug 10, 2026
41b76a0
chore(sdk): bump the Kotlin SDK to 0.1.0-v41int21-SNAPSHOT
bfoss765 Aug 10, 2026
c3c7e7a
fix(shielded): a foreign unshield is a receive, not a self-move
bfoss765 Aug 10, 2026
c17014f
chore(sdk): bump the Kotlin SDK to 0.1.0-v41int22-SNAPSHOT
bfoss765 Aug 10, 2026
68a5535
fix(sdk): one-shot address-window widen heal for migrated wallets
bfoss765 Aug 10, 2026
d205ac1
fix(sdk): heal v2 — arm the SPV filter rescan directly, not via the gate
bfoss765 Aug 11, 2026
35b0ed5
fix(migration): hard-suppress the mixed-funds prompt during field tes…
bfoss765 Aug 11, 2026
5f0ee87
fix(send): relay-safe fee rate for drain builds
bfoss765 Aug 11, 2026
22a66d8
chore(sdk): move to the ground-up AAR 0.1.0-v42int2-SNAPSHOT + adapt …
bfoss765 Aug 12, 2026
f0eae28
chore(sdk): bump ground-up AAR to 0.1.0-v42int3-SNAPSHOT (invitations…
bfoss765 Aug 12, 2026
0af873b
style(crowdnode): restore ktlint lexicographic import order
bfoss765 Aug 12, 2026
32497f2
chore(sdk): bump to AAR 0.1.0-v42int4-SNAPSHOT (all 9 PR review fixes…
bfoss765 Aug 12, 2026
1ba0d72
fix(invites): survive view teardown on the invite-creation completion…
bfoss765 Aug 12, 2026
8db4300
fix(tx-list): never crash on unresolvable adapter positions
bfoss765 Aug 12, 2026
93ec269
fix(sync): gate 'synced' + balance persist on the block pipeline drai…
bfoss765 Aug 12, 2026
9155371
fix(reset): make 'Reset blockchain' replay SDK history post-cutover
bfoss765 Aug 12, 2026
c6f4c36
fix(restore): bounded app-side retry for failed identity discovery
bfoss765 Aug 12, 2026
a6fb39f
fix(tx-store): persist reattribution corrections — stop the every-lau…
bfoss765 Aug 12, 2026
0b82d95
feat(telemetry): ReplayMemTelemetry — memory-vs-progress lines during…
bfoss765 Aug 12, 2026
d9a396c
chore(sdk): pin the release-form AAR coordinate 0.1.0-v42int4
bfoss765 Aug 12, 2026
5882107
fix(ci): green both workflows — uphold ktlint order/wrap; stop minify…
bfoss765 Aug 12, 2026
0702094
feat(logging): WalletHistoryFacts — one-shot first-use line at wallet…
bfoss765 Aug 12, 2026
b0d30c0
feat(telemetry): WalletBalanceFacts — settle-edge balance snapshot
bfoss765 Aug 12, 2026
080a930
fix(dashpay): arm the periodic contact-request poll post-cutover — th…
bfoss765 Aug 12, 2026
1b374b8
fix(dashpay): re-resolve tx-row contact attribution when the contact …
bfoss765 Aug 12, 2026
ceb206e
fix(tx-list): pending_inputs reservations end the lingering receive —…
bfoss765 Aug 12, 2026
f97baaa
fix(restore): stop the 22-hour contested-name walk that stalls restor…
bfoss765 Aug 13, 2026
b16806f
fix(dashpay): a rescan must not permanently disable identity recovery
bfoss765 Aug 13, 2026
89a795c
fix(dashpay): re-arm the post-cutover identity recovery hook
bfoss765 Aug 13, 2026
d0d04a1
fix(dashpay): drive the SDK identity-discovery retry above the identi…
bfoss765 Aug 13, 2026
15582c0
fix(create): narrow the contested-name walk on the identity-creation …
bfoss765 Aug 13, 2026
aec189f
fix(platform): bound the Kotlin-SDK Platform query attempt so bad nod…
bfoss765 Aug 13, 2026
0ab4274
feat(diag): log ContactDerivationFacts — our DIP-15 addresses per con…
bfoss765 Aug 13, 2026
d14b38b
fix(dashpay): rewind for contact accounts registered after the sweep
bfoss765 Aug 13, 2026
abd6ccb
feat(diag): log the SENDING chain in ContactDerivationFacts
bfoss765 Aug 13, 2026
4ccba57
fix(dashpay): give the identity-discovery latch a deadline so a wedge…
bfoss765 Aug 13, 2026
8e77d43
perf(restore): skip contested-name list fetches that cannot match
bfoss765 Aug 13, 2026
bb16fe5
perf(dashpay): stop contact sync waiting behind the discovery retry scan
bfoss765 Aug 13, 2026
8af710f
fix(dashpay): bound the legacy contact fetches and hide mid-replay ba…
bfoss765 Aug 13, 2026
ef6901f
feat(sync): keep the indicator working until DashPay has settled too
bfoss765 Aug 13, 2026
3200c62
fix(dashpay): show pending OUTGOING contact requests in the contacts …
bfoss765 Aug 13, 2026
b0b922b
fix(sync): stop the armed backfill marker pinning the sync indicator on
bfoss765 Aug 13, 2026
247dccd
fix(sync): latch the initial DashPay sync so refreshes stop flickering
bfoss765 Aug 13, 2026
a2a6641
fix(tools): export the CSV from the cutover seam, not the held dashj …
bfoss765 Aug 14, 2026
f4f6c2d
feat(credits): show the identity's credit balance on Buy Credits; doc…
bfoss765 Aug 14, 2026
ba2c373
fix(credits): don't re-enter updateView from onViewCreated (Buy Credi…
bfoss765 Aug 15, 2026
38d4da5
feat(logging): make transaction-metadata fetch, apply and publish-ski…
bfoss765 Aug 15, 2026
9d01c76
fix(metadata): source the historical-metadata upload from the cutover…
bfoss765 Aug 15, 2026
c819b78
fix(metadata): combine both unsaved populations so "Past" can't race …
bfoss765 Aug 15, 2026
a5f3062
fix(credits): stop the identity-balance label vanishing; retry the read
bfoss765 Aug 16, 2026
82a0d84
fix(metadata): stop discarding fetched platform metadata for SDK-owne…
bfoss765 Aug 16, 2026
e131290
fix(metadata): re-merge platform metadata already on the device, once
bfoss765 Aug 17, 2026
25a5e4a
feat(maya)!: swap deposits on the SDK deferred surface — dashj constr…
HashEngineering Aug 17, 2026
f007915
feat(credits)!: SDK-only Buy Credits — background recovery + spend-ev…
HashEngineering Aug 17, 2026
34e520e
feat(crowdnode): message signing via the platform SDK; fence the disa…
HashEngineering Aug 17, 2026
ae0d693
fix(sync): don't crash shutdown when the platform sync job already co…
bfoss765 Aug 17, 2026
464b733
fix(tx): heal undersized OUTGOING nets; export asset-lock burns as ex…
bfoss765 Aug 17, 2026
3ed0d3e
fix(username,tools): contested-name L1 fallback (Mo-973); CSV filenam…
bfoss765 Aug 17, 2026
9804152
fix(tx): heal the AssetLock INTERNAL/net-0 store row; audit-gate the …
bfoss765 Aug 17, 2026
e1c839a
fix(sync): cap the account-build re-provision signal — the S22 rewind…
bfoss765 Aug 17, 2026
6395152
chore: bump Kotlin SDK to 0.1.0-v42int4b (signer-ordering defer + #43…
bfoss765 Aug 18, 2026
8615017
fix(username): reset() wiped the shielded-gate mirrors — button pinne…
bfoss765 Aug 18, 2026
d4887ef
fix(shielded): routine background sync passes no longer demote READY
bfoss765 Aug 18, 2026
176a39a
fix(dashpay): Mo-972 — dual-create's pending contested primary surviv…
bfoss765 Aug 18, 2026
635012a
fix(dashpay): Mo-972 root — fromCreation restore reset destroyed the …
bfoss765 Aug 18, 2026
fd198c1
fix(shielded): stalled-transfer copy says a few minutes, matching the…
bfoss765 Aug 18, 2026
74099c3
fix(username): plain flow shows general validity rules, not invite qu…
bfoss765 Aug 18, 2026
b2cd390
chore: bump SDK to 0.1.0-v42int4c (bounded re-poll in asset-lock lock…
bfoss765 Aug 18, 2026
ad7f782
fix(shielded): hold the stale-balance surface until the balance is st…
bfoss765 Aug 19, 2026
022be70
ci: disable gradle configuration cache in the CI build
bfoss765 Aug 19, 2026
948bc87
fix: never fresh-build over a worker rerun's own consumed top-up lock
bfoss765 Aug 19, 2026
da9ba9c
fix: send SwapKit/NEAR max sells as fixed-amount change-leaving deposits
bfoss765 Aug 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
156 changes: 147 additions & 9 deletions .claude/agents/DEVELOPMENT-PATTERNS.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,88 @@ component to our component:
- ListEmptyState - ListEmptyState
- tablelist-masternodekeys - TableListMasternodeKeyRow
- EnterAmount (input bar) - EnterAmount
- TextField-Base / text.field - TextField
- addressField - AddressField

## Dark Mode Compatibility

Every new screen, dialog, and component must work in both light and dark mode. The app uses `Theme.AppCompat.DayNight` which activates `values-night/` resource qualifiers automatically.

### Compose: The Golden Rule

**One call to `LocalDashColors.current` per composable, at the top. Never use `MyTheme.Colors.*` directly.**

```kotlin
@Composable
fun MyComponent(...) {
val colors = LocalDashColors.current // ← always this, nothing else
Column(modifier = Modifier.background(colors.backgroundPrimary)) {
Text("Hello", color = colors.textPrimary)
}
}
```

**Root entry point wrapping** — The topmost composable in a Fragment's `setContent { }` block must be wrapped in `DashWalletTheme`:

```kotlin
composeView.setContent {
DashWalletTheme { // ← selects light or dark colors once
MyScreen(...)
}
}
```

**Rules:**
- `DashWalletTheme` wraps the root once. Child composables never call `isSystemInDarkTheme()`.
- `MyTheme.Colors` (light) and `MyTheme.DarkColors` (dark) are the source-of-truth instances; `LocalDashColors.current` resolves to the correct one automatically.
- Always wrap previews in `DashWalletTheme`. For dark previews add `uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES`:

```kotlin
@Preview(name = "Dark", uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES)
@Composable
fun MyPreviewDark() {
DashWalletTheme { MyComponent(...) }
}
```

### ColorScheme Fields Reference

Key fields from `MyTheme.ColorScheme` (use via `LocalDashColors.current`):

| Field | Light | Dark | Use for |
|-------|-------|------|---------|
| `backgroundPrimary` | `#F5F6F7` | `#10151F` | Page background |
| `backgroundSecondary` | `#FFFFFF` | `#1D2532` | Cards, sheets, panels |
| `textPrimary` | `#191C1F` | `#FFFFFF` | Primary text |
| `textSecondary` | `#6E757C` | `#92929C` | Secondary / helper text |
| `textTertiary` | `#75808A` | `#75808A` | Tertiary / label text |
| `dashBlue` | `#008DE4` | `#008DE4` | Brand accent, links |
| `dividerColor` | `#EDF0F2` | `#2C3748` | Dividers, borders |
| `disabledButtonBg` | `#EEEEEE` | `#3C3C3C` | Disabled button background |
| `contentDisabled` | `#92929C` | `#92929C` | Disabled text / icon |

### XML Layouts: Semantic Color Tokens

Use semantic tokens from `values/colors.xml` — they have night overrides in `values-night/colors.xml`. Never use `@android:color/white` or literal hex values for surfaces or text.

| Purpose | Token |
|---------|-------|
| Page background | `@color/background_primary` |
| Card / sheet surface | `@color/background_secondary` |
| Primary text | `@color/content_primary` |
| Dividers / borders | `@color/divider_color` |

### XML Drawables: Adaptive Colors

- **Shape drawables** (cards, panels): fill with `@color/background_secondary`, not `@android:color/white`
- **Vector icons**: set `android:tint="@color/content_primary"` on the `<vector>` element instead of a hardcoded fill
- **Color state lists** (`<selector>`): the default (last) item must use `@color/content_primary`, not a hardcoded hex

### DashButton Disabled State

`DashButton` handles the disabled state automatically via `colors.disabledButtonBg` and `colors.contentDisabled`. Do not set `alpha` or override colors manually for disabled buttons — just pass `isEnabled = false`.

---

## NavBar / TopNavBase (Figma: NavBar)

Expand Down Expand Up @@ -373,7 +455,7 @@ ListItem(
Icon(
painter = painterResource(R.drawable.ic_dash_blue_filled),
contentDescription = null,
tint = MyTheme.Colors.dashBlue,
tint = LocalDashColors.current.dashBlue,
modifier = Modifier.size(32.dp)
)
}
Expand Down Expand Up @@ -414,7 +496,7 @@ ListItem(
Icon(
painter = painterResource(R.drawable.ic_menu_row_arrow),
contentDescription = null,
tint = MyTheme.Colors.textTertiary,
tint = LocalDashColors.current.textTertiary,
modifier = Modifier.size(16.dp)
)
}
Expand Down Expand Up @@ -452,7 +534,7 @@ ListEmptyState(
Icon(
painter = painterResource(R.drawable.ic_dash_blue_filled),
contentDescription = null,
tint = MyTheme.Colors.dashBlue,
tint = LocalDashColors.current.dashBlue,
modifier = Modifier.size(48.dp)
)
},
Expand Down Expand Up @@ -605,7 +687,7 @@ FeatureItemNumber(number = "1")

**Visual Specs**:
- Size: 20dp circle
- Background: MyTheme.Colors.dashBlue
- Background: `colors.dashBlue` (via `LocalDashColors.current`)
- Border radius: 8dp
- Text: 12sp, white, centered

Expand Down Expand Up @@ -813,7 +895,7 @@ A horizontal **amount-input bar** from the design system. Renders, left to right
**Figma file:** Design system - Android — node `4414:23352`

The component lives in:
```
```text
common/src/main/java/org/dash/wallet/common/ui/components/EnterAmount.kt
```

Expand Down Expand Up @@ -913,6 +995,58 @@ EnterAmount(
- Typography substitutions vs. the Figma spec: `LabelSmallSemibold` (11 sp) is used in place of the spec's 10 sp SemiBold for the Max label — closest available preset, ~1 sp visual diff.
- The chevron icon `ic_chevron_down_small.xml` is a small (10 × 6 dp) stroke vector created specifically for this component.

## TextField (Figma: TextField-Base / text.field)

The general-purpose design-system text field lives in:
```
common/src/main/java/org/dash/wallet/common/ui/components/TextField.kt
```

**Figma Design System nodes:** base `4111:12913`, variant set `4112:13707`

A rounded (16 dp) input with a **floating label**: when the field is empty, the label renders
full-size (`Typography.TitleSmall`, textSecondary) on the text line as the placeholder; once
there's content it shrinks to a small line above the text (`Typography.LabelMedium`).

### States (driven by focus / content / parameters — no state enum)

| Figma variant | Trigger | Visual |
|---|---|---|
| Default | unfocused, empty | `gray400` @ 10% background, label as placeholder |
| Focused | focused | white background, 1 dp `dashBlue` border, 3 dp `dashBlue` @ 10% focus ring |
| Typing | focused + text | focused look + automatic clear (✕) trailing button (`ic_clear_input`) |
| Filled | unfocused + text | resting gray background, small label above text |
| Error | `isError = true` | `red5` background + 1 dp `red` border; `message` below renders red (wins over focused) |
| Disabled | `enabled = false` | content at 40% alpha, input ignored |

### Slots

- `label` — floating label inside the field (Figma `label`): full-size on the text line when empty, shrinks above the text once filled
- `innerLabel` — permanent small label above the text line, always visible even when empty (same as `AddressField.innerLabel`; don't combine with `label`). **Address-input screens use this for "BTC Address"-style text — never a disappearing hint.**
- `placeholder` — text-line placeholder (hint) when empty; only used when `label` is null
- `helperTextInside` — right-aligned `Typography.BodySmall` inside the field, below the text line (Figma `helpTextInside`); when null and `maxLength` is set, an automatic `n/max` counter renders here
- `message` + `isError` — help text below the field (Figma `helpTextOutside`); `isErrorMessage` (defaults to `isError`) controls the message color independently — pass `isErrorMessage = false` for an error-styled field with neutral gray help text (Figma shows both)
- `trailingIcon` + `onTrailingIconClick` — custom trailing button in a 30 dp / 8 dp-radius touch area (Figma `buttonIcon`); the clear button takes precedence while typing
- `maxLength`, `singleLine`, `showClearButton`, `keyboardOptions`, `visualTransformation`, `focusRequester`, `onImeAction`

### Example

```kotlin
TextField(
value = uiState.name,
onValueChange = viewModel::onNameChanged,
label = stringResource(R.string.name_label),
message = uiState.nameError?.let { stringResource(it) },
isError = uiState.nameError != null,
maxLength = 25
)
```

### Notes

- For crypto addresses use `AddressField` (QR-scan affordance, long-press-to-paste); for search bars use `SearchField`. `TextField` is the generic single/multi-line input.
- Layout specs from Figma: min height 58 dp, padding start 16 / end 12 / vertical 10, radius 16, row gap 10, label-to-text gap 2.

## Typography Mapping (Figma Design System → MyTheme.Typography)

When implementing designs from Figma, use the following typography mappings. All styles are available in `MyTheme.Typography.*`:
Expand Down Expand Up @@ -997,18 +1131,21 @@ When implementing designs from Figma, use the following typography mappings. All
### Usage Examples

```kotlin
// Always read colors at the top of the composable:
val colors = LocalDashColors.current

// Dialog title - Use Headline S Bold
Text(
text = stringResource(R.string.upgrade_pin_title),
style = MyTheme.Typography.HeadlineSmallBold,
color = MyTheme.Colors.textPrimary
color = colors.textPrimary
)

// Dialog description - Use Body M (Regular)
Text(
text = stringResource(R.string.upgrade_pin_description),
style = MyTheme.Typography.BodyMedium,
color = MyTheme.Colors.textSecondary
color = colors.textSecondary
)

// List item title - Use Title M Semibold
Expand All @@ -1021,7 +1158,7 @@ Text(
Text(
text = "2 hours ago",
style = MyTheme.Typography.LabelMedium,
color = MyTheme.Colors.textTertiary
color = colors.textTertiary
)

// Button text - Use Label L Semibold (handled by DashButton)
Expand Down Expand Up @@ -1137,10 +1274,11 @@ private fun SettingsScreenContent(
else -> stringResource(statusId)
}

val colors = LocalDashColors.current
Column(
modifier = Modifier
.fillMaxSize()
.background(MyTheme.Colors.backgroundPrimary)
.background(colors.backgroundPrimary)
) {
// Top Navigation
NavBarBack(onBackClick = onBackClick)
Expand Down
106 changes: 92 additions & 14 deletions .claude/agents/figma-to-compose.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: "figma-to-compose"
description: "Implements Android Jetpack Compose screens from Figma designs. Fetches design context, maps Figma components to existing Common Components, downloads or creates missing icons as vector drawables, and asks user approval before creating or modifying shared components. Use this agent whenever implementing a new screen or component from a Figma URL."
tools: ["mcp__figma-dev-mode-mcp-server__get_design_context", "mcp__figma-dev-mode-mcp-server__get_screenshot", "mcp__figma-dev-mode-mcp-server__get_metadata", "mcp__figma-dev-mode-mcp-server__get_variable_defs", "Read", "Write", "Edit", "Glob", "Grep", "Bash", "WebFetch", "AskUserQuestion", "mcp__ide__getDiagnostics"]
tools: ["mcp__figma-dev-mode-mcp-server__get_design_context", "mcp__figma-dev-mode-mcp-server__get_screenshot", "mcp__figma-dev-mode-mcp-server__get_metadata", "mcp__figma-dev-mode-mcp-server__get_variable_defs", "mcp__figma__get_design_context", "mcp__figma__get_screenshot", "mcp__figma__get_metadata", "mcp__figma__get_variable_defs", "ToolSearch", "Read", "Write", "Edit", "Glob", "Grep", "Bash", "WebFetch", "AskUserQuestion", "mcp__ide__getDiagnostics"]
---

# Figma to Jetpack Compose Agent
Expand All @@ -12,7 +12,8 @@ This agent implements Android Jetpack Compose screens and components from Figma

### 1. Fetch the Design

Call `mcp__figma-dev-mode-mcp-server__get_design_context` with the node ID extracted from the Figma URL:
Call `mcp__figma-dev-mode-mcp-server__get_design_context` with the node ID extracted from the Figma URL.
If the `mcp__figma-dev-mode-mcp-server__*` tools are not available in your session, the same Figma tools may be exposed under the `mcp__figma__*` names (`mcp__figma__get_design_context`, `mcp__figma__get_metadata`, `mcp__figma__get_screenshot`, `mcp__figma__get_variable_defs`) — if they appear as deferred tools, load them with ToolSearch (`select:mcp__figma__get_design_context,...`) before calling. **Never implement a Figma design from guesswork: if no Figma tool is reachable, stop and report that instead of inferring the design from sibling components.**
- URL format: `https://www.figma.com/design/{fileKey}/{name}?node-id={nodeId}`
- Extract nodeId, replacing `-` with `:` (e.g. `24007-4540` → `24007:4540`)
- Always set `clientLanguages: "kotlin"` and `clientFrameworks: "jetpack compose, android"`
Expand Down Expand Up @@ -62,6 +63,8 @@ You MUST consult the component mapping table for every Figma component before wr
| `ListEmptyState` | `ListEmptyState` | `org.dash.wallet.common.ui.components.ListEmptyState` |
| `Toast` | `Toast` composable | `org.dash.wallet.common.ui.components.Toast` |
| `EnterAmount` (input bar) | `EnterAmount` | `org.dash.wallet.common.ui.components.EnterAmount` |
| `TextField-Base` / `text.field` | `TextField` | `org.dash.wallet.common.ui.components.TextField` |
| `addressField` | `AddressField` | `org.dash.wallet.common.ui.components.AddressField` |

See `development-patterns` for full `NavBarBack`/`NavBarBackTitle`/`TopIntro` usage examples and all named NavBar variants.

Expand Down Expand Up @@ -93,18 +96,20 @@ For list rows, prefer the numbered design-system variants `ListItem1`…`ListIte

#### Color Mapping

| Figma Token | MyTheme Reference | Hex |
|-------------|-------------------|-----|
| `text/primary` | `MyTheme.Colors.textPrimary` | `#191C1F` |
| `text/secondary` | `MyTheme.Colors.textSecondary` | `#6E757C` |
| `text/tertiary` | `MyTheme.Colors.textTertiary` | `#75808A` |
| `background/primary` | `MyTheme.Colors.backgroundPrimary` | `#F5F6F7` |
| `background/secondary` | `MyTheme.Colors.backgroundSecondary` | `#FFFFFF` |
| `colors/dash-blue` | `MyTheme.Colors.dashBlue` | `#008DE4` |
| `colors/orange` | `MyTheme.Colors.orange` | `#FA9269` |
| `colors/red` | `MyTheme.Colors.red` | `#EA3943` |
| `colors/green` | `MyTheme.Colors.green` | `#3CB878` |
| `colors/gray` | `MyTheme.Colors.gray` | `#B0B6BC` |
**Important:** Never reference `MyTheme.Colors.*` directly in composables. Always read the current theme colors via `val colors = LocalDashColors.current` at the top of each composable, then use `colors.*`. This ensures correct values in both light and dark mode.

| Figma Token | `colors.*` field | Light hex | Dark hex |
|-------------|-----------------|-----------|----------|
| `text/primary` | `colors.textPrimary` | `#191C1F` | `#FFFFFF` |
| `text/secondary` | `colors.textSecondary` | `#6E757C` | `#92929C` |
| `text/tertiary` | `colors.textTertiary` | `#75808A` | `#75808A` |
| `background/primary` | `colors.backgroundPrimary` | `#F5F6F7` | `#10151F` |
| `background/secondary` | `colors.backgroundSecondary` | `#FFFFFF` | `#1D2532` |
| `colors/dash-blue` | `colors.dashBlue` | `#008DE4` | `#008DE4` |
| `colors/orange` | `colors.orange` | `#FA9269` | `#FA9269` |
| `colors/red` | `colors.red` | `#EA3943` | `#EA3943` |
| `colors/green` | `colors.green` | `#3CB878` | `#3CB878` |
| `colors/gray` | `colors.gray` | `#B0B6BC` | `#B0B6BC` |

### 4. Handle Icons and Image Assets

Expand Down Expand Up @@ -300,6 +305,79 @@ After implementation:
3. Verify all `R.string.*` references have entries in strings.xml
4. Confirm the nav graph `tools:layout` attribute is removed if the fragment uses ComposeView

## Dark Mode Compatibility

Every new screen, dialog, and component must work correctly in both light and dark mode. Follow these rules without exception.

### Compose: Theme Color Access

**Root entry point** — The composable entry point called from a Fragment's `ComposeView.setContent { }` must be wrapped in `DashWalletTheme`:

```kotlin
// In Fragment.onCreateView or onViewCreated:
composeView.setContent {
DashWalletTheme {
MyScreen(...)
}
}
```

**Inside every composable** — read current colors once at the top:

```kotlin
@Composable
fun MyComponent(...) {
val colors = LocalDashColors.current
// Use colors.textPrimary, colors.backgroundSecondary, etc.
// NEVER use MyTheme.Colors.* directly here
}
```

**Rules:**
- Never call `isSystemInDarkTheme()` inside individual components or screens — `DashWalletTheme` handles this once at the root
- Never use `MyTheme.Colors.*` directly in a composable body — it always returns light-mode values
- `MyTheme.Colors` and `MyTheme.DarkColors` are the source-of-truth data class instances; `LocalDashColors.current` selects the right one automatically

### Compose: Preview Dark Mode

Always include both a light and dark preview for new components:

```kotlin
@Composable
@Preview(name = "Light")
fun MyComponentPreviewLight() {
DashWalletTheme { MyComponent(...) }
}

@Composable
@Preview(name = "Dark", uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES)
fun MyComponentPreviewDark() {
DashWalletTheme { MyComponent(...) }
}
```

### XML Layouts: Semantic Color Tokens

Use semantic color names that have night-mode overrides in `values-night/colors.xml`. Never use raw `@android:color/white` or literal hex values for surfaces or text.

| Purpose | Use this color token |
|---------|---------------------|
| Page background | `@color/background_primary` |
| Card / sheet surface | `@color/background_secondary` |
| Primary text | `@color/content_primary` |
| Secondary text | `@color/content_secondary` |
| Dividers / borders | `@color/divider_color` |

### XML Drawables: Adaptive Colors

- **Shape drawables** (cards, panels): fill with `@color/background_secondary`, not `@android:color/white`
- **Vector icons**: add `android:tint="@color/content_primary"` to the `<vector>` element instead of hardcoding a fill color
- **Color state lists** (selectors): default state should use `@color/content_primary`, not a hardcoded dark hex

### DashButton Disabled State

`DashButton` handles disabled appearance automatically through `colors.disabledButtonBg` and `colors.contentDisabled` from `LocalDashColors`. Do not override button colors manually for the disabled case.

## Common Pitfalls

### Kotlin Overload Resolution with Trailing Lambdas
Expand Down
Loading
Loading