Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
8ba3d1c
feat(kotlin-sdk): split build/broadcast with reservation release for …
bfoss765 Jul 10, 2026
a037032
fix(kotlin-sdk): bound deferred-payment token lifetime; harden regist…
bfoss765 Jul 11, 2026
9f76e09
fix(kotlin-sdk): resolve rebase semantic conflicts onto feat/kotlin-s…
bfoss765 Jul 16, 2026
3979580
fix(kotlin-sdk): assert native code 26 for the stale-reservation-toke…
bfoss765 Jul 17, 2026
f037e6a
fix(kotlin-sdk): bound the deferred-payment token on the reservation'…
bfoss765 Jul 17, 2026
41e5808
fix(kotlin-sdk): sweep deferred-payment tokens only when the final wa…
bfoss765 Jul 17, 2026
6d82586
fix(kotlin-sdk): route deferred builds through the atomic finalize-an…
bfoss765 Jul 17, 2026
8d6fd74
fix(kotlin-sdk): delete the dead split register→broadcast chain
bfoss765 Jul 21, 2026
0479e33
fix(kotlin-sdk): baseline the deferred token age on the pre-signing r…
bfoss765 Jul 21, 2026
76a5acc
fix(kotlin-sdk): give the V2 handle and token paths one wallet-genera…
bfoss765 Jul 21, 2026
01a3674
fix(kotlin-sdk): validate the deferred token under the lock, consume …
bfoss765 Jul 21, 2026
b18305f
fix(kotlin-sdk): release deferred reservations at final-alias destroy…
bfoss765 Jul 21, 2026
90470aa
fix(kotlin-sdk): split the conflated deferred-token error code into t…
bfoss765 Jul 21, 2026
96238ab
docs(kotlin-sdk): correct buildSignedPayment KDoc to the finalize-and…
bfoss765 Jul 21, 2026
49227c1
fix(kotlin-sdk): make the deferred payment token an owning AutoClosea…
bfoss765 Jul 21, 2026
1b8ecb8
style(kotlin-sdk): rustfmt wallet_manager.rs after the dead-chain del…
bfoss765 Jul 21, 2026
007205b
fix(kotlin-sdk): object-owning broadcast/release overloads for Signed…
bfoss765 Jul 21, 2026
461d343
fix(kotlin-sdk): retain a releasable account handle for CoinJoin-fund…
bfoss765 Jul 22, 2026
c19a7e2
fix(kotlin-sdk): bind deferred-payment reservation cleanup to its own…
bfoss765 Jul 22, 2026
91b4c16
fix(swift-sdk): surface deferred-token codes 26/27/28 as typed errors
bfoss765 Jul 22, 2026
6e08ad4
docs(kotlin-sdk): correct broadcast KDoc to the split deferred-token …
bfoss765 Jul 22, 2026
be33a6e
chore(rust-dashcore): re-pin to owner-tagged reservation API rev
bfoss765 Jul 23, 2026
8e56aa2
fix: renumber deferred-reservation error codes to 27/28/29
bfoss765 Jul 23, 2026
a9fa98c
fix(platform-wallet): owner-guard the broadcast-reject reservation re…
bfoss765 Jul 23, 2026
fe05f3a
fix(platform-wallet): enforce unique reservation ownership, stop wrap…
bfoss765 Jul 24, 2026
3622c9c
fix(platform-wallet): bind registration to correct wallet generation …
bfoss765 Jul 25, 2026
4311097
fix(platform-wallet): linearize wallet removal with deferred broadcas…
bfoss765 Aug 1, 2026
733472f
fix(platform-wallet-ffi)!: move ErrorReservationWalletMismatch 29 -> …
bfoss765 Aug 1, 2026
513f6fd
refactor(platform-wallet-ffi): drop stale HandleStorage::any left by …
bfoss765 Aug 1, 2026
18d8b14
fix(platform-wallet): scope the lifecycle gate to the wallet generati…
bfoss765 Aug 2, 2026
23880f0
fix(platform-wallet): remove the wallet generation by identity, not b…
bfoss765 Aug 2, 2026
326cd3e
fix(platform-wallet): move the deferred-token trio off the codes #426…
bfoss765 Aug 3, 2026
cd9e15b
fix(kotlin-sdk): stop the stray 98 arm from shadowing PlatformWallet.…
bfoss765 Aug 4, 2026
4feb341
feat(platform-wallet): union-funding build_signed_payment core primitive
bfoss765 Jul 13, 2026
c42c695
feat(sdk): plumb build_signed_payment through FFI, JNI, and Kotlin
bfoss765 Jul 13, 2026
51a31c5
fix(platform-wallet): re-scope build_signed_payment to single-account…
bfoss765 Jul 30, 2026
e9de7a7
feat(platform-wallet): expose account-level derivationPath in account…
bfoss765 Jul 31, 2026
501489c
fix(platform-wallet): dust + size bounds, typed build errors, and tes…
bfoss765 Jul 31, 2026
db7fe37
fix(platform-wallet): fail closed when no wallet-level account matche…
bfoss765 Jul 31, 2026
621884e
feat(kotlin-sdk): expose release_payment_reservation for abandoned bu…
bfoss765 Aug 1, 2026
e867780
docs(ffi): drop the redundant "later ... afterwards" in the send modu…
bfoss765 Aug 3, 2026
fe19e4f
fix(platform-wallet): adopt #4185's WalletGeneration in the send-path…
bfoss765 Aug 3, 2026
446e905
fix(swift-sdk): mirror ErrorTransactionBuild (32) into the Swift resu…
bfoss765 Aug 3, 2026
4e7d2b2
style(platform-wallet): rustfmt the restacked send-path test fixtures
bfoss765 Aug 3, 2026
3505571
fix(platform-wallet): owner-guard the raw-payment reservation release
bfoss765 Aug 4, 2026
bbe36ee
fix(kotlin-sdk): release a cancelled buildSignedPayment's reservation
bfoss765 Aug 4, 2026
684f06f
fix(kotlin-sdk): release reservation on JNI pack failure; harden defe…
bfoss765 Aug 4, 2026
8f9a932
style(ffi): rustfmt a pre-existing drift in the dashpay test module
bfoss765 Aug 4, 2026
8c906d8
fix(kotlin-sdk): release the minted token on the finalize null-txid path
bfoss765 Aug 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 23 additions & 23 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ members = [
]

