Support various currency units

parent c63e730c
Pipeline #29302290 passed with stages
in 3 minutes and 4 seconds
......@@ -6,7 +6,7 @@
<link href="css/site.css" rel="stylesheet" type="text/css">
<title>Ercoin wallet</title>
</head>
<body>
<body lang="en">
<div>
<p>This is a simple in-browser wallet for <a href="http://ercoin.tech">Ercoin</a>. You use it at your own risk. Its <a href="https://gitlab.com/Ercoin/ercoin-browser-wallet">source code</a> is available.</p>
</div>
......
......@@ -4,12 +4,9 @@
[alphabase.base58 :as base58]
[alphabase.hex :as hex]
[ercoin-wallet.uint :as uint]
[ercoin-wallet.converter :refer [Converter]]
[goog.crypt.base64 :as base64]))
(defprotocol Converter
(encode [this from])
(decode [this from]))
(defrecord BinaryConverter [name key encoder decoder]
Converter
(encode [this vect] (encoder (or vect [])))
......
(ns ercoin-wallet.converter)
(defprotocol Converter
(encode [this from])
(decode [this from]))
......@@ -8,9 +8,11 @@
[cljsjs.nacl-fast]
[ercoin-wallet.account :as a]
[ercoin-wallet.binary :as binary]
[ercoin-wallet.converter :as converter]
[ercoin-wallet.tendermint :as tendermint]
[ercoin-wallet.tx :as tx]
[ercoin-wallet.uint :as uint]))
[ercoin-wallet.uint :as uint]
[ercoin-wallet.units :as units]))
;; State
......@@ -20,6 +22,8 @@
(local-storage (r/atom "http://localhost:26657") :rpc-endpoint))
(defonce binary-encoding
(local-storage (r/atom :base58) :binary-encoding))
(defonce unit
(local-storage (r/atom :ercoin) :unit))
;; Tendermint communication
......@@ -47,13 +51,19 @@
(doseq [account (vals @accounts)]
(refresh-account! account)))
;; Binary encoding
;; Converters
(defn binary-decode [string]
(binary/decode (binary/get-converter @binary-encoding) string))
(converter/decode (binary/get-converter @binary-encoding) string))
(defn binary-encode [vect]
(binary/encode (binary/get-converter @binary-encoding) vect))
(converter/encode (binary/get-converter @binary-encoding) vect))
(defn unit-encode [value]
(converter/encode (units/get-unit @unit) value))
(defn unit-decode [value-str]
(converter/decode (units/get-unit @unit) value-str))
;; Views
......@@ -91,7 +101,7 @@
[:td
(when private-key
[hidden-key private-key])]
[:td balance]
[:td (unit-encode balance)]
[:td valid-until]
[:td locked-until]
[:td
......@@ -142,6 +152,18 @@
:value key}
name])]])
(defn unit-field []
[:p
"Unit: "
[:select
{:defaultValue @unit}
(for [{:keys [:name :key]} units/all]
^{:key key}
[:option
{:on-click #(reset! unit key)
:value key}
name])]])
(defn accounts-refresh-button []
[:p
[:input {:type :button
......@@ -160,6 +182,19 @@
{:on-click #(reset! account-atom account)}
(::a/label account)]))]])
(defn amount-field [amount-atom]
(let [{:keys [:resolution :symbol]} (units/get-unit @unit)]
[:p
[:label "Amount"]
[:input {:type :number
:value (unit-encode @amount-atom)
:min 0
:step (if (= 0 resolution)
1
(apply str (concat "0." (repeat (- resolution 1) 0) "1")))
:on-change #(reset! amount-atom (-> % .-target .-value (unit-decode)))}]
" " symbol]))
(defn auto-valid-since [valid-since-atom]
(go
(let [current-height (<! (tendermint/height @rpc-endpoint))]
......@@ -205,11 +240,7 @@
[:div
(account-select "From" from)
(account-select "To" to)
[:p
[:label "Amount"]
[:input {:type :number
:value @amount
:on-change #(reset! amount (-> % .-target .-value (js/parseInt)))}]]
(amount-field amount)
[:p
[:label "Message"]
[:input {:type :text
......@@ -363,7 +394,9 @@
[:div
[:section [:h2 "Configuration"]
[rpc-endpoint-field]
[binary-encoding-field]]
[binary-encoding-field]
[unit-field]
]
[:section [:h2 "Accounts"]
[accounts-refresh-button]
[:p [:kbd "Double click"] " label to edit, " [:kbd "Enter"] " or " [:kbd "Esc"] " to finish editing."]
......
(ns ercoin-wallet.units
(:require
[clojure.string :as string]
[ercoin-wallet.converter :refer [Converter]]
))
(defrecord Unit [name key symbol resolution]
Converter
(encode [this value]
(let [divider (js/Math.pow 10 resolution)
integer-part (quot value divider)
fractional-part (rem value divider)]
(if (> fractional-part 0)
(let [fractional-str-raw (str fractional-part)]
(str
integer-part
"."
(apply str (repeat (- resolution (count fractional-str-raw)) 0))
(string/replace fractional-str-raw #"0+$" "")))
(str integer-part))))
(decode [this value-str]
(let [[integer-str fractional-str] (string/split value-str ".")
integer-part (* (js/parseInt integer-str) (js/Math.pow 10 resolution))]
(if fractional-str
(+ integer-part
(* (js/parseInt fractional-str) (js/Math.pow 10 (- resolution (count fractional-str)))))
integer-part))))
(def ercoin (Unit. "ercoin" :ercoin "ERN" 9))
(def deciercoin (Unit. "deciercoin" :deciercoin "dERN" 8))
(def centiercoin (Unit. "centiercoin" :centiercoin "cERN" 7))
(def miliercoin (Unit. "miliercoin" :miliercoin "mERN" 6))
(def microercoin (Unit. "microercoin" :microercoin "µERN" 3))
(def nanoercoin (Unit. "nanoercoin" :nanoercoin "nERN" 0))
(def kiloercoin (Unit. "kiloercoin" :kiloercoin "kERN" 12))
(def megaercoin (Unit. "megaercoin" :megaercoin "MERN" 15))
(def all (list
ercoin
deciercoin
centiercoin
miliercoin
microercoin
nanoercoin
kiloercoin
megaercoin
))
(def all-map
(into {} (map (fn [unit] [(:key unit) unit]) all)))
(defn get-unit [key]
(get all-map key))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment