mirror of
https://github.com/pezkuwichain/pezkuwi-wallet-android.git
synced 2026-07-22 20:45:53 +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:
+12
@@ -63,6 +63,18 @@ class SubstrateFee(
|
||||
override val asset: Chain.Asset
|
||||
) : Fee
|
||||
|
||||
/**
|
||||
* Fee for a Bitcoin transaction, denominated in sats: `feeRate (sat/vB) * estimated vsize` - see
|
||||
* `RealBitcoinTransactionService` for how both are derived. The network only ever collects what miners include
|
||||
* in a block, which is exactly this amount (unlike account-model chains, a Bitcoin fee is not a cap/estimate
|
||||
* that gets partially refunded - it is the literal difference between input and output values).
|
||||
*/
|
||||
class BitcoinFee(
|
||||
override val amount: BigInteger,
|
||||
override val submissionOrigin: SubmissionOrigin,
|
||||
override val asset: Chain.Asset
|
||||
) : Fee
|
||||
|
||||
class SubstrateFeeBase(
|
||||
override val amount: BigInteger,
|
||||
override val asset: Chain.Asset
|
||||
|
||||
+2
-2
@@ -25,14 +25,14 @@ suspend fun SecretStoreV2.getAccountSecrets(
|
||||
|
||||
fun AccountSecrets.keypair(chain: Chain): Keypair {
|
||||
return fold(
|
||||
left = { mapMetaAccountSecretsToKeypair(it, ethereum = chain.isEthereumBased) },
|
||||
left = { mapMetaAccountSecretsToKeypair(it, ethereum = chain.isEthereumBased, bitcoin = chain.isBitcoinBased) },
|
||||
right = { mapChainAccountSecretsToKeypair(it) }
|
||||
)
|
||||
}
|
||||
|
||||
fun AccountSecrets.derivationPath(chain: Chain): String? {
|
||||
return fold(
|
||||
left = { mapMetaAccountSecretsToDerivationPath(it, ethereum = chain.isEthereumBased) },
|
||||
left = { mapMetaAccountSecretsToDerivationPath(it, ethereum = chain.isEthereumBased, bitcoin = chain.isBitcoinBased) },
|
||||
right = { it[ChainAccountSecrets.DerivationPath] }
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user