user-1: Looks like there is no activity in caravan github repository so maybe someone here can help me with this issue. Already mentioned everything in the below link however my three basic questions are:
https://github.com/unchained-capital/caravan/issues/173

How does tx size and fees calculation work in caravan?
How does it work in other projects if there is any better implementation?
Will there be a standard and easy approach to solve this problem in future which can be easily used by every bitcoin project?



user5406: Generally, the vsize and weight of transactions is determined by counting the byte length of the serialized transaction, and by weighting the different parts of the transactions according to the rules of segwit. As most transactions use standard scripts, the input and output sizes are known in advance and the transaction size can be easily estimated from the count of inputs and outputs (and their script types). Since ECDSA signatures can have a slightly variable size, the transaction weight is usually estimated by using the largest possible weight (safest), or the expected weight. Signature size can be homogenized by using signature grinding.
According to its package.json, Caravan uses bitcoinjs-lib.
bitcoinjs-lib is an established JavaScript library for address and transaction related tooling.
The code for calculating the weight of a transactions in bitcoinjs-lib is found in the Transaction class, specifically in the Transaction.weight() function. After the weight has been determined, the fee is calculated by weight and fee rate. As far as I am aware, bitcoinjs-lib does not provide its own fee rate estimates, so Caravan would likely rely on one of the many publicly available APIs to get a fee rate estimate.
BitGo provides an opensource library called unspents that calculates the virtual size of transactions in dimensions.ts. It's inspired by bitcoinjs-lib but has a special focus on multsig inputs. (Disclaimer: I have contributed code to unspents.)
There are similar libraries for other programming languages to provide tools for creating Bitcoin transactions and addresses.

user109448: The fee rate is pulled here:
export function fetchFeeEstimate(network, client) {
  if (client.type === BLOCK_EXPLORER) {
    return blockExplorerGetFeeEstimate(network);
  }
  return bitcoindEstimateSmartFee({
    ...bitcoindParams(client),
    ...{ numBlocks: 1 },
  });
}

