Skip to content

Remove CoinJoin mixing; begin Kotlin SDK migration (Phases 1, 2, 0 prep + Phase 3 start) - #1507

Closed
bfoss765 wants to merge 135 commits into
masterfrom
claude/blissful-cannon-7d4ac4
Closed

Remove CoinJoin mixing; begin Kotlin SDK migration (Phases 1, 2, 0 prep + Phase 3 start)#1507
bfoss765 wants to merge 135 commits into
masterfrom
claude/blissful-cannon-7d4ac4

Conversation

@bfoss765

@bfoss765 bfoss765 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

First tranche of the dashj → Kotlin SDK migration (full plan: docs/kotlin-sdk-migration-plan.md).

CoinJoin removal (Phase 2)

  • Mixing engine, screens, settings, notifications, analytics, and resources removed (~3,600 lines)
  • Previously mixed funds remain spendable: the CoinJoin keychain is still provisioned on load/create/restore, and sends use the standard coin selector; historical mixing transactions keep their grouped display
  • Regression coverage via the coinjoin.wallet fixture

dashj seam neutralization (Phase 1)

  • New neutral money kit in org.dash.wallet.common.money (Dash, FiatValue, MoneyFormat, address/URI/txid helpers) — mirrors the dashj APIs and delegates to dashj internally, so behavior is identical by construction
  • uphold, exploredash, maya, coinbase no longer depend on dashj at all; their dashj-transaction internals moved into the wallet module behind neutral interfaces
  • crowdnode's UI/API surface is neutral; its tx-protocol layer deliberately keeps dashj until the L1 cutover
  • SendPaymentService gains neutral send/estimate overloads

