mirror of
https://github.com/minibits-cash/minibits_wallet.git
synced 2026-10-05 19:28:26 +00:00
Fixes, set the first mint automatically and a lot of UX tuning
This commit is contained in:
@@ -96,7 +96,7 @@ android {
|
||||
applicationId "com.minibits_wallet"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 58001
|
||||
versionCode 58002
|
||||
versionName "0.1.9"
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "minibits_wallet",
|
||||
"version": "0.1.9-beta",
|
||||
"version": "0.1.9-beta.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"android:clean": "cd android && ./gradlew clean",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/node_modules/@scure/bip32/index.ts b/node_modules/@scure/bip32/index.ts
|
||||
index 51a702f..ac252b2 100644
|
||||
index 51a702f..a13bf43 100644
|
||||
--- a/node_modules/@scure/bip32/index.ts
|
||||
+++ b/node_modules/@scure/bip32/index.ts
|
||||
@@ -8,6 +8,7 @@ import { bytesToHex, concatBytes, createView, hexToBytes, utf8ToBytes } from '@n
|
||||
@@ -15,8 +15,8 @@ index 51a702f..ac252b2 100644
|
||||
);
|
||||
}
|
||||
- const I = hmac(sha512, MASTER_SECRET, seed);
|
||||
+ //const I = hmac(sha512, MASTER_SECRET, seed);
|
||||
+ console.log('[fromMasterSeed] Using patched hmac');
|
||||
+ // const I = hmac(sha512, MASTER_SECRET, seed);
|
||||
+ // console.log('[fromMasterSeed] Using patched hmac');
|
||||
+ const I = new Uint8Array(QuickCrypto.createHmac('sha512', MASTER_SECRET).update(seed).digest());
|
||||
return new HDKey({
|
||||
versions,
|
||||
@@ -28,7 +28,7 @@ index 51a702f..ac252b2 100644
|
||||
- const I = hmac(sha512, this.chainCode, data);
|
||||
+
|
||||
+ // const I = hmac(sha512, this.chainCode, data);
|
||||
+ console.log('[deriveChild] Using patched hmac');
|
||||
+ // console.log('[deriveChild] Using patched hmac');
|
||||
+ const I = new Uint8Array(QuickCrypto.createHmac('sha512', this.chainCode).update(data).digest());
|
||||
+
|
||||
const childTweak = bytesToNumber(I.slice(0, 32));
|
||||
|
||||
@@ -12,7 +12,7 @@ index a903f6e..0bc8651 100644
|
||||
"exports": {
|
||||
".": {
|
||||
diff --git a/node_modules/@scure/bip39/src/index.ts b/node_modules/@scure/bip39/src/index.ts
|
||||
index e6afe12..c1d593b 100644
|
||||
index e6afe12..c4546b4 100644
|
||||
--- a/node_modules/@scure/bip39/src/index.ts
|
||||
+++ b/node_modules/@scure/bip39/src/index.ts
|
||||
@@ -5,6 +5,7 @@ import { sha256 } from '@noble/hashes/sha256';
|
||||
@@ -26,10 +26,10 @@ index e6afe12..c1d593b 100644
|
||||
@@ -142,5 +143,8 @@ export function mnemonicToSeed(mnemonic: string, passphrase = '') {
|
||||
* // new Uint8Array([...64 bytes])
|
||||
*/
|
||||
export function mnemonicToSeedSync(mnemonic: string, passphrase = '') {
|
||||
export function mnemonicToSeedSync(mnemonic: string, passphrase = '') {
|
||||
- return pbkdf2(sha512, normalize(mnemonic).nfkd, salt(passphrase), { c: 2048, dkLen: 64 });
|
||||
+ const original = pbkdf2(sha512, normalize(mnemonic).nfkd, salt(passphrase), { c: 2048, dkLen: 64 });
|
||||
+ // const original = pbkdf2(sha512, normalize(mnemonic).nfkd, salt(passphrase), { c: 2048, dkLen: 64 });
|
||||
+ const updated = new Uint8Array(QuickCrypto.pbkdf2Sync(normalize(mnemonic).nfkd, salt(passphrase), 2048, 64, 'sha512'));
|
||||
+ console.log('[mnemonicToSeedSync] Using patched pbkdf2', {original, updated})
|
||||
+ console.log('[@scure.bip39.mnemonicToSeedSync] Patched to use QuickCrypto.pbkdf2Sync')
|
||||
+ return updated
|
||||
}
|
||||
|
||||
@@ -196,15 +196,11 @@ export const ProofsStoreModel = types
|
||||
|
||||
const rootStore = getRootStore(self)
|
||||
const count = proofsToRemove.length
|
||||
const {userSettingsStore} = rootStore
|
||||
|
||||
if (userSettingsStore.isLocalBackupOn === true) {
|
||||
// TODO refactor recovery to separate model method
|
||||
if(isRecoveredFromPending) {
|
||||
Database.addOrUpdateProofs(proofsToRemove, false, false) // isPending = false, isSpent = false
|
||||
} else {
|
||||
Database.addOrUpdateProofs(proofsToRemove, false, true) // isPending = false, isSpent = true
|
||||
}
|
||||
|
||||
if(isRecoveredFromPending) {
|
||||
Database.addOrUpdateProofs(proofsToRemove, false, false) // isPending = false, isSpent = false
|
||||
} else {
|
||||
Database.addOrUpdateProofs(proofsToRemove, false, true) // isPending = false, isSpent = true
|
||||
}
|
||||
|
||||
proofsToRemove.map((proof) => {
|
||||
|
||||
@@ -342,7 +342,7 @@ export const PrivateContacts = observer(function (props: {
|
||||
}
|
||||
value={newContactName}
|
||||
autoCapitalize="none"
|
||||
keyboardType="default"
|
||||
keyboardType="default"
|
||||
maxLength={80}
|
||||
selectTextOnFocus={true}
|
||||
style={[
|
||||
@@ -420,13 +420,15 @@ const $newContainer: TextStyle = {
|
||||
}
|
||||
|
||||
const $contactInput: TextStyle = {
|
||||
flex: 1,
|
||||
borderTopLeftRadius: spacing.extraSmall,
|
||||
borderBottomLeftRadius: spacing.extraSmall,
|
||||
fontSize: 16,
|
||||
flex: 1,
|
||||
// borderRadius: 0,
|
||||
// borderBottomRightRadius: spacing.extraSmall,
|
||||
// borderTopLeftRadius: spacing.extraSmall,
|
||||
fontSize: moderateVerticalScale(16),
|
||||
padding: spacing.small,
|
||||
alignSelf: 'stretch',
|
||||
textAlignVertical: 'top',
|
||||
// borderWidth: 1,
|
||||
}
|
||||
|
||||
const $contactDomain: TextStyle = {
|
||||
|
||||
@@ -180,6 +180,11 @@ export const MintsScreen: FC<SettingsStackScreenProps<'Mints'>> = observer(funct
|
||||
const removeMint = async function () {
|
||||
if (!selectedMint) {return}
|
||||
|
||||
if(mintsStore.allMints.length === 1) {
|
||||
setInfo('You need to keep at least 1 mint.')
|
||||
return
|
||||
}
|
||||
|
||||
const proofsByMint = proofsStore.getByMint(selectedMint.mintUrl, {isPending: false})
|
||||
const pendingProofsByMint = proofsStore.getByMint(selectedMint.mintUrl, {isPending: true})
|
||||
let message: string = ''
|
||||
@@ -205,7 +210,7 @@ export const MintsScreen: FC<SettingsStackScreenProps<'Mints'>> = observer(funct
|
||||
onPress: () => {
|
||||
try {
|
||||
onMintUnselect()
|
||||
toggleMintMenuModal()
|
||||
setIsMintMenuVisible(false)
|
||||
mintsStore.removeMint(selectedMint as Mint)
|
||||
if (proofsByMint && proofsByMint.length > 0) {
|
||||
proofsStore.removeProofs(proofsByMint)
|
||||
|
||||
@@ -321,8 +321,7 @@ export const ReceiveScreen: FC<WalletStackScreenProps<'Receive'>> = observer(
|
||||
return (
|
||||
<MintListItem
|
||||
key={mintUrl}
|
||||
mint={mint as Mint}
|
||||
separator={'top'}
|
||||
mint={mint as Mint}
|
||||
isSelected={true}
|
||||
isSelectable={true}
|
||||
/>
|
||||
|
||||
@@ -15,7 +15,7 @@ import {useHeader} from '../utils/useHeader'
|
||||
import {log} from '../services/logService'
|
||||
import { IncomingDataType, IncomingParser } from '../services/incomingParser'
|
||||
import AppError, { Err } from '../utils/AppError'
|
||||
import { BottomModal, Button, ErrorModal, Icon, Text } from '../components'
|
||||
import { BottomModal, Button, ErrorModal, Icon, Screen, Text } from '../components'
|
||||
import { LnurlUtils } from '../services/lnurl/lnurlUtils'
|
||||
import { infoMessage } from '../utils/utils'
|
||||
import Clipboard from '@react-native-clipboard/clipboard'
|
||||
@@ -212,12 +212,13 @@ export const ScanScreen: FC<WalletStackScreenProps<'Scan'>> = function ScanScree
|
||||
const inputBg = useThemeColor('background')
|
||||
|
||||
return (shouldLoad ? (
|
||||
<>
|
||||
<Screen contentContainerStyle={$screen}>
|
||||
<Camera
|
||||
cameraType={CameraType.Back}
|
||||
scanBarcode
|
||||
onReadCode={(event: any) => (isScanned ? undefined : onReadCode(event))}
|
||||
hideControls
|
||||
hideControls
|
||||
style={{flex: 1}}
|
||||
/>
|
||||
<View style={$bottomContainer}>
|
||||
{prevRouteName !== 'SendOptions' && (
|
||||
@@ -235,11 +236,15 @@ export const ScanScreen: FC<WalletStackScreenProps<'Scan'>> = function ScanScree
|
||||
)}
|
||||
</View>
|
||||
{error && <ErrorModal error={error} />}
|
||||
</>
|
||||
</Screen>
|
||||
) : null
|
||||
)
|
||||
}
|
||||
|
||||
const $screen: ViewStyle = {
|
||||
flex: 1,
|
||||
}
|
||||
|
||||
const $buttonContainer: ViewStyle = {
|
||||
flexDirection: 'row',
|
||||
alignSelf: 'center',
|
||||
|
||||
@@ -24,8 +24,6 @@ import {
|
||||
ImageStyle,
|
||||
Image,
|
||||
} from 'react-native'
|
||||
import Clipboard from '@react-native-clipboard/clipboard'
|
||||
import QRCode from 'react-native-qrcode-svg'
|
||||
import {spacing, typography, useThemeColor, colors} from '../theme'
|
||||
import {WalletStackScreenProps} from '../navigation'
|
||||
import {
|
||||
@@ -933,8 +931,11 @@ const SelectProofsBlock = observer(function (props: {
|
||||
<Button
|
||||
text={`Send to ${props.contactToSendTo.nip05}`}
|
||||
preset='secondary'
|
||||
onPress={props.toggleNostrDMModal}
|
||||
style={{maxHeight: 50}}
|
||||
onPress={props.toggleNostrDMModal}
|
||||
style={{
|
||||
minHeight: moderateVerticalScale(40),
|
||||
paddingVertical: moderateVerticalScale(spacing.tiny),
|
||||
}}
|
||||
LeftAccessory={() => (
|
||||
<Icon
|
||||
icon='faPaperPlane'
|
||||
@@ -947,8 +948,11 @@ const SelectProofsBlock = observer(function (props: {
|
||||
<Button
|
||||
text='Send to contact'
|
||||
preset='secondary'
|
||||
onPress={props.gotoContacts}
|
||||
style={{maxHeight: 50}}
|
||||
onPress={props.gotoContacts}
|
||||
style={{
|
||||
minHeight: moderateVerticalScale(40),
|
||||
paddingVertical: moderateVerticalScale(spacing.tiny),
|
||||
}}
|
||||
LeftAccessory={() => (
|
||||
<Icon
|
||||
icon='faPaperPlane'
|
||||
@@ -1215,7 +1219,7 @@ const $bottomContainer: ViewStyle = {
|
||||
right: 0,
|
||||
flex: 1,
|
||||
justifyContent: 'flex-end',
|
||||
marginBottom: spacing.medium,
|
||||
marginBottom: spacing.tiny,
|
||||
alignSelf: 'stretch',
|
||||
// opacity: 0,
|
||||
}
|
||||
|
||||
@@ -34,6 +34,13 @@ export const QRCodeBlock = function (props: {
|
||||
|
||||
if(decoded.token[0].proofs[0].id.startsWith('00')) {
|
||||
setKeysetFormat('hex')
|
||||
try {
|
||||
// make v4 default one
|
||||
const encodedV4 = CashuUtils.encodeToken(decoded, 4)
|
||||
setEncodedV4Token(encodedV4)
|
||||
} catch (e: any) {
|
||||
handleQrError(e)
|
||||
}
|
||||
} else {
|
||||
setKeysetFormat('base64')
|
||||
}
|
||||
@@ -63,7 +70,7 @@ export const QRCodeBlock = function (props: {
|
||||
infoMessage(translate('share.cancelled'))
|
||||
}
|
||||
} catch (e: any) {
|
||||
setQrError(e)
|
||||
handleQrError(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +92,7 @@ export const QRCodeBlock = function (props: {
|
||||
setEncodedV4Token(encodedV4)
|
||||
}
|
||||
} catch (e: any) {
|
||||
setQrError(e)
|
||||
handleQrError(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +101,7 @@ export const QRCodeBlock = function (props: {
|
||||
try {
|
||||
Clipboard.setString(encodedV4Token || qrCodeData as string)
|
||||
} catch (e: any) {
|
||||
setQrError(e)
|
||||
handleQrError(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+49
-101
@@ -39,7 +39,7 @@ import {useStores} from '../models'
|
||||
import {WalletStackScreenProps} from '../navigation'
|
||||
import {Mint, UnitBalance} from '../models/Mint'
|
||||
import {MintsByUnit} from '../models/MintsStore'
|
||||
import {Database, log, MinibitsClient, NostrClient} from '../services'
|
||||
import {log, NostrClient} from '../services'
|
||||
import {Env} from '../utils/envtypes'
|
||||
import {Transaction} from '../models/Transaction'
|
||||
import {TransactionListItem} from './Transactions/TransactionListItem'
|
||||
@@ -60,11 +60,7 @@ import { CurrencySign } from './Wallet/CurrencySign'
|
||||
import { CurrencyCode, MintUnit, MintUnitCurrencyPairs, convertToFromSats, getCurrency } from "../services/wallet/currency"
|
||||
import { CurrencyAmount } from './Wallet/CurrencyAmount'
|
||||
import { LeftProfileHeader } from './ContactsScreen'
|
||||
import { maxTransactionsByUnit } from '../models/TransactionsStore'
|
||||
import { NavigationState, Route, TabBar, TabView } from 'react-native-tab-view'
|
||||
import { NwcConnection, NwcConnectionModel } from '../models/NwcStore'
|
||||
import { getSnapshot } from 'mobx-state-tree'
|
||||
import { BackupProof, Proof } from '../models/Proof'
|
||||
|
||||
const deploymentKey = APP_ENV === Env.PROD ? CODEPUSH_PRODUCTION_DEPLOYMENT_KEY : CODEPUSH_STAGING_DEPLOYMENT_KEY
|
||||
|
||||
@@ -159,7 +155,11 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
return // skip further processing so that it does not slow down or clash deep link
|
||||
}
|
||||
|
||||
if(!isInternetReachable) { return }
|
||||
if(!isInternetReachable) { return }
|
||||
|
||||
if(groupedMints.length === 0) {
|
||||
await addMint()
|
||||
}
|
||||
|
||||
// check lnaddress claims on app start and set timestamp to trigger focus updates
|
||||
WalletTask.handleClaim().catch(e => setInfo(e.message))
|
||||
@@ -438,7 +438,7 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
<View style={[
|
||||
$headerContainer, {
|
||||
backgroundColor: headerBg,
|
||||
paddingTop: spacing.medium
|
||||
paddingTop: spacing.small,
|
||||
}
|
||||
]}>
|
||||
<UnitBalanceBlock
|
||||
@@ -472,7 +472,7 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
}
|
||||
/>
|
||||
}
|
||||
style={[$card, {paddingTop: spacing.extraSmall, maxHeight: spacing.screenHeight * 0.3}]}
|
||||
style={[$card, {paddingTop: spacing.extraSmall}]}
|
||||
/>
|
||||
) : (
|
||||
<Card
|
||||
@@ -506,20 +506,23 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
const tabWidth = moderateScale(80)
|
||||
|
||||
const getActiveTabColor = (state: NavigationState<Route>) => {
|
||||
switch (state.routes[tabIndex].key) {
|
||||
case 'usd':
|
||||
return useThemeColor('usd')
|
||||
case 'eur':
|
||||
return useThemeColor('eur')
|
||||
default:
|
||||
return useThemeColor('btc')
|
||||
}
|
||||
|
||||
if(state && state.routes.length > 0) {
|
||||
switch (state.routes[tabIndex].key) {
|
||||
case 'usd':
|
||||
return useThemeColor('usd')
|
||||
case 'eur':
|
||||
return useThemeColor('eur')
|
||||
default:
|
||||
return useThemeColor('btc')
|
||||
}
|
||||
}
|
||||
|
||||
return useThemeColor('btc')
|
||||
}
|
||||
|
||||
const renderTabBar = (props: any) => {
|
||||
return(
|
||||
<View style={{backgroundColor: headerBg, marginTop: -spacing.extraSmall}}>
|
||||
<View style={{backgroundColor: headerBg, marginTop: -spacing.small}}>
|
||||
<View style={{width: routes.length * tabWidth, alignSelf: 'center', backgroundColor: headerBg}}>
|
||||
<TabBar
|
||||
{...props}
|
||||
@@ -579,26 +582,19 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
</>
|
||||
}
|
||||
/>
|
||||
{groupedMints.length === 0 ? (
|
||||
<>
|
||||
<ZeroBalanceBlock/>
|
||||
<View style={$promoContainer}>
|
||||
<PromoBlock addMint={addMint} />
|
||||
</View>
|
||||
</>
|
||||
) : (
|
||||
{groupedMints.length > 0 && (
|
||||
<TabView
|
||||
renderTabBar={renderTabBar}
|
||||
navigationState={{ index: tabIndex, routes }}
|
||||
renderScene={renderUnitTabs}
|
||||
onIndexChange={onTabChange}
|
||||
initialLayout={{ width: spacing.screenWidth }}
|
||||
//style={{borderWidth: 1, borderColor: 'red'}}
|
||||
// style={{borderWidth: 1, borderColor: 'red'}}
|
||||
/>
|
||||
)}
|
||||
<View style={[$bottomContainer, {maxHeight: spacing.screenHeight * 0.3}]}>
|
||||
<View style={[$bottomContainer, {minHeight: spacing.screenHeight * 0.26}]}>
|
||||
{isNwcVisible && (
|
||||
<View>
|
||||
<View style={{flex : 1, justifyContent: 'flex-start', marginBottom: spacing.medium}}>
|
||||
<FlatList
|
||||
data={nwcCardsData}
|
||||
horizontal={true}
|
||||
@@ -608,7 +604,7 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
HeadingComponent={<Text text={item.name} size='xs'/>}
|
||||
ContentComponent={
|
||||
<>
|
||||
<Text text='Spent today' size='xxs' preset='formHelper' style={{color: label}}/>
|
||||
<Text text='Spent today' size='xxs' preset='formHelper' style={{color: label, overflow: 'hidden'}}/>
|
||||
<CurrencyAmount
|
||||
amount={210}
|
||||
currencyCode={CurrencyCode.SAT}
|
||||
@@ -618,10 +614,8 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
</>
|
||||
}
|
||||
style={{
|
||||
width: spacing.screenWidth * 0.3,
|
||||
height: spacing.screenWidth * 0.3,
|
||||
marginRight: spacing.small,
|
||||
marginVertical: spacing.small
|
||||
width: spacing.screenWidth * 0.28,
|
||||
marginRight: spacing.small,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
@@ -639,12 +633,12 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
<Icon
|
||||
icon='faArrowUp'
|
||||
size={spacing.medium}
|
||||
color={mainButtonIcon}
|
||||
//style={{paddingLeft: spacing.medium}}
|
||||
color={mainButtonIcon}
|
||||
/>
|
||||
)}
|
||||
onPress={toggleSendModal}
|
||||
style={[{backgroundColor: mainButtonColor, borderWidth: 1, borderColor: screenBg}, $buttonTopup]}
|
||||
style={[{backgroundColor: mainButtonColor, borderWidth: 1, borderColor: screenBg}, $buttonSend]}
|
||||
textStyle={{marginRight: spacing.tiny}}
|
||||
preset='secondary'
|
||||
tx='payCommon.send'
|
||||
/>
|
||||
@@ -667,11 +661,13 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
icon='faArrowDown'
|
||||
size={spacing.medium}
|
||||
color={mainButtonIcon}
|
||||
containerStyle={{paddingLeft: spacing.tiny}}
|
||||
/>
|
||||
)}
|
||||
onPress={toggleReceiveModal}
|
||||
tx='payCommon.receive'
|
||||
style={[{backgroundColor: mainButtonColor, borderWidth: 1, borderColor: screenBg}, $buttonPay]}
|
||||
style={[{backgroundColor: mainButtonColor, borderWidth: 1, borderColor: screenBg}, $buttonReceive]}
|
||||
textStyle={{marginLeft: spacing.tiny}}
|
||||
preset='secondary'
|
||||
/>
|
||||
</View>
|
||||
@@ -827,53 +823,6 @@ const ZeroBalanceBlock = function () {
|
||||
)
|
||||
}
|
||||
|
||||
const PromoBlock = function (props: {addMint: any}) {
|
||||
return (
|
||||
<Card
|
||||
HeadingComponent={
|
||||
<View style={$promoIconContainer}>
|
||||
<View
|
||||
style={{
|
||||
flex: 0,
|
||||
borderRadius: spacing.small,
|
||||
padding: spacing.extraSmall,
|
||||
backgroundColor: colors.palette.orange600
|
||||
}}
|
||||
>
|
||||
<SvgXml
|
||||
width={spacing.extraLarge}
|
||||
height={spacing.extraLarge}
|
||||
xml={MintIcon}
|
||||
fill='white'
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
}
|
||||
ContentComponent={
|
||||
<View style={{flexDirection: 'row'}}>
|
||||
<RNText style={$promoText}>
|
||||
Add{' '}
|
||||
<Text
|
||||
text='Minibits'
|
||||
style={{fontFamily: 'Gluten-Regular', fontSize: 18}}
|
||||
/>{' '}
|
||||
as your first mint to start!
|
||||
</RNText>
|
||||
</View>
|
||||
}
|
||||
style={[$card, {marginTop: spacing.small}]}
|
||||
FooterComponent={
|
||||
<View style={{alignItems: 'center'}}>
|
||||
<Button
|
||||
preset='default'
|
||||
onPress={props.addMint}
|
||||
tx="walletScreen.addFirstMint"
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const MintsByUnitSummary = observer(function (props: {
|
||||
@@ -1150,29 +1099,28 @@ const $balance: TextStyle = {
|
||||
fontFamily: typography.primary?.medium,
|
||||
}
|
||||
|
||||
const $bottomContainer: ViewStyle = {
|
||||
flexGrow: 0,
|
||||
// justifyContent: 'flex-end',
|
||||
marginHorizontal: spacing.extraSmall,
|
||||
// alignItems: 'center',
|
||||
const $bottomContainer: ViewStyle = {
|
||||
justifyContent: 'flex-end',
|
||||
paddingHorizontal: spacing.extraSmall,
|
||||
// alignSelf: 'stretch',
|
||||
// opacity: 0,
|
||||
}
|
||||
|
||||
const $buttonContainer: ViewStyle = {
|
||||
flexDirection: 'row',
|
||||
marginBottom: spacing.tiny,
|
||||
// marginBottom: spacing.tiny,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
alignItems: 'center',
|
||||
}
|
||||
|
||||
const $buttonTopup: ViewStyle = {
|
||||
const $buttonSend: ViewStyle = {
|
||||
borderTopLeftRadius: moderateVerticalScale(60 / 2),
|
||||
borderBottomLeftRadius: moderateVerticalScale(60 / 2),
|
||||
borderTopRightRadius: 0,
|
||||
borderBottomRightRadius: 0,
|
||||
width: moderateVerticalScale(150),
|
||||
height: moderateVerticalScale(60),
|
||||
marginRight: -25,
|
||||
width: moderateVerticalScale(130),
|
||||
height: moderateVerticalScale(55),
|
||||
marginRight: moderateVerticalScale(-25),
|
||||
}
|
||||
|
||||
const $buttonScan: ViewStyle = {
|
||||
@@ -1182,14 +1130,14 @@ const $buttonScan: ViewStyle = {
|
||||
zIndex: 99,
|
||||
}
|
||||
|
||||
const $buttonPay: ViewStyle = {
|
||||
const $buttonReceive: ViewStyle = {
|
||||
borderTopLeftRadius: 0,
|
||||
borderBottomLeftRadius: 0,
|
||||
borderTopRightRadius: moderateVerticalScale(30),
|
||||
borderBottomRightRadius: moderateVerticalScale(30),
|
||||
width: moderateVerticalScale(150),
|
||||
height: moderateVerticalScale(60),
|
||||
marginLeft: -25,
|
||||
width: moderateVerticalScale(130),
|
||||
height: moderateVerticalScale(55),
|
||||
marginLeft: moderateVerticalScale(-15),
|
||||
}
|
||||
|
||||
const $bottomModal: ViewStyle = {
|
||||
@@ -1206,5 +1154,5 @@ const $offline: TextStyle = {
|
||||
marginVertical: spacing.small,
|
||||
lineHeight: spacing.medium,
|
||||
backgroundColor: colors.palette.orange400,
|
||||
color: 'white',
|
||||
color: 'white'
|
||||
}
|
||||
|
||||
@@ -23,12 +23,15 @@ import {
|
||||
Button,
|
||||
ErrorModal,
|
||||
Icon,
|
||||
InfoModal,
|
||||
Loading,
|
||||
Screen,
|
||||
Text,
|
||||
} from '../components'
|
||||
import {TxKeyPath, translate} from '../i18n'
|
||||
import AppError from '../utils/AppError'
|
||||
import { MINIBITS_MINT_URL } from '@env'
|
||||
import useIsInternetReachable from '../utils/useIsInternetReachable'
|
||||
|
||||
|
||||
const AnimatedPagerView = Animated.createAnimatedComponent(PagerView)
|
||||
@@ -81,14 +84,27 @@ export const WelcomeScreen: FC<AppStackScreenProps<'Welcome'>> =
|
||||
//StatusBarProps: {barStyle: 'dark-content'},
|
||||
})
|
||||
|
||||
const {userSettingsStore, relaysStore, walletProfileStore, walletStore} = useStores()
|
||||
// const {walletStore} = nonPersistedStores
|
||||
const [error, setError] = useState<AppError | undefined>()
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false)
|
||||
const {
|
||||
userSettingsStore,
|
||||
relaysStore,
|
||||
walletProfileStore,
|
||||
walletStore,
|
||||
mintsStore
|
||||
} = useStores()
|
||||
|
||||
const isInternetReachable = useIsInternetReachable()
|
||||
|
||||
const [error, setError] = useState<AppError | undefined>()
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false)
|
||||
const [info, setInfo] = useState<string>('')
|
||||
|
||||
const gotoWallet = async function () {
|
||||
try {
|
||||
if(!isInternetReachable) {
|
||||
setInfo('Please make sure you are online to set up the new wallet.')
|
||||
return
|
||||
}
|
||||
|
||||
// do not overwrite if one was set during recovery
|
||||
setIsLoading(true)
|
||||
const mnemonic = await walletStore.getOrCreateMnemonic()
|
||||
@@ -99,8 +115,10 @@ export const WelcomeScreen: FC<AppStackScreenProps<'Welcome'>> =
|
||||
await walletProfileStore.create(walletId as string)
|
||||
}
|
||||
|
||||
userSettingsStore.setIsOnboarded(true)
|
||||
relaysStore.addDefaultRelays()
|
||||
await mintsStore.addMint(MINIBITS_MINT_URL)
|
||||
relaysStore.addDefaultRelays()
|
||||
|
||||
userSettingsStore.setIsOnboarded(true)
|
||||
navigation.navigate('Tabs')
|
||||
setIsLoading(false)
|
||||
} catch (e: any) {
|
||||
@@ -247,6 +265,7 @@ export const WelcomeScreen: FC<AppStackScreenProps<'Welcome'>> =
|
||||
</View>
|
||||
</View>
|
||||
{error && <ErrorModal error={error} />}
|
||||
{info && <InfoModal message={info} />}
|
||||
{isLoading && <Loading statusMessage={translate("welcomeScreen.generatingWalletSeedStatusMessage")} style={{backgroundColor: headerBg, opacity: 1}} textStyle={{color: 'white'}}/>}
|
||||
</Screen>
|
||||
)
|
||||
|
||||
@@ -171,7 +171,7 @@ const encodeToken = function (token: TokenV3, version: 3 | 4 = 3): string {
|
||||
t: v4tokenEntries
|
||||
}
|
||||
|
||||
log.trace('[encodeToken]', {v4Token})
|
||||
// log.trace('[encodeToken]', {v4Token})
|
||||
|
||||
const encodedCbor = cbor.encode(v4Token)
|
||||
return 'cashuB' + base64urlFromBase64(encodeUint8toBase64(encodedCbor))
|
||||
|
||||
@@ -4,7 +4,8 @@ import {
|
||||
getSignature,
|
||||
SimplePool,
|
||||
validateEvent,
|
||||
utils
|
||||
utils,
|
||||
nip04
|
||||
} from 'nostr-tools'
|
||||
import type {
|
||||
Event as NostrEvent,
|
||||
@@ -158,24 +159,12 @@ const encryptNip04 = async function (
|
||||
): Promise<string> {
|
||||
try {
|
||||
const keys: KeyPair = await getOrCreateKeyPair()
|
||||
const encryptedContent = await nip04.encrypt(keys.privateKey, receiverPubkey, content)
|
||||
|
||||
const key = secp256k1.getSharedSecret(keys.privateKey, '02' + receiverPubkey)
|
||||
const normalizedKey = getNormalizedX(key)
|
||||
const iv = QuickCrypto.randomFillSync(new Uint8Array(16))
|
||||
|
||||
const cipher = QuickCrypto.createCipheriv(
|
||||
'aes-256-cbc',
|
||||
Buffer.from(normalizedKey),
|
||||
iv
|
||||
)
|
||||
return encryptedContent
|
||||
|
||||
let encryptedMessage = cipher.update(content, 'utf8', 'base64')
|
||||
encryptedMessage += cipher.final('base64')
|
||||
let ivBase64 = Buffer.from(iv.buffer).toString('base64')
|
||||
|
||||
return encryptedMessage + '?iv=' + ivBase64
|
||||
} catch (e: any) {
|
||||
throw new AppError(Err.KEYCHAIN_ERROR, e.message)
|
||||
throw new AppError(Err.CONNECTION_ERROR, e.message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,27 +175,11 @@ const decryptNip04 = async function(
|
||||
): Promise<string> {
|
||||
|
||||
const keys: KeyPair = await getOrCreateKeyPair()
|
||||
const key = secp256k1.getSharedSecret(keys.privateKey, '02' + senderPubKey)
|
||||
const normalizedKey = getNormalizedX(key)
|
||||
|
||||
const parts = encryptedContent.split('?')
|
||||
if (parts.length !== 2) {
|
||||
throw new Error('Invalid encrypted content format')
|
||||
}
|
||||
|
||||
const ciphertext = Buffer.from(parts[0], 'base64')
|
||||
const iv = Buffer.from(parts[1].substring(3), 'base64') // remove 'iv='
|
||||
|
||||
const decipher = QuickCrypto.createDecipheriv(
|
||||
'aes-256-cbc',
|
||||
Buffer.from(normalizedKey),
|
||||
iv
|
||||
)
|
||||
|
||||
let decryptedText = decipher.update(ciphertext, 'base64', 'utf8')
|
||||
decryptedText += decipher.final('utf8')
|
||||
|
||||
return decryptedText as string
|
||||
const decryptedContent = nip04.decrypt(keys.privateKey, senderPubKey, encryptedContent)
|
||||
|
||||
log.trace('[decryptNip04]', {decryptedContent})
|
||||
|
||||
return decryptedContent
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -388,7 +388,7 @@ export const colors = {
|
||||
/**
|
||||
* The default bg color of the primary button.
|
||||
*/
|
||||
buttonPressed: palette.success200,
|
||||
buttonPressed: palette.gold200,
|
||||
/**
|
||||
* The default bg color of the primary button.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user