<p>I also struggled getting this to work via the cli.  I went with a solution using the Java <code>cardano-client-lib</code> on the backend to create the base tx, and the <code>cardano-serialization-lib</code> browser package in the browser to add a sig.</p>
<p>here's the relevant browser code (selectively copy-pasted from my project, YMMV)</p>
<pre><code>import * as CardanoSerdes from '@emurgo/cardano-serialization-lib-browser'
const Buffer = require('buffer/').Buffer

// helpers
function toHex(bytes) { return Buffer.from(bytes).toString(&quot;hex&quot;) }
function fromHex(str) { return Buffer.from(str, &quot;hex&quot;) }

const txCborHex = &quot;YOUR BASE TX CBOR HEX HERE&quot;

const namiAddr = &quot;nami wallet addr here&quot;

// parse the base tx into the serialization lib model
const transaction = CardanoSerdes.Transaction.from_bytes(Buffer.from(txCborHex, &quot;hex&quot;))
const transactionWitnessSet = transaction.witness_set()
const transactionBody = transaction.body()

// get a handle on the PubKeyHash for the wallet
const walletAddress = CardanoSerdes.Address.from_bech32(namiAddr)
const baseAddress = CardanoSerdes.BaseAddress.from_address(walletAddress);
const baseAddrBytes = baseAddress.payment_cred().to_keyhash().to_bytes()
const pkh = CardanoSerdes.Ed25519KeyHash.from_bytes(baseAddrBytes)

// Add the pkh as a required signer
const requiredSigners = CardanoSerdes.Ed25519KeyHashes.new();
requiredSigners.add(pkh);
transactionBody.set_required_signers(requiredSigners);

// draft a new tx for the user to sign
let toSign = CardanoSerdes.Transaction.new(transactionBody, transactionWitnessSet);

// get the user to sign the base tx in the browser via nami
let txVkeyWitnesses = await cardano.signTx(
    toHex(toSign.to_bytes()),
    true
);
txVkeyWitnesses = CardanoSerdes.TransactionWitnessSet.from_bytes(
    fromHex(txVkeyWitnesses)
);

// add the sig to the base tx witness set
transactionWitnessSet.set_vkeys(txVkeyWitnesses.vkeys());

// compose a new tx
const readyToSubmit = CardanoSerdes.Transaction.new(transactionBody, transactionWitnessSet);

// convert to cbor hex.  you can submit this in the browser with cardano.submitTx() or using cli on the backend
const finalTx = toHex(readyToSubmit.to_bytes())
</code></pre>
<p>the npm deps in use are:</p>
<pre><code>    &quot;@emurgo/cardano-serialization-lib-browser&quot;: &quot;^9.1.2&quot;,
    &quot;buffer&quot;: &quot;^6.0.3&quot;,
</code></pre>
<p>java dep</p>
<pre><code>'com.bloxbean.cardano:cardano-client-lib:0.2.0-preview2'
</code></pre>

CC BY-SA 4.0
2022-03-08T14:22:28.133Z
This turned out to be a very useful answer for integrating a multi-sig pattern with Nami wallet. Thanks for the detailed answer and code.
spirois
CC BY-SA 4.0
2021-12-23T13:14:43.940Z
2021-12-23T13:22:03.827Z
2021-12-23T13:22:03.827Z
base2c
<p>I made a post on this, maybe this can help you. Basically you'd need to first sign transaction with cli, load transaction to cardano-serialization-lib, clear vkeys from witness-set, sign transaction on the frontend and add vkeys from signature witness-set.</p>
<p>Here's a link to my blogpost: <a href="https://srdjanstankovic.com/2021/12/24/how-to-sign-and-submit-cardano-cli-transaction-using-nami-wallet.html" rel="nofollow noreferrer">https://srdjanstankovic.com/2021/12/24/how-to-sign-and-submit-cardano-cli-transaction-using-nami-wallet.html</a></p>

CC BY-SA 4.0
2021-12-30T08:19:41.807Z
2021-12-30T08:19:41.807Z
pyropy
<p>The problem is that cardano-serialisazion-lib reorders the transaction and that makes the original witness invalid, <a href="https://github.com/Emurgo/cardano-serialization-lib/issues/311" rel="nofollow noreferrer">https://github.com/Emurgo/cardano-serialization-lib/issues/311</a></p>
<p>My solution was</p>
<ul>
<li>create tx with cardano-cli</li>
<li>deserialize with cardano-serialisazion-lib</li>
<li>serialize with cardano-serialisazion-lib</li>
<li>sign with cli</li>
</ul>