[workspace.dependencies]
dashcore = { git = "https://github.com/dashpay/rust-dashcore", rev = "70d4bf8e36057c58e02d56769a6e9760f701dd06" }
dash-network-seeds = { git = "https://github.com/dashpay/rust-dashcore", rev = "70d4bf8e36057c58e02d56769a6e9760f701dd06" }
dash-spv = { git = "https://github.com/dashpay/rust-dashcore", rev = "70d4bf8e36057c58e02d56769a6e9760f701dd06" }
key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "70d4bf8e36057c58e02d56769a6e9760f701dd06" }
key-wallet-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "70d4bf8e36057c58e02d56769a6e9760f701dd06" }
key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "70d4bf8e36057c58e02d56769a6e9760f701dd06" }
dash-network = { git = "https://github.com/dashpay/rust-dashcore", rev = "70d4bf8e36057c58e02d56769a6e9760f701dd06" }
dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "70d4bf8e36057c58e02d56769a6e9760f701dd06" }
dashcore = { git = "https://github.com/bfoss765/rust-dashcore", rev = "e99959ced0062159d629930f488374e29f63c42b" }
dash-network-seeds = { git = "https://github.com/bfoss765/rust-dashcore", rev = "e99959ced0062159d629930f488374e29f63c42b" }
dash-spv = { git = "https://github.com/bfoss765/rust-dashcore", rev = "e99959ced0062159d629930f488374e29f63c42b" }
key-wallet = { git = "https://github.com/bfoss765/rust-dashcore", rev = "e99959ced0062159d629930f488374e29f63c42b" }
key-wallet-ffi = { git = "https://github.com/bfoss765/rust-dashcore", rev = "e99959ced0062159d629930f488374e29f63c42b" }
key-wallet-manager = { git = "https://github.com/bfoss765/rust-dashcore", rev = "e99959ced0062159d629930f488374e29f63c42b" }
dash-network = { git = "https://github.com/bfoss765/rust-dashcore", rev = "e99959ced0062159d629930f488374e29f63c42b" }
dashcore-rpc = { git = "https://github.com/bfoss765/rust-dashcore", rev = "e99959ced0062159d629930f488374e29f63c42b" }

