spacebudz / lucid

Lucid is a library, which allows you to create Cardano transactions and off-chain code for your Plutus contracts in JavaScript, Deno and Node.js.
https://lucid.spacebudz.io
MIT License
339 stars 139 forks source link

Fee Estimation issue when building contract remdemption TX on the backend. #230

Open Legionaaa opened 11 months ago

Legionaaa commented 11 months ago

We're building a TX like this: let tx;

if (Object.keys(restakeUnits).length > 0) {
  tx = await lucid.newTx()
    .collectFrom([cashUtxo])
    .collectFrom(unitUtxo, redeemer)
    .addSignerKey(vPKH)
    .addSignerKey(uPKH)
    .attachSpendingValidator(contractScript)
    .payToContract(
      frankenAddress,
      { inline: datum },
      restakeUnits,
    )
    .complete(changeAddress);
} else {
  tx = await lucid.newTx()
    .collectFrom([cashUtxo])
    .collectFrom(unitUtxo, redeemer)
    .addSignerKey(vPKH)
    .addSignerKey(uPKH)
    .attachSpendingValidator(contractScript)
    .complete(changeAddress);
}

const txSigned = await tx.signWithPrivateKey(validatorKey).complete();

We're signing it on the backend (as it's required by the contract), and the TX is returned to the frontend to be signed by the user. So they can redeem.

The issue is the fee calculation is always a few lovelace short

`0: {"requiredFee":225538,"actualFee":225494}`

I assume this is something to do with it taking into account the second signature size? Is there a way to juice the fee to take this into account or other workaround ?

joacohoyos commented 10 months ago

If you require a backend signature and a frontend signature, you should use tx.partialSignWithPrivateKey which will return you the witnessSet instead of the signedTx.

After the user signs the transaction, you can assemble both witnesses and then I'm pretty sure the fee should be correct.

 const userWitness = <user signature from the frontend>
 const backendWitness = tx.partialSignWithPrivateKey(validatorKey);
 const signedTx = await tx.assemble([userWitness, backendWitness]).complete()