Fixes, set the first mint automatically and a lot of UX tuning

This commit is contained in:
minibits-cash
2024-09-28 01:43:00 +02:00
parent 3aa8bf5bfd
commit f7fa5d8a24
16 changed files with 145 additions and 187 deletions
+1 -1
View File
@@ -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
View File
@@ -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",
+4 -4
View File
@@ -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));
+4 -4
View File
@@ -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
}
+5 -9
View File
@@ -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) => {
+7 -5
View File
@@ -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 = {
+6 -1
View File
@@ -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)
+1 -2
View File
@@ -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}
/>
+9 -4
View File
@@ -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',
+11 -7
View File
@@ -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,
}
+10 -3
View File
@@ -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
View File
@@ -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'
}
+25 -6
View File
@@ -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>
)
+1 -1
View File
@@ -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))
+10 -37
View File
@@ -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
View File
@@ -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.
*/