Skip to content

Commit

Permalink
Set up i18n in mobile wallet
Browse files Browse the repository at this point in the history
Related to #562
  • Loading branch information
nop33 committed Jun 14, 2024
1 parent d98873c commit c486e2f
Show file tree
Hide file tree
Showing 53 changed files with 808 additions and 336 deletions.
4 changes: 3 additions & 1 deletion apps/mobile-wallet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import './shim'
import '~/i18n'

import { registerRootComponent } from 'expo'

import App from './src/App'
import App from '~/App'

registerRootComponent(App)
201 changes: 201 additions & 0 deletions apps/mobile-wallet/locales/en-US/translation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
{
"Could not find address in store: {{ address }}": "Could not find address in store: {{ address }}",
"Color": "Color",
"Pending transactions": "Pending transactions",
"You reached the end of the transactions history.": "You reached the end of the transactions history.",
"Confirmed transactions": "Confirmed transactions",
"No transactions yet": "No transactions yet",
"No NFTs yet": "No NFTs yet",
"group {{ groupNumber }}": "group {{ groupNumber }}",
"Group {{ groupNumber }}": "Group {{ groupNumber }}",
"numberOfNFTsInCollections": "+<1>{{ nftsNumber }}</1>NFTs in <1>{{ nftsCollectionsNumber }}</1> collections",
"Updating default address": "Updating default address",
"Tokens": "Tokens",
"NFTs": "NFTs",
"Receive": "Receive",
"Receive assets": "Receive assets",
"Received": "Received",
"Send": "Send",
"Sending": "Sending",
"Sent": "Sent",
"Send funds": "Send funds",
"Moved": "Moved",
"Pending": "Pending",
"Are you sure?": "Are you sure?",
"If you don't turn on biometrics, anyone who gains access to your device can open the app and steal your funds.": "If you don't turn on biometrics, anyone who gains access to your device can open the app and steal your funds.",
"Cancel": "Cancel",
"Disable": "Disable",
"Consolidation required": "Consolidation required",
"It appers that the address you use to send funds from has too many UTXOs! Would you like to consolidate them? This will cost as small fee.": "It appers that the address you use to send funds from has too many UTXOs! Would you like to consolidate them? This will cost as small fee.",
"Consolidate": "Consolidate",
"Fee": "Fee",
"Estimated fees": "Estimated fees",
"Please enter your pin": "Please enter your pin",
"Missing wallet": "Missing wallet",
"Could not find wallet to authenticate. Please, restart the app.": "Could not find wallet to authenticate. Please, restart the app.",
"Loading wallet": "Loading wallet",
"Advanced options": "Advanced options",
"Genesis TX": "Genesis TX",
"Mining Rewards": "Mining Rewards",
"Scan progress": "Scan progress",
"Camera permissions required": "Camera permissions required",
"Please, enable access to camera through the settings of your device.": "Please, enable access to camera through the settings of your device.",
"Start entering your phrase": "Start entering your phrase",
"No metadata": "No metadata",
"See in explorer": "See in explorer",
"Your address does not have enough balance for this transaction.": "Your address does not have enough balance for this transaction.",
"Error while parsing WalletConnect session request": "Error while parsing WalletConnect session request",
"Could not connect": "Could not connect",
"This WalletConnect session is not valid anymore.": "This WalletConnect session is not valid anymore.",
"Try to refresh the dApp and connect again.": "Try to refresh the dApp and connect again.",
"Could not approve": "Could not approve",
"Expected exactly 1 required chain in the WalletConnect proposal, got {{ numberOfChains }}": "Expected exactly 1 required chain in the WalletConnect proposal, got {{ numberOfChains }}",
"Could not find chain requirements in WalletConnect proposal": "Could not find chain requirements in WalletConnect proposal",
"WalletConnect requested the {{ requestedNetwork }} network, but the current network is {{ currentNetwork }}.": "WalletConnect requested the {{ requestedNetwork }} network, but the current network is {{ currentNetwork }}.",
"The group of the selected address ({{ selectedAddressGroup }}) does not match the group required by WalletConnect ({{ requiredGroup }})": "The group of the selected address ({{ selectedAddressGroup }}) does not match the group required by WalletConnect ({{ requiredGroup }})",
"dApp request approved": "dApp request approved",
"You can go back to your browser.": "You can go back to your browser.",
"dApp request rejected": "dApp request rejected",
"Experimental feature": "Experimental feature",
"WalletConnect is an experimental feature. You can enable it in the settings.": "WalletConnect is an experimental feature. You can enable it in the settings.",
"Generate": "Generate",
"Generate new address": "Generate new address",
"Generating new address": "Generating new address",
"Default": "Default",
"Default address": "Default address",
"New address": "New address",
"Default address for operations": "Default address for operations",
"To remove this address from being the default address, you must set another one as main first.": "To remove this address from being the default address, you must set another one as main first.",
"Addresses": "Addresses",
"Addresses in group {{ groupNumber }}": "Addresses in group {{ groupNumber }}",
"Your addresses": "Your addresses",
"Address settings": "Address settings",
"Address group": "Address group",
"Contacts": "Contacts",
"Connect to dApp": "Connect to dApp",
"Switch network": "Switch network",
"Approve": "Approve",
"Decline": "Decline",
"Accept": "Accept",
"Reject": "Reject",
"Sign": "Sign",
"Submit": "Submit",
"Continue": "Continue",
"Delete": "Delete",
"Deleted": "Deleted",
"Save": "Save",
"Saving address": "Saving address",
"Saved!": "Saved!",
"Copy address": "Copy address",
"Edit": "Edit",
"Share": "Share",
"Share contact": "Share contact",
"Deleting contact": "Deleting contact",
"Edit contact": "Edit contact",
"Saving contact": "Saving contact",
"New contact": "New contact",
"dAppRequiredNetwork": "You are currently connected to <1>{{ currentNetwork }}</1>, but the dApp requires a connection to <1>{{ requiredNetwork }}</1>.",
"dAppRequiredGroup": "The dApp asks for an address in group <1>{{ group }}</1>. Click below to generate one!",
"Tap to select another one": "Tap to select another one",
"If none of the above addresses fit your needs, you can generate a new one.": "If none of the above addresses fit your needs, you can generate a new one.",
"Connect with address": "Connect with address",
"Tap to change the address to connect with.": "Tap to change the address to connect with.",
"Transfer request": "Transfer request",
"Smart contract request": "Smart contract request",
"Sign message": "Sign message",
"Sign unsigned transaction": "Sign unsigned transaction",
"from {{ url }}": "from {{ url }}",
"Signing with": "Signing with",
"From": "From",
"To": "To",
"Initial amount": "Initial amount",
"Issue token amount": "Issue token amount",
"Bytecode": "Bytecode",
"Unsigned TX ID": "Unsigned TX ID",
"Unsigned TX": "Unsigned TX",
"Message": "Message",
"Fast": "Fast",
"{{ seconds }} seconds": "{{ seconds }} seconds",
"Never": "Never",
"Provided fund password is wrong": "Provided fund password is wrong",
"Password is wrong": "Password is wrong",
"Fund password": "Fund password",
"New fund password": "New fund password",
"Confirm fund password": "Confirm fund password",
"Confirm new fund password": "Confirm new fund password",
"Please, enter your fund password.": "Please, enter your fund password.",
"To enhance your security it is recommended to use a fund password.": "To enhance your security it is recommended to use a fund password.",
"Later": "Later",
"Set fund password": "Set fund password",
"Pin replaced by fund password": "Pin replaced by fund password",
"Set password": "Set password",
"fundPasswordModalDescription": "The <1>fund password</1> is an additional authentication layer for critical operations involving the safety of your funds such as <1>revealing your seed phrase</1> or <1>sending funds</1>.\nYou can set it up in the app settings.",
"New passwords don't match": "New passwords don't match",
"Fund password was updated.": "Fund password was updated.",
"Fund password was set up.": "Fund password was set up.",
"Updated fund password": "Updated fund password",
"Created fund password": "Created fund password",
"Delete fund password": "Delete fund password",
"Fund password was deleted.": "Fund password was deleted.",
"You can set a new password below. This password will be required for critical operations involving the safety of your funds and cannot be recovered.": "You can set a new password below. This password will be required for critical operations involving the safety of your funds and cannot be recovered.",
"The fund password acts as an additional authentication layer for critical operations involving the safety of your funds such as revealing your secret recovery phrase or sending funds.": "The fund password acts as an additional authentication layer for critical operations involving the safety of your funds such as revealing your secret recovery phrase or sending funds.",
"Edit password": "Edit password",
"Disable password": "Disable password",
"dApp": "dApp",
"Overview": "Overview",
"Transfers": "Transfers",
"Unlock your wallet": "Unlock your wallet",
"Authentication required": "Authentication required",
"Exit the app and try again.": "Exit the app and try again.",
"Could not unlock app": "Could not unlock app",
"Could not build transaction": "Could not build transaction",
"Could not send transaction": "Could not send transaction",
"Could not sign message": "Could not sign message",
"Could not sign unsigned transaction": "Could not sign unsigned transaction",
"Could not delete contact": "Could not delete contact",
"Could not save contact": "Could not save contact",
"Could not get stored wallet": "Could not get stored wallet",
"Could not get address public key": "Could not get address public key",
"Could not get address private key": "Could not get address private key",
"Could not generate address public key": "Could not generate address public key",
"Could not generate address private key": "Could not generate address private key",
"Could not find a contact with this ID": "Could not find a contact with this ID",
"Could not find stored wallet": "Could not find stored wallet",
"Could not migrate address metadata": "Could not migrate address metadata",
"Could not export mnemonic": "Could not export mnemonic",
"Could not persist contact": "Could not persist contact",
"Could not persist addresses metadata": "Could not persist addresses metadata",
"Could not persist wallet metadata: No entry found in storage": "Could not persist wallet metadata: No entry found in storage",
"Could not initialize keyring": "Could not initialize keyring",
"Could not edit address settings": "Could not edit address settings",
"Could not save new address": "Could not save new address",
"A contact with this address already exists": "A contact with this address already exists",
"A contact with this name already exists": "A contact with this name already exists",
"Wallet metadata not found": "Wallet metadata not found",
"Address metadata not found": "Address metadata not found",
"This field is required": "This field is required",
"Label": "Label",
"Contact name": "Contact name",
"Contact address": "Contact address",
"Are you sure you want to delete this contact?": "Are you sure you want to delete this contact?",
"Show secret recovery phrase": "Show secret recovery phrase",
"Verify secret phrase": "Verify secret phrase",
"In the following screens you will see and verify your secret recover phrase.": "In the following screens you will see and verify your secret recover phrase.",
"Write it down and store it in a safe place.": "Write it down and store it in a safe place.",
"Why is this important?": "Why is this important?",
"Well done!": "Well done!",
"Enjoy your new (backed-up) wallet!": "Enjoy your new (backed-up) wallet!",
"Return to my wallet": "Return to my wallet",
"Could not confirm backup": "Could not confirm backup",
"Please, verify that you wrote your secret phrase down correctly and try again.": "Please, verify that you wrote your secret phrase down correctly and try again.",
"Select the words of your secret recovery phrase in the right order.": "Select the words of your secret recovery phrase in the right order.",
"This is not the word in position {{ positionIndex }}": "This is not the word in position {{ positionIndex }}",
"Word {{ wordIndex }} is:": "Word {{ wordIndex }} is:",
"VALUE TODAY": "VALUE TODAY",
"There is so much left to discover!": "There is so much left to discover!",
"Hello there!": "Hello there!",
"Let's verify!": "Let's verify!",
"Let's do that!": "Let's do that!",
"backupModalMessage1": "The first and most important step is to <1>write down your secret recovery phrase</1> and store it in a safe place.",
"backupModalMessage2": "Have peace of mind by verifying that you <1>wrote your secret recovery phrase down</1> correctly."
}
1 change: 1 addition & 0 deletions apps/mobile-wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.42.1",
"react-i18next": "^13.2.1",
"react-native": "0.73.6",
"react-native-aes-crypto": "^2.1.0",
"react-native-background-actions": "^3.0.1",
Expand Down
19 changes: 4 additions & 15 deletions apps/mobile-wallet/src/api/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
import { AddressHash, AssetAmount, client } from '@alephium/shared'
import { transactionSign } from '@alephium/web3'

