dop-wallet-v6 1.2.13 → 1.2.15

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.
Files changed (37) hide show
  1. package/ASYNCSTORAGE_FIX_SUMMARY.md +79 -0
  2. package/BUILD_SUCCESS_SUMMARY.md +103 -0
  3. package/DOP_WALLET_V6_WALLET_CREATION_GUIDE.md +305 -0
  4. package/REACT_NATIVE_FIXES_COMPLETE.md +162 -0
  5. package/REACT_NATIVE_INTEGRATION_FIXES.md +167 -0
  6. package/REACT_NATIVE_SETUP_QUICK_FIX.md +189 -0
  7. package/REACT_NATIVE_WALLET_HANGING_FIX.md +270 -0
  8. package/README.md +14 -1
  9. package/VERIFICATION_COMPLETE.md +138 -0
  10. package/WALLET_CREATION_MIGRATION_COMPLETE.md +80 -0
  11. package/dist/services/dop/core/react-native-init.d.ts +18 -0
  12. package/dist/services/dop/core/react-native-init.js +30 -24
  13. package/dist/services/dop/core/react-native-init.js.map +1 -1
  14. package/dist/services/dop/crypto/react-native-crypto-provider.d.ts +41 -0
  15. package/dist/services/dop/crypto/react-native-crypto-provider.js +146 -0
  16. package/dist/services/dop/crypto/react-native-crypto-provider.js.map +1 -0
  17. package/dist/services/dop/crypto/react-native-rapidsnark-prover.d.ts +49 -0
  18. package/dist/services/dop/crypto/react-native-rapidsnark-prover.js +202 -0
  19. package/dist/services/dop/crypto/react-native-rapidsnark-prover.js.map +1 -0
  20. package/dist/services/dop/util/runtime.d.ts +1 -0
  21. package/dist/services/dop/util/runtime.js +34 -2
  22. package/dist/services/dop/util/runtime.js.map +1 -1
  23. package/dist/services/dop/wallets/wallets.js +47 -46
  24. package/dist/services/dop/wallets/wallets.js.map +1 -1
  25. package/issuev3.md +50 -35
  26. package/metro.config.react-native.example.js +10 -8
  27. package/node-polyfills/fs-polyfill.js +54 -0
  28. package/node-polyfills/path-polyfill.js +36 -0
  29. package/node-polyfills/process-polyfill.js +61 -0
  30. package/node-polyfills/url-polyfill.js +32 -0
  31. package/node-polyfills/util-polyfill.js +76 -0
  32. package/package.json +14 -3
  33. package/problem.md +41 -0
  34. package/react-native-shims.js +27 -10
  35. package/react-native.js +12 -0
  36. package/WEB_WORKER_TROUBLESHOOTING.md +0 -180
  37. package/node-polyfills/package.json +0 -9
package/issuev3.md CHANGED
@@ -1,78 +1,93 @@
1
- Integrating dop-wallet-v6 into a React Native 0.81 (new architecture) app consistently fails during Metro bundling before the app can run. All failures vanish if dop-wallet-v6 is removed. The errors originate from transitive deps brought in by dop-wallet-v6 (notably ffjavascript, web-worker, wasmcurves, wasmbuilder) that expect Node.js or Web Worker environments. React Native’s Metro/Hermes does not provide those environments by default.
1
+ React Native Integration Report for dopwallet-v6
2
+
3
+ Summary
4
+
5
+ Integrating dop-wallet-v6 into a React Native 0.81 (new architecture) app consistently fails during Metro bundling before the app can run. All failures vanish if dop-wallet-v6 is removed. The errors originate from transitive deps brought in by dop-wallet-v6 (notably ffjavascript, webworker, wasmcurves, wasmbuilder) that expect Node.js or Web Worker environments. React Native’s Metro/Hermes does not provide those environments by default.
2
6
 
3
7
  Key blockers observed:
4
8
 
5
9
  • ffjavascript does require('os') → Metro can’t resolve Node core module os.
10
+
6
11
  • After stubbing/aliasing os, Metro hits web-worker/cjs/node.js and fails on import(mod) (dynamic import in CJS path), which is incompatible in this RN+Metro context.
12
+
7
13
  • Prior to this, we also had to polyfill other Node core modules (assert, events, process, buffer) just to progress to the next error.
