@exodus/bitcoin-api 2.15.0 → 2.16.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/bitcoin-api",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.16.0",
|
|
4
4
|
"description": "Exodus bitcoin-api",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"jest-when": "^3.5.1",
|
|
59
59
|
"safe-buffer": "^5.2.1"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "f6d3343c14d821405ea319c4bb022983a7bd4e4c"
|
|
62
62
|
}
|
|
@@ -54,6 +54,15 @@ export class BitcoinMonitorScanner {
|
|
|
54
54
|
this.#refreshGapLimit = refreshGapLimit
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
async #getGapLimit({ walletAccount, assetName, refresh }) {
|
|
58
|
+
const assetConfig = await this.#assetClientInterface.getAssetConfig?.({
|
|
59
|
+
assetName,
|
|
60
|
+
walletAccount,
|
|
61
|
+
})
|
|
62
|
+
if (typeof assetConfig?.gapLimit === 'number') return assetConfig.gapLimit
|
|
63
|
+
return refresh ? this.#refreshGapLimit : this.#gapLimit
|
|
64
|
+
}
|
|
65
|
+
|
|
57
66
|
async rescanBlockchainInsight({ walletAccount, refresh }) {
|
|
58
67
|
const asset = this.#asset
|
|
59
68
|
const assetClientInterface = this.#assetClientInterface
|
|
@@ -100,6 +109,8 @@ export class BitcoinMonitorScanner {
|
|
|
100
109
|
assetName,
|
|
101
110
|
walletAccount,
|
|
102
111
|
})
|
|
112
|
+
|
|
113
|
+
const resolvedGapLimit = await this.#getGapLimit({ walletAccount, assetName, refresh })
|
|
103
114
|
/*
|
|
104
115
|
* The chain fields/variables are number arrays of size 2
|
|
105
116
|
*
|
|
@@ -153,13 +164,23 @@ export class BitcoinMonitorScanner {
|
|
|
153
164
|
addressIndex,
|
|
154
165
|
})
|
|
155
166
|
.then((address) => {
|
|
167
|
+
const addressObject = this.#asset.address.toLegacyAddress
|
|
168
|
+
? Address.create(
|
|
169
|
+
this.#asset.address.toLegacyAddress(String(address)),
|
|
170
|
+
address.meta
|
|
171
|
+
)
|
|
172
|
+
: address
|
|
173
|
+
|
|
174
|
+
const addressString = String(addressObject)
|
|
175
|
+
|
|
176
|
+
if (addrMap[addressString]) {
|
|
177
|
+
return null
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
addrMap[addressString] = addressObject
|
|
181
|
+
|
|
156
182
|
return {
|
|
157
|
-
address:
|
|
158
|
-
? Address.create(
|
|
159
|
-
this.#asset.address.toLegacyAddress(String(address)),
|
|
160
|
-
address.meta
|
|
161
|
-
)
|
|
162
|
-
: address,
|
|
183
|
+
address: addressObject,
|
|
163
184
|
purpose,
|
|
164
185
|
}
|
|
165
186
|
})
|
|
@@ -168,9 +189,9 @@ export class BitcoinMonitorScanner {
|
|
|
168
189
|
}
|
|
169
190
|
|
|
170
191
|
const addresses = []
|
|
171
|
-
const
|
|
192
|
+
const allAddresses = await Promise.all(promises)
|
|
193
|
+
const result = allAddresses.filter(Boolean)
|
|
172
194
|
result.forEach(({ address, purpose }) => {
|
|
173
|
-
addrMap[String(address)] = address
|
|
174
195
|
purposeMap[String(address)] = purpose
|
|
175
196
|
addresses.push(String(address))
|
|
176
197
|
})
|
|
@@ -185,8 +206,9 @@ export class BitcoinMonitorScanner {
|
|
|
185
206
|
|
|
186
207
|
const fetchAddressesSize = 25
|
|
187
208
|
for (let i = 0; i < addresses.length; i += fetchAddressesSize) {
|
|
209
|
+
const fetchAddresses = addresses.slice(i, i + fetchAddressesSize)
|
|
188
210
|
const promise = insightClient.fetchAllTxData(
|
|
189
|
-
|
|
211
|
+
fetchAddresses,
|
|
190
212
|
txFetchLimit,
|
|
191
213
|
fetchTimeout,
|
|
192
214
|
shouldStop
|
|
@@ -224,8 +246,8 @@ export class BitcoinMonitorScanner {
|
|
|
224
246
|
purpose,
|
|
225
247
|
chain,
|
|
226
248
|
startAddressIndexes: chain.map(() => 0),
|
|
227
|
-
endAddressIndexes: chain.map(
|
|
228
|
-
|
|
249
|
+
endAddressIndexes: chain.map((addressIndex) =>
|
|
250
|
+
refresh ? resolvedGapLimit : addressIndex + resolvedGapLimit
|
|
229
251
|
),
|
|
230
252
|
}
|
|
231
253
|
})
|
|
@@ -336,7 +358,6 @@ export class BitcoinMonitorScanner {
|
|
|
336
358
|
indexData.startAddressIndexes = [...indexData.endAddressIndexes]
|
|
337
359
|
// eslint-disable-next-line @exodus/mutable/no-param-reassign-prop-only
|
|
338
360
|
indexData.endAddressIndexes = indexData.chain.map((addressIndex) => {
|
|
339
|
-
const resolvedGapLimit = refresh ? this.#refreshGapLimit : this.#gapLimit
|
|
340
361
|
return addressIndex + resolvedGapLimit
|
|
341
362
|
})
|
|
342
363
|
})
|
|
@@ -27,10 +27,14 @@ export function createSignWithWallet({
|
|
|
27
27
|
return async (psbt, inputsToSign) => {
|
|
28
28
|
// The Taproot SIGHASH flag includes all previous outputs,
|
|
29
29
|
// so signing is only done AFTER all inputs have been updated
|
|
30
|
+
const signingPromises = []
|
|
31
|
+
|
|
30
32
|
for (let index = 0; index < psbt.inputCount; index++) {
|
|
31
33
|
const inputInfo = inputsToSign[index]
|
|
32
34
|
// dApps request to sign only specific transaction inputs.
|
|
33
35
|
if (!inputInfo) continue
|
|
36
|
+
|
|
37
|
+
const input = psbt.data.inputs[index]
|
|
34
38
|
const { address, sigHash } = inputInfo
|
|
35
39
|
// The sighash value from the PSBT input itself will be used.
|
|
36
40
|
// This list just represents possible sighash values the inputs can have.
|
|
@@ -41,8 +45,7 @@ export function createSignWithWallet({
|
|
|
41
45
|
const { key, purpose, keyId, publicKey } = await getKeyWithMetadata(address)
|
|
42
46
|
|
|
43
47
|
const isP2SH = purpose === 49
|
|
44
|
-
const hasTapLeafScript =
|
|
45
|
-
psbt.data.inputs[index].tapLeafScript && psbt.data.inputs[index].tapLeafScript.length > 0
|
|
48
|
+
const hasTapLeafScript = input.tapLeafScript && input.tapLeafScript.length > 0
|
|
46
49
|
const isTaprootKeySpend = isTaprootPurpose(purpose) && !hasTapLeafScript
|
|
47
50
|
|
|
48
51
|
if (isP2SH) {
|
|
@@ -54,7 +57,7 @@ export function createSignWithWallet({
|
|
|
54
57
|
const p2sh = payments.p2sh({ redeem: p2wpkh })
|
|
55
58
|
if (address === p2sh.address) {
|
|
56
59
|
// Set the redeem script in the psbt in case it's missing.
|
|
57
|
-
if (!Buffer.isBuffer(
|
|
60
|
+
if (!Buffer.isBuffer(input.redeemScript)) {
|
|
58
61
|
psbt.updateInput(index, {
|
|
59
62
|
redeemScript: p2sh.redeem.output,
|
|
60
63
|
})
|
|
@@ -62,7 +65,7 @@ export function createSignWithWallet({
|
|
|
62
65
|
} else {
|
|
63
66
|
throw new Error('Expected P2SH script to be a nested segwit input')
|
|
64
67
|
}
|
|
65
|
-
} else if (isTaprootKeySpend && !Buffer.isBuffer(
|
|
68
|
+
} else if (isTaprootKeySpend && !Buffer.isBuffer(input.tapInternalKey)) {
|
|
66
69
|
// tapInternalKey is metadata for signing and not part of the hash to sign.
|
|
67
70
|
// so modifying it here is fine.
|
|
68
71
|
psbt.updateInput(index, { tapInternalKey: toXOnly(publicKey) })
|
|
@@ -73,7 +76,9 @@ export function createSignWithWallet({
|
|
|
73
76
|
: toAsyncSigner({ keyPair: key, isTaprootKeySpend, network })
|
|
74
77
|
|
|
75
78
|
// desktop / BE / mobile with bip-schnorr signing
|
|
76
|
-
|
|
79
|
+
signingPromises.push(psbt.signInputAsync(index, asyncSigner, allowedSigHashTypes))
|
|
77
80
|
}
|
|
81
|
+
|
|
82
|
+
await Promise.all(signingPromises)
|
|
78
83
|
}
|
|
79
84
|
}
|