@exodus/bitcoin-api 2.7.5 → 2.7.7-fix

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.7.5",
3
+ "version": "2.7.7-fix",
4
4
  "description": "Exodus bitcoin-api",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -42,6 +42,5 @@
42
42
  "@scure/base": "^1.1.3",
43
43
  "@scure/btc-signer": "^1.1.0",
44
44
  "jest-when": "^3.5.1"
45
- },
46
- "gitHead": "7596b820ccf23528fae15ccee13c269fa930434b"
45
+ }
47
46
  }
package/src/balances.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import assert from 'minimalistic-assert'
2
- import { getUtxos } from './utxos-utils'
2
+ import { getOrdinalsUtxos, getUtxos } from './utxos-utils'
3
3
 
4
4
  // known issue!! fee data is static here!
5
5
  // Hydra's balances's module does not provide it when calling asset.api.getBalances
6
6
  // https://github.com/ExodusMovement/exodus-hydra/blob/f9110f8e9e76b8b199bc4d40461cb1bed3a5be1e/modules/balances/module/index.js#L130
7
7
  // feeData is required to know if an unconfirmed tx can or cannot be RBFed?
8
8
  // This could be fixed once we allow all unconfirmed utxos to be RBFed or if we change the balance module to provide the feeData when calling asset.api.getBalances