CC BY-SA 4.0
2022-07-18T18:18:40.130Z
2022-07-18T18:18:40.130Z
wutzebaer
<p>I am attempting to sign and submit a simple &quot;always succeeds&quot; transaction body built by the CLI and signed with nami wallet.</p>
<p><code>cardano-cli transaction build-raw \ --alonzo-era \ --fee 200000 \ --tx-in {NAMI_ADDRESS_UTXO} \ --tx-out {SCRIPT_ADDRESS}+1800000 \ --tx-out {NAMI_ADDRESS}+998000000 \ --invalid-hereafter 50000000 \ --protocol-params-file protocol.json \ --out-file tx-script.draft</code></p>
<p>Signing this file with an initial key in the CLI, I then sign it with nami using
<code>const witnessSet = await window.cardano.signTx(transaction, true);</code></p>
<p>Generating the following hex CBOR:
<code>a10081825820863d383db3cc7494604d02d3bf214706a18a178ce50eb1f04ad3ef45f50815735840da3ef50001e801bb9580ea361cff86fedef6aab41ebf835dbd246afae02a8b380cbfef0bb1c1ad299b57837dcc04d22a8fc81d713989160513fb14020b7ca203</code></p>
<p>This hex is sent to the back-end where I do some transformations to get the set in the form of [0, [vkey witnesses]].</p>
<pre><code>let bufferWitness = Buffer.from(witnessSet, &quot;hex&quot;);
let witnessDecoded = await cbor.decodeFirst(bufferWitness);

const newWitness = [0]; // Array format accepted by the CLI
newWitness.push(witnessDecoded.get(0)[0]); // vkey witness generated by Nami
console.log('Result:', cbor.encode(newWitness).toString(&quot;hex&quot;));
</code></pre>
<p>This generates the following hex CBOR:
<code>8200825820863d383db3cc7494604d02d3bf214706a18a178ce50eb1f04ad3ef45f50815735840da3ef50001e801bb9580ea361cff86fedef6aab41ebf835dbd246afae02a8b380cbfef0bb1c1ad299b57837dcc04d22a8fc81d713989160513fb14020b7ca203</code></p>
<p>Decoded as:
<code> [0, [h'863D383DB3CC7494604D02D3BF214706A18A178CE50EB1F04AD3EF45F5081573', h'DA3EF50001E801BB9580EA361CFF86FEDEF6AAB41EBF835DBD246AFAE02A8B380CBFEF0BB1C1AD299B57837DCC04D22A8FC81D713989160513FB14020B7CA203']]</code></p>
<p>When I use <code>cardano-cli assemble</code> to generate the final transaction and submit, I get this error:</p>
<p><code>ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (InvalidWitnessesUTXOW [VKey (VerKeyEd25519DSIGN &quot;863d383db3cc7494604d02d3bf214706a18a178ce50eb1f04ad3ef45f5081573&quot;)]))])</code></p>
<p>Which I do not understand as the tx body is not altered by the time it is sent to Nami, only signed with a dummy key but I'm assuming that should not affect the witness generated?</p>
<p>Any help would be appreciated, thanks.</p>

<cardano-cli><nami-wallet>
Tx signed by Nami Wallet returning InvalidWitnessesUTXOW in CLI
# Tx signed by Nami Wallet returning InvalidWitnessesUTXOW in CLI

(Asked by: username_0 on 2021-12-18)

I am attempting to sign and submit a simple "always succeeds" transaction body built by the CLI and signed with nami wallet.
cardano-cli transaction build-raw \ --alonzo-era \ --fee 200000 \ --tx-in {NAMI_ADDRESS_UTXO} \ --tx-out {SCRIPT_ADDRESS}+1800000 \ --tx-out {NAMI_ADDRESS}+998000000 \ --invalid-hereafter 50000000 \ --protocol-params-file protocol.json \ --out-file tx-script.draft
Signing this file with an initial key in the CLI, I then sign it with nami using
const witnessSet = await window.cardano.signTx(transaction, true);
Generating the following hex CBOR:
a10081825820863d383db3cc7494604d02d3bf214706a18a178ce50eb1f04ad3ef45f50815735840da3ef50001e801bb9580ea361cff86fedef6aab41ebf835dbd246afae02a8b380cbfef0bb1c1ad299b57837dcc04d22a8fc81d713989160513fb14020b7ca203
This hex is sent to the back-end where I do some transformations to get the set in the form of [0, [vkey witnesses]].
let bufferWitness = Buffer.from(witnessSet, "hex");
let witnessDecoded = await cbor.decodeFirst(bufferWitness);

const newWitness = [0]; // Array format accepted by the CLI
newWitness.push(witnessDecoded.get(0)[0]); // vkey witness generated by Nami
console.log('Result:', cbor.encode(newWitness).toString("hex"));

