diff --git a/.travis.yml b/.travis.yml index 00dc427..aaa4646 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,3 +8,4 @@ rvm: before_script: - cp config/database.yml{.sample,} - bundle exec rake db:create db:test:prepare +- yarn install diff --git a/Gemfile.lock b/Gemfile.lock index 36f73ab..24c4598 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -430,4 +430,4 @@ DEPENDENCIES webmock BUNDLED WITH - 1.16.1 + 1.16.2 diff --git a/app/lib/btc/address_generator.rb b/app/lib/btc/address_generator.rb index 4f1c9e5..3b45df5 100644 --- a/app/lib/btc/address_generator.rb +++ b/app/lib/btc/address_generator.rb @@ -24,11 +24,18 @@ def address(idx) private def multisig_address(idx) - keychain_group = BTC::KeychainGroup.new(extended_keys: xpub) - keychain_group.standard_address({ - index: idx, - signatures_required: signatures_required, - }) + keychains = xpub.map { |x| BTC::Keychain.new(extended_key: x) } + keys = keychains.map { |keychain| keychain.derived_key(idx) } + public_keys = keys.map { |key| BTC.to_hex(key.public_key) }.sort + + command = [ + "node", + Rails.root.join("lib", "address_gen.js"), + public_keys.join(","), + signatures_required, + ].join(" ") + stdout_str, stderr_str, status = Open3.capture3(command) + stdout_str.chomp end def single_address(idx) diff --git a/docs/bitcoin.md b/docs/bitcoin.md index 3e0d01f..2c5d5bc 100644 --- a/docs/bitcoin.md +++ b/docs/bitcoin.md @@ -7,3 +7,13 @@ Bitcoin addresses will be generated from the supplied `BTC_MASTER_PUBLIC_KEY`. ## Bitcoind setup - Set `txindex=1` to [index all transactions](https://bitcore.io/guides/full-node/). + +## Tips + +If you will be using a wallet like Electrum to manage the funds, the master public key you find there *is not* the one you should place here. The key placed here can be derived the following manner: + +```sh +ruby scripts/electrum.rb master_public_key_you_see_in_electrum +``` + +Of course, test that the addresses generated by this application are the same as the receiving addresses in Electrum. diff --git a/lib/address_gen.js b/lib/address_gen.js new file mode 100644 index 0000000..ed7432e --- /dev/null +++ b/lib/address_gen.js @@ -0,0 +1,10 @@ +let bitcoin = require('bitcoinjs-lib') + +let pubKeys = process.argv[2].split(",").sort().map(function (hex) { return Buffer.from(hex, 'hex') }) +let signaturesRequired = parseInt(process.argv[3]) + +var redeemScript = bitcoin.script.multisig.output.encode(signaturesRequired, pubKeys) +var scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript)) +var address = bitcoin.address.fromOutputScript(scriptPubKey) + +console.log(address) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..0ec2f71 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,208 @@ +{ + "name": "crypto_cold_store", + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "base-x": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.4.tgz", + "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "bech32": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.3.tgz", + "integrity": "sha512-yuVFUvrNcoJi0sv5phmqc6P+Fl1HjRDRNOOkHY2X/3LBy2bIGNSFx4fZ95HMaXHupuS7cZR15AsvtmCIF4UEyg==" + }, + "bigi": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz", + "integrity": "sha1-nGZalfiLiwj8Bc/XMfVhhZ1yWCU=" + }, + "bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "bitcoin-ops": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/bitcoin-ops/-/bitcoin-ops-1.4.1.tgz", + "integrity": "sha512-pef6gxZFztEhaE9RY9HmWVmiIHqCb2OyS4HPKkpc6CIiiOa3Qmuoylxc5P2EkU3w+5eTSifI9SEZC88idAIGow==" + }, + "bitcoinjs-lib": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-3.3.2.tgz", + "integrity": "sha512-l5qqvbaK8wwtANPf6oEffykycg4383XgEYdia1rI7/JpGf1jfRWlOUCvx5TiTZS7kyIvY4j/UhIQ2urLsvGkzw==", + "requires": { + "bech32": "1.1.3", + "bigi": "1.4.2", + "bip66": "1.1.5", + "bitcoin-ops": "1.4.1", + "bs58check": "2.1.1", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "ecurve": "1.0.6", + "merkle-lib": "2.0.10", + "pushdata-bitcoin": "1.0.1", + "randombytes": "2.0.6", + "safe-buffer": "5.1.2", + "typeforce": "1.12.0", + "varuint-bitcoin": "1.1.0", + "wif": "2.0.6" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "3.0.4" + } + }, + "bs58check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.1.tgz", + "integrity": "sha512-okRQiWc5FJuA2VOwQ1hB7Sf0MyEFg/EwRN12h4b8HrJoGkZ3xq1CGjkaAfYloLcZyqixQnO5mhPpN6IcHSplVg==", + "requires": { + "bs58": "4.0.1", + "create-hash": "1.2.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.2" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "md5.js": "1.3.4", + "ripemd160": "2.0.2", + "sha.js": "2.4.11" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.2.0", + "inherits": "2.0.3", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", + "sha.js": "2.4.11" + } + }, + "ecurve": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/ecurve/-/ecurve-1.0.6.tgz", + "integrity": "sha512-/BzEjNfiSuB7jIWKcS/z8FK9jNjmEWvUV2YZ4RLSmcDtP7Lq0m6FvDuSnJpBlDpGRpfRQeTLGLBI8H+kEv0r+w==", + "requires": { + "bigi": "1.4.2", + "safe-buffer": "5.1.2" + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + } + }, + "merkle-lib": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/merkle-lib/-/merkle-lib-2.0.10.tgz", + "integrity": "sha1-grjbrnXieneFOItz+ddyXQ9vMyY=" + }, + "pushdata-bitcoin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pushdata-bitcoin/-/pushdata-bitcoin-1.0.1.tgz", + "integrity": "sha1-FZMdPNlnreUiBvUjqnMxrvfUOvc=", + "requires": { + "bitcoin-ops": "1.4.1" + } + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.2" + } + }, + "typeforce": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.12.0.tgz", + "integrity": "sha512-fvnkvueAOFLhtAqDgIA/wMP21SMwS/NQESFKZuwVrj5m/Ew6eK2S0z0iB++cwtROPWDOhaT6OUfla8UwMw4Adg==" + }, + "varuint-bitcoin": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.0.tgz", + "integrity": "sha512-jCEPG+COU/1Rp84neKTyDJQr478/hAfVp5xxYn09QEH0yBjbmPeMfuuQIrp+BUD83hybtYZKhr5elV3bvdV1bA==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "wif": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", + "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=", + "requires": { + "bs58check": "2.1.1" + } + } + } +} diff --git a/package.json b/package.json index 9fc5c5a..bbec19b 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,7 @@ { "name": "crypto_cold_store", "private": true, - "dependencies": {} + "dependencies": { + "bitcoinjs-lib": "^3.3.2" + } } diff --git a/scripts/electrum.rb b/scripts/electrum.rb new file mode 100644 index 0000000..5df5fc0 --- /dev/null +++ b/scripts/electrum.rb @@ -0,0 +1,8 @@ +require "btcruby" + +def receiving_mpk_for(parent_mpk) + keychain = BTC::Keychain.new(extended_key: parent_mpk) + keychain.derived_keychain("0").xpub +end + +puts receiving_mpk_for(ARGV[0]) diff --git a/spec/lib/btc/address_generator_spec.rb b/spec/lib/btc/address_generator_spec.rb index 859ccc5..8ac5a23 100644 --- a/spec/lib/btc/address_generator_spec.rb +++ b/spec/lib/btc/address_generator_spec.rb @@ -76,20 +76,25 @@ module Btc end context "multiple extended keys" do - let(:generator) do - described_class.new(xpub: xpub, signatures_required: 2) - end let(:xpub) do - [ - "xpub6DY7Fqdz98GSsFDN96Levia3PwnREqhFER5RtKwiwrDzBJpEtGX5VcZdPrLgJriUfStunLmWYxrHM6XPygEJhrXZGrVh1fVZc2AQkAVPf9n", - "xpub6DfZs3n92pxJ3LCBf7bfgbyrECteT8PWmee5UpZhG1aBurdF5t1Tu2jxdnCBXETztHu6YkJ8Hin8t8qwPsh3YScNX3dLxduNSaevLF3KLpq", - "xpub6FFgmnaotx9GP3XkdK8oS8j3ExWBXXGdJ5LeWYmCHUAppaG85HPm4QRGrtowZJfwzDqjKkp1kc5mzUwa2W1PEicuynzC45myaa4vVG7bNJy", + # These are from Electrum + mpks = [ + "xpub6D4K8Hb6sMZwwtbk6p94RnRewTb6PykJc1zZwB3GUozGSNXLnTdL2T8uXRehiD9d5Dis3bDpJCvR3pFZcYUu2xpPj5Z73oFNUUQKwkFTewo", + "xpub661MyMwAqRbcGHY2QrfyiUyvSv93zCQN8Cv3eXFB3ivnq7SQ6TLUJueJnGZKR8r8CQ5cLsGrr9D71uwAW9RLKqFyUybARtbbqg1kiHopBsZ", ] + # but since we want the xpub of the receiving chain and not change + # chain... + mpks.map do |mpk| + BTC::Keychain.new(extended_key: mpk).derived_keychain("0").xpub + end + end + let(:generator) do + described_class.new(xpub: xpub, signatures_required: 1) end it "generates an address at the given index for the required number of signatures" do - expect(generator.address(0)).to eq "397Zemr1wRy3hznQBsdQeeu1d8U5M1HrTZ" - expect(generator.address(18)).to eq "3GAGdkU6awG9aiDyiyrmrjvo8tpHbab5Ff" + expect(generator.address(0)).to eq "3GbE5Hn5NNfAbkk33AquoZqtoehkDDBEZn" + expect(generator.address(18)).to eq "3CwgJ7iYBWufLpwgsGKikjEH5YL38CAfz3" end end end diff --git a/spec/services/btc/addresses/creation/gen_address_spec.rb b/spec/services/btc/addresses/creation/gen_address_spec.rb index 4ae9a58..4f465ed 100644 --- a/spec/services/btc/addresses/creation/gen_address_spec.rb +++ b/spec/services/btc/addresses/creation/gen_address_spec.rb @@ -6,21 +6,26 @@ module Creation RSpec.describe GenAddress do let(:master_public_key) do - [ - "xpub6DY7Fqdz98GSsFDN96Levia3PwnREqhFER5RtKwiwrDzBJpEtGX5VcZdPrLgJriUfStunLmWYxrHM6XPygEJhrXZGrVh1fVZc2AQkAVPf9n", - "xpub6DfZs3n92pxJ3LCBf7bfgbyrECteT8PWmee5UpZhG1aBurdF5t1Tu2jxdnCBXETztHu6YkJ8Hin8t8qwPsh3YScNX3dLxduNSaevLF3KLpq", - "xpub6FFgmnaotx9GP3XkdK8oS8j3ExWBXXGdJ5LeWYmCHUAppaG85HPm4QRGrtowZJfwzDqjKkp1kc5mzUwa2W1PEicuynzC45myaa4vVG7bNJy", + # These are from Electrum + # chain... + mpks = [ + "xpub6D4K8Hb6sMZwwtbk6p94RnRewTb6PykJc1zZwB3GUozGSNXLnTdL2T8uXRehiD9d5Dis3bDpJCvR3pFZcYUu2xpPj5Z73oFNUUQKwkFTewo", + "xpub661MyMwAqRbcGHY2QrfyiUyvSv93zCQN8Cv3eXFB3ivnq7SQ6TLUJueJnGZKR8r8CQ5cLsGrr9D71uwAW9RLKqFyUybARtbbqg1kiHopBsZ", ] + # but since we want the xpub of the receiving chain... + mpks.map do |mpk| + BTC::Keychain.new(extended_key: mpk).derived_keychain("0").xpub + end end - let(:address_18) { "3GAGdkU6awG9aiDyiyrmrjvo8tpHbab5Ff" } + let(:address_1) { "3Dur7FTopK9jAUNSmLyGggMQc1nsnL2Cv6" } it "generates an address based on the keychain[address_index]" do resulting_ctx = described_class.execute( master_public_key: master_public_key, - signatures_required: 2, - address_index: 18, + signatures_required: 1, + address_index: 1, ) - expect(resulting_ctx.public_address).to eq address_18 + expect(resulting_ctx.public_address).to eq address_1 end end diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..7480ee3 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,163 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +base-x@^3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.4.tgz#94c1788736da065edb1d68808869e357c977fa77" + dependencies: + safe-buffer "^5.0.1" + +bech32@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.3.tgz#bd47a8986bbb3eec34a56a097a84b8d3e9a2dfcd" + +bigi@^1.1.0, bigi@^1.4.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/bigi/-/bigi-1.4.2.tgz#9c665a95f88b8b08fc05cfd731f561859d725825" + +bip66@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" + dependencies: + safe-buffer "^5.0.1" + +bitcoin-ops@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/bitcoin-ops/-/bitcoin-ops-1.4.1.tgz#e45de620398e22fd4ca6023de43974ff42240278" + +bitcoinjs-lib@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/bitcoinjs-lib/-/bitcoinjs-lib-3.3.2.tgz#780c9c53ecb1222adb463b58bef26386067b609a" + dependencies: + bech32 "^1.1.2" + bigi "^1.4.0" + bip66 "^1.1.0" + bitcoin-ops "^1.3.0" + bs58check "^2.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.3" + ecurve "^1.0.0" + merkle-lib "^2.0.10" + pushdata-bitcoin "^1.0.1" + randombytes "^2.0.1" + safe-buffer "^5.0.1" + typeforce "^1.11.3" + varuint-bitcoin "^1.0.4" + wif "^2.0.1" + +bs58@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + dependencies: + base-x "^3.0.2" + +bs58check@<3.0.0, bs58check@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.1.tgz#8a5d0e587af97b784bf9cbf1b29f454d82bc0222" + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + +cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +create-hash@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +ecurve@^1.0.0: + version "1.0.6" + resolved "https://registry.yarnpkg.com/ecurve/-/ecurve-1.0.6.tgz#dfdabbb7149f8d8b78816be5a7d5b83fcf6de797" + dependencies: + bigi "^1.1.0" + safe-buffer "^5.0.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +inherits@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +md5.js@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +merkle-lib@^2.0.10: + version "2.0.10" + resolved "https://registry.yarnpkg.com/merkle-lib/-/merkle-lib-2.0.10.tgz#82b8dbae75e27a7785388b73f9d7725d0f6f3326" + +pushdata-bitcoin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pushdata-bitcoin/-/pushdata-bitcoin-1.0.1.tgz#15931d3cd967ade52206f523aa7331aef7d43af7" + dependencies: + bitcoin-ops "^1.3.0" + +randombytes@^2.0.1: + version "2.0.6" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" + dependencies: + safe-buffer "^5.1.0" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +typeforce@^1.11.3: + version "1.12.0" + resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.12.0.tgz#ca40899919f1466d7819e37be039406beb912a2e" + +varuint-bitcoin@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/varuint-bitcoin/-/varuint-bitcoin-1.1.0.tgz#7a343f50537607af6a3059312b9782a170894540" + dependencies: + safe-buffer "^5.1.1" + +wif@^2.0.1: + version "2.0.6" + resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" + dependencies: + bs58check "<3.0.0"