Skip to content

Commit 9ae91a3

Browse files
committed
Merge branch 'sats_mode_update'
2 parents 5786ce1 + 38411ca commit 9ae91a3

File tree

15 files changed

+55
-64
lines changed

15 files changed

+55
-64
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- Use mempool.space as preferred fee estimation source for BTC
1212
- Fix Wallet Connect issue where account unspecified by the connecting dapp caused a UI crash
1313
- Fix Wallet Connect issue with required/optionalNamespace and handling all possible namespace definitions
14+
- Add Satoshi as an option in active currencies
1415

1516
## 4.42.0
1617
- Preselect backup when there's only one backup available

backend/accounts.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,11 @@ import (
2828
accountsTypes "github.com/BitBoxSwiss/bitbox-wallet-app/backend/accounts/types"
2929
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/bitsurance"
3030
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc"
31-
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/util"
3231
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/coin"
3332
coinpkg "github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/coin"
3433
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/eth"
3534
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/config"
3635
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/keystore"
37-
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/rates"
3836
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/signing"
3937
"github.com/BitBoxSwiss/bitbox-wallet-app/util/errp"
4038
"github.com/BitBoxSwiss/bitbox-wallet-app/util/observable"
@@ -234,7 +232,6 @@ func (backend *Backend) accountFiatBalance(account accounts.Interface, fiat stri
234232
}
235233

236234
coinDecimals := coin.DecimalsExp(account.Coin())
237-
238235
price, err := backend.RatesUpdater().LatestPriceForPair(account.Coin().Unit(false), fiat)
239236
if err != nil {
240237
return nil, err
@@ -253,13 +250,6 @@ func (backend *Backend) accountFiatBalance(account accounts.Interface, fiat stri
253250
func (backend *Backend) AccountsTotalBalanceByKeystore() (map[string]KeystoreTotalAmount, error) {
254251
totalAmounts := make(map[string]KeystoreTotalAmount)
255252
fiat := backend.Config().AppConfig().Backend.MainFiat
256-
isFiatBtc := fiat == rates.BTC.String()
257-
fiatUnit := fiat
258-
if isFiatBtc && backend.Config().AppConfig().Backend.BtcUnit == coinpkg.BtcUnitSats {
259-
fiatUnit = "sat"
260-
}
261-
262-
formatBtcAsSat := util.FormatBtcAsSat(backend.Config().AppConfig().Backend.BtcUnit)
263253

264254
accountsByKeystore, err := backend.AccountsByKeystore()
265255
if err != nil {
@@ -286,8 +276,8 @@ func (backend *Backend) AccountsTotalBalanceByKeystore() (map[string]KeystoreTot
286276
currentTotal.Add(currentTotal, fiatValue)
287277
}
288278
totalAmounts[rootFingerprint] = KeystoreTotalAmount{
289-
FiatUnit: fiatUnit,
290-
Total: coinpkg.FormatAsCurrency(currentTotal, isFiatBtc, formatBtcAsSat),
279+
FiatUnit: fiat,
280+
Total: coinpkg.FormatAsCurrency(currentTotal, fiat),
291281
}
292282
}
293283
return totalAmounts, nil

backend/bitsurance/bitsurance.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/accounts"
2424
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/accounts/types"
2525
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/coin"
26+
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/rates"
2627
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/signing"
2728
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/util"
2829
"github.com/BitBoxSwiss/bitbox-wallet-app/util/errp"
@@ -86,7 +87,7 @@ func bitsuranceCheckId(devServer bool, httpClient *http.Client, accountId string
8687
return account, err
8788
}
8889
ratAmount := new(big.Rat).SetInt64(int64(account.Details.MaxCoverage))
89-
account.Details.MaxCoverageFormatted = coin.FormatAsCurrency(ratAmount, false, false)
90+
account.Details.MaxCoverageFormatted = coin.FormatAsCurrency(ratAmount, rates.EUR.String())
9091
return account, nil
9192
}
9293

backend/chart.go

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ import (
2121

2222
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/accounts"
2323
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/accounts/errors"
24-
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/util"
2524
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/coin"
26-
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/rates"
2725
"github.com/BitBoxSwiss/bitbox-wallet-app/util/errp"
2826
)
2927

@@ -120,7 +118,6 @@ func (backend *Backend) ChartData() (*Chart, error) {
120118
chartEntriesHourly := map[int64]RatChartEntry{}
121119

122120
fiat := backend.Config().AppConfig().Backend.MainFiat
123-
isFiatBtc := fiat == rates.BTC.String()
124121

125122
// Chart data until this point in time.
126123
until := backend.RatesUpdater().HistoryLatestTimestampAll(backend.allCoinCodes(), fiat)
@@ -131,8 +128,6 @@ func (backend *Backend) ChartData() (*Chart, error) {
131128
isUpToDate := time.Since(until) < 2*time.Hour
132129
lastTimestamp := until.UnixMilli()
133130

134-
formatBtcAsSat := util.FormatBtcAsSat(backend.Config().AppConfig().Backend.BtcUnit)
135-
136131
currentTotal := new(big.Rat)
137132
currentTotalMissing := false
138133
// Total number of transactions across all active accounts.
@@ -245,7 +240,7 @@ func (backend *Backend) ChartData() (*Chart, error) {
245240
result[i] = ChartEntry{
246241
Time: entry.Time,
247242
Value: floatValue,
248-
FormattedValue: coin.FormatAsCurrency(entry.RatValue, fiat == rates.BTC.String(), formatBtcAsSat),
243+
FormattedValue: coin.FormatAsCurrency(entry.RatValue, fiat),
249244
}
250245
i++
251246
}
@@ -261,7 +256,7 @@ func (backend *Backend) ChartData() (*Chart, error) {
261256
result = append(result, ChartEntry{
262257
Time: time.Now().Unix(),
263258
Value: total,
264-
FormattedValue: coin.FormatAsCurrency(currentTotal, isFiatBtc, formatBtcAsSat),
259+
FormattedValue: coin.FormatAsCurrency(currentTotal, fiat),
265260
})
266261
}
267262
// Truncate leading zeroes, if there are any keep the first one to start the chart with 0
@@ -285,23 +280,18 @@ func (backend *Backend) ChartData() (*Chart, error) {
285280
chartDataMissing = false
286281
}
287282

288-
chartFiat := fiat
289-
if isFiatBtc && backend.Config().AppConfig().Backend.BtcUnit == coin.BtcUnitSats {
290-
chartFiat = "sat"
291-
}
292-
293283
var chartTotal *float64
294284
var formattedChartTotal string
295285
if !currentTotalMissing {
296286
tot, _ := currentTotal.Float64()
297287
chartTotal = &tot
298-
formattedChartTotal = coin.FormatAsCurrency(currentTotal, isFiatBtc, formatBtcAsSat)
288+
formattedChartTotal = coin.FormatAsCurrency(currentTotal, fiat)
299289
}
300290
return &Chart{
301291
DataMissing: chartDataMissing,
302292
DataDaily: toSortedSlice(chartEntriesDaily, fiat),
303293
DataHourly: toSortedSlice(chartEntriesHourly, fiat),
304-
Fiat: chartFiat,
294+
Fiat: fiat,
305295
Total: chartTotal,
306296
FormattedTotal: formattedChartTotal,
307297
IsUpToDate: isUpToDate,

backend/coins/coin/conversions.go

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,22 @@ func Btc2Sat(amount *big.Rat) *big.Rat {
2323

2424
// FormatAsPlainCurrency handles formatting for currencies in a simplified way.
2525
// This should be used when `FormatAsCurrency` can't be used because a simpler formatting is needed (e.g. to populate forms in the frontend).
26-
func FormatAsPlainCurrency(amount *big.Rat, isBtc bool, formatBtcAsSats bool) string {
26+
func FormatAsPlainCurrency(amount *big.Rat, currency string) string {
2727
var formatted string
28-
if isBtc {
29-
if formatBtcAsSats {
30-
amount = Btc2Sat(amount)
31-
formatted = amount.FloatString(0)
32-
} else {
33-
formatted = amount.FloatString(8)
34-
}
35-
} else {
28+
switch currency {
29+
case ratesPkg.BTC.String():
30+
formatted = amount.FloatString(8)
31+
case ratesPkg.SAT.String():
32+
formatted = amount.FloatString(0)
33+
default:
3634
formatted = amount.FloatString(2)
3735
}
3836
return formatted
3937
}
4038

4139
// FormatAsCurrency handles formatting for currencies.
42-
func FormatAsCurrency(amount *big.Rat, isBtc bool, formatBtcAsSats bool) string {
43-
formatted := FormatAsPlainCurrency(amount, isBtc, formatBtcAsSats)
40+
func FormatAsCurrency(amount *big.Rat, currency string) string {
41+
formatted := FormatAsPlainCurrency(amount, currency)
4442
position := strings.Index(formatted, ".") - 3
4543
for position > 0 {
4644
formatted = formatted[:position] + "'" + formatted[position:]
@@ -59,7 +57,7 @@ func Conversions(amount Amount, coin Coin, isFee bool, ratesUpdater *ratesPkg.Ra
5957
conversions = map[string]string{}
6058
for key, value := range rates[unit] {
6159
convertedAmount := new(big.Rat).Mul(new(big.Rat).SetFloat64(coin.ToUnit(amount, isFee)), new(big.Rat).SetFloat64(value))
62-
conversions[key] = FormatAsCurrency(convertedAmount, key == ratesPkg.BTC.String(), formatBtcAsSats)
60+
conversions[key] = FormatAsCurrency(convertedAmount, key)
6361
}
6462
}
6563
return conversions
@@ -77,7 +75,7 @@ func ConversionsAtTime(amount Amount, coin Coin, isFee bool, ratesUpdater *rates
7775
conversions[currency] = ""
7876
} else {
7977
convertedAmount := new(big.Rat).Mul(new(big.Rat).SetFloat64(coin.ToUnit(amount, isFee)), new(big.Rat).SetFloat64(value))
80-
conversions[currency] = FormatAsCurrency(convertedAmount, currency == ratesPkg.BTC.String(), formatBtcAsSats)
78+
conversions[currency] = FormatAsCurrency(convertedAmount, currency)
8179
}
8280
}
8381
}

backend/handlers/handlers.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,6 @@ func (handlers *Handlers) getConvertToPlainFiat(r *http.Request) interface{} {
955955
coinCode := r.URL.Query().Get("from")
956956
currency := r.URL.Query().Get("to")
957957
amount := r.URL.Query().Get("amount")
958-
959958
currentCoin, err := handlers.backend.Coin(coinpkg.Code(coinCode))
960959
if err != nil {
961960
handlers.log.WithError(err).Error("Could not get coin " + coinCode)
@@ -979,10 +978,9 @@ func (handlers *Handlers) getConvertToPlainFiat(r *http.Request) interface{} {
979978

980979
convertedAmount := new(big.Rat).Mul(coinUnitAmount, new(big.Rat).SetFloat64(rate))
981980

982-
btcUnit := handlers.backend.Config().AppConfig().Backend.BtcUnit
983981
return map[string]interface{}{
984982
"success": true,
985-
"fiatAmount": coinpkg.FormatAsPlainCurrency(convertedAmount, currency == rates.BTC.String(), util.FormatBtcAsSat(btcUnit)),
983+
"fiatAmount": coinpkg.FormatAsPlainCurrency(convertedAmount, currency),
986984
}
987985
}
988986

@@ -1017,10 +1015,6 @@ func (handlers *Handlers) getConvertFromFiat(r *http.Request) interface{} {
10171015
unit = unit[3:]
10181016
}
10191017

1020-
if from == rates.BTC.String() && handlers.backend.Config().AppConfig().Backend.BtcUnit == coinpkg.BtcUnitSats {
1021-
fiatRat = coinpkg.Sat2Btc(fiatRat)
1022-
}
1023-
10241018
rate := handlers.backend.RatesUpdater().LatestPrice()[unit][from]
10251019
result := coin.NewAmountFromInt64(0)
10261020
if rate != 0.0 {

backend/rates/gecko.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ var (
100100
"SEK": "sek",
101101
"PLN": "pln",
102102
"CZK": "czk",
103+
// Satoshi rates are converted manually in the backend using Bitcoin.
104+
"sat": "btc",
103105
}
104106

105107
// Copied from https://api.coingecko.com/api/v3/simple/supported_vs_currencies.

backend/rates/history.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,12 @@ func (updater *RateUpdater) fetchGeckoMarketRange(ctx context.Context, coin, fia
290290
// Transform the response into a usable result.
291291
rates := make([]exchangeRate, len(jsonBody.Prices))
292292
for i, v := range jsonBody.Prices {
293+
value := v[1]
294+
if fiat == SAT.String() {
295+
value *= unitSatoshi
296+
}
293297
rates[i] = exchangeRate{
294-
value: v[1],
298+
value: value,
295299
timestamp: time.Unix(int64(v[0])/1000, 0), // local timezone
296300
}
297301
}

backend/rates/rates.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ const (
4949

5050
const interval = time.Minute
5151

52+
// unitSatoshi is 1 BTC (default unit) in Satoshi.
53+
const unitSatoshi = 1e8
54+
5255
type exchangeRate struct {
5356
value float64
5457
timestamp time.Time
@@ -83,6 +86,7 @@ const (
8386
SGD Fiat = "SGD"
8487
USD Fiat = "USD"
8588
BTC Fiat = "BTC"
89+
SAT Fiat = "sat"
8690
)
8791

8892
// RateUpdater provides cryptocurrency-to-fiat conversion rates.
@@ -316,11 +320,21 @@ func (updater *RateUpdater) updateLast(ctx context.Context) {
316320
updater.log.Errorf("unsupported fiat: %s", geckoFiat)
317321
continue
318322
}
323+
if fiat == BTC.String() {
324+
newVal[SAT.String()] = rates * unitSatoshi
325+
}
319326
newVal[fiat] = rates
320327
}
321328
rates[coinUnit] = newVal
322329
}
323330

331+
// Create sat rates from BTC
332+
sat := make(map[string]float64)
333+
for currency, rate := range rates[BTC.String()] {
334+
sat[currency] = rate / unitSatoshi
335+
}
336+
rates[SAT.String()] = sat
337+
324338
// Provide conversion rates for testnets as well, useful for testing.
325339
for _, testnetUnit := range []string{"TBTC", "RBTC", "TLTC", "GOETH", "SEPETH"} {
326340
switch testnetUnit {

frontends/web/src/api/account.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export type CoinCode = 'btc' | 'tbtc' | 'ltc' | 'tltc' | 'eth' | 'goeth' | 'sepe
2323

2424
export type AccountCode = string;
2525

26-
export type Fiat = 'AUD' | 'BRL' | 'BTC' | 'CAD' | 'CHF' | 'CNY' | 'CZK' | 'EUR' | 'GBP' | 'HKD' | 'ILS' | 'JPY' | 'KRW' | 'NOK' | 'PLN' | 'RUB' | 'SEK' | 'SGD' | 'USD';
26+
export type Fiat = 'AUD' | 'BRL' | 'BTC' | 'CAD' | 'CHF' | 'CNY' | 'CZK' | 'EUR' | 'GBP' | 'HKD' | 'ILS' | 'JPY' | 'KRW' | 'NOK' | 'PLN' | 'RUB' | 'sat' | 'SEK' | 'SGD' | 'USD';
2727

2828
export type ConversionUnit = Fiat | 'sat'
2929

0 commit comments

Comments
 (0)