├── .nvmrc ├── .ruby-version ├── .watchmanconfig ├── .node-version ├── src ├── assets │ ├── fonts │ │ ├── gilroy │ │ │ └── .gitkeep │ │ ├── basierCircle │ │ │ └── .gitkeep │ │ ├── icons │ │ │ └── icomoon.ttf │ │ ├── openSans │ │ │ ├── OpenSans-Bold.ttf │ │ │ ├── OpenSans-Regular.ttf │ │ │ └── OpenSans-Semibold.ttf │ │ └── passphrase │ │ │ ├── Dots-Regular.ttf │ │ │ └── PTMono-Regular.ttf │ ├── images │ │ ├── security │ │ │ └── app.png │ │ ├── balanceBlur │ │ │ ├── darkBig.png │ │ │ ├── lightBig.png │ │ │ ├── darkMedium.png │ │ │ ├── darkSmall.png │ │ │ ├── lightSmall.png │ │ │ └── lightMedium.png │ │ ├── send │ │ │ ├── noBookmarks3xDark.png │ │ │ ├── noBookmarks3xLight.png │ │ │ ├── secondPassphrase3xDark.png │ │ │ └── secondPassphrase3xLight.png │ │ └── amountBlur │ │ │ ├── incoming │ │ │ ├── darkBig.png │ │ │ ├── darkMedium.png │ │ │ ├── darkSmall.png │ │ │ ├── lightBig.png │ │ │ ├── lightSmall.png │ │ │ └── lightMedium.png │ │ │ └── outgoing │ │ │ ├── darkBig.png │ │ │ ├── darkMedium.png │ │ │ ├── darkSmall.png │ │ │ ├── lightBig.png │ │ │ ├── lightSmall.png │ │ │ └── lightMedium.png │ ├── animations │ │ ├── ScanDeviceAnimation.js │ │ └── LiskLogoAnimation.js │ └── svgs │ │ ├── CircleSvg.js │ │ ├── MoonSvg.js │ │ ├── ExternalLinkSvg.js │ │ ├── StatsSvg.js │ │ ├── LinkSvg.js │ │ ├── InfoRoundSvg.js │ │ ├── CaretSvg.js │ │ ├── ProgressSvg.js │ │ ├── BookmarkSvg.js │ │ ├── CurrencySvg.js │ │ ├── CheckSvg.js │ │ ├── WarningFilledSvg.js │ │ ├── AddSvg.js │ │ └── DownloadSvg.js ├── modules │ ├── Auth │ │ ├── __fixtures__ │ │ │ ├── index.js │ │ │ └── mockAuth.js │ │ ├── utils │ │ │ ├── index.js │ │ │ ├── documentPicker.mock.js │ │ │ ├── downloadAccount.js │ │ │ ├── recoveryPhrase.mock.js │ │ │ ├── documentPicker.js │ │ │ ├── getKeyFromArgon.js │ │ │ ├── decryptAccount.js │ │ │ └── recoveryPhrase.test.js │ │ ├── validators │ │ │ └── index.js │ │ ├── constants │ │ │ └── recoveryPhrase.constants.js │ │ ├── mocks │ │ │ └── index.js │ │ ├── components │ │ │ ├── MigrateToL2Screen │ │ │ │ └── styles.js │ │ │ ├── DecryptRecoveryPhraseScreen │ │ │ │ ├── DecryptRecoveryPhraseScreen.styles.js │ │ │ │ └── DecryptRecoveryPhraseScreen.js │ │ │ ├── AccountsManagerScreen │ │ │ │ └── styles.js │ │ │ ├── AuthType │ │ │ │ └── index.js │ │ │ ├── RecoveryPhraseSecurityAdviceCard │ │ │ │ └── RecoveryPhraseSecurityAdviceCard.js │ │ │ ├── RecoveryPhraseScreen │ │ │ │ └── RecoveryPhraseScreen.styles.js │ │ │ └── CreateAccountButton │ │ │ │ └── CreateAccountButton.styles.js │ │ ├── hooks │ │ │ └── usePasswordForm.js │ │ └── api │ │ │ └── useAuthQuery.test.js │ ├── Accounts │ │ ├── store │ │ │ ├── actions │ │ │ │ ├── index.js │ │ │ │ └── account.js │ │ │ ├── reducer │ │ │ │ └── index.js │ │ │ └── selectors.js │ │ ├── components │ │ │ ├── TokenList │ │ │ │ ├── TokenList.constants.js │ │ │ │ └── components │ │ │ │ │ └── TokenListSkeleton.js │ │ │ ├── AccountDetails │ │ │ │ ├── AccountDetails.styles.js │ │ │ │ └── AccountDetails.js │ │ │ ├── TokensScreen │ │ │ │ └── styles.js │ │ │ ├── AccountHome │ │ │ │ └── AccountHome.styles.js │ │ │ ├── EditAccountScreen │ │ │ │ └── styles.js │ │ │ ├── DeleteAccountScreen │ │ │ │ └── styles.js │ │ │ ├── AccountDetailsScreen │ │ │ │ └── AccountDetailsScreen.styles.js │ │ │ └── TokenRow │ │ │ │ └── components │ │ │ │ └── TokenRowSkeleton.styles.js │ │ ├── __fixtures__ │ │ │ └── index.js │ │ ├── actionTypes │ │ │ └── index.js │ │ ├── mocks │ │ │ └── index.js │ │ ├── hooks │ │ │ ├── useCurrentAccount.js │ │ │ └── useEncryptAccount.js │ │ └── api │ │ │ └── useLegacyAccount.js │ ├── Settings │ │ ├── store │ │ │ ├── actions │ │ │ │ └── index.js │ │ │ ├── reducer │ │ │ │ └── index.js │ │ │ └── actionTypes │ │ │ │ └── index.js │ │ └── components │ │ │ ├── BackupRecoveryPhrase │ │ │ └── BackupRecoveryPhrase.styles.js │ │ │ ├── HarmfulAppRow │ │ │ └── styles.js │ │ │ └── HarmfulAppDetails │ │ │ └── styles.js │ ├── Network │ │ ├── __fixtures__ │ │ │ └── index.js │ │ ├── mocks │ │ │ └── index.js │ │ └── api │ │ │ └── useNetworkStatusQuery.test.js │ ├── SendToken │ │ ├── __fixtures__ │ │ │ ├── index.js │ │ │ └── mockSendTokenResponse.js │ │ ├── constants.js │ │ ├── mocks │ │ │ └── index.js │ │ ├── hooks │ │ │ └── useValidateFeeBalance.js │ │ └── components │ │ │ ├── SendTokenSkeleton │ │ │ └── SendTokenSkeleton.styles.js │ │ │ └── SummaryStep │ │ │ └── styles.js │ ├── Bookmark │ │ ├── store │ │ │ ├── selectors │ │ │ │ └── index.js │ │ │ ├── actionTypes │ │ │ │ └── index.js │ │ │ └── actions │ │ │ │ └── index.js │ │ └── components │ │ │ ├── DeleteBookmark │ │ │ └── index.js │ │ │ ├── index.js │ │ │ ├── List.js │ │ │ └── EmptyState.js │ ├── Transactions │ │ ├── components │ │ │ ├── TransactionList │ │ │ │ ├── TransactionList.constants.js │ │ │ │ └── components │ │ │ │ │ └── TransactionListSkeleton.js │ │ │ ├── TransactionRow │ │ │ │ └── components │ │ │ │ │ ├── TransactionRowSkeleton.styles.js │ │ │ │ │ └── TransactionStatus.js │ │ │ ├── TransactionTimestamp │ │ │ │ └── index.js │ │ │ └── TransactionsHistory │ │ │ │ └── styles.js │ │ ├── __fixtures__ │ │ │ ├── mockTokensFullData.js │ │ │ ├── mockGetAccountTokensQuery.js │ │ │ ├── mockGetTransactionQuery.js │ │ │ ├── mockGetTransactionsQuery.js │ │ │ ├── index.js │ │ │ ├── mockTokens.js │ │ │ └── mockTokensMeta.js │ │ ├── utils │ │ │ └── helpers.test.js │ │ └── api │ │ │ ├── useFeesQuery.js │ │ │ └── useTransactionQuery.test.js │ ├── BlockchainApplication │ │ ├── __fixtures__ │ │ │ ├── index.js │ │ │ ├── mockCurrentApplication.js │ │ │ ├── mockApplicationsFullData.js │ │ │ ├── mockDefaultApplication.js │ │ │ └── mockApplications.js │ │ ├── components │ │ │ ├── DeleteApplicationSuccess │ │ │ │ ├── styles.js │ │ │ │ └── index.js │ │ │ ├── AddApplicationScreen │ │ │ │ └── AddApplicationScreen.styles.js │ │ │ ├── ManageApplication │ │ │ │ └── styles.js │ │ │ ├── ApplicationManagerModal │ │ │ │ └── index.js │ │ │ ├── ApplicationList │ │ │ │ └── components │ │ │ │ │ └── ApplicationListSkeleton.js │ │ │ ├── ApplicationRow │ │ │ │ └── components │ │ │ │ │ └── ApplicationRowSkeleton.styles.js │ │ │ ├── ApplicationsStats │ │ │ │ └── components │ │ │ │ │ ├── ApplicationsStatsSkeleton.js │ │ │ │ │ └── ApplicationsStatsLegendItem.js │ │ │ └── ApplicationsExplorer │ │ │ │ └── styles.js │ │ ├── constants.js │ │ ├── hooks │ │ │ └── useExternalApplicationConnectedAccounts.js │ │ └── api │ │ │ ├── useApplicationsFullDataQuery.js │ │ │ ├── useApplicationStatsQuery.js │ │ │ └── useApplicationsMetaQuery.test.js │ └── RequestToken │ │ └── components │ │ └── RequestTokenSelectField.styles.js ├── constants │ ├── mail.js │ ├── styleGuide │ │ ├── themes.js │ │ ├── index.js │ │ ├── boxes.js │ │ ├── fonts.mock.js │ │ └── fonts.js │ ├── app.js │ ├── languages.js │ ├── currencies.js │ ├── URLs.js │ └── regex.js ├── store │ ├── selectors.js │ ├── middlewares │ │ ├── index.js │ │ └── socket.test.js │ ├── reducers.js │ └── index.js ├── utilities │ ├── api │ │ ├── __fixtures__ │ │ │ ├── index.js │ │ │ ├── mockCustomQuery.js │ │ │ ├── mockInvokeQuery.js │ │ │ └── mockCustomInfiniteQuery.js │ │ ├── reactQueryClient.js │ │ ├── LiskAPIClient.js │ │ ├── constants.js │ │ ├── hooks │ │ │ ├── useQueryKeys.js │ │ │ ├── useInvokeQuery.test.js │ │ │ ├── useInvokeQuery.js │ │ │ └── useIndexStatusQuery.js │ │ └── APIClient.test.js │ ├── clipboard.utils.js │ ├── qrCode.js │ └── qrCode.test.js ├── components │ ├── shared │ │ ├── Tabs │ │ │ ├── hooks.js │ │ │ └── index.js │ │ ├── Picker │ │ │ ├── hooks.js │ │ │ └── index.js │ │ ├── HeaderLogo │ │ │ ├── HeaderLogo.styles.js │ │ │ └── HeaderLogo.js │ │ ├── CopyToClipboard │ │ │ └── CopyToClipboard.styles.js │ │ ├── ObjectViewer │ │ │ ├── utils │ │ │ │ └── ObjectViewer.utils.js │ │ │ ├── ObjectViewer.js │ │ │ └── ObjectViewer.styles.js │ │ ├── Toast │ │ │ └── Toast.config.js │ │ ├── avatar │ │ │ └── styles.js │ │ ├── share │ │ │ └── styles.js │ │ ├── DiscreteModeComponent │ │ │ ├── utils.js │ │ │ ├── styles.js │ │ │ └── index.js │ │ ├── StatusBar │ │ │ └── index.js │ │ ├── Swipeable │ │ │ └── styles.js │ │ ├── Stepper │ │ │ ├── styles.js │ │ │ └── StepProgress.js │ │ ├── Slider │ │ │ └── components │ │ │ │ └── SliderPagination.styles.js │ │ ├── Checkbox │ │ │ ├── styles.js │ │ │ └── index.js │ │ ├── headerTitle │ │ │ ├── index.js │ │ │ └── styles.js │ │ ├── EmptyState │ │ │ ├── index.js │ │ │ └── styles.js │ │ ├── Logo │ │ │ ├── Logo.styles.js │ │ │ └── Logo.js │ │ ├── fadeInView │ │ │ └── index.js │ │ ├── Fab │ │ │ ├── utils │ │ │ │ └── touchable.js │ │ │ └── FloatingItem │ │ │ │ └── styles.js │ │ ├── DataRenderer │ │ │ └── styles.js │ │ ├── Scanner │ │ │ └── CameraAccessAlert.js │ │ ├── Skeleton │ │ │ └── Skeleton.styles.js │ │ ├── DownloadFile │ │ │ └── styles.js │ │ └── toolBox │ │ │ └── icon.js │ ├── screens │ │ ├── terms │ │ │ └── index.js │ │ ├── PrivacyPolicy │ │ │ └── index.js │ │ ├── NotFoundScreen │ │ │ └── NotFoundScreen.styles.js │ │ ├── LoadingFallbackScreen │ │ │ ├── LoadingFallbackScreen.styles.js │ │ │ └── LoadingFallbackScreen.js │ │ └── IntroScreen │ │ │ └── IntroScreen.styles.js │ └── navigation │ │ └── NavigationSafeAreaView │ │ ├── styles.js │ │ └── index.js ├── tests │ ├── i18nextWrapper.js │ ├── queryWrapper.js │ └── constants │ │ └── wallets.js ├── hooks │ ├── useScreenshotPrevent.js │ ├── useDebounce.js │ ├── useCopyToClipboard.js │ ├── useRegisterAndroidModules.js │ ├── useTimeoutMonitor.js │ └── useScreenshotPrevent.test.js ├── navigation │ ├── navigation.linking.js │ ├── navigation.constants.js │ └── components │ │ └── TabBarIcon │ │ └── index.js └── notifications │ └── NotificationsConfig.js ├── .gitattributes ├── .eslintignore ├── app.json ├── .tsconfig.json ├── .bundle └── config ├── .husky ├── pre-commit └── _ │ └── husky.sh ├── server-cert.cer ├── docs └── assets │ ├── pr.png │ ├── issue.png │ └── banner_mobile.png ├── __mocks__ ├── react-native-ssl-pinning.js ├── react-native-background-timer.js └── @react-native-async-storage │ └── async-storage.js ├── android ├── app │ ├── debug.keystore │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── values │ │ │ │ │ ├── strings.xml │ │ │ │ │ ├── colors.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── icon.png │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── lunch_screen_icon.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── icon.png │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── lunch_screen_icon.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── icon.png │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── lunch_screen_icon.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── icon.png │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── lunch_screen_icon.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── icon.png │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── lunch_screen_icon.png │ │ │ │ ├── drawable │ │ │ │ │ ├── quick_action_send.png │ │ │ │ │ ├── quick_action_discreet.png │ │ │ │ │ └── quick_action_request.png │ │ │ │ ├── anim │ │ │ │ │ ├── slide_in_bottom.xml │ │ │ │ │ └── slide_out_bottom.xml │ │ │ │ ├── layout │ │ │ │ │ └── launch_screen.xml │ │ │ │ └── xml │ │ │ │ │ └── data_extraction_rules.xml │ │ │ ├── assets │ │ │ │ ├── server-cert.cer │ │ │ │ └── fonts │ │ │ │ │ ├── icomoon.ttf │ │ │ │ │ ├── Dots-Regular.ttf │ │ │ │ │ └── PTMono-Regular.ttf │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── lisk │ │ │ │ ├── SensitiveClipboardPackage.java │ │ │ │ ├── VerifyAppsPackage.java │ │ │ │ ├── ScopedStoragePackage.java │ │ │ │ ├── ExactAlarmPackage.java │ │ │ │ ├── AppOpsManagerModulePackage.java │ │ │ │ ├── ProviderInstallerPackage.java │ │ │ │ └── RNArgon2Package.java │ │ ├── dev │ │ │ └── res │ │ │ │ └── values │ │ │ │ └── strings.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── release │ │ │ └── java │ │ │ └── com │ │ │ └── lisk │ │ │ └── ReactNativeFlipper.java │ └── proguard-rules.pro └── gradle │ └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── ios ├── Resources │ ├── icomoon.ttf │ ├── Dots-Regular.ttf │ └── PTMono-Regular.ttf ├── Lisk │ ├── Images.xcassets │ │ ├── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── 20x20@2x.png │ │ │ ├── 20x20@3x.png │ │ │ ├── 29x29@2x.png │ │ │ ├── 29x29@3x.png │ │ │ ├── 40x40@2x.png │ │ │ ├── 40x40@3x.png │ │ │ ├── 60x60@2x.png │ │ │ ├── 60x60@3x.png │ │ │ └── 1024x1024-1.png │ │ ├── quick_action_send.imageset │ │ │ ├── Send.png │ │ │ ├── Send@2x.png │ │ │ ├── Send@3x.png │ │ │ └── Contents.json │ │ ├── SplashIcon.imageset │ │ │ ├── lisk-full-white.png │ │ │ ├── lisk-full-white@2x.png │ │ │ ├── lisk-full-white@3x.png │ │ │ └── Contents.json │ │ ├── quick_action_request.imageset │ │ │ ├── Request.png │ │ │ ├── Request@2x.png │ │ │ ├── Request@3x.png │ │ │ └── Contents.json │ │ ├── quick_action_discreet.imageset │ │ │ ├── discreet.png │ │ │ ├── discreet-1.png │ │ │ ├── discreet-2.png │ │ │ └── Contents.json │ │ └── LiskTypographyIcon.imageset │ │ │ ├── liskLogoWhite@1x.png │ │ │ ├── liskLogoWhite@2x.png │ │ │ ├── liskLogoWhite@3x.png │ │ │ └── Contents.json │ ├── AppDelegate.h │ ├── main.m │ ├── Lisk.entitlements │ └── RNArgon2Module.m ├── Bridge.swift ├── LiskTests-Bridging-Header.h ├── Lisk.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Lisk.xcodeproj │ └── project.xcworkspace │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Lisk-Bridging-Header.h ├── .xcode.env ├── LiskTests │ └── Info.plist └── Lisk-tvOSTests │ └── Info.plist ├── react-native.config.js ├── locales ├── resources │ └── index.js ├── index.js └── helpers.js ├── Gemfile ├── .prettierrc ├── libs └── wcm │ ├── constants │ ├── permissions.js │ └── lifeCycle.js │ ├── context │ └── connectionContext.js │ ├── hooks │ └── useEvents.js │ └── utils │ ├── connectionCreator.js │ └── error.js ├── testenv.js ├── scripts ├── removeExtraFonts.js └── setupJestAfterEnv.js ├── .github ├── pull_request_template.md └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── feature_specification.md ├── env.test.json ├── e2e ├── jest.config.js └── utils │ └── testConstants.js ├── index.js ├── services └── msw │ ├── init.js │ └── handlers.js ├── patches ├── react-native-os+1.2.6.patch ├── react-native-app-settings+2.0.1.patch ├── react-native-blur-overlay+1.0.7.patch ├── react-native-tcp+4.0.0.patch ├── jest-circus+29.5.0.patch └── @react-native-community+cli-platform-ios+6.0.0.patch ├── lsk.config.js ├── babel.config.js ├── metro.config.js └── env.example.json /.nvmrc: -------------------------------------------------------------------------------- 1 | 18.15.0 -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.5 2 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 18.15.0 2 | -------------------------------------------------------------------------------- /src/assets/fonts/gilroy/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /src/assets/fonts/basierCircle/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | coverage 4 | shim.js 5 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Lisk", 3 | "displayName": "Lisk" 4 | } 5 | -------------------------------------------------------------------------------- /src/modules/Auth/__fixtures__/index.js: -------------------------------------------------------------------------------- 1 | export * from './mockAuth'; 2 | -------------------------------------------------------------------------------- /.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/react-native/tsconfig.json" 3 | } -------------------------------------------------------------------------------- /src/modules/Accounts/store/actions/index.js: -------------------------------------------------------------------------------- 1 | export * from './account'; 2 | -------------------------------------------------------------------------------- /src/modules/Accounts/store/reducer/index.js: -------------------------------------------------------------------------------- 1 | export * from './account'; 2 | -------------------------------------------------------------------------------- /src/modules/Settings/store/actions/index.js: -------------------------------------------------------------------------------- 1 | export * from './settings'; 2 | -------------------------------------------------------------------------------- /src/modules/Settings/store/reducer/index.js: -------------------------------------------------------------------------------- 1 | export * from './settings'; 2 | -------------------------------------------------------------------------------- /.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /src/modules/Network/__fixtures__/index.js: -------------------------------------------------------------------------------- 1 | export * from './mockNetworkStatus'; 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged -------------------------------------------------------------------------------- /server-cert.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/server-cert.cer -------------------------------------------------------------------------------- /src/constants/mail.js: -------------------------------------------------------------------------------- 1 | export const SUPPORT_EMAIL_ADDRESS = 'mobiledev@lisk.com'; 2 | -------------------------------------------------------------------------------- /src/modules/SendToken/__fixtures__/index.js: -------------------------------------------------------------------------------- 1 | export * from './mockSendTokenResponse'; 2 | -------------------------------------------------------------------------------- /docs/assets/pr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/docs/assets/pr.png -------------------------------------------------------------------------------- /docs/assets/issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/docs/assets/issue.png -------------------------------------------------------------------------------- /src/modules/SendToken/constants.js: -------------------------------------------------------------------------------- 1 | export const BASE_TRANSACTION_MESSAGE_FEE = '10000000'; 2 | -------------------------------------------------------------------------------- /__mocks__/react-native-ssl-pinning.js: -------------------------------------------------------------------------------- 1 | import fetch from 'cross-fetch'; 2 | 3 | export { fetch }; 4 | -------------------------------------------------------------------------------- /android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/debug.keystore -------------------------------------------------------------------------------- /ios/Resources/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Resources/icomoon.ttf -------------------------------------------------------------------------------- /src/constants/styleGuide/themes.js: -------------------------------------------------------------------------------- 1 | export default { 2 | light: 'light', 3 | dark: 'dark', 4 | }; 5 | -------------------------------------------------------------------------------- /docs/assets/banner_mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/docs/assets/banner_mobile.png -------------------------------------------------------------------------------- /src/modules/Accounts/components/TokenList/TokenList.constants.js: -------------------------------------------------------------------------------- 1 | export const NO_OF_TOKENS_ON_OVERVIEW = 2; 2 | -------------------------------------------------------------------------------- /src/store/selectors.js: -------------------------------------------------------------------------------- 1 | const selectSettings = (state) => state.settings; 2 | 3 | export { selectSettings }; 4 | -------------------------------------------------------------------------------- /ios/Resources/Dots-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Resources/Dots-Regular.ttf -------------------------------------------------------------------------------- /ios/Resources/PTMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Resources/PTMono-Regular.ttf -------------------------------------------------------------------------------- /src/modules/Bookmark/store/selectors/index.js: -------------------------------------------------------------------------------- 1 | export const selectBookmarkList = (state) => state.bookmark.list; 2 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Lisk 3 | 4 | -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "author": "xcode", 4 | "version": 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/assets/fonts/icons/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/fonts/icons/icomoon.ttf -------------------------------------------------------------------------------- /src/assets/images/security/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/security/app.png -------------------------------------------------------------------------------- /src/modules/Accounts/__fixtures__/index.js: -------------------------------------------------------------------------------- 1 | export * from './mockSavedAccounts'; 2 | export * from './mockMarketPrices'; 3 | -------------------------------------------------------------------------------- /android/app/src/dev/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | LiskDev 3 | 4 | -------------------------------------------------------------------------------- /src/constants/app.js: -------------------------------------------------------------------------------- 1 | export default { 2 | faceId: 'Face ID', 3 | }; 4 | 5 | export const SEARCH_DEBOUNCE_DELAY = 1000; 6 | -------------------------------------------------------------------------------- /src/modules/Bookmark/components/DeleteBookmark/index.js: -------------------------------------------------------------------------------- 1 | export { DeleteBookmarkModal as default } from './DeleteBookmark'; 2 | -------------------------------------------------------------------------------- /src/modules/Transactions/components/TransactionList/TransactionList.constants.js: -------------------------------------------------------------------------------- 1 | export const NO_OF_TRANSACTIONS_ON_OVERVIEW = 3; 2 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/assets/images/balanceBlur/darkBig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/balanceBlur/darkBig.png -------------------------------------------------------------------------------- /src/assets/images/balanceBlur/lightBig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/balanceBlur/lightBig.png -------------------------------------------------------------------------------- /android/app/src/main/assets/server-cert.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/assets/server-cert.cer -------------------------------------------------------------------------------- /src/assets/fonts/openSans/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/fonts/openSans/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/passphrase/Dots-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/fonts/passphrase/Dots-Regular.ttf -------------------------------------------------------------------------------- /src/assets/images/balanceBlur/darkMedium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/balanceBlur/darkMedium.png -------------------------------------------------------------------------------- /src/assets/images/balanceBlur/darkSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/balanceBlur/darkSmall.png -------------------------------------------------------------------------------- /src/assets/images/balanceBlur/lightSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/balanceBlur/lightSmall.png -------------------------------------------------------------------------------- /src/assets/images/send/noBookmarks3xDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/send/noBookmarks3xDark.png -------------------------------------------------------------------------------- /__mocks__/react-native-background-timer.js: -------------------------------------------------------------------------------- 1 | export default { 2 | runBackgroundTimer: jest.fn(), 3 | stopBackgroundTimer: jest.fn(), 4 | }; 5 | -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/assets/fonts/icomoon.ttf -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-hdpi/icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-mdpi/icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-xhdpi/icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-xxhdpi/icon.png -------------------------------------------------------------------------------- /ios/Bridge.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Bridge.swift 3 | // Lisk 4 | // 5 | // Created by Daniel Ayomide on 25/09/2021. 6 | // 7 | 8 | import Foundation 9 | -------------------------------------------------------------------------------- /src/assets/fonts/openSans/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/fonts/openSans/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /src/assets/fonts/openSans/OpenSans-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/fonts/openSans/OpenSans-Semibold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/passphrase/PTMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/fonts/passphrase/PTMono-Regular.ttf -------------------------------------------------------------------------------- /src/assets/images/balanceBlur/lightMedium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/balanceBlur/lightMedium.png -------------------------------------------------------------------------------- /src/assets/images/send/noBookmarks3xLight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/send/noBookmarks3xLight.png -------------------------------------------------------------------------------- /src/modules/Auth/utils/index.js: -------------------------------------------------------------------------------- 1 | export * from './recoveryPhrase'; 2 | export * from './encryptAccount'; 3 | export * from './decryptAccount'; 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-xxxhdpi/icon.png -------------------------------------------------------------------------------- /ios/LiskTests-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/amountBlur/incoming/darkBig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/amountBlur/incoming/darkBig.png -------------------------------------------------------------------------------- /src/assets/images/amountBlur/outgoing/darkBig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/amountBlur/outgoing/darkBig.png -------------------------------------------------------------------------------- /src/assets/images/send/secondPassphrase3xDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/send/secondPassphrase3xDark.png -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Dots-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/assets/fonts/Dots-Regular.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/PTMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/assets/fonts/PTMono-Regular.ttf -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /react-native.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | project: { 3 | ios: {}, 4 | android: {}, 5 | }, 6 | assets: ['./src/assets/fonts/'], 7 | }; 8 | -------------------------------------------------------------------------------- /src/assets/images/amountBlur/incoming/darkMedium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/amountBlur/incoming/darkMedium.png -------------------------------------------------------------------------------- /src/assets/images/amountBlur/incoming/darkSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/amountBlur/incoming/darkSmall.png -------------------------------------------------------------------------------- /src/assets/images/amountBlur/incoming/lightBig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/amountBlur/incoming/lightBig.png -------------------------------------------------------------------------------- /src/assets/images/amountBlur/incoming/lightSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/amountBlur/incoming/lightSmall.png -------------------------------------------------------------------------------- /src/assets/images/amountBlur/outgoing/darkMedium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/amountBlur/outgoing/darkMedium.png -------------------------------------------------------------------------------- /src/assets/images/amountBlur/outgoing/darkSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/amountBlur/outgoing/darkSmall.png -------------------------------------------------------------------------------- /src/assets/images/amountBlur/outgoing/lightBig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/amountBlur/outgoing/lightBig.png -------------------------------------------------------------------------------- /src/assets/images/amountBlur/outgoing/lightSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/amountBlur/outgoing/lightSmall.png -------------------------------------------------------------------------------- /src/assets/images/send/secondPassphrase3xLight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/send/secondPassphrase3xLight.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/assets/images/amountBlur/incoming/lightMedium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/amountBlur/incoming/lightMedium.png -------------------------------------------------------------------------------- /src/assets/images/amountBlur/outgoing/lightMedium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/src/assets/images/amountBlur/outgoing/lightMedium.png -------------------------------------------------------------------------------- /src/modules/Auth/validators/index.js: -------------------------------------------------------------------------------- 1 | export const passwordValidationRegex = new RegExp( 2 | /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[\W_])(?=.{8,})/g 3 | ); 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/quick_action_send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/drawable/quick_action_send.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/AppIcon.appiconset/20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/AppIcon.appiconset/20x20@2x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/AppIcon.appiconset/20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/AppIcon.appiconset/20x20@3x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/AppIcon.appiconset/29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/AppIcon.appiconset/29x29@2x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/AppIcon.appiconset/29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/AppIcon.appiconset/29x29@3x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/AppIcon.appiconset/40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/AppIcon.appiconset/40x40@2x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/AppIcon.appiconset/40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/AppIcon.appiconset/40x40@3x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/AppIcon.appiconset/60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/AppIcon.appiconset/60x60@2x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/AppIcon.appiconset/60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/AppIcon.appiconset/60x60@3x.png -------------------------------------------------------------------------------- /src/utilities/api/__fixtures__/index.js: -------------------------------------------------------------------------------- 1 | export * from './mockCustomInfiniteQuery'; 2 | export * from './mockCustomQuery'; 3 | export * from './mockInvokeQuery'; 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/quick_action_discreet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/drawable/quick_action_discreet.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/quick_action_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/drawable/quick_action_request.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/lunch_screen_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-hdpi/lunch_screen_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/lunch_screen_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-mdpi/lunch_screen_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/lunch_screen_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-xhdpi/lunch_screen_icon.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/AppIcon.appiconset/1024x1024-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/AppIcon.appiconset/1024x1024-1.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/lunch_screen_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-xxhdpi/lunch_screen_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/lunch_screen_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/android/app/src/main/res/mipmap-xxxhdpi/lunch_screen_icon.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/quick_action_send.imageset/Send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/quick_action_send.imageset/Send.png -------------------------------------------------------------------------------- /src/modules/Accounts/store/selectors.js: -------------------------------------------------------------------------------- 1 | export const selectAccounts = (state) => state.account.list; 2 | export const selectCurrentAccount = (state) => state.account.current; 3 | -------------------------------------------------------------------------------- /src/modules/Auth/__fixtures__/mockAuth.js: -------------------------------------------------------------------------------- 1 | export const mockAuth = { 2 | nonce: '1', 3 | numberOfSignatures: 0, 4 | mandatoryKeys: [], 5 | optionalKeys: [], 6 | }; 7 | -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/SplashIcon.imageset/lisk-full-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/SplashIcon.imageset/lisk-full-white.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/quick_action_send.imageset/Send@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/quick_action_send.imageset/Send@2x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/quick_action_send.imageset/Send@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/quick_action_send.imageset/Send@3x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/SplashIcon.imageset/lisk-full-white@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/SplashIcon.imageset/lisk-full-white@2x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/SplashIcon.imageset/lisk-full-white@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/SplashIcon.imageset/lisk-full-white@3x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/quick_action_request.imageset/Request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/quick_action_request.imageset/Request.png -------------------------------------------------------------------------------- /locales/resources/index.js: -------------------------------------------------------------------------------- 1 | const en = require('./en.json'); 2 | const de = require('./de.json'); 3 | 4 | export default { 5 | de: { common: de }, 6 | en: { common: en }, 7 | }; 8 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby '>= 2.6.10' 5 | 6 | gem 'cocoapods', '>= 1.12.1' 7 | -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/quick_action_discreet.imageset/discreet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/quick_action_discreet.imageset/discreet.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/quick_action_request.imageset/Request@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/quick_action_request.imageset/Request@2x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/quick_action_request.imageset/Request@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/quick_action_request.imageset/Request@3x.png -------------------------------------------------------------------------------- /src/utilities/api/reactQueryClient.js: -------------------------------------------------------------------------------- 1 | import { QueryClient } from '@tanstack/react-query'; 2 | 3 | const reactQueryClient = new QueryClient(); 4 | 5 | export default reactQueryClient; 6 | -------------------------------------------------------------------------------- /__mocks__/@react-native-async-storage/async-storage.js: -------------------------------------------------------------------------------- 1 | import AsyncStorageMock from '@react-native-async-storage/async-storage/jest/async-storage-mock'; 2 | 3 | export default AsyncStorageMock; 4 | -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/quick_action_discreet.imageset/discreet-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/quick_action_discreet.imageset/discreet-1.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/quick_action_discreet.imageset/discreet-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/quick_action_discreet.imageset/discreet-2.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #4070F4 4 | #FFF 5 | 6 | -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/LiskTypographyIcon.imageset/liskLogoWhite@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/LiskTypographyIcon.imageset/liskLogoWhite@1x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/LiskTypographyIcon.imageset/liskLogoWhite@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/LiskTypographyIcon.imageset/liskLogoWhite@2x.png -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/LiskTypographyIcon.imageset/liskLogoWhite@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiskHQ/lisk-mobile/HEAD/ios/Lisk/Images.xcassets/LiskTypographyIcon.imageset/liskLogoWhite@3x.png -------------------------------------------------------------------------------- /src/modules/Settings/store/actionTypes/index.js: -------------------------------------------------------------------------------- 1 | const actionTypes = { 2 | settingsUpdated: 'SETTINGS_UPDATED', 3 | settingsRetrieved: 'SETTINGS_RETRIEVED', 4 | }; 5 | 6 | export default actionTypes; 7 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true, 6 | "bracketSpacing": true, 7 | "arrowParens": "always", 8 | "trailingComma": "es5" 9 | } 10 | -------------------------------------------------------------------------------- /libs/wcm/constants/permissions.js: -------------------------------------------------------------------------------- 1 | export const SIGNING_METHODS = { 2 | SIGN_TRANSACTION: { key: 'sign_transaction', title: 'Signature request' }, 3 | SIGN_MESSAGE: { key: 'sign_message', title: 'Sign message' }, 4 | }; 5 | -------------------------------------------------------------------------------- /src/components/shared/Tabs/hooks.js: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from 'react'; 2 | 3 | export const TabsContext = createContext(); 4 | 5 | export function useTabs() { 6 | return useContext(TabsContext); 7 | } 8 | -------------------------------------------------------------------------------- /src/modules/Auth/constants/recoveryPhrase.constants.js: -------------------------------------------------------------------------------- 1 | export const RECOVERY_PHRASE_STRENGTHS_PER_WORD = { 2 | '12words': 128, 3 | '24words': 256, 4 | }; 5 | 6 | export const defaultDerivationPath = "m/44'/134'/0'"; 7 | -------------------------------------------------------------------------------- /src/constants/styleGuide/index.js: -------------------------------------------------------------------------------- 1 | export { default as colors } from './colors'; 2 | export { default as fonts } from './fonts'; 3 | export { default as boxes } from './boxes'; 4 | export { default as themes } from './themes'; 5 | -------------------------------------------------------------------------------- /src/modules/Bookmark/store/actionTypes/index.js: -------------------------------------------------------------------------------- 1 | const actionTypes = { 2 | addBookmark: 'ADD_BOOKMARK', 3 | editBookmark: 'EDIT_BOOKMARK', 4 | deleteBookmark: 'DELETE_BOOKMARK', 5 | }; 6 | 7 | export default actionTypes; 8 | -------------------------------------------------------------------------------- /src/store/middlewares/index.js: -------------------------------------------------------------------------------- 1 | import thunk from 'redux-thunk'; 2 | import socketMiddleware from './socket'; 3 | import settingsMiddleware from './settings'; 4 | 5 | export default [thunk, socketMiddleware, settingsMiddleware]; 6 | -------------------------------------------------------------------------------- /testenv.js: -------------------------------------------------------------------------------- 1 | // react-native-device-info contains native code, and needs to be mocked. 2 | jest.mock('react-native-device-info', () => ({ 3 | getModel: jest.fn(), 4 | hasNotch: jest.fn(), 5 | getUniqueId: jest.fn(), 6 | })); 7 | -------------------------------------------------------------------------------- /ios/Lisk/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | @interface AppDelegate : RCTAppDelegate 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /src/components/shared/Picker/hooks.js: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from 'react'; 2 | 3 | export const PickerContext = createContext({}); 4 | 5 | export function usePicker() { 6 | return useContext(PickerContext); 7 | } 8 | -------------------------------------------------------------------------------- /src/store/reducers.js: -------------------------------------------------------------------------------- 1 | export { default as account } from 'modules/Accounts/store/reducer/account'; 2 | export { default as settings } from 'modules/Settings/store/reducer/settings'; 3 | export { default as bookmark } from 'modules/Bookmark/store/reducer'; 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/anim/slide_in_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /android/app/src/main/res/anim/slide_out_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /src/modules/Auth/utils/documentPicker.mock.js: -------------------------------------------------------------------------------- 1 | import { mockEncryptedAccount } from '../components/AuthMethod/__fixtures__/mockEncryptedAccount'; 2 | 3 | export const selectEncryptedFile = async () => { 4 | return JSON.stringify(mockEncryptedAccount); 5 | }; 6 | -------------------------------------------------------------------------------- /src/modules/Transactions/__fixtures__/mockTokensFullData.js: -------------------------------------------------------------------------------- 1 | import { mockDefaultToken } from './mockTokens'; 2 | import { mockDefaultTokenMeta } from './mockTokensMeta'; 3 | 4 | export const mockTokensFullData = [{ ...mockDefaultToken, ...mockDefaultTokenMeta }]; 5 | -------------------------------------------------------------------------------- /src/utilities/api/__fixtures__/mockCustomQuery.js: -------------------------------------------------------------------------------- 1 | const mockCustomQueryData = [{ id: '0' }]; 2 | 3 | export const mockCustomQuery = { 4 | data: mockCustomQueryData, 5 | meta: { 6 | count: 1, 7 | offset: 0, 8 | total: 1, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /ios/Lisk/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/components/shared/HeaderLogo/HeaderLogo.styles.js: -------------------------------------------------------------------------------- 1 | export function getHeaderLogoStyles() { 2 | return { 3 | common: { 4 | container: { 5 | alignItems: 'center', 6 | marginVertical: 24, 7 | }, 8 | }, 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /src/modules/Accounts/actionTypes/index.js: -------------------------------------------------------------------------------- 1 | const actionTypes = { 2 | setCurrentAccount: 'SET_CURRENT_ACCOUNT', 3 | addAccount: 'ADD_ACCOUNT', 4 | updateAccount: 'UPDATE_ACCOUNT', 5 | deleteAccount: 'DELETE_ACCOUNT', 6 | }; 7 | 8 | export default actionTypes; 9 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/__fixtures__/index.js: -------------------------------------------------------------------------------- 1 | export * from './mockApplicationsMeta'; 2 | export * from './mockDefaultApplicationMeta'; 3 | export * from './mockApplications'; 4 | export * from './mockApplicationsFullData'; 5 | export * from './mockCurrentApplication'; 6 | -------------------------------------------------------------------------------- /src/modules/SendToken/__fixtures__/mockSendTokenResponse.js: -------------------------------------------------------------------------------- 1 | export const mockSendTokenResponse = { 2 | message: 'Transaction payload was successfully passed to the network node', 3 | transactionID: 'bfd3521aeddd586f43931b6972b5771e9919e18f2cc91e940a15eacb588ecc6c', 4 | }; 5 | -------------------------------------------------------------------------------- /src/components/shared/CopyToClipboard/CopyToClipboard.styles.js: -------------------------------------------------------------------------------- 1 | export default () => ({ 2 | common: { 3 | container: { 4 | flexDirection: 'row', 5 | alignItems: 'center', 6 | }, 7 | icon: { 8 | paddingLeft: 8, 9 | }, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /src/components/shared/ObjectViewer/utils/ObjectViewer.utils.js: -------------------------------------------------------------------------------- 1 | export default function objectType(obj) { 2 | if (obj !== null && typeof obj === 'object' && !Array.isArray(obj)) { 3 | return 'Iterable'; 4 | } 5 | return Object.prototype.toString.call(obj).slice(8, -1); 6 | } 7 | -------------------------------------------------------------------------------- /src/utilities/api/__fixtures__/mockInvokeQuery.js: -------------------------------------------------------------------------------- 1 | export const mockInvokeQuery = { 2 | data: { 3 | userAccount: '5000000', 4 | escrowAccount: '5000000', 5 | }, 6 | meta: { 7 | endpoint: 'token_getInitializationFees', 8 | params: {}, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /src/components/shared/Toast/Toast.config.js: -------------------------------------------------------------------------------- 1 | import React from 'react-native'; 2 | 3 | import { SuccessToast, ErrorToast } from './Toasts'; 4 | 5 | export const toastConfig = { 6 | success: (props) => , 7 | error: (props) => , 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/shared/avatar/styles.js: -------------------------------------------------------------------------------- 1 | export default () => ({ 2 | common: { 3 | figure: { 4 | justifyContent: 'center', 5 | alignItems: 'center', 6 | overflow: 'hidden', 7 | }, 8 | avatar: { 9 | overflow: 'hidden', 10 | }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/components/DeleteApplicationSuccess/styles.js: -------------------------------------------------------------------------------- 1 | export default function getDeleteApplicationSuccessStyles() { 2 | return { 3 | common: { 4 | footer: { 5 | padding: 0, 6 | marginTop: 40, 7 | }, 8 | }, 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /src/modules/Transactions/__fixtures__/mockGetAccountTokensQuery.js: -------------------------------------------------------------------------------- 1 | import { mockTokens } from './mockTokens'; 2 | 3 | export const mockGetAccountTokensQuery = { 4 | data: mockTokens, 5 | meta: { 6 | count: 2, 7 | offset: 0, 8 | total: mockTokens.length, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /scripts/removeExtraFonts.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra'); // eslint-disable-line 2 | 3 | const dir = './node_modules/react-native-vector-icons/Fonts'; 4 | fs.remove(dir) 5 | .then(() => console.log('react-native-vector-icon extra fonts has been deleted')) 6 | .catch((err) => console.error(err)); 7 | -------------------------------------------------------------------------------- /src/modules/Transactions/__fixtures__/mockGetTransactionQuery.js: -------------------------------------------------------------------------------- 1 | import { mockTransactions } from './mockTransactions'; 2 | 3 | export const mockGetTransactionQuery = { 4 | data: [mockTransactions[0]], 5 | meta: { 6 | count: 1, 7 | offset: 0, 8 | total: 1, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### What was the problem? 2 | 3 | This PR resolves #INSERT_ISSUE_NUMBER 4 | 5 | ### How was it solved? 6 | 7 | 8 | 9 | ### How was it tested? 10 | 11 | 12 | -------------------------------------------------------------------------------- /ios/Lisk.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/constants/languages.js: -------------------------------------------------------------------------------- 1 | export const languageMap = { 2 | en: { 3 | symbol: 'EN', 4 | label: 'English', 5 | code: 'en', 6 | }, 7 | de: { 8 | symbol: 'DE', 9 | label: 'Deutsch', 10 | code: 'de', 11 | }, 12 | }; 13 | 14 | export const languageKeys = Object.keys(languageMap); 15 | -------------------------------------------------------------------------------- /src/modules/Transactions/__fixtures__/mockGetTransactionsQuery.js: -------------------------------------------------------------------------------- 1 | import { mockTransactions } from './mockTransactions'; 2 | 3 | export const mockGetTransactionsQuery = { 4 | data: mockTransactions, 5 | meta: { 6 | count: 2, 7 | offset: 0, 8 | total: mockTransactions.length, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /ios/Lisk.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/__fixtures__/mockCurrentApplication.js: -------------------------------------------------------------------------------- 1 | import { mockDefaultApplication } from './mockDefaultApplication'; 2 | import { mockDefaultApplicationMeta } from './mockDefaultApplicationMeta'; 3 | 4 | export const mockCurrentApplication = { ...mockDefaultApplication, ...mockDefaultApplicationMeta }; 5 | -------------------------------------------------------------------------------- /libs/wcm/context/connectionContext.js: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | const ConnectionContext = createContext({ 4 | events: [], 5 | pairings: [], 6 | sessions: [], 7 | sessionProposal: null, 8 | sessionRequest: null, 9 | signClient: null, 10 | }); 11 | 12 | export default ConnectionContext; 13 | -------------------------------------------------------------------------------- /src/constants/styleGuide/boxes.js: -------------------------------------------------------------------------------- 1 | export default { 2 | // heights 3 | buttonHeight: 46, 4 | borderedButtonHeight: 46, 5 | // paddings 6 | boxPadding: 20, 7 | elementPadding: 10, 8 | // borders 9 | buttonBorderWidth: 1, 10 | // border radius 11 | buttonBorderRadius: 2, 12 | boxBorderRadius: 10, 13 | }; 14 | -------------------------------------------------------------------------------- /src/tests/i18nextWrapper.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const ReactI18next = jest.jest.createMockFromModule('react-i18next'); 4 | 5 | const translate = () => (Component) => (props) => str} {...props} />; 6 | 7 | ReactI18next.translate = translate; 8 | 9 | module.exports = ReactI18next; 10 | -------------------------------------------------------------------------------- /locales/index.js: -------------------------------------------------------------------------------- 1 | import i18n from 'i18next'; 2 | import resources from './resources'; 3 | 4 | i18n.init({ 5 | fallbackLng: 'en', 6 | resources, 7 | lang: 'en', 8 | ns: ['common'], 9 | defaultNS: 'common', 10 | saveMissing: true, 11 | debug: false, 12 | nsSeparator: '|', 13 | }); 14 | 15 | export default i18n; 16 | -------------------------------------------------------------------------------- /ios/Lisk.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/constants/currencies.js: -------------------------------------------------------------------------------- 1 | export const currencyMap = { 2 | EUR: { 3 | symbol: '€', 4 | label: 'EUR', 5 | }, 6 | USD: { 7 | symbol: '$', 8 | label: 'USD', 9 | }, 10 | CHF: { 11 | symbol: 'CHF', 12 | label: 'CHF', 13 | }, 14 | }; 15 | 16 | export const currencyKeys = Object.keys(currencyMap); 17 | -------------------------------------------------------------------------------- /src/assets/animations/ScanDeviceAnimation.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Lottie from 'lottie-react-native'; 3 | import lottieSource from 'assets/animations/scanner.json'; 4 | 5 | export default function ScanDeviceAnimation({ style, ...props }) { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: 'type: bug' 6 | assignees: '' 7 | --- 8 | 9 | ### Expected behavior 10 | 11 | ### Actual behavior 12 | 13 | ### Steps to reproduce 14 | 15 | ### Which version(s) does this affect? (Environment, OS, etc...) 16 | -------------------------------------------------------------------------------- /src/hooks/useScreenshotPrevent.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import RNScreenshotPrevent from 'react-native-screenshot-prevent'; 3 | 4 | export default function useScreenshotPrevent() { 5 | useEffect(() => { 6 | RNScreenshotPrevent.enabled(true); 7 | return () => RNScreenshotPrevent.enabled(false); 8 | }, []); 9 | } 10 | -------------------------------------------------------------------------------- /src/utilities/api/LiskAPIClient.js: -------------------------------------------------------------------------------- 1 | import { APIClient } from './APIClient'; 2 | import { API_BASE_URL, WS_BASE_URL } from './constants'; 3 | 4 | const liskAPIClient = new APIClient(); 5 | 6 | liskAPIClient.create({ 7 | http: API_BASE_URL, 8 | ws: WS_BASE_URL, 9 | enableCertPinning: true, 10 | }); 11 | 12 | export default liskAPIClient; 13 | -------------------------------------------------------------------------------- /ios/Lisk-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Lisk-Bridging-Header.h 3 | // Lisk 4 | // 5 | // Created by Raquel Dias on 25.11.19. 6 | // Copyright © 2019 Facebook. All rights reserved. 7 | // 8 | 9 | #ifndef Lisk_Bridging_Header_h 10 | #define Lisk_Bridging_Header_h 11 | 12 | #endif /* Lisk_Bridging_Header_h */ 13 | 14 | #import 15 | -------------------------------------------------------------------------------- /src/store/middlewares/socket.test.js: -------------------------------------------------------------------------------- 1 | import socketMiddleware from './socket'; 2 | 3 | describe('Middleware: Accounts', () => { 4 | const next = jest.fn(); 5 | 6 | it('should pass the action', () => { 7 | const action = { type: 'ANY_ACTION' }; 8 | socketMiddleware()(next)(action); 9 | expect(next).toBeCalledWith(action); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /src/constants/URLs.js: -------------------------------------------------------------------------------- 1 | const URLs = { 2 | liskHomepage: 'https://lisk.com/', 3 | liskTermsAndConditions: 'https://lisk.com/terms-conditions', 4 | liskPrivacyPolicy: 'https://lisk.com/privacy', 5 | liskGettingStarted: 'https://lisk.com/what-is-blockchain', 6 | liskMigration: 'https://portal.lisk.com/claim/regular-account', 7 | }; 8 | 9 | export default URLs; 10 | -------------------------------------------------------------------------------- /src/modules/Transactions/__fixtures__/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/export */ 2 | export * from './mockTransactions'; 3 | export * from './mockGetTransactionsQuery'; 4 | export * from './mockGetTransactionQuery'; 5 | export * from './mockTokens'; 6 | export * from './mockTokensMeta'; 7 | export * from './mockTokensFullData'; 8 | export * from './mockGetAccountTokensQuery'; 9 | -------------------------------------------------------------------------------- /src/utilities/api/__fixtures__/mockCustomInfiniteQuery.js: -------------------------------------------------------------------------------- 1 | export const mockCustomInfiniteQueryData = [...new Array(50)].map((_, index) => ({ id: index })); 2 | 3 | export const mockCustomInfiniteQuery = { 4 | data: mockCustomInfiniteQueryData, 5 | meta: { 6 | count: 2, 7 | offset: 0, 8 | total: mockCustomInfiniteQueryData.length, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Propose an idea for new improvements/features 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | ### Description 10 | 11 | Please describe what functionality is needed 12 | 13 | ### Motivation 14 | 15 | Please describe why it is needed 16 | 17 | ### Additional Information 18 | -------------------------------------------------------------------------------- /src/modules/Auth/utils/downloadAccount.js: -------------------------------------------------------------------------------- 1 | import { stringShortener } from 'utilities/helpers'; 2 | 3 | export function getAccountDownloadableFilename(address) { 4 | const prefix = 'encrypted_secret_recovery_phrase_'; 5 | const extension = '.json'; 6 | const addressAlias = stringShortener(address, 7, 5); 7 | 8 | return prefix + addressAlias + extension; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/shared/share/styles.js: -------------------------------------------------------------------------------- 1 | export default () => ({ 2 | common: { 3 | container: { 4 | minWidth: '20%', 5 | flexDirection: 'row', 6 | alignItems: 'center', 7 | justifyContent: 'space-between', 8 | flex: 1, 9 | }, 10 | text: { 11 | flex: 1, 12 | }, 13 | icon: { 14 | padding: 8, 15 | }, 16 | }, 17 | }); 18 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/constants.js: -------------------------------------------------------------------------------- 1 | export const APPLICATIONS_STORAGE_KEY = '@blockchainApplications'; 2 | 3 | export const PINNED_APPLICATIONS_STORAGE_KEY = '@blockchainPinnedApplications'; 4 | 5 | export const APPLICATION_STATUSES = { 6 | active: 'active', 7 | registered: 'registered', 8 | terminated: 'terminated', 9 | unregistered: 'unregistered', 10 | }; 11 | -------------------------------------------------------------------------------- /src/modules/Bookmark/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as BookmarkList } from './BookmarkList'; 2 | export { default as List } from './List'; 3 | export { default as EmptyState } from './EmptyState'; 4 | export { default as BookmarkItem } from './Item'; 5 | export { default as DeleteBookmarkModal } from './DeleteBookmark'; 6 | export { default as DraggableItem } from './DraggableItem'; 7 | -------------------------------------------------------------------------------- /src/modules/Accounts/components/AccountDetails/AccountDetails.styles.js: -------------------------------------------------------------------------------- 1 | import { boxes } from 'constants/styleGuide'; 2 | 3 | export default function getAccountDetailsStyles() { 4 | return { 5 | common: { 6 | container: { 7 | padding: boxes.boxPadding, 8 | }, 9 | migrateToL2Card: { 10 | marginTop: 16, 11 | }, 12 | }, 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /src/modules/Auth/utils/recoveryPhrase.mock.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/export */ 2 | import testConstants from '../../../../e2e/utils/testConstants'; 3 | 4 | // eslint-disable-next-line import/extensions 5 | export * from './recoveryPhrase.js'; 6 | 7 | export const generateRecoveryPhrase = () => testConstants.secretRecoveryPhrase; 8 | 9 | export const chooseRandomWords = () => [0, 1]; 10 | -------------------------------------------------------------------------------- /locales/helpers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Dummy function to help i18n scanner understand i18next translations. 3 | * We can remove this as soon as react-navigation supports i18n or 4 | * we change the router to another lib with i18n support. 5 | * 6 | * @param {String} str - String to translate. 7 | * @returns {String} Provided input string. 8 | */ 9 | export function t(str) { 10 | return str; 11 | } 12 | -------------------------------------------------------------------------------- /src/utilities/api/constants.js: -------------------------------------------------------------------------------- 1 | export const NETWORK = process.env.NETWORK; 2 | 3 | export const API_BASE_URL = process.env.SERVICE_API_BASE_URL; 4 | 5 | export const WS_BASE_URL = process.env.SERVICE_WS_BASE_URL; 6 | 7 | export const API_VERSION = process.env.SERVICE_API_VERSION; 8 | 9 | export const API_URL = `/api/${API_VERSION}`; 10 | 11 | export const METHOD = 'rest'; 12 | 13 | export const LIMIT = 20; 14 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/__fixtures__/mockApplicationsFullData.js: -------------------------------------------------------------------------------- 1 | import { mockApplicationsMeta } from './mockApplicationsMeta'; 2 | import { mockApplications } from './mockApplications'; 3 | 4 | export const mockApplicationsFullData = mockApplicationsMeta.map((appMetadata) => { 5 | const app = mockApplications.find((_app) => _app.chainID === appMetadata.chainID); 6 | 7 | return { ...appMetadata, ...app }; 8 | }); 9 | -------------------------------------------------------------------------------- /env.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "RECOVERY_PHRASE": "", 3 | "NETWORK": "testnet", 4 | "SERVICE_API_BASE_URL": "https://testnet-service.lisk.com", 5 | "SERVICE_WS_BASE_URL": "wss://testnet-service.lisk.com", 6 | "SERVICE_API_VERSION": "v3", 7 | "PROJECT_ID": "", 8 | "RELAY_URL": "", 9 | "MOCK_SERVICE_API_ENABLED": false, 10 | "MOCKED_SERVICE_ENDPOINTS": "", 11 | "USE_COMMERCIAL_FONTS": false, 12 | "APP_MODE": "mocked" 13 | } -------------------------------------------------------------------------------- /src/modules/Transactions/components/TransactionRow/components/TransactionRowSkeleton.styles.js: -------------------------------------------------------------------------------- 1 | export default function getTransactionRowSkeletonStyles() { 2 | return { 3 | common: { 4 | container: { 5 | flexDirection: 'row', 6 | justifyContent: 'space-between', 7 | }, 8 | row: { 9 | flexDirection: 'row', 10 | alignItems: 'center', 11 | }, 12 | }, 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /src/utilities/api/hooks/useQueryKeys.js: -------------------------------------------------------------------------------- 1 | import { useCurrentApplication } from 'modules/BlockchainApplication/hooks/useCurrentApplication'; 2 | import { METHOD } from 'utilities/api/constants'; 3 | import { APPLICATION } from '../queries'; 4 | 5 | export function useQueryKeys(keys) { 6 | const [currentApplication] = useCurrentApplication(); 7 | 8 | return [...keys, currentApplication.data?.chainID, APPLICATION, METHOD]; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/shared/DiscreteModeComponent/utils.js: -------------------------------------------------------------------------------- 1 | export function getDiscreteModeDataSize(data) { 2 | let dataSize = ''; 3 | const _data = typeof data !== 'string' ? data.toString() : data; 4 | 5 | if (_data.length <= 4) { 6 | dataSize = 'Small'; 7 | } else if (_data.length > 4 && _data.length <= 8) { 8 | dataSize = 'Medium'; 9 | } else { 10 | dataSize = 'Big'; 11 | } 12 | 13 | return dataSize; 14 | } 15 | -------------------------------------------------------------------------------- /src/utilities/clipboard.utils.js: -------------------------------------------------------------------------------- 1 | import { NativeModules, Platform } from 'react-native'; 2 | import Clipboard from '@react-native-clipboard/clipboard'; 3 | 4 | const { SensitiveClipboardModule } = NativeModules; 5 | 6 | export function setValueToClipboard(value) { 7 | if (Platform.OS === 'android') { 8 | SensitiveClipboardModule.copyToClipboardSensitive(value); 9 | } else { 10 | Clipboard.setString(value); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/modules/Network/mocks/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { rest } from 'msw'; 3 | 4 | import { API_VERSION } from 'utilities/api/constants'; 5 | import { mockNetworkStatus } from '../__fixtures__'; 6 | 7 | export const getNetworkStatusMockHandler = rest.get( 8 | `*/api/${API_VERSION}/network/status`, 9 | async (_, res, ctx) => res(ctx.delay(20), ctx.json(mockNetworkStatus)) 10 | ); 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_specification.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature specification 3 | about: Specification of new features/improvements 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | ### Description 10 | 11 | Please describe the specification of new features/improvements 12 | 13 | ### Acceptance Criteria 14 | 15 | Please describe the conditions which must be met for this issue to close 16 | 17 | ### Additional Information 18 | -------------------------------------------------------------------------------- /src/modules/Transactions/__fixtures__/mockTokens.js: -------------------------------------------------------------------------------- 1 | export const mockDefaultToken = { 2 | tokenID: '0400000000000000', 3 | availableBalance: '10000000000', 4 | lockedBalances: [], 5 | }; 6 | 7 | export const mockTokens = [ 8 | mockDefaultToken, 9 | { tokenID: '0500000000000000', availableBalance: '20000000000', lockedBalances: [] }, 10 | { tokenID: '0600000000000000', availableBalance: '30000000000', lockedBalances: [] }, 11 | ]; 12 | -------------------------------------------------------------------------------- /src/components/shared/StatusBar/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StatusBar as BaseStatusBar } from 'react-native'; 3 | import { useSelector } from 'react-redux'; 4 | 5 | import { themes } from 'constants/styleGuide'; 6 | 7 | export default function StatusBar() { 8 | const { theme } = useSelector((state) => state.settings); 9 | 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/__fixtures__/mockDefaultApplication.js: -------------------------------------------------------------------------------- 1 | export const mockDefaultApplication = { 2 | chainName: 'lisk_mainchain', 3 | chainID: '02000000', 4 | status: 'active', 5 | address: 'lskguo9kqnea2zsfo3a6qppozsxsg92nuuma3p7ad', 6 | lastCertificateHeight: 1460, 7 | lastUpdated: 1689782730, 8 | escrow: [ 9 | { 10 | tokenID: '0400000000000000', 11 | amount: '100010000000', 12 | }, 13 | ], 14 | }; 15 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Lisk/Lisk.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.associated-domains 6 | 7 | applinks:lisk.com 8 | 9 | com.apple.developer.default-data-protection 10 | NSFileProtectionComplete 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/modules/Accounts/mocks/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { rest } from 'msw'; 3 | 4 | import { API_VERSION } from 'utilities/api/constants'; 5 | import { mockMarketPrices } from '../__fixtures__'; 6 | 7 | export const getMarketPricesMockHandler = rest.get( 8 | `*/api/${API_VERSION}/market/prices`, 9 | async (req, res, ctx) => { 10 | return res(ctx.delay(20), ctx.json(mockMarketPrices)); 11 | } 12 | ); 13 | -------------------------------------------------------------------------------- /src/modules/Bookmark/store/actions/index.js: -------------------------------------------------------------------------------- 1 | import actionTypes from '../actionTypes'; 2 | 3 | export const addBookmark = (bookmark) => ({ 4 | type: actionTypes.addBookmark, 5 | payload: bookmark, 6 | }); 7 | 8 | export const editBookmark = (bookmark) => ({ 9 | type: actionTypes.editBookmark, 10 | payload: bookmark, 11 | }); 12 | 13 | export const deleteBookmark = (bookmark) => ({ 14 | type: actionTypes.deleteBookmark, 15 | payload: bookmark, 16 | }); 17 | -------------------------------------------------------------------------------- /e2e/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@jest/types').Config.InitialOptions} */ 2 | module.exports = { 3 | rootDir: '..', 4 | testMatch: ['/e2e/**/*.e2e.js'], 5 | testTimeout: 120000, 6 | maxWorkers: 1, 7 | globalSetup: 'detox/runners/jest/globalSetup', 8 | globalTeardown: 'detox/runners/jest/globalTeardown', 9 | reporters: ['detox/runners/jest/reporter'], 10 | testEnvironment: 'detox/runners/jest/testEnvironment', 11 | verbose: true, 12 | }; 13 | -------------------------------------------------------------------------------- /ios/Lisk/RNArgon2Module.m: -------------------------------------------------------------------------------- 1 | // 2 | // RNArgon2Module.m 3 | // Lisk 4 | // 5 | // Created by Daniel Ayomide on 23/08/2023. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | @interface RCT_EXTERN_MODULE(RNArgon2, NSObject) 12 | 13 | RCT_EXTERN_METHOD(argon2: (NSString *)password salt:(NSString *)salt config:(NSDictionary *)config resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import './shim'; 2 | import './services/msw/init'; 3 | import { AppRegistry, Text } from 'react-native'; 4 | import '@walletconnect/react-native-compat'; 5 | import { name as appName } from './app.json'; 6 | import './src/notifications/NotificationsConfig'; 7 | import App from './src/App'; 8 | 9 | if (Text.defaultProps == null) Text.defaultProps = {}; 10 | 11 | Text.defaultProps.allowFontScaling = false; 12 | 13 | AppRegistry.registerComponent(appName, () => App); 14 | -------------------------------------------------------------------------------- /src/constants/styleGuide/fonts.mock.js: -------------------------------------------------------------------------------- 1 | export default { 2 | family: { 3 | heading: 'PTMono-Regular', 4 | context: 'PTMono-Regular', 5 | contextBold: 'PTMono-Regular', 6 | contextSemiBold: 'PTMono-Regular', 7 | recoveryPhrase: 'PTMono-Regular', 8 | recoveryPhraseText: 'PTMono-Regular', 9 | }, 10 | size: { 11 | h1: 26, 12 | h2: 24, 13 | h3: 22, 14 | h4: 20, 15 | base: 16, 16 | small: 13, 17 | input: 14, 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /src/modules/SendToken/mocks/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { rest } from 'msw'; 3 | 4 | import { API_VERSION } from 'utilities/api/constants'; 5 | import { mockSendTokenResponse } from '../__fixtures__'; 6 | 7 | export const sendTokenMockHandler = rest.post( 8 | `*/api/${API_VERSION}/transactions`, 9 | (_, res, ctx) => { 10 | return res(ctx.delay(20), ctx.status(201), ctx.json(mockSendTokenResponse)); 11 | } 12 | ); 13 | -------------------------------------------------------------------------------- /src/components/shared/ObjectViewer/ObjectViewer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ObjectNode from './ObjectNode'; 3 | import objectType from './utils/ObjectViewer.utils'; 4 | 5 | const ObjectViewer = ({ data, style }) => { 6 | const nodeType = objectType(data); 7 | 8 | switch (nodeType) { 9 | case 'Iterable': 10 | return ; 11 | default: 12 | return null; 13 | } 14 | }; 15 | 16 | export default ObjectViewer; 17 | -------------------------------------------------------------------------------- /services/msw/init.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | import { MSWServer } from './MSWServer'; 3 | 4 | if (process.env.MOCK_SERVICE_API_ENABLED) { 5 | require('react-native-url-polyfill/auto'); 6 | 7 | // eslint-disable-next-line @typescript-eslint/no-var-requires 8 | const nativeMsw = require('msw/native'); 9 | 10 | const mswDevServer = new MSWServer('dev', nativeMsw.setupServer); 11 | 12 | mswDevServer.init({ onUnhandledRequest: 'bypass' }); 13 | } 14 | -------------------------------------------------------------------------------- /src/components/screens/terms/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | import { WebView } from 'react-native-webview'; 4 | import URLs from 'constants/URLs'; 5 | 6 | const Terms = () => ( 7 | 8 | 13 | 14 | ); 15 | 16 | export default Terms; 17 | -------------------------------------------------------------------------------- /patches/react-native-os+1.2.6.patch: -------------------------------------------------------------------------------- 1 | diff --git a/node_modules/react-native-os/android/build.gradle b/node_modules/react-native-os/android/build.gradle 2 | index 7055b60..784681d 100644 3 | --- a/node_modules/react-native-os/android/build.gradle 4 | +++ b/node_modules/react-native-os/android/build.gradle 5 | @@ -44,5 +44,5 @@ repositories { 6 | } 7 | 8 | dependencies { 9 | - compile 'com.facebook.react:react-native:+' 10 | + implementation 'com.facebook.react:react-native:+' 11 | } 12 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /src/components/shared/Swipeable/styles.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | 3 | const styles = StyleSheet.create({ 4 | leftAction: { 5 | flex: 1, 6 | backgroundColor: '#497AFC', 7 | justifyContent: 'center', 8 | }, 9 | actionText: { 10 | color: 'white', 11 | fontSize: 14, 12 | textAlign: 'center', 13 | }, 14 | rightAction: { 15 | alignItems: 'center', 16 | flex: 1, 17 | justifyContent: 'center', 18 | }, 19 | }); 20 | 21 | export default styles; 22 | -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/quick_action_send.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "filename": "Send.png", 5 | "idiom": "universal", 6 | "scale": "1x" 7 | }, 8 | { 9 | "filename": "Send@2x.png", 10 | "idiom": "universal", 11 | "scale": "2x" 12 | }, 13 | { 14 | "filename": "Send@3x.png", 15 | "idiom": "universal", 16 | "scale": "3x" 17 | } 18 | ], 19 | "info": { 20 | "author": "xcode", 21 | "version": 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/components/screens/PrivacyPolicy/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | import { WebView } from 'react-native-webview'; 4 | import URLs from 'constants/URLs'; 5 | 6 | export default function PrivacyPolicy() { 7 | return ( 8 | 9 | 14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/quick_action_discreet.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "filename": "discreet.png", 5 | "idiom": "universal", 6 | "scale": "1x" 7 | }, 8 | { 9 | "filename": "discreet-1.png", 10 | "idiom": "universal", 11 | "scale": "2x" 12 | }, 13 | { 14 | "filename": "discreet-2.png", 15 | "idiom": "universal", 16 | "scale": "3x" 17 | } 18 | ], 19 | "info": { 20 | "author": "xcode", 21 | "version": 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/quick_action_request.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "filename": "Request.png", 5 | "idiom": "universal", 6 | "scale": "1x" 7 | }, 8 | { 9 | "filename": "Request@2x.png", 10 | "idiom": "universal", 11 | "scale": "2x" 12 | }, 13 | { 14 | "filename": "Request@3x.png", 15 | "idiom": "universal", 16 | "scale": "3x" 17 | } 18 | ], 19 | "info": { 20 | "author": "xcode", 21 | "version": 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/components/shared/Stepper/styles.js: -------------------------------------------------------------------------------- 1 | import { colors, themes } from 'constants/styleGuide'; 2 | 3 | export default () => ({ 4 | common: { 5 | flex: { 6 | flex: 1, 7 | }, 8 | container: { 9 | flexDirection: 'row', 10 | alignItems: 'center', 11 | paddingRight: 20, 12 | }, 13 | }, 14 | [themes.light]: { 15 | step: { 16 | color: colors.light.black, 17 | }, 18 | }, 19 | [themes.dark]: { 20 | step: { 21 | color: colors.dark.white, 22 | }, 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /src/modules/Accounts/components/TokensScreen/styles.js: -------------------------------------------------------------------------------- 1 | import { colors, themes, boxes } from 'constants/styleGuide'; 2 | 3 | export default { 4 | common: { 5 | container: { 6 | flex: 1, 7 | }, 8 | tokenListContainer: { 9 | padding: boxes.boxPadding, 10 | }, 11 | }, 12 | [themes.light]: { 13 | container: { 14 | backgroundColor: colors.light.white, 15 | }, 16 | }, 17 | [themes.dark]: { 18 | container: { 19 | backgroundColor: colors.dark.mainBg, 20 | }, 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /src/modules/Auth/mocks/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { rest } from 'msw'; 3 | 4 | import { API_VERSION } from 'utilities/api/constants'; 5 | import { mockAuth } from '../__fixtures__'; 6 | 7 | export const getAuthMockHandler = rest.get(`*/api/${API_VERSION}/auth`, async (req, res, ctx) => { 8 | const address = req.url.searchParams.get('address'); 9 | 10 | const response = { data: mockAuth, meta: { address } }; 11 | 12 | return res(ctx.delay(20), ctx.json(response)); 13 | }); 14 | -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/SplashIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "filename": "lisk-full-white.png", 5 | "idiom": "universal", 6 | "scale": "1x" 7 | }, 8 | { 9 | "filename": "lisk-full-white@2x.png", 10 | "idiom": "universal", 11 | "scale": "2x" 12 | }, 13 | { 14 | "filename": "lisk-full-white@3x.png", 15 | "idiom": "universal", 16 | "scale": "3x" 17 | } 18 | ], 19 | "info": { 20 | "author": "xcode", 21 | "version": 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/components/shared/Slider/components/SliderPagination.styles.js: -------------------------------------------------------------------------------- 1 | export default function getSliderPaginationStyles() { 2 | return { 3 | common: { 4 | container: { 5 | position: 'absolute', 6 | bottom: 0, 7 | flexDirection: 'row', 8 | width: '100%', 9 | alignItems: 'center', 10 | justifyContent: 'center', 11 | }, 12 | dot: { 13 | width: 12, 14 | height: 8, 15 | borderRadius: 6, 16 | marginHorizontal: 3, 17 | }, 18 | }, 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /ios/Lisk/Images.xcassets/LiskTypographyIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "filename": "liskLogoWhite@1x.png", 5 | "idiom": "universal", 6 | "scale": "1x" 7 | }, 8 | { 9 | "filename": "liskLogoWhite@2x.png", 10 | "idiom": "universal", 11 | "scale": "2x" 12 | }, 13 | { 14 | "filename": "liskLogoWhite@3x.png", 15 | "idiom": "universal", 16 | "scale": "3x" 17 | } 18 | ], 19 | "info": { 20 | "author": "xcode", 21 | "version": 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/navigation/navigation.linking.js: -------------------------------------------------------------------------------- 1 | import { getPathFromState } from '@react-navigation/core'; 2 | 3 | import { getNavigationStateFromPath } from './navigation.utils'; 4 | 5 | const navigationLinkingConfig = { 6 | screens: { 7 | Send: 'wallet', 8 | NotFound: '*', 9 | Error: 'error', 10 | }, 11 | }; 12 | 13 | const navigationLinking = { 14 | prefixes: ['lisk://'], 15 | config: navigationLinkingConfig, 16 | getStateFromPath: getNavigationStateFromPath, 17 | getPathFromState, 18 | }; 19 | 20 | export default navigationLinking; 21 | -------------------------------------------------------------------------------- /android/app/src/main/res/layout/launch_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /lsk.config.js: -------------------------------------------------------------------------------- 1 | const isTestnet = process.env.NETWORK === 'testnet'; 2 | 3 | export default { 4 | isTestnet, 5 | serviceURL: 'https://service.lisk.com/api', 6 | testnetURL: 'http://165.227.246.146:9901/api', 7 | networkID: '4c09e6a781fc4c7bdb936ee815de8f94190f8a7519becd9de2081832be309a99', 8 | testnetNetworkID: '15f0dacc1060e91818224a94286b13aa04279c640bd5d6f193182031d133df7c', 9 | requestOptions: { 10 | method: 'GET', 11 | headers: { 12 | Accept: 'application/json', 13 | 'Content-Type': 'application/json', 14 | }, 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /src/modules/Accounts/hooks/useCurrentAccount.js: -------------------------------------------------------------------------------- 1 | import { useSelector, useDispatch } from 'react-redux'; 2 | import { setCurrentAccount } from '../store/actions'; 3 | import { selectCurrentAccount } from '../store/selectors'; 4 | 5 | // eslint-disable-next-line 6 | export function useCurrentAccount() { 7 | const dispatch = useDispatch(); 8 | const setAccount = (accountSchema) => { 9 | dispatch(setCurrentAccount(accountSchema)); 10 | }; 11 | const currentAccount = useSelector(selectCurrentAccount); 12 | 13 | return [currentAccount, setAccount]; 14 | } 15 | -------------------------------------------------------------------------------- /e2e/utils/testConstants.js: -------------------------------------------------------------------------------- 1 | export default { 2 | secretRecoveryPhrase: 3 | 'devote mouse hair cereal maximum trigger puppy blossom adult sort ticket neither', 4 | sideChainRecoveryPhrase: 5 | 'where glow borrow found path hero produce gasp entry street recycle rich prepare carry almost parrot maze circle nuclear smile unveil captain assist together', 6 | address: 'lskv6v53emsaen6cwbbk226wusdpa6ojdonunka4x', 7 | newAddress: 'lskujedwe2nxoeehxwpztuateojsjfv6oge2ktefe', 8 | emptyAccount: '', 9 | password: 'Password1!', 10 | accountName: 'lisker', 11 | }; 12 | -------------------------------------------------------------------------------- /src/modules/Settings/components/BackupRecoveryPhrase/BackupRecoveryPhrase.styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors, boxes } from 'constants/styleGuide'; 2 | 3 | export default () => ({ 4 | common: { 5 | container: { 6 | flex: 1, 7 | }, 8 | decryptRecoveryPhrase: { 9 | padding: boxes.boxPadding, 10 | }, 11 | }, 12 | [themes.light]: { 13 | container: { 14 | backgroundColor: colors.light.white, 15 | }, 16 | }, 17 | [themes.dark]: { 18 | container: { 19 | backgroundColor: colors.dark.mainBg, 20 | }, 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import { createStore, combineReducers, applyMiddleware } from 'redux'; 2 | import { composeWithDevTools } from 'redux-devtools-extension'; 3 | import { persistStore } from 'redux-persist'; 4 | import * as reducers from './reducers'; 5 | import middleWares from './middlewares'; 6 | 7 | export * from './selectors'; 8 | 9 | const rootReducer = combineReducers(reducers); 10 | const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(...middleWares))); 11 | export const persistedStore = persistStore(store); 12 | 13 | export default store; 14 | -------------------------------------------------------------------------------- /patches/react-native-app-settings+2.0.1.patch: -------------------------------------------------------------------------------- 1 | diff --git a/node_modules/react-native-app-settings/android/build.gradle b/node_modules/react-native-app-settings/android/build.gradle 2 | index 849e79a..f87bfa7 100644 3 | --- a/node_modules/react-native-app-settings/android/build.gradle 4 | +++ b/node_modules/react-native-app-settings/android/build.gradle 5 | @@ -31,6 +31,6 @@ repositories { 6 | } 7 | 8 | dependencies { 9 | - compile 'com.facebook.react:react-native:+' 10 | + implementation 'com.facebook.react:react-native:+' 11 | } 12 | 13 | \ No newline at end of file 14 | -------------------------------------------------------------------------------- /patches/react-native-blur-overlay+1.0.7.patch: -------------------------------------------------------------------------------- 1 | diff --git a/node_modules/react-native-blur-overlay/android/build.gradle b/node_modules/react-native-blur-overlay/android/build.gradle 2 | index 8c6e8e8..f9aad7c 100644 3 | --- a/node_modules/react-native-blur-overlay/android/build.gradle 4 | +++ b/node_modules/react-native-blur-overlay/android/build.gradle 5 | @@ -31,6 +31,5 @@ repositories { 6 | } 7 | 8 | dependencies { 9 | - compile 'com.facebook.react:react-native:+' 10 | + implementation 'com.facebook.react:react-native:+' 11 | } 12 | - 13 | \ No newline at end of file 14 | -------------------------------------------------------------------------------- /src/modules/Auth/utils/documentPicker.js: -------------------------------------------------------------------------------- 1 | import DocumentPicker from 'react-native-document-picker'; 2 | import RNFS from 'react-native-fs'; 3 | 4 | export const selectEncryptedFile = async (onError) => { 5 | try { 6 | const file = await DocumentPicker.pickSingle({ 7 | type: DocumentPicker.types.allFiles, 8 | }); 9 | if (file.type !== 'application/json') { 10 | throw new Error('Invalid file type'); 11 | } 12 | const encryptedData = await RNFS.readFile(file.uri); 13 | return encryptedData; 14 | } catch (error) { 15 | return onError(); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /src/modules/Auth/utils/getKeyFromArgon.js: -------------------------------------------------------------------------------- 1 | import { NativeModules } from 'react-native'; 2 | 3 | const { RNArgon2 } = NativeModules; 4 | 5 | export const getKeyFromPasswordWithArgon2 = async (options) => { 6 | const { parallelism, password, iterations, memory, hashLength } = options; 7 | const salt = options.salt.toString('hex'); 8 | 9 | const result = await RNArgon2.argon2(password, salt, { 10 | iterations, 11 | memory, 12 | parallelism, 13 | hashLength, 14 | mode: 'argon2id', 15 | }); 16 | const key = Buffer.from(result.rawHash, 'hex'); 17 | return key; 18 | }; 19 | -------------------------------------------------------------------------------- /libs/wcm/hooks/useEvents.js: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import ConnectionContext from '../context/connectionContext'; 3 | 4 | export const useEvents = () => { 5 | const { events, setEvents } = useContext(ConnectionContext); 6 | 7 | const pushEvent = (event) => { 8 | setEvents((prevEvents) => [...prevEvents, event]); 9 | }; 10 | 11 | const removeEvent = (event) => { 12 | const newEvents = events.filter((e) => e.name !== event.name); 13 | setEvents(newEvents); 14 | }; 15 | 16 | return { 17 | events, 18 | removeEvent, 19 | pushEvent, 20 | }; 21 | }; 22 | -------------------------------------------------------------------------------- /src/components/navigation/NavigationSafeAreaView/styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors } from 'constants/styleGuide'; 2 | 3 | export default function getNavigationSafeAreaViewStyles(tabBarHeight) { 4 | return { 5 | common: { 6 | container: { 7 | flex: 1, 8 | paddingBottom: tabBarHeight, 9 | }, 10 | }, 11 | [themes.light]: { 12 | container: { 13 | backgroundColor: colors.light.white, 14 | }, 15 | }, 16 | [themes.dark]: { 17 | container: { 18 | backgroundColor: colors.dark.mainBg, 19 | }, 20 | }, 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /src/components/screens/NotFoundScreen/NotFoundScreen.styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors } from 'constants/styleGuide'; 2 | export default function getNotFoundStyles() { 3 | return { 4 | common: { 5 | container: { 6 | flex: 1, 7 | }, 8 | illustration: { 9 | marginBottom: 8, 10 | }, 11 | }, 12 | [themes.light]: { 13 | container: { 14 | backgroundColor: colors.light.white, 15 | }, 16 | }, 17 | [themes.dark]: { 18 | container: { 19 | backgroundColor: colors.dark.black, 20 | }, 21 | }, 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /src/modules/Accounts/components/AccountHome/AccountHome.styles.js: -------------------------------------------------------------------------------- 1 | import { boxes } from 'constants/styleGuide'; 2 | 3 | export default () => ({ 4 | common: { 5 | flex: { 6 | flex: 1, 7 | }, 8 | body: { 9 | padding: boxes.boxPadding, 10 | }, 11 | topContainer: { 12 | marginLeft: 20, 13 | marginRight: 60, 14 | marginTop: 10, 15 | }, 16 | discreteContainer: { 17 | marginRight: 10, 18 | }, 19 | row: { 20 | flexDirection: 'row', 21 | }, 22 | alignItemsCenter: { 23 | alignItems: 'center', 24 | }, 25 | }, 26 | }); 27 | -------------------------------------------------------------------------------- /src/modules/SendToken/hooks/useValidateFeeBalance.js: -------------------------------------------------------------------------------- 1 | import { useAccountTokenBalancesQuery } from '../../Accounts/api/useAccountTokenBalancesQuery'; 2 | 3 | export const useValidateFeeBalance = (address, customFeeTokenId) => { 4 | const tokenBalances = useAccountTokenBalancesQuery(address); 5 | 6 | const foundTokenBalance = tokenBalances.data?.data?.some( 7 | (tokenBalance) => 8 | tokenBalance?.tokenID === customFeeTokenId && 9 | BigInt(tokenBalance?.availableBalance || 0) > BigInt(0) 10 | ); 11 | 12 | return { 13 | hasSufficientBalanceForFee: !!foundTokenBalance, 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | plugins: [ 4 | '@babel/plugin-transform-react-jsx-source', 5 | ['@babel/plugin-proposal-decorators', { legacy: true }], 6 | 'transform-class-properties', 7 | '@babel/plugin-proposal-optional-chaining', 8 | '@babel/plugin-proposal-nullish-coalescing-operator', 9 | [ 10 | 'module-resolver', 11 | { 12 | root: ['./src'], 13 | alias: { 14 | locales: './locales', 15 | }, 16 | }, 17 | ], 18 | 'react-native-reanimated/plugin', 19 | ], 20 | }; 21 | -------------------------------------------------------------------------------- /src/components/shared/DiscreteModeComponent/styles.js: -------------------------------------------------------------------------------- 1 | export default () => ({ 2 | common: { 3 | container: { 4 | width: '100%', 5 | textAlign: 'right', 6 | justifyContent: 'flex-end', 7 | position: 'relative', 8 | maxHeight: 20, 9 | }, 10 | blurSmall: { 11 | width: 140, 12 | height: 26, 13 | marginRight: -15, 14 | }, 15 | blurMedium: { 16 | width: 140, 17 | height: 26, 18 | marginRight: -10, 19 | }, 20 | blurBig: { 21 | width: 140, 22 | height: 26, 23 | marginRight: -10, 24 | }, 25 | }, 26 | }); 27 | -------------------------------------------------------------------------------- /src/utilities/api/APIClient.test.js: -------------------------------------------------------------------------------- 1 | import client from './APIClient'; 2 | 3 | jest.useRealTimers(); 4 | 5 | describe('APIClient', () => { 6 | it.skip('should work', (done) => { 7 | client.socket.on('hello', (arg) => { 8 | expect(arg).toBe('world'); 9 | done(); 10 | }); 11 | client.socket.emit('hello', 'world'); 12 | }); 13 | 14 | it.skip('should work (with ack)', (done) => { 15 | client.socket.on('hi', (cb) => { 16 | cb('hola'); 17 | }); 18 | client.socket.emit('hi', (arg) => { 19 | expect(arg).toBe('hola'); 20 | done(); 21 | }); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /patches/react-native-tcp+4.0.0.patch: -------------------------------------------------------------------------------- 1 | diff --git a/node_modules/react-native-tcp/android/build.gradle b/node_modules/react-native-tcp/android/build.gradle 2 | index c582eb7..5785289 100644 3 | --- a/node_modules/react-native-tcp/android/build.gradle 4 | +++ b/node_modules/react-native-tcp/android/build.gradle 5 | @@ -44,6 +44,6 @@ repositories { 6 | } 7 | 8 | dependencies { 9 | - compile 'com.facebook.react:react-native:+' 10 | - compile 'com.koushikdutta.async:androidasync:2.1.6' 11 | + implementation 'com.facebook.react:react-native:+' 12 | + implementation 'com.koushikdutta.async:androidasync:2.1.6' 13 | } 14 | -------------------------------------------------------------------------------- /src/components/shared/Checkbox/styles.js: -------------------------------------------------------------------------------- 1 | import { colors } from 'constants/styleGuide'; 2 | 3 | export default { 4 | common: { 5 | container: { 6 | flexDirection: 'row', 7 | alignItems: 'center', 8 | marginVertical: 5, 9 | }, 10 | checkbox: { 11 | alignItems: 'center', 12 | justifyContent: 'center', 13 | borderWidth: 1, 14 | borderColor: colors.light.smoothGray, 15 | height: 20, 16 | width: 20, 17 | borderRadius: 4, 18 | marginRight: 10, 19 | }, 20 | active: { 21 | borderColor: colors.light.ultramarineBlue, 22 | }, 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /src/modules/Accounts/components/EditAccountScreen/styles.js: -------------------------------------------------------------------------------- 1 | import { colors, themes, boxes } from 'constants/styleGuide'; 2 | 3 | export default function getEditAccountScreenStyles() { 4 | return { 5 | common: { 6 | container: { 7 | flex: 1, 8 | }, 9 | formContainer: { 10 | padding: boxes.boxPadding, 11 | }, 12 | }, 13 | [themes.light]: { 14 | container: { 15 | backgroundColor: colors.dark.white, 16 | }, 17 | }, 18 | [themes.dark]: { 19 | container: { 20 | backgroundColor: colors.dark.black, 21 | }, 22 | }, 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/modules/Auth/utils/decryptAccount.js: -------------------------------------------------------------------------------- 1 | import { cryptography } from '@liskhq/lisk-client'; 2 | import { getKeyFromPasswordWithArgon2 } from './getKeyFromArgon'; 3 | 4 | export const decryptAccount = async (crypto, password) => { 5 | try { 6 | const { encrypt } = cryptography; 7 | const plainText = await encrypt.decryptMessageWithPassword(crypto, password, 'utf-8', { 8 | getKey: getKeyFromPasswordWithArgon2, 9 | }); 10 | const { recoveryPhrase, privateKey } = JSON.parse(plainText); 11 | return { recoveryPhrase, privateKey }; 12 | } catch (error) { 13 | throw new Error(error); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /src/modules/Accounts/components/DeleteAccountScreen/styles.js: -------------------------------------------------------------------------------- 1 | import { colors, themes, boxes } from 'constants/styleGuide'; 2 | 3 | export default function getDeleteAccountScreenStyles() { 4 | return { 5 | common: { 6 | container: { 7 | flex: 1, 8 | }, 9 | formContainer: { 10 | padding: boxes.boxPadding, 11 | }, 12 | }, 13 | [themes.light]: { 14 | container: { 15 | backgroundColor: colors.dark.white, 16 | }, 17 | }, 18 | [themes.dark]: { 19 | container: { 20 | backgroundColor: colors.dark.black, 21 | }, 22 | }, 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/modules/Accounts/components/TokenList/components/TokenListSkeleton.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | 4 | import TokenRowSkeleton from '../../TokenRow/components/TokenRowSkeleton'; 5 | 6 | /** 7 | * Skeleton UI placeholder for TokenList loading state. 8 | */ 9 | export default function TokenListSkeleton() { 10 | const skeletonsCount = 2; 11 | 12 | return ( 13 | 14 | {[...new Array(skeletonsCount)].map((_, index) => ( 15 | 16 | ))} 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/hooks/useExternalApplicationConnectedAccounts.js: -------------------------------------------------------------------------------- 1 | import { useAccounts } from 'modules/Accounts/hooks/useAccounts'; 2 | 3 | export function useExternalApplicationConnectedAccounts(namespaces) { 4 | const { accounts } = useAccounts(); 5 | 6 | const connectionAccountsPubKeys = namespaces?.lisk.accounts.map((account) => { 7 | const parts = account.split(':'); 8 | return parts[parts.length - 1]; 9 | }); 10 | 11 | const connectionAccounts = accounts.filter((account) => 12 | connectionAccountsPubKeys.includes(account.metadata.pubkey) 13 | ); 14 | 15 | return connectionAccounts; 16 | } 17 | -------------------------------------------------------------------------------- /src/navigation/navigation.constants.js: -------------------------------------------------------------------------------- 1 | import { TOKEN_TRANSFER_VALIDATION_SCHEMA } from 'modules/Transactions/utils/constants'; 2 | 3 | export const WHITE_LISTED_DEEP_LINKS = [ 4 | { 5 | pathRegex: /^\/\/wallet\/?$/, 6 | validationSchema: TOKEN_TRANSFER_VALIDATION_SCHEMA, 7 | paramsTransformer: (queryParams) => { 8 | let result = queryParams; 9 | 10 | if (!queryParams.amount) { 11 | result = { ...result, amount: '0' }; 12 | } 13 | 14 | if (!queryParams.reference) { 15 | result = { ...result, reference: '' }; 16 | } 17 | 18 | return result; 19 | }, 20 | }, 21 | ]; 22 | -------------------------------------------------------------------------------- /src/components/shared/headerTitle/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Animated } from 'react-native'; 3 | import { translate } from 'react-i18next'; 4 | import withTheme from 'components/shared/withTheme'; 5 | import getStyles from './styles'; 6 | 7 | const HeaderTitle = ({ styles, t, children, ...rest }) => ( 8 | 15 | {t(children)} 16 | 17 | ); 18 | 19 | export default withTheme(translate()(HeaderTitle), getStyles()); 20 | -------------------------------------------------------------------------------- /src/hooks/useDebounce.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | 3 | /** 4 | * Sets a debounced value to value (passed in) after the specified delay. 5 | * @param value - Value to debounce. 6 | * @param delay - Timeout to delay the value setup. 7 | */ 8 | export function useDebounce(value, delay) { 9 | const [debouncedValue, setDebouncedValue] = useState(value); 10 | 11 | useEffect(() => { 12 | const handler = setTimeout(() => { 13 | setDebouncedValue(value); 14 | }, delay); 15 | 16 | return () => { 17 | clearTimeout(handler); 18 | }; 19 | }, [value, delay]); 20 | 21 | return debouncedValue; 22 | } 23 | -------------------------------------------------------------------------------- /src/modules/Accounts/components/AccountDetailsScreen/AccountDetailsScreen.styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors, boxes } from 'constants/styleGuide'; 2 | 3 | export default function getAccountDetailsScreenStyles() { 4 | return { 5 | common: { 6 | flex: { 7 | flex: 1, 8 | }, 9 | container: { 10 | padding: boxes.boxPadding, 11 | }, 12 | }, 13 | [themes.light]: { 14 | container: { 15 | backgroundColor: colors.light.white, 16 | }, 17 | }, 18 | [themes.dark]: { 19 | container: { 20 | backgroundColor: colors.dark.mainBg, 21 | }, 22 | }, 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/modules/SendToken/components/SendTokenSkeleton/SendTokenSkeleton.styles.js: -------------------------------------------------------------------------------- 1 | import { boxes } from 'constants/styleGuide'; 2 | 3 | export function getSendTokenSkeletonStyles() { 4 | return { 5 | common: { 6 | container: { 7 | paddingLeft: boxes.boxPadding, 8 | paddingRight: boxes.boxPadding, 9 | }, 10 | progressBarContainer: { 11 | width: '100%', 12 | marginBottom: 40, 13 | }, 14 | fieldLabelContainer: { 15 | marginBottom: 8, 16 | }, 17 | fieldInputContainer: { 18 | width: '100%', 19 | marginBottom: 24, 20 | }, 21 | }, 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /src/components/shared/headerTitle/styles.js: -------------------------------------------------------------------------------- 1 | import { fonts, themes, colors } from 'constants/styleGuide'; 2 | import { deviceType } from 'utilities/device'; 3 | 4 | export default () => ({ 5 | common: { 6 | main: { 7 | flex: 1, 8 | fontSize: 16, 9 | textAlign: 'center', 10 | marginHorizontal: 16, 11 | marginTop: deviceType() === 'iOSx' ? -10 : -5, 12 | fontFamily: fonts.family.heading, 13 | }, 14 | }, 15 | [themes.light]: { 16 | main: { 17 | color: colors.light.black, 18 | }, 19 | }, 20 | [themes.dark]: { 21 | main: { 22 | color: colors.dark.white, 23 | }, 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/api/useApplicationsFullDataQuery.js: -------------------------------------------------------------------------------- 1 | import { useApplicationsMetaQuery } from './useApplicationsMetaQuery'; 2 | import { transformApplicationsMetaQueryResult } from '../utils'; 3 | 4 | /** 5 | * Fetches off-chain and on-chain applications data and merge them together. 6 | * @returns {Object} Available blockchain applications on and off-chain data. 7 | */ 8 | export function useApplicationsFullDataQuery({ config: customConfig = {}, options = {} } = {}) { 9 | return useApplicationsMetaQuery({ 10 | config: { transformResult: transformApplicationsMetaQueryResult, ...customConfig }, 11 | options, 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /src/modules/Auth/components/MigrateToL2Screen/styles.js: -------------------------------------------------------------------------------- 1 | import { colors, themes, boxes } from 'constants/styleGuide'; 2 | 3 | export default function getAccountsManagerScreenStyles() { 4 | return { 5 | common: { 6 | container: { 7 | flex: 1, 8 | padding: boxes.boxPadding, 9 | }, 10 | migrateToL2Card: { 11 | marginBottom: 16, 12 | }, 13 | }, 14 | [themes.light]: { 15 | container: { 16 | backgroundColor: colors.dark.white, 17 | }, 18 | }, 19 | [themes.dark]: { 20 | container: { 21 | backgroundColor: colors.dark.black, 22 | }, 23 | }, 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 13 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/components/shared/Stepper/StepProgress.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | import { B, P } from '../toolBox/typography'; 4 | import withTheme from '../withTheme'; 5 | import getStyles from './styles'; 6 | 7 | const StepProgress = ({ styles, currentIndex, length }) => { 8 | return ( 9 | 10 | Step 11 | {currentIndex} 12 | / 13 |

