@deserialize/multi-vm-wallet 1.3.1 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/.claude/settings.local.json +7 -1
  2. package/dist/IChainWallet.d.ts +3 -3
  3. package/dist/constant.js +60 -16
  4. package/dist/constant.js.map +1 -1
  5. package/dist/evm/aa-service/index.d.ts +2 -2
  6. package/dist/evm/aa-service/index.js +1 -3
  7. package/dist/evm/aa-service/index.js.map +1 -1
  8. package/dist/evm/aa-service/lib/kernel-account.d.ts +2 -44
  9. package/dist/evm/aa-service/lib/kernel-account.js +42 -93
  10. package/dist/evm/aa-service/lib/kernel-account.js.map +1 -1
  11. package/dist/evm/aa-service/lib/session-keys.d.ts +14 -17
  12. package/dist/evm/aa-service/lib/session-keys.js +40 -58
  13. package/dist/evm/aa-service/lib/session-keys.js.map +1 -1
  14. package/dist/evm/aa-service/lib/type.d.ts +18 -1
  15. package/dist/evm/aa-service/lib/type.js.map +1 -1
  16. package/dist/evm/aa-service/services/account-abstraction.d.ts +7 -29
  17. package/dist/evm/aa-service/services/account-abstraction.js +12 -68
  18. package/dist/evm/aa-service/services/account-abstraction.js.map +1 -1
  19. package/dist/evm/aa-service/services/bundler.d.ts +4 -1
  20. package/dist/evm/aa-service/services/bundler.js +41 -7
  21. package/dist/evm/aa-service/services/bundler.js.map +1 -1
  22. package/dist/evm/evm.d.ts +164 -14
  23. package/dist/evm/evm.js +259 -80
  24. package/dist/evm/evm.js.map +1 -1
  25. package/dist/evm/smartWallet.d.ts +12 -61
  26. package/dist/evm/smartWallet.js +143 -184
  27. package/dist/evm/smartWallet.js.map +1 -1
  28. package/dist/evm/utils.js +1 -1
  29. package/dist/evm/utils.js.map +1 -1
  30. package/dist/helpers/index.d.ts +6 -1
  31. package/dist/helpers/index.js +116 -0
  32. package/dist/helpers/index.js.map +1 -1
  33. package/dist/privacy/artifact-manager.d.ts +117 -0
  34. package/dist/privacy/artifact-manager.js +251 -0
  35. package/dist/privacy/artifact-manager.js.map +1 -0
  36. package/dist/privacy/broadcaster-client.d.ts +166 -0
  37. package/dist/privacy/broadcaster-client.js +261 -0
  38. package/dist/privacy/broadcaster-client.js.map +1 -0
  39. package/dist/privacy/index.d.ts +34 -0
  40. package/dist/privacy/index.js +56 -0
  41. package/dist/privacy/index.js.map +1 -0
  42. package/dist/privacy/network-config.d.ts +57 -0
  43. package/dist/privacy/network-config.js +118 -0
  44. package/dist/privacy/network-config.js.map +1 -0
  45. package/dist/privacy/poi-helper.d.ts +161 -0
  46. package/dist/privacy/poi-helper.js +249 -0
  47. package/dist/privacy/poi-helper.js.map +1 -0
  48. package/dist/privacy/railgun-engine.d.ts +135 -0
  49. package/dist/privacy/railgun-engine.js +205 -0
  50. package/dist/privacy/railgun-engine.js.map +1 -0
  51. package/dist/privacy/railgun-privacy-wallet.d.ts +288 -0
  52. package/dist/privacy/railgun-privacy-wallet.js +539 -0
  53. package/dist/privacy/railgun-privacy-wallet.js.map +1 -0
  54. package/dist/privacy/types.d.ts +229 -0
  55. package/dist/privacy/types.js +26 -0
  56. package/dist/privacy/types.js.map +1 -0
  57. package/dist/savings/savings-manager.d.ts +126 -0
  58. package/dist/savings/savings-manager.js +234 -0
  59. package/dist/savings/savings-manager.js.map +1 -0
  60. package/dist/savings/smart-savings.d.ts +74 -0
  61. package/dist/savings/smart-savings.js +152 -0
  62. package/dist/savings/smart-savings.js.map +1 -0
  63. package/dist/savings/types.d.ts +125 -0
  64. package/dist/savings/types.js +9 -0
  65. package/dist/savings/types.js.map +1 -0
  66. package/dist/svm/svm.d.ts +19 -3
  67. package/dist/svm/svm.js +29 -17
  68. package/dist/svm/svm.js.map +1 -1
  69. package/dist/svm/utils.d.ts +2 -2
  70. package/dist/svm/utils.js +4 -4
  71. package/dist/svm/utils.js.map +1 -1
  72. package/dist/test.js +81 -22
  73. package/dist/test.js.map +1 -1
  74. package/dist/types.d.ts +14 -16
  75. package/dist/types.js.map +1 -1
  76. package/dist/vm.d.ts +14 -0
  77. package/dist/vm.js.map +1 -1
  78. package/package.json +6 -1
  79. package/utils/IChainWallet.ts +3 -3
  80. package/utils/constant.ts +63 -16
  81. package/utils/evm/aa-service/index.ts +1 -3
  82. package/utils/evm/aa-service/lib/kernel-account.ts +45 -136
  83. package/utils/evm/aa-service/lib/session-keys.ts +58 -60
  84. package/utils/evm/aa-service/lib/type.ts +19 -1
  85. package/utils/evm/aa-service/services/account-abstraction.ts +24 -76
  86. package/utils/evm/aa-service/services/bundler.ts +54 -11
  87. package/utils/evm/evm.ts +313 -110
  88. package/utils/evm/smartWallet.ts +124 -214
  89. package/utils/evm/utils.ts +2 -1
  90. package/utils/helpers/index.ts +138 -1
  91. package/utils/savings/savings-manager.ts +271 -0
  92. package/utils/savings/smart-savings.ts +184 -0
  93. package/utils/savings/types.ts +135 -0
  94. package/utils/svm/svm.ts +34 -25
  95. package/utils/svm/utils.ts +4 -10
  96. package/utils/test.ts +112 -24
  97. package/utils/types.ts +15 -17
  98. package/utils/vm.ts +10 -0
