@exodus/bitcoin-api 2.2.1 → 2.2.2
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 +2 -2
- package/src/move-funds.js +31 -33
- package/src/tx-send/index.js +1 -1
- package/src/tx-sign/default-create-tx.js +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/bitcoin-api",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "Exodus bitcoin-api",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"@exodus/bitcoin-meta": "^1.0.0",
|
|
42
42
|
"@noble/secp256k1": "~1.5.3"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "2d223c3c71d00fbd5246af3f39410eec113d0029"
|
|
45
45
|
}
|
package/src/move-funds.js
CHANGED
|
@@ -2,21 +2,45 @@ import wif from 'wif'
|
|
|
2
2
|
import { UtxoCollection, Address } from '@exodus/models'
|
|
3
3
|
import { createInputs, createOutput, getNonWitnessTxs } from './tx-send'
|
|
4
4
|
import assert from 'minimalistic-assert'
|
|
5
|
+
import secp256k1 from 'secp256k1'
|
|
6
|
+
|
|
7
|
+
function wifToPublicKey({ coinInfo, privateKeyWIF }) {
|
|
8
|
+
assert(coinInfo, 'coinInfo is required')
|
|
9
|
+
assert(privateKeyWIF, 'privateKeyWIF is required')
|
|
10
|
+
const { versions } = coinInfo
|
|
11
|
+
|
|
12
|
+
const { privateKey, compressed } = wif.decode(privateKeyWIF, versions.private)
|
|
13
|
+
return secp256k1.publicKeyCreate(privateKey, compressed)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const getAddressesFromPrivateKeyFactory = ({ purposes, keys, coinInfo }) => {
|
|
17
|
+
assert(purposes, 'purposes is required')
|
|
18
|
+
assert(keys, 'keys is required')
|
|
19
|
+
assert(coinInfo, 'coinInfo is required')
|
|
20
|
+
return ({ privateKey }) => {
|
|
21
|
+
const publicKey = wifToPublicKey({ coinInfo, privateKeyWIF: privateKey })
|
|
22
|
+
return purposes.map((purpose) =>
|
|
23
|
+
keys.encodePublic(purpose === 49 ? secp256k1.publicKeyConvert(publicKey, true) : publicKey, {
|
|
24
|
+
purpose,
|
|
25
|
+
})
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
5
29
|
|
|
6
30
|
export const moveFundsFactory = ({
|
|
7
31
|
asset,
|
|
8
32
|
insightClient,
|
|
9
33
|
getFeeEstimator,
|
|
10
|
-
keys,
|
|
11
34
|
signTx,
|
|
12
35
|
address,
|
|
36
|
+
getAddressesFromPrivateKey,
|
|
13
37
|
}) => {
|
|
14
38
|
assert(asset, 'asset is required')
|
|
15
39
|
assert(insightClient, 'insightClient is required')
|
|
16
40
|
assert(getFeeEstimator, 'getFeeEstimator is required')
|
|
17
41
|
assert(address, 'address is required')
|
|
18
|
-
assert(keys, 'keys is required')
|
|
19
42
|
assert(signTx, 'signTx is required')
|
|
43
|
+
assert(getAddressesFromPrivateKey, 'getAddressesFromPrivateKey is required')
|
|
20
44
|
async function prepareFunds(assetName, input, options = {}) {
|
|
21
45
|
const { toAddress, assetClientInterface, MoveFundsError, walletAccount } = options
|
|
22
46
|
assert(MoveFundsError, 'MoveFundsError is required') // should we move MoveFundsError to asset libs?
|
|
@@ -29,6 +53,7 @@ export const moveFundsFactory = ({
|
|
|
29
53
|
asset,
|
|
30
54
|
input,
|
|
31
55
|
}
|
|
56
|
+
// WIF format private key
|
|
32
57
|
const privateKey = input
|
|
33
58
|
|
|
34
59
|
if (!isValidPrivateKey(privateKey)) {
|
|
@@ -36,7 +61,7 @@ export const moveFundsFactory = ({
|
|
|
36
61
|
}
|
|
37
62
|
|
|
38
63
|
const { compressed } = wif.decode(privateKey)
|
|
39
|
-
const addresses =
|
|
64
|
+
const addresses = getAddressesFromPrivateKey({ privateKey })
|
|
40
65
|
|
|
41
66
|
const receiveAddresses = await assetClientInterface.getReceiveAddresses({
|
|
42
67
|
walletAccount,
|
|
@@ -61,7 +86,9 @@ export const moveFundsFactory = ({
|
|
|
61
86
|
}
|
|
62
87
|
}
|
|
63
88
|
if (!found) {
|
|
64
|
-
formatProps.fromAddress = addresses.join(' or
|
|
89
|
+
formatProps.fromAddress = `${addresses.slice(0, -1).join(', ')}, or ${
|
|
90
|
+
addresses[addresses.length - 1]
|
|
91
|
+
}`
|
|
65
92
|
throw new MoveFundsError('balance-zero', formatProps)
|
|
66
93
|
}
|
|
67
94
|
const fromAddress = address
|
|
@@ -114,35 +141,6 @@ export const moveFundsFactory = ({
|
|
|
114
141
|
return { txId, fromAddress, toAddress, amount, fee }
|
|
115
142
|
}
|
|
116
143
|
|
|
117
|
-
function getAllAddressesFromWIF(privateKeyWIF) {
|
|
118
|
-
const { compressed } = wif.decode(privateKeyWIF)
|
|
119
|
-
const legacyAddress = keys.encodePublicFromWIF(privateKeyWIF)
|
|
120
|
-
// TODO: support nested segwit address, right now we don't support send
|
|
121
|
-
// const nestedSegwitAddress = encodeNestedSegwitFromWIF(privateKeyWIF, { asset })
|
|
122
|
-
const nativeSegwitAddress = keys.encodePublicBech32FromWIF(privateKeyWIF)
|
|
123
|
-
|
|
124
|
-
if (compressed) {
|
|
125
|
-
return [nativeSegwitAddress, legacyAddress]
|
|
126
|
-
} else {
|
|
127
|
-
return [legacyAddress]
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/*
|
|
132
|
-
function getPublicFromWIF(privateKeyWIF, { asset }) {
|
|
133
|
-
const { versions } = asset.coinInfo
|
|
134
|
-
const { privateKey, compressed } = wif.decode(privateKeyWIF, versions.private)
|
|
135
|
-
return secp256k1.pointFromScalar(privateKey, compressed)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function encodeNestedSegwitFromWIF(privateKeyWIF, { asset }) {
|
|
139
|
-
const publicKey = getPublicFromWIF(privateKeyWIF, { asset })
|
|
140
|
-
const witnessProgram = bitcoinjs.payments.p2wpkh({ pubkey: publicKey }).output
|
|
141
|
-
const witnessProgramHash = bitcoinjs.crypto.hash160(witnessProgram)
|
|
142
|
-
return bitcoinjs.address.toBase58Check(witnessProgramHash, asset.coinInfo.versions.scripthash)
|
|
143
|
-
}
|
|
144
|
-
*/
|
|
145
|
-
|
|
146
144
|
async function getUtxos({ asset, address }) {
|
|
147
145
|
const rawUtxos = await insightClient.fetchUTXOs([address])
|
|
148
146
|
return UtxoCollection.fromArray(
|
package/src/tx-send/index.js
CHANGED
|
@@ -363,7 +363,7 @@ export const createAndBroadcastTXFactory = ({
|
|
|
363
363
|
sent: selfSend ? [] : receivers,
|
|
364
364
|
rbfEnabled,
|
|
365
365
|
feePerKB: ['bitcoin', 'bitcoinregtest', 'bitcointestnet'].includes(assetName)
|
|
366
|
-
? fee.div(tx.virtualSize
|
|
366
|
+
? fee.div(tx.virtualSize / 1000).toBaseNumber()
|
|
367
367
|
: undefined,
|
|
368
368
|
changeAddress: changeOutput ? ourAddress : undefined,
|
|
369
369
|
blockHeight,
|
|
@@ -115,6 +115,7 @@ export const signTxFactory = ({ assetName, resolvePurpose, keys, coinInfo, netwo
|
|
|
115
115
|
const rawTx = tx.toBuffer()
|
|
116
116
|
const txId = tx.getId()
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
// tx needs to be serializable for desktop RPC send => sign communication
|
|
119
|
+
return { rawTx, txId, tx: { ...tx, virtualSize: tx.virtualSize?.() } }
|
|
119
120
|
}
|
|
120
121
|
}
|