SDK prerequisites (Phase 0, approved decisions)

  • minSdk 24 → 29; 64-bit-only ABIs (the SDK's Halo2/Orchard native core cannot build 32-bit)
  • BIP70 vendored from dashj-core 22.0.3 sources into org.dash.wallet.common.payments.bip70 (kept per product decision; survives dashj removal)
  • CoinJoin-restore verified SAFE at rust-dashcore pin 647fa982+ (details/conditions in the plan doc)

Phase 3 start

  • Adds org.dashfoundation:dash-sdk-android:0.1.0-SNAPSHOT (published from the platform repo's kotlin-sdk package; local build for now — companion platform branch feat/kotlin-sdk-maven-publish adds the publishing). APK packages the native JNI lib for both ABIs; duplicate-class check passes alongside dashj.

Also fixed in passing

  • Two latent production bugs exposed by repairing pre-existing broken tests: gift-card metadata cache overwrote stored fields with nulls; time-skew dialog understated skew (double division)

Test plan

  • assemble_testNet3Debug + full unit-test suites of wallet, common, and all integration modules
  • BIP70: 15 tests green against the vendored classes
  • On-device smoke test (send/receive, old mixed-funds wallet)
  • Translation refresh for the reworded background-processes notification string (18 locales)

🤖 Generated with Claude Code

bfoss765 and others added 13 commits July 7, 2026 16:53
…placement for CoinJoin)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- gift-card metadata cache wrote the partially-populated incoming card instead of
  the merged one, erasing stored fields; also merge redeemUrlChallenge like other fields
- CSV export crashed with uninitialized metadataMap unless callers remembered
  initMetadataMap(); exportString() now self-initializes
- GetUsernameVotingResultOperationTest assumed a 2-minute buffer; production
  DELAY_AFTER_VOTING_PERIOD is 1 minute
- gift-card test updated for the insertGiftCardData signature added by the
  redeem-url change (order/giftCardChallenge/index)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CoinJoin removal (Phase 2 of the Kotlin SDK migration plan):
- delete the mixing engine wiring (CoinJoinService, CoinJoinConfig, DI binding),
  all mixing UI (CoinJoinActivity/info/level screens, MixingStatusCard,
  MixDashFirst dialog, settings row), mixing notification/foreground-service
  promotion, coinjoin coin selectors, analytics events, and all related
  strings/drawables/layouts/nav across every locale
- previously mixed funds STAY SPENDABLE: the wallet still loads as WalletEx and
  the CoinJoin keychain is still provisioned on load/create/restore/upgrade, so
  legacy mixed UTXOs remain visible and are selected by the standard
  ZeroConfCoinSelector; historical mixing transactions keep grouped display
- send flow always uses the standard selectors; useCoinJoin threading removed
  from identity/invite/top-up funding (dashj still receives useCoinJoin=false)
- fix latent time-skew dialog bug exposed by removing the coinjoin branch
  (seconds were divided by 1000 again and shown as minutes)

Start of Phase 1 (dashj seam neutralization in common):
- new neutral SyncStage enum; BlockchainStateProvider no longer exposes
  PeerGroup.SyncStage or AbstractBlockChain
- remove dead SendPaymentService.isFeeTooHigh (no callers, always false)
- consolidate observeSpendableBalance into observeTotalBalance (identical
  streams after mixing removal)

Verified: assemble_testNet3Debug and the full wallet unit-test suite pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New org.dash.wallet.common.money kit (Dash, FiatValue, MoneyFormat,
DashAddressValidator, ExchangeRate conversions): mirrors the Coin/Fiat/
MonetaryFormat APIs and delegates to dashj internally, so behavior is
identical while feature/integration modules no longer see dashj types.
WalletDataProvider gains neutral networkId/receive-address accessors.

integrations/uphold no longer depends on dashj-core.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Gift-card/tx ids flow as hex strings (TxIds helpers), money via the neutral
kit, payment URIs via new DashUri parser, FakeDashSpendService moved into the
wallet module. dashj-core dependency removed from features/exploredash.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Money/URI/address handling via the neutral kit; the dashj swap-transaction
builder (MayaBlockchainApiImpl) moves into the wallet module behind maya's
neutral interface. dashj-core dependency removed from integrations/maya.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Neutral sendCoins/estimateNetworkFee overloads on SendPaymentService
(txId-hex/TransactionEstimate) implemented in the wallet module; money types
via the neutral kit. dashj-core dependency removed from integrations/coinbase.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CrowdNodeApi and all UI/ViewModel/worker code now use the neutral money kit
(Dash amounts, base58 address strings, MoneyFormat). The transaction-protocol
layer (tx filters, blockchain api, confirmation handshake) deliberately stays
dashj-typed — it moves real funds and is the exact surface that gets rewritten
against the Kotlin SDK in the L1-cutover phase — so integrations/crowdnode
keeps its dashj-core dependency for that layer only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Approved prerequisites for the Kotlin SDK (native Halo2/Orchard core is
64-bit-only, minSdk 29). Platform features were already disabled on 32-bit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copies PaymentProtocol/PaymentSession/Protos (+X509 helpers) from
dashj-core 22.0.3 sources into org.dash.wallet.common.payments.bip70 and
repoints all usages. Product decision: BIP70 stays; owning the code lets it
be re-based onto the Kotlin SDK when dashj is removed in Phase 5.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…maven-publish added

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
org.dashfoundation:dash-sdk-android:0.1.0-SNAPSHOT (from mavenLocal, built
and published from the platform repo's kotlin-sdk package). APK packages the
native JNI library for arm64-v8a/x86_64; duplicate-class check passes
alongside dashj. Porting PlatformService/DashPay to the SDK comes next.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 428 files, which is 378 over the limit of 50.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

Usage-priced reviews support at most 300 files.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 51fa1752-e6c1-476a-9284-329fa550516a

📥 Commits

Reviewing files that changed from the base of the PR and between 618ac7b and 6766aaf.

⛔ Files ignored due to path filters (2)
  • features/exploredash/test/resources/empty_explore.db is excluded by !**/*.db
  • features/exploredash/test/resources/explore.db is excluded by !**/*.db
📒 Files selected for processing (447)
  • common/build.gradle
  • common/src/main/java/org/dash/wallet/common/WalletDataProvider.kt
  • common/src/main/java/org/dash/wallet/common/WalletDataProviderExt.kt
  • common/src/main/java/org/dash/wallet/common/data/BaseConfig.kt
  • common/src/main/java/org/dash/wallet/common/data/PaymentIntent.java
  • common/src/main/java/org/dash/wallet/common/data/SyncStage.kt
  • common/src/main/java/org/dash/wallet/common/data/WalletUIConfig.kt
  • common/src/main/java/org/dash/wallet/common/data/entity/GiftCard.kt
  • common/src/main/java/org/dash/wallet/common/data/entity/TransactionMetadata.kt
  • common/src/main/java/org/dash/wallet/common/money/AddressValidation.kt
  • common/src/main/java/org/dash/wallet/common/money/Dash.kt
  • common/src/main/java/org/dash/wallet/common/money/FiatValue.kt
  • common/src/main/java/org/dash/wallet/common/money/MoneyAdapters.kt
  • common/src/main/java/org/dash/wallet/common/money/MoneyFormat.kt
  • common/src/main/java/org/dash/wallet/common/money/TxIds.kt
  • common/src/main/java/org/dash/wallet/common/payments/bip70/PaymentProtocol.java
  • common/src/main/java/org/dash/wallet/common/payments/bip70/PaymentProtocolException.java
  • common/src/main/java/org/dash/wallet/common/payments/bip70/PaymentSession.java
  • common/src/main/java/org/dash/wallet/common/payments/bip70/Protos.java
  • common/src/main/java/org/dash/wallet/common/payments/bip70/TrustStoreLoader.java
  • common/src/main/java/org/dash/wallet/common/payments/bip70/X509Utils.java
  • common/src/main/java/org/dash/wallet/common/payments/parsers/AddressParser.kt
  • common/src/main/java/org/dash/wallet/common/payments/parsers/Bech32AddressParser.kt
  • common/src/main/java/org/dash/wallet/common/payments/parsers/BitcoinAddressParser.kt
  • common/src/main/java/org/dash/wallet/common/payments/parsers/BitcoinUris.kt
  • common/src/main/java/org/dash/wallet/common/payments/parsers/DashPaymentIntentParser.kt
  • common/src/main/java/org/dash/wallet/common/payments/parsers/DashUri.kt
  • common/src/main/java/org/dash/wallet/common/payments/parsers/PaymentIntents.kt
  • common/src/main/java/org/dash/wallet/common/services/BlockchainStateProvider.kt
  • common/src/main/java/org/dash/wallet/common/services/ConfirmTransactionService.kt
  • common/src/main/java/org/dash/wallet/common/services/SendPaymentService.kt
  • common/src/main/java/org/dash/wallet/common/services/SendPaymentServiceExt.kt
  • common/src/main/java/org/dash/wallet/common/services/TransactionMetadataProviderExt.kt
  • common/src/main/java/org/dash/wallet/common/services/analytics/AnalyticsConstants.kt
  • common/src/main/java/org/dash/wallet/common/services/analytics/AnalyticsService.kt
  • common/src/main/java/org/dash/wallet/common/transactions/TransactionUtils.kt
  • common/src/main/java/org/dash/wallet/common/ui/BalanceUIState.kt
  • common/src/main/java/org/dash/wallet/common/ui/CurrencyTextViewExt.kt
  • common/src/main/java/org/dash/wallet/common/ui/components/EnterAmount.kt
  • common/src/main/java/org/dash/wallet/common/ui/components/MenuItem.kt
  • common/src/main/java/org/dash/wallet/common/ui/dialogs/AdaptiveDialog.kt
  • common/src/main/java/org/dash/wallet/common/ui/dialogs/OffsetDialogFragment.kt
  • common/src/main/java/org/dash/wallet/common/ui/enter_amount/AmountViewExt.kt
  • common/src/main/java/org/dash/wallet/common/ui/enter_amount/EnterAmountFragment.kt
  • common/src/main/java/org/dash/wallet/common/ui/enter_amount/EnterAmountViewModel.kt
  • common/src/main/java/org/dash/wallet/common/util/Constants.kt
  • common/src/main/java/org/dash/wallet/common/util/GenericUtils.kt
  • common/src/main/java/org/dash/wallet/common/util/MonetaryExt.kt
  • common/src/main/res/layout/dialog_progress_dismissible.xml
  • common/src/main/res/values-de/strings.xml
  • common/src/main/res/values-el/strings.xml
  • common/src/main/res/values-es/strings.xml
  • common/src/main/res/values-fa/strings.xml
  • common/src/main/res/values-fil/strings.xml
  • common/src/main/res/values-fr/strings.xml
  • common/src/main/res/values-id/strings.xml
  • common/src/main/res/values-it/strings.xml
  • common/src/main/res/values-ja/strings.xml
  • common/src/main/res/values-ko/strings.xml
  • common/src/main/res/values-nl/strings.xml
  • common/src/main/res/values-pl/strings.xml
  • common/src/main/res/values-pt/strings.xml
  • common/src/main/res/values-ru/strings.xml
  • common/src/main/res/values-sk/strings.xml
  • common/src/main/res/values-uk/strings.xml
  • common/src/main/res/values-zh-rTW/strings.xml
  • common/src/main/res/values-zh/strings.xml
  • common/src/main/res/values/strings.xml
  • common/src/test/java/org/dash/wallet/common/transactions/IsEntirelySelfTest.kt
  • docs/kotlin-sdk-issues-to-file.md
  • docs/kotlin-sdk-migration-plan.md
  • features/exploredash/build.gradle
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/data/explore/GiftCardDao.kt
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/network/PiggyCardsRemoteDataSource.kt
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/network/RemoteDataSource.kt
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/repository/PiggyCardsRepository.kt
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/ui/ExploreTestNetFragment.kt
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/ui/dashspend/DashSpendViewModel.kt
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/ui/dashspend/PurchaseGiftCardFragment.kt
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/ui/dashspend/PurchaseGiftCardFragmentV2.kt
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/ui/dashspend/dialogs/GiftCardDetailsDialog.kt
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/ui/dashspend/dialogs/GiftCardDetailsViewModel.kt
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/ui/dashspend/dialogs/GiftCardOrderDetailsDialog.kt
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/ui/dashspend/dialogs/GiftCardOrderDetailsViewModel.kt
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/ui/dashspend/dialogs/GiftCardViewModel.kt
  • features/exploredash/src/main/java/org/dash/wallet/features/exploredash/ui/dashspend/dialogs/PurchaseGiftCardConfirmDialog.kt
  • features/exploredash/src/test/java/org/dash/wallet/features/exploredash/CTXSpendExceptionTest.kt
  • integrations/coinbase/build.gradle
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/model/AccountsResponse.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/model/CoinBaseUserAccountInfo.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/repository/CoinBaseRepository.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/ui/CoinbaseBuyDashFragment.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/ui/CoinbaseConvertCryptoFragment.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/ui/CoinbaseOrderReviewFragment.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/ui/CoinbaseServicesFragment.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/ui/EnterAmountToTransferFragment.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/ui/TransferDashFragment.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/ui/convert_currency/ConvertView.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/ui/convert_currency/ConvertViewFragment.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/ui/convert_currency/TransferView.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/ui/convert_currency/model/SwapRequest.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/ui/dialogs/crypto_wallets/CryptoWalletsDialog.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/viewmodels/CoinbaseBuyDashViewModel.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/viewmodels/CoinbaseConversionPreviewViewModel.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/viewmodels/CoinbaseConvertCryptoViewModel.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/viewmodels/CoinbaseServicesViewModel.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/viewmodels/CoinbaseViewModel.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/viewmodels/ConvertViewViewModel.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/viewmodels/EnterAmountToTransferViewModel.kt
  • integrations/coinbase/src/main/java/org/dash/wallet/integrations/coinbase/viewmodels/TransferDashViewModel.kt
  • integrations/crowdnode/build.gradle
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/api/CrowdNodeApi.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/api/CrowdNodeBlockchainApi.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/api/CrowdNodeConfirmationTxHandler.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/api/CrowdNodeWorker.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/model/WithdrawalLimit.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/transactions/CrowdNodeAcceptTermsResponse.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/transactions/CrowdNodeAcceptTermsTx.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/transactions/CrowdNodeDepositReceivedResponse.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/transactions/CrowdNodeDepositTx.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/transactions/CrowdNodeSignUpTx.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/transactions/CrowdNodeTopUpTx.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/transactions/CrowdNodeWelcomeToApiResponse.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/transactions/CrowdNodeWithdrawalDeniedResponse.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/transactions/CrowdNodeWithdrawalQueueResponse.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/transactions/CrowdNodeWithdrawalReceivedTx.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/ui/CrowdNodeViewModel.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/ui/ResultFragment.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/ui/dialogs/QRDialog.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/ui/dialogs/StakingDialog.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/ui/dialogs/WithdrawalLimitsInfoDialog.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/ui/entry_point/NewAccountFragment.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/ui/online/OnlineSignUpFragment.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/ui/portal/PortalFragment.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/ui/portal/TransferFragment.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/utils/CrowdNodeBalanceCondition.kt
  • integrations/crowdnode/src/main/java/org/dash/wallet/integrations/crowdnode/utils/CrowdNodeConstants.kt
  • integrations/crowdnode/src/test/java/org/dash/wallet/integrations/crowdnode/CrowdNodeViewModelTest.kt
  • integrations/maya/build.gradle
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/api/MayaApi.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/api/MayaBlockchainApi.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/di/MayaModule.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/model/AccountDataUIModel.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/model/MayaErrorResponse.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/model/PoolInfo.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/model/SwapTradeResponse.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/payments/MayaCryptoCurrency.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/payments/parsers/Bech32PaymentIntentParser.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/payments/parsers/BitcoinPaymentIntentParser.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/payments/parsers/EthereumPaymentIntentParser.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/payments/parsers/MayaPaymentIntentParser.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/payments/parsers/RuneAddressParser.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/payments/parsers/XrdPaymentIntentParser.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/payments/parsers/ZcashAddressParser.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/payments/parsers/ZcashPaymentIntentParser.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/ui/MayaConversionPreviewViewModel.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/ui/MayaConvertCryptoFragment.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/ui/MayaConvertCryptoViewModel.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/ui/MayaViewModel.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/ui/convert_currency/ConvertViewFragment.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/ui/convert_currency/ConvertViewViewModel.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/ui/convert_currency/ConverterView.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/ui/convert_currency/model/SwapRequest.kt
  • integrations/maya/src/main/java/org/dash/wallet/integrations/maya/utils/MayaConstants.kt
  • integrations/uphold/build.gradle
  • integrations/uphold/src/main/java/org/dash/wallet/integrations/uphold/api/TopperClient.kt
  • integrations/uphold/src/main/java/org/dash/wallet/integrations/uphold/ui/UpholdPortalFragment.kt
  • integrations/uphold/src/main/java/org/dash/wallet/integrations/uphold/ui/UpholdTransferActivity.kt
  • integrations/uphold/src/main/java/org/dash/wallet/integrations/uphold/ui/UpholdViewModel.kt
  • wallet/AndroidManifest.xml
  • wallet/androidTest/de/schildbach/wallet/security/SecurityGuardMultiThreadingTest.kt
  • wallet/build.gradle
  • wallet/res/drawable/ic_arrows_internal.xml
  • wallet/res/drawable/ic_coinjoin_big.xml
  • wallet/res/drawable/ic_credits_symbol.xml
  • wallet/res/drawable/ic_mixing.xml
  • wallet/res/drawable/ic_mixing_icon.xml
  • wallet/res/drawable/ic_shielded_balance.xml
  • wallet/res/drawable/ic_transfer_instant.xml
  • wallet/res/drawable/ic_transfer_stopwatch.xml
  • wallet/res/drawable/ic_unmixed_funds.xml
  • wallet/res/drawable/rounded_primary_bg_14.xml
  • wallet/res/layout/activity_create_username.xml
  • wallet/res/layout/activity_edit_profile.xml
  • wallet/res/layout/dialog_confirm_username_request.xml
  • wallet/res/layout/dialog_invite_shielded_funding.xml
  • wallet/res/layout/dialog_mix_dash_first.xml
  • wallet/res/layout/dialog_username_payment.xml
  • wallet/res/layout/fragment_coinjoin_info.xml
  • wallet/res/layout/fragment_coinjoin_level.xml
  • wallet/res/layout/fragment_more.xml
  • wallet/res/layout/fragment_request_username.xml
  • wallet/res/layout/home_content.xml
  • wallet/res/layout/identity_creation_state.xml
  • wallet/res/navigation/nav_coinjoin.xml
  • wallet/res/navigation/nav_create_invite.xml
  • wallet/res/raw/mixing_anim.json
  • wallet/res/values-de/strings-dashpay.xml
  • wallet/res/values-de/strings-extra.xml
  • wallet/res/values-de/strings.xml
  • wallet/res/values-el/strings-dashpay.xml
  • wallet/res/values-el/strings-extra.xml
  • wallet/res/values-el/strings.xml
  • wallet/res/values-es/strings-dashpay.xml
  • wallet/res/values-es/strings-extra.xml
  • wallet/res/values-es/strings.xml
  • wallet/res/values-fa/strings-dashpay.xml
  • wallet/res/values-fa/strings-extra.xml
  • wallet/res/values-fa/strings.xml
  • wallet/res/values-fil/strings-dashpay.xml
  • wallet/res/values-fil/strings-extra.xml
  • wallet/res/values-fil/strings.xml
  • wallet/res/values-fr/strings-dashpay.xml
  • wallet/res/values-fr/strings-extra.xml
  • wallet/res/values-fr/strings.xml
  • wallet/res/values-id/strings-dashpay.xml
  • wallet/res/values-id/strings-extra.xml
  • wallet/res/values-id/strings.xml
  • wallet/res/values-it/strings-dashpay.xml
  • wallet/res/values-it/strings-extra.xml
  • wallet/res/values-it/strings.xml
  • wallet/res/values-ja/strings-dashpay.xml
  • wallet/res/values-ja/strings-extra.xml
  • wallet/res/values-ja/strings.xml
  • wallet/res/values-ko/strings-dashpay.xml
  • wallet/res/values-ko/strings-extra.xml
  • wallet/res/values-ko/strings.xml
  • wallet/res/values-nl/strings-dashpay.xml
  • wallet/res/values-nl/strings-extra.xml
  • wallet/res/values-nl/strings.xml
  • wallet/res/values-pl/strings-dashpay.xml
  • wallet/res/values-pl/strings-extra.xml
  • wallet/res/values-pl/strings.xml
  • wallet/res/values-pt/strings-dashpay.xml
  • wallet/res/values-pt/strings-extra.xml
  • wallet/res/values-pt/strings.xml
  • wallet/res/values-ru/strings-dashpay.xml
  • wallet/res/values-ru/strings-extra.xml
  • wallet/res/values-ru/strings.xml
  • wallet/res/values-sk/strings-dashpay.xml
  • wallet/res/values-sk/strings-extra.xml
  • wallet/res/values-sk/strings.xml
  • wallet/res/values-tr/strings-dashpay.xml
  • wallet/res/values-uk/strings-dashpay.xml
  • wallet/res/values-uk/strings-extra.xml
  • wallet/res/values-uk/strings.xml
  • wallet/res/values-zh-rTW/strings-dashpay.xml
  • wallet/res/values-zh-rTW/strings-extra.xml
  • wallet/res/values-zh-rTW/strings.xml
  • wallet/res/values-zh/strings-dashpay.xml
  • wallet/res/values-zh/strings-extra.xml
  • wallet/res/values-zh/strings.xml
  • wallet/res/values/firebase.xml
  • wallet/res/values/strings-dashpay.xml
  • wallet/res/values/strings-extra.xml
  • wallet/res/values/strings.xml
  • wallet/src/de/schildbach/wallet/Constants.java
  • wallet/src/de/schildbach/wallet/WalletApplication.java
  • wallet/src/de/schildbach/wallet/WalletApplicationExt.kt
  • wallet/src/de/schildbach/wallet/data/CoinJoinConfig.kt
  • wallet/src/de/schildbach/wallet/database/entity/BlockchainIdentityData.kt
  • wallet/src/de/schildbach/wallet/di/AppModule.kt
  • wallet/src/de/schildbach/wallet/di/DashPayModule.kt
  • wallet/src/de/schildbach/wallet/di/PlatformSdkModule.kt
  • wallet/src/de/schildbach/wallet/offline/AcceptBluetoothThread.java
  • wallet/src/de/schildbach/wallet/offline/DirectPaymentTask.java
  • wallet/src/de/schildbach/wallet/payments/ChainLockedCoinSelector.kt
  • wallet/src/de/schildbach/wallet/payments/FakeDashSpendService.kt
  • wallet/src/de/schildbach/wallet/payments/MaxOutputAmountCoinJoinCoinSelector.kt
  • wallet/src/de/schildbach/wallet/payments/MayaBlockchainApiImpl.kt
  • wallet/src/de/schildbach/wallet/payments/RequestPaymentRequestTask.java
  • wallet/src/de/schildbach/wallet/payments/SendCoinsTaskRunner.kt
  • wallet/src/de/schildbach/wallet/security/BiometricHelper.kt
  • wallet/src/de/schildbach/wallet/security/FingerprintStorage.java
  • wallet/src/de/schildbach/wallet/service/BlockchainServiceImpl.kt
  • wallet/src/de/schildbach/wallet/service/BlockchainStateDataProvider.kt
  • wallet/src/de/schildbach/wallet/service/CoinJoinService.kt
  • wallet/src/de/schildbach/wallet/service/ForegroundService.kt
  • wallet/src/de/schildbach/wallet/service/WalletFactory.kt
  • wallet/src/de/schildbach/wallet/service/WalletTransactionMetadataProvider.kt
  • wallet/src/de/schildbach/wallet/service/platform/IdentityCacheTolerance.kt
  • wallet/src/de/schildbach/wallet/service/platform/IdentityKeyChainBackfill.kt
  • wallet/src/de/schildbach/wallet/service/platform/IdentityRepository.kt
  • wallet/src/de/schildbach/wallet/service/platform/PlatformBroadcastService.kt
  • wallet/src/de/schildbach/wallet/service/platform/PlatformHealthService.kt
  • wallet/src/de/schildbach/wallet/service/platform/PlatformService.kt
  • wallet/src/de/schildbach/wallet/service/platform/PlatformSyncService.kt
  • wallet/src/de/schildbach/wallet/service/platform/TopUpRepository.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/Bech32m.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/BirthHeightResolver.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/CutoverCoordinator.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/CutoverDebugReadout.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/CutoverEvidenceCollector.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/CutoverReadiness.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/CutoverStateMachine.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/DashSdkService.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/DashSdkServiceImpl.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/L1SendProbeService.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/L1ShadowDebugReset.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/L1ShadowSyncService.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/PlatformMnemonicProvider.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/SdkBridgedTransactionFactory.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/SdkDashPayWrites.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/SdkIdentityVerifyQueries.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/SdkIdentityVerifyWrites.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/SdkL1SendService.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/SdkProfileQueries.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/SdkShieldedUsernameCreation.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/SdkTxMetadataDecryptProbe.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/SdkUsernameQueries.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/SdkVotingQueries.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/SdkWalletBinder.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/SecurityGuardMnemonicProvider.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/ShieldedBalanceService.kt
  • wallet/src/de/schildbach/wallet/service/platform/sdk/ShieldedBalanceServiceImpl.kt
  • wallet/src/de/schildbach/wallet/service/platform/work/RestoreIdentityWorker.kt
  • wallet/src/de/schildbach/wallet/service/platform/work/TopupIdentityWorker.kt
  • wallet/src/de/schildbach/wallet/transactions/CSVExporter.kt
  • wallet/src/de/schildbach/wallet/transactions/TransactionExporter.kt
  • wallet/src/de/schildbach/wallet/transactions/WalletBalanceObserver.kt
  • wallet/src/de/schildbach/wallet/ui/CreateUsernameActivity.kt
  • wallet/src/de/schildbach/wallet/ui/DashPayUserActivity.kt
  • wallet/src/de/schildbach/wallet/ui/DashPayUserActivityViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/EditProfileActivity.kt
  • wallet/src/de/schildbach/wallet/ui/InviteHandlerViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/OnboardingViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/SettingsFragment.kt
  • wallet/src/de/schildbach/wallet/ui/TransactionResultViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/buy_sell/BuyAndSellViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/coinjoin/CoinJoinActivity.kt
  • wallet/src/de/schildbach/wallet/ui/coinjoin/CoinJoinInfoFragment.kt
  • wallet/src/de/schildbach/wallet/ui/coinjoin/CoinJoinLevelFragment.kt
  • wallet/src/de/schildbach/wallet/ui/coinjoin/CoinJoinLevelViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/dashpay/ContactsFragment.kt
  • wallet/src/de/schildbach/wallet/ui/dashpay/CreateIdentityService.kt
  • wallet/src/de/schildbach/wallet/ui/dashpay/CreateIdentityViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/dashpay/DashPayViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/dashpay/HistoryHeaderAdapter.kt
  • wallet/src/de/schildbach/wallet/ui/dashpay/IdentityCreationStatus.kt
  • wallet/src/de/schildbach/wallet/ui/dashpay/NotificationsFragment.kt
  • wallet/src/de/schildbach/wallet/ui/dashpay/PlatformRepo.kt
  • wallet/src/de/schildbach/wallet/ui/dashpay/utils/DashPayConfig.kt
  • wallet/src/de/schildbach/wallet/ui/invite/CreateInviteViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/invite/InvitationFeeDialogFragment.kt
  • wallet/src/de/schildbach/wallet/ui/invite/InviteShieldedFundingDialogFragment.kt
  • wallet/src/de/schildbach/wallet/ui/invite/InviteShieldedFundingSheet.kt
  • wallet/src/de/schildbach/wallet/ui/invite/InviteShieldedFundingViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/main/MainActivity.kt
  • wallet/src/de/schildbach/wallet/ui/main/MainActivityExt.kt
  • wallet/src/de/schildbach/wallet/ui/main/MainViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/main/MixingStatusCard.kt
  • wallet/src/de/schildbach/wallet/ui/main/WalletFragment.kt
  • wallet/src/de/schildbach/wallet/ui/main/WalletTransactionsFragment.kt
  • wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutsViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/more/AboutFragment.kt
  • wallet/src/de/schildbach/wallet/ui/more/ConfirmInviteDialogFragment.kt
  • wallet/src/de/schildbach/wallet/ui/more/MixDashFirstDialogFragment.kt
  • wallet/src/de/schildbach/wallet/ui/more/MixDashFirstViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/more/MoreFragment.kt
  • wallet/src/de/schildbach/wallet/ui/more/SettingsScreen.kt
  • wallet/src/de/schildbach/wallet/ui/more/SettingsViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/more/TransactionMetadataSettingsViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/payments/PaymentsFragment.kt
  • wallet/src/de/schildbach/wallet/ui/payments/PaymentsInternalFragment.kt
  • wallet/src/de/schildbach/wallet/ui/send/PaymentProtocolFragment.kt
  • wallet/src/de/schildbach/wallet/ui/send/SendCoinsActivity.kt
  • wallet/src/de/schildbach/wallet/ui/send/SendCoinsFragment.kt
  • wallet/src/de/schildbach/wallet/ui/send/SendCoinsViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/shielded/ShieldedBalanceActivity.kt
  • wallet/src/de/schildbach/wallet/ui/shielded/ShieldedReceiveScreen.kt
  • wallet/src/de/schildbach/wallet/ui/shielded/ShieldedReceiveViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/shielded/ShieldedSendScreen.kt
  • wallet/src/de/schildbach/wallet/ui/shielded/ShieldedSendViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/shielded/ShieldedTransferExecutor.kt
  • wallet/src/de/schildbach/wallet/ui/shielded/ShieldedTransferScreen.kt
  • wallet/src/de/schildbach/wallet/ui/shielded/ShieldedTransferViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/shielded/ShieldedUi.kt
  • wallet/src/de/schildbach/wallet/ui/username/request/ConfirmUserNameDialogViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/username/request/ConfirmUsernameRequestDialogFragment.kt
  • wallet/src/de/schildbach/wallet/ui/username/request/RequestUserNameViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/username/request/RequestUsernameFragment.kt
  • wallet/src/de/schildbach/wallet/ui/username/request/UsernamePaymentDialogFragment.kt
  • wallet/src/de/schildbach/wallet/ui/username/request/UsernamePaymentSheets.kt
  • wallet/src/de/schildbach/wallet/ui/username/request/UsernamePaymentViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/username/request/UsernameSubmitAuth.kt
  • wallet/src/de/schildbach/wallet/ui/username/request/UsernameSubmitStatusDialogs.kt
  • wallet/src/de/schildbach/wallet/ui/username/request/UsernameVotingInfoFragment.kt
  • wallet/src/de/schildbach/wallet/ui/username/request/VerifyIdentityFragment.kt
  • wallet/src/de/schildbach/wallet/ui/username/request/WelcomeToDashPayFragment.kt
  • wallet/src/de/schildbach/wallet/ui/username/voting/UsernameRequestsViewModel.kt
  • wallet/src/de/schildbach/wallet/ui/util/InputParser.java
  • wallet/test/checkpoints-fixture-testnet.txt
  • wallet/test/de/schildbach/wallet/payments/ChainLockedCoinSelectorTest.kt
  • wallet/test/de/schildbach/wallet/payments/SendCoinsTaskRunnerBIP70Test.kt
  • wallet/test/de/schildbach/wallet/payments/SendCoinsTaskRunnerSdkRoutingTest.kt
  • wallet/test/de/schildbach/wallet/payments/SendCoinsTaskRunnerSelfSpendGraceTest.kt
  • wallet/test/de/schildbach/wallet/service/WalletTransactionMetadataProviderGiftCardTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/IdentityCacheToleranceTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/IdentityKeyChainBackfillTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/IdentityNoResurrectionGuardTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/PlatformHealthTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/PlatformSyncEngineTeardownTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/PlatformUsernameReconcileTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/BirthHeightResolverTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/CutoverReadinessTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/CutoverStateMachineTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/DashSdkServiceImplTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/L1SendProbeServiceTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/L1ShadowSyncServiceTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/SdkBridgedTransactionFactoryTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/SdkDashPayWritesTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/SdkIdentityVerifyQueriesTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/SdkIdentityVerifyWritesTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/SdkL1SendServiceTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/SdkProfileQueriesTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/SdkShieldedUsernameCreationTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/SdkTxMetadataDecryptProbeTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/SdkUsernameQueriesTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/SdkVotingQueriesTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/SdkWalletBinderTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/SecurityGuardMnemonicProviderTest.kt
  • wallet/test/de/schildbach/wallet/service/platform/sdk/ShieldedBalanceServiceTest.kt
  • wallet/test/de/schildbach/wallet/ui/ContactRequestErrorStringsTest.kt
  • wallet/test/de/schildbach/wallet/ui/CreateUsernameStartDestinationTest.kt
  • wallet/test/de/schildbach/wallet/ui/dashpay/ContactsIdentityGateTest.kt
  • wallet/test/de/schildbach/wallet/ui/dashpay/IdentityRetryStatusHintTest.kt
  • wallet/test/de/schildbach/wallet/ui/dashpay/NewSendContactRequestErrorsTest.kt
  • wallet/test/de/schildbach/wallet/ui/dashpay/utils/DashPayConfigSeedTest.kt
  • wallet/test/de/schildbach/wallet/ui/dashpay/work/GetUsernameVotingResultOperationTest.kt
  • wallet/test/de/schildbach/wallet/ui/invite/InviteShieldedFundingUIStateTest.kt
  • wallet/test/de/schildbach/wallet/ui/main/RequestedUsernameDisplayTest.kt
  • wallet/test/de/schildbach/wallet/ui/more/ProfileDisplayUsernameTest.kt
  • wallet/test/de/schildbach/wallet/ui/more/SettingsViewModelTest.kt
  • wallet/test/de/schildbach/wallet/ui/more/ShieldedCardDisplayTest.kt
  • wallet/test/de/schildbach/wallet/ui/more/UsernameVotingEndTimeTest.kt
  • wallet/test/de/schildbach/wallet/ui/payments/PaymentsTabsTest.kt
  • wallet/test/de/schildbach/wallet/ui/shielded/ShieldedTransferExecutorTest.kt
  • wallet/test/de/schildbach/wallet/ui/shielded/ShieldedTransferExitTargetTest.kt
  • wallet/test/de/schildbach/wallet/ui/shielded/ShieldedTransferViewModelTest.kt
  • wallet/test/de/schildbach/wallet/ui/shielded/ShieldedUiFormatTest.kt
  • wallet/test/de/schildbach/wallet/ui/transactions/TransactionRowViewIconTest.kt
  • wallet/test/de/schildbach/wallet/ui/username/request/RequestUserNameViewModelTest.kt
  • wallet/test/de/schildbach/wallet/ui/username/request/UsernameConfirmCostTest.kt
  • wallet/test/de/schildbach/wallet/ui/username/request/UsernamePaymentViewModelTest.kt
  • wallet/test/de/schildbach/wallet/util/services/SendCoinsTaskRunnerTest.kt
  • wallet/test/de/schildbach/wallet/util/viewModels/MainViewModelTest.kt
  • wallet/test/org/dash/wallet/common/data/BaseConfigRegistryTest.kt

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/blissful-cannon-7d4ac4

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.

❤️ Share

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

bfoss765 and others added 3 commits July 8, 2026 12:12
DashSdkService: lazy, explicitly-started SDK runtime (Sdk init, Room DB,
WalletStorage, WalletManagerStore activation) mirroring the example app's
AppContainer bootstrap order. Zero default behavior change — nothing starts
unless ensureStarted() is called; mnemonic bridging is a Phase 3b seam.
resolveUsername() is the verified read-side entry point.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SecurityGuardMnemonicProvider reuses the canonical SecurityFunctions
decrypt path (caller owns authentication; provider never prompts).
DashSdkService.bindAppWallet(seedWords) idempotently creates/rehydrates the
SDK-side wallet (birthHeight=0 until the Phase 5 migration flow maps
wallet-creation time to a height). 20 host-JVM tests; no production call
sites yet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PlatformRepo.getUsername and IdentityRepository.searchUsernames can run on
sdk.dpns.resolve/search behind DashPayConfig.USE_KOTLIN_SDK_DPNS_READS
(default off, re-read per lookup, automatic fallback to the dashj path on
any SDK failure). SdkDpnsMapping synthesizes the dashj document types the
existing callers consume; 16 host-JVM mapping/fallback tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bfoss765 and others added 12 commits July 8, 2026 13:27
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Phase 3d)

PlatformRepo.getVoteContenders maps sdk.voting.contestedResourceVoteState to
dashj Contenders (serialized-document bytes are rs-sdk-identical, so existing
deserialization keeps working). Profile reads (updateDashPayProfile,
searchUsernames enrichment, contact-profile sync) run on sdk.documents search
over dashpay/profile with dashj-parity queries. Same default-off flag and
automatic dashj fallback as Phase 3c; 31 new host-JVM mapping tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Identity-key derivation parity VERIFIED: dashj's DIP-13 auth tree
(m/9'/coin'/5'/0'/0'/0'/i') is byte-identical to the SDK's for identity
index 0, so the SDK can sign for dashj-registered identities. Contact-request
send and profile create/update route through wallet-bound SDK ops behind
USE_KOTLIN_SDK_DASHPAY_WRITES (default off) with a strict three-valued
no-double-broadcast contract (NotBroadcast→fallback, Broadcast→skip dashj,
Ambiguous→surface, never dashj-retry). Owner-id DPNS reads join the read
flag. 40 new host-JVM tests (152 total green).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SdkWalletBinder binds the app wallet to the SDK and attaches the existing
on-chain identity via identityRegistration.discoverIdentities, triggered
fire-and-forget where an unlocked key is already in scope (platform sync
init, dashpay broadcast paths). Provably inert with flags off; single-flight;
never prompts. DIP-15 parity verified funds-safe (xpub/addresses identical;
accountReference slice mismatch documented as an SDK hygiene issue).
171 host-JVM tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
One-time seeding (only if unset) in DashPayConfig; release builds keep the
flags OFF. QA can still toggle afterwards.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
FirebaseAnalyticsServiceImpl resolved Firebase.analytics at construction,
crashing app startup for any build missing the (intentionally optional)
Firebase config. Resolve lazily and no-op when FirebaseApp is absent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three startup crashes in Firebase-less local builds: placeholder FirebaseApp
init (valid-format dummy key) so DI-provided FirebaseAuth constructs;
com.crashlytics.RequireBuildId=false so Crashlytics init tolerates the absent
gradle-plugin build ID. No effect on builds with the real config.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… probe

Live on-device finding: dashpay.syncState throws a Generic FFI error for
identities the wallet doesn't manage instead of returning null, which aborted
the binder before identity discovery could run. SDK issue to file: syncState
should return null or a typed NotFound.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… engages

'no private key stored' surfaces pre-submission; observed live when a
discovered identity's private keys weren't derived/stored. Contact requests
now fall back to dashj instead of erroring. SDK issues to file: typed signing
error; discovery should derive/store identity keys (or expose a repair op).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Root cause of live 'no private key stored': the SDK persistence bridge
derives identity keys into an auth-gated Keystore alias (30s post-unlock
window) and silently skips outside it, so background discovery attached the
identity with no signable keys. ensureIdentityKeysSignable derives each key,
verifies the public half byte-equals the on-chain key (never poisons the
signer store), stores it, and retries on the next binder trigger when the
auth window was closed. 11 new tests. SDK issues: expose a repair op that
verifies; allow non-gated alias policy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bfoss765 and others added 17 commits July 14, 2026 16:32
…e L1 fee

The asset-lock coin-selection shortfall is raised while building the
transaction, strictly pre-broadcast, so it is NotBroadcast, not Ambiguous
(a live Max shield hit the 'may have gone through' dialog on it). Its
message reports required WITHOUT the L1 fee (available == required), so
unlike the shielded note-selection fix there is no exact deficit to parse:
a Max shield instead retries once withholding an estimated fee reserve
sized from the wallet's spendable UTXO count (1 duff/byte Rust-side rate,
2x margin — lossless, the builder returns excess as change; dashj's count
proxies the SDK's via UTXO parity).

Audited every other spend path for fee handling: non-max transfers in both
directions classify cleanly post-fix; username-funding gates match Rust's
exact-equality fee model (fee metered FROM the denomination, none added at
selection); the shield-pool minimum check derives from the prover estimate
plus the platform base cost. shieldFromCredits/unshieldToCredits have no
UI callers today — their address-funds shortfall messages would need rules
before ever being wired up.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…not instant

The shield leg builds an L1 asset lock and runs a ~30 s Halo 2 proof
before the note lands, so 'instant' misstated it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…debug seeding

The L1 shadow scan requires a bound wallet, but the binder's flag gate
and identity gate didn't count USE_KOTLIN_SDK_L1_SHADOW — a shadow-only
configuration could never bind (masked on testnet where the shielded
flag is seeded too). The shadow flag now opens both gates, binding-only,
matching its read-only contract.

Debug flag seeding is now network-aware: mainnet debug builds (prodDebug,
the external large-wallet validation vehicle) seed ONLY the read-only L1
shadow — never shielded UI or SDK write paths against real funds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Testers had no user-visible signal for when the SDK shadow scan finishes
(the home header only tracks dashj). Debug builds now fold a 'Kotlin
sync' label into the syncing header — during dashj sync as a suffix
('Syncing 63% · Kotlin sync: scan 42%'), and after dashj finishes the
header stays visible with the Kotlin state alone until 'Kotlin sync
100%' (✓ once a parity probe matches). Percent derives from the
header/filter counts, not the SDK's overallPercent, which under-reports
mid-scan. Hidden entirely on release builds and while the shadow is
idle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…in percent

The first cut's long labels truncated in the header (ellipsize=middle
mangled both statuses). Now both engines get a compact status: the
Kotlin percent is one monotonic number combining header+filter counts,
and the DashJ side is relabeled only while the debug Kotlin label is
present — the production 'Syncing N%' rendering is untouched otherwise.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…be, dialog finish-gating

1) checkUsername treated any failed platform lookup as 'name available'
   (observed live: a registered name showed available). Lookups now fail
   CLOSED: a non-SUCCESS name query or a thrown contenders read surfaces
   'couldn't verify availability' in the entry screen's availability slot,
   keeps the request button disabled, and logs the failure; retyping
   retries. getVoteContendersOrThrow propagates errors for this caller
   while the other call sites keep the old swallow.