14
+
8
15
  When dop-wallet-v6 is uninstalled (and its import commented out), the app runs normally.
9
16
 
10
-
11
17
  Environment
12
18
 
13
19
  • Platform: React Native 0.81.x (New Architecture enabled)
20
+
14
21
  • Bundler/Engine: Metro + Hermes (RN default)
22
+
15
23
  • OS/Dev machine: macOS (Intel)
24
+
16
25
  • Crypto/Polyfills used in app:
17
- o react-native-quick-crypto (polyfills Node crypto)
18
- o react-native-get-random-values
19
- o Manual/global polyfills for process, Buffer, stream, util, assert, events
20
- o Local “os” stub (details below)
21
- Note: RN ≥0.76 no longer ships Node polyfills automatically. Metro requires explicit polyfills or aliases for Node core modules.
26
+
27
+ o react-native-quick-crypto (polyfills Node crypto) o react-native-get-random-values o Manual/global polyfills for process, Buffer, stream, util, assert, events o Local “os” stub (details below) Note: RN ≥0.76 no longer ships Node polyfills automatically. Metro requires explicit polyfills or aliases for Node core modules.
22
28
 
23
29
  Some Code Snippets
24
30
 
25
31
  Added polyfills.js and import it at the very top of index.js:
26
- // polyfills.js
27
- import 'react-native-get-random-values';
28
- import 'react-native-quick-crypto';
29
-
32
+
33
+ // polyfills.js import 'react-native-get-random-values'; import 'react-native-quick-crypto';
34
+
30
35
  if (typeof global.process === 'undefined') global.process = require('process');
36
+
31
37
  if (typeof global.Buffer === 'undefined') global.Buffer = require('buffer').Buffer;
32
-
33
- // Minimal 'os' ponyfill to get past ffjavascript's 'require("os")'
34
- // (Note: a global doesn’t satisfy require('os'); see metro alias below)
35
- global.os = {
36
- platform: () => 'react-native',
37
- homedir: () => '/',
38
- tmpdir: () => '/tmp',
39
- };
40
-
38
+
39
+ // Minimal 'os' ponyfill to get past ffjavascript's 'require("os")' // (Note: a global doesn’t satisfy require('os'); see metro alias below) global.os = { platform: () => 'react-native', homedir: () => '/', tmpdir: () => '/tmp', };
40
+
41
41
  global.stream = require('stream-browserify');
42
+
42
43
  global.util = require('util');
44
+
43
45
  global.assert = require('assert');
46
+
44
47
  global.events = require('events');
45
48
 
46
49
  In metro.config.js, alias Node core os to our stub (this is what actually satisfies require('os') at bundle-time):
47
- // force `require('os')` to hit our stub file
48
- os: require.resolve('./polyfills.js'),
49
50
 
50
-
51
+ // force `require('os')` to hit our stub file os: require.resolve('./polyfills.js'),
52
+
51
53
  Errors & Logs
52
- ➢ Missing Node core module (os):
53
- BUNDLE ./index.js
54
- ERROR Error: Unable to resolve module os from node_modules/ffjavascript/build/main.cjs:
55
- os could not be found within the project or in these directories: node_modules
56
-
57
- 3 | var crypto = require('crypto');
58
- 4 | var wasmcurves = require('wasmcurves');
54
+
55
+
56
+
57
+ Missing Node core module (os):
58
+
59
+ BUNDLE ./index.js ERROR Error: Unable to resolve module os from node_modules/ffjavascript/build/main.cjs: os could not be found within the project or in these directories: node_modules
60
+
61
+ 3 | var crypto = require('crypto');
62
+
63
+ 4 | var wasmcurves = require('wasmcurves');
64
+
59
65
  > 5 | var os = require('os');
60
- ^
61
- 6 | var Worker = require('web-worker');
66
+
67
+ ^
68
+
69
+ 6 | var Worker = require('web-worker');
70
+
62
71
  • Root: ffjavascript requires the Node core module os.
72
+
63
73
  • Workaround tried:
74
+
64
75
  • Setting global.os = { ... } alone is not enough because require('os') needs a module, not a global.
76
+
65
77
  • Aliasing os to a local stub in metro.config.js resolves bundling past this point.
66
-
67
78
 
68
-
79
+
80
+
81
+ Next blocker from web-worker:
69
82
 
