@exodus/bitcoin-api 4.13.0 → 4.14.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,20 @@
|
|
|
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
|
+
## [4.14.0](https://github.com/ExodusMovement/assets/compare/@exodus/bitcoin-api@4.13.0...@exodus/bitcoin-api@4.14.0) (2026-03-27)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
* feat: add configs for btc mempool api clients (#7670)
|
|
13
|
+
|
|
14
|
+
* feat: add getFeeAsync to bitcoin and bitcoin-like assets (#7616)
|
|
15
|
+
|
|
16
|
+
* feat: add mempool indexer support for btc (#7492)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
6
20
|
## [4.13.0](https://github.com/ExodusMovement/assets/compare/@exodus/bitcoin-api@4.12.0...@exodus/bitcoin-api@4.13.0) (2026-03-20)
|
|
7
21
|
|
|
8
22
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/bitcoin-api",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.14.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",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"type": "git",
|
|
64
64
|
"url": "git+https://github.com/ExodusMovement/assets.git"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "959153b1ea9f3fc33398dd5a167c2c29c8af2df1"
|
|
67
67
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import assert from 'minimalistic-assert'
|
|
2
|
+
|
|
3
|
+
export const getFeeAsyncFactory = ({ createTx, assetClientInterface }) => {
|
|
4
|
+
assert(createTx, 'createTx is required')
|
|
5
|
+
assert(assetClientInterface, 'assetClientInterface is required')
|
|
6
|
+
|
|
7
|
+
return async ({ asset, walletAccount, toAddress, amount, isSendAll, ...extraCreateTxParams }) => {
|
|
8
|
+
assert(asset, 'asset is required')
|
|
9
|
+
assert(walletAccount, 'walletAccount is required')
|
|
10
|
+
|
|
11
|
+
const sendAmount = amount || asset.currency.ZERO
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const { fee } = await createTx({
|
|
15
|
+
asset,
|
|
16
|
+
walletAccount,
|
|
17
|
+
toAddress,
|
|
18
|
+
amount: sendAmount,
|
|
19
|
+
isSendAll,
|
|
20
|
+
...extraCreateTxParams,
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
return { fee }
|
|
24
|
+
} catch {
|
|
25
|
+
const assetName = asset.name
|
|
26
|
+
const [accountState, txSet, feeData] = await Promise.all([
|
|
27
|
+
assetClientInterface.getAccountState({ assetName, walletAccount }),
|
|
28
|
+
assetClientInterface.getTxLog({ assetName, walletAccount }),
|
|
29
|
+
assetClientInterface.getFeeData({ assetName }),
|
|
30
|
+
])
|
|
31
|
+
const { fee } = asset.api.getFee({
|
|
32
|
+
asset,
|
|
33
|
+
accountState,
|
|
34
|
+
txSet,
|
|
35
|
+
feeData,
|
|
36
|
+
amount: sendAmount,
|
|
37
|
+
isSendAll,
|
|
38
|
+
// customFee,
|
|
39
|
+
// receiveAddress,
|
|
40
|
+
// taprootInputWitnessSize,
|
|
41
|
+
})
|
|
42
|
+
return { fee }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
package/src/index.js
CHANGED
|
@@ -27,3 +27,4 @@ export * from './ordinals-utils.js'
|
|
|
27
27
|
export { signMessage, signMessageWithSigner } from './sign-message.js'
|
|
28
28
|
export { writePsbtBlockHeight, readPsbtBlockHeight } from './psbt-proprietary-types.js'
|
|
29
29
|
export { getActivityTxs } from './get-activity-txs.js'
|
|
30
|
+
export { getFeeAsyncFactory } from './get-fee-async.js'
|
|
@@ -106,8 +106,12 @@ export function toWSUrl(apiUrl) {
|
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
export function normalizeInsightConfig(config) {
|
|
109
|
+
export function normalizeInsightConfig(config, monitorType) {
|
|
110
110
|
const apiUrl = config?.insightServers?.[0]
|
|
111
|
-
const
|
|
112
|
-
|
|
111
|
+
const mempoolApiUrl = config?.mempoolServer
|
|
112
|
+
const wsUrl =
|
|
113
|
+
monitorType === 'mempool'
|
|
114
|
+
? config?.mempoolServerWS || toWSUrl(mempoolApiUrl)
|
|
115
|
+
: config?.insightServersWS?.[0] || toWSUrl(apiUrl)
|
|
116
|
+
return { apiUrl, mempoolApiUrl, wsUrl }
|
|
113
117
|
}
|
|
@@ -4,6 +4,7 @@ import lodash from 'lodash'
|
|
|
4
4
|
import assert from 'minimalistic-assert'
|
|
5
5
|
import ms from 'ms'
|
|
6
6
|
|
|
7
|
+
import MempoolWSClient from '../insight-api-client/mempool-ws-client.js'
|
|
7
8
|
import { normalizeInsightConfig, toWSUrl } from '../insight-api-client/util.js'
|
|
8
9
|
import InsightWSClient from '../insight-api-client/ws.js'
|
|
9
10
|
import { resolveUnconfirmedAncestorData } from '../unconfirmed-ancestor-data.js'
|
|
@@ -20,6 +21,9 @@ export class Monitor extends BaseMonitor {
|
|
|
20
21
|
#wsInterval
|
|
21
22
|
#ws
|
|
22
23
|
#apiUrl
|
|
24
|
+
#mempoolApiUrl
|
|
25
|
+
#monitorType
|
|
26
|
+
#maxTrackedAddresses
|
|
23
27
|
#wsUrl
|
|
24
28
|
#insightClient
|
|
25
29
|
#yieldToUI
|
|
@@ -36,6 +40,9 @@ export class Monitor extends BaseMonitor {
|
|
|
36
40
|
logger,
|
|
37
41
|
insightClient,
|
|
38
42
|
apiUrl,
|
|
43
|
+
mempoolApiUrl,
|
|
44
|
+
monitorType,
|
|
45
|
+
maxTrackedAddresses,
|
|
39
46
|
scanner,
|
|
40
47
|
webSocketEnabled = true,
|
|
41
48
|
...extraScannerParams
|
|
@@ -47,6 +54,9 @@ export class Monitor extends BaseMonitor {
|
|
|
47
54
|
this.#wsInterval = wsInterval
|
|
48
55
|
this.#ws = null
|
|
49
56
|
this.#apiUrl = apiUrl
|
|
57
|
+
this.#mempoolApiUrl = mempoolApiUrl
|
|
58
|
+
this.#monitorType = monitorType
|
|
59
|
+
this.#maxTrackedAddresses = maxTrackedAddresses
|
|
50
60
|
this.#yieldToUI = yieldToUI
|
|
51
61
|
this.#webSocketEnabled = webSocketEnabled
|
|
52
62
|
this.#wsUrl = null
|
|
@@ -76,13 +86,26 @@ export class Monitor extends BaseMonitor {
|
|
|
76
86
|
}
|
|
77
87
|
|
|
78
88
|
setServer(assetConfig = {}) {
|
|
79
|
-
const { apiUrl, wsUrl } = normalizeInsightConfig(assetConfig)
|
|
80
|
-
|
|
89
|
+
const { apiUrl, mempoolApiUrl, wsUrl } = normalizeInsightConfig(assetConfig, this.#monitorType)
|
|
90
|
+
|
|
91
|
+
if (this.#monitorType === 'mempool') {
|
|
92
|
+
if (mempoolApiUrl) {
|
|
93
|
+
this.#insightClient.setBaseUrl(mempoolApiUrl)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (apiUrl) {
|
|
97
|
+
this.#insightClient.setInsightBaseUrl(apiUrl)
|
|
98
|
+
}
|
|
99
|
+
} else if (apiUrl) {
|
|
81
100
|
this.#insightClient.setBaseUrl(apiUrl)
|
|
82
101
|
}
|
|
83
102
|
|
|
84
103
|
if (!this.#wsUrl || this.#wsUrl !== wsUrl) {
|
|
85
|
-
this.#connectWS(
|
|
104
|
+
this.#connectWS(
|
|
105
|
+
wsUrl ||
|
|
106
|
+
this.#wsUrl ||
|
|
107
|
+
toWSUrl(this.#monitorType === 'mempool' ? this.#mempoolApiUrl : this.#apiUrl)
|
|
108
|
+
)
|
|
86
109
|
}
|
|
87
110
|
}
|
|
88
111
|
|
|
@@ -129,14 +152,22 @@ export class Monitor extends BaseMonitor {
|
|
|
129
152
|
|
|
130
153
|
this.#addressesByWalletAccount = await this.#getReceiveAddressesByWalletAccount()
|
|
131
154
|
|
|
132
|
-
|
|
155
|
+
let addressesArr = Object.values(this.#addressesByWalletAccount).flat()
|
|
133
156
|
|
|
134
157
|
if (addressesArr.length === 0) {
|
|
135
158
|
this.#logWsStatus('no addressesArr to subscribe')
|
|
136
159
|
return
|
|
137
160
|
}
|
|
138
161
|
|
|
139
|
-
this.#
|
|
162
|
+
if (this.#monitorType === 'mempool') {
|
|
163
|
+
this.#ws = new MempoolWSClient(wsUrl, this.asset.name)
|
|
164
|
+
// Mempool WS rejects oversized track-addresses subscriptions; cap client-side to avoid immediate errors.
|
|
165
|
+
addressesArr = addressesArr.slice(0, this.#maxTrackedAddresses ?? 20)
|
|
166
|
+
} else {
|
|
167
|
+
this.#ws = new InsightWSClient(wsUrl, this.asset.name)
|
|
168
|
+
// Insight/Magnifier tolerates oversized subscribe calls and ignores overflow, so no client-side cap here.
|
|
169
|
+
}
|
|
170
|
+
|
|
140
171
|
this.#ws.connect(addressesArr)
|
|
141
172
|
this.#ws.on('connect', () => {
|
|
142
173
|
this.#logWsStatus('connect to addresses', addressesArr)
|