|
1 | | -This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli). |
| 1 | +# MetaMask Embedded Wallets — React Native Grouped Connections Example |
2 | 2 |
|
3 | | -# Getting Started |
| 3 | +A bare React Native example demonstrating **Grouped Connections** (formerly called Aggregate Verifiers) — a Web3Auth feature that links multiple authentication methods so the same user always gets the **same wallet address**, regardless of which login method they use. |
4 | 4 |
|
5 | | ->**Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding. |
| 5 | +## What this example demonstrates |
6 | 6 |
|
7 | | -## Step 1: Start the Metro Server |
| 7 | +- Configuring a **Grouped Connection** on the Web3Auth Dashboard |
| 8 | +- Linking Google, email passwordless (Auth0), and GitHub (Auth0) under a single connection group |
| 9 | +- Using the shared `verifier` + `verifierSubIdentifier` pattern in `loginConfig` |
| 10 | +- Same Ethereum wallet regardless of which login method is used |
8 | 11 |
|
9 | | -First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native. |
| 12 | +## Why Grouped Connections? |
10 | 13 |
|
11 | | -To start Metro, run the following command from the _root_ of your React Native project: |
| 14 | +Without grouping, a user who logs in with Google gets one wallet, and the same user logging in with their email gets a completely different wallet. Grouped Connections solve this by linking multiple sub-connections under a parent group connection, using a common identifier (such as `email`) to map users across providers. |
12 | 15 |
|
13 | | -```bash |
14 | | -# using npm |
15 | | -npm start |
| 16 | +**Example:** Google (uses `email` as identifier) + Auth0 Email Passwordless (uses `email`) → same wallet. |
16 | 17 |
|
17 | | -# OR using Yarn |
18 | | -yarn start |
19 | | -``` |
| 18 | +## Tech stack |
| 19 | + |
| 20 | +- React Native `0.74.x` (bare workflow) |
| 21 | +- `@web3auth/react-native-sdk` `^8.0.0` |
| 22 | +- `@web3auth/ethereum-provider` `^9.3.0` |
| 23 | +- `ethers` `^6.x` |
| 24 | +- `react-native-encrypted-storage` |
| 25 | +- `@toruslabs/react-native-web-browser` |
| 26 | + |
| 27 | +## Prerequisites |
| 28 | + |
| 29 | +- Node.js `>=18` |
| 30 | +- React Native development environment — [React Native CLI Quickstart](https://reactnative.dev/docs/environment-setup) |
| 31 | +- A [Web3Auth Dashboard](https://dashboard.web3auth.io) project |
20 | 32 |
|
21 | | -## Step 2: Start your Application |
| 33 | +## Dashboard Setup |
22 | 34 |
|
23 | | -Let Metro Bundler run in its _own_ terminal. Open a _new_ terminal from the _root_ of your React Native project. Run the following command to start your _Android_ or _iOS_ app: |
| 35 | +### Create a Grouped Connection |
24 | 36 |
|
25 | | -### For Android |
| 37 | +1. Go to [dashboard.web3auth.io](https://dashboard.web3auth.io) and open your project. |
| 38 | +2. Under **Connections**, create a new **Grouped Connection**. |
| 39 | +3. Add **sub-connections** to the group (e.g. Google, Auth0 Email Passwordless, Auth0 GitHub). |
| 40 | +4. For each sub-connection, ensure the **user identifier field** maps to the same value across providers. For example: |
| 41 | + - Google: use `email` (must be pre-set in Google sub-connection config) |
| 42 | + - Auth0 Email Passwordless: use `email` |
| 43 | + - Auth0 GitHub: use `email` (Auth0 GitHub should include the user's email in the JWT) |
| 44 | +5. Note the **Grouped Connection ID** and each **sub-connection ID**. |
| 45 | +6. Under **Allowed Origins**, add: |
| 46 | + ``` |
| 47 | + web3authrnbareaggregateexample://auth |
| 48 | + ``` |
| 49 | + |
| 50 | +## Installation |
26 | 51 |
|
27 | 52 | ```bash |
28 | | -# using npm |
29 | | -npm run android |
| 53 | +git clone https://github.com/Web3Auth/web3auth-react-native-examples.git |
| 54 | +cd web3auth-react-native-examples/rn-bare-aggregate-verifier-example |
| 55 | +npm install |
| 56 | +``` |
30 | 57 |
|
31 | | -# OR using Yarn |
32 | | -yarn android |
| 58 | +### iOS |
| 59 | + |
| 60 | +```bash |
| 61 | +cd ios && pod install && cd .. |
33 | 62 | ``` |
34 | 63 |
|
35 | | -### For iOS |
| 64 | +## Configuration |
| 65 | + |
| 66 | +In `App.tsx`, each login method references the parent grouped connection via `verifier` and its own sub-connection via `verifierSubIdentifier`: |
| 67 | + |
| 68 | +```typescript |
| 69 | +const web3auth = new Web3Auth(WebBrowser, EncryptedStorage, { |
| 70 | + clientId: "YOUR_WEB3AUTH_CLIENT_ID", |
| 71 | + network: WEB3AUTH_NETWORK.SAPPHIRE_DEVNET, |
| 72 | + redirectUrl: "web3authrnbareaggregateexample://auth", |
| 73 | + privateKeyProvider: ethereumPrivateKeyProvider, |
| 74 | + loginConfig: { |
| 75 | + google: { |
| 76 | + verifier: "YOUR_GROUPED_CONNECTION_ID", // parent group connection |
| 77 | + verifierSubIdentifier: "YOUR_GOOGLE_SUB_ID", // Google sub-connection ID |
| 78 | + typeOfLogin: "google", |
| 79 | + clientId: "YOUR_GOOGLE_OAUTH_CLIENT_ID", |
| 80 | + }, |
| 81 | + auth0emailpasswordless: { |
| 82 | + verifier: "YOUR_GROUPED_CONNECTION_ID", // same parent group connection |
| 83 | + verifierSubIdentifier: "YOUR_A0_EMAIL_SUB_ID", // Auth0 email sub-connection ID |
| 84 | + typeOfLogin: "jwt", |
| 85 | + clientId: "YOUR_AUTH0_CLIENT_ID", |
| 86 | + jwtParameters: { |
| 87 | + domain: "https://YOUR_AUTH0_DOMAIN", |
| 88 | + verifierIdField: "email", |
| 89 | + isVerifierIdCaseSensitive: false, |
| 90 | + }, |
| 91 | + }, |
| 92 | + }, |
| 93 | +}); |
| 94 | +``` |
| 95 | + |
| 96 | +> **Important**: All sub-connections must use the same user identifier value. If Google and Auth0 both return `email`, the same email always resolves to the same wallet. |
| 97 | +
|
| 98 | +## Running the app |
36 | 99 |
|
37 | 100 | ```bash |
38 | | -# using npm |
39 | | -npm run ios |
| 101 | +npm start # start Metro |
| 102 | +npm run ios # iOS |
| 103 | +npm run android # Android |
| 104 | +``` |
40 | 105 |
|
41 | | -# OR using Yarn |
42 | | -yarn ios |
| 106 | +## How it works |
| 107 | + |
| 108 | +### Login with Google |
| 109 | + |
| 110 | +```typescript |
| 111 | +await web3auth.login({ loginProvider: "google" }); |
43 | 112 | ``` |
44 | 113 |
|
45 | | -If everything is set up _correctly_, you should see your new app running in your _Android Emulator_ or _iOS Simulator_ shortly provided you have set up your emulator/simulator correctly. |
| 114 | +### Login with email OTP (Auth0) |
| 115 | + |
| 116 | +```typescript |
| 117 | +await web3auth.login({ |
| 118 | + loginProvider: "auth0emailpasswordless", |
| 119 | + extraLoginOptions: { |
| 120 | + login_hint: email, |
| 121 | + domain: "https://YOUR_AUTH0_DOMAIN", |
| 122 | + }, |
| 123 | +}); |
| 124 | +``` |
46 | 125 |
|
47 | | -This is one way to run your app — you can also run it directly from within Android Studio and Xcode respectively. |
| 126 | +Both methods produce the **same wallet address** for the user with the same email. |
48 | 127 |
|
49 | | -## Step 3: Modifying your App |
| 128 | +## Key concepts |
50 | 129 |
|
51 | | -Now that you have successfully run the app, let's modify it. |
| 130 | +**Grouped Connection** — A parent connection on the Web3Auth Dashboard that aggregates multiple sub-connections. It uses Shamir Secret Sharing across the sub-connection shares to produce the same key regardless of which login method was used. |
52 | 131 |
|
53 | | -1. Open `App.tsx` in your text editor of choice and edit some lines. |
54 | | -2. For **Android**: Press the <kbd>R</kbd> key twice or select **"Reload"** from the **Developer Menu** (<kbd>Ctrl</kbd> + <kbd>M</kbd> (on Window and Linux) or <kbd>Cmd ⌘</kbd> + <kbd>M</kbd> (on macOS)) to see your changes! |
| 132 | +**`verifier`** — Must be the Grouped Connection ID (the parent). |
55 | 133 |
|
56 | | - For **iOS**: Hit <kbd>Cmd ⌘</kbd> + <kbd>R</kbd> in your iOS Simulator to reload the app and see your changes! |
| 134 | +**`verifierSubIdentifier`** — Must be the individual sub-connection ID within the group. |
57 | 135 |
|
58 | | -## Congratulations! :tada: |
| 136 | +**Identifier mapping** — The `verifierIdField` (e.g. `email`) must resolve to the **same value** across all sub-connections for a given user. |
59 | 137 |
|
60 | | -You've successfully run and modified your React Native App. :partying_face: |
| 138 | +## Troubleshooting |
61 | 139 |
|
62 | | -### Now what? |
| 140 | +**Different wallet addresses for different login methods** |
| 141 | +- Confirm all `verifier` fields use the exact same Grouped Connection ID. |
| 142 | +- Confirm the `verifierIdField` resolves to the same value (e.g. same email) across all providers. |
63 | 143 |
|
64 | | -- If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps). |
65 | | -- If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started). |
| 144 | +**`Verifier not found`** |
| 145 | +- The `verifier` and `verifierSubIdentifier` must exactly match what is configured on the dashboard (case-sensitive). |
66 | 146 |
|
67 | | -# Troubleshooting |
| 147 | +**Metro polyfill errors** |
| 148 | +- See [Metro Polyfill Troubleshooting](https://docs.metamask.io/embedded-wallets/troubleshooting/metro-issues/). |
68 | 149 |
|
69 | | -If you can't get this to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page. |
| 150 | +## Resources |
70 | 151 |
|
71 | | -# Learn More |
| 152 | +- [MetaMask Embedded Wallets Docs](https://docs.metamask.io/embedded-wallets/) |
| 153 | +- [React Native SDK Reference](https://docs.metamask.io/embedded-wallets/sdk/react-native/) |
| 154 | +- [Dashboard](https://dashboard.web3auth.io) |
| 155 | +- [Community (Builder Hub)](https://builder.metamask.io/c/embedded-wallets/5) |
72 | 156 |
|
73 | | -To learn more about React Native, take a look at the following resources: |
| 157 | +## License |
74 | 158 |
|
75 | | -- [React Native Website](https://reactnative.dev) - learn more about React Native. |
76 | | -- [Getting Started](https://reactnative.dev/docs/environment-setup) - an **overview** of React Native and how setup your environment. |
77 | | -- [Learn the Basics](https://reactnative.dev/docs/getting-started) - a **guided tour** of the React Native **basics**. |
78 | | -- [Blog](https://reactnative.dev/blog) - read the latest official React Native **Blog** posts. |
79 | | -- [`@facebook/react-native`](https://github.com/facebook/react-native) - the Open Source; GitHub **repository** for React Native. |
| 159 | +MIT — see [LICENSE](../LICENSE). |
0 commit comments