unisat-wallet / dev-support

24 stars 17 forks source link

signPsbt error -32603, invalid psbt #53

Closed amarcu closed 2 months ago

amarcu commented 2 months ago

I want to sign a psbt for a rune burn transaction. This is how I generate the psbt for signing:

  const paymentPublicKey = Buffer.from(paymentPubKeyString, 'hex');
  const ordinalPublicKey = convertToSchnorrPubKey(Buffer.from(ordinalPubKeyString, 'hex'));

  // create segwit spend
  const p2wpkh = btc.p2wpkh(paymentPublicKey, network);
  const p2sh = btc.p2sh(p2wpkh, network);

  // create taproot spend
  const p2tr = btc.p2tr(ordinalPublicKey, undefined, network);

  for (let utxo of runeUtxo) {
    psbt.addInput({
      hash: utxo.txid,
      index: utxo.vout,
      witnessUtxo: {
        script: p2tr.script ? Buffer.from(p2tr.script, 'hex') : Buffer.alloc(0),
        value: utxo.value,
      },
      tapInternalKey: ordinalPublicKey,
    });
  }

  for (let utxo of paymentUtxos) {
    psbt.addInput({
      hash: utxo.txid,
      index: utxo.vout,
      witnessUtxo: {
        script: p2sh.script ? Buffer.from(p2sh.script, 'hex') : Buffer.alloc(0),
        value: utxo.value,
      },
      redeemScript: p2sh.redeemScript ? Buffer.from(p2sh.redeemScript, 'hex') : Buffer.alloc(0),
      // witnessScript: p2sh.witnessScript,
    });
  }
}

// Add Rune-specific outputs
const burnOutput = 0;
const edicts = [new Edict(runeId, bigIntAmount, burnOutput)];
const mintstone = new Runestone(edicts, none(), none(), some(1));

// Add the rest of the transaction construction logic
psbt.addOutput({
  script: mintstone.encipher(),
  value: 0,
});

psbt.addOutput({
  address: ordinalAddress,
  value: 546,
});

const satoshis = paymentUtxos.reduce((acc, utxo) => acc + utxo.value, 0);
const change = satoshis - fee - 546 * 2;

psbt.addOutput({
  address: paymentAddress,
  value: change,
});

This psbt can be signed with other wallets(like xverse), for unisat i get back the error mentioned in the title.

This is the generated psbt:

   psbtBase64  cHNidP8BAMsCAAAAAitsrDWNXvj8r7K87QmLRmNvAB1XsCs46GiVla/EP1aTAQAAAAD/////ArxY+2ozP1n8cVNSyG18GAHd7ew9en32aO5KeNsfD2EAAAAAAP////8DAAAAAAAAAAAQal0NFgEAkKMzf4CU69wDACICAAAAAAAAIlEgneyTH3UQtJBsIrOv0Q/C/9c7Eq+AwUleNLyhrkMj/rwwPAAAAAAAACJRIJ3skx91ELSQbCKzr9EPwv/XOxKvgMFJXjS8oa5DI/68AAAAAAABASsiAgAAAAAAACJRIJ3skx91ELSQbCKzr9EPwv/XOxKvgMFJXjS8oa5DI/68ARcgKPxwol+4jf8QURCf1HDsHJnrh4lt7I4GV+AAhrRmcLwAAQEgIE4AAAAAAAAXqRTc91IIU0NNuTmqNwzhAfnHnb4NVYcBBBYAFF+PHZXziVZJh/OjjDDw1J3pkwS/AAAAAA==

My call to the unisat wallet, also tested with inputsToSign:

   try {
    const txHex = await window.unisat.signPsbt({
      autoFinalized: false,
      psbtHex: psbtBase64,
      toSignInputs: payload.inputsToSign
      network: networkType,
    });
    console.log('Unisat signed tx:', txHex);
    resolve(txHex);
  } catch (error) {
    reject(error);
  }
huanniangstudio commented 2 months ago

https://docs.unisat.io/dev/unisat-developer-center/unisat-wallet#signpsbt Please read the docs here.

You should sign like this

try {
  let res = await window.unisat.signPsbt(
    "70736274ff01007d....",
    {
        autoFinalized:false,
        toSignInputs:[
          {
            index: 0,
            address: "tb1q8h8....mjxzny",
          },
          {
            index: 1,
            publicKey: "tb1q8h8....mjxzny",
            sighashTypes: [1]
          },
          {
            index: 2,
            publicKey: "02062...8779693f",
          }
        ]
    }
  );
  console.log(res)
} catch (e) {
  console.log(e);
}

unisat.signPsbt("xxxxxxxx",{toSignInputs:[{index:0,publicKey:"xxxxxx",disableTweakSigner:true}],autoFinalized:false})
GGG888GGG commented 2 months ago

@amarcu

amarcu commented 2 months ago

Thanks for the help.