input-output-hk / nami

Nami Wallet is a browser based wallet extension to interact with the Cardano blockchain. Support requests: https://iohk.zendesk.com/hc/en-us/requests/new
https://namiwallet.io
Apache License 2.0
373 stars 168 forks source link

Implement balancing unbalanced transactions #183

Open Jeyhey opened 2 years ago

Jeyhey commented 2 years ago

The Nami browser extension API implements signTx and submitTx but no balanceTx. The latter is needed because the standard way to execute smart contracts on Cardano is to fetch an unbalanced transaction from the Plutus Application Backend and have the user wallet add the missing input UTxO, the collateral, and balance the whole thing.

The Nami-demo of the Plutus repository also mentions that the function is missing and should be exposed: https://github.com/input-output-hk/plutus-apps/blob/main/plutus-pab-executables/demo/pab-nami/client/src/Cardano/Wallet/Nami.js#L71

Can we expect an implementation, or does the Nami-team disagree and does not think that this function should be exposed ?

alessandrokonrad commented 2 years ago

The problem is, if Nami has to balance the tx it also has to calculate the fees. Plutus Core is not available in the browser yet, so Nami could not calculate the execution units and fees properly.

Jeyhey commented 2 years ago

I don't think this is true. Nami already has to calculate the fees for simple transactions such as transferring funds and native assets. You can see the fee calculation for instance here: https://github.com/Berry-Pool/nami-wallet/blob/main/src/api/extension/wallet.js

The tricky thing is not the fees but the balancing: making sure enough funds are included (and finding the optimal set of input UTxOs), that exceeding funds get back to the address, that all UTxOs have the minimum Ada value. But again, this is not something Nami does not already do.

And as mentioned in my question above, having the wallet do the balancing is the standard way according to Cardano.

alessandrokonrad commented 2 years ago

Calculating fees based on tx size is something different than also taking execution units into account. If you add inputs and outputs to the transaction you change the ScriptContext and so Nami needs to exectute all scripts with the transaction as context, but it's not possible without Plutus Core.

Jeyhey commented 2 years ago

Ok, very valid point ! This seems to make it unrealistic that browser extensions implement balancing transactions, doesn't it ?

Jeyhey commented 2 years ago

I referenced this discussion on Cardano StackExchange: https://cardano.stackexchange.com/questions/6188/how-can-i-get-a-fully-build-transaction-from-the-pab

koslambrou commented 2 years ago

From my understanding, no need to execute the scripts to calculate the execution units.

You have access to the ExUnit of each Redeemer inside the tx's witness set. The Redeemer contains the ExUnit needed to compute the min fee of a tx.

See cardano-wallet's reference implementation: https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/balanceTransaction. The function does a bunch of clever stuff, but ultimately calculates the min fee of the final transaction with the minfee function in cardano-ledger-specs

alessandrokonrad commented 2 years ago

You have access to the ExUnit of each Redeemer inside the tx's witness set. The Redeemer contains the ExUnit needed to compute the min fee of a tx.

The ExUnits change when the ScriptContext gets changed, which depends on inputs and outputs. So Nami needs to calculate the ExUnits again, this only works if it can run the scripts.

koslambrou commented 2 years ago

Thanks @alessandrokonrad I see it now! cardano-wallet actually DOES re-execute the scripts after the transaction changes.

Jeyhey commented 2 years ago

@alessandrokonrad Is it possible to give some details on why it is not possible to run Plutus Core scripts in the browser and which components would be necessary to achieve this ? I know, it is the task of the Plutus team to implement this, but I think the views of a major wallet developer on this are also relevant and of interest.

klarkc commented 2 years ago

While is still not possible to implement a browser-only solution for this, https://github.com/Plutonomicon/cardano-transaction-lib has a nice example of this using some services to fill the gaps.

Anviking commented 1 year ago

Hello! Is there still interest in having a JS balanceTx library (exUnit eval under the hood without remote calls)?

We're close to extracting the balanceTx implementation from cardano-wallet into a standalone Haskell library. When that is done, and we've also upgraded to GHC-9.6, we should be able to look into compiling to JS.

cc @dclark-iohk