[#9203] Transfers fetching with less requests
- all messages are not shown right away, in order to paginate history a user has to press "load more" button - added link to etherscan before transfers list - there is a new "fetch more" button at the end of the list - rest of changes can be found here status-im/status-go#1775
This commit is contained in:
parent
bddf3fa341
commit
161042066d
|
@ -45,6 +45,7 @@
|
|||
|
||||
(def mainnet-networks
|
||||
[{:id "mainnet_rpc",
|
||||
:etherscan-link "https://etherscan.io/address/",
|
||||
:name "Mainnet with upstream RPC",
|
||||
:config {:NetworkId (ethereum/chain-keyword->chain-id :mainnet)
|
||||
:DataDir "/ethereum/mainnet_rpc"
|
||||
|
@ -67,18 +68,21 @@
|
|||
|
||||
(def testnet-networks
|
||||
[{:id "testnet_rpc",
|
||||
:etherscan-link "https://ropsten.etherscan.io/address/",
|
||||
:name "Ropsten with upstream RPC",
|
||||
:config {:NetworkId (ethereum/chain-keyword->chain-id :testnet)
|
||||
:DataDir "/ethereum/testnet_rpc"
|
||||
:UpstreamConfig {:Enabled true
|
||||
:URL "https://ropsten.infura.io/v3/f315575765b14720b32382a61a89341a"}}}
|
||||
{:id "rinkeby_rpc",
|
||||
:etherscan-link "https://rinkeby.etherscan.io/address/",
|
||||
:name "Rinkeby with upstream RPC",
|
||||
:config {:NetworkId (ethereum/chain-keyword->chain-id :rinkeby)
|
||||
:DataDir "/ethereum/rinkeby_rpc"
|
||||
:UpstreamConfig {:Enabled true
|
||||
:URL "https://rinkeby.infura.io/v3/f315575765b14720b32382a61a89341a"}}}
|
||||
{:id "goerli_rpc",
|
||||
:etherscan-link "https://goerli.etherscan.io/address/",
|
||||
:name "Goerli with upstream RPC",
|
||||
:config {:NetworkId (ethereum/chain-keyword->chain-id :goerli)
|
||||
:DataDir "/ethereum/goerli_rpc"
|
||||
|
@ -88,6 +92,12 @@
|
|||
(def default-networks
|
||||
(concat testnet-networks mainnet-networks sidechain-networks))
|
||||
|
||||
(def default-networks-by-id
|
||||
(into {}
|
||||
(map (fn [{:keys [id] :as network}]
|
||||
[id network])
|
||||
default-networks)))
|
||||
|
||||
(def default-multiaccount
|
||||
{:preview-privacy? config/blank-preview?
|
||||
:wallet/visible-tokens {:mainnet #{:SNT}}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
(update :timestamp decode/uint))}
|
||||
"eth_getTransactionByHash" {}
|
||||
"eth_getTransactionReceipt" {}
|
||||
"eth_getBlockByNumber" {}
|
||||
"eth_newBlockFilter" {:subscription? true}
|
||||
"eth_newFilter" {:subscription? true}
|
||||
"eth_syncing" {}
|
||||
|
@ -80,6 +81,9 @@
|
|||
"status_chats" {}
|
||||
"wallet_getTransfers" {}
|
||||
"wallet_getTokensBalances" {}
|
||||
"wallet_getBlocksByAddress" {}
|
||||
"wallet_getTransfersFromBlock" {}
|
||||
"wallet_getTransfersByAddress" {}
|
||||
"wallet_getCustomTokens" {}
|
||||
"wallet_addCustomToken" {}
|
||||
"wallet_deleteCustomToken" {}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns status-im.ethereum.subscriptions
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ethereum.eip55 :as eip55]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.ethereum.tokens :as tokens]
|
||||
|
@ -29,6 +30,9 @@
|
|||
chain (ethereum/chain-keyword db)
|
||||
chain-tokens (into {} (map (juxt :address identity)
|
||||
(tokens/tokens-for all-tokens chain)))]
|
||||
(log/debug "[wallet-subs] new-block"
|
||||
"accounts" accounts
|
||||
"block" block-number)
|
||||
(fx/merge cofx
|
||||
(cond-> {}
|
||||
(not historical?)
|
||||
|
@ -37,26 +41,63 @@
|
|||
;;NOTE only get transfers if the new block contains some
|
||||
;; from/to one of the multiaccount accounts
|
||||
(not-empty accounts)
|
||||
(assoc ::transactions/get-transfers {:chain-tokens chain-tokens
|
||||
:from-block block-number
|
||||
(assoc :transactions/get-transfers-from-block
|
||||
{:chain-tokens chain-tokens
|
||||
:addresses accounts
|
||||
:block block-number
|
||||
:historical? historical?}))
|
||||
(transactions/check-watched-transactions))))
|
||||
|
||||
(fx/defn reorg
|
||||
[{:keys [db] :as cofx} block-number accounts]
|
||||
[{:keys [db] :as cofx} {:keys [blockNumber accounts]}]
|
||||
(log/debug "[wallet-subs] reorg"
|
||||
"accounts" accounts
|
||||
"block-number" blockNumber)
|
||||
{:db (update-in db [:wallet :transactions]
|
||||
wallet/remove-transactions-since-block blockNumber)})
|
||||
|
||||
(fx/defn recent-history-fetching-started
|
||||
[{:keys [db]} accounts]
|
||||
(log/debug "[wallet-subs] recent-history-fetching-started"
|
||||
"accounts" accounts)
|
||||
{:db (transactions/update-fetching-status db accounts :recent? true)})
|
||||
|
||||
(fx/defn recent-history-fetching-ended
|
||||
[{:keys [db] :as cofx} {:keys [accounts blockNumber]}]
|
||||
(log/debug "[wallet-subs] recent-history-fetching-ended"
|
||||
"accounts" accounts
|
||||
"block" blockNumber)
|
||||
(let [{:keys [:wallet/all-tokens]} db
|
||||
chain (ethereum/chain-keyword db)
|
||||
chain-tokens (into {} (map (juxt :address identity)
|
||||
(tokens/tokens-for all-tokens chain)))]
|
||||
{:db (update-in db [:wallet :accounts]
|
||||
wallet/remove-transactions-since-block block-number)
|
||||
::transactions/get-transfers {:chain-tokens chain-tokens
|
||||
:from-block block-number}}))
|
||||
{:db (-> db
|
||||
(update-in [:wallet :accounts]
|
||||
wallet/remove-transactions-since-block blockNumber)
|
||||
(transactions/update-fetching-status accounts :recent? false))
|
||||
:transactions/get-transfers
|
||||
{:chain-tokens chain-tokens
|
||||
:addresses (reduce
|
||||
(fn [v address]
|
||||
(let [normalized-address
|
||||
(eip55/address->checksum address)]
|
||||
(if (contains? v normalized-address)
|
||||
v
|
||||
(conj v address))))
|
||||
[]
|
||||
accounts)
|
||||
:before-block blockNumber
|
||||
:page-size 20
|
||||
:historical? true}}))
|
||||
|
||||
(fx/defn new-wallet-event
|
||||
[{:keys [db] :as cofx} {:keys [type blockNumber accounts] :as event}]
|
||||
[cofx {:keys [type blockNumber accounts] :as event}]
|
||||
(log/debug "[wallet-subs] new-wallet-event"
|
||||
"event-type" type)
|
||||
(case type
|
||||
"newblock" (new-block cofx false blockNumber accounts)
|
||||
"history" (new-block cofx true blockNumber accounts)
|
||||
"reorg" (reorg cofx blockNumber accounts)
|
||||
"reorg" (reorg cofx event)
|
||||
"recent-history-fetching" (recent-history-fetching-started cofx accounts)
|
||||
"recent-history-ready" (recent-history-fetching-ended cofx event)
|
||||
(log/warn ::unknown-wallet-event :type type :event event)))
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
[status-im.ethereum.encode :as encode]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.ethereum.eip55 :as eip55]
|
||||
[status-im.ethereum.tokens :as tokens]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.utils.money :as money]
|
||||
[status-im.wallet.core :as wallet]))
|
||||
[status-im.wallet.core :as wallet]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def confirmations-count-threshold 12)
|
||||
|
||||
|
@ -130,10 +130,8 @@
|
|||
transaction can contain multiple transfers and they would overwrite each other
|
||||
in the transfer map if identified by hash"
|
||||
[{:keys [db] :as cofx} {:keys [hash id address] :as transfer}]
|
||||
(let [transfer-by-hash (get-in db [:wallet :accounts address :transactions hash])
|
||||
transfer-by-id (get-in db [:wallet :accounts address :transactions id])]
|
||||
(when-let [unique-id (when-not (or transfer-by-id
|
||||
(= transfer transfer-by-hash))
|
||||
(let [transfer-by-hash (get-in db [:wallet :accounts address :transactions hash])]
|
||||
(when-let [unique-id (when-not (= transfer transfer-by-hash)
|
||||
(if (and transfer-by-hash
|
||||
(not (= :pending
|
||||
(:type transfer-by-hash))))
|
||||
|
@ -144,32 +142,146 @@
|
|||
(assoc transfer :hash unique-id))}
|
||||
(check-transaction transfer)))))
|
||||
|
||||
(defn get-min-known-block [db address]
|
||||
(get-in db [:wallet :accounts (eip55/address->checksum address) :min-block]))
|
||||
|
||||
(fx/defn set-lowest-fetched-block
|
||||
[{:keys [db]} address transfers]
|
||||
(let [min-block (reduce
|
||||
(fn [min-block {:keys [block]}]
|
||||
(min (or min-block block) block))
|
||||
(get-min-known-block db address)
|
||||
transfers)]
|
||||
{:db (assoc-in
|
||||
db
|
||||
[:wallet :accounts (eip55/address->checksum address) :min-block]
|
||||
min-block)}))
|
||||
|
||||
(defn update-fetching-status
|
||||
[db addresses fetching-type state]
|
||||
(update-in
|
||||
db [:wallet :fetching]
|
||||
(fn [accounts]
|
||||
(reduce
|
||||
(fn [accounts address]
|
||||
(assoc-in accounts
|
||||
[(eip55/address->checksum address) fetching-type]
|
||||
state))
|
||||
accounts
|
||||
addresses))))
|
||||
|
||||
(fx/defn tx-fetching-in-progress
|
||||
[{:keys [db]} addresses]
|
||||
{:db (update-fetching-status db addresses :history? true)})
|
||||
|
||||
(fx/defn tx-fetching-ended
|
||||
[{:keys [db]} addresses]
|
||||
{:db (update-fetching-status db addresses :history? false)})
|
||||
|
||||
(fx/defn tx-history-end-reached
|
||||
[{:keys [db]} address]
|
||||
{:db (assoc-in db [:wallet :fetching address :all-fetched?] true)})
|
||||
|
||||
(fx/defn new-transfers
|
||||
{:events [::new-transfers]}
|
||||
[{:keys [db] :as cofx} transfers historical?]
|
||||
(let [effects (cond-> (map add-transfer transfers)
|
||||
;;NOTE: we only update the balance for new transfers and not historical ones
|
||||
(not historical?) (conj (wallet/update-balances (into [] (reduce (fn [acc {:keys [address]}]
|
||||
[{:keys [db] :as cofx} transfers {:keys [address historical? before-block]}]
|
||||
(let [min-block (get-in db [:wallet :accounts address :min-block])
|
||||
effects (cond-> [(when (seq transfers)
|
||||
(set-lowest-fetched-block address transfers))]
|
||||
|
||||
(seq transfers)
|
||||
(concat (mapv add-transfer transfers))
|
||||
;;NOTE: we only update the balance for new transfers and not
|
||||
;; historical ones
|
||||
(not historical?)
|
||||
(conj (wallet/update-balances
|
||||
(into [] (reduce (fn [acc {:keys [address]}]
|
||||
(conj acc address))
|
||||
#{}
|
||||
transfers)))))]
|
||||
(apply fx/merge cofx effects)))
|
||||
transfers))))
|
||||
|
||||
(and (= min-block before-block)
|
||||
(<= (count transfers) 1))
|
||||
(conj (tx-history-end-reached address)))]
|
||||
(apply fx/merge cofx (tx-fetching-ended [address]) effects)))
|
||||
|
||||
(fx/defn tx-fetching-failed
|
||||
{:events [::tx-fetching-failed]}
|
||||
[cofx error address]
|
||||
(log/debug "[transactions] tx-fetching-failed"
|
||||
"address" address
|
||||
"error" error)
|
||||
(tx-fetching-ended cofx [address]))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::get-transfers
|
||||
(fn [{:keys [chain-tokens from-block to-block historical?]
|
||||
:or {from-block "0"
|
||||
to-block nil}}]
|
||||
:transactions/get-transfers-from-block
|
||||
(fn [{:keys [chain-tokens addresses block] :as params}]
|
||||
(log/debug "[transactions] get-transfers-from-block"
|
||||
"addresses" addresses
|
||||
"block" block)
|
||||
(doseq [address addresses]
|
||||
(json-rpc/call
|
||||
{:method "wallet_getTransfers"
|
||||
:params [(encode/uint from-block) (encode/uint to-block)]
|
||||
:on-success #(re-frame/dispatch [::new-transfers (enrich-transfers chain-tokens %) historical?])})))
|
||||
{:method "wallet_getTransfersFromBlock"
|
||||
:params [address (encode/uint block)]
|
||||
:on-success #(re-frame/dispatch
|
||||
[::new-transfers
|
||||
(enrich-transfers chain-tokens %)
|
||||
(assoc params :address address)])
|
||||
:on-error #(re-frame/dispatch [::tx-fetching-failed % address])}))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:transactions/get-transfers
|
||||
(fn [{:keys [chain-tokens addresses before-block page-size]
|
||||
:as params
|
||||
:or {page-size 0}}]
|
||||
{:pre [(cljs.spec.alpha/valid?
|
||||
(cljs.spec.alpha/coll-of string?)
|
||||
addresses)]}
|
||||
(log/debug "[transactions] get-transfers"
|
||||
"addresses" addresses
|
||||
"block" before-block
|
||||
"page-size" page-size)
|
||||
(when before-block
|
||||
(doseq [address addresses]
|
||||
(json-rpc/call
|
||||
{:method "wallet_getTransfersByAddress"
|
||||
:params [address (encode/uint before-block) (encode/uint page-size)]
|
||||
:on-success #(re-frame/dispatch
|
||||
[::new-transfers
|
||||
(enrich-transfers chain-tokens %)
|
||||
(assoc params :address address)])
|
||||
:on-error #(re-frame/dispatch [::tx-fetching-failed address])})))))
|
||||
|
||||
(fx/defn initialize
|
||||
[{:keys [db] :as cofx}]
|
||||
[{:keys [db]} addresses]
|
||||
(let [{:keys [:wallet/all-tokens]} db
|
||||
chain (ethereum/chain-keyword db)
|
||||
chain-tokens (into {} (map (juxt :address identity)
|
||||
(tokens/tokens-for all-tokens chain)))]
|
||||
{::get-transfers {:chain-tokens chain-tokens
|
||||
{:transactions/get-transfers
|
||||
{:chain-tokens chain-tokens
|
||||
:addresses (map eip55/address->checksum addresses)
|
||||
:page-size 20
|
||||
:historical? true}}))
|
||||
|
||||
(fx/defn fetch-more-tx
|
||||
{:events [:transactions/fetch-more]}
|
||||
[{:keys [db] :as cofx} address]
|
||||
(let [all-tokens (:wallet/all-tokens db)
|
||||
chain (ethereum/chain-keyword db)
|
||||
chain-tokens (into
|
||||
{}
|
||||
(map (juxt :address identity)
|
||||
(tokens/tokens-for
|
||||
all-tokens chain)))
|
||||
min-known-block (or (get-min-known-block db address)
|
||||
(:ethereum/current-block db))]
|
||||
(fx/merge
|
||||
cofx
|
||||
{:transactions/get-transfers
|
||||
{:chain-tokens chain-tokens
|
||||
:addresses [address]
|
||||
:before-block min-known-block
|
||||
:page-size 20
|
||||
:historical? true}}
|
||||
(tx-fetching-in-progress [address]))))
|
||||
|
|
|
@ -89,7 +89,10 @@
|
|||
(wallet/initialize-tokens custom-tokens)
|
||||
(wallet/update-balances nil)
|
||||
(wallet/update-prices)
|
||||
(transactions/initialize)))
|
||||
(transactions/initialize
|
||||
(->> accounts
|
||||
(filter :wallet)
|
||||
(map :address)))))
|
||||
|
||||
(fx/defn login
|
||||
{:events [:multiaccounts.login.ui/password-input-submitted]}
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
[status-im.utils.config :as config]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.utils.platform :as utils.platform]
|
||||
[status-im.utils.types :as types])
|
||||
[status-im.utils.types :as types]
|
||||
[taoensso.timbre :as log])
|
||||
(:require-macros [status-im.utils.slurp :refer [slurp]]))
|
||||
|
||||
(defn- add-custom-bootnodes [config network all-bootnodes]
|
||||
|
|
|
@ -1174,6 +1174,33 @@
|
|||
(let [vt-set (set visible-tokens)]
|
||||
(group-by :custom? (map #(assoc % :checked? (boolean (get vt-set (keyword (:symbol %))))) all-tokens)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/fetching-tx-history?
|
||||
:<- [:wallet]
|
||||
(fn [wallet [_ address]]
|
||||
(get-in wallet [:fetching address :history?])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/fetching-recent-tx-history?
|
||||
:<- [:wallet]
|
||||
(fn [wallet [_ address]]
|
||||
(get-in wallet [:fetching address :recent?])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/tx-history-fetched?
|
||||
:<- [:wallet]
|
||||
(fn [wallet [_ address]]
|
||||
(get-in wallet [:fetching address :all-fetched?])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/etherscan-link
|
||||
(fn [db [_ address]]
|
||||
(let [network (:networks/current-network db)
|
||||
link (get-in constants/default-networks-by-id
|
||||
[network :etherscan-link])]
|
||||
(when link
|
||||
(str link address)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/error-message
|
||||
:<- [:wallet]
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
(views/defview transactions [address]
|
||||
(views/letsubs [{:keys [transaction-history-sections]}
|
||||
[:wallet.transactions.history/screen address]]
|
||||
[history/history-list transaction-history-sections]))
|
||||
[history/history-list transaction-history-sections address]))
|
||||
|
||||
(views/defview assets-and-collections [address]
|
||||
(views/letsubs [{:keys [tokens nfts]} [:wallet/visible-assets-with-values address]
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.styles :as components.styles]
|
||||
[status-im.ui.components.toolbar.actions :as actions]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
|
@ -71,16 +72,71 @@
|
|||
:icon-opts (merge styles/forward
|
||||
{:accessibility-label :show-transaction-button})}]]]])
|
||||
|
||||
(defn etherscan-link [address]
|
||||
(let [link @(re-frame/subscribe [:wallet/etherscan-link address])]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(when link
|
||||
(.openURL react/linking link))}
|
||||
[react/view
|
||||
{:style {:flex 1
|
||||
:padding-horizontal 14
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:background-color colors/blue-light
|
||||
:height 52}}
|
||||
[vector-icons/tiny-icon
|
||||
:tiny-icons/tiny-external
|
||||
{:color colors/blue
|
||||
:container-style {:margin-right 5}}]
|
||||
[react/text
|
||||
{:style {:marging-left 10
|
||||
:color colors/blue}}
|
||||
(i18n/label :t/check-on-etherscan)]]]))
|
||||
|
||||
(defn history-list
|
||||
[transactions-history-sections]
|
||||
[transactions-history-sections address]
|
||||
(let [fetching-recent-history? @(re-frame/subscribe [:wallet/fetching-recent-tx-history? address])
|
||||
fetching-more-history? @(re-frame/subscribe [:wallet/fetching-tx-history? address])
|
||||
all-fetched? @(re-frame/subscribe [:wallet/tx-history-fetched? address])]
|
||||
[react/view components.styles/flex
|
||||
[list/section-list {:sections transactions-history-sections
|
||||
[etherscan-link address]
|
||||
(when fetching-recent-history?
|
||||
[react/view
|
||||
{:style {:flex 1
|
||||
:height 40
|
||||
:margin-vertical 16}}
|
||||
[react/activity-indicator {:size :large
|
||||
:animating true}]])
|
||||
[list/section-list
|
||||
{:sections transactions-history-sections
|
||||
:key-fn :hash
|
||||
:render-fn #(render-transaction %)
|
||||
:empty-component
|
||||
[react/i18n-text {:style styles/empty-text
|
||||
:key :transactions-history-empty}]
|
||||
:refreshing false}]])
|
||||
:refreshing false}]
|
||||
(when (and (not fetching-recent-history?)
|
||||
(not all-fetched?))
|
||||
(if fetching-more-history?
|
||||
[react/view
|
||||
{:style {:flex 1
|
||||
:height 40
|
||||
:margin-vertical 8}}
|
||||
[react/activity-indicator {:size :large
|
||||
:animating true}]]
|
||||
[react/view
|
||||
{:style {:flex 1
|
||||
:padding-horizontal 14
|
||||
:height 52
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:background-color colors/blue-light}}
|
||||
[react/text
|
||||
{:style {:color colors/blue}
|
||||
:on-press (when-not fetching-more-history?
|
||||
#(re-frame/dispatch
|
||||
[:transactions/fetch-more address]))}
|
||||
(i18n/label :t/transactions-load-more)]]))]))
|
||||
|
||||
(defn- render-item-filter [{:keys [id label checked? on-touch]}]
|
||||
[react/view {:accessibility-label :filter-item}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.39.11",
|
||||
"commit-sha1": "a4f88d001768d2934f1ddbd75d757c52e823accb",
|
||||
"src-sha256": "0vai6sdcf930r7zp2pmr3b5b2402xmvxn8087lfb34q4hwgscw3j"
|
||||
"version": "v0.40.0",
|
||||
"commit-sha1": "dc31c818fce6dbff6cfd76da09d901b0df742e2e",
|
||||
"src-sha256": "1f0fp5c4lqnh244wcvbnl5i4p9fb0f3i0rjjvbiqwkz9zwwp3xlv"
|
||||
}
|
||||
|
|
|
@ -1160,5 +1160,7 @@
|
|||
"delete-account": "Delete account",
|
||||
"watch-only": "Watch-only",
|
||||
"cant-report-bug": "Can't report a bug",
|
||||
"mail-should-be-configured": "Mail client should be configured"
|
||||
"mail-should-be-configured": "Mail client should be configured",
|
||||
"check-on-etherscan": "Check on etherscan",
|
||||
"transactions-load-more": "Load more"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue