@exodus/bitcoin-api 2.29.8 → 2.31.0

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/CHANGELOG.md CHANGED
@@ -3,6 +3,26 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [2.31.0](https://github.com/ExodusMovement/assets/compare/@exodus/bitcoin-api@2.30.0...@exodus/bitcoin-api@2.31.0) (2025-01-23)
7
+
8
+
9
+ ### Features
10
+
11
+
12
+ * feat(eth-like,btc-like): make broadcastTx compatible with rawTx (#4911)
13
+
14
+
15
+
16
+ ## [2.30.0](https://github.com/ExodusMovement/assets/compare/@exodus/bitcoin-api@2.29.8...@exodus/bitcoin-api@2.30.0) (2025-01-10)
17
+
18
+
19
+ ### Features
20
+
21
+
22
+ * feat: bitcoin dust fee display (#4789)
23
+
24
+
25
+
6
26
  ## [2.29.8](https://github.com/ExodusMovement/assets/compare/@exodus/bitcoin-api@2.29.7...@exodus/bitcoin-api@2.29.8) (2025-01-08)
7
27
 
8
28
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/bitcoin-api",
3
- "version": "2.29.8",
3
+ "version": "2.31.0",
4
4
  "description": "Bitcoin transaction and fee monitors, RPC with the blockchain node, other networking code.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -56,5 +56,5 @@
56
56
  "type": "git",
57
57
  "url": "git+https://github.com/ExodusMovement/assets.git"
58
58
  },
59
- "gitHead": "c848fe0785fb999de9241cb35456ed5c56c52093"
59
+ "gitHead": "1f116146a725da6f3c98abdf233261512a6333fc"
60
60
  }
package/src/balances.js CHANGED
@@ -16,23 +16,6 @@ export const getBalancesFactory = ({ feeData, getSpendableBalance, ordinalsEnabl
16
16
  assert(accountState, 'accountState is required')
17
17
  assert(txLog, 'txLog is required')
18
18
 
19
- if (accountState.magicEdenApiFungibleBalances) {
20
- const validBalances = accountState.magicEdenApiFungibleBalances.filter(
21
- (fungibleBalance) => fungibleBalance.asset.ticker === asset.ticker
22
- )
23
- const parsedBalances = validBalances.map(({ balance }) =>
24
- asset.currency.defaultUnit(balance.balance)
25
- )
26
- const totalBalance = asset.currency.defaultUnit(
27
- parsedBalances.reduce((sum, item) => sum.add(item), asset.currency.ZERO)
28
- )
29
- return {
30
- total: totalBalance,
31
- // legacy
32
- balance: totalBalance,
33
- }
34
- }
35
-
36
19
  const utxos = getUtxos({ asset, accountState })
37
20
  const balance = utxos.value
38
21
  const spendableBalance = getSpendableBalance({
@@ -59,7 +59,7 @@ export class GetFeeResolver {
59
59
 
60
60
  const inscriptionIds = getInscriptionIds({ nft, brc20 })
61
61
 
62
- const { resolvedFee, extraFee } = this.#getUtxosData({
62
+ const { fee, unspendableFee, extraFeeData } = this.#getUtxosData({
63
63
  asset,
64
64
  accountState,
65
65
  txSet,
@@ -71,7 +71,7 @@ export class GetFeeResolver {
71
71
  inscriptionIds,
72
72
  taprootInputWitnessSize,
73
73
  })
74
- return { fee: resolvedFee, extraFee }
74
+ return { fee, unspendableFee, extraFeeData }
75
75
  }
76
76
 
77
77
  getAvailableBalance = ({
@@ -3,6 +3,7 @@ import { UtxoCollection } from '@exodus/models'
3
3
  import lodash from 'lodash'
4
4
  import assert from 'minimalistic-assert'
5
5
 
6
+ import { getChangeDustValue } from '../dust.js'
6
7
  import { getConfirmedOrRfbDisabledUtxos, getConfirmedUtxos } from '../utxos-utils.js'
7
8
  import { getExtraFee } from './fee-utils.js'
8
9
 
@@ -265,7 +266,11 @@ export const getUtxosData = ({
265
266
  taprootInputWitnessSize,
266
267
  changeAddressType,
267
268
  }) => {
268
- const { selectedUtxos, replaceTx, fee } = selectUtxos({
269
+ const {
270
+ selectedUtxos,
271
+ replaceTx,
272
+ fee: unspendableFee,
273
+ } = selectUtxos({
269
274
  asset,
270
275
  usableUtxos,
271
276
  replaceableTxs,
@@ -285,18 +290,20 @@ export const getUtxosData = ({
285
290
  changeAddressType,
286
291
  })
287
292
 
288
- const resolvedFee = replaceTx ? fee.sub(replaceTx.feeAmount) : fee
293
+ let fee = replaceTx ? unspendableFee.sub(replaceTx.feeAmount) : unspendableFee
289
294
  const empty = UtxoCollection.createEmpty({ currency: asset.currency })
295
+
296
+ const replaceUtxos = replaceTx ? usableUtxos.getTxIdUtxos(replaceTx.txId) : empty
297
+
290
298
  const spendableUtxos = getConfirmedOrRfbDisabledUtxos({
291
299
  asset,
292
300
  utxos: usableUtxos,
293
301
  allowUnconfirmedRbfEnabledUtxos,
294
- }).union(replaceTx ? usableUtxos.getTxIdUtxos(replaceTx.txId) : empty)
295
- // .union(selectedUtxos || empty)
302
+ }).union(replaceUtxos)
296
303
 
297
304
  const spendableBalance = spendableUtxos.value
298
305
 
299
- const extraFee = selectedUtxos
306
+ const extraFeeCpfp = selectedUtxos
300
307
  ? asset.currency.baseUnit(
301
308
  getExtraFee({
302
309
  asset,
@@ -307,15 +314,38 @@ export const getUtxosData = ({
307
314
  )
308
315
  : asset.currency.ZERO
309
316
 
310
- const availableBalance = spendableBalance.sub(resolvedFee).clampLowerZero()
317
+ const availableBalance = spendableBalance.sub(fee).clampLowerZero()
318
+
319
+ const change =
320
+ selectedUtxos?.size && amount
321
+ ? selectedUtxos.union(replaceUtxos).value.sub(amount).sub(fee)
322
+ : undefined
323
+
324
+ const dust = getChangeDustValue(asset)
325
+
326
+ let extraFeeDust = asset.currency.ZERO
327
+ if (change && !change.isZero && change.lt(dust)) {
328
+ fee = fee.add(change)
329
+ extraFeeDust = change
330
+ }
331
+
332
+ let extraFeeData
333
+ if (!extraFeeCpfp.isZero && !extraFeeDust.isZero) {
334
+ extraFeeData = { type: 'cpfpdust', extraFee: extraFeeCpfp.add(extraFeeDust) }
335
+ } else if (!extraFeeDust.isZero) {
336
+ extraFeeData = { type: 'dust', extraFee: extraFeeDust }
337
+ } else if (!extraFeeCpfp.isZero) {
338
+ extraFeeData = { type: 'cpfp', extraFee: extraFeeCpfp }
339
+ }
340
+
311
341
  return {
312
342
  spendableBalance,
313
343
  availableBalance,
314
344
  selectedUtxos,
345
+ unspendableFee,
315
346
  fee,
316
- resolvedFee,
317
347
  replaceTx,
318
- extraFee,
348
+ extraFeeData,
319
349
  }
320
350
  }
321
351
 
@@ -166,6 +166,7 @@ export default class InsightAPIClient {
166
166
  }
167
167
 
168
168
  async broadcastTx(rawTx) {
169
+ const _rawTx = rawTx instanceof Uint8Array ? Buffer.from(rawTx).toString('hex') : rawTx
169
170
  console.log('gonna broadcastTx')
170
171
  const url = urlJoin(this._baseURL, '/tx/send')
171
172
  const fetchOptions = {
@@ -174,7 +175,7 @@ export default class InsightAPIClient {
174
175
  Accept: 'application/json',
175
176
  'Content-Type': 'application/json',
176
177
  },
177
- body: JSON.stringify({ rawtx: rawTx }),
178
+ body: JSON.stringify({ rawtx: _rawTx }),
178
179
  }
179
180
 
180
181
  const response = await fetch(url, fetchOptions)
@@ -295,12 +295,6 @@ export class Monitor extends BaseMonitor {
295
295
  newData.mem = { unconfirmedTxAncestor }
296
296
  }
297
297
 
298
- if (this.fetchFungibleBalances) {
299
- try {
300
- newData.magicEdenApiFungibleBalances = await this.fetchFungibleBalances(walletAccount)
301
- } catch {}
302
- }
303
-
304
298
  await aci.updateAccountState({
305
299
  assetName,
306
300
  walletAccount,