From f773d7b078719f9af5c30f698f3afeb61a6fad8c Mon Sep 17 00:00:00 2001 From: Oleg Leonov Date: Mon, 23 Feb 2026 15:02:41 +0300 Subject: [PATCH 1/9] Enhance KitState.Syncing to include maxBlockHeight for improved sync tracking --- .../kotlin/io/horizontalsystems/bitcoincore/BitcoinCore.kt | 5 +++-- .../io/horizontalsystems/bitcoincore/managers/SyncManager.kt | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/BitcoinCore.kt b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/BitcoinCore.kt index 9dd98852..24996a26 100644 --- a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/BitcoinCore.kt +++ b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/BitcoinCore.kt @@ -597,13 +597,13 @@ class BitcoinCore( sealed class KitState { object Synced : KitState() class NotSynced(val exception: Throwable) : KitState() - class Syncing(val progress: Double, val substatus: SyncSubstatus? = null) : KitState() + class Syncing(val progress: Double, val substatus: SyncSubstatus? = null, val maxBlockHeight: Int? = null) : KitState() class ApiSyncing(val transactions: Int) : KitState() override fun equals(other: Any?) = when { this is Synced && other is Synced -> true this is NotSynced && other is NotSynced -> exception == other.exception - this is Syncing && other is Syncing -> this.progress == other.progress && this.substatus == other.substatus + this is Syncing && other is Syncing -> this.progress == other.progress && this.substatus == other.substatus && this.maxBlockHeight == other.maxBlockHeight this is ApiSyncing && other is ApiSyncing -> this.transactions == other.transactions else -> false } @@ -623,6 +623,7 @@ class BitcoinCore( if (this is Syncing) { result = 31 * result + progress.hashCode() result = 31 * result + (substatus?.hashCode() ?: 0) + result = 31 * result + (maxBlockHeight?.hashCode() ?: 0) } if (this is NotSynced) { result = 31 * result + exception.hashCode() diff --git a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/managers/SyncManager.kt b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/managers/SyncManager.kt index 6fdad645..3921358b 100644 --- a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/managers/SyncManager.kt +++ b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/managers/SyncManager.kt @@ -161,7 +161,7 @@ class SyncManager( syncState = if (progress >= 1) { KitState.Synced } else { - KitState.Syncing(progress) + KitState.Syncing(progress, maxBlockHeight = maxBlockHeight) } } From 796e8ec8407eb1b8e345ed5e614b953223119f46 Mon Sep 17 00:00:00 2001 From: Oleg Leonov Date: Tue, 24 Feb 2026 13:33:08 +0300 Subject: [PATCH 2/9] Update hdWalletKitAndroid version to b7599f6 for improved functionality --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a417f2d3..33a62c24 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ constraintlayout = "2.1.4" core = "1.5.0" espressoCore = "3.2.0" guava = "33.5.0-android" -hdWalletKitAndroid = "a74b51f" +hdWalletKitAndroid = "b7599f6" junit = "4.13.2" junitVersion = "1.1.1" kotlinxCoroutinesCore = "1.10.1" From 631f634f2a0c3c16a31da8b9d0c86da24cbc658b Mon Sep 17 00:00:00 2001 From: Oleg Leonov Date: Thu, 26 Feb 2026 22:27:28 +0300 Subject: [PATCH 3/9] Fixed merkcle block deserialization --- .../models/converters/MerkleBlockConverter.kt | 22 +++++++++++++++++-- .../network/peer/task/GetMerkleBlocksTask.kt | 2 +- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/models/converters/MerkleBlockConverter.kt b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/models/converters/MerkleBlockConverter.kt index 69286a94..a665c66f 100644 --- a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/models/converters/MerkleBlockConverter.kt +++ b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/models/converters/MerkleBlockConverter.kt @@ -3,15 +3,33 @@ package io.horizontalsystems.bitcoincore.models.converters import androidx.room.TypeConverter import io.horizontalsystems.bitcoincore.models.MerkleBlock import kotlinx.serialization.json.Json +import timber.log.Timber class MerkleBlockConverter { + private val json = Json { allowStructuredMapKeys = true } + @TypeConverter fun fromMerkleBlock(block: MerkleBlock?): String? { - return block?.let { Json.encodeToString(MerkleBlock.serializer(), it) } + return block?.let { + try { + json.encodeToString(MerkleBlock.serializer(), it) + } catch (e: Exception) { + val keys = it.associatedTransactionHashes.keys.take(5).map { key -> "${key::class.simpleName}(${key.bytes.contentToString()})" } + Timber.e(e, "Failed to serialize MerkleBlock: hash=${it.blockHash.contentToString()}, txCount=${it.associatedTransactionHashes.size}, keys=$keys") + null + } + } } @TypeConverter fun toMerkleBlock(data: String?): MerkleBlock? { - return data?.let { Json.decodeFromString(MerkleBlock.serializer(), it) } + return data?.let { + try { + json.decodeFromString(MerkleBlock.serializer(), it) + } catch (e: Exception) { + Timber.e(e, "Failed to deserialize MerkleBlock from: ${it.take(200)}") + null + } + } } } \ No newline at end of file diff --git a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/network/peer/task/GetMerkleBlocksTask.kt b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/network/peer/task/GetMerkleBlocksTask.kt index ba0e0b69..7602e4be 100644 --- a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/network/peer/task/GetMerkleBlocksTask.kt +++ b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/network/peer/task/GetMerkleBlocksTask.kt @@ -163,7 +163,7 @@ class GetMerkleBlocksTask( .d("GetMerkleBlocksTask: Orphan merkle block: hash=${merkleBlock.blockHash.contentToString()}, height=${merkleBlock.height}") } catch (e: Exception) { Timber.tag(logTag) - .d("Failed to process merkle block: hash=${merkleBlock.blockHash.contentToString()}, error=${e.message}") + .e(e, "Failed to process merkle block: hash=${merkleBlock.blockHash.contentToString()}, height=${merkleBlock.height}") listener?.onTaskFailed(this, e) } From 6a0e847ae0b27d367f4821fd721d062b342125a2 Mon Sep 17 00:00:00 2001 From: Oleg Leonov Date: Mon, 2 Mar 2026 17:35:41 +0700 Subject: [PATCH 4/9] Remove redundant restore key converters for BIP44 in BitcoinKit --- .../kotlin/io/horizontalsystems/bitcoinkit/BitcoinKit.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/bitcoinkit/src/main/kotlin/io/horizontalsystems/bitcoinkit/BitcoinKit.kt b/bitcoinkit/src/main/kotlin/io/horizontalsystems/bitcoinkit/BitcoinKit.kt index fe8dd4cd..ea4bcc25 100644 --- a/bitcoinkit/src/main/kotlin/io/horizontalsystems/bitcoinkit/BitcoinKit.kt +++ b/bitcoinkit/src/main/kotlin/io/horizontalsystems/bitcoinkit/BitcoinKit.kt @@ -287,11 +287,6 @@ class BitcoinKit : AbstractKit { Purpose.BIP44 -> { bitcoinCore.addRestoreKeyConverter(Bip44RestoreKeyConverter(base58AddressConverter)) bitcoinCore.addRestoreKeyConverter(hodlerPlugin) - - if (extendedKey != null) { - bitcoinCore.addRestoreKeyConverter(Bip49RestoreKeyConverter(base58AddressConverter)) - bitcoinCore.addRestoreKeyConverter(Bip84RestoreKeyConverter(bech32AddressConverter)) - } } Purpose.BIP49 -> { From 634554613d7a1c6eaa89cf3101b747da96eb668a Mon Sep 17 00:00:00 2001 From: Oleg Leonov Date: Thu, 5 Mar 2026 17:19:35 +0700 Subject: [PATCH 5/9] Update hdWalletKitAndroid version to 8f873a1 for improved functionality --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 33a62c24..5ee93a52 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ constraintlayout = "2.1.4" core = "1.5.0" espressoCore = "3.2.0" guava = "33.5.0-android" -hdWalletKitAndroid = "b7599f6" +hdWalletKitAndroid = "8f873a1" junit = "4.13.2" junitVersion = "1.1.1" kotlinxCoroutinesCore = "1.10.1" From b7d325f030f0b0e6c37c14c6c86f7756e73d3a5f Mon Sep 17 00:00:00 2001 From: Oleg Leonov Date: Fri, 6 Mar 2026 20:59:23 +0700 Subject: [PATCH 6/9] Add IFullTransactionSigner interface for full transaction signing support --- .../transactions/builder/IFullTransactionSigner.kt | 10 ++++++++++ .../transactions/builder/TransactionSigner.kt | 5 +++++ 2 files changed, 15 insertions(+) create mode 100644 bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/IFullTransactionSigner.kt diff --git a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/IFullTransactionSigner.kt b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/IFullTransactionSigner.kt new file mode 100644 index 00000000..cfba55ec --- /dev/null +++ b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/IFullTransactionSigner.kt @@ -0,0 +1,10 @@ +package io.horizontalsystems.bitcoincore.transactions.builder + +data class SignedTransactionData( + val serializedTx: String, + val signatures: List +) + +interface IFullTransactionSigner { + suspend fun signFullTransaction(mutableTransaction: MutableTransaction): SignedTransactionData +} diff --git a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/TransactionSigner.kt b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/TransactionSigner.kt index 485cae9d..4d842f4a 100644 --- a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/TransactionSigner.kt +++ b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/TransactionSigner.kt @@ -11,6 +11,11 @@ class TransactionSigner( private val schnorrInputSigner: ISchnorrInputSigner ) { suspend fun sign(mutableTransaction: MutableTransaction) { + (ecdsaInputSigner as? IFullTransactionSigner)?.let { ecdsaInputSigner -> + ecdsaInputSigner.signFullTransaction(mutableTransaction) + return + } + // Bunch sign added to support Tangem sdk if (mutableTransaction.inputsToSign.size > 1 && isAllOutputsOneType(mutableTransaction)) { if (batchSign(mutableTransaction)) return From f91abc60da7693f34e7955addb8fe62c71293f17 Mon Sep 17 00:00:00 2001 From: Oleg Leonov Date: Tue, 10 Mar 2026 08:51:18 +0700 Subject: [PATCH 7/9] Add support for publishing modules to local Maven repository and generate POM files --- .github/workflows/publish-maven.yml | 73 +++++++++++++++++++ .../transactions/builder/InputSetter.kt | 8 +- .../builder/MutableTransaction.kt | 2 + build.gradle | 68 +++++++++++++++++ 4 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/publish-maven.yml diff --git a/.github/workflows/publish-maven.yml b/.github/workflows/publish-maven.yml new file mode 100644 index 00000000..1ba377f2 --- /dev/null +++ b/.github/workflows/publish-maven.yml @@ -0,0 +1,73 @@ +name: Publish to Maven (GitHub Pages) + +on: + push: + +permissions: + contents: write + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'zulu' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Create local.properties + run: touch local.properties + + - name: Set short SHA + run: echo "SHORT_SHA=$(echo $GITHUB_SHA | cut -c1-7)" >> $GITHUB_ENV + + - name: Build and publish all modules to local repo + run: ./gradlew publishReleasePublicationToLocalRepository generateRootPom + env: + SHORT_SHA: ${{ env.SHORT_SHA }} + + - name: Prepare gh-pages + run: | + REMOTE_URL="https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" + git clone --depth 1 --branch gh-pages "$REMOTE_URL" gh-pages 2>/dev/null || { + mkdir gh-pages + cd gh-pages + git init + } + + - name: Copy artifacts to gh-pages + run: cp -r build/maven-repo/* gh-pages/ + + - name: Keep only last 20 versions + run: | + ROOT_PATH="gh-pages/com/github/piratecash/bitcoin-kit-android" + if [ -d "$ROOT_PATH" ]; then + cd "$ROOT_PATH" + ls -dt */ | tail -n +21 | xargs -r rm -rf + fi + for MODULE_PATH in gh-pages/com/github/piratecash/bitcoin-kit-android/*/; do + if [ -d "$MODULE_PATH" ]; then + cd "$MODULE_PATH" + ls -dt */ 2>/dev/null | tail -n +21 | xargs -r rm -rf + cd - > /dev/null + fi + done + + - name: Commit and push to gh-pages + run: | + cd gh-pages + git checkout -B gh-pages + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add -A + git diff --cached --quiet && echo "No changes" && exit 0 + git commit -m "Publish ${{ env.SHORT_SHA }}" + git remote remove origin 2>/dev/null || true + git remote add origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git + git push --force origin gh-pages diff --git a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/InputSetter.kt b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/InputSetter.kt index bfc807ca..bac06420 100644 --- a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/InputSetter.kt +++ b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/InputSetter.kt @@ -9,6 +9,7 @@ import io.horizontalsystems.bitcoincore.managers.SelectedUnspentOutputInfo import io.horizontalsystems.bitcoincore.managers.SendValueErrors import io.horizontalsystems.bitcoincore.managers.UnspentOutputQueue import io.horizontalsystems.bitcoincore.models.Address +import io.horizontalsystems.bitcoincore.models.PublicKey import io.horizontalsystems.bitcoincore.models.TransactionDataSortType import io.horizontalsystems.bitcoincore.models.TransactionInput import io.horizontalsystems.bitcoincore.storage.InputToSign @@ -115,14 +116,17 @@ class InputSetter( var changeInfo: ChangeInfo? = null unspentOutputInfo.changeValue?.let { changeValue -> val firstOutput = unspentOutputInfo.outputs.firstOrNull() + val changePubKey: PublicKey val changeAddress = if (changeToFirstInput && firstOutput != null) { - addressConverter.convert(firstOutput.publicKey, firstOutput.output.scriptType) + changePubKey = firstOutput.publicKey + addressConverter.convert(changePubKey, firstOutput.output.scriptType) } else { - val changePubKey = publicKeyManager.changePublicKey() + changePubKey = publicKeyManager.changePublicKey() addressConverter.convert(changePubKey, changeScriptType) } mutableTransaction.changeAddress = changeAddress + mutableTransaction.changePublicKey = changePubKey mutableTransaction.changeValue = changeValue changeInfo = ChangeInfo(address = changeAddress, value = changeValue) } diff --git a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/MutableTransaction.kt b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/MutableTransaction.kt index c8b9c41e..f27a14f1 100644 --- a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/MutableTransaction.kt +++ b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/MutableTransaction.kt @@ -1,6 +1,7 @@ package io.horizontalsystems.bitcoincore.transactions.builder import io.horizontalsystems.bitcoincore.models.Address +import io.horizontalsystems.bitcoincore.models.PublicKey import io.horizontalsystems.bitcoincore.models.Transaction import io.horizontalsystems.bitcoincore.models.TransactionOutput import io.horizontalsystems.bitcoincore.serializers.BaseTransactionSerializer @@ -17,6 +18,7 @@ class MutableTransaction(isOutgoing: Boolean = true) { var recipientValue = 0L var memo: String? = null var changeAddress: Address? = null + var changePublicKey: PublicKey? = null var changeValue = 0L private val pluginData = mutableMapOf() diff --git a/build.gradle b/build.gradle index 1afeb3bd..2851928d 100644 --- a/build.gradle +++ b/build.gradle @@ -3,6 +3,15 @@ buildscript { ext.kotlin_version = '2.0.21' ext.room_version = '2.6.1' + ext.shortSha = providers.environmentVariable("SHORT_SHA") + .orElse(provider { + def process = new ProcessBuilder("git", "rev-parse", "--short=7", "HEAD") + .directory(rootDir) + .redirectErrorStream(true) + .start() + process.inputStream.text.trim() ?: "unknown" + }) + .get() repositories { google() mavenCentral() @@ -28,6 +37,65 @@ allprojects { } } +def libraryModules = [ + 'bitcoincore', 'bitcoinkit', 'bitcoincashkit', 'litecoinkit', + 'dashkit', 'dashlib', 'dogecoinkit', 'cosantakit', 'piratecashkit', + 'ecashkit', 'hodler' +] + +subprojects { sub -> + if (libraryModules.contains(sub.name)) { + sub.afterEvaluate { + sub.publishing { + publications.withType(MavenPublication).configureEach { + groupId = "com.github.piratecash.bitcoin-kit-android" + artifactId = sub.name + version = rootProject.ext.shortSha + } + repositories { + maven { + name = "local" + url = uri(rootProject.layout.buildDirectory.dir("maven-repo")) + } + } + } + } + } +} + +tasks.register('generateRootPom') { + def repoDir = rootProject.layout.buildDirectory.dir("maven-repo/com/github/piratecash/bitcoin-kit-android/${rootProject.ext.shortSha}") + outputs.dir(repoDir) + doLast { + def dir = repoDir.get().asFile + dir.mkdirs() + def deps = libraryModules.collect { mod -> + """ + com.github.piratecash.bitcoin-kit-android + ${mod} + ${rootProject.ext.shortSha} + aar + """ + }.join('\n') + + new File(dir, "bitcoin-kit-android-${rootProject.ext.shortSha}.pom").text = """\ + + + 4.0.0 + com.github.piratecash + bitcoin-kit-android + ${rootProject.ext.shortSha} + pom + +${deps} + + +""" + } +} + task clean(type: Delete) { delete rootProject.buildDir } From 3b49e4c35a47a8d72a168a4928f6e226d0806441 Mon Sep 17 00:00:00 2001 From: Oleg Leonov Date: Tue, 10 Mar 2026 08:57:43 +0700 Subject: [PATCH 8/9] Add support for publishing modules to local Maven repository and generate POM files --- .github/workflows/publish-maven.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/publish-maven.yml b/.github/workflows/publish-maven.yml index 1ba377f2..7523f2a8 100644 --- a/.github/workflows/publish-maven.yml +++ b/.github/workflows/publish-maven.yml @@ -11,6 +11,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + submodules: recursive - name: Set up JDK 17 uses: actions/setup-java@v4 From 3f0c17e58e98248fb228c238a2cc1bafa65e8d5e Mon Sep 17 00:00:00 2001 From: Oleg Leonov Date: Tue, 10 Mar 2026 11:31:19 +0700 Subject: [PATCH 9/9] Enhance transaction signing process to support full transaction signing and improve handling of signed data --- .../transactions/TransactionCreator.kt | 30 +++++++++++++++++-- .../transactions/builder/TransactionSigner.kt | 11 +++---- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/TransactionCreator.kt b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/TransactionCreator.kt index b5c7781d..e31fc00c 100644 --- a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/TransactionCreator.kt +++ b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/TransactionCreator.kt @@ -1,6 +1,9 @@ package io.horizontalsystems.bitcoincore.transactions import io.horizontalsystems.bitcoincore.core.IPluginData +import io.horizontalsystems.bitcoincore.extensions.hexToByteArray +import io.horizontalsystems.bitcoincore.io.BitcoinInputMarkable +import io.horizontalsystems.bitcoincore.models.Transaction import io.horizontalsystems.bitcoincore.managers.BloomFilterManager import io.horizontalsystems.bitcoincore.models.TransactionDataSortType import io.horizontalsystems.bitcoincore.serializers.BaseTransactionSerializer @@ -9,6 +12,7 @@ import io.horizontalsystems.bitcoincore.storage.UnspentOutput import io.horizontalsystems.bitcoincore.storage.UtxoFilters import io.horizontalsystems.bitcoincore.transactions.builder.MutableTransaction import io.horizontalsystems.bitcoincore.transactions.builder.TransactionBuilder +import io.horizontalsystems.bitcoincore.transactions.builder.SignedTransactionData import io.horizontalsystems.bitcoincore.transactions.builder.TransactionSigner class TransactionCreator( @@ -66,14 +70,34 @@ class TransactionCreator( } suspend fun create(mutableTransaction: MutableTransaction): FullTransaction { - transactionSigner.sign(mutableTransaction) + val signedData = transactionSigner.sign(mutableTransaction) - val fullTransaction = mutableTransaction.build(transactionSerializer) - processAndSend(fullTransaction) + val fullTransaction = if (signedData != null) { + buildFromSignedData(signedData, mutableTransaction) + } else { + mutableTransaction.build(transactionSerializer) + } + processAndSend(fullTransaction) return fullTransaction } + private fun buildFromSignedData( + signedData: SignedTransactionData, + mutableTransaction: MutableTransaction + ): FullTransaction { + val rawBytes = signedData.serializedTx.hexToByteArray() + val deserialized = transactionSerializer.deserialize( + BitcoinInputMarkable(rawBytes) + ) + deserialized.header.apply { + status = Transaction.Status.NEW + isMine = true + isOutgoing = mutableTransaction.transaction.isOutgoing + } + return deserialized + } + private fun processAndSend(transaction: FullTransaction): FullTransaction { // Always save the transaction first - don't block on peer availability try { diff --git a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/TransactionSigner.kt b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/TransactionSigner.kt index 4d842f4a..57ea9d17 100644 --- a/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/TransactionSigner.kt +++ b/bitcoincore/src/main/kotlin/io/horizontalsystems/bitcoincore/transactions/builder/TransactionSigner.kt @@ -10,15 +10,14 @@ class TransactionSigner( private val ecdsaInputSigner: IInputSigner, private val schnorrInputSigner: ISchnorrInputSigner ) { - suspend fun sign(mutableTransaction: MutableTransaction) { - (ecdsaInputSigner as? IFullTransactionSigner)?.let { ecdsaInputSigner -> - ecdsaInputSigner.signFullTransaction(mutableTransaction) - return + suspend fun sign(mutableTransaction: MutableTransaction): SignedTransactionData? { + (ecdsaInputSigner as? IFullTransactionSigner)?.let { fullSigner -> + return fullSigner.signFullTransaction(mutableTransaction) } // Bunch sign added to support Tangem sdk if (mutableTransaction.inputsToSign.size > 1 && isAllOutputsOneType(mutableTransaction)) { - if (batchSign(mutableTransaction)) return + if (batchSign(mutableTransaction)) return null } mutableTransaction.inputsToSign.forEachIndexed { index, inputToSign -> @@ -28,6 +27,8 @@ class TransactionSigner( ecdsaSign(index, mutableTransaction) } } + + return null } private suspend fun batchSign(mutableTransaction: MutableTransaction): Boolean {