2) The L1 funding gate needs a fresh parity report but the parity loop
   ticks every 60s; after each dashj idle-restart the shadow re-syncs in
   seconds and the gate then sat closed up to a minute (measured 53s,
   recurring every idle cycle — blocked live shielded transfers). The
   loop now also wakes on a conflated SYNCED-edge ping: one immediate
   probe per edge, schedule and decider logic unchanged.

3) The L1 username submit's processing dialog auto-dismissed: the
   identity state machine's first creationState flip made the fragments
   finish the activity under the dialog. Finishing is now gated while a
   submit is in flight; the dialog's explicit user dismissal finishes to
   home (programmatic replacement and lifecycle teardown excluded).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Light tertiary text centered below the picture circle, populated from
the DashPay profile.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ation

Pre-submit: the username screen probes one DAPI node's core height
(Core gRPC getBestBlockHeight — the legacy client has no getStatus) and
compares it against dashj's tip; >= 2 blocks behind renders an advisory
'network is running slower than usual' row. Purely informational — the
submit gate is untouched, and a failed probe says nothing.

During registration: dashj retries the chain-lock asset-lock proof in an
internal loop that swallows every per-attempt error (live incident: ~10
minutes of invisible retries on 'core chain height N is higher than the
current consensus core height M'), so duration is the only app-side
observable — a 30s watchdog around the blocking call flips the
home-screen tile hint to 'waiting for the network to catch up', and the
per-attempt missing-instant-lock failure (visible app-side) shows
'waiting for network confirmation'. Hints live in an in-memory holder
(no schema change) and clear on success.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…l banner at 90s

Every username-request submit path (L1 asset lock, shielded, dual)
handed the spend to CreateIdentityService / the shielded pipeline, which
sign with no user interaction — a non-private username registered on
device with no PIN/biometric at all. All five submit sites now route
through a shared authenticateThenSubmit gate; a cancelled prompt submits
nothing. The error-dialog retry re-authenticates too (fresh spend
attempt).

Shielded transfer stall banner: 180s → 90s. The live slow case was the
SDK waiting one block (~2.5 min on testnet) to confirm its asset lock
after its freshly restarted SPV couldn't verify the InstantSend lock, so
the banner routinely arrived AFTER the wait was nearly over.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…er 35s

dashj's BlockchainService idle-stops tore down the SDK's SPV every few
minutes; each restart left it with stale quorum state, and a live
shielded transfer right after a restart could not verify its asset
lock's InstantSend lock — it waited a full block (~3 min). Debug builds
now keep both SDK engines running across routine service teardowns
(deliberate battery trade-off for testing). Destructive paths are NOT
weakened — the wipe previously relied on shutdown() for the engine
stops, so it now calls the new unconditional stopSdkEngines() explicitly
before finalizeWipe() on every build type, and the shadow recovery
paths already stop the SPV directly.

Also: the transfer stall banner fires at 35s (was 90s) per live QA.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…elded flow + auth order

Username tile (More screen): show the user's display-form name (was the
DPNS-normalized homoglyph label, e.g. 'c0ntested1' for 'contested1') and
guard the voting-end date against unset/epoch timestamps (was 'Dec 31,
1969'); root cause was the restore worker persisting the normalized label
and a zero votingStartedAt. Tapping the requested-username tile now opens
the voting-request details screen instead of dismissing the tile.

Username confirm sheet: show the real cost from whichever pool pays —
the shielded denomination (0.3 contested / 0.1 non-contested) with a
'from shielded balance' label — instead of a misleading 0.00 on the dual
flow's final confirm.

Identity creation feedback: the 'network catching up' status hint now
also renders as a live secondary line inside the processing dialog the
user watches (previously only on the home tile), so a long registration
is explained before the auto-lock can fire.

Invite flow: new shielded-funding decision sheet (mirrors the username
shielded flow — privacy messaging + contested/non-contested cost from the
shared denomination source + shield-first vs continue-without-privacy),
shown only when shielded features are active. Invite auth moved to the
standard order: the fee screen no longer prompts for PIN before showing
the amount; authentication happens on the confirm screen right before the
spend.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…egression)