import i18n from '~/i18n'
import { getAddressAsymetricKey } from '~/persistent-storage/wallet'
import { store } from '~/store/store'
import { Address } from '~/types/addresses'
Expand Down Expand Up @@ -79,9 +80,6 @@ export const buildTransferTransaction = async ({
gasPrice
}: TransferTxData) => {
const { attoAlphAmount, tokens } = getTransactionAssetAmounts(assetAmounts)
const address = store.getState().addresses.entities[fromAddress]

if (!address) throw new Error(`Could not find address in store: ${fromAddress}`)

return await client.node.transactions.postTransactionsBuild({
fromPublicKey: await getAddressAsymetricKey(fromAddress, 'public'),
Expand All @@ -106,10 +104,6 @@ export const buildCallContractTransaction = async ({
}: CallContractTxData) => {
const { attoAlphAmount, tokens } = getOptionalTransactionAssetAmounts(assetAmounts)

const address = store.getState().addresses.entities[fromAddress]

if (!address) throw new Error(`Could not find address in store: ${fromAddress}`)

return await client.node.contracts.postContractsUnsignedTxExecuteScript({
fromPublicKey: await getAddressAsymetricKey(fromAddress, 'public'),
bytecode,
Expand All @@ -127,25 +121,20 @@ export const buildDeployContractTransaction = async ({
issueTokenAmount,
gasAmount,
gasPrice
}: DeployContractTxData) => {
const address = store.getState().addresses.entities[fromAddress]

if (!address) throw new Error(`Could not find address in store: ${fromAddress}`)

return await client.node.contracts.postContractsUnsignedTxDeployContract({
}: DeployContractTxData) =>
await client.node.contracts.postContractsUnsignedTxDeployContract({
fromPublicKey: await getAddressAsymetricKey(fromAddress, 'public'),
bytecode: bytecode,
initialAttoAlphAmount: initialAlphAmount?.amount?.toString(),
issueTokenAmount: issueTokenAmount?.toString(),
gasAmount: gasAmount,
gasPrice: gasPrice?.toString()
})
}

export const signAndSendTransaction = async (fromAddress: AddressHash, txId: string, unsignedTx: string) => {
const address = store.getState().addresses.entities[fromAddress]

if (!address) throw new Error(`Could not find address in store: ${fromAddress}`)
if (!address) throw new Error(i18n.t('Could not find address in store: {{ address }}', { address: fromAddress }))

const signature = transactionSign(txId, await getAddressAsymetricKey(address.hash, 'private'))
const data = await client.node.transactions.postTransactionsSubmit({ unsignedTx, signature })
Expand Down
19 changes: 16 additions & 3 deletions apps/mobile-wallet/src/components/AddressBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
import { AddressHash } from '@alephium/shared'
import { groupBy } from 'lodash'
import { useMemo, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { GestureResponderEvent, Pressable, PressableProps } from 'react-native'
import { Portal } from 'react-native-portalize'
import Animated, { useAnimatedStyle, withSpring } from 'react-native-reanimated'
Expand Down Expand Up @@ -54,6 +55,7 @@ const AddressBox = ({ addressHash, isSelected, onPress, ...props }: AddressBoxPr
const selectAddressesNFTs = useMemo(makeSelectAddressesNFTs, [])
const nfts = useAppSelector((s) => selectAddressesNFTs(s, addressHash))
const theme = useTheme()
const { t } = useTranslation()

const [isNftsModalOpen, setIsNftsModalOpen] = useState(false)

Expand All @@ -76,7 +78,7 @@ const AddressBox = ({ addressHash, isSelected, onPress, ...props }: AddressBoxPr
<AddressBadgeStyled onPress={handlePress} addressHash={addressHash} textStyle={{ fontSize: 18 }} />
<Group>
<AppText color="tertiary" size={14}>
group {address?.group}
{t('group {{ groupNumber }}', { groupNumber: address?.group })}
</AppText>
{isSelected && <Checkmark />}
</Group>
Expand All @@ -98,8 +100,19 @@ const AddressBox = ({ addressHash, isSelected, onPress, ...props }: AddressBoxPr
<AssetsRow style={{ marginTop: VERTICAL_GAP }}>
<NbOfNftsBadge>
<AppText>
+<AppText bold>{nfts.length}</AppText> NFTs in <AppText bold>{nbOfNftCollections}</AppText>{' '}
collections
<Trans
t={t}
i18nKey="numberOfNFTsInCollections"
values={{
nftsNumber: nfts.length,
nftsCollectionsNumber: nbOfNftCollections
}}
components={{
1: <AppText bold />
}}
>
{'+<1>{{ nftsNumber }}</1>NFTs in <1>{{ nftsCollectionsNumber }}</1> collections'}
</Trans>
</AppText>
</NbOfNftsBadge>
</AssetsRow>
Expand Down
6 changes: 4 additions & 2 deletions apps/mobile-wallet/src/components/AddressCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { NavigationProp, useNavigation } from '@react-navigation/native'
import { colord } from 'colord'
import { LinearGradient } from 'expo-linear-gradient'
import { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { StyleProp, View, ViewStyle } from 'react-native'
import styled, { useTheme } from 'styled-components/native'

Expand Down Expand Up @@ -55,6 +56,7 @@ const AddressCard = ({ style, addressHash, onSettingsPress }: AddressCardProps)
const selectAddessesTokensWorth = useMemo(makeSelectAddressesTokensWorth, [])
const balanceInFiat = useAppSelector((s) => selectAddessesTokensWorth(s, addressHash))
const persistAddressSettings = usePersistAddressSettings()
const { t } = useTranslation()

const [loading, setLoading] = useState(false)

Expand Down Expand Up @@ -174,7 +176,7 @@ const AddressCard = ({ style, addressHash, onSettingsPress }: AddressCardProps)
<Amount value={BigInt(address.balance)} color={textColor} size={15} medium suffix="ALPH" />
<AddressGroup>
<AppText style={{ color: textColor }} size={13}>
Group {address.group}
{t('Group {{ groupNumber }}', { groupNumber: address.group })}
</AppText>
</AddressGroup>
</Amounts>
Expand Down Expand Up @@ -204,7 +206,7 @@ const AddressCard = ({ style, addressHash, onSettingsPress }: AddressCardProps)
</ButtonsRow>
</BottomRow>
</CardGradientContainer>
<SpinnerModal isActive={loading} text="Updating default address..." />
<SpinnerModal isActive={loading} text={`${t('Updating default address')}...`} />
</View>
)
}
Expand Down
Loading

0 comments on commit c486e2f

Please sign in to comment.