/* This file is part of TON Blockchain Library. TON Blockchain Library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. TON Blockchain Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . Copyright 2017-2020 Telegram Systems LLP */ #pragma once #include "TonlibCallback.h" #include "tonlib/Config.h" #include "tonlib/ExtClient.h" #include "tonlib/ExtClientOutbound.h" #include "tonlib/KeyStorage.h" #include "tonlib/KeyValue.h" #include "tonlib/LastBlockStorage.h" #include "td/actor/actor.h" #include "td/utils/CancellationToken.h" #include "td/utils/optional.h" #include "smc-envelope/ManualDns.h" #include namespace tonlib { namespace int_api { struct GetAccountState; struct GetPrivateKey; struct GetDnsResolver; struct SendMessage; struct RemoteRunSmcMethod; struct RemoteRunSmcMethodReturnType; inline std::string to_string(const int_api::SendMessage&) { return "Send message"; } } // namespace int_api class AccountState; class Query; td::Result> to_tonlib_api( const ton::ManualDns::EntryData& entry_data); td::Result to_dns_entry_data(tonlib_api::dns_EntryData& entry_data); class TonlibClient : public td::actor::Actor { public: template using object_ptr = tonlib_api::object_ptr; explicit TonlibClient(td::unique_ptr callback); void request(td::uint64 id, object_ptr function); void close(); static object_ptr static_request(object_ptr function); ~TonlibClient(); struct FullConfig { Config config; bool use_callbacks_for_network; LastBlockState last_state; std::string last_state_key; td::uint32 wallet_id; std::string rwallet_init_public_key; }; template void make_request(T&& request, P&& promise) { td::Promise::ReturnType> new_promise = std::move(promise); auto status = do_request(std::forward(request), std::move(new_promise)); if (status.is_error()) { new_promise.operator()(std::move(status)); } } private: enum class State { Uninited, Running, Closed } state_ = State::Uninited; td::unique_ptr callback_; // Config Config config_; td::uint32 config_generation_{0}; td::uint32 wallet_id_; std::string rwallet_init_public_key_; std::string last_state_key_; bool use_callbacks_for_network_{false}; // KeyStorage std::shared_ptr kv_; KeyStorage key_storage_; LastBlockStorage last_block_storage_; struct QueryContext { td::optional block_id; }; QueryContext query_context_; // network td::actor::ActorOwn raw_client_; td::actor::ActorId ext_client_outbound_; td::actor::ActorOwn raw_last_block_; td::actor::ActorOwn raw_last_config_; ExtClient client_; td::CancellationTokenSource source_; std::map> actors_; td::int64 actor_id_{1}; ExtClientRef get_client_ref(); void init_ext_client(); void init_last_block(LastBlockState state); void init_last_config(); bool is_closing_{false}; td::uint32 ref_cnt_{1}; void hangup_shared() override { auto it = actors_.find(get_link_token()); if (it != actors_.end()) { actors_.erase(it); } else { ref_cnt_--; } try_stop(); } void hangup() override; void try_stop() { if (is_closing_ && ref_cnt_ == 0 && actors_.empty()) { stop(); } } void update_last_block_state(LastBlockState state, td::uint32 config_generation_); void update_sync_state(LastBlockSyncState state, td::uint32 config_generation); void on_result(td::uint64 id, object_ptr response); void on_update(object_ptr response); static bool is_static_request(td::int32 id); static bool is_uninited_request(td::int32 id); template static object_ptr do_static_request(const T& request) { return tonlib_api::make_object(400, "Function can't be executed synchronously"); } static object_ptr do_static_request(const tonlib_api::runTests& request); static object_ptr do_static_request(const tonlib_api::getAccountAddress& request); static object_ptr do_static_request(const tonlib_api::packAccountAddress& request); static object_ptr do_static_request(const tonlib_api::unpackAccountAddress& request); static object_ptr do_static_request(tonlib_api::getBip39Hints& request); static object_ptr do_static_request(tonlib_api::setLogStream& request); static object_ptr do_static_request(const tonlib_api::getLogStream& request); static object_ptr do_static_request(const tonlib_api::setLogVerbosityLevel& request); static object_ptr do_static_request(const tonlib_api::setLogTagVerbosityLevel& request); static object_ptr do_static_request(const tonlib_api::getLogVerbosityLevel& request); static object_ptr do_static_request(const tonlib_api::getLogTagVerbosityLevel& request); static object_ptr do_static_request(const tonlib_api::getLogTags& request); static object_ptr do_static_request(const tonlib_api::addLogMessage& request); static object_ptr do_static_request(const tonlib_api::encrypt& request); static object_ptr do_static_request(const tonlib_api::decrypt& request); static object_ptr do_static_request(const tonlib_api::kdf& request); static object_ptr do_static_request(const tonlib_api::msg_decryptWithProof& request); template td::Status do_request(const tonlib_api::runTests& request, P&&); template td::Status do_request(const tonlib_api::getAccountAddress& request, P&&); template td::Status do_request(const tonlib_api::packAccountAddress& request, P&&); template td::Status do_request(const tonlib_api::unpackAccountAddress& request, P&&); template td::Status do_request(tonlib_api::getBip39Hints& request, P&&); template td::Status do_request(tonlib_api::setLogStream& request, P&&); template td::Status do_request(const tonlib_api::getLogStream& request, P&&); template td::Status do_request(const tonlib_api::setLogVerbosityLevel& request, P&&); template td::Status do_request(const tonlib_api::setLogTagVerbosityLevel& request, P&&); template td::Status do_request(const tonlib_api::getLogVerbosityLevel& request, P&&); template td::Status do_request(const tonlib_api::getLogTagVerbosityLevel& request, P&&); template td::Status do_request(const tonlib_api::getLogTags& request, P&&); template td::Status do_request(const tonlib_api::addLogMessage& request, P&&); template td::Status do_request(const tonlib_api::encrypt& request, P&&); template td::Status do_request(const tonlib_api::decrypt& request, P&&); template td::Status do_request(const tonlib_api::kdf& request, P&&); template td::Status do_request(const tonlib_api::msg_decryptWithProof& request, P&&); void make_any_request(tonlib_api::Function& function, QueryContext query_context, td::Promise>&& promise); td::Result validate_config(tonlib_api::object_ptr config); void set_config(FullConfig config); td::Status do_request(const tonlib_api::init& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::close& request, td::Promise>&& promise); td::Status do_request(tonlib_api::options_validateConfig& request, td::Promise>&& promise); td::Status do_request(tonlib_api::options_setConfig& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::raw_sendMessage& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::raw_createAndSendMessage& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::raw_createQuery& request, td::Promise>&& promise); td::Status do_request(tonlib_api::raw_getAccountState& request, td::Promise>&& promise); td::Status do_request(tonlib_api::raw_getTransactions& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::getAccountState& request, td::Promise>&& promise); td::Status do_request(tonlib_api::guessAccountRevision& request, td::Promise>&& promise); td::Status do_request(tonlib_api::guessAccount& request, td::Promise>&& promise); td::Status do_request(tonlib_api::sync& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::createNewKey& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::exportKey& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::deleteKey& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::deleteAllKeys& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::importKey& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::exportPemKey& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::importPemKey& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::exportEncryptedKey& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::importEncryptedKey& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::exportUnencryptedKey& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::importUnencryptedKey& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::changeLocalPassword& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::onLiteServerQueryResult& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::onLiteServerQueryError& request, td::Promise>&& promise); td::int64 next_query_id_{0}; std::map> queries_; td::int64 register_query(td::unique_ptr query); td::Result> get_query_info(td::int64 id); void finish_create_query(td::Result> r_query, td::Promise>&& promise); void query_estimate_fees(td::int64 id, bool ignore_chksig, td::Result r_state, td::Promise>&& promise); td::Status do_request(const tonlib_api::query_getInfo& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::query_estimateFees& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::query_send& request, td::Promise>&& promise); td::Status do_request(tonlib_api::query_forget& request, td::Promise>&& promise); td::Status do_request(tonlib_api::createQuery& request, td::Promise>&& promise); td::Status do_request(tonlib_api::msg_decrypt& request, td::Promise>&& promise); td::int64 next_smc_id_{0}; std::map> smcs_; td::int64 register_smc(td::unique_ptr smc); td::Result> get_smc_info(td::int64 id); void finish_load_smc(td::unique_ptr query, td::Promise>&& promise); td::Status do_request(const tonlib_api::smc_load& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::smc_getCode& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::smc_getData& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::smc_getState& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::smc_runGetMethod& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::dns_resolve& request, td::Promise>&& promise); td::Status do_request(tonlib_api::pchan_signPromise& request, td::Promise>&& promise); td::Status do_request(tonlib_api::pchan_validatePromise& request, td::Promise>&& promise); td::Status do_request(tonlib_api::pchan_packPromise& request, td::Promise>&& promise); td::Status do_request(tonlib_api::pchan_unpackPromise& request, td::Promise>&& promise); void do_dns_request(std::string name, td::int32 category, td::int32 ttl, td::optional block_id, block::StdAddress address, td::Promise>&& promise); struct DnsFinishData { ton::BlockIdExt block_id; ton::SmartContract::State smc_state; }; void finish_dns_resolve(std::string name, td::int32 category, td::int32 ttl, td::optional block_id, DnsFinishData dns_finish_data, td::Promise>&& promise); td::Status do_request(int_api::GetAccountState request, td::Promise>&&); td::Status do_request(int_api::GetPrivateKey request, td::Promise&&); td::Status do_request(int_api::GetDnsResolver request, td::Promise&&); td::Status do_request(int_api::RemoteRunSmcMethod request, td::Promise&& promise); td::Status do_request(int_api::SendMessage request, td::Promise&& promise); td::Status do_request(const tonlib_api::liteServer_getInfo& request, td::Promise>&& promise); td::Status do_request(tonlib_api::withBlock& request, td::Promise>&& promise); void proxy_request(td::int64 query_id, std::string data); friend class TonlibQueryActor; struct Target { bool can_be_empty{true}; bool can_be_uninited{false}; block::StdAddress address; td::optional public_key; }; td::Status guess_revisions(std::vector targets, td::Promise>&& promise); }; } // namespace tonlib