diff --git a/browser/ui/webui/brave_rewards_ui.cc b/browser/ui/webui/brave_rewards_ui.cc index 480f44e0574f..0f9605b8b134 100644 --- a/browser/ui/webui/brave_rewards_ui.cc +++ b/browser/ui/webui/brave_rewards_ui.cc @@ -85,7 +85,8 @@ class RewardsDOMHandler : public WebUIMessageHandler, void SetBackupCompleted(const base::ListValue* args); void OnGetWalletPassphrase(const std::string& pass); void OnGetContributionAmount(double amount); - void OnGetAddresses(const std::map& addresses); + void OnGetAddresses(const std::string func_name, + const std::map& addresses); void OnGetNumExcludedSites(const std::string& publisher_id, uint32_t num); void OnGetAutoContributeProps( int error_code, @@ -97,6 +98,7 @@ class RewardsDOMHandler : public WebUIMessageHandler, void OnIsWalletCreated(bool created); void GetPendingContributionsTotal(const base::ListValue* args); void OnGetPendingContributionsTotal(double amount); + void GetAddressesForPaymentId(const base::ListValue* args); // RewardsServiceObserver implementation void OnWalletInitialized(brave_rewards::RewardsService* rewards_service, @@ -244,6 +246,9 @@ void RewardsDOMHandler::RegisterMessages() { web_ui()->RegisterMessageCallback("brave_rewards.getPendingContributionsTotal", base::BindRepeating(&RewardsDOMHandler::GetPendingContributionsTotal, base::Unretained(this))); + web_ui()->RegisterMessageCallback("brave_rewards.getAddressesForPaymentId", + base::BindRepeating(&RewardsDOMHandler::GetAddressesForPaymentId, + base::Unretained(this))); } void RewardsDOMHandler::Init() { @@ -530,22 +535,26 @@ void RewardsDOMHandler::GetReconcileStamp(const base::ListValue* args) { } void RewardsDOMHandler::OnGetAddresses( + const std::string func_name, const std::map& addresses) { - if (web_ui()->CanCallJavascript()) { + if (web_ui()->CanCallJavascript() && ( + func_name == "addresses" || func_name == "addressesForPaymentId")) { base::DictionaryValue data; data.SetString("BAT", addresses.at("BAT")); data.SetString("BTC", addresses.at("BTC")); data.SetString("ETH", addresses.at("ETH")); data.SetString("LTC", addresses.at("LTC")); - web_ui()->CallJavascriptFunctionUnsafe("brave_rewards.addresses", data); + web_ui()->CallJavascriptFunctionUnsafe("brave_rewards." + func_name, data); } } void RewardsDOMHandler::GetAddresses(const base::ListValue* args) { if (rewards_service_) rewards_service_->GetAddresses(base::Bind( - &RewardsDOMHandler::OnGetAddresses, weak_factory_.GetWeakPtr())); + &RewardsDOMHandler::OnGetAddresses, + weak_factory_.GetWeakPtr(), + "addresses")); } void RewardsDOMHandler::OnAutoContributePropsReady( @@ -893,6 +902,16 @@ void RewardsDOMHandler::OnRewardsMainEnabled( } } +void RewardsDOMHandler::GetAddressesForPaymentId( + const base::ListValue* args) { + if (rewards_service_) { + rewards_service_->GetAddressesForPaymentId(base::Bind( + &RewardsDOMHandler::OnGetAddresses, + weak_factory_.GetWeakPtr(), + "addressesForPaymentId")); + } +} + } // namespace BraveRewardsUI::BraveRewardsUI(content::WebUI* web_ui, const std::string& name) diff --git a/components/brave_rewards/browser/rewards_service.h b/components/brave_rewards/browser/rewards_service.h index ec32738584c8..832c84d04bdc 100644 --- a/components/brave_rewards/browser/rewards_service.h +++ b/components/brave_rewards/browser/rewards_service.h @@ -155,6 +155,9 @@ class RewardsService : public KeyedService { virtual void GetRewardsMainEnabled( const GetRewardsMainEnabledCallback& callback) const = 0; + virtual void GetAddressesForPaymentId( + const GetAddressesCallback& callback) = 0; + void AddObserver(RewardsServiceObserver* observer); void RemoveObserver(RewardsServiceObserver* observer); diff --git a/components/brave_rewards/browser/rewards_service_impl.cc b/components/brave_rewards/browser/rewards_service_impl.cc index a3967b8d1f86..022320ce12be 100644 --- a/components/brave_rewards/browser/rewards_service_impl.cc +++ b/components/brave_rewards/browser/rewards_service_impl.cc @@ -2362,4 +2362,16 @@ void RewardsServiceImpl::OnRestorePublishersInternal( } } +void RewardsServiceImpl::GetAddressesForPaymentId( + const GetAddressesCallback& callback) { + if (!Connected()) { + return; + } + + bat_ledger_->GetAddressesForPaymentId( + base::BindOnce(&RewardsServiceImpl::OnGetAddresses, + AsWeakPtr(), + callback)); +} + } // namespace brave_rewards diff --git a/components/brave_rewards/browser/rewards_service_impl.h b/components/brave_rewards/browser/rewards_service_impl.h index e404b1710e2c..b7475672c64b 100644 --- a/components/brave_rewards/browser/rewards_service_impl.h +++ b/components/brave_rewards/browser/rewards_service_impl.h @@ -179,6 +179,8 @@ class RewardsServiceImpl : public RewardsService, void GetRewardsMainEnabled( const GetRewardsMainEnabledCallback& callback) const override; + void GetAddressesForPaymentId(const GetAddressesCallback& callback) override; + // Testing methods void SetLedgerEnvForTesting(); diff --git a/components/brave_rewards/resources/ui/actions/rewards_actions.ts b/components/brave_rewards/resources/ui/actions/rewards_actions.ts index 328fc35ac63f..f3982221135b 100644 --- a/components/brave_rewards/resources/ui/actions/rewards_actions.ts +++ b/components/brave_rewards/resources/ui/actions/rewards_actions.ts @@ -76,7 +76,7 @@ export const onReconcileStamp = (stamp: number) => action(types.ON_RECONCILE_STA stamp }) -export const onAddresses = (addresses: Record) => action(types.ON_ADDRESSES, { +export const onAddresses = (addresses: Record) => action(types.ON_ADDRESSES, { addresses }) @@ -165,3 +165,10 @@ export const onPendingContributionTotal = (amount: number) => action(types.ON_PE export const onRewardsEnabled = (enabled: boolean) => action(types.ON_REWARDS_ENABLED, { enabled }) + +export const getAddressesForPaymentId = () => action(types.GET_ADDRESSES_FOR_PAYMENT_ID) + +export const onAddressesForPaymentId = (addresses: Record) => + action(types.ON_ADDRESSES_FOR_PAYMENT_ID, { + addresses + }) diff --git a/components/brave_rewards/resources/ui/brave_rewards.tsx b/components/brave_rewards/resources/ui/brave_rewards.tsx index 66ec4d37b722..ef81ed7020fb 100644 --- a/components/brave_rewards/resources/ui/brave_rewards.tsx +++ b/components/brave_rewards/resources/ui/brave_rewards.tsx @@ -85,7 +85,7 @@ window.cr.define('brave_rewards', function () { getActions().onReconcileStamp(stamp) } - function addresses (addresses: Record) { + function addresses (addresses: Record) { getActions().onAddresses(addresses) } @@ -143,6 +143,10 @@ window.cr.define('brave_rewards', function () { getActions().onRewardsEnabled(enabled) } + function addressesForPaymentId (addresses: Record) { + getActions().onAddressesForPaymentId(addresses) + } + return { initialize, walletCreated, @@ -167,7 +171,8 @@ window.cr.define('brave_rewards', function () { adsData, pendingContributionTotal, onPendingContributionSaved, - rewardsEnabled + rewardsEnabled, + addressesForPaymentId } }) diff --git a/components/brave_rewards/resources/ui/components/settingsPage.tsx b/components/brave_rewards/resources/ui/components/settingsPage.tsx index d30304fe362a..9ee438ec2b3f 100644 --- a/components/brave_rewards/resources/ui/components/settingsPage.tsx +++ b/components/brave_rewards/resources/ui/components/settingsPage.tsx @@ -61,6 +61,14 @@ class SettingsPage extends React.Component { if (!this.props.rewardsData.ui.addressCheck) { this.actions.getAddresses() } + + // one time check (legacy fix) + if (!this.props.rewardsData.ui.paymentIdCheck) { + // https://github.com/brave/brave-browser/issues/3060 + this.actions.getAddressesForPaymentId() + // https://github.com/brave/brave-browser/issues/3061 + this.actions.getWalletPassphrase() + } } componentWillUnmount () { diff --git a/components/brave_rewards/resources/ui/constants/rewards_types.ts b/components/brave_rewards/resources/ui/constants/rewards_types.ts index 9e2710d3fe67..3dffc684a42c 100644 --- a/components/brave_rewards/resources/ui/constants/rewards_types.ts +++ b/components/brave_rewards/resources/ui/constants/rewards_types.ts @@ -51,5 +51,7 @@ export const enum types { GET_RECONCILE_STAMP = '@@rewards/GET_RECONCILE_STAMP', GET_PENDING_CONTRIBUTION_TOTAL = '@@rewards/GET_PENDING_CONTRIBUTION_TOTAL', ON_PENDING_CONTRIBUTION_TOTAL = '@@rewards/ON_PENDING_CONTRIBUTION_TOTAL', - ON_REWARDS_ENABLED = '@@rewards/ON_REWARDS_ENABLED' + ON_REWARDS_ENABLED = '@@rewards/ON_REWARDS_ENABLED', + GET_ADDRESSES_FOR_PAYMENT_ID = '@@rewards/GET_ADDRESSES_FOR_PAYMENT_ID', + ON_ADDRESSES_FOR_PAYMENT_ID = '@@rewards/ON_ADDRESSES_FOR_PAYMENT_ID' } diff --git a/components/brave_rewards/resources/ui/reducers/wallet_reducer.ts b/components/brave_rewards/resources/ui/reducers/wallet_reducer.ts index 6e9ce5c5a466..6a0668d0fd0b 100644 --- a/components/brave_rewards/resources/ui/reducers/wallet_reducer.ts +++ b/components/brave_rewards/resources/ui/reducers/wallet_reducer.ts @@ -21,6 +21,36 @@ const createWallet = (state: Rewards.State) => { return state } +const saveAddresses = (state: Rewards.State, addresses: Record) => { + if (!addresses) { + return state + } + + state = { ...state } + state.addresses = { + BAT: { + address: addresses.BAT, + qr: null + }, + BTC: { + address: addresses.BTC, + qr: null + }, + ETH: { + address: addresses.ETH, + qr: null + }, + LTC: { + address: addresses.LTC, + qr: null + } + } + + generateQR(addresses) + + return state +} + const walletReducer: Reducer = (state: Rewards.State, action) => { switch (action.type) { case types.CREATE_WALLET: @@ -128,30 +158,15 @@ const walletReducer: Reducer = (state: Rewards.State, } case types.ON_ADDRESSES: { - if (!action.payload.addresses) { - break - } - state = { ...state } - state.addresses = { - BAT: { - address: action.payload.addresses.BAT, - qr: null - }, - BTC: { - address: action.payload.addresses.BTC, - qr: null - }, - ETH: { - address: action.payload.addresses.ETH, - qr: null - }, - LTC: { - address: action.payload.addresses.LTC, - qr: null - } + state = saveAddresses(state, action.payload.addresses) + let ui = state.ui + ui.addressCheck = true + + state = { + ...state, + ui } - generateQR(action.payload.addresses) break } case types.ON_QR_GENERATED: @@ -210,16 +225,7 @@ const walletReducer: Reducer = (state: Rewards.State, } case types.GET_ADDRESSES: { - state = { ...state } - let ui = state.ui - ui.addressCheck = true - chrome.send('brave_rewards.getAddresses') - - state = { - ...state, - ui - } break } case types.GET_RECONCILE_STAMP: @@ -238,6 +244,26 @@ const walletReducer: Reducer = (state: Rewards.State, state.pendingContributionTotal = action.payload.amount break } + case types.GET_ADDRESSES_FOR_PAYMENT_ID: + { + chrome.send('brave_rewards.getAddressesForPaymentId') + break + } + case types.ON_ADDRESSES_FOR_PAYMENT_ID: + { + state = { ...state } + + state = saveAddresses(state, action.payload.addresses) + + let ui = state.ui + ui.paymentIdCheck = true + + state = { + ...state, + ui + } + break + } } return state diff --git a/components/brave_rewards/resources/ui/storage.ts b/components/brave_rewards/resources/ui/storage.ts index 2e798cf72538..41de2f431ff5 100644 --- a/components/brave_rewards/resources/ui/storage.ts +++ b/components/brave_rewards/resources/ui/storage.ts @@ -32,9 +32,10 @@ export const defaultState: Rewards.State = { recoveryKey: '', reconcileStamp: 0, ui: { - addressCheck: false, + addressCheck: true, emptyWallet: true, modalBackup: false, + paymentIdCheck: true, walletCorrupted: false, walletImported: false, walletRecoverySuccess: null, diff --git a/components/definitions/rewards.d.ts b/components/definitions/rewards.d.ts index beb617d60100..9b17a288e5b2 100644 --- a/components/definitions/rewards.d.ts +++ b/components/definitions/rewards.d.ts @@ -56,6 +56,7 @@ declare namespace Rewards { addressCheck: boolean emptyWallet: boolean modalBackup: boolean + paymentIdCheck: boolean walletRecoverySuccess: boolean | null walletServerProblem: boolean walletCorrupted: boolean diff --git a/components/services/bat_ledger/bat_ledger_impl.cc b/components/services/bat_ledger/bat_ledger_impl.cc index b1d18b26f04d..a41e30877d4c 100644 --- a/components/services/bat_ledger/bat_ledger_impl.cc +++ b/components/services/bat_ledger/bat_ledger_impl.cc @@ -335,4 +335,22 @@ void BatLedgerImpl::HasSufficientBalanceToReconcile( std::move(callback).Run(ledger_->HasSufficientBalanceToReconcile()); } +// static +void BatLedgerImpl::OnAddressesForPaymentId( + CallbackHolder* holder, + std::map addresses) { + if (holder->is_valid()) + std::move(holder->get()).Run(mojo::MapToFlatMap(addresses)); + delete holder; +} + +void BatLedgerImpl::GetAddressesForPaymentId( + GetAddressesForPaymentIdCallback callback) { + // delete in OnAddressesForPaymentId + auto* holder = new CallbackHolder( + AsWeakPtr(), std::move(callback)); + ledger_->GetAddressesForPaymentId( + std::bind(BatLedgerImpl::OnAddressesForPaymentId, holder, _1)); +} + } // namespace bat_ledger diff --git a/components/services/bat_ledger/bat_ledger_impl.h b/components/services/bat_ledger/bat_ledger_impl.h index b32047382aa9..8dbc18d4935f 100644 --- a/components/services/bat_ledger/bat_ledger_impl.h +++ b/components/services/bat_ledger/bat_ledger_impl.h @@ -121,6 +121,9 @@ class BatLedgerImpl : public mojom::BatLedger, void HasSufficientBalanceToReconcile( HasSufficientBalanceToReconcileCallback callback) override; + void GetAddressesForPaymentId( + GetAddressesForPaymentIdCallback callback) override; + private: // workaround to pass base::OnceCallback into std::bind template @@ -143,6 +146,10 @@ class BatLedgerImpl : public mojom::BatLedger, CallbackHolder* holder, std::unique_ptr banner); + static void OnAddressesForPaymentId( + CallbackHolder* holder, + std::map addresses); + std::unique_ptr bat_ledger_client_mojo_proxy_; std::unique_ptr ledger_; diff --git a/components/services/bat_ledger/public/interfaces/bat_ledger.mojom b/components/services/bat_ledger/public/interfaces/bat_ledger.mojom index 732ca0b71527..f97e4f3a081c 100644 --- a/components/services/bat_ledger/public/interfaces/bat_ledger.mojom +++ b/components/services/bat_ledger/public/interfaces/bat_ledger.mojom @@ -95,6 +95,8 @@ interface BatLedger { GetRewardsMainEnabled() => (bool main_enabled); HasSufficientBalanceToReconcile() => (bool sufficient); + + GetAddressesForPaymentId() => (map addresses); }; interface BatLedgerClient { diff --git a/vendor/bat-native-ledger/include/bat/ledger/ledger.h b/vendor/bat-native-ledger/include/bat/ledger/ledger.h index 7d795ce3ee89..d89bd5195a51 100644 --- a/vendor/bat-native-ledger/include/bat/ledger/ledger.h +++ b/vendor/bat-native-ledger/include/bat/ledger/ledger.h @@ -73,6 +73,7 @@ LEDGER_EXPORT struct PaymentData { using PublisherBannerCallback = std::function banner)>; +using WalletAddressesCallback = std::function addresses)>; class LEDGER_EXPORT Ledger { public: @@ -205,6 +206,8 @@ class LEDGER_EXPORT Ledger { virtual uint64_t GetBootStamp() const = 0; virtual bool HasSufficientBalanceToReconcile() = 0; + + virtual void GetAddressesForPaymentId(ledger::WalletAddressesCallback callback) = 0; }; } // namespace ledger diff --git a/vendor/bat-native-ledger/src/bat_client.cc b/vendor/bat-native-ledger/src/bat_client.cc index 10fe0ec1aec9..aec749d0139a 100644 --- a/vendor/bat-native-ledger/src/bat_client.cc +++ b/vendor/bat-native-ledger/src/bat_client.cc @@ -508,4 +508,46 @@ void BatClient::getGrantCaptchaCallback(bool success, ledger_->OnGrantCaptcha(response, it->second); } +void BatClient::GetAddressesForPaymentId( + ledger::WalletAddressesCallback callback) { + std::string currency = ledger_->GetCurrency(); + std::string path = (std::string)WALLET_PROPERTIES + + ledger_->GetPaymentId() + + "?refresh=true"; + ledger_->LoadURL( + braveledger_bat_helper::buildURL(path, PREFIX_V2), + std::vector(), + "", + "", + ledger::URL_METHOD::GET, + std::bind(&BatClient::GetAddressesForPaymentIdCallback, + this, + _1, + _2, + _3, + callback)); +} + +void BatClient::GetAddressesForPaymentIdCallback( + bool success, + const std::string& response, + const std::map& headers, + ledger::WalletAddressesCallback callback) { + ledger_->LogResponse(__func__, success, response, headers); + + std::map addresses; + bool ok = braveledger_bat_helper::getJSONAddresses(response, addresses); + + if (!ok) { + BLOG(ledger_, ledger::LogLevel::LOG_ERROR) << + "Failed to get addresses from payment ID"; + return; + } + + callback(addresses); + ledger_->SetAddresses(addresses); +} + + + } // namespace braveledger_bat_client diff --git a/vendor/bat-native-ledger/src/bat_client.h b/vendor/bat-native-ledger/src/bat_client.h index 1fe34a8c136f..0c3eefdc34a2 100644 --- a/vendor/bat-native-ledger/src/bat_client.h +++ b/vendor/bat-native-ledger/src/bat_client.h @@ -9,6 +9,7 @@ #include #include +#include "bat/ledger/ledger.h" #include "bat/ledger/ledger_callback_handler.h" #include "bat/ledger/publisher_info.h" #include "bat_helper.h" @@ -44,6 +45,8 @@ class BatClient { ledger::Result result, const std::string& data); + void GetAddressesForPaymentId(ledger::WalletAddressesCallback callback); + private: void getGrantCaptchaCallback(bool result, const std::string& response, const std::map& headers); @@ -57,6 +60,12 @@ class BatClient { const std::map& headers, const std::string& paymentId); std::string getAnonizeProof(const std::string& registrarVK, const std::string& id, std::string& preFlight); + void GetAddressesForPaymentIdCallback( + bool success, + const std::string& response, + const std::map& headers, + ledger::WalletAddressesCallback callback); + bat_ledger::LedgerImpl* ledger_; // NOT OWNED }; diff --git a/vendor/bat-native-ledger/src/bat_helper.cc b/vendor/bat-native-ledger/src/bat_helper.cc index 5c91046765c9..d322772eca6a 100644 --- a/vendor/bat-native-ledger/src/bat_helper.cc +++ b/vendor/bat-native-ledger/src/bat_helper.cc @@ -1957,6 +1957,33 @@ static bool ignore_ = false; return !hasError; } + bool getJSONAddresses(const std::string& json, + std::map& addresses) { + rapidjson::Document d; + d.Parse(json.c_str()); + + //has parser errors or wrong types + bool error = d.HasParseError(); + if (false == error) { + error = !(d.HasMember("addresses") && d["addresses"].IsObject()); + } + + if (false == error) { + addresses.insert( + std::make_pair("BAT", d["addresses"]["BAT"].GetString())); + addresses.insert( + std::make_pair("BTC", d["addresses"]["BTC"].GetString())); + addresses.insert( + std::make_pair("CARD_ID", d["addresses"]["CARD_ID"].GetString())); + addresses.insert( + std::make_pair("ETH", d["addresses"]["ETH"].GetString())); + addresses.insert( + std::make_pair("LTC", d["addresses"]["LTC"].GetString())); + } + + return !error; + } + std::vector generateSeed() { //std::ostringstream seedStr; diff --git a/vendor/bat-native-ledger/src/bat_helper.h b/vendor/bat-native-ledger/src/bat_helper.h index da2477446ba0..9b3f164e1902 100644 --- a/vendor/bat-native-ledger/src/bat_helper.h +++ b/vendor/bat-native-ledger/src/bat_helper.h @@ -451,6 +451,9 @@ namespace braveledger_bat_helper { bool getJSONServerList(const std::string& json, std::map& list); + bool getJSONAddresses(const std::string& json, + std::map& addresses); + std::vector generateSeed(); std::vector getHKDF(const std::vector& seed); diff --git a/vendor/bat-native-ledger/src/bat_state.cc b/vendor/bat-native-ledger/src/bat_state.cc index 5dc09a149c71..afea2072ba53 100644 --- a/vendor/bat-native-ledger/src/bat_state.cc +++ b/vendor/bat-native-ledger/src/bat_state.cc @@ -384,4 +384,29 @@ double BatState::GetDefaultContributionAmount() { return state_->walletProperties_.fee_amount_; } +void BatState::SetAddress(std::map addresses) { + for (auto& address : addresses) { + if (address.first == "BAT") { + state_->walletInfo_.addressBAT_ = address.second; + } + + if (address.first == "BTC") { + state_->walletInfo_.addressBTC_ = address.second; + } + + if (address.first == "CARD_ID") { + state_->walletInfo_.addressCARD_ID_ = address.second; + } + + if (address.first == "ETH") { + state_->walletInfo_.addressETH_ = address.second; + } + + if (address.first == "LTC") { + state_->walletInfo_.addressLTC_ = address.second; + } + } + SaveState(); +} + } // namespace braveledger_bat_state diff --git a/vendor/bat-native-ledger/src/bat_state.h b/vendor/bat-native-ledger/src/bat_state.h index 7d647470e5dd..438c98a75c72 100644 --- a/vendor/bat-native-ledger/src/bat_state.h +++ b/vendor/bat-native-ledger/src/bat_state.h @@ -9,6 +9,7 @@ #include #include +#include namespace bat_ledger { class LedgerImpl; @@ -144,6 +145,8 @@ class BatState { double GetDefaultContributionAmount(); + void SetAddress(std::map addresses); + private: void SaveState(); diff --git a/vendor/bat-native-ledger/src/ledger_impl.cc b/vendor/bat-native-ledger/src/ledger_impl.cc index 15e2954f77e1..2876fe0dabfe 100644 --- a/vendor/bat-native-ledger/src/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/ledger_impl.cc @@ -1135,4 +1135,13 @@ bool LedgerImpl::HasSufficientBalanceToReconcile() { return GetBalance() >= GetContributionAmount(); } +void LedgerImpl::GetAddressesForPaymentId( + ledger::WalletAddressesCallback callback) { + bat_client_->GetAddressesForPaymentId(callback); +} + +void LedgerImpl::SetAddresses(std::map addresses) { + bat_state_->SetAddress(addresses); +} + } // namespace bat_ledger diff --git a/vendor/bat-native-ledger/src/ledger_impl.h b/vendor/bat-native-ledger/src/ledger_impl.h index fec7da811105..96831d613d8f 100644 --- a/vendor/bat-native-ledger/src/ledger_impl.h +++ b/vendor/bat-native-ledger/src/ledger_impl.h @@ -298,6 +298,11 @@ class LedgerImpl : public ledger::Ledger, double GetDefaultContributionAmount() override; bool HasSufficientBalanceToReconcile() override; + void GetAddressesForPaymentId(ledger::WalletAddressesCallback callback) + override; + + void SetAddresses(std::map addresses); + private: void AddRecurringPayment(const std::string& publisher_id, const double& value) override; void OnLoad(const ledger::VisitData& visit_data, const uint64_t& current_time) override;