@exodus/bitcoin-api 2.30.0 → 2.31.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/CHANGELOG.md +22 -0
- package/package.json +2 -2
- package/src/account-state.js +1 -5
- package/src/balances.js +0 -17
- package/src/fee/get-fee-resolver.js +2 -10
- package/src/insight-api-client/index.js +2 -1
- package/src/tx-log/bitcoin-monitor-scanner.js +1 -1
- package/src/tx-log/bitcoin-monitor.js +0 -6
- package/src/tx-send/index.js +10 -29
- package/src/utxos-utils.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
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.1](https://github.com/ExodusMovement/assets/compare/@exodus/bitcoin-api@2.31.0...@exodus/bitcoin-api@2.31.1) (2025-03-19)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
* fix: BTC monitor scanning enhancement (#5112)
|
|
13
|
+
|
|
14
|
+
* fix: remove brc20 dead code (#5286)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## [2.31.0](https://github.com/ExodusMovement/assets/compare/@exodus/bitcoin-api@2.30.0...@exodus/bitcoin-api@2.31.0) (2025-01-23)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
* feat(eth-like,btc-like): make broadcastTx compatible with rawTx (#4911)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
## [2.30.0](https://github.com/ExodusMovement/assets/compare/@exodus/bitcoin-api@2.29.8...@exodus/bitcoin-api@2.30.0) (2025-01-10)
|
|
7
29
|
|
|
8
30
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/bitcoin-api",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.31.1",
|
|
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": "
|
|
59
|
+
"gitHead": "f1b6ccb198231db1fb6c9c51a0173967ec4efd1f"
|
|
60
60
|
}
|
package/src/account-state.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AccountState, UtxoCollection } from '@exodus/models'
|
|
2
2
|
|
|
3
|
-
export function createAccountState({ asset, ordinalsEnabled = false
|
|
3
|
+
export function createAccountState({ asset, ordinalsEnabled = false }) {
|
|
4
4
|
const empty = UtxoCollection.createEmpty({
|
|
5
5
|
currency: asset.currency,
|
|
6
6
|
})
|
|
@@ -18,10 +18,6 @@ export function createAccountState({ asset, ordinalsEnabled = false, brc20Enable
|
|
|
18
18
|
defaults.additionalInscriptions = []
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
if (brc20Enabled) {
|
|
22
|
-
defaults.brc20Balances = {}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
21
|
return class BitcoinAccountState extends AccountState {
|
|
26
22
|
static defaults = defaults
|
|
27
23
|
}
|
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({
|
|
@@ -41,23 +41,15 @@ export class GetFeeResolver {
|
|
|
41
41
|
customFee,
|
|
42
42
|
isSendAll,
|
|
43
43
|
nft, // sending one nft
|
|
44
|
-
brc20, // sending multiple inscriptions ids (as in sending multiple transfer ordinals)
|
|
45
44
|
receiveAddress,
|
|
46
45
|
taprootInputWitnessSize,
|
|
47
46
|
}) => {
|
|
48
47
|
if (nft) {
|
|
49
48
|
assert(!amount, 'amount must not be provided when nft is provided!!!')
|
|
50
49
|
assert(!isSendAll, 'isSendAll must not be provided when nft is provided!!!')
|
|
51
|
-
assert(!brc20, 'brc20 must not be provided when nft is provided!!!')
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
// assert(!amount, 'amount must not be provided when brc20 is provided!!!')
|
|
56
|
-
assert(!isSendAll, 'isSendAll must not be provided when brc20 is provided!!!')
|
|
57
|
-
assert(!nft, 'nft must not be provided when brc20 is provided!!!')
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const inscriptionIds = getInscriptionIds({ nft, brc20 })
|
|
52
|
+
const inscriptionIds = getInscriptionIds({ nft })
|
|
61
53
|
|
|
62
54
|
const { fee, unspendableFee, extraFeeData } = this.#getUtxosData({
|
|
63
55
|
asset,
|
|
@@ -65,7 +57,7 @@ export class GetFeeResolver {
|
|
|
65
57
|
txSet,
|
|
66
58
|
feeData,
|
|
67
59
|
receiveAddress,
|
|
68
|
-
amount
|
|
60
|
+
amount,
|
|
69
61
|
customFee,
|
|
70
62
|
isSendAll,
|
|
71
63
|
inscriptionIds,
|
|
@@ -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:
|
|
178
|
+
body: JSON.stringify({ rawtx: _rawTx }),
|
|
178
179
|
}
|
|
179
180
|
|
|
180
181
|
const response = await fetch(url, fetchOptions)
|
|
@@ -619,7 +619,7 @@ export class BitcoinMonitorScanner {
|
|
|
619
619
|
|
|
620
620
|
// this protects from the server returning bad spentTxId
|
|
621
621
|
utxos = utxos.filter((utxo) => {
|
|
622
|
-
|
|
622
|
+
return !vinTxids[`${utxo.txId}-${utxo.vout}`]
|
|
623
623
|
})
|
|
624
624
|
|
|
625
625
|
let utxoCol = UtxoCollection.fromArray(utxos, { currency })
|
|
@@ -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,
|
package/src/tx-send/index.js
CHANGED
|
@@ -202,7 +202,7 @@ export const getPrepareSendTransaction =
|
|
|
202
202
|
assetClientInterface,
|
|
203
203
|
changeAddressType,
|
|
204
204
|
}) =>
|
|
205
|
-
async ({ asset
|
|
205
|
+
async ({ asset, walletAccount, address, amount, options }) => {
|
|
206
206
|
const {
|
|
207
207
|
multipleAddressesEnabled,
|
|
208
208
|
feePerKB,
|
|
@@ -210,14 +210,12 @@ export const getPrepareSendTransaction =
|
|
|
210
210
|
isSendAll,
|
|
211
211
|
bumpTxId,
|
|
212
212
|
nft,
|
|
213
|
-
feeOpts,
|
|
214
213
|
isExchange,
|
|
215
214
|
isBip70,
|
|
216
215
|
isRbfAllowed,
|
|
217
216
|
taprootInputWitnessSize,
|
|
218
217
|
} = options
|
|
219
218
|
|
|
220
|
-
const asset = maybeToken.baseAsset
|
|
221
219
|
const assetName = asset.name
|
|
222
220
|
const accountState = await assetClientInterface.getAccountState({ assetName, walletAccount })
|
|
223
221
|
const feeData = await assetClientInterface.getFeeConfig({ assetName })
|
|
@@ -225,19 +223,11 @@ export const getPrepareSendTransaction =
|
|
|
225
223
|
const insightClient = asset.baseAsset.insightClient
|
|
226
224
|
|
|
227
225
|
const blockHeight = providedBlockHeight || (await getBlockHeight({ assetName, insightClient }))
|
|
228
|
-
const brc20 = options.brc20 || feeOpts?.brc20 // feeOpts is the only way I've found atm to pass brc20 param without changing the tx-send hydra module
|
|
229
226
|
|
|
230
227
|
const rbfEnabled =
|
|
231
|
-
providedRbfEnabled ||
|
|
232
|
-
(feeData.rbfEnabled && !isExchange && !isBip70 && isRbfAllowed && !nft && !brc20)
|
|
228
|
+
providedRbfEnabled || (feeData.rbfEnabled && !isExchange && !isBip70 && isRbfAllowed && !nft)
|
|
233
229
|
|
|
234
|
-
const
|
|
235
|
-
if (isToken) {
|
|
236
|
-
assert(brc20, 'brc20 is required when sending bitcoin token')
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const amount = isToken ? asset.currency.ZERO : tokenAmount
|
|
240
|
-
const inscriptionIds = getInscriptionIds({ nft, brc20 })
|
|
230
|
+
const inscriptionIds = getInscriptionIds({ nft })
|
|
241
231
|
|
|
242
232
|
assert(
|
|
243
233
|
ordinalsEnabled || !inscriptionIds,
|
|
@@ -465,20 +455,16 @@ export const createAndBroadcastTXFactory =
|
|
|
465
455
|
assetClientInterface,
|
|
466
456
|
changeAddressType,
|
|
467
457
|
}) =>
|
|
468
|
-
async ({ asset
|
|
458
|
+
async ({ asset, walletAccount, address, amount, options }) => {
|
|
469
459
|
// Prepare transaction
|
|
470
|
-
const { bumpTxId, nft, isExchange, isBip70, isRbfAllowed = true
|
|
460
|
+
const { bumpTxId, nft, isExchange, isBip70, isRbfAllowed = true } = options
|
|
471
461
|
|
|
472
|
-
const asset = maybeToken.baseAsset
|
|
473
462
|
const assetName = asset.name
|
|
474
463
|
const feeData = await assetClientInterface.getFeeConfig({ assetName })
|
|
475
464
|
const accountState = await assetClientInterface.getAccountState({ assetName, walletAccount })
|
|
476
465
|
const insightClient = asset.baseAsset.insightClient
|
|
477
|
-
const isToken = maybeToken.name !== asset.name
|
|
478
|
-
const brc20 = options.brc20 || feeOpts?.brc20
|
|
479
466
|
|
|
480
|
-
const rbfEnabled =
|
|
481
|
-
feeData.rbfEnabled && !isExchange && !isBip70 && isRbfAllowed && !nft && !brc20
|
|
467
|
+
const rbfEnabled = feeData.rbfEnabled && !isExchange && !isBip70 && isRbfAllowed && !nft
|
|
482
468
|
|
|
483
469
|
// blockHeight
|
|
484
470
|
const blockHeight = await getBlockHeight({ assetName, insightClient })
|
|
@@ -492,9 +478,8 @@ export const createAndBroadcastTXFactory =
|
|
|
492
478
|
rbfEnabled,
|
|
493
479
|
assetClientInterface,
|
|
494
480
|
changeAddressType,
|
|
495
|
-
})({ asset
|
|
481
|
+
})({ asset, walletAccount, address, amount, options })
|
|
496
482
|
const {
|
|
497
|
-
amount,
|
|
498
483
|
change,
|
|
499
484
|
totalAmount,
|
|
500
485
|
currentOrdinalsUtxos,
|
|
@@ -648,11 +633,7 @@ export const createAndBroadcastTXFactory =
|
|
|
648
633
|
|
|
649
634
|
const calculateCoinAmount = () => {
|
|
650
635
|
if (selfSend) {
|
|
651
|
-
return
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
if (isToken) {
|
|
655
|
-
return tokenAmount.abs().negate()
|
|
636
|
+
return asset.currency.ZERO
|
|
656
637
|
}
|
|
657
638
|
|
|
658
639
|
if (nft) {
|
|
@@ -665,14 +646,14 @@ export const createAndBroadcastTXFactory =
|
|
|
665
646
|
const coinAmount = calculateCoinAmount()
|
|
666
647
|
|
|
667
648
|
await assetClientInterface.updateTxLogAndNotify({
|
|
668
|
-
assetName:
|
|
649
|
+
assetName: asset.name,
|
|
669
650
|
walletAccount,
|
|
670
651
|
txs: [
|
|
671
652
|
{
|
|
672
653
|
txId,
|
|
673
654
|
confirmations: 0,
|
|
674
655
|
coinAmount,
|
|
675
|
-
coinName:
|
|
656
|
+
coinName: asset.name,
|
|
676
657
|
feeAmount: fee,
|
|
677
658
|
feeCoinName: assetName,
|
|
678
659
|
selfSend,
|
package/src/utxos-utils.js
CHANGED
|
@@ -10,8 +10,8 @@ export const getInscriptionTxId = (inscriptionId) => {
|
|
|
10
10
|
return inscriptionId.split('i')[0]
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function getInscriptionIds({ nft
|
|
14
|
-
return nft?.tokenId ? [nft?.tokenId] :
|
|
13
|
+
export function getInscriptionIds({ nft }) {
|
|
14
|
+
return nft?.tokenId ? [nft?.tokenId] : undefined
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export function getTransferOrdinalsUtxos({ inscriptionIds, ordinalsUtxos }) {
|