-
Notifications
You must be signed in to change notification settings - Fork 56
feat(kotlin-sdk): bind OP_RETURN, output-order and VIN0-change builder controls #4288
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
QuantumExplorer
merged 12 commits into
dashpay:v4.2-dev
from
HashEngineering:feat/maya-op-return-kotlin
Aug 6, 2026
Merged
Changes from 4 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
6f70092
feat(core-wallet): expose OP_RETURN, output-order and VIN0-change con…
jeanpierreroma 8370b6a
test(sdk): tighten the Maya deposit assertions and gate the suite
jeanpierreroma c3ffb89
Merge branch 'v4.2-dev' into feat/maya-op-return
romchornyi 27b8502
feat(kotlin-sdk): bind OP_RETURN, output-order and VIN0-change builde…
HashEngineering 310deeb
Merge remote-tracking branch 'origin/v4.2-dev' into maya-base
QuantumExplorer d85fa2a
Merge branch 'feat/maya-op-return' into feat/maya-op-return-kotlin
QuantumExplorer 677819f
feat(kotlin-sdk): expose the MAYACHAIN builder controls through build…
QuantumExplorer a1db38d
fix(sdk): follow key-wallet's revert to MAX_STANDARD_OP_RETURN_BYTES
QuantumExplorer c3b16c0
Merge branch 'maya-base' into maya-kotlin
QuantumExplorer b3f2801
chore(deps): bump rust-dashcore to the merged OP_RETURN builder rev
QuantumExplorer 81bdbdd
Merge branch 'maya-base' into maya-kotlin
QuantumExplorer 3af7eb5
Merge remote-tracking branch 'origin/v4.2-dev' into maya-kotlin
QuantumExplorer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
.../androidTest/kotlin/org/dashfoundation/dashsdk/wallet/CoreTxBuilderOpReturnBindingTest.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| package org.dashfoundation.dashsdk.wallet | ||
|
|
||
| import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
| import org.dashfoundation.dashsdk.ffi.DashSDKException | ||
| import org.dashfoundation.dashsdk.ffi.NativeLoader | ||
| import org.dashfoundation.dashsdk.ffi.WalletManagerNative | ||
| import org.junit.Assert.assertNotEquals | ||
| import org.junit.Assert.assertThrows | ||
| import org.junit.Test | ||
| import org.junit.runner.RunWith | ||
|
|
||
| /** | ||
| * Binding-level coverage for the MAYACHAIN-deposit builder controls | ||
| * (`add_op_return`, `preserve_output_order`, `change_to_first_input`, | ||
| * `signed_transaction_v2_bytes`) — the Android counterpart of the gated | ||
| * Swift `MayaDepositVerificationIntegrationTests`, minus everything that | ||
| * needs a funded wallet. Proves the four new JNI symbols resolve, happy-path | ||
| * calls succeed against a live builder, and the FFI's error paths surface as | ||
| * [DashSDKException] instead of aborting. | ||
| * | ||
| * No network, no wallet, no funds: a builder handle alone accepts outputs | ||
| * and options; only funding/finalizing needs a wallet. The full | ||
| * deposit-shape assertion (vault VOUT0 / memo VOUT1 / change VOUT2 on a | ||
| * really-funded transaction) stays with the Swift integration suite and the | ||
| * wallet-side testnet verification. | ||
| */ | ||
| @RunWith(AndroidJUnit4::class) | ||
| class CoreTxBuilderOpReturnBindingTest { | ||
|
|
||
| // Any syntactically valid testnet P2PKH address works — the builder | ||
| // validates encoding/network only; nothing is funded or sent. Same | ||
| // address the FFI's own persistence tests use. | ||
| private val testnetAddress = "yMqShkrgjTRuReBGFpQr7FozEF1QcNBBYA" | ||
|
|
||
| private fun withBuilder(block: (Long) -> Unit) { | ||
| NativeLoader.ensureLoaded() | ||
| val builder = WalletManagerNative.coreTxBuilderNew(network = 1) | ||
| assertNotEquals("builder handle must be live", 0L, builder) | ||
| try { | ||
| block(builder) | ||
| } finally { | ||
| WalletManagerNative.coreTxBuilderDestroy(builder) | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| fun mayaShapeOptionsBindAndAccept() { | ||
| withBuilder { builder -> | ||
| // The canonical Maya deposit sequence, sans funding: vault output, | ||
| // memo, insertion-order + VIN0-change options. | ||
| WalletManagerNative.coreTxBuilderAddOutput(builder, vaultAddressForTest(), 100_000) | ||
| WalletManagerNative.coreTxBuilderAddOpReturn( | ||
| builder, | ||
| "=:ETH.ETH:0x1c7b17362c84287bd1184447e6dfeaf920c31bbe".toByteArray(Charsets.UTF_8), | ||
| ) | ||
| WalletManagerNative.coreTxBuilderPreserveOutputOrder(builder) | ||
| WalletManagerNative.coreTxBuilderChangeToFirstInput(builder) | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| fun opReturnAcceptsExactly80Bytes() { | ||
| withBuilder { builder -> | ||
| WalletManagerNative.coreTxBuilderAddOpReturn(builder, ByteArray(80)) | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| fun opReturnRejects81BytesAndBuilderSurvives() { | ||
| withBuilder { builder -> | ||
| assertThrows(DashSDKException::class.java) { | ||
| WalletManagerNative.coreTxBuilderAddOpReturn(builder, ByteArray(81)) | ||
| } | ||
| // The FFI rejects the payload BEFORE consuming builder state, so | ||
| // the same handle must still accept further configuration. | ||
| WalletManagerNative.coreTxBuilderAddOutput(builder, vaultAddressForTest(), 100_000) | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| fun signedTransactionBytesSymbolBindsAndRejectsNullHandle() { | ||
| NativeLoader.ensureLoaded() | ||
| // Handle 0 can never be a finalized transaction; the call must throw | ||
| // (not crash), which also proves the JNI symbol resolves. | ||
| assertThrows(DashSDKException::class.java) { | ||
| WalletManagerNative.coreSignedTransactionV2Bytes(0L) | ||
| } | ||
| } | ||
|
|
||
| private fun vaultAddressForTest(): String = testnetAddress | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 Blocking: Expose the MAYACHAIN controls through a public atomic API
All three new builder controls are
internal, as are the builder constructor,addOutput, andfinalizeAtomic; the underlyingWalletManagerNativeobject is internal as well. The only public driver,ManagedPlatformWallet.sendToAddresses, accepts ordinary positive-value address outputs, applies none of these controls, immediately broadcasts, and never returns aFinalizedCoreTransaction. Consequently, an application consuming the publisheddash-sdk-androidartifact cannot add the OP_RETURN memo, preserve the required output order, route change to VIN0, or obtain a finalized transaction to inspect withserializedData(). The instrumented test only exercises the internal native surface from within the SDK module, so it does not verify consumer accessibility. Add a public atomic prepare/send API that applies these options and returns aFinalizedCoreTransactionfor inspection while keeping the deprecated splitsetFunding/buildSignedpath inaccessible.source: ['codex']
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Retracting this as a blocker after verifying the stacked integration context. This PR intentionally adds the JNI/Kotlin binding layer on top of #4286; the supported public call site is the option-carrying
ManagedPlatformWallet.buildSignedPayment, whose reservation-token overload belongs to the separate #4185/#4247 deferred-payment stack. The downstream #1535 branch has already exercised that combined stack end to end on mainnet. Requiring a second public atomic API here would duplicate or preempt that stack rather than fix a defect in these bindings. The public entry-point follow-up remains a documented dependency before an integration AAR can ship.