dop-wallet-v6 1.3.32 → 1.3.33
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.
- package/.eslintrc.js +11 -1
- package/README.md +367 -9
- package/dist/services/dop/core/index.d.ts +4 -0
- package/dist/services/dop/core/index.js +5 -0
- package/dist/services/dop/core/index.js.map +1 -1
- package/dist/services/dop/core/react-native-init.js +28 -1
- package/dist/services/dop/core/react-native-init.js.map +1 -1
- package/dist/services/dop/core/react-native-prover-setup.d.ts +31 -0
- package/dist/services/dop/core/react-native-prover-setup.js +111 -0
- package/dist/services/dop/core/react-native-prover-setup.js.map +1 -0
- package/dist/services/dop/crypto/user-rapidsnark-adapter.d.ts +98 -0
- package/dist/services/dop/crypto/user-rapidsnark-adapter.js +226 -0
- package/dist/services/dop/crypto/user-rapidsnark-adapter.js.map +1 -0
- package/package.json +1 -1
- package/react-native.js +6 -1
package/.eslintrc.js
CHANGED
|
@@ -63,15 +63,25 @@ module.exports = {
|
|
|
63
63
|
},
|
|
64
64
|
overrides: [
|
|
65
65
|
{
|
|
66
|
-
files: ['**/__tests__/**', './src/tests/**'],
|
|
66
|
+
files: ['**/__tests__/**', './src/tests/**', '**/*.test.ts'],
|
|
67
67
|
rules: {
|
|
68
68
|
'@typescript-eslint/no-explicit-any': 0,
|
|
69
69
|
'@typescript-eslint/no-unsafe-member-access': 0,
|
|
70
|
+
'@typescript-eslint/no-unsafe-assignment': 0,
|
|
71
|
+
'@typescript-eslint/no-unsafe-call': 0,
|
|
72
|
+
'@typescript-eslint/no-unsafe-argument': 0,
|
|
73
|
+
'@typescript-eslint/no-unsafe-return': 0,
|
|
74
|
+
'@typescript-eslint/strict-boolean-expressions': 0,
|
|
75
|
+
'@typescript-eslint/restrict-template-expressions': 0,
|
|
76
|
+
'@typescript-eslint/no-non-null-assertion': 0,
|
|
70
77
|
'import/no-extraneous-dependencies': 0,
|
|
71
78
|
'no-console': 0,
|
|
72
79
|
'@typescript-eslint/no-unused-vars': 0,
|
|
73
80
|
'no-useless-concat': 0,
|
|
74
81
|
'@typescript-eslint/await-thenable': 0,
|
|
82
|
+
'no-plusplus': 0,
|
|
83
|
+
'no-constant-condition': 0,
|
|
84
|
+
'func-names': 0,
|
|
75
85
|
},
|
|
76
86
|
},
|
|
77
87
|
],
|
package/README.md
CHANGED
|
@@ -1,23 +1,381 @@
|
|
|
1
|
+
# DOP Wallet SDK v6
|
|
1
2
|
|
|
3
|
+
**Privacy-preserving blockchain transactions for Ethereum, Polygon, BNB Chain, Arbitrum, and Base**
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://www.npmjs.com/package/dop-wallet-v6)
|
|
7
|
+
[](https://nodejs.org)
|
|
8
|
+
[](https://reactnative.dev)
|
|
4
9
|
|
|
5
|
-
The DOP Wallet SDK
|
|
10
|
+
The DOP Wallet SDK enables developers to integrate private token transfers, shielding, and zero-knowledge proofs into their applications. Built with TypeScript and compatible with **Node.js**, **browsers**, and **React Native**.
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
**Developed by [DOP](https://www.dop.org) contributors.**
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
---
|
|
10
15
|
|
|
11
|
-
##
|
|
16
|
+
## 📚 Complete Documentation
|
|
12
17
|
|
|
13
|
-
|
|
18
|
+
**See [SDK_DOCS.md](./SDK_DOCS.md) for complete API reference, installation guides, and working examples.**
|
|
19
|
+
|
|
20
|
+
The SDK_DOCS.md contains:
|
|
21
|
+
- Installation for Node.js, Browser, and React Native
|
|
22
|
+
- Complete API reference verified against working test files
|
|
23
|
+
- Step-by-step workflows for Shield, Unshield, and Private Transfers
|
|
24
|
+
- Real code examples that compile and run
|
|
25
|
+
- Error handling and performance tips
|
|
26
|
+
- React Native integration guide
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## ✨ Features
|
|
31
|
+
|
|
32
|
+
- 🔒 **Private Transfers**: Send ERC20, ERC721, ERC1155 tokens without revealing amounts or recipients
|
|
33
|
+
- 🛡️ **Shield/Unshield**: Convert between public and private token balances
|
|
34
|
+
- 📊 **Balance Queries**: View private balances across multiple chains
|
|
35
|
+
- 🔐 **Zero-Knowledge Proofs**: Generate and verify zk-SNARK proofs
|
|
36
|
+
- 🌐 **Multi-Chain**: Ethereum, Polygon, BNB Chain, Arbitrum, Base
|
|
37
|
+
- 📱 **React Native**: Full mobile support with custom proof generation
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 🚀 Quick Start
|
|
42
|
+
|
|
43
|
+
### Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install dop-wallet-v6 dop-sharedmodels-v3
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
For Node.js:
|
|
50
|
+
```bash
|
|
51
|
+
npm install leveldown snarkjs
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
For React Native:
|
|
55
|
+
```bash
|
|
56
|
+
npm install react-native-get-random-values @react-native-async-storage/async-storage
|
|
57
|
+
npm install buffer assert stream-browserify crypto-browserify events
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Node.js Example
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import {
|
|
64
|
+
startDopEngine,
|
|
65
|
+
createOrImportDopWallet,
|
|
66
|
+
gasEstimateForEncrypt,
|
|
67
|
+
populateEncrypt,
|
|
68
|
+
getSerializedERC20Balances,
|
|
69
|
+
getProver
|
|
70
|
+
} from 'dop-wallet-v6';
|
|
71
|
+
import { NetworkName, NETWORK_CONFIG, TXIDVersion } from 'dop-sharedmodels-v3';
|
|
72
|
+
import { groth16 } from 'snarkjs';
|
|
73
|
+
import LevelDOWN from 'leveldown';
|
|
74
|
+
|
|
75
|
+
// Initialize
|
|
76
|
+
const db = new LevelDOWN('./dop-db');
|
|
77
|
+
await startDopEngine('my-app', db, false, artifactStore, false, false, true);
|
|
78
|
+
|
|
79
|
+
// Setup prover (required for transfers/unshield)
|
|
80
|
+
const prover = getProver();
|
|
81
|
+
prover.setSnarkJSGroth16(groth16);
|
|
82
|
+
|
|
83
|
+
// Create wallet
|
|
84
|
+
const { walletInfo, mnemonic } = await createOrImportDopWallet('encryption-key');
|
|
85
|
+
console.log('Save this mnemonic:', mnemonic);
|
|
86
|
+
|
|
87
|
+
// Shield tokens (3-step process)
|
|
88
|
+
const { gasEstimate } = await gasEstimateForEncrypt(/* ... */);
|
|
89
|
+
const txRequest = await populateEncrypt(/* ... */);
|
|
90
|
+
await publicWallet.sendTransaction(txRequest);
|
|
91
|
+
|
|
92
|
+
// Check balance
|
|
93
|
+
const balances = getSerializedERC20Balances(
|
|
94
|
+
TXIDVersion.V3_PoseidonMerkle,
|
|
95
|
+
NETWORK_CONFIG[NetworkName.Polygon].chain,
|
|
96
|
+
walletInfo.id
|
|
97
|
+
);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**See [SDK_DOCS.md](./SDK_DOCS.md) for complete working examples.**
|
|
101
|
+
|
|
102
|
+
### React Native Example
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import 'react-native-get-random-values'; // MUST BE FIRST!
|
|
106
|
+
import { Buffer } from 'buffer';
|
|
107
|
+
global.Buffer = global.Buffer || Buffer;
|
|
108
|
+
import 'dop-wallet-v6/react-native-shims';
|
|
109
|
+
|
|
110
|
+
import {
|
|
111
|
+
startDopEngine,
|
|
112
|
+
createOrImportDopWallet,
|
|
113
|
+
populateEncrypt,
|
|
114
|
+
getSerializedERC20Balances
|
|
115
|
+
} from 'dop-wallet-v6';
|
|
116
|
+
import MemDOWN from 'memdown';
|
|
117
|
+
|
|
118
|
+
// Initialize with React Native settings
|
|
119
|
+
const db = new MemDOWN();
|
|
120
|
+
await startDopEngine('my-app', db, __DEV__, artifactStore, true, false, __DEV__);
|
|
121
|
+
|
|
122
|
+
// Create wallet
|
|
123
|
+
const { walletInfo } = await createOrImportDopWallet('encryption-key');
|
|
124
|
+
|
|
125
|
+
// Shield works immediately
|
|
126
|
+
const txRequest = await populateEncrypt(/* ... */);
|
|
127
|
+
await wallet.sendTransaction(txRequest);
|
|
128
|
+
|
|
129
|
+
// Check balance
|
|
130
|
+
const balances = getSerializedERC20Balances(TXIDVersion.V3_PoseidonMerkle, chain, walletInfo.id);
|
|
131
|
+
|
|
132
|
+
// For private transfers, configure custom Rapidsnark prover
|
|
133
|
+
// See SDK_DOCS.md React Native section
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 📚 Documentation
|
|
139
|
+
|
|
140
|
+
**📖 [SDK_DOCS.md](./SDK_DOCS.md)** - Complete unified documentation (RECOMMENDED)
|
|
141
|
+
|
|
142
|
+
The SDK_DOCS.md contains everything you need:
|
|
143
|
+
- Installation for all platforms
|
|
144
|
+
- Complete API reference verified against tests
|
|
145
|
+
- Step-by-step workflows with real code
|
|
146
|
+
- React Native integration guide
|
|
147
|
+
- Error handling and performance tips
|
|
148
|
+
|
|
149
|
+
### Quick Navigation
|
|
150
|
+
|
|
151
|
+
- **New to DOP?** → Start with [SDK_DOCS.md](./SDK_DOCS.md)
|
|
152
|
+
- **Looking for specific function?** → See API Reference section in SDK_DOCS.md
|
|
153
|
+
- **React Native setup?** → See React Native section in SDK_DOCS.md
|
|
154
|
+
- **Complete workflows?** → See Complete Workflows section in SDK_DOCS.md
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 🔧 Environment Support
|
|
159
|
+
|
|
160
|
+
| Feature | Node.js | Browser | React Native |
|
|
161
|
+
|---------|---------|---------|--------------|
|
|
162
|
+
| Shield (encrypt) tokens | ✅ | ✅ | ✅ |
|
|
163
|
+
| View private balances | ✅ | ✅ | ✅ |
|
|
164
|
+
| Private transfers | ✅ | ✅ | ✅* |
|
|
165
|
+
| Unshield (decrypt) tokens | ✅ | ✅ | ✅* |
|
|
166
|
+
| Wallet management | ✅ | ✅ | ✅ |
|
|
167
|
+
| Transaction history | ✅ | ✅ | ✅ |
|
|
168
|
+
|
|
169
|
+
*React Native private transfers require custom Rapidsnark prover setup. See [REACT_NATIVE_USER_CONFIGURABLE_PROVER.md](./REACT_NATIVE_USER_CONFIGURABLE_PROVER.md).
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 🎯 Use Cases
|
|
174
|
+
|
|
175
|
+
- **Privacy-preserving DeFi**: Let users trade and transfer without revealing balances
|
|
176
|
+
- **Private payroll**: Pay employees privately on-chain
|
|
177
|
+
- **Confidential treasury**: Manage organizational funds with selective transparency
|
|
178
|
+
- **Private gaming economies**: In-game token transfers without public visibility
|
|
179
|
+
- **Compliant privacy**: Optional selective transparency for regulatory requirements
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 🛠️ Core Operations
|
|
184
|
+
|
|
185
|
+
### Important: Multi-Step Process
|
|
186
|
+
|
|
187
|
+
DOP transactions require 3 steps:
|
|
188
|
+
1. **Gas Estimation** - Calculate transaction cost
|
|
189
|
+
2. **Proof Generation** - Create zero-knowledge proof (30s-2min for transfers/unshield)
|
|
190
|
+
3. **Transaction** - Populate and submit transaction
|
|
191
|
+
|
|
192
|
+
### Shield Tokens (Public → Private)
|
|
14
193
|
|
|
15
194
|
```typescript
|
|
195
|
+
// Step 1: Estimate gas
|
|
196
|
+
const { gasEstimate } = await gasEstimateForEncrypt(/* ... */);
|
|
197
|
+
|
|
198
|
+
// Step 2: Populate transaction
|
|
199
|
+
const txRequest = await populateEncrypt(/* ... */);
|
|
200
|
+
|
|
201
|
+
// Step 3: Send
|
|
202
|
+
await wallet.sendTransaction(txRequest);
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Check Private Balances
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
const balances = getSerializedERC20Balances(
|
|
209
|
+
TXIDVersion.V3_PoseidonMerkle,
|
|
210
|
+
chain,
|
|
211
|
+
walletId
|
|
212
|
+
);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Private Transfer
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
// Step 1: Estimate gas
|
|
219
|
+
const { gasEstimate } = await gasEstimateForUnprovenTransfer(/* ... */);
|
|
220
|
+
|
|
221
|
+
// Step 2: Generate proof (1-2 minutes)
|
|
222
|
+
const { proof, publicInputs } = await generateTransferProofForExplorer(/* ... */);
|
|
223
|
+
|
|
224
|
+
// Step 3: Populate and send
|
|
225
|
+
const txRequest = await populateProvedTransfer(/* ... */);
|
|
226
|
+
await wallet.sendTransaction(txRequest);
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Unshield Tokens (Private → Public)
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
// Step 1: Estimate gas
|
|
233
|
+
const { gasEstimate } = await gasEstimateForUnprovenDecrypt(/* ... */);
|
|
234
|
+
|
|
235
|
+
// Step 2: Generate proof (30s-2min)
|
|
236
|
+
const { proof, publicInputs } = await generateDecryptToOriginProof(/* ... */);
|
|
237
|
+
|
|
238
|
+
// Step 3: Populate and send
|
|
239
|
+
const txRequest = await populateProvedDecrypt(/* ... */);
|
|
240
|
+
await wallet.sendTransaction(txRequest);
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**See [SDK_DOCS.md](./SDK_DOCS.md) for complete working examples.**
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## 🌐 Supported Networks
|
|
248
|
+
|
|
249
|
+
- **Ethereum Mainnet**
|
|
250
|
+
- **Polygon**
|
|
251
|
+
- **BNB Chain**
|
|
252
|
+
- **Arbitrum**
|
|
253
|
+
- **Base**
|
|
254
|
+
|
|
255
|
+
All networks support ERC20, ERC721, and ERC1155 tokens.
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## 📱 React Native Setup
|
|
260
|
+
|
|
261
|
+
### Prerequisites
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
npm install react-native-get-random-values @react-native-async-storage/async-storage
|
|
265
|
+
npm install buffer assert stream-browserify crypto-browserify events
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Entry Point Setup (CRITICAL)
|
|
269
|
+
|
|
270
|
+
**At the very top of index.js or App.js:**
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
// MUST BE FIRST IMPORTS
|
|
16
274
|
import 'react-native-get-random-values';
|
|
17
|
-
import {
|
|
275
|
+
import { Buffer } from 'buffer';
|
|
276
|
+
global.Buffer = global.Buffer || Buffer;
|
|
277
|
+
|
|
278
|
+
// Import DOP shims
|
|
279
|
+
import 'dop-wallet-v6/react-native-shims';
|
|
280
|
+
|
|
281
|
+
// Now your app code
|
|
18
282
|
```
|
|
19
283
|
|
|
20
|
-
|
|
284
|
+
### Basic Setup
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
import { startDopEngine } from 'dop-wallet-v6';
|
|
288
|
+
import MemDOWN from 'memdown';
|
|
289
|
+
|
|
290
|
+
const db = new MemDOWN();
|
|
291
|
+
await startDopEngine(
|
|
292
|
+
'my-rn-app',
|
|
293
|
+
db,
|
|
294
|
+
__DEV__,
|
|
295
|
+
artifactStore,
|
|
296
|
+
true, // useNativeArtifacts for React Native
|
|
297
|
+
false,
|
|
298
|
+
__DEV__
|
|
299
|
+
);
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### What Works Out of the Box
|
|
303
|
+
|
|
304
|
+
- ✅ Shield tokens
|
|
305
|
+
- ✅ Check balances
|
|
306
|
+
- ✅ Wallet management
|
|
307
|
+
- ❌ Private transfers (needs Rapidsnark)
|
|
308
|
+
- ❌ Unshield (needs Rapidsnark)
|
|
309
|
+
|
|
310
|
+
**📖 Complete React Native Guide**: See React Native section in [SDK_DOCS.md](./SDK_DOCS.md)
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## 🔐 Security
|
|
315
|
+
|
|
316
|
+
- **Zero-Knowledge Proofs**: Transactions are cryptographically private
|
|
317
|
+
- **Client-Side Keys**: Private keys never leave user's device
|
|
318
|
+
- **Open Source**: Fully auditable codebase
|
|
319
|
+
- **BIP39 Mnemonics**: Standard 12/24-word recovery phrases
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## 🤝 Contributing
|
|
324
|
+
|
|
325
|
+
Contributions are welcome! Please:
|
|
326
|
+
|
|
327
|
+
1. Fork the repository
|
|
328
|
+
2. Create a feature branch
|
|
329
|
+
3. Make your changes with tests
|
|
330
|
+
4. Submit a pull request
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## 📄 License
|
|
335
|
+
|
|
336
|
+
MIT License - see [LICENSE](LICENSE) file for details
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## 🆘 Support
|
|
341
|
+
|
|
342
|
+
- **Documentation**: [SDK_DOCS.md](./SDK_DOCS.md)
|
|
343
|
+
- **Issues**: [GitHub Issues](https://github.com/VAR-META-Tech/new-dop-wallet-v3/issues)
|
|
344
|
+
- **Website**: [https://www.dop.org](https://www.dop.org)
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## 🏗️ Architecture
|
|
349
|
+
|
|
350
|
+
```
|
|
351
|
+
Application
|
|
352
|
+
↓
|
|
353
|
+
DOP Wallet SDK
|
|
354
|
+
↓
|
|
355
|
+
├─ DOP Engine (core logic)
|
|
356
|
+
├─ Merkletree Sync (blockchain scanning)
|
|
357
|
+
├─ Proof Generation
|
|
358
|
+
│ ├─ SnarkJS (Node.js/Browser)
|
|
359
|
+
│ └─ Rapidsnark (React Native - custom setup required)
|
|
360
|
+
└─ Blockchain Interface (ethers.js)
|
|
361
|
+
↓
|
|
362
|
+
Ethereum, Polygon, BNB Chain, Arbitrum, Base
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## 📊 Status
|
|
368
|
+
|
|
369
|
+
**Version**: 1.3.32
|
|
370
|
+
**Status**: Production Ready ✅
|
|
371
|
+
**Last Updated**: December 7, 2025
|
|
372
|
+
|
|
373
|
+
**Recent Updates:**
|
|
374
|
+
- ✅ Comprehensive SDK documentation rewrite
|
|
375
|
+
- ✅ API verified against working test files
|
|
376
|
+
- ✅ Complete workflows with real code examples
|
|
377
|
+
- ✅ React Native integration guide
|
|
21
378
|
|
|
22
|
-
|
|
379
|
+
---
|
|
23
380
|
|
|
381
|
+
**Built by the DOP community**
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
export * from './artifacts';
|
|
2
2
|
export * from './init';
|
|
3
3
|
export * from './react-native-init';
|
|
4
|
+
export * from './react-native-prover-setup';
|
|
4
5
|
export * from './engine';
|
|
5
6
|
export * from './load-provider';
|
|
6
7
|
export * from './merkletree';
|
|
7
8
|
export * from './prover';
|
|
8
9
|
export * from './providers';
|
|
9
10
|
export * from './encrypts';
|
|
11
|
+
export * from '../crypto/react-native-crypto-provider';
|
|
12
|
+
export * from '../crypto/react-native-rapidsnark-prover';
|
|
13
|
+
export * from '../crypto/user-rapidsnark-adapter';
|
|
@@ -17,10 +17,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./artifacts"), exports);
|
|
18
18
|
__exportStar(require("./init"), exports);
|
|
19
19
|
__exportStar(require("./react-native-init"), exports);
|
|
20
|
+
__exportStar(require("./react-native-prover-setup"), exports);
|
|
20
21
|
__exportStar(require("./engine"), exports);
|
|
21
22
|
__exportStar(require("./load-provider"), exports);
|
|
22
23
|
__exportStar(require("./merkletree"), exports);
|
|
23
24
|
__exportStar(require("./prover"), exports);
|
|
24
25
|
__exportStar(require("./providers"), exports);
|
|
25
26
|
__exportStar(require("./encrypts"), exports);
|
|
27
|
+
// Export React Native crypto provider utilities
|
|
28
|
+
__exportStar(require("../crypto/react-native-crypto-provider"), exports);
|
|
29
|
+
__exportStar(require("../crypto/react-native-rapidsnark-prover"), exports);
|
|
30
|
+
__exportStar(require("../crypto/user-rapidsnark-adapter"), exports);
|
|
26
31
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/services/dop/core/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,yCAAuB;AACvB,sDAAoC;AACpC,2CAAyB;AACzB,kDAAgC;AAChC,+CAA6B;AAC7B,2CAAyB;AACzB,8CAA4B;AAC5B,6CAA2B","sourcesContent":["export * from './artifacts';\nexport * from './init';\nexport * from './react-native-init';\nexport * from './engine';\nexport * from './load-provider';\nexport * from './merkletree';\nexport * from './prover';\nexport * from './providers';\nexport * from './encrypts';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/services/dop/core/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,yCAAuB;AACvB,sDAAoC;AACpC,8DAA4C;AAC5C,2CAAyB;AACzB,kDAAgC;AAChC,+CAA6B;AAC7B,2CAAyB;AACzB,8CAA4B;AAC5B,6CAA2B;AAE3B,gDAAgD;AAChD,yEAAuD;AACvD,2EAAyD;AACzD,oEAAkD","sourcesContent":["export * from './artifacts';\nexport * from './init';\nexport * from './react-native-init';\nexport * from './react-native-prover-setup';\nexport * from './engine';\nexport * from './load-provider';\nexport * from './merkletree';\nexport * from './prover';\nexport * from './providers';\nexport * from './encrypts';\n\n// Export React Native crypto provider utilities\nexport * from '../crypto/react-native-crypto-provider';\nexport * from '../crypto/react-native-rapidsnark-prover';\nexport * from '../crypto/user-rapidsnark-adapter';\n"]}
|
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
26
|
exports.startDopEngineReactNative = exports.ReactNativeLevelDB = void 0;
|
|
4
27
|
const init_1 = require("./init");
|
|
@@ -593,8 +616,12 @@ const startDopEngineReactNative = async (walletSource, shouldDebug, artifactStor
|
|
|
593
616
|
});
|
|
594
617
|
}
|
|
595
618
|
// Initialize the DOP Engine with the React Native database
|
|
596
|
-
|
|
619
|
+
await (0, init_1.startDopEngine)(walletSource, db, // Cast to any since TypeScript doesn't know about our custom implementation
|
|
597
620
|
shouldDebug, artifactStore, useNativeArtifacts, skipMerkletreeScans, verboseScanLogging);
|
|
621
|
+
// CRITICAL: Auto-setup Rapidsnark prover for React Native
|
|
622
|
+
// This enables proof generation for transfers, shield, and unshield operations
|
|
623
|
+
const { autoSetupProverForReactNative } = await Promise.resolve().then(() => __importStar(require('./react-native-prover-setup')));
|
|
624
|
+
await autoSetupProverForReactNative();
|
|
598
625
|
};
|
|
599
626
|
exports.startDopEngineReactNative = startDopEngineReactNative;
|
|
600
627
|
//# sourceMappingURL=react-native-init.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-native-init.js","sourceRoot":"","sources":["../../../../src/services/dop/core/react-native-init.ts"],"names":[],"mappings":";;;AAcA,iCAAwC;AACxC,kDAAmD;AAEnD,8DAA8D;AAC9D,IAAI,OAAY,CAAC;AACjB,IAAI;IACF,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CAC9B;AAAC,OAAO,KAAK,EAAE;IACd,MAAM,IAAI,KAAK,CACb,2DAA2D;QAC3D,oDAAoD,CACrD,CAAC;CACH;AAED;;;GAGG;AACH,MAAa,kBAAkB;IACrB,EAAE,CAAM;IACR,UAAU,CAAS;IACnB,YAAY,CAAM;IAClB,cAAc,GAAyC,IAAI,CAAC;IAC5D,OAAO,GAAG,KAAK,CAAC;IAExB,YAAY,IAAY;QACtB,IAAI,CAAC,UAAU,GAAG,WAAW,IAAI,EAAE,CAAC;QACpC,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;QAEpB,2DAA2D;QAC3D,IAAI;YACF,+DAA+D;YAC/D,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,2CAA2C,CAAC,CAAC,OAAO,CAAC;SAClF;QAAC,OAAO,KAAK,EAAE;YACd,4EAA4E;YAC5E,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;SAC1B;IACH,CAAC;IAED,wCAAwC;IACxC,KAAK,CAAC,IAAI,CAAC,iBAAuB,EAAE,QAAkC;QACpE,oEAAoE;QACpE,IAAI,EAA2B,CAAC;QAEhC,IAAI,OAAO,iBAAiB,KAAK,UAAU,EAAE;YAC3C,2BAA2B;YAC3B,EAAE,GAAG,iBAAiB,CAAC;SACxB;aAAM,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;YACzC,oCAAoC;YACpC,EAAE,GAAG,QAAQ,CAAC;SACf;aAAM;YACL,oEAAoE;YACpE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;SACxD;QAED,IAAI;YACF,4DAA4D;YAC5D,IAAI,IAAI,CAAC,YAAY,EAAE;gBACrB,IAAI;oBACF,IAAI,aAAa,GAAkB,IAAI,CAAC;oBAExC,oCAAoC;oBACpC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,UAAU,SAAS,CAAC,CAAC;oBAEjF,IAAI,WAAW,EAAE;wBACf,OAAO,CAAC,GAAG,CAAC,4BAA4B,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;wBACzE,yBAAyB;wBACzB,MAAM,MAAM,GAAa,EAAE,CAAC;wBAC5B,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;wBAExC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,IAAI,EAAE;4BACpD,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;yBAChE;wBAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE;4BACjC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,UAAU,UAAU,CAAC,EAAE,CAAC,CAAC;4BAC/E,IAAI,KAAK,EAAE;gCACT,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;6BACpB;iCAAM;gCACL,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,OAAO,KAAK,0BAA0B,CAAC,CAAC;6BAC3E;yBACF;wBAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;4BACvB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;yBAC7D;wBAED,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;wBAChC,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,MAAM,IAAI,KAAK,YAAY,CAAC,aAAa,CAAC,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;qBACvH;yBAAM;wBACL,2BAA2B;wBAC3B,aAAa,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;wBACjE,IAAI,aAAa,EAAE;4BACjB,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,aAAa,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;yBAC7F;qBACF;oBAED,IAAI,aAAa,EAAE;wBACjB,+BAA+B;wBAC/B,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;4BAChF,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;yBAClF;wBAED,IAAI,IAAyB,CAAC;wBAC9B,IAAI;4BACF,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;yBAClC;wBAAC,OAAO,SAAS,EAAE;4BAClB,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;yBAC7G;wBAED,0DAA0D;wBAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAC/B,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,MAAM,yBAAyB,CAAC,CAAC;wBAElE,2BAA2B;wBAC3B,MAAM,UAAU,GAAU,EAAE,CAAC;wBAC7B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;4BAC/C,+DAA+D;4BAC/D,IAAI,aAAa,GAAG,KAAK,CAAC;4BAC1B,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,IAAI,KAAK,EAAE;gCAC3D,MAAM,UAAU,GAAG,KAAyC,CAAC;gCAC7D,IAAI,UAAU,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ,EAAE;oCACzE,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;iCACxD;qCAAM,IAAI,UAAU,CAAC,MAAM,KAAK,YAAY,IAAI,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ,EAAE;oCACpF,aAAa,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;iCACxE;6BACF;4BAED,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;yBAC7D;wBAED,mDAAmD;wBACnD,MAAM,SAAS,GAAG,GAAG,CAAC;wBACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE;4BACrD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;4BACjD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gCAC1C,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAQ,EAAE,EAAE;oCAChC,IAAI,GAAG;wCAAE,MAAM,CAAC,GAAG,CAAC,CAAC;;wCAChB,OAAO,EAAE,CAAC;gCACjB,CAAC,CAAC,CAAC;4BACL,CAAC,CAAC,CAAC;4BACH,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,aAAa,CAAC,CAAC;yBAC1G;wBAED,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;qBACnE;yBAAM;wBACL,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;qBACzE;iBACF;gBAAC,OAAO,iBAAiB,EAAE;oBAC1B,OAAO,CAAC,KAAK,CAAC,iFAAiF,EAAE,iBAAiB,CAAC,CAAC;oBAEpH,uBAAuB;oBACvB,IAAI;wBACF,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;wBACpD,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,UAAU,SAAS,CAAC,CAAC;wBAEhE,8CAA8C;wBAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE;4BAC/B,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,UAAU,UAAU,CAAC,EAAE,CAAC;4BACjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;4BACzD,IAAI,MAAM,EAAE;gCACV,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;6BAC9C;iCAAM;gCACL,MAAM,CAAC,iBAAiB;6BACzB;yBACF;wBACD,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;qBACvD;oBAAC,OAAO,UAAU,EAAE;wBACnB,OAAO,CAAC,IAAI,CAAC,oCAAoC,EAAE,UAAU,CAAC,CAAC;qBAChE;iBACF;aACF;YAED,4BAA4B;YAC5B,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SAClB;QAAC,OAAO,KAAK,EAAE;YACd,EAAE,CAAC,KAAc,CAAC,CAAC;SACpB;IACH,CAAC;IAED,KAAK,CAAC,QAAiC;QACrC,oCAAoC;QACpC,IAAI,IAAI,CAAC,cAAc,EAAE;YACvB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;SAC5B;QAED,sDAAsD;QACtD,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,YAAY,EAAE;YACrC,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;YACtD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,IAAI,CAAC,YAAY,EAAE;gBACjB,+DAA+D;iBAC9D,IAAI,CAAC,GAAG,EAAE;gBACT,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;gBAChD,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC1B,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBACf,OAAO,CAAC,IAAI,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;gBACtD,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC;SACN;aAAM;YACL,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;SACzB;IACH,CAAC;IAED,6EAA6E;IAC7E,KAAK,CAAC,YAAY;QAChB,IAAI,IAAI,CAAC,cAAc,EAAE;YACvB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;SAC5B;QACD,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,YAAY,EAAE;YACrC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;SAC3B;IACH,CAAC;IAED,2FAA2F;IAC3F,KAAK,CAAC,kBAAkB;QACtB,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;QAC5E,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAC9C,CAAC;IAED,GAAG,CAAC,GAAQ,EAAE,KAAU,EAAE,iBAAuB,EAAE,QAAkC;QACnF,0FAA0F;QAC1F,IAAI,EAA2B,CAAC;QAEhC,IAAI,OAAO,iBAAiB,KAAK,UAAU,EAAE;YAC3C,sCAAsC;YACtC,EAAE,GAAG,iBAAiB,CAAC;SACxB;aAAM,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;YACzC,+CAA+C;YAC/C,EAAE,GAAG,QAAQ,CAAC;SACf;aAAM;YACL,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;SACvD;QAED,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,GAAQ,EAAE,EAAE;YACnC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,YAAY,EAAE;gBAC7B,iCAAiC;gBACjC,IAAI,CAAC,oBAAoB,EAAE,CAAC;aAC7B;YACD,EAAE,CAAC,GAAG,CAAC,CAAC;QACV,CAAC,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,GAAQ,EAAE,iBAAuB,EAAE,QAA+C;QACpF,4EAA4E;QAC5E,IAAI,EAAwC,CAAC;QAE7C,IAAI,OAAO,iBAAiB,KAAK,UAAU,EAAE;YAC3C,+BAA+B;YAC/B,EAAE,GAAG,iBAAiB,CAAC;SACxB;aAAM,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;YACzC,wCAAwC;YACxC,EAAE,GAAG,QAAQ,CAAC;SACf;aAAM;YACL,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;SACvD;QAED,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACvB,CAAC;IAED,GAAG,CAAC,GAAQ,EAAE,iBAAuB,EAAE,QAAkC;QACvE,4EAA4E;QAC5E,IAAI,EAA2B,CAAC;QAEhC,IAAI,OAAO,iBAAiB,KAAK,UAAU,EAAE;YAC3C,+BAA+B;YAC/B,EAAE,GAAG,iBAAiB,CAAC;SACxB;aAAM,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;YACzC,wCAAwC;YACxC,EAAE,GAAG,QAAQ,CAAC;SACf;aAAM;YACL,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;SACvD;QAED,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAQ,EAAE,EAAE;YAC5B,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,YAAY,EAAE;gBAC7B,iCAAiC;gBACjC,IAAI,CAAC,oBAAoB,EAAE,CAAC;aAC7B;YACD,EAAE,CAAC,GAAG,CAAC,CAAC;QACV,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAY,EAAE,QAAiC;QACnD,qDAAqD;QACrD,8DAA8D;QAC9D,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;QAE3C,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE;YACf,QAAQ,CAAC,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC;YACzD,OAAO;SACR;QAED,6DAA6D;QAC7D,MAAM,YAAY,GAAU,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC;YAChC,GAAG;YACH,GAAG;YACH,EAAE;YACF,EAAE;YACF,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,GAAG,EAAE;YACvB,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAQ,EAAE,GAAQ,EAAE,EAAE;gBACnC,IAAI,GAAG,EAAE;oBACP,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE;wBAChB,QAAQ,CAAC,GAAG,CAAC,CAAC;oBAChB,CAAC,CAAC,CAAC;oBACH,OAAO;iBACR;gBAED,IAAI,GAAG,KAAK,SAAS,EAAE;oBACrB,+CAA+C;oBAC/C,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE;wBAChB,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE;4BAC7B,QAAQ,EAAE,CAAC;4BACX,OAAO;yBACR;wBAED,uBAAuB;wBACvB,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;wBACpE,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,QAAa,EAAE,EAAE;4BAC1C,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,YAAY,EAAE;gCAClC,IAAI,CAAC,oBAAoB,EAAE,CAAC;6BAC7B;4BACD,QAAQ,CAAC,QAAQ,CAAC,CAAC;wBACrB,CAAC,CAAC,CAAC;oBACL,CAAC,CAAC,CAAC;oBACH,OAAO;iBACR;gBAED,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACvB,WAAW,EAAE,CAAC;YAChB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,WAAW,EAAE,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,oBAA0B,EAAE,iBAAuB,EAAE,QAAkC;QAC3F,oCAAoC;QACpC,kCAAkC;QAClC,8BAA8B;QAC9B,uCAAuC;QAEvC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE;YAC1B,gEAAgE;YAChE,OAAO,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;SACxB;QAED,wCAAwC;QACxC,MAAM,UAAU,GAAG,oBAAoB,CAAC;QACxC,IAAI,EAA2B,CAAC;QAEhC,IAAI,OAAO,iBAAiB,KAAK,UAAU,EAAE;YAC3C,wCAAwC;YACxC,EAAE,GAAG,iBAAiB,CAAC;SACxB;aAAM,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;YACzC,mDAAmD;YACnD,EAAE,GAAG,QAAQ,CAAC;SACf;aAAM;YACL,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;SACzD;QAED,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,GAAQ,EAAE,EAAE;YACrC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,YAAY,EAAE;gBAC7B,iCAAiC;gBACjC,IAAI,CAAC,oBAAoB,EAAE,CAAC;aAC7B;YACD,EAAE,CAAC,GAAG,CAAC,CAAC;QACV,CAAC,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,OAAa;QACpB,+DAA+D;QAC/D,OAAO,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAEO,oBAAoB;QAC1B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,yBAAyB;QACzB,IAAI,IAAI,CAAC,cAAc,EAAE;YACvB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;SACnC;QAED,qFAAqF;QACrF,iFAAiF;QACjF,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YACpC,IAAI,IAAI,CAAC,OAAO,EAAE;gBAChB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;gBACrB,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBACvC,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC;oBAC3E,yDAAyD;gBAC3D,CAAC,CAAC,CAAC;aACJ;QACH,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,2BAA2B;IACxC,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO;QAE/B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,IAAI;YACF,MAAM,IAAI,GAAwB,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;YAEpC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,MAAM,WAAW,GAAG,GAAG,EAAE;oBACvB,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAQ,EAAE,GAAQ,EAAE,KAAU,EAAE,EAAE;wBAC/C,IAAI,GAAG,EAAE;4BACP,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;4BAChC,OAAO;yBACR;wBAED,IAAI,GAAG,KAAK,SAAS,EAAE;4BACrB,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;4BAC9B,OAAO;yBACR;wBAED,UAAU,IAAI,CAAC,CAAC;wBAEhB,4EAA4E;wBAC5E,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;4BAC1B,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG;gCACrB,MAAM,EAAE,QAAQ;gCAChB,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;6BAC/B,CAAC;yBACH;6BAAM,IAAI,KAAK,YAAY,UAAU,EAAE;4BACtC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG;gCACrB,MAAM,EAAE,YAAY;gCACpB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;6BAC5C,CAAC;yBACH;6BAAM;4BACL,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,KAAK,CAAC;yBAC9B;wBACD,WAAW,EAAE,CAAC;oBAChB,CAAC,CAAC,CAAC;gBACL,CAAC,CAAC;gBACF,WAAW,EAAE,CAAC;YAChB,CAAC,CAAC,CAAC;YAEH,iBAAiB;YACjB,IAAI,QAAgB,CAAC;YACrB,IAAI;gBACF,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;aACjC;YAAC,OAAO,cAAc,EAAE;gBACvB,MAAM,IAAI,KAAK,CAAC,6BAA6B,cAAc,YAAY,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;aACnI;YAED,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAC7C,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;YAEjD,4EAA4E;YAC5E,2EAA2E;YAC3E,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,0CAA0C;YAExE,IAAI,QAAQ,CAAC,MAAM,GAAG,SAAS,EAAE;gBAC/B,+BAA+B;gBAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;gBAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE;oBACnD,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;iBAC/C;gBAED,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,MAAM,YAAY,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;gBAElF,iDAAiD;gBACjD,IAAI,UAAU,GAAG,EAAE,EAAE;oBACnB,OAAO,CAAC,IAAI,CAAC,8BAA8B,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC;iBACrG;gBAED,+DAA+D;gBAC/D,+CAA+C;gBAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;oBACzC,IAAI;wBACF,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,UAAU,UAAU,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;qBAC7E;oBAAC,OAAO,UAAe,EAAE;wBACxB,6DAA6D;wBAC7D,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE,UAAU,CAAC,CAAC;wBAC5E,IAAI,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,UAAU,EAAE,IAAI,KAAK,EAAE,EAAE;4BACpE,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;4BAC1E,kDAAkD;4BAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;gCAC9B,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,UAAU,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;6BACrF;4BACD,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;yBAC3F;wBACD,MAAM,UAAU,CAAC;qBAClB;iBACF;gBAED,+EAA+E;gBAC/E,MAAM,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAE9C,oEAAoE;gBACpE,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,UAAU,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAEvF,wEAAwE;gBACxE,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBAEpE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBACzC,OAAO,CAAC,GAAG,CAAC,eAAe,UAAU,aAAa,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,eAAe,SAAS,kBAAkB,aAAa,KAAK,CAAC,CAAC;aAC5J;iBAAM;gBACL,6BAA6B;gBAC7B,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;gBAE3D,2EAA2E;gBAC3E,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAE/B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBACzC,OAAO,CAAC,GAAG,CAAC,eAAe,UAAU,aAAa,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,SAAS,kBAAkB,aAAa,KAAK,CAAC,CAAC;aAC/I;SACF;QAAC,OAAO,KAAU,EAAE;YACnB,OAAO,CAAC,KAAK,CAAC,2CAA2C,EAAE,KAAK,CAAC,CAAC;YAClE,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE;gBAC9B,OAAO,EAAE,KAAK,EAAE,OAAO;gBACvB,IAAI,EAAE,KAAK,EAAE,IAAI;gBACjB,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACpC,CAAC,CAAC;YAEH,iDAAiD;YACjD,IAAI,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE;gBACzE,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;gBACjF,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;aAChC;YAED,gFAAgF;YAChF,wEAAwE;YACxE,uBAAuB;YAEvB,0EAA0E;YAC1E,eAAe;SAChB;IACH,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,cAAsB;QACtD,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO;QAE/B,IAAI;YACF,wDAAwD;YACxD,KAAK,IAAI,CAAC,GAAG,cAAc,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE;gBAC5C,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,UAAU,UAAU,CAAC,EAAE,CAAC;gBACjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACzD,IAAI,CAAC,MAAM,EAAE;oBACX,MAAM,CAAC,0BAA0B;iBAClC;gBACD,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;aAC9C;SACF;QAAC,OAAO,YAAY,EAAE;YACrB,OAAO,CAAC,IAAI,CAAC,sCAAsC,EAAE,YAAY,CAAC,CAAC;SACpE;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC7B,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO;QAE/B,IAAI;YACF,wBAAwB;YACxB,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,UAAU,SAAS,CAAC,CAAC;YAEhE,kDAAkD;YAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE;gBAC/B,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,UAAU,UAAU,CAAC,EAAE,CAAC;gBACjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACzD,IAAI,CAAC,MAAM,EAAE;oBACX,MAAM,CAAC,0BAA0B;iBAClC;gBACD,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;aAC9C;SACF;QAAC,OAAO,YAAY,EAAE;YACrB,OAAO,CAAC,IAAI,CAAC,gCAAgC,EAAE,YAAY,CAAC,CAAC;SAC9D;IACH,CAAC;IAED,6DAA6D;IACrD,KAAK,CAAC,iBAAiB;QAC7B,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO;QAE/B,IAAI;YACF,wBAAwB;YACxB,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,UAAU,SAAS,CAAC,CAAC;YAEhE,wCAAwC;YACxC,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAEpD,kDAAkD;YAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE;gBAC/B,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,UAAU,UAAU,CAAC,EAAE,CAAC;gBACjD,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;aAC9D;SACF;QAAC,OAAO,YAAY,EAAE;YACrB,OAAO,CAAC,IAAI,CAAC,+BAA+B,EAAE,YAAY,CAAC,CAAC;SAC7D;IACH,CAAC;CACF;AAzkBD,gDAykBC;AAED;;;;;;;;;;;;GAYG;AACI,MAAM,yBAAyB,GAAG,KAAK,EAC5C,YAAoB,EACpB,WAAoB,EACpB,aAA4B,EAC5B,kBAA2B,EAC3B,mBAA4B,EAC5B,kBAA2B,EAC3B,YAAY,GAAG,eAAe,EACf,EAAE;IACjB,iFAAiF;IACjF,MAAM,EAAE,GAAG,IAAI,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAEhD,8CAA8C;IAC9C,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,EAAE,CAAC,IAAI,CAAC,CAAC,KAAa,EAAE,EAAE;YACxB,IAAI,KAAK;gBAAE,MAAM,CAAC,KAAK,CAAC,CAAC;;gBACpB,OAAO,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0CAA0C;IAC1C,IAAI,WAAW,EAAE;QACf,IAAA,mBAAU,EACR,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,EAAE,CAAC,EACnD,CAAC,GAAmB,EAAE,EAAE;YACtB,IAAI,GAAG,YAAY,KAAK,EAAE;gBACxB,OAAO,CAAC,KAAK,CAAC,sBAAsB,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;aACzD;iBAAM;gBACL,OAAO,CAAC,KAAK,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;aAC5C;QACH,CAAC,CACF,CAAC;KACH;IAED,2DAA2D;IAC3D,OAAO,IAAA,qBAAc,EACnB,YAAY,EACZ,EAAS,EAAE,4EAA4E;IACvF,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,CACnB,CAAC;AACJ,CAAC,CAAC;AA5CW,QAAA,yBAAyB,6BA4CpC","sourcesContent":["/* eslint-disable @typescript-eslint/no-var-requires */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/strict-boolean-expressions */\n/* eslint-disable no-underscore-dangle */\n/* eslint-disable no-console */\n/* eslint-disable no-await-in-loop */\n/* eslint-disable @typescript-eslint/no-floating-promises */\n/* eslint-disable global-require */\n/* eslint-disable no-void */\nimport { ArtifactStore } from '../../artifacts/artifact-store';\nimport { startDopEngine } from './init';\nimport { setLoggers } from '../../../utils/logger';\n\n// Use memdown for React Native database - with error handling\nlet memdown: any;\ntry {\n memdown = require('memdown');\n} catch (error) {\n throw new Error(\n 'memdown dependency is required for React Native support. ' +\n 'Please install it with: npm install memdown@^6.1.1'\n );\n}\n\n/**\n * React Native compatible LevelDB implementation using memdown with AsyncStorage persistence.\n * This provides a persistent database solution that works reliably in React Native environments.\n */\nexport class ReactNativeLevelDB {\n private db: any;\n private storageKey: string;\n private AsyncStorage: any;\n private persistTimeout: ReturnType<typeof setTimeout> | null = null;\n private isDirty = false;\n\n constructor(name: string) {\n this.storageKey = `leveldb_${name}`;\n this.db = memdown();\n \n // Dynamically import AsyncStorage to avoid bundling issues\n try {\n // Try to require AsyncStorage - this will work in React Native\n this.AsyncStorage = require('@react-native-async-storage/async-storage').default;\n } catch (error) {\n // AsyncStorage not available - this is expected in Node.js test environment\n this.AsyncStorage = null;\n }\n }\n\n // Implement AbstractLevelDOWN interface\n async open(callbackOrOptions?: any, callback?: (error?: Error) => void): Promise<void> {\n // Handle both open(callback) and open(options, callback) signatures\n let cb: (error?: Error) => void;\n \n if (typeof callbackOrOptions === 'function') {\n // open(callback) signature\n cb = callbackOrOptions;\n } else if (typeof callback === 'function') {\n // open(options, callback) signature\n cb = callback;\n } else {\n // No callback provided - this shouldn't happen in AbstractLevelDOWN\n throw new Error('No callback provided to open method');\n }\n\n try {\n // Load persisted data from AsyncStorage (only if available)\n if (this.AsyncStorage) {\n try {\n let persistedData: string | null = null;\n \n // Check if data is stored in chunks\n const chunksCount = await this.AsyncStorage.getItem(`${this.storageKey}_chunks`);\n \n if (chunksCount) {\n console.log(`📦 Loading database from ${String(chunksCount)} chunks...`);\n // Reassemble from chunks\n const chunks: string[] = [];\n const count = parseInt(chunksCount, 10);\n \n if (Number.isNaN(count) || count < 0 || count > 1000) {\n throw new Error(`Invalid chunk count: ${String(chunksCount)}`);\n }\n \n for (let i = 0; i < count; i += 1) {\n const chunk = await this.AsyncStorage.getItem(`${this.storageKey}_chunk_${i}`);\n if (chunk) {\n chunks.push(chunk);\n } else {\n console.warn(`⚠️ Missing chunk ${i} of ${count}, data may be incomplete`);\n }\n }\n \n if (chunks.length === 0) {\n throw new Error('No chunks found, but chunk count was set');\n }\n \n persistedData = chunks.join('');\n console.log(`📦 Reassembled ${chunks.length}/${count} chunks (${(persistedData.length / 1024 / 1024).toFixed(2)}MB)`);\n } else {\n // Try to get data directly\n persistedData = await this.AsyncStorage.getItem(this.storageKey);\n if (persistedData) {\n console.log(`📦 Loading database directly (${(persistedData.length / 1024).toFixed(2)}KB)`);\n }\n }\n \n if (persistedData) {\n // Validate JSON before parsing\n if (!persistedData.trim().startsWith('{') || !persistedData.trim().endsWith('}')) {\n throw new Error('Persisted data does not look like valid JSON (missing braces)');\n }\n \n let data: Record<string, any>;\n try {\n data = JSON.parse(persistedData);\n } catch (jsonError) {\n throw new Error(`JSON parse failed: ${jsonError instanceof Error ? jsonError.message : String(jsonError)}`);\n }\n \n // Restore data to memdown instance using batch operations\n const keys = Object.keys(data);\n console.log(`📦 Restoring ${keys.length} entries to database...`);\n \n // Prepare batch operations\n const operations: any[] = [];\n for (const [key, value] of Object.entries(data)) {\n // Restore Buffer/Uint8Array types from base64 with type marker\n let restoredValue = value;\n if (value && typeof value === 'object' && '__type' in value) {\n const typedValue = value as { __type: string; data: string };\n if (typedValue.__type === 'Buffer' && typeof typedValue.data === 'string') {\n restoredValue = Buffer.from(typedValue.data, 'base64');\n } else if (typedValue.__type === 'Uint8Array' && typeof typedValue.data === 'string') {\n restoredValue = new Uint8Array(Buffer.from(typedValue.data, 'base64'));\n }\n }\n \n operations.push({ type: 'put', key, value: restoredValue });\n }\n \n // Restore in batches of 500 for better performance\n const batchSize = 500;\n for (let i = 0; i < operations.length; i += batchSize) {\n const batch = operations.slice(i, i + batchSize);\n await new Promise<void>((resolve, reject) => {\n this.db.batch(batch, (err: any) => {\n if (err) reject(err);\n else resolve();\n });\n });\n console.log(`📦 Restored ${Math.min(i + batchSize, operations.length)}/${operations.length} entries...`);\n }\n \n console.log('✅ Successfully restored database from AsyncStorage');\n } else {\n console.log('ℹ️ No persisted data found, starting with empty database');\n }\n } catch (asyncStorageError) {\n console.error('❌ Failed to load from AsyncStorage, clearing corrupted data and starting fresh:', asyncStorageError);\n \n // Clear corrupted data\n try {\n await this.AsyncStorage.removeItem(this.storageKey);\n await this.AsyncStorage.removeItem(`${this.storageKey}_chunks`);\n \n // Try to remove chunks (up to 100 chunks max)\n for (let i = 0; i < 100; i += 1) {\n const chunkKey = `${this.storageKey}_chunk_${i}`;\n const exists = await this.AsyncStorage.getItem(chunkKey);\n if (exists) {\n await this.AsyncStorage.removeItem(chunkKey);\n } else {\n break; // No more chunks\n }\n }\n console.log('🧹 Cleared corrupted AsyncStorage data');\n } catch (clearError) {\n console.warn('⚠️ Failed to clear corrupted data:', clearError);\n }\n }\n }\n \n // Open the memdown database\n this.db.open(cb);\n } catch (error) {\n cb(error as Error);\n }\n }\n\n close(callback: (error?: Error) => void): void {\n // Clear pending persistence timeout\n if (this.persistTimeout) {\n clearTimeout(this.persistTimeout);\n this.persistTimeout = null;\n }\n \n // Force immediate persistence before closing if dirty\n if (this.isDirty && this.AsyncStorage) {\n console.log('💾 Persisting database before close...');\n this.isDirty = false;\n this._persistData()\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n .then(() => {\n console.log('✅ Database persisted, closing...');\n this.db.close(callback);\n })\n .catch((error) => {\n console.warn('⚠️ Failed to persist on close:', error);\n this.db.close(callback);\n });\n } else {\n this.db.close(callback);\n }\n }\n\n // Public method to force immediate persistence (useful after scan completes)\n async forcePersist(): Promise<void> {\n if (this.persistTimeout) {\n clearTimeout(this.persistTimeout);\n this.persistTimeout = null;\n }\n if (this.isDirty && this.AsyncStorage) {\n this.isDirty = false;\n await this._persistData();\n }\n }\n\n // Public method to clear all persisted data (use when recovering from storage full errors)\n async clearPersistedData(): Promise<void> {\n console.log('🧹 Clearing all persisted database data from AsyncStorage...');\n await this._cleanupOldChunks();\n console.log('✅ Cleared all persisted data');\n }\n\n put(key: any, value: any, optionsOrCallback?: any, callback?: (error?: Error) => void): void {\n // Handle both put(key, value, callback) and put(key, value, options, callback) signatures\n let cb: (error?: Error) => void;\n \n if (typeof optionsOrCallback === 'function') {\n // put(key, value, callback) signature\n cb = optionsOrCallback;\n } else if (typeof callback === 'function') {\n // put(key, value, options, callback) signature\n cb = callback;\n } else {\n throw new Error('No callback provided to put method');\n }\n\n this.db.put(key, value, (err: any) => {\n if (!err && this.AsyncStorage) {\n // Schedule throttled persistence\n this._schedulePersistence();\n }\n cb(err);\n });\n }\n\n get(key: any, optionsOrCallback?: any, callback?: (error?: Error, value?: any) => void): void {\n // Handle both get(key, callback) and get(key, options, callback) signatures\n let cb: (error?: Error, value?: any) => void;\n \n if (typeof optionsOrCallback === 'function') {\n // get(key, callback) signature\n cb = optionsOrCallback;\n } else if (typeof callback === 'function') {\n // get(key, options, callback) signature\n cb = callback;\n } else {\n throw new Error('No callback provided to get method');\n }\n\n this.db.get(key, cb);\n }\n\n del(key: any, optionsOrCallback?: any, callback?: (error?: Error) => void): void {\n // Handle both del(key, callback) and del(key, options, callback) signatures\n let cb: (error?: Error) => void;\n \n if (typeof optionsOrCallback === 'function') {\n // del(key, callback) signature\n cb = optionsOrCallback;\n } else if (typeof callback === 'function') {\n // del(key, options, callback) signature\n cb = callback;\n } else {\n throw new Error('No callback provided to del method');\n }\n\n this.db.del(key, (err: any) => {\n if (!err && this.AsyncStorage) {\n // Schedule throttled persistence\n this._schedulePersistence();\n }\n cb(err);\n });\n }\n\n clear(options: any, callback: (error?: Error) => void): void {\n // Handle clear operation for deleting ranges of keys\n // This is required by dop-engine-v3's clearNamespace function\n const { gte, lte, gt, lt } = options || {};\n \n if (!gte && !gt) {\n callback(new Error('clear() requires gte or gt option'));\n return;\n }\n\n // Use iterator to find all keys in the range and delete them\n const keysToDelete: any[] = [];\n const iterator = this.db.iterator({\n gte,\n lte,\n gt,\n lt,\n keys: true,\n values: false,\n });\n\n const processNext = () => {\n iterator.next((err: any, key: any) => {\n if (err) {\n iterator.end(() => {\n callback(err);\n });\n return;\n }\n\n if (key === undefined) {\n // No more keys - now delete all collected keys\n iterator.end(() => {\n if (keysToDelete.length === 0) {\n callback();\n return;\n }\n\n // Delete keys in batch\n const operations = keysToDelete.map(k => ({ type: 'del', key: k }));\n this.db.batch(operations, (batchErr: any) => {\n if (!batchErr && this.AsyncStorage) {\n this._schedulePersistence();\n }\n callback(batchErr);\n });\n });\n return;\n }\n\n keysToDelete.push(key);\n processNext();\n });\n };\n\n processNext();\n }\n\n batch(operationsOrCallback?: any, optionsOrCallback?: any, callback?: (error?: Error) => void): any {\n // Handle multiple batch signatures:\n // batch() - returns chained batch\n // batch(operations, callback)\n // batch(operations, options, callback)\n \n if (arguments.length === 0) {\n // batch() - return chained batch (not commonly used in LevelUp)\n return this.db.batch();\n }\n\n // Handle batch operations with callback\n const operations = operationsOrCallback;\n let cb: (error?: Error) => void;\n \n if (typeof optionsOrCallback === 'function') {\n // batch(operations, callback) signature\n cb = optionsOrCallback;\n } else if (typeof callback === 'function') {\n // batch(operations, options, callback) signature \n cb = callback;\n } else {\n throw new Error('No callback provided to batch method');\n }\n\n this.db.batch(operations, (err: any) => {\n if (!err && this.AsyncStorage) {\n // Schedule throttled persistence\n this._schedulePersistence();\n }\n cb(err);\n });\n }\n\n iterator(options?: any): any {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return this.db.iterator(options);\n }\n\n private _schedulePersistence(): void {\n this.isDirty = true;\n \n // Clear existing timeout\n if (this.persistTimeout) {\n clearTimeout(this.persistTimeout);\n }\n \n // Schedule persistence with longer throttling during heavy writes (every 30 seconds)\n // This dramatically improves scan performance by reducing serialization overhead\n this.persistTimeout = setTimeout(() => {\n if (this.isDirty) {\n this.isDirty = false;\n void this._persistData().catch((error) => {\n console.error('⚠️ Scheduled persistence failed:', error?.message || error);\n // Don't log full stack trace to avoid cluttering console\n });\n }\n }, 30000); // Increased from 5s to 30s\n }\n\n private async _persistData(): Promise<void> {\n if (!this.AsyncStorage) return;\n\n const startTime = Date.now();\n let entryCount = 0;\n\n try {\n const data: Record<string, any> = {};\n const iterator = this.db.iterator();\n \n await new Promise<void>((resolve, reject) => {\n const processNext = () => {\n iterator.next((err: any, key: any, value: any) => {\n if (err) {\n iterator.end(() => reject(err));\n return;\n }\n \n if (key === undefined) {\n iterator.end(() => resolve());\n return;\n }\n \n entryCount += 1;\n \n // Preserve Buffer/Uint8Array types by converting to base64 with type marker\n if (Buffer.isBuffer(value)) {\n data[key.toString()] = {\n __type: 'Buffer',\n data: value.toString('base64'),\n };\n } else if (value instanceof Uint8Array) {\n data[key.toString()] = {\n __type: 'Uint8Array',\n data: Buffer.from(value).toString('base64'),\n };\n } else {\n data[key.toString()] = value;\n }\n processNext();\n });\n };\n processNext();\n });\n\n // Serialize data\n let jsonData: string;\n try {\n jsonData = JSON.stringify(data);\n } catch (stringifyError) {\n throw new Error(`Failed to stringify data: ${stringifyError instanceof Error ? stringifyError.message : String(stringifyError)}`);\n }\n \n const serializeTime = Date.now() - startTime;\n const dataSizeMB = jsonData.length / 1024 / 1024;\n \n // React Native AsyncStorage has a 6MB per-item limit and total quota limits\n // Use 500KB chunks to stay well within limits and avoid SQLITE_FULL errors\n const chunkSize = 512 * 1024; // 500KB chunks (conservative for Android)\n \n if (jsonData.length > chunkSize) {\n // Split large data into chunks\n const chunks: string[] = [];\n for (let i = 0; i < jsonData.length; i += chunkSize) {\n chunks.push(jsonData.slice(i, i + chunkSize));\n }\n \n console.log(`💾 Writing ${chunks.length} chunks (${dataSizeMB.toFixed(2)}MB)...`);\n \n // Check if data is too large (warn if over 50MB)\n if (dataSizeMB > 50) {\n console.warn(`⚠️ Database is very large (${dataSizeMB.toFixed(2)}MB). Consider clearing old data.`);\n }\n \n // Write chunks sequentially to avoid overwhelming AsyncStorage\n // Parallel writes can cause SQLITE_FULL errors\n for (let i = 0; i < chunks.length; i += 1) {\n try {\n await this.AsyncStorage.setItem(`${this.storageKey}_chunk_${i}`, chunks[i]);\n } catch (chunkError: any) {\n // If we hit storage quota, clean up partial writes and throw\n console.error(`❌ Failed to write chunk ${i}/${chunks.length}:`, chunkError);\n if (chunkError?.message?.includes('full') || chunkError?.code === 13) {\n console.error('💥 Storage quota exceeded! Cleaning up partial writes...');\n // Only clean up the chunks we just tried to write\n for (let j = 0; j <= i; j += 1) {\n await this.AsyncStorage.removeItem(`${this.storageKey}_chunk_${j}`).catch(() => {});\n }\n throw new Error('AsyncStorage quota exceeded. Please clear app data or restart the app.');\n }\n throw chunkError;\n }\n }\n \n // Clean up any extra chunks from previous saves (if we had more chunks before)\n await this._cleanupExtraChunks(chunks.length);\n \n // Only update chunk count after all chunks are written successfully\n await this.AsyncStorage.setItem(`${this.storageKey}_chunks`, chunks.length.toString());\n \n // Remove direct storage if it exists (migrating from direct to chunked)\n await this.AsyncStorage.removeItem(this.storageKey).catch(() => {});\n \n const totalTime = Date.now() - startTime;\n console.log(`✅ Persisted ${entryCount} entries (${dataSizeMB.toFixed(2)}MB in ${chunks.length} chunks) in ${totalTime}ms (serialize: ${serializeTime}ms)`);\n } else {\n // Small data, store directly\n await this.AsyncStorage.setItem(this.storageKey, jsonData);\n \n // Clean up chunked storage if it exists (migrating from chunked to direct)\n await this._cleanupAllChunks();\n \n const totalTime = Date.now() - startTime;\n console.log(`✅ Persisted ${entryCount} entries (${(jsonData.length / 1024).toFixed(2)}KB) in ${totalTime}ms (serialize: ${serializeTime}ms)`);\n }\n } catch (error: any) {\n console.error('❌ Failed to persist data to AsyncStorage:', error);\n console.error('Error details:', {\n message: error?.message,\n code: error?.code,\n stack: error?.stack?.split('\\n')[0]\n });\n \n // If quota exceeded, clear everything to recover\n if (error?.message?.includes('quota') || error?.message?.includes('full')) {\n console.error('💥 Storage full! Clearing all AsyncStorage data for recovery...');\n await this._cleanupAllChunks();\n }\n \n // Don't mark as dirty - if persistence fails, we don't want to retry infinitely\n // The data is still in memory (memdown) so the app can continue working\n // this.isDirty = true;\n \n // Don't throw - this allows the app to continue even if persistence fails\n // throw error;\n }\n }\n\n private async _cleanupExtraChunks(keepChunkCount: number): Promise<void> {\n if (!this.AsyncStorage) return;\n \n try {\n // Remove chunks beyond the new count (cleanup old data)\n for (let i = keepChunkCount; i < 200; i += 1) {\n const chunkKey = `${this.storageKey}_chunk_${i}`;\n const exists = await this.AsyncStorage.getItem(chunkKey);\n if (!exists) {\n break; // No more chunks to clean\n }\n await this.AsyncStorage.removeItem(chunkKey);\n }\n } catch (cleanupError) {\n console.warn('⚠️ Error during extra chunk cleanup:', cleanupError);\n }\n }\n\n private async _cleanupAllChunks(): Promise<void> {\n if (!this.AsyncStorage) return;\n \n try {\n // Remove chunk metadata\n await this.AsyncStorage.removeItem(`${this.storageKey}_chunks`);\n \n // Remove all chunk entries (try up to 200 chunks)\n for (let i = 0; i < 200; i += 1) {\n const chunkKey = `${this.storageKey}_chunk_${i}`;\n const exists = await this.AsyncStorage.getItem(chunkKey);\n if (!exists) {\n break; // No more chunks to clean\n }\n await this.AsyncStorage.removeItem(chunkKey);\n }\n } catch (cleanupError) {\n console.warn('⚠️ Error during chunk cleanup:', cleanupError);\n }\n }\n\n // Keep old method for clearing persisted data (full cleanup)\n private async _cleanupOldChunks(): Promise<void> {\n if (!this.AsyncStorage) return;\n \n try {\n // Remove chunk metadata\n await this.AsyncStorage.removeItem(`${this.storageKey}_chunks`);\n \n // Remove old direct storage (if exists)\n await this.AsyncStorage.removeItem(this.storageKey);\n \n // Remove all chunk entries (try up to 200 chunks)\n for (let i = 0; i < 200; i += 1) {\n const chunkKey = `${this.storageKey}_chunk_${i}`;\n await this.AsyncStorage.removeItem(chunkKey).catch(() => {});\n }\n } catch (cleanupError) {\n console.warn('⚠️ Error during full cleanup:', cleanupError);\n }\n }\n}\n\n/**\n * Initialize DOP Engine specifically for React Native environments.\n * Uses a custom LevelDB implementation that persists data to AsyncStorage.\n * This provides full database persistence while being compatible with React Native.\n * \n * @param walletSource - Name for your wallet implementation (max 16 chars, lowercase)\n * @param shouldDebug - Whether to forward Engine debug logs to console\n * @param artifactStore - Persistent store for downloading large artifact files\n * @param useNativeArtifacts - Whether to download native C++ artifacts (should be TRUE for mobile)\n * @param skipMerkletreeScans - Whether to skip merkletree syncs and private balance scans\n * @param verboseScanLogging - Enable verbose logging for scanning operations\n * @param databaseName - Name for the database (used as prefix in AsyncStorage)\n */\nexport const startDopEngineReactNative = async (\n walletSource: string,\n shouldDebug: boolean,\n artifactStore: ArtifactStore,\n useNativeArtifacts: boolean,\n skipMerkletreeScans: boolean,\n verboseScanLogging: boolean,\n databaseName = 'dop-wallet-db'\n): Promise<void> => {\n // Create React Native compatible database instance with AsyncStorage persistence\n const db = new ReactNativeLevelDB(databaseName);\n \n // Ensure database is opened before proceeding\n await new Promise<void>((resolve, reject) => {\n db.open((error?: Error) => {\n if (error) reject(error);\n else resolve();\n });\n });\n\n // Set up console logging for React Native\n if (shouldDebug) {\n setLoggers(\n (msg: string) => console.log(`[DOP Wallet] ${msg}`),\n (err: Error | string) => {\n if (err instanceof Error) {\n console.error(`[DOP Wallet Error] ${err.message}`, err);\n } else {\n console.error(`[DOP Wallet Error] ${err}`);\n }\n }\n );\n }\n\n // Initialize the DOP Engine with the React Native database\n return startDopEngine(\n walletSource,\n db as any, // Cast to any since TypeScript doesn't know about our custom implementation\n shouldDebug,\n artifactStore,\n useNativeArtifacts,\n skipMerkletreeScans,\n verboseScanLogging\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"react-native-init.js","sourceRoot":"","sources":["../../../../src/services/dop/core/react-native-init.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-var-requires */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/strict-boolean-expressions */\n/* eslint-disable no-underscore-dangle */\n/* eslint-disable no-console */\n/* eslint-disable no-await-in-loop */\n/* eslint-disable @typescript-eslint/no-floating-promises */\n/* eslint-disable global-require */\n/* eslint-disable no-void */\nimport { ArtifactStore } from '../../artifacts/artifact-store';\nimport { startDopEngine } from './init';\nimport { setLoggers } from '../../../utils/logger';\n\n// Use memdown for React Native database - with error handling\nlet memdown: any;\ntry {\n memdown = require('memdown');\n} catch (error) {\n throw new Error(\n 'memdown dependency is required for React Native support. ' +\n 'Please install it with: npm install memdown@^6.1.1'\n );\n}\n\n/**\n * React Native compatible LevelDB implementation using memdown with AsyncStorage persistence.\n * This provides a persistent database solution that works reliably in React Native environments.\n */\nexport class ReactNativeLevelDB {\n private db: any;\n private storageKey: string;\n private AsyncStorage: any;\n private persistTimeout: ReturnType<typeof setTimeout> | null = null;\n private isDirty = false;\n\n constructor(name: string) {\n this.storageKey = `leveldb_${name}`;\n this.db = memdown();\n \n // Dynamically import AsyncStorage to avoid bundling issues\n try {\n // Try to require AsyncStorage - this will work in React Native\n this.AsyncStorage = require('@react-native-async-storage/async-storage').default;\n } catch (error) {\n // AsyncStorage not available - this is expected in Node.js test environment\n this.AsyncStorage = null;\n }\n }\n\n // Implement AbstractLevelDOWN interface\n async open(callbackOrOptions?: any, callback?: (error?: Error) => void): Promise<void> {\n // Handle both open(callback) and open(options, callback) signatures\n let cb: (error?: Error) => void;\n \n if (typeof callbackOrOptions === 'function') {\n // open(callback) signature\n cb = callbackOrOptions;\n } else if (typeof callback === 'function') {\n // open(options, callback) signature\n cb = callback;\n } else {\n // No callback provided - this shouldn't happen in AbstractLevelDOWN\n throw new Error('No callback provided to open method');\n }\n\n try {\n // Load persisted data from AsyncStorage (only if available)\n if (this.AsyncStorage) {\n try {\n let persistedData: string | null = null;\n \n // Check if data is stored in chunks\n const chunksCount = await this.AsyncStorage.getItem(`${this.storageKey}_chunks`);\n \n if (chunksCount) {\n console.log(`📦 Loading database from ${String(chunksCount)} chunks...`);\n // Reassemble from chunks\n const chunks: string[] = [];\n const count = parseInt(chunksCount, 10);\n \n if (Number.isNaN(count) || count < 0 || count > 1000) {\n throw new Error(`Invalid chunk count: ${String(chunksCount)}`);\n }\n \n for (let i = 0; i < count; i += 1) {\n const chunk = await this.AsyncStorage.getItem(`${this.storageKey}_chunk_${i}`);\n if (chunk) {\n chunks.push(chunk);\n } else {\n console.warn(`⚠️ Missing chunk ${i} of ${count}, data may be incomplete`);\n }\n }\n \n if (chunks.length === 0) {\n throw new Error('No chunks found, but chunk count was set');\n }\n \n persistedData = chunks.join('');\n console.log(`📦 Reassembled ${chunks.length}/${count} chunks (${(persistedData.length / 1024 / 1024).toFixed(2)}MB)`);\n } else {\n // Try to get data directly\n persistedData = await this.AsyncStorage.getItem(this.storageKey);\n if (persistedData) {\n console.log(`📦 Loading database directly (${(persistedData.length / 1024).toFixed(2)}KB)`);\n }\n }\n \n if (persistedData) {\n // Validate JSON before parsing\n if (!persistedData.trim().startsWith('{') || !persistedData.trim().endsWith('}')) {\n throw new Error('Persisted data does not look like valid JSON (missing braces)');\n }\n \n let data: Record<string, any>;\n try {\n data = JSON.parse(persistedData);\n } catch (jsonError) {\n throw new Error(`JSON parse failed: ${jsonError instanceof Error ? jsonError.message : String(jsonError)}`);\n }\n \n // Restore data to memdown instance using batch operations\n const keys = Object.keys(data);\n console.log(`📦 Restoring ${keys.length} entries to database...`);\n \n // Prepare batch operations\n const operations: any[] = [];\n for (const [key, value] of Object.entries(data)) {\n // Restore Buffer/Uint8Array types from base64 with type marker\n let restoredValue = value;\n if (value && typeof value === 'object' && '__type' in value) {\n const typedValue = value as { __type: string; data: string };\n if (typedValue.__type === 'Buffer' && typeof typedValue.data === 'string') {\n restoredValue = Buffer.from(typedValue.data, 'base64');\n } else if (typedValue.__type === 'Uint8Array' && typeof typedValue.data === 'string') {\n restoredValue = new Uint8Array(Buffer.from(typedValue.data, 'base64'));\n }\n }\n \n operations.push({ type: 'put', key, value: restoredValue });\n }\n \n // Restore in batches of 500 for better performance\n const batchSize = 500;\n for (let i = 0; i < operations.length; i += batchSize) {\n const batch = operations.slice(i, i + batchSize);\n await new Promise<void>((resolve, reject) => {\n this.db.batch(batch, (err: any) => {\n if (err) reject(err);\n else resolve();\n });\n });\n console.log(`📦 Restored ${Math.min(i + batchSize, operations.length)}/${operations.length} entries...`);\n }\n \n console.log('✅ Successfully restored database from AsyncStorage');\n } else {\n console.log('ℹ️ No persisted data found, starting with empty database');\n }\n } catch (asyncStorageError) {\n console.error('❌ Failed to load from AsyncStorage, clearing corrupted data and starting fresh:', asyncStorageError);\n \n // Clear corrupted data\n try {\n await this.AsyncStorage.removeItem(this.storageKey);\n await this.AsyncStorage.removeItem(`${this.storageKey}_chunks`);\n \n // Try to remove chunks (up to 100 chunks max)\n for (let i = 0; i < 100; i += 1) {\n const chunkKey = `${this.storageKey}_chunk_${i}`;\n const exists = await this.AsyncStorage.getItem(chunkKey);\n if (exists) {\n await this.AsyncStorage.removeItem(chunkKey);\n } else {\n break; // No more chunks\n }\n }\n console.log('🧹 Cleared corrupted AsyncStorage data');\n } catch (clearError) {\n console.warn('⚠️ Failed to clear corrupted data:', clearError);\n }\n }\n }\n \n // Open the memdown database\n this.db.open(cb);\n } catch (error) {\n cb(error as Error);\n }\n }\n\n close(callback: (error?: Error) => void): void {\n // Clear pending persistence timeout\n if (this.persistTimeout) {\n clearTimeout(this.persistTimeout);\n this.persistTimeout = null;\n }\n \n // Force immediate persistence before closing if dirty\n if (this.isDirty && this.AsyncStorage) {\n console.log('💾 Persisting database before close...');\n this.isDirty = false;\n this._persistData()\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n .then(() => {\n console.log('✅ Database persisted, closing...');\n this.db.close(callback);\n })\n .catch((error) => {\n console.warn('⚠️ Failed to persist on close:', error);\n this.db.close(callback);\n });\n } else {\n this.db.close(callback);\n }\n }\n\n // Public method to force immediate persistence (useful after scan completes)\n async forcePersist(): Promise<void> {\n if (this.persistTimeout) {\n clearTimeout(this.persistTimeout);\n this.persistTimeout = null;\n }\n if (this.isDirty && this.AsyncStorage) {\n this.isDirty = false;\n await this._persistData();\n }\n }\n\n // Public method to clear all persisted data (use when recovering from storage full errors)\n async clearPersistedData(): Promise<void> {\n console.log('🧹 Clearing all persisted database data from AsyncStorage...');\n await this._cleanupOldChunks();\n console.log('✅ Cleared all persisted data');\n }\n\n put(key: any, value: any, optionsOrCallback?: any, callback?: (error?: Error) => void): void {\n // Handle both put(key, value, callback) and put(key, value, options, callback) signatures\n let cb: (error?: Error) => void;\n \n if (typeof optionsOrCallback === 'function') {\n // put(key, value, callback) signature\n cb = optionsOrCallback;\n } else if (typeof callback === 'function') {\n // put(key, value, options, callback) signature\n cb = callback;\n } else {\n throw new Error('No callback provided to put method');\n }\n\n this.db.put(key, value, (err: any) => {\n if (!err && this.AsyncStorage) {\n // Schedule throttled persistence\n this._schedulePersistence();\n }\n cb(err);\n });\n }\n\n get(key: any, optionsOrCallback?: any, callback?: (error?: Error, value?: any) => void): void {\n // Handle both get(key, callback) and get(key, options, callback) signatures\n let cb: (error?: Error, value?: any) => void;\n \n if (typeof optionsOrCallback === 'function') {\n // get(key, callback) signature\n cb = optionsOrCallback;\n } else if (typeof callback === 'function') {\n // get(key, options, callback) signature\n cb = callback;\n } else {\n throw new Error('No callback provided to get method');\n }\n\n this.db.get(key, cb);\n }\n\n del(key: any, optionsOrCallback?: any, callback?: (error?: Error) => void): void {\n // Handle both del(key, callback) and del(key, options, callback) signatures\n let cb: (error?: Error) => void;\n \n if (typeof optionsOrCallback === 'function') {\n // del(key, callback) signature\n cb = optionsOrCallback;\n } else if (typeof callback === 'function') {\n // del(key, options, callback) signature\n cb = callback;\n } else {\n throw new Error('No callback provided to del method');\n }\n\n this.db.del(key, (err: any) => {\n if (!err && this.AsyncStorage) {\n // Schedule throttled persistence\n this._schedulePersistence();\n }\n cb(err);\n });\n }\n\n clear(options: any, callback: (error?: Error) => void): void {\n // Handle clear operation for deleting ranges of keys\n // This is required by dop-engine-v3's clearNamespace function\n const { gte, lte, gt, lt } = options || {};\n \n if (!gte && !gt) {\n callback(new Error('clear() requires gte or gt option'));\n return;\n }\n\n // Use iterator to find all keys in the range and delete them\n const keysToDelete: any[] = [];\n const iterator = this.db.iterator({\n gte,\n lte,\n gt,\n lt,\n keys: true,\n values: false,\n });\n\n const processNext = () => {\n iterator.next((err: any, key: any) => {\n if (err) {\n iterator.end(() => {\n callback(err);\n });\n return;\n }\n\n if (key === undefined) {\n // No more keys - now delete all collected keys\n iterator.end(() => {\n if (keysToDelete.length === 0) {\n callback();\n return;\n }\n\n // Delete keys in batch\n const operations = keysToDelete.map(k => ({ type: 'del', key: k }));\n this.db.batch(operations, (batchErr: any) => {\n if (!batchErr && this.AsyncStorage) {\n this._schedulePersistence();\n }\n callback(batchErr);\n });\n });\n return;\n }\n\n keysToDelete.push(key);\n processNext();\n });\n };\n\n processNext();\n }\n\n batch(operationsOrCallback?: any, optionsOrCallback?: any, callback?: (error?: Error) => void): any {\n // Handle multiple batch signatures:\n // batch() - returns chained batch\n // batch(operations, callback)\n // batch(operations, options, callback)\n \n if (arguments.length === 0) {\n // batch() - return chained batch (not commonly used in LevelUp)\n return this.db.batch();\n }\n\n // Handle batch operations with callback\n const operations = operationsOrCallback;\n let cb: (error?: Error) => void;\n \n if (typeof optionsOrCallback === 'function') {\n // batch(operations, callback) signature\n cb = optionsOrCallback;\n } else if (typeof callback === 'function') {\n // batch(operations, options, callback) signature \n cb = callback;\n } else {\n throw new Error('No callback provided to batch method');\n }\n\n this.db.batch(operations, (err: any) => {\n if (!err && this.AsyncStorage) {\n // Schedule throttled persistence\n this._schedulePersistence();\n }\n cb(err);\n });\n }\n\n iterator(options?: any): any {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return this.db.iterator(options);\n }\n\n private _schedulePersistence(): void {\n this.isDirty = true;\n \n // Clear existing timeout\n if (this.persistTimeout) {\n clearTimeout(this.persistTimeout);\n }\n \n // Schedule persistence with longer throttling during heavy writes (every 30 seconds)\n // This dramatically improves scan performance by reducing serialization overhead\n this.persistTimeout = setTimeout(() => {\n if (this.isDirty) {\n this.isDirty = false;\n void this._persistData().catch((error) => {\n console.error('⚠️ Scheduled persistence failed:', error?.message || error);\n // Don't log full stack trace to avoid cluttering console\n });\n }\n }, 30000); // Increased from 5s to 30s\n }\n\n private async _persistData(): Promise<void> {\n if (!this.AsyncStorage) return;\n\n const startTime = Date.now();\n let entryCount = 0;\n\n try {\n const data: Record<string, any> = {};\n const iterator = this.db.iterator();\n \n await new Promise<void>((resolve, reject) => {\n const processNext = () => {\n iterator.next((err: any, key: any, value: any) => {\n if (err) {\n iterator.end(() => reject(err));\n return;\n }\n \n if (key === undefined) {\n iterator.end(() => resolve());\n return;\n }\n \n entryCount += 1;\n \n // Preserve Buffer/Uint8Array types by converting to base64 with type marker\n if (Buffer.isBuffer(value)) {\n data[key.toString()] = {\n __type: 'Buffer',\n data: value.toString('base64'),\n };\n } else if (value instanceof Uint8Array) {\n data[key.toString()] = {\n __type: 'Uint8Array',\n data: Buffer.from(value).toString('base64'),\n };\n } else {\n data[key.toString()] = value;\n }\n processNext();\n });\n };\n processNext();\n });\n\n // Serialize data\n let jsonData: string;\n try {\n jsonData = JSON.stringify(data);\n } catch (stringifyError) {\n throw new Error(`Failed to stringify data: ${stringifyError instanceof Error ? stringifyError.message : String(stringifyError)}`);\n }\n \n const serializeTime = Date.now() - startTime;\n const dataSizeMB = jsonData.length / 1024 / 1024;\n \n // React Native AsyncStorage has a 6MB per-item limit and total quota limits\n // Use 500KB chunks to stay well within limits and avoid SQLITE_FULL errors\n const chunkSize = 512 * 1024; // 500KB chunks (conservative for Android)\n \n if (jsonData.length > chunkSize) {\n // Split large data into chunks\n const chunks: string[] = [];\n for (let i = 0; i < jsonData.length; i += chunkSize) {\n chunks.push(jsonData.slice(i, i + chunkSize));\n }\n \n console.log(`💾 Writing ${chunks.length} chunks (${dataSizeMB.toFixed(2)}MB)...`);\n \n // Check if data is too large (warn if over 50MB)\n if (dataSizeMB > 50) {\n console.warn(`⚠️ Database is very large (${dataSizeMB.toFixed(2)}MB). Consider clearing old data.`);\n }\n \n // Write chunks sequentially to avoid overwhelming AsyncStorage\n // Parallel writes can cause SQLITE_FULL errors\n for (let i = 0; i < chunks.length; i += 1) {\n try {\n await this.AsyncStorage.setItem(`${this.storageKey}_chunk_${i}`, chunks[i]);\n } catch (chunkError: any) {\n // If we hit storage quota, clean up partial writes and throw\n console.error(`❌ Failed to write chunk ${i}/${chunks.length}:`, chunkError);\n if (chunkError?.message?.includes('full') || chunkError?.code === 13) {\n console.error('💥 Storage quota exceeded! Cleaning up partial writes...');\n // Only clean up the chunks we just tried to write\n for (let j = 0; j <= i; j += 1) {\n await this.AsyncStorage.removeItem(`${this.storageKey}_chunk_${j}`).catch(() => {});\n }\n throw new Error('AsyncStorage quota exceeded. Please clear app data or restart the app.');\n }\n throw chunkError;\n }\n }\n \n // Clean up any extra chunks from previous saves (if we had more chunks before)\n await this._cleanupExtraChunks(chunks.length);\n \n // Only update chunk count after all chunks are written successfully\n await this.AsyncStorage.setItem(`${this.storageKey}_chunks`, chunks.length.toString());\n \n // Remove direct storage if it exists (migrating from direct to chunked)\n await this.AsyncStorage.removeItem(this.storageKey).catch(() => {});\n \n const totalTime = Date.now() - startTime;\n console.log(`✅ Persisted ${entryCount} entries (${dataSizeMB.toFixed(2)}MB in ${chunks.length} chunks) in ${totalTime}ms (serialize: ${serializeTime}ms)`);\n } else {\n // Small data, store directly\n await this.AsyncStorage.setItem(this.storageKey, jsonData);\n \n // Clean up chunked storage if it exists (migrating from chunked to direct)\n await this._cleanupAllChunks();\n \n const totalTime = Date.now() - startTime;\n console.log(`✅ Persisted ${entryCount} entries (${(jsonData.length / 1024).toFixed(2)}KB) in ${totalTime}ms (serialize: ${serializeTime}ms)`);\n }\n } catch (error: any) {\n console.error('❌ Failed to persist data to AsyncStorage:', error);\n console.error('Error details:', {\n message: error?.message,\n code: error?.code,\n stack: error?.stack?.split('\\n')[0]\n });\n \n // If quota exceeded, clear everything to recover\n if (error?.message?.includes('quota') || error?.message?.includes('full')) {\n console.error('💥 Storage full! Clearing all AsyncStorage data for recovery...');\n await this._cleanupAllChunks();\n }\n \n // Don't mark as dirty - if persistence fails, we don't want to retry infinitely\n // The data is still in memory (memdown) so the app can continue working\n // this.isDirty = true;\n \n // Don't throw - this allows the app to continue even if persistence fails\n // throw error;\n }\n }\n\n private async _cleanupExtraChunks(keepChunkCount: number): Promise<void> {\n if (!this.AsyncStorage) return;\n \n try {\n // Remove chunks beyond the new count (cleanup old data)\n for (let i = keepChunkCount; i < 200; i += 1) {\n const chunkKey = `${this.storageKey}_chunk_${i}`;\n const exists = await this.AsyncStorage.getItem(chunkKey);\n if (!exists) {\n break; // No more chunks to clean\n }\n await this.AsyncStorage.removeItem(chunkKey);\n }\n } catch (cleanupError) {\n console.warn('⚠️ Error during extra chunk cleanup:', cleanupError);\n }\n }\n\n private async _cleanupAllChunks(): Promise<void> {\n if (!this.AsyncStorage) return;\n \n try {\n // Remove chunk metadata\n await this.AsyncStorage.removeItem(`${this.storageKey}_chunks`);\n \n // Remove all chunk entries (try up to 200 chunks)\n for (let i = 0; i < 200; i += 1) {\n const chunkKey = `${this.storageKey}_chunk_${i}`;\n const exists = await this.AsyncStorage.getItem(chunkKey);\n if (!exists) {\n break; // No more chunks to clean\n }\n await this.AsyncStorage.removeItem(chunkKey);\n }\n } catch (cleanupError) {\n console.warn('⚠️ Error during chunk cleanup:', cleanupError);\n }\n }\n\n // Keep old method for clearing persisted data (full cleanup)\n private async _cleanupOldChunks(): Promise<void> {\n if (!this.AsyncStorage) return;\n \n try {\n // Remove chunk metadata\n await this.AsyncStorage.removeItem(`${this.storageKey}_chunks`);\n \n // Remove old direct storage (if exists)\n await this.AsyncStorage.removeItem(this.storageKey);\n \n // Remove all chunk entries (try up to 200 chunks)\n for (let i = 0; i < 200; i += 1) {\n const chunkKey = `${this.storageKey}_chunk_${i}`;\n await this.AsyncStorage.removeItem(chunkKey).catch(() => {});\n }\n } catch (cleanupError) {\n console.warn('⚠️ Error during full cleanup:', cleanupError);\n }\n }\n}\n\n/**\n * Initialize DOP Engine specifically for React Native environments.\n * Uses a custom LevelDB implementation that persists data to AsyncStorage.\n * This provides full database persistence while being compatible with React Native.\n * \n * @param walletSource - Name for your wallet implementation (max 16 chars, lowercase)\n * @param shouldDebug - Whether to forward Engine debug logs to console\n * @param artifactStore - Persistent store for downloading large artifact files\n * @param useNativeArtifacts - Whether to download native C++ artifacts (should be TRUE for mobile)\n * @param skipMerkletreeScans - Whether to skip merkletree syncs and private balance scans\n * @param verboseScanLogging - Enable verbose logging for scanning operations\n * @param databaseName - Name for the database (used as prefix in AsyncStorage)\n */\nexport const startDopEngineReactNative = async (\n walletSource: string,\n shouldDebug: boolean,\n artifactStore: ArtifactStore,\n useNativeArtifacts: boolean,\n skipMerkletreeScans: boolean,\n verboseScanLogging: boolean,\n databaseName = 'dop-wallet-db'\n): Promise<void> => {\n // Create React Native compatible database instance with AsyncStorage persistence\n const db = new ReactNativeLevelDB(databaseName);\n \n // Ensure database is opened before proceeding\n await new Promise<void>((resolve, reject) => {\n db.open((error?: Error) => {\n if (error) reject(error);\n else resolve();\n });\n });\n\n // Set up console logging for React Native\n if (shouldDebug) {\n setLoggers(\n (msg: string) => console.log(`[DOP Wallet] ${msg}`),\n (err: Error | string) => {\n if (err instanceof Error) {\n console.error(`[DOP Wallet Error] ${err.message}`, err);\n } else {\n console.error(`[DOP Wallet Error] ${err}`);\n }\n }\n );\n }\n\n // Initialize the DOP Engine with the React Native database\n await startDopEngine(\n walletSource,\n db as any, // Cast to any since TypeScript doesn't know about our custom implementation\n shouldDebug,\n artifactStore,\n useNativeArtifacts,\n skipMerkletreeScans,\n verboseScanLogging\n );\n \n // CRITICAL: Auto-setup Rapidsnark prover for React Native\n // This enables proof generation for transfers, shield, and unshield operations\n const { autoSetupProverForReactNative } = await import('./react-native-prover-setup');\n await autoSetupProverForReactNative();\n};\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native Prover Setup
|
|
3
|
+
*
|
|
4
|
+
* IMPORTANT: Direct proof generation in React Native is not currently supported by the DOP SDK.
|
|
5
|
+
*
|
|
6
|
+
* The DOP Engine uses SnarkJS internally which requires WebAssembly and Web Workers that
|
|
7
|
+
* are not available in React Native's JavaScriptCore engine.
|
|
8
|
+
*
|
|
9
|
+
* Rapidsnark (@iden3/react-native-rapidsnark) is a native module for mobile proof generation,
|
|
10
|
+
* but it requires a different integration approach that is not yet implemented in dop-engine-v3.
|
|
11
|
+
*
|
|
12
|
+
* WORKAROUNDS:
|
|
13
|
+
* 1. Use a relay service that generates proofs server-side
|
|
14
|
+
* 2. Use encrypted transfers only (which don't require proofs)
|
|
15
|
+
* 3. Wait for DOP to release React Native-compatible proof generation
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Check if proof generation is available in React Native
|
|
19
|
+
* Returns false with helpful error message
|
|
20
|
+
*/
|
|
21
|
+
export declare const checkReactNativeProverSupport: () => Promise<boolean>;
|
|
22
|
+
/**
|
|
23
|
+
* Setup Groth16 prover for React Native
|
|
24
|
+
* Currently logs a warning that this is not yet supported
|
|
25
|
+
*/
|
|
26
|
+
export declare const setupReactNativeProver: () => Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* Auto-setup prover if in React Native environment
|
|
29
|
+
* Currently just checks and warns about lack of support
|
|
30
|
+
*/
|
|
31
|
+
export declare const autoSetupProverForReactNative: () => Promise<void>;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* React Native Prover Setup
|
|
4
|
+
*
|
|
5
|
+
* IMPORTANT: Direct proof generation in React Native is not currently supported by the DOP SDK.
|
|
6
|
+
*
|
|
7
|
+
* The DOP Engine uses SnarkJS internally which requires WebAssembly and Web Workers that
|
|
8
|
+
* are not available in React Native's JavaScriptCore engine.
|
|
9
|
+
*
|
|
10
|
+
* Rapidsnark (@iden3/react-native-rapidsnark) is a native module for mobile proof generation,
|
|
11
|
+
* but it requires a different integration approach that is not yet implemented in dop-engine-v3.
|
|
12
|
+
*
|
|
13
|
+
* WORKAROUNDS:
|
|
14
|
+
* 1. Use a relay service that generates proofs server-side
|
|
15
|
+
* 2. Use encrypted transfers only (which don't require proofs)
|
|
16
|
+
* 3. Wait for DOP to release React Native-compatible proof generation
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.autoSetupProverForReactNative = exports.setupReactNativeProver = exports.checkReactNativeProverSupport = void 0;
|
|
20
|
+
const runtime_1 = require("../util/runtime");
|
|
21
|
+
const react_native_rapidsnark_prover_1 = require("../crypto/react-native-rapidsnark-prover");
|
|
22
|
+
/**
|
|
23
|
+
* Check if proof generation is available in React Native
|
|
24
|
+
* Returns false with helpful error message
|
|
25
|
+
*/
|
|
26
|
+
const checkReactNativeProverSupport = async () => {
|
|
27
|
+
if (!runtime_1.isReactNative) {
|
|
28
|
+
return true; // Not in React Native, no issue
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
// Check if Rapidsnark is available
|
|
32
|
+
const initialized = await (0, react_native_rapidsnark_prover_1.initializeRapidsnark)();
|
|
33
|
+
if (!initialized || !(0, react_native_rapidsnark_prover_1.isRapidsnarkAvailable)()) {
|
|
34
|
+
console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
35
|
+
console.error('⚠️ REACT NATIVE PROOF GENERATION NOT SUPPORTED');
|
|
36
|
+
console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
37
|
+
console.error('');
|
|
38
|
+
console.error('The DOP SDK cannot generate zero-knowledge proofs directly');
|
|
39
|
+
console.error('in React Native because SnarkJS requires WebAssembly and');
|
|
40
|
+
console.error('Web Workers that are not available in JavaScriptCore.');
|
|
41
|
+
console.error('');
|
|
42
|
+
console.error('WORKAROUNDS:');
|
|
43
|
+
console.error('');
|
|
44
|
+
console.error('1. Use Relay Service (Recommended):');
|
|
45
|
+
console.error(' Set up a proof generation relay service that runs');
|
|
46
|
+
console.error(' Node.js and handles proof generation server-side.');
|
|
47
|
+
console.error('');
|
|
48
|
+
console.error('2. Use Encrypted Transfers Only:');
|
|
49
|
+
console.error(' Encrypt tokens to the DOP contract (shield operations)');
|
|
50
|
+
console.error(' without generating proofs for private transfers.');
|
|
51
|
+
console.error('');
|
|
52
|
+
console.error('3. Wait for Native Support:');
|
|
53
|
+
console.error(' DOP is working on React Native-compatible proof');
|
|
54
|
+
console.error(' generation using @iden3/react-native-rapidsnark.');
|
|
55
|
+
console.error('');
|
|
56
|
+
console.error('Operations that require proofs:');
|
|
57
|
+
console.error(' - Private transfers (sendERC20Token)');
|
|
58
|
+
console.error(' - Private NFT transfers');
|
|
59
|
+
console.error(' - Unshield operations (decryptERC20Token)');
|
|
60
|
+
console.error('');
|
|
61
|
+
console.error('Operations that work without proofs:');
|
|
62
|
+
console.error(' - Shield operations (encryptERC20Token)');
|
|
63
|
+
console.error(' - Balance queries');
|
|
64
|
+
console.error(' - Wallet creation');
|
|
65
|
+
console.error(' - Transaction history');
|
|
66
|
+
console.error('');
|
|
67
|
+
console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
// Rapidsnark is available but not yet integrated
|
|
71
|
+
console.warn('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
72
|
+
console.warn('⚠️ RAPIDSNARK DETECTED BUT NOT YET INTEGRATED');
|
|
73
|
+
console.warn('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
74
|
+
console.warn('');
|
|
75
|
+
console.warn('Rapidsnark (@iden3/react-native-rapidsnark) is installed');
|
|
76
|
+
console.warn('but the DOP SDK does not yet support it automatically.');
|
|
77
|
+
console.warn('');
|
|
78
|
+
console.warn('This feature is under development. For now, use one of');
|
|
79
|
+
console.warn('the workarounds mentioned in the documentation.');
|
|
80
|
+
console.warn('');
|
|
81
|
+
console.warn('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error('Error checking React Native prover support:', error);
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
exports.checkReactNativeProverSupport = checkReactNativeProverSupport;
|
|
90
|
+
/**
|
|
91
|
+
* Setup Groth16 prover for React Native
|
|
92
|
+
* Currently logs a warning that this is not yet supported
|
|
93
|
+
*/
|
|
94
|
+
const setupReactNativeProver = async () => {
|
|
95
|
+
if (!runtime_1.isReactNative) {
|
|
96
|
+
return true; // Not in React Native, nothing to do
|
|
97
|
+
}
|
|
98
|
+
return (0, exports.checkReactNativeProverSupport)();
|
|
99
|
+
};
|
|
100
|
+
exports.setupReactNativeProver = setupReactNativeProver;
|
|
101
|
+
/**
|
|
102
|
+
* Auto-setup prover if in React Native environment
|
|
103
|
+
* Currently just checks and warns about lack of support
|
|
104
|
+
*/
|
|
105
|
+
const autoSetupProverForReactNative = async () => {
|
|
106
|
+
if (runtime_1.isReactNative) {
|
|
107
|
+
await (0, exports.setupReactNativeProver)();
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
exports.autoSetupProverForReactNative = autoSetupProverForReactNative;
|
|
111
|
+
//# sourceMappingURL=react-native-prover-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-native-prover-setup.js","sourceRoot":"","sources":["../../../../src/services/dop/core/react-native-prover-setup.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * React Native Prover Setup\n * \n * IMPORTANT: Direct proof generation in React Native is not currently supported by the DOP SDK.\n * \n * The DOP Engine uses SnarkJS internally which requires WebAssembly and Web Workers that\n * are not available in React Native's JavaScriptCore engine.\n * \n * Rapidsnark (@iden3/react-native-rapidsnark) is a native module for mobile proof generation,\n * but it requires a different integration approach that is not yet implemented in dop-engine-v3.\n * \n * WORKAROUNDS:\n * 1. Use a relay service that generates proofs server-side\n * 2. Use encrypted transfers only (which don't require proofs)\n * 3. Wait for DOP to release React Native-compatible proof generation\n */\n\nimport { getProver } from './prover';\nimport { isReactNative } from '../util/runtime';\nimport { initializeRapidsnark, isRapidsnarkAvailable } from '../crypto/react-native-rapidsnark-prover';\n\n/**\n * Check if proof generation is available in React Native\n * Returns false with helpful error message\n */\nexport const checkReactNativeProverSupport = async (): Promise<boolean> => {\n if (!isReactNative) {\n return true; // Not in React Native, no issue\n }\n\n try {\n // Check if Rapidsnark is available\n const initialized = await initializeRapidsnark();\n \n if (!initialized || !isRapidsnarkAvailable()) {\n console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n console.error('⚠️ REACT NATIVE PROOF GENERATION NOT SUPPORTED');\n console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n console.error('');\n console.error('The DOP SDK cannot generate zero-knowledge proofs directly');\n console.error('in React Native because SnarkJS requires WebAssembly and');\n console.error('Web Workers that are not available in JavaScriptCore.');\n console.error('');\n console.error('WORKAROUNDS:');\n console.error('');\n console.error('1. Use Relay Service (Recommended):');\n console.error(' Set up a proof generation relay service that runs');\n console.error(' Node.js and handles proof generation server-side.');\n console.error('');\n console.error('2. Use Encrypted Transfers Only:');\n console.error(' Encrypt tokens to the DOP contract (shield operations)');\n console.error(' without generating proofs for private transfers.');\n console.error('');\n console.error('3. Wait for Native Support:');\n console.error(' DOP is working on React Native-compatible proof');\n console.error(' generation using @iden3/react-native-rapidsnark.');\n console.error('');\n console.error('Operations that require proofs:');\n console.error(' - Private transfers (sendERC20Token)');\n console.error(' - Private NFT transfers');\n console.error(' - Unshield operations (decryptERC20Token)');\n console.error('');\n console.error('Operations that work without proofs:');\n console.error(' - Shield operations (encryptERC20Token)');\n console.error(' - Balance queries');\n console.error(' - Wallet creation');\n console.error(' - Transaction history');\n console.error('');\n console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n \n return false;\n }\n \n // Rapidsnark is available but not yet integrated\n console.warn('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n console.warn('⚠️ RAPIDSNARK DETECTED BUT NOT YET INTEGRATED');\n console.warn('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n console.warn('');\n console.warn('Rapidsnark (@iden3/react-native-rapidsnark) is installed');\n console.warn('but the DOP SDK does not yet support it automatically.');\n console.warn('');\n console.warn('This feature is under development. For now, use one of');\n console.warn('the workarounds mentioned in the documentation.');\n console.warn('');\n console.warn('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n \n return false;\n \n } catch (error) {\n console.error('Error checking React Native prover support:', error);\n return false;\n }\n};\n\n/**\n * Setup Groth16 prover for React Native\n * Currently logs a warning that this is not yet supported\n */\nexport const setupReactNativeProver = async (): Promise<boolean> => {\n if (!isReactNative) {\n return true; // Not in React Native, nothing to do\n }\n\n return checkReactNativeProverSupport();\n};\n\n/**\n * Auto-setup prover if in React Native environment\n * Currently just checks and warns about lack of support\n */\nexport const autoSetupProverForReactNative = async (): Promise<void> => {\n if (isReactNative) {\n await setupReactNativeProver();\n }\n};\n"]}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User-Configurable Rapidsnark Adapter for React Native
|
|
3
|
+
*
|
|
4
|
+
* This module provides a way for React Native developers to configure
|
|
5
|
+
* their own Rapidsnark prover implementation, bypassing SDK limitations.
|
|
6
|
+
*
|
|
7
|
+
* The user is responsible for:
|
|
8
|
+
* 1. Installing @iden3/react-native-rapidsnark
|
|
9
|
+
* 2. Managing circuit files (.zkey files)
|
|
10
|
+
* 3. Implementing witness generation
|
|
11
|
+
* 4. Calling setCustomRapidsnarkProver() after engine initialization
|
|
12
|
+
*/
|
|
13
|
+
import type { FormattedCircuitInputsDop, Proof } from 'dop-engine-v3';
|
|
14
|
+
/**
|
|
15
|
+
* Interface that users must implement for their Rapidsnark prover
|
|
16
|
+
*/
|
|
17
|
+
export interface UserRapidsnarkProver {
|
|
18
|
+
/**
|
|
19
|
+
* Generate a zero-knowledge proof using Rapidsnark
|
|
20
|
+
*
|
|
21
|
+
* @param circuitId - The circuit identifier (e.g., 'dop', 'decrypt', 'nullify')
|
|
22
|
+
* @param zkeyBuffer - The zkey file buffer (or path to zkey file in user's implementation)
|
|
23
|
+
* @param jsonInputs - The circuit inputs as JSON object
|
|
24
|
+
* @param progressCallback - Optional callback for progress updates
|
|
25
|
+
* @returns Promise containing the generated proof
|
|
26
|
+
*/
|
|
27
|
+
generateProof(circuitId: string, zkeyBuffer: Uint8Array, jsonInputs: FormattedCircuitInputsDop, progressCallback?: (progress: number) => void): Promise<Proof>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Helper function to convert Uint8Array to base64 string
|
|
31
|
+
*/
|
|
32
|
+
export declare const uint8ArrayToBase64: (buffer: Uint8Array) => string;
|
|
33
|
+
/**
|
|
34
|
+
* Helper function to save buffer to file system (React Native)
|
|
35
|
+
* Users should implement their own version using react-native-fs or similar
|
|
36
|
+
*/
|
|
37
|
+
export declare const saveBufferToFile: (_buffer: Uint8Array, _filename: string) => Promise<string>;
|
|
38
|
+
/**
|
|
39
|
+
* Set a custom Rapidsnark prover implementation
|
|
40
|
+
*
|
|
41
|
+
* This function allows React Native developers to provide their own
|
|
42
|
+
* Rapidsnark implementation, giving them full control over proof generation.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* import { setCustomRapidsnarkProver } from 'dop-wallet-v6';
|
|
47
|
+
* import { groth16Prove } from '@iden3/react-native-rapidsnark';
|
|
48
|
+
* import RNFS from 'react-native-fs';
|
|
49
|
+
*
|
|
50
|
+
* // Implement your own prover adapter
|
|
51
|
+
* const myRapidsnarkAdapter = {
|
|
52
|
+
* async generateProof(circuitId, zkeyBuffer, jsonInputs, progressCallback) {
|
|
53
|
+
* // 1. Save zkey to file
|
|
54
|
+
* const zkeyPath = `${RNFS.DocumentDirectoryPath}/${circuitId}.zkey`;
|
|
55
|
+
* await RNFS.writeFile(zkeyPath, uint8ArrayToBase64(zkeyBuffer), 'base64');
|
|
56
|
+
*
|
|
57
|
+
* // 2. Generate witness (implement your own witness generation)
|
|
58
|
+
* const witnessBase64 = await generateWitness(circuitId, jsonInputs);
|
|
59
|
+
*
|
|
60
|
+
* // 3. Generate proof with Rapidsnark
|
|
61
|
+
* const rapidsnarkProof = await groth16Prove(zkeyPath, witnessBase64);
|
|
62
|
+
*
|
|
63
|
+
* // 4. Convert to DOP Engine proof format
|
|
64
|
+
* return {
|
|
65
|
+
* pi_a: rapidsnarkProof.proof.a,
|
|
66
|
+
* pi_b: rapidsnarkProof.proof.b,
|
|
67
|
+
* pi_c: rapidsnarkProof.proof.c,
|
|
68
|
+
* publicSignals: rapidsnarkProof.pub_signals
|
|
69
|
+
* };
|
|
70
|
+
* }
|
|
71
|
+
* };
|
|
72
|
+
*
|
|
73
|
+
* // Set it after engine initialization
|
|
74
|
+
* await startDopEngineReactNative(...);
|
|
75
|
+
* setCustomRapidsnarkProver(myRapidsnarkAdapter);
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
/**
|
|
79
|
+
* Circuit ID mapping for DOP Engine
|
|
80
|
+
* These IDs are used internally by DOP Engine's native prover interface
|
|
81
|
+
*/
|
|
82
|
+
export declare const CIRCUIT_IDS: {
|
|
83
|
+
readonly dop: 0;
|
|
84
|
+
readonly decrypt: 1;
|
|
85
|
+
readonly nullify: 2;
|
|
86
|
+
};
|
|
87
|
+
export declare const setCustomRapidsnarkProver: (userProver: UserRapidsnarkProver) => void;
|
|
88
|
+
/**
|
|
89
|
+
* Remove custom prover and revert to default behavior
|
|
90
|
+
*/
|
|
91
|
+
export declare const clearCustomRapidsnarkProver: () => void;
|
|
92
|
+
/**
|
|
93
|
+
* Example implementation template for users to customize
|
|
94
|
+
*
|
|
95
|
+
* This is a reference implementation that users should copy and modify
|
|
96
|
+
* according to their specific needs and file system setup.
|
|
97
|
+
*/
|
|
98
|
+
export declare const createRapidsnarkProverTemplate: () => string;
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* User-Configurable Rapidsnark Adapter for React Native
|
|
4
|
+
*
|
|
5
|
+
* This module provides a way for React Native developers to configure
|
|
6
|
+
* their own Rapidsnark prover implementation, bypassing SDK limitations.
|
|
7
|
+
*
|
|
8
|
+
* The user is responsible for:
|
|
9
|
+
* 1. Installing @iden3/react-native-rapidsnark
|
|
10
|
+
* 2. Managing circuit files (.zkey files)
|
|
11
|
+
* 3. Implementing witness generation
|
|
12
|
+
* 4. Calling setCustomRapidsnarkProver() after engine initialization
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.createRapidsnarkProverTemplate = exports.clearCustomRapidsnarkProver = exports.setCustomRapidsnarkProver = exports.CIRCUIT_IDS = exports.saveBufferToFile = exports.uint8ArrayToBase64 = void 0;
|
|
16
|
+
const prover_1 = require("../core/prover");
|
|
17
|
+
const runtime_1 = require("../util/runtime");
|
|
18
|
+
/**
|
|
19
|
+
* Helper function to convert Uint8Array to base64 string
|
|
20
|
+
*/
|
|
21
|
+
const uint8ArrayToBase64 = (buffer) => {
|
|
22
|
+
if (typeof Buffer !== 'undefined') {
|
|
23
|
+
return Buffer.from(buffer).toString('base64');
|
|
24
|
+
}
|
|
25
|
+
// Fallback for environments without Buffer
|
|
26
|
+
let binary = '';
|
|
27
|
+
for (let i = 0; i < buffer.length; i += 1) {
|
|
28
|
+
binary += String.fromCharCode(buffer[i]);
|
|
29
|
+
}
|
|
30
|
+
return btoa(binary);
|
|
31
|
+
};
|
|
32
|
+
exports.uint8ArrayToBase64 = uint8ArrayToBase64;
|
|
33
|
+
/**
|
|
34
|
+
* Helper function to save buffer to file system (React Native)
|
|
35
|
+
* Users should implement their own version using react-native-fs or similar
|
|
36
|
+
*/
|
|
37
|
+
const saveBufferToFile = async (_buffer, _filename) => {
|
|
38
|
+
throw new Error('saveBufferToFile must be implemented by the user. ' +
|
|
39
|
+
'Use react-native-fs or similar library to save buffer to file system.');
|
|
40
|
+
};
|
|
41
|
+
exports.saveBufferToFile = saveBufferToFile;
|
|
42
|
+
/**
|
|
43
|
+
* Set a custom Rapidsnark prover implementation
|
|
44
|
+
*
|
|
45
|
+
* This function allows React Native developers to provide their own
|
|
46
|
+
* Rapidsnark implementation, giving them full control over proof generation.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* import { setCustomRapidsnarkProver } from 'dop-wallet-v6';
|
|
51
|
+
* import { groth16Prove } from '@iden3/react-native-rapidsnark';
|
|
52
|
+
* import RNFS from 'react-native-fs';
|
|
53
|
+
*
|
|
54
|
+
* // Implement your own prover adapter
|
|
55
|
+
* const myRapidsnarkAdapter = {
|
|
56
|
+
* async generateProof(circuitId, zkeyBuffer, jsonInputs, progressCallback) {
|
|
57
|
+
* // 1. Save zkey to file
|
|
58
|
+
* const zkeyPath = `${RNFS.DocumentDirectoryPath}/${circuitId}.zkey`;
|
|
59
|
+
* await RNFS.writeFile(zkeyPath, uint8ArrayToBase64(zkeyBuffer), 'base64');
|
|
60
|
+
*
|
|
61
|
+
* // 2. Generate witness (implement your own witness generation)
|
|
62
|
+
* const witnessBase64 = await generateWitness(circuitId, jsonInputs);
|
|
63
|
+
*
|
|
64
|
+
* // 3. Generate proof with Rapidsnark
|
|
65
|
+
* const rapidsnarkProof = await groth16Prove(zkeyPath, witnessBase64);
|
|
66
|
+
*
|
|
67
|
+
* // 4. Convert to DOP Engine proof format
|
|
68
|
+
* return {
|
|
69
|
+
* pi_a: rapidsnarkProof.proof.a,
|
|
70
|
+
* pi_b: rapidsnarkProof.proof.b,
|
|
71
|
+
* pi_c: rapidsnarkProof.proof.c,
|
|
72
|
+
* publicSignals: rapidsnarkProof.pub_signals
|
|
73
|
+
* };
|
|
74
|
+
* }
|
|
75
|
+
* };
|
|
76
|
+
*
|
|
77
|
+
* // Set it after engine initialization
|
|
78
|
+
* await startDopEngineReactNative(...);
|
|
79
|
+
* setCustomRapidsnarkProver(myRapidsnarkAdapter);
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
/**
|
|
83
|
+
* Circuit ID mapping for DOP Engine
|
|
84
|
+
* These IDs are used internally by DOP Engine's native prover interface
|
|
85
|
+
*/
|
|
86
|
+
exports.CIRCUIT_IDS = {
|
|
87
|
+
dop: 0,
|
|
88
|
+
decrypt: 1,
|
|
89
|
+
nullify: 2 // Nullifier circuit
|
|
90
|
+
};
|
|
91
|
+
const setCustomRapidsnarkProver = (userProver) => {
|
|
92
|
+
if (!runtime_1.isReactNative) {
|
|
93
|
+
// eslint-disable-next-line no-console
|
|
94
|
+
console.warn('⚠️ Custom Rapidsnark prover is only needed in React Native environment');
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const prover = (0, prover_1.getProver)();
|
|
99
|
+
// Wrap user's prover to match DOP Engine's expected interface
|
|
100
|
+
// DOP Engine expects: (circuitId: number, datBuffer, zkeyBuffer, inputJson, progressCallback)
|
|
101
|
+
const wrappedProver = (circuitId, datBuffer, zkeyBuffer, jsonInputs, progressCallback) => {
|
|
102
|
+
// Convert numeric circuit ID to string name for user's convenience
|
|
103
|
+
const circuitName = Object.keys(exports.CIRCUIT_IDS).find(key => exports.CIRCUIT_IDS[key] === circuitId);
|
|
104
|
+
const circuitDisplayName = circuitName ?? `circuit_${circuitId}`;
|
|
105
|
+
// eslint-disable-next-line no-console
|
|
106
|
+
console.log(`🔄 Generating proof for circuit: ${circuitDisplayName} (ID: ${circuitId})`);
|
|
107
|
+
try {
|
|
108
|
+
const proof = userProver.generateProof(circuitDisplayName, zkeyBuffer, jsonInputs, progressCallback);
|
|
109
|
+
// eslint-disable-next-line no-console
|
|
110
|
+
console.log(`✅ Proof generated successfully for circuit: ${circuitDisplayName}`);
|
|
111
|
+
return proof;
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
// eslint-disable-next-line no-console
|
|
115
|
+
console.error(`❌ Proof generation failed for circuit ${circuitDisplayName}:`, error);
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
// Set the native prover in DOP Engine with circuit ID mapping
|
|
120
|
+
prover.setNativeProverGroth16(wrappedProver, exports.CIRCUIT_IDS);
|
|
121
|
+
// eslint-disable-next-line no-console
|
|
122
|
+
console.log('✅ Custom Rapidsnark prover configured successfully');
|
|
123
|
+
// eslint-disable-next-line no-console
|
|
124
|
+
console.log('🚀 React Native proof generation is now enabled');
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
// eslint-disable-next-line no-console
|
|
128
|
+
console.error('❌ Failed to set custom Rapidsnark prover:', error);
|
|
129
|
+
throw new Error(`Failed to set custom Rapidsnark prover: ${String(error)}`);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
exports.setCustomRapidsnarkProver = setCustomRapidsnarkProver;
|
|
133
|
+
/**
|
|
134
|
+
* Remove custom prover and revert to default behavior
|
|
135
|
+
*/
|
|
136
|
+
const clearCustomRapidsnarkProver = () => {
|
|
137
|
+
try {
|
|
138
|
+
const prover = (0, prover_1.getProver)();
|
|
139
|
+
prover.setNativeProverGroth16(undefined, {});
|
|
140
|
+
// eslint-disable-next-line no-console
|
|
141
|
+
console.log('✅ Custom Rapidsnark prover cleared');
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
// eslint-disable-next-line no-console
|
|
145
|
+
console.error('❌ Failed to clear custom prover:', error);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
exports.clearCustomRapidsnarkProver = clearCustomRapidsnarkProver;
|
|
149
|
+
/**
|
|
150
|
+
* Example implementation template for users to customize
|
|
151
|
+
*
|
|
152
|
+
* This is a reference implementation that users should copy and modify
|
|
153
|
+
* according to their specific needs and file system setup.
|
|
154
|
+
*/
|
|
155
|
+
const createRapidsnarkProverTemplate = () => {
|
|
156
|
+
return `
|
|
157
|
+
// Example Rapidsnark Prover Implementation Template
|
|
158
|
+
// Copy this and customize for your app's needs
|
|
159
|
+
|
|
160
|
+
import { setCustomRapidsnarkProver, uint8ArrayToBase64 } from 'dop-wallet-v6';
|
|
161
|
+
import { groth16Prove } from '@iden3/react-native-rapidsnark';
|
|
162
|
+
import RNFS from 'react-native-fs';
|
|
163
|
+
|
|
164
|
+
// 1. Implement witness generation (specific to your circuit setup)
|
|
165
|
+
const generateWitness = async (circuitId: string, inputs: any): Promise<string> => {
|
|
166
|
+
// TODO: Implement witness generation
|
|
167
|
+
// This depends on your circuit setup and how you handle .wasm files
|
|
168
|
+
|
|
169
|
+
// Option A: Use a witness generator service
|
|
170
|
+
const response = await fetch('https://your-backend.com/generate-witness', {
|
|
171
|
+
method: 'POST',
|
|
172
|
+
body: JSON.stringify({ circuitId, inputs })
|
|
173
|
+
});
|
|
174
|
+
const { witnessBase64 } = await response.json();
|
|
175
|
+
return witnessBase64;
|
|
176
|
+
|
|
177
|
+
// Option B: Generate locally if you have witness generator
|
|
178
|
+
// const witnessBuffer = await yourWitnessGenerator(circuitId, inputs);
|
|
179
|
+
// return uint8ArrayToBase64(witnessBuffer);
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
// 2. Create your prover adapter
|
|
183
|
+
const myRapidsnarkProver = {
|
|
184
|
+
async generateProof(circuitId, zkeyBuffer, jsonInputs, progressCallback) {
|
|
185
|
+
try {
|
|
186
|
+
// Save zkey to file system
|
|
187
|
+
const zkeyPath = \`\${RNFS.DocumentDirectoryPath}/circuits/\${circuitId}.zkey\`;
|
|
188
|
+
await RNFS.mkdir(\`\${RNFS.DocumentDirectoryPath}/circuits\`);
|
|
189
|
+
await RNFS.writeFile(zkeyPath, uint8ArrayToBase64(zkeyBuffer), 'base64');
|
|
190
|
+
|
|
191
|
+
if (progressCallback) progressCallback(0.3);
|
|
192
|
+
|
|
193
|
+
// Generate witness
|
|
194
|
+
const witnessBase64 = await generateWitness(circuitId, jsonInputs);
|
|
195
|
+
|
|
196
|
+
if (progressCallback) progressCallback(0.6);
|
|
197
|
+
|
|
198
|
+
// Generate proof with Rapidsnark
|
|
199
|
+
const rapidsnarkProof = await groth16Prove(zkeyPath, witnessBase64);
|
|
200
|
+
|
|
201
|
+
if (progressCallback) progressCallback(0.9);
|
|
202
|
+
|
|
203
|
+
// Convert to DOP Engine proof format
|
|
204
|
+
return {
|
|
205
|
+
pi_a: rapidsnarkProof.proof.a,
|
|
206
|
+
pi_b: rapidsnarkProof.proof.b,
|
|
207
|
+
pi_c: rapidsnarkProof.proof.c,
|
|
208
|
+
publicSignals: rapidsnarkProof.pub_signals
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
} catch (error) {
|
|
212
|
+
console.error('Proof generation failed:', error);
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// 3. Set it up after DOP Engine initialization
|
|
219
|
+
export const setupMyRapidsnarkProver = () => {
|
|
220
|
+
setCustomRapidsnarkProver(myRapidsnarkProver);
|
|
221
|
+
console.log('✅ My custom Rapidsnark prover is ready!');
|
|
222
|
+
};
|
|
223
|
+
`;
|
|
224
|
+
};
|
|
225
|
+
exports.createRapidsnarkProverTemplate = createRapidsnarkProverTemplate;
|
|
226
|
+
//# sourceMappingURL=user-rapidsnark-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-rapidsnark-adapter.js","sourceRoot":"","sources":["../../../../src/services/dop/crypto/user-rapidsnark-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User-Configurable Rapidsnark Adapter for React Native\n * \n * This module provides a way for React Native developers to configure\n * their own Rapidsnark prover implementation, bypassing SDK limitations.\n * \n * The user is responsible for:\n * 1. Installing @iden3/react-native-rapidsnark\n * 2. Managing circuit files (.zkey files)\n * 3. Implementing witness generation\n * 4. Calling setCustomRapidsnarkProver() after engine initialization\n */\n\nimport { getProver } from '../core/prover';\nimport type { FormattedCircuitInputsDop, Proof } from 'dop-engine-v3';\nimport { isReactNative } from '../util/runtime';\n\n/**\n * Interface that users must implement for their Rapidsnark prover\n */\nexport interface UserRapidsnarkProver {\n /**\n * Generate a zero-knowledge proof using Rapidsnark\n * \n * @param circuitId - The circuit identifier (e.g., 'dop', 'decrypt', 'nullify')\n * @param zkeyBuffer - The zkey file buffer (or path to zkey file in user's implementation)\n * @param jsonInputs - The circuit inputs as JSON object\n * @param progressCallback - Optional callback for progress updates\n * @returns Promise containing the generated proof\n */\n generateProof(\n circuitId: string,\n zkeyBuffer: Uint8Array,\n jsonInputs: FormattedCircuitInputsDop,\n progressCallback?: (progress: number) => void\n ): Promise<Proof>;\n}\n\n/**\n * Helper function to convert Uint8Array to base64 string\n */\nexport const uint8ArrayToBase64 = (buffer: Uint8Array): string => {\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(buffer).toString('base64');\n }\n \n // Fallback for environments without Buffer\n let binary = '';\n for (let i = 0; i < buffer.length; i += 1) {\n binary += String.fromCharCode(buffer[i]);\n }\n return btoa(binary);\n};\n\n/**\n * Helper function to save buffer to file system (React Native)\n * Users should implement their own version using react-native-fs or similar\n */\nexport const saveBufferToFile = async (\n _buffer: Uint8Array,\n _filename: string\n): Promise<string> => {\n throw new Error(\n 'saveBufferToFile must be implemented by the user. ' +\n 'Use react-native-fs or similar library to save buffer to file system.'\n );\n};\n\n/**\n * Set a custom Rapidsnark prover implementation\n * \n * This function allows React Native developers to provide their own\n * Rapidsnark implementation, giving them full control over proof generation.\n * \n * @example\n * ```typescript\n * import { setCustomRapidsnarkProver } from 'dop-wallet-v6';\n * import { groth16Prove } from '@iden3/react-native-rapidsnark';\n * import RNFS from 'react-native-fs';\n * \n * // Implement your own prover adapter\n * const myRapidsnarkAdapter = {\n * async generateProof(circuitId, zkeyBuffer, jsonInputs, progressCallback) {\n * // 1. Save zkey to file\n * const zkeyPath = `${RNFS.DocumentDirectoryPath}/${circuitId}.zkey`;\n * await RNFS.writeFile(zkeyPath, uint8ArrayToBase64(zkeyBuffer), 'base64');\n * \n * // 2. Generate witness (implement your own witness generation)\n * const witnessBase64 = await generateWitness(circuitId, jsonInputs);\n * \n * // 3. Generate proof with Rapidsnark\n * const rapidsnarkProof = await groth16Prove(zkeyPath, witnessBase64);\n * \n * // 4. Convert to DOP Engine proof format\n * return {\n * pi_a: rapidsnarkProof.proof.a,\n * pi_b: rapidsnarkProof.proof.b,\n * pi_c: rapidsnarkProof.proof.c,\n * publicSignals: rapidsnarkProof.pub_signals\n * };\n * }\n * };\n * \n * // Set it after engine initialization\n * await startDopEngineReactNative(...);\n * setCustomRapidsnarkProver(myRapidsnarkAdapter);\n * ```\n */\n/**\n * Circuit ID mapping for DOP Engine\n * These IDs are used internally by DOP Engine's native prover interface\n */\nexport const CIRCUIT_IDS = {\n dop: 0, // Main DOP transfer circuit\n decrypt: 1, // Decrypt circuit\n nullify: 2 // Nullifier circuit\n} as const;\n\nexport const setCustomRapidsnarkProver = (userProver: UserRapidsnarkProver): void => {\n if (!isReactNative) {\n // eslint-disable-next-line no-console\n console.warn('⚠️ Custom Rapidsnark prover is only needed in React Native environment');\n return;\n }\n\n try {\n const prover = getProver();\n \n // Wrap user's prover to match DOP Engine's expected interface\n // DOP Engine expects: (circuitId: number, datBuffer, zkeyBuffer, inputJson, progressCallback)\n const wrappedProver = (\n circuitId: number,\n datBuffer: Uint8Array,\n zkeyBuffer: Uint8Array,\n jsonInputs: FormattedCircuitInputsDop,\n progressCallback?: (progress: number) => void\n ): Promise<Proof> => {\n // Convert numeric circuit ID to string name for user's convenience\n const circuitName = Object.keys(CIRCUIT_IDS).find(\n key => CIRCUIT_IDS[key as keyof typeof CIRCUIT_IDS] === circuitId\n );\n const circuitDisplayName = circuitName ?? `circuit_${circuitId}`;\n \n // eslint-disable-next-line no-console\n console.log(`🔄 Generating proof for circuit: ${circuitDisplayName} (ID: ${circuitId})`);\n \n try {\n const proof = userProver.generateProof(\n circuitDisplayName,\n zkeyBuffer,\n jsonInputs,\n progressCallback\n );\n \n // eslint-disable-next-line no-console\n console.log(`✅ Proof generated successfully for circuit: ${circuitDisplayName}`);\n return proof;\n \n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(`❌ Proof generation failed for circuit ${circuitDisplayName}:`, error);\n throw error;\n }\n };\n \n // Set the native prover in DOP Engine with circuit ID mapping\n prover.setNativeProverGroth16(wrappedProver as any, CIRCUIT_IDS);\n \n // eslint-disable-next-line no-console\n console.log('✅ Custom Rapidsnark prover configured successfully');\n // eslint-disable-next-line no-console\n console.log('🚀 React Native proof generation is now enabled');\n \n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('❌ Failed to set custom Rapidsnark prover:', error);\n throw new Error(`Failed to set custom Rapidsnark prover: ${String(error)}`);\n }\n};\n\n/**\n * Remove custom prover and revert to default behavior\n */\nexport const clearCustomRapidsnarkProver = (): void => {\n try {\n const prover = getProver();\n prover.setNativeProverGroth16(undefined as any, {});\n // eslint-disable-next-line no-console\n console.log('✅ Custom Rapidsnark prover cleared');\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('❌ Failed to clear custom prover:', error);\n }\n};\n\n/**\n * Example implementation template for users to customize\n * \n * This is a reference implementation that users should copy and modify\n * according to their specific needs and file system setup.\n */\nexport const createRapidsnarkProverTemplate = (): string => {\n return `\n// Example Rapidsnark Prover Implementation Template\n// Copy this and customize for your app's needs\n\nimport { setCustomRapidsnarkProver, uint8ArrayToBase64 } from 'dop-wallet-v6';\nimport { groth16Prove } from '@iden3/react-native-rapidsnark';\nimport RNFS from 'react-native-fs';\n\n// 1. Implement witness generation (specific to your circuit setup)\nconst generateWitness = async (circuitId: string, inputs: any): Promise<string> => {\n // TODO: Implement witness generation\n // This depends on your circuit setup and how you handle .wasm files\n \n // Option A: Use a witness generator service\n const response = await fetch('https://your-backend.com/generate-witness', {\n method: 'POST',\n body: JSON.stringify({ circuitId, inputs })\n });\n const { witnessBase64 } = await response.json();\n return witnessBase64;\n \n // Option B: Generate locally if you have witness generator\n // const witnessBuffer = await yourWitnessGenerator(circuitId, inputs);\n // return uint8ArrayToBase64(witnessBuffer);\n};\n\n// 2. Create your prover adapter\nconst myRapidsnarkProver = {\n async generateProof(circuitId, zkeyBuffer, jsonInputs, progressCallback) {\n try {\n // Save zkey to file system\n const zkeyPath = \\`\\${RNFS.DocumentDirectoryPath}/circuits/\\${circuitId}.zkey\\`;\n await RNFS.mkdir(\\`\\${RNFS.DocumentDirectoryPath}/circuits\\`);\n await RNFS.writeFile(zkeyPath, uint8ArrayToBase64(zkeyBuffer), 'base64');\n \n if (progressCallback) progressCallback(0.3);\n \n // Generate witness\n const witnessBase64 = await generateWitness(circuitId, jsonInputs);\n \n if (progressCallback) progressCallback(0.6);\n \n // Generate proof with Rapidsnark\n const rapidsnarkProof = await groth16Prove(zkeyPath, witnessBase64);\n \n if (progressCallback) progressCallback(0.9);\n \n // Convert to DOP Engine proof format\n return {\n pi_a: rapidsnarkProof.proof.a,\n pi_b: rapidsnarkProof.proof.b,\n pi_c: rapidsnarkProof.proof.c,\n publicSignals: rapidsnarkProof.pub_signals\n };\n \n } catch (error) {\n console.error('Proof generation failed:', error);\n throw error;\n }\n }\n};\n\n// 3. Set it up after DOP Engine initialization\nexport const setupMyRapidsnarkProver = () => {\n setCustomRapidsnarkProver(myRapidsnarkProver);\n console.log('✅ My custom Rapidsnark prover is ready!');\n};\n`;\n};\n"]}
|
package/package.json
CHANGED
package/react-native.js
CHANGED
|
@@ -9,4 +9,9 @@
|
|
|
9
9
|
require('./react-native-shims');
|
|
10
10
|
|
|
11
11
|
// Re-export the main SDK
|
|
12
|
-
|
|
12
|
+
const sdk = require('./dist/index.js');
|
|
13
|
+
|
|
14
|
+
// Export React Native-specific prover utilities
|
|
15
|
+
sdk.reactNativeRapidsnark = require('./dist/services/dop/crypto/react-native-rapidsnark-prover.js');
|
|
16
|
+
|
|
17
|
+
module.exports = sdk;
|