├── hooks
├── useColorScheme.ts
├── useColorScheme.web.ts
└── useThemeColor.ts
├── assets
└── images
│ ├── icon.png
│ ├── favicon.png
│ ├── splash.png
│ └── adaptive-icon.png
├── expo-env.d.ts
├── babel.config.js
├── entrypoint.js
├── tsconfig.json
├── .gitignore
├── metro.config.js
├── components
├── login
│ ├── PrivyUI.tsx
│ ├── PasskeyLogin.tsx
│ ├── OAuth.tsx
│ └── SMS.tsx
├── LoginScreen.tsx
├── walletActions
│ ├── EVMWalletActions.tsx
│ └── SolanaWalletActions.tsx
├── userManagement
│ ├── Wallets.tsx
│ ├── UnlinkAccounts.tsx
│ └── LinkAccounts.tsx
└── UserScreen.tsx
├── app
├── _layout.tsx
└── index.tsx
├── constants
└── Colors.ts
├── app.json
├── README.md
├── package.json
└── scripts
└── reset-project.js
/hooks/useColorScheme.ts:
--------------------------------------------------------------------------------
1 | export { useColorScheme } from 'react-native';
2 |
--------------------------------------------------------------------------------
/assets/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/privy-io/expo-starter/HEAD/assets/images/icon.png
--------------------------------------------------------------------------------
/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/privy-io/expo-starter/HEAD/assets/images/favicon.png
--------------------------------------------------------------------------------
/assets/images/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/privy-io/expo-starter/HEAD/assets/images/splash.png
--------------------------------------------------------------------------------
/assets/images/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/privy-io/expo-starter/HEAD/assets/images/adaptive-icon.png
--------------------------------------------------------------------------------
/expo-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | // NOTE: This file should not be edited and should be in your git ignore
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function (api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo'],
5 | };
6 | };
7 |
--------------------------------------------------------------------------------
/entrypoint.js:
--------------------------------------------------------------------------------
1 | // entrypoint.js
2 |
3 | // Import required polyfills first
4 | // IMPORTANT: These polyfills must be installed in this order
5 | import "react-native-get-random-values";
6 | import "@ethersproject/shims";
7 | import { Buffer } from "buffer";
8 | global.Buffer = Buffer;
9 | // Then import the expo router
10 | import "expo-router/entry";
11 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "expo/tsconfig.base",
3 | "compilerOptions": {
4 | "strict": true,
5 | // Allows us to use conditional/deep imports on published packages
6 | "moduleResolution": "Bundler",
7 | "paths": {
8 | "@/*": [
9 | "./*"
10 | ]
11 | }
12 | },
13 | "include": [
14 | "**/*.ts",
15 | "**/*.tsx",
16 | ".expo/types/**/*.ts",
17 | "expo-env.d.ts"
18 | , "app/index.js" ]
19 | }
20 |
--------------------------------------------------------------------------------
/hooks/useColorScheme.web.ts:
--------------------------------------------------------------------------------
1 | // NOTE: The default React Native styling doesn't support server rendering.
2 | // Server rendered styles should not change between the first render of the HTML
3 | // and the first render on the client. Typically, web developers will use CSS media queries
4 | // to render different styles on the client and server, these aren't directly supported in React Native
5 | // but can be achieved using a styling library like Nativewind.
6 | export function useColorScheme() {
7 | return 'light';
8 | }
9 |
--------------------------------------------------------------------------------
/hooks/useThemeColor.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Learn more about light and dark modes:
3 | * https://docs.expo.dev/guides/color-schemes/
4 | */
5 |
6 | import { useColorScheme } from 'react-native';
7 |
8 | import { Colors } from '@/constants/Colors';
9 |
10 | export function useThemeColor(
11 | props: { light?: string; dark?: string },
12 | colorName: keyof typeof Colors.light & keyof typeof Colors.dark
13 | ) {
14 | const theme = useColorScheme() ?? 'light';
15 | const colorFromProps = props[theme];
16 |
17 | if (colorFromProps) {
18 | return colorFromProps;
19 | } else {
20 | return Colors[theme][colorName];
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
2 |
3 | # dependencies
4 | node_modules/
5 |
6 | # Expo
7 | .expo/
8 | dist/
9 | web-build/
10 |
11 | # Native
12 | *.orig.*
13 | *.jks
14 | *.p8
15 | *.p12
16 | *.key
17 | *.mobileprovision
18 |
19 | # Metro
20 | .metro-health-check*
21 |
22 | # debug
23 | npm-debug.*
24 | yarn-debug.*
25 | yarn-error.*
26 |
27 | # macOS
28 | .DS_Store
29 | *.pem
30 |
31 | # local env files
32 | .env*.local
33 |
34 | # builds
35 | android/
36 | ios/
37 |
38 | # typescript
39 | *.tsbuildinfo
40 | # @generated expo-cli sync-2b81b286409207a5da26e14c78851eb30d8ccbdb
41 | # The following patterns were generated by expo-cli
42 |
43 | expo-env.d.ts
44 | # @end expo-cli
--------------------------------------------------------------------------------
/metro.config.js:
--------------------------------------------------------------------------------
1 | // Learn more https://docs.expo.io/guides/customizing-metro
2 | const { getDefaultConfig } = require("expo/metro-config");
3 |
4 | /** @type {import('expo/metro-config').MetroConfig} */
5 | const config = getDefaultConfig(__dirname);
6 |
7 | const resolveRequestWithPackageExports = (context, moduleName, platform) => {
8 | // Package exports in `jose` are incorrect, so we need to force the browser version
9 | if (moduleName === "jose") {
10 | const ctx = {
11 | ...context,
12 | unstable_conditionNames: ["browser"],
13 | };
14 | return ctx.resolveRequest(ctx, moduleName, platform);
15 | }
16 |
17 | return context.resolveRequest(context, moduleName, platform);
18 | };
19 |
20 | config.resolver.resolveRequest = resolveRequestWithPackageExports;
21 |
22 | module.exports = config;
23 |
--------------------------------------------------------------------------------
/components/login/PrivyUI.tsx:
--------------------------------------------------------------------------------
1 | import { useLogin } from "@privy-io/expo/ui";
2 | import { Button, View, Text } from "react-native";
3 | import { useState } from "react";
4 |
5 | export default function PrivyUI() {
6 | const [error, setError] = useState("");
7 |
8 | const { login } = useLogin();
9 | return (
10 |
11 |
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/app/_layout.tsx:
--------------------------------------------------------------------------------
1 | import Constants from "expo-constants";
2 | import { Stack } from "expo-router";
3 | import { PrivyProvider } from "@privy-io/expo";
4 | import { PrivyElements } from "@privy-io/expo/ui";
5 | import {
6 | Inter_400Regular,
7 | Inter_500Medium,
8 | Inter_600SemiBold,
9 | } from "@expo-google-fonts/inter";
10 | import { useFonts } from "expo-font";
11 |
12 | export default function RootLayout() {
13 | useFonts({
14 | Inter_400Regular,
15 | Inter_500Medium,
16 | Inter_600SemiBold,
17 | });
18 | return (
19 |
23 |
24 |
25 |
26 |
27 |
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/constants/Colors.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Below are the colors that are used in the app. The colors are defined in the light and dark mode.
3 | * There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc.
4 | */
5 |
6 | const tintColorLight = '#0a7ea4';
7 | const tintColorDark = '#fff';
8 |
9 | export const Colors = {
10 | light: {
11 | text: '#11181C',
12 | background: '#fff',
13 | tint: tintColorLight,
14 | icon: '#687076',
15 | tabIconDefault: '#687076',
16 | tabIconSelected: tintColorLight,
17 | },
18 | dark: {
19 | text: '#ECEDEE',
20 | background: '#151718',
21 | tint: tintColorDark,
22 | icon: '#9BA1A6',
23 | tabIconDefault: '#9BA1A6',
24 | tabIconSelected: tintColorDark,
25 | },
26 | };
27 |
--------------------------------------------------------------------------------
/components/login/PasskeyLogin.tsx:
--------------------------------------------------------------------------------
1 | import Constants from "expo-constants";
2 | import { useState } from "react";
3 | import { Button, Text } from "react-native";
4 |
5 | import { useLoginWithPasskey } from "@privy-io/expo/passkey";
6 |
7 | export default function PasskeyLogin() {
8 | const [error, setError] = useState("");
9 | const { loginWithPasskey } = useLoginWithPasskey({
10 | onError: (err) => {
11 | console.log(err);
12 | setError(JSON.stringify(err.message));
13 | },
14 | });
15 | return (
16 | <>
17 |