From 1b16d310725523841745d5a0e18852a38a59ebed Mon Sep 17 00:00:00 2001 From: Fernando Pelliccioni Date: Wed, 9 Aug 2023 00:46:11 +0200 Subject: [PATCH] new wallet func --- binding.gyp | 5 + include/kth/js-native/chain/block.hpp | 4 +- include/kth/js-native/chain/tools.hpp | 6 +- include/kth/js-native/chain/transaction.hpp | 4 +- include/kth/js-native/helper.hpp | 22 +- include/kth/js-native/wallet/convertions.hpp | 124 ++++++ include/kth/js-native/wallet/ec_private.hpp | 30 ++ include/kth/js-native/wallet/ec_public.hpp | 28 ++ .../kth/js-native/wallet/elliptic_curve.hpp | 16 + include/kth/js-native/wallet/hd_private.hpp | 31 ++ include/kth/js-native/wallet/hd_public.hpp | 29 ++ include/kth/js-native/wallet/wallet.hpp | 20 + package-lock.json | 18 +- package.json | 4 +- src/chain/block.cpp | 56 +-- src/chain/tools.cpp | 43 +-- src/chain/transaction.cpp | 66 ++-- src/config/blockchain_settings.cpp | 2 +- src/config/network_settings.cpp | 6 +- src/kth-native.cpp | 91 ++++- src/string_list.cpp | 13 +- src/wallet/ec_private.cpp | 341 +++++++++++++++++ src/wallet/ec_public.cpp | 307 +++++++++++++++ src/wallet/elliptic_curve.cpp | 67 ++++ src/wallet/hd_private.cpp | 357 ++++++++++++++++++ src/wallet/hd_public.cpp | 293 ++++++++++++++ src/wallet/payment_address.cpp | 80 +++- src/wallet/wallet.cpp | 160 ++++++++ tests.js | 59 ++- 29 files changed, 2115 insertions(+), 167 deletions(-) create mode 100644 include/kth/js-native/wallet/convertions.hpp create mode 100644 include/kth/js-native/wallet/ec_private.hpp create mode 100644 include/kth/js-native/wallet/ec_public.hpp create mode 100644 include/kth/js-native/wallet/elliptic_curve.hpp create mode 100644 include/kth/js-native/wallet/hd_private.hpp create mode 100644 include/kth/js-native/wallet/hd_public.hpp create mode 100644 include/kth/js-native/wallet/wallet.hpp create mode 100644 src/wallet/ec_private.cpp create mode 100644 src/wallet/ec_public.cpp create mode 100644 src/wallet/elliptic_curve.cpp create mode 100644 src/wallet/hd_private.cpp create mode 100644 src/wallet/hd_public.cpp create mode 100644 src/wallet/wallet.cpp diff --git a/binding.gyp b/binding.gyp index 2045c12..9473d91 100644 --- a/binding.gyp +++ b/binding.gyp @@ -42,7 +42,12 @@ "src/config/settings.cpp", "src/wallet/ec_private.cpp", + "src/wallet/ec_public.cpp", + "src/wallet/elliptic_curve.cpp", + "src/wallet/hd_private.cpp", + "src/wallet/hd_public.cpp", "src/wallet/payment_address.cpp", + "src/wallet/wallet.cpp", ], diff --git a/include/kth/js-native/chain/block.hpp b/include/kth/js-native/chain/block.hpp index 81b845e..563ef62 100644 --- a/include/kth/js-native/chain/block.hpp +++ b/include/kth/js-native/chain/block.hpp @@ -16,7 +16,7 @@ void chain_block_destruct(v8::FunctionCallbackInfo const& args); void chain_block_is_valid(v8::FunctionCallbackInfo const& args); void chain_block_header(v8::FunctionCallbackInfo const& args); void chain_block_hash(v8::FunctionCallbackInfo const& args); -void chain_block_hash_out(v8::FunctionCallbackInfo const& args); +// void chain_block_hash_out(v8::FunctionCallbackInfo const& args); void chain_block_proof_str(v8::FunctionCallbackInfo const& args); void chain_block_transactions(v8::FunctionCallbackInfo const& args); void chain_block_serialized_size(v8::FunctionCallbackInfo const& args); @@ -25,7 +25,7 @@ void chain_block_fees(v8::FunctionCallbackInfo const& args); void chain_block_claim(v8::FunctionCallbackInfo const& args); void chain_block_reward(v8::FunctionCallbackInfo const& args); void chain_block_generate_merkle_root(v8::FunctionCallbackInfo const& args); -void chain_block_generate_merkle_root_out(v8::FunctionCallbackInfo const& args); +// void chain_block_generate_merkle_root_out(v8::FunctionCallbackInfo const& args); void chain_block_signature_operations(v8::FunctionCallbackInfo const& args); void chain_block_signature_operations_bip16_active(v8::FunctionCallbackInfo const& args); void chain_block_total_inputs(v8::FunctionCallbackInfo const& args); diff --git a/include/kth/js-native/chain/tools.hpp b/include/kth/js-native/chain/tools.hpp index bfa3fad..3908d3e 100644 --- a/include/kth/js-native/chain/tools.hpp +++ b/include/kth/js-native/chain/tools.hpp @@ -10,10 +10,8 @@ namespace kth::js_native { kth_hash_t to_native_hash(v8::Local const& arr); -kth_shorthash_t to_native_shorthash(v8::Local arr); -kth_wif_compressed_t to_native_wif_compressed(v8::Local arr); -kth_wif_uncompressed_t to_native_wif_uncompressed(v8::Local arr); -kth_ec_secret_t to_native_ec_secret(v8::Local arr); +kth_shorthash_t to_native_shorthash(v8::Local const& arr); +kth_longhash_t to_native_longhash(v8::Local const& arr); } // namespace kth::js_native diff --git a/include/kth/js-native/chain/transaction.hpp b/include/kth/js-native/chain/transaction.hpp index d6660e6..8a13988 100644 --- a/include/kth/js-native/chain/transaction.hpp +++ b/include/kth/js-native/chain/transaction.hpp @@ -17,9 +17,9 @@ void chain_transaction_is_valid(v8::FunctionCallbackInfo const& args) void chain_transaction_version(v8::FunctionCallbackInfo const& args); void chain_transaction_set_version(v8::FunctionCallbackInfo const& args); void chain_transaction_hash(v8::FunctionCallbackInfo const& args); -void chain_transaction_hash_out(v8::FunctionCallbackInfo const& args); +// void chain_transaction_hash_out(v8::FunctionCallbackInfo const& args); void chain_transaction_hash_sighash_type(v8::FunctionCallbackInfo const& args); -void chain_transaction_hash_sighash_type_out(v8::FunctionCallbackInfo const& args); +// void chain_transaction_hash_sighash_type_out(v8::FunctionCallbackInfo const& args); void chain_transaction_locktime(v8::FunctionCallbackInfo const& args); void chain_transaction_serialized_size(v8::FunctionCallbackInfo const& args); void chain_transaction_fees(v8::FunctionCallbackInfo const& args); diff --git a/include/kth/js-native/helper.hpp b/include/kth/js-native/helper.hpp index b09a5f3..0ff08a5 100644 --- a/include/kth/js-native/helper.hpp +++ b/include/kth/js-native/helper.hpp @@ -57,13 +57,19 @@ T copy_data_and_free(context_t& context) { #if defined(_WIN32) inline -v8::Local string_to_js(v8::Isolate* isolate, wchar_t const* str) { +v8::Local string_to_js(v8::Isolate* isolate, wchar_t const* str) { + if (str == nullptr) { + return v8::Null(isolate); + } return v8::String::NewFromTwoByte(isolate, reinterpret_cast(str), v8::NewStringType::kNormal).ToLocalChecked(); } #endif // defined(_WIN32) inline -v8::Local string_to_js(v8::Isolate* isolate, char const* str) { +v8::Local string_to_js(v8::Isolate* isolate, char const* str) { + if (str == nullptr) { + return v8::Null(isolate); + } return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kNormal).ToLocalChecked(); } @@ -119,6 +125,11 @@ v8::Local shorthash_to_js(v8::Isolate* isolate, kth_shorthash_t return byte_array_to_js(isolate, hash.hash, 16); } +inline +v8::Local longhash_to_js(v8::Isolate* isolate, kth_longhash_t const& hash) { + return byte_array_to_js(isolate, hash.hash, 64); +} + inline kth_bool_t bool_to_cpp(v8::Isolate* isolate, v8::Local const& x) { bool b = x->BooleanValue(isolate); @@ -164,13 +175,6 @@ kth_db_mode_t db_mode_to_cpp(v8::Isolate* isolate, v8::Local const& x return res; } -// Wallet -inline -v8::Local ec_secret_to_js(v8::Isolate* isolate, kth_ec_secret_t const& x) { - return byte_array_to_js(isolate, x.data, 32); -} - - } // namespace kth::js_native #endif // KTH_JS_NATIVE_HELPER_HPP_ diff --git a/include/kth/js-native/wallet/convertions.hpp b/include/kth/js-native/wallet/convertions.hpp new file mode 100644 index 0000000..a4bd611 --- /dev/null +++ b/include/kth/js-native/wallet/convertions.hpp @@ -0,0 +1,124 @@ +// Copyright (c) 2016-2023 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef KTH_JS_NATIVE_WALLET_CONVERTIONS_HPP_ +#define KTH_JS_NATIVE_WALLET_CONVERTIONS_HPP_ + +#include +#include + +#include +#include + +#include + +namespace kth::js_native { + +inline +v8::Local ec_secret_to_js(v8::Isolate* isolate, kth_ec_secret_t const& x) { + return byte_array_to_js(isolate, x.hash, KTH_BITCOIN_EC_SECRET_SIZE); +} + +inline +v8::Local hd_key_to_js(v8::Isolate* isolate, kth_hd_key_t const& x) { + return byte_array_to_js(isolate, x.data, KTH_HD_KEY_SIZE); +} + +inline +v8::Local ec_compressed_to_js(v8::Isolate* isolate, kth_ec_compressed_t const& x) { + return byte_array_to_js(isolate, x.data, KTH_EC_COMPRESSED_SIZE); +} + +inline +v8::Local ec_uncompressed_to_js(v8::Isolate* isolate, kth_ec_uncompressed_t const& x) { + return byte_array_to_js(isolate, x.data, KTH_BITCOIN_EC_UNCOMPRESSED_SIZE); +} + +inline +v8::Local hd_chain_code_to_js(v8::Isolate* isolate, kth_hd_chain_code_t const& x) { + return byte_array_to_js(isolate, x.data, KTH_HD_CHAIN_CODE_SIZE); +} + +inline +v8::Local hd_lineage_to_js(v8::Isolate* isolate, kth_hd_lineage const& x) { + auto ctx = isolate->GetCurrentContext(); + v8::Local res = v8::Object::New(isolate); + res->Set(ctx, string_to_js(isolate, "prefixes"), v8::Number::New(isolate, x.prefixes)); + res->Set(ctx, string_to_js(isolate, "depth"), v8::Number::New(isolate, x.depth)); + res->Set(ctx, string_to_js(isolate, "parent_fingerprint"), v8::Number::New(isolate, x.parent_fingerprint)); + res->Set(ctx, string_to_js(isolate, "child_number"), v8::Number::New(isolate, x.child_number)); + return res; +} + +inline +kth_hd_key_t to_native_hd_key(v8::Local const& arr) { + //precondition: arr->Length() == KTH_HD_KEY_SIZE + kth_hd_key_t res; + +#if (V8_MAJOR_VERSION >= 8) + uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetBackingStore()->Data(); +#else + uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetContents().Data(); +#endif + + for (uint32_t i = 0; i < arr->Length(); ++i) { + res.data[i] = native_arr[i]; + } + return res; +} + +inline +kth_ec_secret_t to_native_ec_secret(v8::Local const& arr) { + //precondition: arr->Length() == 32 + kth_ec_secret_t res; + +#if (V8_MAJOR_VERSION >= 8) + uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetBackingStore()->Data(); +#else + uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetContents().Data(); +#endif + + for (uint32_t i = 0; i < arr->Length(); ++i) { + res.hash[i] = native_arr[i]; + } + return res; +} + +inline +kth_wif_compressed_t to_native_wif_compressed(v8::Local arr) { + //precondition: arr->Length() == 38 + kth_wif_compressed_t res; + +#if (V8_MAJOR_VERSION >= 8) + uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetBackingStore()->Data(); +#else + uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetContents().Data(); +#endif + + for (uint32_t i = 0; i < arr->Length(); ++i) { + res.data[i] = native_arr[i]; + } + return res; +} + +inline +kth_wif_uncompressed_t to_native_wif_uncompressed(v8::Local arr) { + //precondition: arr->Length() == 37 + kth_wif_uncompressed_t res; + +#if (V8_MAJOR_VERSION >= 8) + uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetBackingStore()->Data(); +#else + uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetContents().Data(); +#endif + + for (uint32_t i = 0; i < arr->Length(); ++i) { + res.data[i] = native_arr[i]; + } + return res; +} + +} // namespace kth::js_native + +#endif // KTH_JS_NATIVE_WALLET_CONVERTIONS_HPP_ diff --git a/include/kth/js-native/wallet/ec_private.hpp b/include/kth/js-native/wallet/ec_private.hpp new file mode 100644 index 0000000..541fdd8 --- /dev/null +++ b/include/kth/js-native/wallet/ec_private.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2016-2023 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef KTH_JS_WALLET_EC_PRIVATE_HPP_ +#define KTH_JS_WALLET_EC_PRIVATE_HPP_ + +#include + +namespace kth::js_native { + +void wallet_ec_private_construct_default(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_construct_string(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_construct_compressed(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_construct_uncompressed(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_construct_secret(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_destruct(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_is_valid(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_encoded(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_secret(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_version(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_payment_version(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_wif_version(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_compressed(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_to_public(v8::FunctionCallbackInfo const& args); +void wallet_ec_private_to_payment_address(v8::FunctionCallbackInfo const& args); + +} // namespace kth::js_native + +#endif //KTH_JS_WALLET_EC_PRIVATE_HPP_ diff --git a/include/kth/js-native/wallet/ec_public.hpp b/include/kth/js-native/wallet/ec_public.hpp new file mode 100644 index 0000000..cd8b57f --- /dev/null +++ b/include/kth/js-native/wallet/ec_public.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2016-2023 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef KTH_JS_WALLET_EC_PUBLIC_HPP_ +#define KTH_JS_WALLET_EC_PUBLIC_HPP_ + +#include + +namespace kth::js_native { + +void wallet_ec_public_construct_default(v8::FunctionCallbackInfo const& args); +void wallet_ec_public_construct(v8::FunctionCallbackInfo const& args); +void wallet_ec_public_construct_from_decoded(v8::FunctionCallbackInfo const& args); +void wallet_ec_public_construct_from_base16(v8::FunctionCallbackInfo const& args); +void wallet_ec_public_construct_from_point(v8::FunctionCallbackInfo const& args); +void wallet_ec_public_destruct(v8::FunctionCallbackInfo const& args); +void wallet_ec_public_is_valid(v8::FunctionCallbackInfo const& args); +void wallet_ec_public_encoded(v8::FunctionCallbackInfo const& args); +void wallet_ec_public_point(v8::FunctionCallbackInfo const& args); +void wallet_ec_public_compressed(v8::FunctionCallbackInfo const& args); +void wallet_ec_public_to_data(v8::FunctionCallbackInfo const& args); +void wallet_ec_public_to_uncompressed(v8::FunctionCallbackInfo const& args); +void wallet_ec_public_to_payment_address(v8::FunctionCallbackInfo const& args); + +} // namespace kth::js_native + +#endif //KTH_JS_WALLET_EC_PUBLIC_HPP_ diff --git a/include/kth/js-native/wallet/elliptic_curve.hpp b/include/kth/js-native/wallet/elliptic_curve.hpp new file mode 100644 index 0000000..92691b3 --- /dev/null +++ b/include/kth/js-native/wallet/elliptic_curve.hpp @@ -0,0 +1,16 @@ +// Copyright (c) 2016-2023 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef KTH_JS_WALLET_ELLIPTIC_CURVE_HPP +#define KTH_JS_WALLET_ELLIPTIC_CURVE_HPP + +#include + +namespace kth::js_native { + +void wallet_secret_to_public(v8::FunctionCallbackInfo const& args); + +} // namespace kth::js_native + +#endif //KTH_JS_WALLET_ELLIPTIC_CURVE_HPP diff --git a/include/kth/js-native/wallet/hd_private.hpp b/include/kth/js-native/wallet/hd_private.hpp new file mode 100644 index 0000000..89718d6 --- /dev/null +++ b/include/kth/js-native/wallet/hd_private.hpp @@ -0,0 +1,31 @@ +// Copyright (c) 2016-2023 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef KTH_JS_WALLET_HD_PRIVATE_HPP_ +#define KTH_JS_WALLET_HD_PRIVATE_HPP_ + +#include + +namespace kth::js_native { + +void wallet_hd_private_construct_default(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_construct(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_construct_with_prefix(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_construct_with_prefixes(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_construct_with_seed(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_construct_string(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_construct_string_with_prefix(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_construct_string_with_prefixes(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_destruct(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_encoded(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_secret(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_to_hd_key(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_to_public(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_derive_private(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_derive_public(v8::FunctionCallbackInfo const& args); + + +} // namespace kth::js_native + +#endif //KTH_JS_WALLET_HD_PRIVATE_HPP_ diff --git a/include/kth/js-native/wallet/hd_public.hpp b/include/kth/js-native/wallet/hd_public.hpp new file mode 100644 index 0000000..189d85a --- /dev/null +++ b/include/kth/js-native/wallet/hd_public.hpp @@ -0,0 +1,29 @@ +// Copyright (c) 2016-2023 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef KTH_JS_WALLET_HD_PUBLIC_HPP_ +#define KTH_JS_WALLET_HD_PUBLIC_HPP_ + +#include + +namespace kth::js_native { + +void wallet_hd_public_construct_default(v8::FunctionCallbackInfo const& args); +void wallet_hd_public_construct(v8::FunctionCallbackInfo const& args); +void wallet_hd_public_construct_with_prefix(v8::FunctionCallbackInfo const& args); +void wallet_hd_public_construct_string(v8::FunctionCallbackInfo const& args); +void wallet_hd_public_construct_string_with_prefix(v8::FunctionCallbackInfo const& args); +void wallet_hd_public_destruct(v8::FunctionCallbackInfo const& args); +void wallet_hd_public_is_valid(v8::FunctionCallbackInfo const& args); +void wallet_hd_public_encoded(v8::FunctionCallbackInfo const& args); +void wallet_hd_public_chain_code(v8::FunctionCallbackInfo const& args); +void wallet_hd_public_lineage(v8::FunctionCallbackInfo const& args); +void wallet_hd_public_point(v8::FunctionCallbackInfo const& args); +void wallet_hd_public_to_hd_key(v8::FunctionCallbackInfo const& args); +void wallet_hd_public_derive_public(v8::FunctionCallbackInfo const& args); + + +} // namespace kth::js_native + +#endif //KTH_JS_WALLET_HD_PUBLIC_HPP_ diff --git a/include/kth/js-native/wallet/wallet.hpp b/include/kth/js-native/wallet/wallet.hpp new file mode 100644 index 0000000..62147a3 --- /dev/null +++ b/include/kth/js-native/wallet/wallet.hpp @@ -0,0 +1,20 @@ +// Copyright (c) 2016-2023 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef KTH_JS_WALLET_WALLET_HPP_ +#define KTH_JS_WALLET_WALLET_HPP_ + +#include + +namespace kth::js_native { + +void wallet_mnemonics_to_seed(v8::FunctionCallbackInfo const& args); +void wallet_hd_new(v8::FunctionCallbackInfo const& args); +void wallet_hd_private_to_ec(v8::FunctionCallbackInfo const& args); +void wallet_ec_to_public(v8::FunctionCallbackInfo const& args); +void wallet_ec_to_address(v8::FunctionCallbackInfo const& args); + +} // namespace kth::js_native + +#endif //KTH_JS_WALLET_WALLET_HPP_ diff --git a/package-lock.json b/package-lock.json index d5f06cc..129e138 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { "name": "@knuth/bch-native", - "version": "0.57.0", + "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@knuth/bch-native", - "version": "0.57.0", + "version": "1.0.0", "hasInstallScript": true, "license": "MIT", "dependencies": { "@mapbox/node-pre-gyp": "^1.0.11", - "nan": "^2.16.0" + "nan": "^2.17.0" }, "devDependencies": { "jest": "^28.1.1" @@ -2845,9 +2845,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nan": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==" + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==" }, "node_modules/natural-compare": { "version": "1.4.0", @@ -5895,9 +5895,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "nan": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==" + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==" }, "natural-compare": { "version": "1.4.0", diff --git a/package.json b/package.json index 19eded4..cd04417 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@knuth/bch-native", - "version": "0.57.0", + "version": "1.0.0", "description": "Foundation library for @knuth/bch (Bitcoin Cash development platform for Javascript applications)", "repository": { "type": "git", @@ -34,7 +34,7 @@ }, "dependencies": { "@mapbox/node-pre-gyp": "^1.0.11", - "nan": "^2.16.0" + "nan": "^2.17.0" }, "devDependencies": { "jest": "^28.1.1" diff --git a/src/chain/block.cpp b/src/chain/block.cpp index bf476f9..adeeeec 100644 --- a/src/chain/block.cpp +++ b/src/chain/block.cpp @@ -178,25 +178,25 @@ void chain_block_hash(v8::FunctionCallbackInfo const& args) { args.GetReturnValue().Set(hash_to_js(isolate, res)); } -void chain_block_hash_out(v8::FunctionCallbackInfo const& args) { - Isolate* isolate = args.GetIsolate(); +// void chain_block_hash_out(v8::FunctionCallbackInfo const& args) { +// Isolate* isolate = args.GetIsolate(); - if (args.Length() != 1) { - throw_exception(isolate, "Wrong number of arguments. chain_block_hash_out function requires 2 arguments."); - return; - } +// if (args.Length() != 1) { +// throw_exception(isolate, "Wrong number of arguments. chain_block_hash_out function requires 2 arguments."); +// return; +// } - if ( ! args[0]->IsExternal()) { - throw_exception(isolate, "Wrong argument type for argument block (#1). Required to be IsExternal."); - return; - } +// if ( ! args[0]->IsExternal()) { +// throw_exception(isolate, "Wrong argument type for argument block (#1). Required to be IsExternal."); +// return; +// } - kth_block_t block = (kth_block_t)v8::External::Cast(*args[0])->Value(); - kth_hash_t hash; +// kth_block_t block = (kth_block_t)v8::External::Cast(*args[0])->Value(); +// kth_hash_t hash; - kth_chain_block_hash_out(block, &hash); +// kth_chain_block_hash_out(block, &hash); -} +// } void chain_block_proof_str(v8::FunctionCallbackInfo const& args) { Isolate* isolate = args.GetIsolate(); @@ -362,25 +362,25 @@ void chain_block_generate_merkle_root(v8::FunctionCallbackInfo const& args.GetReturnValue().Set(hash_to_js(isolate, res)); } -void chain_block_generate_merkle_root_out(v8::FunctionCallbackInfo const& args) { - Isolate* isolate = args.GetIsolate(); +// void chain_block_generate_merkle_root_out(v8::FunctionCallbackInfo const& args) { +// Isolate* isolate = args.GetIsolate(); - if (args.Length() != 1) { - throw_exception(isolate, "Wrong number of arguments. chain_block_generate_merkle_root_out function requires 2 arguments."); - return; - } +// if (args.Length() != 1) { +// throw_exception(isolate, "Wrong number of arguments. chain_block_generate_merkle_root_out function requires 2 arguments."); +// return; +// } - if ( ! args[0]->IsExternal()) { - throw_exception(isolate, "Wrong argument type for argument block (#1). Required to be IsExternal."); - return; - } +// if ( ! args[0]->IsExternal()) { +// throw_exception(isolate, "Wrong argument type for argument block (#1). Required to be IsExternal."); +// return; +// } - kth_block_t block = (kth_block_t)v8::External::Cast(*args[0])->Value(); - kth_hash_t merkle; +// kth_block_t block = (kth_block_t)v8::External::Cast(*args[0])->Value(); +// kth_hash_t merkle; - kth_chain_block_generate_merkle_root_out(block, &merkle); +// kth_chain_block_generate_merkle_root_out(block, &merkle); -} +// } void chain_block_signature_operations(v8::FunctionCallbackInfo const& args) { Isolate* isolate = args.GetIsolate(); diff --git a/src/chain/tools.cpp b/src/chain/tools.cpp index 00be44c..4c37081 100644 --- a/src/chain/tools.cpp +++ b/src/chain/tools.cpp @@ -25,7 +25,7 @@ kth_hash_t to_native_hash(v8::Local const& arr) { return res; } -kth_shorthash_t to_native_shorthash(v8::Local arr) { +kth_shorthash_t to_native_shorthash(v8::Local const& arr) { //precondition: arr->Length() == 20 kth_shorthash_t res; @@ -41,9 +41,9 @@ kth_shorthash_t to_native_shorthash(v8::Local arr) { return res; } -kth_wif_compressed_t to_native_wif_compressed(v8::Local arr) { - //precondition: arr->Length() == 38 - kth_wif_compressed_t res; +kth_longhash_t to_native_longhash(v8::Local const& arr) { + //precondition: arr->Length() == 64 + kth_longhash_t res; #if (V8_MAJOR_VERSION >= 8) uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetBackingStore()->Data(); @@ -52,42 +52,9 @@ kth_wif_compressed_t to_native_wif_compressed(v8::Local arr) { #endif for (uint32_t i = 0; i < arr->Length(); ++i) { - res.data[i] = native_arr[i]; - } - return res; -} - -kth_wif_uncompressed_t to_native_wif_uncompressed(v8::Local arr) { - //precondition: arr->Length() == 37 - kth_wif_uncompressed_t res; - -#if (V8_MAJOR_VERSION >= 8) - uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetBackingStore()->Data(); -#else - uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetContents().Data(); -#endif - - for (uint32_t i = 0; i < arr->Length(); ++i) { - res.data[i] = native_arr[i]; - } - return res; -} - -kth_ec_secret_t to_native_ec_secret(v8::Local arr) { - //precondition: arr->Length() == 32 - kth_ec_secret_t res; - -#if (V8_MAJOR_VERSION >= 8) - uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetBackingStore()->Data(); -#else - uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetContents().Data(); -#endif - - for (uint32_t i = 0; i < arr->Length(); ++i) { - res.data[i] = native_arr[i]; + res.hash[i] = native_arr[i]; } return res; } - } // namespace kth::js_native diff --git a/src/chain/transaction.cpp b/src/chain/transaction.cpp index b761c90..888e1b6 100644 --- a/src/chain/transaction.cpp +++ b/src/chain/transaction.cpp @@ -213,25 +213,25 @@ void chain_transaction_hash(v8::FunctionCallbackInfo const& args) { args.GetReturnValue().Set(hash_to_js(isolate, res)); } -void chain_transaction_hash_out(v8::FunctionCallbackInfo const& args) { - Isolate* isolate = args.GetIsolate(); +// void chain_transaction_hash_out(v8::FunctionCallbackInfo const& args) { +// Isolate* isolate = args.GetIsolate(); - if (args.Length() != 1) { - throw_exception(isolate, "Wrong number of arguments. chain_transaction_hash_out function requires 2 arguments."); - return; - } +// if (args.Length() != 1) { +// throw_exception(isolate, "Wrong number of arguments. chain_transaction_hash_out function requires 2 arguments."); +// return; +// } - if ( ! args[0]->IsExternal()) { - throw_exception(isolate, "Wrong argument type for argument transaction (#1). Required to be IsExternal."); - return; - } +// if ( ! args[0]->IsExternal()) { +// throw_exception(isolate, "Wrong argument type for argument transaction (#1). Required to be IsExternal."); +// return; +// } - kth_transaction_t transaction = (kth_transaction_t)v8::External::Cast(*args[0])->Value(); - kth_hash_t hash; +// kth_transaction_t transaction = (kth_transaction_t)v8::External::Cast(*args[0])->Value(); +// kth_hash_t hash; - kth_chain_transaction_hash_out(transaction, &hash); +// kth_chain_transaction_hash_out(transaction, &hash); -} +// } void chain_transaction_hash_sighash_type(v8::FunctionCallbackInfo const& args) { Isolate* isolate = args.GetIsolate(); @@ -258,31 +258,31 @@ void chain_transaction_hash_sighash_type(v8::FunctionCallbackInfo con args.GetReturnValue().Set(hash_to_js(isolate, res)); } -void chain_transaction_hash_sighash_type_out(v8::FunctionCallbackInfo const& args) { - Isolate* isolate = args.GetIsolate(); +// void chain_transaction_hash_sighash_type_out(v8::FunctionCallbackInfo const& args) { +// Isolate* isolate = args.GetIsolate(); - if (args.Length() != 2) { - throw_exception(isolate, "Wrong number of arguments. chain_transaction_hash_sighash_type_out function requires 3 arguments."); - return; - } +// if (args.Length() != 2) { +// throw_exception(isolate, "Wrong number of arguments. chain_transaction_hash_sighash_type_out function requires 3 arguments."); +// return; +// } - if ( ! args[0]->IsExternal()) { - throw_exception(isolate, "Wrong argument type for argument transaction (#1). Required to be IsExternal."); - return; - } +// if ( ! args[0]->IsExternal()) { +// throw_exception(isolate, "Wrong argument type for argument transaction (#1). Required to be IsExternal."); +// return; +// } - if ( ! args[1]->IsNumber()) { - throw_exception(isolate, "Wrong argument type for argument sighash_type (#2). Required to be IsNumber."); - return; - } +// if ( ! args[1]->IsNumber()) { +// throw_exception(isolate, "Wrong argument type for argument sighash_type (#2). Required to be IsNumber."); +// return; +// } - kth_transaction_t transaction = (kth_transaction_t)v8::External::Cast(*args[0])->Value(); - uint32_t sighash_type = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); - kth_hash_t hash; +// kth_transaction_t transaction = (kth_transaction_t)v8::External::Cast(*args[0])->Value(); +// uint32_t sighash_type = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); +// kth_hash_t hash; - kth_chain_transaction_hash_sighash_type_out(transaction, sighash_type, &hash); +// kth_chain_transaction_hash_sighash_type_out(transaction, sighash_type, &hash); -} +// } void chain_transaction_locktime(v8::FunctionCallbackInfo const& args) { Isolate* isolate = args.GetIsolate(); diff --git a/src/config/blockchain_settings.cpp b/src/config/blockchain_settings.cpp index 6a035e9..9b88a11 100644 --- a/src/config/blockchain_settings.cpp +++ b/src/config/blockchain_settings.cpp @@ -47,7 +47,7 @@ Local config_checkpoints_to_js(Isolate* isolate, kth_checkpoint* checkpoi Local jsArr = Nan::New(n); for (size_t i = 0; i < jsArr->Length(); ++i) { auto elem = config_checkpoint_to_js(isolate, *checkpoint); - jsArr->Set(ctx, i, elem); + auto _ = jsArr->Set(ctx, i, elem); ++checkpoint; } return jsArr; diff --git a/src/config/network_settings.cpp b/src/config/network_settings.cpp index 3b761c9..7c0b2df 100644 --- a/src/config/network_settings.cpp +++ b/src/config/network_settings.cpp @@ -48,7 +48,7 @@ v8::Local config_endpoints_to_js(Isolate* isolate, kth_endpoint* endp v8::Local jsArr = Nan::New(n); for (size_t i = 0; i < jsArr->Length(); ++i) { auto elem = config_endpoint_to_js(isolate, *endpoint); - jsArr->Set(ctx, i, elem); + auto _ = jsArr->Set(ctx, i, elem); ++endpoint; } return jsArr; @@ -67,7 +67,7 @@ v8::Local config_authorities_to_js(Isolate* isolate, kth_authority* a v8::Local jsArr = Nan::New(n); for (size_t i = 0; i < jsArr->Length(); ++i) { auto elem = config_authority_to_js(isolate, *authority); - jsArr->Set(ctx, i, elem); + auto _ = jsArr->Set(ctx, i, elem); ++authority; } return jsArr; @@ -78,7 +78,7 @@ v8::Local config_strings_to_js(Isolate* isolate, char** strs, size_t v8::Local jsArr = Nan::New(n); for (size_t i = 0; i < jsArr->Length(); ++i) { auto elem = string_to_js(isolate, *strs); - jsArr->Set(ctx, i, elem); + auto _ = jsArr->Set(ctx, i, elem); ++strs; } return jsArr; diff --git a/src/kth-native.cpp b/src/kth-native.cpp index 23e1fb5..e4b5494 100644 --- a/src/kth-native.cpp +++ b/src/kth-native.cpp @@ -39,7 +39,13 @@ #include #include +#include +#include +#include +#include +#include #include +#include #include #include @@ -131,7 +137,7 @@ void init(v8::Local exports) { NODE_SET_METHOD(exports, "chain_block_is_valid", chain_block_is_valid); NODE_SET_METHOD(exports, "chain_block_header", chain_block_header); NODE_SET_METHOD(exports, "chain_block_hash", chain_block_hash); - NODE_SET_METHOD(exports, "chain_block_hash_out", chain_block_hash_out); + // NODE_SET_METHOD(exports, "chain_block_hash_out", chain_block_hash_out); NODE_SET_METHOD(exports, "chain_block_proof_str", chain_block_proof_str); NODE_SET_METHOD(exports, "chain_block_transactions", chain_block_transactions); NODE_SET_METHOD(exports, "chain_block_serialized_size", chain_block_serialized_size); @@ -140,7 +146,7 @@ void init(v8::Local exports) { NODE_SET_METHOD(exports, "chain_block_claim", chain_block_claim); NODE_SET_METHOD(exports, "chain_block_reward", chain_block_reward); NODE_SET_METHOD(exports, "chain_block_generate_merkle_root", chain_block_generate_merkle_root); - NODE_SET_METHOD(exports, "chain_block_generate_merkle_root_out", chain_block_generate_merkle_root_out); + // NODE_SET_METHOD(exports, "chain_block_generate_merkle_root_out", chain_block_generate_merkle_root_out); NODE_SET_METHOD(exports, "chain_block_signature_operations", chain_block_signature_operations); NODE_SET_METHOD(exports, "chain_block_signature_operations_bip16_active", chain_block_signature_operations_bip16_active); NODE_SET_METHOD(exports, "chain_block_total_inputs", chain_block_total_inputs); @@ -170,9 +176,9 @@ void init(v8::Local exports) { NODE_SET_METHOD(exports, "chain_transaction_version", chain_transaction_version); NODE_SET_METHOD(exports, "chain_transaction_set_version", chain_transaction_set_version); NODE_SET_METHOD(exports, "chain_transaction_hash", chain_transaction_hash); - NODE_SET_METHOD(exports, "chain_transaction_hash_out", chain_transaction_hash_out); + // NODE_SET_METHOD(exports, "chain_transaction_hash_out", chain_transaction_hash_out); NODE_SET_METHOD(exports, "chain_transaction_hash_sighash_type", chain_transaction_hash_sighash_type); - NODE_SET_METHOD(exports, "chain_transaction_hash_sighash_type_out", chain_transaction_hash_sighash_type_out); + // NODE_SET_METHOD(exports, "chain_transaction_hash_sighash_type_out", chain_transaction_hash_sighash_type_out); NODE_SET_METHOD(exports, "chain_transaction_locktime", chain_transaction_locktime); NODE_SET_METHOD(exports, "chain_transaction_serialized_size", chain_transaction_serialized_size); NODE_SET_METHOD(exports, "chain_transaction_fees", chain_transaction_fees); @@ -282,15 +288,86 @@ void init(v8::Local exports) { NODE_SET_METHOD(exports, "chain_stealth_compact_list_count", chain_stealth_compact_list_count); NODE_SET_METHOD(exports, "chain_stealth_compact_list_nth", chain_stealth_compact_list_nth); + NODE_SET_METHOD(exports, "wallet_ec_private_construct_default", wallet_ec_private_construct_default); + NODE_SET_METHOD(exports, "wallet_ec_private_construct_string", wallet_ec_private_construct_string); + NODE_SET_METHOD(exports, "wallet_ec_private_construct_compressed", wallet_ec_private_construct_compressed); + NODE_SET_METHOD(exports, "wallet_ec_private_construct_uncompressed", wallet_ec_private_construct_uncompressed); + NODE_SET_METHOD(exports, "wallet_ec_private_construct_secret", wallet_ec_private_construct_secret); + NODE_SET_METHOD(exports, "wallet_ec_private_destruct", wallet_ec_private_destruct); + NODE_SET_METHOD(exports, "wallet_ec_private_is_valid", wallet_ec_private_is_valid); + NODE_SET_METHOD(exports, "wallet_ec_private_encoded", wallet_ec_private_encoded); + NODE_SET_METHOD(exports, "wallet_ec_private_secret", wallet_ec_private_secret); + NODE_SET_METHOD(exports, "wallet_ec_private_version", wallet_ec_private_version); + NODE_SET_METHOD(exports, "wallet_ec_private_payment_version", wallet_ec_private_payment_version); + NODE_SET_METHOD(exports, "wallet_ec_private_wif_version", wallet_ec_private_wif_version); + NODE_SET_METHOD(exports, "wallet_ec_private_compressed", wallet_ec_private_compressed); + NODE_SET_METHOD(exports, "wallet_ec_private_to_public", wallet_ec_private_to_public); + NODE_SET_METHOD(exports, "wallet_ec_private_to_payment_address", wallet_ec_private_to_payment_address); + + NODE_SET_METHOD(exports, "wallet_ec_public_construct_default", wallet_ec_public_construct_default); + NODE_SET_METHOD(exports, "wallet_ec_public_construct", wallet_ec_public_construct); + NODE_SET_METHOD(exports, "wallet_ec_public_construct_from_decoded", wallet_ec_public_construct_from_decoded); + NODE_SET_METHOD(exports, "wallet_ec_public_construct_from_base16", wallet_ec_public_construct_from_base16); + NODE_SET_METHOD(exports, "wallet_ec_public_construct_from_point", wallet_ec_public_construct_from_point); + NODE_SET_METHOD(exports, "wallet_ec_public_destruct", wallet_ec_public_destruct); + NODE_SET_METHOD(exports, "wallet_ec_public_is_valid", wallet_ec_public_is_valid); + NODE_SET_METHOD(exports, "wallet_ec_public_encoded", wallet_ec_public_encoded); + NODE_SET_METHOD(exports, "wallet_ec_public_point", wallet_ec_public_point); + NODE_SET_METHOD(exports, "wallet_ec_public_compressed", wallet_ec_public_compressed); + NODE_SET_METHOD(exports, "wallet_ec_public_to_data", wallet_ec_public_to_data); + NODE_SET_METHOD(exports, "wallet_ec_public_to_uncompressed", wallet_ec_public_to_uncompressed); + NODE_SET_METHOD(exports, "wallet_ec_public_to_payment_address", wallet_ec_public_to_payment_address); + + NODE_SET_METHOD(exports, "wallet_secret_to_public", wallet_secret_to_public); + + NODE_SET_METHOD(exports, "wallet_hd_private_construct_default", wallet_hd_private_construct_default); + NODE_SET_METHOD(exports, "wallet_hd_private_construct", wallet_hd_private_construct); + NODE_SET_METHOD(exports, "wallet_hd_private_construct_with_prefix", wallet_hd_private_construct_with_prefix); + NODE_SET_METHOD(exports, "wallet_hd_private_construct_with_prefixes", wallet_hd_private_construct_with_prefixes); + NODE_SET_METHOD(exports, "wallet_hd_private_construct_with_seed", wallet_hd_private_construct_with_seed); + NODE_SET_METHOD(exports, "wallet_hd_private_construct_string", wallet_hd_private_construct_string); + NODE_SET_METHOD(exports, "wallet_hd_private_construct_string_with_prefix", wallet_hd_private_construct_string_with_prefix); + NODE_SET_METHOD(exports, "wallet_hd_private_construct_string_with_prefixes", wallet_hd_private_construct_string_with_prefixes); + NODE_SET_METHOD(exports, "wallet_hd_private_destruct", wallet_hd_private_destruct); + NODE_SET_METHOD(exports, "wallet_hd_private_encoded", wallet_hd_private_encoded); + NODE_SET_METHOD(exports, "wallet_hd_private_secret", wallet_hd_private_secret); + NODE_SET_METHOD(exports, "wallet_hd_private_to_hd_key", wallet_hd_private_to_hd_key); + NODE_SET_METHOD(exports, "wallet_hd_private_to_public", wallet_hd_private_to_public); + NODE_SET_METHOD(exports, "wallet_hd_private_derive_private", wallet_hd_private_derive_private); + NODE_SET_METHOD(exports, "wallet_hd_private_derive_public", wallet_hd_private_derive_public); + + NODE_SET_METHOD(exports, "wallet_hd_public_construct_default", wallet_hd_public_construct_default); + NODE_SET_METHOD(exports, "wallet_hd_public_construct", wallet_hd_public_construct); + NODE_SET_METHOD(exports, "wallet_hd_public_construct_with_prefix", wallet_hd_public_construct_with_prefix); + NODE_SET_METHOD(exports, "wallet_hd_public_construct_string", wallet_hd_public_construct_string); + NODE_SET_METHOD(exports, "wallet_hd_public_construct_string_with_prefix", wallet_hd_public_construct_string_with_prefix); + NODE_SET_METHOD(exports, "wallet_hd_public_destruct", wallet_hd_public_destruct); + NODE_SET_METHOD(exports, "wallet_hd_public_is_valid", wallet_hd_public_is_valid); + NODE_SET_METHOD(exports, "wallet_hd_public_encoded", wallet_hd_public_encoded); + NODE_SET_METHOD(exports, "wallet_hd_public_chain_code", wallet_hd_public_chain_code); + NODE_SET_METHOD(exports, "wallet_hd_public_lineage", wallet_hd_public_lineage); + NODE_SET_METHOD(exports, "wallet_hd_public_point", wallet_hd_public_point); + NODE_SET_METHOD(exports, "wallet_hd_public_to_hd_key", wallet_hd_public_to_hd_key); + NODE_SET_METHOD(exports, "wallet_hd_public_derive_public", wallet_hd_public_derive_public); + + NODE_SET_METHOD(exports, "wallet_payment_address_construct_from_string", wallet_payment_address_construct_from_string); + NODE_SET_METHOD(exports, "wallet_payment_address_construct_from_hash", wallet_payment_address_construct_from_hash); + NODE_SET_METHOD(exports, "wallet_payment_address_construct_from_public", wallet_payment_address_construct_from_public); + NODE_SET_METHOD(exports, "wallet_payment_address_construct_from_script", wallet_payment_address_construct_from_script); + NODE_SET_METHOD(exports, "wallet_payment_address_destruct", wallet_payment_address_destruct); NODE_SET_METHOD(exports, "wallet_payment_address_set_cashaddr_prefix", wallet_payment_address_set_cashaddr_prefix); - NODE_SET_METHOD(exports, "wallet_payment_address_encoded_legacy", wallet_payment_address_encoded_legacy); NODE_SET_METHOD(exports, "wallet_payment_address_encoded_cashaddr", wallet_payment_address_encoded_cashaddr); - NODE_SET_METHOD(exports, "wallet_payment_address_construct_from_string", wallet_payment_address_construct_from_string); + NODE_SET_METHOD(exports, "wallet_payment_address_encoded_legacy", wallet_payment_address_encoded_legacy); NODE_SET_METHOD(exports, "wallet_payment_address_hash20", wallet_payment_address_hash20); NODE_SET_METHOD(exports, "wallet_payment_address_hash32", wallet_payment_address_hash32); NODE_SET_METHOD(exports, "wallet_payment_address_version", wallet_payment_address_version); NODE_SET_METHOD(exports, "wallet_payment_address_is_valid", wallet_payment_address_is_valid); - NODE_SET_METHOD(exports, "wallet_payment_address_destruct", wallet_payment_address_destruct); + + NODE_SET_METHOD(exports, "wallet_mnemonics_to_seed", wallet_mnemonics_to_seed); + NODE_SET_METHOD(exports, "wallet_hd_new", wallet_hd_new); + NODE_SET_METHOD(exports, "wallet_hd_private_to_ec", wallet_hd_private_to_ec); + NODE_SET_METHOD(exports, "wallet_ec_to_public", wallet_ec_to_public); + NODE_SET_METHOD(exports, "wallet_ec_to_address", wallet_ec_to_address); NODE_SET_METHOD(exports, "core_string_list_construct", core_string_list_construct); NODE_SET_METHOD(exports, "core_string_list_destruct", core_string_list_destruct); diff --git a/src/string_list.cpp b/src/string_list.cpp index aefb800..cce5e20 100644 --- a/src/string_list.cpp +++ b/src/string_list.cpp @@ -56,10 +56,8 @@ void core_string_list_destruct(v8::FunctionCallbackInfo const& args) return; } - void* vptr = v8::External::Cast(*args[0])->Value(); - kth_string_list_t string_list = (kth_string_list_t)vptr; - - kth_core_string_list_destruct(string_list); + auto obj = (kth_string_list_t)v8::External::Cast(*args[0])->Value(); + kth_core_string_list_destruct(obj); } void core_string_list_push_back(v8::FunctionCallbackInfo const& args) { @@ -80,10 +78,9 @@ void core_string_list_push_back(v8::FunctionCallbackInfo const& args) return; } - void* vptr = v8::External::Cast(*args[0])->Value(); - kth_string_list_t string_list = (kth_string_list_t)vptr; - v8::String::Utf8Value str(isolate, args[0]->ToString(isolate->GetCurrentContext()).ToLocalChecked()); - kth_core_string_list_push_back(string_list, *str); + auto obj = (kth_string_list_t)v8::External::Cast(*args[0])->Value(); + v8::String::Utf8Value str(isolate, args[1]->ToString(isolate->GetCurrentContext()).ToLocalChecked()); + kth_core_string_list_push_back(obj, *str); } } // namespace kth::js_native diff --git a/src/wallet/ec_private.cpp b/src/wallet/ec_private.cpp new file mode 100644 index 0000000..f517661 --- /dev/null +++ b/src/wallet/ec_private.cpp @@ -0,0 +1,341 @@ +// Copyright (c) 2016-2023 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +namespace kth::js_native { + +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Global; + +using v8::Object; +using v8::String; +using v8::Boolean; +using v8::Value; +using v8::External; +using v8::Exception; +using v8::Number; +using v8::Persistent; +using v8::Function; +using v8::Uint8Array; +using v8::ArrayBuffer; + +void wallet_ec_private_construct_default(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 0) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + kth_ec_private_t res = kth_wallet_ec_private_construct_default(); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_ec_private_construct_string(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsString()) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[1]->IsNumber()) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + uint8_t version = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + v8::String::Utf8Value wif(isolate, args[0]->ToString(isolate->GetCurrentContext()).ToLocalChecked()); + kth_ec_private_t res = kth_wallet_ec_private_construct_string(*wif, version); + args.GetReturnValue().Set(External::New(isolate, res)); + +} + +void wallet_ec_private_construct_compressed(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsUint8Array()) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[1]->IsNumber()) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + v8::Local arr = v8::Local::Cast(args[0]); + if (arr->Length() != 38U) { + throw_exception(isolate, "Wrong arguments, WIF length must be 38 bytes"); + return; + } + + kth_wif_compressed_t wif_compressed = to_native_wif_compressed(arr); + uint8_t version = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + kth_ec_private_t res = kth_wallet_ec_private_construct_compressed(&wif_compressed, version); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_ec_private_construct_uncompressed(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsUint8Array()) { + throw_exception(isolate, "Wrong arguments: Expected Uint8Array for WIF Uncompressed"); + return; + } + + if ( ! args[1]->IsNumber()) { + throw_exception(isolate, "Wrong arguments: Expected number for version"); + return; + } + + v8::Local arr = v8::Local::Cast(args[0]); + if (arr->Length() != 37) { + throw_exception(isolate, "Wrong arguments, 1, number of bytes"); + return; + } + + kth_wif_uncompressed_t wif_uncompressed = to_native_wif_uncompressed(arr); + uint8_t version = static_cast(args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked()); + + kth_ec_private_t res = kth_wallet_ec_private_construct_uncompressed(&wif_uncompressed, version); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_ec_private_construct_secret(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 3) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsUint8Array()) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + v8::Local arr = v8::Local::Cast(args[0]); + if (arr->Length() != 32) { + throw_exception(isolate, "Wrong arguments, secret length must be 32 bytes"); + return; + } + + kth_ec_secret_t secret = to_native_ec_secret(arr); + uint16_t version = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + kth_bool_t compress = bool_to_cpp(isolate, args[2]); + kth_ec_private_t res = kth_wallet_ec_private_construct_secret(&secret, version, compress); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_ec_private_destruct(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external private object"); + return; + } + + kth_ec_private_t obj = (kth_ec_private_t)v8::External::Cast(*args[0])->Value(); + kth_wallet_ec_private_destruct(obj); +} + +void wallet_ec_private_is_valid(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external private object"); + return; + } + + kth_ec_private_t obj = (kth_ec_private_t)v8::External::Cast(*args[0])->Value(); + kth_bool_t res = kth_wallet_ec_private_is_valid(obj); + args.GetReturnValue().Set(Boolean::New(isolate, res != 0)); +} + +void wallet_ec_private_encoded(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external private object"); + return; + } + + kth_ec_private_t obj = (kth_ec_private_t)v8::External::Cast(*args[0])->Value(); + char* res = kth_wallet_ec_private_encoded(obj); + args.GetReturnValue().Set(string_to_js(isolate, res)); + kth_platform_free(res); +} + +void wallet_ec_private_secret(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external private object"); + return; + } + + kth_ec_private_t obj = (kth_ec_private_t)v8::External::Cast(*args[0])->Value(); + kth_ec_secret_t res = kth_wallet_ec_private_secret(obj); + args.GetReturnValue().Set(ec_secret_to_js(isolate, res)); +} + +void wallet_ec_private_version(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external private object"); + return; + } + + kth_ec_private_t obj = (kth_ec_private_t)v8::External::Cast(*args[0])->Value(); + uint16_t version = kth_wallet_ec_private_version(obj); + args.GetReturnValue().Set(Number::New(isolate, version)); +} + +void wallet_ec_private_payment_version(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external private object"); + return; + } + + kth_ec_private_t obj = (kth_ec_private_t)v8::External::Cast(*args[0])->Value(); + uint8_t payment_version = kth_wallet_ec_private_payment_version(obj); + args.GetReturnValue().Set(Number::New(isolate, payment_version)); +} + +void wallet_ec_private_wif_version(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external private object"); + return; + } + + kth_ec_private_t obj = (kth_ec_private_t)v8::External::Cast(*args[0])->Value(); + uint8_t wif_version = kth_wallet_ec_private_wif_version(obj); + args.GetReturnValue().Set(Number::New(isolate, wif_version)); +} + +void wallet_ec_private_compressed(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external private object"); + return; + } + + kth_ec_private_t obj = (kth_ec_private_t)v8::External::Cast(*args[0])->Value(); + kth_bool_t res = kth_wallet_ec_private_compressed(obj); + args.GetReturnValue().Set(Boolean::New(isolate, res != 0)); +} + +void wallet_ec_private_to_public(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external private object"); + return; + } + + auto obj = (kth_ec_private_t)v8::External::Cast(*args[0])->Value(); + auto res = kth_wallet_ec_private_to_public(obj); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_ec_private_to_payment_address(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external private object"); + return; + } + + kth_ec_private_t obj = (kth_ec_private_t)v8::External::Cast(*args[0])->Value(); + auto res = kth_wallet_ec_private_to_payment_address(obj); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +} // namespace kth::js_native diff --git a/src/wallet/ec_public.cpp b/src/wallet/ec_public.cpp new file mode 100644 index 0000000..4fda12f --- /dev/null +++ b/src/wallet/ec_public.cpp @@ -0,0 +1,307 @@ +// Copyright (c) 2016-2023 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +namespace kth::js_native { + +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Global; + +using v8::Object; +using v8::String; +using v8::Boolean; +using v8::Value; +using v8::External; +using v8::Exception; +using v8::Number; +using v8::Persistent; +using v8::Function; +using v8::Uint8Array; +using v8::ArrayBuffer; + + +void wallet_ec_public_construct_default(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 0) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + auto res = kth_wallet_ec_public_construct_default(); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_ec_public_construct(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external private object"); + return; + } + + auto priv = (kth_ec_private_t)v8::External::Cast(*args[0])->Value(); + auto res = kth_wallet_ec_public_construct(priv); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_ec_public_construct_from_decoded(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsUint8Array()) { + throw_exception(isolate, "Wrong arguments: Expected a Uint8Array for decoded data"); + return; + } + + //TODO: improve this way of getting arrays + v8::Local arr = v8::Local::Cast(args[0]); +#if (V8_MAJOR_VERSION >= 8) + uint8_t* decoded_data = (uint8_t*)arr->Buffer()->GetBackingStore()->Data(); +#else + uint8_t* decoded_data = (uint8_t*)arr->Buffer()->GetContents().Data(); +#endif + + kth_size_t size = arr->Length(); + auto res = kth_wallet_ec_public_construct_from_decoded(decoded_data, size); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_ec_public_construct_from_base16(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsString()) { + throw_exception(isolate, "Wrong arguments: Expected a base16 string"); + return; + } + + v8::String::Utf8Value base16(isolate, args[0]->ToString(isolate->GetCurrentContext()).ToLocalChecked()); + auto res = kth_wallet_ec_public_construct_from_base16(*base16); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +kth_ec_compressed_t to_native_ec_compressed(v8::Local arr) { + kth_ec_compressed_t point; + +#if (V8_MAJOR_VERSION >= 8) + uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetBackingStore()->Data(); +#else + uint8_t* native_arr = (uint8_t*)arr->Buffer()->GetContents().Data(); +#endif + + for (uint32_t i = 0; i < arr->Length(); ++i) { + point.data[i] = native_arr[i]; + } + return point; +} + +void wallet_ec_public_construct_from_point(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsUint8Array()) { + throw_exception(isolate, "Wrong arguments: Expected an Uint8Array for ec_compressed point"); + return; + } + + if ( ! args[1]->IsBoolean()) { + throw_exception(isolate, "Wrong arguments: Expected a boolean for compression flag"); + return; + } + + v8::Local arr = v8::Local::Cast(args[0]); + kth_ec_compressed_t point = to_native_ec_compressed(arr); + kth_bool_t compress = args[1]->BooleanValue(isolate); + + auto res = kth_wallet_ec_public_construct_from_point(&point, compress); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_ec_public_destruct(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external ec_public object"); + return; + } + + auto obj = (kth_ec_public_t)v8::External::Cast(*args[0])->Value(); + kth_wallet_ec_public_destruct(obj); + // args.GetReturnValue().SetUndefined(); +} + +void wallet_ec_public_is_valid(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external ec_public object"); + return; + } + + auto obj = (kth_ec_public_t)v8::External::Cast(*args[0])->Value(); + kth_bool_t res = kth_wallet_ec_public_is_valid(obj); + args.GetReturnValue().Set(Boolean::New(isolate, res != 0)); +} + +void wallet_ec_public_encoded(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external ec_public object"); + return; + } + + auto obj = (kth_ec_public_t)v8::External::Cast(*args[0])->Value(); + char* res = kth_wallet_ec_public_encoded(obj); + args.GetReturnValue().Set(string_to_js(isolate, res)); + kth_platform_free(res); //TODO: call kth_platform_free in all the similar places +} + +void wallet_ec_public_point(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external ec_public object"); + return; + } + + auto obj = (kth_ec_public_t)v8::External::Cast(*args[0])->Value(); + auto res = kth_wallet_ec_public_point(obj); + args.GetReturnValue().Set(ec_compressed_to_js(isolate, res)); +} + +void wallet_ec_public_compressed(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external ec_public object"); + return; + } + + auto obj = (kth_ec_public_t)v8::External::Cast(*args[0])->Value(); + kth_bool_t res = kth_wallet_ec_public_compressed(obj); + args.GetReturnValue().Set(Boolean::New(isolate, res != 0)); +} + +void wallet_ec_public_to_data(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external ec_public object"); + return; + } + + auto obj = (kth_ec_public_t)v8::External::Cast(*args[0])->Value(); + kth_size_t size; + uint8_t const* res = kth_wallet_ec_public_to_data(obj, &size); + args.GetReturnValue().Set(byte_array_to_js(isolate, res, size)); +} + +void wallet_ec_public_to_uncompressed(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external ec_public object"); + return; + } + + auto obj = (kth_ec_public_t)v8::External::Cast(*args[0])->Value(); + kth_ec_uncompressed_t out_data; + kth_bool_t res = kth_wallet_ec_public_to_uncompressed(obj, &out_data); + + if (res == 0) { + args.GetReturnValue().SetUndefined(); + return; + } + args.GetReturnValue().Set(ec_uncompressed_to_js(isolate, out_data)); +} + +void wallet_ec_public_to_payment_address(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal() || !args[1]->IsNumber()) { + throw_exception(isolate, "Wrong arguments: Expected an external ec_public object and a number (version)"); + return; + } + + auto obj = (kth_ec_public_t)v8::External::Cast(*args[0])->Value(); + uint8_t version = static_cast(args[1]->Int32Value(isolate->GetCurrentContext()).ToChecked()); + + auto res = kth_wallet_ec_public_to_payment_address(obj, version); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +} // namespace kth::js_native diff --git a/src/wallet/elliptic_curve.cpp b/src/wallet/elliptic_curve.cpp new file mode 100644 index 0000000..3396843 --- /dev/null +++ b/src/wallet/elliptic_curve.cpp @@ -0,0 +1,67 @@ +// Copyright (c) 2016-2023 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include + +#include + +#include + +#include +#include +#include + +namespace kth::js_native { + +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Global; + +using v8::Object; +using v8::String; +using v8::Boolean; +using v8::Value; +using v8::External; +using v8::Exception; +using v8::Number; +using v8::Persistent; +using v8::Function; +using v8::Uint8Array; +using v8::ArrayBuffer; + +void wallet_secret_to_public(v8::FunctionCallbackInfo const& args) { + v8::Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsUint8Array()) { + throw_exception(isolate, "Argument 0 must be a Uint8Array"); + return; + } + + v8::Local arr = v8::Local::Cast(args[0]); + + if (arr->Length() != KTH_BITCOIN_EC_SECRET_SIZE) { + throw_exception(isolate, "Wrong arguments, hash length must be 32 bytes"); + return; + } + + auto secret = to_native_ec_secret(arr); + kth_ec_compressed_t out; + kth_bool_t res = kth_wallet_secret_to_public(&out, secret); + + if (res == 0) { + args.GetReturnValue().SetUndefined(); + return; + } + args.GetReturnValue().Set(ec_compressed_to_js(isolate, out)); +} + + +} // namespace kth::js_native diff --git a/src/wallet/hd_private.cpp b/src/wallet/hd_private.cpp new file mode 100644 index 0000000..e30b658 --- /dev/null +++ b/src/wallet/hd_private.cpp @@ -0,0 +1,357 @@ +// Copyright (c) 2016-2023 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +namespace kth::js_native { + +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Global; + +using v8::Object; +using v8::String; +using v8::Boolean; +using v8::Value; +using v8::External; +using v8::Exception; +using v8::Number; +using v8::Persistent; +using v8::Function; +using v8::Uint8Array; +using v8::ArrayBuffer; + +void wallet_hd_private_construct_default(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 0) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + kth_hd_private_t res = kth_wallet_hd_private_construct_default(); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_hd_private_construct(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsUint8Array()) { + throw_exception(isolate, "Wrong argument type: Uint8Array expected"); + return; + } + + v8::Local arr = v8::Local::Cast(args[0]); + kth_hd_key_t key = to_native_hd_key(arr); + kth_hd_private_t res = kth_wallet_hd_private_construct(&key); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_hd_private_construct_with_prefix(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsUint8Array()) { + throw_exception(isolate, "Wrong argument type: Uint8Array expected"); + return; + } + + if ( ! args[1]->IsNumber()) { + throw_exception(isolate, "Wrong argument type: Number expected"); + return; + } + + v8::Local arr = v8::Local::Cast(args[0]); + kth_hd_key_t key = to_native_hd_key(arr); + uint32_t prefix = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + kth_hd_private_t res = kth_wallet_hd_private_construct_with_prefix(&key, prefix); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_hd_private_construct_with_prefixes(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsUint8Array()) { + throw_exception(isolate, "Wrong argument type: Uint8Array expected"); + return; + } + + if ( ! args[1]->IsNumber()) { + throw_exception(isolate, "Wrong argument type: Number expected"); + return; + } + + v8::Local arr = v8::Local::Cast(args[0]); + kth_hd_key_t key = to_native_hd_key(arr); + uint64_t prefixes = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + kth_hd_private_t res = kth_wallet_hd_private_construct_with_prefixes(&key, prefixes); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_hd_private_construct_with_seed(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsUint8Array()) { + throw_exception(isolate, "Wrong argument type: Uint8Array expected"); + return; + } + + if ( ! args[1]->IsNumber()) { + throw_exception(isolate, "Wrong argument type: Number expected"); + return; + } + + v8::Local arr = v8::Local::Cast(args[0]); +#if (V8_MAJOR_VERSION >= 8) + uint8_t* seed = (uint8_t*)arr->Buffer()->GetBackingStore()->Data(); +#else + uint8_t* seed = (uint8_t*)arr->Buffer()->GetContents().Data(); +#endif + + kth_size_t size = arr->Length(); + uint64_t prefixes = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + + kth_hd_private_t res = kth_wallet_hd_private_construct_with_seed(seed, size, prefixes); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_hd_private_construct_string(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsString()) { + throw_exception(isolate, "Wrong argument type: String expected"); + return; + } + + v8::String::Utf8Value encoded(isolate, args[0]->ToString(isolate->GetCurrentContext()).ToLocalChecked()); + kth_hd_private_t res = kth_wallet_hd_private_construct_string(*encoded); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_hd_private_construct_string_with_prefix(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsString()) { + throw_exception(isolate, "Wrong argument type: String expected"); + return; + } + + if ( ! args[1]->IsNumber()) { + throw_exception(isolate, "Wrong argument type: Number expected"); + return; + } + + String::Utf8Value encoded(isolate, args[0]); + // uint32_t prefix = args[1]->Uint32Value(isolate->GetCurrentContext()).ToChecked(); + uint32_t prefix = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + + kth_hd_private_t res = kth_wallet_hd_private_construct_string_with_prefix(*encoded, prefix); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_hd_private_construct_string_with_prefixes(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsString()) { + throw_exception(isolate, "Wrong argument type: String expected"); + return; + } + + if ( ! args[1]->IsNumber()) { + throw_exception(isolate, "Wrong argument type: Number expected"); + return; + } + + String::Utf8Value encoded(isolate, args[0]); + uint64_t prefixes = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + + kth_hd_private_t res = kth_wallet_hd_private_construct_string_with_prefixes(*encoded, prefixes); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_hd_private_destruct(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong argument type: External expected"); + return; + } + + auto obj = (kth_hd_private_t)v8::External::Cast(*args[0])->Value(); + kth_wallet_hd_private_destruct(obj); +} + +void wallet_hd_private_encoded(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong argument type: External expected"); + return; + } + + auto obj = (kth_hd_private_t)v8::External::Cast(*args[0])->Value(); + char* res = kth_wallet_hd_private_encoded(obj); + args.GetReturnValue().Set(string_to_js(isolate, res)); + kth_platform_free(res); +} + +void wallet_hd_private_secret(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong argument type: External expected"); + return; + } + + auto obj = (kth_hd_private_t)v8::External::Cast(*args[0])->Value(); + kth_ec_secret_t res = kth_wallet_hd_private_secret(obj); + args.GetReturnValue().Set(ec_secret_to_js(isolate, res)); +} + +void wallet_hd_private_to_hd_key(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong argument type: External expected"); + return; + } + + auto obj = (kth_hd_private_t)v8::External::Cast(*args[0])->Value(); + kth_hd_key_t res = kth_wallet_hd_private_to_hd_key(obj); + args.GetReturnValue().Set(hd_key_to_js(isolate, res)); +} + +void wallet_hd_private_to_public(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong argument type: External expected"); + return; + } + + auto obj = (kth_hd_private_t)v8::External::Cast(*args[0])->Value(); + kth_hd_public_t hd_public = kth_wallet_hd_private_to_public(obj); + args.GetReturnValue().Set(External::New(isolate, hd_public)); +} + +void wallet_hd_private_derive_private(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong argument type: External expected"); + return; + } + + if ( ! args[1]->IsUint32()) { + throw_exception(isolate, "Wrong argument type: Number expected"); + return; + } + + auto obj = (kth_hd_private_t)v8::External::Cast(*args[0])->Value(); + uint32_t index = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + kth_hd_private_t derived_hd_private = kth_wallet_hd_private_derive_private(obj, index); + args.GetReturnValue().Set(External::New(isolate, derived_hd_private)); +} + +void wallet_hd_private_derive_public(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong argument type: External expected"); + return; + } + + //TODO: should I use IsUint32 or IsNumber? + if ( ! args[1]->IsUint32()) { + throw_exception(isolate, "Wrong argument type: Number expected"); + return; + } + + auto obj = (kth_hd_private_t)v8::External::Cast(*args[0])->Value(); + uint32_t index = args[1]->Uint32Value(isolate->GetCurrentContext()).ToChecked(); + kth_hd_public_t derived_hd_public = kth_wallet_hd_private_derive_public(obj, index); + args.GetReturnValue().Set(External::New(isolate, derived_hd_public)); +} + +} // namespace kth::js_native diff --git a/src/wallet/hd_public.cpp b/src/wallet/hd_public.cpp new file mode 100644 index 0000000..2d6481c --- /dev/null +++ b/src/wallet/hd_public.cpp @@ -0,0 +1,293 @@ +// Copyright (c) 2016-2023 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +namespace kth::js_native { + +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Global; + +using v8::Object; +using v8::String; +using v8::Boolean; +using v8::Value; +using v8::External; +using v8::Exception; +using v8::Number; +using v8::Persistent; +using v8::Function; +using v8::Uint8Array; +using v8::ArrayBuffer; + +void wallet_hd_public_construct_default(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 0) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + kth_hd_public_t res = kth_wallet_hd_public_construct_default(); + args.GetReturnValue().Set(External::New(args.GetIsolate(), res)); +} + +void wallet_hd_public_construct(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsUint8Array()) { + throw_exception(isolate, "Argument 0 must be a Uint8Array"); + return; + } + + v8::Local arr = v8::Local::Cast(args[0]); + + if (arr->Length() != KTH_HD_KEY_SIZE) { + throw_exception(isolate, "Wrong arguments, hash length must be 82 bytes"); + return; + } + + auto key = to_native_hd_key(arr); + auto res = kth_wallet_hd_public_construct(&key); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_hd_public_construct_with_prefix(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsUint8Array()) { + throw_exception(isolate, "Argument 0 must be a Uint8Array"); + return; + } + + if ( ! args[1]->IsNumber()) { + throw_exception(isolate, "Argument 1 must be a uint32_t"); + return; + } + + uint32_t prefix = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + + v8::Local arr = v8::Local::Cast(args[0]); + if (arr->Length() != KTH_HD_KEY_SIZE) { + throw_exception(isolate, "Wrong arguments, hash length must be 82 bytes"); + return; + } + + auto key = to_native_hd_key(arr); + auto res = kth_wallet_hd_public_construct_with_prefix(&key, prefix); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_hd_public_construct_string(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsString()) { + throw_exception(isolate, "Argument 0 must be a string"); + return; + } + v8::String::Utf8Value encoded(isolate, args[0]->ToString(isolate->GetCurrentContext()).ToLocalChecked()); + kth_hd_public_t res = kth_wallet_hd_public_construct_string(*encoded); + args.GetReturnValue().Set(External::New(args.GetIsolate(), res)); +} + +void wallet_hd_public_construct_string_with_prefix(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsString()) { + throw_exception(isolate, "Argument 0 must be a string"); + return; + } + + if ( ! args[1]->IsNumber()) { + throw_exception(isolate, "Argument 1 must be a uint32_t"); + return; + } + + v8::String::Utf8Value encoded(args.GetIsolate(), args[0]->ToString(args.GetIsolate()->GetCurrentContext()).ToLocalChecked()); + uint32_t prefix = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + kth_hd_public_t res = kth_wallet_hd_public_construct_string_with_prefix(*encoded, prefix); + args.GetReturnValue().Set(External::New(args.GetIsolate(), res)); +} + +void wallet_hd_public_destruct(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Argument 0 must be an external object"); + return; + } + auto obj = (kth_hd_public_t)v8::External::Cast(*args[0])->Value(); + kth_wallet_hd_public_destruct(obj); + args.GetReturnValue().SetUndefined(); +} + +void wallet_hd_public_is_valid(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Argument 0 must be an external object"); + return; + } + auto obj = (kth_hd_public_t)v8::External::Cast(*args[0])->Value(); + kth_bool_t res = kth_wallet_hd_public_is_valid(obj); + args.GetReturnValue().Set(Boolean::New(args.GetIsolate(), res != 0)); +} + +void wallet_hd_public_encoded(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Argument 0 must be an external object"); + return; + } + + auto obj = (kth_hd_public_t)v8::External::Cast(*args[0])->Value(); + char* res = kth_wallet_hd_public_encoded(obj); + args.GetReturnValue().Set(string_to_js(isolate, res)); + kth_platform_free(res); +} + +void wallet_hd_public_chain_code(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Argument 0 must be an external object"); + return; + } + + auto obj = (kth_hd_public_t)v8::External::Cast(*args[0])->Value(); + kth_hd_chain_code_t res = kth_wallet_hd_public_chain_code(obj); + args.GetReturnValue().Set(hd_chain_code_to_js(isolate, res)); +} + +void wallet_hd_public_lineage(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Argument 0 must be an external object"); + return; + } + auto obj = (kth_hd_public_t)v8::External::Cast(*args[0])->Value(); + kth_hd_lineage_t res = kth_wallet_hd_public_lineage(obj); + args.GetReturnValue().Set(hd_lineage_to_js(isolate, res)); +} + +void wallet_hd_public_point(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Argument 0 must be an external object"); + return; + } + auto obj = (kth_hd_public_t)v8::External::Cast(*args[0])->Value(); + kth_ec_compressed_t res = kth_wallet_hd_public_point(obj); + args.GetReturnValue().Set(ec_compressed_to_js(isolate, res)); +} + +void wallet_hd_public_to_hd_key(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Argument 0 must be an external object"); + return; + } + + auto obj = (kth_hd_public_t)v8::External::Cast(*args[0])->Value(); + kth_hd_key_t res = kth_wallet_hd_public_to_hd_key(obj); + args.GetReturnValue().Set(hd_key_to_js(isolate, res)); +} + +void wallet_hd_public_derive_public(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Arguments must be of the form (external object, uint32)"); + return; + } + + if ( ! args[1]->IsNumber()) { + throw_exception(isolate, "Arguments must be of the form (external object, uint32)"); + return; + } + + auto obj = (kth_hd_public_t)v8::External::Cast(*args[0])->Value(); + uint32_t index = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + kth_hd_public_t res = kth_wallet_hd_public_derive_public(obj, index); + args.GetReturnValue().Set(External::New(args.GetIsolate(), res)); +} + +} // namespace kth::js_native diff --git a/src/wallet/payment_address.cpp b/src/wallet/payment_address.cpp index 00046a4..2147e90 100644 --- a/src/wallet/payment_address.cpp +++ b/src/wallet/payment_address.cpp @@ -11,6 +11,7 @@ #include #include +#include namespace kth::js_native { @@ -31,19 +32,6 @@ using v8::Function; using v8::Uint8Array; using v8::ArrayBuffer; -// void wallet_payment_address_construct_from_string(v8::FunctionCallbackInfo const& args); -// void wallet_payment_address_construct_from_hash(v8::FunctionCallbackInfo const& args); -// void wallet_payment_address_construct_from_public(v8::FunctionCallbackInfo const& args); -// void wallet_payment_address_construct_from_script(v8::FunctionCallbackInfo const& args); -// void wallet_payment_address_destruct(v8::FunctionCallbackInfo const& args); -// void wallet_payment_address_set_cashaddr_prefix(v8::FunctionCallbackInfo const& args); -// void wallet_payment_address_encoded_cashaddr(v8::FunctionCallbackInfo const& args); -// void wallet_payment_address_encoded_legacy(v8::FunctionCallbackInfo const& args); -// void wallet_payment_address_hash20(v8::FunctionCallbackInfo const& args); -// void wallet_payment_address_hash32(v8::FunctionCallbackInfo const& args); -// void wallet_payment_address_version(v8::FunctionCallbackInfo const& args); -// void wallet_payment_address_is_valid(v8::FunctionCallbackInfo const& args); - // kth_payment_address_t kth_wallet_payment_address_construct_from_string(char const* address); void wallet_payment_address_construct_from_string(v8::FunctionCallbackInfo const& args) { Isolate* isolate = args.GetIsolate(); @@ -53,7 +41,7 @@ void wallet_payment_address_construct_from_string(v8::FunctionCallbackInfoIsString()) { + if ( ! args[0]->IsString()) { throw_exception(isolate, "Wrong argument type for argument path (#1). Required to be IsString."); return; } @@ -71,12 +59,12 @@ void wallet_payment_address_construct_from_hash(v8::FunctionCallbackInfoIsUint8Array()) { + if ( ! args[0]->IsUint8Array()) { throw_exception(isolate, "Wrong arguments"); return; } - if (!args[1]->IsNumber()) { + if ( ! args[1]->IsNumber()) { throw_exception(isolate, "Wrong arguments"); return; } @@ -89,12 +77,66 @@ void wallet_payment_address_construct_from_hash(v8::FunctionCallbackInfo(args[1]->NumberValue(isolate->GetCurrentContext()).ToChecked()); + // uint8_t version = static_cast(args[1]->NumberValue(isolate->GetCurrentContext()).ToChecked()); + uint32_t version = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); kth_payment_address_t res = kth_wallet_payment_address_construct_from_hash(&hash, version); args.GetReturnValue().Set(External::New(isolate, res)); } +// kth_payment_address_t kth_wallet_payment_address_construct_from_public(kth_ec_public_t point, uint8_t version); +void wallet_payment_address_construct_from_public(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external ec_public object"); + return; + } + + if ( ! args[1]->IsNumber()) { + //TODO: refactor error messages + throw_exception(isolate, "Wrong arguments"); + return; + } + + auto pub = (kth_ec_public_t)v8::External::Cast(*args[0])->Value(); + uint32_t version = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + + kth_payment_address_t res = kth_wallet_payment_address_construct_from_public(pub, version); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_payment_address_construct_from_script(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong number of arguments"); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments: Expected an external ec_public object"); + return; + } + + if ( ! args[1]->IsNumber()) { + //TODO: refactor error messages + throw_exception(isolate, "Wrong arguments"); + return; + } + + auto script = (kth_script_t)v8::External::Cast(*args[0])->Value(); + uint32_t version = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + + kth_payment_address_t res = kth_wallet_payment_address_construct_from_script(script, version); + args.GetReturnValue().Set(External::New(isolate, res)); +} + // void kth_wallet_payment_address_destruct(kth_payment_address_t payment_address); void wallet_payment_address_destruct(v8::FunctionCallbackInfo const& args) { Isolate* isolate = args.GetIsolate(); @@ -113,8 +155,6 @@ void wallet_payment_address_destruct(v8::FunctionCallbackInfo const& kth_wallet_payment_address_destruct(payment_address); } - - // void kth_wallet_payment_address_set_cashaddr_prefix(char const* prefix); void wallet_payment_address_set_cashaddr_prefix(v8::FunctionCallbackInfo const& args) { Isolate* isolate = args.GetIsolate(); @@ -124,7 +164,7 @@ void wallet_payment_address_set_cashaddr_prefix(v8::FunctionCallbackInfoIsString()) { + if ( ! args[0]->IsString()) { throw_exception(isolate, "Wrong argument type for argument path (#1). Required to be IsString."); return; } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp new file mode 100644 index 0000000..378b9f1 --- /dev/null +++ b/src/wallet/wallet.cpp @@ -0,0 +1,160 @@ +// Copyright (c) 2016-2023 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include + +#include + +#include + +#include +#include +#include +#include + +namespace kth::js_native { + +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Global; + +using v8::Object; +using v8::String; +using v8::Boolean; +using v8::Value; +using v8::External; +using v8::Exception; +using v8::Number; +using v8::Persistent; +using v8::Function; +using v8::Uint8Array; +using v8::ArrayBuffer; + + +void wallet_mnemonics_to_seed(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments."); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong arguments"); + return; + } + + auto obj = (kth_string_list_t)v8::External::Cast(*args[0])->Value(); + + kth_longhash_t res = kth_wallet_mnemonics_to_seed(obj); + args.GetReturnValue().Set(longhash_to_js(isolate, res)); +} + +void wallet_hd_new(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong number of arguments."); + return; + } + + if ( ! args[0]->IsUint8Array()) { + throw_exception(isolate, "Wrong argument type for argument seed (#1). Required to be Uint8Array."); + return; + } + + v8::Local arr = v8::Local::Cast(args[0]); + if (arr->Length() != 64) { + throw_exception(isolate, "Wrong argument type for argument seed (#2). Required to be 64-byte array."); + return; + } + kth_longhash_t seed = to_native_longhash(arr); + + uint32_t version = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + + kth_hd_private_t res = kth_wallet_hd_new(seed, version); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_hd_private_to_ec(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 1) { + throw_exception(isolate, "Wrong number of arguments."); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong argument type for argument key (#1). Required to be IsExternal."); + return; + } + + kth_hd_private_t key = (kth_hd_private_t)v8::External::Cast(*args[0])->Value(); + kth_ec_secret_t res = kth_wallet_hd_private_to_ec(key); + args.GetReturnValue().Set(ec_secret_to_js(isolate, res)); +} + +void wallet_ec_to_public(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + // Verificar que se tienen el nĂºmero correcto de argumentos. + if (args.Length() != 2) { + throw_exception(isolate, "Wrong number of arguments. kth_wallet_ec_to_public function requires 2 arguments."); + return; + } + + // Asegurarse de que se pasa el tipo correcto para "secret". + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong argument type for argument secret (#1). Required to be IsExternal."); + return; + } + + // Asegurarse de que el segundo argumento es un booleano. + if ( ! args[1]->IsBoolean()) { + throw_exception(isolate, "Wrong argument type for argument uncompressed (#2). Required to be Boolean."); + return; + } + + v8::Local arr = v8::Local::Cast(args[0]); + if (arr->Length() != 32) { + throw_exception(isolate, "Wrong arguments, secret length must be 32 bytes"); + return; + } + kth_ec_secret_t secret = to_native_ec_secret(arr); + + kth_bool_t uncompressed = bool_to_cpp(isolate, args[1]); + kth_ec_public_t res = kth_wallet_ec_to_public(secret, uncompressed); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +void wallet_ec_to_address(v8::FunctionCallbackInfo const& args) { + Isolate* isolate = args.GetIsolate(); + + if (args.Length() != 2) { + throw_exception(isolate, "Wrong number of arguments. kth_wallet_ec_to_address function requires 2 arguments."); + return; + } + + if ( ! args[0]->IsExternal()) { + throw_exception(isolate, "Wrong argument type for argument point (#1). Required to be IsExternal."); + return; + } + + //TODO: Use IsUint32() and friends instead of IsNumber() in all the code. + if ( ! args[1]->IsUint32()) { + throw_exception(isolate, "Wrong argument type for argument version (#2). Required to be Uint32."); + return; + } + + kth_ec_public_t point = (kth_ec_public_t)v8::External::Cast(*args[0])->Value(); + // uint32_t version = args[1]->Uint32Value(isolate->GetCurrentContext()).ToChecked(); + uint32_t version = args[1]->IntegerValue(isolate->GetCurrentContext()).ToChecked(); + + kth_payment_address_t res = kth_wallet_ec_to_address(point, version); + args.GetReturnValue().Set(External::New(isolate, res)); +} + +} // namespace kth::js_native diff --git a/tests.js b/tests.js index ac2ed83..aa51904 100644 --- a/tests.js +++ b/tests.js @@ -151,6 +151,7 @@ function chain_fetch_last_height(chain) { }) }); } + async function wait_until_block(chain, desired_height) { var res = await chain_fetch_last_height(chain); @@ -166,8 +167,64 @@ async function wait_until_block(chain, desired_height) { } } +function testBIP44Addresses() { + const MAINNET_P2KH = 0x00; + const MAINNET_P2SH = 0x05; + const HD_FIRST_HARDENED_KEY = 0x80000000; //(1 << 31) + const HD_PRIVATE_MAINNET = 326702167824577054; + const HD_PRIVATE_TESTNET = 303293221666392015; + + + // car slab tail dirt wife custom front shield diet pear skull vapor gorilla token yard + // https://iancoleman.io/bip39/ + // e0b6ebf43ebcaa428f59a1f9241019ba4c083a1c05d988677c8bf28ec6505ae07286515a9bb0bf98d836f582a94f29fc92bbe9a0a5805ce6dc4756a439ebd1d9 + + const words = [ + 'car', 'slab', 'tail', 'dirt', 'wife', 'custom', 'front', + 'shield', 'diet', 'pear', 'skull', 'vapor', 'gorilla', 'token', 'yard' + ]; + + + let wl = kth.core_string_list_construct(); + console.log("------------------------------------------------"); + words.forEach(word => { + // console.log(word); + kth.core_string_list_push_back(wl, word); + }); + console.log("------------------------------------------------"); + + const seed = kth.wallet_mnemonics_to_seed(wl); + console.log("seed: ", seed); + // return; + + const m = kth.wallet_hd_private_construct_with_seed(seed, HD_PRIVATE_MAINNET); + const m44h = kth.wallet_hd_private_derive_private(m, 44 + HD_FIRST_HARDENED_KEY); + const m44h145h = kth.wallet_hd_private_derive_private(m44h, 145 + HD_FIRST_HARDENED_KEY); + const m44h145h0h = kth.wallet_hd_private_derive_private(m44h145h, 0 + HD_FIRST_HARDENED_KEY); + const m44h145h0h0 = kth.wallet_hd_private_derive_private(m44h145h0h, 0); + + console.log("BIP32 Root Key:", kth.wallet_hd_private_encoded(m)); + console.log("BIP44 Account Extended Private Key:", kth.wallet_hd_private_encoded(m44h145h0h)); + console.log("BIP44 Account Extended Public Key:", kth.wallet_hd_public_encoded(kth.wallet_hd_private_to_public(m44h145h0h))); + console.log("BIP32 Account Extended Private Key:", kth.wallet_hd_private_encoded(m44h145h0h0)); + console.log("BIP32 Account Extended Public Key:", kth.wallet_hd_public_encoded(kth.wallet_hd_private_to_public(m44h145h0h0))); + + // print addresses + for (let i = 0; i < 20; ++i) { + const key = kth.wallet_hd_private_derive_private(m44h145h0h0, i); + const secret = kth.wallet_hd_private_secret(key); + const point = kth.wallet_secret_to_public(secret); + const ecp = kth.wallet_ec_public_construct_from_point(point, true); + const pa = kth.wallet_ec_public_to_payment_address(ecp, MAINNET_P2KH); + console.log(kth.wallet_payment_address_encoded_cashaddr(pa, false)); + } +} + + async function main() { - test_encoding(); + testBIP44Addresses(); + return; + // test_encoding(); const mainnet = 0; const justChain = 1;