mirror of
https://github.com/pezkuwichain/pezkuwi-wallet-android.git
synced 2026-07-22 16:05:49 +00:00
feat: Bitcoin transaction construction, signing, and sending
RealBitcoinTransactionService builds and signs native SegWit transactions client-side (mempool.space only exposes UTXOs/fee-rate/broadcast, not construction, unlike TronGrid): greedy largest-first UTXO selection over confirmed UTXOs, inputs*68 + outputs*31 + 11 vsize heuristic for fees (matching pezkuwi-exchange's proven approach), RBF-signaled inputs, and a 546-sat dust threshold that folds sub-dust change into the fee rather than creating an uneconomical output. Each input gets its own BIP143 sighash, signed via the existing raw-hash signing primitive (NovaSigner.signRaw with skipMessageHashing) already used for Ethereum/Tron, then DER-encoded with low-S normalization - no new signing call path was added, only the DER encoding step. Also fixes multiChainEncryptionFor/getMetaAccountKeypair to recognize Bitcoin accounts: previously neither function had any Bitcoin (or Tron) branch, so signing would have silently used the wrong keypair. Threads a bitcoin flag through mapMetaAccountSecretsToKeypair/DerivationPath and AccountSecrets.keypair(chain)/derivationPath(chain) the same way ethereum already is.
This commit is contained in:
+6
-3
@@ -146,7 +146,8 @@ class SecretsSigner(
|
||||
return secretStoreV2.getKeypair(
|
||||
metaAccount = metaAccount,
|
||||
accountId = accountId,
|
||||
isEthereumBased = multiChainEncryption is MultiChainEncryption.Ethereum
|
||||
isEthereumBased = multiChainEncryption is MultiChainEncryption.Ethereum,
|
||||
isBitcoinBased = metaAccount.bitcoinAddress?.contentEquals(accountId) == true
|
||||
)
|
||||
}
|
||||
|
||||
@@ -159,11 +160,12 @@ class SecretsSigner(
|
||||
private suspend fun SecretStoreV2.getKeypair(
|
||||
metaAccount: MetaAccount,
|
||||
accountId: AccountId,
|
||||
isEthereumBased: Boolean
|
||||
isEthereumBased: Boolean,
|
||||
isBitcoinBased: Boolean = false,
|
||||
) = if (hasChainSecrets(metaAccount.id, accountId)) {
|
||||
getChainAccountKeypair(metaAccount.id, accountId)
|
||||
} else {
|
||||
getMetaAccountKeypair(metaAccount.id, isEthereumBased)
|
||||
getMetaAccountKeypair(metaAccount.id, isEthereumBased, isBitcoinBased)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,6 +175,7 @@ class SecretsSigner(
|
||||
return when {
|
||||
substrateAccountId.contentEquals(accountId) -> substrateCryptoType?.let(MultiChainEncryption.Companion::substrateFrom)
|
||||
ethereumAccountId().contentEquals(accountId) -> MultiChainEncryption.Ethereum
|
||||
bitcoinAddress?.contentEquals(accountId) == true -> MultiChainEncryption.Ethereum
|
||||
else -> {
|
||||
val chainAccount = chainAccounts.values.firstOrNull { it.accountId.contentEquals(accountId) } ?: return null
|
||||
val cryptoType = chainAccount.cryptoType ?: return null
|
||||
|
||||
Reference in New Issue
Block a user