@exodus/bitcoin-api 2.8.1 → 2.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/bitcoin-api",
3
- "version": "2.8.1",
3
+ "version": "2.9.1",
4
4
  "description": "Exodus bitcoin-api",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -42,5 +42,5 @@
42
42
  "@scure/btc-signer": "^1.1.0",
43
43
  "jest-when": "^3.5.1"
44
44
  },
45
- "gitHead": "652eb821c1fe5b2bd561710d05fcb569d9f4a137"
45
+ "gitHead": "1f96673b2977e792373f9f3c4eb98c778817b2b6"
46
46
  }
@@ -6,12 +6,16 @@ export function createAccountState({ asset, ordinalsEnabled = false, brc20Enable
6
6
  })
7
7
  const defaults = {
8
8
  utxos: empty,
9
+ mem: {
10
+ unconfirmedTxAncestor: {},
11
+ },
9
12
  }
10
13
 
11
14
  if (ordinalsEnabled) {
12
15
  defaults.ordinalsUtxos = empty
13
16
  defaults.knownBalanceUtxoIds = []
14
17
  defaults.mustAvoidUtxoIds = []
18
+ defaults.additionalInscriptions = []
15
19
  }
16
20
 
17
21
  if (brc20Enabled) {
@@ -4,6 +4,7 @@ import { findUnconfirmedSentRbfTxs } from '../tx-utils'
4
4
  import { getUsableUtxos, getUtxos } from '../utxos-utils'
5
5
 
6
6
  import { BumpType } from '@exodus/bitcoin-lib'
7
+ import { getUnconfirmedTxAncestorMap } from '../unconfirmed-ancestor-data'
7
8
 
8
9
  export const ASSET_NAMES = ['bitcoin', 'bitcoinregtest', 'bitcointestnet']
9
10
 
@@ -51,13 +52,14 @@ const _canBumpTx = ({
51
52
  }
52
53
 
53
54
  const utxos = getUtxos({ accountState, asset })
54
-
55
+ const unconfirmedTxAncestor = getUnconfirmedTxAncestorMap({ accountState })
55
56
  const usableUtxos = getUsableUtxos({
56
57
  asset,
57
58
  utxos,
58
59
  feeData,
59
60
  txSet,
60
61
  allowUnconfirmedRbfEnabledUtxos,
62
+ unconfirmedTxAncestor,
61
63
  })
62
64
  if (usableUtxos.value.isZero) return { errorMessage: 'insufficient funds' }
63
65
 
@@ -86,6 +88,7 @@ const _canBumpTx = ({
86
88
  receiveAddress: null,
87
89
  getFeeEstimator,
88
90
  allowUnconfirmedRbfEnabledUtxos,
91
+ unconfirmedTxAncestor,
89
92
  })
90
93
  if (replaceTx) return { bumpType: BumpType.RBF, bumpFee: fee.sub(replaceTx.feeAmount) }
91
94
  }
@@ -98,6 +101,7 @@ const _canBumpTx = ({
98
101
  getFeeEstimator,
99
102
  mustSpendUtxos: changeUtxos,
100
103
  allowUnconfirmedRbfEnabledUtxos,
104
+ unconfirmedTxAncestor,
101
105
  })
102
106
 
103
107
  return fee ? { bumpType: BumpType.CPFP } : { errorMessage: 'insufficient funds' }
@@ -5,7 +5,7 @@ import assert from 'minimalistic-assert'
5
5
 
6
6
  export const isHex = (s) => typeof s === 'string' && /[0-9a-f]*/.test(s.toLowerCase())
7
7
 
8
- export function getExtraFee({ asset, inputs, feePerKB }) {
8
+ export function getExtraFee({ asset, inputs, feePerKB, unconfirmedTxAncestor }) {
9
9
  let extraFee = 0
10
10
  // Add extra fee to unconfirmed bitcoin utxos to allow transaction to CPFP ancestors
11
11
  if (
@@ -18,7 +18,12 @@ export function getExtraFee({ asset, inputs, feePerKB }) {
18
18
  )
19
19
  const txIds = new Set(utxos.map(({ txId }) => txId))
20
20
  for (const txId of txIds) {
21
- extraFee += resolveExtraFeeOfTx({ assetName: asset.name, feeRate, txId })
21
+ extraFee += resolveExtraFeeOfTx({
22
+ assetName: asset.name,
23
+ feeRate,
24
+ txId,
25
+ unconfirmedTxAncestor,
26
+ })
22
27
  }
23
28
  extraFee = Math.ceil(extraFee)
24
29
  }
@@ -26,9 +31,13 @@ export function getExtraFee({ asset, inputs, feePerKB }) {
26
31
  }
27
32
 
28
33
  export default function createDefaultFeeEstimator(getSize) {
29
- return (asset, feePerKB, options) => {
30
- return ({ inputs = options.inputs, outputs = options.outputs } = {}) => {
31
- const extraFee = getExtraFee({ asset, inputs, feePerKB })
34
+ return (asset, feePerKB, options = {}) => {
35
+ return ({
36
+ inputs = options.inputs,
37
+ outputs = options.outputs,
38
+ unconfirmedTxAncestor = options.unconfirmedTxAncestor,
39
+ } = {}) => {
40
+ const extraFee = getExtraFee({ asset, inputs, feePerKB, unconfirmedTxAncestor })
32
41
  // Yes, it's suppose to be '1000' and not '1024'
33
42
  // https://bitcoin.stackexchange.com/questions/24000/a-fee-is-added-per-kilobyte-of-data-that-means-1000-bytes-or-1024
34
43
  const size = getSize(asset, inputs, outputs, options)
@@ -3,6 +3,7 @@ import { getUtxosData } from './utxo-selector'
3
3
  import { findUnconfirmedSentRbfTxs } from '../tx-utils'
4
4
  import { getUsableUtxos, getUtxos } from '../utxos-utils'
5
5
  import { canBumpTx } from './can-bump-tx'
6
+ import { getUnconfirmedTxAncestorMap } from '../unconfirmed-ancestor-data'
6
7
 
7
8
  export class GetFeeResolver {
8
9
  #getFeeEstimator
@@ -10,7 +11,8 @@ export class GetFeeResolver {
10
11
 
11
12
  constructor({ getFeeEstimator, allowUnconfirmedRbfEnabledUtxos }) {
12
13
  assert(getFeeEstimator, 'getFeeEstimator must be provided')
13
- this.#getFeeEstimator = (asset, { feePerKB }) => getFeeEstimator(asset, feePerKB)
14
+ this.#getFeeEstimator = (asset, { feePerKB, ...options }) =>
15
+ getFeeEstimator(asset, feePerKB, options)
14
16
  this.#allowUnconfirmedRbfEnabledUtxos = allowUnconfirmedRbfEnabledUtxos
15
17
  }
16
18
 
@@ -92,12 +94,14 @@ export class GetFeeResolver {
92
94
  assert(txSet, 'txSet must be provided')
93
95
 
94
96
  const utxos = getUtxos({ accountState, asset })
97
+ const unconfirmedTxAncestor = getUnconfirmedTxAncestorMap({ accountState })
95
98
 
96
99
  const usableUtxos = getUsableUtxos({
97
100
  asset,
98
101
  utxos,
99
102
  feeData,
100
103
  txSet,
104
+ unconfirmedTxAncestor,
101
105
  })
102
106
  const replaceableTxs = findUnconfirmedSentRbfTxs(txSet)
103
107
 
@@ -113,6 +117,7 @@ export class GetFeeResolver {
113
117
  isSendAll: isSendAll,
114
118
  getFeeEstimator: this.#getFeeEstimator,
115
119
  allowUnconfirmedRbfEnabledUtxos: this.#allowUnconfirmedRbfEnabledUtxos,
120
+ unconfirmedTxAncestor,
116
121
  })
117
122
  }
118
123
 
@@ -29,6 +29,7 @@ export const selectUtxos = ({
29
29
  disableReplacement = false,
30
30
  mustSpendUtxos,
31
31
  allowUnconfirmedRbfEnabledUtxos,
32
+ unconfirmedTxAncestor,
32
33
  inscriptionIds, // for each inscription transfer, we need to calculate one more input and one more output
33
34
  }) => {
34
35
  const resolvedReceiveAddresses = getBestReceiveAddresses({
@@ -52,7 +53,7 @@ export const selectUtxos = ({
52
53
  ? 'P2WPKH'
53
54
  : 'P2PKH'
54
55
 
55
- const feeEstimator = getFeeEstimator(asset, { feePerKB: feeRate })
56
+ const feeEstimator = getFeeEstimator(asset, { feePerKB: feeRate, unconfirmedTxAncestor })
56
57
  const { currency } = asset
57
58
  if (!amount) amount = currency.ZERO
58
59
 
@@ -78,7 +79,7 @@ export const selectUtxos = ({
78
79
  feePerKB = feeRate
79
80
  }
80
81
 
81
- const replaceFeeEstimator = getFeeEstimator(asset, { feePerKB })
82
+ const replaceFeeEstimator = getFeeEstimator(asset, { feePerKB, unconfirmedTxAncestor })
82
83
  // how to avoid replace tx inputs when inputs are ordinals? !!!!
83
84
  const inputs = UtxoCollection.fromJSON(tx.data.inputs, { currency })
84
85
  const outputs = isSendAll
@@ -118,7 +119,10 @@ export const selectUtxos = ({
118
119
 
119
120
  // Add a new UTXO and recalculate the fee
120
121
  additionalUtxos = additionalUtxos.addUtxo(confirmedUtxosArray.shift())
121
- fee = replaceFeeEstimator({ inputs: inputs.union(additionalUtxos), outputs })
122
+ fee = replaceFeeEstimator({
123
+ inputs: inputs.union(additionalUtxos),
124
+ outputs,
125
+ })
122
126
  }
123
127
  }
124
128
  if (isSendAll || replaceTxAmount.add(additionalUtxos.value).gte(amount.add(fee))) {
@@ -224,6 +228,7 @@ export const getUtxosData = ({
224
228
  mustSpendUtxos,
225
229
  allowUnconfirmedRbfEnabledUtxos,
226
230
  inscriptionIds,
231
+ unconfirmedTxAncestor,
227
232
  }) => {
228
233
  const { selectedUtxos, replaceTx, fee } = selectUtxos({
229
234
  asset,
@@ -237,6 +242,7 @@ export const getUtxosData = ({
237
242
  disableReplacement,
238
243
  mustSpendUtxos,
239
244
  allowUnconfirmedRbfEnabledUtxos,
245
+ unconfirmedTxAncestor,
240
246
  inscriptionIds,
241
247
  })
242
248
 
@@ -252,7 +258,14 @@ export const getUtxosData = ({
252
258
  const spendableBalance = spendableUtxos.value
253
259
 
254
260
  const extraFee = selectedUtxos
255
- ? asset.currency.baseUnit(getExtraFee({ asset, inputs: selectedUtxos, feePerKB: feeRate }))
261
+ ? asset.currency.baseUnit(
262
+ getExtraFee({
263
+ asset,
264
+ inputs: selectedUtxos,
265
+ feePerKB: feeRate,
266
+ unconfirmedTxAncestor,
267
+ })
268
+ )
256
269
  : asset.currency.ZERO
257
270
 
258
271
  const availableBalance = spendableBalance.sub(resolvedFee).clampLowerZero()
@@ -603,6 +603,7 @@ export class BitcoinMonitorScanner {
603
603
  ordinalAddress,
604
604
  knownBalanceUtxoIds: latestAccountState.knownBalanceUtxoIds,
605
605
  mustAvoidUtxoIds: latestAccountState.mustAvoidUtxoIds,
606
+ additionalInscriptions: latestAccountState.additionalInscriptions,
606
607
  })
607
608
  : {}
608
609
 
@@ -674,6 +675,7 @@ export class BitcoinMonitorScanner {
674
675
  ordinalAddress: ordinalAddress,
675
676
  knownBalanceUtxoIds: latestAccountState.knownBalanceUtxoIds,
676
677
  mustAvoidUtxoIds: latestAccountState.mustAvoidUtxoIds,
678
+ additionalInscriptions: latestAccountState.additionalInscriptions,
677
679
  })
678
680
 
679
681
  return {
@@ -3,7 +3,7 @@ import { isEmpty, isEqual, pickBy } from 'lodash'
3
3
 
4
4
  import { BaseMonitor } from '@exodus/asset-lib'
5
5
  import InsightWSClient from '../insight-api-client/ws'
6
- import { updateUnconfirmedAncestorData } from '../unconfirmed-ancestor-data'
6
+ import { resolveUnconfirmedAncestorData } from '../unconfirmed-ancestor-data'
7
7
  import { BitcoinMonitorScanner } from './bitcoin-monitor-scanner'
8
8
  import { normalizeInsightConfig, toWSUrl } from '../insight-api-client/util'
9
9
  import ms from 'ms'
@@ -153,32 +153,35 @@ export class Monitor extends BaseMonitor {
153
153
  walletAccount,
154
154
  })
155
155
 
156
+ const newData = {}
156
157
  if (utxos || ordinalsUtxos) {
157
- await aci.updateAccountState({
158
- assetName,
159
- walletAccount,
160
- newData: pickBy(
158
+ Object.assign(
159
+ newData,
160
+ pickBy(
161
161
  {
162
162
  utxos,
163
163
  ordinalsUtxos,
164
164
  },
165
165
  Boolean
166
- ),
167
- })
166
+ )
167
+ )
168
168
  }
169
169
 
170
170
  if (txsToUpdate.length) {
171
- const accountState = await aci.getAccountState({ assetName, walletAccount })
172
171
  await this.updateTxLog({ assetName, walletAccount, logItems: txsToUpdate })
173
- if (['bitcoin', 'bitcoinregtest', 'bitcointestnet'].includes(assetName)) {
174
- updateUnconfirmedAncestorData({
175
- asset,
176
- walletAccount,
177
- accountState,
172
+ if (utxos && ['bitcoin', 'bitcoinregtest', 'bitcointestnet'].includes(assetName)) {
173
+ const unconfirmedTxAncestor = await resolveUnconfirmedAncestorData({
174
+ utxos,
178
175
  insightClient: this.#insightClient,
179
176
  })
177
+ newData.mem = { unconfirmedTxAncestor }
180
178
  }
181
179
  }
180
+ await aci.updateAccountState({
181
+ assetName,
182
+ walletAccount,
183
+ newData,
184
+ })
182
185
  }
183
186
  }
184
187
 
@@ -228,20 +231,19 @@ export class Monitor extends BaseMonitor {
228
231
  walletAccount,
229
232
  refresh,
230
233
  })
231
- const accountState = await aci.getAccountState({ assetName, walletAccount })
232
234
 
235
+ const newData = {}
233
236
  if (utxos || ordinalsUtxos)
234
- await aci.updateAccountState({
235
- assetName,
236
- walletAccount,
237
- newData: pickBy(
237
+ Object.assign(
238
+ newData,
239
+ pickBy(
238
240
  {
239
241
  utxos,
240
242
  ordinalsUtxos,
241
243
  },
242
244
  Boolean
243
- ),
244
- })
245
+ )
246
+ )
245
247
 
246
248
  if (!isEmpty(changedUnusedAddressIndexes)) {
247
249
  // Only for mobile atm, browser and hydra calculates from the latest txLogs
@@ -264,14 +266,19 @@ export class Monitor extends BaseMonitor {
264
266
  }
265
267
 
266
268
  // Move to after tick
267
- if (['bitcoin', 'bitcoinregtest', 'bitcointestnet'].includes(assetName)) {
268
- updateUnconfirmedAncestorData({
269
- asset: this.asset,
270
- walletAccount,
271
- accountState,
269
+ if (utxos && ['bitcoin', 'bitcoinregtest', 'bitcointestnet'].includes(assetName)) {
270
+ const unconfirmedTxAncestor = await resolveUnconfirmedAncestorData({
271
+ utxos,
272
272
  insightClient: this.#insightClient,
273
273
  })
274
+ newData.mem = { unconfirmedTxAncestor }
274
275
  }
276
+
277
+ await aci.updateAccountState({
278
+ assetName,
279
+ walletAccount,
280
+ newData,
281
+ })
275
282
  }
276
283
 
277
284
  #logWsStatus = (message, ...args) => {
@@ -22,6 +22,7 @@ import {
22
22
  } from '../utxos-utils'
23
23
 
24
24
  import * as defaultBitcoinjsLib from '@exodus/bitcoinjs-lib'
25
+ import { getUnconfirmedTxAncestorMap } from '../unconfirmed-ancestor-data'
25
26
 
26
27
  const ASSETS_SUPPORTED_BIP_174 = [
27
28
  'bitcoin',
@@ -209,11 +210,13 @@ export const createAndBroadcastTXFactory = ({
209
210
  const insightClient = asset.baseAsset.insightClient
210
211
  const currency = asset.currency
211
212
  const feeData = await assetClientInterface.getFeeConfig({ assetName })
213
+ const unconfirmedTxAncestor = getUnconfirmedTxAncestorMap({ accountState })
212
214
  const usableUtxos = getUsableUtxos({
213
215
  asset,
214
216
  utxos: getUtxos({ accountState, asset }),
215
217
  feeData,
216
218
  txSet,
219
+ unconfirmedTxAncestor,
217
220
  })
218
221
 
219
222
  let replaceableTxs = findUnconfirmedSentRbfTxs(txSet)
@@ -257,9 +260,10 @@ export const createAndBroadcastTXFactory = ({
257
260
  feeRate: customFee || feeRate,
258
261
  receiveAddress: receiveAddress,
259
262
  isSendAll: resolvedIsSendAll,
260
- getFeeEstimator: (asset, { feePerKB }) => getFeeEstimator(asset, feePerKB),
263
+ getFeeEstimator: (asset, { feePerKB, ...options }) => getFeeEstimator(asset, feePerKB, options),
261
264
  mustSpendUtxos: utxosToBump,
262
265
  allowUnconfirmedRbfEnabledUtxos,
266
+ unconfirmedTxAncestor,
263
267
  inscriptionIds,
264
268
  })
265
269
 
package/src/tx-utils.js CHANGED
@@ -11,14 +11,18 @@ export const findUnconfirmedSentRbfTxs = (txSet) =>
11
11
  tx.data.inputs
12
12
  )
13
13
 
14
- export const findLargeUnconfirmedTxs = ({ assetName, txSet, feeRate, maxFee }) =>
14
+ export const findLargeUnconfirmedTxs = ({ txSet, feeRate, maxFee, unconfirmedTxAncestor }) =>
15
15
  !txSet
16
16
  ? new Set()
17
17
  : new Set(
18
18
  Array.from(txSet)
19
19
  .filter((tx) => {
20
20
  if (!tx.pending) return false
21
- const extraFee = resolveExtraFeeOfTx({ assetName, feeRate, txId: tx.txId })
21
+ const extraFee = resolveExtraFeeOfTx({
22
+ feeRate,
23
+ txId: tx.txId,
24
+ unconfirmedTxAncestor,
25
+ })
22
26
  return extraFee && extraFee > maxFee
23
27
  })
24
28
  .map((tx) => tx.txId)
@@ -1,46 +1,32 @@
1
- import { getUtxos } from './utxos-utils'
1
+ import assert from 'minimalistic-assert'
2
2
 
3
- const dataMap = new Map()
4
-
5
- export async function updateUnconfirmedAncestorData({
6
- asset,
7
- walletAccount,
8
- accountState,
9
- insightClient,
10
- }) {
11
- for (const [txId, stored] of dataMap) {
12
- if (stored.walletAccount === walletAccount && stored.assetName === asset.name)
13
- dataMap.delete(txId)
14
- }
15
-
16
- const utxos = getUtxos({ accountState, asset })
17
- .toArray()
18
- .filter((data) => {
19
- return !data.confirmations || data.confirmations <= 0
20
- })
21
- const txIds = new Set(utxos.map(({ txId }) => txId))
3
+ export async function resolveUnconfirmedAncestorData({ utxos, insightClient }) {
4
+ assert(utxos, 'utxos is required')
5
+ assert(insightClient, 'insightClient is required')
6
+ const dataMap = Object.create(null)
7
+ const unconfirmedUtxos = utxos.toArray().filter((data) => {
8
+ return !data.confirmations || data.confirmations <= 0
9
+ })
10
+ const txIds = new Set(unconfirmedUtxos.map(({ txId }) => txId))
22
11
  for (const txId of txIds) {
23
12
  try {
24
13
  const { size, fees } = await insightClient.fetchUnconfirmedAncestorData(txId)
25
14
  if (size !== 0) {
26
- dataMap.set(txId, { assetName: asset.name, walletAccount, size, fees })
15
+ dataMap[txId] = { size, fees }
27
16
  }
28
17
  } catch (e) {
29
18
  console.warn(e)
30
19
  }
31
20
  }
21
+ return dataMap
32
22
  }
33
23
 
34
- function getUnconfirmedAncestorData({ txId, assetName }) {
35
- const stored = dataMap.get(txId)
36
- if (stored?.assetName === assetName) {
37
- return { size: stored.size, fees: stored.fees }
38
- }
39
- return undefined
24
+ export function getUnconfirmedTxAncestorMap({ accountState }) {
25
+ return accountState?.mem?.unconfirmedTxAncestor || Object.create(null)
40
26
  }
41
27
 
42
- export function resolveExtraFeeOfTx({ assetName, feeRate, txId }) {
43
- const data = getUnconfirmedAncestorData({ assetName, txId })
28
+ export function resolveExtraFeeOfTx({ feeRate, txId, unconfirmedTxAncestor }) {
29
+ const data = unconfirmedTxAncestor?.[txId]
44
30
  if (!data) return 0
45
31
  const { fees, size } = data
46
32
  // Get the difference in fee rate between ancestors and current estimate
@@ -122,17 +122,54 @@ function isOrdinalUtxo({
122
122
  return hasOrdinals
123
123
  }
124
124
 
125
+ export function mergeAdditionalInscriptions({ allUtxos, additionalInscriptions }) {
126
+ return UtxoCollection.fromArray(
127
+ allUtxos.toArray().map((utxo) => {
128
+ const inscriptions = additionalInscriptions
129
+ .filter((additionalInscription) => {
130
+ const forUtxo =
131
+ additionalInscription.vout === utxo.vout && additionalInscription.txId === utxo.txId
132
+ if (forUtxo) {
133
+ // avoid duplicated
134
+ return !utxo.inscriptions?.find(
135
+ (existingInscription) =>
136
+ existingInscription.inscriptionId === additionalInscription.inscriptionId
137
+ )
138
+ }
139
+ return forUtxo
140
+ })
141
+ .map((additionalInscription) => ({
142
+ inscriptionId: additionalInscription.inscriptionId,
143
+ offset: additionalInscription.offset || 0,
144
+ }))
145
+ if (inscriptions.length) {
146
+ utxo.inscriptions = [...(utxo.inscriptions || []), ...inscriptions]
147
+ }
148
+ return utxo
149
+ }),
150
+ {
151
+ currency: allUtxos.currency,
152
+ }
153
+ )
154
+ }
155
+
125
156
  export function partitionUtxos({
126
157
  allUtxos,
127
158
  ordinalsEnabled,
128
159
  knownBalanceUtxoIds,
129
160
  ordinalAddress,
130
161
  mustAvoidUtxoIds,
162
+ additionalInscriptions,
131
163
  }) {
132
164
  assert(allUtxos, 'allUtxos is required')
133
165
  if (ordinalsEnabled) assert(ordinalAddress, 'ordinalAddress is required')
166
+
167
+ const expandedAllUtxos = ordinalsEnabled
168
+ ? mergeAdditionalInscriptions({ allUtxos, additionalInscriptions })
169
+ : allUtxos
170
+
134
171
  return {
135
- utxos: allUtxos.filter(
172
+ utxos: expandedAllUtxos.filter(
136
173
  (utxo) =>
137
174
  !isOrdinalUtxo({
138
175
  utxo,
@@ -142,7 +179,7 @@ export function partitionUtxos({
142
179
  mustAvoidUtxoIds,
143
180
  })
144
181
  ),
145
- ordinalsUtxos: allUtxos.filter((utxo) =>
182
+ ordinalsUtxos: expandedAllUtxos.filter((utxo) =>
146
183
  isOrdinalUtxo({
147
184
  utxo,
148
185
  ordinalsEnabled,
@@ -178,7 +215,7 @@ function filterDustUtxos({ utxos, feeData }) {
178
215
  return utxos
179
216
  }
180
217
 
181
- export function getUsableUtxos({ asset, utxos, feeData, txSet }) {
218
+ export function getUsableUtxos({ asset, utxos, feeData, txSet, unconfirmedTxAncestor }) {
182
219
  assert(asset, 'asset is required')
183
220
  assert(utxos, 'utxos is required')
184
221
  assert(feeData, 'feeData is required')
@@ -191,10 +228,10 @@ export function getUsableUtxos({ asset, utxos, feeData, txSet }) {
191
228
  assert(typeof maxFee === 'number' && !Number.isNaN(maxFee), 'maxFee must be a number')
192
229
 
193
230
  const largeUnconfirmedTxs = findLargeUnconfirmedTxs({
194
- assetName: asset.name,
195
231
  txSet,
196
232
  feeRate,
197
233
  maxFee,
234
+ unconfirmedTxAncestor,
198
235
  })
199
236
  const confirmedAndSmallUtxos =
200
237
  largeUnconfirmedTxs.size === 0