The prior change showed the shielded denomination on the instant/secondary
username confirm in a fresh dual creation. That was wrong: the instant name
adds no incremental cost — the identity funding (0.3 shielded / L1 asset
lock) is the same with or without it and is disclosed on the PRIMARY
contested confirm. Showing a price on the instant confirm contradicted
'instant username at no cost' (and the store behavior). Secondary now always
resolves to 0.00; the shielded/L1 cost display stays on the primary confirm.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t the exit denomination

The sheet asks how much to shield, which is the fund-minimum
(SHIELDED_USERNAME_FUND_MIN 0.15 / _CONTESTED 0.35 — the 0.1/0.3 Type-20
exit denomination padded for the shielded-spend fee), not the bare
denomination (0.1/0.3) that finally leaves the pool.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…icker, entry auth

1) Dismissing a terminal shielded-transfer outcome entered via
   'Shield your funds first' unwound the create-username/invite back
   stack one screen at a time; shield-first entries now clear straight
   to home (card entries keep the plain finish).
2) The More screen showed the CONTESTED name under the avatar right
   after a dual creation (profile seeded with the primary; refresh
   persists the owned instant name) — the under-avatar name now derives
   from the identity's active username when the dual-voting rule holds.
3) Tapping the requested-username tile flashed and bounced: the XML
   navGraph eagerly instantiated the request fragment (whose identity
   observer finishes the activity for a name in voting) before the code
   set the resolved start destination — graph now set only in code.