9
- export const getBalancesFactory = ({ feeData, getSpendableBalance }) => {
9
+ export const getBalancesFactory = ({ feeData, getSpendableBalance, ordinalsEnabled }) => {
10
10
  assert(feeData, 'feeData is required')
11
11
  assert(getSpendableBalance, 'getSpendableBalance is required')
12
12
  return ({ asset, accountState, txLog }) => {
@@ -14,7 +14,10 @@ export const getBalancesFactory = ({ feeData, getSpendableBalance }) => {
14
14
  assert(accountState, 'accountState is required')
15
15
  assert(txLog, 'txLog is required')
16
16
  const utxos = getUtxos({ asset, accountState })
17
- const balance = utxos.value
17
+ const unknownBalance = ordinalsEnabled
18
+ ? getOrdinalsUtxos({ asset, accountState }).filter((utxo) => !utxo.inscriptions?.length).value
19
+ : undefined
20
+ const balance = ordinalsEnabled ? utxos.value.add(unknownBalance) : utxos.value
18
21
  const spendableBalance = getSpendableBalance({
19
22
  asset,
20
23
  accountState,
@@ -100,7 +100,7 @@ const _canBumpTx = ({
100
100
  allowUnconfirmedRbfEnabledUtxos,
101
101
  })
102
102
 
103
- return fee ? { bumpType: BumpType.CPFP } : { errorMessage: 'insufficient funds' }
103
+ return fee ? { bumpType: BumpType.CPFP, bumpFee: fee } : { errorMessage: 'insufficient funds' }
104
104
  }
105
105
 
106
106
  const validateIsNumber = (number, name) => {
@@ -22,6 +22,7 @@ export class Monitor extends BaseMonitor {
22
22
  #insightClient
23
23
  #yieldToUI
24
24
  #scanner
25
+ #webSocketEnabled
25
26
 
26
27
  constructor({
27
28
  asset,
@@ -34,6 +35,7 @@ export class Monitor extends BaseMonitor {
34
35
  insightClient,
35
36
  apiUrl,
36
37
  scanner,
38
+ webSocketEnabled = true,
37
39
  ...extraScannerParams
38
40
  }) {
39
41
  super({ asset, interval, assetClientInterface, logger, runner })
@@ -44,6 +46,7 @@ export class Monitor extends BaseMonitor {
44
46
  this.#ws = null
45
47
  this.#apiUrl = apiUrl
46
48
  this.#yieldToUI = yieldToUI
49
+ this.#webSocketEnabled = webSocketEnabled
47
50
  this.#wsUrl = null
48
51
  this.#runningByWalletAccount = Object.create(null)
49
52
  this.#addressesByWalletAccount = Object.create(null)
@@ -95,6 +98,9 @@ export class Monitor extends BaseMonitor {
95
98
  }
96
99
 
97
100
  #connectWS = async (wsUrl) => {
101
+ if (!this.#webSocketEnabled) {
102
+ return
103
+ }
98
104
  if (this.#ws) {
99
105
  this.#ws.close()
100
106
  this.#ws = null
@@ -4,30 +4,33 @@ import { cloneDeep } from 'lodash'
4
4
  export const indexOutputs = ({ tx, currency }) => {
5
5
  const inscriptions = []
6
6
 
7
- let inputOffset = 0
7
+ let inputOffset = currency.ZERO
8
8
  for (let i = 0; i < tx.vin.length; i++) {
9
9
  const vin = tx.vin[i]
10
- const value = currency.defaultUnit(vin.value).toBaseNumber()
10
+ const value = currency.defaultUnit(vin.value)
11
11
  inscriptions.push(
12
- ...(vin.inscriptions || []).map((i) => ({ ...i, offset: i.offset + inputOffset }))
12
+ ...(vin.inscriptions || []).map((i) => ({
13
+ ...i,
14
+ offset: currency.baseUnit(i.offset).add(inputOffset),
15
+ }))
13
16
  )
14
- inputOffset = value
17
+ inputOffset = inputOffset.add(value)
15
18
  }
16
19
 
17
- let outputOffset = 0
20
+ let outputOffset = currency.ZERO
18
21
  for (let i = 0; i < tx.vout.length; i++) {
19
22
  const vout = tx.vout[i]
20
- const value = currency.defaultUnit(vout.value).toBaseNumber()
23
+ const value = currency.defaultUnit(vout.value)
21
24
  vout.inscriptions = inscriptions
22
- .map((i) => ({ ...i, offset: i.offset - outputOffset }))
23
- .filter((i) => i.offset >= 0 && i.offset < value)
24
- outputOffset = value
25
+ .filter((i) => i.offset.gte(outputOffset) && i.offset.lt(value.add(outputOffset)))
26
+ .map((i) => ({ ...i, offset: i.offset.sub(outputOffset).toBaseNumber() }))
27
+ outputOffset = outputOffset.add(value)
25
28
  }
26
29
  tx.inscriptionsMemoryIndexed = true // avoids btc being spent even when the mempool index was done in memory
27
30
  return tx
28
31
  }
29
32
 
30
- export const indexOrdinalUnconfirmedTx = memoizeLruCache(
33
+ export const cachedIndexOrdinalUnconfirmedTx = memoizeLruCache(
31
34
  async ({ insightClient, currency, tx }) => {
32
35
  if (tx.inscriptionsIndexed || tx.inscriptionsMemoryIndexed) {
33
36
  return tx
@@ -35,7 +38,7 @@ export const indexOrdinalUnconfirmedTx = memoizeLruCache(
35
38
  const copyTx = cloneDeep(tx)
36
39
  await Promise.all(
37
40
  copyTx.vin.map(async (vin) => {
38
- const outputTx = await indexOrdinalUnconfirmedTx({
41
+ const outputTx = await cachedIndexOrdinalUnconfirmedTx({
39
42
  insightClient,
40
43
  currency,
41
44
  tx: await insightClient.fetchTxObject(vin.txid),
@@ -51,3 +54,14 @@ export const indexOrdinalUnconfirmedTx = memoizeLruCache(
51
54
  ({ tx }) => `${tx.txid}_${tx.confirmations}`,
52
55
  100
53
56
  )
57
+
58
+ export const indexOrdinalUnconfirmedTx = ({ insightClient, currency, tx }) => {
59
+ if (tx.inscriptionsIndexed) {
60
+ return tx
61
+ }
62
+ return cachedIndexOrdinalUnconfirmedTx({
63
+ insightClient,
64
+ currency,
65
+ tx,
66
+ })
67
+ }