(https://github.com/unchained-capital/caravan/blob/3514039983984e184e8babb6c61c21a46798fc70/src/blockchain.js#L97-L105)
It depends on if you are using a block explorer or a local bitcoind node.
If using bitcoind, it uses the estimatesmartfee rpi cal:
export async function bitcoindEstimateSmartFee({ url, auth, numBlocks = 2 }) {
  const resp = await callBitcoind(url, auth, "estimatesmartfee", [numBlocks]);
  const feeRate = resp.result.feerate;
  return Math.ceil(feeRate * 100000);
}

(https://github.com/unchained-capital/caravan/blob/3514039983984e184e8babb6c61c21a46798fc70/src/bitcoind.js#L111-L115)
As for the transaction size/ total fee calculation, caravan uses estimateMultisigTransactionFee from unchained-bitcoin
(https://github.com/unchained-capital/caravan/blob/fd214eb573c7185c01dfa2040aa914e87a0de359/src/actions/walletActions.js#L129)
Which depending on the transaction type (P2SH, P2WSH, P2SH-P2WSH) calls a transaction size estimator. The P2SH one is:
export function estimateMultisigP2SHTransactionVSize(config) {
  const baseSize = 41 * config.numInputs + 34 * config.numOutputs + 30;
  const signatureLength = 72 + 1; // approx including push byte
  const scriptOverhead = 4; 
  const keylength = 33 + 1;  // push byte
  const sigSize = signatureLength*config.m*config.numInputs + keylength*config.n*config.numInputs + scriptOverhead*config.numInputs;
  const vsize = baseSize + sigSize;
  return vsize;
}

(https://github.com/unchained-capital/unchained-bitcoin/blob/e9177e7171c3bf11ad5c245c7d633dac484f409c/src/p2sh.js#L27-L35)
Regarding your other questions, I look forward to hearing more about this. When we wrote this, I wasn't aware of unspents. It would be nice if there was a standard, well-tested package for calculating transaction fees.
Regarding other projects: Lily uses unchained-bitcoin: (https://github.com/KayBeSee/lily-wallet/blob/5945175f9e25cc7a8ff29159de39c228b79ef205/src/pages/Send/utils.js#L48) so it's the same as Caravan. I don't know what Casa does. I would assume BitGo uses unspents that Murch linked to. I'm pretty sure Electrum has it's own thing, but I haven't looked, I'd assume the same for Specter.
Hope this helps, sorry we didn't get back to you on the caravan issue, infomational tickets like that are low-priority for us right now.

-1: <p>Looks like there is no activity in caravan github repository so maybe someone here can help me with this issue. Already mentioned everything in the below link however my three basic questions are:</p>
<p><a href="https://github.com/unchained-capital/caravan/issues/173" rel="nofollow noreferrer">https://github.com/unchained-capital/caravan/issues/173</a></p>
<ol>
<li>How does tx size and fees calculation work in caravan?</li>
<li>How does it work in other projects if there is any better implementation?</li>
<li>Will there be a standard and easy approach to solve this problem in future which can be easily used by every bitcoin project?</li>
</ol>
<p><a href="https://i.stack.imgur.com/zRQrd.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/zRQrd.png" alt="Screenshot-Caravan" /></a></p>
 5406: <p>Generally, the vsize and weight of transactions is determined by counting the byte length of the serialized transaction, and by weighting the different parts of the transactions according to the rules of segwit. As most transactions use standard scripts, the input and output sizes are known in advance and the transaction size can be easily estimated from the count of inputs and outputs (and their script types). Since ECDSA signatures can have a slightly variable size, the transaction weight is usually estimated by using the largest possible weight (safest), or the expected weight. Signature size can be homogenized by using signature grinding.</p>
<p>According to its <code>package.json</code>, <code>Caravan</code> uses <code>bitcoinjs-lib</code>.
<code>bitcoinjs-lib</code> is an established JavaScript library for address and transaction related tooling.</p>
<p>The code for calculating the weight of a transactions in <code>bitcoinjs-lib</code> is found in the <code>Transaction</code> class, specifically in the <a href="https://github.com/bitcoinjs/bitcoinjs-lib/blob/68fb3cdb1167677e0df86ffaee11cb7cacdf3562/src/transaction.js#L148" rel="nofollow noreferrer"><code>Transaction.weight()</code></a> function. After the weight has been determined, the fee is calculated by weight and fee rate. As far as I am aware, <code>bitcoinjs-lib</code> does not provide its own fee rate estimates, so <code>Caravan</code> would likely rely on one of the many publicly available APIs to get a fee rate estimate.</p>
<p>BitGo provides an opensource library called <code>unspents</code> that calculates the virtual size of transactions in <a href="https://github.com/BitGo/unspents/blob/2af6ac31cd2b34086918f9e6915d290bdc8bf275/src/dimensions.ts#L65" rel="nofollow noreferrer"><code>dimensions.ts</code></a>. It's inspired by <code>bitcoinjs-lib</code> but has a special focus on multsig inputs. (Disclaimer: I have contributed code to <code>unspents</code>.)</p>
<p>There are similar libraries for other programming languages to provide tools for creating Bitcoin transactions and addresses.</p>
 109448: <p>The fee rate is pulled here:</p>
<pre><code>export function fetchFeeEstimate(network, client) {
  if (client.type === BLOCK_EXPLORER) {
    return blockExplorerGetFeeEstimate(network);
  }
  return bitcoindEstimateSmartFee({
    ...bitcoindParams(client),
    ...{ numBlocks: 1 },
  });
}
</code></pre>
<p>(<a href="https://github.com/unchained-capital/caravan/blob/3514039983984e184e8babb6c61c21a46798fc70/src/blockchain.js#L97-L105" rel="nofollow noreferrer">https://github.com/unchained-capital/caravan/blob/3514039983984e184e8babb6c61c21a46798fc70/src/blockchain.js#L97-L105</a>)</p>
<p>It depends on if you are using a block explorer or a local bitcoind node.
If using bitcoind, it uses the <code>estimatesmartfee</code> rpi cal:</p>
<pre><code>export async function bitcoindEstimateSmartFee({ url, auth, numBlocks = 2 }) {
  const resp = await callBitcoind(url, auth, &quot;estimatesmartfee&quot;, [numBlocks]);
  const feeRate = resp.result.feerate;
  return Math.ceil(feeRate * 100000);
}
</code></pre>
<p>(<a href="https://github.com/unchained-capital/caravan/blob/3514039983984e184e8babb6c61c21a46798fc70/src/bitcoind.js#L111-L115" rel="nofollow noreferrer">https://github.com/unchained-capital/caravan/blob/3514039983984e184e8babb6c61c21a46798fc70/src/bitcoind.js#L111-L115</a>)</p>
<p>As for the transaction size/ total fee calculation, caravan uses <code>estimateMultisigTransactionFee</code> from <code>unchained-bitcoin</code>
(<a href="https://github.com/unchained-capital/caravan/blob/fd214eb573c7185c01dfa2040aa914e87a0de359/src/actions/walletActions.js#L129" rel="nofollow noreferrer">https://github.com/unchained-capital/caravan/blob/fd214eb573c7185c01dfa2040aa914e87a0de359/src/actions/walletActions.js#L129</a>)</p>
<p>Which depending on the transaction type (P2SH, P2WSH, P2SH-P2WSH) calls a transaction size estimator. The P2SH one is:</p>
<pre><code>export function estimateMultisigP2SHTransactionVSize(config) {
  const baseSize = 41 * config.numInputs + 34 * config.numOutputs + 30;
  const signatureLength = 72 + 1; // approx including push byte
  const scriptOverhead = 4; 
  const keylength = 33 + 1;  // push byte
  const sigSize = signatureLength*config.m*config.numInputs + keylength*config.n*config.numInputs + scriptOverhead*config.numInputs;
  const vsize = baseSize + sigSize;
  return vsize;
}
</code></pre>
<p>(<a href="https://github.com/unchained-capital/unchained-bitcoin/blob/e9177e7171c3bf11ad5c245c7d633dac484f409c/src/p2sh.js#L27-L35" rel="nofollow noreferrer">https://github.com/unchained-capital/unchained-bitcoin/blob/e9177e7171c3bf11ad5c245c7d633dac484f409c/src/p2sh.js#L27-L35</a>)</p>
<p>Regarding your other questions, I look forward to hearing more about this. When we wrote this, I wasn't aware of <code>unspents</code>. It would be nice if there was a standard, well-tested package for calculating transaction fees.</p>
<p>Regarding other projects: Lily uses <code>unchained-bitcoin</code>: (<a href="https://github.com/KayBeSee/lily-wallet/blob/5945175f9e25cc7a8ff29159de39c228b79ef205/src/pages/Send/utils.js#L48" rel="nofollow noreferrer">https://github.com/KayBeSee/lily-wallet/blob/5945175f9e25cc7a8ff29159de39c228b79ef205/src/pages/Send/utils.js#L48</a>) so it's the same as Caravan. I don't know what Casa does. I would assume BitGo uses <code>unspents</code> that Murch linked to. I'm pretty sure Electrum has it's own thing, but I haven't looked, I'd assume the same for Specter.</p>
<p>Hope this helps, sorry we didn't get back to you on the caravan issue, infomational tickets like that are low-priority for us right now.</p>