4) Opening the shielded transfer screen prompted for auth: createIntent
   now carries KEEP_UNLOCKED (SendCoinsActivity precedent); auth remains
   solely on transfer submit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d variant

profileDisplayUsername preferred the identity's activeUsername, which is
the DPNS-normalized secondary label (homoglyphs folded: 'c0ntested11-2').
Once the profile refreshes, profileUsername holds that name's display
label ('contested11-2'); prefer it when its normalized form matches the
active label. The normalized value now shows only in the brief first
render before the profile refresh, instead of persistently.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ool gate

The 'shielded pool still syncing' pre-broadcast refusal (nothing spent)
surfaced as a red 'network error' dialog. Two fixes:
- Fix A: the pool-not-ready reasons are now classified (typed constants +
  isPoolNotReadyReason) and shown as a calm 'Your shielded balance is
  still syncing, please wait and try again' dialog, not the error dialog.
- Fix B: the Request button follows the LIVE shielded sync status — while
  the pool is not READY on the shielded path it shows a disabled
  'Preparing shielded balance…' and re-enables when ready, instead of
  accepting the tap from a stale cache and failing at the SDK. The L1
  path is never gated on shielded sync status.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The L1/non-shielded submit set usernameRequestSubmitting=true and handed
off to CreateIdentityService, which runs out-of-band and never reported
back — so the processing dialog stayed up until the user dismissed it
manually, even though the identity was already created behind it (the
earlier finish-gating fix turned the old screen-finish dismissal into a
deadlock for this path). The ViewModel now observes the persisted
identity creation state and clears submitting (dismissing the dialog and
completing the flow) once it reaches a terminal state (DONE /
DONE_AND_DISMISS / VOTING) while a submit is in flight. The shielded path
already clears submitting via its executor states — no-op there; a
pre-existing DONE with no submit in flight is ignored.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bfoss765 added a commit to bfoss765/platform that referenced this pull request Jul 16, 2026
… on base's upstreamed router fix (dashpay#4074)

