wasm_interface.cpp 19.80 KiB
#include "core/foundation.hpp"
#include "core/protocol_impl.hpp"
#include "core/protobuf_protocol_impl.hpp"
#include "core/protocol_impl.inl"
#include "core/protobuf_protocol_impl.inl"
#include <iostream>
#include <emscripten/bind.h>
using namespace cpp;
using namespace emscripten;
using manabar_fn_t = result(const int32_t, const uint32_t, const uint32_t, const uint32_t, const uint32_t, const uint32_t);
using ext_json_asset_fn_t = json_asset(const int32_t, const int32_t)const;
/// unfortunetely emscripten can't handle correctly C++ set -> JS Set transformation, so we have to use a vector instead.
struct required_authority_collectionV
{
typedef std::vector<std::string> account_vector;
typedef account_vector account_collection_t;
account_vector posting_accounts;
account_vector active_accounts;
account_vector owner_accounts;
std::vector<wax_authority> other_authorities;
};
using authority_verification_trace = hive::protocol::authority_verification_trace;
class foundation_wasm : public foundation
{
private:
long long join_lh(int32_t low, int32_t high)const
{ return (long long) high << 32 | (uint32_t) low; }
unsigned long long join_lh(uint32_t low, uint32_t high)const
{ return (unsigned long long) high << 32 | low; }
public:
using required_authority_collection_t = required_authority_collectionV;
result cpp_calculate_manabar_full_regeneration_time(const int32_t now, const uint32_t max_mana_low, const uint32_t max_mana_high, const uint32_t current_mana_low, const uint32_t current_mana_high, const uint32_t last_update_time)
{ return foundation::cpp_calculate_manabar_full_regeneration_time(now, join_lh(max_mana_low, max_mana_high), join_lh(current_mana_low, current_mana_high), last_update_time); }
result cpp_calculate_current_manabar_value(const int32_t now, const uint32_t max_mana_low, const uint32_t max_mana_high, const uint32_t current_mana_low, const uint32_t current_mana_high, const uint32_t last_update_time)
{ return foundation::cpp_calculate_current_manabar_value(now, join_lh(max_mana_low, max_mana_high), join_lh(current_mana_low, current_mana_high), last_update_time); }
json_asset cpp_general_asset(const uint32_t asset_num, const int32_t amount_low, const int32_t amount_high)const
{ return foundation::cpp_general_asset(asset_num, join_lh(amount_low, amount_high)); }
json_asset cpp_hive(const int32_t amount_low, const int32_t amount_high)const
{ return foundation::cpp_hive(join_lh(amount_low, amount_high)); }
json_asset cpp_hbd(const int32_t amount_low, const int32_t amount_high)const
{ return foundation::cpp_hbd(join_lh(amount_low, amount_high)); }
json_asset cpp_vests(const int32_t amount_low, const int32_t amount_high)const
{ return foundation::cpp_vests(join_lh(amount_low, amount_high)); }
witness_set_properties_serialized cpp_serialize_witness_set_properties(const witness_set_properties_data& value) const
{ return foundation::cpp_serialize_witness_set_properties(value); }
witness_set_properties_data cpp_deserialize_witness_set_properties(const witness_set_properties_serialized& value) const
{ return foundation::cpp_deserialize_witness_set_properties(value); }
std::string cpp_asset_value(const json_asset& value) const
{ return foundation::cpp_asset_value(value); }
std::string cpp_asset_symbol(const json_asset& value) const
{ return foundation::cpp_asset_symbol(value); }
void cpp_throws(int value) const
{ foundation::cpp_throws(value); }
crypto_memo cpp_crypto_memo_from_string(const std::string& value) const
{ return foundation::cpp_crypto_memo_from_string(value); }
std::string cpp_crypto_memo_dump_string(const crypto_memo& value) const
{ return foundation::cpp_crypto_memo_dump_string(value); }
void cpp_scan_text_for_matching_private_keys(const std::string& text, const std::string& account, const wax_authorities& auths, const std::string& memo_key,
const std::vector<std::string>& imported_keys) const
{
return foundation::cpp_check_memo_for_private_keys(text, account, auths, memo_key, imported_keys);
}
brain_key_data cpp_suggest_brain_key()
{ return foundation::cpp_suggest_brain_key(); }
result cpp_generate_private_key()
{ return foundation::cpp_generate_private_key(); }
private_key_data cpp_generate_private_key_password_based(const std::string& account, const std::string& role, const std::string& password)
{ return foundation::cpp_generate_private_key(account, role, password); }
std::string cpp_convert_raw_private_key_to_wif(const std::string& hexData)
{
return foundation::cpp_convert_raw_private_key_to_wif(hexData);
}
std::string cpp_convert_raw_public_key_to_wif(const std::string& hexData)
{
return foundation::cpp_convert_raw_public_key_to_wif(hexData);
}
result cpp_get_public_key_from_signature(const std::string& digest, const std::string& signature)
{ return foundation::cpp_get_public_key_from_signature(digest, signature); }
result cpp_calculate_public_key(const std::string& wif)
{ return foundation::cpp_calculate_public_key(wif); }
std::map<std::string, std::string> cpp_get_hive_protocol_config(const std::string& chain_id)
{ return foundation::cpp_get_hive_protocol_config(chain_id); }
ref_block_data cpp_get_tapos_data(const std::string& block_id)
{ return foundation::cpp_get_tapos_data(block_id); }
std::string cpp_get_address_prefix()
{ return HIVE_ADDRESS_PREFIX; }
result cpp_calculate_hp_apr(
const uint32_t head_block_num,
const uint16_t vesting_reward_percent,
const json_asset& virtual_supply,
const json_asset& total_vesting_fund_hive) const
{
return foundation::cpp_calculate_hp_apr(
head_block_num, vesting_reward_percent, virtual_supply, total_vesting_fund_hive);
}
json_asset cpp_hbd_to_hive(const json_asset &hbd, const json_asset& base, const json_asset& quote) const
{
return foundation::cpp_hbd_to_hive(hbd, base, quote);
}
json_asset cpp_hive_to_hbd(const json_asset& amount, const json_asset& base, const json_asset& quote) const
{
return foundation::cpp_hive_to_hbd(amount, base, quote);
}
json_asset cpp_vests_to_hp(const json_asset& vests, const json_asset& total_vesting_fund_hive, const json_asset& total_vesting_shares) const
{
return foundation::cpp_vests_to_hp(vests, total_vesting_fund_hive, total_vesting_shares);
}
json_asset cpp_hp_to_vests(const json_asset& vests, const json_asset& total_vesting_fund_hive, const json_asset& total_vesting_shares) const
{
return foundation::cpp_hp_to_vests(vests, total_vesting_fund_hive, total_vesting_shares);
}
result cpp_calculate_inflation_rate_for_block(const uint32_t block_num) const
{
return foundation::cpp_calculate_inflation_rate_for_block( block_num );
}
json_asset cpp_estimate_hive_collateral( const json_price& current_median_history, const json_price& current_min_history, const json_asset& hbd_amount_to_get ) const
{
return foundation::cpp_estimate_hive_collateral( current_median_history, current_min_history, hbd_amount_to_get );
}
bool cpp_is_valid_account_name( const std::string& name ) const
{
return foundation::cpp_is_valid_account_name( name );
}
};
class AccountAuthorityProviderWrapper final : public emscripten::wrapper<IAccountAuthorityProvider>
{
public:
EMSCRIPTEN_WRAPPER(AccountAuthorityProviderWrapper);
virtual std::optional<wax_authority> getAuthority(std::string account_name, std::string authorityRole) override
{
return call<std::optional<wax_authority>>("getAuthority", account_name, authorityRole);
}
virtual std::optional<std::string> getWitnessPublicKey(std::string account_name) override
{
return call<std::optional<std::string>>("getWitnessPublicKey", account_name);
}
};
using protocol_wasm = cpp::protocol_impl<foundation_wasm>;
using proto_protocol_wasm = cpp::proto_protocol_impl<foundation_wasm>;
EMSCRIPTEN_BINDINGS(wax_api_instance) {
enum_<error_code>("error_code")
.value("fail", error_code::fail)
.value("ok", error_code::ok)
;
value_object<result>("result")
.field("value", &result::value)
.field("content", &result::content)
.field("exception_message", &result::exception_message)
;
value_object<brain_key_data>("brain_key_data")
.field("associated_public_key", &brain_key_data::associated_public_key)
.field("brain_key", &brain_key_data::brain_key)
.field("wif_private_key", &brain_key_data::wif_private_key)
;
value_object<private_key_data>("private_key_data")
.field("associated_public_key", &private_key_data::associated_public_key)
.field("wif_private_key", &private_key_data::wif_private_key)
;
value_object<json_asset>("json_asset")
.field("amount", &json_asset::amount)
.field("precision", &json_asset::precision)
.field("nai", &json_asset::nai)
;
value_object<crypto_memo>("crypto_memo")
.field("from", &crypto_memo::_from)
.field("to", &crypto_memo::to)
.field("content", &crypto_memo::content)
;
value_object<wax_authority>("wax_authority")
.field("weight_threshold", &wax_authority::weight_threshold)
.field("account_auths", &wax_authority::account_auths)
.field("key_auths", &wax_authority::key_auths)
;
value_object<wax_authorities>("wax_authorities")
.field("active", &wax_authorities::active)
.field("owner", &wax_authorities::owner)
.field("posting", &wax_authorities::posting)
;
value_object<required_authority_collectionV>("required_authority_collection")
.field("posting_accounts", &required_authority_collectionV::posting_accounts)
.field("active_accounts", &required_authority_collectionV::active_accounts)
.field("owner_accounts", &required_authority_collectionV::owner_accounts)
.field("other_authorities", &required_authority_collectionV::other_authorities)
;
value_object<ref_block_data>("ref_block_data")
.field("ref_block_num", &ref_block_data::ref_block_num)
.field("ref_block_prefix", &ref_block_data::ref_block_prefix)
;
value_object<json_price>("json_price")
.field("base", &json_price::base)
.field("quote", &json_price::quote)
;
value_object<binary_data_node>("binary_data_node")
.field("key", &binary_data_node::key)
.field("type", &binary_data_node::type)
.field("offset", &binary_data_node::offset)
.field("size", &binary_data_node::size)
.field("value", &binary_data_node::value)
.field("length", &binary_data_node::length)
.field("children", &binary_data_node::children)
;
value_object<binary_data>("binary_data")
.field("binary", &binary_data::binary)
.field("offsets", &binary_data::offsets)
;
register_optional<std::string>();
register_optional<uint32_t>();
register_optional<uint16_t>();
register_optional<int32_t>();
register_optional<json_asset>();
register_optional<json_price>();
register_vector<std::string>("VectorString"); // Required for map binding -> keys() method
register_vector<wax_authority>("VectorWaxAuthority");
register_vector<binary_data_node>("VectorBinaryDataNode");
register_vector<authority_verification_trace::path_entry>("VectorPathEntry");
register_map<std::string, std::string>("MapStringString");
register_map<std::string, uint16_t>("MapStringUInt16");
value_object<witness_set_properties_data>("witness_set_properties_data")
.field("key", &witness_set_properties_data::key)
.field("new_signing_key", &witness_set_properties_data::new_signing_key)
.field("account_creation_fee", &witness_set_properties_data::account_creation_fee)
.field("url", &witness_set_properties_data::url)
.field("hbd_exchange_rate", &witness_set_properties_data::hbd_exchange_rate)
.field("maximum_block_size", &witness_set_properties_data::maximum_block_size)
.field("hbd_interest_rate", &witness_set_properties_data::hbd_interest_rate)
.field("account_subsidy_budget", &witness_set_properties_data::account_subsidy_budget)
.field("account_subsidy_decay", &witness_set_properties_data::account_subsidy_decay)
;
value_object<authority_verification_trace::path_entry>("path_entry")
.field("processed_entry", &authority_verification_trace::path_entry::processed_entry)
.field("processed_role", &authority_verification_trace::path_entry::processed_role)
.field("recursion_depth", &authority_verification_trace::path_entry::recursion_depth)
.field("threshold", &authority_verification_trace::path_entry::threshold)
.field("weight", &authority_verification_trace::path_entry::weight)
.field("flags", &authority_verification_trace::path_entry::flags)
.field("visited_entries", &authority_verification_trace::path_entry::visited_entries)
;
value_object<authority_verification_trace>("authority_verification_trace")
.field("root", &authority_verification_trace::root)
.field("final_authority_path", &authority_verification_trace::final_authority_path)
.field("verification_status", &authority_verification_trace::verification_status)
;
class_<IAccountAuthorityProvider>("IAccountAuthorityProvider")
.allow_subclass<AccountAuthorityProviderWrapper>("AccountAuthorityProviderWrapper")
.function("getAuthority", &IAccountAuthorityProvider::getAuthority, pure_virtual())
.function("getWitnessPublicKey", &IAccountAuthorityProvider::getWitnessPublicKey, pure_virtual())
;
class_<foundation_wasm>("protocol_foundation")
.constructor<>()
.function("cpp_get_address_prefix", &foundation_wasm::cpp_get_address_prefix)
.function("cpp_calculate_public_key", &foundation_wasm::cpp_calculate_public_key)
.function("cpp_suggest_brain_key", &foundation_wasm::cpp_suggest_brain_key)
.function("cpp_get_hive_protocol_config", &foundation_wasm::cpp_get_hive_protocol_config)
.function("cpp_generate_private_key", &foundation_wasm::cpp_generate_private_key)
.function("cpp_generate_private_key_password_based", &foundation_wasm::cpp_generate_private_key_password_based)
.function("cpp_convert_raw_private_key_to_wif", &foundation_wasm::cpp_convert_raw_private_key_to_wif)
.function("cpp_convert_raw_public_key_to_wif", &foundation_wasm::cpp_convert_raw_public_key_to_wif)
.function("cpp_get_public_key_from_signature", &foundation_wasm::cpp_get_public_key_from_signature)
// Based on https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#overloaded-functions:
.function("cpp_general_asset", select_overload<json_asset(const uint32_t, const int32_t, const int32_t)const>(&foundation_wasm::cpp_general_asset))
.function("cpp_hive", select_overload<ext_json_asset_fn_t>(&foundation_wasm::cpp_hive))
.function("cpp_hbd", select_overload<ext_json_asset_fn_t>(&foundation_wasm::cpp_hbd))
.function("cpp_vests", select_overload<ext_json_asset_fn_t>(&foundation_wasm::cpp_vests))
.function("cpp_serialize_witness_set_properties", &foundation_wasm::cpp_serialize_witness_set_properties)
.function("cpp_deserialize_witness_set_properties", &foundation_wasm::cpp_deserialize_witness_set_properties)
.function("cpp_asset_value", &foundation_wasm::cpp_asset_value)
.function("cpp_asset_symbol", &foundation_wasm::cpp_asset_symbol)
.function("cpp_throws", &foundation_wasm::cpp_throws)
.function("cpp_crypto_memo_from_string", &foundation_wasm::cpp_crypto_memo_from_string)
.function("cpp_crypto_memo_dump_string", &foundation_wasm::cpp_crypto_memo_dump_string)
.function("cpp_scan_text_for_matching_private_keys", &foundation_wasm::cpp_scan_text_for_matching_private_keys)
.function("cpp_calculate_manabar_full_regeneration_time", select_overload<manabar_fn_t>(&foundation_wasm::cpp_calculate_manabar_full_regeneration_time))
.function("cpp_calculate_current_manabar_value", select_overload<manabar_fn_t>(&foundation_wasm::cpp_calculate_current_manabar_value))
.function("cpp_get_tapos_data", &foundation_wasm::cpp_get_tapos_data)
.function("cpp_calculate_hp_apr", &foundation_wasm::cpp_calculate_hp_apr)
.function("cpp_calculate_inflation_rate_for_block", &foundation_wasm::cpp_calculate_inflation_rate_for_block)
.function("cpp_vests_to_hp", &foundation_wasm::cpp_vests_to_hp)
.function("cpp_hp_to_vests", &foundation_wasm::cpp_hp_to_vests)
.function("cpp_hbd_to_hive", &foundation_wasm::cpp_hbd_to_hive)
.function("cpp_hive_to_hbd", &foundation_wasm::cpp_hive_to_hbd)
.function("cpp_estimate_hive_collateral", &foundation_wasm::cpp_estimate_hive_collateral)
.function("cpp_is_valid_account_name", &foundation_wasm::cpp_is_valid_account_name)
;
class_<protocol_wasm, base<foundation_wasm>>("protocol")
.constructor<>()
.function("cpp_operation_get_impacted_accounts", &protocol_wasm::cpp_operation_get_impacted_accounts)
.function("cpp_transaction_get_impacted_accounts", &protocol_wasm::cpp_transaction_get_impacted_accounts)
.function("cpp_generate_binary_transaction_metadata", &protocol_wasm::cpp_generate_binary_transaction_metadata)
.function("cpp_generate_binary_operation_metadata", &protocol_wasm::cpp_generate_binary_operation_metadata)
.function("cpp_validate_operation", &protocol_wasm::cpp_validate_operation)
.function("cpp_validate_transaction", &protocol_wasm::cpp_validate_transaction)
.function("cpp_calculate_transaction_id", &protocol_wasm::cpp_calculate_transaction_id)
.function("cpp_calculate_legacy_transaction_id", &protocol_wasm::cpp_calculate_legacy_transaction_id)
.function("cpp_calculate_sig_digest", &protocol_wasm::cpp_calculate_sig_digest)
.function("cpp_calculate_legacy_sig_digest", &protocol_wasm::cpp_calculate_legacy_sig_digest)
.function("cpp_serialize_transaction", &protocol_wasm::cpp_serialize_transaction)
.function("cpp_deserialize_transaction", &protocol_wasm::cpp_deserialize_transaction)
.function("cpp_collect_transaction_required_authorities", &protocol_wasm::cpp_collect_transaction_required_authorities)
.function("cpp_trace_authority_verification", &protocol_wasm::cpp_trace_authority_verification)
.function("cpp_get_hive_protocol_config", &protocol_wasm::cpp_get_hive_protocol_config)
;
// We have to use it this way because JavaScript (and emscripten in conclusion) doesn't support multiple inheritance
class_<proto_protocol_wasm, base<foundation_wasm>>("proto_protocol")
.constructor<>()
.function("cpp_operation_get_impacted_accounts", &proto_protocol_wasm::cpp_operation_get_impacted_accounts)
.function("cpp_transaction_get_impacted_accounts", &proto_protocol_wasm::cpp_transaction_get_impacted_accounts)
.function("cpp_generate_binary_transaction_metadata", &proto_protocol_wasm::cpp_generate_binary_transaction_metadata)
.function("cpp_generate_binary_operation_metadata", &proto_protocol_wasm::cpp_generate_binary_operation_metadata)
.function("cpp_validate_operation", &proto_protocol_wasm::cpp_validate_operation)
.function("cpp_validate_transaction", &proto_protocol_wasm::cpp_validate_transaction)
.function("cpp_calculate_transaction_id", &proto_protocol_wasm::cpp_calculate_transaction_id)
.function("cpp_calculate_legacy_transaction_id", &proto_protocol_wasm::cpp_calculate_legacy_transaction_id)
.function("cpp_calculate_sig_digest", &proto_protocol_wasm::cpp_calculate_sig_digest)
.function("cpp_calculate_legacy_sig_digest", &proto_protocol_wasm::cpp_calculate_legacy_sig_digest)
.function("cpp_serialize_transaction", &proto_protocol_wasm::cpp_serialize_transaction)
.function("cpp_deserialize_transaction", &proto_protocol_wasm::cpp_deserialize_transaction)
.function("cpp_proto_to_api", &proto_protocol_wasm::cpp_proto_to_api)
.function("cpp_proto_to_legacy_api", &proto_protocol_wasm::cpp_proto_to_legacy_api)
.function("cpp_api_to_proto", &proto_protocol_wasm::cpp_api_to_proto)
.function("cpp_collect_transaction_required_authorities", &proto_protocol_wasm::cpp_collect_transaction_required_authorities)
;
}
int main() {
// Main should not be run during TypeScript generation.
// abort();
// std::cout << "This function does nothing... You have to instantiate wax_api on JS side to play with..." << std::endl;
return 0;
}