mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-03-13 11:09:20 +01:00
FIX: Currency test
This commit is contained in:
parent
1cd934aa46
commit
a633f671e2
11 changed files with 218 additions and 280 deletions
|
@ -1,17 +0,0 @@
|
|||
/* global jest */
|
||||
|
||||
export const startIfNotStarted = jest.fn(async (key, value, callback) => {
|
||||
return 666;
|
||||
});
|
||||
|
||||
export const get = jest.fn();
|
||||
export const post = jest.fn();
|
||||
export const deleteMock = jest.fn();
|
||||
export const stopIfRunning = jest.fn();
|
||||
export const getDaemonStatus = jest.fn();
|
||||
|
||||
const mock = jest.fn().mockImplementation(() => {
|
||||
return { startIfNotStarted, get, post, delete: deleteMock, stopIfRunning, getDaemonStatus };
|
||||
});
|
||||
|
||||
export default mock;
|
|
@ -13,6 +13,13 @@
|
|||
"symbol": "د.إ.",
|
||||
"country": "United Arab Emirates (UAE Dirham)"
|
||||
},
|
||||
"AMD": {
|
||||
"endPointKey": "AMD",
|
||||
"locale": "hy-AM",
|
||||
"source": "CoinDesk",
|
||||
"symbol": "֏",
|
||||
"country": "Armenia (Armenian Dram)"
|
||||
},
|
||||
"ANG": {
|
||||
"endPointKey": "ANG",
|
||||
"locale": "en-SX",
|
||||
|
@ -293,6 +300,13 @@
|
|||
"symbol": "lei",
|
||||
"country": "Romania (Romanian Leu)"
|
||||
},
|
||||
"RSD": {
|
||||
"endPointKey": "RSD",
|
||||
"locale": "sr-RS",
|
||||
"source": "CoinGecko",
|
||||
"symbol": "DIN",
|
||||
"country": "Serbia (Serbian Dinar)"
|
||||
},
|
||||
"RUB": {
|
||||
"endPointKey": "RUB",
|
||||
"locale": "ru-RU",
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import DefaultPreference from 'react-native-default-preference';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import DefaultPreference from 'react-native-default-preference';
|
||||
import * as RNLocalize from 'react-native-localize';
|
||||
|
||||
import { FiatUnit, FiatUnitType, getFiatRate } from '../models/fiatUnit';
|
||||
|
@ -30,60 +29,6 @@ let skipUpdateExchangeRate: boolean = false;
|
|||
let currencyFormatter: Intl.NumberFormat | null = null;
|
||||
let btcFormatter: Intl.NumberFormat | null = null;
|
||||
|
||||
// Initialize DefaultPreference with the correct group name
|
||||
DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
|
||||
/**
|
||||
* Migration Function:
|
||||
* Transfers data from AsyncStorage to DefaultPreference if present.
|
||||
* DefaultPreference uses truly native preference storage which makes use of
|
||||
* extensions easier.
|
||||
* After migration, removes the data from AsyncStorage.
|
||||
*/
|
||||
async function migrateAsyncStorageToDefaultPreference(): Promise<void> {
|
||||
try {
|
||||
// Migrate Preferred Currency
|
||||
const asyncPreferredCurrency = await AsyncStorage.getItem(PREFERRED_CURRENCY_STORAGE_KEY);
|
||||
if (asyncPreferredCurrency) {
|
||||
try {
|
||||
const parsedCurrency = JSON.parse(asyncPreferredCurrency);
|
||||
if (FiatUnit[parsedCurrency.endPointKey]) {
|
||||
await DefaultPreference.set(PREFERRED_CURRENCY_STORAGE_KEY, parsedCurrency.endPointKey);
|
||||
await DefaultPreference.set(PREFERRED_CURRENCY_LOCALE_STORAGE_KEY, parsedCurrency.locale.replace('-', '_'));
|
||||
preferredFiatCurrency = FiatUnit[parsedCurrency.endPointKey];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to parse preferred currency from AsyncStorage:', error);
|
||||
} finally {
|
||||
await AsyncStorage.removeItem(PREFERRED_CURRENCY_STORAGE_KEY);
|
||||
await AsyncStorage.removeItem(PREFERRED_CURRENCY_LOCALE_STORAGE_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate Exchange Rates
|
||||
const asyncExchangeRates = await AsyncStorage.getItem(EXCHANGE_RATES_STORAGE_KEY);
|
||||
if (asyncExchangeRates) {
|
||||
try {
|
||||
const parsedRates = JSON.parse(asyncExchangeRates);
|
||||
await DefaultPreference.set(EXCHANGE_RATES_STORAGE_KEY, asyncExchangeRates);
|
||||
exchangeRates = parsedRates;
|
||||
} catch (error) {
|
||||
console.error('Failed to parse exchange rates from AsyncStorage:', error);
|
||||
} finally {
|
||||
} catch (error) {
|
||||
console.error('Failed to parse exchange rates from AsyncStorage:', error);
|
||||
} else {
|
||||
// Remove from AsyncStorage only if migration was successful
|
||||
await AsyncStorage.removeItem(EXCHANGE_RATES_STORAGE_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Migration from AsyncStorage to DefaultPreference completed.');
|
||||
} catch (migrationError) {
|
||||
console.error('Migration failed:', migrationError);
|
||||
}
|
||||
}
|
||||
|
||||
function getCurrencyFormatter(): Intl.NumberFormat {
|
||||
if (
|
||||
!currencyFormatter ||
|
||||
|
@ -117,32 +62,27 @@ function getBTCFormatter(): Intl.NumberFormat {
|
|||
}
|
||||
|
||||
async function setPreferredCurrency(item: FiatUnitType): Promise<void> {
|
||||
try {
|
||||
await DefaultPreference.set(PREFERRED_CURRENCY_STORAGE_KEY, item.endPointKey);
|
||||
await DefaultPreference.set(PREFERRED_CURRENCY_LOCALE_STORAGE_KEY, item.locale.replace('-', '_'));
|
||||
preferredFiatCurrency = item;
|
||||
currencyFormatter = null;
|
||||
btcFormatter = null;
|
||||
} catch (error) {
|
||||
console.error('Failed to set preferred currency:', error);
|
||||
throw error;
|
||||
}
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
await DefaultPreference.set(PREFERRED_CURRENCY_STORAGE_KEY, JSON.stringify(item));
|
||||
await DefaultPreference.set(PREFERRED_CURRENCY_LOCALE_STORAGE_KEY, item.locale.replace('-', '_'));
|
||||
currencyFormatter = null;
|
||||
btcFormatter = null;
|
||||
}
|
||||
|
||||
async function updateExchangeRate(): Promise<void> {
|
||||
if (skipUpdateExchangeRate) return;
|
||||
if (Date.now() - lastTimeUpdateExchangeRateWasCalled <= 10000) {
|
||||
// Simple debounce to prevent race conditions
|
||||
// simple debounce so there's no race conditions
|
||||
return;
|
||||
}
|
||||
lastTimeUpdateExchangeRateWasCalled = Date.now();
|
||||
|
||||
const lastUpdated = exchangeRates[LAST_UPDATED] as number | undefined;
|
||||
if (lastUpdated && Date.now() - lastUpdated <= 30 * 60 * 1000) {
|
||||
// Not updating too often
|
||||
// not updating too often
|
||||
return;
|
||||
}
|
||||
console.log('Updating exchange rate...');
|
||||
console.log('updating exchange rate...');
|
||||
|
||||
try {
|
||||
const rate = await getFiatRate(preferredFiatCurrency.endPointKey);
|
||||
|
@ -152,22 +92,27 @@ async function updateExchangeRate(): Promise<void> {
|
|||
|
||||
try {
|
||||
const exchangeRatesString = JSON.stringify(exchangeRates);
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
await DefaultPreference.set(EXCHANGE_RATES_STORAGE_KEY, exchangeRatesString);
|
||||
} catch (error) {
|
||||
console.error('Failed to set exchange rates in DefaultPreference:', error);
|
||||
await DefaultPreference.clear(EXCHANGE_RATES_STORAGE_KEY);
|
||||
exchangeRates = { LAST_UPDATED_ERROR: false };
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch fiat rate:', error);
|
||||
try {
|
||||
const ratesString = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
const ratesValue = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
let ratesString: string | null = null;
|
||||
|
||||
if (typeof ratesValue === 'string') {
|
||||
ratesString = ratesValue;
|
||||
}
|
||||
|
||||
let rate;
|
||||
if (ratesString) {
|
||||
try {
|
||||
rate = JSON.parse(ratesString);
|
||||
} catch (parseError) {
|
||||
console.error('Failed to parse exchange rates:', parseError);
|
||||
await DefaultPreference.clear(EXCHANGE_RATES_STORAGE_KEY);
|
||||
rate = {};
|
||||
}
|
||||
|
@ -178,7 +123,6 @@ async function updateExchangeRate(): Promise<void> {
|
|||
exchangeRates.LAST_UPDATED_ERROR = true;
|
||||
await DefaultPreference.set(EXCHANGE_RATES_STORAGE_KEY, JSON.stringify(rate));
|
||||
} catch (storageError) {
|
||||
console.error('Failed to handle exchange rate error:', storageError);
|
||||
exchangeRates = { LAST_UPDATED_ERROR: true };
|
||||
throw storageError;
|
||||
}
|
||||
|
@ -186,58 +130,61 @@ async function updateExchangeRate(): Promise<void> {
|
|||
}
|
||||
|
||||
async function getPreferredCurrency(): Promise<FiatUnitType> {
|
||||
try {
|
||||
const preferredCurrencyString = await DefaultPreference.get(PREFERRED_CURRENCY_STORAGE_KEY);
|
||||
if (preferredCurrencyString) {
|
||||
try {
|
||||
if (!FiatUnit[preferredCurrencyString]) {
|
||||
throw new Error('Invalid Fiat Unit');
|
||||
}
|
||||
preferredFiatCurrency = FiatUnit[preferredCurrencyString];
|
||||
} catch (error) {
|
||||
console.error('Failed to parse preferred currency:', error);
|
||||
await DefaultPreference.clear(PREFERRED_CURRENCY_STORAGE_KEY);
|
||||
await DefaultPreference.clear(PREFERRED_CURRENCY_LOCALE_STORAGE_KEY);
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
const preferredCurrencyValue = await DefaultPreference.get(PREFERRED_CURRENCY_STORAGE_KEY);
|
||||
let preferredCurrency: string | null = null;
|
||||
|
||||
const deviceCurrencies = RNLocalize.getCurrencies();
|
||||
if (deviceCurrencies[0] && FiatUnit[deviceCurrencies[0]]) {
|
||||
preferredFiatCurrency = FiatUnit[deviceCurrencies[0]];
|
||||
} else {
|
||||
preferredFiatCurrency = FiatUnit.USD;
|
||||
}
|
||||
await setPreferredCurrency(preferredFiatCurrency);
|
||||
if (typeof preferredCurrencyValue === 'string') {
|
||||
preferredCurrency = preferredCurrencyValue;
|
||||
}
|
||||
|
||||
if (preferredCurrency) {
|
||||
let parsedPreferredCurrency;
|
||||
try {
|
||||
parsedPreferredCurrency = JSON.parse(preferredCurrency);
|
||||
if (!FiatUnit[parsedPreferredCurrency.endPointKey]) {
|
||||
throw new Error('Invalid Fiat Unit');
|
||||
}
|
||||
preferredFiatCurrency = FiatUnit[parsedPreferredCurrency.endPointKey];
|
||||
} catch (error) {
|
||||
await DefaultPreference.clear(PREFERRED_CURRENCY_STORAGE_KEY);
|
||||
|
||||
return preferredFiatCurrency;
|
||||
const deviceCurrencies = RNLocalize.getCurrencies();
|
||||
if (deviceCurrencies[0] && FiatUnit[deviceCurrencies[0]]) {
|
||||
preferredFiatCurrency = FiatUnit[deviceCurrencies[0]];
|
||||
} else {
|
||||
preferredFiatCurrency = FiatUnit.USD;
|
||||
}
|
||||
}
|
||||
|
||||
// If no preferred currency is set, determine based on device settings
|
||||
const deviceCurrencies = RNLocalize.getCurrencies();
|
||||
if (deviceCurrencies[0] && FiatUnit[deviceCurrencies[0]]) {
|
||||
preferredFiatCurrency = FiatUnit[deviceCurrencies[0]];
|
||||
} else {
|
||||
preferredFiatCurrency = FiatUnit.USD;
|
||||
}
|
||||
|
||||
await setPreferredCurrency(preferredFiatCurrency);
|
||||
return preferredFiatCurrency;
|
||||
} catch (error) {
|
||||
console.error('Failed to get preferred currency:', error);
|
||||
// Fallback to USD in case of error
|
||||
preferredFiatCurrency = FiatUnit.USD;
|
||||
await setPreferredCurrency(preferredFiatCurrency);
|
||||
await DefaultPreference.set(PREFERRED_CURRENCY_LOCALE_STORAGE_KEY, preferredFiatCurrency.locale.replace('-', '_'));
|
||||
return preferredFiatCurrency;
|
||||
}
|
||||
|
||||
const deviceCurrencies = RNLocalize.getCurrencies();
|
||||
if (deviceCurrencies[0] && FiatUnit[deviceCurrencies[0]]) {
|
||||
preferredFiatCurrency = FiatUnit[deviceCurrencies[0]];
|
||||
} else {
|
||||
preferredFiatCurrency = FiatUnit.USD;
|
||||
}
|
||||
|
||||
return preferredFiatCurrency;
|
||||
}
|
||||
|
||||
async function _restoreSavedExchangeRatesFromStorage(): Promise<void> {
|
||||
try {
|
||||
const ratesString = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
const ratesValue = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
let ratesString: string | null = null;
|
||||
|
||||
if (typeof ratesValue === 'string') {
|
||||
ratesString = ratesValue;
|
||||
}
|
||||
|
||||
if (ratesString) {
|
||||
try {
|
||||
exchangeRates = JSON.parse(ratesString);
|
||||
} catch (error) {
|
||||
console.error('Failed to parse exchange rates:', error);
|
||||
await DefaultPreference.clear(EXCHANGE_RATES_STORAGE_KEY);
|
||||
exchangeRates = { LAST_UPDATED_ERROR: false };
|
||||
await updateExchangeRate();
|
||||
|
@ -246,7 +193,6 @@ async function _restoreSavedExchangeRatesFromStorage(): Promise<void> {
|
|||
exchangeRates = { LAST_UPDATED_ERROR: false };
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to restore exchange rates:', error);
|
||||
exchangeRates = { LAST_UPDATED_ERROR: false };
|
||||
await updateExchangeRate();
|
||||
}
|
||||
|
@ -254,15 +200,25 @@ async function _restoreSavedExchangeRatesFromStorage(): Promise<void> {
|
|||
|
||||
async function _restoreSavedPreferredFiatCurrencyFromStorage(): Promise<void> {
|
||||
try {
|
||||
const storedCurrencyString = await DefaultPreference.get(PREFERRED_CURRENCY_STORAGE_KEY);
|
||||
if (!storedCurrencyString) throw new Error('No Preferred Fiat selected');
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
const storedCurrencyValue = await DefaultPreference.get(PREFERRED_CURRENCY_STORAGE_KEY);
|
||||
let storedCurrency: string | null = null;
|
||||
|
||||
if (typeof storedCurrencyValue === 'string') {
|
||||
storedCurrency = storedCurrencyValue;
|
||||
}
|
||||
|
||||
if (!storedCurrency) throw new Error('No Preferred Fiat selected');
|
||||
|
||||
let parsedCurrency;
|
||||
try {
|
||||
preferredFiatCurrency = FiatUnit[storedCurrencyString];
|
||||
parsedCurrency = JSON.parse(storedCurrency);
|
||||
if (!FiatUnit[parsedCurrency.endPointKey]) {
|
||||
throw new Error('Invalid Fiat Unit');
|
||||
}
|
||||
preferredFiatCurrency = FiatUnit[parsedCurrency.endPointKey];
|
||||
} catch (error) {
|
||||
console.error('Failed to parse stored currency:', error);
|
||||
await DefaultPreference.clear(PREFERRED_CURRENCY_STORAGE_KEY);
|
||||
await DefaultPreference.clear(PREFERRED_CURRENCY_LOCALE_STORAGE_KEY);
|
||||
|
||||
const deviceCurrencies = RNLocalize.getCurrencies();
|
||||
if (deviceCurrencies[0] && FiatUnit[deviceCurrencies[0]]) {
|
||||
|
@ -270,29 +226,32 @@ async function _restoreSavedPreferredFiatCurrencyFromStorage(): Promise<void> {
|
|||
} else {
|
||||
preferredFiatCurrency = FiatUnit.USD;
|
||||
}
|
||||
await setPreferredCurrency(preferredFiatCurrency);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to restore preferred fiat currency:', error);
|
||||
const deviceCurrencies = RNLocalize.getCurrencies();
|
||||
if (deviceCurrencies[0] && FiatUnit[deviceCurrencies[0]]) {
|
||||
preferredFiatCurrency = FiatUnit[deviceCurrencies[0]];
|
||||
} else {
|
||||
preferredFiatCurrency = FiatUnit.USD;
|
||||
}
|
||||
await setPreferredCurrency(preferredFiatCurrency);
|
||||
}
|
||||
}
|
||||
|
||||
async function isRateOutdated(): Promise<boolean> {
|
||||
try {
|
||||
const rateString = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
const rateValue = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
let rateString: string | null = null;
|
||||
|
||||
if (typeof rateValue === 'string') {
|
||||
rateString = rateValue;
|
||||
}
|
||||
|
||||
let rate;
|
||||
if (rateString) {
|
||||
try {
|
||||
rate = JSON.parse(rateString);
|
||||
} catch (parseError) {
|
||||
console.error('Failed to parse exchange rates:', parseError);
|
||||
await DefaultPreference.clear(EXCHANGE_RATES_STORAGE_KEY);
|
||||
rate = {};
|
||||
await updateExchangeRate();
|
||||
|
@ -301,8 +260,7 @@ async function isRateOutdated(): Promise<boolean> {
|
|||
rate = {};
|
||||
}
|
||||
return rate.LAST_UPDATED_ERROR || Date.now() - (rate[LAST_UPDATED] || 0) >= 31 * 60 * 1000;
|
||||
} catch (error) {
|
||||
console.error('Failed to determine if rate is outdated:', error);
|
||||
} catch {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -313,12 +271,12 @@ async function restoreSavedPreferredFiatCurrencyAndExchangeFromStorage(): Promis
|
|||
}
|
||||
|
||||
async function initCurrencyDaemon(clearLastUpdatedTime: boolean = false): Promise<void> {
|
||||
await restoreSavedPreferredFiatCurrencyAndExchangeFromStorage();
|
||||
await _restoreSavedExchangeRatesFromStorage();
|
||||
await _restoreSavedPreferredFiatCurrencyFromStorage();
|
||||
|
||||
if (clearLastUpdatedTime) {
|
||||
exchangeRates[LAST_UPDATED] = 0;
|
||||
lastTimeUpdateExchangeRateWasCalled = 0;
|
||||
await DefaultPreference.set(EXCHANGE_RATES_STORAGE_KEY, JSON.stringify(exchangeRates));
|
||||
}
|
||||
|
||||
await updateExchangeRate();
|
||||
|
@ -343,12 +301,12 @@ function satoshiToLocalCurrency(satoshi: number, format: boolean = true): string
|
|||
formattedAmount = convertedAmount.toPrecision(2);
|
||||
}
|
||||
|
||||
if (!format) return formattedAmount;
|
||||
if (format === false) return formattedAmount;
|
||||
|
||||
try {
|
||||
return getCurrencyFormatter().format(Number(formattedAmount));
|
||||
} catch (error) {
|
||||
console.error('Failed to format currency:', error);
|
||||
console.error(error);
|
||||
return formattedAmount;
|
||||
}
|
||||
}
|
||||
|
@ -360,13 +318,19 @@ function BTCToLocalCurrency(bitcoin: BigNumber.Value): string {
|
|||
|
||||
async function mostRecentFetchedRate(): Promise<CurrencyRate> {
|
||||
try {
|
||||
const currencyInformationString = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
const currencyInfoValue = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
let currencyInformationString: string | null = null;
|
||||
|
||||
if (typeof currencyInfoValue === 'string') {
|
||||
currencyInformationString = currencyInfoValue;
|
||||
}
|
||||
|
||||
let currencyInformation;
|
||||
if (currencyInformationString) {
|
||||
try {
|
||||
currencyInformation = JSON.parse(currencyInformationString);
|
||||
} catch (parseError) {
|
||||
console.error('Failed to parse exchange rates:', parseError);
|
||||
await DefaultPreference.clear(EXCHANGE_RATES_STORAGE_KEY);
|
||||
currencyInformation = {};
|
||||
await updateExchangeRate();
|
||||
|
@ -380,8 +344,7 @@ async function mostRecentFetchedRate(): Promise<CurrencyRate> {
|
|||
LastUpdated: currencyInformation[LAST_UPDATED] ? new Date(currencyInformation[LAST_UPDATED]) : null,
|
||||
Rate: rate ? getCurrencyFormatter().format(rate) : '...',
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch most recent rate:', error);
|
||||
} catch {
|
||||
return {
|
||||
LastUpdated: null,
|
||||
Rate: null,
|
||||
|
@ -417,7 +380,7 @@ function formatBTC(btc: BigNumber.Value): string {
|
|||
try {
|
||||
return getBTCFormatter().format(Number(btc));
|
||||
} catch (error) {
|
||||
console.error('Failed to format BTC:', error);
|
||||
console.error(error);
|
||||
return new BigNumber(btc).toFixed(8);
|
||||
}
|
||||
}
|
||||
|
@ -455,5 +418,4 @@ export {
|
|||
setPreferredCurrency,
|
||||
updateExchangeRate,
|
||||
formatBTC,
|
||||
migrateAsyncStorageToDefaultPreference,
|
||||
};
|
||||
|
|
|
@ -9,7 +9,7 @@ import { GROUP_IO_BLUEWALLET } from '../blue_modules/currency';
|
|||
export const getLNDHub = async (): Promise<string | undefined> => {
|
||||
try {
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
let value = await DefaultPreference.get(BlueApp.LNDHUB);
|
||||
let value = await DefaultPreference.get(BlueApp.LNDHUB) as string | null;
|
||||
|
||||
// If not found, check AsyncStorage and migrate it to DefaultPreference
|
||||
if (!value) {
|
||||
|
|
|
@ -155,7 +155,7 @@
|
|||
B4D0B2682C1DED67006B6B1B /* ReceiveMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4D0B2672C1DED67006B6B1B /* ReceiveMethod.swift */; };
|
||||
B4EE583C226703320003363C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B40D4E35225841ED00428FCC /* Assets.xcassets */; };
|
||||
B4EFF73B2C3F6C5E0095D655 /* MockData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4EFF73A2C3F6C5E0095D655 /* MockData.swift */; };
|
||||
C978A716948AB7DEC5B6F677 /* (null) in Frameworks */ = {isa = PBXBuildFile; };
|
||||
C978A716948AB7DEC5B6F677 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
@ -416,7 +416,7 @@
|
|||
files = (
|
||||
782F075B5DD048449E2DECE9 /* libz.tbd in Frameworks */,
|
||||
764B49B1420D4AEB8109BF62 /* libsqlite3.0.tbd in Frameworks */,
|
||||
C978A716948AB7DEC5B6F677 /* (null) in Frameworks */,
|
||||
C978A716948AB7DEC5B6F677 /* BuildFile in Frameworks */,
|
||||
17CDA0718F42DB2CE856C872 /* libPods-BlueWallet.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
|
@ -1,108 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1500"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B40D4E2F225841EC00428FCC"
|
||||
BuildableName = "BlueWalletWatch.app"
|
||||
BlueprintName = "BlueWalletWatch"
|
||||
ReferencedContainer = "container:BlueWallet.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "BlueWallet.app"
|
||||
BlueprintName = "BlueWallet"
|
||||
ReferencedContainer = "container:BlueWallet.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO"
|
||||
parallelizable = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B47B21E82B2128B8001F6690"
|
||||
BuildableName = "BlueWalletUITests.xctest"
|
||||
BlueprintName = "BlueWalletUITests"
|
||||
ReferencedContainer = "container:BlueWallet.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES"
|
||||
launchAutomaticallySubstyle = "8"
|
||||
notificationPayloadFile = "BlueWalletWatch Extension/PushNotificationPayload.apns">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B40D4E2F225841EC00428FCC"
|
||||
BuildableName = "BlueWalletWatch.app"
|
||||
BlueprintName = "BlueWalletWatch"
|
||||
ReferencedContainer = "container:BlueWallet.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
launchAutomaticallySubstyle = "8"
|
||||
notificationPayloadFile = "BlueWalletWatch Extension/PushNotificationPayload.apns">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B40D4E2F225841EC00428FCC"
|
||||
BuildableName = "BlueWalletWatch.app"
|
||||
BlueprintName = "BlueWalletWatch"
|
||||
ReferencedContainer = "container:BlueWallet.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
use
|
|
@ -70,7 +70,7 @@ export const removeBlockExplorer = async (): Promise<boolean> => {
|
|||
|
||||
export const getBlockExplorerUrl = async (): Promise<string> => {
|
||||
try {
|
||||
const url = await DefaultPreference.get(BLOCK_EXPLORER_STORAGE_KEY);
|
||||
const url = (await DefaultPreference.get(BLOCK_EXPLORER_STORAGE_KEY)) as string | null;
|
||||
return url ?? BLOCK_EXPLORERS.default.url;
|
||||
} catch (error) {
|
||||
console.error('Error getting block explorer:', error);
|
||||
|
|
8
package-lock.json
generated
8
package-lock.json
generated
|
@ -65,7 +65,7 @@
|
|||
"react-native-blue-crypto": "github:BlueWallet/react-native-blue-crypto#3cb5442",
|
||||
"react-native-camera-kit": "13.0.0",
|
||||
"react-native-crypto": "2.2.0",
|
||||
"react-native-default-preference": "1.4.4",
|
||||
"react-native-default-preference": "https://github.com/BlueWallet/react-native-default-preference.git#258a3f07a36b86d34d4d1b682e928bab5524cc8c",
|
||||
"react-native-device-info": "13.2.0",
|
||||
"react-native-document-picker": "9.3.1",
|
||||
"react-native-draggable-flatlist": "github:BlueWallet/react-native-draggable-flatlist#3a61627",
|
||||
|
@ -20579,9 +20579,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/react-native-default-preference": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/react-native-default-preference/-/react-native-default-preference-1.4.4.tgz",
|
||||
"integrity": "sha512-h0vtgiSKws3UmMRJykXAVM4ne1SgfoocUcoBD19ewRpQd6wqurE0HJRQGrSxcHK5LdKE7QPSIB1VX3YGIVS8Jg==",
|
||||
"version": "1.5.1",
|
||||
"resolved": "git+ssh://git@github.com/BlueWallet/react-native-default-preference.git#258a3f07a36b86d34d4d1b682e928bab5524cc8c",
|
||||
"integrity": "sha512-29z1QFauCI2UprTIfiB5wLvUTf46+ogiP/S0FbHvFjDPohAm+mdB4+sO1rzhdmbSbKCSuX9O9micBhyOh867ew==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react-native": ">=0.47.0"
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
"react-native-blue-crypto": "github:BlueWallet/react-native-blue-crypto#3cb5442",
|
||||
"react-native-camera-kit": "13.0.0",
|
||||
"react-native-crypto": "2.2.0",
|
||||
"react-native-default-preference": "1.4.4",
|
||||
"react-native-default-preference": "https://github.com/BlueWallet/react-native-default-preference.git#258a3f07a36b86d34d4d1b682e928bab5524cc8c",
|
||||
"react-native-device-info": "13.2.0",
|
||||
"react-native-document-picker": "9.3.1",
|
||||
"react-native-draggable-flatlist": "github:BlueWallet/react-native-draggable-flatlist#3a61627",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import DefaultPreference from 'react-native-default-preference';
|
||||
import assert from 'assert';
|
||||
|
||||
import {
|
||||
|
@ -8,24 +8,34 @@ import {
|
|||
LAST_UPDATED,
|
||||
PREFERRED_CURRENCY_STORAGE_KEY,
|
||||
setPreferredCurrency,
|
||||
GROUP_IO_BLUEWALLET,
|
||||
} from '../../blue_modules/currency';
|
||||
import { FiatUnit } from '../../models/fiatUnit';
|
||||
|
||||
jest.setTimeout(90 * 1000);
|
||||
|
||||
describe('currency', () => {
|
||||
it('fetches exchange rate and saves to AsyncStorage', async () => {
|
||||
beforeAll(async () => {
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await DefaultPreference.clearAll();
|
||||
});
|
||||
|
||||
it('fetches exchange rate and saves to DefaultPreference', async () => {
|
||||
await initCurrencyDaemon();
|
||||
let cur = await AsyncStorage.getItem(EXCHANGE_RATES_STORAGE_KEY);
|
||||
cur = JSON.parse(cur);
|
||||
let curString = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
let cur = JSON.parse(curString || '{}');
|
||||
assert.ok(Number.isInteger(cur[LAST_UPDATED]));
|
||||
assert.ok(cur[LAST_UPDATED] > 0);
|
||||
assert.ok(cur.BTC_USD > 0);
|
||||
|
||||
// now, setting other currency as default
|
||||
await AsyncStorage.setItem(PREFERRED_CURRENCY_STORAGE_KEY, JSON.stringify(FiatUnit.JPY));
|
||||
await DefaultPreference.set(PREFERRED_CURRENCY_STORAGE_KEY, JSON.stringify(FiatUnit.JPY));
|
||||
await initCurrencyDaemon(true);
|
||||
cur = JSON.parse(await AsyncStorage.getItem(EXCHANGE_RATES_STORAGE_KEY));
|
||||
curString = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
cur = JSON.parse(curString || '{}');
|
||||
assert.ok(cur.BTC_JPY > 0);
|
||||
|
||||
// now setting with a proper setter
|
||||
|
@ -33,25 +43,29 @@ describe('currency', () => {
|
|||
await initCurrencyDaemon(true);
|
||||
const preferred = await getPreferredCurrency();
|
||||
assert.strictEqual(preferred.endPointKey, 'EUR');
|
||||
cur = JSON.parse(await AsyncStorage.getItem(EXCHANGE_RATES_STORAGE_KEY));
|
||||
curString = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
cur = JSON.parse(curString || '{}');
|
||||
assert.ok(cur.BTC_EUR > 0);
|
||||
|
||||
// test Yadio rate source
|
||||
await setPreferredCurrency(FiatUnit.ARS);
|
||||
await initCurrencyDaemon(true);
|
||||
cur = JSON.parse(await AsyncStorage.getItem(EXCHANGE_RATES_STORAGE_KEY));
|
||||
curString = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
cur = JSON.parse(curString || '{}');
|
||||
assert.ok(cur.BTC_ARS > 0);
|
||||
|
||||
// test YadioConvert rate source
|
||||
await setPreferredCurrency(FiatUnit.LBP);
|
||||
await initCurrencyDaemon(true);
|
||||
cur = JSON.parse(await AsyncStorage.getItem(EXCHANGE_RATES_STORAGE_KEY));
|
||||
curString = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
cur = JSON.parse(curString || '{}');
|
||||
assert.ok(cur.BTC_LBP > 0);
|
||||
|
||||
// test Exir rate source
|
||||
await setPreferredCurrency(FiatUnit.IRT);
|
||||
await initCurrencyDaemon(true);
|
||||
cur = JSON.parse(await AsyncStorage.getItem(EXCHANGE_RATES_STORAGE_KEY));
|
||||
curString = await DefaultPreference.get(EXCHANGE_RATES_STORAGE_KEY);
|
||||
cur = JSON.parse(curString || '{}');
|
||||
assert.ok(cur.BTC_IRT > 0);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -72,9 +72,81 @@ jest.mock('react-native-quick-actions', () => {
|
|||
});
|
||||
|
||||
jest.mock('react-native-default-preference', () => {
|
||||
let mockPreferences = {};
|
||||
let currentSuiteName = 'default';
|
||||
|
||||
const getSuite = name => {
|
||||
if (!mockPreferences[name]) {
|
||||
mockPreferences[name] = {};
|
||||
}
|
||||
return mockPreferences[name];
|
||||
};
|
||||
|
||||
return {
|
||||
setName: jest.fn(),
|
||||
set: jest.fn(),
|
||||
setName: jest.fn(name => {
|
||||
currentSuiteName = name;
|
||||
if (!mockPreferences[name]) {
|
||||
mockPreferences[name] = {};
|
||||
}
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
getName: jest.fn(() => {
|
||||
return Promise.resolve(currentSuiteName);
|
||||
}),
|
||||
|
||||
get: jest.fn(key => {
|
||||
const suite = getSuite(currentSuiteName);
|
||||
return Promise.resolve(Object.prototype.hasOwnProperty.call(suite, key) ? suite[key] : null);
|
||||
}),
|
||||
|
||||
set: jest.fn((key, value) => {
|
||||
const suite = getSuite(currentSuiteName);
|
||||
suite[key] = value;
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
clear: jest.fn(key => {
|
||||
const suite = getSuite(currentSuiteName);
|
||||
delete suite[key];
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
getMultiple: jest.fn(keys => {
|
||||
const suite = getSuite(currentSuiteName);
|
||||
const values = keys.map(key => (Object.prototype.hasOwnProperty.call(suite, key) ? suite[key] : null));
|
||||
return Promise.resolve(values);
|
||||
}),
|
||||
|
||||
setMultiple: jest.fn(keyValuePairs => {
|
||||
const suite = getSuite(currentSuiteName);
|
||||
Object.entries(keyValuePairs).forEach(([key, value]) => {
|
||||
suite[key] = value;
|
||||
});
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
clearMultiple: jest.fn(keys => {
|
||||
const suite = getSuite(currentSuiteName);
|
||||
keys.forEach(key => delete suite[key]);
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
getAll: jest.fn(() => {
|
||||
const suite = getSuite(currentSuiteName);
|
||||
return Promise.resolve({ ...suite });
|
||||
}),
|
||||
|
||||
clearAll: jest.fn(() => {
|
||||
mockPreferences[currentSuiteName] = {};
|
||||
return Promise.resolve();
|
||||
}),
|
||||
|
||||
reset: jest.fn(() => {
|
||||
mockPreferences = {};
|
||||
currentSuiteName = 'default'; // Reset the current suite name
|
||||
return Promise.resolve();
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue