@utxopia/sdk 0.1.0-alpha.2 → 0.1.0-alpha.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 (142) hide show
  1. package/README.md +214 -108
  2. package/{packages/sdk/dist → dist}/client.d.ts +25 -1
  3. package/{packages/sdk/dist → dist}/client.js +36 -1
  4. package/{packages/sdk/dist → dist}/crypto-ed25519.d.ts +14 -0
  5. package/{packages/sdk/dist → dist}/crypto-ed25519.js +14 -0
  6. package/{packages/sdk/dist → dist}/index.d.ts +3 -3
  7. package/{packages/sdk/dist → dist}/index.js +3 -3
  8. package/{packages/sdk/dist → dist}/instructions.d.ts +28 -11
  9. package/{packages/sdk/dist → dist}/instructions.js +45 -15
  10. package/{packages/sdk/dist → dist}/stealth.d.ts +104 -9
  11. package/{packages/sdk/dist → dist}/stealth.js +146 -14
  12. package/{packages/sdk/dist → dist}/taproot.d.ts +39 -2
  13. package/{packages/sdk/dist → dist}/taproot.js +54 -2
  14. package/package.json +86 -63
  15. package/src/announcement-client.ts +457 -0
  16. package/src/auditor-ciphertext.ts +181 -0
  17. package/src/auditor.ts +409 -0
  18. package/src/bitcoin/ika.ts +103 -0
  19. package/src/bitcoin/index.ts +5 -0
  20. package/src/bound-params.ts +322 -0
  21. package/src/chadbuffer.ts +603 -0
  22. package/src/circomlibjs.d.ts +51 -0
  23. package/src/claim-link.ts +53 -0
  24. package/src/client.ts +638 -0
  25. package/src/commitment-tree.ts +736 -0
  26. package/src/config.ts +772 -0
  27. package/src/core/esplora.ts +332 -0
  28. package/src/core/mempool.ts +159 -0
  29. package/src/crypto-babyjub.ts +385 -0
  30. package/src/crypto-ed25519.ts +297 -0
  31. package/src/crypto.ts +199 -0
  32. package/src/event-client.ts +231 -0
  33. package/src/events.ts +384 -0
  34. package/src/explorer.ts +300 -0
  35. package/src/index.ts +902 -0
  36. package/src/instructions.ts +2820 -0
  37. package/src/keys.ts +1228 -0
  38. package/src/logger.ts +41 -0
  39. package/src/magicblock.ts +278 -0
  40. package/src/merkle.ts +197 -0
  41. package/src/note.ts +754 -0
  42. package/src/pda.ts +516 -0
  43. package/src/pool-state.ts +176 -0
  44. package/src/poseidon.ts +175 -0
  45. package/src/prover/index.ts +19 -0
  46. package/src/prover/mobile.ts +303 -0
  47. package/src/prover/web.ts +771 -0
  48. package/src/psbt.ts +333 -0
  49. package/src/selective-disclosure.ts +284 -0
  50. package/src/sender-memo.ts +343 -0
  51. package/src/snarkjs.d.ts +19 -0
  52. package/src/sns-resolver.ts +333 -0
  53. package/src/solana/connection.ts +189 -0
  54. package/src/solana/priority-fee.ts +201 -0
  55. package/src/spend-doc.ts +163 -0
  56. package/src/stealth.ts +1477 -0
  57. package/src/taproot.ts +707 -0
  58. package/src/token-registry.ts +207 -0
  59. package/src/utils/encoding.ts +33 -0
  60. package/src/vk-registry.ts +295 -0
  61. package/LICENSE +0 -21
  62. package/packages/btc-client/src/esplora-client.ts +0 -153
  63. package/packages/btc-client/src/index.ts +0 -3
  64. package/packages/btc-client/src/op-return.ts +0 -93
  65. package/packages/btc-client/src/types.ts +0 -112
  66. package/packages/sdk/README.md +0 -277
  67. /package/{packages/sdk/dist → dist}/announcement-client.d.ts +0 -0
  68. /package/{packages/sdk/dist → dist}/announcement-client.js +0 -0
  69. /package/{packages/sdk/dist → dist}/auditor-ciphertext.d.ts +0 -0
  70. /package/{packages/sdk/dist → dist}/auditor-ciphertext.js +0 -0
  71. /package/{packages/sdk/dist → dist}/auditor.d.ts +0 -0
  72. /package/{packages/sdk/dist → dist}/auditor.js +0 -0
  73. /package/{packages/sdk/dist → dist}/bitcoin/ika.d.ts +0 -0
  74. /package/{packages/sdk/dist → dist}/bitcoin/ika.js +0 -0
  75. /package/{packages/sdk/dist → dist}/bitcoin/index.d.ts +0 -0
  76. /package/{packages/sdk/dist → dist}/bitcoin/index.js +0 -0
  77. /package/{packages/sdk/dist → dist}/bound-params.d.ts +0 -0
  78. /package/{packages/sdk/dist → dist}/bound-params.js +0 -0
  79. /package/{packages/sdk/dist → dist}/chadbuffer.d.ts +0 -0
  80. /package/{packages/sdk/dist → dist}/chadbuffer.js +0 -0
  81. /package/{packages/sdk/dist → dist}/claim-link.d.ts +0 -0
  82. /package/{packages/sdk/dist → dist}/claim-link.js +0 -0
  83. /package/{packages/sdk/dist → dist}/commitment-tree.d.ts +0 -0
  84. /package/{packages/sdk/dist → dist}/commitment-tree.js +0 -0
  85. /package/{packages/sdk/dist → dist}/config.d.ts +0 -0
  86. /package/{packages/sdk/dist → dist}/config.js +0 -0
  87. /package/{packages/sdk/dist → dist}/core/esplora.d.ts +0 -0
  88. /package/{packages/sdk/dist → dist}/core/esplora.js +0 -0
  89. /package/{packages/sdk/dist → dist}/core/mempool.d.ts +0 -0
  90. /package/{packages/sdk/dist → dist}/core/mempool.js +0 -0
  91. /package/{packages/sdk/dist → dist}/crypto-babyjub.d.ts +0 -0
  92. /package/{packages/sdk/dist → dist}/crypto-babyjub.js +0 -0
  93. /package/{packages/sdk/dist → dist}/crypto.d.ts +0 -0
  94. /package/{packages/sdk/dist → dist}/crypto.js +0 -0
  95. /package/{packages/sdk/dist → dist}/event-client.d.ts +0 -0
  96. /package/{packages/sdk/dist → dist}/event-client.js +0 -0
  97. /package/{packages/sdk/dist → dist}/events.d.ts +0 -0
  98. /package/{packages/sdk/dist → dist}/events.js +0 -0
  99. /package/{packages/sdk/dist → dist}/explorer.d.ts +0 -0
  100. /package/{packages/sdk/dist → dist}/explorer.js +0 -0
  101. /package/{packages/sdk/dist → dist}/keys.d.ts +0 -0
  102. /package/{packages/sdk/dist → dist}/keys.js +0 -0
  103. /package/{packages/sdk/dist → dist}/logger.d.ts +0 -0
  104. /package/{packages/sdk/dist → dist}/logger.js +0 -0
  105. /package/{packages/sdk/dist → dist}/magicblock.d.ts +0 -0
  106. /package/{packages/sdk/dist → dist}/magicblock.js +0 -0
  107. /package/{packages/sdk/dist → dist}/merkle.d.ts +0 -0
  108. /package/{packages/sdk/dist → dist}/merkle.js +0 -0
  109. /package/{packages/sdk/dist → dist}/note.d.ts +0 -0
  110. /package/{packages/sdk/dist → dist}/note.js +0 -0
  111. /package/{packages/sdk/dist → dist}/pda.d.ts +0 -0
  112. /package/{packages/sdk/dist → dist}/pda.js +0 -0
  113. /package/{packages/sdk/dist → dist}/pool-state.d.ts +0 -0
  114. /package/{packages/sdk/dist → dist}/pool-state.js +0 -0
  115. /package/{packages/sdk/dist → dist}/poseidon.d.ts +0 -0
  116. /package/{packages/sdk/dist → dist}/poseidon.js +0 -0
  117. /package/{packages/sdk/dist → dist}/prover/index.d.ts +0 -0
  118. /package/{packages/sdk/dist → dist}/prover/index.js +0 -0
  119. /package/{packages/sdk/dist → dist}/prover/mobile.d.ts +0 -0
  120. /package/{packages/sdk/dist → dist}/prover/mobile.js +0 -0
  121. /package/{packages/sdk/dist → dist}/prover/web.d.ts +0 -0
  122. /package/{packages/sdk/dist → dist}/prover/web.js +0 -0
  123. /package/{packages/sdk/dist → dist}/psbt.d.ts +0 -0
  124. /package/{packages/sdk/dist → dist}/psbt.js +0 -0
  125. /package/{packages/sdk/dist → dist}/selective-disclosure.d.ts +0 -0
  126. /package/{packages/sdk/dist → dist}/selective-disclosure.js +0 -0
  127. /package/{packages/sdk/dist → dist}/sender-memo.d.ts +0 -0
  128. /package/{packages/sdk/dist → dist}/sender-memo.js +0 -0
  129. /package/{packages/sdk/dist → dist}/sns-resolver.d.ts +0 -0
  130. /package/{packages/sdk/dist → dist}/sns-resolver.js +0 -0
  131. /package/{packages/sdk/dist → dist}/solana/connection.d.ts +0 -0
  132. /package/{packages/sdk/dist → dist}/solana/connection.js +0 -0
  133. /package/{packages/sdk/dist → dist}/solana/priority-fee.d.ts +0 -0
  134. /package/{packages/sdk/dist → dist}/solana/priority-fee.js +0 -0
  135. /package/{packages/sdk/dist → dist}/spend-doc.d.ts +0 -0
  136. /package/{packages/sdk/dist → dist}/spend-doc.js +0 -0
  137. /package/{packages/sdk/dist → dist}/token-registry.d.ts +0 -0
  138. /package/{packages/sdk/dist → dist}/token-registry.js +0 -0
  139. /package/{packages/sdk/dist → dist}/utils/encoding.d.ts +0 -0
  140. /package/{packages/sdk/dist → dist}/utils/encoding.js +0 -0
  141. /package/{packages/sdk/dist → dist}/vk-registry.d.ts +0 -0
  142. /package/{packages/sdk/dist → dist}/vk-registry.js +0 -0
@@ -0,0 +1,322 @@
1
+ /**
2
+ * Bound Parameters Hash for JoinSplit transactions
3
+ *
4
+ * The operation hash binds transaction metadata to the proof:
5
+ * - treeNumber: Which commitment tree (for multi-tree support)
6
+ * - unshieldAddress: Recipient for public unshield (null = private transfer)
7
+ * - chainId: Prevents cross-chain replay
8
+ * - stealthDataHash: SHA256 of concatenated stealth data (prevents relayer tampering)
9
+ *
10
+ * Hash: SHA256(serialize(params)) mod BN254_SCALAR_FIELD
11
+ *
12
+ * Solana callers must wrap this operation hash with
13
+ * `computeSolanaDomainBoundParamsHash()` before generating a proof.
14
+ */
15
+
16
+ import { sha256 } from "@noble/hashes/sha2.js";
17
+ import { BN254_FIELD_PRIME, bytesToBigint } from "./crypto";
18
+ import { poseidonHashSync } from "./poseidon";
19
+
20
+ /** Bound params mode: transfer(0), unshield(1), redeem(2) */
21
+ export type BoundParamsMode = 'transfer' | 'unshield' | 'redeem';
22
+
23
+ export interface BoundParams {
24
+ /** Tree number (0 for default) */
25
+ treeNumber: number;
26
+ /** Unshield recipient address (null = private transfer, 32 bytes = public unshield/redeem) */
27
+ unshieldAddress: Uint8Array | null;
28
+ /** Chain ID (prevents cross-chain replay) */
29
+ chainId: bigint;
30
+ /** Mode flag: 'transfer'(0), 'unshield'(1), 'redeem'(2). Defaults to inferred from unshieldAddress. */
31
+ mode?: BoundParamsMode;
32
+ /** SHA256 of concatenated stealth data (prevents relayer from corrupting change outputs) */
33
+ stealthDataHash: Uint8Array;
34
+ /**
35
+ * Requester pubkey (32 bytes) — REQUIRED for redeem. Binds the proof to the signing account
36
+ * that becomes RedemptionRequest.requester so a privileged orderflow actor cannot replay the
37
+ * proof under their own key. Ignored for transfer/unshield.
38
+ */
39
+ requester?: Uint8Array;
40
+ }
41
+
42
+ export type SolanaPrivacyDomainKind = "public" | "institution";
43
+
44
+ export interface SolanaPrivacyDomainContext {
45
+ programId: Uint8Array;
46
+ poolState: Uint8Array;
47
+ kind: SolanaPrivacyDomainKind;
48
+ }
49
+
50
+ const SOLANA_DOMAIN_TAG = new TextEncoder().encode("UTXOPIA_DOMAIN_V1");
51
+
52
+ function assert32Bytes(value: Uint8Array, name: string): void {
53
+ if (value.length !== 32) {
54
+ throw new Error(`${name} must be 32 bytes`);
55
+ }
56
+ }
57
+
58
+ function u64le(value: bigint): Uint8Array {
59
+ if (value < 0n || value > 0xffffffffffffffffn) {
60
+ throw new Error("chainId must fit in u64");
61
+ }
62
+ const bytes = new Uint8Array(8);
63
+ let remaining = value;
64
+ for (let i = 0; i < bytes.length; i++) {
65
+ bytes[i] = Number(remaining & 0xffn);
66
+ remaining >>= 8n;
67
+ }
68
+ return bytes;
69
+ }
70
+
71
+ /**
72
+ * Compute the canonical public/institution domain field for Solana.
73
+ *
74
+ * SHA256("UTXOPIA_DOMAIN_V1" || chainIdLE || programId || poolState || kind)
75
+ * reduced modulo BN254 Fr. The on-chain verifier recomputes this from the
76
+ * actual program, pool account, and PoolState.permissioned flag.
77
+ */
78
+ export function computeSolanaDomainSeparator(
79
+ context: SolanaPrivacyDomainContext,
80
+ chainId: bigint = SOLANA_BOUND_CHAIN_ID,
81
+ ): bigint {
82
+ assert32Bytes(context.programId, "programId");
83
+ assert32Bytes(context.poolState, "poolState");
84
+ if (context.kind !== "public" && context.kind !== "institution") {
85
+ throw new Error("kind must be public or institution");
86
+ }
87
+ const preimage = new Uint8Array(SOLANA_DOMAIN_TAG.length + 8 + 32 + 32 + 1);
88
+ let offset = 0;
89
+ preimage.set(SOLANA_DOMAIN_TAG, offset);
90
+ offset += SOLANA_DOMAIN_TAG.length;
91
+ preimage.set(u64le(chainId), offset);
92
+ offset += 8;
93
+ preimage.set(context.programId, offset);
94
+ offset += 32;
95
+ preimage.set(context.poolState, offset);
96
+ offset += 32;
97
+ preimage[offset] = context.kind === "institution" ? 1 : 0;
98
+ return bytesToBigint(sha256(preimage)) % BN254_FIELD_PRIME;
99
+ }
100
+
101
+ /**
102
+ * Bind an operation-specific hash to its exact Solana privacy domain.
103
+ *
104
+ * This occupies the existing boundParamsHash public input, so circuit/VK
105
+ * dimensions remain unchanged while proofs become non-replayable across pools.
106
+ */
107
+ export function computeSolanaDomainBoundParamsHash(
108
+ params: BoundParams,
109
+ context: SolanaPrivacyDomainContext,
110
+ ): bigint {
111
+ if (
112
+ params.chainId !== SOLANA_DEVNET_BOUND_CHAIN_ID
113
+ && params.chainId !== SOLANA_MAINNET_BOUND_CHAIN_ID
114
+ ) {
115
+ throw new Error("Solana domain binding requires a supported Solana chain ID");
116
+ }
117
+ return poseidonHashSync([
118
+ computeSolanaDomainSeparator(context, params.chainId),
119
+ computeBoundParamsHash(params),
120
+ ]);
121
+ }
122
+
123
+ /**
124
+ * Compute SHA256 hash of concatenated stealth data arrays.
125
+ * Returns 32-byte hash, or all zeros if no stealth data.
126
+ */
127
+ export function computeStealthDataHash(stealthData: Uint8Array[]): Uint8Array {
128
+ // Always SHA256 the concatenation — even for empty arrays.
129
+ // On-chain: sha256(&data[stealth_start..stealth_end]) — empty slice → sha256("")
130
+ const totalLen = stealthData.reduce((sum, sd) => sum + sd.length, 0);
131
+ const concat = new Uint8Array(totalLen);
132
+ let offset = 0;
133
+ for (const sd of stealthData) {
134
+ concat.set(sd, offset);
135
+ offset += sd.length;
136
+ }
137
+ return sha256(concat);
138
+ }
139
+
140
+ /**
141
+ * Compute the operation-specific bound parameters hash.
142
+ *
143
+ * Solana callers must wrap this with
144
+ * `computeSolanaDomainBoundParamsHash()` to bind the program and pool.
145
+ *
146
+ * Deterministic serialization:
147
+ * - treeNumber: 4 bytes LE
148
+ * - flag: 1 byte (0=transfer, 1=unshield, 2=redeem)
149
+ * - unshieldAddress: 32 bytes (zeros if null)
150
+ * - chainId: 8 bytes LE
151
+ * - stealthDataHash: 32 bytes (SHA256 of concatenated stealth data)
152
+ * - requester: 32 bytes (redeem only — appended, extending the buffer to 109 bytes)
153
+ *
154
+ * Total: 77 bytes (transfer/unshield) or 109 bytes (redeem) → SHA256 → mod BN254
155
+ */
156
+ export function computeBoundParamsHash(params: BoundParams): bigint {
157
+ const isRedeem = params.mode === 'redeem';
158
+ // Redeem binds the requester pubkey, extending the preimage by 32 bytes (must match the
159
+ // on-chain compute_bound_params_hash_redeem layout).
160
+ const buf = new Uint8Array(isRedeem ? 109 : 77);
161
+ const view = new DataView(buf.buffer);
162
+
163
+ // treeNumber (4 bytes LE)
164
+ view.setUint32(0, params.treeNumber, true);
165
+
166
+ // flag byte: transfer=0, unshield=1, redeem=2
167
+ if (isRedeem) {
168
+ buf[4] = 2;
169
+ } else if (params.mode === 'unshield' || params.unshieldAddress) {
170
+ buf[4] = 1;
171
+ } else {
172
+ buf[4] = 0;
173
+ }
174
+
175
+ // unshieldAddress (32 bytes, zeros if null)
176
+ if (params.unshieldAddress) {
177
+ buf.set(params.unshieldAddress.slice(0, 32), 5);
178
+ }
179
+
180
+ // chainId (8 bytes LE)
181
+ const chainIdBuf = new Uint8Array(8);
182
+ let chainId = params.chainId;
183
+ for (let i = 0; i < 8; i++) {
184
+ chainIdBuf[i] = Number(chainId & 0xffn);
185
+ chainId >>= 8n;
186
+ }
187
+ buf.set(chainIdBuf, 37);
188
+
189
+ // stealthDataHash (32 bytes)
190
+ buf.set(params.stealthDataHash.slice(0, 32), 45);
191
+
192
+ // requester (32 bytes) — redeem only
193
+ if (isRedeem) {
194
+ if (!params.requester || params.requester.length !== 32) {
195
+ throw new Error("redeem bound params require a 32-byte requester pubkey");
196
+ }
197
+ buf.set(params.requester.slice(0, 32), 77);
198
+ }
199
+
200
+ // SHA256 → mod BN254
201
+ const hash = sha256(buf);
202
+ return bytesToBigint(hash) % BN254_FIELD_PRIME;
203
+ }
204
+
205
+ /** Canonical chain ids folded into bound-params hashes (must match on-chain). */
206
+ export const SOLANA_MAINNET_BOUND_CHAIN_ID = 101n;
207
+ export const SOLANA_DEVNET_BOUND_CHAIN_ID = 103n;
208
+ /** Backward-compatible devnet alias. Prefer the network-specific constants. */
209
+ export const SOLANA_BOUND_CHAIN_ID = SOLANA_DEVNET_BOUND_CHAIN_ID;
210
+
211
+ /**
212
+ * Default bound params for Solana devnet (private transfer)
213
+ */
214
+ export function createTransferBoundParams(
215
+ stealthDataHash: Uint8Array,
216
+ chainId: bigint = 103n,
217
+ treeNumber: number = 0,
218
+ ): BoundParams {
219
+ return {
220
+ treeNumber,
221
+ unshieldAddress: null,
222
+ chainId,
223
+ stealthDataHash,
224
+ };
225
+ }
226
+
227
+ /** @deprecated Use createTransferBoundParams instead */
228
+ export const DEFAULT_BOUND_PARAMS: BoundParams = {
229
+ treeNumber: 0,
230
+ unshieldAddress: null,
231
+ chainId: 103n,
232
+ stealthDataHash: new Uint8Array(32),
233
+ };
234
+
235
+ /**
236
+ * Create bound params for a redeem (JoinSplit → BTC withdrawal, multi-output)
237
+ *
238
+ * The BTC scriptPubKeys are concatenated and SHA-256 hashed into the address field
239
+ * so the proof cryptographically binds ALL withdrawal destinations.
240
+ *
241
+ * For single output: SHA256(script_1) — no special case.
242
+ * For multi-output: SHA256(script_1 || script_2 || ...)
243
+ *
244
+ * `requester` is the 32-byte pubkey of the signer that will submit the redeem (becomes
245
+ * RedemptionRequest.requester); it is bound into the hash so the proof cannot be replayed
246
+ * under a different signer.
247
+ */
248
+ function u32le(n: number): Uint8Array {
249
+ const b = new Uint8Array(4);
250
+ new DataView(b.buffer).setUint32(0, n >>> 0, true);
251
+ return b;
252
+ }
253
+
254
+ export function createRedeemBoundParams(
255
+ btcScripts: Uint8Array | Uint8Array[],
256
+ stealthDataHash: Uint8Array,
257
+ requester: Uint8Array,
258
+ chainId: bigint = 103n,
259
+ treeNumber: number = 0,
260
+ ): BoundParams {
261
+ if (!requester || requester.length !== 32) {
262
+ throw new Error("createRedeemBoundParams requires a 32-byte requester pubkey");
263
+ }
264
+ // Normalize to array
265
+ const scripts = btcScripts instanceof Uint8Array ? [btcScripts] : btcScripts;
266
+ // Length-prefixed scripts hash (audit #4): sha256(u32le(count) || per-script
267
+ // [u32le(len) || bytes]). Binds the script boundaries so a redeem proof cannot be
268
+ // replayed with the scripts re-partitioned to the same concatenation. Must match the
269
+ // on-chain Solana `length_prefixed_hash` in compute_bound_params_hash_redeem.
270
+ const lpParts: Uint8Array[] = [u32le(scripts.length)];
271
+ for (const s of scripts) {
272
+ lpParts.push(u32le(s.length), s);
273
+ }
274
+ const lpTotal = lpParts.reduce((sum, p) => sum + p.length, 0);
275
+ const lp = new Uint8Array(lpTotal);
276
+ let off = 0;
277
+ for (const p of lpParts) {
278
+ lp.set(p, off);
279
+ off += p.length;
280
+ }
281
+ const scriptHash = sha256(lp);
282
+ return {
283
+ treeNumber,
284
+ unshieldAddress: scriptHash,
285
+ chainId,
286
+ mode: 'redeem',
287
+ stealthDataHash,
288
+ requester,
289
+ };
290
+ }
291
+
292
+
293
+ /**
294
+ * Create bound params for an unshield (public withdrawal, multi-output)
295
+ *
296
+ * For multi-output: destinations_hash = SHA256(owner_1 || owner_2 || ...)
297
+ * For single output: SHA256(owner_1) — no special case.
298
+ */
299
+ export function createUnshieldBoundParams(
300
+ recipientAddresses: Uint8Array | Uint8Array[],
301
+ stealthDataHash: Uint8Array,
302
+ chainId: bigint = 103n,
303
+ treeNumber: number = 0,
304
+ ): BoundParams {
305
+ // Normalize to array
306
+ const addrs = recipientAddresses instanceof Uint8Array ? [recipientAddresses] : recipientAddresses;
307
+ // Concatenate all addresses
308
+ const totalLen = addrs.reduce((sum, a) => sum + a.length, 0);
309
+ const concat = new Uint8Array(totalLen);
310
+ let off = 0;
311
+ for (const a of addrs) {
312
+ concat.set(a, off);
313
+ off += a.length;
314
+ }
315
+ const addressHash = sha256(concat);
316
+ return {
317
+ treeNumber,
318
+ unshieldAddress: addressHash,
319
+ chainId,
320
+ stealthDataHash,
321
+ };
322
+ }