@exodus/bitcoin-api 2.2.0 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/bitcoin-api",
3
- "version": "2.2.0",
3
+ "version": "2.2.2",
4
4
  "description": "Exodus bitcoin-api",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -22,7 +22,6 @@
22
22
  "@exodus/asset-lib": "^3.7.2",
23
23
  "@exodus/bip44-constants": "^195.0.0",
24
24
  "@exodus/bitcoinjs-lib": "6.0.2-beta.5",
25
- "@exodus/keychain": "^3.0.0",
26
25
  "@exodus/models": "^8.10.4",
27
26
  "@exodus/secp256k1": "4.0.2-exodus.0",
28
27
  "@exodus/simple-retry": "0.0.6",
@@ -37,8 +36,10 @@
37
36
  "url-join": "4.0.0"
38
37
  },
39
38
  "devDependencies": {
39
+ "@exodus/bcash-meta": "^1.0.0",
40
40
  "@exodus/bip-schnorr": "0.6.6-fork-1",
41
+ "@exodus/bitcoin-meta": "^1.0.0",
41
42
  "@noble/secp256k1": "~1.5.3"
42
43
  },
43
- "gitHead": "822be47e11cc1537913d678bc2771ac4c09eb899"
44
+ "gitHead": "2d223c3c71d00fbd5246af3f39410eec113d0029"
44
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 = getAllAddressesFromWIF(privateKey)
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(
@@ -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() / 1000).toBaseNumber()
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
- return { rawTx, txId, tx }
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
  }