tokio-metrics = "0.5"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,24 @@ sealed class DashSdkError(
class CoreInsufficientFunds(message: String, cause: Throwable? = null) :
PlatformWallet(message, cause)

/**
* `ErrorTransactionBuild` (native code 32). A Core transaction could
* not be assembled from the request. The REQUEST is at fault, so a
* verbatim retry fails identically — the caller must change it.
*
* It is what every non-shortfall `buildSignedPayment` rejection
* surfaces as: a `fundingPath` matching no spendable funds account or
* naming a watch-only one (the two failure modes the single-account
* send design rests on, dashpay/platform#4184), a request breaching a
* monetary bound (MAX_MONEY total, max fee rate, a below-dust
* recipient, an over-100 kB recipient list), or a malformed recipients
* blob. Before this code existed they all arrived as [Generic] with
* native code 99 and could only be told apart by string-matching the
* message. The specific cause is still in [message].
*/
class TransactionBuild(message: String, cause: Throwable? = null) :
PlatformWallet(message, cause)

class AssetLockNotTracked(message: String, cause: Throwable? = null) :
PlatformWallet(message, cause)

Expand Down Expand Up @@ -239,6 +257,67 @@ sealed class DashSdkError(
class NotFound(message: String, cause: Throwable? = null) :
PlatformWallet(message, cause)

/**
* `ErrorTransactionBroadcastRejected` (native code 26). Core
* DEFINITIVELY rejected the core transaction: it is not on the network
* and will not get there. The build's UTXO reservation was released and,
* on the deferred (BIP70/BIP270) path, the token was consumed at the
* same time — so the inputs are spendable again and the token is gone.
*
* The definitive counterpart to [TransactionBroadcastUnconfirmed] (20),
* whose outcome is AMBIGUOUS and which therefore keeps its inputs
* reserved. Because the reservation and token are already gone, this is
* NOT retryable in place: address the rejection reason carried in the
* message, then rebuild with
* [buildSignedPayment][org.dashfoundation.dashsdk.wallet.ManagedPlatformWallet.buildSignedPayment]
* (deferred) or re-issue the send.
*/
class TransactionBroadcastRejected(message: String, cause: Throwable? = null) :
PlatformWallet(message, cause)
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/**
* `ErrorStaleReservationToken` (native code 34). A deferred
* (BIP70/BIP270) [broadcastSigned][org.dashfoundation.dashsdk.wallet.ManagedPlatformWallet.broadcastSigned]
* token has outlived its funding reservation's lifetime: key-wallet's
* TTL may already have swept and re-selected the inputs, so acting on it
* could touch a newer, unrelated reservation. The call did NOT touch the
* network. NOT retryable in place — rebuild the payment with
* [buildSignedPayment][org.dashfoundation.dashsdk.wallet.ManagedPlatformWallet.buildSignedPayment].
*
* Sibling of the other two deferred-token failures this code used to
* conflate: [ReservationTokenConsumed] (unknown / already broadcast /
* already released) and [ReservationWalletMismatch] (minted against a
* different wallet generation).
*/
class StaleReservationToken(message: String, cause: Throwable? = null) :
PlatformWallet(message, cause)

/**
* `ErrorReservationTokenConsumed` (native code 35). A deferred
* (BIP70/BIP270) [broadcastSigned][org.dashfoundation.dashsdk.wallet.ManagedPlatformWallet.broadcastSigned]
* token is unknown, already broadcast, or already released — the guard
* that turns a double-broadcast (or a broadcast after release) into a
* typed error instead of a second send. The call did NOT touch the
* network. NOT retryable: rebuild the payment with
* [buildSignedPayment][org.dashfoundation.dashsdk.wallet.ManagedPlatformWallet.buildSignedPayment].
* (Release is idempotent and never raises this.)
*/
class ReservationTokenConsumed(message: String, cause: Throwable? = null) :
PlatformWallet(message, cause)

/**
* `ErrorReservationWalletMismatch` (native code 36). A deferred
* (BIP70/BIP270) [broadcastSigned][org.dashfoundation.dashsdk.wallet.ManagedPlatformWallet.broadcastSigned]
* token was minted against a different wallet *generation* than the one
* broadcasting it (e.g. a wallet re-created under the same id); its
* reservation lives in that other generation's reservation set. The call
* did NOT touch the network and did NOT consume the rightful owner's
* token. NOT retryable through this handle: rebuild the payment with
* [buildSignedPayment][org.dashfoundation.dashsdk.wallet.ManagedPlatformWallet.buildSignedPayment].
*/
class ReservationWalletMismatch(message: String, cause: Throwable? = null) :
PlatformWallet(message, cause)

/**
* Any other `PlatformWalletFFIResultCode` without a dedicated type.
* Carries the platform-wallet [nativeCode] (already de-offset) and
Expand Down Expand Up @@ -335,6 +414,20 @@ sealed class DashSdkError(
// RAW code via translateManagedIdentityNotFoundToZero (#4051)
// before this mapping ever runs. BREAKING for Kotlin hosts that
// caught DashSdkError.NotFound from platform-wallet operations.
//
// 98 is also what the wallet-was-REMOVED case returns on BOTH
// deferred-send paths:
// * deferred (BIP70/BIP270) TOKEN path — a signed-payment broadcast
// whose wallet is no longer registered in the manager, or a
// signed-payment finalize whose wallet was removed while it was
// being signed;
// * finalized-transaction HANDLE (V2) path — a tx-builder finalize
// whose wallet was removed or re-created during signing (no handle
// is published), or a V2 broadcast whose generation is gone.
// Every one reconciles the build's UTXO reservation before returning.
// Nothing was broadcast, and unlike ReservationWalletMismatch (36)
// no other live generation holds the payment either — so it is not
// retryable. See dashpay/platform#4185.
PLATFORM_WALLET_NOT_FOUND_CODE ->
PlatformWallet.NotFound(message, cause)
16 -> PlatformWallet.ShieldedBroadcastFailed(message, cause) // ErrorShieldedBroadcastFailed
Expand All @@ -345,6 +438,17 @@ sealed class DashSdkError(
23 -> PlatformWallet.AssetLockNotTracked(message, cause) // ErrorAssetLockNotTracked
24 -> PlatformWallet.AssetLockAlreadyConsumed(message, cause) // ErrorAssetLockAlreadyConsumed
25 -> PlatformWallet.AssetLockFundingMismatch(message, cause) // ErrorAssetLockFundingMismatch
26 -> PlatformWallet.TransactionBroadcastRejected(message, cause) // ErrorTransactionBroadcastRejected
32 -> PlatformWallet.TransactionBuild(message, cause) // ErrorTransactionBuild
// The deferred-token trio sits at the contiguous block 34-36 because
// 27-33 are claimed elsewhere: 27 ErrorShutdownIncomplete
// (dashpay/platform#4268, merged), 29 ErrorAssetLockInsufficientFunds
// (#4184), 31 ErrorSigningKeyUnavailable (#4183/#4259), 32
// ErrorTransactionBuild (#4247/#4256), 33 ErrorTransactionSigning
// (#4256). See packages/rs-platform-wallet-ffi/ERROR_CODE_REGISTRY.md.
34 -> PlatformWallet.StaleReservationToken(message, cause) // ErrorStaleReservationToken
35 -> PlatformWallet.ReservationTokenConsumed(message, cause) // ErrorReservationTokenConsumed
36 -> PlatformWallet.ReservationWalletMismatch(message, cause) // ErrorReservationWalletMismatch
// ErrorSigningKeyUnavailable — the STRUCTURED signer
// discriminator (dashpay/platform#4060 finding 7): the typed
// completion code rides the whole Rust round-trip, no message
Expand Down
Loading
Loading