70
- ➢ Next blocker from web-worker:
71
83
  ERROR node_modules/web-worker/cjs/node.js: node_modules/web-worker/cjs/node.js: Invalid call at line 201: import(mod)
72
84
 
73
85
  Analysis (why this breaks on RN)
74
86
 
75
87
  1. Node core deps in transitive packages (ffjavascript → require('os')) aren’t available in RN. We can alias some, but it’s brittle and incomplete.
88
+
76
89
  2. Web Worker dependency (web-worker, wasmbuilder) assumes either Node (worker threads / dynamic loading) or browser (DOM Workers). React Native has neither by default. Metro/Hermes do not support those code paths out of the box.
90
+
77
91
  3. Dynamic import in a CJS Node path (web-worker/cjs/node.js → import(mod)) is not compatible with RN/Metro bundle stage in this context.
92
+
78
93
  4. Potential WASM assets (wasmcurves, wasmbuilder) usually require Metro config for *.wasm and a runtime that supports WASM in Hermes (partial/experimental). Even if we get past web-worker, WASM loading likely becomes the next blocker unless the SDK ships an RN-ready path.
@@ -22,13 +22,14 @@ const config = {
22
22
  'stream': require.resolve('stream-browserify'),
23
23
  'buffer': require.resolve('buffer'),
24
24
  'events': require.resolve('events'),
25
- 'util': require.resolve('util'),
25
+ 'util': require.resolve('./node-polyfills/util-polyfill.js'),
26
26
  'assert': require.resolve('assert'),
27
- 'process': require.resolve('process/browser'),
27
+ 'process': require.resolve('./node-polyfills/process-polyfill.js'),
28
28
 
29
29
  // Additional modules that might be needed
30
- 'path': require.resolve('path-browserify'),
31
- 'url': require.resolve('url'),
30
+ 'path': require.resolve('./node-polyfills/path-polyfill.js'),
31
+ 'url': require.resolve('./node-polyfills/url-polyfill.js'),
32
+ 'fs': require.resolve('./node-polyfills/fs-polyfill.js'),
32
33
  'querystring': require.resolve('querystring-es3'),
33
34
  'http': require.resolve('stream-http'),
34
35
  'https': require.resolve('https-browserify'),
@@ -51,11 +52,12 @@ const config = {
51
52
  'stream': require.resolve('stream-browserify'),
52
53
  'buffer': require.resolve('buffer'),
53
54
  'events': require.resolve('events'),
54
- 'util': require.resolve('util'),
55
+ 'util': require.resolve('./node-polyfills/util-polyfill.js'),
55
56
  'assert': require.resolve('assert'),
56
- 'process': require.resolve('process/browser'),
57
- 'path': require.resolve('path-browserify'),
58
- 'url': require.resolve('url'),
57
+ 'process': require.resolve('./node-polyfills/process-polyfill.js'),
58
+ 'path': require.resolve('./node-polyfills/path-polyfill.js'),
59
+ 'url': require.resolve('./node-polyfills/url-polyfill.js'),
60
+ 'fs': require.resolve('./node-polyfills/fs-polyfill.js'),
59
61
  'querystring': require.resolve('querystring-es3'),
60
62
  'http': require.resolve('stream-http'),
61
63
  'https': require.resolve('https-browserify'),
@@ -0,0 +1,54 @@
1
+ /**
2
+ * File System (fs) polyfill for React Native
3
+ *
4
+ * This addresses the usage of 'fs' module in test files and prevents
5
+ * any accidental Node.js fs usage in production React Native code.
6
+ */
7
+
8
+ console.warn('fs polyfill: File system operations are not supported in React Native.');
9
+
10
+ // Mock fs operations that might be called
11
+ const throwError = (operation) => {
12
+ throw new Error(`fs.${operation}() is not supported in React Native environment. Use AsyncStorage or RNFS instead.`);
13
+ };
14
+
15
+ module.exports = {
16
+ // Common fs methods that might be imported
17
+ readFile: () => throwError('readFile'),
18
+ readFileSync: () => throwError('readFileSync'),
19
+ writeFile: () => throwError('writeFile'),
20
+ writeFileSync: () => throwError('writeFileSync'),
21
+ exists: () => throwError('exists'),
22
+ existsSync: () => throwError('existsSync'),
23
+ mkdir: () => throwError('mkdir'),
24
+ mkdirSync: () => throwError('mkdirSync'),
25
+ rmdir: () => throwError('rmdir'),
26
+ rmdirSync: () => throwError('rmdirSync'),
27
+ unlink: () => throwError('unlink'),
28
+ unlinkSync: () => throwError('unlinkSync'),
29
+ rmSync: () => throwError('rmSync'),
30
+ stat: () => throwError('stat'),
31
+ statSync: () => throwError('statSync'),
32
+
33
+ // Mock fs constants that might be referenced
34
+ constants: {
35
+ F_OK: 0,
36
+ R_OK: 4,
37
+ W_OK: 2,
38
+ X_OK: 1,
39
+ },
40
+
41
+ // Mock createReadStream and createWriteStream
42
+ createReadStream: () => throwError('createReadStream'),
43
+ createWriteStream: () => throwError('createWriteStream'),
44
+
45
+ // Promises namespace
46
+ promises: {
47
+ readFile: () => throwError('promises.readFile'),
48
+ writeFile: () => throwError('promises.writeFile'),
49
+ mkdir: () => throwError('promises.mkdir'),
50
+ rmdir: () => throwError('promises.rmdir'),
51
+ unlink: () => throwError('promises.unlink'),
52
+ stat: () => throwError('promises.stat'),
53
+ }
54
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Path module polyfill for React Native
3
+ *
4
+ * This provides a minimal path module implementation that works in React Native.
5
+ * Uses path-browserify for most functionality but adds React Native specific handling.
6
+ */
7
+
8
+ const pathBrowserify = require('path-browserify');
9
+
10
+ console.warn('path polyfill: Using browserify path implementation for React Native.');
11
+
12
+ // Export all path-browserify functionality
13
+ module.exports = {
14
+ ...pathBrowserify,
15
+
16
+ // Override or add any React Native specific path handling if needed
17
+ resolve: (...paths) => {
18
+ // In React Native, we don't have access to process.cwd()
19
+ // so we handle relative paths differently
20
+ return pathBrowserify.resolve(...paths);
21
+ },
22
+
23
+ // Ensure we handle React Native bundle paths correctly
24
+ join: (...paths) => {
25
+ return pathBrowserify.join(...paths);
26
+ },
27
+
28
+ // React Native specific helpers
29
+ isAbsolute: (path) => {
30
+ // In React Native, absolute paths might start with different prefixes
31
+ return pathBrowserify.isAbsolute(path) ||
32
+ path.startsWith('file://') ||
33
+ path.startsWith('bundle://') ||
34
+ path.startsWith('content://');
35
+ },
36
+ };
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Process polyfill for React Native
3
+ *
4
+ * This extends the basic process polyfill with React Native specific environment handling.
5
+ */
6
+
7
+ const processPolyfill = require('process/browser');
8
+
9
+ // Enhance the basic process polyfill for React Native
10
+ const enhancedProcess = {
11
+ ...processPolyfill,
12
+
13
+ // React Native specific environment
14
+ platform: 'react-native',
15
+
16
+ // Ensure we have proper environment variables
17
+ env: {
18
+ ...processPolyfill.env,
19
+ NODE_ENV: processPolyfill.env.NODE_ENV || 'production',
20
+ // React Native specific environment indicators
21
+ REACT_NATIVE: true,
22
+ REACT_NATIVE_DEBUGGER: typeof __DEV__ !== 'undefined' && __DEV__,
23
+ },
24
+
25
+ // React Native doesn't have these, so provide safe defaults
26
+ cwd: () => '/',
27
+ chdir: () => {
28
+ console.warn('process.chdir() is not supported in React Native');
29
+ },
30
+
31
+ // Add React Native detection
32
+ versions: {
33
+ ...processPolyfill.versions,
34
+ 'react-native': '0.70.0', // Indicate React Native environment
35
+ },
36
+
37
+ // Override stdout/stderr for React Native
38
+ stdout: {
39
+ write: (data) => console.log(data),
40
+ isTTY: false,
41
+ },
42
+ stderr: {
43
+ write: (data) => console.error(data),
44
+ isTTY: false,
45
+ },
46
+
47
+ // Add hrtime polyfill for React Native
48
+ hrtime: (time) => {
49
+ const now = Date.now() * 1e-3;
50
+ if (time) {
51
+ const [seconds, nanoseconds] = time;
52
+ const diff = now - (seconds + nanoseconds * 1e-9);
53
+ const diffSeconds = Math.floor(diff);
54
+ const diffNanoseconds = Math.floor((diff - diffSeconds) * 1e9);
55
+ return [diffSeconds, diffNanoseconds];
56
+ }
57
+ return [Math.floor(now), Math.floor((now % 1) * 1e9)];
58
+ },
59
+ };
60
+
61
+ module.exports = enhancedProcess;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * URL module polyfill for React Native
3
+ *
4
+ * This provides URL parsing functionality for React Native using the 'url' package.
5
+ */
6
+
7
+ // Use the existing url package which should work in React Native
8
+ const url = require('url');
9
+
10
+ console.warn('url polyfill: Using url package for React Native URL parsing.');
11
+
12
+ // Export the url module functionality
13
+ module.exports = {
14
+ ...url,
15
+
16
+ // Ensure URL and URLSearchParams are available as globals if needed
17
+ URL: typeof URL !== 'undefined' ? URL : require('url').URL,
18
+ URLSearchParams: typeof URLSearchParams !== 'undefined' ? URLSearchParams : require('url').URLSearchParams,
19
+
20
+ // Add React Native specific URL handling if needed
21
+ parse: (urlString, parseQueryString, slashesDenoteHost) => {
22
+ return url.parse(urlString, parseQueryString, slashesDenoteHost);
23
+ },
24
+
25
+ format: (urlObject) => {
26
+ return url.format(urlObject);
27
+ },
28
+
29
+ resolve: (from, to) => {
30
+ return url.resolve(from, to);
31
+ },
32
+ };
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Util module polyfill for React Native
3
+ *
4
+ * This provides Node.js util functionality for React Native.
5
+ */
6
+
7
+ // Use the util package which should work in React Native
8
+ const util = require('util');
9
+
10
+ console.warn('util polyfill: Using util package for React Native.');
11
+
12
+ // Ensure promisify is available - this is critical for crypto operations
13
+ const promisify = util.promisify || ((fn) => {
14
+ return function promisified(...args) {
15
+ return new Promise((resolve, reject) => {
16
+ fn.call(this, ...args, (err, result) => {
17
+ if (err) reject(err);
18
+ else resolve(result);
19
+ });
20
+ });
21
+ };
22
+ });
23
+
24
+ // Export util functionality with React Native enhancements
25
+ module.exports = {
26
+ ...util,
27
+
28
+ // Ensure promisify is always available
29
+ promisify,
30
+
31
+ // Add React Native safe implementations
32
+ inspect: (obj, options = {}) => {
33
+ // In React Native, we might not have full util.inspect capabilities
34
+ if (typeof obj === 'object' && obj !== null) {
35
+ try {
36
+ return JSON.stringify(obj, null, options.depth || 2);
37
+ } catch (error) {
38
+ return '[Object object]';
39
+ }
40
+ }
41
+ return String(obj);
42
+ },
43
+
44
+ // Provide format function
45
+ format: util.format || ((f, ...args) => {
46
+ let index = 0;
47
+ return f.replace(/%[sdj%]/g, (match) => {
48
+ if (index >= args.length) return match;
49
+ switch (match) {
50
+ case '%s': return String(args[index++]);
51
+ case '%d': return Number(args[index++]);
52
+ case '%j':
53
+ try {
54
+ return JSON.stringify(args[index++]);
55
+ } catch (error) {
56
+ return '[Circular]';
57
+ }
58
+ case '%%': return '%';
59
+ default:
60
+ return match;
61
+ }
62
+ });
63
+ }),
64
+
65
+ // Provide deprecate function
66
+ deprecate: util.deprecate || ((fn, msg) => {
67
+ let warned = false;
68
+ return function deprecated(...args) {
69
+ if (!warned) {
70
+ console.warn(msg);
71
+ warned = true;
72
+ }
73
+ return fn.apply(this, args);
74
+ };
75
+ }),
76
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dop-wallet-v6",
3
- "version": "1.2.13",
3
+ "version": "1.2.15",
4
4
  "description": "DOP Wallet SDK, compatible with mobile, browser and nodejs environments.",
5
5
  "main": "dist/index.js",
6
6
  "license": "MIT",
@@ -14,6 +14,7 @@
14
14
  ],
15
15
  "exports": {
16
16
  ".": "./dist/index.js",
17
+ "./react-native": "./react-native.js",
17
18
  "./react-native-shims": "./react-native-shims.js"
18
19
  },
19
20
  "scripts": {
@@ -29,7 +30,8 @@
29
30
  "eslint": "eslint src/**/* --ext .ts,.tsx --ignore-pattern **/*.graphql --fix",
30
31
  "lint": "npm run check-circular-deps && npm run eslint && npm run tsc && npm run tsc-test",
31
32
  "prepare": "npm run build",
32
- "postinstall": "node postinstall.js"
33
+ "postinstall": "node postinstall.js",
34
+ "verify-rn-compatibility": "node verify-react-native-compatibility.cjs"
33
35
  },
34
36
  "dependencies": {
35
37
  "@graphql-mesh/cross-helpers": "^0.3.4",
@@ -44,6 +46,7 @@
44
46
  "@noble/ed25519": "^1.7.1",
45
47
  "@react-native-async-storage/async-storage": "^1.24.0",
46
48
  "@whatwg-node/fetch": "^0.8.4",
49
+ "@zk-kit/eddsa-poseidon": "^1.1.0",
47
50
  "assert": "2.0.0",
48
51
  "axios": "1.7.2",
49
52
  "brotli": "^1.3.3",
@@ -57,6 +60,7 @@
57
60
  "events": "3.3.0",
58
61
  "graphql": "^16.6.0",
59
62
  "memdown": "^6.1.1",
63
+ "poseidon-lite": "^0.3.0",
60
64
  "stream-browserify": "3.0.0"
61
65
  },
62
66
  "devDependencies": {
@@ -87,16 +91,23 @@
87
91
  "typescript": "^4.9.4"
88
92
  },
89
93
  "peerDependencies": {
94
+ "@iden3/react-native-rapidsnark": "^0.0.1-beta.1",
90
95
  "@react-native-async-storage/async-storage": "^1.24.0"
91
96
  },
92
97
  "peerDependenciesMeta": {
93
98
  "@react-native-async-storage/async-storage": {
94
99
  "optional": false
100
+ },
101
+ "@iden3/react-native-rapidsnark": {
102
+ "optional": true
95
103
  }
96
104
  },
97
105
  "react-native": {
98
106
  "crypto": false,
99
- "util": false
107
+ "util": false,
108
+ "fs": false,
109
+ "path": false,
110
+ "os": false
100
111
  },
101
112
  "resolutions": {
102
113
  "ethers": "6.13.1"
package/problem.md ADDED
@@ -0,0 +1,41 @@
1
+ 1.3 Mnemonic Handling
2
+ Docs suggested passing undefined to createDopWallet so it would generate a mnemonic automatically:
3
+
4
+ const wallet = await createDopWallet(encryptionKey, undefined, creationBlockNumbers);
5
+
6
+ However, in React Native this failed with:
7
+ [wallet] failed: Error: Invalid mnemonic type: undefined

Resolution:
 Instead of relying on auto-generation, we had to supply a valid 12-word Metamask seed phrase directly.
8
+ 1.4 Encryption Key & Wallet Creation (merged with 3)
9
+ This was the biggest blocker.
10
+ Issue: Wrong Encryption Key Format
11
+ When trying plain strings (like "abcdefghijklmnopqrstuvwxyzabcdqa..."), the engine threw:
12
+ [wallet] failed: Error: encryptionKey must be a 32-byte string
13
+ Even when using a 64-character hex string (which visually looked correct length), the SDK still rejected it.
14
+ Root Cause:
15
+ The DOP engine expects a raw 32-byte Uint8Array, not a text string.
16
+ "abcd..." → string length, not raw bytes
17
+ "4b22bfaa2cd4826c04efa..." (64 hex chars) → still a string, needed conversion
18
+ Fix: Convert Hex → Bytes
19
+ We converted to Buffer / Uint8Array before passing:
20
+
21
+ import { Buffer } from 'buffer';

const encryptionKeyHex = '4b22bfaa2cd4826c04efa1beb5c3debf8a534223200ce50ce3ca979af93911c1';
const encryptionKey = Buffer.from(encryptionKeyHex, 'hex'); // 32 bytes
22
+
23
+ Validated with:

24
+ console.log(Buffer.from(encryptionKeyHex, 'hex').length); // 32
25
+
26
+
27
+ ✅ Now the key passed validation. But still there was some issue, issue explained below-
28
+ Issue: Wallet Creation “Stuck”
29
+ At times, wallet creation froze after:
30
+ DOP Engine initialized successfully
Calling createNewWallet...
Creating new wallet with encryption key...
31
+ and never returned.


32
+ Supposed Root Causes:
33
+ Passing undefined mnemonic (engine waited indefinitely).
34
+ Wrong encryption key type (string instead of raw bytes).
35
+ Heavy sync overhead (engine scanning entire chain).
36
+ Tried Fixes:
37
+ Passed a valid mnemonic instead of undefined.
38
+ Correctly used a raw 32-byte Uint8Array for encryptionKey.
39
+ Added:
40
+ const skipMerkletreeScans = true;
const creationBlockNumbers = { [NetworkName.EthereumSepolia]: 6000000 };

41
+ to reduce sync load during testing.

After trying all fixes and debugging, now there were no errors in logs, but the wallet creation never succeded, it always seemed to be stuck, but showed no errors.
@@ -29,10 +29,12 @@ global.crypto.subtle.digest ??= (algorithm, data) => {
29
29
  return cryptoBrowserify.createHash(algo).update(data).digest();
30
30
  };
31
31
 
32
- // CRITICAL FIX: Force circomlibjs to use synchronous mode in React Native
32
+ // CRITICAL FIX: Force optimal crypto libraries for React Native
33
33
  // This prevents hanging during wallet creation due to Web Worker incompatibility
34
34
  if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
35
- // Disable Web Workers and WebAssembly for circomlibjs
35
+ console.log('🔧 Applying React Native crypto optimizations...');
36
+
37
+ // Disable Web Workers and WebAssembly for circomlibjs fallback
36
38
  global.Worker = undefined;
37
39
  global.WebAssembly = undefined;
38
40
 
@@ -65,18 +67,33 @@ if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
65
67
  }
66
68
  return originalSetTimeout.apply(this, arguments);
67
69
  };
70
+
71
+ console.log('✅ React Native crypto optimizations applied');
68
72
  }
69
73
 
70
74
  /**
75
+ * React Native Compatibility Information:
76
+ *
77
+ * This SDK now uses lightweight crypto alternatives for React Native:
78
+ * - poseidon-lite: Lightweight poseidon hash (replaces circomlibjs poseidon)
79
+ * - @zk-kit/eddsa-poseidon: EdDSA operations (replaces circomlibjs eddsa)
80
+ * - @iden3/react-native-rapidsnark: Fast proof generation (optional, recommended)
81
+ *
82
+ * Benefits:
83
+ * - Faster initialization and smaller bundle size
84
+ * - No Web Worker dependencies
85
+ * - Better mobile performance
86
+ * - Native iOS/Android compilation support via rapidsnark
87
+ *
88
+ * Installation for React Native projects:
89
+ * npm install @react-native-async-storage/async-storage react-native-get-random-values
90
+ * npm install @iden3/react-native-rapidsnark # Optional but recommended
91
+ *
71
92
  * Other package.json dependencies and why we need them:
72
- * - assert:
73
- * - engine uses circomlibjs which uses assert
74
- * - events:
75
- * - engine uses EventEmitter;
76
- * - engine uses levelup which uses EventEmitter
77
- * - stream-browserify:
78
- * - engine uses AES encryption, which we shim with browserify-aes, which
79
- * needs cipher-base, which needs stream
93
+ * - assert: engine uses circomlibjs which uses assert (now uses lightweight alternatives)
94
+ * - events: engine uses EventEmitter; engine uses levelup which uses EventEmitter
95
+ * - stream-browserify: engine uses AES encryption, which we shim with browserify-aes,
96
+ * which needs cipher-base, which needs stream
80
97
  *
81
98
  * AsyncStorage Compatibility Note:
82
99
  * - This wallet SDK is compatible with React Native 0.60+ which moved AsyncStorage
@@ -0,0 +1,12 @@
1
+ /**
2
+ * React Native specific entry point for DOP Wallet SDK
3
+ *
4
+ * This file provides React Native-specific initialization and polyfill setup.
5
+ * Import this before importing the main SDK to ensure proper React Native compatibility.
6
+ */
7
+
8
+ // Apply React Native shims first
9
+ require('./react-native-shims');
10
+
11
+ // Re-export the main SDK
12
+ module.exports = require('./dist/index.js');