-
Notifications
You must be signed in to change notification settings - Fork 2
/
money.go
86 lines (73 loc) · 2.17 KB
/
money.go
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
package newop
import (
"fmt"
"log"
"github.com/btcsuite/btcutil"
"github.com/shopspring/decimal"
)
// MonetaryAmount holds an amount of money in a certain currency
type MonetaryAmount struct {
Value decimal.Decimal
Currency string
}
func NewMonetaryAmountFromSatoshis(value int64) *MonetaryAmount {
v := decimal.NewFromInt(value).Div(decimal.NewFromInt(100_000_000))
return &MonetaryAmount{
Value: v,
Currency: "BTC",
}
}
func NewMonetaryAmountFromFiat(value string, currency string) *MonetaryAmount {
v, err := decimal.NewFromString(value)
if err != nil {
log.Printf("could not initialize monetary amount: %v", err)
return nil
}
return &MonetaryAmount{
Value: v,
Currency: currency,
}
}
func (m *MonetaryAmount) ValueAsString() string {
return m.Value.String()
}
func (m *MonetaryAmount) String() string {
return fmt.Sprintf("%v %v", m.Value, m.Currency) // TODO(newop): this is just a stub implementation
}
func (m *MonetaryAmount) toBtc(window *ExchangeRateWindow) btcutil.Amount {
rate := window.Rate(m.Currency)
v := m.Value.Div(decimal.NewFromFloat(rate)).Mul(decimal.NewFromInt(100_000_000))
v = v.RoundBank(0)
return btcutil.Amount(v.IntPart())
}
func (m *MonetaryAmount) add(n *MonetaryAmount) *MonetaryAmount {
if m.Currency != n.Currency {
panic("currencies do not match") // TODO(newop): replace panic and bubble up errors?
}
return &MonetaryAmount{
Value: m.Value.Add(n.Value),
Currency: m.Currency,
}
}
func (m *MonetaryAmount) toBitcoinAmount(window *ExchangeRateWindow, primaryCurrency string) *BitcoinAmount {
return &BitcoinAmount{
InSat: int64(m.toBtc(window)),
InInputCurrency: m,
InPrimaryCurrency: window.convert(m, primaryCurrency),
}
}
type BitcoinAmount struct {
InSat int64
InPrimaryCurrency *MonetaryAmount
InInputCurrency *MonetaryAmount
}
func (a *BitcoinAmount) toBtc() btcutil.Amount {
return btcutil.Amount(a.InSat)
}
func (a *BitcoinAmount) add(b *BitcoinAmount) *BitcoinAmount {
return &BitcoinAmount{
InSat: a.InSat + b.InSat,
InInputCurrency: a.InInputCurrency.add(b.InInputCurrency),
InPrimaryCurrency: a.InPrimaryCurrency.add(b.InPrimaryCurrency),
}
}