{length}

14 |
15 | ); 16 | }; 17 | 18 | export default withTheme(StepProgress, getStyles()); 19 | -------------------------------------------------------------------------------- /src/modules/Auth/components/DecryptRecoveryPhraseScreen/DecryptRecoveryPhraseScreen.styles.js: -------------------------------------------------------------------------------- 1 | import { colors, themes, boxes } from 'constants/styleGuide'; 2 | 3 | export default function getDecryptRecoveryPhraseScreenStyles() { 4 | return { 5 | common: { 6 | container: { 7 | flex: 1, 8 | }, 9 | form: { 10 | padding: boxes.boxPadding, 11 | }, 12 | }, 13 | [themes.light]: { 14 | container: { 15 | backgroundColor: colors.dark.white, 16 | }, 17 | }, 18 | 19 | [themes.dark]: { 20 | container: { 21 | backgroundColor: colors.dark.black, 22 | }, 23 | }, 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /src/modules/Transactions/components/TransactionTimestamp/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import moment from 'moment'; 3 | 4 | import FormattedDate from 'components/shared/formattedDate'; 5 | import { P } from 'components/shared/toolBox/typography'; 6 | 7 | export default function TransactionTimestamp({ 8 | timestamp, 9 | styles, 10 | format = 'MMM D, YYYY LTS', 11 | transformer = moment.unix, 12 | }) { 13 | return ( 14 | 20 | {timestamp} 21 | 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /libs/wcm/constants/lifeCycle.js: -------------------------------------------------------------------------------- 1 | export const STATUS = { 2 | SUCCESS: 'SUCCESS', 3 | FAILURE: 'FAILURE', 4 | }; 5 | 6 | export const ACTIONS = { 7 | APPROVE: 'APPROVE', 8 | REJECT: 'REJECT', 9 | }; 10 | 11 | export const EVENTS = { 12 | SESSION_PROPOSAL: 'session_proposal', 13 | SESSION_REQUEST: 'session_request', 14 | SESSION_PING: 'session_ping', 15 | SESSION_EVENT: 'session_event', 16 | SESSION_UPDATE: 'session_update', 17 | SESSION_DELETE: 'session_delete', 18 | }; 19 | 20 | export const ERROR_CASES = { 21 | USER_DISCONNECTED: 'USER_DISCONNECTED', 22 | INVALID_METHOD: 'INVALID_METHOD', 23 | USER_REJECTED_METHODS: 'USER_REJECTED_METHODS', 24 | }; 25 | -------------------------------------------------------------------------------- /src/modules/Auth/components/AccountsManagerScreen/styles.js: -------------------------------------------------------------------------------- 1 | import { colors, themes, boxes } from 'constants/styleGuide'; 2 | 3 | export default function getAccountsManagerScreenStyles() { 4 | return { 5 | common: { 6 | container: { 7 | flex: 1, 8 | padding: boxes.boxPadding, 9 | }, 10 | headerLogoContainer: { 11 | marginVertical: 40, 12 | }, 13 | }, 14 | [themes.light]: { 15 | container: { 16 | backgroundColor: colors.dark.white, 17 | }, 18 | }, 19 | 20 | [themes.dark]: { 21 | container: { 22 | backgroundColor: colors.dark.black, 23 | }, 24 | }, 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /src/assets/animations/LiskLogoAnimation.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Lottie from 'lottie-react-native'; 3 | 4 | export default function LiskLogoAnimation({ variant = 'blue', style, ...props }) { 5 | let src; 6 | 7 | switch (variant) { 8 | case 'blue': 9 | src = require('assets/animations/lisk-logo-animation-blue.json'); 10 | break; 11 | 12 | case 'white': 13 | src = require('assets/animations/lisk-logo-animation-white.json'); 14 | break; 15 | 16 | default: 17 | break; 18 | } 19 | 20 | if (!src) { 21 | return null; 22 | } 23 | 24 | return ; 25 | } 26 | -------------------------------------------------------------------------------- /src/assets/svgs/CircleSvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Svg, Path } from 'react-native-svg'; 3 | 4 | import colors from 'constants/styleGuide/colors'; 5 | 6 | export default function CircleSvg({ 7 | color = colors.light.blueGray, 8 | height = 24, 9 | width = 24, 10 | style, 11 | }) { 12 | return ( 13 | 14 | 20 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/components/AddApplicationScreen/AddApplicationScreen.styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors } from 'constants/styleGuide'; 2 | 3 | export default function getAddApplicationStyles() { 4 | return { 5 | common: { 6 | wrapper: { 7 | flex: 1, 8 | }, 9 | applicationsListContainer: { 10 | paddingLeft: 16, 11 | paddingRight: 16, 12 | }, 13 | }, 14 | [themes.light]: { 15 | wrapper: { 16 | backgroundColor: colors.light.white, 17 | }, 18 | }, 19 | 20 | [themes.dark]: { 21 | wrapper: { 22 | backgroundColor: colors.dark.mainBg, 23 | }, 24 | }, 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /src/assets/svgs/MoonSvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Svg, Path } from 'react-native-svg'; 3 | 4 | export default ({ color, style }) => ( 5 | 6 | 11 | 12 | ); 13 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/__fixtures__/mockApplications.js: -------------------------------------------------------------------------------- 1 | import { mockDefaultApplication } from './mockDefaultApplication'; 2 | 3 | export const mockApplications = [ 4 | mockDefaultApplication, 5 | ...[...new Array(100)].map((_, index) => ({ 6 | chainName: `app_mainchain_${index}`, 7 | chainID: index.toString(16).padStart(8, '0'), // 8-digit hex representation 8 | status: 'active', 9 | address: 'lskguo9kqnea2zsfo3a6qppozsxsg92nuuma3p7ad', 10 | lastCertificateHeight: 1460, 11 | lastUpdated: 1689782730, 12 | escrow: [ 13 | { 14 | tokenID: '0400000000000000', 15 | amount: '100010000000', 16 | }, 17 | ], 18 | })), 19 | ]; 20 | -------------------------------------------------------------------------------- /src/components/shared/ObjectViewer/ObjectViewer.styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors, fonts } from 'constants/styleGuide'; 2 | 3 | export default function getStyles() { 4 | return { 5 | common: { 6 | container: { flexDirection: 'row', flex: 1, padding: 5, marginLeft: 10 }, 7 | text: { 8 | fontFamily: fonts.family.context, 9 | fontSize: fonts.size.small, 10 | }, 11 | flex: { 12 | flex: 1, 13 | }, 14 | }, 15 | [themes.light]: { 16 | text: { 17 | color: colors.light.zodiacBlue, 18 | }, 19 | }, 20 | [themes.dark]: { 21 | text: { 22 | color: colors.dark.white, 23 | }, 24 | }, 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /src/modules/Auth/utils/recoveryPhrase.test.js: -------------------------------------------------------------------------------- 1 | import { toSecureRecoveryPhraseString } from './recoveryPhrase'; 2 | 3 | describe('toSecureRecoveryPhraseString', () => { 4 | it('should return a secured recovery phrase', () => { 5 | const input = 'attract squeeze option inflict dynamic'; 6 | const expectedOutput = '****** ****** ****** ****** ******'; 7 | expect(toSecureRecoveryPhraseString(input)).toBe(expectedOutput); 8 | }); 9 | 10 | it('should handle an empty string', () => { 11 | expect(toSecureRecoveryPhraseString('')).toBe(''); 12 | }); 13 | 14 | it('should handle a single word', () => { 15 | expect(toSecureRecoveryPhraseString('singleword')).toBe('******'); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /services/msw/handlers.js: -------------------------------------------------------------------------------- 1 | import * as authHandlers from 'modules/Auth/mocks'; 2 | import * as sendTokenHandlers from 'modules/SendToken/mocks'; 3 | import * as transactionHandlers from 'modules/Transactions/mocks'; 4 | import * as applicationsHandlers from 'modules/BlockchainApplication/mocks'; 5 | import * as accountHandlers from 'modules/Accounts/mocks'; 6 | import * as networkHandlers from 'modules/Network/mocks'; 7 | import * as generalApiHandlers from 'utilities/api/mocks'; 8 | 9 | export const mswHandlers = { 10 | ...sendTokenHandlers, 11 | ...transactionHandlers, 12 | ...generalApiHandlers, 13 | ...applicationsHandlers, 14 | ...networkHandlers, 15 | ...accountHandlers, 16 | ...authHandlers, 17 | }; 18 | -------------------------------------------------------------------------------- /src/components/screens/LoadingFallbackScreen/LoadingFallbackScreen.styles.js: -------------------------------------------------------------------------------- 1 | import { colors, boxes } from 'constants/styleGuide'; 2 | 3 | export function getLoadingFallbackScreenStyles() { 4 | return { 5 | common: { 6 | container: { 7 | flex: 1, 8 | backgroundColor: colors.light.ultramarineBlue, 9 | paddingLeft: boxes.boxPadding, 10 | paddingRight: boxes.boxPadding, 11 | alignItems: 'center', 12 | justifyContent: 'center', 13 | }, 14 | animationContainer: { 15 | position: 'absolute', 16 | bottom: 40, 17 | }, 18 | animation: { 19 | width: 80, 20 | height: 80, 21 | }, 22 | }, 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /libs/wcm/utils/connectionCreator.js: -------------------------------------------------------------------------------- 1 | import SignClient from '@walletconnect/sign-client'; 2 | import { to } from 'await-to-js'; 3 | 4 | import pkg from '../../../package.json'; 5 | 6 | export async function createSignClient(icon) { 7 | const [error, result] = await to( 8 | SignClient.init({ 9 | projectId: process.env.PROJECT_ID, 10 | metadata: { 11 | name: pkg.name, 12 | description: pkg.description, 13 | url: pkg.homepage, 14 | icons: [icon], 15 | }, 16 | }) 17 | ); 18 | 19 | if (error) { 20 | throw error; 21 | } 22 | 23 | if (!result) { 24 | throw new Error('Not able to setup WalletConnect client.'); 25 | } 26 | 27 | return result; 28 | } 29 | -------------------------------------------------------------------------------- /src/components/shared/Tabs/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | 4 | import { useTheme } from 'contexts/ThemeContext'; 5 | 6 | import { TabsContext } from './hooks'; 7 | import { Tab, TabsPanel } from './components'; 8 | import { getTabsStyles } from './styles'; 9 | 10 | export default function Tabs({ value, onClick, children }) { 11 | const { styles } = useTheme({ 12 | styles: getTabsStyles(), 13 | }); 14 | 15 | return ( 16 | 17 | {children} 18 | 19 | ); 20 | } 21 | 22 | Tabs.Tab = Tab; 23 | Tabs.Panel = TabsPanel; 24 | -------------------------------------------------------------------------------- /src/modules/Auth/components/AuthType/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, TouchableOpacity } from 'react-native'; 3 | import withTheme from 'components/shared/withTheme'; 4 | import getStyles from './styles'; 5 | 6 | const AuthTypeItem = ({ illustration, label, styles, onPress, testID }) => ( 7 | 12 | {illustration} 13 | 14 | {label} 15 | 16 | 17 | ); 18 | 19 | export default withTheme(AuthTypeItem, getStyles()); 20 | -------------------------------------------------------------------------------- /src/modules/Transactions/components/TransactionList/components/TransactionListSkeleton.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | 4 | import TransactionRowSkeleton from '../../TransactionRow/components/TransactionRowSkeleton'; 5 | 6 | /** 7 | * Skeleton UI placeholder for TransactionList loading state. 8 | */ 9 | export default function TransactionListSkeleton() { 10 | const skeletonsCount = 3; 11 | 12 | return ( 13 | 14 | {[...new Array(skeletonsCount)].map((_, index) => ( 15 | 19 | ))} 20 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/api/useApplicationStatsQuery.js: -------------------------------------------------------------------------------- 1 | import { useCustomQuery } from 'utilities/api/hooks/useCustomQuery'; 2 | import { GET_APPLICATION_STATS } from 'utilities/api/queries'; 3 | import { API_URL } from 'utilities/api/constants'; 4 | import { useQueryKeys } from 'utilities/api/hooks/useQueryKeys'; 5 | import liskAPIClient from 'utilities/api/LiskAPIClient'; 6 | 7 | export function useApplicationStatsQuery() { 8 | const config = { 9 | url: `${API_URL}/blockchain/apps/statistics`, 10 | method: 'GET', 11 | }; 12 | 13 | const keys = useQueryKeys([GET_APPLICATION_STATS, config]); 14 | 15 | return useCustomQuery({ 16 | keys, 17 | config, 18 | client: liskAPIClient, 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /src/modules/Accounts/hooks/useEncryptAccount.js: -------------------------------------------------------------------------------- 1 | import { encryptAccount as encryptAccountUtils } from 'modules/Auth/utils'; 2 | import { defaultDerivationPath } from '../../Auth/constants/recoveryPhrase.constants'; 3 | 4 | export function useEncryptAccount(useDerivationPath) { 5 | const encryptAccount = ({ recoveryPhrase, password, name, derivationPath }) => 6 | encryptAccountUtils({ 7 | recoveryPhrase, 8 | password, 9 | name, 10 | enableCustomDerivationPath: useDerivationPath, 11 | // Use default derivation path if derivationPath is not passed 12 | derivationPath: useDerivationPath && !derivationPath ? defaultDerivationPath : derivationPath, 13 | }); 14 | return { encryptAccount }; 15 | } 16 | -------------------------------------------------------------------------------- /src/components/shared/EmptyState/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | 4 | import { useTheme } from 'contexts/ThemeContext'; 5 | import EmptyIllustrationSvg from 'assets/svgs/EmptyIllustrationSvg'; 6 | import { P } from 'components/shared/toolBox/typography'; 7 | 8 | import getEmptyStateStyles from './styles'; 9 | 10 | export default function EmptyState({ message, style = {} }) { 11 | const { styles } = useTheme({ styles: getEmptyStateStyles() }); 12 | 13 | return ( 14 | 15 | 16 |

{message}

17 |
18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /src/hooks/useCopyToClipboard.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from 'react'; 2 | 3 | import { setValueToClipboard } from 'utilities/clipboard.utils'; 4 | 5 | export function useCopyToClipboard(value, { autoCleanup = false } = {}) { 6 | const [copied, setCopied] = useState(false); 7 | 8 | const timeout = useRef(); 9 | 10 | const handleCopy = () => { 11 | setValueToClipboard(value); 12 | 13 | setCopied(true); 14 | 15 | timeout.current = setTimeout(() => { 16 | setCopied(false); 17 | 18 | if (autoCleanup) { 19 | setValueToClipboard(''); 20 | } 21 | }, 10000); 22 | }; 23 | 24 | useEffect(() => () => clearTimeout(timeout.current), []); 25 | 26 | return [copied, handleCopy]; 27 | } 28 | -------------------------------------------------------------------------------- /src/modules/Accounts/api/useLegacyAccount.js: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query'; 2 | import { useCurrentAccount } from '../hooks/useCurrentAccount'; 3 | 4 | async function fetchLegacyAccount(address) { 5 | const response = await fetch(`https://legacy.lisk.com/accounts/${address}.json`); 6 | const data = await response.json(); 7 | return data; 8 | } 9 | 10 | export default function useLegacyAccount(options = {}) { 11 | const [currentAccount] = useCurrentAccount(); 12 | const address = currentAccount.metadata.address; 13 | 14 | const query = useQuery({ 15 | queryKey: ['GET_ACCOUNT_BALANCE_LEGACY', address], 16 | queryFn: () => fetchLegacyAccount(address), 17 | ...options, 18 | }); 19 | 20 | return query; 21 | } 22 | -------------------------------------------------------------------------------- /src/modules/Transactions/components/TransactionsHistory/styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors, boxes } from 'constants/styleGuide'; 2 | 3 | export default function getTransactionsHistoryStyles() { 4 | return { 5 | common: { 6 | container: { 7 | flex: 1, 8 | }, 9 | header: { 10 | marginBottom: 24, 11 | }, 12 | listContainer: { 13 | paddingLeft: boxes.boxPadding, 14 | paddingRight: boxes.boxPadding, 15 | }, 16 | }, 17 | [themes.light]: { 18 | container: { 19 | backgroundColor: colors.light.white, 20 | }, 21 | }, 22 | [themes.dark]: { 23 | container: { 24 | backgroundColor: colors.dark.mainBg, 25 | }, 26 | }, 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /src/assets/svgs/ExternalLinkSvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Svg, Path } from 'react-native-svg'; 3 | 4 | import colors from '../../constants/styleGuide/colors'; 5 | 6 | export default function ExternalLinkSvg({ size = 1, color = colors.dark.ultramarineBlue, style }) { 7 | return ( 8 | 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /src/components/navigation/NavigationSafeAreaView/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs'; 3 | import { SafeAreaView } from 'react-native-safe-area-context'; 4 | 5 | import { useTheme } from 'contexts/ThemeContext'; 6 | 7 | import getNavigationSafeAreaViewStyles from './styles'; 8 | 9 | export default function NavigationSafeAreaView({ children, style }) { 10 | const tabBarHeight = useBottomTabBarHeight(); 11 | 12 | const { styles } = useTheme({ 13 | styles: getNavigationSafeAreaViewStyles(tabBarHeight), 14 | }); 15 | 16 | return ( 17 | 18 | {children} 19 | 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /src/hooks/useRegisterAndroidModules.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import { NativeModules, Platform } from 'react-native'; 3 | 4 | const { AppOpsManagerModule, ProviderInstaller } = NativeModules; 5 | 6 | /** 7 | * Registers native modules for android OS 8 | * Performs data auditing for monitoring user's private data access on the app. 9 | * Registers ProviderInstaller module which provides a secure library for network 10 | * connections that can be updated independently of the Android OS 11 | */ 12 | export function useRegisterAndroidModules() { 13 | useEffect(() => { 14 | if (Platform.OS === 'android') { 15 | AppOpsManagerModule.startWatching(); 16 | ProviderInstaller.installIfNeeded(); 17 | } 18 | }, []); 19 | } 20 | -------------------------------------------------------------------------------- /src/notifications/NotificationsConfig.js: -------------------------------------------------------------------------------- 1 | import { Platform } from 'react-native'; 2 | import PushNotification from 'react-native-push-notification'; 3 | import PushNotificationIOS from '@react-native-community/push-notification-ios'; 4 | 5 | PushNotification.configure({ 6 | onRegister: function (token) { 7 | console.log('Registered for push notifications:', token); 8 | }, 9 | 10 | onNotification: function (notification) { 11 | notification.finish(PushNotificationIOS.FetchResult.NoData); 12 | }, 13 | 14 | permissions: { 15 | alert: true, 16 | badge: true, 17 | sound: true, 18 | }, 19 | 20 | popInitialNotification: true, 21 | requestPermissions: Platform.OS === 'ios', 22 | }); 23 | 24 | export default PushNotification; 25 | -------------------------------------------------------------------------------- /src/assets/svgs/StatsSvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Svg, Path } from 'react-native-svg'; 3 | 4 | export default function StatsSvg({ width, height, style }) { 5 | return ( 6 | 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /src/utilities/api/hooks/useInvokeQuery.test.js: -------------------------------------------------------------------------------- 1 | import { renderHook } from '@testing-library/react-hooks'; 2 | 3 | import { queryWrapper } from 'tests/queryWrapper'; 4 | import { mockInvokeQuery } from '../__fixtures__'; 5 | import { useInvokeQuery } from './useInvokeQuery'; 6 | 7 | jest.useRealTimers(); 8 | 9 | describe('useInvokeQuery hook', () => { 10 | it('fetch data correctly', async () => { 11 | const { result, waitFor } = renderHook(() => useInvokeQuery({}), { wrapper: queryWrapper }); 12 | 13 | expect(result.current.isLoading).toBeTruthy(); 14 | 15 | await waitFor(() => result.current.isFetched); 16 | 17 | expect(result.current.isSuccess).toBeTruthy(); 18 | expect(result.current.data).toEqual(mockInvokeQuery); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /metro.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | /** 3 | * Metro configuration for React Native 4 | * https://github.com/facebook/react-native 5 | * 6 | * @format 7 | */ 8 | 9 | const defaultSourceExts = require('metro-config/src/defaults/defaults').sourceExts; 10 | 11 | const env = require('./env.json'); 12 | 13 | console.log('env.APP_MODE', env.APP_MODE); 14 | 15 | module.exports = { 16 | resolver: { 17 | sourceExts: env.APP_MODE === 'mocked' ? ['mock.js', ...defaultSourceExts] : defaultSourceExts, 18 | }, 19 | transformer: { 20 | getTransformOptions: async () => ({ 21 | transform: { 22 | experimentalImportSupport: false, 23 | inlineRequires: false, 24 | }, 25 | }), 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/components/ManageApplication/styles.js: -------------------------------------------------------------------------------- 1 | import { colors, themes, boxes } from 'constants/styleGuide'; 2 | 3 | export default { 4 | common: { 5 | container: { 6 | flex: 1, 7 | }, 8 | title: { 9 | textAlign: 'center', 10 | marginBottom: 16, 11 | }, 12 | footer: { 13 | paddingTop: boxes.boxPadding, 14 | }, 15 | }, 16 | [themes.light]: { 17 | container: { 18 | backgroundColor: colors.dark.white, 19 | }, 20 | title: { 21 | color: colors.light.zodiacBlue, 22 | }, 23 | }, 24 | [themes.dark]: { 25 | container: { 26 | backgroundColor: colors.dark.black, 27 | }, 28 | title: { 29 | color: colors.dark.white, 30 | }, 31 | }, 32 | }; 33 | -------------------------------------------------------------------------------- /src/tests/queryWrapper.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { MutationCache, QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query'; 3 | import { addCleanup } from '@testing-library/react-hooks'; 4 | 5 | export function queryWrapper({ children }) { 6 | const mutationCache = new MutationCache(); 7 | 8 | const queryCache = new QueryCache(); 9 | 10 | const queryClient = new QueryClient({ 11 | queryCache, 12 | mutationCache, 13 | defaultOptions: { 14 | queries: { 15 | retry: false, 16 | }, 17 | }, 18 | }); 19 | 20 | addCleanup(() => { 21 | mutationCache.clear(); 22 | queryCache.clear(); 23 | }); 24 | 25 | return {children}; 26 | } 27 | -------------------------------------------------------------------------------- /src/components/shared/Picker/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { useModal } from 'hooks/useModal'; 4 | import { PickerContext } from './hooks'; 5 | import { PickerItem, PickerLabel, usePickerMenu, PickerToggle } from './components'; 6 | 7 | export default function Picker({ children, value, error }) { 8 | const modal = useModal(); 9 | 10 | return ( 11 | 19 | {children} 20 | 21 | ); 22 | } 23 | 24 | Picker.usePickerMenu = usePickerMenu; 25 | Picker.Item = PickerItem; 26 | Picker.Label = PickerLabel; 27 | Picker.Toggle = PickerToggle; 28 | -------------------------------------------------------------------------------- /src/utilities/api/hooks/useInvokeQuery.js: -------------------------------------------------------------------------------- 1 | import { API_VERSION } from '../constants'; 2 | import { INVOKE_QUERY } from '../queries'; 3 | import { useCustomQuery } from './useCustomQuery'; 4 | 5 | /** 6 | * Query that acts as proxy to call direct invoke methods to blockchain application client. 7 | * @param {object} params.config - Query custom configs. 8 | * @param {string} params.options - Query custom options. 9 | */ 10 | export function useInvokeQuery({ config: customConfig = {}, options }) { 11 | const config = { 12 | url: `/api/${API_VERSION}/invoke`, 13 | method: 'POST', 14 | event: 'post.invoke', 15 | ...customConfig, 16 | }; 17 | return useCustomQuery({ 18 | keys: [INVOKE_QUERY, config, options], 19 | config, 20 | options, 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /src/components/shared/Logo/Logo.styles.js: -------------------------------------------------------------------------------- 1 | import { colors } from 'constants/styleGuide'; 2 | 3 | export default function getLogoStyles(size) { 4 | return { 5 | common: { 6 | image: { 7 | borderRadius: 50, 8 | width: size, 9 | height: size, 10 | borderWidth: 1, 11 | borderColor: colors.light.platinumGray, 12 | }, 13 | initialsContainer: { 14 | width: size, 15 | height: size, 16 | borderRadius: 50, 17 | backgroundColor: colors.light.silverGrey, 18 | justifyContent: 'center', 19 | alignItems: 'center', 20 | }, 21 | initials: { 22 | color: colors.light.zodiacBlue, 23 | fontSize: size / 2.5, 24 | fontWeight: 'bold', 25 | }, 26 | }, 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /src/components/shared/fadeInView/index.js: -------------------------------------------------------------------------------- 1 | import React, { useRef } from 'react'; 2 | import { Animated } from 'react-native'; 3 | 4 | const FadeInView = (props) => { 5 | const fadeAnim = useRef(new Animated.Value(0)).current; // Initial value for opacity: 0 6 | 7 | React.useEffect(() => { 8 | Animated.timing(fadeAnim, { 9 | toValue: 1, 10 | duration: 1000, 11 | useNativeDriver: false, 12 | }).start(); 13 | }, [fadeAnim]); 14 | 15 | return ( 16 | 24 | {props.children} 25 | 26 | ); 27 | }; 28 | 29 | export default FadeInView; 30 | -------------------------------------------------------------------------------- /src/constants/styleGuide/fonts.js: -------------------------------------------------------------------------------- 1 | const commercialFontFamily = { 2 | heading: 'Gilroy-Bold', 3 | context: 'BasierCircle-Regular', 4 | contextBold: 'BasierCircle-Bold', 5 | contextSemiBold: 'BasierCircle-SemiBold', 6 | }; 7 | 8 | const freeFontFamily = { 9 | heading: 'OpenSans-Bold', 10 | context: 'OpenSans-Regular', 11 | contextBold: 'OpenSans-Bold', 12 | contextSemiBold: 'OpenSans-SemiBold', 13 | }; 14 | 15 | export default { 16 | family: { 17 | ...(process.env.USE_COMMERCIAL_FONTS ? commercialFontFamily : freeFontFamily), 18 | recoveryPhrase: 'Dots-Regular', 19 | recoveryPhraseText: 'PTMono-Regular', 20 | }, 21 | size: { 22 | h1: 26, 23 | h2: 24, 24 | h3: 22, 25 | h4: 20, 26 | base: 16, 27 | small: 13, 28 | input: 14, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /android/app/src/main/res/xml/data_extraction_rules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 10 | 12 | 14 | 15 | 16 | 18 | 20 | 22 | 24 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/modules/Accounts/components/TokenRow/components/TokenRowSkeleton.styles.js: -------------------------------------------------------------------------------- 1 | import { colors, themes } from 'constants/styleGuide'; 2 | 3 | export default function getTokenRowSkeletonStyles() { 4 | return { 5 | common: { 6 | container: { 7 | flexDirection: 'row', 8 | justifyContent: 'space-between', 9 | borderWidth: 1, 10 | borderRadius: 8, 11 | padding: 16, 12 | }, 13 | row: { 14 | flexDirection: 'row', 15 | alignItems: 'center', 16 | }, 17 | }, 18 | [themes.light]: { 19 | container: { 20 | borderColor: colors.light.platinumGray, 21 | }, 22 | }, 23 | [themes.dark]: { 24 | container: { 25 | borderColor: colors.dark.textInputBg, 26 | }, 27 | }, 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /src/modules/Settings/components/HarmfulAppRow/styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors, fonts } from 'constants/styleGuide'; 2 | 3 | export default () => ({ 4 | common: { 5 | row: { 6 | flexDirection: 'row', 7 | alignItems: 'center', 8 | marginBottom: 20, 9 | }, 10 | packageName: { 11 | fontSize: fonts.size.base, 12 | fontFamily: fonts.family.context, 13 | flex: 1, 14 | }, 15 | appLogo: { 16 | height: 35, 17 | width: 35, 18 | borderRadius: 20, 19 | marginRight: 10, 20 | }, 21 | }, 22 | 23 | [themes.light]: { 24 | packageName: { 25 | color: colors.light.maastrichtBlue, 26 | }, 27 | }, 28 | 29 | [themes.dark]: { 30 | packageName: { 31 | color: colors.dark.platinum, 32 | }, 33 | }, 34 | }); 35 | -------------------------------------------------------------------------------- /patches/jest-circus+29.5.0.patch: -------------------------------------------------------------------------------- 1 | diff --git a/node_modules/jest-circus/build/utils.js b/node_modules/jest-circus/build/utils.js 2 | index 755741b..2022adb 100644 3 | --- a/node_modules/jest-circus/build/utils.js 4 | +++ b/node_modules/jest-circus/build/utils.js 5 | @@ -320,12 +320,12 @@ const callAsyncCircusFn = (testOrHook, testContext, {isHook, timeout}) => { 6 | completed = true; 7 | // If timeout is not cleared/unrefed the node process won't exit until 8 | // it's resolved. 9 | - timeoutID.unref?.(); 10 | + timeoutID?.unref?.(); 11 | clearTimeout(timeoutID); 12 | }) 13 | .catch(error => { 14 | completed = true; 15 | - timeoutID.unref?.(); 16 | + timeoutID?.unref?.(); 17 | clearTimeout(timeoutID); 18 | throw error; 19 | }); 20 | -------------------------------------------------------------------------------- /src/components/shared/Fab/utils/touchable.js: -------------------------------------------------------------------------------- 1 | import { Platform, TouchableOpacity, TouchableNativeFeedback } from 'react-native'; 2 | 3 | import { shadeColor } from './color'; 4 | 5 | export function getTouchableComponent(useNativeFeedback = true) { 6 | if (useNativeFeedback === true && Platform.OS === 'android') { 7 | return TouchableNativeFeedback; 8 | } 9 | return TouchableOpacity; 10 | } 11 | 12 | export function getRippleProps(color, useNativeFeedback = true) { 13 | // less than API 21 don't support Ripple 14 | if (useNativeFeedback === true && Platform.OS === 'android' && Platform.Version >= 21) { 15 | return { 16 | // eslint-disable-next-line new-cap 17 | background: TouchableNativeFeedback.Ripple(shadeColor(color, -30), true), 18 | }; 19 | } 20 | return {}; 21 | } 22 | -------------------------------------------------------------------------------- /src/modules/Transactions/__fixtures__/mockTokensMeta.js: -------------------------------------------------------------------------------- 1 | export const mockDefaultTokenMeta = { 2 | chainID: '00000001', 3 | chainName: 'Lisk', 4 | tokenID: '0400000000000000', 5 | description: 'Default token for the entire Lisk ecosystem', 6 | logo: { 7 | png: 'https://lisk-qa.ams3.digitaloceanspaces.com/Artboard%201%20copy%2019.png', 8 | svg: 'https://lisk-qa.ams3.digitaloceanspaces.com/Logo-20.svg', 9 | }, 10 | symbol: 'LSK', 11 | displayDenom: 'lsk', 12 | baseDenom: 'beddows', 13 | denomUnits: [ 14 | { 15 | denom: 'beddows', 16 | decimals: 0, 17 | aliases: ['Beddows'], 18 | }, 19 | { 20 | denom: 'lsk', 21 | decimals: 8, 22 | aliases: ['Lisk'], 23 | }, 24 | ], 25 | }; 26 | 27 | export const mockTokensMeta = [mockDefaultTokenMeta]; 28 | -------------------------------------------------------------------------------- /src/modules/Transactions/utils/helpers.test.js: -------------------------------------------------------------------------------- 1 | import { computeNonce } from './helpers'; 2 | 3 | describe('Transaction module helpers', () => { 4 | describe('computeNonce', () => { 5 | it('returns the authNonce if transactionPool is empty', () => { 6 | const authNonce = '123456'; 7 | const transactionPool = []; 8 | const result = computeNonce(authNonce, transactionPool); 9 | expect(result).toEqual(authNonce); 10 | }); 11 | 12 | it('returns the maximum nonce from the transactionPool', () => { 13 | const authNonce = '123456'; 14 | const transactionPool = [{ nonce: '123450' }, { nonce: '123454' }, { nonce: '123455' }]; 15 | const result = computeNonce(authNonce, transactionPool); 16 | expect(result).toEqual('123455'); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /android/app/src/release/java/com/lisk/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package io.lisk.mobile; 8 | 9 | import android.content.Context; 10 | import com.facebook.react.ReactInstanceManager; 11 | 12 | /** 13 | * Class responsible of loading Flipper inside your React Native application. This is the release 14 | * flavor of it so it's empty as we don't want to load Flipper. 15 | */ 16 | public class ReactNativeFlipper { 17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 18 | // Do nothing as we don't want to initialize Flipper on Release. 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/modules/Accounts/store/actions/account.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable max-lines */ 2 | import actionTypes from '../../actionTypes'; 3 | 4 | /** 5 | * Trigger this action to log out of the account 6 | * while already logged in 7 | * 8 | * @returns {Object} - Action object 9 | */ 10 | export const setCurrentAccount = (encryptedAccount) => ({ 11 | type: actionTypes.setCurrentAccount, 12 | encryptedAccount, 13 | }); 14 | 15 | export const addAccount = (encryptedAccount) => ({ 16 | type: actionTypes.addAccount, 17 | encryptedAccount, 18 | }); 19 | 20 | export const updateAccount = (address, accountData) => ({ 21 | type: actionTypes.updateAccount, 22 | address, 23 | accountData, 24 | }); 25 | 26 | export const deleteAccount = (address) => ({ 27 | type: actionTypes.deleteAccount, 28 | address, 29 | }); 30 | -------------------------------------------------------------------------------- /src/utilities/qrCode.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/prefer-default-export 2 | export const decodeLaunchUrl = (data) => { 3 | const recipientReg = /\?recipient=([^&]+)&/; 4 | const amountReg = /amount=(\d+)\.?(\d+)?/; 5 | const referenceReg = /reference=.*$/; 6 | const liskProtocolReg = /^[l|L]isk:\/\//; 7 | 8 | if (liskProtocolReg.test(data) && recipientReg.test(data)) { 9 | const address = data.match(recipientReg)[1]; 10 | const amount = data.match(amountReg) ? data.match(amountReg)[0].replace('amount=', '') : ''; 11 | const reference = data.match(referenceReg) 12 | ? window.decodeURIComponent(data.match(referenceReg)[0].replace('reference=', '')) 13 | : ''; 14 | 15 | return { address, amount, reference }; 16 | } 17 | 18 | return { address: data || '' }; 19 | }; 20 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/components/ApplicationManagerModal/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Stepper from 'components/shared/Stepper'; 3 | import { useModal } from 'hooks/useModal'; 4 | 5 | import ManageApplication from '../ManageApplication'; 6 | import DeleteApplication from '../DeleteApplication'; 7 | import DeleteApplicationSuccess from '../DeleteApplicationSuccess'; 8 | 9 | export default function ApplicationManagerModal({ navigation }) { 10 | const modal = useModal(); 11 | const closeModal = () => modal.toggle(false); 12 | 13 | return ( 14 | 15 | 16 | 17 | 18 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/lisk/SensitiveClipboardPackage.java: -------------------------------------------------------------------------------- 1 | package io.lisk.mobile; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.NativeModule; 5 | import com.facebook.react.bridge.ReactApplicationContext; 6 | import com.facebook.react.uimanager.ViewManager; 7 | import java.util.Arrays; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class SensitiveClipboardPackage implements ReactPackage { 12 | 13 | @Override 14 | public List createNativeModules(ReactApplicationContext reactContext) { 15 | return Arrays.asList(new SensitiveClipboardModule(reactContext)); 16 | } 17 | 18 | @Override 19 | public List createViewManagers(ReactApplicationContext reactContext) { 20 | return Collections.emptyList(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/lisk/VerifyAppsPackage.java: -------------------------------------------------------------------------------- 1 | package io.lisk.mobile; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.NativeModule; 5 | import com.facebook.react.bridge.ReactApplicationContext; 6 | import com.facebook.react.uimanager.ViewManager; 7 | 8 | import java.util.Collections; 9 | import java.util.List; 10 | import java.util.Arrays; 11 | 12 | public class VerifyAppsPackage implements ReactPackage { 13 | 14 | @Override 15 | public List createNativeModules(ReactApplicationContext reactContext) { 16 | return Arrays.asList(new VerifyAppsModule(reactContext)); 17 | } 18 | 19 | @Override 20 | public List createViewManagers(ReactApplicationContext reactContext) { 21 | return Collections.emptyList(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/components/shared/Logo/Logo.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Image } from 'react-native'; 3 | 4 | import { useTheme } from 'contexts/ThemeContext'; 5 | import { P } from 'components/shared/toolBox/typography'; 6 | import { getInitials } from 'utilities/helpers'; 7 | 8 | import getStyles from './Logo.styles'; 9 | 10 | export default function Logo({ uri, name, size = 40, style }) { 11 | const { styles } = useTheme({ styles: getStyles(size) }); 12 | 13 | if (uri) { 14 | return ; 15 | } 16 | 17 | if (name) { 18 | const initials = getInitials(name); 19 | 20 | return ( 21 | 22 |

{initials}

23 | 24 | ); 25 | } 26 | 27 | return null; 28 | } 29 | -------------------------------------------------------------------------------- /ios/LiskTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/modules/SendToken/components/SummaryStep/styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors, boxes } from 'constants/styleGuide'; 2 | 3 | export default function getSendTokenSummaryStepStyles() { 4 | return { 5 | common: { 6 | container: { 7 | flex: 1, 8 | padding: boxes.boxPadding, 9 | }, 10 | footer: { 11 | flexDirection: 'row', 12 | alignItems: 'center', 13 | justifyContent: 'center', 14 | padding: boxes.boxPadding, 15 | }, 16 | buttonMarginVertical: { 17 | marginVertical: 16, 18 | }, 19 | }, 20 | [themes.light]: { 21 | container: { 22 | backgroundColor: colors.light.white, 23 | }, 24 | }, 25 | [themes.dark]: { 26 | container: { 27 | backgroundColor: colors.dark.mainBg, 28 | }, 29 | }, 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /src/modules/Transactions/components/TransactionRow/components/TransactionStatus.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import CircleCrossedSvg from 'assets/svgs/CircleCrossedSvg'; 4 | import CheckSvg from 'assets/svgs/CheckSvg'; 5 | import SandClockSvg from 'assets/svgs/SandClockSvg'; 6 | 7 | export function TransactionStatus({ transaction }) { 8 | let children = null; 9 | 10 | const props = { height: 14, width: 14 }; 11 | 12 | switch (transaction.executionStatus) { 13 | case 'successful': 14 | children = ; 15 | break; 16 | 17 | case 'pending': 18 | children = ; 19 | break; 20 | 21 | case 'failed': 22 | children = ; 23 | break; 24 | 25 | default: 26 | break; 27 | } 28 | 29 | return children; 30 | } 31 | -------------------------------------------------------------------------------- /ios/Lisk-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/modules/Auth/hooks/usePasswordForm.js: -------------------------------------------------------------------------------- 1 | import { useForm, useController } from 'react-hook-form'; 2 | import * as yup from 'yup'; 3 | import { yupResolver } from '@hookform/resolvers/yup'; 4 | 5 | import { passwordValidationRegex } from 'modules/Auth/validators'; 6 | 7 | const validationSchema = yup 8 | .object() 9 | .shape({ 10 | password: yup.string().required('Password must have a value.').matches(passwordValidationRegex), 11 | }) 12 | .required(); 13 | 14 | export function usePasswordForm(props = {}) { 15 | const form = useForm({ 16 | defaultValues: { 17 | password: '', 18 | }, 19 | resolver: yupResolver(validationSchema), 20 | ...props, 21 | }); 22 | 23 | const controller = useController({ 24 | name: 'password', 25 | control: form.control, 26 | }); 27 | 28 | return [form, controller]; 29 | } 30 | -------------------------------------------------------------------------------- /src/components/shared/Checkbox/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | import { TouchableOpacity } from 'react-native-gesture-handler'; 4 | import { useTheme } from 'contexts/ThemeContext'; 5 | import CheckSvg from 'assets/svgs/CheckSvg'; 6 | import checkboxStyles from './styles'; 7 | 8 | export default function Checkbox({ children, selected, onPress, style, ...props }) { 9 | const { styles } = useTheme({ styles: checkboxStyles }); 10 | return ( 11 | 12 | 13 | {selected && } 14 | 15 | 16 | {children} 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /src/components/shared/DataRenderer/styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors, fonts } from 'constants/styleGuide'; 2 | 3 | export default function getDataRendererStyles() { 4 | return { 5 | common: { 6 | text: { 7 | fontFamily: fonts.family.context, 8 | fontSize: fonts.size.base, 9 | }, 10 | errorText: { 11 | fontFamily: fonts.family.context, 12 | fontSize: fonts.size.base, 13 | }, 14 | }, 15 | [themes.light]: { 16 | text: { 17 | color: colors.light.zodiacBlue, 18 | }, 19 | errorText: { 20 | color: colors.light.burntSieanna, 21 | }, 22 | }, 23 | [themes.dark]: { 24 | text: { 25 | color: colors.light.whiteSmoke, 26 | }, 27 | errorText: { 28 | color: colors.light.burntSieanna, 29 | }, 30 | }, 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /src/components/screens/IntroScreen/IntroScreen.styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors, boxes } from 'constants/styleGuide'; 2 | 3 | export default function getIntroScreenStyles() { 4 | return { 5 | common: { 6 | container: { 7 | flex: 1, 8 | justifyContent: 'space-between', 9 | }, 10 | footer: { 11 | flexDirection: 'row', 12 | alignItems: 'flex-end', 13 | padding: boxes.boxPadding, 14 | height: 152, 15 | }, 16 | lastSlideFooter: { 17 | padding: boxes.boxPadding, 18 | height: 152, 19 | }, 20 | }, 21 | [themes.light]: { 22 | container: { 23 | backgroundColor: colors.light.white, 24 | }, 25 | }, 26 | [themes.dark]: { 27 | container: { 28 | backgroundColor: colors.dark.mainBg, 29 | }, 30 | }, 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /src/assets/svgs/LinkSvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Svg, Path } from 'react-native-svg'; 3 | 4 | export default () => ( 5 | 6 | 12 | 18 | 24 | 25 | ); 26 | -------------------------------------------------------------------------------- /src/components/shared/Fab/FloatingItem/styles.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | import { colors, fonts } from 'constants/styleGuide'; 3 | 4 | export default StyleSheet.create({ 5 | container: { 6 | elevation: 0, 7 | flex: 1, 8 | flexDirection: 'column', 9 | }, 10 | actionContainer: { 11 | elevation: 0, 12 | flex: 1, 13 | flexDirection: 'row', 14 | alignItems: 'center', 15 | paddingLeft: 0, 16 | paddingRight: 0, 17 | }, 18 | textContainer: { 19 | paddingHorizontal: 8, 20 | borderRadius: 4, 21 | height: 22, 22 | }, 23 | text: { 24 | fontSize: 15, 25 | fontFamily: fonts.family.contextBold, 26 | color: colors.light.white, 27 | }, 28 | button: { 29 | alignItems: 'center', 30 | justifyContent: 'center', 31 | backgroundColor: colors.light.ultramarineBlue, 32 | }, 33 | }); 34 | -------------------------------------------------------------------------------- /src/hooks/useTimeoutMonitor.js: -------------------------------------------------------------------------------- 1 | import { useRef, useEffect, useCallback } from 'react'; 2 | 3 | export function useTimeoutMonitor(maxTime, onTimeout) { 4 | const timerRef = useRef(null); 5 | 6 | const initialize = useCallback(() => { 7 | if (timerRef.current) { 8 | clearTimeout(timerRef.current); 9 | } 10 | 11 | timerRef.current = setTimeout(() => { 12 | if (onTimeout && typeof onTimeout === 'function') { 13 | onTimeout(); 14 | } 15 | }, maxTime); 16 | }, [maxTime, onTimeout]); 17 | 18 | const destroy = useCallback(() => { 19 | if (timerRef.current) { 20 | clearTimeout(timerRef.current); 21 | } 22 | }, []); 23 | 24 | useEffect(() => { 25 | return () => { 26 | if (timerRef.current) clearTimeout(timerRef.current); 27 | }; 28 | }, []); 29 | 30 | return { initialize, destroy }; 31 | } 32 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/components/ApplicationList/components/ApplicationListSkeleton.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | 4 | import ApplicationRowSkeleton from '../../ApplicationRow/components/ApplicationRowSkeleton'; 5 | 6 | /** 7 | * Skeleton UI placeholder for ApplicationList loading state. 8 | * @param {React.CSSProperties} style - Custom styles to add to the main component 9 | * container (optional). 10 | */ 11 | export default function ApplicationListSkeleton({ style }) { 12 | const skeletonsCount = 5; 13 | 14 | return ( 15 | 16 | {[...new Array(skeletonsCount)].map((_, index) => ( 17 | 21 | ))} 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /src/assets/svgs/InfoRoundSvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Svg, Path, Circle } from 'react-native-svg'; 3 | 4 | export default ({ color, size = 20, style }) => ( 5 | 13 | 17 | 18 | 19 | ); 20 | -------------------------------------------------------------------------------- /src/constants/regex.js: -------------------------------------------------------------------------------- 1 | export default { 2 | amount: /^\d+(?:[.,]\d{1,8})?$/, 3 | publicKey: /^[a-f0-9]{64}$/i, 4 | address: /^lsk[a-z0-9]{0,38}$/, 5 | legacyAddress: /^[1-9]\d{0,19}L$/, 6 | username: /^[a-z0-9!@$&_.]{3,20}$/, 7 | delegateName: /^[a-z0-9!@$&_.]{3,20}$/, 8 | transactionId: /^[0-9a-z]{64}/, 9 | blockId: /^[0-9a-z]{64}/, 10 | blockHeight: /^[0-9]+$/, 11 | truncate: { 12 | small: /^(.{6})(.+)?(.{5})$/, 13 | medium: 14 | /\b((bc|tb)(0([ac-hj-np-z02-9]{39}|[ac-hj-np-z02-9]{59})|1[ac-hj-np-z02-9]{8,87})|([13]|[mn2])[a-km-zA-HJ-NP-Z1-9]{25,39})\b/, 15 | }, 16 | lskAddressTrunk: /^(.{6})(.+)?(.{5})$/, 17 | publicKeyTrunk: /^(.{6})(.+)?(.{5})$/, 18 | delegateSpecialChars: /[a-z0-9!@$&_.]+/g, 19 | htmlElements: /<(\w+).*?>([\s\S]*?)<\/\1>(.*)/, 20 | releaseSummary: /

([\s\S]*?)<\/h4>/i, 21 | searchbar: /^(.{9})(.+)$/, 22 | }; 23 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/lisk/ScopedStoragePackage.java: -------------------------------------------------------------------------------- 1 | package io.lisk.mobile; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.NativeModule; 5 | import com.facebook.react.bridge.ReactApplicationContext; 6 | import com.facebook.react.uimanager.ViewManager; 7 | 8 | import java.util.Arrays; 9 | import java.util.Collections; 10 | import java.util.List; 11 | 12 | public class ScopedStoragePackage implements ReactPackage { 13 | 14 | @Override 15 | public List createViewManagers(ReactApplicationContext reactContext) { 16 | return Collections.emptyList(); 17 | } 18 | 19 | @Override 20 | public List createNativeModules(ReactApplicationContext reactContext) { 21 | return Arrays.asList( 22 | new ScopedStorageModule(reactContext) 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /env.example.json: -------------------------------------------------------------------------------- 1 | { 2 | "RECOVERY_PHRASE": "A RECOVERY PHRASE FOR DEV PURPOSES", 3 | "NETWORK": "NETWORK IN USE", 4 | "SERVICE_API_BASE_URL": "SERVICE HTTP API BASE URL", 5 | "SERVICE_WS_BASE_URL": "SERVICE WEB SOCKETS API BASE URL", 6 | "SERVICE_API_VERSION": "v3", 7 | "PROJECT_ID": "WALLET CONNECT PROJECT ID", 8 | "RELAY_URL": "WALLET CONNECT RELAY URL", 9 | "MOCK_SERVICE_API_ENABLED": "FLAG THAT INDICATES IF SERVICE API MOCKING IS OR NOT ENABLED", 10 | "MOCKED_SERVICE_ENDPOINTS": "NAMES OF SERVICE ENDPOINTS TO MOCK, SEPARATED BY ';'. SHOULD FOLLOW THE DEFINED NOMENCLATURE. EXAMPLE: 'getApplications;getApplicationsMeta'", 11 | "APP_MODE": "USE 'mocked' FOR END TO END TESTS TO ENABLE PREDICTING RESULTS OF SOME SYSTEM AND APP FUNCTIONS", 12 | "USE_COMMERCIAL_FONTS": "USED TO DECIDE IF THE LISK MOBILE SHOULD USE COMMERCIAL FONTS OR FREE FONTS" 13 | } -------------------------------------------------------------------------------- /src/components/shared/EmptyState/styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors } from 'constants/styleGuide'; 2 | 3 | export default function getEmptyStateStyles() { 4 | return { 5 | common: { 6 | container: { 7 | alignItems: 'center', 8 | justifyContent: 'center', 9 | padding: 10, 10 | }, 11 | messageText: { 12 | marginTop: 10, 13 | fontSize: 14, 14 | textAlign: 'center', 15 | }, 16 | }, 17 | [themes.light]: { 18 | container: { 19 | backgroundColor: colors.light.white, 20 | }, 21 | messageText: { 22 | color: colors.light.slateGray, 23 | }, 24 | }, 25 | [themes.dark]: { 26 | container: { 27 | backgroundColor: colors.dark.mainBg, 28 | }, 29 | messageText: { 30 | color: colors.dark.slateGray, 31 | }, 32 | }, 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /src/modules/Bookmark/components/List.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import InfiniteScrollList from 'components/shared/InfiniteScrollList'; 4 | import { validateAddress } from 'utilities/validators'; 5 | import withTheme from 'components/shared/withTheme'; 6 | import { DraggableItem, Item } from './Item'; 7 | import getStyles from './styles'; 8 | 9 | const List = ({ list, onPress, draggable, Component }) => { 10 | const Element = Component || (draggable ? DraggableItem : Item); 11 | 12 | return ( 13 | ( 16 | 22 | )} 23 | /> 24 | ); 25 | }; 26 | 27 | export default withTheme(List, getStyles()); 28 | -------------------------------------------------------------------------------- /.husky/_/husky.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | if [ -z "$husky_skip_init" ]; then 3 | debug () { 4 | if [ "$HUSKY_DEBUG" = "1" ]; then 5 | echo "husky (debug) - $1" 6 | fi 7 | } 8 | 9 | readonly hook_name="$(basename -- "$0")" 10 | debug "starting $hook_name..." 11 | 12 | if [ "$HUSKY" = "0" ]; then 13 | debug "HUSKY env variable is set to 0, skipping hook" 14 | exit 0 15 | fi 16 | 17 | if [ -f ~/.huskyrc ]; then 18 | debug "sourcing ~/.huskyrc" 19 | . ~/.huskyrc 20 | fi 21 | 22 | readonly husky_skip_init=1 23 | export husky_skip_init 24 | sh -e "$0" "$@" 25 | exitCode="$?" 26 | 27 | if [ $exitCode != 0 ]; then 28 | echo "husky - $hook_name hook exited with code $exitCode (error)" 29 | fi 30 | 31 | if [ $exitCode = 127 ]; then 32 | echo "husky - command not found in PATH=$PATH" 33 | fi 34 | 35 | exit $exitCode 36 | fi 37 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/components/ApplicationRow/components/ApplicationRowSkeleton.styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors } from 'constants/styleGuide'; 2 | 3 | export default function getApplicationRowSkeletonStyles() { 4 | return { 5 | common: { 6 | container: { 7 | flexDirection: 'row', 8 | justifyContent: 'space-between', 9 | alignItems: 'center', 10 | paddingTop: 16, 11 | paddingBottom: 16, 12 | borderBottomWidth: 1, 13 | }, 14 | row: { 15 | flexDirection: 'row', 16 | alignItems: 'center', 17 | }, 18 | }, 19 | [themes.light]: { 20 | container: { 21 | borderBottomColor: colors.light.platinumGray, 22 | }, 23 | }, 24 | 25 | [themes.dark]: { 26 | container: { 27 | borderBottomColor: colors.dark.volcanicSand, 28 | }, 29 | }, 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/lisk/ExactAlarmPackage.java: -------------------------------------------------------------------------------- 1 | package io.lisk.mobile; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.NativeModule; 5 | import com.facebook.react.bridge.ReactApplicationContext; 6 | import com.facebook.react.uimanager.ViewManager; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Collections; 10 | import java.util.List; 11 | 12 | public class ExactAlarmPackage implements ReactPackage { 13 | @Override 14 | public List createViewManagers(ReactApplicationContext reactContext) { 15 | return Collections.emptyList(); 16 | } 17 | 18 | @Override 19 | public List createNativeModules(ReactApplicationContext reactContext) { 20 | List modules = new ArrayList<>(); 21 | modules.add(new ExactAlarmModule(reactContext)); 22 | return modules; 23 | } 24 | } -------------------------------------------------------------------------------- /src/components/shared/Scanner/CameraAccessAlert.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import { Alert } from 'react-native'; 3 | import OpenAppSettings from 'react-native-app-settings'; 4 | import i18next from 'i18next'; 5 | 6 | export default function CameraAccessAlert({ type, close }) { 7 | const handleOpenSettingsPress = () => OpenAppSettings.open(); 8 | 9 | useEffect(() => { 10 | if (type === 'noAuth') { 11 | Alert.alert( 12 | i18next.t('scanner.cameraAccessTitle'), 13 | i18next.t('scanner.cameraAccessDescription'), 14 | [ 15 | { 16 | text: i18next.t('commons.buttons.cancel'), 17 | onPress: close, 18 | style: 'cancel', 19 | }, 20 | { text: i18next.t('settings.title'), onPress: handleOpenSettingsPress }, 21 | ] 22 | ); 23 | } 24 | }, [close, type]); 25 | 26 | return null; 27 | } 28 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/lisk/AppOpsManagerModulePackage.java: -------------------------------------------------------------------------------- 1 | package io.lisk.mobile; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.NativeModule; 5 | import com.facebook.react.bridge.ReactApplicationContext; 6 | import com.facebook.react.uimanager.ViewManager; 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class AppOpsManagerModulePackage implements ReactPackage { 12 | 13 | @Override 14 | public List createViewManagers(ReactApplicationContext reactContext) { 15 | return Collections.emptyList(); 16 | } 17 | 18 | @Override 19 | public List createNativeModules(ReactApplicationContext reactContext) { 20 | List modules = new ArrayList<>(); 21 | 22 | modules.add(new AppOpsManagerModule(reactContext)); 23 | 24 | return modules; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/lisk/ProviderInstallerPackage.java: -------------------------------------------------------------------------------- 1 | package io.lisk.mobile; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.NativeModule; 5 | import com.facebook.react.bridge.ReactApplicationContext; 6 | import com.facebook.react.uimanager.ViewManager; 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class ProviderInstallerPackage implements ReactPackage { 12 | 13 | @Override 14 | public List createViewManagers(ReactApplicationContext reactContext) { 15 | return Collections.emptyList(); 16 | } 17 | 18 | @Override 19 | public List createNativeModules(ReactApplicationContext reactContext) { 20 | List modules = new ArrayList<>(); 21 | 22 | modules.add(new ProviderInstallerModule(reactContext)); 23 | 24 | return modules; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/modules/Accounts/components/AccountDetails/AccountDetails.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | 4 | import { useTheme } from 'contexts/ThemeContext'; 5 | import AccountCard from '../AccountCard/AccountCard'; 6 | import getAccountDetailsStyles from './AccountDetails.styles'; 7 | import MigrateToL2Card from '../MigrateToL2Card/MigrateToL2Card'; 8 | 9 | /** 10 | * Renders a account detailed information (personal data, tokens and transactions) given an address. 11 | * @param {Object} account - Account to which render its information. 12 | */ 13 | export default function AccountDetails({ account }) { 14 | const { styles } = useTheme({ styles: getAccountDetailsStyles() }); 15 | 16 | return ( 17 | 18 | 19 | 20 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /src/modules/Network/api/useNetworkStatusQuery.test.js: -------------------------------------------------------------------------------- 1 | import { renderHook } from '@testing-library/react-hooks'; 2 | 3 | import { mockNetworkStatus } from '../__fixtures__'; 4 | import { useNetworkStatusQuery } from './useNetworkStatusQuery'; 5 | import { applicationsWrapper } from '../../../tests/applicationsWrapper'; 6 | 7 | jest.useRealTimers(); 8 | 9 | describe('useNetworkStatusQuery hook', () => { 10 | const wrapper = ({ children }) => applicationsWrapper({ children }); 11 | 12 | it('fetches data correctly', async () => { 13 | const { result, waitFor } = renderHook(() => useNetworkStatusQuery(), { 14 | wrapper, 15 | }); 16 | 17 | expect(result.current.isLoading).toBeTruthy(); 18 | 19 | await waitFor(() => result.current.isFetched); 20 | 21 | expect(result.current.isSuccess).toBeTruthy(); 22 | 23 | expect(result.current.data).toEqual(mockNetworkStatus); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/utilities/qrCode.test.js: -------------------------------------------------------------------------------- 1 | import * as qrCode from './qrCode'; 2 | 3 | describe('QR Code Helper', () => { 4 | it('decodes QR data that contains URL', () => { 5 | const data = 'lisk://wallet?recipient=1L&amount=1&reference=test'; 6 | expect(qrCode.decodeLaunchUrl(data)).toEqual({ 7 | address: '1L', 8 | amount: '1', 9 | reference: 'test', 10 | }); 11 | }); 12 | 13 | it('decodes QR data that contains URL and reference with space', () => { 14 | const data = 'lisk://wallet?recipient=1L&amount=1&reference=test%20mobile'; 15 | expect(qrCode.decodeLaunchUrl(data)).toEqual({ 16 | address: '1L', 17 | amount: '1', 18 | reference: 'test mobile', 19 | }); 20 | }); 21 | 22 | it('decodes QR data just address', () => { 23 | const data = '1L'; 24 | expect(qrCode.decodeLaunchUrl(data)).toEqual({ 25 | address: data, 26 | }); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /patches/@react-native-community+cli-platform-ios+6.0.0.patch: -------------------------------------------------------------------------------- 1 | diff --git a/node_modules/@react-native-community/cli-platform-ios/native_modules.rb b/node_modules/@react-native-community/cli-platform-ios/native_modules.rb 2 | index 1b6eece..18744c7 100644 3 | --- a/node_modules/@react-native-community/cli-platform-ios/native_modules.rb 4 | +++ b/node_modules/@react-native-community/cli-platform-ios/native_modules.rb 5 | @@ -43,6 +43,15 @@ def use_native_modules!(config = nil) 6 | found_pods = [] 7 | 8 | packages.each do |package_name, package| 9 | + 10 | + # PATCH TO DISABLE CONFLICTING MODULES (duplicate symbols) 11 | + puts ">> package_name #{package_name}" 12 | + 13 | + next if %w( 14 | + react-native-udp 15 | + react-native-tcp 16 | + ).include?(package_name) 17 | + 18 | next unless package_config = package["platforms"]["ios"] 19 | 20 | podspec_path = package_config["podspecPath"] 21 | -------------------------------------------------------------------------------- /src/modules/Auth/components/RecoveryPhraseSecurityAdviceCard/RecoveryPhraseSecurityAdviceCard.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | import i18next from 'i18next'; 4 | 5 | import { useTheme } from 'contexts/ThemeContext'; 6 | import { P } from 'components/shared/toolBox/typography'; 7 | 8 | import { getRecoveryPhraseSecurityAdviceCardStyles } from './RecoveryPhraseSecurityAdviceCard.styles'; 9 | 10 | export default function RecoveryPhraseSecurityAdviceCard({ style }) { 11 | const { styles } = useTheme({ 12 | styles: getRecoveryPhraseSecurityAdviceCardStyles(), 13 | }); 14 | 15 | return ( 16 | 17 |

18 | {i18next.t('commons.recoveryPhrase.writeDownInstructions')} 19 |

20 |
21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /libs/wcm/utils/error.js: -------------------------------------------------------------------------------- 1 | export const PARSE_ERROR = 'PARSE_ERROR'; 2 | export const INVALID_REQUEST = 'INVALID_REQUEST'; 3 | export const METHOD_NOT_FOUND = 'METHOD_NOT_FOUND'; 4 | export const INVALID_PARAMS = 'INVALID_PARAMS'; 5 | export const INTERNAL_ERROR = 'INTERNAL_ERROR'; 6 | export const SERVER_ERROR = 'SERVER_ERROR'; 7 | 8 | export const RESERVED_ERROR_CODES = [-32700, -32600, -32601, -32602, -32603]; 9 | export const SERVER_ERROR_CODE_RANGE = [-32000, -32099]; 10 | 11 | export const STANDARD_ERROR_MAP = { 12 | [PARSE_ERROR]: { code: -32700, message: 'Parse error' }, 13 | [INVALID_REQUEST]: { code: -32600, message: 'Invalid Request' }, 14 | [METHOD_NOT_FOUND]: { code: -32601, message: 'Method not found' }, 15 | [INVALID_PARAMS]: { code: -32602, message: 'Invalid params' }, 16 | [INTERNAL_ERROR]: { code: -32603, message: 'Internal error' }, 17 | [SERVER_ERROR]: { code: -32000, message: 'Server error' }, 18 | }; 19 | -------------------------------------------------------------------------------- /src/assets/svgs/CaretSvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Svg, Path } from 'react-native-svg'; 3 | 4 | export default function CaretSvg({ 5 | direction = 'right', 6 | color = 'currentColor', 7 | height = 20, 8 | width = 20, 9 | style, 10 | }) { 11 | let d; 12 | 13 | switch (direction) { 14 | case 'right': 15 | d = 'M6.5 4L13.5 10L6.5 16'; 16 | break; 17 | case 'down': 18 | d = 'M4 6.5L10 13.5L16 6.5'; 19 | break; 20 | 21 | case 'left': 22 | d = 'M13.5 4L6.5 10L13.5 16'; 23 | break; 24 | 25 | case 'up': 26 | d = 'M16 13.5L10 6.5L4 13.5'; 27 | break; 28 | 29 | default: 30 | break; 31 | } 32 | 33 | return ( 34 | 35 | 36 | 37 | ); 38 | } 39 | -------------------------------------------------------------------------------- /src/modules/Transactions/api/useFeesQuery.js: -------------------------------------------------------------------------------- 1 | import { API_URL } from 'utilities/api/constants'; 2 | import { GET_FEES_QUERY } from 'utilities/api/queries'; 3 | import { useCustomQuery } from 'utilities/api/hooks/useCustomQuery'; 4 | import { useQueryKeys } from 'utilities/api/hooks/useQueryKeys'; 5 | 6 | /** 7 | * Requests fee estimates of a network. 8 | * @param {Object} config - Custom configurations for the query. 9 | * @param {Object} options - Custom options for the query. 10 | * @returns - The fee estimate per byte used for transaction fee calculation. 11 | */ 12 | export function useFeesQuery({ config: customConfig = {}, options = {} } = {}) { 13 | const config = { 14 | url: `${API_URL}/fees`, 15 | method: 'GET', 16 | event: 'get.fees', 17 | ...customConfig, 18 | }; 19 | 20 | const keys = useQueryKeys([GET_FEES_QUERY, config]); 21 | 22 | return useCustomQuery({ config, options, keys }); 23 | } 24 | -------------------------------------------------------------------------------- /src/components/shared/Skeleton/Skeleton.styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors } from 'constants/styleGuide'; 2 | 3 | export function getSkeletonStyles({ width, height, variant }) { 4 | return { 5 | common: { 6 | container: { 7 | width, 8 | height: variant === 'circle' ? width : height, 9 | overflow: 'hidden', 10 | }, 11 | animation: { 12 | position: 'absolute', 13 | top: 0, 14 | bottom: 0, 15 | right: 0, 16 | left: 0, 17 | }, 18 | rectangleContainer: { 19 | borderRadius: 4, 20 | }, 21 | circleContainer: { 22 | borderRadius: 50, 23 | }, 24 | }, 25 | [themes.light]: { 26 | container: { 27 | backgroundColor: colors.light.platinumGray, 28 | }, 29 | }, 30 | [themes.dark]: { 31 | container: { 32 | backgroundColor: colors.dark.textInputBg, 33 | }, 34 | }, 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /src/assets/svgs/ProgressSvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Svg, Path, Rect } from 'react-native-svg'; 3 | 4 | export default ({ color, size = 1 }) => ( 5 | 12 | 13 | 19 | 23 | 24 | ); 25 | -------------------------------------------------------------------------------- /src/hooks/useScreenshotPrevent.test.js: -------------------------------------------------------------------------------- 1 | import { renderHook } from '@testing-library/react-hooks'; 2 | import RNScreenshotPrevent from 'react-native-screenshot-prevent'; 3 | 4 | import useScreenshotPrevent from './useScreenshotPrevent'; 5 | 6 | jest.mock('react-native-screenshot-prevent', () => ({ 7 | enabled: jest.fn(), 8 | })); 9 | 10 | describe('useScreenshotPrevent hook', () => { 11 | it('should be defined', () => { 12 | expect(useScreenshotPrevent).toBeDefined(); 13 | }); 14 | 15 | it('enables/disables properly the functionality when mounting/unmounting', () => { 16 | const { unmount } = renderHook(() => useScreenshotPrevent()); 17 | 18 | expect(RNScreenshotPrevent.enabled).toBeCalledTimes(1); 19 | expect(RNScreenshotPrevent.enabled).toBeCalledWith(true); 20 | 21 | unmount(); 22 | 23 | expect(RNScreenshotPrevent.enabled).toBeCalledTimes(2); 24 | expect(RNScreenshotPrevent.enabled).toBeCalledWith(false); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/components/DeleteApplicationSuccess/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import i18next from 'i18next'; 3 | 4 | import ResultScreen from 'components/screens/ResultScreen'; 5 | import { useTheme } from 'contexts/ThemeContext'; 6 | 7 | import getStyles from './styles'; 8 | 9 | export default function DeleteApplicationSuccess({ finalCallback, sharedData: { application } }) { 10 | const { styles } = useTheme({ styles: getStyles() }); 11 | 12 | return ( 13 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/lisk/RNArgon2Package.java: -------------------------------------------------------------------------------- 1 | package io.lisk.mobile; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.JavaScriptModule; 5 | import com.facebook.react.bridge.NativeModule; 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.react.uimanager.ViewManager; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Collections; 11 | import java.util.List; 12 | 13 | public class RNArgon2Package implements ReactPackage { 14 | @Override 15 | public List createNativeModules(ReactApplicationContext reactContext) { 16 | List modules = new ArrayList<>(); 17 | 18 | modules.add(new RNArgon2Module(reactContext)); 19 | return modules; 20 | } 21 | 22 | @Override 23 | public List createViewManagers(ReactApplicationContext reactApplicationContext) { 24 | return Collections.emptyList(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /scripts/setupJestAfterEnv.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { setupServer } from 'msw/node'; 3 | 4 | import { MSWServer } from '../services/msw/MSWServer'; 5 | import apiClient from '../src/utilities/api/APIClient'; 6 | import liskAPIClient from '../src/utilities/api/LiskAPIClient'; 7 | 8 | const mswTestServer = new MSWServer('test', setupServer); 9 | 10 | // Establish API mocking before all tests. 11 | beforeAll(() => { 12 | mswTestServer.init({ onUnhandledRequest: 'error' }); 13 | 14 | apiClient.create({ ws: 'wss://localhost', http: 'http://localhost' }); 15 | liskAPIClient.create({ ws: 'wss://localhost', http: 'http://localhost' }); 16 | }); 17 | 18 | // Reset any request handlers that we may add during the tests, 19 | // so they don't affect other tests. 20 | afterEach(() => mswTestServer.server.resetHandlers()); 21 | 22 | // Clean up after the tests are finished. 23 | afterAll(() => mswTestServer.server.close()); 24 | -------------------------------------------------------------------------------- /src/assets/svgs/BookmarkSvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Svg, Path } from 'react-native-svg'; 3 | 4 | export default () => ( 5 | 6 | 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/components/ApplicationsStats/components/ApplicationsStatsSkeleton.js: -------------------------------------------------------------------------------- 1 | import { View } from 'react-native'; 2 | import React from 'react'; 3 | 4 | import Skeleton from 'components/shared/Skeleton/Skeleton'; 5 | 6 | /** 7 | * Skeleton UI placeholder for ApplicationsStats loading state. 8 | */ 9 | export default function ApplicationsStatsSkeleton() { 10 | return ( 11 | 12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /src/modules/RequestToken/components/RequestTokenSelectField.styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors } from 'constants/styleGuide'; 2 | 3 | export default function getRequestTokenSelectFieldStyles() { 4 | return { 5 | common: { 6 | row: { 7 | flexDirection: 'row', 8 | alignItems: 'center', 9 | justifyContent: 'center', 10 | }, 11 | logo: { 12 | height: 24, 13 | width: 24, 14 | borderRadius: 16, 15 | marginLeft: 8, 16 | }, 17 | primaryText: { 18 | color: colors.light.ultramarineBlue, 19 | }, 20 | text: { 21 | fontSize: 16, 22 | }, 23 | skeleton: { 24 | marginBottom: 16, 25 | }, 26 | }, 27 | [themes.light]: { 28 | text: { 29 | color: colors.light.zodiacBlue, 30 | }, 31 | }, 32 | [themes.dark]: { 33 | text: { 34 | color: colors.light.whiteSmoke, 35 | }, 36 | }, 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /src/assets/svgs/CurrencySvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Svg, Path } from 'react-native-svg'; 3 | 4 | export default ({ color, style }) => ( 5 | 13 | 19 | 20 | ); 21 | -------------------------------------------------------------------------------- /src/components/shared/DownloadFile/styles.js: -------------------------------------------------------------------------------- 1 | import { colors, themes, fonts } from 'constants/styleGuide'; 2 | 3 | export default function getDeleteAccountFormStyles() { 4 | return { 5 | common: { 6 | container: { 7 | width: '100%', 8 | }, 9 | row: { 10 | flexDirection: 'row', 11 | alignItems: 'center', 12 | justifyContent: 'center', 13 | }, 14 | filenameContainer: { 15 | marginTop: 16, 16 | }, 17 | text: { 18 | fontFamily: fonts.family.heading, 19 | fontSize: fonts.size.small, 20 | marginLeft: 8, 21 | maxWidth: 320, 22 | }, 23 | downloadFileIcon: { 24 | marginLeft: 6, 25 | }, 26 | }, 27 | [themes.light]: { 28 | text: { 29 | color: colors.light.zodiacBlue, 30 | }, 31 | }, 32 | 33 | [themes.dark]: { 34 | text: { 35 | color: colors.light.white, 36 | }, 37 | }, 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /src/components/shared/toolBox/icon.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createIconSetFromIcoMoon } from 'react-native-vector-icons'; 3 | import iconsConfig from 'assets/fonts/icons/selection.json'; 4 | 5 | const Icomoon = createIconSetFromIcoMoon(iconsConfig); 6 | 7 | /** 8 | * Creates icon from Icomoon selection 9 | * in order to show an icon, the icon should exist in the font file 10 | * 11 | * @param {Object} props 12 | * @param {String} props.color - A valid Hex color code 13 | * @param {String} props.name - An icon name existing in our icons list 14 | * @param {Number} props.size - THe size of the icon in pixels, defaults to 35 15 | * @param {Object} props.style - styles from stylesheet 16 | * @param {Function} props.onPress - onPress event handler function 17 | */ 18 | const Icon = ({ name, size, color, style, onPress }) => ( 19 | 20 | ); 21 | 22 | export default Icon; 23 | -------------------------------------------------------------------------------- /src/navigation/components/TabBarIcon/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { colors } from 'constants/styleGuide'; 4 | import ApplicationsSvg from 'assets/svgs/ApplicationsSvg'; 5 | import HomeSvg from 'assets/svgs/HomeSvg'; 6 | import BookmarksSvg from 'assets/svgs/BookmarksSvg'; 7 | import SettingsSvg from 'assets/svgs/SettingsSvg'; 8 | 9 | export default function TabBarIcon({ name, focused, size = 24 }) { 10 | const props = { 11 | height: size, 12 | width: size, 13 | color: colors.light.white, 14 | variant: focused ? 'fill' : 'outline', 15 | }; 16 | 17 | switch (name) { 18 | case 'AccountHome': 19 | return ; 20 | 21 | case 'Applications': 22 | return ; 23 | 24 | case 'Bookmarks': 25 | return ; 26 | 27 | case 'Settings': 28 | return ; 29 | 30 | default: 31 | return null; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/modules/Settings/components/HarmfulAppDetails/styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors, fonts } from 'constants/styleGuide'; 2 | 3 | export default () => ({ 4 | common: { 5 | row: { 6 | alignItems: 'center', 7 | marginBottom: 20, 8 | }, 9 | packageName: { 10 | fontSize: fonts.size.base, 11 | fontFamily: fonts.family.context, 12 | textAlign: 'center', 13 | }, 14 | description: { 15 | fontSize: fonts.size.base, 16 | fontFamily: fonts.family.context, 17 | textAlign: 'center', 18 | }, 19 | appLogo: { 20 | height: 40, 21 | width: 40, 22 | borderRadius: 20, 23 | marginBottom: 10, 24 | }, 25 | buttonContainer: { 26 | borderWidth: 0, 27 | }, 28 | }, 29 | 30 | [themes.light]: { 31 | text: { 32 | color: colors.light.maastrichtBlue, 33 | }, 34 | }, 35 | 36 | [themes.dark]: { 37 | text: { 38 | color: colors.dark.platinum, 39 | }, 40 | }, 41 | }); 42 | -------------------------------------------------------------------------------- /src/assets/svgs/CheckSvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Svg, Path } from 'react-native-svg'; 3 | 4 | import colors from 'constants/styleGuide/colors'; 5 | 6 | export default function CheckSvg({ 7 | color = colors.light.ultramarineBlue, 8 | height = 9, 9 | width = 12, 10 | style, 11 | strokeWidth = 0, 12 | }) { 13 | return ( 14 | 15 | 23 | 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /src/assets/svgs/WarningFilledSvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Svg, Path } from 'react-native-svg'; 3 | import { themes, colors } from 'constants/styleGuide'; 4 | 5 | export default ({ theme }) => ( 6 | 7 | 13 | 14 | ); 15 | -------------------------------------------------------------------------------- /src/modules/Auth/components/DecryptRecoveryPhraseScreen/DecryptRecoveryPhraseScreen.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useNavigation, useRoute } from '@react-navigation/native'; 3 | import { SafeAreaView } from 'react-native'; 4 | 5 | import { useTheme } from 'contexts/ThemeContext'; 6 | import DecryptRecoveryPhrase from '../DecryptRecoveryPhrase/DecryptRecoveryPhrase'; 7 | 8 | import getStyles from './DecryptRecoveryPhraseScreen.styles'; 9 | 10 | /** 11 | * Renders an decrypt recoveryPhrase screen details screen given an encryptedData. 12 | */ 13 | export default function DecryptRecoveryPhraseScreen() { 14 | const navigation = useNavigation(); 15 | const route = useRoute(); 16 | 17 | const { styles } = useTheme({ styles: getStyles() }); 18 | 19 | return ( 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /src/modules/Auth/components/RecoveryPhraseScreen/RecoveryPhraseScreen.styles.js: -------------------------------------------------------------------------------- 1 | import { colors, themes, boxes, fonts } from 'constants/styleGuide'; 2 | 3 | export default () => ({ 4 | common: { 5 | wrapper: { 6 | flex: 1, 7 | }, 8 | container: { 9 | flex: 1, 10 | paddingLeft: boxes.boxPadding, 11 | paddingRight: boxes.boxPadding, 12 | paddingBottom: boxes.boxPadding, 13 | }, 14 | description: { 15 | fontFamily: fonts.family.context, 16 | fontSize: fonts.size.input, 17 | marginTop: 8, 18 | marginBottom: 16, 19 | }, 20 | }, 21 | [themes.light]: { 22 | wrapper: { 23 | backgroundColor: colors.dark.white, 24 | }, 25 | description: { 26 | color: colors.light.smoothGray, 27 | }, 28 | }, 29 | 30 | [themes.dark]: { 31 | wrapper: { 32 | backgroundColor: colors.dark.black, 33 | }, 34 | description: { 35 | color: colors.dark.mountainMist, 36 | }, 37 | }, 38 | }); 39 | -------------------------------------------------------------------------------- /src/components/shared/HeaderLogo/HeaderLogo.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | 4 | import { useTheme } from 'contexts/ThemeContext'; 5 | import LiskMobileLogoSvg from 'assets/svgs/LiskMobileLogoSvg'; 6 | 7 | import { getHeaderLogoStyles } from './HeaderLogo.styles'; 8 | 9 | /** 10 | * Renders Lisk logo and project description in a single header component. 11 | * @param {Object} style - Custom styles for internal components (optional). 12 | * @param {React.CSSProperties} style.container - Custom styles for component main container. 13 | * @param {React.CSSProperties} style.logo - Custom styles for the logo. 14 | * @param {React.CSSProperties} style.title - Custom styles for the title. 15 | */ 16 | export default function HeaderLogo({ style }) { 17 | const { styles } = useTheme({ styles: getHeaderLogoStyles() }); 18 | 19 | return ( 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /src/modules/Auth/api/useAuthQuery.test.js: -------------------------------------------------------------------------------- 1 | import { renderHook } from '@testing-library/react-hooks'; 2 | import { applicationsWrapper } from '../../../tests/applicationsWrapper'; 3 | import { mockSavedAccounts } from '../../Accounts/__fixtures__'; 4 | 5 | import { mockAuth } from '../__fixtures__'; 6 | 7 | import { useAuthQuery } from './useAuthQuery'; 8 | 9 | jest.useRealTimers(); 10 | 11 | describe('useAuthQuery hook', () => { 12 | const address = mockSavedAccounts[0].metadata.address; 13 | 14 | const wrapper = ({ children }) => applicationsWrapper({ children }); 15 | 16 | it('fetches data correctly', async () => { 17 | const { result, waitFor } = renderHook(() => useAuthQuery(address), { 18 | wrapper, 19 | }); 20 | 21 | expect(result.current.isLoading).toBeTruthy(); 22 | 23 | await waitFor(() => result.current.isFetched); 24 | 25 | expect(result.current.isSuccess).toBeTruthy(); 26 | 27 | expect(result.current.data.data).toEqual(mockAuth); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/components/ApplicationsExplorer/styles.js: -------------------------------------------------------------------------------- 1 | import { themes, colors } from 'constants/styleGuide'; 2 | 3 | export default function getBlockchainApplicationsExplorerStyles() { 4 | return { 5 | common: { 6 | header: { 7 | marginBottom: 24, 8 | }, 9 | flex: { 10 | flex: 1, 11 | }, 12 | body: { 13 | flex: 1, 14 | paddingLeft: 16, 15 | paddingRight: 16, 16 | }, 17 | message: { 18 | padding: 20, 19 | }, 20 | bridgeModal: { 21 | height: 350, 22 | }, 23 | statsModalCloseButton: { 24 | position: 'absolute', 25 | right: 12, 26 | top: 24, 27 | zIndex: 1, 28 | }, 29 | }, 30 | [themes.light]: { 31 | message: { 32 | color: colors.light.zodiacBlue, 33 | }, 34 | }, 35 | 36 | [themes.dark]: { 37 | message: { 38 | color: colors.dark.white, 39 | }, 40 | }, 41 | }; 42 | } 43 | -------------------------------------------------------------------------------- /src/modules/Auth/components/CreateAccountButton/CreateAccountButton.styles.js: -------------------------------------------------------------------------------- 1 | import { colors, themes } from 'constants/styleGuide'; 2 | 3 | export default function getCreateAccountStyles() { 4 | return { 5 | common: { 6 | container: { 7 | width: '100%', 8 | justifyContent: 'center', 9 | flexDirection: 'row', 10 | }, 11 | question: { 12 | color: colors.light.slateGray, 13 | textAlign: 'center', 14 | marginRight: 4, 15 | marginBottom: 5, 16 | }, 17 | link: { 18 | textAlign: 'center', 19 | }, 20 | }, 21 | [themes.light]: { 22 | question: { 23 | color: colors.light.zodiacBlue, 24 | }, 25 | link: { 26 | color: colors.light.ultramarineBlue, 27 | }, 28 | }, 29 | [themes.dark]: { 30 | question: { 31 | color: colors.dark.white, 32 | }, 33 | link: { 34 | color: colors.light.ultramarineBlue, 35 | }, 36 | }, 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /src/modules/Transactions/api/useTransactionQuery.test.js: -------------------------------------------------------------------------------- 1 | import { renderHook } from '@testing-library/react-hooks'; 2 | 3 | import { mockGetTransactionQuery, mockTransactions } from '../__fixtures__'; 4 | import { useTransactionQuery } from './useTransactionQuery'; 5 | import { applicationsWrapper } from '../../../tests/applicationsWrapper'; 6 | 7 | jest.useRealTimers(); 8 | 9 | describe('useTransactionQuery hook', () => { 10 | const wrapper = ({ children }) => applicationsWrapper({ children }); 11 | 12 | it('fetch data correctly', async () => { 13 | const { result, waitFor } = renderHook(() => useTransactionQuery(mockTransactions[0].id), { 14 | wrapper, 15 | }); 16 | 17 | expect(result.current.isLoading).toBeTruthy(); 18 | 19 | await waitFor(() => result.current.isFetched); 20 | 21 | expect(result.current.isSuccess).toBeTruthy(); 22 | 23 | const expectedResponse = mockGetTransactionQuery; 24 | 25 | expect(result.current.data).toEqual(expectedResponse); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /src/components/shared/DiscreteModeComponent/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Image } from 'react-native'; 3 | import { useSelector } from 'react-redux'; 4 | 5 | import { useTheme } from 'contexts/ThemeContext'; 6 | 7 | import getStyles from './styles'; 8 | import { BLUR_VARIANTS } from './constants'; 9 | import { getDiscreteModeDataSize } from './utils'; 10 | 11 | export default function DiscreteModeComponent({ children, blurVariant = 'incoming', data, style }) { 12 | const isDiscreteMode = useSelector((state) => state.settings.discrete); 13 | 14 | const { theme, styles } = useTheme({ styles: getStyles() }); 15 | 16 | if (!isDiscreteMode) return children; 17 | 18 | const dataSize = getDiscreteModeDataSize(data); 19 | 20 | return ( 21 | 22 | 26 | 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /src/components/screens/LoadingFallbackScreen/LoadingFallbackScreen.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { SafeAreaView, View } from 'react-native'; 3 | 4 | import { useTheme } from 'contexts/ThemeContext'; 5 | import LiskMobileLogoSvg from 'assets/svgs/LiskMobileLogoSvg'; 6 | import LiskLogoAnimation from 'assets/animations/LiskLogoAnimation'; 7 | import { colors } from 'constants/styleGuide'; 8 | 9 | import { getLoadingFallbackScreenStyles } from './LoadingFallbackScreen.styles'; 10 | 11 | /** 12 | * Fallback screen component for application loading state. 13 | */ 14 | export default function LoadingFallbackScreen() { 15 | const { styles } = useTheme({ styles: getLoadingFallbackScreenStyles() }); 16 | 17 | return ( 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /src/modules/Bookmark/components/EmptyState.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Image } from 'react-native'; 3 | import { translate } from 'react-i18next'; 4 | import { themes } from 'constants/styleGuide'; 5 | import noBookmarkLightImg from 'assets/images/send/noBookmarks3xLight.png'; 6 | import noBookmarkDarkImg from 'assets/images/send/noBookmarks3xDark.png'; 7 | import { P } from 'components/shared/toolBox/typography'; 8 | import withTheme from 'components/shared/withTheme'; 9 | import getStyles from './styles'; 10 | 11 | const EmptyState = ({ theme, styles, t, style }) => ( 12 | 13 | 14 | 18 | 19 |

{t('You don’t have any bookmarks.')}

20 |
21 | ); 22 | 23 | export default withTheme(translate()(EmptyState), getStyles()); 24 | -------------------------------------------------------------------------------- /src/tests/constants/wallets.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable max-lines */ 2 | const wallets = { 3 | genesis: { 4 | recoveryPhrase: 'peanut hundred pen hawk invite exclude brain chunk gadget wait wrong ready', 5 | summary: { 6 | publicKey: '0fe9a3f1a21b5530f27f87a414b549e79a940bf24fdf2b2f05e7f22aeeecc86a', 7 | serverPublicKey: '0fe9a3f1a21b5530f27f87a414b549e79a940bf24fdf2b2f05e7f22aeeecc86a', 8 | address: 'lskdxc4ta5j43jp9ro3f8zqbxta9fn6jwzjucw7yt', 9 | balance: '9897000000000000', 10 | isMigrated: true, 11 | isMultisignature: false, 12 | privateKey: 13 | 'ae7522b1fd7a24886b1396b392368fe6c9b2e0e40cf86ecf193e46babe3cbe8a0fe9a3f1a21b5530f27f87a414b549e79a940bf24fdf2b2f05e7f22aeeecc86a', 14 | }, 15 | token: { balance: '9897000000000000' }, 16 | sequence: { nonce: '1' }, 17 | keys: { numberOfSignatures: 0, mandatoryKeys: [], optionalKeys: [] }, 18 | dpos: { 19 | delegate: {}, 20 | sentVotes: [], 21 | }, 22 | }, 23 | }; 24 | 25 | export default wallets; 26 | -------------------------------------------------------------------------------- /src/utilities/api/hooks/useIndexStatusQuery.js: -------------------------------------------------------------------------------- 1 | import { API_URL, METHOD } from 'utilities/api/constants'; 2 | import { GET_INDEX_STATUS_QUERY } from 'utilities/api/queries'; 3 | import { useCustomQuery } from 'utilities/api/hooks/useCustomQuery'; 4 | import liskAPIClient from 'utilities/api/LiskAPIClient'; 5 | import { useMemo } from 'react'; 6 | 7 | export function useIndexStatusQuery() { 8 | const config = { 9 | url: `${API_URL}/index/status`, 10 | method: 'GET', 11 | event: 'get.index.status', 12 | }; 13 | 14 | const keys = [GET_INDEX_STATUS_QUERY, config, METHOD]; 15 | 16 | const options = { 17 | refetchInterval: 10000, 18 | refetchIntervalInBackground: false, 19 | }; 20 | 21 | const query = useCustomQuery({ config, keys, options, client: liskAPIClient }); 22 | 23 | const isLoading = useMemo( 24 | () => query.isLoading || query.data?.data.isIndexingInProgress, 25 | [query.isLoading, query.data?.data.isIndexingInProgress] 26 | ); 27 | 28 | return { ...query, isLoading }; 29 | } 30 | -------------------------------------------------------------------------------- /src/assets/svgs/AddSvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Animated } from 'react-native'; 3 | import { Svg, Path } from 'react-native-svg'; 4 | import { colors } from 'constants/styleGuide'; 5 | 6 | const AnimatedPath = Animated.createAnimatedComponent(Path); 7 | 8 | export default ({ color = colors.light.ultramarineBlue, height = 16, width = 16, style }) => ( 9 | 10 | 16 | 17 | ); 18 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/api/useApplicationsMetaQuery.test.js: -------------------------------------------------------------------------------- 1 | import { renderHook } from '@testing-library/react-hooks'; 2 | import { applicationsWrapper } from '../../../tests/applicationsWrapper'; 3 | 4 | import { mockApplicationsMeta } from '../__fixtures__'; 5 | 6 | import { useApplicationsMetaQuery } from './useApplicationsMetaQuery'; 7 | 8 | describe.skip('useApplicationsMetaQuery hook', () => { 9 | it('should fetch data correctly', async () => { 10 | const wrapper = ({ children }) => applicationsWrapper({ children }); 11 | 12 | const { result, waitFor } = renderHook(() => useApplicationsMetaQuery(), { wrapper }); 13 | 14 | await waitFor(() => result.current.isFetched); 15 | 16 | expect(result.current.isSuccess).toBeTruthy(); 17 | 18 | const expectedResponse = { 19 | data: mockApplicationsMeta, 20 | meta: { 21 | count: mockApplicationsMeta.length, 22 | offset: 0, 23 | }, 24 | }; 25 | 26 | expect(result.current.data).toEqual(expectedResponse); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/assets/svgs/DownloadSvg.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Svg, Path } from 'react-native-svg'; 3 | 4 | export default function DownloadSvg({ color = '#4070F4', height = 16, width = 16, style }) { 5 | return ( 6 | 7 | 13 | 14 | 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/modules/BlockchainApplication/components/ApplicationsStats/components/ApplicationsStatsLegendItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | import i18next from 'i18next'; 4 | 5 | import { P } from 'components/shared/toolBox/typography'; 6 | import { useTheme } from 'contexts/ThemeContext'; 7 | 8 | import getStyles from '../ApplicationsStat.styles'; 9 | 10 | export default function ApplicationsStatsLegendItem({ label, amount }) { 11 | const { styles } = useTheme({ styles: getStyles() }); 12 | 13 | return ( 14 | 15 | 16 | 17 |

18 |

19 | {amount}{' '} 20 |

21 | {i18next.t(`application.stats.${label}`)} 22 |

23 |
24 |
25 | ); 26 | } 27 | --------------------------------------------------------------------------------