@exodus/bitcoin-api 2.1.0 → 2.2.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.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "Exodus bitcoin-api",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -40,5 +40,5 @@
40
40
  "@exodus/bip-schnorr": "0.6.6-fork-1",
41
41
  "@noble/secp256k1": "~1.5.3"
42
42
  },
43
- "gitHead": "667523b6a37cb6d9755082df52c812a86cda594d"
43
+ "gitHead": "822be47e11cc1537913d678bc2771ac4c09eb899"
44
44
  }
@@ -2,11 +2,12 @@ import bs58check from 'bs58check'
2
2
  import bech32 from 'bech32'
3
3
  import assert from 'minimalistic-assert'
4
4
  import { identity, pickBy } from 'lodash'
5
+ import * as bitcoinjsOriginal from '@exodus/bitcoinjs-lib'
5
6
 
6
7
  export const createBtcLikeAddress = ({
7
8
  versions,
8
9
  coinInfo,
9
- bitcoinjsLib,
10
+ bitcoinjsLib: bitcoinjsLibFork,
10
11
  ecc,
11
12
  useBip86 = false,
12
13
  validateFunctions = {},
@@ -50,11 +51,11 @@ export const createBtcLikeAddress = ({
50
51
  const isP2TR =
51
52
  validateFunctions.isP2TR ||
52
53
  (useBip86 &&
53
- bitcoinjsLib &&
54
+ bitcoinjsLibFork &&
54
55
  ((addr) => {
55
56
  try {
56
57
  const network = coinInfo.toBitcoinJS()
57
- bitcoinjsLib.payments.p2tr({ address: addr, network }, { eccLib: ecc })
58
+ bitcoinjsLibFork.payments.p2tr({ address: addr, network }, { eccLib: ecc })
58
59
  return true
59
60
  } catch (e) {
60
61
  return false
@@ -88,13 +89,16 @@ export const createBtcLikeAddress = ({
88
89
  purposeValidators.find(({ validator }) => validator(string))?.purpose
89
90
  const validate = (string) => Object.values(resolvedValidateFunctions).some((fn) => fn(string))
90
91
 
91
- const toScriptPubKey =
92
- coinInfo && bitcoinjsLib?.address?.toOutputScript
93
- ? (string) => {
94
- const network = coinInfo.toBitcoinJS()
95
- return bitcoinjsLib.address.toOutputScript(string, network, ecc)
96
- }
97
- : undefined
92
+ const toScriptPubKey = (string) => {
93
+ const network = coinInfo.toBitcoinJS()
94
+ return bitcoinjsOriginal.address.toOutputScript(string, network, ecc)
95
+ }
96
+
97
+ const fromScriptPubKey = (scriptPubKey) => {
98
+ if (typeof scriptPubKey === 'string') scriptPubKey = Buffer.from(scriptPubKey, 'hex')
99
+ const network = coinInfo.toBitcoinJS()
100
+ return bitcoinjsOriginal.address.fromOutputScript(scriptPubKey, network)
101
+ }
98
102
 
99
103
  return pickBy(
100
104
  {
@@ -103,6 +107,7 @@ export const createBtcLikeAddress = ({
103
107
  validate,
104
108
  resolvePurpose,
105
109
  toScriptPubKey,
110
+ fromScriptPubKey,
106
111
  ...extraFunctions,
107
112
  },
108
113
  identity
@@ -1,19 +1,14 @@
1
1
  import bs58check from 'bs58check'
2
2
  import wif from 'wif'
3
- import createHash from 'create-hash'
4
3
  import bech32 from 'bech32'
5
4
  import assert from 'minimalistic-assert'
6
5
  import { identity, pickBy } from 'lodash'
7
6
  import * as defaultBitcoinjsLib from '@exodus/bitcoinjs-lib'
7
+ import secp256k1 from 'secp256k1'
8
+ import { hash160 } from './hash-utils'
8
9
 
9
10
  export const publicKeyToHashFactory = (p2pkh) => (publicKey) => {
10
- const sha = createHash('sha256')
11
- .update(publicKey)
12
- .digest()
13
- const pubKeyHash = createHash('rmd160')
14
- .update(sha)
15
- .digest()
16
- const payload = Buffer.concat([Buffer.from([p2pkh]), pubKeyHash])
11
+ const payload = Buffer.concat([Buffer.from([p2pkh]), hash160(publicKey)])
17
12
  return bs58check.encode(payload)
18
13
  }
19
14
 
@@ -54,12 +49,7 @@ export const createBtcLikeKeys = ({
54
49
  const encodePublicBech32 =
55
50
  encodePublicBech32Custom || versions.bech32 !== undefined
56
51
  ? (publicKey) => {
57
- const sha = createHash('sha256')
58
- .update(publicKey)
59
- .digest()
60
- const pubKeyHash = createHash('rmd160')
61
- .update(sha)
62
- .digest()
52
+ const pubKeyHash = hash160(publicKey)
63
53
  const witnessVersion = Buffer.from([0])
64
54
  const witnessProgram = Buffer.concat([
65
55
  witnessVersion,
@@ -82,8 +72,9 @@ export const createBtcLikeKeys = ({
82
72
  const encodeNestedP2WPKH =
83
73
  encodeNestedP2WPKHCustom || bitcoinjsLib
84
74
  ? (publicKey) => {
75
+ const pubkey = secp256k1.publicKeyConvert(publicKey, true)
85
76
  const witnessProgram = bitcoinjsLib.payments.p2wpkh({
86
- pubkey: publicKey,
77
+ pubkey,
87
78
  }).output
88
79
 
89
80
  const witnessProgramHash = bitcoinjsLib.crypto.hash160(witnessProgram)
@@ -0,0 +1,19 @@
1
+ import createHash from 'create-hash'
2
+ export function hash160(buffer) {
3
+ const sha256Hash = sha256(buffer)
4
+ try {
5
+ return createHash('ripemd160')
6
+ .update(sha256Hash)
7
+ .digest()
8
+ } catch {
9
+ return createHash('rmd160')
10
+ .update(sha256Hash)
11
+ .digest()
12
+ }
13
+ }
14
+
15
+ export function sha256(buffer) {
16
+ return createHash('sha256')
17
+ .update(buffer)
18
+ .digest()
19
+ }
package/src/move-funds.js CHANGED
@@ -2,21 +2,28 @@ 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 assets from '@exodus/assets'
6
5
 
7
- export const moveFundsFactory = ({ insightClient, getFeeEstimator, keys, signTx, address }) => {
6
+ export const moveFundsFactory = ({
7
+ asset,
8
+ insightClient,
9
+ getFeeEstimator,
10
+ keys,
11
+ signTx,
12
+ address,
13
+ }) => {
14
+ assert(asset, 'asset is required')
8
15
  assert(insightClient, 'insightClient is required')
9
16
  assert(getFeeEstimator, 'getFeeEstimator is required')
10
17
  assert(address, 'address is required')
11
18
  assert(keys, 'keys is required')
12
19
  assert(signTx, 'signTx is required')
13
20
  async function prepareFunds(assetName, input, options = {}) {
14
- const asset = assets[assetName]
15
21
  const { toAddress, assetClientInterface, MoveFundsError, walletAccount } = options
16
22
  assert(MoveFundsError, 'MoveFundsError is required') // should we move MoveFundsError to asset libs?
17
23
  assert(toAddress, 'toAddress is required')
18
24
  assert(assetClientInterface, 'assetClientInterface is required')
19
25
  assert(walletAccount, 'walletAccount is required')
26
+ assert(asset.name === assetName, `expected asset ${asset.name} but got assetName ${assetName}`)
20
27
 
21
28
  const formatProps = {
22
29
  asset,
@@ -130,9 +130,10 @@ export const createAndBroadcastTXFactory = ({
130
130
 
131
131
  let replaceableTxs = findUnconfirmedSentRbfTxs(txSet)
132
132
 
133
- if (assetName === 'bcash') {
133
+ if (asset.address.toLegacyAddress) {
134
134
  address = asset.address.toLegacyAddress(address)
135
135
  }
136
+
136
137
  if (assetName === 'digibyte') {
137
138
  if (asset.address.isP2SH2(address)) {
138
139
  address = asset.address.P2SH2ToP2SH(address)
@@ -216,7 +217,7 @@ export const createAndBroadcastTXFactory = ({
216
217
  const change = selectedUtxos.value.sub(totalAmount).sub(fee)
217
218
  const dust = getDustValue(asset)
218
219
  let ourAddress = replaceTx?.data?.changeAddress || changeAddress
219
- if (['bcash'].includes(assetName)) {
220
+ if (asset.address.toLegacyAddress) {
220
221
  const legacyAddress = asset.address.toLegacyAddress(ourAddress.address)
221
222
  ourAddress = Address.create(legacyAddress, ourAddress.meta)
222
223
  }