dop-wallet-v6 1.2.15 → 1.2.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,305 +0,0 @@
1
- # DOP Wallet v6 - Wallet Creation Guide
2
-
3
- ## Overview
4
-
5
- This guide explains the different ways to create wallets using the new-dop-wallet-v3 SDK, including automatic mnemonic generation and importing existing mnemonics.
6
-
7
- ## Wallet Creation Functions
8
-
9
- ### 1. `createOrImportDopWallet` - **Recommended** ⭐
10
-
11
- This is the most comprehensive and user-friendly function that supports both creating new wallets and importing existing ones.
12
-
13
- ```typescript
14
- import { createOrImportDopWallet } from 'dop-wallet-v6';
15
-
16
- // Create a new wallet with auto-generated mnemonic
17
- const { walletInfo, mnemonic } = await createOrImportDopWallet(encryptionKey);
18
-
19
- // Create a new wallet with 24-word mnemonic
20
- const { walletInfo, mnemonic } = await createOrImportDopWallet(encryptionKey, {
21
- mnemonicStrength: 256 // 256 bits = 24 words
22
- });
23
-
24
- // Import an existing wallet
25
- const { walletInfo, mnemonic } = await createOrImportDopWallet(encryptionKey, {
26
- mnemonic: 'your existing twelve word mnemonic phrase goes here like this example'
27
- });
28
- ```
29
-
30
- **Parameters:**
31
- - `encryptionKey`: string | Buffer | Uint8Array (32 bytes)
32
- - `options.mnemonic?`: string - Import this mnemonic (if undefined, generates new)
33
- - `options.creationBlockNumbers?`: Optional block numbers for faster sync
34
- - `options.dopWalletDerivationIndex?`: number (default: 0)
35
- - `options.timeout?`: number (default: 60000ms)
36
- - `options.mnemonicStrength?`: 128 | 192 | 256 (default: 128 = 12 words)
37
-
38
- **Returns:**
39
- ```typescript
40
- {
41
- walletInfo: DopWalletInfo, // Wallet details (ID, address, etc.)
42
- mnemonic: string // The mnemonic (generated or imported)
43
- }
44
- ```
45
-
46
- ### 2. `createDopWalletSafe` - Safe Creation with Timeout
47
-
48
- For when you already have a mnemonic and want safe creation with React Native compatibility.
49
-
50
- ```typescript
51
- import { createDopWalletSafe } from 'dop-wallet-v6';
52
-
53
- const walletInfo = await createDopWalletSafe(
54
- encryptionKey,
55
- mnemonic,
56
- creationBlockNumbers,
57
- derivationIndex,
58
- timeout
59
- );
60
- ```
61
-
62
- ### 3. `createDopWallet` - Basic Creation
63
-
64
- The original function for creating wallets from existing mnemonics.
65
-
66
- ```typescript
67
- import { createDopWallet } from 'dop-wallet-v6';
68
-
69
- const walletInfo = await createDopWallet(
70
- encryptionKey,
71
- mnemonic,
72
- creationBlockNumbers,
73
- derivationIndex
74
- );
75
- ```
76
-
77
- ## Input Requirements
78
-
79
- ### Encryption Key
80
- The encryption key must be a **32-byte** value in one of these formats:
81
- - `string`: Hex string (64 characters)
82
- - `Buffer`: 32-byte buffer
83
- - `Uint8Array`: 32-byte array
84
-
85
- ```typescript
86
- // Examples of valid encryption keys
87
- const encryptionKey1 = crypto.randomBytes(32).toString('hex'); // string
88
- const encryptionKey2 = crypto.randomBytes(32); // Buffer
89
- const encryptionKey3 = new Uint8Array(32); // Uint8Array
90
- ```
91
-
92
- ### Mnemonic Options
93
-
94
- | Strength | Bits | Words | Security Level |
95
- |----------|------|-------|----------------|
96
- | 128 | 128 | 12 | Standard ✅ |
97
- | 192 | 192 | 18 | High |
98
- | 256 | 256 | 24 | Maximum 🔒 |
99
-
100
- ```typescript
101
- // Generate different mnemonic lengths
102
- const { walletInfo, mnemonic } = await createOrImportDopWallet(encryptionKey, {
103
- mnemonicStrength: 128 // 12 words (default)
104
- });
105
-
106
- const { walletInfo, mnemonic } = await createOrImportDopWallet(encryptionKey, {
107
- mnemonicStrength: 192 // 18 words
108
- });
109
-
110
- const { walletInfo, mnemonic } = await createOrImportDopWallet(encryptionKey, {
111
- mnemonicStrength: 256 // 24 words (most secure)
112
- });
113
- ```
114
-
115
- ## React Native Integration
116
-
117
- For React Native apps, use these functions which include circomlibjs compatibility testing:
118
-
119
- ```typescript
120
- import { createOrImportDopWallet, testCircomlibjs } from 'dop-wallet-v6';
121
-
122
- // Test compatibility first (optional but recommended)
123
- const isCompatible = await testCircomlibjs();
124
- if (!isCompatible) {
125
- throw new Error('Cryptography not compatible with this environment');
126
- }
127
-
128
- // Create wallet
129
- const { walletInfo, mnemonic } = await createOrImportDopWallet(encryptionKey, {
130
- timeout: 90000 // Increase timeout for React Native
131
- });
132
- ```
133
-
134
- ## Error Handling
135
-
136
- ```typescript
137
- try {
138
- const { walletInfo, mnemonic } = await createOrImportDopWallet(encryptionKey, {
139
- mnemonic: userInputMnemonic,
140
- timeout: 60000
141
- });
142
-
143
- console.log('Wallet created:', walletInfo.id);
144
- console.log('Address:', walletInfo.dopAddress);
145
-
146
- // IMPORTANT: Securely store the mnemonic
147
- await secureStorage.setItem('wallet_mnemonic', mnemonic);
148
-
149
- } catch (error) {
150
- if (error.message.includes('Invalid mnemonic')) {
151
- // Handle invalid mnemonic input
152
- console.error('The provided mnemonic is invalid');
153
- } else if (error.message.includes('timed out')) {
154
- // Handle timeout (usually circomlibjs hanging)
155
- console.error('Wallet creation timed out, try restarting the app');
156
- } else {
157
- // Handle other errors
158
- console.error('Wallet creation failed:', error);
159
- }
160
- }
161
- ```
162
-
163
- ## Complete Examples
164
-
165
- ### Example 1: Create New Wallet (Auto-Generate Mnemonic)
166
-
167
- ```typescript
168
- import { createOrImportDopWallet } from 'dop-wallet-v6';
169
- import { randomBytes } from 'crypto';
170
-
171
- const createNewWallet = async () => {
172
- try {
173
- // Generate encryption key
174
- const encryptionKey = randomBytes(32);
175
-
176
- // Create wallet with auto-generated mnemonic
177
- const { walletInfo, mnemonic } = await createOrImportDopWallet(encryptionKey);
178
-
179
- console.log('✅ New wallet created!');
180
- console.log('Wallet ID:', walletInfo.id);
181
- console.log('Address:', walletInfo.dopAddress);
182
- console.log('Mnemonic (SAVE THIS!):', mnemonic);
183
-
184
- // Store securely
185
- await secureStorage.setItem('encryption_key', encryptionKey.toString('hex'));
186
- await secureStorage.setItem('wallet_mnemonic', mnemonic);
187
-
188
- return walletInfo;
189
- } catch (error) {
190
- console.error('Failed to create wallet:', error);
191
- throw error;
192
- }
193
- };
194
- ```
195
-
196
- ### Example 2: Import Existing Wallet
197
-
198
- ```typescript
199
- import { createOrImportDopWallet } from 'dop-wallet-v6';
200
-
201
- const importExistingWallet = async (userMnemonic: string) => {
202
- try {
203
- // Get stored encryption key or create new one
204
- const encryptionKey = await getOrCreateEncryptionKey();
205
-
206
- // Import wallet from mnemonic
207
- const { walletInfo, mnemonic } = await createOrImportDopWallet(encryptionKey, {
208
- mnemonic: userMnemonic.trim().toLowerCase()
209
- });
210
-
211
- console.log('✅ Wallet imported successfully!');
212
- console.log('Wallet ID:', walletInfo.id);
213
- console.log('Address:', walletInfo.dopAddress);
214
-
215
- return walletInfo;
216
- } catch (error) {
217
- if (error.message.includes('Invalid mnemonic')) {
218
- throw new Error('Please check your mnemonic phrase and try again');
219
- }
220
- throw error;
221
- }
222
- };
223
- ```
224
-
225
- ### Example 3: React Native with AsyncStorage
226
-
227
- ```typescript
228
- import { createOrImportDopWallet } from 'dop-wallet-v6';
229
- import AsyncStorage from '@react-native-async-storage/async-storage';
230
-
231
- const createWalletRN = async () => {
232
- try {
233
- // Test compatibility first
234
- await testCircomlibjs();
235
-
236
- // Generate encryption key
237
- const encryptionKey = randomBytes(32);
238
-
239
- // Create wallet with longer timeout for React Native
240
- const { walletInfo, mnemonic } = await createOrImportDopWallet(encryptionKey, {
241
- mnemonicStrength: 256, // 24 words for maximum security
242
- timeout: 90000 // 90 seconds timeout
243
- });
244
-
245
- // Store in AsyncStorage
246
- await AsyncStorage.multiSet([
247
- ['encryption_key', encryptionKey.toString('hex')],
248
- ['wallet_mnemonic', mnemonic],
249
- ['wallet_id', walletInfo.id],
250
- ['wallet_address', walletInfo.dopAddress]
251
- ]);
252
-
253
- console.log('✅ Wallet created and stored in React Native!');
254
- return walletInfo;
255
-
256
- } catch (error) {
257
- console.error('React Native wallet creation failed:', error);
258
- throw error;
259
- }
260
- };
261
- ```
262
-
263
- ## Best Practices
264
-
265
- 1. **Always validate user input mnemonics** before importing
266
- 2. **Use secure storage** for encryption keys and mnemonics
267
- 3. **Increase timeout** for React Native (90+ seconds)
268
- 4. **Test circomlibjs compatibility** in React Native before wallet creation
269
- 5. **Handle timeout errors** gracefully - suggest app restart
270
- 6. **Use 24-word mnemonics** for maximum security when possible
271
- 7. **Never log or store mnemonics in plain text** in production
272
-
273
- ## Troubleshooting
274
-
275
- ### "Invalid mnemonic phrase"
276
- - Ensure mnemonic has correct number of words (12, 18, or 24)
277
- - Check for typos or extra spaces
278
- - Verify words are from the BIP39 wordlist
279
-
280
- ### "Wallet creation timed out"
281
- - Increase timeout value
282
- - Restart the React Native app
283
- - Check if circomlibjs shims are properly loaded
284
-
285
- ### "Cryptography not compatible"
286
- - Ensure react-native-shims.js is imported before any wallet operations
287
- - Check Metro bundler configuration
288
- - Verify all polyfills are installed
289
-
290
- ## Migration from Old API
291
-
292
- If you're upgrading from older wallet creation methods:
293
-
294
- ```typescript
295
- // OLD WAY ❌
296
- const walletInfo = await createDopWallet(encryptionKey, mnemonic, creationBlockNumbers);
297
-
298
- // NEW WAY ✅
299
- const { walletInfo, mnemonic } = await createOrImportDopWallet(encryptionKey, {
300
- mnemonic: existingMnemonic, // or leave undefined to generate
301
- creationBlockNumbers
302
- });
303
- ```
304
-
305
- The new API provides the mnemonic in the response, making it easier to handle both wallet creation and mnemonic storage in one step.
@@ -1,162 +0,0 @@
1
- # DOP Wallet v6 React Native Integration - Complete Fix Summary
2
-
3
- ## 🚨 **Issues Identified by React Native Developer**
4
-
5
- 1. **Legacy AsyncStorage References**: SDK dependencies still referenced legacy RN-core AsyncStorage
6
- 2. **Missing Required Polyfills**: Required polyfills and Node.js shims not documented as mandatory
7
- 3. **Level-FS Integration Broken**: The Level-FS integration described in docs doesn't work in React Native
8
-
9
- ## ✅ **Comprehensive Fixes Applied**
10
-
11
- ### **Fix #1: Legacy AsyncStorage - RESOLVED**
12
-
13
- **Problem**: GraphQL Mesh cache dependencies were trying to use legacy `require('react-native').AsyncStorage`
14
-
15
- **Solution**:
16
- - ✅ Disabled `@graphql-mesh/cache-localforage` in all GraphQL files
17
- - ✅ Added `@react-native-async-storage/async-storage` as direct dependency
18
- - ✅ Updated `react-native-shims.js` with compatibility notes
19
-
20
- **Code Changes**:
21
- ```typescript
22
- // In all GraphQL files:
23
- // MODIFIED: Replaced MeshCache with undefined to disable caching for React Native compatibility
24
- // import MeshCache from "@graphql-mesh/cache-localforage";
25
- const cache = undefined; // Instead of: new MeshCache({...})
26
- ```
27
-
28
- ### **Fix #2: Required Polyfills - RESOLVED**
29
-
30
- **Problem**: Users didn't know which polyfills were mandatory, causing runtime errors
31
-
32
- **Solution**:
33
- - ✅ Added all required polyfills to `package.json` dependencies
34
- - ✅ Updated integration guide with mandatory polyfill documentation
35
- - ✅ Enhanced `react-native-shims.js` with automatic setup
36
-
37
- **Required Dependencies Now Bundled**:
38
- ```json
39
- {
40
- "dependencies": {
41
- "@react-native-async-storage/async-storage": "^1.24.0",
42
- "buffer": "^6.0.3",
43
- "crypto-browserify": "3.12.0",
44
- "stream-browserify": "3.0.0",
45
- "memdown": "^6.1.1"
46
- }
47
- }
48
- ```
49
-
50
- ### **Fix #3: Level-FS Integration - COMPLETELY RESOLVED**
51
-
52
- **Problem**: `react-native-level-fs` returns filesystem interface, not LevelDB constructor
53
-
54
- **Solution**:
55
- - ✅ Created `startDopEngineReactNative()` function that handles database internally
56
- - ✅ Implemented custom React Native LevelDB using `memdown` + AsyncStorage persistence
57
- - ✅ Removed all problematic level-fs dependencies
58
- - ✅ Updated integration guide with simplified approach
59
-
60
- **New React Native API**:
61
- ```typescript
62
- // ✅ New simplified approach - no database management needed
63
- import { startDopEngineReactNative } from 'dop-wallet-v6';
64
-
65
- await startDopEngineReactNative(
66
- walletSource, // string
67
- shouldDebug, // boolean
68
- artifactStore, // ArtifactStore implementation
69
- useNativeArtifacts, // boolean (default: true)
70
- skipMerkletreeScans, // boolean (default: false)
71
- verboseScanLogging, // boolean (default: false)
72
- databaseName // string (default: 'dop-wallet-db')
73
- );
74
- ```
75
-
76
- ### **Fix #4: Enhanced Database Implementation**
77
-
78
- **Problem**: Previous solution used in-memory only database (data lost on restart)
79
-
80
- **Solution**:
81
- - ✅ Created custom `ReactNativeLevelDB` class
82
- - ✅ Implements full `AbstractLevelDOWN` interface
83
- - ✅ Uses `memdown` for fast in-memory operations
84
- - ✅ Automatically persists to AsyncStorage for data retention
85
- - ✅ Gracefully handles AsyncStorage unavailability
86
-
87
- **Technical Implementation**:
88
- ```typescript
89
- class ReactNativeLevelDB {
90
- // Implements AbstractLevelDOWN interface
91
- // Uses memdown for performance + AsyncStorage for persistence
92
- // Automatically syncs data in background
93
- // Compatible with all DOP Engine operations
94
- }
95
- ```
96
-
97
- ## 📋 **Updated Integration Process**
98
-
99
- ### **1. Install Dependencies** (Simplified)
100
- ```bash
101
- npm install dop-wallet-v6 @react-native-async-storage/async-storage react-native-get-random-values react-native-url-polyfill
102
- ```
103
-
104
- ### **2. Setup Polyfills** (Automatic)
105
- ```typescript
106
- // App entry point
107
- import 'react-native-get-random-values';
108
- import 'react-native-url-polyfill/auto';
109
- import 'dop-wallet-v6/react-native-shims'; // Handles Buffer, crypto, etc.
110
- ```
111
-
112
- ### **3. Initialize Engine** (Simplified)
113
- ```typescript
114
- import { startDopEngineReactNative } from 'dop-wallet-v6';
115
-
116
- await startDopEngineReactNative(
117
- 'myapp',
118
- __DEV__,
119
- artifactStore
120
- );
121
- ```
122
-
123
- ## 🎯 **Results for React Native Developer**
124
-
125
- ### **Before (Broken)**:
126
- - ❌ AsyncStorage errors from GraphQL Mesh
127
- - ❌ "Cannot read property 'call' of undefined" from missing polyfills
128
- - ❌ "level is not a function" from incorrect Level-FS usage
129
- - ❌ Complex database setup with multiple dependencies
130
- - ❌ Data loss on app restart
131
-
132
- ### **After (Fixed)**:
133
- - ✅ No AsyncStorage conflicts - uses modern `@react-native-async-storage/async-storage`
134
- - ✅ All polyfills bundled and auto-configured
135
- - ✅ Single function call to initialize: `startDopEngineReactNative()`
136
- - ✅ Database persistence between app sessions
137
- - ✅ Zero manual database management required
138
- - ✅ Comprehensive error handling and fallbacks
139
-
140
- ## 🔧 **Breaking Changes (v1.2.10)**
141
-
142
- **For React Native Users**:
143
- - **OLD**: `startDopEngine(walletSource, db, ...)`
144
- - **NEW**: `startDopEngineReactNative(walletSource, shouldDebug, artifactStore, ...)`
145
-
146
- **Migration is Simple**:
147
- 1. Replace `startDopEngine` import with `startDopEngineReactNative`
148
- 2. Remove database creation code (`level`, `AsyncStorageDown`, etc.)
149
- 3. Update function call to new signature
150
- 4. Remove level-fs dependencies from package.json
151
-
152
- ## ✅ **Verification**
153
-
154
- - ✅ SDK builds successfully
155
- - ✅ All TypeScript checks pass
156
- - ✅ Integration test updated to use new API
157
- - ✅ Documentation updated with correct examples
158
- - ✅ No more legacy AsyncStorage dependencies
159
- - ✅ Polyfills are automatically handled
160
- - ✅ Database persistence works in React Native
161
-
162
- **Bottom Line**: All React Native integration issues have been resolved. The SDK now provides a seamless, one-function initialization that handles all the complexity internally.
@@ -1,167 +0,0 @@
1
- # React Native Integration Fixes
2
-
3
- ## Problem Summary
4
-
5
- Users were experiencing critical setup issues when integrating the DOP Wallet v6 SDK into React Native applications:
6
-
7
- 1. **"Cannot read property 'call' of undefined" errors** during wallet initialization
8
- 2. **Missing polyfill documentation** - essential polyfills were not documented
9
- 3. **Metro configuration requirements** - Node.js core modules needed browserify aliases
10
- 4. **Import order issues** - polyfills needed to be imported in specific order
11
-
12
- ## Root Causes
13
-
14
- ### 1. Missing Polyfills
15
- The SDK requires several polyfills that were not documented:
16
- - `react-native-get-random-values` - for crypto.getRandomValues()
17
- - `react-native-url-polyfill` - for URL APIs
18
- - `buffer` - for Node.js Buffer support
19
-
20
- ### 2. Missing Metro Configuration
21
- React Native's Metro bundler needed aliases for Node.js core modules:
22
- - `stream` → `stream-browserify`
23
- - `crypto` → `crypto-browserify`
24
- - `http` → `stream-http`
25
- - `https` → `https-browserify`
26
- - `url` → `url`
27
- - `zlib` → `browserify-zlib`
28
- - `path` → `path-browserify`
29
-
30
- ### 3. Import Order Dependencies
31
- Polyfills must be imported before any other modules, including the DOP Wallet SDK.
32
-
33
- ## Solutions Implemented
34
-
35
- ### 1. Updated Integration Guide
36
-
37
- **File**: `DOP_WALLET_V6_REACT_NATIVE_INTEGRATION_GUIDE.md`
38
-
39
- #### Added Complete Dependencies Section
40
- - Comprehensive list of all required dependencies
41
- - Single command to install everything
42
- - Version specifications
43
-
44
- #### Added Metro Configuration
45
- - Complete `metro.config.js` template
46
- - Node.js core module aliases
47
- - Resolver configuration
48
-
49
- #### Added Critical Import Order Instructions
50
- - Step-by-step polyfill import guide
51
- - Warning about import order requirements
52
- - Global Buffer setup
53
-
54
- #### Enhanced Troubleshooting Section
55
- - Specific error messages and solutions
56
- - Setup verification scripts
57
- - Complete dependency checklist
58
- - Debug mode instructions
59
-
60
- ### 2. Documentation Improvements
61
-
62
- #### Complete Example Updates
63
- - Proper App.js setup with correct import order
64
- - Full React Native component example
65
- - Service file structure
66
-
67
- #### Platform-Specific Setup
68
- - iOS Podfile requirements
69
- - Android build.gradle configuration
70
- - Pod install instructions
71
-
72
- #### Verification Tools
73
- - Setup verification script
74
- - Runtime checks for polyfills
75
- - Debug logging helpers
76
-
77
- ## Before vs After
78
-
79
- ### Before (Broken)
80
- ```typescript
81
- // ❌ This would cause "Cannot read property 'call' of undefined"
82
- import { createDopWallet } from 'dop-wallet-v6';
83
- import 'react-native-get-random-values'; // Too late!
84
-
85
- // Missing Metro config would cause "Module not found" errors
86
- // Missing dependencies would cause runtime failures
87
- ```
88
-
89
- ### After (Working)
90
- ```typescript
91
- // ✅ Correct order prevents all initialization errors
92
- import 'react-native-get-random-values';
93
- import 'react-native-url-polyfill/auto';
94
- import { Buffer } from 'buffer';
95
- global.Buffer = global.Buffer || Buffer;
96
- import 'dop-wallet-v6/react-native-shims';
97
-
98
- import { createDopWallet } from 'dop-wallet-v6';
99
- ```
100
-
101
- ## Complete Dependency List
102
-
103
- ### Runtime Dependencies
104
- ```json
105
- {
106
- "dop-wallet-v6": "^1.2.10",
107
- "react-native-level-fs": "^3.0.1",
108
- "@react-native-async-storage/async-storage": "^1.19.0",
109
- "react-native-get-random-values": "^1.9.0",
110
- "react-native-url-polyfill": "^2.0.0",
111
- "buffer": "^6.0.3",
112
- "stream-browserify": "^3.0.0",
113
- "crypto-browserify": "^3.12.0",
114
- "stream-http": "^3.2.0",
115
- "https-browserify": "^1.0.0",
116
- "url": "^0.11.3",
117
- "browserify-zlib": "^0.2.0",
118
- "path-browserify": "^1.0.1"
119
- }
120
- ```
121
-
122
- ### Metro Configuration
123
- ```javascript
124
- config.resolver.alias = {
125
- 'stream': require.resolve('stream-browserify'),
126
- 'crypto': require.resolve('crypto-browserify'),
127
- 'http': require.resolve('stream-http'),
128
- 'https': require.resolve('https-browserify'),
129
- 'url': require.resolve('url'),
130
- 'zlib': require.resolve('browserify-zlib'),
131
- 'path': require.resolve('path-browserify'),
132
- 'fs': require.resolve('react-native-level-fs'),
133
- };
134
- ```
135
-
136
- ## Impact
137
-
138
- ### For Users
139
- - ✅ **Eliminates setup errors** - No more "Cannot read property 'call' of undefined"
140
- - ✅ **Clear documentation** - Step-by-step setup instructions
141
- - ✅ **Verification tools** - Scripts to test setup before integration
142
- - ✅ **Comprehensive troubleshooting** - Solutions for common issues
143
-
144
- ### For Developers
145
- - ✅ **Reduced support burden** - Fewer setup-related issues
146
- - ✅ **Better developer experience** - Clear integration path
147
- - ✅ **Future-proof setup** - Handles React Native polyfill requirements
148
-
149
- ## Validation
150
-
151
- The updated integration guide includes:
152
- 1. **Setup verification script** to test polyfill installation
153
- 2. **Complete example** showing working integration
154
- 3. **Troubleshooting guide** for common issues
155
- 4. **Dependency checklist** for verification
156
-
157
- Users can now follow the guide step-by-step and have a working integration without encountering the previously reported errors.
158
-
159
- ## Version Compatibility
160
-
161
- This fix documentation is for:
162
- - **DOP Wallet v6**: v1.2.10+
163
- - **React Native**: 0.65+
164
- - **Metro**: 0.76+
165
- - **Node.js**: 16+
166
-
167
- The solutions are forward-compatible and should work with future versions of these dependencies.