@unionlabs/payments 0.1.0

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.
@@ -0,0 +1,835 @@
1
+ /**
2
+ * TypeScript SDK for privacy-preserving transfers using Union's ZK proof system.
3
+ *
4
+ * @remarks
5
+ * @see https://pdfs.cdn.union.build/union-private-bridging.pdf
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+
10
+ import { Address } from 'viem';
11
+ import { GetProofReturnType } from 'viem';
12
+ import { Hash } from 'viem';
13
+ import { Hex } from 'viem';
14
+ import { PublicClient } from 'viem';
15
+ import { WalletClient } from 'viem';
16
+ import { Withdrawal } from 'viem';
17
+
18
+ /**
19
+ * Client for attestation service that signs poseidon(unspendable_address, beneficiary)
20
+ * @public
21
+ */
22
+ export declare class AttestationClient {
23
+ private baseUrl;
24
+ private apiKey;
25
+ constructor(baseUrl: string, apiKey: string);
26
+ getAttestation(unspendableAddress: Address, beneficiary: Address): Promise<AttestationResponse>;
27
+ }
28
+
29
+ /**
30
+ * @public
31
+ */
32
+ export declare interface AttestationRequest {
33
+ unspendableAddress: Address;
34
+ beneficiary: Address;
35
+ }
36
+
37
+ /**
38
+ * @public
39
+ */
40
+ export declare interface AttestationResponse {
41
+ /** Poseidon hash of (unspendableAddress, beneficiary) */
42
+ attestedMessage: Hex;
43
+ signature: Hex;
44
+ }
45
+
46
+ /**
47
+ * @public
48
+ */
49
+ export declare interface BalanceInfo {
50
+ /** Pending deposits not yet visible to light client */
51
+ pending: bigint;
52
+ /** Deposits visible to the light client (provable balance) */
53
+ confirmed: bigint;
54
+ /** Already redeemed via nullifier */
55
+ redeemed: bigint;
56
+ /** Available for redemption (confirmed - redeemed) */
57
+ available: bigint;
58
+ /** Light client height used for confirmed balance */
59
+ lightClientHeight: bigint;
60
+ /** Latest height for the pending balance */
61
+ latestHeight: bigint;
62
+ }
63
+
64
+ export declare namespace Client {
65
+ export {
66
+ ClientOptions,
67
+ UpdateLightClientOptions,
68
+ DepositOptions,
69
+ GetBalanceOptions,
70
+ RedeemOptions,
71
+ make,
72
+ UnionPrivatePayments,
73
+ waitForBlockCondition
74
+ }
75
+ }
76
+
77
+ /**
78
+ * @public
79
+ */
80
+ export declare interface ClientOptions {
81
+ proverUrl?: URL | undefined;
82
+ rpcUrl: URL;
83
+ chainId: bigint;
84
+ assetAddress: Address;
85
+ attestationUrl?: string | undefined;
86
+ attestorApiKey?: string | undefined;
87
+ }
88
+
89
+ /**
90
+ * Compute the nullifier: Poseidon2(0xDEAD || chainId || secret)
91
+ * @public
92
+ */
93
+ export declare function computeNullifier(secret: Hex, dstChainId: bigint): bigint;
94
+
95
+ /**
96
+ * Compute the storage slot for an ERC20 balance mapping: keccak256(abi.encode(address, slot))
97
+ * @public
98
+ */
99
+ export declare function computeStorageSlot(address: Address, mappingSlot: bigint): Hex;
100
+
101
+ /**
102
+ * Compute the unspendable address: bottom 160 bits of
103
+ * Poseidon2(0xDEAF || dstChainId || secret || beneficiary1..4)
104
+ * @public
105
+ */
106
+ export declare function computeUnspendableAddress(secret: Hex, dstChainId: bigint, beneficiaries: [Address, Address, Address, Address]): Address;
107
+
108
+ /**
109
+ * @public
110
+ */
111
+ export declare interface ConsensusState {
112
+ stateRoot: Hash;
113
+ }
114
+
115
+ /**
116
+ * @public
117
+ */
118
+ export declare interface CounterpartyInfo {
119
+ tokenAddressKey: Hash;
120
+ balanceSlot: Hash;
121
+ }
122
+
123
+ /**
124
+ * @public
125
+ */
126
+ export declare interface DepositOptions {
127
+ /** The 32-byte secret payment key as a hex string */
128
+ paymentKey: Hex;
129
+ /** Array of 0-4 beneficiary addresses*/
130
+ beneficiaries: Address[];
131
+ /** Amount to deposit (in underlying token's smallest unit) */
132
+ amount: bigint;
133
+ /** viem WalletClient with account and chain configured */
134
+ walletClient: WalletClient;
135
+ }
136
+
137
+ /**
138
+ * Result from deposit() after wrapping and transferring tokens to the unspendable address.
139
+ * @public
140
+ */
141
+ export declare interface DepositResult {
142
+ /** Transaction hash of the deposit */
143
+ txHash: Hash;
144
+ /** The unspendable deposit address derived from the secret */
145
+ depositAddress: Address;
146
+ /** Address of the underlying token that was wrapped */
147
+ underlyingToken: Address;
148
+ /** Chain ID where the deposit occurred */
149
+ chainId: bigint;
150
+ /** Block height of deposit transaction */
151
+ height: bigint;
152
+ }
153
+
154
+ /**
155
+ * Deposit underlying tokens to ZAsset and transfer to a deposit address.
156
+ * Executes 3 transactions: approve → deposit → transfer.
157
+ *
158
+ * @param rpcUrl - RPC URL for the chain
159
+ * @param zAssetAddress - Address of the ZAsset contract
160
+ * @param depositAddress - Address to receive the ZAsset tokens (derived from secret)
161
+ * @param amount - Amount to deposit (in underlying token's smallest unit)
162
+ * @param walletClient - viem WalletClient with account and chain configured
163
+ * @returns Transaction hash of the final transfer, underlying token address, and chain ID
164
+ * @public
165
+ */
166
+ export declare function depositToZAsset(rpcUrl: string, zAssetAddress: Address, depositAddress: Address, amount: bigint, walletClient: WalletClient): Promise<DepositToZAssetResult>;
167
+
168
+ /**
169
+ * @public
170
+ */
171
+ export declare interface DepositToZAssetResult {
172
+ txHash: Hash;
173
+ underlyingToken: Address;
174
+ chainId: bigint;
175
+ }
176
+
177
+ /**
178
+ * Deterministically shuffle light clients using the secret as seed.
179
+ * Same secret always produces the same ordering for privacy.
180
+ * @public
181
+ */
182
+ export declare function deterministicShuffleClients(clients: LightClientData[], secret: Hex): LightClientData[];
183
+
184
+ /**
185
+ * @public
186
+ */
187
+ export declare function fetchLightClients(dstClient: RpcClient, zassetAddress: Address, clientIds: number[]): Promise<LightClientData[]>;
188
+
189
+ /**
190
+ * @public
191
+ */
192
+ export declare function fetchMptProof(srcClient: RpcClient, tokenAddress: Address, storageSlot: Hex, blockNumber: bigint): Promise<MptProofData>;
193
+
194
+ /**
195
+ * Result from redeem() containing the transaction hash and proof details.
196
+ * @public
197
+ */
198
+ export declare interface FullRedeemResult {
199
+ /** Transaction hash of the redemption */
200
+ txHash: Hash;
201
+ /** The generated proof (for record-keeping) */
202
+ proof: ProofJSON;
203
+ /** Metadata about the redemption */
204
+ metadata: ProofMetadata;
205
+ }
206
+
207
+ /**
208
+ * Generate a random secret valid for BN254 scalar field
209
+ * @public
210
+ */
211
+ export declare function generatePaymentKey(): Hex;
212
+
213
+ /**
214
+ * Combined result from generateProof() containing the proof and associated metadata.
215
+ * @public
216
+ */
217
+ export declare interface GenerateProofResult {
218
+ /** Proof generation result from the prover */
219
+ proof: ProofResult;
220
+ /** Metadata for constructing the redeem transaction (present on success) */
221
+ metadata?: ProofMetadata;
222
+ }
223
+
224
+ /**
225
+ * @public
226
+ */
227
+ export declare interface GetBalanceOptions {
228
+ /** The deposit address (unspendable address) */
229
+ depositAddress: Address;
230
+ /** The nullifier for this paymentKey */
231
+ nullifier: bigint;
232
+ /** The light client ID to use for querying the source chain state */
233
+ clientId: number;
234
+ }
235
+
236
+ /**
237
+ * Light client state data used for proof generation and balance queries.
238
+ * Light clients provide verified blockchain state roots via IBC.
239
+ * @public
240
+ */
241
+ export declare interface LightClientData {
242
+ /** Unique identifier for this light client */
243
+ clientId: number;
244
+ /** Block height at which this state was captured */
245
+ height: bigint;
246
+ /** Ethereum state root at this height */
247
+ stateRoot: Hash;
248
+ }
249
+
250
+ /**
251
+ * Construct a {@link UnionPrivatePayments} client.
252
+ *
253
+ * @throws Error if asset is unrecognized.
254
+ * @public
255
+ */
256
+ declare const make: (options: ClientOptions) => UnionPrivatePayments;
257
+
258
+ /**
259
+ * @public
260
+ */
261
+ export declare interface MptProofData {
262
+ accountProof: Hex[];
263
+ storageProof: Hex[];
264
+ storageValue: Hex;
265
+ storageRoot: Hash;
266
+ }
267
+
268
+ /**
269
+ * @public
270
+ */
271
+ export declare function parseProofJson(proofJsonBytes: Uint8Array): ProofJSON;
272
+
273
+ /**
274
+ * @public
275
+ */
276
+ export declare interface ProofJSON {
277
+ proof: [string, string, string, string, string, string, string, string];
278
+ commitments: [string, string];
279
+ commitmentPok: [string, string];
280
+ publicInputs: string[];
281
+ }
282
+
283
+ /**
284
+ * @public
285
+ */
286
+ export declare function proofJsonToRedeemParams(proofJson: ProofJSON, metadata: RedeemMetadata): RedeemParams;
287
+
288
+ /**
289
+ * Client-side metadata derived from witness inputs (NOT from the prover)
290
+ * @public
291
+ */
292
+ export declare interface ProofMetadata {
293
+ depositAddress: Address;
294
+ beneficiary: Address;
295
+ value: bigint;
296
+ lightClients: LightClientData[];
297
+ nullifier: bigint;
298
+ }
299
+
300
+ /**
301
+ * Result from the prover server after proof generation.
302
+ * @public
303
+ */
304
+ export declare interface ProofResult {
305
+ /** Whether proof generation succeeded */
306
+ success: boolean;
307
+ /** Serialized proof data (only present on success) */
308
+ proofJson?: Uint8Array;
309
+ /** Error message (only present on failure) */
310
+ error?: string;
311
+ /** Timestamp when the proof was created */
312
+ createdAt?: Date;
313
+ }
314
+
315
+ /**
316
+ * Prover client for communicating with the prover gRPC-web server
317
+ *
318
+ * Uses `@connectrpc/connect-web` to communicate with the gRPC-web server.
319
+ * @public
320
+ */
321
+ export declare class ProverClient {
322
+ private client;
323
+ private pollIntervalMs;
324
+ private maxPollAttempts;
325
+ constructor(proverUrl: string, options?: {
326
+ pollIntervalMs?: number;
327
+ maxPollAttempts?: number;
328
+ });
329
+ /**
330
+ * Generate a proof by sending witness data to the prover server
331
+ *
332
+ * The server handles witness transformation internally, so we send
333
+ * the structured WitnessData instead of pre-serialized circuit witness bytes.
334
+ */
335
+ generateProof(witness: WitnessData): Promise<ProofResult>;
336
+ /**
337
+ * Export the verifier contract from the prover server
338
+ */
339
+ exportVerifier(): Promise<string>;
340
+ private witnessToProto;
341
+ private sleep;
342
+ }
343
+
344
+ /**
345
+ * Client-side metadata for redeem (NOT from prover)
346
+ * @public
347
+ */
348
+ export declare interface RedeemMetadata {
349
+ lightClients: LightClientData[];
350
+ nullifier: bigint;
351
+ value: bigint;
352
+ beneficiary: Address;
353
+ attestedMessage: Hex;
354
+ signature: Hex;
355
+ }
356
+
357
+ /**
358
+ * @public
359
+ */
360
+ export declare interface RedeemOptions {
361
+ /** The 32-byte secret payment key as a hex string */
362
+ paymentKey: Hex;
363
+ /** Array of 0-4 beneficiary addresses */
364
+ beneficiaries: Address[];
365
+ /** The beneficiary address to redeem to */
366
+ beneficiary: Address;
367
+ /** Amount to redeem */
368
+ amount: bigint;
369
+ /** Light client IDs to include in the proof (for anonymity set) */
370
+ clientIds: number[];
371
+ /** The specific light client ID to use for the proof */
372
+ selectedClientId: number;
373
+ /** viem WalletClient with account and chain configured */
374
+ walletClient: WalletClient;
375
+ /** Auto unwrap */
376
+ unwrap?: boolean | undefined;
377
+ }
378
+
379
+ /**
380
+ * @public
381
+ */
382
+ export declare interface RedeemParams {
383
+ proof: [bigint, bigint, bigint, bigint, bigint, bigint, bigint, bigint];
384
+ commitments: [bigint, bigint];
385
+ commitmentPok: [bigint, bigint];
386
+ lightClients: {
387
+ clientId: number;
388
+ height: bigint;
389
+ }[];
390
+ nullifier: bigint;
391
+ value: bigint;
392
+ beneficiary: Address;
393
+ attestedMessage: Hex;
394
+ signature: Hex;
395
+ }
396
+
397
+ /**
398
+ * @public
399
+ */
400
+ export declare interface RedeemResult {
401
+ txHash: Hash;
402
+ success: boolean;
403
+ error?: string;
404
+ }
405
+
406
+ /**
407
+ * @public
408
+ */
409
+ export declare interface RedeemTransaction {
410
+ txHash: Hash;
411
+ blockNumber: bigint;
412
+ timestamp: bigint;
413
+ nullifier: bigint;
414
+ value: bigint;
415
+ beneficiary: Address;
416
+ }
417
+
418
+ /**
419
+ * A single redemption event from getRedemptionHistory().
420
+ * @public
421
+ */
422
+ export declare interface RedemptionHistoryEntry {
423
+ /** Transaction hash of the redemption */
424
+ txHash: Hash;
425
+ /** Block number when the redemption was confirmed */
426
+ blockNumber: bigint;
427
+ /** Amount redeemed in this transaction */
428
+ redeemAmount: bigint;
429
+ /** Address that received the redeemed tokens */
430
+ beneficiary: Address;
431
+ }
432
+
433
+ /**
434
+ * @public
435
+ */
436
+ export declare class RpcClient {
437
+ private client;
438
+ constructor(rpcUrl: string);
439
+ getClient(): PublicClient;
440
+ getChainId(): Promise<bigint>;
441
+ getLatestBlockNumber(): Promise<bigint>;
442
+ getBalance(tokenAddress: Address, accountAddress: Address, blockNumber?: bigint): Promise<bigint>;
443
+ getDecimals(tokenAddress: Address): Promise<number>;
444
+ getSymbol(tokenAddress: Address): Promise<string>;
445
+ getLightClientAddress(ibcStoreAddress: Address, clientId: number): Promise<Address>;
446
+ getLatestHeight(lightClientAddress: Address, clientId: number): Promise<bigint>;
447
+ /**
448
+ * Get consensus state, extracting the state root at the given byte index
449
+ */
450
+ getConsensusState(lightClientAddress: Address, clientId: number, height: bigint, stateRootIndex: bigint): Promise<ConsensusState>;
451
+ getNullifierBalance(zassetAddress: Address, nullifier: bigint): Promise<bigint>;
452
+ getCounterparty(zassetAddress: Address, clientId: number): Promise<CounterpartyInfo>;
453
+ getIbcHandlerAddress(zassetAddress: Address): Promise<Address>;
454
+ getStateRootIndex(zassetAddress: Address, clientId: number): Promise<bigint>;
455
+ getProof(address: Address, storageKeys: Hex[], blockNumber: bigint): Promise<GetProofReturnType>;
456
+ getBlock(blockNumber: bigint): Promise<{
457
+ number: bigint;
458
+ nonce: `0x${string}`;
459
+ hash: `0x${string}`;
460
+ logsBloom: `0x${string}`;
461
+ baseFeePerGas: bigint | null;
462
+ blobGasUsed: bigint;
463
+ difficulty: bigint;
464
+ excessBlobGas: bigint;
465
+ extraData: Hex;
466
+ gasLimit: bigint;
467
+ gasUsed: bigint;
468
+ miner: Address;
469
+ mixHash: Hash;
470
+ parentBeaconBlockRoot?: `0x${string}` | undefined;
471
+ parentHash: Hash;
472
+ receiptsRoot: Hex;
473
+ sealFields: Hex[];
474
+ sha3Uncles: Hash;
475
+ size: bigint;
476
+ stateRoot: Hash;
477
+ timestamp: bigint;
478
+ totalDifficulty: bigint | null;
479
+ transactionsRoot: Hash;
480
+ uncles: Hash[];
481
+ withdrawals?: Withdrawal[] | undefined | undefined;
482
+ withdrawalsRoot?: `0x${string}` | undefined;
483
+ transactions: `0x${string}`[];
484
+ }>;
485
+ /**
486
+ * Get redemption history for a nullifier by querying Redeemed events
487
+ */
488
+ getRedemptionHistory(zassetAddress: Address, nullifier: bigint, fromBlock?: bigint, toBlock?: bigint): Promise<RedemptionHistoryEntry[]>;
489
+ }
490
+
491
+ /**
492
+ * Sign an attested message with raw ECDSA (no EIP-191 prefix).
493
+ * Matches Go CLI's crypto.Sign behavior for SignatureCheckerLib verification.
494
+ * @public
495
+ */
496
+ export declare function signAttestedMessage(message: Hex, privateKey: Hex): Promise<Hex>;
497
+
498
+ /**
499
+ * @public
500
+ */
501
+ export declare function submitRedeem(zassetAddress: Address, params: RedeemParams, walletClient: WalletClient): Promise<Hash>;
502
+
503
+ /**
504
+ * Token metadata from getSrcZAssetInfo() or getDstZAssetInfo().
505
+ * @public
506
+ */
507
+ export declare interface TokenInfo {
508
+ /** Token symbol (e.g., "USDC") */
509
+ symbol: string;
510
+ /** Number of decimal places */
511
+ decimals: number;
512
+ }
513
+
514
+ /**
515
+ * Union Private Payments client
516
+ *
517
+ * This class provides a high-level interface for performing private transfers
518
+ * using the Union protocol. It handles:
519
+ *
520
+ * - Generating unspendable addresses for deposits
521
+ *
522
+ * - Querying balances (confirmed, pending, redeemed, available)
523
+ *
524
+ * - Building witness data for proof generation
525
+ *
526
+ * - Communicating with the prover server
527
+ *
528
+ * @example
529
+ * ```typescript
530
+ * import { UnionPrivatePayments } from '@unionlabs/payments';
531
+ *
532
+ * const client = new UnionPrivatePayments({
533
+ * proverUrl: 'http://localhost:8080',
534
+ * sourceRpcUrl: 'https://eth-mainnet.alchemyapi.io/v2/...',
535
+ * destinationRpcUrl: 'https://arbitrum-mainnet.alchemyapi.io/v2/...',
536
+ * srcZAssetAddress: '0x...', // ZAsset on source chain
537
+ * dstZAssetAddress: '0x...', // ZAsset on destination chain
538
+ * sourceChainId: 1n,
539
+ * destinationChainId: 42161n,
540
+ * });
541
+ *
542
+ * // Generate deposit address
543
+ * const address = client.getDepositAddress(secret, beneficiaries);
544
+ *
545
+ * // Check balance
546
+ * const balance = await client.getBalance({ depositAddress, nullifier, clientId });
547
+ *
548
+ * // Generate proof for redemption
549
+ * const proof = await client.generateProof(secret, beneficiaries, beneficiary, amount, clientIds);
550
+ * ```
551
+ * @public
552
+ */
553
+ export declare class UnionPrivatePayments {
554
+ private config;
555
+ private srcClient;
556
+ private dstClient;
557
+ private proverClient;
558
+ constructor(config: UnionPrivatePaymentsConfig);
559
+ /**
560
+ * Get the deposit address for a given secret and beneficiaries
561
+ *
562
+ * The returned address is an "unspendable" address derived from the secret.
563
+ * Tokens sent to this address can only be redeemed via ZK proof.
564
+ *
565
+ * @param secret - The 32-byte secret as a hex string
566
+ * @param beneficiaries - Array of 1-4 beneficiary addresses (remaining slots zero-padded)
567
+ * @returns The unspendable deposit address
568
+ */
569
+ getDepositAddress(secret: Hex, beneficiaries: Address[]): Address;
570
+ /**
571
+ * Get the nullifier for a given paymentKey
572
+ *
573
+ * The nullifier is used to prevent double-spending. Each (paymentKey, chainId) pair
574
+ * produces a unique nullifier that is recorded on-chain when funds are redeemed.
575
+ *
576
+ * @param paymentKey - The 32-byte paymentKey as a hex string
577
+ * @returns The nullifier as a bigint
578
+ */
579
+ getNullifier(paymentKey: Hex): bigint;
580
+ /**
581
+ * Get balance information
582
+ *
583
+ * Returns:
584
+ * - confirmed: balance visible to light client (provable)
585
+ * - redeemed: amount already redeemed via nullifier
586
+ * - available: amount that can be redeemed now (confirmed - redeemed)
587
+ * - pending: deposits not yet visible to light client
588
+ *
589
+ * @param options - Options for getting balance
590
+ * @returns Balance information
591
+ */
592
+ getBalance(options: GetBalanceOptions): Promise<BalanceInfo>;
593
+ /**
594
+ * Get balance information at a specific block height
595
+ *
596
+ * @param depositAddress - The deposit address (unspendable address)
597
+ * @param nullifier - The nullifier for this secret
598
+ * @param height - The block height to query confirmed balance at
599
+ * @returns Balance information at the given height
600
+ */
601
+ getBalanceAtHeight(depositAddress: Address, nullifier: bigint, height: bigint): Promise<Omit<BalanceInfo, "lightClientHeight">>;
602
+ /**
603
+ * Generate a proof for redeeming funds
604
+ *
605
+ * This method:
606
+ * 1. Fetches light client data from the destination chain
607
+ * 2. Deterministically shuffles clients for privacy
608
+ * 3. Fetches MPT proof from the source chain
609
+ * 4. Builds the witness data
610
+ * 5. Sends the witness to the prover server
611
+ * 6. Polls until the proof is ready
612
+ *
613
+ * @param secret - The 32-byte secret as a hex string
614
+ * @param beneficiaries - Array of 0-4 beneficiary addresses (empty array = unbounded mode)
615
+ * @param beneficiary - The beneficiary address to redeem to
616
+ * @param amount - Amount to redeem
617
+ * @param clientIds - Light client IDs to include in the proof (for anonymity set)
618
+ * @param selectedClientId - The specific light client ID to use for the proof
619
+ * @returns GenerateProofResult containing proof result and client-side metadata
620
+ */
621
+ generateProof(secret: Hex, beneficiaries: Address[], beneficiary: Address, amount: bigint, clientIds: number[], selectedClientId: number): Promise<GenerateProofResult>;
622
+ /**
623
+ * Export the verifier contract from the prover server
624
+ *
625
+ * The verifier contract is used to verify proofs on-chain.
626
+ * It is circuit-specific and does not change between proofs.
627
+ *
628
+ * @returns The Solidity verifier contract source code
629
+ */
630
+ exportVerifier(): Promise<string>;
631
+ /**
632
+ * Get source ZAsset token information
633
+ *
634
+ * @returns Token symbol and decimals
635
+ */
636
+ getSrcZAssetInfo(): Promise<TokenInfo>;
637
+ /**
638
+ * Get destination ZAsset token information
639
+ *
640
+ * @returns Token symbol and decimals
641
+ */
642
+ getDstZAssetInfo(): Promise<TokenInfo>;
643
+ /**
644
+ * Deposit underlying tokens to ZAsset and transfer to deposit address
645
+ *
646
+ * Executes 3 transactions: approve → deposit → transfer.
647
+ * The wallet client must be connected to the source chain.
648
+ *
649
+ * @param secret - The 32-byte secret as a hex string
650
+ * @param beneficiaries - Array of 0-4 beneficiary addresses
651
+ * @param amount - Amount to deposit (in underlying token's smallest unit)
652
+ * @param walletClient - viem WalletClient with account and chain configured
653
+ * @returns Transaction hash, deposit address, underlying token, and chain ID
654
+ */
655
+ deposit(options: DepositOptions): Promise<DepositResult>;
656
+ /**
657
+ * Deposit underlying tokens to ZAsset and transfer to deposit address
658
+ *
659
+ * Executes 3 transactions: approve → deposit → transfer.
660
+ * The wallet client must be connected to the source chain.
661
+ *
662
+ * @param secret - The 32-byte secret as a hex string
663
+ * @param beneficiaries - Array of 0-4 beneficiary addresses
664
+ * @param amount - Amount to deposit (in underlying token's smallest unit)
665
+ * @param walletClient - viem WalletClient with account and chain configured
666
+ * @returns Transaction hash, deposit address, underlying token, and chain ID
667
+ */
668
+ unsafeDeposit(options: DepositOptions): Promise<DepositResult>;
669
+ /**
670
+ * Update loopback light client to a specific block height
671
+ *
672
+ * Fetches the IBC handler address internally from the destination ZAsset.
673
+ * The wallet client must be connected to the destination chain.
674
+ *
675
+ * @returns Transaction hash, block number, state root, and chain ID
676
+ */
677
+ updateLightClient(options: UpdateLightClientOptions): Promise<UpdateLightClientResult>;
678
+ /**
679
+ * Update loopback light client to a specific block height
680
+ *
681
+ * Fetches the IBC handler address internally from the destination ZAsset.
682
+ * The wallet client must be connected to the destination chain.
683
+ *
684
+ * @returns Transaction hash, block number, state root, and chain ID
685
+ */
686
+ unsafeUpdateLightClient(options: UpdateLightClientOptions): Promise<UpdateLightClientResult>;
687
+ /**
688
+ * Get redemption history for a secret
689
+ *
690
+ * Queries the Redeemed events filtered by the nullifier derived from the secret.
691
+ * This is a read-only operation that doesn't require a wallet.
692
+ *
693
+ * @param secret - The 32-byte secret as a hex string
694
+ * @param fromBlock - Start block number (default: earliest)
695
+ * @param toBlock - End block number (default: latest)
696
+ * @returns Array of redemption transactions
697
+ */
698
+ getRedemptionHistory(secret: Hex, fromBlock?: bigint, toBlock?: bigint): Promise<RedemptionHistoryEntry[]>;
699
+ /**
700
+ * Get redemption history for a secret
701
+ *
702
+ * Queries the Redeemed events filtered by the nullifier derived from the secret.
703
+ * This is a read-only operation that doesn't require a wallet.
704
+ *
705
+ * @param secret - The 32-byte secret as a hex string
706
+ * @param fromBlock - Start block number (default: earliest)
707
+ * @param toBlock - End block number (default: latest)
708
+ * @returns Array of redemption transactions
709
+ */
710
+ unsafeGetRedemptionHistory(secret: Hex, fromBlock?: bigint, toBlock?: bigint): Promise<RedemptionHistoryEntry[]>;
711
+ /**
712
+ * Full redeem flow: generate proof + get attestation + submit transaction
713
+ *
714
+ * This method orchestrates the entire redemption process:
715
+ * 1. Generates a ZK proof via the prover server
716
+ * 2. Gets attestation from the attestation service
717
+ * 3. Submits the redeem transaction
718
+ *
719
+ * The wallet client must be connected to the destination chain.
720
+ *
721
+ * @returns Transaction hash, proof, and metadata
722
+ */
723
+ redeem(options: RedeemOptions): Promise<FullRedeemResult>;
724
+ /**
725
+ * Full redeem flow: generate proof + get attestation + submit transaction
726
+ *
727
+ * This method orchestrates the entire redemption process:
728
+ * 1. Generates a ZK proof via the prover server
729
+ * 2. Gets attestation from the attestation service
730
+ * 3. Submits the redeem transaction
731
+ *
732
+ * The wallet client must be connected to the destination chain.
733
+ *
734
+ * @returns Transaction hash, proof, and metadata
735
+ */
736
+ unsafeRedeem(options: RedeemOptions): Promise<FullRedeemResult>;
737
+ /**
738
+ * Pad beneficiaries array to exactly 4 addresses
739
+ * Empty array = unbounded mode (all zeros, any beneficiary allowed)
740
+ */
741
+ private padBeneficiaries;
742
+ }
743
+
744
+ /**
745
+ * Configuration for the UnionPrivatePayments client.
746
+ * @public
747
+ */
748
+ export declare interface UnionPrivatePaymentsConfig {
749
+ /** URL of the ZK prover server (gRPC-web endpoint) */
750
+ proverUrl: string;
751
+ /** RPC URL for the source chain where deposits are made */
752
+ sourceRpcUrl: string;
753
+ /** RPC URL for the destination chain where redemptions occur */
754
+ destinationRpcUrl: string;
755
+ /** ZAsset contract address on the source chain */
756
+ srcZAssetAddress: Address;
757
+ /** ZAsset contract address on the destination chain */
758
+ dstZAssetAddress: Address;
759
+ /** Chain ID of the source chain */
760
+ sourceChainId: bigint;
761
+ /** Chain ID of the destination chain */
762
+ destinationChainId: bigint;
763
+ /** Optional attestation service URL for redemptions */
764
+ attestorUrl?: string;
765
+ /** Optional attestation service API key */
766
+ attestorApiKey?: string;
767
+ }
768
+
769
+ /**
770
+ * @public
771
+ */
772
+ export declare interface UpdateLightClientOptions {
773
+ /** The light client ID to update */
774
+ clientId: number;
775
+ /** Block height to update to (bigint or 'latest') */
776
+ height: bigint | "latest";
777
+ /** viem WalletClient with account and chain configured */
778
+ walletClient: WalletClient;
779
+ }
780
+
781
+ /**
782
+ * Result from updateLightClient() after updating a loopback light client.
783
+ * @public
784
+ */
785
+ export declare interface UpdateLightClientResult {
786
+ /** Transaction hash of the update */
787
+ txHash: Hash;
788
+ /** Block number the light client was updated to */
789
+ blockNumber: bigint;
790
+ /** State root at the updated block height */
791
+ stateRoot: Hash;
792
+ /** Chain ID where the update occurred */
793
+ chainId: bigint;
794
+ }
795
+
796
+ /**
797
+ * Update a loopback light client to a specific block height.
798
+ * The loopback client operates on the same chain, so only one RPC URL is needed.
799
+ *
800
+ * @param rpcUrl - RPC URL for the chain (same chain for fetching block and submitting tx)
801
+ * @param ibcHandlerAddress - Address of the IBCHandler contract
802
+ * @param clientId - The light client ID to update
803
+ * @param height - Block height to update to (bigint or 'latest')
804
+ * @param walletClient - viem WalletClient with account and chain configured
805
+ * @returns Transaction hash, block number, state root, and chain ID
806
+ * @public
807
+ */
808
+ export declare function updateLoopbackClient(rpcUrl: string, ibcHandlerAddress: Address, clientId: number, height: bigint | 'latest', walletClient: WalletClient): Promise<UpdateLightClientResult>;
809
+
810
+ /**
811
+ * Wait for predicate on block height
812
+ * @public
813
+ */
814
+ export declare const waitForBlockCondition: <T extends PublicClient>(publicClient: T, predicate: (blockNumber: bigint) => boolean, options?: {
815
+ timeoutMs?: number | undefined;
816
+ }) => Promise<bigint>;
817
+
818
+ /**
819
+ * @public
820
+ */
821
+ export declare interface WitnessData {
822
+ secret: Hex;
823
+ dstChainId: bigint;
824
+ beneficiaries: [Address, Address, Address, Address];
825
+ beneficiary: Address;
826
+ redeemAmount: bigint;
827
+ alreadyRedeemed: bigint;
828
+ lightClients: LightClientData[];
829
+ selectedClientIndex: number;
830
+ mptProof: MptProofData;
831
+ srcZAssetAddress: Address;
832
+ mappingSlot: Hex;
833
+ }
834
+
835
+ export { }