@@ -0,0 +1,539 @@
1
+ "use strict";
2
+ /**
3
+ * RAILGUN Privacy Wallet
4
+ *
5
+ * Core class for RAILGUN privacy operations:
6
+ * - Create/load private wallets
7
+ * - Shield (public → private)
8
+ * - Unshield (private → public)
9
+ * - Private transfers (private → private)
10
+ * - Query private balances
11
+ *
12
+ * STATELESS: Does not store wallet data.
13
+ * Implementer must store RailgunWalletInfo and manage encryption keys.
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.RailgunPrivacyWallet = void 0;
50
+ const wallet_1 = require("@railgun-community/wallet");
51
+ const shared_models_1 = require("@railgun-community/shared-models");
52
+ const types_1 = require("./types");
53
+ const railgun_engine_1 = require("./railgun-engine");
54
+ /**
55
+ * RAILGUN Privacy Wallet
56
+ *
57
+ * Provides privacy features for a single RAILGUN wallet.
58
+ * Wallets are encrypted and stored in the LevelDB database.
59
+ *
60
+ * STATELESS DESIGN:
61
+ * - Does NOT store wallet data internally
62
+ * - All operations require explicit parameters
63
+ * - Implementer manages RailgunWalletInfo storage
64
+ */
65
+ class RailgunPrivacyWallet {
66
+ railgunWalletID;
67
+ railgunAddress;
68
+ /**
69
+ * Private constructor - use static create() or load() methods
70
+ */
71
+ constructor(railgunWalletID, railgunAddress) {
72
+ this.railgunWalletID = railgunWalletID;
73
+ this.railgunAddress = railgunAddress;
74
+ }
75
+ // ============================================
76
+ // WALLET CREATION & LOADING
77
+ // ============================================
78
+ /**
79
+ * Create a new RAILGUN wallet from mnemonic
80
+ *
81
+ * IMPORTANT: This creates an encrypted wallet in the LevelDB database.
82
+ * Returns RailgunWalletInfo that MUST be stored by implementer.
83
+ *
84
+ * @param encryptionKey - Key to encrypt wallet (derive from user password)
85
+ * @param mnemonic - BIP-39 mnemonic phrase
86
+ * @param creationBlockNumbers - Optional block numbers per chain for faster syncing
87
+ *
88
+ * @returns RailgunWalletInfo to store
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * import { Wallet } from 'ethers';
93
+ *
94
+ * const mnemonic = Wallet.createRandom().mnemonic.phrase;
95
+ * const encryptionKey = deriveKeyFromPassword(userPassword);
96
+ *
97
+ * const walletInfo = await RailgunPrivacyWallet.create(
98
+ * encryptionKey,
99
+ * mnemonic
100
+ * );
101
+ *
102
+ * // Implementer stores this
103
+ * await storage.save({
104
+ * railgunWalletID: walletInfo.railgunWalletID,
105
+ * railgunAddress: walletInfo.railgunAddress,
106
+ * viewingPrivateKey: encrypt(walletInfo.viewingPrivateKey),
107
+ * spendingPublicKey: walletInfo.spendingPublicKey
108
+ * });
109
+ * ```
110
+ */
111
+ static async create(encryptionKey, mnemonic, creationBlockNumbers) {
112
+ if (!railgun_engine_1.RailgunEngine.isInitialized()) {
113
+ throw new Error('RAILGUN engine not initialized');
114
+ }
115
+ const wallet = await (0, wallet_1.createRailgunWallet)(encryptionKey, mnemonic, creationBlockNumbers);
116
+ return {
117
+ railgunWalletID: wallet.id,
118
+ railgunAddress: wallet.railgunAddress,
119
+ viewingPrivateKey: wallet.viewingPrivateKey,
120
+ spendingPublicKey: wallet.spendingPublicKey,
121
+ creationBlockNumberMap: creationBlockNumbers,
122
+ };
123
+ }
124
+ /**
125
+ * Load existing RAILGUN wallet by ID
126
+ *
127
+ * Retrieves wallet from LevelDB database.
128
+ * Implementer must have stored railgunWalletID from create().
129
+ *
130
+ * @param encryptionKey - Same key used during creation
131
+ * @param railgunWalletID - Wallet ID from RailgunWalletInfo
132
+ *
133
+ * @returns RailgunPrivacyWallet instance
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const stored = await storage.get(userId);
138
+ * const encryptionKey = deriveKeyFromPassword(userPassword);
139
+ *
140
+ * const wallet = await RailgunPrivacyWallet.load(
141
+ * encryptionKey,
142
+ * stored.railgunWalletID
143
+ * );
144
+ * ```
145
+ */
146
+ static async load(encryptionKey, railgunWalletID) {
147
+ if (!railgun_engine_1.RailgunEngine.isInitialized()) {
148
+ throw new Error('RAILGUN engine not initialized');
149
+ }
150
+ const wallet = await (0, wallet_1.loadWalletByID)(encryptionKey, railgunWalletID, false);
151
+ return new RailgunPrivacyWallet(wallet.id, wallet.railgunAddress);
152
+ }
153
+ /**
154
+ * Create RAILGUN wallet for specific BIP-44 account index
155
+ *
156
+ * Useful for linking privacy to savings pockets or account indices.
157
+ *
158
+ * @param encryptionKey - Encryption key
159
+ * @param mnemonic - BIP-39 mnemonic
160
+ * @param accountIndex - BIP-44 account index
161
+ * @param creationBlockNumbers - Optional block numbers
162
+ *
163
+ * @returns RailgunWalletInfo to store
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * // Create privacy wallet for savings account #1
168
+ * const walletInfo = await RailgunPrivacyWallet.createForAccount(
169
+ * encryptionKey,
170
+ * mnemonic,
171
+ * 1 // Same index as savings pocket
172
+ * );
173
+ * ```
174
+ */
175
+ static async createForAccount(encryptionKey, mnemonic, accountIndex, creationBlockNumbers) {
176
+ // Derive mnemonic for specific account index
177
+ // Note: RAILGUN uses same mnemonic, differentiation is via wallet name
178
+ const walletName = `account-${accountIndex}`;
179
+ const walletInfo = await this.create(encryptionKey, mnemonic, creationBlockNumbers);
180
+ return {
181
+ ...walletInfo,
182
+ // Add metadata for tracking
183
+ creationBlockNumberMap: {
184
+ ...creationBlockNumbers,
185
+ accountIndex, // Store for reference
186
+ },
187
+ };
188
+ }
189
+ // ============================================
190
+ // SHIELD TRANSACTIONS (Public → Private)
191
+ // ============================================
192
+ /**
193
+ * Build shield transaction (ERC-20)
194
+ *
195
+ * Shields ERC-20 tokens from public address into this RAILGUN wallet.
196
+ * NO PROOF REQUIRED - direct contract interaction.
197
+ *
198
+ * Fees: 0.25% shield fee
199
+ * Standby: 1 hour on mainnet before spendable
200
+ *
201
+ * @param fromAddress - Public address sending tokens
202
+ * @param tokenAddress - ERC-20 contract address
203
+ * @param amount - Amount to shield (in smallest units)
204
+ * @param network - Network name
205
+ * @param options - Shield options
206
+ *
207
+ * @returns Shield transaction ready for broadcast
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * const shieldTx = await wallet.buildShield(
212
+ * publicAddress,
213
+ * USDC_ADDRESS,
214
+ * parseUnits("100", 6), // 100 USDC
215
+ * NetworkName.Ethereum
216
+ * );
217
+ *
218
+ * // Broadcast using standard wallet
219
+ * await publicWallet.sendTransaction(shieldTx);
220
+ * ```
221
+ */
222
+ async buildShield(fromAddress, tokenAddress, amount, network, options) {
223
+ // Shield transactions don't require proofs
224
+ // They're just ERC-20 transfers to RAILGUN contract
225
+ // Import generateDeposit from RAILGUN SDK
226
+ const { generateDeposit } = await Promise.resolve().then(() => __importStar(require('@railgun-community/wallet')));
227
+ const depositData = await generateDeposit(network, this.railgunAddress, tokenAddress, amount);
228
+ // Calculate 0.25% fee
229
+ const fee = (amount * 25n) / 10000n;
230
+ return {
231
+ type: 'shield',
232
+ to: depositData.to,
233
+ data: depositData.data,
234
+ value: depositData.value ? BigInt(depositData.value) : 0n,
235
+ gasLimit: BigInt(depositData.gasEstimate || 200000),
236
+ tokenAddress,
237
+ shieldAmount: amount,
238
+ railgunAddress: this.railgunAddress,
239
+ fee,
240
+ };
241
+ }
242
+ /**
243
+ * Build shield transaction (base token)
244
+ *
245
+ * Shields native token (ETH, MATIC, BNB) into RAILGUN.
246
+ *
247
+ * @param fromAddress - Public address
248
+ * @param amount - Amount to shield (in wei)
249
+ * @param network - Network name
250
+ * @param options - Shield options
251
+ *
252
+ * @returns Shield transaction
253
+ */
254
+ async buildShieldBaseToken(fromAddress, amount, network, options) {
255
+ const { generateDeposit } = await Promise.resolve().then(() => __importStar(require('@railgun-community/wallet')));
256
+ // Use zero address for base token
257
+ const BASE_TOKEN_ADDRESS = '0x0000000000000000000000000000000000000000';
258
+ const depositData = await generateDeposit(network, this.railgunAddress, BASE_TOKEN_ADDRESS, amount);
259
+ const fee = (amount * 25n) / 10000n;
260
+ return {
261
+ type: 'shield',
262
+ to: depositData.to,
263
+ data: depositData.data,
264
+ value: BigInt(depositData.value || amount),
265
+ gasLimit: BigInt(depositData.gasEstimate || 200000),
266
+ tokenAddress: BASE_TOKEN_ADDRESS,
267
+ shieldAmount: amount,
268
+ railgunAddress: this.railgunAddress,
269
+ fee,
270
+ };
271
+ }
272
+ // ============================================
273
+ // UNSHIELD TRANSACTIONS (Private → Public)
274
+ // ============================================
275
+ /**
276
+ * Build unshield transaction (ERC-20)
277
+ *
278
+ * Unshields ERC-20 tokens from RAILGUN to public address.
279
+ * REQUIRES PROOF GENERATION (20-30 seconds).
280
+ *
281
+ * Fees: 0.25% unshield fee
282
+ *
283
+ * @param toAddress - Public address to receive tokens
284
+ * @param tokenAddress - ERC-20 contract address
285
+ * @param amount - Amount to unshield
286
+ * @param network - Network name
287
+ * @param encryptionKey - Wallet encryption key
288
+ * @param options - Unshield options
289
+ *
290
+ * @returns Unshield transaction with proof
291
+ *
292
+ * @example
293
+ * ```typescript
294
+ * const unshieldTx = await wallet.buildUnshield(
295
+ * recipientAddress,
296
+ * USDC_ADDRESS,
297
+ * parseUnits("50", 6),
298
+ * NetworkName.Ethereum,
299
+ * encryptionKey,
300
+ * {
301
+ * onProgress: (p) => console.log(`Proof: ${p}%`)
302
+ * }
303
+ * );
304
+ *
305
+ * // Broadcast
306
+ * await wallet.sendTransaction(unshieldTx);
307
+ * ```
308
+ */
309
+ async buildUnshield(toAddress, tokenAddress, amount, network, encryptionKey, options) {
310
+ const erc20AmountRecipients = [
311
+ {
312
+ tokenAddress,
313
+ amount,
314
+ recipientAddress: toAddress,
315
+ },
316
+ ];
317
+ // Step 1: Gas estimation
318
+ const gasDetails = await (0, wallet_1.gasEstimateForUnprovenUnshield)(shared_models_1.TXIDVersion.V2_PoseidonMerkle, network, this.railgunWalletID, encryptionKey, options?.memoText, erc20AmountRecipients, [], // NFTs
319
+ { gasEstimate: 500000n }, // Initial estimate
320
+ options?.broadcasterFee
321
+ ? {
322
+ tokenAddress: options.broadcasterFee.tokenAddress,
323
+ feePerUnitGas: options.broadcasterFee.amount,
324
+ }
325
+ : undefined, options?.sendWithPublicWallet ?? true);
326
+ // Step 2: Generate proof (slow!)
327
+ const progressCallback = options?.onProgress
328
+ ? (progress) => options.onProgress(progress * 100)
329
+ : undefined;
330
+ await (0, wallet_1.generateUnshieldProof)(shared_models_1.TXIDVersion.V2_PoseidonMerkle, network, this.railgunWalletID, encryptionKey, options?.memoText, erc20AmountRecipients, [], options?.broadcasterFee
331
+ ? {
332
+ tokenAddress: options.broadcasterFee.tokenAddress,
333
+ amount: options.broadcasterFee.amount,
334
+ }
335
+ : undefined, options?.sendWithPublicWallet ?? true, options?.minGasPrice ?? 0n, progressCallback);
336
+ // Step 3: Populate transaction
337
+ const populatedTx = await (0, wallet_1.populateProvedUnshield)(shared_models_1.TXIDVersion.V2_PoseidonMerkle, network, this.railgunWalletID, erc20AmountRecipients, [], options?.broadcasterFee
338
+ ? {
339
+ tokenAddress: options.broadcasterFee.tokenAddress,
340
+ amount: options.broadcasterFee.amount,
341
+ }
342
+ : undefined, options?.sendWithPublicWallet ?? true, options?.minGasPrice ?? 0n, gasDetails);
343
+ const fee = (amount * 25n) / 10000n;
344
+ return {
345
+ type: 'unshield',
346
+ to: populatedTx.to,
347
+ data: populatedTx.data,
348
+ value: BigInt(populatedTx.value || 0),
349
+ gasLimit: BigInt(gasDetails.gasEstimate),
350
+ tokenAddress,
351
+ unshieldAmount: amount,
352
+ recipientAddress: toAddress,
353
+ fee,
354
+ proof: '', // Proof is embedded in data
355
+ publicInputs: [],
356
+ };
357
+ }
358
+ // ============================================
359
+ // PRIVATE TRANSFERS (Private → Private)
360
+ // ============================================
361
+ /**
362
+ * Build private transfer transaction
363
+ *
364
+ * Transfers tokens from this RAILGUN wallet to another 0zk address.
365
+ * Fully encrypted - sender, receiver, amount all hidden.
366
+ * REQUIRES PROOF GENERATION (20-30 seconds).
367
+ *
368
+ * @param toRailgunAddress - Recipient's 0zk address
369
+ * @param tokenAddress - ERC-20 contract address
370
+ * @param amount - Amount to transfer
371
+ * @param network - Network name
372
+ * @param encryptionKey - Wallet encryption key
373
+ * @param options - Transfer options (broadcasterFee REQUIRED for anonymity)
374
+ *
375
+ * @returns Private transfer transaction with proof
376
+ *
377
+ * @example
378
+ * ```typescript
379
+ * const transferTx = await wallet.buildPrivateTransfer(
380
+ * "0zk1234...",
381
+ * USDC_ADDRESS,
382
+ * parseUnits("25", 6),
383
+ * NetworkName.Ethereum,
384
+ * encryptionKey,
385
+ * {
386
+ * broadcasterFee: {
387
+ * tokenAddress: USDC_ADDRESS,
388
+ * amount: parseUnits("0.1", 6)
389
+ * },
390
+ * onProgress: (p) => console.log(`${p}%`)
391
+ * }
392
+ * );
393
+ *
394
+ * // Submit via broadcaster for anonymity
395
+ * await broadcasterClient.submitTransaction(transferTx);
396
+ * ```
397
+ */
398
+ async buildPrivateTransfer(toRailgunAddress, tokenAddress, amount, network, encryptionKey, options) {
399
+ const erc20AmountRecipients = [
400
+ {
401
+ tokenAddress,
402
+ amount,
403
+ recipientAddress: toRailgunAddress,
404
+ },
405
+ ];
406
+ // Step 1: Gas estimation
407
+ const gasDetails = await (0, wallet_1.gasEstimateForUnprovenTransfer)(shared_models_1.TXIDVersion.V2_PoseidonMerkle, network, this.railgunWalletID, encryptionKey, options?.memoText, erc20AmountRecipients, [], { gasEstimate: 500000n }, {
408
+ tokenAddress: options.broadcasterFee.tokenAddress,
409
+ feePerUnitGas: options.broadcasterFee.amount,
410
+ }, false // Don't send with public wallet (use broadcaster)
411
+ );
412
+ // Step 2: Generate proof
413
+ const progressCallback = options?.onProgress
414
+ ? (progress) => options.onProgress(progress * 100)
415
+ : undefined;
416
+ await (0, wallet_1.generateTransferProof)(shared_models_1.TXIDVersion.V2_PoseidonMerkle, network, this.railgunWalletID, encryptionKey, options?.showSenderToRecipient ?? false, options?.memoText, erc20AmountRecipients, [], {
417
+ tokenAddress: options.broadcasterFee.tokenAddress,
418
+ amount: options.broadcasterFee.amount,
419
+ }, false, options?.minGasPrice ?? 0n, progressCallback);
420
+ // Step 3: Populate transaction
421
+ const populatedTx = await (0, wallet_1.populateProvedTransfer)(shared_models_1.TXIDVersion.V2_PoseidonMerkle, network, this.railgunWalletID, options?.showSenderToRecipient ?? false, options?.memoText, erc20AmountRecipients, [], {
422
+ tokenAddress: options.broadcasterFee.tokenAddress,
423
+ amount: options.broadcasterFee.amount,
424
+ }, false, options?.minGasPrice ?? 0n, gasDetails);
425
+ return {
426
+ type: 'private_transfer',
427
+ to: populatedTx.to,
428
+ data: populatedTx.data,
429
+ value: BigInt(populatedTx.value || 0),
430
+ gasLimit: BigInt(gasDetails.gasEstimate),
431
+ tokenAddress,
432
+ transferAmount: amount,
433
+ recipientRailgunAddress: toRailgunAddress,
434
+ broadcasterFee: options.broadcasterFee,
435
+ proof: '',
436
+ publicInputs: [],
437
+ };
438
+ }
439
+ // ============================================
440
+ // BALANCE QUERIES
441
+ // ============================================
442
+ /**
443
+ * Scan blockchain for new private transactions
444
+ *
445
+ * Must be called before getBalances() to get latest data.
446
+ * Scans merkletree for encrypted notes belonging to this wallet.
447
+ *
448
+ * @param network - Network to scan
449
+ *
450
+ * @example
451
+ * ```typescript
452
+ * await wallet.scanTransactions(NetworkName.Ethereum);
453
+ * const balances = await wallet.getBalances(NetworkName.Ethereum);
454
+ * ```
455
+ */
456
+ async scanTransactions(network) {
457
+ await (0, wallet_1.refreshBalances)(shared_models_1.TXIDVersion.V2_PoseidonMerkle, network, this.railgunWalletID);
458
+ }
459
+ /**
460
+ * Get private balances for this wallet
461
+ *
462
+ * Returns balances grouped by POI bucket status.
463
+ * Call scanTransactions() first for latest data.
464
+ *
465
+ * @param network - Network to query
466
+ * @param tokenAddresses - Optional filter for specific tokens
467
+ *
468
+ * @returns Array of private balances
469
+ *
470
+ * @example
471
+ * ```typescript
472
+ * const balances = await wallet.getBalances(
473
+ * NetworkName.Ethereum,
474
+ * [USDC_ADDRESS, DAI_ADDRESS]
475
+ * );
476
+ *
477
+ * const spendable = balances.filter(b => b.bucket === BalanceBucket.Spendable);
478
+ * ```
479
+ */
480
+ async getBalances(network, tokenAddresses) {
481
+ const balanceBuckets = await (0, wallet_1.getWalletBalances)(this.railgunWalletID, network);
482
+ const allBalances = [];
483
+ // Iterate through all buckets
484
+ for (const [bucketName, tokenBalances] of Object.entries(balanceBuckets)) {
485
+ const bucket = bucketName;
486
+ for (const [tokenAddress, balance] of Object.entries(tokenBalances)) {
487
+ // Filter by token addresses if provided
488
+ if (tokenAddresses && !tokenAddresses.includes(tokenAddress)) {
489
+ continue;
490
+ }
491
+ allBalances.push({
492
+ tokenAddress,
493
+ amount: BigInt(balance.balance || 0),
494
+ bucket,
495
+ symbol: balance.symbol,
496
+ decimals: balance.decimals,
497
+ });
498
+ }
499
+ }
500
+ return allBalances;
501
+ }
502
+ /**
503
+ * Get balance for single token
504
+ *
505
+ * @param network - Network to query
506
+ * @param tokenAddress - Token contract address
507
+ *
508
+ * @returns Total balance across all buckets
509
+ */
510
+ async getBalance(network, tokenAddress) {
511
+ const balances = await this.getBalances(network, [tokenAddress]);
512
+ return balances.reduce((sum, b) => sum + b.amount, 0n);
513
+ }
514
+ /**
515
+ * Get spendable balance only
516
+ *
517
+ * @param network - Network to query
518
+ * @param tokenAddress - Token contract address
519
+ *
520
+ * @returns Spendable balance (excludes pending/blocked)
521
+ */
522
+ async getSpendableBalance(network, tokenAddress) {
523
+ const balances = await this.getBalances(network, [tokenAddress]);
524
+ return balances
525
+ .filter(b => b.bucket === types_1.BalanceBucket.Spendable)
526
+ .reduce((sum, b) => sum + b.amount, 0n);
527
+ }
528
+ // ============================================
529
+ // WALLET INFO
530
+ // ============================================
531
+ getRailgunAddress() {
532
+ return this.railgunAddress;
533
+ }
534
+ getRailgunWalletID() {
535
+ return this.railgunWalletID;
536
+ }
537
+ }
538
+ exports.RailgunPrivacyWallet = RailgunPrivacyWallet;
539
+ //# sourceMappingURL=railgun-privacy-wallet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"railgun-privacy-wallet.js","sourceRoot":"","sources":["../../utils/privacy/railgun-privacy-wallet.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,sDAWmC;AACnC,oEAAyG;AAEzG,mCAUiB;AACjB,qDAAiD;AAEjD;;;;;;;;;;GAUG;AACH,MAAa,oBAAoB;IACvB,eAAe,CAAS;IACxB,cAAc,CAAS;IAE/B;;OAEG;IACH,YAAoB,eAAuB,EAAE,cAAsB;QACjE,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAED,+CAA+C;IAC/C,4BAA4B;IAC5B,+CAA+C;IAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CACjB,aAAqB,EACrB,QAAgB,EAChB,oBAA6C;QAE7C,IAAI,CAAC,8BAAa,CAAC,aAAa,EAAE,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAA,4BAAmB,EAAC,aAAa,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC;QAExF,OAAO;YACL,eAAe,EAAE,MAAM,CAAC,EAAE;YAC1B,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;YAC3C,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;YAC3C,sBAAsB,EAAE,oBAAoB;SAC7C,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,CACf,aAAqB,EACrB,eAAuB;QAEvB,IAAI,CAAC,8BAAa,CAAC,aAAa,EAAE,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAc,EAAC,aAAa,EAAE,eAAe,EAAE,KAAK,CAAC,CAAC;QAE3E,OAAO,IAAI,oBAAoB,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;IACpE,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAC3B,aAAqB,EACrB,QAAgB,EAChB,YAAoB,EACpB,oBAA6C;QAE7C,6CAA6C;QAC7C,uEAAuE;QACvE,MAAM,UAAU,GAAG,WAAW,YAAY,EAAE,CAAC;QAE7C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC;QAEpF,OAAO;YACL,GAAG,UAAU;YACb,4BAA4B;YAC5B,sBAAsB,EAAE;gBACtB,GAAG,oBAAoB;gBACvB,YAAY,EAAE,sBAAsB;aAC9B;SACT,CAAC;IACJ,CAAC;IAED,+CAA+C;IAC/C,yCAAyC;IACzC,+CAA+C;IAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,KAAK,CAAC,WAAW,CACf,WAAmB,EACnB,YAAoB,EACpB,MAAc,EACd,OAAoB,EACpB,OAAuB;QAEvB,2CAA2C;QAC3C,oDAAoD;QAEpD,0CAA0C;QAC1C,MAAM,EAAE,eAAe,EAAE,GAAG,wDAAa,2BAA2B,GAAC,CAAC;QAEtE,MAAM,WAAW,GAAG,MAAM,eAAe,CACvC,OAAO,EACP,IAAI,CAAC,cAAc,EACnB,YAAY,EACZ,MAAM,CACP,CAAC;QAEF,sBAAsB;QACtB,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC;QAEpC,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,EAAE,EAAE,WAAW,CAAC,EAAE;YAClB,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;YACzD,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW,IAAI,MAAM,CAAC;YACnD,YAAY;YACZ,YAAY,EAAE,MAAM;YACpB,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,GAAG;SACJ,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,oBAAoB,CACxB,WAAmB,EACnB,MAAc,EACd,OAAoB,EACpB,OAAuB;QAEvB,MAAM,EAAE,eAAe,EAAE,GAAG,wDAAa,2BAA2B,GAAC,CAAC;QAEtE,kCAAkC;QAClC,MAAM,kBAAkB,GAAG,4CAA4C,CAAC;QAExE,MAAM,WAAW,GAAG,MAAM,eAAe,CACvC,OAAO,EACP,IAAI,CAAC,cAAc,EACnB,kBAAkB,EAClB,MAAM,CACP,CAAC;QAEF,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC;QAEpC,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,EAAE,EAAE,WAAW,CAAC,EAAE;YAClB,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,IAAI,MAAM,CAAC;YAC1C,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW,IAAI,MAAM,CAAC;YACnD,YAAY,EAAE,kBAAkB;YAChC,YAAY,EAAE,MAAM;YACpB,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,GAAG;SACJ,CAAC;IACJ,CAAC;IAED,+CAA+C;IAC/C,2CAA2C;IAC3C,+CAA+C;IAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,KAAK,CAAC,aAAa,CACjB,SAAiB,EACjB,YAAoB,EACpB,MAAc,EACd,OAAoB,EACpB,aAAqB,EACrB,OAAyB;QAEzB,MAAM,qBAAqB,GAAkC;YAC3D;gBACE,YAAY;gBACZ,MAAM;gBACN,gBAAgB,EAAE,SAAS;aAC5B;SACF,CAAC;QAEF,yBAAyB;QACzB,MAAM,UAAU,GAAG,MAAM,IAAA,uCAA8B,EACrD,2BAAW,CAAC,iBAAiB,EAC7B,OAAO,EACP,IAAI,CAAC,eAAe,EACpB,aAAa,EACb,OAAO,EAAE,QAAQ,EACjB,qBAAqB,EACrB,EAAE,EAAE,OAAO;QACX,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,mBAAmB;QAC7C,OAAO,EAAE,cAAc;YACrB,CAAC,CAAC;gBACE,YAAY,EAAE,OAAO,CAAC,cAAc,CAAC,YAAY;gBACjD,aAAa,EAAE,OAAO,CAAC,cAAc,CAAC,MAAM;aAC7C;YACH,CAAC,CAAC,SAAS,EACb,OAAO,EAAE,oBAAoB,IAAI,IAAI,CACtC,CAAC;QAEF,iCAAiC;QACjC,MAAM,gBAAgB,GAAG,OAAO,EAAE,UAAU;YAC1C,CAAC,CAAC,CAAC,QAAgB,EAAE,EAAE,CAAC,OAAO,CAAC,UAAW,CAAC,QAAQ,GAAG,GAAG,CAAC;YAC3D,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,IAAA,8BAAqB,EACzB,2BAAW,CAAC,iBAAiB,EAC7B,OAAO,EACP,IAAI,CAAC,eAAe,EACpB,aAAa,EACb,OAAO,EAAE,QAAQ,EACjB,qBAAqB,EACrB,EAAE,EACF,OAAO,EAAE,cAAc;YACrB,CAAC,CAAC;gBACE,YAAY,EAAE,OAAO,CAAC,cAAc,CAAC,YAAY;gBACjD,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,MAAM;aACtC;YACH,CAAC,CAAC,SAAS,EACb,OAAO,EAAE,oBAAoB,IAAI,IAAI,EACrC,OAAO,EAAE,WAAW,IAAI,EAAE,EAC1B,gBAAgB,CACjB,CAAC;QAEF,+BAA+B;QAC/B,MAAM,WAAW,GAAG,MAAM,IAAA,+BAAsB,EAC9C,2BAAW,CAAC,iBAAiB,EAC7B,OAAO,EACP,IAAI,CAAC,eAAe,EACpB,qBAAqB,EACrB,EAAE,EACF,OAAO,EAAE,cAAc;YACrB,CAAC,CAAC;gBACE,YAAY,EAAE,OAAO,CAAC,cAAc,CAAC,YAAY;gBACjD,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,MAAM;aACtC;YACH,CAAC,CAAC,SAAS,EACb,OAAO,EAAE,oBAAoB,IAAI,IAAI,EACrC,OAAO,EAAE,WAAW,IAAI,EAAE,EAC1B,UAAU,CACX,CAAC;QAEF,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC;QAEpC,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,EAAE,EAAE,WAAW,CAAC,EAAY;YAC5B,IAAI,EAAE,WAAW,CAAC,IAAc;YAChC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC,CAAC;YACrC,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC;YACxC,YAAY;YACZ,cAAc,EAAE,MAAM;YACtB,gBAAgB,EAAE,SAAS;YAC3B,GAAG;YACH,KAAK,EAAE,EAAE,EAAE,4BAA4B;YACvC,YAAY,EAAE,EAAE;SACjB,CAAC;IACJ,CAAC;IAED,+CAA+C;IAC/C,wCAAwC;IACxC,+CAA+C;IAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;IACH,KAAK,CAAC,oBAAoB,CACxB,gBAAwB,EACxB,YAAoB,EACpB,MAAc,EACd,OAAoB,EACpB,aAAqB,EACrB,OAA+B;QAE/B,MAAM,qBAAqB,GAAkC;YAC3D;gBACE,YAAY;gBACZ,MAAM;gBACN,gBAAgB,EAAE,gBAAgB;aACnC;SACF,CAAC;QAEF,yBAAyB;QACzB,MAAM,UAAU,GAAG,MAAM,IAAA,uCAA8B,EACrD,2BAAW,CAAC,iBAAiB,EAC7B,OAAO,EACP,IAAI,CAAC,eAAe,EACpB,aAAa,EACb,OAAO,EAAE,QAAQ,EACjB,qBAAqB,EACrB,EAAE,EACF,EAAE,WAAW,EAAE,OAAO,EAAE,EACxB;YACE,YAAY,EAAE,OAAO,CAAC,cAAc,CAAC,YAAY;YACjD,aAAa,EAAE,OAAO,CAAC,cAAc,CAAC,MAAM;SAC7C,EACD,KAAK,CAAC,kDAAkD;SACzD,CAAC;QAEF,yBAAyB;QACzB,MAAM,gBAAgB,GAAG,OAAO,EAAE,UAAU;YAC1C,CAAC,CAAC,CAAC,QAAgB,EAAE,EAAE,CAAC,OAAO,CAAC,UAAW,CAAC,QAAQ,GAAG,GAAG,CAAC;YAC3D,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,IAAA,8BAAqB,EACzB,2BAAW,CAAC,iBAAiB,EAC7B,OAAO,EACP,IAAI,CAAC,eAAe,EACpB,aAAa,EACb,OAAO,EAAE,qBAAqB,IAAI,KAAK,EACvC,OAAO,EAAE,QAAQ,EACjB,qBAAqB,EACrB,EAAE,EACF;YACE,YAAY,EAAE,OAAO,CAAC,cAAc,CAAC,YAAY;YACjD,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,MAAM;SACtC,EACD,KAAK,EACL,OAAO,EAAE,WAAW,IAAI,EAAE,EAC1B,gBAAgB,CACjB,CAAC;QAEF,+BAA+B;QAC/B,MAAM,WAAW,GAAG,MAAM,IAAA,+BAAsB,EAC9C,2BAAW,CAAC,iBAAiB,EAC7B,OAAO,EACP,IAAI,CAAC,eAAe,EACpB,OAAO,EAAE,qBAAqB,IAAI,KAAK,EACvC,OAAO,EAAE,QAAQ,EACjB,qBAAqB,EACrB,EAAE,EACF;YACE,YAAY,EAAE,OAAO,CAAC,cAAc,CAAC,YAAY;YACjD,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,MAAM;SACtC,EACD,KAAK,EACL,OAAO,EAAE,WAAW,IAAI,EAAE,EAC1B,UAAU,CACX,CAAC;QAEF,OAAO;YACL,IAAI,EAAE,kBAAkB;YACxB,EAAE,EAAE,WAAW,CAAC,EAAY;YAC5B,IAAI,EAAE,WAAW,CAAC,IAAc;YAChC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC,CAAC;YACrC,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC;YACxC,YAAY;YACZ,cAAc,EAAE,MAAM;YACtB,uBAAuB,EAAE,gBAAgB;YACzC,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,KAAK,EAAE,EAAE;YACT,YAAY,EAAE,EAAE;SACjB,CAAC;IACJ,CAAC;IAED,+CAA+C;IAC/C,kBAAkB;IAClB,+CAA+C;IAE/C;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,gBAAgB,CAAC,OAAoB;QACzC,MAAM,IAAA,wBAAe,EAAC,2BAAW,CAAC,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;IACtF,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,KAAK,CAAC,WAAW,CACf,OAAoB,EACpB,cAAyB;QAEzB,MAAM,cAAc,GAAG,MAAM,IAAA,0BAAiB,EAAC,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAE9E,MAAM,WAAW,GAAqB,EAAE,CAAC;QAEzC,8BAA8B;QAC9B,KAAK,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;YACzE,MAAM,MAAM,GAAG,UAA2B,CAAC;YAE3C,KAAK,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAoB,CAAC,EAAE,CAAC;gBAC3E,wCAAwC;gBACxC,IAAI,cAAc,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;oBAC7D,SAAS;gBACX,CAAC;gBAED,WAAW,CAAC,IAAI,CAAC;oBACf,YAAY;oBACZ,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC;oBACpC,MAAM;oBACN,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;iBAC3B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,UAAU,CAAC,OAAoB,EAAE,YAAoB;QACzD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;QACjE,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,mBAAmB,CAAC,OAAoB,EAAE,YAAoB;QAClE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;QACjE,OAAO,QAAQ;aACZ,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,qBAAa,CAAC,SAAS,CAAC;aACjD,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,+CAA+C;IAC/C,cAAc;IACd,+CAA+C;IAE/C,iBAAiB;QACf,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;CACF;AA9nBD,oDA8nBC"}