{"version":3,"sources":["../src/bitcoinUtils/selectUTXOs.ts"],"sourcesContent":["import { hasAny, sortBy } from \"../utils/arrayHelpers\"\nimport { MAX_BIGINT, sum } from \"../utils/bigintHelpers\"\nimport {\n  isSameUTXO,\n  sumUTXO,\n  UTXOBasic,\n  UTXOConfirmed,\n  UTXOSpendable,\n} from \"./bitcoinHelpers\"\nimport { decodeHex } from \"../utils/hexHelpers\"\nimport { isNotNull } from \"../utils/typeHelpers\"\nimport { ReselectSpendableUTXOsFn } from \"./prepareTransaction\"\n\nexport type GetConfirmedSpendableUTXOFn = (\n  utxo: UTXOBasic,\n) => Promise<undefined | (UTXOSpendable & UTXOConfirmed)>\n\nexport const reselectSpendableUTXOsFactory = (\n  availableUTXOs: UTXOBasic[],\n  getUTXOSpendable: GetConfirmedSpendableUTXOFn,\n): ReselectSpendableUTXOsFn => {\n  return async (satsToSend, pinnedUTXOs, _lastTimeSelectedUTXOs) => {\n    const lastTimeSelectedUTXOs = await Promise.all(\n      _lastTimeSelectedUTXOs.map(getUTXOSpendable),\n    ).then(utxos => utxos.filter(isNotNull))\n\n    const otherAvailableUTXOs = await Promise.all(\n      availableUTXOs\n        .filter(\n          availableUTXO =>\n            !lastTimeSelectedUTXOs.find(selectedUTXO =>\n              isSameUTXO(availableUTXO, selectedUTXO),\n            ),\n        )\n        .map(getUTXOSpendable),\n    ).then(utxos => utxos.filter(isNotNull))\n\n    return selectUTXOs(satsToSend, lastTimeSelectedUTXOs, otherAvailableUTXOs)\n  }\n}\n\nexport const reselectSpendableUTXOsWithSafePadFactory = (\n  availableUTXOs: UTXOBasic[],\n  getUTXOSpendable: GetConfirmedSpendableUTXOFn,\n): ReselectSpendableUTXOsFn => {\n  const reselect = reselectSpendableUTXOsFactory(\n    availableUTXOs,\n    getUTXOSpendable,\n  )\n\n  return async (satsToSend, pinnedUTXOs, lastTimeSelectedUTXOs) => {\n    const utxos = await reselect(satsToSend, pinnedUTXOs, lastTimeSelectedUTXOs)\n    const selectedAmount = sumUTXO(utxos)\n\n    const difference = satsToSend - selectedAmount\n    if (difference > 0n) {\n      return utxos.concat({\n        addressType: \"p2pkh\",\n        txId: \"0000000000000000000000000000000000000000000000000000000000000000\",\n        index: 0,\n        amount: MAX_BIGINT,\n        /**\n         * OutScript.encode({\n         *   type: 'pkh',\n         *   hash: hash160(secp256k1.getPublicKey(\n         *     hex.decode('0000000000000000000000000000000000000000000000000000000000000001'),\n         *     false,\n         *   ))\n         * })\n         */\n        scriptPubKey: decodeHex(\n          \"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\",\n        ),\n        isPublicKeyCompressed: false,\n      })\n    }\n\n    return utxos\n  }\n}\n\nexport function selectUTXOs<T extends UTXOConfirmed>(\n  satsToSend: bigint,\n  selectedUTXOs: T[],\n  otherAvailableUTXOs: T[],\n): T[] {\n  const inputs: Array<T> = []\n\n  let sumValue = 0n\n\n  otherAvailableUTXOs = otherAvailableUTXOs.slice()\n\n  if (hasAny(selectedUTXOs)) {\n    inputs.push(...selectedUTXOs)\n    sumValue = sum([sumValue, ...selectedUTXOs.map(o => o.amount)])\n  }\n\n  // Sort UTXOs:\n  // 1. By amount in descending order\n  // 2. By block height in ascending order\n  otherAvailableUTXOs = sortBy(\n    [o => -o.amount, o => o.blockHeight],\n    otherAvailableUTXOs,\n  )\n\n  for (const utxo of otherAvailableUTXOs) {\n    inputs.push(utxo)\n    sumValue = sumValue + utxo.amount\n\n    if (sumValue >= satsToSend) {\n      break\n    }\n  }\n\n  return inputs\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAiBO,IAAM,gCAAgC,CAC3C,gBACA,qBAC6B;AAC7B,SAAO,OAAO,YAAY,aAAa,2BAA2B;AAChE,UAAM,wBAAwB,MAAM,QAAQ;AAAA,MAC1C,uBAAuB,IAAI,gBAAgB;AAAA,IAC7C,EAAE,KAAK,WAAS,MAAM,OAAO,SAAS,CAAC;AAEvC,UAAM,sBAAsB,MAAM,QAAQ;AAAA,MACxC,eACG;AAAA,QACC,mBACE,CAAC,sBAAsB;AAAA,UAAK,kBAC1B,WAAW,eAAe,YAAY;AAAA,QACxC;AAAA,MACJ,EACC,IAAI,gBAAgB;AAAA,IACzB,EAAE,KAAK,WAAS,MAAM,OAAO,SAAS,CAAC;AAEvC,WAAO,YAAY,YAAY,uBAAuB,mBAAmB;AAAA,EAC3E;AACF;AAEO,IAAM,2CAA2C,CACtD,gBACA,qBAC6B;AAC7B,QAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,EACF;AAEA,SAAO,OAAO,YAAY,aAAa,0BAA0B;AAC/D,UAAM,QAAQ,MAAM,SAAS,YAAY,aAAa,qBAAqB;AAC3E,UAAM,iBAAiB,QAAQ,KAAK;AAEpC,UAAM,aAAa,aAAa;AAChC,QAAI,aAAa,IAAI;AACnB,aAAO,MAAM,OAAO;AAAA,QAClB,aAAa;AAAA,QACb,MAAM;AAAA,QACN,OAAO;AAAA,QACP,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAUR,cAAc;AAAA,UACZ;AAAA,QACF;AAAA,QACA,uBAAuB;AAAA,MACzB,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AACF;AAEO,SAAS,YACd,YACA,eACA,qBACK;AACL,QAAM,SAAmB,CAAC;AAE1B,MAAI,WAAW;AAEf,wBAAsB,oBAAoB,MAAM;AAEhD,MAAI,OAAO,aAAa,GAAG;AACzB,WAAO,KAAK,GAAG,aAAa;AAC5B,eAAW,IAAI,CAAC,UAAU,GAAG,cAAc,IAAI,OAAK,EAAE,MAAM,CAAC,CAAC;AAAA,EAChE;AAKA,wBAAsB;AAAA,IACpB,CAAC,OAAK,CAAC,EAAE,QAAQ,OAAK,EAAE,WAAW;AAAA,IACnC;AAAA,EACF;AAEA,aAAW,QAAQ,qBAAqB;AACtC,WAAO,KAAK,IAAI;AAChB,eAAW,WAAW,KAAK;AAE3B,QAAI,YAAY,YAAY;AAC1B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}