This generates the following hex CBOR:
8200825820863d383db3cc7494604d02d3bf214706a18a178ce50eb1f04ad3ef45f50815735840da3ef50001e801bb9580ea361cff86fedef6aab41ebf835dbd246afae02a8b380cbfef0bb1c1ad299b57837dcc04d22a8fc81d713989160513fb14020b7ca203
Decoded as:
 [0, [h'863D383DB3CC7494604D02D3BF214706A18A178CE50EB1F04AD3EF45F5081573', h'DA3EF50001E801BB9580EA361CFF86FEDEF6AAB41EBF835DBD246AFAE02A8B380CBFEF0BB1C1AD299B57837DCC04D22A8FC81D713989160513FB14020B7CA203']]
When I use cardano-cli assemble to generate the final transaction and submit, I get this error:
ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (InvalidWitnessesUTXOW [VKey (VerKeyEd25519DSIGN "863d383db3cc7494604d02d3bf214706a18a178ce50eb1f04ad3ef45f5081573")]))])
Which I do not understand as the tx body is not altered by the time it is sent to Nami, only signed with a dummy key but I'm assuming that should not affect the witness generated?
Any help would be appreciated, thanks.

**Tags:** cardano-cli, nami-wallet

---

## 3 answers

### Answer by username_1 on 2021-12-23. Score: 2

I also struggled getting this to work via the cli.  I went with a solution using the Java cardano-client-lib on the backend to create the base tx, and the cardano-serialization-lib browser package in the browser to add a sig.
here's the relevant browser code (selectively copy-pasted from my project, YMMV)
import * as CardanoSerdes from '@emurgo/cardano-serialization-lib-browser'
const Buffer = require('buffer/').Buffer

// helpers
function toHex(bytes) { return Buffer.from(bytes).toString("hex") }
function fromHex(str) { return Buffer.from(str, "hex") }

const txCborHex = "YOUR BASE TX CBOR HEX HERE"

const namiAddr = "nami wallet addr here"

// parse the base tx into the serialization lib model
const transaction = CardanoSerdes.Transaction.from_bytes(Buffer.from(txCborHex, "hex"))
const transactionWitnessSet = transaction.witness_set()
const transactionBody = transaction.body()

// get a handle on the PubKeyHash for the wallet
const walletAddress = CardanoSerdes.Address.from_bech32(namiAddr)
const baseAddress = CardanoSerdes.BaseAddress.from_address(walletAddress);
const baseAddrBytes = baseAddress.payment_cred().to_keyhash().to_bytes()
const pkh = CardanoSerdes.Ed25519KeyHash.from_bytes(baseAddrBytes)

// Add the pkh as a required signer
const requiredSigners = CardanoSerdes.Ed25519KeyHashes.new();
requiredSigners.add(pkh);
transactionBody.set_required_signers(requiredSigners);

// draft a new tx for the user to sign
let toSign = CardanoSerdes.Transaction.new(transactionBody, transactionWitnessSet);

// get the user to sign the base tx in the browser via nami
let txVkeyWitnesses = await cardano.signTx(
    toHex(toSign.to_bytes()),
    true
);
txVkeyWitnesses = CardanoSerdes.TransactionWitnessSet.from_bytes(
    fromHex(txVkeyWitnesses)
);

// add the sig to the base tx witness set
transactionWitnessSet.set_vkeys(txVkeyWitnesses.vkeys());

// compose a new tx
const readyToSubmit = CardanoSerdes.Transaction.new(transactionBody, transactionWitnessSet);

// convert to cbor hex.  you can submit this in the browser with cardano.submitTx() or using cli on the backend
const finalTx = toHex(readyToSubmit.to_bytes())

the npm deps in use are:
    "@emurgo/cardano-serialization-lib-browser": "^9.1.2",
    "buffer": "^6.0.3",

java dep
'com.bloxbean.cardano:cardano-client-lib:0.2.0-preview2'

> **Comments:**
> **username_2**: This turned out to be a very useful answer for integrating a multi-sig pattern with Nami wallet. Thanks for the detailed answer and code.  

---

### Answer by username_3 on 2021-12-30. Score: 1

I made a post on this, maybe this can help you. Basically you'd need to first sign transaction with cli, load transaction to cardano-serialization-lib, clear vkeys from witness-set, sign transaction on the frontend and add vkeys from signature witness-set.

Here's a link to my blogpost: <https://srdjanstankovic.com/2021/12/24/how-to-sign-and-submit-cardano-cli-transaction-using-nami-wallet.html>


---

### Answer by username_4 on 2022-07-18. Score: 1

The problem is that cardano-serialisazion-lib reorders the transaction and that makes the original witness invalid, <https://github.com/Emurgo/cardano-serialization-lib/issues/311>

My solution was

* create tx with cardano-cli
* deserialize with cardano-serialisazion-lib
* serialize with cardano-serialisazion-lib
* sign with cli


---

