/
EtherUnit.purs
148 lines (110 loc) · 3.81 KB
/
EtherUnit.purs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
module Network.Ethereum.Web3.Types.EtherUnit
( class EtherUnit, fromWei, toWei
, class EtherUnitSpec
, divider
, name
, convert
, Wei
, Babbage
, Lovelace
, Shannon
, Szabo
, Finney
, Ether
, KEther
, Value
, NoPay
, mkValue
) where
import Prelude
import Data.Foreign.Class (class Decode, class Encode, encode)
import Data.Maybe (fromJust)
import Data.Module (class LeftModule, (^*))
import Data.Monoid (class Monoid)
import Network.Ethereum.Web3.Types.BigNumber (BigNumber, decimal, floorBigNumber, parseBigNumber)
import Partial.Unsafe (unsafePartial)
import Type.Proxy (Proxy(..))
-- | Ether value in denomination `a`
newtype Value a = Value BigNumber
derive newtype instance eqValue :: Eq (Value a)
derive newtype instance showValue :: Show (Value a)
derive newtype instance encodeValue :: Encode (Value a)
instance encodeNoPay :: Encode (Value NoPay) where
encode _ = encode (Value zero)
derive newtype instance decodeValue :: Decode (Value a)
unValue :: forall a . Value a -> BigNumber
unValue (Value a) = a
-- | Useful for converting to and from the base denomination `Wei`
class EtherUnit a where
fromWei :: BigNumber -> a
toWei :: a -> BigNumber
-- | Convert between two denominations
convert :: forall a b . EtherUnit a => EtherUnit b => a -> b
convert = fromWei <<< toWei
class EtherUnitSpec a where
divider :: Proxy a -> BigNumber
name :: Proxy a -> String
-- | Convert a big number into value, first using `floor` function to take the integer part
mkValue :: forall a . EtherUnitSpec a => BigNumber -> Value a
mkValue = modify res <<< floorBigNumber <<< (mul (divider res))
where res :: EtherUnitSpec a => Proxy a
res = Proxy
modify :: Proxy a -> BigNumber -> Value a
modify _ = Value
instance unitEtherUnitSpec :: EtherUnitSpec a => EtherUnit (Value a) where
fromWei = Value
toWei = unValue
instance semigroupEtherUnitSpec :: EtherUnitSpec a => Semigroup (Value a) where
append a b = Value (unValue a `add` unValue b)
instance monoidEtherUnitSpec :: EtherUnitSpec a => Monoid (Value a) where
mempty = mkValue zero
instance modukeEtherUnitSpec :: EtherUnitSpec a => LeftModule (Value a) Int where
mzeroL = mkValue zero
maddL (Value a) (Value b) = Value $ a + b
msubL (Value a) (Value b) = Value $ a - b
mmulL a (Value b) = Value $ a ^* b
data Wei
instance unitSpecWei :: EtherUnitSpec Wei where
divider = const $ unsafeConvert "1"
name = const "wei"
-- | Babbage unit type
data Babbage
instance unitSpecB :: EtherUnitSpec Babbage where
divider = const $ unsafeConvert "1000"
name = const "babbage"
-- | Lovelace unit type
data Lovelace
instance unitSpecL :: EtherUnitSpec Lovelace where
divider = const $ unsafeConvert "1000000"
name = const "lovelace"
-- | Shannon unit type
data Shannon
instance unitSpecS :: EtherUnitSpec Shannon where
divider = const $ unsafeConvert "1000000000"
name = const "shannon"
-- | Szabo unit type
data Szabo
instance unitSpecSz :: EtherUnitSpec Szabo where
divider = const $ unsafeConvert "1000000000000"
name = const "szabo"
-- | Finney unit type
data Finney
instance unitSpecF :: EtherUnitSpec Finney where
divider = const $ unsafeConvert "1000000000000000"
name = const "finney"
-- | Ether unit type
data Ether
instance unitSpecE :: EtherUnitSpec Ether where
divider = const $ unsafeConvert "1000000000000000000"
name = const "ether"
-- | KEther unit type
data KEther
instance unitSpecKE :: EtherUnitSpec KEther where
divider = const $ unsafeConvert $ "1000000000000000000000"
name = const "kether"
data NoPay
instance unitSpecNoPay :: EtherUnitSpec NoPay where
divider = const $ zero
name = const "nopay"
unsafeConvert :: String -> BigNumber
unsafeConvert a = unsafePartial fromJust <<< parseBigNumber decimal $ a