@exodus/bitcoin-api 1.0.3 → 1.0.4
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": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Exodus bitcoin-api",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"@exodus/models": "^8.10.4",
|
|
26
26
|
"@exodus/secp256k1": "4.0.2-exodus.0",
|
|
27
27
|
"@exodus/simple-retry": "0.0.6",
|
|
28
|
+
"bech32": "^1.1.3",
|
|
28
29
|
"bip44-constants": "55.0.0",
|
|
29
30
|
"coininfo": "5.1.0",
|
|
30
31
|
"delay": "4.0.1",
|
|
@@ -38,5 +39,5 @@
|
|
|
38
39
|
"@exodus/bip-schnorr": "0.6.6-fork-1",
|
|
39
40
|
"@noble/secp256k1": "~1.5.3"
|
|
40
41
|
},
|
|
41
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "00377ab9ad8a29114f5064efcb0197d4257056d1"
|
|
42
43
|
}
|
|
@@ -4,6 +4,25 @@ import urlJoin from 'url-join'
|
|
|
4
4
|
import qs from 'querystring'
|
|
5
5
|
import delay from 'delay'
|
|
6
6
|
|
|
7
|
+
const getTextFromResponse = async (response) => {
|
|
8
|
+
try {
|
|
9
|
+
const responseBody = await response.text()
|
|
10
|
+
return responseBody.substring(0, 100)
|
|
11
|
+
} catch (e) {
|
|
12
|
+
return ''
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const fetchJson = async (url, fetchOptions) => {
|
|
17
|
+
const response = await fetch(url, fetchOptions)
|
|
18
|
+
if (!response.ok)
|
|
19
|
+
throw new Error(
|
|
20
|
+
`${url} returned ${response.status}: ${response.statusText ||
|
|
21
|
+
'Unknown Status Text'}. Body: ${await getTextFromResponse(response)}`
|
|
22
|
+
)
|
|
23
|
+
return response.json()
|
|
24
|
+
}
|
|
25
|
+
|
|
7
26
|
// TODO: use p-retry
|
|
8
27
|
async function fetchJsonRetry(url, fetchOptions) {
|
|
9
28
|
const waitTimes = [5, 10, 20, 30].map((t) => t * 1000)
|
|
@@ -22,12 +41,6 @@ async function fetchJsonRetry(url, fetchOptions) {
|
|
|
22
41
|
}
|
|
23
42
|
}
|
|
24
43
|
}
|
|
25
|
-
|
|
26
|
-
async function fetchJson(url, fetchOptions) {
|
|
27
|
-
const response = await fetch(url, fetchOptions)
|
|
28
|
-
if (!response.ok) throw new Error(`${url} returned ${response.status}: ${response.statusText}`)
|
|
29
|
-
return response.json()
|
|
30
|
-
}
|
|
31
44
|
}
|
|
32
45
|
|
|
33
46
|
export default class InsightAPIClient {
|
|
@@ -41,9 +54,7 @@ export default class InsightAPIClient {
|
|
|
41
54
|
|
|
42
55
|
async isNetworkConnected() {
|
|
43
56
|
const url = urlJoin(this._baseURL, '/peer')
|
|
44
|
-
const
|
|
45
|
-
const peerStatus = await resp.json()
|
|
46
|
-
|
|
57
|
+
const peerStatus = await fetchJson(url, { timeout: 10000 })
|
|
47
58
|
return !!peerStatus.connected
|
|
48
59
|
}
|
|
49
60
|
|
|
@@ -56,9 +67,7 @@ export default class InsightAPIClient {
|
|
|
56
67
|
|
|
57
68
|
async fetchBlockHeight() {
|
|
58
69
|
const url = urlJoin(this._baseURL, '/status')
|
|
59
|
-
const
|
|
60
|
-
const status = await resp.json()
|
|
61
|
-
|
|
70
|
+
const status = await fetchJson(url, { timeout: 10000 })
|
|
62
71
|
return status.info.blocks
|
|
63
72
|
}
|
|
64
73
|
|
|
@@ -68,9 +77,7 @@ export default class InsightAPIClient {
|
|
|
68
77
|
this._baseURL,
|
|
69
78
|
opts.includeTxs ? `/addr/${encodedAddress}` : `/addr/${encodedAddress}?noTxList=1`
|
|
70
79
|
)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return response.json()
|
|
80
|
+
return fetchJson(url)
|
|
74
81
|
}
|
|
75
82
|
|
|
76
83
|
async fetchUTXOs(addresses, { assetNames = [] } = {}) {
|
|
@@ -81,8 +88,7 @@ export default class InsightAPIClient {
|
|
|
81
88
|
}
|
|
82
89
|
const encodedAddresses = encodeURIComponent(addresses)
|
|
83
90
|
const url = urlJoin(this._baseURL, `/addrs/${encodedAddresses}/utxo?${query}`)
|
|
84
|
-
const
|
|
85
|
-
const utxos = await response.json()
|
|
91
|
+
const utxos = await fetchJson(url)
|
|
86
92
|
|
|
87
93
|
return utxos.map((utxo) => ({
|
|
88
94
|
address: utxo.address,
|
|
@@ -111,8 +117,7 @@ export default class InsightAPIClient {
|
|
|
111
117
|
async fetchRawTx(txId: string) {
|
|
112
118
|
const encodedTxId = encodeURIComponent(txId)
|
|
113
119
|
const url = urlJoin(this._baseURL, `/rawtx/${encodedTxId}`)
|
|
114
|
-
const
|
|
115
|
-
const { rawtx } = await response.json()
|
|
120
|
+
const { rawtx } = await fetchJson(url)
|
|
116
121
|
return rawtx
|
|
117
122
|
}
|
|
118
123
|
|
|
@@ -155,14 +160,12 @@ export default class InsightAPIClient {
|
|
|
155
160
|
async fetchUnconfirmedAncestorData(txId: string) {
|
|
156
161
|
const encodedTxId = encodeURIComponent(txId)
|
|
157
162
|
const url = urlJoin(this._baseURL, `/unconfirmed_ancestor/${encodedTxId}`)
|
|
158
|
-
|
|
159
|
-
return response.json()
|
|
163
|
+
return fetchJson(url)
|
|
160
164
|
}
|
|
161
165
|
|
|
162
166
|
async fetchFeeRate() {
|
|
163
167
|
const url = urlJoin(this._baseURL, '/v2/fees')
|
|
164
|
-
|
|
165
|
-
return response.json()
|
|
168
|
+
return fetchJson(url)
|
|
166
169
|
}
|
|
167
170
|
|
|
168
171
|
async broadcastTx(rawTx) {
|
|
@@ -200,16 +203,12 @@ export default class InsightAPIClient {
|
|
|
200
203
|
async getClaimable(address) {
|
|
201
204
|
const encodedAddress = encodeURIComponent(address)
|
|
202
205
|
const url = urlJoin(this._baseURL, `/addr/${encodedAddress}/claimable`)
|
|
203
|
-
|
|
204
|
-
if (!response.ok) throw new Error(`${url} returned ${response.status}: ${response.statusText}`)
|
|
205
|
-
return response.json()
|
|
206
|
+
return fetchJson(url)
|
|
206
207
|
}
|
|
207
208
|
|
|
208
209
|
async getUnclaimed(address) {
|
|
209
210
|
const encodedAddress = encodeURIComponent(address)
|
|
210
211
|
const url = urlJoin(this._baseURL, `/addr/${encodedAddress}/unclaimed`)
|
|
211
|
-
|
|
212
|
-
if (!response.ok) throw new Error(`${url} returned ${response.status}: ${response.statusText}`)
|
|
213
|
-
return response.json()
|
|
212
|
+
return fetchJson(url)
|
|
214
213
|
}
|
|
215
214
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from 'minimalistic-assert'
|
|
2
2
|
import lodash from 'lodash'
|
|
3
3
|
import ECPairFactory from 'ecpair'
|
|
4
|
-
import { Psbt } from '@exodus/bitcoinjs-lib'
|
|
4
|
+
import { Psbt, Transaction } from '@exodus/bitcoinjs-lib'
|
|
5
5
|
|
|
6
6
|
import { toAsyncSigner, tweakSigner } from './taproot'
|
|
7
7
|
|
|
@@ -12,6 +12,15 @@ const _MAXIMUM_FEE_RATES = {
|
|
|
12
12
|
ravencoin: 1000000,
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
const canParseTx = (rawTxBuffer) => {
|
|
16
|
+
try {
|
|
17
|
+
Transaction.fromBuffer(rawTxBuffer)
|
|
18
|
+
return true
|
|
19
|
+
} catch (e) {
|
|
20
|
+
return false
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
export const signTxFactory = ({ assetName, resolvePurpose, keys, coinInfo, network, ecc }) => {
|
|
16
25
|
assert(assetName, 'assetName is required')
|
|
17
26
|
assert(resolvePurpose, 'resolvePurpose is required')
|
|
@@ -62,10 +71,18 @@ export const signTxFactory = ({ assetName, resolvePurpose, keys, coinInfo, netwo
|
|
|
62
71
|
// witness outputs only require the value and the script, not the full transaction
|
|
63
72
|
txIn.witnessUtxo = { value, script: Buffer.from(script, 'hex') }
|
|
64
73
|
} else {
|
|
65
|
-
// non-witness outptus require the full transaction
|
|
66
74
|
const rawTx = (rawTxs || []).find((t) => t.txId === txId)
|
|
75
|
+
// non-witness outptus require the full transaction
|
|
67
76
|
assert(!!rawTx, 'Non-witness outputs require the full previous transaction.')
|
|
68
|
-
|
|
77
|
+
const rawTxBuffer = Buffer.from(rawTx.rawData, 'hex')
|
|
78
|
+
if (canParseTx(rawTxBuffer)) {
|
|
79
|
+
txIn.nonWitnessUtxo = rawTxBuffer
|
|
80
|
+
} else {
|
|
81
|
+
// temp fix for https://exodusio.slack.com/archives/CP202D90Q/p1671014704829939 until bitcoinjs could parse a mweb tx without failing
|
|
82
|
+
console.warn(`Setting psbt.__CACHE.__UNSAFE_SIGN_NONSEGWIT = true for asset ${assetName}`)
|
|
83
|
+
psbt.__CACHE.__UNSAFE_SIGN_NONSEGWIT = true
|
|
84
|
+
txIn.witnessUtxo = { value, script: Buffer.from(script, 'hex') }
|
|
85
|
+
}
|
|
69
86
|
}
|
|
70
87
|
psbt.addInput(txIn)
|
|
71
88
|
}
|