gemhq / money-tree Goto Github PK
View Code? Open in Web Editor NEWThis project forked from wink/money-tree
A Ruby implementation of Bitcoin HD Wallets (Hierarchical Deterministic) BIP32
License: MIT License
This project forked from wink/money-tree
A Ruby implementation of Bitcoin HD Wallets (Hierarchical Deterministic) BIP32
License: MIT License
Dear Wink.
Does the gem support hardened key derivation ?
We use money-tree to maintain our wallet and generated around 30k+ addresses, each associated with a unique path
Recent audit revealed that there are 26 paths would generate a different address now compared to 6 months ago!
What could be the possible causes of this? Is there any way to recover the fund sent to old generated address? And how to prevent this from happening again?
Example:
https://iancoleman.github.io/bip39/
BIP39 Mnemonic:
romance exercise immense final promote blossom swamp strong village dinner salad target
Gives:
BIP44 Derivation Path - BIP32 Extended Public Key:
xpub6ENYRtaTwwoFKfA5CYHJ6sM27xRu6NJLjDG2W2ahVP9xQW65VEm4Rtf2grdCcjTvPYYhqqsctWuKgeydCwYnrySpiDMrhfDY8C81YzhjV3B
BIP49 Derivation Path - BIP32 Extended Public Key:
xpub6FQxoDQx1U5pdzp8CtRAnkoBUcebLrg7xazUZ6YfdyrWdGNEyHs8hZFt54uyKqUwxvjre7rrp2Bni59Ybok5FNmpFQaRRN8n7xBZbiNSBuQ
m/44'/0'/0'/0/0
should be address 1NhXS3e19HeQhbzF3wvxSbM5KrEL18eiDF
node = MoneyTree::Node.from_bip32('xpub6ENYRtaTwwoFKfA5CYHJ6sM27xRu6NJLjDG2W2ahVP9xQW65VEm4Rtf2grdCcjTvPYYhqqsctWuKgeydCwYnrySpiDMrhfDY8C81YzhjV3B').node_for_path("0").to_address
=> "1NhXS3e19HeQhbzF3wvxSbM5KrEL18eiDF"
Success!
m/49'/0'/0'/0/0
should be address 3HnFEPAxBpDfSMXNvKb3EgaBdkN89zc4gF
node = MoneyTree::Node.from_bip32('xpub6FQxoDQx1U5pdzp8CtRAnkoBUcebLrg7xazUZ6YfdyrWdGNEyHs8hZFt54uyKqUwxvjre7rrp2Bni59Ybok5FNmpFQaRRN8n7xBZbiNSBuQ').node_for_path("0").to_address
=> "1JNtziN11HdS4HXAMUJzF511R4Cza7EPqA"
Fail! Address missmatch
Am I doing / thinking wrong or has the Money Tree GEM a problem calculating BIP49 addresses?
My apologies for the ignorant question as I can't find the answer elsewhere.
Do the wallets created by this gem only support BTC? I would like to use this for DOGE instead and am wondering if anything needs to be done differently or the addresses created will also work.
I fixed this with a PR here: #23
Thanks!
on ubuntu 20 with openssl 1.1 everything is ok
on ubuntu 22, since july 8th, with OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022), I have this error
OpenSSL::Digest::DigestError:
Digest initialization failed: initialization error
# .rvm/gems/ruby-3.1.2@gems/money-tree-0.10.0/lib/money-tree/support.rb:62:in `digestify'
# .rvm/gems/ruby-3.1.2@gems/money-tree-0.10.0/lib/money-tree/support.rb:70:in `ripemd160'
# .rvm/gems/ruby-3.1.2@gems/money-tree-0.10.0/lib/money-tree/key.rb:246:in `to_ripemd160'
# .rvm/gems/ruby-3.1.2@gems/money-tree-0.10.0/lib/money-tree/node.rb:130:in `to_identifier'
# .rvm/gems/ruby-3.1.2@gems/money-tree-0.10.0/lib/money-tree/node.rb:146:in `to_address'
# .rvm/gems/ruby-3.1.2@bundler/gems/cryptocoin_payable-776b48475f73/lib/cryptocoin_payable/adapters/bitcoin.rb:20:in `create_address'
According to the readme:
"m/0'/1" == "m/0p/1" == "m/2147483648/1"
But I got this output:
master.node_for_path("m/0'/1").to_address
=> "1136fnhDPuJaA9KkSiZ29UGbwzdH1DYsfX"
master.node_for_path("m/0p/1").to_address
=> "1136fnhDPuJaA9KkSiZ29UGbwzdH1DYsfX"
master.node_for_path("m/2147483648/1").to_address
=> "14QqrtsnNZest6RTQVWxmbgDKSsveEGyx7"
And accourding to https://iancoleman.github.io/bip39/
m/2147483648/1 -> 1136fnhDPuJaA9KkSiZ29UGbwzdH1DYsfX
What am I missing?
ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin16]
gem list money-tree
money-tree (0.9.0)
Does this support p2sh? For example, importing public keys several co-signers to derive addresses for the offline wallet
It looks like the .gemspec
file was last updated 3 years ago and the published gem is quite old.
I'm trying to use this project in cryptocoin_payable which doesn't seem to be possible unless we publish this fork as a gem.
Can we update the gemspec file and publish a gem?
Given a BIP32 key, I'd like to figure out if it's a public or private key and on which network it's used. The information is in the key and the version info is already available in MoneyTrey::Network
.
https://github.com/GemHQ/money-tree/blob/master/lib/money-tree/node.rb#L19 simply strips the version info from the key. I'd like to change that:
node = MoneyTree::Node.from_bip32("tpub...")
node.version
# => :bitcoin_testnet_pubkey
or
node = MoneyTree::Node.from_bip32("tpub...")
node.network
# => :bitcoin_testnet
node.key_type
# => :pubkey
Two questions:
I'd be happy to test and implement these changes.
Can this be used for generating Ethereum addresses from a seed? Looks like some gems like this one are attempting it but I can't get their generated addresses to work properly. The addresses the gem I linked generates don't match the ones that MyEtherWallet or this tool would generate. I'm not experienced enough to know why though.
Any idea what would be required to get the money-tree gem to work in JRuby?
I always struggle here and tried both ways plenty of time
i use the rubygem "moneytree" and electrum 3.3
@master = MoneyTree::Master.new
@master.to_bip32(:private)
this will give me tprv8ZgxMBicQKsPe8hnfLVQdtZk2qMKnnDQs2ZKLgoJQBhedKQ5vB7srAb6Tk2iUYNkhaacTjNP9WzkbjCqPjk8ExUFGECbiR1Z8tZDs76jytn
however, i can't import this in electrum. the next
button is just non active.
i tried the other way around and created a wallet with seed fabric body bright coffee special music virus raccoon side double shield shrug
and exported the master public key which will gives me xpub661MyMwAqRbcGq54zC5FfD3rTjgcAGd36JvtW6r4RGheQjSdUVqAS9Q1DLAvzyvvxdYziZced4Y6kHLCqo73vuB4gGSpt6tJwtCWYm8zsBb
now i'll run the following
master_pub_key = "xpub661MyMwAqRbcGq54zC5FfD3rTjgcAGd36JvtW6r4RGheQjSdUVqAS9Q1DLAvzyvvxdYziZced4Y6kHLCqo73vuB4gGSpt6tJwtCWYm8zsBb"
$bitcoin_root_node = MoneyTree::Node.from_bip32(master_pub_key)
i = 0
20.times do
p $bitcoin_root_node.node_for_path("m/0/#{i}").to_address
i+= 1
end
all generated addresses will look like this
mpQPcBLyTqPPCw9dhdXYm3Dvnnn58Y4dwA
mt6UdprJNAuJUtG3BYWTy3dZrST7nZTwtZ
starting with a small M
however, in electrum all the addresses are starting with 1xxxxx
what am i doing wrong?
the following tests pass but should raise errors
it "recognizes pubkey version / prvkey mismatch" do
MoneyTree::Node.from_bip32 "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6LBpB85b3D2yc8sfvZU521AAwdZafEz7mnzBBsz4wKY5fTtTQBm"
end
it "recognizes prvkey version / pubkey mismatch" do
MoneyTree::Node.from_bip32 "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGTQQD3dC4H2D5GBj7vWvSQaaBv5cxi9gafk7NF3pnBju6dwKvH"
end
it "recognizes zero depth with non-zero parent fingerprint" do
MoneyTree::Node.from_bip32 "xprv9s2SPatNQ9Vc6GTbVMFPFo7jsaZySyzk7L8n2uqKXJen3KUmvQNTuLh3fhZMBoG3G4ZW1N2kZuHEPY53qmbZzCHshoQnNf4GvELZfqTUrcv"
end
it "recognizes zero depth with non-zero parent fingerprint" do
MoneyTree::Node.from_bip32 "xpub661no6RGEX3uJkY4bNnPcw4URcQTrSibUZ4NqJEw5eBkv7ovTwgiT91XX27VbEXGENhYRCf7hyEbWrR3FewATdCEebj6znwMfQkhRYHRLpJ"
end
it "recognizes zero depth with non-zero index" do
MoneyTree::Node.from_bip32 "xprv9s21ZrQH4r4TsiLvyLXqM9P7k1K3EYhA1kkD6xuquB5i39AU8KF42acDyL3qsDbU9NmZn6MsGSUYZEsuoePmjzsB3eFKSUEh3Gu1N3cqVUN"
end
it "recognizes zero depth with non-zero index" do
MoneyTree::Node.from_bip32 "xpub661MyMwAuDcm6CRQ5N4qiHKrJ39Xe1R1NyfouMKTTWcguwVcfrZJaNvhpebzGerh7gucBvzEQWRugZDuDXjNDRmXzSZe4c7mnTK97pTvGS8"
end
it "recognizes unknown extended key version" do
MoneyTree::Node.from_bip32 "DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHGMQzT7ayAmfo4z3gY5KfbrZWZ6St24UVf2Qgo6oujFktLHdHY4"
end
it "recognizes unknown extended key version" do
MoneyTree::Node.from_bip32 "DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHPmHJiEDXkTiJTVV9rHEBUem2mwVbbNfvT2MTcAqj3nesx8uBf9"
end
it "recognizes private key 0 not in 1..n-1" do
MoneyTree::Node.from_bip32 "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx"
end
it "recognizes private key n not in 1..n-1" do
MoneyTree::Node.from_bip32 "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD5SDKr24z3aiUvKr9bJpdrcLg1y3G"
end
ref https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#test-vector-5
Hi @wink - if you have the time, please review the following release that removes unsafe ffi and monkey patching to openssl:
If possible, please consider release v0.11.0 to rubygems.org
Thank you ๐๐ผ
hi
I think this should work for litecoin
litecoin: { address_version: '30', p2sh_version: '32', p2sh_char: '3',##TODO privkey_version: 'b0', privkey_compression_flag: '01',##TODO extended_privkey_version: "019d9cfe", extended_pubkey_version: "019da462", compressed_wif_chars: %w(K L),##TODO uncompressed_wif_chars: %w(5),##TODO protocol_version: 70002 }, litecoin_testnet: { address_version: '6f', p2sh_version: '3a', p2sh_char: '2',##TODO privkey_version: 'ef', privkey_compression_flag: '01',##TODO extended_privkey_version: "0436ef7d", extended_pubkey_version: "0436f6e1", compressed_wif_chars: %w(c),##TODO uncompressed_wif_chars: %w(9),##TODO protocol_version: 70002 }
could you add it to NETWORK ?
thanks
Is it possible to generate a master node from a private key instead of the seed? I generated a random node and want to save just the priv key and generate that same node from that key.
money-tree/lib/openssl_extensions.rb
Line 9 in 2686577
Should add 'libssl.1.0.0'
in the begining of the list. Like this:
ffi_lib ['libssl.1.0.0', 'libssl.so.1.0.0', 'libssl.so.10', 'libssl1.0.0', 'ssl']
There are two defects:
OpenSSL::PKey::EC::Point
this gem can cause error when other code performs EC operations on a curve other then secp256k1
- Do not monkey patch the OpenSSL library.libcyrpto
binaries in the same process.PR #43 solves both of these issues as well as provides a test to ensure conformance.
Error message when trying to import a private key using OpenSSL 3.0.5:
MoneyTree::Master.from_bip32(private)
results in this exception:
Exception: OpenSSL::PKey::PKeyError: pkeys are immutable on OpenSSL 3.0
--
0: /Users/username/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/bundler/gems/money-tree-5d80ffb7302b/lib/money-tree/key.rb:58:in `private_key='
1: /Users/username/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/bundler/gems/money-tree-5d80ffb7302b/lib/money-tree/key.rb:58:in `import'
2: /Users/username/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/bundler/gems/money-tree-5d80ffb7302b/lib/money-tree/key.rb:46:in `initialize'
3: /Users/username/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/bundler/gems/money-tree-5d80ffb7302b/lib/money-tree/node.rb:36:in `new'
4: /Users/username/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/bundler/gems/money-tree-5d80ffb7302b/lib/money-tree/node.rb:36:in `parse_out_key'
5: /Users/username/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/bundler/gems/money-tree-5d80ffb7302b/lib/money-tree/node.rb:31:in `from_bip32'
I get the following error when I try to deploy a project to heroku with this gem as dependency:
2017-06-12T20:03:50.912570+00:00 app[web.1]: * Version 3.9.1 (ruby 2.3.1-p112), codename: Private Caller
2017-06-12T20:03:50.912540+00:00 app[web.1]: Puma starting in single mode...
2017-06-12T20:03:50.912571+00:00 app[web.1]: * Min threads: 5, max threads: 5
2017-06-12T20:03:50.912572+00:00 app[web.1]: * Environment: production
2017-06-12T20:03:52.571169+00:00 app[web.1]: ! Unable to load application: LoadError: Could not open library '/usr/lib/ssl': /usr/lib/ssl: cannot read file data: Is a directory.
2017-06-12T20:03:52.571196+00:00 app[web.1]: Could not open library 'libssl.so': libssl.so: cannot open shared object file: No such file or directory
2017-06-12T20:03:52.571379+00:00 app[web.1]: bundler: failed to load command: puma (/app/vendor/bundle/ruby/2.3.0/bin/puma)
2017-06-12T20:03:52.571474+00:00 app[web.1]: LoadError: Could not open library '/usr/lib/ssl': /usr/lib/ssl: cannot read file data: Is a directory.
2017-06-12T20:03:52.571476+00:00 app[web.1]: Could not open library 'libssl.so': libssl.so: cannot open shared object file: No such file or directory
2017-06-12T20:03:52.571477+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/ffi-1.9.18/lib/ffi/library.rb:147:in `block in ffi_lib'
2017-06-12T20:03:52.571477+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/ffi-1.9.18/lib/ffi/library.rb:100:in `map'
2017-06-12T20:03:52.571478+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/ffi-1.9.18/lib/ffi/library.rb:100:in `ffi_lib'
2017-06-12T20:03:52.571479+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/money-tree-0.9.0/lib/openssl_extensions.rb:9:in `<module:OpenSSLExtensions>'
2017-06-12T20:03:52.571480+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/money-tree-0.9.0/lib/openssl_extensions.rb:7:in `<module:MoneyTree>'
2017-06-12T20:03:52.571481+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/money-tree-0.9.0/lib/openssl_extensions.rb:6:in `<top (required)>'
2017-06-12T20:03:52.571481+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/money-tree-0.9.0/lib/money-tree.rb:1:in `require'
2017-06-12T20:03:52.571482+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/money-tree-0.9.0/lib/money-tree.rb:1:in `<top (required)>'
2017-06-12T20:03:52.571483+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime.rb:91:in `require'
2017-06-12T20:03:52.571483+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime.rb:91:in `block (2 levels) in require'
2017-06-12T20:03:52.571484+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime.rb:86:in `each'
2017-06-12T20:03:52.571485+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime.rb:86:in `block in require'
2017-06-12T20:03:52.571485+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime.rb:75:in `each'
2017-06-12T20:03:52.571486+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime.rb:75:in `require'
2017-06-12T20:03:52.571487+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.13.7/lib/bundler.rb:106:in `require'
2017-06-12T20:03:52.571488+00:00 app[web.1]: /app/config/application.rb:7:in `<top (required)>'
2017-06-12T20:03:52.571488+00:00 app[web.1]: /app/config/environment.rb:2:in `require_relative'
2017-06-12T20:03:52.571489+00:00 app[web.1]: /app/config/environment.rb:2:in `<top (required)>'
2017-06-12T20:03:52.571490+00:00 app[web.1]: config.ru:3:in `require_relative'
2017-06-12T20:03:52.571491+00:00 app[web.1]: config.ru:3:in `block in <main>'
2017-06-12T20:03:52.571491+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-2.0.3/lib/rack/builder.rb:55:in `instance_eval'
2017-06-12T20:03:52.571492+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-2.0.3/lib/rack/builder.rb:55:in `initialize'
2017-06-12T20:03:52.571493+00:00 app[web.1]: config.ru:in `new'
2017-06-12T20:03:52.571494+00:00 app[web.1]: config.ru:in `<main>'
2017-06-12T20:03:52.571494+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-2.0.3/lib/rack/builder.rb:49:in `eval'
2017-06-12T20:03:52.571495+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-2.0.3/lib/rack/builder.rb:49:in `new_from_string'
2017-06-12T20:03:52.571496+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-2.0.3/lib/rack/builder.rb:40:in `parse_file'
2017-06-12T20:03:52.571496+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/puma-3.9.1/lib/puma/configuration.rb:313:in `load_rackup'
2017-06-12T20:03:52.571497+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/puma-3.9.1/lib/puma/configuration.rb:242:in `app'
2017-06-12T20:03:52.571498+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/puma-3.9.1/lib/puma/runner.rb:138:in `load_and_bind'
2017-06-12T20:03:52.571498+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/puma-3.9.1/lib/puma/single.rb:87:in `run'
2017-06-12T20:03:52.571499+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/puma-3.9.1/lib/puma/launcher.rb:174:in `run'
2017-06-12T20:03:52.571499+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/puma-3.9.1/lib/puma/cli.rb:77:in `run'
2017-06-12T20:03:52.571500+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/puma-3.9.1/bin/puma:10:in `<top (required)>'
2017-06-12T20:03:52.571501+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/bin/puma:23:in `load'
2017-06-12T20:03:52.571609+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/bin/puma:23:in `<top (required)>'
It looks like the way this gem is loading the SSL lib is wrong.
https://github.com/GemHQ/money-tree/blob/master/lib/openssl_extensions.rb#L9
If you ever want to create DASH Addreses, feel free to use these changes.
i hope you found this via google, so i saved you lot of headache!
have a nice day
I used to be able to retrieve testnet adresses...
master_node = "tpubD6NzVbkrYhZ4XhirPF9aBVXJ5jRXqEnvbNYjvT3A2TEJMS1WH98PJCQR7BKeDFm3qdYemwT4xroThSMj3G7s5RcGv1Eona6L2jajST7SRBx"
node_path = "m/0/1"
MoneyTree::Node.from_serialized_address(master_node).node_for_path(node_path).to_address
=> "mvrvQHJuUhXmbBuTJ9oXp34VsCjTQt2W3F"
This doesn't work anymore either with this syntax, or with the new "from_bip32" syntax, which are just synonyms anyway. Main net addresses are returned.
master_node = "tpubD6NzVbkrYhZ4XhirPF9aBVXJ5jRXqEnvbNYjvT3A2TEJMS1WH98PJCQR7BKeDFm3qdYemwT4xroThSMj3G7s5RcGv1Eona6L2jajST7SRBx"
node_path = "m/0/1"
MoneyTree::Node.from_serialized_address(master_node).node_for_path(node_path).to_address
=> "1GLy7EDvfg6Wp5Rqaaq9z7rB1D8kXdFWgo"
i've expected a configuration where we simply say
config.testnet = true
we then don't need to pass arguments into the address generation anymore
def to_serialized_hex(type = :public, network: :bitcoin)
could be changed to
def to_serialized_hex(type = :public, network: nil)
network = config.network unless network
what would be against this idea?
would also benefit for testing purposes
Hi
I tried to import a public key, but receive the error "undefined method to_fingerprint
for nil:NilClass" creating the serialized address.
Here is what I did:
master = MoneyTree::Master.new
master.seed_hex #=> "abfe0d5341dffd5fb4fed0931a2acbc445deb6b87d72912e757b7f5e8237dc89"
n = master.node_for_path("m/0/1").to_serialized_address
n2 = MoneyTree::Node.from_serialized_address n
n2.to_serialized_address #=> explodes
Thanks a lot for your help!
The gem on rubygems ( 0.11.1 / 0.11.0 ) is requiring bech32 dependency which is not present on gemspec.
Fix is already present on master, is it possible to publish a new version with this fix ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.