Context
The SDK cutover routes simple L1 sends through the SDK post-cutover (SdkL1SendService + CoreSendAllNative, bridged back via SdkBridgedTransactionFactory). Everything else in the send funnel currently fails closed — SendCoinsTaskRunner.cutoverSendRoute (wallet/src/de/schildbach/wallet/payments/SendCoinsTaskRunner.kt:123-139,898-923) throws IllegalStateException once the dashj peergroup is held, because the tx would be dashj-built and cannot be broadcast.
Phase 1A (core L1/L2 sync + username/invite creation) completes when invites work. The items below are the remaining Phase-1 functions that still build dashj transactions or use dashj-only signing; each needs an SDK-routed equivalent (or an explicit decision to keep it dashj-backed and gate it out of cutover). Split into Phase 1B for hand-off.
Source of the file:line references: the 6-domain dashj-dependency audit of build-11105.
1. BIP70 / BIP270 direct payment
- Where:
SendCoinsTaskRunner.kt:640-788 (PaymentProtocol.createPaymentMessage, wallet.completeTx, tx.unsafeBitcoinSerialize(), wallet.freshAddress(REFUND), maybeCommitTx), UI in ui/send/PaymentProtocolFragment.kt / PaymentProtocolViewModel.kt.
- Now: fails closed post-cutover.
- To do: SDK path to build + sign + broadcast a payment-request tx (single/multi output), produce the serialized tx + refund address for the BIP70
Payment message, and commit the returned tx via SdkBridgedTransactionFactory.
2. Custom coin-selection sends
- Where:
transactions/DashjSelectors.kt (ByAddressCoinSelector, ExactOutputsSelector), payments/MaxOutputAmountCoinSelector.kt, payments/ChainLockedCoinSelector.kt. Routed to fail-closed at SendCoinsTaskRunner.kt:183,527-535.
- Now: SDK exposes only
SelectionStrategy (all / max) — no equivalent for "spend only these inputs / addresses".
- To do: SDK API to send with a constrained input set (by-address, exact-outputs, chainlock-only) OR reimplement these selectors over SDK-reported UTXOs and hand the chosen inputs to the SDK builder.
3. Asset-lock sends from the send UI
- Where:
ui/send/SendCoinsViewModel.kt:283-335 (signAndSendAssetLock) + SendCoinsTaskRunner.kt:807-841 (createAssetLockSendRequest, SendRequest.assetLock, AssetLockTransaction.assetLockPayload.creditOutputs).
- Now: OP_RETURN credit output →
extractSdkRoutablePayment returns null → fails closed. (Note: identity funding asset-locks ARE SDK-routed via SdkTransparentUsernameCreation/SdkTransparentTopUp; this is the standalone send-UI asset-lock path that is not.)
- To do: route the send-UI asset-lock through the SDK asset-lock builder, or converge it with the existing SDK funding path.
4. Maya (DEX swap send)
- Where:
wallet/src/de/schildbach/wallet/payments/MayaBlockchainApiImpl.kt:20-27,91-139 — builds the Dash swap tx with dashj SendRequest (Asgard vault output + ScriptBuilder.createOpReturnScript memo, controlled change ordering). The integrations/maya module itself is dashj-free; this wallet-side bridge is the coupling.
- Now: OP_RETURN memo output → not SDK-routable → fails closed post-cutover.
- To do: SDK path to send a tx with an arbitrary OP_RETURN memo output and deterministic output ordering.
5. CrowdNode (deposit / withdraw send + message signing)
- Where: locked-output sends —
SendCoinsTaskRunner.kt:544-563 (lockOutputsPayingTo / canSendLockedOutput); address message signing — security/SecurityFunctions.kt:152-158 (wallet.findKeyFromAddress(...).signMessage), consumed by integrations/crowdnode/.../CrowdNodeWebApi.kt:120,137.
- Now: the SDK has no UTXO-lock/exclusion API, and the SDK drain is even blocked while any app-locked output exists;
signMessage is dashj-only.
- To do: (a) SDK UTXO exclusion/lock so CrowdNode account outputs can be preserved across sends; (b) SDK address message signing to replace
SecurityFunctions.signMessage.
6. SwapKit
- Where: DEX sell-swap tracking (SwapKit
/track) — an 11.9.0 feature. Not present in the cutover build (branch is on the 11.8.2 baseline; see the 11.9.0-merge prerequisite).
- Now: not in build; its swap send would go through the Maya/asset-lock send funnel (items 3–4 above).
- To do: depends on the 11.9.0 merge landing first; then verify the SwapKit swap-send routes through whatever item 3/4 produce.
Acceptance for Phase 1B: each function above either (a) sends/signs through the SDK post-cutover and is verified on testnet with a committed cutover, or (b) has an explicit, documented decision to remain dashj-backed with the feature gated accordingly. Prerequisite for items 3/4/6: the 11.9.0 merge into the cutover branch.
Context
The SDK cutover routes simple L1 sends through the SDK post-cutover (
SdkL1SendService+CoreSendAllNative, bridged back viaSdkBridgedTransactionFactory). Everything else in the send funnel currently fails closed —SendCoinsTaskRunner.cutoverSendRoute(wallet/src/de/schildbach/wallet/payments/SendCoinsTaskRunner.kt:123-139,898-923) throwsIllegalStateExceptiononce the dashj peergroup is held, because the tx would be dashj-built and cannot be broadcast.Phase 1A (core L1/L2 sync + username/invite creation) completes when invites work. The items below are the remaining Phase-1 functions that still build dashj transactions or use dashj-only signing; each needs an SDK-routed equivalent (or an explicit decision to keep it dashj-backed and gate it out of cutover). Split into Phase 1B for hand-off.
Source of the file:line references: the 6-domain dashj-dependency audit of
build-11105.1. BIP70 / BIP270 direct payment
SendCoinsTaskRunner.kt:640-788(PaymentProtocol.createPaymentMessage,wallet.completeTx,tx.unsafeBitcoinSerialize(),wallet.freshAddress(REFUND),maybeCommitTx), UI inui/send/PaymentProtocolFragment.kt/PaymentProtocolViewModel.kt.Paymentmessage, and commit the returned tx viaSdkBridgedTransactionFactory.2. Custom coin-selection sends
transactions/DashjSelectors.kt(ByAddressCoinSelector,ExactOutputsSelector),payments/MaxOutputAmountCoinSelector.kt,payments/ChainLockedCoinSelector.kt. Routed to fail-closed atSendCoinsTaskRunner.kt:183,527-535.SelectionStrategy(all / max) — no equivalent for "spend only these inputs / addresses".3. Asset-lock sends from the send UI
ui/send/SendCoinsViewModel.kt:283-335(signAndSendAssetLock) +SendCoinsTaskRunner.kt:807-841(createAssetLockSendRequest,SendRequest.assetLock,AssetLockTransaction.assetLockPayload.creditOutputs).extractSdkRoutablePaymentreturns null → fails closed. (Note: identity funding asset-locks ARE SDK-routed viaSdkTransparentUsernameCreation/SdkTransparentTopUp; this is the standalone send-UI asset-lock path that is not.)4. Maya (DEX swap send)
wallet/src/de/schildbach/wallet/payments/MayaBlockchainApiImpl.kt:20-27,91-139— builds the Dash swap tx with dashjSendRequest(Asgard vault output +ScriptBuilder.createOpReturnScriptmemo, controlled change ordering). Theintegrations/mayamodule itself is dashj-free; this wallet-side bridge is the coupling.5. CrowdNode (deposit / withdraw send + message signing)
SendCoinsTaskRunner.kt:544-563(lockOutputsPayingTo/canSendLockedOutput); address message signing —security/SecurityFunctions.kt:152-158(wallet.findKeyFromAddress(...).signMessage), consumed byintegrations/crowdnode/.../CrowdNodeWebApi.kt:120,137.signMessageis dashj-only.SecurityFunctions.signMessage.6. SwapKit
/track) — an 11.9.0 feature. Not present in the cutover build (branch is on the 11.8.2 baseline; see the 11.9.0-merge prerequisite).Acceptance for Phase 1B: each function above either (a) sends/signs through the SDK post-cutover and is verified on testnet with a committed cutover, or (b) has an explicit, documented decision to remain dashj-backed with the feature gated accordingly. Prerequisite for items 3/4/6: the 11.9.0 merge into the cutover branch.