Skip to content
This repository has been archived by the owner on Dec 12, 2022. It is now read-only.

district0x/district-ui-web3-balances

Repository files navigation

district-ui-web3-balances

Build Status

Clojurescript re-mount module, that handles web3 balances of Ether or other ERC20 tokens.

Installation

Add Clojars Project into your project.clj
Include [district.ui.web3-balances] in your CLJS file, where you use mount/start

API Overview

Warning: district0x modules are still in early stages, therefore API can change in a future.

district.ui.web3-balances

This namespace contains web3-balances mount module.

You can pass following args to initiate this module:

  • :contracts (optional) Map of contracts with their addresses, so you can later refer to them in subscriptions and queries by human-readable key
  (ns my-district.core
    (:require [mount.core :as mount]
              [district.ui.web3-balances]))

  (-> (mount/with-args
        {:web3 {:url "https://mainnet.infura.io/"}
         :web3-balances {:contracts {:GNT {:address "0xa74476443119A942dE498590Fe1f2454d7D4aC0d"}
                                     :ICN {:address "0x888666CA69E0f178DED6D75b5726Cee99A87D698"}
                                     :DNT {:address "0x0abdace70d3790235af448c88547603b945604ea"}}}})
    (mount/start))

Notice format of :contracts map is the same as :contracts passed to district-ui-smart-contracts, so you can conveniently pass the same value to both, if you use both modules.

district.ui.web3-balances.subs

re-frame subscriptions provided by this module:

Returns all balances.

Returns balance of an address. Optionally, you can pass contract to get balance of an ERC20 token. Contract param can be in 3 different forms:

  • Contract key as defined in :contracts you passed to the module
  • Contract address
  • Contract instance
  • Additionally, if you use keyword :ETH, if will refer to Ether
(ns my-district.core
    (:require [mount.core :as mount]
              [district.ui.web3-balances.subs :as balances-subs]
              [cljs-web3-next.core :as web3]))
  
  (defn home-page []
    (let [addr "0x0000000000000000000000000000000000000000"
          balance-eth (subscribe [::balances-subs/balance addr])
          balance-gnt (subscribe [::balances-subs/balance addr :GNT])
          balance-icn (subscribe [::balances-subs/balance addr "0x888666CA69E0f178DED6D75b5726Cee99A87D698"])
          balance-dnt (subscribe [::balances-subs/balance addr DNTInstance])] ;; def of DNTInstance is skipped  
      (fn []
        [:div "Address " addr " has following balances:"]
        [:div (web3/from-wei @balance-eth :ether) " ETH"]
        [:div (web3/from-wei @balance-gnt :ether) " GNT"]
        [:div (web3/from-wei @balance-icn :ether) " ICN"]
        [:div (web3/from-wei @balance-dnt :ether) " DNT"])))

Returns map of contracts as passed into module at start

Returns address of a contract by its key

district.ui.web3-balances.events

re-frame events provided by this module:

Loads collection of balances. To each item, you can pass :watch? true to keep watching balance for changes. Also, you can optionally pass :contract in same 3 different forms as you'd pass into subscription ::balance.

(let [addr "0x0000000000000000000000000000000000000000"]
    (dispatch [::events/load-balances
               [{:address addr :watch? true}
                {:address addr :contract :GNT}
                {:address addr :contract "0x0abdace70d3790235af448c88547603b945604ea"}
                {:address addr :contract ICNInstance :watch? true}]]))

Sets a balance into re-frame db. Format of item is same as for ::load-balances. You can use this event to hook into event flow, to be notified when a balance was loaded.

Fired when there was an error loading a balance.

Use to stop watching balances. Format of items is same as for ::load-balances.

Stops watching all balances watched by this module.

district.ui.web3-balances.queries

DB queries provided by this module:
You should use them in your events, instead of trying to get this module's data directly with get-in into re-frame db.

Works the same way as sub ::balances

Works the same way as sub ::balance

(ns my-district.events
    (:require [district.ui.web3-balances.queries :as balances-queries]
              [re-frame.core :refer [reg-event-fx]]))

(reg-event-fx
  ::my-event
  (fn [{:keys [:db]}]
    (if (.gt (balances-queries/balance db "0x0000000000000000000000000000000000000000" :DNT) 0)
      {:dispatch [::has-some-dnt]}
      {:dispatch [::has-no-dnt]})))

assoc-balance [db address contract balance]

Associates balance and returns new re-frame db.

Merges balances into existing ones and returns new re-frame db.

Returns all contracts

Returns contract address by key.

Merges contracts into existing ones and returns new re-frame db.

Returns ids of currently watched balances

Concats new watch-ids with existing ones and returns new re-frame db.

Merges balances, contracts and watch-ids into this module.

Dependency on other district UI modules

Development

  1. Setup local testnet
  • spin up a testnet instance in a separate shell

    • npx truffle develop
  • migrate contracts in test/ folder

    • (cd test; npx truffle migrate --network ganache --reset)
  1. Run test suite:
  • Browser
    • npx shadow-cljs watch test-browser
    • open https://d0x-vm:6502
    • tests refresh automatically on code change
  • CI (Headless Chrome, Karma)
    • npx shadow-cljs compile test-ci
    • CHROME_BIN=`which chromium-browser` npx karma start karma.conf.js --single-run
  1. Build
  • on merging pull request to master on GitHub, CI builds & publishes new version automatically
  • update version in build.clj
  • to build: clj -T:build jar
  • to release: clj -T:build deploy (needs CLOJARS_USERNAME and CLOJARS_PASSWORD env vars to be set)