diff --git a/package.json b/package.json index 038626bf..08009685 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "minibits_wallet", - "version": "0.1.5-beta.19", + "version": "0.1.5-beta.20", "private": true, "scripts": { "android:clean": "cd android && ./gradlew clean", diff --git a/src/navigation/TabsNavigator.tsx b/src/navigation/TabsNavigator.tsx index 415848b4..74b32b23 100644 --- a/src/navigation/TabsNavigator.tsx +++ b/src/navigation/TabsNavigator.tsx @@ -20,7 +20,8 @@ import { ProfileScreen, WalletNameScreen, SettingsScreen, - MintsScreen, + MintsScreen, + MintInfoScreen, DeveloperScreen, SecurityScreen, PrivacyScreen, @@ -204,6 +205,7 @@ export type ContactsStackScreenProps = S export type SettingsStackParamList = { Settings: undefined Mints: {scannedMintUrl? : string} + MintInfo: {mintUrl : string} Security: undefined Privacy: undefined Update: { @@ -238,6 +240,7 @@ const SettingsNavigator = function SettingsNavigator() { > + diff --git a/src/screens/MintInfoScreen.tsx b/src/screens/MintInfoScreen.tsx new file mode 100644 index 00000000..13865091 --- /dev/null +++ b/src/screens/MintInfoScreen.tsx @@ -0,0 +1,189 @@ +import {observer} from 'mobx-react-lite' +import React, {FC, useEffect, useState} from 'react' +import {Alert, FlatList, TextStyle, View, ViewStyle} from 'react-native' +import {colors, spacing, useThemeColor} from '../theme' +import {SettingsStackScreenProps} from '../navigation' +import { + APP_ENV, + NATIVE_VERSION_ANDROID, + JS_BUNDLE_VERSION, + COMMIT, + MINIBITS_MINT_URL, + MINIBITS_RELAY_URL, + MINIBITS_NIP05_DOMAIN, + MINIBITS_SERVER_API_HOST +} from '@env' +import packageJson from '../../package.json' +import { + Icon, + ListItem, + Screen, + Text, + Card, + Loading, + ErrorModal, + InfoModal, + BottomModal, + Button, +} from '../components' +import {useHeader} from '../utils/useHeader' +import {useStores} from '../models' +import {translate} from '../i18n' +import AppError, { Err } from '../utils/AppError' +import {Database, KeyChain, log, MintClient, NostrClient} from '../services' +import {MMKVStorage} from '../services' +import {maxTransactionsInModel} from '../models/TransactionsStore' +import { LogLevel } from '../services/log/logTypes' +import { GetInfoResponse } from '@cashu/cashu-ts' +import { delay } from '../utils/utils' +import JSONTree from 'react-native-json-tree' +import { getSnapshot } from 'mobx-state-tree' +import { Mint } from '../models/Mint' +import useColorScheme from '../theme/useThemeColor' + +// refresh + +export const MintInfoScreen: FC> = observer(function MintInfoScreen(_props) { + const {navigation, route} = _props + useHeader({ + leftIcon: 'faArrowLeft', + onLeftPress: () => navigation.navigate('Settings'), + }) + + const {mintsStore} = useStores() + + const [isLoading, setIsLoading] = useState(false) + const [mintInfo, setMintInfo] = useState() + + const [error, setError] = useState() + const [info, setInfo] = useState('') + + useEffect(() => { + const getInfo = async () => { + try { + if(!route.params || !route.params.mintUrl) { + throw new AppError(Err.VALIDATION_ERROR, 'Missing mintUrl') + } + + log.trace('useEffect', {mintUrl: route.params.mintUrl}) + + setIsLoading(true) + const info = await MintClient.getMintInfo(route.params.mintUrl) + await delay(1000) + setMintInfo(info) + setIsLoading(false) + } catch (e: any) { + handleError(e) + } + } + getInfo() + }, []) + + + + const handleError = function (e: AppError): void { + setIsLoading(false) + setError(e) + } + + const headerBg = useThemeColor('header') + const iconSelectedColor = useThemeColor('button') + const iconColor = useThemeColor('textDim') + const labelColor = useThemeColor('textDim') + const colorScheme = useColorScheme() + + return ( + + + + + + + <> + ( + } + topSeparator={index === 0 ? false : true} + key={key} + /> + )) + ) : ( + isLoading && + )} + style={$card} + /> + + + + + } + /> + + + + + {error && } + {info && } + + + ) + }) + +const $screen: ViewStyle = { + flex: 1, +} + +const $headerContainer: TextStyle = { + alignItems: 'center', + padding: spacing.medium, + height: spacing.screenHeight * 0.1, +} + +const $contentContainer: TextStyle = { + flex: 1, + padding: spacing.extraSmall, + // alignItems: 'center', +} + +const $card: ViewStyle = { + marginBottom: 0, +} + +const $item: ViewStyle = { + paddingHorizontal: spacing.small, + paddingLeft: 0, +} + +const $rightContainer: ViewStyle = { + padding: spacing.extraSmall, + alignSelf: 'center', + marginLeft: spacing.small, +} + +const $buttonContainer: ViewStyle = { + flexDirection: 'row', + alignSelf: 'center', + alignItems: 'center', + marginTop: spacing.large, +} diff --git a/src/screens/Mints/MintListItem.tsx b/src/screens/Mints/MintListItem.tsx index 509f45b3..0323f037 100644 --- a/src/screens/Mints/MintListItem.tsx +++ b/src/screens/Mints/MintListItem.tsx @@ -31,7 +31,7 @@ export const MintListItem = observer(function(props: { rightIconColor={props.isBlocked ? iconBlockedColor : iconColor as string} onPress={props.onMintSelect ? () => props.onMintSelect(props.mint, props.mintBalance) : undefined} RightComponent={props.mintBalance && } - style={{paddingHorizontal: spacing.small}} + style={{paddingHorizontal: spacing.tiny}} containerStyle={{alignSelf: 'stretch'}} bottomSeparator={props.separator === 'bottom' || props.separator === 'both'} topSeparator={props.separator === 'top' || props.separator === 'both'} diff --git a/src/screens/MintsScreen.tsx b/src/screens/MintsScreen.tsx index d53d14e8..b2188c3e 100644 --- a/src/screens/MintsScreen.tsx +++ b/src/screens/MintsScreen.tsx @@ -73,6 +73,13 @@ export const MintsScreen: FC> = observer(funct navigation.navigate('WalletNavigator', {screen: 'Scan'}) } + + const gotoInfo = function () { + if(!selectedMint) {return} + navigation.navigate('MintInfo', {mintUrl: selectedMint?.mintUrl}) + onMintUnselect() + } + const addMint = async function () { setIsAddMintVisible(false) @@ -288,7 +295,7 @@ export const MintsScreen: FC> = observer(funct Alert.alert('Not yet implemented')} + onPress={gotoInfo} tx={'mintsScreen.mintInfo'} bottomSeparator={true} style={{paddingHorizontal: spacing.medium}} diff --git a/src/screens/WalletScreen.tsx b/src/screens/WalletScreen.tsx index b6e59384..db3cc4d1 100644 --- a/src/screens/WalletScreen.tsx +++ b/src/screens/WalletScreen.tsx @@ -357,6 +357,10 @@ export const WalletScreen: FC = observer( navigation.navigate('Scan') } + const gotoMintInfo = function (mintUrl: string) { + navigation.navigate('SettingsNavigator', {screen: 'MintInfo', params: {mintUrl}}) + } + const gotoTranHistory = function () { navigation.navigate('TranHistory') } @@ -468,7 +472,8 @@ export const WalletScreen: FC = observer( balance.mint.includes(mints.hostname))} + mintBalances={balances.mintBalances.filter(balance => balance.mint.includes(mints.hostname))} + gotoMintInfo={gotoMintInfo} /> {transactionsStore.recentByHostname(mints.hostname).length > 0 && ( } ContentComponent={ @@ -670,6 +676,7 @@ const MintsByHostnameListItem = observer(function (props: { } topSeparator={true} style={$item} + onPress={() => props.gotoMintInfo(mint.mintUrl)} /> ))} diff --git a/src/screens/index.ts b/src/screens/index.ts index a6087e98..7b7bdbc5 100644 --- a/src/screens/index.ts +++ b/src/screens/index.ts @@ -24,6 +24,7 @@ export * from './OwnKeysScreen' // SettingsNavigator export * from './SettingsScreen' export * from './MintsScreen' +export * from './MintInfoScreen' export * from './SecurityScreen' export * from './PrivacyScreen' export * from './UpdateScreen' diff --git a/src/services/cashuMintClient.ts b/src/services/cashuMintClient.ts index bcb91dee..e261428d 100644 --- a/src/services/cashuMintClient.ts +++ b/src/services/cashuMintClient.ts @@ -483,6 +483,29 @@ const restore = async function ( } } + +const getMintInfo = async function ( + mintUrl: string, +) { + try { + const cashuMint = getMint(mintUrl) + const info = await cashuMint.getInfo() + log.trace('[getMintInfo]', {info}) + return info + } catch (e: any) { + throw new AppError( + Err.MINT_ERROR, + 'The mint could not return mint information.', + { + caller: 'getMintInfo', + mintUrl, + message: e.message + } + ) + } +} + + export const MintClient = { getOrCreateMnemonic, getMnemonic, @@ -497,4 +520,5 @@ export const MintClient = { requestLightningInvoice, requestProofs, restore, + getMintInfo, }