diff --git a/components/Amount.tsx b/components/Amount.tsx
index 5dfc49b74..e184bd76d 100644
--- a/components/Amount.tsx
+++ b/components/Amount.tsx
@@ -1,18 +1,23 @@
import * as React from 'react';
import { TouchableOpacity, StyleSheet, View } from 'react-native';
import { inject, observer } from 'mobx-react';
+
import FiatStore from '../stores/FiatStore';
import UnitsStore from '../stores/UnitsStore';
import SettingsStore from '../stores/SettingsStore';
-import PrivacyUtils from '../utils/PrivacyUtils';
-import ClockIcon from '../assets/images/SVG/Clock.svg';
-import { localeString } from '../utils/LocaleUtils';
-import { themeColor } from '../utils/ThemeUtils';
+
import { Spacer } from './layout/Spacer';
import { Row } from './layout/Row';
import { Body } from './text/Body';
import LoadingIndicator from './LoadingIndicator';
+import { localeString } from '../utils/LocaleUtils';
+import { themeColor } from '../utils/ThemeUtils';
+import { formatBitcoinWithSpaces } from '../utils/UnitsUtils';
+import PrivacyUtils from '../utils/PrivacyUtils';
+
+import ClockIcon from '../assets/images/SVG/Clock.svg';
+
import stores from '../stores/Stores';
type Units = 'sats' | 'BTC' | 'fiat';
@@ -185,6 +190,8 @@ function AmountDisplay({
{negative ? '-' : ''}
{amount === 'N/A' && fiatRatesLoading ? (
+ ) : unit === 'BTC' ? (
+ formatBitcoinWithSpaces(amount)
) : (
amount.toString()
)}
@@ -216,6 +223,8 @@ function AmountDisplay({
{negative ? '-' : ''}
{amount === 'N/A' && fiatRatesLoading ? (
+ ) : unit === 'BTC' ? (
+ formatBitcoinWithSpaces(amount)
) : (
amount.toString()
)}
diff --git a/components/AmountInput.tsx b/components/AmountInput.tsx
index b4f50cbbd..42fd28740 100644
--- a/components/AmountInput.tsx
+++ b/components/AmountInput.tsx
@@ -7,11 +7,12 @@ import Amount from './Amount';
import TextInput from './TextInput';
import { themeColor } from '../utils/ThemeUtils';
+import { SATS_PER_BTC } from '../utils/UnitsUtils';
import Stores from '../stores/Stores';
import FiatStore from '../stores/FiatStore';
import SettingsStore from '../stores/SettingsStore';
-import UnitsStore, { SATS_PER_BTC } from '../stores/UnitsStore';
+import UnitsStore from '../stores/UnitsStore';
import ExchangeBitcoinSVG from '../assets/images/SVG/ExchangeBitcoin.svg';
import ExchangeFiatSVG from '../assets/images/SVG/ExchangeFiat.svg';
diff --git a/components/LSPS1OrderResponse.tsx b/components/LSPS1OrderResponse.tsx
index 2ca1ff8b3..46a8b0830 100644
--- a/components/LSPS1OrderResponse.tsx
+++ b/components/LSPS1OrderResponse.tsx
@@ -11,11 +11,11 @@ import Button from './Button';
import { localeString } from '../utils/LocaleUtils';
import { themeColor } from '../utils/ThemeUtils';
+import { numberWithCommas } from '../utils/UnitsUtils';
import UrlUtils from '../utils/UrlUtils';
import InvoicesStore from '../stores/InvoicesStore';
import NodeInfoStore from '../stores/NodeInfoStore';
-import FiatStore from '../stores/FiatStore';
import { ChannelItem } from './Channels/ChannelItem';
interface LSPS1OrderResponseProps {
@@ -23,11 +23,10 @@ interface LSPS1OrderResponseProps {
orderResponse: any;
InvoicesStore?: InvoicesStore;
NodeInfoStore?: NodeInfoStore;
- FiatStore?: FiatStore;
orderView: boolean;
}
-@inject('InvoicesStore', 'NodeInfoStore', 'FiatStore')
+@inject('InvoicesStore', 'NodeInfoStore')
@observer
export default class LSPS1OrderResponse extends React.Component<
LSPS1OrderResponseProps,
@@ -38,7 +37,6 @@ export default class LSPS1OrderResponse extends React.Component<
orderResponse,
InvoicesStore,
NodeInfoStore,
- FiatStore,
orderView,
navigation
} = this.props;
@@ -108,7 +106,7 @@ export default class LSPS1OrderResponse extends React.Component<
keyValue={localeString(
'views.LSPS1.channelExpiryBlocks'
)}
- value={FiatStore!.numberWithCommas(
+ value={numberWithCommas(
orderResponse?.channel_expiry_blocks
)}
/>
diff --git a/locales/en.json b/locales/en.json
index 6d9a7d601..f47e0ac48 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -742,6 +742,7 @@
"views.Settings.Display.displayNickname": "Display node nickname on main views",
"views.Settings.Display.bigKeypadButtons": "Big keypad buttons",
"views.Settings.Display.showAllDecimalPlaces": "Show all decimal places",
+ "views.Settings.Display.removeDecimalSpaces": "Remove decimal spaces from Bitcoin denominated amounts",
"views.Settings.Display.showMillisatoshiAmounts": "Show millisatoshi amounts",
"views.Settings.Display.selectNodeOnStartup": "Select node on startup",
"views.Settings.privacy": "Privacy",
diff --git a/stores/FiatStore.ts b/stores/FiatStore.ts
index 2efa51e66..b144a987a 100644
--- a/stores/FiatStore.ts
+++ b/stores/FiatStore.ts
@@ -3,7 +3,11 @@ import ReactNativeBlobUtil from 'react-native-blob-util';
import BigNumber from 'bignumber.js';
import SettingsStore from './SettingsStore';
-import { SATS_PER_BTC } from './UnitsStore';
+import {
+ SATS_PER_BTC,
+ numberWithCommas,
+ numberWithDecimals
+} from '../utils/UnitsUtils';
interface CurrencyDisplayRules {
symbol: string;
@@ -24,13 +28,6 @@ export default class FiatStore {
@observable public loading = false;
@observable public error = false;
- @observable public numberWithCommas = (x: string | number) =>
- x?.toString()?.replace(/\B(?=(\d{3})+(?!\d))/g, ',') || '0';
-
- @observable public numberWithDecimals = (x: string | number) =>
- this.numberWithCommas(x).replace(/[,.]/g, (y: string) =>
- y === ',' ? '.' : ','
- );
private sourceOfCurrentFiatRates: string | undefined;
getFiatRatesToken: any;
@@ -581,12 +578,12 @@ export default class FiatStore {
.toFixed(0);
const formattedRate = separatorSwap
- ? this.numberWithDecimals(rate)
- : this.numberWithCommas(rate);
+ ? numberWithDecimals(rate)
+ : numberWithCommas(rate);
const formattedMoscow = separatorSwap
- ? this.numberWithDecimals(moscowTime)
- : this.numberWithCommas(moscowTime);
+ ? numberWithDecimals(moscowTime)
+ : numberWithCommas(moscowTime);
if (sats) {
return `${formattedMoscow} sats = 1 ${fiat}`;
@@ -749,8 +746,8 @@ export default class FiatStore {
public formatAmountForDisplay = (input: string | number) => {
const { symbol, space, rtl, separatorSwap } = this.getSymbol();
const amount = separatorSwap
- ? this.numberWithDecimals(input)
- : this.numberWithCommas(input);
+ ? numberWithDecimals(input)
+ : numberWithCommas(input);
if (rtl) return `${amount}${space ? ' ' : ''}${symbol}`;
return `${symbol}${space ? ' ' : ''}${amount}`;
diff --git a/stores/PosStore.ts b/stores/PosStore.ts
index a45ade8db..e149f0431 100644
--- a/stores/PosStore.ts
+++ b/stores/PosStore.ts
@@ -2,12 +2,14 @@ import { action, observable } from 'mobx';
import EncryptedStorage from 'react-native-encrypted-storage';
import ReactNativeBlobUtil from 'react-native-blob-util';
import BigNumber from 'bignumber.js';
+import { v4 as uuidv4 } from 'uuid';
-import { SATS_PER_BTC } from './UnitsStore';
+import FiatStore from './FiatStore';
import SettingsStore, { PosEnabled } from './SettingsStore';
+
import Order from '../models/Order';
-import { v4 as uuidv4 } from 'uuid';
-import FiatStore from './FiatStore';
+
+import { SATS_PER_BTC } from '../utils/UnitsUtils';
export interface orderPaymentInfo {
orderId: string;
diff --git a/stores/SettingsStore.ts b/stores/SettingsStore.ts
index 115f27cb7..11e7a1584 100644
--- a/stores/SettingsStore.ts
+++ b/stores/SettingsStore.ts
@@ -44,6 +44,7 @@ interface DisplaySettings {
displayNickname?: boolean;
bigKeypadButtons?: boolean;
showAllDecimalPlaces?: boolean;
+ removeDecimalSpaces?: boolean;
showMillisatoshiAmounts?: boolean;
}
@@ -1106,6 +1107,7 @@ export default class SettingsStore {
displayNickname: false,
bigKeypadButtons: false,
showAllDecimalPlaces: false,
+ removeDecimalSpaces: false,
showMillisatoshiAmounts: true
},
pos: {
diff --git a/stores/UnitsStore.ts b/stores/UnitsStore.ts
index abc6a7ea5..5cfca5ec6 100644
--- a/stores/UnitsStore.ts
+++ b/stores/UnitsStore.ts
@@ -3,12 +3,15 @@ import EncryptedStorage from 'react-native-encrypted-storage';
import SettingsStore from './SettingsStore';
import FiatStore from './FiatStore';
-import FeeUtils from './../utils/FeeUtils';
-type Units = 'sats' | 'BTC' | 'fiat';
+import {
+ SATS_PER_BTC,
+ numberWithCommas,
+ numberWithDecimals
+} from '../utils/UnitsUtils';
+import FeeUtils from '../utils/FeeUtils';
-// 100_000_000
-export const SATS_PER_BTC = 100000000;
+type Units = 'sats' | 'BTC' | 'fiat';
const UNIT_KEY = 'zeus-units';
@@ -94,7 +97,7 @@ export default class UnitsStore {
};
} else if (units === 'sats') {
return {
- amount: this.fiatStore.numberWithCommas(absValueSats),
+ amount: numberWithCommas(absValueSats),
unit: 'sats',
negative,
plural: !(Number(value) === 1 || Number(value) === -1)
@@ -134,8 +137,8 @@ export default class UnitsStore {
return {
amount: separatorSwap
- ? this.fiatStore.numberWithDecimals(amount)
- : this.fiatStore.numberWithCommas(amount),
+ ? numberWithDecimals(amount)
+ : numberWithCommas(amount),
unit: 'fiat',
symbol,
negative,
@@ -177,9 +180,9 @@ export default class UnitsStore {
Number(wholeSats || 0) / SATS_PER_BTC
)}`;
} else if (units === 'sats') {
- const sats = `${
- this.fiatStore.numberWithCommas(wholeSats || value) || 0
- } ${Number(value) === 1 || Number(value) === -1 ? 'sat' : 'sats'}`;
+ const sats = `${numberWithCommas(wholeSats || value) || 0} ${
+ Number(value) === 1 || Number(value) === -1 ? 'sat' : 'sats'
+ }`;
return sats;
} else if (units === 'fiat' && fiat) {
if (this.fiatStore.fiatRates) {
@@ -197,8 +200,8 @@ export default class UnitsStore {
).toFixed(2);
const formattedAmount = separatorSwap
- ? this.fiatStore.numberWithDecimals(amount)
- : this.fiatStore.numberWithCommas(amount);
+ ? numberWithDecimals(amount)
+ : numberWithCommas(amount);
if (rtl) {
return `${formattedAmount}${space ? ' ' : ''}${symbol}`;
@@ -231,9 +234,9 @@ export default class UnitsStore {
return `₿${FeeUtils.toFixed(Number(value || 0))}`;
} else if (units === 'sats') {
const [wholeSats] = value.toString().split('.');
- const sats = `${
- this.fiatStore.numberWithCommas(wholeSats || value) || 0
- } ${Number(value) === 1 || Number(value) === -1 ? 'sat' : 'sats'}`;
+ const sats = `${numberWithCommas(wholeSats || value) || 0} ${
+ Number(value) === 1 || Number(value) === -1 ? 'sat' : 'sats'
+ }`;
return sats;
} else if (units === 'fiat' && fiat) {
if (this.fiatStore.fiatRates) {
@@ -250,8 +253,8 @@ export default class UnitsStore {
).toFixed(2);
const formattedAmount = separatorSwap
- ? this.fiatStore.numberWithDecimals(amount)
- : this.fiatStore.numberWithCommas(amount);
+ ? numberWithDecimals(amount)
+ : numberWithCommas(amount);
if (rtl) {
return `${formattedAmount}${space ? ' ' : ''}${symbol}`;
diff --git a/utils/AddressUtils.test.ts b/utils/AddressUtils.test.ts
index d7c706d11..d968bd574 100644
--- a/utils/AddressUtils.test.ts
+++ b/utils/AddressUtils.test.ts
@@ -5,6 +5,16 @@ jest.mock('react-native-encrypted-storage', () => ({
clear: jest.fn(() => Promise.resolve())
}));
+jest.mock('../stores/Stores', () => ({
+ SettingsStore: {
+ settings: {
+ display: {
+ removeDecimalSpaces: false
+ }
+ }
+ }
+}));
+
import AddressUtils from './AddressUtils';
import { walletrpc } from '../proto/lightning';
diff --git a/utils/AddressUtils.ts b/utils/AddressUtils.ts
index bb1460cf1..5882a2a22 100644
--- a/utils/AddressUtils.ts
+++ b/utils/AddressUtils.ts
@@ -3,7 +3,7 @@ const bitcoin = require('bitcoinjs-lib');
import Base64Utils from '../utils/Base64Utils';
-import { SATS_PER_BTC } from '../stores/UnitsStore';
+import { SATS_PER_BTC } from '../utils/UnitsUtils';
import { walletrpc } from '../proto/lightning';
diff --git a/utils/UnitsUtils.test.ts b/utils/UnitsUtils.test.ts
index 7cf768c39..466baa2fa 100644
--- a/utils/UnitsUtils.test.ts
+++ b/utils/UnitsUtils.test.ts
@@ -1,14 +1,24 @@
+jest.mock('../stores/Stores', () => ({
+ SettingsStore: {
+ settings: {
+ display: {
+ removeDecimalSpaces: false
+ }
+ }
+ }
+}));
+
import { getDecimalPlaceholder } from './UnitsUtils';
describe('UnitsUtils', () => {
describe('getDecimalPlaceholder', () => {
it('Returns string and count properly', () => {
expect(getDecimalPlaceholder('1231.2', 'BTC')).toEqual({
- string: '0000000',
+ string: '0 000 000',
count: 7
});
expect(getDecimalPlaceholder('1231.', 'BTC')).toEqual({
- string: '00000000',
+ string: '00 000 000',
count: 8
});
diff --git a/utils/UnitsUtils.ts b/utils/UnitsUtils.ts
index b6a7bcfbc..a7f176216 100644
--- a/utils/UnitsUtils.ts
+++ b/utils/UnitsUtils.ts
@@ -1,6 +1,11 @@
+import stores from '../stores/Stores';
+
+// 100_000_000
+const SATS_PER_BTC = 100000000;
+
const getDecimalPlaceholder = (amount: string, units: string) => {
- const occupiedPlaces: number =
- (amount.split('.')[1] && amount.split('.')[1].length) || 0;
+ const [_, decimalPart] = amount.split('.');
+ const occupiedPlaces: number = (decimalPart && decimalPart.length) || 0;
let placeholderCount = 0;
if (units === 'sats') {
@@ -12,9 +17,60 @@ const getDecimalPlaceholder = (amount: string, units: string) => {
}
return {
- string: amount.includes('.') ? '0'.repeat(placeholderCount) : null,
+ string: amount.includes('.')
+ ? units === 'BTC' &&
+ !stores?.settingsStore?.settings?.display?.removeDecimalSpaces
+ ? '00 000 000'.slice(
+ occupiedPlaces +
+ (decimalPart.length > 5
+ ? 2
+ : decimalPart.length > 2
+ ? 1
+ : 0)
+ )
+ : '0'.repeat(placeholderCount)
+ : null,
count: amount.includes('.') ? placeholderCount : 0
};
};
-export { getDecimalPlaceholder };
+const numberWithCommas = (x: string | number) =>
+ x?.toString()?.replace(/\B(?=(\d{3})+(?!\d))/g, ',') || '0';
+
+const numberWithDecimals = (x: string | number) =>
+ numberWithCommas(x).replace(/[,.]/g, (y: string) =>
+ y === ',' ? '.' : ','
+ );
+
+const formatBitcoinWithSpaces = (x: string | number) => {
+ // Convert to string to handle decimal parts
+ const [integerPart, decimalPart] = x.toString().split('.');
+
+ const integerFormatted = numberWithCommas(integerPart);
+
+ // // If no decimal part, return the integer part as is
+ if (x.toString().includes('.') && !decimalPart) {
+ return `${integerFormatted}.`;
+ } else if (!decimalPart) {
+ return integerFormatted;
+ }
+
+ if (stores?.settingsStore?.settings?.display?.removeDecimalSpaces) {
+ return `${integerFormatted}.${decimalPart}`;
+ }
+
+ // Handle the first two characters, then group the rest in threes
+ const firstTwo = decimalPart.slice(0, 2);
+ const rest = decimalPart.slice(2).replace(/(\d{3})(?=\d)/g, '$1 ');
+
+ // Combine integer part, first two characters, and formatted rest
+ return `${integerFormatted}.${firstTwo} ${rest}`.trim();
+};
+
+export {
+ SATS_PER_BTC,
+ getDecimalPlaceholder,
+ numberWithCommas,
+ numberWithDecimals,
+ formatBitcoinWithSpaces
+};
diff --git a/views/Activity/Activity.tsx b/views/Activity/Activity.tsx
index 9cf5a6b58..9aa52d49c 100644
--- a/views/Activity/Activity.tsx
+++ b/views/Activity/Activity.tsx
@@ -23,13 +23,17 @@ import { Row } from '../../components/layout/Row';
import { localeString } from '../../utils/LocaleUtils';
import BackendUtils from '../../utils/BackendUtils';
import { themeColor } from '../../utils/ThemeUtils';
+import {
+ SATS_PER_BTC,
+ numberWithCommas,
+ numberWithDecimals
+} from '../../utils/UnitsUtils';
import ActivityStore from '../../stores/ActivityStore';
import FiatStore from '../../stores/FiatStore';
import PosStore from '../../stores/PosStore';
import SettingsStore from '../../stores/SettingsStore';
import NotesStore from '../../stores/NotesStore';
-import { SATS_PER_BTC } from '../../stores/UnitsStore';
import Filter from '../../assets/images/SVG/Filter On.svg';
import Invoice from '../../models/Invoice';
@@ -200,8 +204,8 @@ export default class Activity extends React.PureComponent<
};
const formattedRate = separatorSwap
- ? FiatStore.numberWithDecimals(rate)
- : FiatStore.numberWithCommas(rate);
+ ? numberWithDecimals(rate)
+ : numberWithCommas(rate);
const exchangeRate = rtl
? `${formattedRate}${
diff --git a/views/Order.tsx b/views/Order.tsx
index cf3af7b3f..538453785 100644
--- a/views/Order.tsx
+++ b/views/Order.tsx
@@ -23,10 +23,11 @@ import TextInput from '../components/TextInput';
import { localeString } from '../utils/LocaleUtils';
import { themeColor } from '../utils/ThemeUtils';
+import { SATS_PER_BTC } from '../utils/UnitsUtils';
import SettingsStore, { PosEnabled } from '../stores/SettingsStore';
import FiatStore from '../stores/FiatStore';
-import UnitsStore, { SATS_PER_BTC } from '../stores/UnitsStore';
+import UnitsStore from '../stores/UnitsStore';
import RNPrint from 'react-native-print';
import PosStore from '../stores/PosStore';
diff --git a/views/PendingHTLCs.tsx b/views/PendingHTLCs.tsx
index e289e8981..03607acf0 100644
--- a/views/PendingHTLCs.tsx
+++ b/views/PendingHTLCs.tsx
@@ -15,15 +15,14 @@ import Switch from '../components/Switch';
import { localeString } from '../utils/LocaleUtils';
import { restartNeeded } from '../utils/RestartUtils';
import { themeColor } from '../utils/ThemeUtils';
+import { numberWithCommas } from '../utils/UnitsUtils';
import ChannelsStore from '../stores/ChannelsStore';
-import FiatStore from '../stores/FiatStore';
import SettingsStore from '../stores/SettingsStore';
interface PendingHTLCsProps {
navigation: StackNavigationProp;
ChannelsStore: ChannelsStore;
- FiatStore: FiatStore;
SettingsStore: SettingsStore;
route: Route<'PendingHTLCs', { pending_htlcs: any }>;
}
@@ -35,7 +34,7 @@ interface PendingHTLCsState {
const PERSISTENT_KEY = 'persistentServicesEnabled';
-@inject('ChannelsStore', 'FiatStore', 'SettingsStore')
+@inject('ChannelsStore', 'SettingsStore')
@observer
export default class PendingHTLCs extends React.PureComponent<
PendingHTLCsProps,
@@ -71,8 +70,7 @@ export default class PendingHTLCs extends React.PureComponent<
};
render() {
- const { navigation, ChannelsStore, FiatStore, SettingsStore } =
- this.props;
+ const { navigation, ChannelsStore, SettingsStore } = this.props;
const { pendingHTLCs, persistentMode } = this.state;
const { getChannels, loading } = ChannelsStore;
const { updateSettings, implementation } = SettingsStore;
@@ -103,9 +101,7 @@ export default class PendingHTLCs extends React.PureComponent<
: localeString('views.PendingHTLCs.outgoing');
const subTitle = `${localeString(
'views.PendingHTLCs.expirationHeight'
- )}: ${FiatStore.numberWithCommas(
- item.expiration_height
- )}`;
+ )}: ${numberWithCommas(item.expiration_height)}`;
return (
diff --git a/views/Receive.tsx b/views/Receive.tsx
index 3812035a7..28a2b5385 100644
--- a/views/Receive.tsx
+++ b/views/Receive.tsx
@@ -66,13 +66,14 @@ import PosStore from '../stores/PosStore';
import SettingsStore, { TIME_PERIOD_KEYS } from '../stores/SettingsStore';
import LightningAddressStore from '../stores/LightningAddressStore';
import LSPStore from '../stores/LSPStore';
-import UnitsStore, { SATS_PER_BTC } from '../stores/UnitsStore';
+import UnitsStore from '../stores/UnitsStore';
import { localeString } from '../utils/LocaleUtils';
import BackendUtils from '../utils/BackendUtils';
import Base64Utils from '../utils/Base64Utils';
import NFCUtils from '../utils/NFCUtils';
import { themeColor } from '../utils/ThemeUtils';
+import { SATS_PER_BTC } from '../utils/UnitsUtils';
import lndMobile from '../lndmobile/LndMobileInjection';
import { decodeSubscribeTransactionsResult } from '../lndmobile/onchain';
diff --git a/views/Settings/CurrencyConverter.tsx b/views/Settings/CurrencyConverter.tsx
index 38b3820df..e510ac0ef 100644
--- a/views/Settings/CurrencyConverter.tsx
+++ b/views/Settings/CurrencyConverter.tsx
@@ -33,6 +33,8 @@ import Edit from '../../assets/images/SVG/Pen.svg';
import DragDots from '../../assets/images/SVG/DragDots.svg';
import BitcoinIcon from '../../assets/images/SVG/bitcoin-icon.svg';
+import { numberWithCommas } from '../../utils/UnitsUtils';
+
interface CurrencyConverterProps {
navigation: StackNavigationProp;
FiatStore?: FiatStore;
@@ -176,14 +178,14 @@ export default class CurrencyConverter extends React.Component<
if (currency === 'BTC') {
// If BTC and the value is greater than 1, apply formatting with numberWithCommas
if (parseFloat(value) > 1) {
- return FiatStore.numberWithCommas(value);
+ return numberWithCommas(value);
} else {
// Otherwise, return the value as it is
return value;
}
} else {
// For other currencies, apply formatting with numberWithCommas
- return FiatStore.numberWithCommas(value);
+ return numberWithCommas(value);
}
};
diff --git a/views/Settings/Display.tsx b/views/Settings/Display.tsx
index 8dfa8f0c3..6699dfdc6 100644
--- a/views/Settings/Display.tsx
+++ b/views/Settings/Display.tsx
@@ -28,6 +28,7 @@ interface DisplayState {
displayNickname: boolean;
bigKeypadButtons: boolean;
showAllDecimalPlaces: boolean;
+ removeDecimalSpaces: boolean;
showMillisatoshiAmounts: boolean;
selectNodeOnStartup: boolean;
}
@@ -44,6 +45,7 @@ export default class Display extends React.Component<
displayNickname: false,
bigKeypadButtons: false,
showAllDecimalPlaces: false,
+ removeDecimalSpaces: false,
showMillisatoshiAmounts: false,
selectNodeOnStartup: false
};
@@ -65,6 +67,9 @@ export default class Display extends React.Component<
showAllDecimalPlaces:
(settings.display && settings.display.showAllDecimalPlaces) ||
false,
+ removeDecimalSpaces:
+ (settings.display && settings.display.removeDecimalSpaces) ||
+ false,
showMillisatoshiAmounts:
(settings.display &&
settings.display.showMillisatoshiAmounts) ||
@@ -90,6 +95,7 @@ export default class Display extends React.Component<
bigKeypadButtons,
theme,
showAllDecimalPlaces,
+ removeDecimalSpaces,
showMillisatoshiAmounts,
selectNodeOnStartup
} = this.state;
@@ -126,6 +132,7 @@ export default class Display extends React.Component<
bigKeypadButtons,
defaultView,
showAllDecimalPlaces,
+ removeDecimalSpaces,
showMillisatoshiAmounts
}
});
@@ -156,6 +163,7 @@ export default class Display extends React.Component<
bigKeypadButtons,
theme,
showAllDecimalPlaces,
+ removeDecimalSpaces,
showMillisatoshiAmounts
}
});
@@ -200,6 +208,7 @@ export default class Display extends React.Component<
bigKeypadButtons,
displayNickname: !displayNickname,
showAllDecimalPlaces,
+ removeDecimalSpaces,
showMillisatoshiAmounts
}
});
@@ -245,6 +254,7 @@ export default class Display extends React.Component<
displayNickname,
bigKeypadButtons: !bigKeypadButtons,
showAllDecimalPlaces,
+ removeDecimalSpaces,
showMillisatoshiAmounts
}
});
@@ -292,6 +302,55 @@ export default class Display extends React.Component<
bigKeypadButtons,
showAllDecimalPlaces:
!showAllDecimalPlaces,
+ removeDecimalSpaces,
+ showMillisatoshiAmounts
+ }
+ });
+ }}
+ />
+
+
+
+
+
+ {localeString(
+ 'views.Settings.Display.removeDecimalSpaces'
+ )}
+
+
+ {
+ this.setState({
+ removeDecimalSpaces:
+ !removeDecimalSpaces
+ });
+ await updateSettings({
+ display: {
+ defaultView,
+ theme,
+ displayNickname,
+ bigKeypadButtons,
+ showAllDecimalPlaces,
+ removeDecimalSpaces:
+ !removeDecimalSpaces,
showMillisatoshiAmounts
}
});
@@ -299,6 +358,7 @@ export default class Display extends React.Component<
/>
+
;
}
@@ -74,7 +73,6 @@ interface LSPS1State {
'ChannelsStore',
'InvoicesStore',
'SettingsStore',
- 'FiatStore',
'NodeInfoStore'
)
@observer
@@ -352,7 +350,6 @@ export default class LSPS1 extends React.Component {
navigation,
LSPStore,
InvoicesStore,
- FiatStore,
NodeInfoStore,
SettingsStore
} = this.props;
@@ -683,9 +680,9 @@ export default class LSPS1 extends React.Component {
keyValue={`${localeString(
'views.Channel.channelBalance'
)}`}
- value={`${FiatStore.numberWithCommas(
+ value={`${numberWithCommas(
info?.min_channel_balance_sat
- )} - ${FiatStore.numberWithCommas(
+ )} - ${numberWithCommas(
info?.max_channel_balance_sat
)} ${localeString(
'general.sats'
@@ -698,9 +695,9 @@ export default class LSPS1 extends React.Component {
keyValue={`${localeString(
'views.LSPS1.initialLSPBalance'
)}`}
- value={`${FiatStore.numberWithCommas(
+ value={`${numberWithCommas(
info?.min_initial_lsp_balance_sat
- )} - ${FiatStore.numberWithCommas(
+ )} - ${numberWithCommas(
info?.max_initial_lsp_balance_sat
)} ${localeString(
'general.sats'
@@ -736,7 +733,7 @@ export default class LSPS1 extends React.Component {
keyValue={localeString(
'views.LSPS1.maxChannelExpiryBlocks'
)}
- value={FiatStore.numberWithCommas(
+ value={numberWithCommas(
info?.max_channel_expiry_blocks
)}
/>
@@ -833,9 +830,7 @@ export default class LSPS1 extends React.Component {
placeholder={`${localeString(
'views.LSPS1.initialLSPBalance'
)} (${localeString('general.sats')})`}
- value={FiatStore.numberWithCommas(
- lspBalanceSat
- )}
+ value={numberWithCommas(lspBalanceSat)}
onChangeText={(text: any) => {
const value = text.replace(
/,/g,
@@ -856,7 +851,7 @@ export default class LSPS1 extends React.Component {
color: themeColor('text')
}}
>
- {FiatStore.numberWithCommas(
+ {numberWithCommas(
info?.min_initial_lsp_balance_sat
)}
@@ -865,7 +860,7 @@ export default class LSPS1 extends React.Component {
color: themeColor('text')
}}
>
- {FiatStore.numberWithCommas(
+ {numberWithCommas(
info?.max_initial_lsp_balance_sat
)}
@@ -914,7 +909,7 @@ export default class LSPS1 extends React.Component {
placeholder={localeString(
'views.LSPS1.channelExpiryBlocks'
)}
- value={FiatStore.numberWithCommas(
+ value={numberWithCommas(
channelExpiryBlocks
)}
onChangeText={(text: any) => {
@@ -1044,7 +1039,7 @@ export default class LSPS1 extends React.Component {
)} (${localeString(
'general.sats'
)})`}
- value={FiatStore.numberWithCommas(
+ value={numberWithCommas(
clientBalanceSat
).toString()}
onChangeText={(
@@ -1075,7 +1070,7 @@ export default class LSPS1 extends React.Component {
)
}}
>
- {FiatStore.numberWithCommas(
+ {numberWithCommas(
info?.min_initial_client_balance_sat
)}
@@ -1086,7 +1081,7 @@ export default class LSPS1 extends React.Component {
)
}}
>
- {FiatStore.numberWithCommas(
+ {numberWithCommas(
info?.max_initial_client_balance_sat
)}
diff --git a/views/Settings/PointOfSaleRecon.tsx b/views/Settings/PointOfSaleRecon.tsx
index afc9da1fb..4023942c1 100644
--- a/views/Settings/PointOfSaleRecon.tsx
+++ b/views/Settings/PointOfSaleRecon.tsx
@@ -21,11 +21,11 @@ import Export from '../../assets/images/SVG/Export.svg';
import FiatStore from '../../stores/FiatStore';
import PosStore from '../../stores/PosStore';
-import { SATS_PER_BTC } from '../../stores/UnitsStore';
import BackendUtils from '../../utils/BackendUtils';
import { localeString } from '../../utils/LocaleUtils';
import { themeColor } from '../../utils/ThemeUtils';
+import { SATS_PER_BTC } from '../../utils/UnitsUtils';
import { ReconHeader } from './PointOfSaleReconHeader';
diff --git a/views/Wallet/KeypadPane.tsx b/views/Wallet/KeypadPane.tsx
index 4e5e795ec..40d03c35e 100644
--- a/views/Wallet/KeypadPane.tsx
+++ b/views/Wallet/KeypadPane.tsx
@@ -12,7 +12,6 @@ import WalletHeader from '../../components/WalletHeader';
import { getSatAmount } from '../../components/AmountInput';
import ChannelsStore from '../../stores/ChannelsStore';
-import FiatStore from '../../stores/FiatStore';
import NodeInfoStore from '../../stores/NodeInfoStore';
import SettingsStore from '../../stores/SettingsStore';
import UnitsStore from '../../stores/UnitsStore';
@@ -20,12 +19,15 @@ import UnitsStore from '../../stores/UnitsStore';
import BackendUtils from '../../utils/BackendUtils';
import { localeString } from '../../utils/LocaleUtils';
import { themeColor } from '../../utils/ThemeUtils';
-import { getDecimalPlaceholder } from '../../utils/UnitsUtils';
+import {
+ getDecimalPlaceholder,
+ formatBitcoinWithSpaces,
+ numberWithCommas
+} from '../../utils/UnitsUtils';
interface KeypadPaneProps {
navigation: StackNavigationProp;
ChannelsStore?: ChannelsStore;
- FiatStore?: FiatStore;
NodeInfoStore?: NodeInfoStore;
SettingsStore?: SettingsStore;
UnitsStore?: UnitsStore;
@@ -39,15 +41,7 @@ interface KeypadPaneState {
lspNotConfigured: boolean;
}
-const MAX_LENGTH = 10;
-
-@inject(
- 'ChannelsStore',
- 'FiatStore',
- 'NodeInfoStore',
- 'SettingsStore',
- 'UnitsStore'
-)
+@inject('ChannelsStore', 'NodeInfoStore', 'SettingsStore', 'UnitsStore')
@observer
export default class KeypadPane extends React.PureComponent<
KeypadPaneProps,
@@ -99,17 +93,34 @@ export default class KeypadPane extends React.PureComponent<
return this.startShake();
}
if (units === 'BTC') {
- if (amount.split('.')[1] && amount.split('.')[1].length == 8)
+ const [integerPart, decimalPart] = amount.split('.');
+ // deny if trying to add more than 8 figures of Bitcoin
+ if (
+ !decimalPart &&
+ integerPart &&
+ integerPart.length == 8 &&
+ !amount.includes('.') &&
+ value !== '.'
+ )
+ return this.startShake();
+ // deny if trying to add more than 8 decimal places of satoshis
+ if (decimalPart && decimalPart.length == 8)
return this.startShake();
}
- if (amount.length >= MAX_LENGTH) {
- newAmount = amount;
+ const proposedNewAmountStr = `${amount}${value}`;
+ const proposedNewAmount = new BigNumber(proposedNewAmountStr);
+
+ // deny if exceeding BTC 21 million capacity
+ if (units === 'BTC' && proposedNewAmount.gt(21000000))
return this.startShake();
- } else if (amount === '0') {
+ if (units === 'sats' && proposedNewAmount.gt(2100000000000000.0))
+ return this.startShake();
+
+ if (amount === '0') {
newAmount = value;
} else {
- newAmount = `${amount}${value}`;
+ newAmount = proposedNewAmountStr;
}
let needInbound = false;
@@ -197,8 +208,10 @@ export default class KeypadPane extends React.PureComponent<
return needInbound ? 40 : 50;
case 8:
return needInbound ? 35 : 45;
- default:
+ case 9:
return needInbound ? 25 : 35;
+ default:
+ return needInbound ? 20 : 30;
}
};
@@ -242,7 +255,7 @@ export default class KeypadPane extends React.PureComponent<
};
render() {
- const { FiatStore, UnitsStore, navigation } = this.props;
+ const { UnitsStore, navigation } = this.props;
const { amount, needInbound, belowMinAmount, overrideBelowMinAmount } =
this.state;
const { units } = UnitsStore!;
@@ -326,7 +339,9 @@ export default class KeypadPane extends React.PureComponent<
fontFamily: 'PPNeueMontreal-Medium'
}}
>
- {FiatStore?.numberWithCommas(amount)}
+ {units === 'BTC'
+ ? formatBitcoinWithSpaces(amount)
+ : numberWithCommas(amount)}
{getDecimalPlaceholder(amount, units).string}
diff --git a/views/Wallet/SquarePosPane.tsx b/views/Wallet/SquarePosPane.tsx
index 4b0de0dae..64fc0eb13 100644
--- a/views/Wallet/SquarePosPane.tsx
+++ b/views/Wallet/SquarePosPane.tsx
@@ -25,12 +25,13 @@ import ActivityStore from '../../stores/ActivityStore';
import FiatStore from '../../stores/FiatStore';
import NodeInfoStore from '../../stores/NodeInfoStore';
import PosStore from '../../stores/PosStore';
-import UnitsStore, { SATS_PER_BTC } from '../../stores/UnitsStore';
+import UnitsStore from '../../stores/UnitsStore';
import SettingsStore from '../../stores/SettingsStore';
import { localeString } from '../../utils/LocaleUtils';
import { protectedNavigation } from '../../utils/NavigationUtils';
import { themeColor } from '../../utils/ThemeUtils';
+import { SATS_PER_BTC } from '../../utils/UnitsUtils';
import { version } from './../../package.json';
diff --git a/views/Wallet/StandalonePosKeypadPane.tsx b/views/Wallet/StandalonePosKeypadPane.tsx
index 9820611ac..e33273b46 100644
--- a/views/Wallet/StandalonePosKeypadPane.tsx
+++ b/views/Wallet/StandalonePosKeypadPane.tsx
@@ -10,21 +10,23 @@ import UnitToggle from '../../components/UnitToggle';
import WalletHeader from '../../components/WalletHeader';
import ChannelsStore from '../../stores/ChannelsStore';
-import FiatStore from '../../stores/FiatStore';
-import UnitsStore, { SATS_PER_BTC } from '../../stores/UnitsStore';
+import UnitsStore from '../../stores/UnitsStore';
import SettingsStore from '../../stores/SettingsStore';
import PosStore from '../../stores/PosStore';
import { localeString } from '../../utils/LocaleUtils';
import { themeColor } from '../../utils/ThemeUtils';
-import { getDecimalPlaceholder } from '../../utils/UnitsUtils';
+import {
+ SATS_PER_BTC,
+ getDecimalPlaceholder,
+ numberWithCommas
+} from '../../utils/UnitsUtils';
import { PricedIn } from '../../models/Product';
interface PosKeypadPaneProps {
navigation: StackNavigationProp;
ChannelsStore?: ChannelsStore;
- FiatStore?: FiatStore;
UnitsStore?: UnitsStore;
SettingsStore?: SettingsStore;
PosStore?: PosStore;
@@ -36,7 +38,7 @@ interface PosKeypadPaneState {
const MAX_LENGTH = 10;
-@inject('ChannelsStore', 'FiatStore', 'UnitsStore', 'SettingsStore', 'PosStore')
+@inject('ChannelsStore', 'UnitsStore', 'SettingsStore', 'PosStore')
@observer
export default class PosKeypadPane extends React.PureComponent<
PosKeypadPaneProps,
@@ -206,7 +208,7 @@ export default class PosKeypadPane extends React.PureComponent<
};
render() {
- const { FiatStore, UnitsStore, navigation } = this.props;
+ const { UnitsStore, navigation } = this.props;
const { amount } = this.state;
const { units } = UnitsStore!;
@@ -241,7 +243,7 @@ export default class PosKeypadPane extends React.PureComponent<
fontFamily: 'PPNeueMontreal-Medium'
}}
>
- {FiatStore?.numberWithCommas(amount)}
+ {numberWithCommas(amount)}
{getDecimalPlaceholder(amount, units).string}
diff --git a/views/Wallet/StandalonePosPane.tsx b/views/Wallet/StandalonePosPane.tsx
index 86b9429ed..b2e7863af 100644
--- a/views/Wallet/StandalonePosPane.tsx
+++ b/views/Wallet/StandalonePosPane.tsx
@@ -28,13 +28,14 @@ import ActivityStore from '../../stores/ActivityStore';
import FiatStore from '../../stores/FiatStore';
import NodeInfoStore from '../../stores/NodeInfoStore';
import PosStore from '../../stores/PosStore';
-import UnitsStore, { SATS_PER_BTC } from '../../stores/UnitsStore';
+import UnitsStore from '../../stores/UnitsStore';
import SettingsStore from '../../stores/SettingsStore';
import InventoryStore from '../../stores/InventoryStore';
import { localeString } from '../../utils/LocaleUtils';
import { protectedNavigation } from '../../utils/NavigationUtils';
import { themeColor } from '../../utils/ThemeUtils';
+import { SATS_PER_BTC } from '../../utils/UnitsUtils';
import { version } from './../../package.json';