Rebase of PR dashpay#4074 (fix/kotlin-sdk-assetlock-multi-account) onto
feat/kotlin-sdk-and-example-app. The platform-wallet asset-lock changes are
preserved; the PR's OWN rust-dashcore customization is dropped because the
base branch now carries the same fix upstream.

What this brings to the asset-lock code path (packages/rs-platform-wallet):
- Multi-account funding builder `build_asset_lock_tx_from_all_funding_accounts`
  that unions spendable UTXOs across BIP44 + CoinJoin + DashPay funds accounts
  (dashpay#4073), with LargestFirst coin selection pinned for the
  many-small-denomination CoinJoin shape.
- Exclusion of watch-only `DashpayExternalAccount` UTXOs from the union — those
  are a contact's coins the local mnemonic can't sign; selecting one yields an
  invalid input signature. The receiving (ours) DashPay account stays included.
- `NoUtxosAvailable` mapped to the typed asset-lock insufficient-funds error.
- Regression tests covering the router-fix persistence path (CoinJoin +
  DashpayReceivingFunds legs) and the watch-only exclusion, plus split-funded
  test fixtures (`split_funded_wallet_manager`, `..._dashpay`,
  `..._many_coinjoin`).

Why the PR's rust-dashcore vendoring/[patch] is DROPPED:
The PR originally shipped the asset-lock transaction-router fix by pinning
rust-dashcore at 1860089e and redirecting it via a `[patch]` to a bfoss765
fork (rev e8c7335 = 1860089e + the router fix + a CoinJoin gap-limit 30->100
bump). The base branch's rust-dashcore rev 19690d31 now contains BOTH fixes
upstream:
  * `TransactionRouter::get_relevant_account_types(AssetLock)` includes
    CoinJoin, DashpayReceivingFunds, and DashpayExternalAccount (via
    `fund_bearing_account_types()`);
  * `DEFAULT_COINJOIN_GAP_LIMIT = 100`.
So the fork [patch], the pinned 1860089e rev, and the leftover
`third_party/rust-dashcore` are all obsolete and removed. Cargo.toml/Cargo.lock
are taken as-is from base (rust-dashcore resolves from dashpay @ 19690d31, no
patch table). Because base's fix debits CoinJoin/DashPay asset-lock spends via
the normal `check_core_transaction` scan, the PR's earlier broadcast-time
`debit_router_omitted_asset_lock_spends` mitigation is gone — as it already was
in the PR's final state (dashpay/dash-wallet#1507).

History note: the PR's 10 original commits touched the same four files the base
branch had independently rewritten (+928 lines), and included add-then-remove
churn (the interim mitigation) plus vendor-then-git-patch churn that base's
upstreamed fix makes moot. They are collapsed into this single commit to keep
the rebased history coherent. Verified: `cargo check -p platform-wallet
--all-targets`, `-p rs-unified-sdk-jni`, `-p platform-wallet-ffi` all green;
`cargo test -p platform-wallet --lib` = 502 passed / 0 failed, including the
router-fix and watch-only-exclusion regression tests, against base's 19690d31.

Original commits folded in: 9be2e14, 5376235, e1593f4, da97eec
(app-code only; vendoring dropped), ce482fd (app-code only; vendored
gap-limit dropped), 380645a, b43caed (dropped: pure [patch] plumbing),
a5ea9e5, 77561d2, 189e068.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bfoss765 added a commit to bfoss765/platform that referenced this pull request Jul 16, 2026
…BIP70 deferred submission

BIP70/BIP270 (CTX/DashSpend) sends must sign, POST the raw bytes to a
merchant server, and broadcast only on ack — structurally impossible on the
one-shot `sendToAddresses`. Expose the existing internal build/broadcast split
with an explicit reservation lifecycle, keeping `CoreTransactionBuilder`
internal so the manager stays the sole driver of the setFunding/buildSigned
race.

Rust core (rs-platform-wallet):
- New `SignedPaymentRegistry`: a generic, in-memory registry that owns a
  built+signed tx and its held UTXO reservation between build and submission,
  keyed by an opaque `ReservationToken`. `broadcast` removes the entry before
  sending (no double-broadcast — a repeat/concurrent call gets `StaleToken`),
  binds each token to its originating wallet instance (`Arc::ptr_eq` on the
  shared `WalletManager`, so a re-created wallet is rejected), and reconciles
  the reservation on failure via the existing release-on-rejection path.
  `release` is idempotent. Reservations are memory-only, so a crash between
  build and broadcast drops both the entry and the reservation on restart —
  the same property dashj has.
- `CoreWallet::release_transaction_reservation` — the explicit "abandoned /
  nacked" release arm.

FFI (platform-wallet-ffi) — additive C ABI:
- `core_wallet_transaction_get_bytes`, `core_wallet_signed_payment_register`
  (token + fee + txid), `core_wallet_signed_payment_broadcast`,
  `core_wallet_signed_payment_release`, backed by one process-global registry
  pinned to `SpvBroadcaster`.
- New `ErrorStaleReservationToken` (22) result code.

JNI (rs-unified-sdk-jni) — additive: `coreTransactionGetBytes`,
`coreWalletRegisterSignedPayment` (BLOB), `coreWalletBroadcastSignedPayment`,
`coreWalletReleaseSignedPayment`.

Kotlin — additive: `ManagedPlatformWallet.SignedCoreTransaction`,
`buildSignedPayment` (build under coreSendMutex), `broadcastSigned(token)`,
`releaseReservation(token)`; `DashSdkError.PlatformWallet.StaleReservationToken`.
No existing signatures change.

Refs dashpay#4089, dashpay/dash-wallet#1507 Phase 5c GAP-4.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bfoss765

Copy link
Copy Markdown
Contributor Author

Superseded by the reviewable stack: #1512 (CoinJoin removal) + #1515 (Kotlin SDK migration slice, tree-identical to this PR's final state). Closing to keep the review surface on those; branch retained.

@bfoss765 bfoss765 closed this Jul 17, 2026
bfoss765 added a commit to bfoss765/platform that referenced this pull request Jul 23, 2026
… on base's upstreamed router fix (dashpay#4074)

Rebase of PR dashpay#4074 (fix/kotlin-sdk-assetlock-multi-account) onto
feat/kotlin-sdk-and-example-app. The platform-wallet asset-lock changes are
preserved; the PR's OWN rust-dashcore customization is dropped because the
base branch now carries the same fix upstream.

What this brings to the asset-lock code path (packages/rs-platform-wallet):
- Multi-account funding builder `build_asset_lock_tx_from_all_funding_accounts`
  that unions spendable UTXOs across BIP44 + CoinJoin + DashPay funds accounts
  (dashpay#4073), with LargestFirst coin selection pinned for the
  many-small-denomination CoinJoin shape.
- Exclusion of watch-only `DashpayExternalAccount` UTXOs from the union — those
  are a contact's coins the local mnemonic can't sign; selecting one yields an
  invalid input signature. The receiving (ours) DashPay account stays included.
- `NoUtxosAvailable` mapped to the typed asset-lock insufficient-funds error.
- Regression tests covering the router-fix persistence path (CoinJoin +
  DashpayReceivingFunds legs) and the watch-only exclusion, plus split-funded
  test fixtures (`split_funded_wallet_manager`, `..._dashpay`,
  `..._many_coinjoin`).

Why the PR's rust-dashcore vendoring/[patch] is DROPPED:
The PR originally shipped the asset-lock transaction-router fix by pinning
rust-dashcore at 1860089e and redirecting it via a `[patch]` to a bfoss765
fork (rev e8c7335 = 1860089e + the router fix + a CoinJoin gap-limit 30->100
bump). The base branch's rust-dashcore rev 19690d31 now contains BOTH fixes
upstream:
  * `TransactionRouter::get_relevant_account_types(AssetLock)` includes
    CoinJoin, DashpayReceivingFunds, and DashpayExternalAccount (via
    `fund_bearing_account_types()`);
  * `DEFAULT_COINJOIN_GAP_LIMIT = 100`.
So the fork [patch], the pinned 1860089e rev, and the leftover
`third_party/rust-dashcore` are all obsolete and removed. Cargo.toml/Cargo.lock
are taken as-is from base (rust-dashcore resolves from dashpay @ 19690d31, no
patch table). Because base's fix debits CoinJoin/DashPay asset-lock spends via
the normal `check_core_transaction` scan, the PR's earlier broadcast-time
`debit_router_omitted_asset_lock_spends` mitigation is gone — as it already was
in the PR's final state (dashpay/dash-wallet#1507).

History note: the PR's 10 original commits touched the same four files the base
branch had independently rewritten (+928 lines), and included add-then-remove
churn (the interim mitigation) plus vendor-then-git-patch churn that base's
upstreamed fix makes moot. They are collapsed into this single commit to keep
the rebased history coherent. Verified: `cargo check -p platform-wallet
--all-targets`, `-p rs-unified-sdk-jni`, `-p platform-wallet-ffi` all green;
`cargo test -p platform-wallet --lib` = 502 passed / 0 failed, including the
router-fix and watch-only-exclusion regression tests, against base's 19690d31.

Original commits folded in: 9be2e14, 5376235, e1593f4, da97eec
(app-code only; vendoring dropped), ce482fd (app-code only; vendored
gap-limit dropped), 380645a, b43caed (dropped: pure [patch] plumbing),
a5ea9e5, 77561d2, 189e068.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bfoss765 added a commit to bfoss765/platform that referenced this pull request Jul 23, 2026
…BIP70 deferred submission

BIP70/BIP270 (CTX/DashSpend) sends must sign, POST the raw bytes to a
merchant server, and broadcast only on ack — structurally impossible on the
one-shot `sendToAddresses`. Expose the existing internal build/broadcast split
with an explicit reservation lifecycle, keeping `CoreTransactionBuilder`
internal so the manager stays the sole driver of the setFunding/buildSigned
race.

Rust core (rs-platform-wallet):
- New `SignedPaymentRegistry`: a generic, in-memory registry that owns a
  built+signed tx and its held UTXO reservation between build and submission,
  keyed by an opaque `ReservationToken`. `broadcast` removes the entry before
  sending (no double-broadcast — a repeat/concurrent call gets `StaleToken`),
  binds each token to its originating wallet instance (`Arc::ptr_eq` on the
  shared `WalletManager`, so a re-created wallet is rejected), and reconciles
  the reservation on failure via the existing release-on-rejection path.
  `release` is idempotent. Reservations are memory-only, so a crash between
  build and broadcast drops both the entry and the reservation on restart —
  the same property dashj has.
- `CoreWallet::release_transaction_reservation` — the explicit "abandoned /
  nacked" release arm.

FFI (platform-wallet-ffi) — additive C ABI:
- `core_wallet_transaction_get_bytes`, `core_wallet_signed_payment_register`
  (token + fee + txid), `core_wallet_signed_payment_broadcast`,
  `core_wallet_signed_payment_release`, backed by one process-global registry
  pinned to `SpvBroadcaster`.
- New `ErrorStaleReservationToken` (22) result code.

JNI (rs-unified-sdk-jni) — additive: `coreTransactionGetBytes`,
`coreWalletRegisterSignedPayment` (BLOB), `coreWalletBroadcastSignedPayment`,
`coreWalletReleaseSignedPayment`.

Kotlin — additive: `ManagedPlatformWallet.SignedCoreTransaction`,
`buildSignedPayment` (build under coreSendMutex), `broadcastSigned(token)`,
`releaseReservation(token)`; `DashSdkError.PlatformWallet.StaleReservationToken`.
No existing signatures change.

Refs dashpay#4089, dashpay/dash-wallet#1507 Phase 5c GAP-4.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bfoss765
bfoss765 deleted the claude/blissful-cannon-7d4ac4 branch August 2, 2026 21:26
bfoss765 added a commit to bfoss765/platform that referenced this pull request Aug 3, 2026
… on base's upstreamed router fix (dashpay#4074)

Rebase of PR dashpay#4074 (fix/kotlin-sdk-assetlock-multi-account) onto
feat/kotlin-sdk-and-example-app. The platform-wallet asset-lock changes are
preserved; the PR's OWN rust-dashcore customization is dropped because the
base branch now carries the same fix upstream.

What this brings to the asset-lock code path (packages/rs-platform-wallet):
- Multi-account funding builder `build_asset_lock_tx_from_all_funding_accounts`
  that unions spendable UTXOs across BIP44 + CoinJoin + DashPay funds accounts
  (dashpay#4073), with LargestFirst coin selection pinned for the
  many-small-denomination CoinJoin shape.
- Exclusion of watch-only `DashpayExternalAccount` UTXOs from the union — those
  are a contact's coins the local mnemonic can't sign; selecting one yields an
  invalid input signature. The receiving (ours) DashPay account stays included.
- `NoUtxosAvailable` mapped to the typed asset-lock insufficient-funds error.
- Regression tests covering the router-fix persistence path (CoinJoin +
  DashpayReceivingFunds legs) and the watch-only exclusion, plus split-funded
  test fixtures (`split_funded_wallet_manager`, `..._dashpay`,
  `..._many_coinjoin`).

Why the PR's rust-dashcore vendoring/[patch] is DROPPED:
The PR originally shipped the asset-lock transaction-router fix by pinning
rust-dashcore at 1860089e and redirecting it via a `[patch]` to a bfoss765
fork (rev e8c7335 = 1860089e + the router fix + a CoinJoin gap-limit 30->100
bump). The base branch's rust-dashcore rev 19690d31 now contains BOTH fixes
upstream:
  * `TransactionRouter::get_relevant_account_types(AssetLock)` includes
    CoinJoin, DashpayReceivingFunds, and DashpayExternalAccount (via
    `fund_bearing_account_types()`);
  * `DEFAULT_COINJOIN_GAP_LIMIT = 100`.
So the fork [patch], the pinned 1860089e rev, and the leftover
`third_party/rust-dashcore` are all obsolete and removed. Cargo.toml/Cargo.lock
are taken as-is from base (rust-dashcore resolves from dashpay @ 19690d31, no
patch table). Because base's fix debits CoinJoin/DashPay asset-lock spends via
the normal `check_core_transaction` scan, the PR's earlier broadcast-time
`debit_router_omitted_asset_lock_spends` mitigation is gone — as it already was
in the PR's final state (dashpay/dash-wallet#1507).

History note: the PR's 10 original commits touched the same four files the base
branch had independently rewritten (+928 lines), and included add-then-remove
churn (the interim mitigation) plus vendor-then-git-patch churn that base's
upstreamed fix makes moot. They are collapsed into this single commit to keep
the rebased history coherent. Verified: `cargo check -p platform-wallet
--all-targets`, `-p rs-unified-sdk-jni`, `-p platform-wallet-ffi` all green;
`cargo test -p platform-wallet --lib` = 502 passed / 0 failed, including the
router-fix and watch-only-exclusion regression tests, against base's 19690d31.

Original commits folded in: 9be2e14, 5376235, e1593f4, da97eec
(app-code only; vendoring dropped), ce482fd (app-code only; vendored
gap-limit dropped), 380645a, b43caed (dropped: pure [patch] plumbing),
a5ea9e5, 77561d2, 189e068.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bfoss765 added a commit to bfoss765/platform that referenced this pull request Aug 4, 2026
… on base's upstreamed router fix (dashpay#4074)

Rebase of PR dashpay#4074 (fix/kotlin-sdk-assetlock-multi-account) onto
feat/kotlin-sdk-and-example-app. The platform-wallet asset-lock changes are
preserved; the PR's OWN rust-dashcore customization is dropped because the
base branch now carries the same fix upstream.

What this brings to the asset-lock code path (packages/rs-platform-wallet):
- Multi-account funding builder `build_asset_lock_tx_from_all_funding_accounts`
  that unions spendable UTXOs across BIP44 + CoinJoin + DashPay funds accounts
  (dashpay#4073), with LargestFirst coin selection pinned for the
  many-small-denomination CoinJoin shape.
- Exclusion of watch-only `DashpayExternalAccount` UTXOs from the union — those
  are a contact's coins the local mnemonic can't sign; selecting one yields an
  invalid input signature. The receiving (ours) DashPay account stays included.
- `NoUtxosAvailable` mapped to the typed asset-lock insufficient-funds error.
- Regression tests covering the router-fix persistence path (CoinJoin +
  DashpayReceivingFunds legs) and the watch-only exclusion, plus split-funded
  test fixtures (`split_funded_wallet_manager`, `..._dashpay`,
  `..._many_coinjoin`).

Why the PR's rust-dashcore vendoring/[patch] is DROPPED:
The PR originally shipped the asset-lock transaction-router fix by pinning
rust-dashcore at 1860089e and redirecting it via a `[patch]` to a bfoss765
fork (rev e8c7335 = 1860089e + the router fix + a CoinJoin gap-limit 30->100
bump). The base branch's rust-dashcore rev 19690d31 now contains BOTH fixes
upstream:
  * `TransactionRouter::get_relevant_account_types(AssetLock)` includes
    CoinJoin, DashpayReceivingFunds, and DashpayExternalAccount (via
    `fund_bearing_account_types()`);
  * `DEFAULT_COINJOIN_GAP_LIMIT = 100`.
So the fork [patch], the pinned 1860089e rev, and the leftover
`third_party/rust-dashcore` are all obsolete and removed. Cargo.toml/Cargo.lock
are taken as-is from base (rust-dashcore resolves from dashpay @ 19690d31, no
patch table). Because base's fix debits CoinJoin/DashPay asset-lock spends via
the normal `check_core_transaction` scan, the PR's earlier broadcast-time
`debit_router_omitted_asset_lock_spends` mitigation is gone — as it already was
in the PR's final state (dashpay/dash-wallet#1507).

History note: the PR's 10 original commits touched the same four files the base
branch had independently rewritten (+928 lines), and included add-then-remove
churn (the interim mitigation) plus vendor-then-git-patch churn that base's
upstreamed fix makes moot. They are collapsed into this single commit to keep
the rebased history coherent. Verified: `cargo check -p platform-wallet
--all-targets`, `-p rs-unified-sdk-jni`, `-p platform-wallet-ffi` all green;
`cargo test -p platform-wallet --lib` = 502 passed / 0 failed, including the
router-fix and watch-only-exclusion regression tests, against base's 19690d31.

Original commits folded in: 9be2e14, 5376235, e1593f4, da97eec
(app-code only; vendoring dropped), ce482fd (app-code only; vendored
gap-limit dropped), 380645a, b43caed (dropped: pure [patch] plumbing),
a5ea9e5, 77561d2, 189e068.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bfoss765 added a commit to bfoss765/platform that referenced this pull request Aug 4, 2026
…BIP70 deferred submission

BIP70/BIP270 (CTX/DashSpend) sends must sign, POST the raw bytes to a
merchant server, and broadcast only on ack — structurally impossible on the
one-shot `sendToAddresses`. Expose the existing internal build/broadcast split
with an explicit reservation lifecycle, keeping `CoreTransactionBuilder`
internal so the manager stays the sole driver of the setFunding/buildSigned
race.

Rust core (rs-platform-wallet):
- New `SignedPaymentRegistry`: a generic, in-memory registry that owns a
  built+signed tx and its held UTXO reservation between build and submission,
  keyed by an opaque `ReservationToken`. `broadcast` removes the entry before
  sending (no double-broadcast — a repeat/concurrent call gets `StaleToken`),
  binds each token to its originating wallet instance (`Arc::ptr_eq` on the
  shared `WalletManager`, so a re-created wallet is rejected), and reconciles
  the reservation on failure via the existing release-on-rejection path.
  `release` is idempotent. Reservations are memory-only, so a crash between
  build and broadcast drops both the entry and the reservation on restart —
  the same property dashj has.
- `CoreWallet::release_transaction_reservation` — the explicit "abandoned /
  nacked" release arm.

FFI (platform-wallet-ffi) — additive C ABI:
- `core_wallet_transaction_get_bytes`, `core_wallet_signed_payment_register`
  (token + fee + txid), `core_wallet_signed_payment_broadcast`,
  `core_wallet_signed_payment_release`, backed by one process-global registry
  pinned to `SpvBroadcaster`.
- New `ErrorStaleReservationToken` (22) result code.

JNI (rs-unified-sdk-jni) — additive: `coreTransactionGetBytes`,
`coreWalletRegisterSignedPayment` (BLOB), `coreWalletBroadcastSignedPayment`,
`coreWalletReleaseSignedPayment`.

Kotlin — additive: `ManagedPlatformWallet.SignedCoreTransaction`,
`buildSignedPayment` (build under coreSendMutex), `broadcastSigned(token)`,
`releaseReservation(token)`; `DashSdkError.PlatformWallet.StaleReservationToken`.
No existing signatures change.

Refs dashpay#4089, dashpay/dash-wallet#1507 Phase 5c GAP-4.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bfoss765 added a commit to bfoss765/platform that referenced this pull request Aug 5, 2026
…BIP70 deferred submission

BIP70/BIP270 (CTX/DashSpend) sends must sign, POST the raw bytes to a
merchant server, and broadcast only on ack — structurally impossible on the
one-shot `sendToAddresses`. Expose the existing internal build/broadcast split
with an explicit reservation lifecycle, keeping `CoreTransactionBuilder`
internal so the manager stays the sole driver of the setFunding/buildSigned
race.

Rust core (rs-platform-wallet):
- New `SignedPaymentRegistry`: a generic, in-memory registry that owns a
  built+signed tx and its held UTXO reservation between build and submission,
  keyed by an opaque `ReservationToken`. `broadcast` removes the entry before
  sending (no double-broadcast — a repeat/concurrent call gets `StaleToken`),
  binds each token to its originating wallet instance (`Arc::ptr_eq` on the
  shared `WalletManager`, so a re-created wallet is rejected), and reconciles
  the reservation on failure via the existing release-on-rejection path.
  `release` is idempotent. Reservations are memory-only, so a crash between
  build and broadcast drops both the entry and the reservation on restart —
  the same property dashj has.
- `CoreWallet::release_transaction_reservation` — the explicit "abandoned /
  nacked" release arm.

FFI (platform-wallet-ffi) — additive C ABI:
- `core_wallet_transaction_get_bytes`, `core_wallet_signed_payment_register`
  (token + fee + txid), `core_wallet_signed_payment_broadcast`,
  `core_wallet_signed_payment_release`, backed by one process-global registry
  pinned to `SpvBroadcaster`.
- New `ErrorStaleReservationToken` (22) result code.

JNI (rs-unified-sdk-jni) — additive: `coreTransactionGetBytes`,
`coreWalletRegisterSignedPayment` (BLOB), `coreWalletBroadcastSignedPayment`,
`coreWalletReleaseSignedPayment`.

Kotlin — additive: `ManagedPlatformWallet.SignedCoreTransaction`,
`buildSignedPayment` (build under coreSendMutex), `broadcastSigned(token)`,
`releaseReservation(token)`; `DashSdkError.PlatformWallet.StaleReservationToken`.
No existing signatures change.

Refs dashpay#4089, dashpay/dash-wallet#1507 Phase 5c GAP-4.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant