secretkeylabs / sats-connect

Sats connect is a simple javascript library that connects apps to Bitcoin wallets
https://www.npmjs.com/package/sats-connect
97 stars 36 forks source link

Setting RBF dynamic cost is invalid #158

Open mlymq0080 opened 1 month ago

mlymq0080 commented 1 month ago

Is there an existing issue for this?

SATS-CONNECT Version

2.5.x

Current Behavior

设置 sequence 这个字段数字为4294967295,xverse里面拉起来的时候确不能动态调整free费

Expected Behavior

No response

Steps To Reproduce

//使用包装隔离验证 (P2SH-P2WPHK) 地址创建交易 SegWit 标志 // addresses[1].publicKey 就是 payment publicKey,在获取地址时拿到 const publicKey = hex.decode(addresses[0].publicKey) const p2wpkh = btc.p2wpkh(publicKey, bitcoinTestnet) const p2sh = btc.p2sh(p2wpkh, bitcoinTestnet)

tx.addInput({ txid: output.txid, index: output.vout, sequence: btc.DEFAULT_SEQUENCE, //RBF标志 目前设置了没有效果 witnessUtxo: { script: p2sh.script, amount: BigInt(output.value) }, redeemScript: p2sh.redeemScript })

Link to Minimal Reproducible Example (CodeSandbox, StackBlitz, etc.)

No response

Anything else?

No response

mlymq0080 commented 1 month ago

Set the number of the sequence field to 4294967295, and when pulling up the xverse, the free fee cannot be dynamically adjusted

victorkirov commented 1 month ago

Hi @mlymq0080

I just want to confirm the issue. Is the scenario:

If this is the issue, this is expected behavior. If the transaction was created externally and just sent to Xverse for signing, then we assume that the transaction is what needs to be signed and is not mutable. In order to make the fees changeable, we would need to edit the outputs of the PSBT and, possibly, add an input, which would result in a completely new transaction.

If you'd like the user to set a fee rate on the transaction, you need to allow them to set it on your site and calculate the fee when building the transaction before sending it to the wallet for signing.

mlymq0080 commented 1 month ago

HI @victorkirov Yes, as you said. I created a PSBT and signed it with the xverse wallet.

I still don't understand what you mean. Do I need to input another unused UTXO into the output in order to make the transaction cost variable? Can you write a simple example.

mlymq0080 commented 1 month ago

async sign(addresses,unspentOutputs,fastestFee){

const createPsbt = (addresses,unspentOutputs,fastestFee) => {

const tx = new btc.Transaction({ allowUnknownOutputs: true, })

const bitcoinTestnet = { bech32: 'bc', pubKeyHash: 0x00, scriptHash: 0x05, wif: 0x80 }

const output = unspentOutputs

const publicKey = hex.decode(addresses[0].publicKey) const p2wpkh = btc.p2wpkh(publicKey, bitcoinTestnet) const p2sh = btc.p2sh(p2wpkh, bitcoinTestnet)

tx.addInput({ txid: output.txid, index: output.vout, sequence: btc.DEFAULT_SEQUENCE, witnessUtxo: { script: p2sh.script, amount: BigInt(output.value) }, redeemScript: p2sh.redeemScript })

const changeAddress = addresses[0].address

tx.addOutputAddress(this.recipient, BigInt(1000), bitcoinTestnet)

const sizes = tx.inputsLength 148 + (tx.outputsLength +1) 44 + 10 const sxf = sizes * fastestFee const zhamount = output.value - 1000 - sxf

tx.addOutputAddress(changeAddress, BigInt(zhamount), bitcoinTestnet)

const psbt = tx.toPSBT(0) const psbtB64 = base64.encode(psbt) console.log('psbtB64是:'+psbtB64) return psbtB64 }

await signTransaction({ payload: { network: {

      type: BitcoinNetworkType.Mainnet 
 },

 psbtBase64: createPsbt(addresses,unspentOutputs,fastestFee),
 broadcast: true,
 inputsToSign: [
   {

     address: addresses[0].address,  
     signingIndexes: [0]    
   }
 ]

}, onFinish: (response) => {

//  data.signatureBase64 = response.psbtBase64
 console.log('签名', response)

}, onCancel: () => { console.log('sign cancel') } }) }

victorkirov commented 1 month ago

When signing a PSBT, the wallet doesn't edit the transaction sent by the dapp. It just parses it and displays it for confirmation and signing.

In order to edit fees, we would need to change the values of the outputs, which would change the underlying PSBT, so we don't do it. This means that the desired fee would need to be taken into account by the dapp that builds the PSBT before it is sent to the wallet for signing.

victorkirov commented 1 month ago

Setting the sequence to a value which enables RBF for an input doesn't change how we handle the transaction. It will only allow the transaction to be replaced via RBF with one with a higher fee once it is published.