0

If we create a transaction body in the backend using cardano-cli for example, and only for signing the transaction would like to get the frontend wallet to sign it, how is this done in the best possible way ?

2 Answers 2

1

Basically, there are two ways:

  1. After getting the transaction in the frontend, load the CBOR to CSL (cardano-serialization-lib), and proceed from there.

The workflow would be: build the transaction with cardano-cli, sign it with some random wallet stored in backend, send the signed transaction CBOR to frontend, deserialize the CBOR to CSL Transaction object, remove the witness you signed with in backend, call any wallet extension (eternl, nami..) injected signTx() method and get current user witness, add it to the CSL Transaction object and submit it with submitTx() wallet method.

This worked fine for me with Alonzo era and simple transactions, but had some problems with complicated (inline datums, plutusV2 scripts, etc.) Babbage era transactions. You kind of need to dig deep into CSL to make it work. So I chose the second, easier approach.

  1. Build the transaction using cardano-cli, send it to the frontend in order to retrieve a witness, return both transaction CBOR and witness to backend, assemble the transaction and submit it.

In depth steps:

  1. cardano-cli transaction build-raw --babbage-era --cddl-format ...

build instead of build-raw also works. Do not forget to add --cddl-format flag, in order for frontend sign() method to understand the format. Also you do not need to sign the transaction, only build it.

  1. Send built transaction CBOR to frontend

  2. encodedTxVkeyWitnesses = await window.signTx(cbor, true)

Call signTx() wallet method with received CBOR as a parameter. You will get the encdoded witness, which is basically a proof that user signed the transaction. The resulting hex string will look like this: a10081825820cccfe2be401c85342497f6e1e4a241629790b0fb7f2af5f18441779d11f25b1f5840c38a93d63faac9335ecc2f24ead7ca2d46a6637f354ee707bb06eb8192af2fa6a676fb72f8772cd1c42b491ec6dfc798c76b61c55dc4eecab362e71ffab26305

  1. await handleSubmit(cbor, encodedTxVkeyWitnesses)

Call your backend from frontend, and pass the very same transaction CBOR you received from backend and recently acquired witness CBOR.

  1. $witnessCbor = substr($encodedTxVkeyWitnesses, strpos($encodedTxVkeyWitnesses,'825820'), (strlen($encodedTxVkeyWitnesses) - strpos($encodedTxVkeyWitnesses,'825820')));

Note: example is in PHP. signTx() method returns a bit different witness structure than required by cardano-cli. You basically need to strip first 6 chars from the string. They represent data structure, in this case some nested arrays and stuff. You can look at structure differences here, by comparing both stripped and not stripped hex witness CBOR strings: https://cbor.nemo157.com/

6.

transactionCborFile = '
        {
            "type": "Unwitnessed Tx BabbageEra",
            "description": "Ledger Cddl Format",
            "cborHex": "<transaction CBOR here>"
        }
    ';
    $witnessCborFile = '
        {
            "type": "TxWitness BabbageEra",
            "description": "Key Witness ShelleyEra",
            "cborHex": "<stripped witness CBOR here>"
        }
    ';

Create two files as described above containing transaction and witness CBOR, as cardano-cli assemble command require files as parameters.

  1. cardano-cli transaction assemble --tx-body-file <transaction_cbor_file_path> --witness-file <witness_cbor_file_path> --out-file tx.assembled

Use cardano-cli assemble command to combine both transaction and witness CBOR in order to receive a signed transaction. At this point, transaction is signed and is ready to be submitted.

  1. cardano-cli transaction submit $MAGIC --tx-file tx.assembled

That's it!

1
  • I cannot thank you enough I have spent 2 days trying to solve this problem using every permutation I could think of and then I stumbled upon this post after being at my wits end. Thankyou!
    – DeafMap
    Commented Feb 19, 2023 at 13:37
0

I have a different type of example that might be helpful to anyone looking for ways to sign (and build) transactions using both a browser wallet and a server side private key. Code is here https://github.com/lley154/helios-examples/tree/main/nft-multisig And video https://youtu.be/CSd9ev_XH5w

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.